"Fossies" - the Fresh Open Source Software Archive

Member "gretl-2020b/gui/library.c" (24 Mar 2020, 231268 Bytes) of package /linux/misc/gretl-2020b.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "library.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2020a_vs_2020b.

    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 /* library.c for gretl -- main interface to libgretl functions */
   21 
   22 #include "gretl.h"
   23 #include "var.h"
   24 #include "johansen.h"
   25 #include "textbuf.h"
   26 #include "gpt_control.h"
   27 #include "graph_page.h"
   28 #include "console.h"
   29 #include "system.h"
   30 #include "gretl_restrict.h"
   31 #include "gretl_func.h"
   32 #include "monte_carlo.h"
   33 #include "forecast.h"
   34 #include "dbwrite.h"
   35 #include "menustate.h"
   36 #include "dlgutils.h"
   37 #include "ssheet.h"
   38 #include "toolbar.h"
   39 #include "treeutils.h"
   40 #include "lib_private.h"
   41 #include "cmd_private.h"
   42 #include "flow_control.h"
   43 #include "libset.h"
   44 #include "libglue.h"
   45 #include "objstack.h"
   46 #include "gretl_xml.h"
   47 #include "gretl_panel.h"
   48 #include "gretl_midas.h"
   49 #include "gretl_foreign.h"
   50 #include "gretl_help.h"
   51 #include "gretl_zip.h"
   52 #include "uservar.h"
   53 #include "gretl_string_table.h"
   54 #include "csvdata.h"
   55 #include "matrix_extra.h"
   56 #include "gretl_typemap.h"
   57 #include "gretl_www.h"
   58 #include "texprint.h"
   59 #include "bootstrap.h"
   60 #include "fileselect.h"
   61 #include "database.h"
   62 #include "winstack.h"
   63 #include "guiprint.h"
   64 #include "varinfo.h"
   65 #include "fncall.h"
   66 
   67 #ifdef G_OS_WIN32
   68 # include <io.h>
   69 # include "gretlwin32.h"
   70 #else
   71 # include <unistd.h>
   72 # include <sys/stat.h>
   73 #endif
   74 
   75 #include "session.h"
   76 #include "selector.h"
   77 #include "boxplots.h"
   78 #include "series_view.h"
   79 #include "objectsave.h"
   80 #include "datafiles.h"
   81 #include "model_table.h"
   82 #include "cmdstack.h"
   83 #include "filelists.h"
   84 #include "fnsave.h"
   85 #include "dbread.h"
   86 
   87 #if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 20
   88 # include "spinner.h"
   89 #endif
   90 
   91 #define CMD_DEBUG 0
   92 
   93 /* file scope state variables */
   94 static CMD libcmd;
   95 static char libline[MAXLINE];
   96 static int original_n;
   97 static int gui_main_exec;
   98 
   99 char *get_lib_cmdline (void)
  100 {
  101     return libline;
  102 }
  103 
  104 CMD *get_lib_cmd (void)
  105 {
  106     return &libcmd;
  107 }
  108 
  109 void lib_cmd_destroy_context (void)
  110 {
  111     gretl_cmd_destroy_context(&libcmd);
  112 }
  113 
  114 void set_original_n (int n)
  115 {
  116     original_n = n;
  117 }
  118 
  119 int get_original_n (void)
  120 {
  121     return original_n;
  122 }
  123 
  124 /* the following two functions are called from gretl.c,
  125    at start-up and at exit respectively */
  126 
  127 void library_command_init (void)
  128 {
  129     gretl_cmd_init(&libcmd);
  130 }
  131 
  132 void library_command_free (void)
  133 {
  134     gretl_cmd_free(&libcmd);
  135 }
  136 
  137 void gui_graph_handler (int err)
  138 {
  139     if (err) {
  140     gui_errmsg(err);
  141     } else {
  142     register_graph();
  143     }
  144 }
  145 
  146 /* the following three functions are used to write
  147    a command line into the static string @libline
  148 */
  149 
  150 int lib_command_sprintf (const char *template, ...)
  151 {
  152     va_list args;
  153     int len;
  154 
  155     memset(libline, 0, MAXLINE);
  156 
  157     va_start(args, template);
  158     len = g_vsnprintf(libline, MAXLINE, template, args);
  159     va_end(args);
  160 
  161     if (len > MAXLINE) {
  162     warnbox_printf(_("Maximum length of command line "
  163              "(%d bytes) exceeded"), MAXLINE);
  164     }
  165 
  166     return len;
  167 }
  168 
  169 int lib_command_strcpy (const char *s)
  170 {
  171     memset(libline, 0, MAXLINE);
  172     strncat(libline, s, MAXLINE - 1);
  173 
  174     return 0;
  175 }
  176 
  177 int lib_command_strcat (const char *s)
  178 {
  179     int n = MAXLINE - strlen(libline) - 1;
  180 
  181     if (n > 0) {
  182     strncat(libline, s, n);
  183     }
  184 
  185     return 0;
  186 }
  187 
  188 int user_fopen (const char *fname, char *fullname, PRN **pprn)
  189 {
  190     int err = 0;
  191 
  192     strcpy(fullname, gretl_dotdir());
  193     strcat(fullname, fname);
  194 
  195     *pprn = gretl_print_new_with_filename(fullname, &err);
  196 
  197     if (err) {
  198     gui_errmsg(err);
  199     }
  200 
  201     return err;
  202 }
  203 
  204 gint bufopen (PRN **pprn)
  205 {
  206     static int has_minus = -1;
  207     int err = 0;
  208 
  209     *pprn = gretl_print_new(GRETL_PRINT_BUFFER, &err);
  210 
  211     if (err) {
  212     gui_errmsg(err);
  213     } else {
  214     if (has_minus < 0) {
  215         /* check for Unicode minus sign, U+2212 */
  216         has_minus = font_has_symbol(fixed_font, 0x2212);
  217     }
  218 
  219     if (has_minus > 0) {
  220         gretl_print_set_has_minus(*pprn);
  221     }
  222     }
  223 
  224     return err;
  225 }
  226 
  227 static char *cmd_to_buf (CMD *cmd, const char *line)
  228 {
  229     PRN *cmdprn = NULL;
  230     char *buf = NULL;
  231 
  232     bufopen(&cmdprn);
  233 
  234     if (cmdprn != NULL) {
  235     gretl_record_command(cmd, line, cmdprn);
  236     buf = gretl_print_steal_buffer(cmdprn);
  237     gretl_print_destroy(cmdprn);
  238     }
  239 
  240     return buf;
  241 }
  242 
  243 /*                 -- A note on recording commands --
  244 
  245    Wherever it's appropriate, we want to record the CLI equivalent of
  246    actions performed via the gretl GUI. There are two variant methods
  247    for doing this, depending on the complexity of the command. These
  248    methods share the same first step, namely:
  249 
  250    Step 1: The functions lib_command_{strcpy|strcat|sprintf} are used
  251    to write the relevant command into the static string @libline,
  252    which lives in this file, library.c. This stores the command line
  253    but does not yet write it into the command log.
  254 
  255    The SIMPLER command-recording variant then uses
  256    record_command_verbatim() to arrange for the string stored in
  257    @libline to be written to the log. (Note that this shouldn't be
  258    done until it's known that the GUI action in question was
  259    successful; we don't want to write failed commands into the log.)
  260 
  261    The MORE COMPLEX variant uses parse_lib_command() followed by
  262    record_lib_command(). The first of these functions runs the stored
  263    @libline through the libgretl command parser, and the second calls
  264    the libgretl function gretl_record_command() to produce the
  265    "canonical form" of the command, which is then entered in the
  266    command log.
  267 
  268    Why bother with the more complex variant? First, parsing the
  269    command line may expose an error which we'll then be able to
  270    catch. In addition, gretl_record_command() automatically breaks
  271    overly long lines, making for better legibility.
  272 
  273    IMPORTANT: when the second command-logging method is used,
  274    parse_lib_command() must always be called before
  275    record_lib_command(). The correct "echoing" of a command depends on
  276    the gretl CMD structure @libcmd being filled out appropriately by
  277    the parser, and moreover wrong use of record_lib_command() can
  278    produce a segfault in certain conditions.
  279 
  280    Typically, between calling parse_lib_command and record_lib_command
  281    we check to see if the action is successful; once again, we'd like
  282    to avoid logging failed commands.
  283 
  284    Final point: at present we're not actually logging all the GUI
  285    actions that have a CLI counterpart. A useful task for a "rainy
  286    day" would be to find unrecorded actions and add some more logging
  287    code.
  288 */
  289 
  290 /* To have the command flagged as associated with a particular
  291    model, give the model's ID member a argument; otherwise
  292    give 0.
  293 */
  294 
  295 static int real_record_lib_command (int model_ID)
  296 {
  297     char *buf;
  298     int err = 0;
  299 
  300     /* @libcmd must be filled out using parse_lib_command()
  301        before we get here: see the long note above
  302     */
  303 
  304 #if CMD_DEBUG
  305     fprintf(stderr, "record_lib_command:\n");
  306     fprintf(stderr, " libcmd.ci: %d\n", libcmd.ci);
  307     fprintf(stderr, " libcmd.param: '%s'\n", libcmd.param);
  308     fprintf(stderr, " libcmd.opt: %d\n", (int) libcmd.opt);
  309     fprintf(stderr, " line: '%s'\n", libline);
  310 #endif
  311 
  312     buf = cmd_to_buf(&libcmd, libline);
  313 
  314     if (buf == NULL) {
  315     err = 1;
  316     } else {
  317 #if CMD_DEBUG
  318     fprintf(stderr, "from gretl_record_command: buf='%s'\n", buf);
  319 #endif
  320     if (model_ID > 0) {
  321         err = add_model_command_to_stack(buf, model_ID, 1);
  322     } else {
  323         err = add_command_to_stack(buf, 1);
  324     }
  325     free(buf);
  326     }
  327 
  328     return err;
  329 }
  330 
  331 /* log a command in @libline that has been pre-parsed */
  332 
  333 static int record_lib_command (void)
  334 {
  335     return real_record_lib_command(0);
  336 }
  337 
  338 /* variant of the above for commands that pertain to a
  339    given model
  340 */
  341 
  342 static int record_model_command (int model_ID)
  343 {
  344     return real_record_lib_command(model_ID);
  345 }
  346 
  347 /* log a "simple" command when we already know that it
  348    worked OK; doesn't require that parse_lib_command
  349    has been called
  350 */
  351 
  352 int record_command_verbatim (void)
  353 {
  354     return add_command_to_stack(libline, 0);
  355 }
  356 
  357 /* variant of the above for commands that pertain to a
  358    given model
  359 */
  360 
  361 int record_model_command_verbatim (int model_ID)
  362 {
  363     return add_model_command_to_stack(libline, model_ID, 0);
  364 }
  365 
  366 /* parses @libline and fills out @libcmd, but does
  367    not of itself record (or execute) the command
  368 */
  369 
  370 static int parse_lib_command (void)
  371 {
  372     int err;
  373 
  374 #if CMD_DEBUG
  375     fprintf(stderr, "parse_lib_command: '%s'\n", libline);
  376 #endif
  377 
  378     err = parse_gui_command(libline, &libcmd, dataset);
  379     if (err) {
  380     gui_errmsg(err);
  381     }
  382 
  383     return err;
  384 }
  385 
  386 /* checks command line @s for errors, and if OK returns
  387    an allocated copy of the command list */
  388 
  389 int *command_list_from_string (const char *s, int *err)
  390 {
  391     int *list = NULL;
  392 
  393     list = generate_list(s, dataset, err);
  394 
  395     if (*err) {
  396     gui_errmsg(*err);
  397     }
  398 
  399     return list;
  400 }
  401 
  402 static int gui_exact_fit_check (MODEL *pmod)
  403 {
  404     if (pmod->rsq == 1.0) {
  405     infobox(_("The model exhibits an exact linear fit"));
  406     return 1;
  407     }
  408 
  409     return 0;
  410 }
  411 
  412 static int add_or_replace_series (double *x,
  413                   const char *vname,
  414                   const char *descrip,
  415                   int flag)
  416 {
  417     int v = series_index(dataset, vname);
  418     int err = 0;
  419 
  420     if (v > 0 && v < dataset->v) {
  421     /* replacing */
  422     err = dataset_replace_series(dataset, v, x,
  423                      descrip, flag);
  424     } else {
  425     /* adding */
  426     if (flag == DS_GRAB_VALUES) {
  427         err = dataset_add_allocated_series(dataset, x);
  428     } else {
  429         err = dataset_add_series(dataset, 1);
  430     }
  431     if (err) {
  432         gui_errmsg(err);
  433     } else {
  434         v = dataset->v - 1;
  435         strcpy(dataset->varname[v], vname);
  436         series_record_label(dataset, v, descrip);
  437         if (flag == DS_COPY_VALUES) {
  438         int t;
  439 
  440         for (t=0; t<dataset->n; t++) {
  441             dataset->Z[v][t] = x[t];
  442         }
  443         }
  444     }
  445     }
  446 
  447     return err;
  448 }
  449 
  450 static int add_or_replace_series_data (const double *x,
  451                        int t1, int t2,
  452                        const char *vname,
  453                        const char *descrip)
  454 {
  455     int v = series_index(dataset, vname);
  456     int err = 0;
  457 
  458     if (v > 0 && v < dataset->v) {
  459     /* replacing */
  460     err = dataset_replace_series_data(dataset, v,
  461                       x, t1, t2,
  462                       descrip);
  463     } else {
  464     /* adding */
  465     int t, s = 0;
  466 
  467     err = dataset_add_series(dataset, 1);
  468     if (err) {
  469         gui_errmsg(err);
  470     } else {
  471         v = dataset->v - 1;
  472         strcpy(dataset->varname[v], vname);
  473         series_record_label(dataset, v, descrip);
  474         for (t=0; t<dataset->n; t++) {
  475         if (t >= t1 && t <= t2) {
  476             dataset->Z[v][t] = x[s++];
  477         } else {
  478             dataset->Z[v][t] = NADBL;
  479         }
  480         }
  481     }
  482     }
  483 
  484     return err;
  485 }
  486 
  487 void add_mahalanobis_data (windata_t *vwin)
  488 {
  489     MahalDist *md = (MahalDist *) vwin->data;
  490     const double *dx;
  491     const int *mlist;
  492     char *liststr;
  493     char vname[VNAMELEN];
  494     char descrip[MAXLABEL];
  495     int cancel = 0;
  496     int err = 0;
  497 
  498     if (md == NULL) {
  499     errbox(_("Error adding variables"));
  500     return;
  501     }
  502 
  503     dx = mahal_dist_get_distances(md);
  504     mlist = mahal_dist_get_varlist(md);
  505     if (dx == NULL || mlist == NULL) {
  506     errbox(_("Error adding variables"));
  507     return;
  508     }
  509 
  510     strcpy(vname, "mdist");
  511     strcpy(descrip, _("Mahalanobis distances"));
  512 
  513     name_new_series_dialog(vname, descrip, vwin, &cancel);
  514 
  515     if (cancel) {
  516     return;
  517     }
  518 
  519     err = add_or_replace_series((double *) dx, vname, descrip,
  520                 DS_COPY_VALUES);
  521 
  522     if (!err) {
  523     liststr = gretl_list_to_string(mlist, dataset, &err);
  524     if (liststr != NULL) {
  525         lib_command_sprintf("mahal%s --save", liststr);
  526         record_command_verbatim();
  527         free(liststr);
  528     }
  529     }
  530 }
  531 
  532 void add_pca_data (windata_t *vwin)
  533 {
  534     VMatrix *cmat = (VMatrix *) vwin->data;
  535     int oldv = dataset->v;
  536     int err;
  537 
  538     err = call_pca_plugin(cmat, dataset, OPT_D, NULL);
  539 
  540     if (err) {
  541     gui_errmsg(err);
  542     } else if (dataset->v > oldv) {
  543     int addv = dataset->v - oldv;
  544     gretlopt opt = (addv == cmat->dim)? OPT_A : OPT_O;
  545     char *liststr;
  546 
  547     liststr = gretl_list_to_string(cmat->list, dataset, &err);
  548     if (liststr != NULL) {
  549         lib_command_sprintf("pca%s%s", liststr, print_flags(opt, PCA));
  550         record_command_verbatim();
  551         free(liststr);
  552     }
  553     }
  554 }
  555 
  556 static void EC_num_from_action (GtkAction *action, int *j)
  557 {
  558     const gchar *s = gtk_action_get_name(action);
  559 
  560     sscanf(s, "%*s %d", j);
  561 }
  562 
  563 void VECM_add_EC_data (GtkAction *action, gpointer p)
  564 {
  565     windata_t *vwin = (windata_t *) p;
  566     GRETL_VAR *var = (GRETL_VAR *) vwin->data;
  567     double *x = NULL;
  568     char vname[VNAMELEN];
  569     char descrip[MAXLABEL];
  570     int id = gretl_VECM_id(var);
  571     int j, cancel = 0;
  572     int err = 0;
  573 
  574     EC_num_from_action(action, &j);
  575     x = gretl_VECM_get_EC(var, j, dataset, &err);
  576     if (err) {
  577     gui_errmsg(err);
  578     return;
  579     }
  580 
  581     j++;
  582     sprintf(vname, "EC%d", j);
  583     sprintf(descrip, "error correction term %d from VECM %d", j, id);
  584 
  585     name_new_series_dialog(vname, descrip, vwin, &cancel);
  586     if (cancel) {
  587     free(x);
  588     return;
  589     }
  590 
  591     err = add_or_replace_series(x, vname, descrip, DS_GRAB_VALUES);
  592 
  593     if (err) {
  594     free(x);
  595     } else {
  596     populate_varlist();
  597     mark_dataset_as_modified();
  598     }
  599 }
  600 
  601 /* note: called from add_data_callback() */
  602 
  603 void add_fcast_data (windata_t *vwin, ModelDataIndex idx)
  604 {
  605     FITRESID *fr = (FITRESID *) vwin->data;
  606     char vname[VNAMELEN];
  607     char descrip[MAXLABEL];
  608     int cancel = 0;
  609     int err = 0;
  610 
  611     strcpy(vname, fr->depvar);
  612     gretl_trunc(vname, 12);
  613 
  614     if (idx == M_FCSE) {
  615     strcat(vname, "_se");
  616     sprintf(descrip, _("forecast std errors of %s"), fr->depvar);
  617     } else {
  618     strcat(vname, "_hat");
  619     sprintf(descrip, _("forecast of %s"), fr->depvar);
  620     }
  621 
  622     name_new_series_dialog(vname, descrip, vwin, &cancel);
  623     if (cancel) {
  624     return;
  625     }
  626 
  627     err = add_or_replace_series(idx == M_FCSE ? fr->sderr : fr->fitted,
  628                 vname, descrip, DS_COPY_VALUES);
  629 
  630     if (!err) {
  631     char stobs[OBSLEN], endobs[OBSLEN];
  632 
  633     ntodate(stobs, fr->t1, dataset);
  634     ntodate(endobs, fr->t2, dataset);
  635     if (idx == M_FCSE) {
  636         lib_command_sprintf("fcast %s %s --quiet", stobs, endobs);
  637         record_model_command_verbatim(fr->model_ID);
  638         lib_command_sprintf("series %s = $fcse", vname);
  639         record_model_command_verbatim(fr->model_ID);
  640     } else {
  641         lib_command_sprintf("fcast %s %s %s", stobs, endobs, vname);
  642         record_model_command_verbatim(fr->model_ID);
  643     }
  644     refresh_data();
  645     }
  646 }
  647 
  648 static const char *selected_varname (void)
  649 {
  650     return dataset->varname[mdata_active_var()];
  651 }
  652 
  653 static int get_summary_stats_option (gretlopt *popt,
  654                      GtkWidget *parent)
  655 {
  656     static int deflt = 0;
  657     const char *opts[] = {
  658     N_("Show main statistics"),
  659     N_("Show full statistics")
  660     };
  661     int resp;
  662 
  663     resp = radio_dialog(NULL, NULL, opts, 2, deflt,
  664             0, parent);
  665 
  666     if (resp >= 0) {
  667     deflt = resp;
  668     }
  669 
  670     if (resp == 0) {
  671     *popt = OPT_S;
  672     }
  673 
  674     return resp;
  675 }
  676 
  677 void do_menu_op (int ci, const char *liststr, gretlopt opt,
  678          GtkWidget *parent)
  679 {
  680     PRN *prn;
  681     char title[128];
  682     gpointer obj = NULL;
  683     gint hsize = 78, vsize = 380;
  684     const char *flagstr = NULL;
  685     int err = 0;
  686 
  687     strcpy(title, "gretl: ");
  688 
  689     if (ci == CORR || ci == PCA || ci == XTAB) {
  690     flagstr = print_flags(opt, ci);
  691     }
  692 
  693     if (ci == ALL_SUMMARY || ci == SUMMARY) {
  694     /* all series or listed series */
  695     int resp = get_summary_stats_option(&opt, parent);
  696 
  697     if (resp == GRETL_CANCEL) return;
  698     }
  699 
  700     if (ci == ALL_CORR) {
  701     /* correlation matrix, all series */
  702     lib_command_strcpy("corr");
  703     strcat(title, _("correlation matrix"));
  704     ci = CORR;
  705     } else if (ci == ALL_SUMMARY) {
  706     /* summary stats, all series or list */
  707     if (opt & OPT_S) {
  708         lib_command_strcpy("summary --simple");
  709     } else {
  710         lib_command_strcpy("summary");
  711     }
  712     strcat(title, _("summary statistics"));
  713     ci = SUMMARY;
  714     } else if (ci == VAR_SUMMARY) {
  715     /* summary stats, single series */
  716     lib_command_sprintf("summary %s", selected_varname());
  717     strcat(title, _("summary stats: "));
  718     strcat(title, selected_varname());
  719     ci = SUMMARY;
  720     vsize = 300;
  721     } else if (ci == NORMTEST) {
  722     /* normality test, single series */
  723     lib_command_sprintf("normtest %s --all", selected_varname());
  724     strcat(title, _("normality test"));
  725     vsize = 300;
  726     } else if (liststr == NULL) {
  727     /* beyond here we need a list */
  728     err = E_DATA;
  729     } else {
  730     switch (ci) {
  731     case CORR:
  732         lib_command_sprintf("corr%s%s", liststr, flagstr);
  733         strcat(title, _("correlation matrix"));
  734         break;
  735     case PCA:
  736         lib_command_sprintf("pca%s%s", liststr, flagstr);
  737         strcat(title, _("principal components"));
  738         break;
  739     case MAHAL:
  740         lib_command_sprintf("mahal%s", liststr);
  741         hsize = 60;
  742         strcat(title, _("Mahalanobis distances"));
  743         break;
  744     case XTAB:
  745         lib_command_sprintf("xtab %s%s", liststr, flagstr);
  746         strcat(title, _("cross tabulation"));
  747         vsize = 340;
  748         break;
  749     case SUMMARY:
  750         if (opt & OPT_S) {
  751         lib_command_sprintf("summary%s --simple", liststr);
  752         } else {
  753         lib_command_sprintf("summary%s", liststr);
  754         }
  755         strcat(title, _("summary statistics"));
  756         break;
  757     default:
  758         break;
  759     }
  760     }
  761 
  762     if (err || parse_lib_command() || bufopen(&prn)) {
  763     return;
  764     }
  765 
  766     if (libcmd.list == NULL) {
  767     libcmd.list = full_var_list(dataset, NULL);
  768     if (libcmd.list == NULL) {
  769         return;
  770     }
  771     }
  772 
  773     switch (ci) {
  774     case CORR:
  775     case PCA:
  776     obj = corrlist(ci, libcmd.list, dataset, opt, &err);
  777     if (!err) {
  778         if (ci == CORR) {
  779         print_corrmat(obj, dataset, prn);
  780         } else {
  781         err = call_pca_plugin((VMatrix *) obj, dataset,
  782                       OPT_NONE, prn);
  783         }
  784     }
  785     break;
  786     case XTAB:
  787     if (libcmd.list[0] == 2) {
  788         obj = single_crosstab(libcmd.list, dataset, opt,
  789                   prn, &err);
  790     } else {
  791         err = crosstab(libcmd.list, dataset, opt, prn);
  792         ci = PRINT;
  793     }
  794     break;
  795     case MAHAL:
  796     if (libcmd.list[0] <= 4) {
  797         opt = OPT_V;
  798     }
  799     obj = get_mahal_distances(libcmd.list, dataset, opt,
  800                   prn, &err);
  801     break;
  802     case SUMMARY:
  803     obj = get_summary(libcmd.list, dataset, opt, prn, &err);
  804     if (!err) {
  805         print_summary(obj, dataset, prn);
  806     }
  807     break;
  808     case NORMTEST:
  809     err = gretl_normality_test(libcmd.list[1], dataset,
  810                    OPT_A, prn);
  811     ci = PRINT;
  812     break;
  813     }
  814 
  815     if (err) {
  816     gui_errmsg(err);
  817     gretl_print_destroy(prn);
  818     } else {
  819     record_lib_command();
  820     view_buffer(prn, hsize, vsize, title, ci, obj);
  821     }
  822 }
  823 
  824 static void do_qq_xyplot (const char *buf, gretlopt opt)
  825 {
  826     int err;
  827 
  828     lib_command_sprintf("qqplot%s", buf);
  829     err = parse_lib_command();
  830 
  831     if (!err) {
  832     err = qq_plot(libcmd.list, dataset, opt);
  833     gui_graph_handler(err);
  834     }
  835 
  836     if (!err) {
  837     record_command_verbatim();
  838     }
  839 }
  840 
  841 int menu_op_wrapper (selector *sr)
  842 {
  843     const char *buf = selector_list(sr);
  844     int ci = selector_code(sr);
  845     gretlopt opt = selector_get_opts(sr);
  846     int err = 0;
  847 
  848     if (buf == NULL) {
  849     err = 1;
  850     } else if (ci == QQPLOT) {
  851     do_qq_xyplot(buf, opt);
  852     } else {
  853     do_menu_op(ci, buf, opt, NULL);
  854     }
  855 
  856     return err;
  857 }
  858 
  859 static int menu_op_ci (GtkAction *action)
  860 {
  861     const char *s = gtk_action_get_name(action);
  862     int ci = gretl_command_number(s);
  863 
  864     if (ci == 0) {
  865     if (!strcmp(s, "VarSummary")) {
  866         ci = VAR_SUMMARY;
  867     } else if (!strcmp(s, "GR_QQ")) {
  868         ci = QQPLOT;
  869     }
  870     }
  871 
  872     return ci;
  873 }
  874 
  875 void menu_op_action (GtkAction *action, gpointer p)
  876 {
  877     int ci = menu_op_ci(action);
  878 
  879     if (ci == VAR_SUMMARY || ci == NORMTEST) {
  880     /* a single-variable action */
  881     do_menu_op(ci, NULL, OPT_NONE, NULL);
  882     } else {
  883     /* potentially a multi-variable option */
  884     const char *str = NULL;
  885     gchar *title;
  886 
  887     if (ci == PCA) {
  888         str = N_("Principal Components Analysis");
  889     } else if (ci == MAHAL) {
  890         str = N_("Mahalanobis distances");
  891     } else if (ci == SUMMARY) {
  892         str = N_("summary statistics");
  893     } else if (ci == CORR) {
  894         str = N_("correlation matrix");
  895     } else if (ci == QQPLOT) {
  896         str = N_("Q-Q plot");
  897     } else if (ci == XTAB) {
  898         str = N_("cross tabulation");
  899     }
  900 
  901     title = gretl_window_title(_(str));
  902     simple_selection(ci, title, menu_op_wrapper, NULL);
  903     g_free(title);
  904     }
  905 }
  906 
  907 int do_coint (selector *sr)
  908 {
  909     const char *buf = selector_list(sr);
  910     int action = selector_code(sr);
  911     GRETL_VAR *jvar = NULL;
  912     const char *flagstr = NULL;
  913     PRN *prn;
  914     int err = 0;
  915 
  916     if (buf == NULL) {
  917     return 1;
  918     }
  919 
  920     libcmd.opt = selector_get_opts(sr);
  921 
  922     if (action == COINT && (libcmd.opt & OPT_E)) {
  923     /* try for a parameter to the --test-down option */
  924     const char *s = selector_get_extra_data(sr);
  925 
  926     if (s != NULL) {
  927         push_option_param(action, OPT_E, gretl_strdup(s));
  928     }
  929     }
  930 
  931     flagstr = print_flags(libcmd.opt, action);
  932 
  933     if (action == COINT) {
  934     lib_command_sprintf("coint %s%s", buf, flagstr);
  935     } else {
  936     lib_command_sprintf("coint2 %s%s", buf, flagstr);
  937     }
  938 
  939     if (parse_lib_command() || bufopen(&prn)) {
  940     return 1;
  941     }
  942 
  943     if (action == COINT) {
  944     err = engle_granger_test(libcmd.order, libcmd.list, dataset,
  945                  libcmd.opt, prn);
  946     } else {
  947     jvar = johansen_test(libcmd.order, libcmd.list, dataset,
  948                  libcmd.opt, prn);
  949     if (jvar == NULL) {
  950         err = E_DATA;
  951     } else if ((err = jvar->err)) {
  952         gretl_VAR_free(jvar);
  953     }
  954     }
  955 
  956     if (err) {
  957     gui_errmsg(err);
  958     gretl_print_destroy(prn);
  959     } else {
  960     record_lib_command();
  961     view_buffer(prn, 78, 400, _("gretl: cointegration test"),
  962             action, (action == COINT2)? jvar : NULL);
  963     }
  964 
  965     return err;
  966 }
  967 
  968 static int ok_obs_in_series (int v)
  969 {
  970     int t, t1, t2;
  971 
  972     for (t=dataset->t1; t<dataset->t2; t++) {
  973     if (!na(dataset->Z[v][t])) break;
  974     }
  975 
  976     t1 = t;
  977 
  978     for (t=dataset->t2; t>=dataset->t1; t--) {
  979     if (!na(dataset->Z[v][t])) break;
  980     }
  981 
  982     t2 = t;
  983 
  984     return t2 - t1 + 1;
  985 }
  986 
  987 static void switch_test_down_opt (GtkComboBox *combo,
  988                   int *option)
  989 {
  990     *option = gtk_combo_box_get_active(combo);
  991 }
  992 
  993 static GtkWidget *adf_test_down_selector (int ci, int *option)
  994 {
  995     GtkWidget *hbox, *label, *combo;
  996 
  997     hbox = gtk_hbox_new(FALSE, 5);
  998     label = gtk_label_new(_("criterion"));
  999     gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
 1000     combo = gtk_combo_box_text_new();
 1001     gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 5);
 1002     if (ci == DFGLS) {
 1003     combo_box_append_text(combo, _("modified AIC"));
 1004     combo_box_append_text(combo, _("modified BIC"));
 1005     } else {
 1006     combo_box_append_text(combo, _("AIC"));
 1007     combo_box_append_text(combo, _("BIC"));
 1008     combo_box_append_text(combo, _("t-statistic"));
 1009     }
 1010     gtk_combo_box_set_active(GTK_COMBO_BOX(combo), *option);
 1011     g_signal_connect(G_OBJECT(combo), "changed",
 1012              G_CALLBACK(switch_test_down_opt),
 1013              option);
 1014 
 1015     return hbox;
 1016 }
 1017 
 1018 static int adf_get_options (const char *title, int panel,
 1019                 int omax, int *order,
 1020                 gretlopt *popt)
 1021 {
 1022     const char *ts_opts[] = {
 1023     /* checkbox items */
 1024     N_("test down from maximum lag order"),
 1025     N_("test without constant"),
 1026     N_("with constant"),
 1027     N_("with constant and trend"),
 1028     N_("with constant, trend and trend squared"),
 1029     N_("include seasonal dummies"),
 1030     N_("show regression results"),
 1031     /* non-panel: radio items */
 1032     N_("use level of variable"),
 1033     N_("use first difference of variable")
 1034     };
 1035     const char *panel_opts[] = {
 1036     /* radio-button items */
 1037     N_("with constant"),
 1038     N_("with constant and trend"),
 1039     /* checkbox items */
 1040     N_("test down from maximum lag order"),
 1041     N_("use first difference of variable"),
 1042     N_("show individual test results")
 1043     };
 1044     static int ts_active[] = { 1, 0, 1, 1, 0, 0, 0 };
 1045     static int panel_active[] = { 0, 0, 1 };
 1046     const char **opts = panel ? panel_opts : ts_opts;
 1047     int *active = panel ? panel_active : ts_active;
 1048     int nchecks = panel ? 3 : 7;
 1049     int nradios = panel ? -2 : 2;
 1050     int check_min = panel ? 0 : 1;
 1051     int check_max = panel ? 0 : 5;
 1052     int pantrend = 0;
 1053     int difference = 0;
 1054     int *radio_var = panel ? &pantrend : &difference;
 1055     int save_seas = ts_active[5];
 1056     GtkWidget *tdown;
 1057     static int test_down_opt = 0;
 1058     gretlopt opt = OPT_NONE;
 1059     int retval;
 1060 
 1061     if (!panel && dataset->pd == 1) {
 1062     /* disallow seasonal dummies option */
 1063     ts_active[5] = -1;
 1064     }
 1065 
 1066     tdown = adf_test_down_selector(ADF, &test_down_opt);
 1067     set_checks_dialog_extra(0, tdown);
 1068 
 1069     /* note: making nradios < 0 places the radio buttons before the
 1070        check boxes in the dialog box produced by checks_dialog()
 1071     */
 1072 
 1073     retval = checks_dialog(_(title), NULL,
 1074                opts, nchecks, active,
 1075                check_min, check_max,
 1076                nradios, radio_var, order,
 1077                _("Lag order for ADF test:"),
 1078                0, omax, panel ? 0 : ADF, NULL);
 1079 
 1080     if (retval == 0) {
 1081     if (panel) {
 1082         if (active[0]) opt |= OPT_E; /* test down */
 1083         if (active[1]) opt |= OPT_F; /* difference */
 1084         if (active[2]) opt |= OPT_V; /* verbose */
 1085         if (pantrend)  opt |= OPT_T;
 1086     } else {
 1087         if (active[0]) opt |= OPT_E;
 1088         if (active[1]) opt |= OPT_N;
 1089         if (active[2]) opt |= OPT_C;
 1090         if (active[3]) opt |= OPT_T;
 1091         if (active[4]) opt |= OPT_R;     /* quad trend */
 1092         if (active[5] > 0) opt |= OPT_D; /* seasonals */
 1093         if (active[6]) opt |= OPT_V;     /* verbosity */
 1094         if (difference) opt |= OPT_F;
 1095     }
 1096     *popt = opt;
 1097     }
 1098 
 1099     if (opt & OPT_E) {
 1100     if (test_down_opt == 0) {
 1101         /* AIC */
 1102         set_optval_string(ADF, OPT_E, "AIC");
 1103     } else if (test_down_opt == 1) {
 1104         /* BIC */
 1105         set_optval_string(ADF, OPT_E, "BIC");
 1106     } else {
 1107         set_optval_string(ADF, OPT_E, "tstat");
 1108     }
 1109     }
 1110 
 1111     if (ts_active[5] < 0) {
 1112     ts_active[5] = save_seas;
 1113     }
 1114 
 1115     return retval;
 1116 }
 1117 
 1118 static int dfgls_get_options (const char *title, int panel,
 1119                   int omax, int *order,
 1120                   gretlopt *popt)
 1121 {
 1122     const char *ts_opts[] = {
 1123     /* checkbox items */
 1124     N_("test down from maximum lag order"),
 1125     N_("use Perron-Qu method"),
 1126     N_("include a trend"),
 1127     N_("show regression results"),
 1128     /* radio-button items */
 1129     N_("use level of variable"),
 1130     N_("use first difference of variable")
 1131     };
 1132     const char *panel_opts[] = {
 1133     /* checkbox items */
 1134     N_("include a trend"),
 1135     N_("use first difference of variable"),
 1136     N_("show individual test results")
 1137     };
 1138     static int ts_active[] = { 1, 1, 0, 0 };
 1139     static int panel_active[] = { 0, 0, 1 };
 1140     const char **opts = panel ? panel_opts : ts_opts;
 1141     int *active = panel ? panel_active : ts_active;
 1142     int nchecks = panel ? 3 : 4;
 1143     int nradios = panel ? 0 : 2;
 1144     int difference = 0;
 1145     int *radio_var = panel ? NULL : &difference;
 1146     gretlopt opt = OPT_G; /* --gls */
 1147     GtkWidget *tdown;
 1148     static int test_down_opt = 0;
 1149     int retval;
 1150 
 1151     tdown = adf_test_down_selector(DFGLS, &test_down_opt);
 1152     set_checks_dialog_extra(0, tdown);
 1153 
 1154     retval = checks_dialog(_(title), NULL,
 1155                opts, nchecks, active, 0, 0,
 1156                nradios, radio_var, order,
 1157                _("Lag order for ADF test:"),
 1158                0, omax, panel? 0 : DFGLS, NULL);
 1159 
 1160     if (retval == 0) {
 1161     /* OK */
 1162     if (panel) {
 1163         if (active[0]) opt |= OPT_T;
 1164         if (active[1]) opt |= OPT_F;
 1165         if (active[2]) opt |= OPT_V;
 1166     } else {
 1167         if (active[0]) {
 1168         opt |= OPT_E;
 1169         if (active[1]) opt |= OPT_U;
 1170         }
 1171         if (active[2]) opt |= OPT_T;
 1172         if (active[3]) opt |= OPT_V;
 1173         if (difference) opt |= OPT_F;
 1174     }
 1175     if (!(opt & OPT_T)) opt |= OPT_C;
 1176 
 1177     *popt = opt;
 1178     }
 1179 
 1180     if (opt & OPT_E) {
 1181     if (test_down_opt == 0) {
 1182         /* AIC */
 1183         set_optval_string(ADF, OPT_E, "AIC");
 1184     } else if (test_down_opt == 1) {
 1185         /* BIC */
 1186         set_optval_string(ADF, OPT_E, "BIC");
 1187     } else {
 1188         set_optval_string(ADF, OPT_E, "tstat");
 1189     }
 1190     }
 1191 
 1192     return retval;
 1193 }
 1194 
 1195 static int kpss_get_options (const char *title, int panel,
 1196                  int omax, int *order,
 1197                  gretlopt *popt)
 1198 {
 1199     const char *ts_opts[] = {
 1200     /* checkbox items */
 1201     N_("include a trend"),
 1202     N_("include seasonal dummies"),
 1203     N_("show regression results"),
 1204     /* radio-button items */
 1205     N_("use level of variable"),
 1206     N_("use first difference of variable")
 1207     };
 1208     const char *panel_opts[] = {
 1209     /* checkbox items */
 1210     N_("include a trend"),
 1211     N_("use first difference of variable"),
 1212     N_("show individual test results")
 1213     };
 1214     static int ts_active[] = { 0, 0, 0 };
 1215     static int panel_active[] = { 0, 0, 1 };
 1216     const char **opts = panel ? panel_opts : ts_opts;
 1217     int *active = panel ? panel_active : ts_active;
 1218     int nchecks = 3;
 1219     int nradios = panel ? 0 : 2;
 1220     int difference = 0;
 1221     int *rvar = panel ? NULL : &difference;
 1222     gretlopt opt = OPT_NONE;
 1223     int save_seas = ts_active[1];
 1224     int retval;
 1225 
 1226     if (!panel && dataset->pd == 1) {
 1227     /* disallow seasonal dummies option */
 1228     ts_active[1] = -1;
 1229     }
 1230 
 1231     retval = checks_dialog(_(title), NULL,
 1232                opts, nchecks, active, 0, 0,
 1233                nradios, rvar, order,
 1234                _("Lag order for KPSS test:"),
 1235                0, omax, panel ? 0 : KPSS, NULL);
 1236 
 1237     if (retval == 0) {
 1238     /* OK */
 1239     if (panel) {
 1240         if (active[0]) opt |= OPT_T;
 1241         if (active[1]) opt |= OPT_F; /* difference */
 1242         if (active[2]) opt |= OPT_V; /* verbose */
 1243     } else {
 1244         if (active[0]) opt |= OPT_T;
 1245         if (active[1] > 0) opt |= OPT_D;
 1246         if (active[2]) opt |= OPT_V;
 1247         if (difference) opt |= OPT_F;
 1248     }
 1249     *popt = opt;
 1250     }
 1251 
 1252     if (ts_active[1] < 0) {
 1253     ts_active[1] = save_seas;
 1254     }
 1255 
 1256     return retval;
 1257 }
 1258 
 1259 static int levin_lin_get_options (const char *title,  int panel,
 1260                   int omax, int *order,
 1261                   gretlopt *popt)
 1262 {
 1263     const char *opts[] = {
 1264     /* check-box item */
 1265         N_("show individual results"),
 1266     /* radio-button items */
 1267     N_("test without constant"),
 1268     N_("with constant"),
 1269     N_("with constant and trend")
 1270     };
 1271     static int llc_case = 1;
 1272     static int active = 1;
 1273     gretlopt opt = OPT_NONE;
 1274     int retval;
 1275 
 1276     retval = checks_dialog(_(title), NULL,
 1277                opts, 1, &active, 0, 0,
 1278                3, &llc_case, order,
 1279                _("Lag order for ADF test:"),
 1280                0, omax, LEVINLIN, NULL);
 1281 
 1282     if (retval == 0) {
 1283     /* OK */
 1284     if (llc_case == 0) opt |= OPT_N; /* no const */
 1285         if (llc_case == 2) opt |= OPT_T; /* trend */
 1286     if (active) opt |= OPT_V; /* verbose */
 1287     *popt = opt;
 1288     }
 1289 
 1290     return retval;
 1291 }
 1292 
 1293 void unit_root_test (int ci)
 1294 {
 1295     /* save the user's settings, per session */
 1296     static int ts_order = -1;
 1297     static int panel_order = 0;
 1298     const char *titles[] = {
 1299     N_("gretl: ADF test"),
 1300     N_("gretl: ADF-GLS test"),
 1301     N_("gretl: KPSS test"),
 1302     N_("gretl: Levin-Lin-Chu test")
 1303     };
 1304     const char *title;
 1305     gretlopt opt = OPT_NONE;
 1306     int panel = dataset_is_panel(dataset);
 1307     int order, omax, okT, v = mdata_active_var();
 1308     PRN *prn;
 1309     int err;
 1310 
 1311     if (panel) {
 1312     okT = dataset->pd;
 1313     order = panel_order;
 1314     } else {
 1315     okT = ok_obs_in_series(v);
 1316     }
 1317 
 1318     omax = okT / 2;
 1319 
 1320     if (ci == KPSS) {
 1321     order = 4.0 * pow(okT / 100.0, 0.25);
 1322     } else if (!panel) {
 1323     if (ts_order >= 0) {
 1324         order = ts_order;
 1325     } else {
 1326         /* default to L_{12}: see G. W. Schwert, "Tests for Unit Roots:
 1327            A Monte Carlo Investigation", Journal of Business and
 1328            Economic Statistics, 7(2), 1989, pp. 5-17.
 1329         */
 1330         order = 12.0 * pow(okT/100.0, 0.25);
 1331     }
 1332     }
 1333 
 1334     /* hand off to a specific function to gather the
 1335        relevant options for the given sort of test
 1336     */
 1337 
 1338     if (ci == ADF) {
 1339     title = titles[0];
 1340     err = adf_get_options(title, panel, omax, &order, &opt);
 1341     } else if (ci == DFGLS) {
 1342     title = titles[1];
 1343     err = dfgls_get_options(title, panel, omax, &order, &opt);
 1344     } else if (ci == KPSS) {
 1345     title = titles[2];
 1346     err = kpss_get_options(title, panel, omax, &order, &opt);
 1347     } else {
 1348     title = titles[3];
 1349     err = levin_lin_get_options(title, panel, omax, &order, &opt);
 1350     }
 1351 
 1352     if (err < 0) {
 1353     /* canceled */
 1354     return;
 1355     }
 1356 
 1357     if (order == 0 && (opt & OPT_E)) {
 1358     /* scrub the test-down option, if present  */
 1359     opt &= ~OPT_E;
 1360     }
 1361 
 1362     if (bufopen(&prn)) {
 1363     return;
 1364     }
 1365 
 1366     if (ci == ADF || ci == DFGLS || ci == KPSS) {
 1367     int vlist[2] = {1, v};
 1368 
 1369     if (ci == KPSS) {
 1370         err = kpss_test(order, vlist, dataset, opt, prn);
 1371     } else {
 1372         err = adf_test(order, vlist, dataset, opt, prn);
 1373     }
 1374     } else {
 1375     int plist[2] = {1, order};
 1376 
 1377     err = levin_lin_test(v, plist, dataset, opt, prn);
 1378     }
 1379 
 1380     if (err) {
 1381     gui_errmsg(err);
 1382     gretl_print_destroy(prn);
 1383     } else {
 1384     int rci = (ci == DFGLS)? ADF : ci;
 1385 
 1386     lib_command_sprintf("%s %d %s%s", gretl_command_word(rci),
 1387                 order, dataset->varname[v],
 1388                 print_flags(opt, rci));
 1389     record_command_verbatim();
 1390 
 1391     if (panel) {
 1392         panel_order = order;
 1393     } else if (ci == ADF || ci == DFGLS) {
 1394         ts_order = order;
 1395     }
 1396 
 1397     view_buffer(prn, 78, 350, title, ci, NULL);
 1398     }
 1399 }
 1400 
 1401 static int ur_code (const gchar *s)
 1402 {
 1403     if (!strcmp(s, "dfgls")) {
 1404     return DFGLS;
 1405     } else {
 1406     return gretl_command_number(s);
 1407     }
 1408 }
 1409 
 1410 void ur_callback (GtkAction *action)
 1411 {
 1412     int ci = ur_code(gtk_action_get_name(action));
 1413 
 1414     unit_root_test(ci);
 1415 }
 1416 
 1417 /* cross-correlogram: if two variables are selected in the main
 1418    window we use those, otherwise we present a selection dialog
 1419    (with a max of two selected variables) and use that
 1420    selection */
 1421 
 1422 int do_xcorrgm (selector *sr)
 1423 {
 1424     const char *sbuf = NULL;
 1425     char *mbuf = NULL;
 1426     gchar *title;
 1427     PRN *prn;
 1428     int order = 0;
 1429     int err = 0;
 1430 
 1431     if (sr != NULL) {
 1432     sbuf = selector_list(sr);
 1433     } else {
 1434     mbuf = main_window_selection_as_string();
 1435     }
 1436 
 1437     if (sbuf == NULL && mbuf == NULL) {
 1438     return 1;
 1439     }
 1440 
 1441     title = gretl_window_title(_("cross-correlogram"));
 1442 
 1443     order = default_lag_order(dataset);
 1444     if (order > dataset->n / 4) {
 1445     order = dataset->n / 4;
 1446     }
 1447 
 1448     err = spin_dialog(title, NULL, &order, _("Lag order:"),
 1449               1, dataset->n / 4, 0, NULL);
 1450     if (err < 0) {
 1451     /* canceled */
 1452     free(mbuf);
 1453     g_free(title);
 1454     return 0;
 1455     }
 1456 
 1457     if (sbuf != NULL) {
 1458     lib_command_sprintf("xcorrgm%s %d", sbuf, order);
 1459     } else {
 1460     lib_command_sprintf("xcorrgm%s %d", mbuf, order);
 1461     free(mbuf);
 1462     }
 1463 
 1464     if (parse_lib_command() || bufopen(&prn)) {
 1465     err = 1;
 1466     } else {
 1467     err = xcorrgram(libcmd.list, order, dataset,
 1468             OPT_NONE, prn);
 1469     if (err) {
 1470         gui_errmsg(err);
 1471         gretl_print_destroy(prn);
 1472     } else {
 1473         record_lib_command();
 1474         view_buffer(prn, 60, 300, title, XCORRGM, NULL);
 1475         register_graph();
 1476     }
 1477     }
 1478 
 1479     g_free(title);
 1480 
 1481     return err;
 1482 }
 1483 
 1484 void dataset_info (void)
 1485 {
 1486     if (dataset->descrip == NULL) {
 1487     if (yes_no_dialog(_("gretl: add info"),
 1488               _("The data file contains no informative comments.\n"
 1489                 "Would you like to add some now?"),
 1490               NULL) == GRETL_YES) {
 1491         edit_buffer(&dataset->descrip, 80, 400, _("gretl: edit data info"),
 1492             EDIT_HEADER);
 1493     }
 1494     } else if (data_status & BOOK_DATA) {
 1495     char *buf = g_strdup(dataset->descrip);
 1496     PRN *prn;
 1497 
 1498     if (buf != NULL) {
 1499         prn = gretl_print_new_with_buffer(buf);
 1500         view_buffer(prn, 80, 400, _("gretl: data info"), INFO, NULL);
 1501     }
 1502     } else {
 1503     edit_buffer(&dataset->descrip, 80, 400, _("gretl: edit data info"),
 1504             EDIT_HEADER);
 1505     }
 1506 }
 1507 
 1508 void gui_errmsg (int errcode)
 1509 {
 1510     if (errcode == E_STOP) {
 1511     gui_warnmsg(errcode);
 1512     } else {
 1513     const char *msg = errmsg_get_with_default(errcode);
 1514 
 1515     if (msg != NULL && *msg != '\0') {
 1516         errbox(msg);
 1517         /* avoid duplicating this error message */
 1518         gretl_error_clear();
 1519     } else {
 1520         errbox(_("Unspecified error"));
 1521     }
 1522     }
 1523 }
 1524 
 1525 void gui_warnmsg (int errcode)
 1526 {
 1527     const char *msg = NULL;
 1528 
 1529     if (errcode > 0) {
 1530     msg = errmsg_get_with_default(errcode);
 1531     } else {
 1532     msg = gretl_warnmsg_get();
 1533     }
 1534 
 1535     if (msg != NULL && *msg != '\0') {
 1536     warnbox(msg);
 1537     }
 1538 }
 1539 
 1540 static int perma_sample_options (const char *param, int *list,
 1541                  DATASET *dset, gretlopt opt,
 1542                  PRN *prn, int *n_dropped,
 1543                  int *cancel)
 1544 {
 1545     /* we have a saved-models problem with the specified
 1546        permanent subsample -- what to do?
 1547     */
 1548     gchar *msg;
 1549     int resp;
 1550     int err = 0;
 1551 
 1552     msg =
 1553     g_strdup_printf(_("Changing the dataset in this way will "
 1554               "result in the deletion\nof %d model(s) "
 1555               "from this gretl session.\n\n"
 1556               "You may wish to say No here and save the "
 1557               "session first.\n\n"
 1558               "Do you want to go ahead with the "
 1559               "subsampling now?"),
 1560             *n_dropped);
 1561 
 1562     resp = yes_no_dialog(NULL, msg, NULL);
 1563     g_free(msg);
 1564 
 1565     if (resp == GRETL_YES) {
 1566     *n_dropped = 0;
 1567     if (opt == OPT_T && param == NULL) {
 1568         /* freezing current restriction */
 1569         err = perma_sample(dset, opt, prn, NULL);
 1570     } else {
 1571         err = restrict_sample(param, list, dataset, NULL,
 1572                   opt | OPT_F, prn, n_dropped);
 1573     }
 1574     if (!err) {
 1575         mark_session_changed();
 1576     }
 1577     } else {
 1578     *cancel = 1;
 1579     }
 1580 
 1581     return err;
 1582 }
 1583 
 1584 /* OPT_M  drop all obs with missing data values
 1585    OPT_A  drop obs with no valid data
 1586    OPT_W  drop weekends
 1587    OPT_O  sample using dummy variable
 1588    OPT_R  sample using boolean expression
 1589    OPT_N  random sub-sample
 1590    OPT_C  replace current restriction
 1591 
 1592    OPT_T  restriction is permanent
 1593    OPT_U  use current restriction
 1594 */
 1595 
 1596 int bool_subsample (const char *param, gretlopt opt,
 1597             GtkWidget *dialog)
 1598 {
 1599     const char *msg;
 1600     PRN *prn;
 1601     int n_dropped = 0;
 1602     int err = 0;
 1603 
 1604     if (bufopen(&prn)) {
 1605     return 1;
 1606     }
 1607 
 1608     if ((opt & OPT_T) && (opt & OPT_U)) {
 1609     /* freezing current restriction */
 1610     err = perma_sample(dataset, OPT_T, prn, &n_dropped);
 1611     } else {
 1612     err = restrict_sample(param, NULL, dataset, NULL,
 1613                   opt, prn, &n_dropped);
 1614     }
 1615 
 1616     if (err == E_CANCEL && (opt & OPT_T)) {
 1617     int cancel = 0;
 1618 
 1619     err = perma_sample_options(param, NULL, dataset,
 1620                    opt, prn, &n_dropped,
 1621                    &cancel);
 1622     if (cancel) {
 1623         gretl_print_destroy(prn);
 1624         return 0;
 1625     }
 1626     }
 1627 
 1628     msg = gretl_print_get_buffer(prn);
 1629 
 1630     if (err) {
 1631     errmsg_plus(err, msg);
 1632     } else {
 1633     if (dialog != NULL) {
 1634         gtk_widget_hide(dialog);
 1635     }
 1636     if (msg != NULL && *msg != '\0') {
 1637         infobox(msg);
 1638     } else if (n_dropped > 0) {
 1639         infobox_printf(_("Dropped %d observations"), n_dropped);
 1640     }
 1641     if (opt & OPT_T) {
 1642         mark_dataset_as_modified();
 1643     } else {
 1644         set_sample_label(dataset);
 1645     }
 1646     }
 1647 
 1648     gretl_print_destroy(prn);
 1649 
 1650     return err;
 1651 }
 1652 
 1653 void perma_sample_callback (void)
 1654 {
 1655     bool_subsample(NULL, OPT_T | OPT_U, NULL);
 1656 }
 1657 
 1658 static int any_missing (void)
 1659 {
 1660     int i, t;
 1661 
 1662     for (i=1; i<dataset->v; i++) {
 1663     if (!series_is_hidden(dataset, i)) {
 1664         for (t=0; t<dataset->n; t++) {
 1665         if (na(dataset->Z[i][t])) {
 1666             return 1;
 1667         }
 1668         }
 1669     }
 1670     }
 1671 
 1672     return 0;
 1673 }
 1674 
 1675 static int any_all_missing (void)
 1676 {
 1677     int vt = current_series_index(dataset, "time");
 1678     int vi = current_series_index(dataset, "index");
 1679     int i, t, allmiss, nv = 0;
 1680 
 1681     for (i=1; i<dataset->v; i++) {
 1682     if (!series_is_hidden(dataset, i) &&
 1683         i != vt && i != vi) {
 1684         nv++;
 1685     }
 1686     }
 1687 
 1688     if (nv < 2) {
 1689     return 0;
 1690     }
 1691 
 1692     for (t=0; t<dataset->n; t++) {
 1693     allmiss = 1;
 1694     for (i=1; i<dataset->v; i++) {
 1695         if (!series_is_hidden(dataset, i) &&
 1696         i != vt && i != vi &&
 1697         !na(dataset->Z[i][t])) {
 1698         allmiss = 0;
 1699         break;
 1700         }
 1701     }
 1702     if (allmiss) {
 1703         return 1;
 1704     }
 1705     }
 1706 
 1707     return 0;
 1708 }
 1709 
 1710 void drop_missing_data (void)
 1711 {
 1712     int permanent = 0;
 1713     gretlopt opt = OPT_M;
 1714     int resp = 0;
 1715 
 1716     if (!any_missing_user_values(dataset)) {
 1717     infobox(_("No missing data values"));
 1718     return;
 1719     }
 1720 
 1721     if (any_all_missing()) {
 1722     const char *opts[] = {
 1723         N_("Drop rows with at least one missing value"),
 1724         N_("Drop rows that have no valid data")
 1725     };
 1726     int deflt = 0;
 1727 
 1728     if (complex_subsampled()) {
 1729         resp = radio_dialog("gretl", _("Drop missing data"),
 1730                 opts, 2, deflt, 0, NULL);
 1731     } else {
 1732         resp = radio_dialog_with_check("gretl", _("Drop missing data"),
 1733                        opts, 2, deflt, 0,
 1734                        &permanent,
 1735                        _("Make this permanent"),
 1736                        NULL);
 1737     }
 1738     if (resp == 1) {
 1739         opt = OPT_A;
 1740     }
 1741     } else if (!complex_subsampled()) {
 1742     const char *opts[] = {
 1743         N_("Make this permanent"),
 1744         NULL
 1745     };
 1746 
 1747     resp = checks_only_dialog("gretl",
 1748                   _("Drop observations with missing values"),
 1749                   opts, 1, &permanent, 0, NULL);
 1750     }
 1751 
 1752     if (resp == 0 || resp == 1) {
 1753     int err;
 1754 
 1755     if (permanent) {
 1756         opt |= OPT_T; /* --permanent */
 1757     }
 1758     err = bool_subsample(NULL, opt, NULL);
 1759     if (!err) {
 1760         lib_command_sprintf("smpl%s", print_flags(opt, SMPL));
 1761         record_command_verbatim();
 1762     }
 1763     }
 1764 }
 1765 
 1766 void count_missing (void)
 1767 {
 1768     const char *opts[] = {
 1769     N_("Show count of missing values at each observation"),
 1770     NULL
 1771     };
 1772     gretlopt opt;
 1773     int resp, active;
 1774     int mc, err = 0;
 1775     PRN *prn;
 1776 
 1777     if (!any_missing()) {
 1778     infobox(_("No missing data values"));
 1779     return;
 1780     }
 1781 
 1782     active = (dataset->n < 1000);
 1783 
 1784     resp = checks_only_dialog(_("gretl: missing values info"), NULL,
 1785                   opts, 1, &active, 0, NULL);
 1786 
 1787     if (canceled(resp) || bufopen(&prn)) {
 1788     return;
 1789     }
 1790 
 1791     opt = (active)? (OPT_V | OPT_A) : OPT_A;
 1792     mc = count_missing_values(dataset, opt, prn, &err);
 1793 
 1794     if (!err && mc > 0) {
 1795     view_buffer(prn, 78, 300, _("gretl: missing values info"),
 1796             SMPL, NULL);
 1797     } else {
 1798     if (err) {
 1799         gui_errmsg(err);
 1800     } else {
 1801         infobox(_("No missing data values"));
 1802     }
 1803     gretl_print_destroy(prn);
 1804     }
 1805 }
 1806 
 1807 void do_add_markers (const char *fname)
 1808 {
 1809     int err = add_obs_markers_from_file(dataset, fname);
 1810 
 1811     if (err) {
 1812     gui_errmsg(err);
 1813     } else {
 1814     lib_command_sprintf("markers --from-file=\"%s\"", fname);
 1815     record_command_verbatim();
 1816     mark_dataset_as_modified();
 1817     }
 1818 }
 1819 
 1820 int do_save_markers (const char *fname)
 1821 {
 1822     FILE *fp;
 1823     int i;
 1824 
 1825     if (dataset->S == NULL) {
 1826     return E_DATA;
 1827     }
 1828 
 1829     fp = gretl_fopen(fname, "w");
 1830 
 1831     if (fp == NULL) {
 1832     file_write_errbox(fname);
 1833     return E_FOPEN;
 1834     }
 1835 
 1836     for (i=0; i<dataset->n; i++) {
 1837     fprintf(fp, "%s\n", dataset->S[i]);
 1838     }
 1839 
 1840     fclose(fp);
 1841 
 1842     lib_command_sprintf("markers --to-file=\"%s\"", fname);
 1843     record_command_verbatim();
 1844 
 1845     return 0;
 1846 }
 1847 
 1848 /* called from main window Data menu */
 1849 
 1850 void markers_callback (void)
 1851 {
 1852     if (dataset->S != NULL) {
 1853     /* we have markers in place */
 1854     const char *opts[] = {
 1855         N_("Export the markers to file"),
 1856         N_("Remove the markers")
 1857     };
 1858     int resp;
 1859 
 1860     resp = radio_dialog("gretl", _("The dataset has observation markers.\n"
 1861                 "Would you like to:"),
 1862                 opts, 2, 0, 0, NULL);
 1863     if (resp == 0) {
 1864         file_selector(SAVE_MARKERS, FSEL_DATA_NONE, NULL);
 1865     } else if (resp == 1) {
 1866         dataset_destroy_obs_markers(dataset);
 1867         mark_dataset_as_modified();
 1868         lib_command_strcpy("markers --delete");
 1869         record_command_verbatim();
 1870     }
 1871     } else {
 1872     if (yes_no_dialog("gretl",
 1873               _("The dataset has no observation markers.\n"
 1874                 "Add some from file now?"),
 1875               NULL) == GRETL_YES) {
 1876         file_selector(OPEN_MARKERS, FSEL_DATA_NONE, NULL);
 1877     }
 1878     }
 1879 }
 1880 
 1881 void do_add_labels (const char *fname)
 1882 {
 1883     int err = add_var_labels_from_file(dataset, fname);
 1884 
 1885     if (err) {
 1886     gui_errmsg(err);
 1887     } else {
 1888     lib_command_sprintf("labels --from-file=\"%s\"", fname);
 1889     record_command_verbatim();
 1890     refresh_data();
 1891     mark_dataset_as_modified();
 1892     }
 1893 }
 1894 
 1895 int do_save_labels (const char *fname)
 1896 {
 1897     int err = save_var_labels_to_file(dataset, fname);
 1898 
 1899     if (err) {
 1900     file_write_errbox(fname);
 1901     } else {
 1902     lib_command_sprintf("labels --to-file=\"%s\"", fname);
 1903     record_command_verbatim();
 1904     }
 1905 
 1906     return err;
 1907 }
 1908 
 1909 static void gui_remove_var_labels (void)
 1910 {
 1911     int i;
 1912 
 1913     for (i=1; i<dataset->v; i++) {
 1914     series_set_label(dataset, i, "");
 1915     }
 1916 
 1917     lib_command_strcpy("labels --delete");
 1918     record_command_verbatim();
 1919     populate_varlist();
 1920     mark_dataset_as_modified();
 1921 }
 1922 
 1923 void labels_callback (void)
 1924 {
 1925     if (dataset_has_var_labels(dataset)) {
 1926     /* we have (some) labels in place */
 1927     const char *opts[] = {
 1928         N_("Export the labels to file"),
 1929         N_("Remove the labels")
 1930     };
 1931     int resp;
 1932 
 1933     resp = radio_dialog("gretl", _("The dataset has variable labels.\n"
 1934                        "Would you like to:"),
 1935                 opts, 2, 0, SAVE_LABELS, NULL);
 1936     if (resp == 0) {
 1937         file_selector(SAVE_LABELS, FSEL_DATA_NONE, NULL);
 1938     } else if (resp == 1) {
 1939         gui_remove_var_labels();
 1940     }
 1941     } else {
 1942     if (yes_no_help_dialog(_("The dataset has no variable labels.\n"
 1943                  "Add some from file now?"),
 1944                    OPEN_LABELS) == GRETL_YES) {
 1945         file_selector(OPEN_LABELS, FSEL_DATA_NONE, NULL);
 1946     }
 1947     }
 1948 }
 1949 
 1950 int out_of_sample_info (int add_ok, int *t2)
 1951 {
 1952     const char *can_add =
 1953     N_("There are no observations available for forecasting\n"
 1954        "out of sample.  You can add some observations now\n"
 1955        "if you wish.");
 1956     int err = 0;
 1957 
 1958     if (add_ok) {
 1959     int n = add_obs_dialog(_(can_add), 0, OPT_NONE, NULL);
 1960 
 1961     if (n < 0) {
 1962         err = 1;
 1963     } else if (n > 0) {
 1964         set_original_n(dataset->n);
 1965         err = dataset_add_observations(dataset, n, OPT_A);
 1966         if (err) {
 1967         gui_errmsg(err);
 1968         } else {
 1969         lib_command_sprintf("dataset addobs %d", n);
 1970         record_command_verbatim();
 1971         mark_dataset_as_modified();
 1972         drop_obs_state(TRUE);
 1973         *t2 += n;
 1974         }
 1975     }
 1976     } else {
 1977     infobox(_("There are no observations available for forecasting\n"
 1978           "out of sample.  If you wish, you can add observations\n"
 1979           "(Data menu, Edit data), or you can shorten the sample\n"
 1980           "range over which the model is estimated (Sample menu)."));
 1981     }
 1982 
 1983     return err;
 1984 }
 1985 
 1986 void gui_do_forecast (GtkAction *action, gpointer p)
 1987 {
 1988     static gretlopt gopt = OPT_P | OPT_H;
 1989     windata_t *vwin = (windata_t *) p;
 1990     MODEL *pmod = vwin->data;
 1991     char startobs[OBSLEN], endobs[OBSLEN];
 1992     int t2, t1 = 0;
 1993     int flags = 0;
 1994     int premax, pre_n = 0;
 1995     int t1min = 0;
 1996     int recursive = 0, k = 1, *kptr;
 1997     int dt2 = dataset->n - 1;
 1998     int st2 = dataset->n - 1;
 1999     gretlopt opt = OPT_NONE;
 2000     double conf = 0.95;
 2001     FITRESID *fr;
 2002     PRN *prn = NULL;
 2003     int resp, err = 0;
 2004 
 2005     err = model_sample_problem(pmod, dataset);
 2006     if (err) {
 2007     gui_errmsg(err);
 2008     return;
 2009     }
 2010 
 2011     /* try to figure which options might be applicable */
 2012     forecast_options_for_model(pmod, dataset, &flags,
 2013                    &dt2, &st2);
 2014 
 2015     if (flags & (FC_DYNAMIC_OK | FC_AUTO_OK)) {
 2016     t2 = dt2;
 2017     } else {
 2018     t2 = st2;
 2019     }
 2020 
 2021     /* if no out-of-sample obs are available in case of time-
 2022        series data, alert the user */
 2023     if (t2 <= pmod->t2 && dataset_is_time_series(dataset)) {
 2024     err = out_of_sample_info(flags & FC_ADDOBS_OK, &t2);
 2025     if (err) {
 2026         return;
 2027     }
 2028     }
 2029 
 2030     /* max number of pre-forecast obs in "best case" */
 2031     premax = dataset->n - 1;
 2032 
 2033     /* if there are spare obs available, default to an
 2034        out-of-sample forecast */
 2035     if (t2 > pmod->t2) {
 2036     t1 = pmod->t2 + 1;
 2037     pre_n = pmod->t2 / 2;
 2038     if (pre_n > 100) {
 2039         pre_n = 100;
 2040     }
 2041     if (pmod->ci == GARCH) {
 2042         /* force out-of-sample fcast */
 2043         t1min = t1;
 2044     }
 2045     } else {
 2046     pre_n = 0;
 2047     }
 2048 
 2049     if (flags & FC_INTEGRATE_OK) {
 2050     kptr = NULL;
 2051     } else {
 2052     kptr = &k;
 2053     }
 2054 
 2055     resp = forecast_dialog(t1min, t2, &t1,
 2056                0, t2, &t2, kptr,
 2057                0, premax, &pre_n,
 2058                flags, &gopt, &conf,
 2059                pmod, vwin_toplevel(vwin));
 2060 
 2061     if (canceled(resp)) {
 2062     gopt = OPT_P | OPT_H;
 2063     return;
 2064     }
 2065 
 2066     if (resp == 1) {
 2067     opt = OPT_D;
 2068     } else if (resp == 2) {
 2069     opt = OPT_S;
 2070     } else if (resp == 3) {
 2071     recursive = 1;
 2072     }
 2073 
 2074     if (gopt & OPT_I) {
 2075     /* transfer OPT_I (integrate forecast) from graph
 2076        to general options */
 2077     opt |= OPT_I;
 2078     gopt &= ~OPT_I;
 2079     }
 2080 
 2081     if (gopt & OPT_M) {
 2082     /* OPT_M (show interval for mean): copy to opt */
 2083     opt |= OPT_M;
 2084     }
 2085 
 2086     if (recursive) {
 2087     fr = recursive_OLS_k_step_fcast(pmod, dataset,
 2088                     t1, t2, k, pre_n,
 2089                     &err);
 2090     } else {
 2091     ntodate(startobs, t1, dataset);
 2092     ntodate(endobs, t2, dataset);
 2093     lib_command_sprintf("fcast %s %s%s", startobs, endobs,
 2094                 print_flags(opt, FCAST));
 2095     if (parse_lib_command()) {
 2096         return;
 2097     }
 2098     fr = get_forecast(pmod, t1, t2, pre_n, dataset,
 2099               opt, &err);
 2100     if (!err) {
 2101         record_lib_command();
 2102     }
 2103     }
 2104 
 2105     if (err) {
 2106     gui_errmsg(err);
 2107     } else {
 2108     err = bufopen(&prn);
 2109     }
 2110 
 2111     if (!err) {
 2112     int ols_special = 0;
 2113     int width = 78;
 2114 
 2115     if (recursive) {
 2116         err = text_print_fit_resid(fr, dataset, prn);
 2117     } else {
 2118         if (dataset_is_cross_section(dataset)) {
 2119         ols_special = gretl_is_simple_OLS(pmod);
 2120         }
 2121         if (LIMDEP(pmod->ci) || ols_special) {
 2122         /* don't generate plot via text_print_forecast() */
 2123         gopt &= ~OPT_P;
 2124         } else {
 2125         gopt |= OPT_P;
 2126         }
 2127         fr->alpha = 1 - conf;
 2128         err = text_print_forecast(fr, dataset, gopt, prn);
 2129     }
 2130 
 2131     if (ols_special) {
 2132         err = plot_simple_fcast_bands(pmod, fr,
 2133                       dataset,
 2134                       gopt);
 2135         gopt |= OPT_P;
 2136     }
 2137     if (!err && (gopt & OPT_P)) {
 2138         register_graph();
 2139     }
 2140     if (!recursive && fr->sderr == NULL) {
 2141         width = 60;
 2142     }
 2143     view_buffer_with_parent(vwin, prn, width, 400,
 2144                 _("gretl: forecasts"),
 2145                 FCAST, fr);
 2146     }
 2147 
 2148     /* don't remember the "mean" option */
 2149     gopt &= ~OPT_M;
 2150 }
 2151 
 2152 void do_bootstrap (GtkAction *action, gpointer p)
 2153 {
 2154     windata_t *vwin = (windata_t *) p;
 2155     MODEL *pmod = vwin->data;
 2156     gretlopt opt = OPT_NONE;
 2157     double alpha = 0.05;
 2158     int B = 1000;
 2159     int k = 0;
 2160     PRN *prn;
 2161     int resp, err;
 2162 
 2163     err = model_sample_problem(pmod, dataset);
 2164     if (err) {
 2165     gui_errmsg(err);
 2166     return;
 2167     }
 2168 
 2169     resp = bootstrap_dialog(vwin, &k, &B, &opt);
 2170 
 2171     if (canceled(resp) || bufopen(&prn)) {
 2172     return;
 2173     }
 2174 
 2175     err = bootstrap_analysis(pmod, k, B, alpha, dataset, opt, prn);
 2176 
 2177     if (err) {
 2178     gui_errmsg(err);
 2179     gretl_print_destroy(prn);
 2180     } else {
 2181     windata_t *w;
 2182 
 2183     w = view_buffer_with_parent(vwin, prn, 78, 300,
 2184                     _("gretl: bootstrap analysis"),
 2185                     PRINT, NULL);
 2186     if (opt & OPT_G) {
 2187         register_graph();
 2188     }
 2189     if (opt & OPT_A) {
 2190         file_selector(SAVE_BOOT_DATA, FSEL_DATA_VWIN, w);
 2191     }
 2192     }
 2193 }
 2194 
 2195 int do_coeff_sum (selector *sr)
 2196 {
 2197     windata_t *vwin = selector_get_data(sr);
 2198     const char *buf = selector_list(sr);
 2199     MODEL *pmod = vwin->data;
 2200     PRN *prn;
 2201     int err = 0;
 2202 
 2203     if (buf == NULL) {
 2204     return 0;
 2205     }
 2206 
 2207     lib_command_sprintf("coeffsum %s", buf);
 2208 
 2209     if (parse_lib_command() || bufopen(&prn)) {
 2210     return 1;
 2211     }
 2212 
 2213     err = gretl_sum_test(libcmd.list, pmod, dataset, OPT_NONE, prn);
 2214 
 2215     if (err) {
 2216         gui_errmsg(err);
 2217         gretl_print_destroy(prn);
 2218     } else {
 2219     gchar *title = gretl_window_title(_("Sum of coefficients"));
 2220 
 2221     record_model_command(pmod->ID);
 2222     view_buffer_with_parent(vwin, prn, 78, 200, title,
 2223                 COEFFSUM, NULL);
 2224     g_free(title);
 2225     }
 2226 
 2227     return err;
 2228 }
 2229 
 2230 static DATASET *
 2231 maybe_get_model_data (MODEL *pmod, gretlopt opt, int *err)
 2232 {
 2233     DATASET *dset = NULL;
 2234 
 2235     if (gretl_is_between_model(pmod)) {
 2236     if (pmod->dataset != NULL) {
 2237         dset = pmod->dataset;
 2238     } else {
 2239         gretl_errmsg_set("The group-means dataset is not available");
 2240         *err = E_DATA;
 2241         gui_errmsg(*err);
 2242     }
 2243     } else if (model_sample_problem(pmod, dataset)) {
 2244     *err = add_dataset_to_model(pmod, dataset, opt);
 2245     if (*err) {
 2246         gui_errmsg(*err);
 2247     } else {
 2248         dset = pmod->dataset;
 2249     }
 2250     } else {
 2251     dset = dataset;
 2252     *err = 0;
 2253     }
 2254 
 2255     return dset;
 2256 }
 2257 
 2258 static void trim_dataset (MODEL *pmod, int origv)
 2259 {
 2260     if (pmod != NULL && pmod->dataset != NULL) {
 2261     if (!gretl_is_between_model(pmod)) {
 2262         destroy_dataset(pmod->dataset);
 2263         pmod->dataset = NULL;
 2264     }
 2265     } else if (origv > 0) {
 2266     dataset_drop_last_variables(dataset, dataset->v - origv);
 2267     }
 2268 }
 2269 
 2270 static void print_test_to_window (const MODEL *pmod, GtkWidget *w)
 2271 {
 2272     if (w != NULL) {
 2273     GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w));
 2274     GtkTextIter iter, ibak;
 2275     const char *txt;
 2276     PRN *prn;
 2277 
 2278     if (bufopen(&prn)) return;
 2279 
 2280     gretl_model_print_last_test(pmod, prn);
 2281     txt = gretl_print_get_buffer(prn);
 2282     gtk_text_buffer_get_end_iter(buf, &iter);
 2283 
 2284     ibak = iter;
 2285     if (gtk_text_iter_backward_chars(&ibak, 2)) {
 2286         gchar *tmp = gtk_text_buffer_get_text(buf, &ibak, &iter, FALSE);
 2287 
 2288         if (strcmp(tmp, "\n\n")) {
 2289         gtk_text_buffer_insert(buf, &iter, "\n", -1);
 2290         }
 2291         g_free(tmp);
 2292     }
 2293 
 2294     gtk_text_buffer_insert(buf, &iter, txt, -1);
 2295     gretl_print_destroy(prn);
 2296     }
 2297 }
 2298 
 2299 static void update_model_tests (windata_t *vwin)
 2300 {
 2301     MODEL *pmod = (MODEL *) vwin->data;
 2302 
 2303 #if 0
 2304     fprintf(stderr, "update_model_tests: pmod->ntests = %d,\n"
 2305         " vwin->n_model_tests = %d\n", pmod->ntests, vwin->n_model_tests);
 2306 #endif
 2307 
 2308     if (pmod->ntests > vwin->n_model_tests) {
 2309     print_test_to_window(pmod, vwin->text);
 2310     vwin->n_model_tests += 1;
 2311     }
 2312 }
 2313 
 2314 int do_add_omit (selector *sr)
 2315 {
 2316     windata_t *vwin = selector_get_data(sr);
 2317     const char *buf = selector_list(sr);
 2318     int ci = selector_code(sr);
 2319     gretlopt opt = OPT_S | selector_get_opts(sr);
 2320     int auto_omit = (ci == OMIT && (opt & OPT_A));
 2321     const char *flagstr = NULL;
 2322     MODEL *pmod, *newmod = NULL;
 2323     DATASET *dset = dataset;
 2324     PRN *prn;
 2325     int err = 0;
 2326 
 2327     if (buf == NULL && !auto_omit) {
 2328     warnbox(_("No variables are selected"));
 2329     return 1;
 2330     }
 2331 
 2332     pmod = vwin->data;
 2333 
 2334     if (ci == OMIT && (opt & OPT_W)) {
 2335     ; /* Wald test */
 2336     } else {
 2337     gretlopt data_opt = (ci == ADD)? OPT_F : OPT_NONE;
 2338 
 2339     dset = maybe_get_model_data(pmod, data_opt, &err);
 2340     if (err) {
 2341         return err;
 2342     }
 2343     }
 2344 
 2345     flagstr = print_flags(opt, ci);
 2346 
 2347     if (ci == ADD) {
 2348         lib_command_sprintf("add%s%s", buf, flagstr);
 2349     } else if (buf == NULL) {
 2350     lib_command_sprintf("omit%s", flagstr);
 2351     } else {
 2352         lib_command_sprintf("omit%s%s", buf, flagstr);
 2353     }
 2354 
 2355     if (parse_lib_command() || bufopen(&prn)) {
 2356     return 1;
 2357     }
 2358 
 2359     if (ci == ADD && (opt & OPT_L)) {
 2360     err = add_test(pmod, libcmd.list, dset, opt, prn);
 2361     } else if (ci == OMIT && (opt & OPT_W)) {
 2362     err = omit_test(pmod, libcmd.list, dset, opt, prn);
 2363     } else {
 2364     newmod = gretl_model_new();
 2365     if (newmod == NULL) {
 2366         err = E_ALLOC;
 2367     } else if (ci == ADD) {
 2368         err = add_test_full(pmod, newmod, libcmd.list,
 2369                 dset, opt, prn);
 2370     } else {
 2371         err = omit_test_full(pmod, newmod, libcmd.list,
 2372                  dset, opt, prn);
 2373     }
 2374     }
 2375 
 2376     if (err) {
 2377     if (err == E_NOOMIT) {
 2378         const char *msg = errmsg_get_with_default(err);
 2379 
 2380         warnbox(msg);
 2381         err = 0;
 2382     } else {
 2383         gui_errmsg(err);
 2384     }
 2385         gretl_print_destroy(prn);
 2386     gretl_model_free(newmod);
 2387     } else {
 2388     update_model_tests(vwin);
 2389     record_model_command(pmod->ID);
 2390 
 2391     if (newmod != NULL && newmod->ncoeff > 0) {
 2392         /* record sub-sample info (if any) with the model */
 2393         if (pmod->dataset != NULL) {
 2394         newmod->submask = copy_subsample_mask(pmod->submask, &err);
 2395         } else {
 2396         attach_subsample_to_model(newmod, dataset);
 2397         }
 2398         printmodel(newmod, dataset, OPT_NONE, prn);
 2399         view_model(prn, newmod, NULL);
 2400     } else {
 2401         const char *omit_title = NULL;
 2402 
 2403         if (newmod != NULL) {
 2404         omit_title = N_("gretl: sequential omit test");
 2405         gretl_model_free(newmod);
 2406         } else {
 2407         omit_title = N_("gretl: Wald omit test");
 2408         }
 2409         view_buffer_with_parent(vwin, prn, 78, 400,
 2410                     (ci == OMIT)? _(omit_title) :
 2411                     _("gretl: LM test"),
 2412                     PRINT, NULL);
 2413     }
 2414     }
 2415 
 2416     trim_dataset(pmod, 0);
 2417 
 2418     return err;
 2419 }
 2420 
 2421 int do_VAR_omit (selector *sr)
 2422 {
 2423     windata_t *vwin = selector_get_data(sr);
 2424     const char *buf = selector_list(sr);
 2425     gretlopt opt = selector_get_opts(sr);
 2426     GRETL_VAR *var = vwin->data;
 2427     GRETL_VAR *vnew = NULL;
 2428     int *omitlist;
 2429     PRN *prn;
 2430     int err = 0;
 2431 
 2432     /* Here we're omitting one or more exogenous terms, other than an
 2433        auto-added trend or seasonals. The selector gives the option of
 2434        just a Wald test (OPT_W) or estimation of the reduced model.
 2435     */
 2436 
 2437     if (buf == NULL) {
 2438     return 1;
 2439     }
 2440 
 2441     if (bufopen(&prn)) {
 2442     return 1;
 2443     }
 2444 
 2445     omitlist = command_list_from_string(buf, &err);
 2446 
 2447     if (!err) {
 2448     if (opt & OPT_W) {
 2449         err = gretl_VAR_wald_omit_test(var, omitlist, dataset,
 2450                        OPT_NONE, prn);
 2451     } else {
 2452         vnew = gretl_VAR_omit_test(var, omitlist, dataset,
 2453                        OPT_NONE, prn, &err);
 2454     }
 2455     free(omitlist);
 2456     }
 2457 
 2458     if (err) {
 2459         gui_errmsg(err);
 2460         gretl_print_destroy(prn);
 2461     } else if (opt & OPT_W) {
 2462     lib_command_sprintf("omit%s --test-only", buf);
 2463     record_command_verbatim();
 2464     view_buffer(prn, 78, 200, _("gretl: Wald omit test"),
 2465             PRINT, NULL);
 2466     } else {
 2467     lib_command_sprintf("omit%s", buf);
 2468     record_command_verbatim();
 2469     view_buffer(prn, 78, 450, _("gretl: vector autoregression"),
 2470             VAR, vnew);
 2471     }
 2472 
 2473     return err;
 2474 }
 2475 
 2476 void VAR_omit_auto (GtkAction *action, gpointer p)
 2477 {
 2478     const gchar *aname = gtk_action_get_name(action);
 2479     windata_t *vwin = (windata_t *) p;
 2480     GRETL_VAR *var = vwin->data;
 2481     gretlopt opt;
 2482     PRN *prn;
 2483     int err;
 2484 
 2485     /* Here we're omitting an "auto-added" term: either
 2486        a trend or a set of seasonal dummies.
 2487     */
 2488 
 2489     if (bufopen(&prn)) {
 2490     return;
 2491     }
 2492 
 2493     if (!strcmp(aname, "VarOmitTrend")) {
 2494     opt = OPT_T;
 2495     } else {
 2496     opt = OPT_E;
 2497     }
 2498 
 2499     err = gretl_VAR_wald_omit_test(var, NULL, dataset,
 2500                    opt, prn);
 2501     if (err) {
 2502         gui_errmsg(err);
 2503         gretl_print_destroy(prn);
 2504     } else {
 2505     lib_command_sprintf("omit --%s --test-only", (opt & OPT_T)?
 2506                 "trend" : "seasonals");
 2507     record_command_verbatim();
 2508     view_buffer(prn, 78, 200, _("gretl: Wald omit test"),
 2509             PRINT, NULL);
 2510     }
 2511 }
 2512 
 2513 int do_confidence_region (selector *sr)
 2514 {
 2515     windata_t *vwin = selector_get_data(sr);
 2516     const char *buf = selector_list(sr);
 2517     MODEL *pmod;
 2518     char *mask = NULL;
 2519     char iname[VNAMELEN];
 2520     char jname[VNAMELEN];
 2521     gretl_matrix *V = NULL;
 2522     int v[2];
 2523     double b[2];
 2524     double tcrit, Fcrit, alpha;
 2525     int err = 0;
 2526 
 2527     if (buf == NULL || sscanf(buf, "%lf %d %d", &alpha, &v[0], &v[1]) != 3) {
 2528     return 1;
 2529     }
 2530 
 2531     pmod = (MODEL *) vwin->data;
 2532     if (pmod == NULL) {
 2533     gui_errmsg(E_DATA);
 2534     return 0;
 2535     }
 2536 
 2537     mask = calloc(pmod->ncoeff, 1);
 2538     if (mask == NULL) {
 2539     nomem();
 2540     return 0;
 2541     }
 2542 
 2543     mask[v[0]] = mask[v[1]] = 1;
 2544 
 2545     V = gretl_vcv_matrix_from_model(pmod, mask, &err);
 2546     if (err) {
 2547     free(mask);
 2548     return 0;
 2549     }
 2550 
 2551     b[0] = pmod->coeff[v[0]];
 2552     b[1] = pmod->coeff[v[1]];
 2553 
 2554     tcrit = student_cdf_inverse(pmod->dfd, 1 - alpha / 2);
 2555     Fcrit = 2.0 * snedecor_critval(2, pmod->dfd, alpha);
 2556 
 2557     gretl_model_get_param_name(pmod, dataset, v[0], iname);
 2558     gretl_model_get_param_name(pmod, dataset, v[1], jname);
 2559 
 2560     err = confidence_ellipse_plot(V, b, tcrit, Fcrit, alpha,
 2561                   iname, jname);
 2562     gui_graph_handler(err);
 2563 
 2564     gretl_matrix_free(V);
 2565     free(mask);
 2566 
 2567     return 0;
 2568 }
 2569 
 2570 static gretlopt modtest_get_opt (GtkAction *action)
 2571 {
 2572     const gchar *s = gtk_action_get_name(action);
 2573 
 2574     if (strchr(s, ':')) {
 2575     char c, word[9];
 2576 
 2577     sscanf(s, "%8[^:]:%c", word, &c);
 2578     return opt_from_flag((unsigned char) c);
 2579     } else if (!strcmp(s, "White")) {
 2580     return OPT_W;
 2581     } else if (!strcmp(s, "WhiteSquares")) {
 2582     return OPT_X;
 2583     } else if (!strcmp(s, "BreuschPagan")) {
 2584     return OPT_B;
 2585     } else if (!strcmp(s, "Koenker")) {
 2586     return (OPT_B | OPT_R);
 2587     } else if (!strcmp(s, "Groupwise")) {
 2588     return OPT_P;
 2589     } else {
 2590     return OPT_NONE;
 2591     }
 2592 }
 2593 
 2594 void do_modtest (GtkAction *action, gpointer p)
 2595 {
 2596     windata_t *vwin = (windata_t *) p;
 2597     MODEL *pmod = (MODEL *) vwin->data;
 2598     DATASET *dset = dataset;
 2599     PRN *prn;
 2600     char title[128];
 2601     gretlopt opt = OPT_NONE;
 2602     int err = 0;
 2603 
 2604     if (gui_exact_fit_check(pmod)) {
 2605     return;
 2606     }
 2607 
 2608     if (bufopen(&prn)) return;
 2609 
 2610     dset = maybe_get_model_data(pmod, OPT_NONE, &err);
 2611     if (err) {
 2612     gretl_print_destroy(prn);
 2613     return;
 2614     }
 2615 
 2616     opt = modtest_get_opt(action);
 2617 
 2618     strcpy(title, _("gretl: LM test "));
 2619 
 2620     if (opt == OPT_W) {
 2621     strcat(title, _("(heteroskedasticity)"));
 2622     lib_command_strcpy("modtest --white");
 2623     err = whites_test(pmod, dset, OPT_S, prn);
 2624     } else if (opt == OPT_X) {
 2625     strcat(title, _("(heteroskedasticity)"));
 2626     lib_command_strcpy("modtest --white-nocross");
 2627     err = whites_test(pmod, dset, OPT_S | OPT_X, prn);
 2628     } else if (opt & OPT_B) {
 2629     strcat(title, _("(heteroskedasticity)"));
 2630     if (opt & OPT_R) {
 2631         lib_command_strcpy("modtest --breusch-pagan --robust");
 2632     } else {
 2633         lib_command_strcpy("modtest --breusch-pagan");
 2634     }
 2635     err = whites_test(pmod, dset, opt | OPT_S, prn);
 2636     } else if (opt == OPT_P) {
 2637     strcpy(title, _("gretl: groupwise heteroskedasticity"));
 2638     lib_command_strcpy("modtest --panel");
 2639     err = groupwise_hetero_test(pmod, dset, opt | OPT_S, prn);
 2640     } else if (opt & (OPT_S | OPT_L)) {
 2641     int aux = (opt == OPT_S)? AUX_SQ : AUX_LOG;
 2642 
 2643     strcat(title, _("(non-linearity)"));
 2644     if (aux == AUX_SQ) {
 2645         lib_command_strcpy("modtest --squares");
 2646     } else {
 2647         lib_command_strcpy("modtest --logs");
 2648     }
 2649     err = nonlinearity_test(pmod, dset, aux, OPT_S, prn);
 2650     } else if (opt == OPT_C) {
 2651     strcpy(title, _("gretl: common factor test"));
 2652     lib_command_strcpy("modtest --comfac");
 2653     err = comfac_test(pmod, dset, OPT_S, prn);
 2654     } else if (opt == OPT_D) {
 2655     strcpy(title, _("gretl: cross-sectional dependence"));
 2656     lib_command_strcpy("modtest --xdepend");
 2657     err = panel_xdepend_test(pmod, dset, OPT_S, prn);
 2658     }
 2659 
 2660     if (err) {
 2661     gui_errmsg(err);
 2662     gretl_print_destroy(prn);
 2663     } else {
 2664     update_model_tests(vwin);
 2665     record_model_command_verbatim(pmod->ID);
 2666     view_buffer_with_parent(vwin, prn, 78, 400,
 2667                 title, MODTEST, NULL);
 2668     }
 2669 
 2670     trim_dataset(pmod, 0);
 2671 }
 2672 
 2673 void do_arch (GtkAction *action, gpointer p)
 2674 {
 2675     windata_t *vwin = (windata_t *) p;
 2676     MODEL *pmod = vwin->data;
 2677     PRN *prn;
 2678     int order, resp;
 2679     int err = 0;
 2680 
 2681     if (gui_exact_fit_check(pmod)) {
 2682     return;
 2683     }
 2684 
 2685     order = default_lag_order(dataset);
 2686 
 2687     resp = spin_dialog(_("gretl: ARCH test"), NULL,
 2688                &order, _("Lag order for ARCH test:"),
 2689                1, dataset->n / 2, 0,
 2690                vwin_toplevel(vwin));
 2691 
 2692     if (canceled(resp) || bufopen(&prn)) {
 2693     return;
 2694     }
 2695 
 2696     err = arch_test(pmod, order, dataset, OPT_S, prn);
 2697 
 2698     if (err) {
 2699     gui_errmsg(err);
 2700     gretl_print_destroy(prn);
 2701     } else {
 2702     update_model_tests(vwin);
 2703     lib_command_sprintf("modtest %d --arch", order);
 2704     record_model_command_verbatim(pmod->ID);
 2705     view_buffer_with_parent(vwin, prn, 78, 400,
 2706                 _("gretl: ARCH test"),
 2707                 MODTEST, NULL);
 2708     }
 2709 }
 2710 
 2711 void do_panel_tests (GtkAction *action, gpointer p)
 2712 {
 2713     windata_t *vwin = (windata_t *) p;
 2714     MODEL *pmod = (MODEL *) vwin->data;
 2715     PRN *prn;
 2716     int err;
 2717 
 2718     err = model_sample_problem(pmod, dataset);
 2719     if (err) {
 2720     gui_errmsg(err);
 2721     return;
 2722     }
 2723 
 2724     if (bufopen(&prn)) {
 2725     return;
 2726     }
 2727 
 2728     err = panel_diagnostics(pmod, dataset, OPT_NONE, prn);
 2729 
 2730     if (err) {
 2731     gui_errmsg(err);
 2732     gretl_print_destroy(prn);
 2733     } else {
 2734     view_buffer_with_parent(vwin, prn, 78, 400,
 2735                 _("gretl: panel model diagnostics"),
 2736                 PANEL, NULL);
 2737     }
 2738 }
 2739 
 2740 static void set_model_id_on_vwin (windata_t *vwin, int ID)
 2741 {
 2742     widget_set_int(vwin->main, "model_ID", ID);
 2743 }
 2744 
 2745 static int get_model_id_from_vwin (windata_t *vwin)
 2746 {
 2747     return widget_get_int(vwin->main, "model_ID");
 2748 }
 2749 
 2750 void add_leverage_data (windata_t *vwin)
 2751 {
 2752     unsigned char (*leverage_data_dialog) (void);
 2753     gretl_matrix *m = (gretl_matrix *) vwin->data;
 2754     unsigned char opt;
 2755     int err;
 2756 
 2757     if (m == NULL) return;
 2758 
 2759     leverage_data_dialog = gui_get_plugin_function("leverage_data_dialog");
 2760     if (leverage_data_dialog == NULL) return;
 2761 
 2762     opt = leverage_data_dialog();
 2763     if (opt == 0) return;
 2764 
 2765     err = add_leverage_values_to_dataset(dataset, m, opt);
 2766 
 2767     if (err) {
 2768     gui_errmsg(err);
 2769     } else {
 2770     int ID = get_model_id_from_vwin(vwin);
 2771 
 2772     lib_command_strcpy("leverage --save");
 2773     record_model_command_verbatim(ID);
 2774     }
 2775 }
 2776 
 2777 void do_leverage (GtkAction *action, gpointer p)
 2778 {
 2779     windata_t *vwin = (windata_t *) p;
 2780     MODEL *pmod = (MODEL *) vwin->data;
 2781     gretl_matrix *(*model_leverage) (const MODEL *, DATASET *,
 2782                      gretlopt, PRN *, int *);
 2783     PRN *prn;
 2784     gretl_matrix *m;
 2785     int err = 0;
 2786 
 2787     if (gui_exact_fit_check(pmod)) {
 2788     return;
 2789     }
 2790 
 2791     model_leverage = gui_get_plugin_function("model_leverage");
 2792     if (model_leverage == NULL) {
 2793     return;
 2794     }
 2795 
 2796     if (bufopen(&prn)) {
 2797     return;
 2798     }
 2799 
 2800     m = (*model_leverage)(pmod, dataset, OPT_NONE, prn, &err);
 2801 
 2802     if (err) {
 2803     gui_errmsg(err);
 2804     gretl_print_destroy(prn);
 2805     } else {
 2806     windata_t *vbuf;
 2807 
 2808     vbuf = view_buffer_with_parent(vwin, prn, 78, 400,
 2809                        _("gretl: leverage and influence"),
 2810                        LEVERAGE, m);
 2811     set_model_id_on_vwin(vbuf, pmod->ID);
 2812     register_graph();
 2813     lib_command_strcpy("leverage");
 2814     record_model_command_verbatim(pmod->ID);
 2815     }
 2816 }
 2817 
 2818 void do_collin (GtkAction *action, gpointer p)
 2819 {
 2820     windata_t *vwin = (windata_t *) p;
 2821     MODEL *pmod = (MODEL *) vwin->data;
 2822     DATASET *dset = NULL;
 2823     PRN *prn = NULL;
 2824     int show = 0;
 2825     int err, verr, berr;
 2826 
 2827     if (bufopen(&prn)) {
 2828     return;
 2829     }
 2830 
 2831     err = verr = berr = 0;
 2832     dset = maybe_get_model_data(pmod, OPT_NONE, &err);
 2833 
 2834     if (!err && model_test_ok(VIF, OPT_NONE, pmod, dset)) {
 2835     /* show VIFs if possible */
 2836     int (*compute_vifs) (MODEL *, DATASET *, gretlopt, PRN *);
 2837 
 2838     compute_vifs = gui_get_plugin_function("compute_vifs");
 2839     if (compute_vifs == NULL) {
 2840         verr = E_FOPEN;
 2841     } else {
 2842         verr = (*compute_vifs)(pmod, dset, OPT_G, prn);
 2843     }
 2844     if (!verr) {
 2845         lib_command_strcpy("vif");
 2846         record_model_command_verbatim(pmod->ID);
 2847         show = 1;
 2848     }
 2849     }
 2850 
 2851     if (!err) {
 2852     /* BKW analysis? (more generally applicable) */
 2853     int (*compute_bkw) (MODEL *, const DATASET *, gretlopt, PRN *);
 2854 
 2855     compute_bkw = get_plugin_function("compute_bkw");
 2856     if (compute_bkw == NULL) {
 2857         berr = E_FOPEN;
 2858     } else {
 2859         berr = (*compute_bkw)(pmod, dset, OPT_G, prn);
 2860     }
 2861     if (!berr) {
 2862         lib_command_strcpy("bkw");
 2863         record_model_command_verbatim(pmod->ID);
 2864         show = 1;
 2865     }
 2866     }
 2867 
 2868     if (dset != NULL) {
 2869     trim_dataset(pmod, 0);
 2870     }
 2871 
 2872     if (show) {
 2873     view_buffer_with_parent(vwin, prn, 78, 400,
 2874                 _("gretl: collinearity"),
 2875                 PRINT, NULL);
 2876     } else {
 2877     if (!err) {
 2878         err = verr ? verr : berr;
 2879     }
 2880     gui_errmsg(err);
 2881     gretl_print_destroy(prn);
 2882     }
 2883 }
 2884 
 2885 void do_gini (void)
 2886 {
 2887     gretlopt opt = OPT_NONE;
 2888     PRN *prn;
 2889     int v = mdata_active_var();
 2890     int err;
 2891 
 2892     if (bufopen(&prn)) {
 2893     return;
 2894     }
 2895 
 2896     err = gini(v, dataset, opt, prn);
 2897 
 2898     if (err) {
 2899     gui_errmsg(err);
 2900     gretl_print_destroy(prn);
 2901     } else {
 2902     gchar *title = gretl_window_title(_("Gini coefficient"));
 2903 
 2904     view_buffer(prn, 78, 200, title, PRINT, NULL);
 2905     g_free(title);
 2906     register_graph();
 2907     }
 2908 }
 2909 
 2910 void do_qqplot (void)
 2911 {
 2912     const char *opts[] = {
 2913     N_("use sample mean and variance for normal quantiles"),
 2914     N_("standardize the data"),
 2915     N_("raw quantiles versus N(0, 1)")
 2916     };
 2917     int v = mdata_active_var();
 2918     gretlopt opt = OPT_NONE;
 2919     gchar *title;
 2920     int resp;
 2921 
 2922     title = gretl_window_title(_("Q-Q plot"));
 2923     resp = radio_dialog(title, _("Normal Q-Q plot"), opts, 3, 0,
 2924             QQPLOT, NULL);
 2925     g_free(title);
 2926 
 2927     if (canceled(resp)) {
 2928     return;
 2929     }
 2930 
 2931     if (resp == 1) {
 2932     opt |= OPT_Z; /* --z-scores */
 2933     } else if (resp == 2) {
 2934     opt |= OPT_R; /* --raw */
 2935     }
 2936 
 2937     lib_command_sprintf("qqplot %s%s", dataset->varname[v],
 2938             print_flags(opt, QQPLOT));
 2939 
 2940     if (parse_lib_command() == 0) {
 2941     int list[2] = {1, v};
 2942     int err;
 2943 
 2944     err = qq_plot(list, dataset, opt);
 2945     gui_graph_handler(err);
 2946     if (!err) {
 2947         record_lib_command();
 2948     }
 2949     }
 2950 }
 2951 
 2952 void do_kernel (void)
 2953 {
 2954     int (*kernel_density) (const double *, int, double,
 2955                const char *, gretlopt);
 2956     gretlopt opt = OPT_NONE;
 2957     double bw = 1.0;
 2958     int v = mdata_active_var();
 2959     int T = sample_size(dataset);
 2960     int resp, err = 0;
 2961 
 2962     if (T < 30) {
 2963     gui_errmsg(E_TOOFEW);
 2964     return;
 2965     }
 2966 
 2967     resp = density_dialog(v, &bw);
 2968     if (canceled(resp)) {
 2969     return;
 2970     }
 2971 
 2972     if (resp > 0) {
 2973     opt |= OPT_O;
 2974     }
 2975 
 2976     kernel_density = gui_get_plugin_function("kernel_density");
 2977 
 2978     if (kernel_density != NULL) {
 2979     const double *y = dataset->Z[v] + dataset->t1;
 2980 
 2981     err = (*kernel_density)(y, T, bw,
 2982                 dataset->varname[v],
 2983                 opt);
 2984     gui_graph_handler(err);
 2985 
 2986     if (!err) {
 2987         gretl_push_c_numeric_locale();
 2988         lib_command_sprintf("matrix kd__ = kdensity(%s, %g, %d)",
 2989                 dataset->varname[v], bw,
 2990                 (opt & OPT_O)? 1 : 0);
 2991         record_command_verbatim();
 2992         lib_command_strcpy("cnameset(kd__, \"value density\")");
 2993         record_command_verbatim();
 2994         lib_command_strcpy("gnuplot 2 1 --matrix=kd__ --with-lines "
 2995                    "--fit=none --output=display");
 2996         record_command_verbatim();
 2997         lib_command_strcpy("delete kd__");
 2998         record_command_verbatim();
 2999         gretl_pop_c_numeric_locale();
 3000     }
 3001     }
 3002 }
 3003 
 3004 static int chow_cusum_ci (GtkAction *action)
 3005 {
 3006     const gchar *s = gtk_action_get_name(action);
 3007 
 3008     if (!strcmp(s, "chow"))
 3009     return CHOW;
 3010     else if (!strcmp(s, "qlrtest"))
 3011     return QLRTEST;
 3012     else if (!strcmp(s, "cusum"))
 3013     return CUSUM;
 3014     else if (!strcmp(s, "cusum:r"))
 3015     return CUSUMSQ;
 3016     else
 3017     return CHOW;
 3018 }
 3019 
 3020 struct chowparms {
 3021     int splitbrk;
 3022     int splitdum;
 3023 };
 3024 
 3025 static int real_limited_chow (selector *sr)
 3026 {
 3027     windata_t *vwin = selector_get_data(sr);
 3028     MODEL *pmod = vwin->data;
 3029     gretlopt opt = OPT_S | OPT_L;
 3030     struct chowparms *cp;
 3031     const char *lstr;
 3032     PRN *prn = NULL;
 3033     int *clist = NULL;
 3034     int err = 0;
 3035 
 3036     cp = g_object_get_data(G_OBJECT(vwin->main), "chowparms");
 3037     lstr = selector_list(sr);
 3038     if (lstr == NULL) {
 3039     warnbox(_("You must select at least one regressor"));
 3040     return 1;
 3041     }
 3042 
 3043     clist = gretl_list_from_varnames(lstr, dataset, &err);
 3044 
 3045 #if 0
 3046     fprintf(stderr, "lstr = '%s'\n", lstr);
 3047     printlist(clist, "chow arg list");
 3048 #endif
 3049 
 3050     if (!err) {
 3051     err = remember_list(clist, "chow_args_", NULL);
 3052     if (!err) {
 3053         err = push_option_param(CHOW, OPT_L, gretl_strdup("chow_args_"));
 3054     }
 3055     if (!err) {
 3056         lib_command_sprintf("list chow_args_ =%s", lstr);
 3057         record_command_verbatim();
 3058     }
 3059     }
 3060 
 3061     if (err) {
 3062     gui_errmsg(err);
 3063     } else {
 3064     if (cp->splitdum > 0) {
 3065         lib_command_sprintf("chow %s --dummy --limit-to=chowargs",
 3066                 dataset->varname[cp->splitdum]);
 3067         opt |= OPT_D;
 3068     } else {
 3069         char brkstr[OBSLEN];
 3070 
 3071         ntodate(brkstr, cp->splitbrk, dataset);
 3072         lib_command_sprintf("chow %s --limit-to=chow_args_", brkstr);
 3073     }
 3074     err = bufopen(&prn);
 3075     }
 3076 
 3077     if (!err) {
 3078     if (opt & OPT_D) {
 3079         err = chow_test_from_dummy(cp->splitdum, pmod, dataset, opt, prn);
 3080     } else {
 3081         err = chow_test(cp->splitbrk, pmod, dataset, opt, prn);
 3082     }
 3083     if (err) {
 3084         gui_errmsg(err);
 3085         gretl_print_destroy(prn);
 3086     } else {
 3087         update_model_tests(vwin);
 3088         record_model_command_verbatim(pmod->ID);
 3089         view_buffer_with_parent(vwin, prn, 78, 400,
 3090                     _("gretl: Chow test output"),
 3091                     CHOW, NULL);
 3092     }
 3093     }
 3094 
 3095     free(cp);
 3096     g_object_set_data(G_OBJECT(vwin->main), "chowparms", NULL);
 3097     free(clist);
 3098 
 3099     return 0;
 3100 }
 3101 
 3102 void do_chow_cusum (GtkAction *action, gpointer p)
 3103 {
 3104     windata_t *vwin = (windata_t *) p;
 3105     MODEL *pmod = vwin->data;
 3106     gretlopt opt = OPT_S; /* save test result */
 3107     int splitbrk = 0;
 3108     int splitdum = 0;
 3109     PRN *prn;
 3110     int ci, err = 0;
 3111 
 3112     if (pmod->ci != OLS) {
 3113     errbox(_("This test only implemented for OLS models"));
 3114     return;
 3115     }
 3116 
 3117     if (gui_exact_fit_check(pmod)) {
 3118     return;
 3119     }
 3120 
 3121     ci = chow_cusum_ci(action);
 3122 
 3123     if (ci == CHOW) {
 3124     int resp;
 3125 
 3126     splitbrk = pmod->t1 + (pmod->t2 - pmod->t1) / 2;
 3127 
 3128     if (pmod->ncoeff > 2) {
 3129         resp = chow_dialog(pmod->t1 + 1, pmod->t2 - 1, &splitbrk,
 3130                    &splitdum, &opt, vwin_toplevel(vwin));
 3131     } else {
 3132         resp = chow_dialog(pmod->t1 + 1, pmod->t2 - 1, &splitbrk,
 3133                    &splitdum, NULL, vwin_toplevel(vwin));
 3134     }
 3135     if (canceled(resp)) {
 3136         return;
 3137     }
 3138     if (opt & OPT_L) {
 3139         struct chowparms *cp = malloc(sizeof *cp);
 3140 
 3141         cp->splitdum = splitdum;
 3142         cp->splitbrk = splitbrk;
 3143         g_object_set_data(G_OBJECT(vwin->main), "chowparms", cp);
 3144         simple_selection_for_viewer(CHOW, _("gretl: chow test"),
 3145                     real_limited_chow, vwin);
 3146         /* execution resumes with real_limited_chow() */
 3147         return;
 3148     }
 3149     }
 3150 
 3151     if (ci == CHOW) {
 3152     if (splitdum > 0) {
 3153         lib_command_sprintf("chow %s --dummy", dataset->varname[splitdum]);
 3154         opt |= OPT_D;
 3155     } else {
 3156         char brkstr[OBSLEN];
 3157 
 3158         ntodate(brkstr, splitbrk, dataset);
 3159         lib_command_sprintf("chow %s", brkstr);
 3160     }
 3161     } else if (ci == QLRTEST) {
 3162     lib_command_strcpy("qlrtest");
 3163     } else if (ci == CUSUM) {
 3164     lib_command_strcpy("cusum");
 3165     } else if (ci == CUSUMSQ) {
 3166     lib_command_strcpy("cusum --squares");
 3167     }
 3168 
 3169     if (bufopen(&prn)) {
 3170     return;
 3171     }
 3172 
 3173     if (ci == CHOW) {
 3174     if (opt & OPT_D) {
 3175         err = chow_test_from_dummy(splitdum, pmod, dataset, opt, prn);
 3176     } else {
 3177         err = chow_test(splitbrk, pmod, dataset, opt, prn);
 3178     }
 3179     } else if (ci == QLRTEST) {
 3180     err = QLR_test(pmod, dataset, opt, prn);
 3181     } else {
 3182     if (ci == CUSUMSQ) {
 3183         opt |= OPT_R;
 3184     }
 3185     err = cusum_test(pmod, dataset, opt, prn);
 3186     }
 3187 
 3188     if (err) {
 3189     gui_errmsg(err);
 3190     gretl_print_destroy(prn);
 3191     } else {
 3192     if (ci == CUSUM || ci == CUSUMSQ || ci == QLRTEST) {
 3193         register_graph();
 3194     }
 3195 
 3196     update_model_tests(vwin);
 3197     record_model_command_verbatim(pmod->ID);
 3198 
 3199     view_buffer_with_parent(vwin, prn, 78, 400,
 3200                 (ci == CHOW)?
 3201                 _("gretl: Chow test output") :
 3202                 (ci == QLRTEST)?
 3203                 _("gretl: QLR test output") :
 3204                 (ci == CUSUM)?
 3205                 _("gretl: CUSUM test output") :
 3206                 _("gretl: CUSUMSQ test output"),
 3207                 ci, NULL);
 3208     }
 3209 }
 3210 
 3211 void do_reset (GtkAction *action, gpointer p)
 3212 {
 3213     windata_t *vwin = (windata_t *) p;
 3214     MODEL *pmod = vwin->data;
 3215     DATASET *dset;
 3216     PRN *prn;
 3217     const char *optstrs[] = {
 3218     N_("squares and cubes"),
 3219     N_("squares only"),
 3220     N_("cubes only"),
 3221     N_("all variants")
 3222     };
 3223     gretlopt opt = OPT_S;
 3224     int width = 78;
 3225     int height = 400;
 3226     int resp, err = 0;
 3227 
 3228     if (gui_exact_fit_check(pmod)) {
 3229     return;
 3230     }
 3231 
 3232     resp = radio_dialog(_("gretl: RESET test"),
 3233             _("RESET specification test"),
 3234             optstrs, 4, 0, RESET,
 3235             vwin_toplevel(vwin));
 3236 
 3237     if (canceled(resp) || bufopen(&prn)) {
 3238     return;
 3239     }
 3240 
 3241     dset = maybe_get_model_data(pmod, OPT_NONE, &err);
 3242     if (err) {
 3243     gretl_print_destroy(prn);
 3244     return;
 3245     }
 3246 
 3247     lib_command_strcpy("reset");
 3248 
 3249     if (resp == 1) {
 3250     opt |= OPT_R;
 3251     lib_command_strcat(" --squares-only");
 3252     } else if (resp == 2) {
 3253     lib_command_strcat(" --cubes-only");
 3254     opt |= OPT_C;
 3255     } else if (resp == 3) {
 3256     opt = (OPT_Q | OPT_G);
 3257     }
 3258 
 3259     if (opt & OPT_G) {
 3260     /* gui special: show short form of all 3 tests */
 3261     width = 60;
 3262     height = 320;
 3263     err = reset_test(pmod, dset, opt, prn);
 3264     if (!err) {
 3265         err = reset_test(pmod, dset, (opt | OPT_R), prn);
 3266     }
 3267     if (!err) {
 3268         err = reset_test(pmod, dset, (opt | OPT_C), prn);
 3269     }
 3270     } else {
 3271     err = reset_test(pmod, dset, opt, prn);
 3272     }
 3273 
 3274     if (err) {
 3275     gui_errmsg(err);
 3276     gretl_print_destroy(prn);
 3277     } else {
 3278     if (opt & OPT_S) {
 3279         update_model_tests(vwin);
 3280     }
 3281     record_model_command_verbatim(pmod->ID);
 3282     view_buffer_with_parent(vwin, prn, width, height,
 3283                 _("gretl: RESET test"),
 3284                 RESET, NULL);
 3285     }
 3286 
 3287     trim_dataset(pmod, 0);
 3288 }
 3289 
 3290 void do_autocorr (GtkAction *action, gpointer p)
 3291 {
 3292     windata_t *vwin = (windata_t *) p;
 3293     MODEL *pmod = vwin->data;
 3294     PRN *prn;
 3295     int order = 1;
 3296     int resp, err;
 3297 
 3298     if (gui_exact_fit_check(pmod)) {
 3299     return;
 3300     }
 3301 
 3302     if (dataset_is_panel(dataset)) {
 3303     /* first-order test only */
 3304     if (bufopen(&prn)) {
 3305         return;
 3306     }
 3307     } else {
 3308     order = default_lag_order(dataset);
 3309     resp = spin_dialog(_("gretl: autocorrelation"), NULL,
 3310                &order, _("Lag order for test:"),
 3311                1, dataset->n / 2, 0,
 3312                vwin_toplevel(vwin));
 3313 
 3314     if (canceled(resp) || bufopen(&prn)) {
 3315         return;
 3316     }
 3317     }
 3318 
 3319     if (dataset_is_panel(dataset)) {
 3320     err = panel_autocorr_test(pmod, dataset, OPT_S, prn);
 3321     } else {
 3322     err = autocorr_test(pmod, order, dataset, OPT_S, prn);
 3323     }
 3324 
 3325     if (err) {
 3326     gui_errmsg(err);
 3327     gretl_print_destroy(prn);
 3328     } else {
 3329     gchar *title =
 3330         g_strdup_printf(_("gretl: autocorrelation"));
 3331 
 3332     update_model_tests(vwin);
 3333     lib_command_sprintf("modtest --autocorr %d", order);
 3334     record_model_command_verbatim(pmod->ID);
 3335     view_buffer_with_parent(vwin, prn, 78, 400,
 3336                 title, MODTEST, NULL);
 3337     g_free(title);
 3338     }
 3339 }
 3340 
 3341 void do_dwpval (GtkAction *action, gpointer p)
 3342 {
 3343     windata_t *vwin = (windata_t *) p;
 3344     MODEL *pmod = vwin->data;
 3345     PRN *prn;
 3346     double pv;
 3347     int err = 0;
 3348 
 3349     if (bufopen(&prn)) {
 3350     return;
 3351     }
 3352 
 3353     pv = get_DW_pvalue_for_model(pmod, dataset, &err);
 3354 
 3355     if (err) {
 3356     gui_errmsg(err);
 3357     gretl_print_destroy(prn);
 3358     } else {
 3359     gchar *title = gretl_window_title(_("Durbin-Watson"));
 3360 
 3361     pprintf(prn, "%s = %g\n", _("Durbin-Watson statistic"), pmod->dw);
 3362     if (na(pv)) {
 3363         pputs(prn, _("p-value is \"very small\" (the Imhof integral could not\n"
 3364              "be evaluated so a definite value is not available)"));
 3365     } else {
 3366         pprintf(prn, "%s = %g\n", _("p-value"), pv);
 3367     }
 3368     view_buffer_with_parent(vwin, prn, 78, 200,
 3369                 title, PRINT, NULL);
 3370     g_free(title);
 3371     }
 3372 }
 3373 
 3374 static int model_error (MODEL *pmod)
 3375 {
 3376     int err = 0;
 3377 
 3378     if (pmod->errcode) {
 3379     if (pmod->errcode != E_CANCEL) {
 3380         gui_errmsg(pmod->errcode);
 3381     }
 3382     gretl_model_free(pmod);
 3383     err = 1;
 3384     }
 3385 
 3386     return err;
 3387 }
 3388 
 3389 static int model_output (MODEL *pmod, PRN *prn)
 3390 {
 3391     int err = 0;
 3392 
 3393     if (model_error(pmod)) {
 3394     err = 1;
 3395     } else {
 3396     printmodel(pmod, dataset, OPT_NONE, prn);
 3397     warnmsg(prn); /* just in case */
 3398     }
 3399 
 3400     return err;
 3401 }
 3402 
 3403 static void record_command_block_from_buf (const gchar *buf,
 3404                        const char *startline,
 3405                        const char *endline,
 3406                        int model_ID)
 3407 {
 3408     bufgets_init(buf);
 3409 
 3410     if (startline != NULL) {
 3411     lib_command_strcpy(startline);
 3412     if (model_ID > 0) {
 3413         record_model_command_verbatim(model_ID);
 3414     } else {
 3415         record_command_verbatim();
 3416     }
 3417     }
 3418 
 3419     while (bufgets(libline, MAXLINE, buf)) {
 3420     if (string_is_blank(libline)) {
 3421         continue;
 3422     }
 3423     top_n_tail(libline, sizeof libline, NULL);
 3424     if (model_ID > 0) {
 3425         record_model_command_verbatim(model_ID);
 3426     } else {
 3427         record_command_verbatim();
 3428     }
 3429     }
 3430 
 3431     bufgets_finalize(buf);
 3432 
 3433     if (endline != NULL) {
 3434     lib_command_strcpy(endline);
 3435     if (model_ID > 0) {
 3436         record_model_command_verbatim(model_ID);
 3437     } else {
 3438         record_command_verbatim();
 3439     }
 3440     }
 3441 }
 3442 
 3443 void do_restrict (GtkWidget *w, dialog_t *dlg)
 3444 {
 3445     windata_t *vwin = (windata_t *) edit_dialog_get_data(dlg);
 3446     gretlopt opt = edit_dialog_get_opt(dlg);
 3447     MODEL *pmod = NULL;
 3448     equation_system *sys = NULL;
 3449     GRETL_VAR *vecm = NULL;
 3450     GRETL_VAR *vnew = NULL;
 3451     gchar *buf;
 3452     PRN *prn;
 3453     char bufline[MAXLINE];
 3454     gretl_restriction *my_rset = NULL;
 3455     int save_t1 = dataset->t1;
 3456     int save_t2 = dataset->t2;
 3457     int got_start = 0, got_end = 0;
 3458     int height = 300;
 3459     int err = 0;
 3460 
 3461     if (vwin->role == VIEW_MODEL) {
 3462     pmod = (MODEL *) vwin->data;
 3463     } else if (vwin->role == VECM) {
 3464     vecm = (GRETL_VAR *) vwin->data;
 3465     } else if (vwin->role == SYSTEM) {
 3466     sys = (equation_system *) vwin->data;
 3467     }
 3468 
 3469     if (pmod == NULL && vecm == NULL && sys == NULL) {
 3470     edit_dialog_close(dlg);
 3471     return;
 3472     }
 3473 
 3474     buf = edit_dialog_special_get_text(dlg);
 3475     if (buf == NULL) return;
 3476 
 3477     bufgets_init(buf);
 3478 
 3479     while (bufgets(bufline, sizeof bufline, buf) && !err) {
 3480     if (string_is_blank(bufline)) {
 3481         continue;
 3482     }
 3483 
 3484     top_n_tail(bufline, MAXLINE, NULL);
 3485 
 3486     if (!strcmp(bufline, "end restrict")) {
 3487         got_end = 1;
 3488         break;
 3489     } else if (!strncmp(bufline, "restrict", 8)) {
 3490         got_start = 1;
 3491     }
 3492 
 3493     if (my_rset == NULL) {
 3494         if (pmod != NULL) {
 3495         my_rset = eqn_restriction_set_start(bufline, pmod,
 3496                             dataset, opt);
 3497         } else if (sys != NULL) {
 3498         my_rset = cross_restriction_set_start(bufline, sys);
 3499         } else {
 3500         my_rset = var_restriction_set_start(bufline, vecm);
 3501         }
 3502         if (my_rset == NULL) {
 3503         err = 1;
 3504         gui_errmsg(err);
 3505         }
 3506     } else {
 3507         err = restriction_set_parse_line(my_rset, bufline, dataset);
 3508         if (err) {
 3509         gui_errmsg(err);
 3510         }
 3511     }
 3512     }
 3513 
 3514     bufgets_finalize(buf);
 3515 
 3516     if (err) {
 3517     g_free(buf);
 3518     return;
 3519     }
 3520 
 3521     edit_dialog_close(dlg);
 3522 
 3523     if (opt & OPT_B) {
 3524     gretlopt bootopt = OPT_NONE;
 3525     int resp;
 3526     int B = 1000;
 3527 
 3528     resp = bootstrap_dialog(vwin, NULL, &B, &bootopt);
 3529     if (canceled(resp)) {
 3530         /* command context? */
 3531         destroy_restriction_set(my_rset);
 3532         return;
 3533     }
 3534     gretl_restriction_set_boot_params(B, bootopt);
 3535     }
 3536 
 3537     if (bufopen(&prn)) return;
 3538 
 3539     if (pmod != NULL) {
 3540     dataset->t1 = pmod->t1;
 3541     dataset->t2 = pmod->t2;
 3542     }
 3543 
 3544     if (opt & OPT_F) {
 3545     vnew = gretl_restricted_vecm(my_rset, dataset, opt, prn, &err);
 3546     } else {
 3547     err = gretl_restriction_finalize(my_rset, dataset, OPT_NONE, prn);
 3548     }
 3549 
 3550     if (err) {
 3551     errmsg(err, prn);
 3552     } else {
 3553     if (pmod != NULL) {
 3554         /* FIXME --boot option */
 3555         const char *s0 = got_start ? NULL : "restrict";
 3556         const char *s1 = got_end ? NULL : "end restrict";
 3557 
 3558         record_command_block_from_buf(buf, s0, s1, pmod->ID);
 3559     } else if (sys != NULL) {
 3560         equation_system_estimate(sys, dataset, OPT_NONE, prn);
 3561         height = 450;
 3562     } else if (vecm != NULL) {
 3563         height = 450;
 3564     }
 3565     }
 3566 
 3567     g_free(buf);
 3568 
 3569     if (vnew != NULL) {
 3570     view_buffer(prn, 78, 450, _("gretl: VECM"), VECM, vnew);
 3571     } else {
 3572     gchar *title = gretl_window_title(_("linear restrictions"));
 3573 
 3574     view_buffer_with_parent(vwin, prn, 78, height, title,
 3575                 PRINT, NULL);
 3576     g_free(title);
 3577     }
 3578 
 3579     dataset->t1 = save_t1;
 3580     dataset->t2 = save_t2;
 3581 }
 3582 
 3583 static void maybe_grab_system_name (const char *s, char *name)
 3584 {
 3585     s = strstr(s, "name=");
 3586     if (s != NULL) {
 3587     s += 5;
 3588     if (*s == '"') {
 3589         sscanf(s + 1, "%31[^\"]", name);
 3590     } else {
 3591         sscanf(s, "%31s", name);
 3592     }
 3593     }
 3594 }
 3595 
 3596 static int get_sys_method_from_opt (gretlopt *opt)
 3597 {
 3598     int method = *opt;
 3599 
 3600     if (*opt & OPT_V) {
 3601     /* extract verbose option */
 3602     *opt |= OPT_V;
 3603     method &= ~OPT_V;
 3604     }
 3605 
 3606     if (*opt & OPT_T) {
 3607     /* extract iterate option */
 3608     *opt |= OPT_T;
 3609     method &= ~OPT_T;
 3610     }
 3611 
 3612     return method;
 3613 }
 3614 
 3615 static int gui_handle_equations_line (equation_system *sys,
 3616                       const char *s)
 3617 {
 3618     char s1[VNAMELEN] = {0};
 3619     char s2[VNAMELEN] = {0};
 3620     int n, err;
 3621 
 3622     /* extract one or two names to pass as arguments */
 3623 
 3624     n = sscanf(s, "%31s %31s", s1, s2);
 3625     if (n == 2) {
 3626     err = equation_system_append_multi(sys, s1, s2, dataset);
 3627     } else if (n == 1) {
 3628     err = equation_system_append_multi(sys, s1, NULL, dataset);
 3629     } else {
 3630     err = E_ARGS;
 3631     }
 3632 
 3633     return err;
 3634 }
 3635 
 3636 void do_eqn_system (GtkWidget *w, dialog_t *dlg)
 3637 {
 3638     equation_system *my_sys = NULL;
 3639     gretlopt opt;
 3640     gchar *buf;
 3641     PRN *prn;
 3642     char sysname[32] = {0};
 3643     char bufline[MAXLINE];
 3644     int *slist = NULL;
 3645     char *startline = NULL;
 3646     int got_end = 0;
 3647     int method, err = 0;
 3648 
 3649     buf = edit_dialog_special_get_text(dlg);
 3650     if (buf == NULL) {
 3651     return;
 3652     }
 3653 
 3654     opt = edit_dialog_get_opt(dlg);
 3655     method = get_sys_method_from_opt(&opt);
 3656 
 3657     bufgets_init(buf);
 3658     *sysname = 0;
 3659 
 3660     while (bufgets(bufline, sizeof bufline, buf) && !err) {
 3661     if (string_is_blank(bufline) || *bufline == '#') {
 3662         continue;
 3663     }
 3664 
 3665     top_n_tail(bufline, MAXLINE, NULL);
 3666 
 3667     if (!strcmp(bufline, "end system")) {
 3668         got_end = 1;
 3669         break;
 3670     }
 3671 
 3672     if (!strcmp(bufline, "system")) {
 3673         /* harmless header line */
 3674         continue;
 3675     }
 3676 
 3677     if (!strncmp(bufline, "system ", 7)) {
 3678         maybe_grab_system_name(bufline, sysname);
 3679         continue;
 3680     }
 3681 
 3682     if (my_sys == NULL) {
 3683         startline = g_strdup_printf("system method=%s",
 3684                     system_method_short_string(method));
 3685         /* FIXME opt? */
 3686         my_sys = equation_system_start(startline + 7, NULL,
 3687                        OPT_NONE, &err);
 3688     }
 3689 
 3690     if (err) {
 3691         gui_errmsg(err);
 3692         break;
 3693     }
 3694 
 3695     if (!strncmp(bufline, "equation ", 9)) {
 3696         slist = command_list_from_string(bufline + 9, &err);
 3697         if (slist != NULL) {
 3698         err = equation_system_append(my_sys, slist);
 3699         free(slist);
 3700         }
 3701     } else if (!strncmp(bufline, "equations ", 10)) {
 3702         err = gui_handle_equations_line(my_sys, bufline + 10);
 3703     } else {
 3704         err = system_parse_line(my_sys, bufline, dataset);
 3705     }
 3706 
 3707     if (err) {
 3708         /* sys is destroyed on error */
 3709         gui_errmsg(err);
 3710     }
 3711     }
 3712 
 3713     bufgets_finalize(buf);
 3714 
 3715     if (err) {
 3716     g_free(buf);
 3717     return;
 3718     }
 3719 
 3720     edit_dialog_close(dlg);
 3721 
 3722     if (bufopen(&prn)) {
 3723     g_free(buf);
 3724     return;
 3725     }
 3726 
 3727     err = equation_system_finalize(my_sys, dataset, opt, prn);
 3728     if (err) {
 3729     errmsg(err, prn);
 3730     } else {
 3731     const char *endline = got_end ? NULL : "end system";
 3732 
 3733     record_command_block_from_buf(buf, startline, endline, 0);
 3734     if (*sysname != 0) {
 3735         my_sys->name = g_strdup(sysname);
 3736     }
 3737     }
 3738 
 3739     g_free(buf);
 3740     g_free(startline);
 3741 
 3742     view_buffer(prn, 78, 450,
 3743         (my_sys->name != NULL)? my_sys->name:
 3744         _("gretl: simultaneous equations system"),
 3745         SYSTEM, my_sys);
 3746 }
 3747 
 3748 void do_saved_eqn_system (GtkWidget *w, dialog_t *dlg)
 3749 {
 3750     equation_system *my_sys;
 3751     gretlopt opt;
 3752     PRN *prn;
 3753     int err = 0;
 3754 
 3755     my_sys = (equation_system *) edit_dialog_get_data(dlg);
 3756     if (my_sys == NULL) {
 3757     return;
 3758     }
 3759 
 3760     opt = edit_dialog_get_opt(dlg);
 3761     my_sys->method = get_sys_method_from_opt(&opt);
 3762 
 3763     edit_dialog_close(dlg);
 3764 
 3765     if (bufopen(&prn)) {
 3766     return;
 3767     }
 3768 
 3769     err = equation_system_estimate(my_sys, dataset,
 3770                    opt, prn);
 3771     if (err) {
 3772     errmsg(err, prn);
 3773     }
 3774 
 3775     view_buffer(prn, 78, 450, my_sys->name, SYSTEM, my_sys);
 3776 }
 3777 
 3778 /* Try for the most informative possible error message
 3779    from genr, but also try to avoid duplication. In context,
 3780    @plus is (or may be) a specific message from "genr".
 3781 */
 3782 
 3783 void errmsg_plus (int err, const char *plus)
 3784 {
 3785     int handled = 0;
 3786 
 3787     if (plus != NULL && *plus != '\0') {
 3788     const char *s1 = errmsg_get_with_default(err);
 3789     gchar *s2 = g_strstrip(g_strdup(plus));
 3790     const char *s3 = NULL;
 3791 
 3792     if (err == E_PARSE && get_local_decpoint() == ',') {
 3793         s3 = N_("Please note: the decimal character must be '.'\n"
 3794             "in this context");
 3795     }
 3796 
 3797     if (*s1 != '\0' && *s2 != '\0' && strcmp(s1, s2)) {
 3798         if (s3 != NULL) {
 3799         errbox_printf("%s\n\n%s", s1, _(s3));
 3800         } else {
 3801         errbox_printf("%s\n\n%s", s1, s2);
 3802         }
 3803         handled = 1;
 3804     } else if (*s1 == '\0' && *s2 != '\0') {
 3805         if (s3 != NULL) {
 3806         errbox_printf("%s\n\n%s", s2, _(s3));
 3807         } else {
 3808         errbox(s2);
 3809         }
 3810         handled = 1;
 3811     }
 3812 
 3813     g_free(s2);
 3814     }
 3815 
 3816     if (!handled) {
 3817     /* fallback */
 3818     gui_errmsg(err);
 3819     }
 3820 }
 3821 
 3822 /* The point of the following is to take a line such as
 3823    "matrix M = I(5)", with leading type specification,
 3824    and to pre-process it as the tokenizer does for "genr"
 3825    expressions entered via script or command line. That is,
 3826    strip out the type-word (if present) but use the
 3827    information it carries to fill out the @gtype argument to
 3828    the libgretl generate() function.
 3829 */
 3830 
 3831 int gui_run_genr (const char *line, DATASET *dset,
 3832           gretlopt opt, PRN *prn)
 3833 {
 3834     GretlType gtype = GRETL_TYPE_ANY;
 3835     char word[32];
 3836 
 3837     if (sscanf(line, "%31s", word)) {
 3838     GretlType t = gretl_get_gen_type(word);
 3839 
 3840     if (t > 0) {
 3841         gtype = t;
 3842         line += strlen(word);
 3843         line += strspn(line, " ");
 3844     }
 3845     }
 3846 
 3847     return generate(line, dset, gtype, opt, prn);
 3848 }
 3849 
 3850 static int finish_genr (MODEL *pmod, dialog_t *dlg)
 3851 {
 3852     PRN *prn;
 3853     const char *gbuf;
 3854     int err = 0;
 3855 
 3856     if (bufopen(&prn)) {
 3857     return 1;
 3858     }
 3859 
 3860     if (pmod != NULL) {
 3861     set_genr_model(pmod, GRETL_OBJ_EQN);
 3862     }
 3863 
 3864     err = gui_run_genr(libline, dataset, OPT_NONE, prn);
 3865     unset_genr_model();
 3866     gbuf = gretl_print_get_buffer(prn);
 3867 
 3868     if (err) {
 3869     errmsg_plus(err, gbuf);
 3870     } else {
 3871     int gentype = genr_get_last_output_type();
 3872 
 3873     if (dlg != NULL) {
 3874         edit_dialog_close(dlg);
 3875     }
 3876 
 3877     if (pmod != NULL) {
 3878         record_model_command_verbatim(pmod->ID);
 3879     } else {
 3880         record_command_verbatim();
 3881     }
 3882 
 3883     if (gentype == GRETL_TYPE_SERIES || gentype == GRETL_TYPE_LIST) {
 3884         populate_varlist();
 3885         mark_dataset_as_modified();
 3886     } else if (gentype == GRETL_TYPE_DOUBLE) {
 3887         if (autoicon_on()) {
 3888         edit_scalars();
 3889         } else {
 3890         infobox(gbuf);
 3891         }
 3892     } else if (gentype == GRETL_TYPE_MATRIX) {
 3893         if (autoicon_on()) {
 3894         view_session();
 3895         } else {
 3896         infobox(gbuf);
 3897         }
 3898     }
 3899 
 3900     maybe_warn();
 3901     }
 3902 
 3903     gretl_print_destroy(prn);
 3904 
 3905     return err;
 3906 }
 3907 
 3908 /* identify "genr" lines within a block command such
 3909    as nls, mle, gmm */
 3910 
 3911 static int is_genr_line (char *s)
 3912 {
 3913     if (!strncmp(s, "genr ", 5) ||
 3914     !strncmp(s, "series ", 7) ||
 3915     !strncmp(s, "scalar ", 7) ||
 3916     !strncmp(s, "matrix ", 7) ||
 3917     !strncmp(s, "list ", 5)) {
 3918     return 1;
 3919     } else if (!strncmp(s, "param ", 6) && strchr(s, '=')) {
 3920     gchar *tmp = g_strdup_printf("genr %s", s + 6);
 3921 
 3922     strcpy(s, tmp);
 3923     g_free(tmp);
 3924     return 1;
 3925     } else {
 3926     return 0;
 3927     }
 3928 }
 3929 
 3930 static void real_do_nonlinear_model (dialog_t *dlg, int ci)
 3931 {
 3932     gchar *buf = edit_dialog_special_get_text(dlg);
 3933     gretlopt opt = edit_dialog_get_opt(dlg);
 3934     char realline[MAXLINE];
 3935     char bufline[MAXLINE];
 3936     char **lines = NULL;
 3937     int n_lines = 0;
 3938     int started = 0, ended = 0;
 3939     MODEL *pmod = NULL;
 3940     const char *cstr;
 3941     char endstr[8];
 3942     PRN *prn = NULL;
 3943     int err = 0;
 3944 
 3945     if (buf == NULL) {
 3946     return;
 3947     }
 3948 
 3949     cstr = gretl_command_word(ci);
 3950     sprintf(endstr, "end %s", cstr);
 3951 
 3952     bufgets_init(buf);
 3953     *realline = '\0';
 3954 
 3955     while (bufgets(bufline, sizeof bufline, buf) && !err) {
 3956     int len, cont = 0;
 3957 
 3958     if (string_is_blank(bufline) || *bufline == '#') {
 3959         *realline = '\0';
 3960         continue;
 3961     }
 3962 
 3963     /* allow for backslash continuation of lines */
 3964     cont = top_n_tail(bufline, sizeof bufline, &err);
 3965     if (!err) {
 3966         len = strlen(bufline) + strlen(realline);
 3967         if (len > MAXLINE - 1) {
 3968         err = E_TOOLONG;
 3969         }
 3970     }
 3971 
 3972     if (err) {
 3973         gui_errmsg(err);
 3974         break;
 3975     }
 3976 
 3977     strcat(realline, bufline);
 3978 
 3979     if (cont) {
 3980         continue;
 3981     }
 3982 
 3983     if (started && !strncmp(realline, endstr, 7)) {
 3984         /* we got, e.g., "end nls" */
 3985         strings_array_add(&lines, &n_lines, realline);
 3986         ended = 1;
 3987         break;
 3988     }
 3989 
 3990     if (!started && is_genr_line(realline)) {
 3991         /* handle possible "genr" lines before the actual
 3992            command block: for such lines the recording
 3993            or error message is handled by finish_genr
 3994         */
 3995         lib_command_strcpy(realline);
 3996         err = finish_genr(NULL, NULL);
 3997         *realline = '\0';
 3998         continue; /* on to the next line */
 3999     }
 4000 
 4001     if (!started && strncmp(realline, cstr, 3)) {
 4002         /* insert, e.g., "nls" if it's not present */
 4003         gchar *tmp = g_strdup_printf("%s %s", cstr, realline);
 4004 
 4005         *realline = '\0';
 4006         strncat(realline, tmp, MAXLINE - 1);
 4007         g_free(tmp);
 4008     }
 4009 
 4010     err = nl_parse_line(ci, realline, dataset, NULL);
 4011 
 4012     if (err) {
 4013         gui_errmsg(err);
 4014     } else {
 4015         strings_array_add(&lines, &n_lines, realline);
 4016         if (!started) {
 4017         started = 1;
 4018         }
 4019     }
 4020 
 4021     *realline = '\0';
 4022     }
 4023 
 4024     bufgets_finalize(buf);
 4025     g_free(buf);
 4026 
 4027     if (!err && !ended) {
 4028     /* if the user didn't give "end XXX", add it for the record */
 4029     strings_array_add(&lines, &n_lines, endstr);
 4030     }
 4031 
 4032     if (!err && bufopen(&prn)) {
 4033     err = 1;
 4034     }
 4035 
 4036     if (!err) {
 4037     pmod = gretl_model_new();
 4038     if (pmod == NULL) {
 4039         nomem();
 4040         err = E_ALLOC;
 4041     } else {
 4042         *pmod = nl_model(dataset, opt, prn);
 4043         err = model_output(pmod, prn);
 4044     }
 4045     }
 4046 
 4047     if (err) {
 4048     gretl_print_destroy(prn);
 4049     } else {
 4050     if (lines != NULL) {
 4051         /* on success, log all the commands */
 4052         int i;
 4053 
 4054         for (i=0; i<n_lines; i++) {
 4055         add_command_to_stack(lines[i], 0);
 4056         }
 4057     }
 4058     edit_dialog_close(dlg);
 4059     attach_subsample_to_model(pmod, dataset);
 4060     view_model(prn, pmod, NULL);
 4061     }
 4062 
 4063     strings_array_free(lines, n_lines);
 4064 }
 4065 
 4066 void do_nls_model (GtkWidget *w, dialog_t *dlg)
 4067 {
 4068     real_do_nonlinear_model(dlg, NLS);
 4069 }
 4070 
 4071 void do_mle_model (GtkWidget *w, dialog_t *dlg)
 4072 {
 4073     real_do_nonlinear_model(dlg, MLE);
 4074 }
 4075 
 4076 void do_gmm_model (GtkWidget *w, dialog_t *dlg)
 4077 {
 4078     real_do_nonlinear_model(dlg, GMM);
 4079 }
 4080 
 4081 static int do_straight_anova (void)
 4082 {
 4083     PRN *prn;
 4084     int err;
 4085 
 4086     if (parse_lib_command() || bufopen(&prn)) {
 4087     return 1;
 4088     }
 4089 
 4090     err = anova(libcmd.list, dataset, libcmd.opt, prn);
 4091 
 4092     if (err) {
 4093     gui_errmsg(err);
 4094     gretl_print_destroy(prn);
 4095     } else {
 4096     gchar *title = gretl_window_title(_("ANOVA"));
 4097 
 4098     view_buffer(prn, 78, 400, title, PRINT, NULL);
 4099     g_free(title);
 4100     record_lib_command();
 4101     }
 4102 
 4103     return err;
 4104 }
 4105 
 4106 static int real_do_model (int action)
 4107 {
 4108     int orig_v = dataset->v;
 4109     MODEL *pmod;
 4110     PRN *prn;
 4111     int err = 0;
 4112 
 4113 #if 0
 4114     fprintf(stderr, "do_model: libline = '%s'\n", libline);
 4115 #endif
 4116 
 4117     if (parse_lib_command() || bufopen(&prn)) {
 4118     return 1;
 4119     }
 4120 
 4121     pmod = gretl_model_new();
 4122     if (pmod == NULL) {
 4123     nomem();
 4124     gretl_print_destroy(prn);
 4125     return 1;
 4126     }
 4127 
 4128     switch (action) {
 4129 
 4130     case AR1:
 4131     *pmod = ar1_model(libcmd.list, dataset, libcmd.opt | OPT_G, prn);
 4132     break;
 4133     case OLS:
 4134     case WLS:
 4135     *pmod = lsq(libcmd.list, dataset, action, libcmd.opt);
 4136     break;
 4137     case PANEL:
 4138     *pmod = panel_model(libcmd.list, dataset, libcmd.opt, prn);
 4139     break;
 4140     case ARBOND:
 4141     /* FIXME instrument spec */
 4142     *pmod = arbond_model(libcmd.list, NULL, dataset,
 4143                  libcmd.opt, prn);
 4144     break;
 4145     case DPANEL:
 4146     /* FIXME ylags, instrument spec */
 4147     *pmod = dpd_model(libcmd.list, NULL, NULL, dataset,
 4148               libcmd.opt, prn);
 4149     break;
 4150     case HSK:
 4151     *pmod = hsk_model(libcmd.list, dataset, libcmd.opt);
 4152     break;
 4153     case IVREG:
 4154     *pmod = ivreg(libcmd.list, dataset, libcmd.opt);
 4155     break;
 4156     case AR:
 4157     *pmod = ar_model(libcmd.list, dataset, OPT_NONE, prn);
 4158     break;
 4159     case LOGIT:
 4160     case PROBIT:
 4161     *pmod = logit_probit(libcmd.list, dataset, action, libcmd.opt,
 4162                  prn);
 4163     break;
 4164     case BIPROBIT:
 4165     *pmod = biprobit_model(libcmd.list, dataset, libcmd.opt, prn);
 4166     break;
 4167     case TOBIT:
 4168     *pmod = tobit_driver(libcmd.list, dataset, libcmd.opt, prn);
 4169     break;
 4170     case HECKIT:
 4171     *pmod = heckit_model(libcmd.list, dataset, libcmd.opt, prn);
 4172     break;
 4173     case POISSON:
 4174     case NEGBIN:
 4175     *pmod = count_model(libcmd.list, action, dataset, libcmd.opt,
 4176                 prn);
 4177     break;
 4178     case DURATION:
 4179     *pmod = duration_model(libcmd.list, dataset, libcmd.opt,
 4180                    prn);
 4181     break;
 4182     case ARMA:
 4183     *pmod = arma(libcmd.list, libcmd.auxlist, dataset,
 4184              libcmd.opt, prn);
 4185     break;
 4186     case ARCH:
 4187     *pmod = arch_model(libcmd.list, libcmd.order, dataset,
 4188                libcmd.opt);
 4189     break;
 4190     case GARCH:
 4191     *pmod = garch(libcmd.list, dataset, libcmd.opt, prn);
 4192     break;
 4193     case LOGISTIC:
 4194     *pmod = logistic_driver(libcmd.list, dataset, libcmd.opt);
 4195     break;
 4196     case LAD:
 4197     *pmod = lad_model(libcmd.list, dataset, libcmd.opt);
 4198     break;
 4199     case QUANTREG:
 4200     *pmod = quantreg_driver(libcmd.param, libcmd.list, dataset,
 4201                 libcmd.opt, prn);
 4202     break;
 4203     case INTREG:
 4204     *pmod = interval_model(libcmd.list, dataset, libcmd.opt, prn);
 4205     break;
 4206     case MPOLS:
 4207     *pmod = mp_ols(libcmd.list, dataset, libcmd.opt);
 4208     break;
 4209     case MIDASREG:
 4210     *pmod = midas_model(libcmd.list, libcmd.param, dataset,
 4211                 libcmd.opt, prn);
 4212     break;
 4213     default:
 4214     errbox(_("Sorry, not implemented yet!"));
 4215     err = 1;
 4216     break;
 4217     }
 4218 
 4219     if (!err) {
 4220     err = model_output(pmod, prn);
 4221     }
 4222 
 4223     if (!err && action == AR1 && (libcmd.opt & OPT_H)) {
 4224     register_graph();
 4225     }
 4226 
 4227     if (err) {
 4228     if (action == GARCH && (libcmd.opt & OPT_V)) {
 4229         /* non-convergence info? */
 4230         view_buffer(prn, 78, 400, _("gretl: GARCH"), PRINT, NULL);
 4231     } else {
 4232         gretl_print_destroy(prn);
 4233     }
 4234     } else {
 4235     record_model_command(pmod->ID);
 4236     attach_subsample_to_model(pmod, dataset);
 4237     view_model(prn, pmod, NULL);
 4238     }
 4239 
 4240     if (dataset->v > orig_v) {
 4241     refresh_data();
 4242     }
 4243 
 4244     return err;
 4245 }
 4246 
 4247 static void compose_midas_listname (gui_midas_spec *si, int i)
 4248 {
 4249     char *vname = dataset->varname[si->leadvar];
 4250     char *p = strrchr(vname, '_');
 4251 
 4252     *si->listname = '\0';
 4253 
 4254     if (p != NULL && strlen(p) == 3) {
 4255     char tmp[VNAMELEN];
 4256 
 4257     strcpy(tmp, vname);
 4258     p = strrchr(tmp, '_');
 4259     *p = '\0';
 4260     if (current_series_index(dataset, tmp) < 0 &&
 4261         get_user_var_by_name(tmp) == NULL) {
 4262         /* no collision? */
 4263         strcpy(si->listname, tmp);
 4264     }
 4265     }
 4266 
 4267     if (*si->listname == '\0') {
 4268     /* fallback */
 4269     sprintf(si->listname, "HFL___%d", i+1);
 4270     }
 4271 }
 4272 
 4273 static gchar *compose_midas_param (gpointer p,
 4274                    gretlopt *addopt,
 4275                    int *err)
 4276 {
 4277     gui_midas_spec *si, *specs = p;
 4278     char *tmp, *buf = NULL;
 4279     int *list = NULL;
 4280     int nt, any_beta1 = 0;
 4281     int umidas = 1;
 4282     int i;
 4283 
 4284     if (specs == NULL) {
 4285     *err = E_DATA;
 4286     return NULL;
 4287     }
 4288 
 4289     nt = specs[0].nterms;
 4290 
 4291     for (i=0; i<nt; i++) {
 4292     if (specs[i].ptype != MIDAS_U) {
 4293         umidas = 0;
 4294     }
 4295     if (specs[i].ptype == MIDAS_BETA1) {
 4296         any_beta1 = 1;
 4297     }
 4298     }
 4299 
 4300     if (any_beta1) {
 4301     if (nt > 1) {
 4302         errbox("One-parameter beta term cannot be combined with others");
 4303         *err = E_DATA;
 4304         return NULL;
 4305     } else {
 4306         specs[0].ptype = MIDAS_BETA0;
 4307         *addopt |= OPT_C;
 4308     }
 4309     }
 4310 
 4311     for (i=0; i<nt; i++) {
 4312     si = &specs[i];
 4313     if (si->listname[0] == '\0') {
 4314         /* we'll have to construct a list */
 4315         int lmax = si->leadvar + si->fratio - 1;
 4316 
 4317         list = gretl_consecutive_list_new(si->leadvar, lmax);
 4318         if (nt == 1) {
 4319         compose_midas_listname(si, i);
 4320         } else {
 4321         sprintf(si->listname, "HFL___%d", i+1);
 4322         }
 4323         remember_list(list, si->listname, NULL);
 4324         user_var_privatize_by_name(si->listname);
 4325 
 4326     }
 4327     if (umidas) {
 4328         tmp = g_strdup_printf("mds(%s,%d,%d,%d)",
 4329                   si->listname, si->minlag,
 4330                   si->maxlag, si->ptype);
 4331     } else if (si->ptype == MIDAS_BETA0 ||
 4332            si->ptype == MIDAS_BETAN ||
 4333            si->ptype == MIDAS_U) {
 4334         tmp = g_strdup_printf("mds(%s,%d,%d,%d,null)",
 4335                   si->listname, si->minlag,
 4336                   si->maxlag, si->ptype);
 4337     } else {
 4338         tmp = g_strdup_printf("mds(%s,%d,%d,%d,%d)",
 4339                   si->listname, si->minlag,
 4340                   si->maxlag, si->ptype,
 4341                   si->nparm);
 4342     }
 4343     if (i == 0) {
 4344         buf = tmp;
 4345     } else {
 4346         gchar *tmp2 = g_strjoin(" ", buf, tmp, NULL);
 4347 
 4348         g_free(buf);
 4349         g_free(tmp);
 4350         buf = tmp2;
 4351     }
 4352     }
 4353 
 4354     return buf;
 4355 }
 4356 
 4357 int do_model (selector *sr)
 4358 {
 4359     gretlopt opt, addopt = OPT_NONE;
 4360     gpointer extra_data;
 4361     char estimator[9];
 4362     const char *buf;
 4363     const char *flagstr;
 4364     gchar *pbuf = NULL;
 4365     int ci, err = 0;
 4366 
 4367     if (selector_error(sr)) {
 4368     return 1;
 4369     }
 4370 
 4371     buf = selector_list(sr);
 4372     if (buf == NULL) {
 4373     return 1;
 4374     }
 4375 
 4376     ci = selector_code(sr);
 4377     opt = selector_get_opts(sr);
 4378     extra_data = selector_get_extra_data(sr);
 4379 
 4380     /* In some cases, choices which are represented by option flags in
 4381        gretl script are represented by ancillary "ci" values in the
 4382        GUI model selector (in order to avoid overloading the model
 4383        selection dialog with options).  Here we have to decode such
 4384        values, parsing them out into basic command index value and
 4385        associated option.
 4386     */
 4387 
 4388     if (ci == OLS && dataset_is_panel(dataset)) {
 4389     /* pooled OLS */
 4390     ci = PANEL;
 4391     addopt = OPT_P;
 4392     } else if (ci == MLOGIT) {
 4393     /* multinomial logit */
 4394     ci = LOGIT;
 4395     addopt = OPT_M;
 4396     } else if (ci == OLOGIT) {
 4397     /* ordered logit */
 4398     ci = LOGIT;
 4399     } else if (ci == OPROBIT) {
 4400     /* ordered probit */
 4401     ci = PROBIT;
 4402     } else if (ci == REPROBIT) {
 4403     /* random-effects probit */
 4404     ci = PROBIT;
 4405     addopt = OPT_E;
 4406     } else if (ci == FE_LOGISTIC) {
 4407     ci = LOGISTIC;
 4408     addopt = OPT_F;
 4409     } else if (ci == IV_LIML || ci == IV_GMM) {
 4410     /* single-equation LIML, GMM */
 4411     if (ci == IV_LIML) {
 4412         addopt = OPT_L;
 4413     } else if (ci == IV_GMM) {
 4414         addopt = OPT_G;
 4415     }
 4416     ci = IVREG;
 4417     } else if (ci == COUNTMOD) {
 4418     if (opt & (OPT_M | OPT_N)) {
 4419         ci = NEGBIN;
 4420         opt &= ~OPT_N;
 4421     } else {
 4422         ci = POISSON;
 4423     }
 4424     } else if (ci == MIDASREG) {
 4425     pbuf = compose_midas_param(extra_data, &addopt, &err);
 4426     }
 4427 
 4428     if (err) {
 4429     return err;
 4430     }
 4431 
 4432     strcpy(estimator, gretl_command_word(ci));
 4433 
 4434     libcmd.opt = opt | addopt;
 4435     flagstr = print_flags(libcmd.opt, ci);
 4436     if (pbuf != NULL) {
 4437     lib_command_sprintf("%s %s ; %s%s", estimator, buf, pbuf, flagstr);
 4438     } else {
 4439     lib_command_sprintf("%s %s%s", estimator, buf, flagstr);
 4440     }
 4441 
 4442 #if 0
 4443     fprintf(stderr, "\nmodel command elements:\n");
 4444     fprintf(stderr, "estimator: '%s'\n", estimator);
 4445     fprintf(stderr, "selector_list: '%s'\n\n", buf);
 4446 #endif
 4447 
 4448     if (ci == ANOVA) {
 4449     return do_straight_anova();
 4450     } else {
 4451     return real_do_model(ci);
 4452     }
 4453 }
 4454 
 4455 /* callback from selection dialog for two nonparametric
 4456    estimators, loess and Nadaraya-Watson
 4457 */
 4458 
 4459 int do_nonparam_model (selector *sr)
 4460 {
 4461     gretl_bundle *bundle = NULL;
 4462     double *m = NULL;
 4463     const char *s, *buf;
 4464     char yname[VNAMELEN];
 4465     char xname[VNAMELEN];
 4466     const double *y, *x;
 4467     gretlopt opt;
 4468     int ci, vy, vx;
 4469     int i, err = 0;
 4470 
 4471     if (selector_error(sr)) {
 4472     return 1;
 4473     }
 4474 
 4475     buf = selector_list(sr);
 4476     if (buf == NULL || sscanf(buf, "%31s %31s", yname, xname) != 2) {
 4477     return 1;
 4478     }
 4479 
 4480     ci = selector_code(sr);
 4481     opt = selector_get_opts(sr);
 4482 
 4483     /* get the two input series */
 4484     vy = current_series_index(dataset, yname);
 4485     vx = current_series_index(dataset, xname);
 4486     y = dataset->Z[vy];
 4487     x = dataset->Z[vx];
 4488 
 4489     /* storage for the fitted series */
 4490     m = malloc(dataset->n * sizeof *m);
 4491     if (m == NULL) {
 4492     err = E_ALLOC;
 4493     } else {
 4494     for (i=0; i<dataset->n; i++) {
 4495         m[i] = NADBL;
 4496     }
 4497     }
 4498 
 4499     if (!err) {
 4500     /* bundle to hold parameters and results */
 4501     bundle = gretl_bundle_new();
 4502     if (bundle == NULL) {
 4503         err = E_ALLOC;
 4504     } else {
 4505         gretl_bundle_set_string(bundle, "yname", yname);
 4506         gretl_bundle_set_string(bundle, "xname", xname);
 4507     }
 4508     }
 4509 
 4510     if (!err && ci == LOESS) {
 4511     int robust = (opt & OPT_R)? 1 : 0;
 4512     int d = 1;
 4513     double q = 0.5;
 4514 
 4515     /* scan the buffer from the selector for
 4516        d and q specifications */
 4517     if ((s = strstr(buf, "d=")) != NULL) {
 4518         d = atoi(s + 2);
 4519     }
 4520     if ((s = strstr(buf, "q=")) != NULL) {
 4521         q = atof(s + 2);
 4522     }
 4523 
 4524     err = gretl_loess(y, x, d, q, robust, dataset, m);
 4525     if (!err) {
 4526         gretl_bundle_set_string(bundle, "function", "loess");
 4527         gretl_bundle_set_int(bundle, "d", d);
 4528         gretl_bundle_set_scalar(bundle, "q", q);
 4529         gretl_bundle_set_int(bundle, "robust", robust);
 4530         gretl_bundle_set_series(bundle, "m", m, dataset->n);
 4531         lib_command_sprintf("loess(%s, %s, %d, %g, %d)",
 4532                 yname, xname, d, q, robust);
 4533         record_command_verbatim();
 4534     }
 4535 
 4536     } else if (!err && ci == NADARWAT) {
 4537     int LOO = (opt & OPT_O)? 1 : 0;
 4538     double trim = libset_get_double(NADARWAT_TRIM);
 4539     double h = 0; /* automatic */
 4540 
 4541     if ((s = strstr(buf, "h=")) != NULL) {
 4542         h = atof(s + 2);
 4543     }
 4544 
 4545     err = nadaraya_watson(y, x, h, dataset, LOO, trim, m);
 4546     if (!err) {
 4547         gretl_bundle_set_string(bundle, "function", "nadarwat");
 4548         gretl_bundle_set_scalar(bundle, "h", h);
 4549         gretl_bundle_set_int(bundle, "LOO", LOO);
 4550         gretl_bundle_set_scalar(bundle, "trim", trim);
 4551         gretl_bundle_set_series(bundle, "m", m, dataset->n);
 4552         lib_command_sprintf("nadarwat(%s, %s, %g, %d, %g)",
 4553                 yname, xname, h, LOO, trim);
 4554         record_command_verbatim();
 4555     }
 4556     }
 4557 
 4558     if (err) {
 4559     gui_errmsg(err);
 4560     } else {
 4561     gchar *title;
 4562     PRN *prn;
 4563 
 4564     err = bufopen(&prn);
 4565     if (!err) {
 4566         title = gretl_window_title(ci == LOESS ? _("loess") :
 4567                        _("Nadaraya-Watson"));
 4568         text_print_x_y_fitted(vx, vy, m, dataset, prn);
 4569         view_buffer(prn, 78, 450, title, ci, bundle);
 4570         g_free(title);
 4571     }
 4572     }
 4573 
 4574     free(m);
 4575 
 4576     if (err) {
 4577     gretl_bundle_destroy(bundle);
 4578     }
 4579 
 4580     return 0;
 4581 }
 4582 
 4583 static double *nonparam_retrieve_fitted (gretl_bundle *bundle)
 4584 {
 4585     double *m;
 4586     int n, err = 0;
 4587 
 4588     m = gretl_bundle_get_series(bundle, "m", &n, &err);
 4589 
 4590     if (err) {
 4591     gui_errmsg(err);
 4592     } else if (n != dataset->n) {
 4593     errbox(_("Series length does not match the dataset"));
 4594     }
 4595 
 4596     return m;
 4597 }
 4598 
 4599 void add_nonparam_data (windata_t *vwin)
 4600 {
 4601     gretl_bundle *bundle = vwin->data;
 4602     double *m;
 4603     int err = 0;
 4604 
 4605     m = nonparam_retrieve_fitted(bundle);
 4606 
 4607     if (m != NULL) {
 4608     const char *func = gretl_bundle_get_string(bundle, "function", &err);
 4609     const char *yname = gretl_bundle_get_string(bundle, "yname", &err);
 4610     const char *xname = gretl_bundle_get_string(bundle, "xname", &err);
 4611     char vname[VNAMELEN];
 4612     char descrip[MAXLABEL];
 4613     double q = 0, h = 0, trim = 0;
 4614     int d = 0, robust = 0, LOO = 0;
 4615     int cancel = 0;
 4616 
 4617     if (!strcmp(func, "loess")) {
 4618         d = gretl_bundle_get_int(bundle, "d", &err);
 4619         q = gretl_bundle_get_scalar(bundle, "q", &err);
 4620         robust = gretl_bundle_get_int(bundle, "robust", &err);
 4621         strcpy(vname, "loess_fit");
 4622         sprintf(descrip, "loess(%s, %s, %d, %g, %d)",
 4623             yname, xname, d, q, robust);
 4624     } else {
 4625         h = gretl_bundle_get_scalar(bundle, "h", &err);
 4626         LOO = gretl_bundle_get_int(bundle, "LOO", &err);
 4627         trim = gretl_bundle_get_scalar(bundle, "trim", &err);
 4628         strcpy(vname, "nw_fit");
 4629         sprintf(descrip, "nadarwat(%s, %s, %g, %d, %g)",
 4630             yname, xname, h, LOO, trim);
 4631     }
 4632 
 4633     name_new_series_dialog(vname, descrip, vwin, &cancel);
 4634 
 4635     if (!cancel) {
 4636         err = add_or_replace_series(m, vname, descrip, DS_COPY_VALUES);
 4637     }
 4638 
 4639     if (!cancel && !err) {
 4640         gretl_push_c_numeric_locale();
 4641         if (!strcmp(func, "loess")) {
 4642         lib_command_sprintf("%s = loess(%s, %s, %d, %g, %d)",
 4643                     vname, yname, xname, d, q, robust);
 4644         } else {
 4645         lib_command_sprintf("%s = nadarwat(%s, %s, %g)",
 4646                     vname, yname, xname, h);
 4647         }
 4648         record_command_verbatim();
 4649         gretl_pop_c_numeric_locale();
 4650     }
 4651     }
 4652 }
 4653 
 4654 void do_nonparam_plot (windata_t *vwin)
 4655 {
 4656     gretl_bundle *bundle = vwin->data;
 4657     double *m;
 4658     int err = 0;
 4659 
 4660     m = nonparam_retrieve_fitted(bundle);
 4661 
 4662     if (m != NULL) {
 4663     const char *func = gretl_bundle_get_string(bundle, "function", &err);
 4664     const char *yname = gretl_bundle_get_string(bundle, "yname", &err);
 4665     const char *xname = gretl_bundle_get_string(bundle, "xname", &err);
 4666     int vy = current_series_index(dataset, yname);
 4667     int vx = current_series_index(dataset, xname);
 4668     char **S = NULL;
 4669     gretl_matrix *plotmat, *tmp;
 4670     const double *x;
 4671     int need_sort = 0;
 4672     int i, j, n = sample_size(dataset);
 4673 
 4674     if (vy < 0 || vx < 0) {
 4675         gui_errmsg(E_DATA);
 4676         return;
 4677     }
 4678 
 4679     plotmat = gretl_matrix_alloc(n, 3);
 4680     if (plotmat == NULL) {
 4681         nomem();
 4682         return;
 4683     }
 4684 
 4685     for (j=0; j<3; j++) {
 4686         x = (j == 0)? dataset->Z[vy] : (j == 1)? m : dataset->Z[vx];
 4687         for (i=0; i<n; i++) {
 4688         gretl_matrix_set(plotmat, i, j, x[i+dataset->t1]);
 4689         if (!need_sort && j == 2 && i > 0 &&
 4690             !na(x[i]) && !na(x[i]) && x[i] < x[i-1]) {
 4691             need_sort = 1;
 4692         }
 4693         }
 4694     }
 4695 
 4696     if (need_sort) {
 4697         /* sort by the x column to avoid wrap-back of plot line */
 4698         tmp = gretl_matrix_sort_by_column(plotmat, 2, &err);
 4699         if (!err) {
 4700         gretl_matrix_free(plotmat);
 4701         plotmat = tmp;
 4702         }
 4703     }
 4704 
 4705     if (!err) {
 4706         S = strings_array_new_with_length(3, VNAMELEN);
 4707         if (S != NULL) {
 4708         strcpy(S[0], yname);
 4709         strcpy(S[1], _("fitted"));
 4710         strcpy(S[2], xname);
 4711         gretl_matrix_set_colnames(plotmat, S);
 4712         }
 4713     }
 4714 
 4715     if (err) {
 4716         gui_errmsg(err);
 4717     } else {
 4718         gchar *literal, *title;
 4719 
 4720         if (!strcmp(func, "loess")) {
 4721         title = g_strdup_printf(_("%s versus %s with loess fit"),
 4722                     yname, xname);
 4723         } else {
 4724         title = g_strdup_printf(_("%s versus %s with Nadaraya-Watson fit"),
 4725                     yname, xname);
 4726         }
 4727         literal = g_strdup_printf("{ set title \"%s\"; }", title);
 4728         set_optval_string(GNUPLOT, OPT_O, "fitted");
 4729         err = matrix_plot(plotmat, NULL, literal, OPT_O | OPT_G);
 4730         gui_graph_handler(err);
 4731         g_free(literal);
 4732         g_free(title);
 4733     }
 4734 
 4735     gretl_matrix_free(plotmat);
 4736     }
 4737 }
 4738 
 4739 int do_vector_model (selector *sr)
 4740 {
 4741     GRETL_VAR *var;
 4742     char estimator[9];
 4743     const char *buf;
 4744     const char *flagstr;
 4745     PRN *prn;
 4746     int action;
 4747     int err = 0;
 4748 
 4749     if (selector_error(sr)) {
 4750     return 1;
 4751     }
 4752 
 4753     buf = selector_list(sr);
 4754     if (buf == NULL) {
 4755     return 1;
 4756     }
 4757 
 4758     libcmd.opt = selector_get_opts(sr);
 4759     action = selector_code(sr);
 4760 
 4761     if (action == VLAGSEL) {
 4762     libcmd.opt |= OPT_L;
 4763     action = VAR;
 4764     }
 4765 
 4766     strcpy(estimator, gretl_command_word(action));
 4767     flagstr = print_flags(libcmd.opt, action);
 4768     lib_command_sprintf("%s %s%s", estimator, buf, flagstr);
 4769 
 4770 #if 0
 4771     fprintf(stderr, "do_vector_model: libline = '%s'\n", libline);
 4772 #endif
 4773 
 4774     if (parse_lib_command() || bufopen(&prn)) {
 4775     return 1;
 4776     }
 4777 
 4778     if (libcmd.order > var_max_order(libcmd.list, dataset)) {
 4779     gui_errmsg(E_TOOFEW);
 4780     gretl_print_destroy(prn);
 4781     return 1;
 4782     }
 4783 
 4784     if (action == VAR && !(libcmd.opt & OPT_L)) {
 4785     /* regular VAR, not VAR lag selection */
 4786     var = gretl_VAR(libcmd.order, libcmd.auxlist, libcmd.list, dataset,
 4787             libcmd.opt, prn, &err);
 4788     if (!err) {
 4789         view_buffer(prn, 78, 450, _("gretl: vector autoregression"),
 4790             VAR, var);
 4791     }
 4792     } else if (action == VAR) {
 4793     /* VAR lag selection */
 4794     gretl_VAR(libcmd.order, NULL, libcmd.list, dataset,
 4795           libcmd.opt, prn, &err);
 4796     if (!err) {
 4797         view_buffer(prn, 72, 350, _("gretl: VAR lag selection"),
 4798             PRINT, NULL);
 4799     }
 4800     } else if (action == VECM) {
 4801     /* Vector Error Correction Model */
 4802     var = gretl_VECM(libcmd.order, libcmd.auxint, libcmd.list,
 4803              dataset, libcmd.opt, prn, &err);
 4804     if (!err) {
 4805         view_buffer(prn, 78, 450, _("gretl: VECM"), VECM, var);
 4806     }
 4807     } else {
 4808     err = 1;
 4809     }
 4810 
 4811     if (err) {
 4812     gui_errmsg(err);
 4813     gretl_print_destroy(prn);
 4814     } else {
 4815     /* note: paired with parse_lib_command() above */
 4816     record_lib_command();
 4817     }
 4818 
 4819     return err;
 4820 }
 4821 
 4822 static char *alt_list_buf (const int *src, int fit,
 4823                int *err)
 4824 {
 4825     char *buf;
 4826     int yvar = src[1];
 4827     int xvar = src[3];
 4828     int list[5];
 4829     int addv;
 4830 
 4831     if (fit == PLOT_FIT_QUADRATIC) {
 4832     addv = xpxgenr(xvar, xvar, dataset);
 4833     } else {
 4834     addv = invgenr(xvar, dataset);
 4835     }
 4836 
 4837     if (addv < 0) {
 4838     nomem();
 4839     return NULL;
 4840     }
 4841 
 4842     if (fit == PLOT_FIT_QUADRATIC) {
 4843     list[0] = 4;
 4844     list[1] = yvar;
 4845     list[2] = 0;
 4846     list[3] = xvar;
 4847     list[4] = addv;
 4848     } else {
 4849     list[0] = 3;
 4850     list[1] = yvar;
 4851     list[2] = 0;
 4852     list[3] = addv;
 4853     }
 4854 
 4855     buf = gretl_list_to_string(list, dataset, err);
 4856 
 4857     return buf;
 4858 }
 4859 
 4860 /* called from gpt_control.c: the incoming @list should
 4861    be of the form {3, Y, 0, X}
 4862 */
 4863 
 4864 void do_graph_model (const int *list, int fit)
 4865 {
 4866     MODEL *pmod = NULL;
 4867     char *buf = NULL;
 4868     PRN *prn;
 4869     int orig_v = dataset->v;
 4870     int err = 0;
 4871 
 4872     if (list == NULL) {
 4873     gui_errmsg(E_DATA);
 4874     return;
 4875     }
 4876 
 4877     if (fit == PLOT_FIT_QUADRATIC || fit == PLOT_FIT_INVERSE) {
 4878     buf = alt_list_buf(list, fit, &err);
 4879     } else {
 4880     buf = gretl_list_to_string(list, dataset, &err);
 4881     }
 4882 
 4883     if (err) {
 4884     gui_errmsg(err);
 4885     return;
 4886     }
 4887 
 4888     lib_command_sprintf("ols%s", buf);
 4889     free(buf);
 4890 
 4891     if (parse_lib_command() || bufopen(&prn)) {
 4892     return;
 4893     }
 4894 
 4895     pmod = gretl_model_new();
 4896 
 4897     if (pmod == NULL) {
 4898     nomem();
 4899     err = E_ALLOC;
 4900     } else {
 4901     *pmod = lsq(libcmd.list, dataset, OLS, libcmd.opt);
 4902     err = model_output(pmod, prn);
 4903     }
 4904 
 4905     if (err) {
 4906     gretl_print_destroy(prn);
 4907     } else {
 4908     /* note: paired with parse_lib_command() above */
 4909     record_lib_command();
 4910     attach_subsample_to_model(pmod, dataset);
 4911     view_model(prn, pmod, NULL);
 4912     }
 4913 
 4914     if (dataset->v > orig_v) {
 4915     refresh_data();
 4916     }
 4917 }
 4918 
 4919 /* budget version of gretl console */
 4920 
 4921 void do_minibuf (GtkWidget *w, dialog_t *dlg)
 4922 {
 4923     char *buf = gretl_strdup(edit_dialog_get_text(dlg));
 4924     ExecState state;
 4925     char cword[9];
 4926     int ci, err;
 4927 
 4928     if (buf == NULL) {
 4929     return;
 4930     }
 4931 
 4932     edit_dialog_close(dlg);
 4933 
 4934     sscanf(buf, "%8s", cword);
 4935     ci = gretl_command_number(cword);
 4936 
 4937     /* actions we can't/won't handle here (should be more?) */
 4938     if (ci == LOOP || ci == RESTRICT || ci == SYSTEM ||
 4939     ci == EQUATION || ci == VAR || ci == VECM ||
 4940     ci == NLS || ci == MLE || ci == GMM ||
 4941     is_model_ref_cmd(ci)) {
 4942     dummy_call();
 4943     free(buf);
 4944     return;
 4945     }
 4946 
 4947     if (MODEL_COMMAND(ci)) {
 4948     lib_command_strcpy(buf);
 4949     real_do_model(ci);
 4950     free(buf);
 4951     return;
 4952     }
 4953 
 4954     gretl_exec_state_init(&state, CONSOLE_EXEC, libline, &libcmd,
 4955               model, NULL);
 4956     lib_command_strcpy(buf);
 4957     free(buf);
 4958 
 4959     console_record_sample(dataset);
 4960     err = gui_exec_line(&state, dataset, mdata->main);
 4961 
 4962     if (err) {
 4963     gui_errmsg(err);
 4964     } else {
 4965     /* update variable listing in main window if needed */
 4966     if (check_dataset_is_changed()) {
 4967         mark_dataset_as_modified();
 4968         populate_varlist();
 4969     }
 4970     /* update sample info and options if needed */
 4971     if (console_sample_changed(dataset)) {
 4972         set_sample_label(dataset);
 4973     }
 4974     }
 4975 }
 4976 
 4977 #define REPLACE_COMMA_HACK 1
 4978 
 4979 #if REPLACE_COMMA_HACK
 4980 
 4981 static gchar *maybe_fix_decimal_comma (const gchar *s)
 4982 {
 4983     gchar *cpy = g_strdup(s);
 4984     gchar *p = cpy;
 4985     int inbrackets = 0;
 4986     int inparens = 0;
 4987     int inbraces = 0;
 4988     int inquotes = 0;
 4989 
 4990     /* experimental */
 4991 
 4992     while (*p) {
 4993     if (*p == '[') {
 4994         inbrackets++;
 4995     } else if (*p == ']') {
 4996         inbrackets--;
 4997     } else if (*p == '(') {
 4998         inparens++;
 4999     } else if (*p == ')') {
 5000         inparens--;
 5001     } else if (*p == '{') {
 5002         inbraces++;
 5003     } else if (*p == '}') {
 5004         inbraces--;
 5005     } else if (*p == '"') {
 5006         inquotes = !inquotes;
 5007     }
 5008     if (*p == ',' && !inparens && !inbrackets &&
 5009         !inbraces && !inquotes && isdigit(*(p+1))) {
 5010         *p = '.';
 5011     }
 5012     p++;
 5013     }
 5014 
 5015     return cpy;
 5016 }
 5017 
 5018 #endif /* REPLACE_COMMA_HACK */
 5019 
 5020 gchar *get_genr_string (GtkWidget *entry, dialog_t *dlg)
 5021 {
 5022     const gchar *s = NULL;
 5023     gchar *gstr = NULL;
 5024 
 5025     if (dlg != NULL) {
 5026     s = edit_dialog_get_text(dlg);
 5027     } else if (entry != NULL) {
 5028     s = gtk_entry_get_text(GTK_ENTRY(entry));
 5029     }
 5030 
 5031     if (s != NULL && *s != '\0') {
 5032     while (isspace((unsigned char) *s)) s++;
 5033 #if REPLACE_COMMA_HACK
 5034     if (get_local_decpoint() == ',' && strchr(s, ',') != NULL) {
 5035         gstr = maybe_fix_decimal_comma(s);
 5036     } else {
 5037         gstr = g_strdup(s);
 5038     }
 5039 #else
 5040     gstr = g_strdup(s);
 5041 #endif
 5042     }
 5043 
 5044     return gstr;
 5045 }
 5046 
 5047 static int is_full_genr_command (const char *s)
 5048 {
 5049     int sppos = gretl_charpos(' ', s);
 5050 
 5051     if (sppos > 1 && sppos < 9) {
 5052     char word1[9] = {0};
 5053 
 5054     strncat(word1, s, sppos);
 5055     if (!strcmp(word1, "genr") || word_is_genr_alias(word1)) {
 5056         return 1;
 5057     }
 5058     }
 5059 
 5060     return 0;
 5061 }
 5062 
 5063 void do_genr (GtkWidget *w, dialog_t *dlg)
 5064 {
 5065     gchar *s = get_genr_string(NULL, dlg);
 5066     int err, edit = 0;
 5067 
 5068     if (s == NULL) {
 5069     return;
 5070     }
 5071 
 5072     if (is_full_genr_command(s)) {
 5073     /* don't mess with what the user typed */
 5074     lib_command_strcpy(s);
 5075     } else if (strchr(s, '=') == NULL) {
 5076     if (genr_special_word(s)) {
 5077         /* as in "genr time", but without the "genr" */
 5078         lib_command_sprintf("genr %s", s);
 5079     } else {
 5080         /* a bare varname? */
 5081         lib_command_sprintf("series %s = NA", s);
 5082         edit = 1;
 5083     }
 5084     } else {
 5085     lib_command_strcpy(s);
 5086     }
 5087 
 5088     g_free(s);
 5089 
 5090     err = finish_genr(NULL, dlg);
 5091 
 5092     if (edit && !err) {
 5093     mdata_select_last_var();
 5094     show_spreadsheet(SHEET_EDIT_VARLIST);
 5095     }
 5096 }
 5097 
 5098 void do_selector_genr (GtkWidget *w, dialog_t *dlg)
 5099 {
 5100     gchar *s = get_genr_string(NULL, dlg);
 5101     gpointer p = edit_dialog_get_data(dlg);
 5102     int err, oldv = dataset->v;
 5103 
 5104     if (s == NULL) {
 5105     return;
 5106     }
 5107 
 5108     if (is_full_genr_command(s)) {
 5109     lib_command_strcpy(s);
 5110     } else if (strchr(s, '=') == NULL && genr_special_word(s)) {
 5111     lib_command_sprintf("genr %s", s);
 5112     } else {
 5113     lib_command_sprintf("series %s", s);
 5114     }
 5115 
 5116     g_free(s);
 5117 
 5118     err = finish_genr(NULL, dlg);
 5119 
 5120     if (!err && dataset->v > oldv) {
 5121     selector_register_genr(dataset->v - oldv, p);
 5122     }
 5123 }
 5124 
 5125 /* callback for defining new series or scalar variable
 5126    from the GUI function-call dialog
 5127 */
 5128 
 5129 void do_fncall_genr (GtkWidget *w, dialog_t *dlg)
 5130 {
 5131     gchar *s = get_genr_string(NULL, dlg);
 5132     gpointer p = edit_dialog_get_data(dlg);
 5133     int scalargen = 0, oldv = -1;
 5134     int type, err;
 5135 
 5136     if (s == NULL) {
 5137     return;
 5138     }
 5139 
 5140     while (isspace((unsigned char) *s)) s++;
 5141 
 5142     type = widget_get_int(p, "ptype");
 5143 
 5144     if (type == GRETL_TYPE_SERIES) {
 5145     if (!strncmp(s, "series", 6)) {
 5146         lib_command_strcpy(s);
 5147     } else {
 5148         lib_command_sprintf("series %s", s);
 5149     }
 5150     oldv = dataset->v;
 5151     } else if (type == GRETL_TYPE_DOUBLE) {
 5152     if (!strncmp(s, "scalar", 6)) {
 5153         lib_command_strcpy(s);
 5154     } else {
 5155         lib_command_sprintf("scalar %s", s);
 5156     }
 5157     oldv = n_user_scalars();
 5158     scalargen = 1;
 5159     }
 5160 
 5161     g_free(s);
 5162 
 5163     err = finish_genr(NULL, dlg);
 5164 
 5165     if (!err) {
 5166     int newv = (scalargen)? n_user_scalars(): dataset->v;
 5167 
 5168     if (oldv >= 0 && newv > oldv) {
 5169         fncall_register_genr(newv - oldv, p);
 5170     }
 5171     }
 5172 }
 5173 
 5174 void do_model_genr (GtkWidget *w, dialog_t *dlg)
 5175 {
 5176     gchar *s = get_genr_string(NULL, dlg);
 5177     windata_t *vwin = (windata_t *) edit_dialog_get_data(dlg);
 5178     MODEL *pmod = vwin->data;
 5179 
 5180     if (s != NULL) {
 5181     lib_command_sprintf("%s", s);
 5182     finish_genr(pmod, dlg);
 5183     g_free(s);
 5184     }
 5185 }
 5186 
 5187 void do_range_dummy_genr (const gchar *buf)
 5188 {
 5189     lib_command_strcpy(buf);
 5190     finish_genr(NULL, NULL);
 5191 }
 5192 
 5193 static int real_do_setmiss (double missval, int varno)
 5194 {
 5195     int i, t, count = 0;
 5196     int start = 1, end = dataset->v;
 5197 
 5198     if (varno) {
 5199     start = varno;
 5200     end = varno + 1;
 5201     }
 5202 
 5203     for (i=start; i<end; i++) {
 5204     for (t=0; t<dataset->n; t++) {
 5205         if (dataset->Z[i][t] == missval) {
 5206         dataset->Z[i][t] = NADBL;
 5207         count++;
 5208         }
 5209     }
 5210     }
 5211 
 5212     return count;
 5213 }
 5214 
 5215 void do_global_setmiss (GtkWidget *w, dialog_t *dlg)
 5216 {
 5217     const gchar *buf;
 5218     double missval;
 5219     int count, err;
 5220 
 5221     buf = edit_dialog_get_text(dlg);
 5222     if (buf == NULL) return;
 5223 
 5224     if ((err = check_atof(buf))) {
 5225     gui_errmsg(err);
 5226     return;
 5227     }
 5228 
 5229     missval = atof(buf);
 5230     count = real_do_setmiss(missval, 0);
 5231 
 5232     edit_dialog_close(dlg);
 5233 
 5234     if (count) {
 5235     infobox_printf(_("Set %d values to \"missing\""), count);
 5236     mark_dataset_as_modified();
 5237     } else {
 5238     errbox(_("Didn't find any matching observations"));
 5239     }
 5240 }
 5241 
 5242 void do_variable_setmiss (GtkWidget *w, dialog_t *dlg)
 5243 {
 5244     const gchar *buf;
 5245     double missval;
 5246     int v = mdata_active_var();
 5247     int count, err;
 5248 
 5249     buf = edit_dialog_get_text(dlg);
 5250     if (buf == NULL) return;
 5251 
 5252     if ((err = check_atof(buf))) {
 5253     gui_errmsg(err);
 5254     return;
 5255     }
 5256 
 5257     missval = atof(buf);
 5258     count = real_do_setmiss(missval, v);
 5259 
 5260     edit_dialog_close(dlg);
 5261 
 5262     if (count) {
 5263     infobox_printf(_("Set %d observations to \"missing\""), count);
 5264     mark_dataset_as_modified();
 5265     } else {
 5266     errbox(_("Didn't find any matching observations"));
 5267     }
 5268 }
 5269 
 5270 int do_rename_variable (int v, const char *newname,
 5271             GtkWidget *parent)
 5272 {
 5273     int err = 0;
 5274 
 5275     if (v < dataset->v && !strcmp(newname, dataset->varname[v])) {
 5276     /* no-op (shouldn't happen) */
 5277     return 0;
 5278     }
 5279 
 5280     if (gretl_is_series(newname, dataset)) {
 5281     errbox_printf(_("A series named %s already exists"), newname);
 5282     err = E_DATA;
 5283     } else {
 5284     err = gui_validate_varname(newname, GRETL_TYPE_SERIES, parent);
 5285     }