X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fcommand.c;h=bffd13ebb0d74b119de6d296b7e4f4fe3ba91f60;hb=91240a3a96a0ffed8b1bcc4866378b4d865e6f6e;hp=068ae0ea631a7f19da70898336a2414052205c55;hpb=cd221d80fafb54e550398c6de105d4c1b7f02ba0;p=pspp diff --git a/src/language/command.c b/src/language/command.c index 068ae0ea63..bffd13ebb0 100644 --- a/src/language/command.c +++ b/src/language/command.c @@ -55,9 +55,6 @@ cmd_result_is_valid (enum cmd_result result) 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: @@ -89,19 +86,23 @@ cmd_result_is_failure (enum cmd_result result) /* 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. */ @@ -123,10 +124,10 @@ static const struct command commands[] = #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); /* Command parser. */ @@ -162,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, dataset_has_source (ds) && - dict_get_var_cnt (dict) > 0 ? + dict_get_n_vars (dict) > 0 ? CMD_STATE_DATA : CMD_STATE_INITIAL); } @@ -262,7 +263,7 @@ find_best_match (struct substring s, const struct command **matchp) 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); @@ -360,22 +361,22 @@ parse_command_name (struct lexer *lexer, int *n_tokens) 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: @@ -441,14 +442,35 @@ report_state_mismatch (const struct command *command, enum cmd_state state) 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; + } } /* Command name completion. */ @@ -471,7 +493,7 @@ cmd_complete (const char *prefix, const struct command **cmd) 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)