X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fcommand.c;h=803b5398888dec3c739c748afa8c13059d272ec3;hb=beac6e15a941bd498ae9301cc91e409653be6c1a;hp=4083daad6f876ed7fb08896f56845e2fd819b611;hpb=f5c108becd49d78f4898cab11352291f5689d24e;p=pspp-builds.git diff --git a/src/language/command.c b/src/language/command.c index 4083daad..803b5398 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 @@ -25,6 +23,12 @@ #include #include #include +#if HAVE_SYS_WAIT_H +#include +#endif +#if HAVE_READLINE +#include +#endif #include #include @@ -33,22 +37,16 @@ #include #include #include -#include #include #include #include #include #include -#include -#include +#include +#include -#if HAVE_SYS_WAIT_H -#include -#endif - -#if HAVE_READLINE -#include -#endif +#include "xalloc.h" +#include "xmalloca.h" #include "gettext.h" #define _(msgid) gettext (msgid) @@ -142,11 +140,7 @@ cmd_parse_in_state (struct lexer *lexer, struct dataset *ds, { int result; - som_new_series (); - result = do_parse_command (lexer, ds, state); - if (cmd_result_is_failure (result)) - lex_discard_rest_of_command (lexer); assert (!proc_is_open (ds)); unset_cmd_algorithm (); @@ -171,58 +165,88 @@ 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; + const struct command *command = NULL; enum cmd_result result; + bool opened = false; /* Read the command's first token. */ prompt_set_style (PROMPT_FIRST); set_completion_state (state); lex_get (lexer); if (lex_token (lexer) == T_STOP) - return CMD_EOF; + { + 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; + } + text_item_submit (text_item_create (TEXT_ITEM_COMMAND_OPEN, command->name)); + opened = true; + + if (command->function == NULL) + { + msg (SE, _("%s is not yet implemented."), command->name); + result = CMD_NOT_IMPLEMENTED; } - else if ((command->flags & F_TESTING) && !get_testing_mode ()) + 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; } - 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; } else if (!in_correct_state (command, state)) { report_state_mismatch (command, state); - return CMD_FAILURE; + result = CMD_FAILURE; + } + else + { + /* Execute command. */ + msg_set_command_name (command->name); + result = command->function (lexer, ds); + msg_set_command_name (NULL); } - - /* Execute command. */ - msg_set_command_name (command->name); - tab_set_command_name (command->name); - 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)) + { + lex_discard_rest_of_command (lexer); + if (source_stream_current_error_mode ( + lex_get_source_stream (lexer)) == ERRMODE_STOP ) + { + msg (MW, _("Error encountered while ERROR=STOP is effective.")); + result = CMD_CASCADING_FAILURE; + } + } + + if (opened) + text_item_submit (text_item_create (TEXT_ITEM_COMMAND_CLOSE, + command->name)); + return result; } @@ -594,37 +618,77 @@ 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); + msg (SE, _("%s is not allowed inside %s."), command->name, "INPUT PROGRAM" ); else if (state == CMD_STATE_FILE_TYPE) - msg (SE, _("%s is not allowed inside FILE TYPE."), command->name); + msg (SE, _("%s is not allowed inside %s."), command->name, "FILE TYPE"); return false; } @@ -651,8 +715,8 @@ cmd_complete (const char *prefix, const struct command **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)) @@ -701,7 +765,7 @@ cmd_execute (struct lexer *lexer, struct dataset *ds) int cmd_erase (struct lexer *lexer, struct dataset *ds UNUSED) { - if (get_safer_mode ()) + if (settings_get_safer_mode ()) { msg (SE, _("This command not allowed when the SAFER option is set.")); return CMD_FAILURE; @@ -752,7 +816,7 @@ shell (void) { 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")) @@ -809,7 +873,7 @@ cmd_host (struct lexer *lexer, struct dataset *ds UNUSED) { int look_ahead; - if (get_safer_mode ()) + if (settings_get_safer_mode ()) { msg (SE, _("This command not allowed when the SAFER option is set.")); return CMD_FAILURE;