1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "language/command.h"
26 #include "data/casereader.h"
27 #include "data/dataset.h"
28 #include "data/dictionary.h"
29 #include "data/session.h"
30 #include "data/settings.h"
31 #include "data/variable.h"
32 #include "language/lexer/command-name.h"
33 #include "language/lexer/lexer.h"
34 #include "libpspp/assertion.h"
35 #include "libpspp/compiler.h"
36 #include "libpspp/i18n.h"
37 #include "libpspp/message.h"
38 #include "libpspp/str.h"
39 #include "output/driver.h"
40 #include "output/output-item.h"
45 #define _(msgid) gettext (msgid)
46 #define N_(msgid) msgid
48 /* Returns true if RESULT is a valid "enum cmd_result",
51 cmd_result_is_valid (enum cmd_result result)
59 case CMD_NOT_IMPLEMENTED:
60 case CMD_CASCADING_FAILURE:
68 /* Returns true if RESULT indicates success,
71 cmd_result_is_success (enum cmd_result result)
73 assert (cmd_result_is_valid (result));
77 /* Returns true if RESULT indicates failure,
80 cmd_result_is_failure (enum cmd_result result)
82 assert (cmd_result_is_valid (result));
86 /* Command processing states. */
89 S_INITIAL = 1 << CMD_STATE_INITIAL,
90 S_DATA = 1 << CMD_STATE_DATA,
91 S_INPUT_PROGRAM = 1 << CMD_STATE_INPUT_PROGRAM,
92 S_FILE_TYPE = 1 << CMD_STATE_FILE_TYPE,
93 S_NESTED_DATA = 1 << CMD_STATE_NESTED_DATA,
94 S_NESTED_INPUT_PROGRAM = 1 << CMD_STATE_NESTED_INPUT_PROGRAM,
96 S_NESTED_ANY = S_NESTED_DATA | S_NESTED_INPUT_PROGRAM,
97 S_ANY = S_INITIAL | S_DATA | S_INPUT_PROGRAM | S_FILE_TYPE | S_NESTED_ANY,
100 /* Other command requirements. */
103 F_ENHANCED = 1 << 0, /* Allowed only in enhanced syntax mode. */
104 F_TESTING = 1 << 1, /* Allowed only in testing mode. */
105 F_ABBREV = 1 << 2 /* Not a candidate for name completion. */
108 /* A single command. */
111 enum states states; /* States in which command is allowed. */
112 enum flags flags; /* Other command requirements. */
113 const char *name; /* Command name. */
114 int (*function) (struct lexer *, struct dataset *); /* Function to call. */
117 /* Define the command array. */
118 #define DEF_CMD(STATES, FLAGS, NAME, FUNCTION) {STATES, FLAGS, NAME, FUNCTION},
119 #define UNIMPL_CMD(NAME, DESCRIPTION) {S_ANY, 0, NAME, NULL},
120 static const struct command commands[] =
122 #include "command.def"
127 static const size_t n_commands = sizeof commands / sizeof *commands;
129 static bool in_correct_state (const struct command *, enum cmd_state);
130 static char *report_state_mismatch (const struct command *, enum cmd_state);
131 static void set_completion_state (enum cmd_state);
133 /* Command parser. */
135 static const struct command *parse_command_name (struct lexer *,
137 static enum cmd_result do_parse_command (struct lexer *, struct dataset *, enum cmd_state);
139 /* Parses an entire command, from command name to terminating
140 dot. On failure, skips to the terminating dot.
141 Returns the command's success or failure result. */
143 cmd_parse_in_state (struct lexer *lexer, struct dataset *ds,
144 enum cmd_state state)
146 struct session *session = dataset_session (ds);
149 result = do_parse_command (lexer, ds, state);
151 ds = session_active_dataset (session);
152 assert (!proc_is_open (ds));
153 unset_cmd_algorithm ();
154 if (!dataset_end_of_command (ds))
155 result = CMD_CASCADING_FAILURE;
161 cmd_parse (struct lexer *lexer, struct dataset *ds)
163 const struct dictionary *dict = dataset_dict (ds);
164 return cmd_parse_in_state (lexer, ds,
165 dataset_has_source (ds) &&
166 dict_get_n_vars (dict) > 0 ?
167 CMD_STATE_DATA : CMD_STATE_INITIAL);
171 /* Parses an entire command, from command name to terminating
173 static enum cmd_result
174 do_parse_command (struct lexer *lexer,
175 struct dataset *ds, enum cmd_state state)
177 const struct command *command = NULL;
178 size_t nesting_level = SIZE_MAX;
179 enum cmd_result result;
182 /* Read the command's first token. */
183 set_completion_state (state);
184 if (lex_token (lexer) == T_STOP)
189 else if (lex_token (lexer) == T_ENDCMD)
191 /* Null commands can result from extra empty lines. */
192 result = CMD_SUCCESS;
196 /* Parse the command name. */
197 command = parse_command_name (lexer, &n_tokens);
200 result = CMD_FAILURE;
204 nesting_level = output_open_group (group_item_create_nocopy (
205 utf8_to_title (command->name),
206 utf8_to_title (command->name)));
208 int end = n_tokens - 1;
209 if (command->function == NULL)
211 lex_ofs_error (lexer, 0, end, _("%s is not yet implemented."),
213 result = CMD_NOT_IMPLEMENTED;
215 else if ((command->flags & F_TESTING) && !settings_get_testing_mode ())
217 lex_ofs_error (lexer, 0, end, _("%s may be used only in testing mode."),
219 result = CMD_FAILURE;
221 else if ((command->flags & F_ENHANCED) && settings_get_syntax () != ENHANCED)
223 lex_ofs_error (lexer, 0, end,
224 _("%s may be used only in enhanced syntax mode."),
226 result = CMD_FAILURE;
228 else if (!in_correct_state (command, state))
230 char *message = report_state_mismatch (command, state);
231 lex_ofs_error (lexer, 0, end, "%s", message);
234 result = CMD_FAILURE;
238 /* Execute command. */
241 for (i = 0; i < n_tokens; i++)
243 result = command->function (lexer, ds);
246 assert (cmd_result_is_valid (result));
249 if (cmd_result_is_failure (result))
250 lex_interactive_reset (lexer);
251 else if (result == CMD_SUCCESS)
252 result = lex_end_of_command (lexer);
254 lex_discard_rest_of_command (lexer);
255 if (result != CMD_EOF && result != CMD_FINISH)
256 while (lex_token (lexer) == T_ENDCMD)
259 if (nesting_level != SIZE_MAX)
260 output_close_groups (nesting_level);
266 find_best_match (struct substring s, const struct command **matchp)
268 const struct command *cmd;
269 struct command_matcher cm;
272 command_matcher_init (&cm, s);
273 for (cmd = commands; cmd < &commands[n_commands]; cmd++)
274 command_matcher_add (&cm, ss_cstr (cmd->name), CONST_CAST (void *, cmd));
276 *matchp = command_matcher_get_match (&cm);
277 missing_words = command_matcher_get_missing_words (&cm);
279 command_matcher_destroy (&cm);
281 return missing_words;
285 parse_command_word (struct lexer *lexer, struct string *s, int n)
287 bool need_space = ds_last (s) != EOF && ds_last (s) != '-';
289 switch (lex_next_token (lexer, n))
292 ds_put_byte (s, '-');
297 ds_put_byte (s, ' ');
298 ds_put_cstr (s, lex_next_tokcstr (lexer, n));
302 if (lex_next_is_integer (lexer, n))
304 int integer = lex_next_integer (lexer, n);
308 ds_put_byte (s, ' ');
309 ds_put_format (s, "%ld", lex_next_integer (lexer, n));
320 /* Parses the command name. On success returns a pointer to the corresponding
321 struct command and stores the number of tokens in the command name into
322 *N_TOKENS. On failure, returns a null pointer and stores the number of
323 tokens required to determine that no command name was present into
325 static const struct command *
326 parse_command_name (struct lexer *lexer, int *n_tokens)
328 const struct command *command;
337 while (parse_command_word (lexer, &s, word))
339 missing_words = find_best_match (ds_ss (&s), &command);
340 if (missing_words <= 0)
345 if (command == NULL && missing_words > 0)
347 ds_put_cstr (&s, " .");
348 missing_words = find_best_match (ds_ss (&s), &command);
349 ds_truncate (&s, ds_length (&s) - 2);
352 *n_tokens = (word + 1) + missing_words;
355 if (ds_is_empty (&s))
356 lex_error (lexer, _("Syntax error expecting command name."));
358 lex_ofs_error (lexer, 0, *n_tokens - 1,
359 _("Unknown command `%s'."), ds_cstr (&s));
367 /* Returns true if COMMAND is allowed in STATE,
370 in_correct_state (const struct command *command, enum cmd_state state)
372 return command->states & (1 << state);
375 /* Returns an appropriate error message for trying to invoke
378 report_state_mismatch (const struct command *command, enum cmd_state state)
380 assert (!in_correct_state (command, state));
384 case CMD_STATE_INITIAL:
386 switch ((int) command->states
387 & (S_INITIAL | S_DATA | S_INPUT_PROGRAM | S_FILE_TYPE))
389 /* One allowed state. */
391 return xasprintf (_("%s is allowed only before the active dataset has "
392 "been defined."), command->name);
394 return xasprintf (_("%s is allowed only after the active dataset has "
395 "been defined."), command->name);
396 case S_INPUT_PROGRAM:
397 return xasprintf (_("%s is allowed only inside %s."),
398 command->name, "INPUT PROGRAM");
400 return xasprintf (_("%s is allowed only inside %s."), command->name, "FILE TYPE");
402 /* Two allowed states. */
403 case S_INITIAL | S_DATA:
405 case S_INITIAL | S_INPUT_PROGRAM:
406 return xasprintf (_("%s is allowed only before the active dataset "
407 "has been defined or inside %s."),
408 command->name, "INPUT PROGRAM");
409 case S_INITIAL | S_FILE_TYPE:
410 return xasprintf (_("%s is allowed only before the active dataset "
411 "has been defined or inside %s."),
412 command->name, "FILE TYPE");
413 case S_DATA | S_INPUT_PROGRAM:
414 return xasprintf (_("%s is allowed only after the active dataset "
415 "has been defined or inside %s."),
416 command->name, "INPUT PROGRAM");
417 case S_DATA | S_FILE_TYPE:
418 return xasprintf (_("%s is allowed only after the active dataset "
419 "has been defined or inside %s."),
420 command->name, "FILE TYPE");
421 case S_INPUT_PROGRAM | S_FILE_TYPE:
422 return xasprintf (_("%s is allowed only inside %s or inside %s."),
423 command->name, "INPUT PROGRAM", "FILE TYPE");
425 /* Three allowed states. */
426 case S_DATA | S_INPUT_PROGRAM | S_FILE_TYPE:
427 return xasprintf (_("%s is allowed only after the active dataset has "
428 "been defined, inside INPUT PROGRAM, or inside "
429 "FILE TYPE."), command->name);
430 case S_INITIAL | S_INPUT_PROGRAM | S_FILE_TYPE:
431 return xasprintf (_("%s is allowed only before the active dataset "
432 "has been defined, inside INPUT PROGRAM, or "
433 "inside FILE TYPE."), command->name);
434 case S_INITIAL | S_DATA | S_FILE_TYPE:
436 case S_INITIAL | S_DATA | S_INPUT_PROGRAM:
439 /* Four allowed states. */
440 case S_INITIAL | S_DATA | S_INPUT_PROGRAM | S_FILE_TYPE:
448 case CMD_STATE_INPUT_PROGRAM:
449 return xasprintf (_("%s is not allowed inside %s."),
450 command->name, "INPUT PROGRAM");
452 case CMD_STATE_FILE_TYPE:
453 return xasprintf (_("%s is not allowed inside %s."),
454 command->name, "FILE TYPE");
456 case CMD_STATE_NESTED_DATA:
457 case CMD_STATE_NESTED_INPUT_PROGRAM:
458 switch ((int) command->states & S_NESTED_ANY)
461 return xasprintf (_("%s is not allowed inside DO IF or LOOP."),
465 return xasprintf (_("In INPUT PROGRAM, "
466 "%s is not allowed inside DO IF or LOOP."),
477 /* Command name completion. */
479 static enum cmd_state completion_state = CMD_STATE_INITIAL;
482 set_completion_state (enum cmd_state state)
484 completion_state = state;
487 /* Returns the next possible completion of a command name that
488 begins with PREFIX, in the current command state, or a null
489 pointer if no completions remain.
490 Before calling the first time, set *CMD to a null pointer. */
492 cmd_complete (const char *prefix, const struct command **cmd)
497 for (; *cmd < commands + n_commands; (*cmd)++)
498 if (!memcasecmp ((*cmd)->name, prefix, strlen (prefix))
499 && (!((*cmd)->flags & F_TESTING) || settings_get_testing_mode ())
500 && (!((*cmd)->flags & F_ENHANCED) || settings_get_syntax () == ENHANCED)
501 && !((*cmd)->flags & F_ABBREV)
502 && ((*cmd)->function != NULL)
503 && in_correct_state (*cmd, completion_state))
504 return (*cmd)++->name;
509 /* Simple commands. */
511 /* Parse and execute FINISH command. */
513 cmd_finish (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
518 /* Parses the N command. */
520 cmd_n_of_cases (struct lexer *lexer, struct dataset *ds)
522 if (!lex_force_int_range (lexer, "N OF CASES", 1, LONG_MAX))
524 long n = lex_integer (lexer);
526 if (!lex_match_id (lexer, "ESTIMATED"))
527 dict_set_case_limit (dataset_dict (ds), n);
532 /* Parses, performs the EXECUTE procedure. */
534 cmd_execute (struct lexer *lexer UNUSED, struct dataset *ds)
536 bool ok = casereader_destroy (proc_open (ds));
537 if (!proc_commit (ds) || !ok)
538 return CMD_CASCADING_FAILURE;
542 /* Parses, performs the ERASE command. */
544 cmd_erase (struct lexer *lexer, struct dataset *ds UNUSED)
549 if (settings_get_safer_mode ())
551 lex_ofs_error (lexer, 0, 0,
552 _("This command not allowed when the %s option is set."),
557 if (!lex_force_match_id (lexer, "FILE"))
559 lex_match (lexer, T_EQUALS);
560 if (!lex_force_string (lexer))
563 filename = utf8_to_filename (lex_tokcstr (lexer));
564 retval = remove (filename);
569 msg (SW, _("Error removing `%s': %s."),
570 lex_tokcstr (lexer), strerror (errno));
578 /* Parses, performs the NEW FILE command. */
580 cmd_new_file (struct lexer *lexer UNUSED, struct dataset *ds)