X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fcommand.c;h=c00d94b9c4b3597bcc2416ae0e29fd56018b229f;hb=e9599a2f8e86d986fff1518682ba8942bd67d1c0;hp=70d5b02e747416e9f08554d4c57868196aef3812;hpb=44326932c8227c64a87f7a92ef16ce83c2fba2d4;p=pspp-builds.git diff --git a/src/language/command.c b/src/language/command.c index 70d5b02e..c00d94b9 100644 --- a/src/language/command.c +++ b/src/language/command.c @@ -1,20 +1,18 @@ -/* PSPP - computes sample statistics. - Copyright (C) 1997-9, 2000 Free Software Foundation, Inc. +/* PSPP - a program for statistical analysis. + Copyright (C) 1997-9, 2000, 2009 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ + along with this program. If not, see . */ #include @@ -26,13 +24,13 @@ #include #include +#include #include #include #include #include #include #include -#include #include #include #include @@ -40,6 +38,7 @@ #include #include #include +#include #if HAVE_SYS_WAIT_H #include @@ -49,6 +48,9 @@ #include #endif +#include "xalloc.h" +#include "xmalloca.h" + #include "gettext.h" #define _(msgid) gettext (msgid) #define N_(msgid) msgid @@ -56,7 +58,7 @@ /* Returns true if RESULT is a valid "enum cmd_result", false otherwise. */ static inline bool -cmd_result_is_valid (enum cmd_result result) +cmd_result_is_valid (enum cmd_result result) { return (result == CMD_SUCCESS || result == CMD_EOF || result == CMD_FINISH || (result >= CMD_PRIVATE_FIRST && result <= CMD_PRIVATE_LAST) @@ -67,7 +69,7 @@ cmd_result_is_valid (enum cmd_result result) /* Returns true if RESULT indicates success, false otherwise. */ bool -cmd_result_is_success (enum cmd_result result) +cmd_result_is_success (enum cmd_result result) { assert (cmd_result_is_valid (result)); return result > 0; @@ -76,7 +78,7 @@ cmd_result_is_success (enum cmd_result result) /* Returns true if RESULT indicates failure, false otherwise. */ bool -cmd_result_is_failure (enum cmd_result result) +cmd_result_is_failure (enum cmd_result result) { assert (cmd_result_is_valid (result)); return result < 0; @@ -93,7 +95,7 @@ enum states }; /* Other command requirements. */ -enum flags +enum flags { F_ENHANCED = 0x10, /* Allowed only in enhanced syntax mode. */ F_TESTING = 0x20, /* Allowed only in testing mode. */ @@ -113,7 +115,7 @@ struct command /* Define the command array. */ #define DEF_CMD(STATES, FLAGS, NAME, FUNCTION) {STATES, FLAGS, NAME, FUNCTION}, #define UNIMPL_CMD(NAME, DESCRIPTION) {S_ANY, 0, NAME, NULL}, -static const struct command commands[] = +static const struct command commands[] = { #include "command.def" }; @@ -125,7 +127,7 @@ static const size_t command_cnt = sizeof commands / sizeof *commands; static bool in_correct_state (const struct command *, enum cmd_state); static bool report_state_mismatch (const struct command *, enum cmd_state); static const struct command *find_command (const char *name); -static void set_completion_state (enum cmd_state); +static void set_completion_state (enum cmd_state); /* Command parser. */ @@ -147,8 +149,11 @@ cmd_parse_in_state (struct lexer *lexer, struct dataset *ds, if (cmd_result_is_failure (result)) lex_discard_rest_of_command (lexer); + assert (!proc_is_open (ds)); unset_cmd_algorithm (); dict_clear_aux (dataset_dict (ds)); + if (!dataset_end_of_command (ds)) + result = CMD_CASCADING_FAILURE; return result; } @@ -158,7 +163,7 @@ cmd_parse (struct lexer *lexer, struct dataset *ds) { const struct dictionary *dict = dataset_dict (ds); return cmd_parse_in_state (lexer, ds, - proc_has_source (ds) && + proc_has_active_file (ds) && dict_get_var_cnt (dict) > 0 ? CMD_STATE_DATA : CMD_STATE_INITIAL); } @@ -167,7 +172,8 @@ cmd_parse (struct lexer *lexer, struct dataset *ds) /* Parses an entire command, from command name to terminating dot. */ static enum cmd_result -do_parse_command (struct lexer *lexer, struct dataset *ds, enum cmd_state state) +do_parse_command (struct lexer *lexer, + struct dataset *ds, enum cmd_state state) { const struct command *command; enum cmd_result result; @@ -177,38 +183,50 @@ do_parse_command (struct lexer *lexer, struct dataset *ds, enum cmd_state state) set_completion_state (state); lex_get (lexer); if (lex_token (lexer) == T_STOP) - return CMD_EOF; - else if (lex_token (lexer) == '.') + { + result = CMD_EOF; + goto finish; + } + else if (lex_token (lexer) == '.') { /* Null commands can result from extra empty lines. */ - return CMD_SUCCESS; + result = CMD_SUCCESS; + goto finish; } + prompt_set_style (PROMPT_LATER); /* Parse the command name. */ command = parse_command_name (lexer); if (command == NULL) - return CMD_FAILURE; - else if (command->function == NULL) { - msg (SE, _("%s is unimplemented."), command->name); - return CMD_NOT_IMPLEMENTED; + result = CMD_FAILURE; + goto finish; } - else if ((command->flags & F_TESTING) && !get_testing_mode ()) + else if (command->function == NULL) + { + msg (SE, _("%s is not yet implemented."), command->name); + result = CMD_NOT_IMPLEMENTED; + goto finish; + } + else if ((command->flags & F_TESTING) && !settings_get_testing_mode ()) { msg (SE, _("%s may be used only in testing mode."), command->name); - return CMD_FAILURE; + result = CMD_FAILURE; + goto finish; } - else if ((command->flags & F_ENHANCED) && get_syntax () != ENHANCED) + else if ((command->flags & F_ENHANCED) && settings_get_syntax () != ENHANCED) { msg (SE, _("%s may be used only in enhanced syntax mode."), command->name); - return CMD_FAILURE; + result = CMD_FAILURE; + goto finish; } - else if (!in_correct_state (command, state)) + else if (!in_correct_state (command, state)) { report_state_mismatch (command, state); - return CMD_FAILURE; + result = CMD_FAILURE; + goto finish; } /* Execute command. */ @@ -217,18 +235,31 @@ do_parse_command (struct lexer *lexer, struct dataset *ds, enum cmd_state state) result = command->function (lexer, ds); tab_set_command_name (NULL); msg_set_command_name (NULL); - + assert (cmd_result_is_valid (result)); + + finish: + if ( cmd_result_is_failure (result)) + { + const struct source_stream *cs = lex_get_source_stream (lexer); + + if ( source_stream_current_error_mode (cs) == ERRMODE_STOP ) + { + msg (MW, _("Error encountered while ERROR=STOP is effective.")); + result = CMD_CASCADING_FAILURE; + } + } + return result; } static size_t match_strings (const char *a, size_t a_len, - const char *b, size_t b_len) + const char *b, size_t b_len) { size_t match_len = 0; - - while (a_len > 0 && b_len > 0) + + while (a_len > 0 && b_len > 0) { /* Mismatch always returns zero. */ if (toupper ((unsigned char) *a++) != toupper ((unsigned char) *b++)) @@ -250,21 +281,21 @@ match_strings (const char *a, size_t a_len, non-alphanumeric characters. Words are delimited by spaces. */ static const char * -find_word (const char *string, size_t *word_len) +find_word (const char *string, size_t *word_len) { /* Skip whitespace and asterisks. */ while (isspace ((unsigned char) *string)) string++; /* End of string? */ - if (*string == '\0') + if (*string == '\0') { *word_len = 0; return NULL; } /* Special one-character word? */ - if (!isalnum ((unsigned char) *string)) + if (!isalnum ((unsigned char) *string)) { *word_len = 1; return string; @@ -281,7 +312,7 @@ find_word (const char *string, size_t *word_len) /* Returns true if strings A and B can be confused based on their first three letters. */ static bool -conflicting_3char_prefixes (const char *a, const char *b) +conflicting_3char_prefixes (const char *a, const char *b) { size_t aw_len, bw_len; const char *aw, *bw; @@ -293,7 +324,7 @@ conflicting_3char_prefixes (const char *a, const char *b) /* Words that are the same don't conflict. */ if (aw_len == bw_len && !buf_compare_case (aw, bw, aw_len)) return false; - + /* Words that are otherwise the same in the first three letters do conflict. */ return ((aw_len > 3 && bw_len > 3) @@ -304,7 +335,7 @@ conflicting_3char_prefixes (const char *a, const char *b) /* Returns true if CMD can be confused with another command based on the first three letters of its first word. */ static bool -conflicting_3char_prefix_command (const struct command *cmd) +conflicting_3char_prefix_command (const struct command *cmd) { assert (cmd >= commands && cmd < commands + command_cnt); @@ -345,18 +376,18 @@ cmd_match_words (const struct command *cmd, size_t match_chars = match_strings (word, word_len, words[word_idx], strlen (words[word_idx])); - if (match_chars == 0) + if (match_chars == 0) { /* Mismatch. */ return MISMATCH; } - else if (match_chars == 1 || match_chars == 2) + else if (match_chars == 1 || match_chars == 2) { /* One- and two-character abbreviations are not acceptable. */ - return MISMATCH; + return MISMATCH; } - else if (match_chars == 3) + else if (match_chars == 3) { /* Three-character abbreviations are acceptable in the first word of a command if there are @@ -365,29 +396,29 @@ cmd_match_words (const struct command *cmd, if (word_idx == 0 && conflicting_3char_prefix_command (cmd)) return MISMATCH; } - else /* match_chars > 3 */ + else /* match_chars > 3 */ { /* Four-character and longer abbreviations are always acceptable. */ } } - if (word == NULL && word_idx == word_cnt) + if (word == NULL && word_idx == word_cnt) { /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR"}. */ return COMPLETE_MATCH; } - else if (word == NULL) + else if (word == NULL) { /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR", "BAZ"}. */ - return MISMATCH; + return MISMATCH; } - else + else { /* cmd->name = "FOO BAR BAZ", words[] = {"FOO", "BAR"}. */ if (word[0] == '-' && dash_possible != NULL) *dash_possible = 1; - return PARTIAL_MATCH; + return PARTIAL_MATCH; } } @@ -397,16 +428,16 @@ cmd_match_words (const struct command *cmd, otherwise it is set to 0. */ static int count_matching_commands (char *const words[], size_t word_cnt, - int *dash_possible) + int *dash_possible) { const struct command *cmd; int cmd_match_count; cmd_match_count = 0; *dash_possible = 0; - for (cmd = commands; cmd < commands + command_cnt; cmd++) - if (cmd_match_words (cmd, words, word_cnt, dash_possible) != MISMATCH) - cmd_match_count++; + for (cmd = commands; cmd < commands + command_cnt; cmd++) + if (cmd_match_words (cmd, words, word_cnt, dash_possible) != MISMATCH) + cmd_match_count++; return cmd_match_count; } @@ -415,25 +446,25 @@ count_matching_commands (char *const words[], size_t word_cnt, a complete match. Returns a null pointer if no such command exists. */ static const struct command * -get_complete_match (char *const words[], size_t word_cnt) +get_complete_match (char *const words[], size_t word_cnt) { const struct command *cmd; - - for (cmd = commands; cmd < commands + command_cnt; cmd++) - if (cmd_match_words (cmd, words, word_cnt, NULL) == COMPLETE_MATCH) - return cmd; - + + for (cmd = commands; cmd < commands + command_cnt; cmd++) + if (cmd_match_words (cmd, words, word_cnt, NULL) == COMPLETE_MATCH) + return cmd; + return NULL; } /* Returns the command with the given exact NAME. Aborts if no such command exists. */ static const struct command * -find_command (const char *name) +find_command (const char *name) { const struct command *cmd; - - for (cmd = commands; cmd < commands + command_cnt; cmd++) + + for (cmd = commands; cmd < commands + command_cnt; cmd++) if (!strcmp (cmd->name, name)) return cmd; NOT_REACHED (); @@ -441,10 +472,10 @@ find_command (const char *name) /* Frees the WORD_CNT words in WORDS. */ static void -free_words (char *words[], size_t word_cnt) +free_words (char *words[], size_t word_cnt) { size_t idx; - + for (idx = 0; idx < word_cnt; idx++) free (words[idx]); } @@ -452,17 +483,17 @@ free_words (char *words[], size_t word_cnt) /* Flags an error that the command whose name is given by the WORD_CNT words in WORDS is unknown. */ static void -unknown_command_error (struct lexer *lexer, char *const words[], size_t word_cnt) +unknown_command_error (struct lexer *lexer, char *const words[], size_t word_cnt) { - if (word_cnt == 0) + if (word_cnt == 0) lex_error (lexer, _("expecting command name")); - else + else { struct string s; size_t i; ds_init_empty (&s); - for (i = 0; i < word_cnt; i++) + for (i = 0; i < word_cnt; i++) { if (i != 0) ds_put_char (&s, ' '); @@ -486,21 +517,21 @@ parse_command_name (struct lexer *lexer) int complete_word_cnt; int dash_possible; - if (lex_token (lexer) == T_EXP || - lex_token (lexer) == '*' || lex_token (lexer) == '[') + if (lex_token (lexer) == T_EXP || + lex_token (lexer) == '*' || lex_token (lexer) == '[') return find_command ("COMMENT"); dash_possible = 0; word_cnt = complete_word_cnt = 0; - while (lex_token (lexer) == T_ID || (dash_possible && lex_token (lexer) == '-')) + while (lex_token (lexer) == T_ID || (dash_possible && lex_token (lexer) == '-')) { int cmd_match_cnt; - + assert (word_cnt < sizeof words / sizeof *words); - if (lex_token (lexer) == T_ID) + if (lex_token (lexer) == T_ID) { words[word_cnt] = ds_xstrdup (lex_tokstr (lexer)); - str_uppercase (words[word_cnt]); + str_uppercase (words[word_cnt]); } else if (lex_token (lexer) == '-') words[word_cnt] = xstrdup ("-"); @@ -508,12 +539,12 @@ parse_command_name (struct lexer *lexer) cmd_match_cnt = count_matching_commands (words, word_cnt, &dash_possible); - if (cmd_match_cnt == 0) + if (cmd_match_cnt == 0) break; - else if (cmd_match_cnt == 1) + else if (cmd_match_cnt == 1) { const struct command *command = get_complete_match (words, word_cnt); - if (command != NULL) + if (command != NULL) { if (!(command->flags & F_KEEP_FINAL_TOKEN)) lex_get (lexer); @@ -532,7 +563,7 @@ parse_command_name (struct lexer *lexer) /* If we saw a complete command name earlier, drop back to it. */ - if (complete_word_cnt) + if (complete_word_cnt) { int pushback_word_cnt; const struct command *command; @@ -546,14 +577,14 @@ parse_command_name (struct lexer *lexer) pushback_word_cnt = complete_word_cnt + 1; if (command->flags & F_KEEP_FINAL_TOKEN) pushback_word_cnt--; - + /* FIXME: We only support one-token pushback. */ assert (pushback_word_cnt + 1 >= word_cnt); - while (word_cnt > pushback_word_cnt) + while (word_cnt > pushback_word_cnt) { word_cnt--; - if (strcmp (words[word_cnt], "-")) + if (strcmp (words[word_cnt], "-")) lex_put_back_id (lexer, words[word_cnt]); else lex_put_back (lexer, '-'); @@ -573,7 +604,7 @@ parse_command_name (struct lexer *lexer) /* Returns true if COMMAND is allowed in STATE, false otherwise. */ static bool -in_correct_state (const struct command *command, enum cmd_state state) +in_correct_state (const struct command *command, enum cmd_state state) { return ((state == CMD_STATE_INITIAL && command->states & S_INITIAL) || (state == CMD_STATE_DATA && command->states & S_DATA) @@ -590,32 +621,72 @@ report_state_mismatch (const struct command *command, enum cmd_state state) assert (!in_correct_state (command, state)); if (state == CMD_STATE_INITIAL || state == CMD_STATE_DATA) { - const char *allowed[3]; - int allowed_cnt; - char *s; - - allowed_cnt = 0; - if (command->states & S_INITIAL) - allowed[allowed_cnt++] = _("before the active file has been defined"); - else if (command->states & S_DATA) - allowed[allowed_cnt++] = _("after the active file has been defined"); - if (command->states & S_INPUT_PROGRAM) - allowed[allowed_cnt++] = _("inside INPUT PROGRAM"); - if (command->states & S_FILE_TYPE) - allowed[allowed_cnt++] = _("inside FILE TYPE"); - - if (allowed_cnt == 1) - s = xstrdup (allowed[0]); - else if (allowed_cnt == 2) - s = xasprintf (_("%s or %s"), allowed[0], allowed[1]); - else if (allowed_cnt == 3) - s = xasprintf (_("%s, %s, or %s"), allowed[0], allowed[1], allowed[2]); - else - NOT_REACHED (); - - msg (SE, _("%s is allowed only %s."), command->name, s); - - free (s); + switch (command->states) + { + /* One allowed state. */ + case S_INITIAL: + msg (SE, _("%s is allowed only before the active file has " + "been defined."), command->name); + break; + case S_DATA: + msg (SE, _("%s is allowed only after the active file has " + "been defined."), command->name); + break; + case S_INPUT_PROGRAM: + msg (SE, _("%s is allowed only inside INPUT PROGRAM."), + command->name); + break; + case S_FILE_TYPE: + msg (SE, _("%s is allowed only inside FILE TYPE."), command->name); + break; + + /* Two allowed states. */ + case S_INITIAL | S_DATA: + NOT_REACHED (); + case S_INITIAL | S_INPUT_PROGRAM: + msg (SE, _("%s is allowed only before the active file has " + "been defined or inside INPUT PROGRAM."), command->name); + break; + case S_INITIAL | S_FILE_TYPE: + msg (SE, _("%s is allowed only before the active file has " + "been defined or inside FILE TYPE."), command->name); + break; + case S_DATA | S_INPUT_PROGRAM: + msg (SE, _("%s is allowed only after the active file has " + "been defined or inside INPUT PROGRAM."), command->name); + break; + case S_DATA | S_FILE_TYPE: + msg (SE, _("%s is allowed only after the active file has " + "been defined or inside FILE TYPE."), command->name); + break; + case S_INPUT_PROGRAM | S_FILE_TYPE: + msg (SE, _("%s is allowed only inside INPUT PROGRAM " + "or inside FILE TYPE."), command->name); + break; + + /* Three allowed states. */ + case S_DATA | S_INPUT_PROGRAM | S_FILE_TYPE: + msg (SE, _("%s is allowed only after the active file has " + "been defined, inside INPUT PROGRAM, or inside " + "FILE TYPE."), command->name); + break; + case S_INITIAL | S_INPUT_PROGRAM | S_FILE_TYPE: + msg (SE, _("%s is allowed only before the active file has " + "been defined, inside INPUT PROGRAM, or inside " + "FILE TYPE."), command->name); + break; + case S_INITIAL | S_DATA | S_FILE_TYPE: + NOT_REACHED (); + case S_INITIAL | S_DATA | S_INPUT_PROGRAM: + NOT_REACHED (); + + /* Four allowed states. */ + case S_INITIAL | S_DATA | S_INPUT_PROGRAM | S_FILE_TYPE: + NOT_REACHED (); + + default: + NOT_REACHED (); + } } else if (state == CMD_STATE_INPUT_PROGRAM) msg (SE, _("%s is not allowed inside INPUT PROGRAM."), command->name); @@ -630,7 +701,7 @@ report_state_mismatch (const struct command *command, enum cmd_state state) static enum cmd_state completion_state = CMD_STATE_INITIAL; static void -set_completion_state (enum cmd_state state) +set_completion_state (enum cmd_state state) { completion_state = state; } @@ -645,10 +716,10 @@ cmd_complete (const char *prefix, const struct command **cmd) if (*cmd == NULL) *cmd = commands; - for (; *cmd < commands + command_cnt; (*cmd)++) + for (; *cmd < commands + command_cnt; (*cmd)++) if (!memcasecmp ((*cmd)->name, prefix, strlen (prefix)) - && (!((*cmd)->flags & F_TESTING) || get_testing_mode ()) - && (!((*cmd)->flags & F_ENHANCED) || get_syntax () == ENHANCED) + && (!((*cmd)->flags & F_TESTING) || settings_get_testing_mode ()) + && (!((*cmd)->flags & F_ENHANCED) || settings_get_syntax () == ENHANCED) && !((*cmd)->flags & F_ABBREV) && ((*cmd)->function != NULL) && in_correct_state (*cmd, completion_state)) @@ -687,7 +758,8 @@ cmd_n_of_cases (struct lexer *lexer, struct dataset *ds) int cmd_execute (struct lexer *lexer, struct dataset *ds) { - if (!procedure (ds, NULL, NULL)) + bool ok = casereader_destroy (proc_open (ds)); + if (!proc_commit (ds) || !ok) return CMD_CASCADING_FAILURE; return lex_end_of_command (lexer); } @@ -696,12 +768,12 @@ cmd_execute (struct lexer *lexer, struct dataset *ds) int cmd_erase (struct lexer *lexer, struct dataset *ds UNUSED) { - if (get_safer_mode ()) - { - msg (SE, _("This command not allowed when the SAFER option is set.")); - return CMD_FAILURE; - } - + if (settings_get_safer_mode ()) + { + msg (SE, _("This command not allowed when the SAFER option is set.")); + return CMD_FAILURE; + } + if (!lex_force_match_id (lexer, "FILE")) return CMD_FAILURE; lex_match (lexer, '='); @@ -724,7 +796,7 @@ static bool shell (void) { int pid; - + pid = fork (); switch (pid) { @@ -732,10 +804,10 @@ shell (void) { const char *shell_fn; char *shell_process; - + { int i; - + for (i = 3; i < 20; i++) close (i); } @@ -743,17 +815,17 @@ shell (void) shell_fn = getenv ("SHELL"); if (shell_fn == NULL) shell_fn = "/bin/sh"; - + { const char *cp = strrchr (shell_fn, '/'); cp = cp ? &cp[1] : shell_fn; - shell_process = local_alloc (strlen (cp) + 8); + shell_process = xmalloca (strlen (cp) + 8); strcpy (shell_process, "-"); strcat (shell_process, cp); if (strcmp (cp, "sh")) shell_process[0] = '+'; } - + execl (shell_fn, shell_process, NULL); _exit (1); @@ -785,7 +857,7 @@ shell (void) static bool run_command (const char *command) { - if (system (NULL) == 0) + if (system (NULL) == 0) { msg (SE, _("Command shell not supported on this platform.")); return false; @@ -804,14 +876,14 @@ cmd_host (struct lexer *lexer, struct dataset *ds UNUSED) { int look_ahead; - if (get_safer_mode ()) - { - msg (SE, _("This command not allowed when the SAFER option is set.")); - return CMD_FAILURE; - } + if (settings_get_safer_mode ()) + { + msg (SE, _("This command not allowed when the SAFER option is set.")); + return CMD_FAILURE; + } look_ahead = lex_look_ahead (lexer); - if (look_ahead == '.') + if (look_ahead == '.') { lex_get (lexer); return shell () ? CMD_SUCCESS : CMD_FAILURE; @@ -819,7 +891,7 @@ cmd_host (struct lexer *lexer, struct dataset *ds UNUSED) else if (look_ahead == '\'' || look_ahead == '"') { bool ok; - + lex_get (lexer); if (!lex_force_string (lexer)) NOT_REACHED (); @@ -828,9 +900,9 @@ cmd_host (struct lexer *lexer, struct dataset *ds UNUSED) lex_get (lexer); return ok ? lex_end_of_command (lexer) : CMD_FAILURE; } - else + else { - bool ok = run_command (lex_rest_of_line (lexer, NULL)); + bool ok = run_command (lex_rest_of_line (lexer)); lex_discard_line (lexer); return ok ? CMD_SUCCESS : CMD_FAILURE; } @@ -840,7 +912,7 @@ cmd_host (struct lexer *lexer, struct dataset *ds UNUSED) int cmd_new_file (struct lexer *lexer, struct dataset *ds) { - discard_variables (ds); + proc_discard_active_file (ds); return lex_end_of_command (lexer); }