1 /*
2  *  gretl -- Gnu Regression, Econometrics and Time-series Library
3  *  Copyright (C) 2001 Allin Cottrell and Riccardo "Jack" Lucchetti
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 #include "libgretl.h"
21 #include "monte_carlo.h"
22 #include "var.h"
23 #include "johansen.h"
24 #include "system.h"
25 #include "objstack.h"
26 #include "usermat.h"
27 #include "forecast.h"
28 #include "bootstrap.h"
29 #include "libset.h"
30 
31 #define ODEBUG 0
32 
33 typedef struct stacker_ stacker;
34 
35 struct stacker_ {
36     int type;
37     void *ptr;
38 };
39 
40 static stacker *ostack;
41 static int n_obj;
42 static int n_sys;
43 static int n_vars;
44 
45 static stacker last_model;
46 static stacker genr_model;
47 
get_stacked_type_by_data(void * ptr)48 static GretlObjType get_stacked_type_by_data (void *ptr)
49 {
50     int i;
51 
52     for (i=0; i<n_obj; i++) {
53 	if (ostack[i].ptr == ptr) {
54 	    return ostack[i].type;
55 	}
56     }
57 
58     return GRETL_OBJ_NULL;
59 }
60 
61 #if ODEBUG
62 
object_get_refcount(void * ptr,GretlObjType type)63 static int object_get_refcount (void *ptr, GretlObjType type)
64 {
65     int rc = -999;
66 
67     if (type == GRETL_OBJ_EQN) {
68 	MODEL *pmod = (MODEL *) ptr;
69 
70 	if (pmod != NULL) {
71 	    rc = pmod->refcount;
72 	}
73 	rc = pmod->refcount;
74     } else if (type == GRETL_OBJ_VAR) {
75 	GRETL_VAR *var = (GRETL_VAR *) ptr;
76 
77 	if (var != NULL) {
78 	    rc = var->refcount;
79 	}
80     } else if (type == GRETL_OBJ_SYS) {
81 	equation_system *sys = (equation_system *) ptr;
82 
83 	if (sys != NULL) {
84 	    rc = sys->refcount;
85 	}
86     }
87 
88     return rc;
89 }
90 
91 #endif
92 
93 #if ODEBUG > 1
94 
print_ostack(void)95 static void print_ostack (void)
96 {
97     fprintf(stderr, "\n*** object stack: n_obj = %d\n", n_obj);
98 
99     if (n_obj > 0) {
100 	void *p;
101 	int i, t;
102 
103 	for (i=0; i<n_obj; i++) {
104 	    p = ostack[i].ptr;
105 	    t = ostack[i].type;
106 	    fprintf(stderr, " %d: %p (type=%d, refcount=%d)\n", i, p,
107 		    t, object_get_refcount(p, t));
108 	}
109 	fputc('\n', stderr);
110     }
111 }
112 
113 #endif
114 
115 /**
116  * gretl_object_ref:
117  * @ptr: pointer to gretl obejct (e.g. #MODEL).
118  * @type: type of object.
119  *
120  * Augments the reference count for the object represented by
121  * @ptr, of type @type.
122  */
123 
gretl_object_ref(void * ptr,GretlObjType type)124 void gretl_object_ref (void *ptr, GretlObjType type)
125 {
126     if (type == GRETL_OBJ_EQN) {
127 	MODEL *pmod = (MODEL *) ptr;
128 
129 	if (pmod != NULL) {
130 	    pmod->refcount += 1;
131 #if ODEBUG
132 	    fprintf(stderr, "gretl_object_ref: refcount on %p is now %d\n",
133 		    (void *) pmod, pmod->refcount);
134 #endif
135 	}
136     } else if (type == GRETL_OBJ_VAR) {
137 	GRETL_VAR *var = (GRETL_VAR *) ptr;
138 
139 	if (var != NULL) {
140 	    var->refcount += 1;
141 	}
142     } else if (type == GRETL_OBJ_SYS) {
143 	equation_system *sys = (equation_system *) ptr;
144 
145 	if (sys != NULL) {
146 	    sys->refcount += 1;
147 	}
148     }
149 }
150 
151 enum {
152     UNSTACK_REMOVE,
153     UNSTACK_DESTROY
154 };
155 
156 static int unstack_replace;
157 
gretl_object_unstack(void * ptr,int action)158 static void gretl_object_unstack (void *ptr, int action)
159 {
160     int i, pos = -1;
161 
162 #if ODEBUG
163     fprintf(stderr, "gretl_object_unstack: ptr=%p, action=%d\n", ptr, action);
164 #endif
165 
166     if (action == UNSTACK_DESTROY && ptr == last_model.ptr) {
167 #if ODEBUG
168 	fprintf(stderr, " %p is 'last_model'\n", ptr);
169 #endif
170 	/* avoid double-freeing */
171 	last_model.ptr = NULL;
172 	last_model.type = GRETL_OBJ_NULL;
173     }
174 
175     if (unstack_replace) {
176 	return;
177     }
178 
179     for (i=0; i<n_obj; i++) {
180 	if (ptr == ostack[i].ptr) {
181 	    pos = i;
182 	    break;
183 	}
184     }
185 
186 #if ODEBUG
187     fprintf(stderr, " stack pos for %p = %d, n_obj = %d\n",
188 	    ptr, pos, n_obj);
189 #endif
190 
191     if (pos >= 0) {
192 	n_obj--;
193 	if (n_obj == 0) {
194 	    free(ostack);
195 	    ostack = NULL;
196 	} else {
197 	    stacker *new_stack;
198 
199 	    for (i=pos; i<n_obj; i++) {
200 		ostack[i] = ostack[i+1];
201 	    }
202 
203 	    new_stack = realloc(ostack, n_obj * sizeof *new_stack);
204 	    if (new_stack != NULL) {
205 		ostack = new_stack;
206 	    }
207 	}
208     }
209 }
210 
gretl_object_destroy(void * ptr,GretlObjType type)211 static void gretl_object_destroy (void *ptr, GretlObjType type)
212 {
213 #if ODEBUG
214     fprintf(stderr, "gretl_object_destroy: ptr %p, type %d\n",
215 	    ptr, type);
216 #endif
217 
218     gretl_object_unstack(ptr, UNSTACK_DESTROY);
219 
220     if (type == GRETL_OBJ_EQN) {
221 	gretl_model_free(ptr);
222     } else if (type == GRETL_OBJ_VAR) {
223 	gretl_VAR_free(ptr);
224     } else if (type == GRETL_OBJ_SYS) {
225 	equation_system_destroy(ptr);
226     }
227 }
228 
229 /* The stuff below: Note that we can't "protect" a model (against
230    deletion) simply by setting its refcount to some special value,
231    when models are being reused, since the refcount will go to 0 every
232    time the model is assigned to!  Hence we need to set up this
233    "protected species" list.
234 */
235 
236 static MODEL **protected_models;
237 static int n_prot;
238 
gretl_model_protect(MODEL * pmod)239 int gretl_model_protect (MODEL *pmod)
240 {
241     MODEL **prmod;
242     int err = 0;
243 
244     prmod = realloc(protected_models, (n_prot + 1) * sizeof *prmod);
245 
246     if (prmod == NULL) {
247 	fprintf(stderr, "gretl_model_protect: out of memory!\n");
248 	err = E_ALLOC;
249     } else {
250 	protected_models = prmod;
251 	protected_models[n_prot++] = pmod;
252     }
253 
254     return err;
255 }
256 
gretl_model_unprotect(MODEL * pmod)257 int gretl_model_unprotect (MODEL *pmod)
258 {
259     MODEL **prmod;
260     int match = 0;
261     int i, j, err = 0;
262 
263     for (i=0; i<n_prot; i++) {
264 	if (protected_models[i] == pmod) {
265 	    match = 1;
266 	    for (j=i; j<n_prot-1; j++) {
267 		protected_models[j] = protected_models[j+1];
268 	    }
269 	    break;
270 	}
271     }
272 
273     if (match) {
274 	if (n_prot == 1) {
275 	    free(protected_models);
276 	    protected_models = NULL;
277 	    n_prot = 0;
278 	} else {
279 	    prmod = realloc(protected_models, (n_prot - 1) * sizeof *prmod);
280 	    if (prmod == NULL) {
281 		fprintf(stderr, "gretl_model_unprotect: out of memory!\n");
282 		err = E_ALLOC;
283 	    } else {
284 		protected_models = prmod;
285 		n_prot--;
286 	    }
287 	}
288     }
289 
290     return err;
291 }
292 
model_is_protected(MODEL * pmod)293 static int model_is_protected (MODEL *pmod)
294 {
295     int i, prot = 0;
296 
297     for (i=0; i<n_prot; i++) {
298 	if (pmod == protected_models[i]) {
299 	    prot = 1;
300 	    break;
301 	}
302     }
303 
304     if (!prot) {
305 	prot = model_is_in_loop(pmod);
306     }
307 
308 #if ODEBUG
309     if (prot) {
310 	fprintf(stderr, "model at %p is protected\n", (void *) pmod);
311     }
312 #endif
313 
314     return prot;
315 }
316 
317 /**
318  * gretl_object_unref:
319  * @ptr: pointer to gretl object (e.g. #MODEL).
320  * @type: type of object.
321  *
322  * Decrements the reference count for the object represented by
323  * @ptr, of type @type. When the count reaches zero the object
324  * is destroyed.
325  */
326 
gretl_object_unref(void * ptr,GretlObjType type)327 void gretl_object_unref (void *ptr, GretlObjType type)
328 {
329     int *rc = NULL;
330 
331     if (ptr == NULL) {
332 	/* no-op */
333 	return;
334     }
335 
336     if (type == GRETL_OBJ_ANY) {
337 	type = get_stacked_type_by_data(ptr);
338     }
339 
340     if (type == GRETL_OBJ_EQN) {
341 	MODEL *pmod = (MODEL *) ptr;
342 
343 	if (pmod != NULL) {
344 	    if (model_is_protected(pmod)) {
345 		return; /* note! */
346 	    }
347 	    rc = &pmod->refcount;
348 	}
349     } else if (type == GRETL_OBJ_VAR) {
350 	GRETL_VAR *var = (GRETL_VAR *) ptr;
351 
352 	if (var != NULL) {
353 	    rc = &var->refcount;
354 	}
355     } else if (type == GRETL_OBJ_SYS) {
356 	equation_system *sys = (equation_system *) ptr;
357 
358 	if (sys != NULL) {
359 	    rc = &sys->refcount;
360 	}
361     } else {
362 	fprintf(stderr, "gretl_object_unref: %p: bad object type\n",
363 		ptr);
364 	return;
365     }
366 
367 #if ODEBUG
368     fprintf(stderr, "gretl_object_unref: %p (incoming count = %d)\n",
369 	    ptr, *rc);
370 #endif
371 
372     if (rc != NULL) {
373 	*rc -= 1;
374 	if (*rc <= 0) {
375 	    gretl_object_destroy(ptr, type);
376 	}
377     }
378 
379 #if ODEBUG > 1
380     print_ostack();
381 #endif
382 }
383 
384 /**
385  * set_as_last_model:
386  * @ptr: pointer to gretl object (e.g. #MODEL).
387  * @type: type of object.
388  *
389  * Puts @ptr in place as the "last model" (which will be
390  * accessed by default via accessors such as "$uhat").
391  */
392 
set_as_last_model(void * ptr,GretlObjType type)393 void set_as_last_model (void *ptr, GretlObjType type)
394 {
395 #if ODEBUG
396     fprintf(stderr, "set_as_last_model: ptr=%p, type=%d; 'old' ptr=%p\n",
397 	    ptr, type, last_model.ptr);
398 #endif
399 
400     if (last_model.ptr != ptr && last_model.ptr != NULL) {
401 #if ODEBUG
402 	fprintf(stderr, " unrefing old object at %p (type %d)\n",
403 		last_model.ptr, last_model.type);
404 #endif
405 	gretl_object_unref(last_model.ptr, last_model.type);
406     }
407 
408     if (last_model.ptr != ptr || last_model.type != type) {
409 	last_model.ptr = ptr;
410 	last_model.type = type;
411 	if (ptr != NULL) {
412 	    gretl_object_ref(ptr, type);
413 	}
414     }
415 
416     /* Note: ensure that a newly estimated model supercedes
417        the "genr_model" set by the GUI (fncall.c), if present.
418     */
419     if (ptr != NULL && genr_model.ptr != NULL && genr_model.ptr != ptr) {
420 	unset_genr_model();
421     }
422 
423 #if ODEBUG
424     if (last_model.ptr != NULL) {
425 	int rc = object_get_refcount(last_model.ptr, last_model.type);
426 
427 	fprintf(stderr, " refcount on \"last_model\" = %d\n", rc);
428     }
429 #endif
430 }
431 
432 /**
433  * get_last_model:
434  * @type: location to receive type of last model, or %NULL.
435  *
436  * Returns: pointer to the last model estimated.  Note that
437  * this may be %NULL if no model has been estimated.
438  */
439 
get_last_model(GretlObjType * type)440 void *get_last_model (GretlObjType *type)
441 {
442     if (type != NULL) {
443 	*type = last_model.type;
444     }
445 
446     return last_model.ptr;
447 }
448 
449 /**
450  * get_last_model_type:
451  *
452  * Returns: the type indentifier for the last model estimated.
453  */
454 
get_last_model_type(void)455 GretlObjType get_last_model_type (void)
456 {
457     return last_model.type;
458 }
459 
460 /**
461  * gretl_object_get_name:
462  * @p: pointer to gretl object (e.g. #MODEL).
463  * @type: type of object.
464  *
465  * Returns: the name of the object of type @type with
466  * location @p, or %NULL if the object is not found.
467  * The return value may be ovewritten (up to
468  * MAXSAVENAME-1 characters), but must not be freed.
469  */
470 
gretl_object_get_name(void * p,GretlObjType type)471 char *gretl_object_get_name (void *p, GretlObjType type)
472 {
473     if (type == GRETL_OBJ_EQN) {
474 	MODEL *pmod = p;
475 
476 	if (pmod->name == NULL) {
477 	    pmod->name = calloc(MAXSAVENAME, 1);
478 	}
479 	return pmod->name;
480     } else if (type == GRETL_OBJ_VAR) {
481 	GRETL_VAR *var = p;
482 
483 	if (var->name == NULL) {
484 	    var->name = calloc(MAXSAVENAME, 1);
485 	}
486 	return var->name;
487     } else if (type == GRETL_OBJ_SYS) {
488 	equation_system *sys = p;
489 
490 	if (sys->name == NULL) {
491 	    sys->name = calloc(MAXSAVENAME, 1);
492 	}
493 	return sys->name;
494     }
495 
496     return NULL;
497 }
498 
499 static stacker *
get_stacker_by_name(const char * oname,GretlObjType type,int * onum)500 get_stacker_by_name (const char *oname, GretlObjType type, int *onum)
501 {
502     stacker *s = NULL;
503     const char *test;
504     int i;
505 
506     if (oname == NULL) {
507 	return NULL;
508     }
509 
510     for (i=0; i<n_obj; i++) {
511 	if (type == GRETL_OBJ_ANY || type == ostack[i].type) {
512 	    test = gretl_object_get_name(ostack[i].ptr, ostack[i].type);
513 	    if (!strcmp(oname, test)) {
514 		if (onum != NULL) {
515 		    *onum = i;
516 		}
517 		s = &ostack[i];
518 		break;
519 	    }
520 	}
521     }
522 
523 #if ODEBUG
524     fprintf(stderr, "get_stacker_by_name: name='%s', type=%d: got s=%p\n",
525 	    oname, type, (void *) s);
526 #endif
527 
528     return s;
529 }
530 
531 static void *
get_object_by_name(const char * oname,GretlObjType type,int * onum)532 get_object_by_name (const char *oname, GretlObjType type, int *onum)
533 {
534     void *ptr = NULL;
535     const char *test;
536     int i;
537 
538     if (oname == NULL) {
539 	return NULL;
540     }
541 
542     for (i=0; i<n_obj; i++) {
543 	if (type == GRETL_OBJ_ANY || type == ostack[i].type) {
544 	    test = gretl_object_get_name(ostack[i].ptr, ostack[i].type);
545 	    if (!strcmp(oname, test)) {
546 		if (onum != NULL) {
547 		    *onum = i;
548 		}
549 		ptr = ostack[i].ptr;
550 		break;
551 	    }
552 	}
553     }
554 
555 #if ODEBUG
556     fprintf(stderr, "get_object_by_name: name='%s', type=%d, ptr=%p\n",
557 	    oname, type, (void *) ptr);
558     if (ptr == NULL) {
559 	if (n_obj == 0) {
560 	    fprintf(stderr, "(no currently saved objects)\n");
561 	} else {
562 	    fprintf(stderr, "failed: current objects:\n");
563 	    for (i=0; i<n_obj; i++) {
564 		fprintf(stderr, " %02d: '%s' (%p, type %d)\n", i,
565 			gretl_object_get_name(ostack[i].ptr, ostack[i].type),
566 			ostack[i].ptr, ostack[i].type);
567 	    }
568 	}
569     }
570 #endif
571 
572     return ptr;
573 }
574 
gretl_get_object_by_name(const char * name)575 void *gretl_get_object_by_name (const char *name)
576 {
577     return get_object_by_name(name, GRETL_OBJ_ANY, NULL);
578 }
579 
get_model_object_and_type(const char * name,GretlObjType * type)580 void *get_model_object_and_type (const char *name,
581 				 GretlObjType *type)
582 {
583     void *ret = NULL;
584     GretlObjType ti;
585     const char *test;
586     int i;
587 
588     *type = GRETL_OBJ_NULL;
589 
590     if (name == NULL) {
591 	return NULL;
592     }
593 
594     for (i=0; i<n_obj; i++) {
595 	ti = ostack[i].type;
596 	if (ti == GRETL_OBJ_EQN || ti == GRETL_OBJ_VAR ||
597 	    ti == GRETL_OBJ_SYS) {
598 	    test = gretl_object_get_name(ostack[i].ptr, ti);
599 	    if (!strcmp(name, test)) {
600 		ret = ostack[i].ptr;
601 		*type = ti;
602 		break;
603 	    }
604 	}
605     }
606 
607     return ret;
608 }
609 
gretl_get_object_and_type(const char * name,GretlObjType * type)610 void *gretl_get_object_and_type (const char *name,
611 				 GretlObjType *type)
612 {
613     void *ret = NULL;
614     const char *test;
615     int i;
616 
617     *type = GRETL_OBJ_NULL;
618 
619     if (name == NULL) {
620 	return NULL;
621     }
622 
623     for (i=0; i<n_obj; i++) {
624 	test = gretl_object_get_name(ostack[i].ptr, ostack[i].type);
625 	if (!strcmp(name, test)) {
626 	    ret = ostack[i].ptr;
627 	    *type = ostack[i].type;
628 	    break;
629 	}
630     }
631 
632     return ret;
633 }
634 
get_model_by_ID(int ID)635 MODEL *get_model_by_ID (int ID)
636 {
637     MODEL *pmod;
638     int i;
639 
640     for (i=0; i<n_obj; i++) {
641 	if (ostack[i].type == GRETL_OBJ_EQN) {
642 	    pmod = (MODEL *) ostack[i].ptr;
643 	    if (pmod->ID == ID) {
644 		return pmod;
645 	    }
646 	}
647     }
648 
649     return NULL;
650 }
651 
get_model_by_name(const char * mname)652 MODEL *get_model_by_name (const char *mname)
653 {
654     return get_object_by_name(mname, GRETL_OBJ_EQN, NULL);
655 }
656 
get_VAR_by_name(const char * vname)657 GRETL_VAR *get_VAR_by_name (const char *vname)
658 {
659     return get_object_by_name(vname, GRETL_OBJ_VAR, NULL);
660 }
661 
get_VECM_by_name(const char * vname)662 GRETL_VAR *get_VECM_by_name (const char *vname)
663 {
664     GRETL_VAR *var = get_object_by_name(vname, GRETL_OBJ_VAR, NULL);
665 
666     if (var != NULL && var->ci == VECM) {
667 	return var;
668     } else {
669 	return NULL;
670     }
671 }
672 
get_equation_system_by_name(const char * sname)673 equation_system *get_equation_system_by_name (const char *sname)
674 {
675     return get_object_by_name(sname, GRETL_OBJ_SYS, NULL);
676 }
677 
gretl_object_compose_name(void * p,GretlObjType type)678 int gretl_object_compose_name (void *p, GretlObjType type)
679 {
680     char name[48];
681     int err = 0;
682 
683     if (type == GRETL_OBJ_EQN) {
684 	MODEL *pmod = (MODEL *) p;
685 
686 	sprintf(name, "%s %d", _("Model"), pmod->ID);
687 	gretl_model_set_name(pmod, name);
688     } else if (type == GRETL_OBJ_VAR) {
689 	GRETL_VAR *var = (GRETL_VAR *) p;
690 
691 	if (var->ci == VAR) {
692 	    sprintf(name, "%s %d", _("VAR"), ++n_vars);
693 	} else {
694 	    sprintf(name, "%s %d", _("VECM"), gretl_VECM_id(var));
695 	}
696 	gretl_VAR_set_name(var, name);
697     } else if (type == GRETL_OBJ_SYS) {
698 	equation_system *sys = (equation_system *) p;
699 
700 	sprintf(name, "%s %d", _("System"), ++n_sys);
701 	equation_system_set_name(sys, name);
702     } else {
703 	err = 1;
704     }
705 
706     return err;
707 }
708 
gretl_object_compose_unique_name(void * p,GretlObjType type)709 int gretl_object_compose_unique_name (void *p, GretlObjType type)
710 {
711     char name[48];
712     int id, err = 0;
713 
714     if (type == GRETL_OBJ_EQN) {
715 	MODEL *pmod = (MODEL *) p;
716 
717 	id = pmod->ID;
718 	sprintf(name, "%s %d", _("Model"), id);
719 	while (get_model_by_name(name) != NULL) {
720 	    sprintf(name, "%s %d", _("Model"), ++id);
721 	}
722 	gretl_model_set_name(pmod, name);
723     } else if (type == GRETL_OBJ_VAR) {
724 	GRETL_VAR *var = (GRETL_VAR *) p;
725 
726 	if (var->ci == VAR) {
727 	    char *vstr = _("VAR");
728 
729 	    if (strlen(vstr) > 3) {
730 		vstr = "VAR";
731 	    }
732 	    id = ++n_vars;
733 	    sprintf(name, "%s %d", vstr, id);
734 	    while (get_VAR_by_name(name) != NULL) {
735 		sprintf(name, "%s %d", vstr, ++id);
736 	    }
737 	} else {
738 	    char *vstr = _("VECM");
739 
740 	    if (strlen(vstr) > 4) {
741 		vstr = "VECM";
742 	    }
743 	    id = gretl_VECM_id(var);
744 	    sprintf(name, "%s %d", vstr, id);
745 	    while (get_VECM_by_name(name) != NULL) {
746 		sprintf(name, "%s %d", vstr, ++id);
747 	    }
748 	}
749 	gretl_VAR_set_name(var, name);
750     } else if (type == GRETL_OBJ_SYS) {
751 	equation_system *sys = (equation_system *) p;
752 
753 	id = ++n_sys;
754 	sprintf(name, "%s %d", _("System"), id);
755 	while (get_equation_system_by_name(name) != NULL) {
756 	    sprintf(name, "%s %d", _("System"), ++id);
757 	}
758 	equation_system_set_name(sys, name);
759     } else {
760 	err = 1;
761     }
762 
763     return err;
764 }
765 
gretl_object_rename(void * p,GretlObjType type,const char * oname)766 int gretl_object_rename (void *p, GretlObjType type, const char *oname)
767 {
768     int err = 0;
769 
770     if (type == GRETL_OBJ_EQN) {
771 	gretl_model_set_name((MODEL *) p, oname);
772     } else if (type == GRETL_OBJ_VAR) {
773 	gretl_VAR_set_name((GRETL_VAR *) p, oname);
774     } else if (type == GRETL_OBJ_SYS) {
775 	equation_system_set_name((equation_system *) p, oname);
776     } else {
777 	err = 1;
778     }
779 
780     return err;
781 }
782 
783 /* safety measure prior to freeing models on exit */
784 
remove_model_from_stack_on_exit(MODEL * pmod)785 void remove_model_from_stack_on_exit (MODEL *pmod)
786 {
787     int i;
788 
789     for (i=0; i<n_obj; i++) {
790 	if (pmod == ostack[i].ptr) {
791 	    ostack[i].ptr = NULL;
792 	    ostack[i].type = 0;
793 	    break;
794 	}
795     }
796 
797     if (last_model.ptr == pmod) {
798 	last_model.ptr = NULL;
799 	last_model.type = 0;
800     }
801 
802     gretl_model_unprotect(pmod);
803 }
804 
gretl_object_remove_from_stack(void * ptr,GretlObjType type)805 void gretl_object_remove_from_stack (void *ptr, GretlObjType type)
806 {
807 #if ODEBUG
808     fprintf(stderr, "gretl_object_remove_from_stack\n");
809 #endif
810     gretl_object_unstack(ptr, UNSTACK_REMOVE);
811     gretl_object_unref(ptr, type);
812 }
813 
object_stack_index(const void * p)814 static int object_stack_index (const void *p)
815 {
816     int i, ret = -1;
817 
818     for (i=0; i<n_obj; i++) {
819 	if (p == ostack[i].ptr) {
820 	    ret = i;
821 	    break;
822 	}
823     }
824 
825 #if ODEBUG
826     if (ret >= 0) {
827 	fprintf(stderr, "object_on_stack: object at %p already stacked "
828 		"at pos %d\n", p, ret);
829     }
830 #endif
831 
832     return ret;
833 }
834 
object_is_on_stack(const void * ptr)835 int object_is_on_stack (const void *ptr)
836 {
837     return (object_stack_index(ptr) >= 0);
838 }
839 
840 static int
real_stack_object(void * p,GretlObjType type,const char * name,PRN * prn)841 real_stack_object (void *p, GretlObjType type, const char *name, PRN *prn)
842 {
843     stacker *orig;
844     int onum, err = 0;
845 
846 #if ODEBUG
847     fprintf(stderr, "real_stack_object: on entry, p=%p, type=%d, name='%s'\n",
848 	    (void *) p, type, name);
849 #endif
850 
851     if (p == NULL) {
852 	return 1;
853     }
854 
855     if (object_stack_index(p) >= 0) {
856 #if ODEBUG
857 	fprintf(stderr, " real_stack_object: done, no-op\n");
858 #endif
859 	return 0;
860     }
861 
862     if (name == NULL || *name == '\0') {
863 	err = gretl_object_compose_name(p, type);
864     } else {
865 	err = gretl_object_rename(p, type, name);
866     }
867 
868     if (err) {
869 	return err;
870     }
871 
872     orig = get_stacker_by_name(name, type, &onum);
873 
874     if (orig != NULL) {
875 	/* replace existing object of same name */
876 #if ODEBUG
877 	fprintf(stderr, "  replacing at %p (onum = %d, ptr = %p)\n",
878 		orig, onum, orig->ptr);
879 #endif
880 	unstack_replace = 1;
881 	gretl_object_unref(orig->ptr, orig->type);
882 	unstack_replace = 0;
883 	ostack[onum].ptr = p;
884 	ostack[onum].type = type;
885 	pprintf(prn, "Replaced object '%s'\n", name);
886 	gretl_object_ref(p, type);
887     } else {
888 	stacker *tmp;
889 
890 	tmp = realloc(ostack, (n_obj + 1) * sizeof *ostack);
891 	if (tmp == NULL) {
892 	    return E_ALLOC;
893 	}
894 	ostack = tmp;
895 	ostack[n_obj].ptr = p;
896 	ostack[n_obj].type = type;
897 	gretl_object_ref(p, type);
898 	n_obj++;
899 	pprintf(prn, "Added object '%s'\n", name);
900     }
901 
902 #if ODEBUG
903     fprintf(stderr, " real_stack_object, on exit: '%s', type=%d, ptr=%p (n_obj=%d)\n",
904 	    name, type, (void *) p, n_obj);
905 #endif
906 
907 #if ODEBUG > 1
908     print_ostack();
909 #endif
910 
911     return 0;
912 }
913 
gretl_stack_object(void * ptr,GretlObjType type)914 int gretl_stack_object (void *ptr, GretlObjType type)
915 {
916     char *name = gretl_object_get_name(ptr, type);
917 
918     return real_stack_object(ptr, type, name, NULL);
919 }
920 
gretl_stack_object_as(void * ptr,GretlObjType type,const char * name)921 int gretl_stack_object_as (void *ptr, GretlObjType type, const char *name)
922 {
923     return real_stack_object(ptr, type, name, NULL);
924 }
925 
maybe_stack_var(GRETL_VAR * var,CMD * cmd)926 int maybe_stack_var (GRETL_VAR *var, CMD *cmd)
927 {
928     int err = 0;
929 
930     if (var != NULL) {
931 	const char *name = gretl_cmd_get_savename(cmd);
932 
933 	set_as_last_model(var, GRETL_OBJ_VAR);
934 	if (*name != '\0') {
935 	    err = real_stack_object(var, GRETL_OBJ_VAR, name, NULL);
936 	}
937     }
938 
939     return err;
940 }
941 
942 /* Called from interact.c, after sucessful estimation of a
943    (single-equation) model.  We automatically put the model in place
944    as the "last model" for reference purposes (e.g. in genr).  In
945    addition, if the model has been assigned a "savename" (via
946    something like "mymod <- ols 1 0 2"), we make a copy and add it to
947    the stack of saved objects.  We need to do the copying so that
948    if/when the original model pointer is reassigned to, via a further
949    estimation command, we do not lose the saved (named) model content.
950 
951    Reference counting: the model that is passed in should have its
952    refcount raised by 1 on account of set_as_last_model.  The refcount of
953    the copy (if applicable) should be 1, since the only reference to
954    this model pointer is the one on the stack of named objects.
955 
956    We return a pointer to the model as stacked, in case any further
957    action has to be taken (e.g. in the GUI).
958 */
959 
maybe_stack_model(MODEL * pmod,CMD * cmd,PRN * prn,int * err)960 MODEL *maybe_stack_model (MODEL *pmod, CMD *cmd, PRN *prn, int *err)
961 {
962     const char *name = gretl_cmd_get_savename(cmd);
963     gretlopt opt = gretl_cmd_get_opt(cmd);
964     MODEL *smod = NULL;
965 
966     if (*name != '\0' || (opt & OPT_W)) {
967 	MODEL *cpy = gretl_model_copy(pmod);
968 
969 	if (cpy == NULL) {
970 	    *err = E_ALLOC;
971 	} else if (*name != '\0') {
972 	    *err = real_stack_object(cpy, GRETL_OBJ_EQN, name, NULL);
973 	}
974 
975 	if (!*err) {
976 	    set_as_last_model(cpy, GRETL_OBJ_EQN);
977 	    if (*name != '\0') {
978 		pprintf(prn, _("%s saved\n"), name);
979 	    }
980 	} else {
981 	    errmsg(*err, prn);
982 	}
983 	smod = cpy;
984     } else {
985 	set_as_last_model(pmod, GRETL_OBJ_EQN);
986 	smod = pmod;
987     }
988 
989     return smod;
990 }
991 
992 #define INVALID_STAT -999.999
993 
994 /* retrieve from an object some value that is stored on the object in
995    the form of a simple scalar */
996 
real_get_obj_scalar(void * p,GretlObjType type,DATASET * dset,int idx)997 static double real_get_obj_scalar (void *p, GretlObjType type,
998 				   DATASET *dset, int idx)
999 {
1000     double x = INVALID_STAT;
1001     int err = 0;
1002 
1003     if (idx <= 0) {
1004 	return x;
1005     }
1006 
1007     if (type == GRETL_OBJ_EQN) {
1008 	MODEL *pmod = (MODEL *) p;
1009 
1010 	x = gretl_model_get_scalar(pmod, idx, dset, &err);
1011 	if (err) {
1012 	    x = INVALID_STAT;
1013 	}
1014     } else if (type == GRETL_OBJ_SYS) {
1015 	equation_system *sys = (equation_system *) p;
1016 
1017 	if (idx == M_T) {
1018 	    x = sys->T;
1019 	} else if (idx == M_LNL) {
1020 	    x = sys->ll;
1021 	} else if (idx == M_ESS) {
1022 	    x = sys->ess;
1023 	} else if (idx == M_DF) {
1024 	    x = sys->df;
1025 	} else if (idx == M_DIAGTEST) {
1026 	    err = system_diag_test(sys, &x, NULL);
1027 	} else if (idx == M_DIAGPVAL) {
1028 	    err = system_diag_test(sys, NULL, &x);
1029 	}
1030     } else if (type == GRETL_OBJ_VAR) {
1031 	GRETL_VAR *var = (GRETL_VAR *) p;
1032 
1033 	if (idx == M_T) {
1034 	    x = var->T;
1035 	} else if (idx == M_DF) {
1036 	    x = var->df;
1037 	} else if (idx == M_NCOEFF) {
1038 	    x = var->ncoeff;
1039 	} else if (idx == M_LNL) {
1040 	    x = var->ll;
1041 	} else if (idx == M_AIC) {
1042 	    x = var->AIC;
1043 	} else if (idx == M_BIC) {
1044 	    x = var->BIC;
1045 	} else if (idx == M_HQC) {
1046 	    x = var->HQC;
1047 	}
1048     }
1049 
1050     return x;
1051 }
1052 
1053 /* find out what sort of object we're dealing with, and call
1054    the appropriate function to get the requested matrix
1055 */
1056 
1057 static gretl_matrix *
real_get_obj_matrix(void * p,GretlObjType type,int idx,int * err)1058 real_get_obj_matrix (void *p, GretlObjType type, int idx, int *err)
1059 {
1060     gretl_matrix *M = NULL;
1061 
1062     if (idx <= 0) {
1063 	*err = 1;
1064 	return M;
1065     }
1066 
1067     if (type == GRETL_OBJ_EQN) {
1068 	MODEL *pmod = (MODEL *) p;
1069 
1070 	M = gretl_model_get_matrix(pmod, idx, err);
1071     } else if (type == GRETL_OBJ_SYS) {
1072 	equation_system *sys = (equation_system *) p;
1073 
1074 	M = equation_system_get_matrix(sys, idx, err);
1075     } else if (type == GRETL_OBJ_VAR) {
1076 	GRETL_VAR *var = (GRETL_VAR *) p;
1077 
1078 	M = gretl_VAR_get_matrix(var, idx, err);
1079     }
1080 
1081     return M;
1082 }
1083 
1084 #define list_carrying_type(t) (t == GRETL_OBJ_EQN || \
1085 			       t == GRETL_OBJ_VAR || \
1086 			       t == GRETL_OBJ_SYS)
1087 
1088 static int *
real_get_obj_list(void * p,GretlObjType type,int idx,int * err)1089 real_get_obj_list (void *p, GretlObjType type, int idx, int *err)
1090 {
1091     const MODEL *pmod = NULL;
1092     const GRETL_VAR *var = NULL;
1093     const equation_system *sys = NULL;
1094     const int *list = NULL;
1095     int *ret = NULL;
1096 
1097     if (idx <= 0 || p == NULL || !list_carrying_type(type)) {
1098 	*err = E_DATA;
1099 	return NULL;
1100     }
1101 
1102     if (type == GRETL_OBJ_EQN) {
1103 	pmod = p;
1104     } else if (type == GRETL_OBJ_VAR) {
1105 	var = p;
1106     } else {
1107 	sys = p;
1108     }
1109 
1110     if (idx == M_XLIST) {
1111 	if (type == GRETL_OBJ_EQN) {
1112 	    /* the list is already a copy */
1113 	    ret = gretl_model_get_x_list(pmod);
1114 	} else {
1115 	    if (type == GRETL_OBJ_VAR) {
1116 		list = var->xlist;
1117 	    } else {
1118 		list = sys->xlist;
1119 	    }
1120 	    if (list == NULL) {
1121 		*err = E_BADSTAT;
1122 	    } else {
1123 		ret = gretl_list_copy(list);
1124 	    }
1125 	}
1126     } else if (idx == M_YLIST) {
1127 	if (type == GRETL_OBJ_EQN) {
1128 	    ret = gretl_model_get_y_list(pmod);
1129 	} else {
1130 	    if (type == GRETL_OBJ_VAR) {
1131 		list = gretl_VAR_get_endo_list(var);
1132 	    } else {
1133 		list = system_get_endog_vars(sys);
1134 	    }
1135 	    if (list == NULL) {
1136 		*err = E_BADSTAT;
1137 	    } else {
1138 		ret = gretl_list_copy(list);
1139 	    }
1140 	}
1141     } else {
1142 	*err = E_BADSTAT;
1143     }
1144 
1145     if (ret == NULL && !*err) {
1146 	*err = E_ALLOC;
1147     }
1148 
1149     return ret;
1150 }
1151 
1152 static char *
real_get_obj_string(void * p,GretlObjType type,int idx,const DATASET * dset,int * err)1153 real_get_obj_string (void *p, GretlObjType type, int idx,
1154 		     const DATASET *dset, int *err)
1155 {
1156     char *str = NULL;
1157 
1158     if (idx <= 0) {
1159 	*err = 1;
1160 	return str;
1161     }
1162 
1163     if (idx == M_COMMAND) {
1164 	if (type == GRETL_OBJ_EQN) {
1165 	    MODEL *pmod = (MODEL *) p;
1166 
1167 	    str = gretl_strdup(gretl_command_word(pmod->ci));
1168 	} else if (type == GRETL_OBJ_SYS) {
1169 	    str = gretl_strdup(gretl_command_word(SYSTEM));
1170 	} else if (type == GRETL_OBJ_VAR) {
1171 	    GRETL_VAR *var = (GRETL_VAR *) p;
1172 
1173 	    str = gretl_strdup(gretl_command_word(var->ci));
1174 	}
1175     } else if (idx == M_DEPVAR && type == GRETL_OBJ_EQN) {
1176 	const char *s = gretl_model_get_depvar_name((MODEL *) p,
1177 						    dset);
1178 	str = gretl_strdup(s);
1179     }
1180 
1181     if (str == NULL) {
1182 	*err = E_BADSTAT;
1183     }
1184 
1185     return str;
1186 }
1187 
set_genr_model(void * ptr,GretlObjType type)1188 void set_genr_model (void *ptr, GretlObjType type)
1189 {
1190     genr_model.ptr = ptr;
1191     genr_model.type = type;
1192 }
1193 
unset_genr_model(void)1194 void unset_genr_model (void)
1195 {
1196     genr_model.type = GRETL_OBJ_NULL;
1197     genr_model.ptr = NULL;
1198 }
1199 
get_genr_model(GretlObjType * type)1200 void *get_genr_model (GretlObjType *type)
1201 {
1202     if (type != NULL) {
1203 	*type = genr_model.type;
1204     }
1205 
1206     return genr_model.ptr;
1207 }
1208 
get_genr_model_ID(void)1209 int get_genr_model_ID (void)
1210 {
1211     if (genr_model.ptr != NULL && genr_model.type == GRETL_OBJ_EQN) {
1212 	MODEL *pmod = genr_model.ptr;
1213 
1214 	return pmod->ID;
1215     } else {
1216 	return 0;
1217     }
1218 }
1219 
find_smatch(const char * oname)1220 static stacker *find_smatch (const char *oname)
1221 {
1222     stacker *smatch = NULL;
1223 
1224     if (oname == NULL || *oname == '\0') {
1225 	if (genr_model.ptr != NULL) {
1226 	    smatch = &genr_model;
1227 	} else {
1228 	    smatch = &last_model;
1229 	}
1230     } else {
1231 	const char *test;
1232 	int i;
1233 
1234 	for (i=0; i<n_obj; i++) {
1235 	    test = gretl_object_get_name(ostack[i].ptr, ostack[i].type);
1236 	    if (!strcmp(oname, test)) {
1237 		smatch = &ostack[i];
1238 		break;
1239 	    }
1240 	}
1241     }
1242 
1243     if (smatch != NULL && smatch->type == GRETL_OBJ_EQN) {
1244 	MODEL *pmod = smatch->ptr;
1245 
1246 	if (pmod == NULL || pmod->errcode) {
1247 	    fprintf(stderr, "find_smatch: duff model data!\n");
1248 	    smatch = NULL;
1249 	}
1250     }
1251 
1252     return smatch;
1253 }
1254 
saved_object_get_data_type(const char * name,ModelDataIndex idx)1255 GretlType saved_object_get_data_type (const char *name,
1256 				      ModelDataIndex idx)
1257 {
1258     stacker *smatch = find_smatch(name);
1259     GretlType ret = GRETL_TYPE_NONE;
1260 
1261     /* note: handles M_UHAT, M_YHAT, M_SIGMA */
1262 
1263     if (smatch != NULL) {
1264 	if (smatch->type == GRETL_OBJ_EQN) {
1265 	    if (idx == M_SIGMA) {
1266 		ret = GRETL_TYPE_DOUBLE;
1267 	    } else {
1268 		MODEL *pmod = smatch->ptr;
1269 
1270 		if (pmod->ci == BIPROBIT ||
1271 		    gretl_is_between_model(pmod)) {
1272 		    ret = GRETL_TYPE_MATRIX;
1273 		} else {
1274 		    ret = GRETL_TYPE_SERIES;
1275 		}
1276 	    }
1277 	} else {
1278 	    /* VAR, VECM, system */
1279 	    ret = GRETL_TYPE_MATRIX;
1280 	}
1281     }
1282 
1283     return ret;
1284 }
1285 
saved_object_get_list(const char * oname,int idx,int * err)1286 int *saved_object_get_list (const char *oname, int idx, int *err)
1287 {
1288     int *ret = NULL;
1289     stacker *smatch;
1290 
1291     smatch = find_smatch(oname);
1292 
1293     if (smatch != NULL) {
1294 	ret = real_get_obj_list(smatch->ptr, smatch->type, idx, err);
1295     }
1296 
1297     return ret;
1298 }
1299 
saved_object_get_string(const char * oname,int idx,const DATASET * dset,int * err)1300 char *saved_object_get_string (const char *oname, int idx,
1301 			       const DATASET *dset, int *err)
1302 {
1303     char *ret = NULL;
1304     stacker *smatch;
1305 
1306     smatch = find_smatch(oname);
1307 
1308     if (smatch != NULL) {
1309 	ret = real_get_obj_string(smatch->ptr, smatch->type, idx,
1310 				  dset, err);
1311     }
1312 
1313     return ret;
1314 }
1315 
saved_object_get_scalar(const char * oname,int idx,DATASET * dset,int * err)1316 double saved_object_get_scalar (const char *oname, int idx,
1317 				DATASET *dset, int *err)
1318 {
1319     double ret = INVALID_STAT;
1320     stacker *smatch;
1321 
1322     smatch = find_smatch(oname);
1323 
1324     if (smatch != NULL) {
1325 	ret = real_get_obj_scalar(smatch->ptr, smatch->type,
1326 				  dset, idx);
1327     }
1328 
1329     if (ret == INVALID_STAT) {
1330 	*err = E_BADSTAT;
1331     }
1332 
1333     return ret;
1334 }
1335 
saved_object_get_series(double * x,const char * oname,int idx,const DATASET * dset)1336 int saved_object_get_series (double *x, const char *oname,
1337 			     int idx, const DATASET *dset)
1338 {
1339     int err = 0;
1340 
1341     if (idx <= 0) {
1342 	err = E_DATA;
1343     } else {
1344 	stacker *smatch = find_smatch(oname);
1345 
1346 	if (smatch == NULL || smatch->type != GRETL_OBJ_EQN) {
1347 	    err = E_BADSTAT;
1348 	} else {
1349 	    MODEL *pmod = (MODEL *) smatch->ptr;
1350 
1351 	    err = gretl_model_get_series(x, pmod, dset, idx);
1352 	}
1353     }
1354 
1355     return err;
1356 }
1357 
1358 /* starting point for getting a matrix from a saved model
1359    of one kind or another.  We start by looking for the right
1360    model: this is either a match for @oname, or if @oname
1361    is NULL or blank, the last model estimated.
1362 */
1363 
1364 gretl_matrix *
saved_object_get_matrix(const char * oname,int idx,int * err)1365 saved_object_get_matrix (const char *oname, int idx, int *err)
1366 {
1367     gretl_matrix *M = NULL;
1368 
1369     if (idx == M_FCAST || idx == M_FCSE) {
1370 	M = get_forecast_matrix(idx, err);
1371     } else {
1372 	stacker *smatch = find_smatch(oname);
1373 
1374 	if (smatch != NULL) {
1375 	    M = real_get_obj_matrix(smatch->ptr, smatch->type, idx, err);
1376 	}
1377     }
1378 
1379     if (M == NULL && !*err) {
1380 	*err = E_BADSTAT;
1381     }
1382 
1383     return M;
1384 }
1385 
1386 /* similar to the above, but in this case the matrix to be
1387    retrieved is not pre-built, and requires (or may require)
1388    access to the current dataset for its building.
1389 */
1390 
1391 gretl_matrix *
saved_object_build_matrix(const char * oname,int idx,const DATASET * dset,int * err)1392 saved_object_build_matrix (const char *oname, int idx,
1393 			   const DATASET *dset,
1394 			   int *err)
1395 {
1396     stacker *smatch = find_smatch(oname);
1397     gretl_matrix *M = NULL;
1398 
1399     if (smatch == NULL) {
1400 	*err = E_DATA;
1401     } else if (idx == M_MNLPROBS && smatch->type == GRETL_OBJ_EQN) {
1402 	M = mn_logit_probabilities(smatch->ptr, dset, err);
1403     } else if (idx == M_EC && smatch->type == GRETL_OBJ_VAR) {
1404 	M = VECM_get_EC_matrix(smatch->ptr, dset, err);
1405     } else if (idx == M_VMA && smatch->type == GRETL_OBJ_VAR) {
1406 	M = gretl_VAR_get_vma_matrix(smatch->ptr, dset, err);
1407     } else if (idx == M_FEVD && smatch->type == GRETL_OBJ_VAR) {
1408 	M = gretl_VAR_get_full_FEVD_matrix(smatch->ptr, dset, err);
1409     } else {
1410 	*err = E_BADSTAT;
1411     }
1412 
1413     return M;
1414 }
1415 
saved_object_get_array(const char * oname,int idx,const DATASET * dset,int * err)1416 void *saved_object_get_array (const char *oname, int idx,
1417 			      const DATASET *dset,
1418 			      int *err)
1419 {
1420     stacker *smatch = find_smatch(oname);
1421     gretl_array *A = NULL;
1422 
1423     if (smatch == NULL) {
1424 	*err = E_DATA;
1425     } else if (idx == M_PARNAMES && smatch->type == GRETL_OBJ_EQN) {
1426 	A = gretl_model_get_param_names(smatch->ptr, dset, err);
1427     } else {
1428 	*err = E_BADSTAT;
1429     }
1430 
1431     return A;
1432 }
1433 
1434 gretl_matrix *
last_model_get_irf_matrix(int targ,int shock,double alpha,const DATASET * dset,int * err)1435 last_model_get_irf_matrix (int targ, int shock, double alpha,
1436 			   const DATASET *dset, int *err)
1437 {
1438     stacker *smatch = find_smatch(NULL);
1439     gretl_matrix *M = NULL;
1440 
1441     if (smatch == NULL || smatch->type != GRETL_OBJ_VAR) {
1442 	*err = E_BADSTAT;
1443     } else {
1444 	M = gretl_VAR_get_impulse_response(smatch->ptr, targ, shock, 0,
1445 					   alpha, dset, err);
1446     }
1447 
1448     return M;
1449 }
1450 
last_model_get_boot_ci(int cnum,const DATASET * dset,int B,double alpha,int method,int studentize,int * err)1451 gretl_matrix *last_model_get_boot_ci (int cnum,
1452 				      const DATASET *dset,
1453 				      int B,
1454 				      double alpha,
1455 				      int method,
1456 				      int studentize,
1457 				      int *err)
1458 {
1459     stacker *smatch = find_smatch(NULL);
1460     gretl_matrix *ret = NULL;
1461 
1462     if (smatch == NULL || smatch->type != GRETL_OBJ_EQN) {
1463 	*err = E_DATA;
1464     } else {
1465 	MODEL *pmod = smatch->ptr;
1466 
1467 	ret = bootstrap_ci_matrix(pmod, dset, cnum, B, alpha,
1468 				  method, studentize, err);
1469     }
1470 
1471     return ret;
1472 }
1473 
last_model_get_boot_pval(int cnum,const DATASET * dset,int B,int method,int * err)1474 double last_model_get_boot_pval (int cnum,
1475 				 const DATASET *dset,
1476 				 int B,
1477 				 int method,
1478 				 int *err)
1479 {
1480     stacker *smatch = find_smatch(NULL);
1481     double ret = NADBL;
1482 
1483     if (smatch == NULL || smatch->type != GRETL_OBJ_EQN) {
1484 	*err = E_DATA;
1485     } else {
1486 	MODEL *pmod = smatch->ptr;
1487 
1488 	ret = bootstrap_pvalue(pmod, dset, cnum, B, method, err);
1489     }
1490 
1491     return ret;
1492 }
1493 
last_model_get_data(const char * key,GretlType * type,int * size,int * copied,int * err)1494 void *last_model_get_data (const char *key, GretlType *type,
1495 			   int *size, int *copied, int *err)
1496 {
1497     stacker *smatch = find_smatch(NULL);
1498     void *ret = NULL;
1499 
1500     if (smatch == NULL || smatch->type != GRETL_OBJ_EQN) {
1501 	*err = E_DATA;
1502     } else {
1503 	const MODEL *pmod = smatch->ptr;
1504 	size_t sz = 0;
1505 
1506 	ret = gretl_model_get_data_full(pmod, key, type, copied, &sz);
1507 	if (ret == NULL) {
1508 	    *err = E_DATA;
1509 	} else if (size != NULL) {
1510 	    *size = sz;
1511 	}
1512     }
1513 
1514     if (*err) {
1515 	gretl_errmsg_sprintf("\"%s\": %s", key, _("no such item"));
1516     }
1517 
1518     return ret;
1519 }
1520 
last_model_get_vcv_type(void)1521 char *last_model_get_vcv_type (void)
1522 {
1523     stacker *smatch = find_smatch(NULL);
1524     static char ret[16];
1525 
1526     *ret = '\0';
1527 
1528     if (smatch != NULL && smatch->type == GRETL_OBJ_EQN) {
1529 	const MODEL *pmod = smatch->ptr;
1530 	VCVInfo *vi;
1531 
1532 	vi = gretl_model_get_data(pmod, "vcv_info");
1533 
1534 	if (vi != NULL && vi->vmaj == VCV_ML) {
1535 	    if (vi->vmin == ML_HESSIAN) {
1536 		strcpy(ret, "Hessian");
1537 	    } else if (vi->vmin == ML_OP) {
1538 		strcpy(ret, "OPG");
1539 	    } else if (vi->vmin == ML_QML) {
1540 		strcpy(ret, "Sandwich");
1541 	    }
1542 	}
1543     }
1544 
1545     return (*ret != '\0')? ret : NULL;
1546 }
1547 
namechar_spn_with_space(const char * s)1548 static int namechar_spn_with_space (const char *s)
1549 {
1550     const char *ok = "abcdefghijklmnopqrstuvwxyz"
1551 	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1552 	"0123456789_ ";
1553     int ret = 0;
1554 
1555     if (isalpha(*s)) {
1556 	ret = strspn(s, ok);
1557     }
1558 
1559     return ret;
1560 }
1561 
1562 #define OPDEBUG 0
1563 
1564 /* try to parse an "object-oriented" command, such as
1565    MyModel.free or "System 1".show */
1566 
parse_object_command(const char * s,char * name,char ** cmd)1567 int parse_object_command (const char *s, char *name, char **cmd)
1568 {
1569     int len, quoted = 0;
1570     int err = 0;
1571 
1572     *name = 0;
1573     *cmd = 0;
1574 
1575     /* skip any leading whitespace */
1576     while (*s && isspace(*s)) {
1577 	s++;
1578     }
1579 
1580     /* skip an opening quote */
1581     if (*s == '"') {
1582 	quoted = 1;
1583 	s++;
1584     }
1585 
1586     if (quoted) {
1587 	len = namechar_spn_with_space(s);
1588     } else {
1589 	len = gretl_namechar_spn(s);
1590     }
1591 
1592     if (len == 0) {
1593 	return 0;
1594     }
1595 
1596     if (len > MAXSAVENAME - 1) {
1597 	len = MAXSAVENAME - 1;
1598     }
1599 
1600     strncat(name, s, len);
1601     s += len;
1602 
1603     if (quoted && *s == '"') {
1604 	s++;
1605     }
1606 
1607     /* is an object command embedded? */
1608     if (*s == '.') {
1609 	s++;
1610 	if (*s && !isspace(*s)) {
1611 	    *cmd = gretl_strdup(s);
1612 	    if (*cmd == NULL) {
1613 		err = 1;
1614 	    }
1615 	}
1616     }
1617 
1618 #if OPDEBUG
1619     if (*cmd != NULL) {
1620 	fprintf(stderr, "name='%s', cmd='%s'\n", name, *cmd);
1621     } else {
1622 	fprintf(stderr, "name='%s'\n", name);
1623     }
1624 #endif
1625 
1626     return err;
1627 }
1628 
match_object_command(const char * s)1629 int match_object_command (const char *s)
1630 {
1631     if (strcmp(s, "show") == 0) {
1632 	return OBJ_ACTION_SHOW;
1633     } else if (strcmp(s, "free") == 0) {
1634 	return OBJ_ACTION_FREE;
1635     } else {
1636 	return OBJ_ACTION_INVALID;
1637     }
1638 }
1639 
saved_object_free(stacker * s)1640 static void saved_object_free (stacker *s)
1641 {
1642     if (s == NULL) {
1643 	return;
1644     }
1645 
1646     if (s->type == GRETL_OBJ_EQN) {
1647 	if (!model_is_protected(s->ptr)) {
1648 	    gretl_model_free(s->ptr);
1649 	}
1650     } else if (s->type == GRETL_OBJ_VAR) {
1651 	gretl_VAR_free(s->ptr);
1652     } else if (s->type == GRETL_OBJ_SYS) {
1653 	equation_system_destroy(s->ptr);
1654     }
1655 }
1656 
1657 #define sys_modtest_opt_ok(o) (o & (OPT_A | OPT_H | OPT_N))
1658 
last_model_test_ok(int ci,gretlopt opt,const DATASET * dset,PRN * prn)1659 int last_model_test_ok (int ci, gretlopt opt, const DATASET *dset,
1660 			PRN *prn)
1661 {
1662     GretlObjType type;
1663     void *ptr;
1664     int err = 0;
1665 
1666     ptr = get_last_model(&type);
1667     if (ptr == NULL) {
1668 	pputs(prn, _("Can't do this: no model has been estimated yet\n"));
1669 	return E_DATA;
1670     }
1671 
1672     if (type == GRETL_OBJ_EQN) {
1673 	MODEL *pmod = (MODEL *) ptr;
1674 
1675 	if (pmod->errcode) {
1676 	    err = E_DATA;
1677 	} else if (!model_test_ok(ci, opt, pmod, dset)) {
1678 	    err = E_NOTIMP;
1679 	} else if (ci == FCAST) {
1680 	    err = fcast_not_feasible(pmod, dset);
1681 	} else if (model_sample_problem(pmod, dset)) {
1682 	    pputs(prn, _("Can't do: the current data set is different from "
1683 			 "the one on which\nthe reference model was estimated\n"));
1684 	    err = E_DATA;
1685 	}
1686     } else if (type == GRETL_OBJ_SYS) {
1687 	err = E_NOTIMP;
1688 	if (ci == RESTRICT || ci == FCAST) {
1689 	    err = 0;
1690 	} else if (ci == MODTEST && sys_modtest_opt_ok(opt)) {
1691 	    err = 0;
1692 	}
1693     } else if (type == GRETL_OBJ_VAR) {
1694 	GRETL_VAR *var = (GRETL_VAR *) ptr;
1695 	int r = gretl_VECM_rank(var);
1696 
1697 	err = E_NOTIMP;
1698 
1699 	if (ci == RESTRICT) {
1700 	    err = 0;
1701 	} else if (ci == FCAST) {
1702 	    err = 0;
1703 	} else if (ci == MODTEST && sys_modtest_opt_ok(opt)) {
1704 	    err = 0;
1705 	} else if (ci == OMIT && r == 0 && !(opt & OPT_A)) {
1706 	    /* we can handle a test on exogenous terms in a VAR */
1707 	    err = 0;
1708 	}
1709     }
1710 
1711     return err;
1712 }
1713 
last_model_test_uhat(DATASET * dset,gretlopt opt,PRN * prn)1714 int last_model_test_uhat (DATASET *dset, gretlopt opt, PRN *prn)
1715 {
1716     GretlObjType type;
1717     void *ptr;
1718     int err = 0;
1719 
1720     ptr = get_last_model(&type);
1721     if (ptr == NULL) {
1722 	return E_DATA;
1723     }
1724 
1725     if (type == GRETL_OBJ_EQN) {
1726 	err = model_error_dist(ptr, dset, opt, prn);
1727     } else if (type == GRETL_OBJ_SYS) {
1728 	err = system_normality_test(ptr, opt, prn);
1729     } else if (type == GRETL_OBJ_VAR) {
1730 	err = gretl_VAR_normality_test(ptr, opt, prn);
1731     } else {
1732 	err = E_DATA;
1733     }
1734 
1735     return err;
1736 }
1737 
highest_numbered_var_in_saved_object(const DATASET * dset)1738 int highest_numbered_var_in_saved_object (const DATASET *dset)
1739 {
1740     GretlObjType type;
1741     void *ptr, *lmp = NULL;
1742     int i, mvm, vmax = 0;
1743 
1744     for (i=-1; i<n_obj; i++) {
1745 	if (i < 0) {
1746 	    lmp = ptr = get_last_model(&type);
1747 	} else {
1748 	    ptr = ostack[i].ptr;
1749 	    type = ostack[i].type;
1750 	}
1751 	if (ptr == NULL || (i >= 0 && ptr == lmp)) {
1752 	    continue;
1753 	}
1754 	if (type == GRETL_OBJ_EQN) {
1755 	    mvm = highest_numbered_var_in_model((MODEL *) ptr, dset);
1756 	    if (mvm > vmax) {
1757 		vmax = mvm;
1758 	    }
1759 	} else if (type == GRETL_OBJ_VAR) {
1760 	    mvm = gretl_VAR_get_highest_variable((GRETL_VAR *) ptr);
1761 	    if (mvm > vmax) {
1762 		vmax = mvm;
1763 	    }
1764 	} else if (type == GRETL_OBJ_SYS) {
1765 	    mvm = highest_numbered_var_in_system((equation_system *) ptr, dset);
1766 	    if (mvm > vmax) {
1767 		vmax = mvm;
1768 	    }
1769 	}
1770     }
1771 
1772     return vmax;
1773 }
1774 
check_variable_deletion_list(int * list,const DATASET * dset)1775 int check_variable_deletion_list (int *list, const DATASET *dset)
1776 {
1777     int pruned = 0;
1778     int i, vsave;
1779 
1780     vsave = highest_numbered_var_in_saved_object(dset);
1781 
1782     for (i=list[0]; i>0; i--) {
1783 	if (list[i] <= vsave) {
1784 	    gretl_list_delete_at_pos(list, i);
1785 	    pruned = 1;
1786 	}
1787     }
1788 
1789     return pruned;
1790 }
1791 
1792 static GList *(*get_or_send_gui_models)(GList *);
1793 
set_gui_model_list_callback(GList * (* callback)())1794 void set_gui_model_list_callback (GList *(*callback)())
1795 {
1796     get_or_send_gui_models = callback;
1797 }
1798 
1799 /* The following function is called from subsample.c when
1800    the user has called for a permanent subsampling (represented
1801    by @newmask) of the original dataset.
1802 
1803    If @ndropped is non-NULL that means we're just checking
1804    whether the proposed subsampling is inconsistent with
1805    preservation of any saved models -- and this argument gets
1806    filled out with the number of such models. This variant
1807    call is issued only in gui mode.
1808 
1809    Otherwise, for each saved model, we either mark it for
1810    deletion (via the GUI) or revise its sample information
1811    appropriately in light of the shrinkage of the dataset.
1812 */
1813 
check_models_for_subsample(char * newmask,int * ndropped)1814 int check_models_for_subsample (char *newmask, int *ndropped)
1815 {
1816     GList *fromgui = NULL;
1817     GretlObjType type;
1818     MODEL *pmod;
1819     void *ptr;
1820     int moderr;
1821     int err = 0;
1822 
1823     if (get_or_send_gui_models != NULL) {
1824 	fromgui = (*get_or_send_gui_models)(NULL);
1825     }
1826 
1827     if (ndropped != NULL) {
1828 	/* gui-only precheck: how many models are problematic? */
1829 	*ndropped = 0;
1830 	while (fromgui != NULL) {
1831 	    pmod = fromgui->data;
1832 	    moderr = subsample_check_model(pmod, newmask);
1833 	    if (moderr) {
1834 		*ndropped += 1;
1835 		err = E_CANCEL;
1836 	    }
1837 	    if (fromgui->next != NULL) {
1838 		fromgui = fromgui->next;
1839 	    } else {
1840 		break;
1841 	    }
1842 	}
1843 	fprintf(stderr, "gui-precheck: ndropped = %d\n", *ndropped);
1844     } else {
1845 	/* delete or fix-up affected models */
1846 	GList *togui = NULL;
1847 
1848 	ptr = get_last_model(&type);
1849 	if (ptr != NULL && type == GRETL_OBJ_EQN) {
1850 	    pmod = ptr;
1851 	    moderr = subsample_check_model(pmod, newmask);
1852 	    if (moderr) {
1853 		set_as_last_model(NULL, GRETL_OBJ_NULL);
1854 	    } else if (fromgui == NULL || g_list_find(fromgui, ptr) == NULL) {
1855 		/* don't do this twice on a given model */
1856 		remove_model_subsample_info(pmod);
1857 	    }
1858 	}
1859 
1860 	while (fromgui != NULL) {
1861 	    pmod = fromgui->data;
1862 	    fprintf(stderr, "finalizing model %p\n", fromgui->data);
1863 	    moderr = subsample_check_model(pmod, newmask);
1864 	    if (moderr) {
1865 		fprintf(stderr, " error: adding to deletion list\n");
1866 		togui = g_list_append(togui, fromgui->data);
1867 	    } else {
1868 		fprintf(stderr, " OK: fixing sample info\n");
1869 		remove_model_subsample_info(pmod);
1870 	    }
1871 	    if (fromgui->next != NULL) {
1872 		fromgui = fromgui->next;
1873 	    } else {
1874 		break;
1875 	    }
1876 	}
1877 
1878 	if (togui != NULL && get_or_send_gui_models != NULL) {
1879 	    (*get_or_send_gui_models)(togui);
1880 	}
1881     }
1882 
1883     if (fromgui != NULL) {
1884 	g_list_free(fromgui);
1885     }
1886 
1887     return err;
1888 }
1889 
n_stacked_models(void)1890 int n_stacked_models (void)
1891 {
1892     GList *list = NULL;
1893     int n = 0;
1894 
1895     if (get_or_send_gui_models != NULL) {
1896 	list = (*get_or_send_gui_models)(NULL);
1897 	n = g_list_length(list);
1898 	g_list_free(list);
1899     } else {
1900 	GretlObjType type;
1901 	void *ptr;
1902 	int i;
1903 
1904 	for (i=0; i<n_obj; i++) {
1905 	    ptr = ostack[i].ptr;
1906 	    type = ostack[i].type;
1907 	    if (ptr != NULL && type == GRETL_OBJ_EQN) {
1908 		n++;
1909 	    }
1910 	}
1911     }
1912 
1913     return n;
1914 }
1915 
gretl_saved_objects_cleanup(void)1916 void gretl_saved_objects_cleanup (void)
1917 {
1918     void *lmp = last_model.ptr;
1919     int lmt = last_model.type;
1920     int i;
1921 
1922 #if ODEBUG
1923     fprintf(stderr, "gretl_saved_objects_cleanup, n_obj = %d\n", n_obj);
1924 #endif
1925 
1926     for (i=0; i<n_obj; i++) {
1927 	if (ostack[i].ptr == lmp) {
1928 	    /* stacked object i also occupies the "last model" place;
1929 	       so we drop the associated refcount and nullify the
1930 	       last model pointer to guard against double-freeing
1931 	    */
1932 #if ODEBUG
1933 	    fprintf(stderr, " ostack[%d] = last model, unrefing\n", i);
1934 #endif
1935 	    gretl_object_unref(lmp, lmt);
1936 	    last_model.ptr = NULL;
1937 	    last_model.type = 0;
1938 	    lmp = NULL;
1939 	}
1940 #if ODEBUG
1941 	fprintf(stderr, " calling saved_object_free on ostack[%d] (%p)\n",
1942 		i, ostack[i].ptr);
1943 #endif
1944 	saved_object_free(&ostack[i]);
1945     }
1946 
1947     free(ostack);
1948     ostack = NULL;
1949 
1950     n_obj = 0;
1951     n_sys = 0;
1952     n_vars = 0;
1953 
1954     if (lmp != NULL) {
1955 	if (lmt != GRETL_OBJ_EQN || !model_is_protected(lmp)) {
1956 #if ODEBUG
1957 	    fprintf(stderr, "gretl_saved_objects_cleanup:\n"
1958 		    " calling gretl_object_destroy on last_model (%p)\n", lmp);
1959 #endif
1960 	    gretl_object_destroy(lmp, lmt);
1961 	}
1962 	last_model.ptr = NULL;
1963 	last_model.type = 0;
1964     }
1965 }
1966