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