"Fossies" - the Fresh Open Source Software Archive

Member "gretl-2020b/lib/src/interact.c" (18 Mar 2020, 91823 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 "interact.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 /* interact.c for gretl */
   21 
   22 #include "libgretl.h"
   23 #include "monte_carlo.h"
   24 #include "var.h"
   25 #include "johansen.h"
   26 #include "gretl_func.h"
   27 #include "compat.h"
   28 #include "system.h"
   29 #include "forecast.h"
   30 #include "cmd_private.h"
   31 #include "libset.h"
   32 #include "uservar.h"
   33 #include "gretl_panel.h"
   34 #include "texprint.h"
   35 #include "gretl_xml.h"
   36 #include "gretl_string_table.h"
   37 #include "gretl_typemap.h"
   38 #include "gretl_midas.h"
   39 #include "dbread.h"
   40 #include "gretl_foreign.h"
   41 #include "boxplots.h"
   42 #include "gretl_plot.h"
   43 #include "flow_control.h"
   44 #include "libglue.h"
   45 #include "csvdata.h"
   46 #include "gretl_zip.h"
   47 #include "matrix_extra.h"
   48 #ifdef USE_CURL
   49 # include "gretl_www.h"
   50 #endif
   51 
   52 #include <errno.h>
   53 
   54 /* for the "shell" command */
   55 #ifdef WIN32
   56 # include "gretl_win32.h"
   57 #else
   58 # ifdef HAVE_PATHS_H
   59 #  include <paths.h>
   60 # endif
   61 #endif
   62 
   63 #define CMD_DEBUG 0
   64 #define ECHO_DEBUG 0
   65 
   66 #include "tokenize.c"
   67 
   68 #define bare_quote(p,s)   (*p == '"' && (p-s==0 || *(p-1) != '\\'))
   69 #define starts_comment(p) (*p == '/' && *(p+1) == '*')
   70 #define ends_comment(p)   (*p == '*' && *(p+1) == '/')
   71 
   72 static int install_function_package (const char *pkgname,
   73                      gretlopt opt,
   74                      ExecState *s,
   75                      PRN *prn);
   76 
   77 static int strip_inline_comments (char *s)
   78 {
   79     int ret = 0;
   80 
   81     if (*s == '#') {
   82     /* the entire line is a comment */
   83     ret = 1;
   84     } else if (strstr(s, "#")) {
   85     int quoted = 0;
   86     int braced = 0;
   87     char *p = s;
   88 
   89     while (*p) {
   90         if (bare_quote(p, s)) {
   91         quoted = !quoted;
   92         } else if (!quoted) {
   93         if (*p == '{') {
   94             braced++;
   95         } else if (*p == '}') {
   96             braced--;
   97         }
   98         }
   99         if (!quoted && !braced) {
  100         if (*p == '#') {
  101             *p = '\0';
  102             break;
  103         }
  104         }
  105         p++;
  106     }
  107     }
  108 
  109     return ret;
  110 }
  111 
  112 /* filter_comments: strip comments out of line; return non-zero if
  113    the whole line is a comment */
  114 
  115 static int filter_comments (char *s, CMD *cmd)
  116 {
  117     char tmp[MAXLINE];
  118     char *p = s;
  119     int quoted = 0;
  120     int ignore = (cmd->flags & CMD_IGNORE);
  121     int j = 0, filt = 0;
  122 
  123     if (strlen(s) >= MAXLINE) {
  124     cmd->err = E_TOOLONG;
  125     return 0;
  126     }
  127 
  128     while (*p) {
  129     if (!quoted && !ignore && *p == '#') {
  130         break;
  131     }
  132     if (!ignore && bare_quote(p, s)) {
  133         quoted = !quoted;
  134     }
  135     if (!quoted) {
  136         if (starts_comment(p)) {
  137         ignore = 1;
  138         p += 2;
  139         } else if (ends_comment(p)) {
  140         if (!ignore) {
  141             cmd->err = E_PARSE;
  142             return 0;
  143         }
  144         ignore = 0;
  145         p += 2;
  146         p += strspn(p, " ");
  147         }
  148     }
  149     if (!ignore && *p != '\r') {
  150         tmp[j++] = *p;
  151     }
  152     if (*p) {
  153         p++;
  154     }
  155     }
  156 
  157     tmp[j] = '\0';
  158     strcpy(s, tmp);
  159     tailstrip(s);
  160 
  161     if (*s == '\0') {
  162     filt = 1;
  163     } else if (!ignore) {
  164     /* '#' comments */
  165     filt = strip_inline_comments(s);
  166     tailstrip(s);
  167     }
  168 
  169     if (filt) {
  170     /* the whole line is a comment */
  171     cmd->ci = CMD_COMMENT;
  172     }
  173 
  174     if (ignore) {
  175     /* the line ends in multi-line comment mode */
  176     cmd->flags |= CMD_IGNORE;
  177     } else {
  178     cmd->flags &= ~CMD_IGNORE;
  179     }
  180 
  181     return filt;
  182 }
  183 
  184 #define MODIFIES_LIST(c) (c == DIFF ||      \
  185               c == DUMMIFY ||   \
  186               c == LDIFF ||     \
  187               c == SDIFF ||     \
  188               c == LAGS ||      \
  189               c == LOGS ||      \
  190               c == SQUARE ||    \
  191                       c == ORTHDEV ||   \
  192               c == STDIZE)
  193 
  194 static int has_param (const CMD *cmd)
  195 {
  196     return cmd->param != NULL && *cmd->param != '\0';
  197 }
  198 
  199 /* Look for a line with an "implicit genr", such as
  200    y = 3*x, x += 10, etc. This is used in nls.c to
  201    assess auxiliary genrs in nls, mle, gmm.
  202 */
  203 
  204 int plausible_genr_start (const char *s, const DATASET *dset)
  205 {
  206     int ret = 0;
  207 
  208     if (strchr(s, '=') || strstr(s, "++") || strstr(s, "--")) {
  209     const char *ok = ".+-*/%^~|=[";
  210     char word[VNAMELEN] = {0};
  211     char fmt[20];
  212 
  213     sprintf(fmt, "%%%d[^[ .+*/%%^~|=-]", VNAMELEN - 1);
  214 
  215     if (sscanf(s, fmt, word)) {
  216         s += strlen(word);
  217         while (*s == ' ') s++;
  218         if (strspn(s, ok) > 0 && check_identifier(word) == 0) {
  219         ret = 1;
  220         }
  221     }
  222     } else if (gretl_type_from_name(s, dset) != 0) {
  223     ret = 1;
  224     }
  225 
  226     return ret;
  227 }
  228 
  229 static int ends_foreign_block (const char *s)
  230 {
  231     s += strspn(s, " \t");
  232 
  233     if (!strncmp(s, "end ", 4)) {
  234     s += 3;
  235     s += strspn(s, " \t");
  236     if (!strncmp(s, "foreign", 7)) {
  237         return 1;
  238     } else if (!strncmp(s, "mpi", 3)) {
  239         return 1;
  240     }
  241     }
  242 
  243     return 0;
  244 }
  245 
  246 /**
  247  * parse_command_line:
  248  * @s: pointer to execution-state struct.
  249  * @cmd: pointer to command struct.
  250  * @dset: dataset struct.
  251  * @ptr: pointer for use with "compilation" of
  252  * conditionals in loops.
  253  *
  254  * Parses @line and fills out @cmd accordingly.
  255  *
  256  * Returns: 0 on success, non-zero code on error.
  257  */
  258 
  259 int parse_command_line (ExecState *s, DATASET *dset, void *ptr)
  260 {
  261     char *line = s->line;
  262     CMD *cmd = s->cmd;
  263 
  264     gretl_cmd_clear(cmd);
  265     gretl_error_clear();
  266 
  267 #if CMD_DEBUG
  268     fprintf(stderr, "parse_command_line: '%s' (nosub=%d)\n",
  269         line, cmd_nosub(cmd) ? 1 : 0);
  270 #endif
  271 
  272     if (!gretl_strsub_on() || cmd_nosub(cmd)) {
  273     cmd->flags &= ~CMD_SUBST;
  274     } else {
  275     int subst = 0;
  276 
  277     cmd->err = substitute_named_strings(line, &subst);
  278     if (cmd->err) {
  279         return cmd->err;
  280     } else if (subst) {
  281         /* record the fact that substitution has been done */
  282         cmd->flags |= CMD_SUBST;
  283     } else {
  284         cmd->flags &= ~CMD_SUBST;
  285     }
  286     }
  287 
  288 #if CMD_DEBUG
  289     if (cmd->flags & CMD_SUBST) {
  290     fprintf(stderr, "after substitution: '%s'\n", line);
  291     }
  292 #endif
  293 
  294     if ((cmd->context == FOREIGN || cmd->context == MPI) &&
  295     !ends_foreign_block(line)) {
  296     cmd->opt = OPT_NONE;
  297     cmd->ci = cmd->context;
  298     return 0;
  299     }
  300 
  301     if ((cmd->flags & CMD_SUBST) || !gretl_looping_currently()) {
  302     /* normalize line spaces */
  303     compress_spaces(line);
  304 
  305     /* trap lines that are nothing but comments */
  306     if (filter_comments(line, cmd)) {
  307         return 0;
  308     }
  309 
  310     /* catch errors associated with comment syntax */
  311     if (cmd->err) {
  312         return cmd->err;
  313     }
  314     }
  315 
  316     cmd->err = real_parse_command(s, dset, 0, ptr);
  317 
  318     if (cmd->err) {
  319     gretl_cmd_destroy_context(cmd);
  320     }
  321 
  322     return cmd->err;
  323 }
  324 
  325 #ifndef WIN32
  326 
  327 static int gretl_shell_async (const char *cmdline, PRN *prn)
  328 {
  329     GError *gerr = NULL;
  330     gchar **argv = NULL;
  331     gint argc = 0;
  332     int err = 0;
  333 
  334     g_shell_parse_argv(cmdline, &argc, &argv, &gerr);
  335 
  336     if (gerr == NULL) {
  337     g_spawn_async(gretl_workdir(), argv, NULL,
  338               G_SPAWN_SEARCH_PATH,
  339               NULL, NULL, NULL, &gerr);
  340     g_strfreev(argv);
  341     }
  342 
  343     if (gerr != NULL) {
  344     pprintf(prn, "%s\n", gerr->message);
  345     g_error_free(gerr);
  346     err = 1;
  347     }
  348 
  349     return err;
  350 }
  351 
  352 static int gretl_shell_sync (const char *arg, gchar **psout,
  353                  PRN *prn)
  354 {
  355     gchar *sout = NULL;
  356     gchar *serr = NULL;
  357     GError *gerr = NULL;
  358     int status;
  359     gchar *argv[5];
  360     const char *theshell = getenv("SHELL");
  361     const char *namep;
  362     char shellnam[40];
  363     int err = 0;
  364 
  365     if (theshell == NULL) {
  366 #ifdef HAVE_PATHS_H
  367     theshell =_PATH_BSHELL;
  368 #else
  369     theshell = "/bin/sh";
  370 #endif
  371     }
  372 
  373     namep = strrchr(theshell, '/');
  374     if (namep == NULL) {
  375     namep = theshell;
  376     }
  377 
  378     strcpy(shellnam, "-");
  379     strcat(shellnam, ++namep);
  380     if (strcmp(namep, "sh") != 0) {
  381     shellnam[0] = '+';
  382     }
  383 
  384     argv[0] = g_strdup(theshell);
  385     argv[1] = shellnam;
  386     argv[2] = g_strdup("-c");
  387     argv[3] = g_strdup(arg);
  388     argv[4] = NULL;
  389 
  390     g_spawn_sync(gretl_workdir(), argv, NULL, 0, NULL, NULL,
  391          &sout, &serr, &status, &gerr);
  392 
  393     g_free(argv[0]);
  394     g_free(argv[2]);
  395     g_free(argv[3]);
  396 
  397     if (gerr != NULL) {
  398     if (prn != NULL) {
  399         pprintf(prn, "%s\n", gerr->message);
  400     } else {
  401         gretl_errmsg_set(gerr->message);
  402     }
  403     g_error_free(gerr);
  404     err = 1;
  405     }
  406 
  407     if (psout != NULL) {
  408     *psout = sout;
  409     } else if (sout != NULL) {
  410     pputs(prn, sout);
  411     g_free(sout);
  412     }
  413 
  414     if (serr != NULL) {
  415     pputs(prn, serr);
  416     g_free(serr);
  417     }
  418 
  419     return err;
  420 }
  421 
  422 /**
  423  * gretl_shell_grab:
  424  * @arg: command line to be executed.
  425  * @sout: location to receive output from command.
  426  *
  427  * Calls the shell to execute @arg syncronously and captures the
  428  * standard output, if any, in @sout.
  429  *
  430  * Returns: 0 on successful completion, non-zero on error.
  431  */
  432 
  433 int gretl_shell_grab (const char *arg, char **sout)
  434 {
  435     /* note: the win32 implementation of gretl_shell_grab()
  436        is defined in gretl_win32.c
  437     */
  438     return gretl_shell_sync(arg, sout, NULL);
  439 }
  440 
  441 static int gretl_shell (const char *arg, gretlopt opt, PRN *prn)
  442 {
  443     int err = 0;
  444 
  445     if (arg == NULL || *arg == '\0') {
  446     return 0;
  447     }
  448 
  449     if (!libset_get_bool(SHELL_OK)) {
  450     gretl_errmsg_set(_("The shell command is not activated."));
  451     return 1;
  452     }
  453 
  454     arg += strspn(arg, " \t");
  455 
  456     if (opt & OPT_A) {
  457     /* "launch" */
  458     err = gretl_shell_async(arg, prn);
  459     } else {
  460     err = gretl_shell_sync(arg, NULL, prn);
  461     }
  462 
  463     return err;
  464 }
  465 
  466 #endif /* ! WIN32 */
  467 
  468 #define SAFELEN 78 /* ? */
  469 
  470 static void trim_to_length (char *s)
  471 {
  472     int i, n = strlen(s);
  473 
  474     if (n < SAFELEN - 1) return;
  475 
  476     for (i=n-1; i>0; i--) {
  477     if (s[i] == ' ') {
  478         s[i] = '\0';
  479         break;
  480     }
  481     }
  482 }
  483 
  484 void safe_print_line (const char *line, int *plen, PRN *prn)
  485 {
  486     char tmp[SAFELEN];
  487     const char *q, *p = line;
  488     int n, m, rem, out = 0;
  489     int len0 = *plen;
  490 
  491     rem = n = strlen(line);
  492 
  493     while (out < n) {
  494     *tmp = 0;
  495     q = p;
  496     strncat(tmp, p, SAFELEN - 1);
  497     len0 = 0;
  498     trim_to_length(tmp - len0);
  499     len0 = 0;
  500     m = strlen(tmp);
  501     out += m;
  502     rem = n - out;
  503     p = q + m;
  504     if (rem > 0) {
  505         pprintf(prn, "%s \\\n ", tmp);
  506         *plen = 1;
  507     } else {
  508         pprintf(prn, "%s", tmp);
  509         *plen += m;
  510     }
  511     }
  512 }
  513 
  514 static void new_trim_to_length (char *s, int len)
  515 {
  516     int n = strlen(s);
  517 
  518     if (n > len) {
  519     int i, quoted = 0;
  520     int bp0 = 0, bp1 = 0;
  521 
  522     for (i=1; i<n-1; i++) {
  523         if (s[i] == '"' && s[i-1] != '\\') {
  524         quoted = !quoted;
  525         }
  526         if (!quoted && s[i] == ' ') {
  527         if (i < len) {
  528             bp0 = i;
  529         } else {
  530             bp1 = i;
  531             break;
  532         }
  533         }
  534     }
  535     if (bp0 > 0) {
  536         s[bp0] = '\0';
  537     } else if (bp1 > 0) {
  538         s[bp1] = '\0';
  539     }
  540     }
  541 }
  542 
  543 static void basic_trim_to_length (char *s, int len)
  544 {
  545     int n = strlen(s);
  546 
  547     if (n > len) {
  548     int i;
  549     int bp0 = 0, bp1 = 0;
  550 
  551     for (i=1; i<n-1; i++) {
  552         if (s[i] == ' ') {
  553         if (i < len) {
  554             bp0 = i;
  555         } else {
  556             bp1 = i;
  557             break;
  558         }
  559         }
  560     }
  561     if (bp0 > 0) {
  562         s[bp0] = '\0';
  563     } else if (bp1 > 0) {
  564         s[bp1] = '\0';
  565     }
  566     }
  567 }
  568 
  569 #define TESTLEN 256
  570 #define LINELEN 70
  571 
  572 static void reflow_line (const char *line, const CMD *cmd,
  573              const char *leader, PRN *prn)
  574 {
  575     int maxline = LINELEN;
  576 
  577     if (leader != NULL) {
  578     maxline -= 2;
  579     pputs(prn, leader);
  580     }
  581 
  582     if (cmd != NULL && (cmd->ciflags & CI_EXPR)) {
  583     /* "genr"-type lines: be more generous? */
  584     maxline += 10;
  585     } else if (gretl_in_gui_mode()) {
  586     /* we can handle a little more width */
  587     maxline += 4;
  588     }
  589 
  590     if (strlen(line) < maxline) {
  591     pputs(prn, line);
  592     } else {
  593     const char *p = line;
  594     char buf[TESTLEN];
  595     int linenum = 0;
  596 
  597     while (*p) {
  598         *buf = '\0';
  599         strncat(buf, p, TESTLEN - 1);
  600         if (linenum > 0 && leader == NULL) {
  601         new_trim_to_length(buf, maxline - 2);
  602         } else {
  603         new_trim_to_length(buf, maxline);
  604         }
  605         p += strlen(buf);
  606         if (!string_is_blank(buf)) {
  607         if (linenum > 0) {
  608             pputs(prn, "  ");
  609         }
  610         pputs(prn, (*buf == ' ')? buf + 1 : buf);
  611         if (*p) {
  612             pputs(prn, " \\\n");
  613         }
  614         }
  615         linenum++;
  616     }
  617     }
  618 }
  619 
  620 static int command_is_silent (const CMD *cmd, const char *line)
  621 {
  622     if (cmd == NULL) {
  623     return 0;
  624     }
  625 
  626     if (cmd->ci == FUNCERR || cmd->ci == PRINTF ||
  627     (cmd->ci == PRINT && strchr(line, '"'))) {
  628     return 1;
  629     }
  630 
  631     if (!strcmp(line, "set echo off") ||
  632     !strcmp(line, "set verbose off") ||
  633     !strcmp(line, "flush")) {
  634     return 1;
  635     }
  636 
  637     if (!strncmp(line, "quit", 4) && string_is_blank(line + 4)) {
  638     return 1;
  639     }
  640 
  641     if (cmd->ci == SET && cmd->param != NULL &&
  642     !strcmp(cmd->param, "echo") &&
  643     gretl_function_depth() > 0) {
  644     return 1;
  645     }
  646 
  647     if ((cmd->ci == OUTFILE && cmd->opt == OPT_C) ||
  648     (cmd->ci == END && cmd->param != NULL &&
  649      !strcmp(cmd->param, "outfile"))) {
  650     return 1;
  651     }
  652 
  653     if (*line == '!') {
  654     return 1;
  655     }
  656 
  657     return 0;
  658 }
  659 
  660 /*
  661  * real_echo_command:
  662  * @cmd: pointer to #CMD struct.
  663  * @line: "raw" command line associated with @cmd.
  664  * @recording: echo is going to command log (0/1).
  665  * @prn: pointer to gretl printing struct.
  666  *
  667  * Echoes the user command represented by @cmd and @line to
  668  * @prn.  This is used for two distinct purposes: to give
  669  * visual feedback on the command supplied, and (in some
  670  * contexts) to record a command that was executed interactively.
  671  */
  672 
  673 static void real_echo_command (CMD *cmd, const char *line,
  674                    int recording, PRN *prn)
  675 {
  676     const char *leader = NULL;
  677     int commented_store = 0;
  678     int compiling = 0;
  679 
  680     if (line == NULL || *line == '\0' || prn == NULL) {
  681     return;
  682     }
  683 
  684     if (cmd != NULL && cmd->ci >= NC) {
  685     return;
  686     }
  687 
  688     if (gretl_compiling_function() || gretl_compiling_loop()) {
  689     compiling = 1;
  690     }
  691 
  692 #if ECHO_DEBUG
  693     if (cmd != NULL) {
  694     fprintf(stderr, "echo_cmd:\n*** line='%s'\n param='%s' parm2='%s'\n",
  695         line, cmd->param, cmd->parm2);
  696     fprintf(stderr, " cmd->opt=%d, recording=%d, compiling=%d\n",
  697         cmd->opt, recording, compiling);
  698     fprintf(stderr, " cmd->ci = %d (%s), context = %d\n", cmd->ci,
  699         gretl_command_word(cmd->ci), cmd->context);
  700     fprintf(stderr, " cmd->savename = '%s'\n", cmd->savename);
  701     if (cmd->list != NULL) {
  702         printlist(cmd->list, "cmd->list");
  703     }
  704     }
  705 #endif
  706 
  707     /* certain things don't get echoed at all, if not recording or
  708        compiling a function or loop */
  709     if (!recording && !compiling && command_is_silent(cmd, line)) {
  710 #if ECHO_DEBUG
  711     fprintf(stderr, " silent: no echo\n");
  712 #endif
  713     return;
  714     }
  715 
  716     /* print leading string before echo? */
  717     if (recording) {
  718     if (cmd != NULL && cmd->ci == STORE) {
  719         commented_store = 1;
  720     }
  721     } else if (compiling) {
  722     leader = "> ";
  723     } else {
  724     leader = "? ";
  725     }
  726 
  727     if (commented_store) {
  728     pputs(prn, "# ");
  729     pputs(prn, line);
  730     } else if (cmd != NULL && (cmd->context == FOREIGN || cmd->context == MPI)) {
  731     if (leader != NULL) {
  732         pputs(prn, leader);
  733     }
  734     pputs(prn, line);
  735     } else {
  736     reflow_line(line, cmd, leader, prn);
  737     }
  738 
  739     pputc(prn, '\n');
  740 
  741     gretl_print_flush_stream(prn);
  742 }
  743 
  744 void gretl_echo_command (CMD *cmd, const char *line, PRN *prn)
  745 {
  746     real_echo_command(cmd, line, 0, prn);
  747 }
  748 
  749 void gretl_record_command (CMD *cmd, const char *line, PRN *prn)
  750 {
  751     real_echo_command(cmd, line, 1, prn);
  752 }
  753 
  754 static int set_var_info (const int *list,
  755              const char *parm1,
  756              const char *parm2,
  757              gretlopt opt,
  758              DATASET *dset)
  759 {
  760     int vi, v = list[1];
  761     int i, err = 0;
  762 
  763     if (dset == NULL || dset->varinfo == NULL) {
  764     return E_NODATA;
  765     } else if (v <= 0 || v >= dset->v) {
  766     return E_DATA;
  767     }
  768 
  769     if (opt & OPT_M) {
  770     err = gretl_list_set_midas(list, dset);
  771     if (err) {
  772         return err;
  773     }
  774     }
  775 
  776     for (i=1; i<=list[0]; i++) {
  777     vi = list[i];
  778     if (opt & OPT_D) {
  779         series_set_discrete(dset, vi, 1);
  780     } else if (opt & OPT_C) {
  781         series_set_discrete(dset, vi, 0);
  782     }
  783     if (opt & OPT_F) {
  784         /* --coded */
  785         int ivals = series_is_integer_valued(dset, vi);
  786         int isdum = gretl_isdummy(0, dset->n - 1, dset->Z[vi]);
  787 
  788         if (ivals && !isdum) {
  789         series_set_flag(dset, vi, VAR_CODED);
  790         } else {
  791         gretl_errmsg_sprintf("%s cannot be set as 'coded' (%s)",
  792                      dset->varname[vi], ivals ?
  793                      _("is a 0/1 variable") :
  794                      _("not integer-valued"));
  795         err = E_TYPES;
  796         }
  797     } else if (opt & OPT_N) {
  798         /* -- numeric (i.e. not-coded) */
  799         series_unset_flag(dset, vi, VAR_CODED);
  800     }
  801     }
  802 
  803     if (err) {
  804     return err;
  805     }
  806 
  807     /* below: we'll accept multi-series lists, but the
  808        string-setting facility will apply to just the
  809        first member, as "representative" of the list
  810     */
  811 
  812     if (opt & OPT_I) {
  813     const char *s = get_optval_string(SETINFO, OPT_I);
  814 
  815     if (s == NULL) {
  816         err = E_ARGS;
  817     } else {
  818         series_record_label(dset, v, s);
  819     }
  820     } else if (parm1 != NULL) {
  821     /* backward compatibility */
  822     series_record_label(dset, v, parm1);
  823     }
  824 
  825     if (opt & OPT_G) {
  826     const char *s = get_optval_string(SETINFO, OPT_G);
  827 
  828     if (s == NULL) {
  829         err = E_ARGS;
  830     } else {
  831         series_record_display_name(dset, v, s);
  832     }
  833     } else if (parm2 != NULL) {
  834     /* backward compatibility */
  835     series_record_display_name(dset, v, parm2);
  836     }
  837 
  838     return err;
  839 }
  840 
  841 static void reflow_label (const char *line, PRN *prn)
  842 {
  843     int maxline = 72;
  844 
  845     if (strlen(line) < maxline) {
  846     pputc(prn, ' ');
  847     pputs(prn, line);
  848     pputc(prn, '\n');
  849     } else {
  850     const char *p = line;
  851     char buf[TESTLEN];
  852     int lnum = 0;
  853 
  854     while (*p) {
  855         *buf = '\0';
  856         strncat(buf, p, TESTLEN - 1);
  857         if (lnum == 1) {
  858         maxline -= 2;
  859         }
  860         basic_trim_to_length(buf, maxline);
  861         p += strlen(buf);
  862         if (!string_is_blank(buf)) {
  863         if (lnum == 0) {
  864             pputc(prn, ' ');
  865         } else {
  866             pputs(prn, "   ");
  867         }
  868         pputs(prn, (*buf == ' ')? buf + 1 : buf);
  869         pputc(prn, '\n');
  870         } else {
  871         pputc(prn, '\n');
  872         }
  873         lnum++;
  874     }
  875     }
  876 }
  877 
  878 static void showlabels (const int *list, gretlopt opt,
  879             const DATASET *dset, PRN *prn)
  880 {
  881     const char *label;
  882     gchar *tmp;
  883     int i, v, vmax, nl = 0;
  884 
  885     if (dset == NULL || dset->v == 0) {
  886     pprintf(prn, _("No series are defined\n"));
  887     return;
  888     }
  889 
  890     vmax = list == NULL ? dset->v - 1 : list[0];
  891 
  892     for (i=1; i<=vmax; i++) {
  893     v = list == NULL ? i : list[i];
  894     if (v >= 0 && v < dset->v) {
  895         label = series_get_label(dset, v);
  896         if (label != NULL && *label != '\0') {
  897         nl++;
  898         }
  899     }
  900     }
  901 
  902     if (nl == 0) {
  903     pprintf(prn, _("No series labels are defined\n"));
  904     return;
  905     }
  906 
  907     pputc(prn, '\n');
  908     for (i=1; i<=vmax; i++) {
  909     v = list == NULL ? i : list[i];
  910     if (v >= 0 && v < dset->v) {
  911         label = series_get_label(dset, v);
  912         if (label != NULL && *label != '\0') {
  913         if (opt & OPT_Q) {
  914             pprintf(prn, "%s: %s\n", dset->varname[v], label);
  915         } else {
  916             tmp = g_strdup_printf("%s: %s", dset->varname[v], label);
  917             reflow_label(tmp, prn);
  918             g_free(tmp);
  919         }
  920         }
  921     }
  922     }
  923     pputc(prn, '\n');
  924 }
  925 
  926 static int outfile_redirect (PRN *prn, FILE *fp, const char *strvar,
  927                  gretlopt opt, int *parms)
  928 {
  929     int err;
  930 
  931     err = print_start_redirection(prn, fp, strvar);
  932     if (err) {
  933     return err;
  934     }
  935 
  936     if (opt & OPT_Q) {
  937     parms[0] = gretl_echo_on();
  938     parms[1] = gretl_messages_on();
  939     set_gretl_echo(0);
  940     set_gretl_messages(0);
  941     } else {
  942     parms[0] = parms[1] = -1;
  943     }
  944 
  945     return 0;
  946 }
  947 
  948 static void maybe_restore_vparms (int *parms)
  949 {
  950     if (parms[0] == 1) {
  951     set_gretl_echo(1);
  952     }
  953     if (parms[1] == 1) {
  954     set_gretl_messages(1);
  955     }
  956     parms[0] = parms[1] = -1;
  957 }
  958 
  959 static int cwd_is_workdir (void)
  960 {
  961     gchar *thisdir = g_get_current_dir();
  962     int ret = 0;
  963 
  964     if (thisdir != NULL) {
  965     int n = strlen(thisdir);
  966 
  967     ret = (strncmp(thisdir, gretl_workdir(), n) == 0);
  968     g_free(thisdir);
  969     }
  970 
  971     return ret;
  972 }
  973 
  974 static int redirection_ok (PRN *prn)
  975 {
  976     int fd = gretl_function_depth();
  977 
  978     if (fd == 0) {
  979     return 0;
  980     } else if (print_redirected_at_level(prn, fd)) {
  981     /* we may want to lift this ban in future? */
  982     return 0;
  983     } else {
  984     return 1;
  985     }
  986 }
  987 
  988 static int outname_check (const char *name, int backward,
  989               const DATASET *dset)
  990 {
  991     GretlType t = gretl_type_from_name(name, dset);
  992     int err = 0;
  993 
  994     if (t != GRETL_TYPE_NONE && t != GRETL_TYPE_STRING) {
  995     err = E_TYPES;
  996     } else if (t == GRETL_TYPE_NONE) {
  997     if (backward) {
  998         /* compatibility: create the variable if possible */
  999         err = check_identifier(name);
 1000         if (!err) {
 1001         err = create_user_var(name, GRETL_TYPE_STRING);
 1002         }
 1003     } else {
 1004         /* we now require that the variable already exists */
 1005         gretl_errmsg_sprintf(_("'%s' : not a string variable"), name);
 1006         err = E_DATA;
 1007     }
 1008     }
 1009 
 1010     return err;
 1011 }
 1012 
 1013 /* We come here in the --tempfile and --buffer cases of
 1014    "outfile". The @strvar argument, which names a string
 1015    variable, plays a different role in each case: with
 1016    --tempfile (OPT_T) the variable should get as its
 1017    value the _name_ of the temporary file, but with --buffer
 1018    (OPT_B) it should get the _content_ of that file when
 1019    redirection ends. We accomplish the former effect here,
 1020    but arrange for the latter effect by passing @strvar
 1021    to outfile_redirect().
 1022 */
 1023 
 1024 static int redirect_to_tempfile (const char *strvar, PRN *prn,
 1025                  gretlopt opt, int *vparms)
 1026 {
 1027     gchar *tempname = NULL;
 1028     FILE *fp = NULL;
 1029     int err = 0;
 1030 
 1031     tempname = gretl_make_dotpath("outfile.XXXXXX");
 1032     if (opt & OPT_B) {
 1033     fp = gretl_mktemp(tempname, "wb+");
 1034     } else {
 1035     fp = gretl_mktemp(tempname, "wb");
 1036     }
 1037 
 1038     if (fp == NULL) {
 1039     err = E_FOPEN;
 1040     } else if (opt & OPT_B) {
 1041     err = outfile_redirect(prn, fp, strvar, opt, vparms);
 1042     } else {
 1043     err = outfile_redirect(prn, fp, NULL, opt, vparms);
 1044     }
 1045     if (!err && (opt & OPT_T)) {
 1046     /* write the tempfile name into strvar */
 1047     user_string_reset(strvar, tempname, &err);
 1048     if (err) {
 1049         fclose(fp);
 1050     }
 1051     }
 1052 
 1053     g_free(tempname);
 1054 
 1055     return err;
 1056 }
 1057 
 1058 static const char *maybe_get_string_name (gretlopt opt)
 1059 {
 1060     if (opt & (OPT_B | OPT_T)) {
 1061     gretlopt active = (opt & OPT_T)? OPT_T : OPT_B;
 1062 
 1063     return get_optval_string(OUTFILE, active);
 1064     } else {
 1065     return NULL;
 1066     }
 1067 }
 1068 
 1069 static int
 1070 do_outfile_command (gretlopt opt, const char *fname,
 1071             const DATASET *dset, PRN *prn)
 1072 {
 1073     static char savename[MAXLEN];
 1074     static int vparms[2];
 1075     const char *strvar = NULL;
 1076     const char *check = NULL;
 1077     int rlevel = 0;
 1078     int err = 0;
 1079 
 1080     if (prn == NULL) {
 1081     return 0;
 1082     }
 1083 
 1084     /* make --write the default in the absence of a
 1085        contrary option (--append or --close)
 1086     */
 1087     if (!(opt & (OPT_A | OPT_C))) {
 1088     opt |= OPT_W;
 1089     }
 1090 
 1091     /* allow at most one of --append, --buffer, --tempfile, --close */
 1092     err = incompatible_options(opt, (OPT_A | OPT_B | OPT_T | OPT_C));
 1093     if (err) {
 1094     return err;
 1095     }
 1096 
 1097     rlevel = print_redirection_level(prn);
 1098 
 1099     if (opt & OPT_C) {
 1100     /* command to close outfile */
 1101     if (rlevel == 0) {
 1102         pputs(prn, _("Output is not currently diverted to file\n"));
 1103         err = 1;
 1104     } else {
 1105         print_end_redirection(prn);
 1106         maybe_restore_vparms(vparms);
 1107         if (gretl_messages_on() && *savename != '\0') {
 1108         pprintf(prn, _("Closed output file '%s'\n"), savename);
 1109         }
 1110     }
 1111     return err;
 1112     }
 1113 
 1114     /* pre-check: in the buffer or tempfile cases, did we
 1115        get a string-name attached to the option flag?
 1116     */
 1117     strvar = maybe_get_string_name(opt);
 1118     check = strvar != NULL ? strvar : fname;
 1119 
 1120     /* below: diverting output to a file or buffer: first
 1121        check that this is feasible */
 1122 
 1123     if (check == NULL || *check == '\0') {
 1124     return E_ARGS;
 1125     } else if (rlevel > 0 && !redirection_ok(prn)) {
 1126     gretl_errmsg_sprintf(_("Output is already diverted to '%s'"),
 1127                  savename);
 1128     return 1;
 1129     }
 1130 
 1131     /* Handle the cases where we're going via a temporary
 1132        file (and the @fname that was passed in is really the
 1133        name of a string variable).
 1134     */
 1135     if (opt & (OPT_B | OPT_T)) {
 1136     int backward = 0;
 1137 
 1138     if (strvar == NULL) {
 1139         /* backward compatibility */
 1140         strvar = fname;
 1141         backward = 1;
 1142     }
 1143     err = outname_check(strvar, backward, dset);
 1144     if (!err) {
 1145         err = redirect_to_tempfile(strvar, prn, opt, vparms);
 1146     }
 1147     *savename = '\0';
 1148     return err; /* we're done */
 1149     }
 1150 
 1151     /* Handle the remaining file-based cases */
 1152 
 1153     if (!strcmp(fname, "null")) {
 1154     if (gretl_messages_on()) {
 1155         pputs(prn, _("Now discarding output\n"));
 1156     }
 1157     err = outfile_redirect(prn, NULL, NULL, opt, vparms);
 1158     *savename = '\0';
 1159     } else if (!strcmp(fname, "stderr")) {
 1160     err = outfile_redirect(prn, stderr, NULL, opt, vparms);
 1161     *savename = '\0';
 1162     } else if (!strcmp(fname, "stdout")) {
 1163     err = outfile_redirect(prn, stdout, NULL, opt, vparms);
 1164     *savename = '\0';
 1165     } else {
 1166     /* should the stream be opened in binary mode on Windows? */
 1167     char outname[FILENAME_MAX];
 1168     const char *targ;
 1169     FILE *fp;
 1170 
 1171     /* switch to workdir if needed */
 1172     strcpy(outname, fname);
 1173     gretl_maybe_prepend_dir(outname);
 1174     if (opt & OPT_A) {
 1175         /* appending */
 1176         fp = gretl_fopen(outname, "a");
 1177     } else {
 1178         /* writing */
 1179         fp = gretl_fopen(outname, "w");
 1180     }
 1181 
 1182     if (fp == NULL) {
 1183         pprintf(prn, _("Couldn't open %s for writing\n"), outname);
 1184         return E_FOPEN;
 1185     }
 1186 
 1187     /* string to identify the output stream for display */
 1188     targ = cwd_is_workdir() ? fname : outname;
 1189 
 1190     if (gretl_messages_on()) {
 1191         /* print message before actual redirection! */
 1192         if (opt & OPT_A) {
 1193         pprintf(prn, _("Now appending output to '%s'\n"), targ);
 1194         } else {
 1195         pprintf(prn, _("Now writing output to '%s'\n"), targ);
 1196         }
 1197     }
 1198 
 1199     err = outfile_redirect(prn, fp, NULL, opt, vparms);
 1200     if (err) {
 1201         fclose(fp);
 1202         remove(outname);
 1203     } else {
 1204         strcpy(savename, targ);
 1205     }
 1206     }
 1207 
 1208     return err;
 1209 }
 1210 
 1211 int call_pca_plugin (VMatrix *cmat, DATASET *dset,
 1212              gretlopt opt, PRN *prn)
 1213 {
 1214     int (*pca_from_cmatrix) (VMatrix *, DATASET *,
 1215                  gretlopt, PRN *);
 1216 
 1217     gretl_error_clear();
 1218 
 1219     pca_from_cmatrix = get_plugin_function("pca_from_cmatrix");
 1220     if (pca_from_cmatrix == NULL) {
 1221         return 1;
 1222     }
 1223 
 1224     return (*pca_from_cmatrix) (cmat, dset, opt, prn);
 1225 }
 1226 
 1227 static int do_pca (int *list, DATASET *dset,
 1228            gretlopt opt, PRN *prn)
 1229 {
 1230     int freelist = 0;
 1231     int err = 0;
 1232 
 1233     if (list != NULL && list[0] == 0) {
 1234     return 0;
 1235     }
 1236 
 1237     if (list == NULL) {
 1238     list = full_var_list(dset, NULL);
 1239     freelist = 1;
 1240     }
 1241 
 1242     if (list != NULL) {
 1243     VMatrix *cmat = NULL;
 1244 
 1245     /* adding OPT_U ensures a uniform sample for the
 1246        correlation or covariance matrix */
 1247     cmat = corrlist(PCA, list, dset, opt, &err);
 1248     if (!err) {
 1249         err = call_pca_plugin(cmat, dset, opt, prn);
 1250         if (!err && (opt & (OPT_O | OPT_A))) {
 1251         /* results saved as series */
 1252         if (gretl_messages_on() && !gretl_looping_quietly()) {
 1253             pputs(prn, "Generated principal component series\n");
 1254         }
 1255         }
 1256         free_vmatrix(cmat);
 1257     }
 1258     if (freelist) {
 1259         free(list);
 1260     }
 1261     }
 1262 
 1263     return err;
 1264 }
 1265 
 1266 static void query_package (const char *pkgname,
 1267                gretlopt opt, PRN *prn)
 1268 {
 1269     char path[MAXLEN];
 1270     int err = 0;
 1271 
 1272     if (has_suffix(pkgname, ".gfn")) {
 1273     err = get_full_filename(pkgname, path, OPT_I);
 1274     } else {
 1275     gchar *gfn = g_strdup_printf("%s.gfn", pkgname);
 1276 
 1277     err = get_full_filename(gfn, path, OPT_I);
 1278     g_free(gfn);
 1279     }
 1280     if (opt & OPT_Q) {
 1281     gretl_bundle *b = gretl_bundle_new();
 1282 
 1283     if (b != NULL && err) {
 1284         gretl_bundle_set_int(b, "not_found", 1);
 1285         set_last_result_data(b, GRETL_TYPE_BUNDLE);
 1286     } else if (b != NULL) {
 1287         bundle_function_package_info(path, b);
 1288         set_last_result_data(b, GRETL_TYPE_BUNDLE);
 1289     }
 1290     } else {
 1291     if (err) {
 1292         pprintf(prn, "%s: not found\n\n", pkgname);
 1293     } else {
 1294         print_function_package_info(path, 0, prn);
 1295     }
 1296     }
 1297 }
 1298 
 1299 static int do_pkg_command (const char *action,
 1300                const char *pkgname,
 1301                gretlopt opt,
 1302                ExecState *s,
 1303                PRN *prn)
 1304 {
 1305     int err = 0;
 1306 
 1307     if (!strcmp(action, "install")) {
 1308     err = install_function_package(pkgname, opt, s, prn);
 1309     } else if (!strcmp(action, "unload")) {
 1310     err = uninstall_function_package(pkgname, OPT_NONE, prn);
 1311     } else if (!strcmp(action, "remove")) {
 1312     err = uninstall_function_package(pkgname, OPT_P, prn);
 1313     } else if (!strcmp(action, "query")) {
 1314     query_package(pkgname, opt, prn);
 1315     } else {
 1316     gretl_errmsg_sprintf("pkg: unknown action '%s'", action);
 1317     err = E_PARSE;
 1318     }
 1319 
 1320     return err;
 1321 }
 1322 
 1323 static void print_info (gretlopt opt, DATASET *dset, PRN *prn)
 1324 {
 1325     if (dset != NULL && dset->descrip != NULL) {
 1326     pprintf(prn, "%s\n", dset->descrip);
 1327     } else {
 1328     pputs(prn, _("No data information is available.\n"));
 1329     }
 1330 }
 1331 
 1332 /* After estimating a model, check its errcode member to see
 1333    if anything went wrong, and reset gretl_errno to zero.
 1334 
 1335    If we're looping (that is, if a loop is in progress at the
 1336    current level of function execution) and @loop_force is 0,
 1337    that's all, but if not then:
 1338 
 1339    (a) print the model (this may require special handling inside
 1340    loops);
 1341 
 1342    (b) if the user has employed the "name <- command" mechanism,
 1343    attach the supplied name to the model;
 1344 
 1345    (c) conditionally add the model to the stack in objstack.c,
 1346    and if this is done, signal the fact by setting the 'pmod'
 1347    member of @ExecState.
 1348 
 1349    (d) if we're called by the GUI program and the model has
 1350    been assigned a name, activate the callback that adds the
 1351    model to the GUI session.
 1352 */
 1353 
 1354 static int print_save_model (MODEL *pmod, DATASET *dset,
 1355                  gretlopt opt, int loop_force,
 1356                  PRN *prn, ExecState *s)
 1357 {
 1358     int err = pmod->errcode;
 1359 
 1360     if (!err) {
 1361     set_gretl_errno(0);
 1362     if (!gretl_looping_currently() || loop_force) {
 1363         int havename = *s->cmd->savename != '\0';
 1364         int window = (opt & OPT_W) != 0;
 1365         gretlopt popt;
 1366 
 1367         if (havename) {
 1368         gretl_model_set_name(pmod, s->cmd->savename);
 1369         }
 1370 
 1371         popt = get_printmodel_opt(pmod, opt);
 1372         printmodel(pmod, dset, popt, prn);
 1373         attach_subsample_to_model(pmod, dset);
 1374         s->pmod = maybe_stack_model(pmod, s->cmd, prn, &err);
 1375         if (!err && gretl_in_gui_mode() && s->callback != NULL &&
 1376         (havename || window)) {
 1377         if (s->pmod != NULL && (opt & OPT_Q) && !window) {
 1378             /* With OPT_Q (--quiet) and without the --window
 1379                flag, this model will not have a unique ID;
 1380                but that will be needed if it's going to be
 1381                a fully fledged gui model, as requested by
 1382                its having been given a "savename".
 1383             */
 1384             set_model_id(s->pmod, OPT_NONE);
 1385         }
 1386         s->callback(s, s->pmod, GRETL_OBJ_EQN);
 1387         }
 1388     }
 1389     }
 1390 
 1391     return err;
 1392 }
 1393 
 1394 static void save_var_vecm (ExecState *s)
 1395 {
 1396     maybe_stack_var(s->var, s->cmd);
 1397 
 1398     if (gretl_in_gui_mode() && s->callback != NULL) {
 1399     int havename = *s->cmd->savename != '\0';
 1400     int window = (s->cmd->opt & OPT_W) != 0;
 1401 
 1402     if (havename || window) {
 1403         s->callback(s, s->var, GRETL_OBJ_VAR);
 1404     }
 1405     }
 1406 }
 1407 
 1408 static void gui_save_system (ExecState *s)
 1409 {
 1410     /* note: with GRETL_OBJ_SYS, the business of calling
 1411        "maybe_stack" is handled within system.c, so here
 1412        all we have to do is invoke the GUI callback, if
 1413        appropriate
 1414     */
 1415     if (gretl_in_gui_mode() && s->callback != NULL &&
 1416     *s->cmd->savename != '\0') {
 1417     s->callback(s, s->sys, GRETL_OBJ_SYS);
 1418     }
 1419 }
 1420 
 1421 static int model_test_check (CMD *cmd, DATASET *dset, PRN *prn)
 1422 {
 1423     int err = last_model_test_ok(cmd->ci, cmd->opt, dset, prn);
 1424 
 1425     if (err == E_DATA && cmd->ci == RESTRICT && has_param(cmd)) {
 1426     /* try for a not-yet estimated anonymous system */
 1427     if (get_anonymous_equation_system() != NULL) {
 1428         gretl_error_clear();
 1429         err = 0;
 1430     }
 1431     }
 1432 
 1433     return err;
 1434 }
 1435 
 1436 static int get_line_continuation (char *line, FILE *fp, PRN *prn)
 1437 {
 1438     char tmp[MAXLINE];
 1439     int err = 0;
 1440 
 1441     if (!strncmp(line, "quit", 4)) {
 1442     return 0;
 1443     }
 1444 
 1445     while (top_n_tail(line, MAXLINE, &err)) {
 1446     if (err) {
 1447         break;
 1448     }
 1449     *tmp = '\0';
 1450     if (fgets(tmp, sizeof tmp, fp) && *tmp != '\0') {
 1451         if (strlen(line) + strlen(tmp) > MAXLINE - 1) {
 1452         pprintf(prn, _("Maximum length of command line "
 1453                    "(%d bytes) exceeded"), MAXLINE);
 1454         pputc(prn, '\n');
 1455         err = E_TOOLONG;
 1456         break;
 1457         } else {
 1458         strcat(line, tmp);
 1459         compress_spaces(line);
 1460         }
 1461     }
 1462     }
 1463 
 1464     return err;
 1465 }
 1466 
 1467 static int run_script (const char *fname, ExecState *s,
 1468                DATASET *dset, gretlopt opt,
 1469                PRN *prn)
 1470 {
 1471     int indent = gretl_if_state_record();
 1472     int echo = gretl_echo_on();
 1473     int messages = gretl_messages_on();
 1474     FILE *fp;
 1475     int iferr, err = 0;
 1476 
 1477     fp = gretl_fopen(fname, "r");
 1478     if (fp == NULL) {
 1479     gretl_errmsg_sprintf(_("Couldn't open %s"), fname);
 1480     return E_FOPEN;
 1481     }
 1482 
 1483     strcpy(s->runfile, fname);
 1484 
 1485     if (opt & OPT_Q) {
 1486     set_gretl_echo(0);
 1487     set_gretl_messages(0);
 1488     }
 1489 
 1490     if (gretl_echo_on()) {
 1491     pprintf(prn, "run \"%s\"\n", fname);
 1492     }
 1493 
 1494     while (fgets(s->line, MAXLINE - 1, fp) && !err) {
 1495     err = get_line_continuation(s->line, fp, prn);
 1496     if (!err) {
 1497         err = maybe_exec_line(s, dset, NULL);
 1498     }
 1499     }
 1500 
 1501     fclose(fp);
 1502 
 1503     if (opt & OPT_Q) {
 1504     set_gretl_echo(echo);
 1505     set_gretl_messages(messages);
 1506     }
 1507 
 1508     iferr = gretl_if_state_check(indent);
 1509     if (iferr && !err) {
 1510     err = iferr;
 1511     }
 1512 
 1513     return err;
 1514 }
 1515 
 1516 static int lib_clear_data (ExecState *s, DATASET *dset)
 1517 {
 1518     int err = 0;
 1519 
 1520     if (dset->Z != NULL) {
 1521     err = restore_full_sample(dset, NULL);
 1522     free_Z(dset);
 1523     }
 1524 
 1525     clear_model(s->model);
 1526     clear_datainfo(dset, CLEAR_FULL);
 1527     libgretl_session_cleanup(SESSION_CLEAR_DATASET);
 1528     set_model_count(0);
 1529     gretl_cmd_destroy_context(s->cmd);
 1530 
 1531     return err;
 1532 }
 1533 
 1534 static int join_aggregation_method (const char *s, int *seqval,
 1535                     char **auxname, int *err)
 1536 {
 1537     int ret = -1;
 1538 
 1539     if (!strncmp(s, "seq:", 4)) {
 1540     char *endptr;
 1541 
 1542     *seqval = (int) strtol(s + 4, &endptr, 10);
 1543     if (*endptr == '\0' && *seqval != 0) {
 1544         ret = AGGR_SEQ;
 1545     } else {
 1546         gretl_errmsg_sprintf(_("%s: invalid input '%s'\n"), "--seq", s + 4);
 1547         *err = E_DATA;
 1548     }
 1549     } else if (!strcmp(s, "count")) {
 1550     ret = AGGR_COUNT;
 1551     } else if (!strcmp(s, "avg")) {
 1552     ret = AGGR_AVG;
 1553     } else if (!strcmp(s, "sum")) {
 1554     ret = AGGR_SUM;
 1555     } else if (!strcmp(s, "min")) {
 1556     ret = AGGR_MIN;
 1557     } else if (!strcmp(s, "max")) {
 1558     ret = AGGR_MAX;
 1559     } else if (!strcmp(s, "none")) {
 1560     ret = AGGR_NONE;
 1561     } else if (!strcmp(s, "spread")) {
 1562     ret = AGGR_MIDAS;
 1563     } else if (!strncmp(s, "min(", 4) ||
 1564            !strncmp(s, "max(", 4)) {
 1565     const char *p = strchr(s + 4, ')');
 1566 
 1567     if (p != NULL && strlen(p) == 1) {
 1568         int len = p - (s + 4);
 1569 
 1570         if (len > 0) {
 1571         *auxname = gretl_strndup(s + 4, len);
 1572         if (*auxname == NULL) {
 1573             *err = E_ALLOC;
 1574         } else {
 1575             ret = (s[1] == 'a')? AGGR_MAX : AGGR_MIN;
 1576         }
 1577         }
 1578     } else {
 1579         *err = E_PARSE;
 1580     }
 1581     } else {
 1582     *err = E_PARSE;
 1583     }
 1584 
 1585     return ret;
 1586 }
 1587 
 1588 static int get_inner_key_id (const char *s, int n,
 1589                  const DATASET *dset,
 1590                  int *err)
 1591 {
 1592     char vname[VNAMELEN];
 1593     int id = -1;
 1594 
 1595     if (n == 0 || n >= VNAMELEN) {
 1596     *err = E_PARSE;
 1597     } else {
 1598     *vname = '\0';
 1599     strncat(vname, s, n);
 1600     if (gretl_namechar_spn(vname) != n) {
 1601         gretl_errmsg_sprintf(_("field '%s' in command is invalid"), vname);
 1602         *err = E_PARSE;
 1603     } else {
 1604         id = current_series_index(dset, vname);
 1605         if (id < 0) {
 1606         gretl_errmsg_sprintf("'%s': no such series", vname);
 1607         *err = E_UNKVAR;
 1608         }
 1609     }
 1610     }
 1611 
 1612     return id;
 1613 }
 1614 
 1615 static int *get_inner_keys (const char *s, DATASET *dset,
 1616                 int *err)
 1617 {
 1618     int *klist = NULL;
 1619     int ikey1 = -1, ikey2 = -1;
 1620     int nkeys = 0;
 1621 
 1622     if (strchr(s, ',') == NULL) {
 1623     /* just one key, fine */
 1624     ikey1 = current_series_index(dset, s);
 1625     if (ikey1 < 0) {
 1626         gretl_errmsg_sprintf("'%s': no such series", s);
 1627         *err = E_UNKVAR;
 1628     } else {
 1629         nkeys = 1;
 1630     }
 1631     } else {
 1632     /* we should have a double key */
 1633     int n = strcspn(s, ",");
 1634 
 1635     ikey1 = get_inner_key_id(s, n, dset, err);
 1636 
 1637     if (!*err) {
 1638         s += n + 1;
 1639         n = strlen(s);
 1640         ikey2 = get_inner_key_id(s, n, dset, err);
 1641     }
 1642 
 1643     if (!*err) {
 1644         nkeys = 2;
 1645     }
 1646     }
 1647 
 1648     if (!*err) {
 1649     klist = gretl_list_new(nkeys);
 1650     if (klist == NULL) {
 1651         *err = E_ALLOC;
 1652     } else {
 1653         klist[1] = ikey1;
 1654         if (nkeys == 2) {
 1655         klist[2] = ikey2;
 1656         }
 1657     }
 1658     }
 1659 
 1660     return klist;
 1661 }
 1662 
 1663 static int check_join_import_names (char **S, int ns,
 1664                     DATASET *dset)
 1665 {
 1666     int i, err = 0;
 1667 
 1668     for (i=0; i<ns && !err; i++) {
 1669     if (S[i] == NULL || S[i][0] == '\0') {
 1670         err = E_DATA;
 1671     } else if (strchr(S[i], '*') || strchr(S[i], '?')) {
 1672         ; /* wildcards: may be OK? */
 1673     } else if (current_series_index(dset, S[i]) < 0) {
 1674         err = check_varname(S[i]);
 1675         if (!err && gretl_type_from_name(S[i], NULL)) {
 1676         err = E_TYPES;
 1677         }
 1678     }
 1679     }
 1680 
 1681     return err;
 1682 }
 1683 
 1684 static char **names_from_array_arg (gretl_array *A,
 1685                     int *ns,
 1686                     int *err)
 1687 {
 1688     char **S = NULL;
 1689 
 1690     if (gretl_array_get_type(A) != GRETL_TYPE_STRINGS) {
 1691     *err = E_TYPES;
 1692     } else {
 1693     S = gretl_array_get_strings(A, ns);
 1694     if (S == NULL) {
 1695         *err = E_DATA;
 1696     }
 1697     }
 1698 
 1699     return S;
 1700 }
 1701 
 1702 static char **strings_array_singleton (const char *s,
 1703                        int *err)
 1704 {
 1705     int len = strlen(s) + 1;
 1706     char **S = strings_array_new_with_length(1, len);
 1707 
 1708     if (S == NULL) {
 1709     *err = E_ALLOC;
 1710     } else {
 1711     strcat(S[0], s);
 1712     }
 1713 
 1714     return S;
 1715 }
 1716 
 1717 static int get_join_import_names (const char *s,
 1718                   DATASET *dset,
 1719                   char ***pvnames,
 1720                   int *pnvars)
 1721 {
 1722     char **S = NULL;
 1723     gretl_array *A = NULL;
 1724     int ns = 0;
 1725     int err = 0;
 1726 
 1727     if (s == NULL) {
 1728     return E_PARSE;
 1729     }
 1730 
 1731     if (strchr(s, ' ') != NULL) {
 1732     /* @s should hold two or more names */
 1733     S = gretl_string_split(s, &ns, NULL);
 1734     if (S == NULL) {
 1735         err = E_DATA;
 1736     }
 1737     } else if ((A = get_array_by_name(s)) != NULL) {
 1738     /* @s should be the name of an array of strings */
 1739     S = names_from_array_arg(A, &ns, &err);
 1740     } else {
 1741     /* @s should be a legit series name */
 1742     S = strings_array_singleton(s, &err);
 1743     ns = 1;
 1744     }
 1745 
 1746     if (S != NULL) {
 1747     err = check_join_import_names(S, ns, dset);
 1748     }
 1749 
 1750     if (!err) {
 1751     if (A != NULL) {
 1752         /* copy strings "borrowed" from array */
 1753         *pvnames = strings_array_dup(S, ns);
 1754         if (*pvnames == NULL) {
 1755         err = E_ALLOC;
 1756         }
 1757     } else {
 1758         /* grab strings allocated here */
 1759         *pvnames = S;
 1760     }
 1761     *pnvars = ns;
 1762     }
 1763 
 1764     return err;
 1765 }
 1766 
 1767 static int lib_join_data (ExecState *s,
 1768               char *newfile,
 1769               DATASET *dset,
 1770               gretlopt opt,
 1771               PRN *prn)
 1772 {
 1773     gretlopt opts[] = {
 1774     OPT_I, /* ikey: inner key(s) */
 1775     OPT_O, /* okey: outer key(s) */
 1776     OPT_F, /* filter: filter expression */
 1777     OPT_A, /* aggr: aggregation method */
 1778     OPT_D, /* data: "payload" spec */
 1779     OPT_K, /* tkey: outer time-key name,format */
 1780     OPT_X, /* tconvert: date columns for conversion */
 1781     OPT_T, /* tconv-fmt: format for "tconvert" */
 1782     OPT_P, /* pd: outer data frequency */
 1783     0
 1784     };
 1785     char *okey = NULL, *filter = NULL;
 1786     const char *param;
 1787     char **vnames = NULL;
 1788     char *dataname = NULL;
 1789     char *auxname = NULL;
 1790     char *tconvstr = NULL;
 1791     char *tconvfmt = NULL;
 1792     int *ikeyvars = NULL;
 1793     int aggr = 0, seqval = 0;
 1794     int midas_pd = 0;
 1795     int tseries = 0;
 1796     int nvars = 1;
 1797     int i, err = 0;
 1798 
 1799     if (opt & OPT_K) {
 1800     /* --tkey implies special handling of keys */
 1801     if (opt & (OPT_I | OPT_O)) {
 1802         return E_BADOPT;
 1803     } else if (!dataset_is_time_series(dset)) {
 1804         return E_PDWRONG;
 1805     }
 1806     }
 1807 
 1808     tseries = dataset_is_time_series(dset);
 1809     param = s->cmd->parm2;
 1810 
 1811     err = get_join_import_names(param, dset, &vnames, &nvars);
 1812 
 1813     if (!err && nvars > 1) {
 1814     /* multiple series: we can't handle the --data option */
 1815     if (opt & OPT_D) {
 1816         err = E_BADOPT;
 1817     }
 1818     }
 1819 
 1820     for (i=0; opts[i] && !err; i++) {
 1821     gretlopt jopt = opts[i];
 1822     const char *param;
 1823 
 1824     if (opt & jopt) {
 1825         param = get_optval_string(JOIN, jopt);
 1826         if (param == NULL) {
 1827         gretl_errmsg_set("Missing option parameter");
 1828         err = E_DATA;
 1829         } else if (jopt == OPT_I) {
 1830         /* --ikey: the inner key(s) string */
 1831         ikeyvars = get_inner_keys(param, dset, &err);
 1832         } else if (jopt == OPT_O) {
 1833         /* --okey: the outer key(s) string */
 1834         okey = gretl_strdup(param);
 1835         } else if (jopt == OPT_F) {
 1836         /* --filter: string specifying a row filter */
 1837         filter = gretl_strdup(param);
 1838         } else if (jopt == OPT_A) {
 1839         /* --aggr: aggregation */
 1840         aggr = join_aggregation_method(param, &seqval,
 1841                            &auxname, &err);
 1842         } else if (jopt == OPT_D) {
 1843         /* --data: string specifying the outer data series */
 1844         dataname = gretl_strdup(param);
 1845         } else if (jopt == OPT_K) {
 1846         /* --tkey: string specifying outer time key */
 1847         okey = gretl_strdup(param);
 1848         } else if (jopt == OPT_X) {
 1849         /* --tconvert: list of time/date cols */
 1850         tconvstr = gretl_strdup(param);
 1851         } else if (jopt == OPT_T) {
 1852         /* --tconv-fmt: format for tconvert columns */
 1853         tconvfmt = gretl_strdup(param);
 1854         } else if (jopt == OPT_P) {
 1855         midas_pd = atoi(param);
 1856         }
 1857     }
 1858     }
 1859 
 1860     if (!err && okey != NULL && ikeyvars == NULL && !(opt & OPT_K)) {
 1861     /* We can't have an outer key but no inner one, unless
 1862        we're matching by the time-series structure of the
 1863        left-hand dataset (implied by OPT_K)
 1864     */
 1865     gretl_errmsg_set(_("Inner key is missing"));
 1866     err = E_PARSE;
 1867     }
 1868 
 1869     if (!err && aggr != 0 && ikeyvars == NULL && !tseries) {
 1870     /* aggregation requires ikeyvars, unless there's
 1871        an implicit time-series inner key
 1872     */
 1873     gretl_errmsg_set(_("Inner key is missing"));
 1874     err = E_ARGS;
 1875     }
 1876 
 1877     if (!err) {
 1878     err = gretl_join_data(newfile,
 1879                   (const char **) vnames,
 1880                   nvars, dset,
 1881                   ikeyvars, okey, filter,
 1882                   dataname, aggr, seqval,
 1883                   auxname, tconvstr,
 1884                   tconvfmt, midas_pd,
 1885                   opt, prn);
 1886     }
 1887 
 1888     strings_array_free(vnames, nvars);
 1889     free(ikeyvars);
 1890     free(okey);
 1891     free(filter);
 1892     free(dataname);
 1893     free(auxname);
 1894     free(tconvstr);
 1895     free(tconvfmt);
 1896 
 1897     return err;
 1898 }
 1899 
 1900 static int is_http (const char *s)
 1901 {
 1902     return (strncmp(s, "http://", 7) == 0 ||
 1903         strncmp(s, "https://", 8) == 0);
 1904 }
 1905 
 1906 static int lib_open_append (ExecState *s,
 1907                 DATASET *dset,
 1908                 char *newfile,
 1909                 PRN *prn)
 1910 {
 1911     CMD *cmd = s->cmd;
 1912     gretlopt opt = cmd->opt;
 1913     PRN *vprn = prn;
 1914     int quiet = (opt & OPT_Q);
 1915     int http = 0;
 1916     int dbdata = 0;
 1917     int ftype = -1;
 1918     int no_dset;
 1919     int err = 0;
 1920 
 1921     no_dset = (dset == NULL || dset->v == 0);
 1922 
 1923     if (cmd->ci == JOIN && no_dset) {
 1924     /* "join" is not applicable in the absence of
 1925        a dataset */
 1926     return E_NODATA;
 1927     }
 1928 
 1929     /* initial detection of some variants */
 1930 
 1931     if (opt & OPT_W) {
 1932     /* --www: remote databases only, no other options
 1933        applicable */
 1934     if (opt != OPT_W) {
 1935         return E_BADOPT;
 1936     }
 1937     ftype = GRETL_NATIVE_DB_WWW;
 1938     dbdata = 1;
 1939     *newfile = '\0';
 1940     strncat(newfile, cmd->param, MAXLEN - 1);
 1941     } else if (cmd->ci != JOIN && (opt & OPT_O)) {
 1942     ftype = GRETL_ODBC;
 1943     dbdata = 1;
 1944     } else if (!strcmp(cmd->param, "dbnomics")) {
 1945     ftype = GRETL_DBNOMICS;
 1946     dbdata = 1;
 1947     } else if (is_http(cmd->param)) {
 1948     http = 1;
 1949     }
 1950 
 1951     if (dbdata) {
 1952     goto next_step;
 1953     }
 1954 
 1955     if (http) {
 1956     err = try_http(cmd->param, newfile, NULL);
 1957     } else {
 1958     err = get_full_filename(cmd->param, newfile, OPT_NONE);
 1959     }
 1960 
 1961     if (err) {
 1962     errmsg(err, prn);
 1963     return err;
 1964     }
 1965 
 1966     if (ftype < 0) {
 1967     ftype = detect_filetype(newfile, OPT_P);
 1968     }
 1969 
 1970     if (cmd->ci == JOIN) {
 1971     if (ftype == GRETL_CSV || ftype == GRETL_XML_DATA ||
 1972         ftype == GRETL_BINARY_DATA) {
 1973         dset->modflag = 0;
 1974         if (ftype != GRETL_CSV) {
 1975         opt |= OPT_G;
 1976         }
 1977         err = lib_join_data(s, newfile, dset, opt, prn);
 1978     } else {
 1979         gretl_errmsg_set("join: only CSV and gdt[b] files are supported");
 1980         err = E_DATA;
 1981     }
 1982     if (err) {
 1983         errmsg(err, prn);
 1984     }
 1985     return err; /* note: "join" handled */
 1986     }
 1987 
 1988     if (!dbdata) {
 1989     dbdata = (ftype == GRETL_NATIVE_DB ||
 1990           ftype == GRETL_RATS_DB ||
 1991           ftype == GRETL_PCGIVE_DB);
 1992     }
 1993 
 1994     if (cmd->ci == OPEN && !dbdata && gretl_function_depth() > 0) {
 1995     gretl_errmsg_sprintf(_("The \"%s\" command cannot be used in this context"),
 1996                  gretl_command_word(cmd->ci));
 1997     return E_DATA;
 1998     }
 1999 
 2000     if (cmd->ci == OPEN && !dbdata) {
 2001     lib_clear_data(s, dset);
 2002     }
 2003 
 2004  next_step:
 2005 
 2006     if (quiet) {
 2007     /* in case we hit any problems below... */
 2008     vprn = gretl_print_new(GRETL_PRINT_BUFFER, NULL);
 2009     }
 2010 
 2011     if (ftype == GRETL_CSV) {
 2012     err = import_csv(newfile, dset, opt, vprn);
 2013     } else if (SPREADSHEET_IMPORT(ftype)) {
 2014     err = import_spreadsheet(newfile, ftype, cmd->list, cmd->parm2,
 2015                  dset, opt, vprn);
 2016     } else if (OTHER_IMPORT(ftype)) {
 2017     err = import_other(newfile, ftype, dset, opt, vprn);
 2018     } else if (ftype == GRETL_XML_DATA || ftype == GRETL_BINARY_DATA) {
 2019     err = gretl_read_gdt(newfile, dset, opt, vprn);
 2020     } else if (ftype == GRETL_ODBC) {
 2021     err = set_odbc_dsn(cmd->param, vprn);
 2022     } else if (dbdata) {
 2023     err = set_db_name(newfile, ftype, vprn);
 2024     } else {
 2025     err = gretl_get_data(newfile, dset, opt, vprn);
 2026     }
 2027 
 2028     if (vprn != prn) {
 2029     if (err) {
 2030         /* The user asked for --quiet operation, but something
 2031            went wrong so let's print any info we got on
 2032            vprn.
 2033         */
 2034         const char *buf = gretl_print_get_buffer(vprn);
 2035 
 2036         if (buf != NULL && *buf != '\0') {
 2037         pputs(prn, buf);
 2038         }
 2039     } else if (ftype != GRETL_NATIVE_DB_WWW && ftype != GRETL_ODBC) {
 2040         /* print minimal success message */
 2041         pprintf(prn, _("Read datafile %s\n"), newfile);
 2042     }
 2043     gretl_print_destroy(vprn);
 2044     }
 2045 
 2046     if (err) {
 2047     errmsg(err, prn);
 2048     return err;
 2049     }
 2050 
 2051     if (dset->v > 0 && !dbdata && !quiet) {
 2052     list_series(dset, OPT_NONE, prn);
 2053     }
 2054 
 2055     if (http) {
 2056     remove(newfile);
 2057     }
 2058 
 2059     if (dbdata || http || cmd->ci == JOIN) {
 2060     /* signal to the gretlcli callback that we didn't do
 2061        a regular datafile open
 2062     */
 2063     *newfile = '\0';
 2064     }
 2065 
 2066     return err;
 2067 }
 2068 
 2069 static int check_clear_data (void)
 2070 {
 2071     if (gretl_function_depth() > 0) {
 2072     gretl_errmsg_sprintf(_("The \"%s\" command cannot be used in this context"),
 2073                  gretl_command_word(CLEAR));
 2074     return E_DATA;
 2075     }
 2076 
 2077     return 0;
 2078 }
 2079 
 2080 static EXEC_CALLBACK gui_callback;
 2081 
 2082 static void schedule_callback (ExecState *s)
 2083 {
 2084     if (s->callback != NULL) {
 2085     s->flags |= CALLBACK_EXEC;
 2086     }
 2087 }
 2088 
 2089 static int callback_scheduled (ExecState *s)
 2090 {
 2091     return (s->flags & CALLBACK_EXEC) ? 1 : 0;
 2092 }
 2093 
 2094 static void callback_exec (ExecState *s, char *fname, int err)
 2095 {
 2096     if (!err && s->callback != NULL) {
 2097     if (s->cmd->ci == OPEN) {
 2098         s->callback(s, fname, 0);
 2099     } else {
 2100         s->callback(s, NULL, 0);
 2101     }
 2102     }
 2103 
 2104     s->flags &= ~CALLBACK_EXEC;
 2105     *s->cmd->savename = '\0';
 2106 }
 2107 
 2108 /* for use in contexts where we don't have an
 2109    ExecState (or CMD) to hand
 2110 */
 2111 
 2112 void manufacture_gui_callback (int ci)
 2113 {
 2114     if (gui_callback != NULL) {
 2115     ExecState s = {0};
 2116     CMD cmd = {0};
 2117 
 2118     cmd.ci = ci;
 2119     if (ci == FLUSH) {
 2120         cmd.opt = OPT_Q;
 2121     }
 2122     s.cmd = &cmd;
 2123     gui_callback(&s, NULL, 0);
 2124     }
 2125 }
 2126 
 2127 /* whether we're in gui or cli mode, try to ensure
 2128    that printed output gets displayed
 2129 */
 2130 
 2131 void gretl_flush (PRN *prn)
 2132 {
 2133     if (gui_callback != NULL) {
 2134     ExecState s = {0};
 2135     CMD cmd = {0};
 2136 
 2137     cmd.ci = FLUSH;
 2138     cmd.opt = OPT_Q;
 2139     s.cmd = &cmd;
 2140     gui_callback(&s, NULL, 0);
 2141     } else {
 2142     gretl_print_flush_stream(prn);
 2143     }
 2144 }
 2145 
 2146 static int do_end_restrict (ExecState *s, DATASET *dset)
 2147 {
 2148     GretlObjType otype = gretl_restriction_get_type(s->rset);
 2149     gretlopt ropt = gretl_restriction_get_options(s->rset);
 2150     gretlopt opt = s->cmd->opt | ropt;
 2151     int err = 0;
 2152 
 2153     if (opt & OPT_F) {
 2154     /* restrict --full */
 2155     if (otype == GRETL_OBJ_VAR) {
 2156         s->var = gretl_restricted_vecm(s->rset, dset,
 2157                        opt, s->prn, &err);
 2158         if (!err && s->var != NULL) {
 2159         save_var_vecm(s);
 2160         }
 2161     } else if (otype == GRETL_OBJ_EQN) {
 2162         err = gretl_restriction_finalize_full(s, s->rset, dset,
 2163                           opt, s->prn);
 2164         if (!err) {
 2165         gretlopt printopt = OPT_NONE;
 2166 
 2167         if (opt & (OPT_Q | OPT_S)) {
 2168             printopt = OPT_Q;
 2169         }
 2170         print_save_model(s->pmod, dset, printopt, 1,
 2171                  s->prn, s);
 2172         }
 2173     }
 2174     } else {
 2175     err = gretl_restriction_finalize(s->rset, dset,
 2176                      opt, s->prn);
 2177     }
 2178 
 2179     s->rset = NULL;
 2180 
 2181     return err;
 2182 }
 2183 
 2184 static int do_debug_command (ExecState *state, const char *param,
 2185                  gretlopt opt)
 2186 {
 2187     int err = incompatible_options(opt, OPT_C | OPT_N | OPT_Q);
 2188 
 2189     if (err) {
 2190     return err;
 2191     }
 2192 
 2193     if (opt & (OPT_C | OPT_N)) {
 2194     /* continue, next */
 2195     if (!(state->flags & DEBUG_EXEC)) {
 2196         gretl_errmsg_set("Debugging is not in progress");
 2197         return E_DATA;
 2198     } else {
 2199         /* handled in debug_command_loop */
 2200         return 0;
 2201     }
 2202     } else {
 2203     /* OPT_Q quits debugging of the given function */
 2204     return user_function_set_debug(param, !(opt & OPT_Q));
 2205     }
 2206 }
 2207 
 2208 /* Given the name of a discrete variable, perform a command for each
 2209    value of the discrete variable. Note that at present the only
 2210    command supported in this way is SUMMARY.
 2211 */
 2212 
 2213 static int do_command_by (CMD *cmd, DATASET *dset, PRN *prn)
 2214 {
 2215     const char *byname = get_optval_string(cmd->ci, OPT_B);
 2216     int byvar;
 2217     series_table *st = NULL;
 2218     gretl_matrix *xvals = NULL;
 2219     const double *x;
 2220     int *list = cmd->list;
 2221     int i, nvals = 0;
 2222     int single, err = 0;
 2223 
 2224     if (dset == NULL || byname == NULL) {
 2225     return E_DATA;
 2226     }
 2227 
 2228     /* FIXME accept "unit" and "time"/"period" in place of actual
 2229        variables for panel data? */
 2230 
 2231     byvar = current_series_index(dset, byname);
 2232     if (byvar < 0) {
 2233     return E_UNKVAR;
 2234     }
 2235 
 2236     x = (const double *) dset->Z[byvar];
 2237 
 2238     if (!series_is_discrete(dset, byvar) && !gretl_isdiscrete(dset->t1, dset->t2, x)) {
 2239     gretl_errmsg_sprintf(_("The variable '%s' is not discrete"), byname);
 2240     return E_DATA;
 2241     }
 2242 
 2243     if (list == NULL) {
 2244     /* compose full series list, but exclude the "by" variable */
 2245     int pos;
 2246 
 2247     list = full_var_list(dset, NULL);
 2248     if (list == NULL) {
 2249         return E_ALLOC;
 2250     }
 2251     pos = in_gretl_list(list, byvar);
 2252     if (pos > 0) {
 2253         gretl_list_delete_at_pos(list, pos);
 2254     }
 2255     if (list[0] == 0) {
 2256         free(list);
 2257         return E_DATA;
 2258     }
 2259     }
 2260 
 2261     single = (list[0] == 1);
 2262 
 2263     xvals = gretl_matrix_values(x + dset->t1, dset->t2 - dset->t1 + 1,
 2264                 OPT_S, &err);
 2265 
 2266     if (!err) {
 2267     nvals = gretl_vector_get_length(xvals);
 2268     if (nvals == 0) {
 2269         err = E_DATA;
 2270     } else {
 2271         st = series_get_string_table(dset, byvar);
 2272     }
 2273     }
 2274 
 2275     if (!err && single) {
 2276     pputc(prn, '\n');
 2277     pprintf(prn, _("Summary statistics for %s, by value of %s"),
 2278         dset->varname[list[1]], byname);
 2279     pputc(prn, '\n');
 2280     }
 2281 
 2282     for (i=0; i<nvals && !err; i++) {
 2283     Summary *summ = NULL;
 2284     char genline[64];
 2285     double xi = gretl_vector_get(xvals, i);
 2286     double *rv = NULL;
 2287 
 2288     gretl_push_c_numeric_locale();
 2289     sprintf(genline, "%s == %g", byname, xi);
 2290     gretl_pop_c_numeric_locale();
 2291     rv = generate_series(genline, dset, prn, &err);
 2292 
 2293     if (!err) {
 2294         summ = get_summary_restricted(list, dset, rv,
 2295                       cmd->opt, prn, &err);
 2296     }
 2297 
 2298     if (!err) {
 2299         if (i == 0) {
 2300         pputc(prn, '\n');
 2301         }
 2302         if (single) {
 2303         bufspace(2, prn);
 2304         }
 2305         if (st != NULL) {
 2306         const char *s = series_table_get_string(st, xi);
 2307 
 2308         pprintf(prn, "%s = %s (n = %d):\n", byname, s, summ->n);
 2309         } else {
 2310         pprintf(prn, "%s = %g (n = %d):\n", byname, xi, summ->n);
 2311         }
 2312         print_summary(summ, dset, prn);
 2313         free_summary(summ);
 2314     }
 2315 
 2316     free(rv);
 2317     }
 2318 
 2319     gretl_matrix_free(xvals);
 2320     if (list != cmd->list) {
 2321     free(list);
 2322     }
 2323 
 2324     return err;
 2325 }
 2326 
 2327 static void exec_state_prep (ExecState *s)
 2328 {
 2329     s->flags &= ~CALLBACK_EXEC;
 2330     s->pmod = NULL;
 2331 }
 2332 
 2333 int gretl_delete_variables (int *list,
 2334                 const char *param,
 2335                 gretlopt opt,
 2336                 DATASET *dset,
 2337                 int *renumber,
 2338                 PRN *prn)
 2339 {
 2340     int err;
 2341 
 2342     err = incompatible_options(opt, OPT_T | OPT_D | OPT_F);
 2343 
 2344     if (!err) {
 2345     if (opt & OPT_T) {
 2346         /* delete all vars of given type */
 2347         if (list != NULL || param != NULL) {
 2348         err = E_BADOPT;
 2349         }
 2350     } else if (opt & OPT_D) {
 2351         /* delete named vars from database */
 2352         if (list != NULL || param == NULL) {
 2353         err = E_BADOPT;
 2354         }
 2355     }
 2356     }
 2357 
 2358     if (err) {
 2359     return err;
 2360     }
 2361 
 2362     if (opt & OPT_T) {
 2363     const char *s = get_optval_string(DELEET, OPT_T);
 2364 
 2365     if (s == NULL) {
 2366         err = E_ARGS;
 2367     } else {
 2368         GretlType type = gretl_type_from_string(s);
 2369 
 2370         err = delete_user_vars_of_type(type, prn);
 2371     }
 2372     } else if (opt & OPT_D) {
 2373     err = db_delete_series_by_name(param, prn);
 2374     } else if (param != NULL) {
 2375     err = gretl_delete_var_by_name(param, prn);
 2376     } else if (list != NULL) {
 2377     /* delete listed series from dataset */
 2378     if (renumber == NULL && !(opt & OPT_F)) {
 2379         /* lacking the --force option */
 2380         pputs(prn, _("You cannot delete series in this context\n"));
 2381         err = E_DATA;
 2382     } else {
 2383         err = dataset_drop_listed_variables(list, dset,
 2384                         renumber, prn);
 2385     }
 2386     } else {
 2387     err = E_DATA;
 2388     }
 2389 
 2390     return err;
 2391 }
 2392 
 2393 /* OMIT and ADD: if we're estimating a revised model, should
 2394    we be saving it as the "last model", or are we just treating
 2395    the command as a stand-alone test?
 2396 */
 2397 
 2398 static int add_omit_save (CMD *cmd, MODEL *pmod)
 2399 {
 2400     int ret = 1;
 2401 
 2402     if (cmd->ci == ADD) {
 2403     if (cmd->opt & OPT_L) {
 2404         /* not saving if given the --lm option */
 2405         ret = 0;
 2406     }
 2407     } else if (cmd->ci == OMIT) {
 2408     if (cmd->opt & OPT_W) {
 2409         /* not saving under the --test-only (Wald) option */
 2410         ret = 0;
 2411     } else if (!(cmd->opt & OPT_A)) {
 2412         /* not in --auto mode */
 2413         if (cmd->list != NULL && pmod->list != NULL &&
 2414         cmd->list[0] == pmod->list[0] - 1) {
 2415         /* omitting everything, can't save */
 2416         ret = 0;
 2417         }
 2418     }
 2419     }
 2420 
 2421     return ret;
 2422 }
 2423 
 2424 static int VAR_omit_driver (CMD *cmd, DATASET *dset, PRN *prn)
 2425 {
 2426     GRETL_VAR *var = get_last_model(NULL);
 2427     int err = 0;
 2428 
 2429     if (cmd->opt & OPT_W) {
 2430     /* Wald test using VCV */
 2431     err = gretl_VAR_wald_omit_test(var, cmd->list, dset,
 2432                        cmd->opt, prn);
 2433     } else {
 2434     /* the full deal: estimate reduced system */
 2435     GRETL_VAR *vnew;
 2436 
 2437     vnew = gretl_VAR_omit_test(var, cmd->list, dset, cmd->opt,
 2438                    prn, &err);
 2439     if (!err) {
 2440         err = maybe_stack_var(vnew, cmd);
 2441     }
 2442     }
 2443 
 2444     return err;
 2445 }
 2446 
 2447 static int model_print_driver (MODEL *pmod, DATASET *dset,
 2448                    int ci, const char *param,
 2449                    gretlopt opt, PRN *prn)
 2450 {
 2451     int err = incompatible_options(opt, OPT_R | OPT_C);
 2452 
 2453     if (!err) {
 2454     char fname[FILENAME_MAX];
 2455 
 2456     *fname = '\0';
 2457 
 2458     if (param != NULL) {
 2459         /* the legacy mechanism */
 2460         strcpy(fname, param);
 2461     } else if (opt & OPT_U) {
 2462         /* try for --output=filename, and if found let
 2463            the suffix determine the output type
 2464         */
 2465         const char *s = get_optval_string(ci, OPT_U);
 2466 
 2467         if (s != NULL && *s != '\0') {
 2468         strcpy(fname, s);
 2469         if (has_suffix(fname, ".rtf")) {
 2470             opt |= OPT_R;
 2471         } else if (has_suffix(fname, ".csv")) {
 2472             opt |= OPT_C;
 2473         }
 2474         }
 2475     }
 2476 
 2477     if (*fname == '\0') {
 2478         /* fallback */
 2479         const char *sfx = (opt & OPT_R)? "rtf" :
 2480         (opt & OPT_C)? "csv" : "tex";
 2481 
 2482         if (pmod->ID > 0) {
 2483         sprintf(fname, "model_%d.%s", pmod->ID, sfx);
 2484         } else {
 2485         /* FIXME: this needs to be checked! */
 2486         sprintf(fname, "model_%" G_GINT64_FORMAT ".%s",
 2487             pmod->esttime, sfx);
 2488         }
 2489     }
 2490 
 2491     if (opt & OPT_R) {
 2492         err = rtfprint(pmod, dset, fname, opt);
 2493     } else if (opt & OPT_C) {
 2494         err = csvprint(pmod, dset, fname, opt);
 2495     } else {
 2496         gretlopt texopt = opt;
 2497 
 2498         if (ci == EQNPRINT) {
 2499         texopt |= OPT_E;
 2500         }
 2501         err = texprint(pmod, dset, fname, texopt);
 2502     }
 2503     if (!err) {
 2504         pprintf(prn, _("Model printed to %s\n"), fname);
 2505     }
 2506     }
 2507 
 2508     return err;
 2509 }
 2510 
 2511 #if USE_CURL
 2512 
 2513 static int package_check_dependencies (const char *fname,
 2514                        ExecState *s,
 2515                        PRN *prn)
 2516 {
 2517     char **depends;
 2518     int ndeps;
 2519     int err = 0;
 2520 
 2521     if (has_suffix(fname, ".zip")) {
 2522     /* we need to map from @fname to the gfn name */
 2523     gchar *tmp, *gfnname;
 2524     const char *p;
 2525 
 2526     tmp = g_strndup(fname, strlen(fname) - 4);
 2527     p = path_last_element(tmp);
 2528     gfnname = g_strdup_printf("%s%c%s.gfn", tmp, SLASH, p);
 2529     depends = package_peek_dependencies(gfnname, &ndeps);
 2530     g_free(tmp);
 2531     g_free(gfnname);
 2532     } else {
 2533     depends = package_peek_dependencies(fname, &ndeps);
 2534     }
 2535 
 2536     if (depends != NULL) {
 2537     char *pkgpath;
 2538     int i;
 2539 
 2540     for (i=0; i<ndeps && !err; i++) {
 2541         pkgpath = gretl_function_package_get_path(depends[i], PKG_ALL);
 2542         if (pkgpath == NULL) {
 2543         err = install_function_package(depends[i], OPT_D, s, prn);
 2544         }
 2545         free(pkgpath);
 2546     }
 2547     strings_array_free(depends, ndeps);
 2548     }
 2549 
 2550     return err;
 2551 }
 2552 
 2553 static int install_function_package (const char *pkgname,
 2554                      gretlopt opt,
 2555                      ExecState *s,
 2556                      PRN *prn)
 2557 {
 2558     char *fname = NULL;
 2559     gchar *gfname = NULL;
 2560     int filetype = 0;
 2561     int local = (opt & OPT_L);
 2562     int addon = 0;
 2563     int http = 0;
 2564     int err = 0;
 2565 
 2566     if (!local && package_is_addon(pkgname)) {
 2567     addon = 1;
 2568     filetype = 2;
 2569     if (strchr(pkgname, '.') == NULL) {
 2570         gfname = g_strdup_printf("%s.zip", pkgname);
 2571         fname = gfname;
 2572     }
 2573     goto next_step;
 2574     }
 2575 
 2576     if (!strncmp(pkgname, "http://", 7) ||
 2577     !strncmp(pkgname, "https://", 8)) {
 2578     http = 1;
 2579     }
 2580 
 2581     if (strstr(pkgname, ".gfn")) {
 2582     filetype = 1;
 2583     } else if (strstr(pkgname, ".zip")) {
 2584     filetype = 2;
 2585     } else if (local || http) {
 2586     /* must have suitable suffix */
 2587     err = E_DATA;
 2588     } else {
 2589     /* from gretl server: determine the correct suffix */
 2590     fname = retrieve_remote_pkg_filename(pkgname, &err);
 2591     if (!err) {
 2592         filetype = strstr(fname, ".zip") ? 2 : 1;
 2593     }
 2594     }
 2595 
 2596     if (!err) {
 2597     if (http) {
 2598         /* get @fname as last portion of URL */
 2599         const char *p = strrchr(pkgname, '/');
 2600 
 2601         if (p == NULL) {
 2602         err = E_DATA;
 2603         } else {
 2604         fname = gretl_strdup(p + 1);
 2605         }
 2606     } else if (local) {
 2607         const char *p;
 2608 
 2609         gretl_maybe_switch_dir(pkgname);
 2610         p = strrchr(pkgname, SLASH);
 2611         if (p != NULL) {
 2612         fname = gretl_strdup(p + 1);
 2613         }
 2614 
 2615     }
 2616     }
 2617 
 2618  next_step:
 2619 
 2620     if (!err && filetype) {
 2621     const char *basename = fname != NULL ? fname : pkgname;
 2622     const char *instpath = gretl_function_package_path();
 2623     gchar *fullname;
 2624 
 2625     fullname = g_strdup_printf("%s%s", instpath, basename);
 2626 
 2627     if (addon) {
 2628         gchar *uri = get_uri_for_addon(basename, &err);
 2629 
 2630         if (!err) {
 2631         err = retrieve_public_file(uri, fullname);
 2632         }
 2633         g_free(uri);
 2634     } else if (local) {
 2635         err = gretl_copy_file(pkgname, fullname);
 2636     } else if (http) {
 2637         /* get file from a specified server */
 2638         err = retrieve_public_file(pkgname, fullname);
 2639     } else {
 2640         /* get file from default gretl server */
 2641         err = retrieve_remote_function_package(basename, fullname);
 2642     }
 2643 
 2644     if (!err && filetype == 2) {
 2645         err = gretl_unzip_into(fullname, instpath);
 2646         if (!err) {
 2647         /* delete the zipfile */
 2648         gretl_remove(fullname);
 2649         }
 2650     }
 2651 
 2652     if (!err && !addon) {
 2653         package_check_dependencies(fullname, s, prn);
 2654     }
 2655 
 2656     if (!err && gretl_messages_on()) {
 2657         if (opt & OPT_D) {
 2658         pprintf(prn, "Installed dependency %s\n", basename);
 2659         } else {
 2660         pprintf(prn, "Installed %s\n", basename);
 2661         }
 2662     }
 2663 
 2664     if (!err && s != NULL && gui_callback != NULL &&
 2665         !addon && !(opt & OPT_D)) {
 2666         /* FIXME: handling of OPT_D here? */
 2667         gretl_bundle *b = gretl_bundle_new();
 2668         char *p, *nosfx = gretl_strdup(basename);
 2669 
 2670         p = strrchr(nosfx, '.');
 2671         if (p != NULL) {
 2672         *p = '\0';
 2673         }
 2674         gretl_bundle_set_string(b, "filename", fullname);
 2675         gretl_bundle_set_string(b, "pkgname", nosfx);
 2676         gretl_bundle_set_int(b, "zipfile", filetype == 2);
 2677         gui_callback(s, b, GRETL_OBJ_BUNDLE);
 2678         free(nosfx);
 2679     }
 2680 
 2681     g_free(fullname);
 2682     }
 2683 
 2684     if (addon) {
 2685     g_free(gfname);
 2686     } else {
 2687     free(fname);
 2688     }
 2689 
 2690     return err;
 2691 }
 2692 
 2693 #else /* !USE_CURL */
 2694 
 2695 /* in this case we can only install from a local file */
 2696 
 2697 static int install_function_package (const char *pkgname,
 2698                      gretlopt opt,
 2699                      ExecState *s,
 2700                      PRN *prn)
 2701 {
 2702     char *fname = NULL;
 2703     int filetype = 0;
 2704     int err = 0;
 2705 
 2706     if (!strncmp(pkgname, "http://", 7) ||
 2707     !strncmp(pkgname, "https://", 8)) {
 2708     gretl_errmsg_set(_("Internet access not supported"));
 2709     return E_DATA;
 2710     }
 2711 
 2712     if (strstr(pkgname, ".gfn")) {
 2713     filetype = 1;
 2714     } else if (strstr(pkgname, ".zip")) {
 2715     filetype = 2;
 2716     } else {
 2717     /* must have suitable suffix */
 2718     err = E_DATA;
 2719     }
 2720 
 2721     if (!err) {
 2722     /* get last portion of local filename */
 2723     const char *p;
 2724 
 2725     gretl_maybe_switch_dir(pkgname);
 2726     p = strrchr(pkgname, SLASH);
 2727     if (p != NULL) {
 2728         fname = gretl_strdup(p + 1);
 2729     }
 2730     }
 2731 
 2732     if (!err && filetype) {
 2733     const char *basename = fname != NULL ? fname : pkgname;
 2734     const char *instpath = gretl_function_package_path();
 2735     gchar *fullname;
 2736 
 2737     fullname = g_strdup_printf("%s%s", instpath, basename);
 2738 
 2739     /* copy file into place */
 2740     err = gretl_copy_file(pkgname, fullname);
 2741 
 2742     if (!err && filetype == 2) {
 2743         err = gretl_unzip_into(fullname, instpath);
 2744         if (!err) {
 2745         /* delete the zipfile */
 2746         gretl_remove(fullname);
 2747         }
 2748     }
 2749 
 2750     g_free(fullname);
 2751 
 2752     if (!err && gretl_messages_on()) {
 2753         pprintf(prn, "Installed %s\n", basename);
 2754     }
 2755     }
 2756 
 2757     free(fname);
 2758 
 2759     return err;
 2760 }
 2761 
 2762 #endif
 2763 
 2764 static void abort_execution (ExecState *s)
 2765 {
 2766     *s->cmd->savename = '\0';
 2767     gretl_cmd_destroy_context(s->cmd);
 2768     errmsg(E_STOP, s->prn);
 2769 }
 2770 
 2771 static int plot_ok;
 2772 
 2773 void set_plot_produced (void)
 2774 {
 2775     plot_ok = 1;
 2776 }
 2777 
 2778 int is_plotting_command (CMD *cmd)
 2779 {
 2780     if (GRAPHING_COMMAND(cmd->ci)) {
 2781     return cmd->ci;
 2782     } else if (cmd->ci == END &&
 2783            cmd->param != NULL &&
 2784            !strcmp(cmd->param, "plot")) {
 2785     return PLOT;
 2786     } else {
 2787     return 0;
 2788     }
 2789 }
 2790 
 2791 static void maybe_schedule_graph_callback (ExecState *s)
 2792 {
 2793     int gui_mode = gretl_in_gui_mode();
 2794 
 2795     if (graph_written_to_file()) {
 2796     if (gui_mode && *s->cmd->savename != '\0') {
 2797         pprintf(s->prn, "Warning: ignoring \"%s <-\"\n", s->cmd->savename);
 2798     }
 2799     report_plot_written(s->prn);
 2800     } else if (gui_mode) {
 2801     schedule_callback(s);
 2802     }
 2803 }
 2804 
 2805 static int execute_plot_call (CMD *cmd, DATASET *dset,
 2806                   char *line, PRN *prn)
 2807 {
 2808     gretlopt opt = cmd->opt;
 2809     int err = 0;
 2810 
 2811     if (gretl_in_gui_mode() && *cmd->savename != '\0') {
 2812     /* saving plot "as icon": add internal option to
 2813        override production of a "gpttmp" file
 2814     */
 2815     opt |= OPT_G;
 2816     }
 2817 
 2818 #if 1
 2819     if (!gretl_in_gui_mode() && getenv("CLI_NO_PLOTS")
 2820     && cmd->ci != END) {
 2821     return 0;
 2822     }
 2823 #endif
 2824 
 2825     if (cmd->ci == END) {
 2826     /* end of a "plot" block */
 2827     err = gretl_plot_finalize(line, dset, opt);
 2828     } else if (opt & OPT_X) {
 2829     err = matrix_command_driver(cmd->ci, cmd->list, cmd->param,
 2830                     dset, opt, prn);
 2831     } else if (cmd->ci == GNUPLOT) {
 2832     if (opt & OPT_I) {
 2833         err = gnuplot_process_file(opt, prn);
 2834     } else if (opt & OPT_C) {
 2835         err = xy_plot_with_control(cmd->list, cmd->param,
 2836                        dset, opt);
 2837     } else {
 2838         err = gnuplot(cmd->list, cmd->param, dset, opt);
 2839     }
 2840     } else if (cmd->ci == SCATTERS) {
 2841     err = multi_scatters(cmd->list, dset, opt);
 2842     } else if (cmd->ci == BXPLOT) {
 2843     err = boxplots(cmd->list, cmd->param, dset, opt);
 2844     } else if (cmd->ci == HFPLOT) {
 2845     err = hf_plot(cmd->list, cmd->param, dset, opt);
 2846     } else if (cmd->ci == PANPLOT) {
 2847     err = cli_panel_plot(cmd->list, cmd->param, dset, opt);
 2848     } else if (cmd->ci == QQPLOT) {
 2849     err = qq_plot(cmd->list, dset, opt);
 2850     }
 2851 
 2852     return err;
 2853 }
 2854 
 2855 static int smpl_restrict (gretlopt opt)
 2856 {
 2857     opt &= ~OPT_Q;
 2858     opt &= ~OPT_T;
 2859     return opt != OPT_NONE;
 2860 }
 2861 
 2862 static int panel_smpl_special (gretlopt opt)
 2863 {
 2864     /* --unit [or, maybe someday, --time] */
 2865     return opt & OPT_U;
 2866 }
 2867 
 2868 static void maybe_print_error_message (CMD *cmd, int err, PRN *prn)
 2869 {
 2870     if (gretl_function_depth() > 0) {
 2871     ; /* defer printing */
 2872     } else if (cmd->flags & CMD_CATCH) {
 2873     /* print only if messages on */
 2874     if (gretl_messages_on()) {
 2875         errmsg(err, prn);
 2876     }
 2877     } else {
 2878     /* otherwise go ahead and print */
 2879     errmsg(err, prn);
 2880     }
 2881 }
 2882 
 2883 int gretl_cmd_exec (ExecState *s, DATASET *dset)
 2884 {
 2885     CMD *cmd = s->cmd;
 2886     char *line = s->line;
 2887     MODEL *model = s->model;
 2888     PRN *prn = s->prn;
 2889     char readfile[MAXLEN];
 2890     int *listcpy = NULL;
 2891     int err = 0;
 2892 
 2893     exec_state_prep(s);
 2894     plot_ok = 0;
 2895 
 2896     if (gretl_in_gui_mode() && check_for_stop()) {
 2897     /* the GUI user clicked the "Stop" button */
 2898     abort_execution(s);
 2899     return E_STOP;
 2900     }
 2901 
 2902     if (NEEDS_MODEL_CHECK(cmd->ci)) {
 2903     err = model_test_check(cmd, dset, prn);
 2904     } else if (MODIFIES_LIST(cmd->ci)) {
 2905     if (cmd->list[0] == 0) {
 2906         /* no-op */
 2907         return 0;
 2908     } else {
 2909         /* list is potentially modified -> make a copy */
 2910         listcpy = gretl_list_copy(cmd->list);
 2911         if (listcpy == NULL) {
 2912         err = E_ALLOC;
 2913         }
 2914     }
 2915     }
 2916 
 2917     if (err) {
 2918     goto bailout;
 2919     }
 2920 
 2921     *readfile = '\0';
 2922 
 2923     if (cmd->ci == OLS && dataset_is_panel(dset)) {
 2924     cmd->ci = PANEL;
 2925     cmd->opt |= OPT_P; /* panel pooled OLS flag */
 2926     }
 2927 
 2928 #if 0
 2929     fprintf(stderr, "gretl_cmd_exec: '%s' (ci %d) \n", line, cmd->ci);
 2930 #endif
 2931 
 2932     switch (cmd->ci) {
 2933 
 2934     case APPEND:
 2935     case JOIN:
 2936     case OPEN:
 2937     err = lib_open_append(s, dset, readfile, prn);
 2938     if (!err) {
 2939         schedule_callback(s);
 2940     }
 2941     break;
 2942 
 2943     case CLEAR:
 2944     err = check_clear_data();
 2945     if (!err) {
 2946         if (gretl_in_gui_mode()) {
 2947         schedule_callback(s);
 2948         } else {
 2949         lib_clear_data(s, dset);
 2950         }
 2951     }
 2952     break;
 2953 
 2954     case FLUSH:
 2955     if (gretl_in_gui_mode()) {
 2956         schedule_callback(s);
 2957     } else {
 2958         gretl_print_flush_stream(prn);
 2959     }
 2960     break;
 2961 
 2962     case ANOVA:
 2963     err = anova(cmd->list, dset, cmd->opt, prn);
 2964     break;
 2965 
 2966     case ADF:
 2967     err = adf_test(cmd->order, cmd->list, dset, cmd->opt, prn);
 2968     break;
 2969 
 2970     case KPSS:
 2971     err = kpss_test(cmd->order, cmd->list, dset, cmd->opt, prn);
 2972     break;
 2973 
 2974     case LEVINLIN:
 2975     err = llc_test_driver(cmd->param, cmd->list, dset,
 2976                   cmd->opt, prn);
 2977     break;
 2978 
 2979     case COINT:
 2980     err = engle_granger_test(cmd->order, cmd->list, dset,
 2981                  cmd->opt, prn);
 2982     break;
 2983 
 2984     case COINT2:
 2985     err = johansen_test_simple(cmd->order, cmd->list,
 2986                    dset, cmd->opt, prn);
 2987     break;
 2988 
 2989     case CORR:
 2990     err = incompatible_options(cmd->opt, OPT_N | OPT_S | OPT_K);
 2991     if (!err) {
 2992         err = incompatible_options(cmd->opt, OPT_X | OPT_S | OPT_K);
 2993     }
 2994     if (err) {
 2995         break;
 2996     }
 2997     if (cmd->opt & OPT_K) {
 2998         err = kendall_tau(cmd->list, dset, cmd->opt, prn);
 2999     } else if (cmd->opt & OPT_S) {
 3000         err = spearman_rho(cmd->list, dset, cmd->opt, prn);
 3001     } else if (cmd->opt & OPT_X) {
 3002         err = matrix_command_driver(CORR, cmd->list, cmd->param,
 3003                     dset, cmd->opt, prn);
 3004     } else {
 3005         err = gretl_corrmx(cmd->list, dset, cmd->opt, prn);
 3006     }
 3007     break;
 3008 
 3009     case CORRGM:
 3010     err = corrgram(cmd->list[1], cmd->order, 0, dset,
 3011                cmd->opt, prn);
 3012     break;
 3013 
 3014     case XCORRGM:
 3015     err = xcorrgram(cmd->list, cmd->order, dset,
 3016             cmd->opt, prn);
 3017     break;
 3018 
 3019     case PERGM:
 3020     err = periodogram(cmd->list[1], cmd->order, dset,
 3021               cmd->opt, prn);
 3022     break;
 3023 
 3024     case FRACTINT:
 3025     err = fractint(cmd->list[1], cmd->order, dset,
 3026                cmd->opt, prn);
 3027     break;
 3028 
 3029     case FUNDEBUG:
 3030     err = do_debug_command(s, cmd->param, cmd->opt);
 3031     break;
 3032 
 3033     case BREAK:
 3034     case ENDLOOP:
 3035     pprintf(prn, _("You can't end a loop here, "
 3036                "you haven't started one\n"));
 3037     err = 1;
 3038     break;
 3039 
 3040     case FCAST:
 3041     err = do_forecast(cmd->param, dset, cmd->opt, prn);
 3042     break;
 3043 
 3044     case FREQ:
 3045     if (cmd->opt & OPT_X) {
 3046         err = matrix_freq_driver(cmd->list, cmd->opt, prn);
 3047     } else {
 3048         err = freqdist(cmd->list[1], dset, cmd->opt, prn);
 3049     }
 3050     break;
 3051 
 3052     case DISCRETE:
 3053     err = list_makediscrete(cmd->list, dset, cmd->opt);
 3054     break;
 3055 
 3056     case ESTIMATE:
 3057     err = estimate_named_system(cmd->param, cmd->parm2, dset,
 3058                     cmd->opt, prn);
 3059     break;
 3060 
 3061     case FUNC:
 3062     err = gretl_start_compiling_function(cmd->param, dset, prn);
 3063     break;
 3064 
 3065     case GENR:
 3066     case EVAL:
 3067     if (cmd->flags & CMD_CATCH) {
 3068         err = generate(cmd->vstart, dset, cmd->gtype,
 3069                cmd->opt | OPT_C, prn);
 3070         if (err == E_BADCATCH) {
 3071         cmd->flags ^= CMD_CATCH;
 3072         }
 3073     } else {
 3074         err = generate(cmd->vstart, dset, cmd->gtype,
 3075                cmd->opt, prn);
 3076     }
 3077     break;
 3078 
 3079     case PCA:
 3080     err = do_pca(cmd->list, dset, cmd->opt, prn);
 3081     break;
 3082 
 3083     case DATA:
 3084     err = db_get_series(cmd->param, dset, cmd->opt, prn);
 3085     break;
 3086 
 3087     case DATAMOD:
 3088     err = modify_dataset(dset, cmd->auxint, cmd->list,
 3089                  cmd->parm2, cmd->opt, prn);
 3090     if (!err) {
 3091         schedule_callback(s);
 3092     }
 3093     break;
 3094 
 3095     case DIFF:
 3096     case LDIFF:
 3097     case SDIFF:
 3098     err = list_diffgenr(listcpy, cmd->ci, dset);
 3099     if (!err) {
 3100         maybe_list_series(dset, prn);
 3101         set_dataset_is_changed();
 3102     }
 3103     break;
 3104 
 3105     case ORTHDEV:
 3106     err = list_orthdev(listcpy, dset);
 3107     if (!err) {
 3108         maybe_list_series(dset, prn);
 3109         set_dataset_is_changed();
 3110     }
 3111     break;
 3112 
 3113     case DUMMIFY:
 3114     err = list_dumgenr(&listcpy, dset, cmd->opt);
 3115     if (!err) {
 3116         maybe_list_series(dset, prn);
 3117         set_dataset_is_changed();
 3118     }
 3119     break;
 3120 
 3121     case LAGS:
 3122     err = list_laggenr(&listcpy, 1, cmd->order, NULL,
 3123                dset, 0, cmd->opt);
 3124     if (!err) {
 3125         maybe_list_series(dset, prn);
 3126         set_dataset_is_changed();
 3127     }
 3128     break;
 3129 
 3130     case LOGS:
 3131     err = list_loggenr(listcpy, dset);
 3132     if (!err) {
 3133         maybe_list_series(dset, prn);
 3134         set_dataset_is_changed();
 3135     }
 3136     break;
 3137 
 3138     case STDIZE:
 3139     err = list_stdgenr(listcpy, dset, cmd->opt);
 3140     if (!err) {
 3141         maybe_list_series(dset, prn);
 3142         set_dataset_is_changed();
 3143     }
 3144     break;
 3145 
 3146     case SQUARE:
 3147     err = list_xpxgenr(&listcpy, dset, cmd->opt);
 3148     if (!err) {
 3149         maybe_list_series(dset, prn);
 3150         set_dataset_is_changed();
 3151     }
 3152     break;
 3153 
 3154     case TEXTPLOT:
 3155     err = textplot(cmd->list, dset, cmd->opt, prn);
 3156     break;
 3157 
 3158     case RMPLOT:
 3159     err = rmplot(cmd->list, dset, cmd->opt, prn);
 3160     break;
 3161 
 3162     case HURST:
 3163     err = hurstplot(cmd->list, dset, cmd->opt, prn);
 3164     break;
 3165 
 3166     case INFO:
 3167     print_info(cmd->opt, dset, prn);
 3168     break;
 3169 
 3170     case RENAME:
 3171     err = dataset_rename_series(dset, cmd->auxint, cmd->parm2);
 3172     if (!err && !(cmd->opt & OPT_Q)) {
 3173         maybe_list_series(dset, prn);
 3174     }
 3175     break;
 3176 
 3177     case SET:
 3178     err = execute_set(cmd->param, cmd->parm2, dset, cmd->opt, prn);
 3179     break;
 3180 
 3181     case SETINFO:
 3182     err = set_var_info(cmd->list, cmd->param, cmd->parm2,
 3183                cmd->opt, dset);
 3184     break;
 3185 
 3186     case SETMISS:
 3187     err = set_miss(cmd->list, cmd->param, dset, prn);
 3188         break;
 3189 
 3190     case LABELS:
 3191     if (cmd->opt & (OPT_D | OPT_F | OPT_T | OPT_A | OPT_R)) {
 3192         err = read_or_write_var_labels(cmd->opt, dset, prn);
 3193         if (!err && (cmd->opt & (OPT_D | OPT_F))) {
 3194         schedule_callback(s);
 3195         }
 3196     } else {
 3197         showlabels(cmd->list, cmd->opt, dset, prn);
 3198     }
 3199     break;
 3200 
 3201     case MARKERS:
 3202     err = read_or_write_obs_markers(cmd->opt, dset, prn);
 3203     if (!err && (cmd->opt & (OPT_D | OPT_F))) {
 3204         schedule_callback(s);
 3205     }
 3206     break;
 3207 
 3208     case VARLIST:
 3209     if (cmd->opt & OPT_T) {
 3210         list_user_vars_of_type(dset, prn);
 3211     } else if (cmd->opt & OPT_S) {
 3212         print_scalars(prn);
 3213     } else if (cmd->opt & OPT_A) {
 3214         list_ok_dollar_vars(dset, prn);
 3215     } else {
 3216         list_series(dset, cmd->opt, prn);
 3217     }
 3218     break;
 3219 
 3220     case PRINT:
 3221     if (cmd->opt & OPT_L) {
 3222         err = printdata(NULL, cmd->param, dset, OPT_NONE, prn);
 3223     } else if (cmd->param != NULL) {
 3224         /* directly printing a string literal */
 3225         pputs(prn, cmd->param);
 3226         pputc(prn, '\n');
 3227     } else {
 3228         err = printdata(cmd->list, cmd->parm2, dset, cmd->opt, prn);
 3229     }
 3230     break;
 3231 
 3232     case PRINTF:
 3233     case SSCANF:
 3234     err = do_printscan_command(cmd->ci, cmd->param, cmd->parm2,
 3235                    cmd->vstart, dset, prn);
 3236     break;
 3237 
 3238     case PVAL:
 3239     err = batch_pvalue(cmd->param, dset, prn);
 3240     break;
 3241 
 3242     case SUMMARY:
 3243     err = incompatible_options(cmd->opt, OPT_B | OPT_W);
 3244     if (err) {
 3245         break;
 3246     }
 3247     if (cmd->opt & OPT_B) {
 3248         err = do_command_by(cmd, dset, prn);
 3249     } else if (cmd->opt & OPT_X) {
 3250         err = matrix_command_driver(cmd->ci, cmd->list, cmd->param,
 3251                     dset, cmd->opt, prn);
 3252     } else {
 3253         err = list_summary_driver(cmd->list, dset, cmd->opt, prn);
 3254     }
 3255     break;
 3256 
 3257     case XTAB:
 3258     if (cmd->opt & OPT_X) {
 3259         err = crosstab_from_matrix(cmd->opt, prn);
 3260     } else {
 3261         err = crosstab(cmd->list, dset, cmd->opt, prn);
 3262     }
 3263     break;
 3264 
 3265     case MAHAL:
 3266     err = mahalanobis_distance(cmd->list, dset, cmd->opt, prn);
 3267     break;
 3268 
 3269     case MEANTEST:
 3270     err = means_test(cmd->list, dset, cmd->opt, prn);
 3271     break;
 3272 
 3273     case VARTEST:
 3274     err = vars_test(cmd->list, dset, prn);
 3275     break;
 3276 
 3277     case RUNS:
 3278     err = runs_test(cmd->list[1], dset, cmd->opt, prn);
 3279     break;
 3280 
 3281     case SPEARMAN:
 3282     err = spearman_rho(cmd->list, dset, cmd->opt, prn);
 3283     break;
 3284 
 3285     case DIFFTEST:
 3286     err = diff_test(cmd->list, dset, cmd->opt, prn);
 3287     break;
 3288 
 3289     case OUTFILE:
 3290     err = do_outfile_command(cmd->opt, cmd->param, dset, prn);
 3291     break;
 3292 
 3293     case SETOBS:
 3294     err = set_obs(cmd->param, cmd->parm2, dset, cmd->opt);
 3295     if (!err) {
 3296         if (dset->n > 0) {
 3297         if (!(cmd->opt & (OPT_I | OPT_G))) {
 3298             print_smpl(dset, 0, OPT_NONE, prn);
 3299         }
 3300         schedule_callback(s);
 3301         } else {
 3302         pprintf(prn, _("data frequency = %d\n"), dset->pd);
 3303         }
 3304     }
 3305     break;
 3306 
 3307     case SETOPT:
 3308     err = set_options_for_command(cmd->param, cmd->parm2, cmd->opt);
 3309     if (!err && gretl_messages_on()) {
 3310         pprintf(prn, "Set option(s) for command \"%s\"\n", cmd->param);
 3311     }
 3312     break;
 3313 
 3314     case SMPL:
 3315     if (cmd->opt == OPT_F) {
 3316         err = restore_full_sample(dset, s);
 3317     } else if (cmd->opt == OPT_T && cmd->param == NULL) {
 3318         /* --permanent, by itself */
 3319         err = perma_sample(dset, cmd->opt, prn, NULL);
 3320     } else if (panel_smpl_special(cmd->opt)) {
 3321         /* the panel --unit option */
 3322         err = set_panel_sample(cmd->param, cmd->parm2, cmd->opt, dset);
 3323     } else if (smpl_restrict(cmd->opt)) {
 3324         /* --restrict, --dummy, etc. */
 3325         err = restrict_sample(cmd->param, cmd->list, dset,
 3326                   s, cmd->opt, prn, NULL);
 3327     } else if (cmd->param == NULL && cmd->parm2 == NULL) {
 3328         /* no args given: give a report */
 3329         print_smpl(dset, get_full_length_n(), OPT_F, prn);
 3330         break;
 3331     } else {
 3332         /* simple setting of t1, t2 business */
 3333         err = set_sample(cmd->param, cmd->parm2, dset, cmd->opt);
 3334     }
 3335     if (!err && !(cmd->opt & OPT_Q)) {
 3336         print_smpl(dset, get_full_length_n(), OPT_NONE, prn);
 3337     }
 3338     break;
 3339 
 3340     case PKG:
 3341     err = do_pkg_command(cmd->param, cmd->parm2, cmd->opt, s, prn);
 3342     break;
 3343 
 3344     case MAKEPKG:
 3345     err = create_and_write_function_package(cmd->param, cmd->opt, prn);
 3346     break;
 3347 
 3348     case STORE:
 3349     if (!has_param(cmd)) {
 3350         pputs(prn, _("store: no filename given\n"));
 3351         err = E_PARSE;
 3352     } else if (cmd->opt & OPT_A) {
 3353         err = write_matrix_as_dataset(cmd->param, cmd->opt, prn);
 3354     } else if (dset == NULL || dset->Z == NULL) {
 3355         err = E_NODATA;
 3356     } else {
 3357         err = write_data(cmd->param, cmd->list, dset, cmd->opt, prn);
 3358     }
 3359     break;
 3360 
 3361     case SHELL:
 3362     err = gretl_shell(cmd->vstart, cmd->opt, prn);
 3363     break;
 3364 
 3365     case OLS:
 3366     case WLS:
 3367     clear_model(model);
 3368     *model = lsq(cmd->list, dset, cmd->ci, cmd->opt);
 3369     err = print_save_model(model, dset, cmd->opt, 0, prn, s);
 3370     break;
 3371 
 3372     case MPOLS:
 3373     clear_model(model);
 3374     *model = mp_ols(cmd->list, dset, cmd->opt);
 3375     err = print_save_model(model, dset, cmd->opt, 0, prn, s);
 3376     break;
 3377 
 3378     case AR:
 3379     case AR1:
 3380     case ARMA:
 3381     case ARCH:
 3382     clear_model(model);
 3383     if (cmd->ci == AR) {
 3384         *model = ar_model(cmd->list, dset, cmd->opt, prn);
 3385     } else if (cmd->ci == AR1) {
 3386         *model = ar1_model(cmd->list, dset, cmd->opt, prn);
 3387     } else if (cmd->ci == ARMA) {
 3388         *model = arma(cmd->list, cmd->auxlist, dset,
 3389               cmd->opt, prn);
 3390     } else {
 3391         *model = arch_model(cmd->list, cmd->order, dset,
 3392                 cmd->opt);
 3393     }
 3394     err = print_save_model(model, dset, cmd->opt, 0, prn, s);
 3395     break;
 3396 
 3397     case ARBOND:
 3398     case PANEL:
 3399     case DPANEL:
 3400     if (!dataset_is_panel(dset)) {
 3401         gretl_errmsg_set(_("This estimator requires panel data"));
 3402         err = E_DATA;
 3403         break;
 3404     }
 3405     /* Falls through. */
 3406     case GARCH:
 3407     case HECKIT:
 3408     case HSK:
 3409     case INTREG:
 3410     case IVREG:
 3411     case LAD:
 3412     case LOGISTIC:
 3413     case LOGIT:
 3414     case POISSON:
 3415     case NEGBIN:
 3416     case PROBIT:
 3417     case QUANTREG:
 3418     case TOBIT:
 3419     case DURATION:
 3420     case BIPROBIT:
 3421     case MIDASREG:
 3422     clear_model(model);
 3423     if (cmd->ci == LOGIT || cmd->ci == PROBIT) {
 3424         *model = logit_probit(cmd->list, dset, cmd->ci, cmd->opt, prn);
 3425     } else if (cmd->ci == HSK) {
 3426         *model = hsk_model(cmd->list, dset, cmd->opt);
 3427     } else if (cmd->ci == LOGISTIC) {
 3428         *model = logistic_driver(cmd->list, dset, cmd->opt);
 3429     } else if (cmd->ci == TOBIT) {
 3430         *model = tobit_driver(cmd->list, dset, cmd->opt, prn);
 3431     } else if (cmd->ci == POISSON || cmd->ci == NEGBIN) {
 3432         *model = count_model(cmd->list, cmd->ci, dset, cmd->opt, prn);
 3433     } else if (cmd->ci == HECKIT) {
 3434         *model = heckit_model(cmd->list, dset, cmd->opt, prn);
 3435     } else if (cmd->ci == IVREG) {
 3436         *model = ivreg(cmd->list, dset, cmd->opt);
 3437     } else if (cmd->ci == LAD) {
 3438         *model = lad_model(cmd->list, dset, cmd->opt);
 3439     } else if (cmd->ci == QUANTREG) {
 3440         *model = quantreg_driver(cmd->param, cmd->list, dset,
 3441                      cmd->opt, prn);
 3442     } else if (cmd->ci == DURATION) {
 3443         *model = duration_model(cmd->list, dset, cmd->opt, prn);
 3444     } else if (cmd->ci == GARCH) {
 3445         *model = garch(cmd->list, dset, cmd->opt, prn);
 3446     } else if (cmd->ci == PANEL) {
 3447         *model = panel_model(cmd->list, dset, cmd->opt, prn);
 3448     } else if (cmd->ci == ARBOND) {
 3449         *model = arbond_model(cmd->list, cmd->param, dset,
 3450                   cmd->opt, prn);
 3451     } else if (cmd->ci == DPANEL) {
 3452         *model = dpd_model(cmd->list, cmd->auxlist, cmd->param,
 3453                    dset, cmd->opt, prn);
 3454     } else if (cmd->ci == INTREG) {
 3455         *model = interval_model(cmd->list, dset, cmd->opt, prn);
 3456     } else if (cmd->ci == BIPROBIT) {
 3457         *model = biprobit_model(cmd->list, dset, cmd->opt, prn);
 3458     } else if (cmd->ci == MIDASREG) {
 3459         *model = midas_model(cmd->list, cmd->param, dset,
 3460                  cmd->opt, prn);
 3461     } else {
 3462         /* can't happen */
 3463         err = 1;
 3464         break;
 3465     }
 3466     err = print_save_model(model, dset, cmd->opt, 0, prn, s);
 3467     break;
 3468 
 3469     case GMM:
 3470     case MLE:
 3471     case NLS:
 3472     err = nl_parse_line(cmd->ci, cmd->vstart, dset, prn);
 3473     if (!err) {
 3474         gretl_cmd_set_context(cmd, cmd->ci);
 3475     }
 3476     break;
 3477 
 3478     case FOREIGN:
 3479     case MPI:
 3480     if (cmd->context == FOREIGN || cmd->context == MPI) {
 3481         err = foreign_append(line, cmd->context);
 3482     } else {
 3483         err = foreign_start(cmd->ci, cmd->param, cmd->opt, prn);
 3484         if (!err) {
 3485         gretl_cmd_set_context(cmd, cmd->ci);
 3486         }
 3487     }
 3488     break;
 3489 
 3490     case PLOT:
 3491     if (!cmd->context) {
 3492         err = gretl_plot_start(cmd->param, dset);
 3493     } else {
 3494         err = gretl_plot_append_line(line, dset);
 3495     }
 3496     if (!err && !cmd->context) {
 3497         gretl_cmd_set_context(cmd, cmd->ci);
 3498     }
 3499     break;
 3500 
 3501     case ADD:
 3502     case OMIT:
 3503     if (get_last_model_type() == GRETL_OBJ_VAR) {
 3504         err = VAR_omit_driver(cmd, dset, prn);
 3505     } else if (add_omit_save(cmd, model)) {
 3506         MODEL mymod;
 3507 
 3508         gretl_model_init(&mymod, dset);
 3509         if (cmd->ci == ADD) {
 3510         err = add_test_full(model, &mymod, cmd->list,
 3511                     dset, cmd->opt, prn);
 3512         } else {
 3513         err = omit_test_full(model, &mymod, cmd->list,
 3514                      dset, cmd->opt, prn);
 3515         }
 3516         if (!err && mymod.ncoeff > 0) {
 3517         gretlopt popt = OPT_NONE;
 3518 
 3519         if (cmd->opt & (OPT_I | OPT_Q)) {
 3520             popt = OPT_Q;
 3521         } else if (cmd->opt & OPT_O) {
 3522             popt = OPT_O; /* --vcv printing option */
 3523         }
 3524         clear_model(model);
 3525         *model = mymod;
 3526         print_save_model(model, dset, popt, 1, prn, s);
 3527         }
 3528     } else if (cmd->ci == ADD) {
 3529         err = add_test(model, cmd->list, dset, cmd->opt, prn);
 3530     } else {
 3531         err = omit_test(model, cmd->list, dset, cmd->opt, prn);
 3532     }
 3533     if (err == E_NOOMIT) {
 3534         /* auto-omit was a no-op */
 3535         err = 0;
 3536     }
 3537     break;
 3538 
 3539     case BKW:
 3540     case COEFFSUM:
 3541     case CUSUM:
 3542     case RESET:
 3543     case CHOW:
 3544     case QLRTEST:
 3545     case VIF:
 3546     if (cmd->ci == COEFFSUM) {
 3547         err = gretl_sum_test(cmd->list, model, dset, cmd->opt, prn);
 3548     } else if (cmd->ci == CUSUM) {
 3549         err = cusum_test(model, dset, cmd->opt, prn);
 3550     } else if (cmd->ci == RESET) {
 3551         err = reset_test(model, dset, cmd->opt, prn);
 3552     } else if (cmd->ci == CHOW) {
 3553         err = chow_test_driver(cmd->param, model, dset, cmd->opt, prn);
 3554     } else if (cmd->ci == QLRTEST) {
 3555         err = QLR_test(model, dset, cmd->opt, prn);
 3556     } else if (cmd->ci == VIF) {
 3557         err = vif_test(model, dset, cmd->opt, prn);
 3558     } else if (cmd->ci == BKW) {
 3559         err = bkw_test(model, dset, cmd->opt, prn);
 3560     }
 3561     break;
 3562 
 3563     case NORMTEST:
 3564     err = gretl_normality_test(cmd->list[1], dset, cmd->opt, prn);
 3565     break;
 3566 
 3567     case HAUSMAN:
 3568     err = panel_hausman_test(model, dset, cmd->opt, prn);
 3569     break;
 3570 
 3571     case MODTEST:
 3572     err = model_test_driver(cmd->order, dset, cmd->opt, prn);
 3573     break;
 3574 
 3575     case LEVERAGE:
 3576     err = leverage_test(model, dset, cmd->opt, prn);
 3577     if (!err && (cmd->opt & OPT_S) && !(cmd->opt & OPT_Q)) {
 3578         maybe_list_series(dset, prn);
 3579     }
 3580     break;
 3581 
 3582     case EQNPRINT:
 3583     case TABPRINT:
 3584     if (model->errcode == E_NAN) {
 3585         pprintf(prn, _("Couldn't format model\n"));
 3586     } else {
 3587         err = model_print_driver(model, dset, cmd->ci,
 3588                      cmd->param, cmd->opt,
 3589                      prn);
 3590     }
 3591     break;
 3592 
 3593     case RESTRICT:
 3594     /* joint hypothesis test on model */
 3595     if (s->rset == NULL) {
 3596         if (!has_param(cmd)) {
 3597         /* if param is non-blank, we're restricting a named system */
 3598         err = model_test_check(cmd, dset, prn);
 3599         if (err) break;
 3600         }
 3601         s->rset = restriction_set_start(cmd->param, cmd->opt, &err);
 3602         if (!err) {
 3603         /* FIXME redundant? */
 3604         gretl_cmd_set_context(cmd, RESTRICT);
 3605         }
 3606     } else {
 3607         err = restriction_set_parse_line(s->rset, line, dset);
 3608         if (err) {
 3609         s->rset = NULL;
 3610         }
 3611     }
 3612     break;
 3613 
 3614     case SYSTEM:
 3615     if (s->sys == NULL) {
 3616         /* no equation system is defined currently */
 3617         s->sys = equation_system_start(cmd->param, cmd->savename,
 3618                        cmd->opt, &err);
 3619         if (!err) {
 3620         gretl_cmd_set_context(cmd, SYSTEM);
 3621         }
 3622     } else {
 3623         /* tokenize: use of @line OK here? */
 3624         err = system_parse_line(s->sys, line, dset);
 3625         if (err) {
 3626         s->sys = NULL;
 3627         }
 3628     }
 3629     break;
 3630 
 3631     case EQUATION:
 3632     if (cmd->opt & OPT_M) {
 3633         err = equation_system_append_multi(s->sys, cmd->param,
 3634                            cmd->parm2, dset);
 3635     } else {
 3636         err = equation_system_append(s->sys, cmd->list);
 3637     }
 3638     if (err) {
 3639         s->sys = NULL;
 3640     }
 3641     break;
 3642 
 3643     case END:
 3644     if (!strcmp(cmd->param, "system")) {
 3645         err = equation_system_finalize(s->sys, dset, cmd->opt, prn);
 3646         if (!err) {
 3647         gui_save_system(s);
 3648         }
 3649         /* clear for next use */
 3650         s->sys = NULL;
 3651     } else if (!strcmp(cmd->param, "mle") ||
 3652            !strcmp(cmd->param, "nls") ||
 3653            !strcmp(cmd->param, "gmm")) {
 3654         clear_model(model);
 3655         *model = nl_model(dset, cmd->opt, prn);
 3656         err = print_save_model(model, dset, cmd->opt, 0, prn, s);
 3657     } else if (!strcmp(cmd->param, "restrict")) {
 3658         err = do_end_restrict(s, dset);
 3659     } else if (!strcmp(cmd->param, "foreign")) {
 3660         err = foreign_execute(dset, cmd->opt, prn);
 3661     } else if (!strcmp(cmd->param, "mpi")) {
 3662         err = foreign_execute(dset, cmd->opt, prn);
 3663     } else if (!strcmp(cmd->param, "plot")) {
 3664         err = execute_plot_call(cmd, dset, line, prn);
 3665     } else if (!strcmp(cmd->param, "outfile")) {
 3666         err = do_outfile_command(OPT_C, NULL, NULL, prn);
 3667     } else {
 3668         err = E_PARSE;
 3669     }
 3670     break;
 3671 
 3672     case VAR:
 3673     case VECM:
 3674     if (cmd->ci == VAR) {
 3675         s->var = gretl_VAR(cmd->order, cmd->auxlist, cmd->list,
 3676                    dset, cmd->opt, prn, &err);
 3677     } else {
 3678         s->var = gretl_VECM(cmd->order, cmd->auxint, cmd->list,
 3679                 dset, cmd->opt, prn, &err);
 3680     }
 3681     if (!err && s->var != NULL) {
 3682         save_var_vecm(s);
 3683     }
 3684     break;
 3685 
 3686     case RUN:
 3687     case INCLUDE:
 3688     if (cmd->ci == RUN) {
 3689         err = get_full_filename(cmd->param, readfile, OPT_S);
 3690     } else {
 3691         err = get_full_filename(cmd->param, readfile, OPT_I);
 3692         cmd->opt |= OPT_Q;
 3693     }
 3694     if (err) {
 3695         break;
 3696     }
 3697     if (gretl_messages_on()) {
 3698         pprintf(prn, " %s\n", readfile);
 3699     }
 3700     if (cmd->ci == INCLUDE && gretl_is_xml_file(readfile)) {
 3701         err = load_XML_functions_file(readfile, cmd->opt, prn);
 3702         break;
 3703     } else if (cmd->ci == INCLUDE && gfn_is_loaded(readfile)) {
 3704         break;
 3705     }
 3706     if (!strcmp(readfile, s->runfile)) {
 3707         pprintf(prn, _("Infinite loop detected in script\n"));
 3708         err = 1;
 3709         break;
 3710     }
 3711     err = run_script(readfile, s, dset, cmd->opt, prn);
 3712     break;
 3713 
 3714     case FUNCERR:
 3715     case FUNCRET:
 3716     if (gretl_function_depth() == 0) {
 3717         gretl_errmsg_sprintf("'%s': can only be used within a function",
 3718                  gretl_command_word(cmd->ci));
 3719         err = 1;
 3720     } else if (cmd->ci == FUNCERR) {
 3721         err = E_FUNCERR;
 3722     }
 3723     break;
 3724 
 3725     case DELEET:
 3726     err = gretl_delete_variables(cmd->list, cmd->param, cmd->opt,
 3727                      dset, NULL, prn);
 3728     break;
 3729 
 3730     case MODPRINT:
 3731     err = do_modprint(cmd->param, cmd->parm2, cmd->opt, prn);
 3732     break;
 3733 
 3734     case GNUPLOT:
 3735     case BXPLOT:
 3736     case SCATTERS:
 3737     case HFPLOT:
 3738     case PANPLOT:
 3739     case QQPLOT:
 3740     err = execute_plot_call(cmd, dset, NULL, prn);
 3741     break;
 3742 
 3743     case MODELTAB:
 3744     case GRAPHPG:
 3745     if (gretl_in_gui_mode()) {
 3746         schedule_callback(s);
 3747     } else {
 3748         pprintf(prn, _("%s: command not available\n"),
 3749             gretl_command_word(cmd->ci));
 3750     }
 3751     break;
 3752 
 3753     default:
 3754     {
 3755         const char *word = gretl_command_word(cmd->ci);
 3756 
 3757         if (*word != '\0') {
 3758         pprintf(prn, _("The \"%s\" command cannot be used in this context"),
 3759             word);
 3760         pputc(prn, '\n');
 3761         } else {
 3762         pprintf(prn, "What??\n");
 3763         }
 3764     }
 3765     err = 1;
 3766     break;
 3767     }
 3768 
 3769     if (listcpy != NULL) {
 3770     free(listcpy);
 3771     }
 3772 
 3773     if (err == E_OK) {
 3774     err = 0;
 3775     }
 3776 
 3777     if (!err && plot_ok) {
 3778     maybe_schedule_graph_callback(s);
 3779     plot_ok = 0;
 3780     }
 3781 
 3782     if (callback_scheduled(s)) {
 3783     callback_exec(s, readfile, err);
 3784     }
 3785 
 3786  bailout:
 3787 
 3788     if (err) {
 3789     maybe_print_error_message(cmd, err, prn);
 3790     err = process_command_error(s, err);
 3791     }
 3792 
 3793     if (err) {
 3794     gretl_cmd_destroy_context(cmd);
 3795     } else {
 3796     /* this is a no-op if there's no warning */
 3797     warnmsg(prn);
 3798     }
 3799 
 3800     return err;
 3801 }
 3802 
 3803 /* called by functions, and by scripts executed from within
 3804    functions */
 3805 
 3806 int maybe_exec_line (ExecState *s, DATASET *dset, int *loopstart)
 3807 {
 3808     int err = 0;
 3809 
 3810     if (string_is_blank(s->line)) {
 3811     return 0;
 3812     }
 3813 
 3814     if (gretl_compiling_loop()) {
 3815     err = get_command_index(s, LOOP);
 3816     } else {
 3817     /* FIXME last arg to parse_command_line() ? */
 3818     err = parse_command_line(s, dset, NULL);
 3819     if (loopstart != NULL && s->cmd->ci == LOOP) {
 3820         *loopstart = 1;
 3821     }
 3822     }
 3823 
 3824     if (err) {
 3825         errmsg(err, s->prn);
 3826         return err;
 3827     }
 3828 
 3829     gretl_exec_state_transcribe_flags(s, s->cmd);
 3830 
 3831     if (s->cmd->ci < 0) {
 3832     return 0; /* nothing there, or a comment */
 3833     }
 3834 
 3835     if (s->cmd->ci == LOOP || gretl_compiling_loop()) {
 3836     /* accumulating loop commands */
 3837     err = gretl_loop_append_line(s, dset);
 3838     if (err) {
 3839         errmsg(err, s->prn);
 3840         return err;
 3841     }
 3842     return 0;
 3843     }
 3844 
 3845     s->pmod = NULL; /* be on the safe side */
 3846 
 3847     if (s->cmd->ci == FUNCERR) {
 3848     err = E_FUNCERR;
 3849     } else {
 3850     /* note: error messages may be printed to s->prn */
 3851     err = gretl_cmd_exec(s, dset);
 3852     }
 3853 
 3854     return err;
 3855 }
 3856 
 3857 /**
 3858  * get_command_index:
 3859  * @s: pointer to execution state
 3860  * @cmode: compilation mode: LOOP or FUNC
 3861   *
 3862  * Parse @line and assign to the %ci field of @s->cmd the index number of
 3863  * the command embedded in @s->line.  Note: this is a "lite" version of
 3864  * parse_command_line().  It is used when commands are being stacked
 3865  * for execution within a loop. Command options are not parsed out.
 3866  *
 3867  * Returns: 1 on error, otherwise 0.
 3868  */
 3869 
 3870 int get_command_index (ExecState *s, int cmode)
 3871 {
 3872     CMD *cmd = s->cmd;
 3873     char *line = s->line;
 3874     int err = 0;
 3875 
 3876     gretl_cmd_clear(cmd);
 3877 
 3878 #if CMD_DEBUG
 3879     fprintf(stderr, "get_command_index2: line='%s'\n", line);
 3880 #endif
 3881 
 3882     if ((cmd->context == FOREIGN || cmd->context == MPI) &&
 3883     !ends_foreign_block(line)) {
 3884     cmd->opt = OPT_NONE;
 3885     cmd->ci = cmd->context;
 3886     return 0;
 3887     }
 3888 
 3889     if (filter_comments(line, cmd)) {
 3890     return 0;
 3891     }
 3892 
 3893     err = real_parse_command(s, NULL, cmode, NULL);
 3894 
 3895     if (!err && cmd->ci == 0) {
 3896     /* maybe genr via series name? */
 3897     const char *s = cmd->toks[0].s;
 3898 
 3899     if (s != NULL) {
 3900         if (*s == '$' || *s == '@') s++;
 3901         if (strlen(s) == gretl_namechar_spn(s)) {
 3902         cmd->ci = GENR;
 3903         }
 3904     }
 3905     }
 3906 
 3907     if (!err && cmd->ci == 0) {
 3908     /* FIXME watch out for fallout! (2012-03-01) */
 3909     cmd->ci = CMD_NULL;
 3910     err = E_PARSE;
 3911     }
 3912 
 3913     if (err) {
 3914     return err;
 3915     }
 3916 
 3917     if (cmd->ci == END) {
 3918     cmd->context = 0;
 3919     } else if (cmd->context) {
 3920     cmd->ci = cmd->context;
 3921     }
 3922 
 3923     if (cmd->ci == NLS || cmd->ci == MLE ||
 3924     cmd->ci == GMM || cmd->ci == FOREIGN ||
 3925     cmd->ci == PLOT || cmd->ci == MPI) {
 3926     cmd->context = cmd->ci;
 3927     }
 3928 
 3929 #if CMD_DEBUG
 3930     fprintf(stderr, " get_command_index: cmd->ci set to %d\n", cmd->ci);
 3931 #endif
 3932 
 3933     return 0;
 3934 }
 3935 
 3936 void gretl_cmd_set_context (CMD *cmd, int ci)
 3937 {
 3938     cmd->context = ci;
 3939 }
 3940 
 3941 void gretl_cmd_destroy_context (CMD *cmd)
 3942 {
 3943     if (cmd->context == FOREIGN || cmd->context == MPI) {
 3944     foreign_destroy();
 3945     }
 3946     cmd->context = 0;
 3947     *cmd->savename = '\0';
 3948 }
 3949 
 3950 gretlopt gretl_cmd_get_opt (const CMD *cmd)
 3951 {
 3952     return cmd->opt;
 3953 }
 3954 
 3955 void gretl_cmd_set_opt (CMD *cmd, gretlopt opt)
 3956 {
 3957     cmd->opt = opt;
 3958 }
 3959 
 3960 const char *gretl_cmd_get_savename (CMD *cmd)
 3961 {
 3962     return cmd->savename;
 3963 }
 3964 
 3965 #define PMDEBUG 0
 3966 
 3967 void gretl_exec_state_init (ExecState *s,
 3968                 ExecFlags flags,
 3969                 char *line,
 3970                 CMD *cmd,
 3971                 MODEL *model,
 3972                 PRN *prn)
 3973 {
 3974     s->flags = flags;
 3975 
 3976     s->line = line;
 3977     if (s->line != NULL) {
 3978     *s->line = '\0';
 3979     }
 3980     s->more = NULL;
 3981 
 3982     s->cmd = cmd;
 3983     if (s->cmd != NULL) {
 3984     s->cmd->ci = 0;
 3985     }
 3986 
 3987     *s->runfile = '\0';
 3988 
 3989     s->model = model;
 3990     s->prn = prn;
 3991 
 3992     s->pmod = NULL;
 3993     s->sys = NULL;
 3994     s->rset = NULL;
 3995     s->var = NULL;
 3996     s->in_comment = 0;
 3997     s->padded = 0;
 3998 
 3999     if (flags == FUNCTION_EXEC) {
 4000     /* On entry to function execution we check if there's
 4001        a 'last model' in place. If so, we want to make
 4002        this invisible within the function, but set things
 4003        up so that we can restore it as last model on
 4004        exit from the function -- the idea being that
 4005        executing a function should not change the 'last
 4006        model' state at caller level. To achieve this we
 4007        need to take out a 'private' reference to the
 4008        model, stored in the ExecState, and then remove
 4009        it from last model position for the present.
 4010     */
 4011     s->prev_model = get_last_model(&s->prev_type);
 4012     if (s->prev_model != NULL) {
 4013 #if PMDEBUG
 4014         fprintf(stderr, "ExecState %p: set prev_model %p\n",
 4015             (void *) s, s->prev_model);
 4016 #endif
 4017         gretl_object_ref(s->prev_model, s->prev_type);
 4018         set_as_last_model(NULL, GRETL_OBJ_NULL);
 4019     }
 4020     s->prev_model_count = get_model_count();
 4021     } else {
 4022     s->prev_model = NULL;
 4023     s->prev_type = GRETL_OBJ_NULL;
 4024     s->prev_model_count = -1;
 4025     }
 4026 
 4027     s->submask = NULL;
 4028     s->callback = NULL;
 4029 }
 4030 
 4031 void function_state_init (CMD *cmd, ExecState *state, int *indent0)
 4032 {
 4033     cmd->list = NULL;
 4034     cmd->auxlist = NULL;
 4035     cmd->param = NULL;
 4036     cmd->parm2 = NULL;
 4037     /* FIXME tokenize more needed? */
 4038 
 4039     state->cmd = NULL;
 4040     state->model = NULL;
 4041     state->submask = NULL;
 4042 
 4043     state->padded = 0;
 4044 
 4045     *indent0 = gretl_if_state_record();
 4046 }
 4047 
 4048 void gretl_exec_state_set_callback (ExecState *s, EXEC_CALLBACK callback,
 4049                     gretlopt opt)
 4050 {
 4051     s->callback = callback;
 4052     s->pmod = NULL;
 4053 
 4054     if (opt & OPT_G) {
 4055     gui_callback = callback;
 4056     }
 4057 }
 4058 
 4059 EXEC_CALLBACK get_gui_callback (void)
 4060 {
 4061     return gui_callback;
 4062 }
 4063 
 4064 void gretl_exec_state_clear (ExecState *s)
 4065 {
 4066     gretl_cmd_free(s->cmd);
 4067 
 4068     if (s->flags & FUNCTION_EXEC) {
 4069     /* Restore whatever was the 'last model' before
 4070        function execution. Note that this includes
 4071        the case where there was no 'last model', in
 4072        which case we restore the null state. Drop
 4073        the extra refcount for the model we put into
 4074        last model position (if any), so we don't end
 4075        up leaking memory.
 4076     */
 4077     set_as_last_model(s->prev_model, s->prev_type);
 4078     if (s->prev_model != NULL) {
 4079         gretl_object_unref(s->prev_model, s->prev_type);
 4080     }
 4081 #if PMDEBUG
 4082     fprintf(stderr, "ExecState %p, set prev_model %p as last_model\n",
 4083         (void *) s, (void *) s->prev_model);
 4084 #endif
 4085     /* restore the previous model count */
 4086     if (s->prev_model_count >= 0) {
 4087         set_model_count(s->prev_model_count);
 4088     }
 4089     }
 4090 
 4091     destroy_working_model(s->model);
 4092 
 4093     s->prev_model = NULL;
 4094     s->prev_type = GRETL_OBJ_NULL;
 4095     s->prev_model_count = -1;
 4096 
 4097     free_subsample_mask(s->submask);
 4098 }
 4099 
 4100 void gretl_exec_state_destroy (ExecState *s)
 4101 {
 4102     free_subsample_mask(s->submask);
 4103     gretl_abort_compiling_loop();
 4104     free(s);
 4105 }
 4106 
 4107 void gretl_exec_state_uncomment (ExecState *s)
 4108 {
 4109     s->in_comment = 0;
 4110     s->cmd->flags &= ~CMD_IGNORE;
 4111 }
 4112 
 4113 void gretl_exec_state_transcribe_flags (ExecState *s, CMD *cmd)
 4114 {
 4115     s->in_comment = (cmd_ignore(cmd))? 1 : 0;
 4116 }
 4117 
 4118 void gretl_exec_state_set_model (ExecState *s, MODEL *pmod)
 4119 {
 4120     s->pmod = pmod;
 4121 }
 4122 
 4123 int process_command_error (ExecState *s, int err)
 4124 {
 4125     int ret = err;
 4126 
 4127     if (err) {
 4128     if (gretl_compiling_function() ||
 4129         gretl_compiling_loop()) {
 4130         ; /* pass the error through */
 4131     } else if (s->cmd->flags & CMD_CATCH) {
 4132         /* local "continue on error" */
 4133         set_gretl_errno(err);
 4134         s->cmd->flags ^= CMD_CATCH;
 4135         ret = 0;
 4136     }
 4137     }
 4138 
 4139     if (ret && print_redirection_level(s->prn) > 0) {
 4140     print_end_redirection(s->prn);
 4141     pputs(s->prn, _("An error occurred when 'outfile' was active\n"));
 4142     }
 4143 
 4144     return ret;
 4145 }