case CMD_SUCCESS:
case CMD_EOF:
case CMD_FINISH:
- case CMD_DATA_LIST:
- case CMD_END_CASE:
- case CMD_END_FILE:
case CMD_FAILURE:
case CMD_NOT_IMPLEMENTED:
case CMD_CASCADING_FAILURE:
/* Command processing states. */
enum states
{
- S_INITIAL = 0x01, /* Allowed before active dataset defined. */
- S_DATA = 0x02, /* Allowed after active dataset defined. */
- S_INPUT_PROGRAM = 0x04, /* Allowed in INPUT PROGRAM. */
- S_FILE_TYPE = 0x08, /* Allowed in FILE TYPE. */
- S_ANY = 0x0f /* Allowed anywhere. */
+ S_INITIAL = 1 << CMD_STATE_INITIAL,
+ S_DATA = 1 << CMD_STATE_DATA,
+ S_INPUT_PROGRAM = 1 << CMD_STATE_INPUT_PROGRAM,
+ S_FILE_TYPE = 1 << CMD_STATE_FILE_TYPE,
+ S_NESTED_DATA = 1 << CMD_STATE_NESTED_DATA,
+ S_NESTED_INPUT_PROGRAM = 1 << CMD_STATE_NESTED_INPUT_PROGRAM,
+
+ S_NESTED_ANY = S_NESTED_DATA | S_NESTED_INPUT_PROGRAM,
+ S_ANY = S_INITIAL | S_DATA | S_INPUT_PROGRAM | S_FILE_TYPE | S_NESTED_ANY,
};
/* Other command requirements. */
enum flags
{
- F_ENHANCED = 0x10, /* Allowed only in enhanced syntax mode. */
- F_TESTING = 0x20, /* Allowed only in testing mode. */
- F_ABBREV = 0x80 /* Not a candidate for name completion. */
+ F_ENHANCED = 1 << 0, /* Allowed only in enhanced syntax mode. */
+ F_TESTING = 1 << 1, /* Allowed only in testing mode. */
+ F_ABBREV = 1 << 2 /* Not a candidate for name completion. */
};
/* A single command. */
#undef DEF_CMD
#undef UNIMPL_CMD
-static const size_t command_cnt = sizeof commands / sizeof *commands;
+static const size_t n_commands = 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 void report_state_mismatch (const struct command *, enum cmd_state);
static void set_completion_state (enum cmd_state);
\f
/* Command parser. */
const struct dictionary *dict = dataset_dict (ds);
return cmd_parse_in_state (lexer, ds,
dataset_has_source (ds) &&
- dict_get_var_cnt (dict) > 0 ?
+ dict_get_n_vars (dict) > 0 ?
CMD_STATE_DATA : CMD_STATE_INITIAL);
}
int missing_words;
command_matcher_init (&cm, s);
- for (cmd = commands; cmd < &commands[command_cnt]; cmd++)
+ for (cmd = commands; cmd < &commands[n_commands]; cmd++)
command_matcher_add (&cm, ss_cstr (cmd->name), CONST_CAST (void *, cmd));
*matchp = command_matcher_get_match (&cm);
static bool
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)
- || (state == CMD_STATE_INPUT_PROGRAM
- && command->states & S_INPUT_PROGRAM)
- || (state == CMD_STATE_FILE_TYPE && command->states & S_FILE_TYPE));
+ return command->states & (1 << state);
}
/* Emits an appropriate error message for trying to invoke
COMMAND in STATE. */
-static bool
+static void
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)
+
+ switch (state)
{
- switch ((int) command->states)
+ case CMD_STATE_INITIAL:
+ case CMD_STATE_DATA:
+ switch ((int) command->states
+ & (S_INITIAL | S_DATA | S_INPUT_PROGRAM | S_FILE_TYPE))
{
/* One allowed state. */
case S_INITIAL:
default:
NOT_REACHED ();
}
- }
- else if (state == CMD_STATE_INPUT_PROGRAM)
- 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 %s."), command->name, "FILE TYPE");
+ break;
- return false;
+ case CMD_STATE_INPUT_PROGRAM:
+ msg (SE, _("%s is not allowed inside %s."),
+ command->name, "INPUT PROGRAM");
+ break;
+
+ case CMD_STATE_FILE_TYPE:
+ msg (SE, _("%s is not allowed inside %s."), command->name, "FILE TYPE");
+ break;
+
+ case CMD_STATE_NESTED_DATA:
+ case CMD_STATE_NESTED_INPUT_PROGRAM:
+ switch ((int) command->states & S_NESTED_ANY)
+ {
+ case 0:
+ msg (SE, _("%s is not allowed inside DO IF or LOOP."), command->name);
+ break;
+
+ case S_NESTED_DATA:
+ msg (SE, _("In INPUT PROGRAM, "
+ "%s is not allowed inside DO IF or LOOP."), command->name);
+ break;
+
+ default:
+ NOT_REACHED ();
+ }
+ break;
+ }
}
\f
/* Command name completion. */
if (*cmd == NULL)
*cmd = commands;
- for (; *cmd < commands + command_cnt; (*cmd)++)
+ for (; *cmd < commands + n_commands; (*cmd)++)
if (!memcasecmp ((*cmd)->name, prefix, strlen (prefix))
&& (!((*cmd)->flags & F_TESTING) || settings_get_testing_mode ())
&& (!((*cmd)->flags & F_ENHANCED) || settings_get_syntax () == ENHANCED)