-/* PSPP - computes sample statistics.
+/* PSPP - a program for statistical analysis.
Copyright (C) 1997-9, 2000 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 <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <data/variable.h>
#include <language/lexer/lexer.h>
#include <language/prompt.h>
-#include <libpspp/alloc.h>
#include <libpspp/assertion.h>
#include <libpspp/compiler.h>
#include <libpspp/message.h>
#include <libpspp/str.h>
#include <output/manager.h>
#include <output/table.h>
+#include <libpspp/getl.h>
#if HAVE_SYS_WAIT_H
#include <sys/wait.h>
#include <readline/readline.h>
#endif
+#include "xalloc.h"
+#include "xmalloca.h"
+
#include "gettext.h"
#define _(msgid) gettext (msgid)
#define N_(msgid) msgid
/* 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;
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;
+ {
+ result = CMD_FAILURE;
+ goto finish;
+ }
else if (command->function == NULL)
{
msg (SE, _("%s is unimplemented."), command->name);
- return CMD_NOT_IMPLEMENTED;
+ result = CMD_NOT_IMPLEMENTED;
+ goto finish;
}
- 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;
+ 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))
{
report_state_mismatch (command, state);
- return CMD_FAILURE;
+ result = CMD_FAILURE;
+ goto finish;
}
/* Execute command. */
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;
}
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);
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))
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;
{
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"))
{
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;