1 /* PSPP - computes sample statistics.
2 Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 #include <language/command.h>
30 #include <data/dictionary.h>
31 #include <data/procedure.h>
32 #include <data/settings.h>
33 #include <data/variable.h>
34 #include <language/lexer/lexer.h>
35 #include <libpspp/alloc.h>
36 #include <libpspp/compiler.h>
37 #include <libpspp/message.h>
38 #include <libpspp/message.h>
39 #include <libpspp/str.h>
40 #include <output/manager.h>
41 #include <output/table.h>
48 #include <readline/readline.h>
52 #define _(msgid) gettext (msgid)
53 #define N_(msgid) msgid
55 /* Returns true if RESULT is a valid "enum cmd_result",
58 cmd_result_is_valid (enum cmd_result result)
60 return (result == CMD_SUCCESS || result == CMD_EOF || result == CMD_FINISH
61 || (result >= CMD_PRIVATE_FIRST && result <= CMD_PRIVATE_LAST)
62 || result == CMD_FAILURE || result == CMD_NOT_IMPLEMENTED
63 || result == CMD_CASCADING_FAILURE);
66 /* Returns true if RESULT indicates success,
69 cmd_result_is_success (enum cmd_result result)
71 assert (cmd_result_is_valid (result));
75 /* Returns true if RESULT indicates failure,
78 cmd_result_is_failure (enum cmd_result result)
80 assert (cmd_result_is_valid (result));
84 /* Command processing states. */
87 S_INITIAL = 0x01, /* Allowed before active file defined. */
88 S_DATA = 0x02, /* Allowed after active file defined. */
89 S_INPUT_PROGRAM = 0x04, /* Allowed in INPUT PROGRAM. */
90 S_FILE_TYPE = 0x08, /* Allowed in FILE TYPE. */
91 S_ANY = 0x0f /* Allowed anywhere. */
94 /* Other command requirements. */
97 F_ENHANCED = 0x10, /* Allowed only in enhanced syntax mode. */
98 F_TESTING = 0x20, /* Allowed only in testing mode. */
99 F_KEEP_FINAL_TOKEN = 0x40 /* Don't skip final token in command name. */
102 /* A single command. */
105 enum states states; /* States in which command is allowed. */
106 enum flags flags; /* Other command requirements. */
107 const char *name; /* Command name. */
108 int (*function) (void); /* Function to call. */
111 /* Define the command array. */
112 #define DEF_CMD(STATES, FLAGS, NAME, FUNCTION) {STATES, FLAGS, NAME, FUNCTION},
113 #define UNIMPL_CMD(NAME, DESCRIPTION) {S_ANY, 0, NAME, NULL},
114 static const struct command commands[] =
116 #include "command.def"
121 static const size_t command_cnt = sizeof commands / sizeof *commands;
123 static bool verify_valid_command (const struct command *, enum cmd_state);
124 static const struct command *find_command (const char *name);
126 /* Command parser. */
128 static const struct command *parse_command_name (void);
129 static enum cmd_result do_parse_command (enum cmd_state);
131 /* Parses an entire command, from command name to terminating
132 dot. On failure, skips to the terminating dot.
133 Returns the command's success or failure result. */
135 cmd_parse (enum cmd_state state)
141 result = do_parse_command (state);
142 if (cmd_result_is_failure (result))
143 lex_discard_rest_of_command ();
145 unset_cmd_algorithm ();
146 dict_clear_aux (default_dict);
151 /* Parses an entire command, from command name to terminating
153 static enum cmd_result
154 do_parse_command (enum cmd_state state)
156 const struct command *command;
157 enum cmd_result result;
159 /* Null commands can result from extra empty lines. */
163 /* Parse the command name. */
164 command = parse_command_name ();
167 else if (command->function == NULL)
168 return CMD_NOT_IMPLEMENTED;
169 else if ((command->flags & F_TESTING) && !get_testing_mode ())
171 msg (SE, _("%s may be used only in testing mode."), command->name);
174 else if ((command->flags & F_ENHANCED) && get_syntax () != ENHANCED)
176 msg (SE, _("%s may be used only in enhanced syntax mode."),
180 else if (!verify_valid_command (command, state))
183 /* Execute command. */
184 msg_set_command_name (command->name);
185 tab_set_command_name (command->name);
186 result = command->function ();
187 tab_set_command_name (NULL);
188 msg_set_command_name (NULL);
190 assert (cmd_result_is_valid (result));
195 match_strings (const char *a, size_t a_len,
196 const char *b, size_t b_len)
198 size_t match_len = 0;
200 while (a_len > 0 && b_len > 0)
202 /* Mismatch always returns zero. */
203 if (toupper ((unsigned char) *a++) != toupper ((unsigned char) *b++))
215 /* Returns the first character in the first word in STRING,
216 storing the word's length in *WORD_LEN. If no words remain,
217 returns a null pointer and stores 0 in *WORD_LEN. Words are
218 sequences of alphanumeric characters or single
219 non-alphanumeric characters. Words are delimited by
222 find_word (const char *string, size_t *word_len)
224 /* Skip whitespace and asterisks. */
225 while (isspace ((unsigned char) *string))
235 /* Special one-character word? */
236 if (!isalnum ((unsigned char) *string))
242 /* Alphanumeric word. */
244 while (isalnum ((unsigned char) string[*word_len]))
250 /* Returns nonzero if strings A and B can be confused based on
251 their first three letters. */
253 conflicting_3char_prefixes (const char *a, const char *b)
255 size_t aw_len, bw_len;
258 aw = find_word (a, &aw_len);
259 bw = find_word (b, &bw_len);
260 assert (aw != NULL && bw != NULL);
262 /* Words that are the same don't conflict. */
263 if (aw_len == bw_len && !buf_compare_case (aw, bw, aw_len))
266 /* Words that are otherwise the same in the first three letters
268 return ((aw_len > 3 && bw_len > 3)
269 || (aw_len == 3 && bw_len > 3)
270 || (bw_len == 3 && aw_len > 3)) && !buf_compare_case (aw, bw, 3);
273 /* Returns nonzero if CMD can be confused with another command
274 based on the first three letters of its first word. */
276 conflicting_3char_prefix_command (const struct command *cmd)
278 assert (cmd >= commands && cmd < commands + command_cnt);
280 return ((cmd > commands
281 && conflicting_3char_prefixes (cmd[-1].name, cmd[0].name))
282 || (cmd < commands + command_cnt
283 && conflicting_3char_prefixes (cmd[0].name, cmd[1].name)));
286 /* Ways that a set of words can match a command name. */
289 MISMATCH, /* Not a match. */
290 PARTIAL_MATCH, /* The words begin the command name. */
291 COMPLETE_MATCH /* The words are the command name. */
294 /* Figures out how well the WORD_CNT words in WORDS match CMD,
295 and returns the appropriate enum value. If WORDS are a
296 partial match for CMD and the next word in CMD is a dash, then
297 *DASH_POSSIBLE is set to 1 if DASH_POSSIBLE is non-null;
298 otherwise, *DASH_POSSIBLE is unchanged. */
299 static enum command_match
300 cmd_match_words (const struct command *cmd,
301 char *const words[], size_t word_cnt,
308 for (word = find_word (cmd->name, &word_len), word_idx = 0;
309 word != NULL && word_idx < word_cnt;
310 word = find_word (word + word_len, &word_len), word_idx++)
311 if (word_len != strlen (words[word_idx])
312 || buf_compare_case (word, words[word_idx], word_len))
314 size_t match_chars = match_strings (word, word_len,
316 strlen (words[word_idx]));
317 if (match_chars == 0)
322 else if (match_chars == 1 || match_chars == 2)
324 /* One- and two-character abbreviations are not
328 else if (match_chars == 3)
330 /* Three-character abbreviations are acceptable
331 in the first word of a command if there are
332 no name conflicts. They are always
333 acceptable after the first word. */
334 if (word_idx == 0 && conflicting_3char_prefix_command (cmd))
337 else /* match_chars > 3 */
339 /* Four-character and longer abbreviations are
340 always acceptable. */
344 if (word == NULL && word_idx == word_cnt)
346 /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR"}. */
347 return COMPLETE_MATCH;
349 else if (word == NULL)
351 /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR", "BAZ"}. */
356 /* cmd->name = "FOO BAR BAZ", words[] = {"FOO", "BAR"}. */
357 if (word[0] == '-' && dash_possible != NULL)
359 return PARTIAL_MATCH;
363 /* Returns the number of commands for which the WORD_CNT words in
364 WORDS are a partial or complete match. If some partial match
365 has a dash as the next word, then *DASH_POSSIBLE is set to 1,
366 otherwise it is set to 0. */
368 count_matching_commands (char *const words[], size_t word_cnt,
371 const struct command *cmd;
376 for (cmd = commands; cmd < commands + command_cnt; cmd++)
377 if (cmd_match_words (cmd, words, word_cnt, dash_possible) != MISMATCH)
380 return cmd_match_count;
383 /* Returns the command for which the WORD_CNT words in WORDS are
384 a complete match. Returns a null pointer if no such command
386 static const struct command *
387 get_complete_match (char *const words[], size_t word_cnt)
389 const struct command *cmd;
391 for (cmd = commands; cmd < commands + command_cnt; cmd++)
392 if (cmd_match_words (cmd, words, word_cnt, NULL) == COMPLETE_MATCH)
398 /* Returns the command with the given exact NAME.
399 Aborts if no such command exists. */
400 static const struct command *
401 find_command (const char *name)
403 const struct command *cmd;
405 for (cmd = commands; cmd < commands + command_cnt; cmd++)
406 if (!strcmp (cmd->name, name))
411 /* Frees the WORD_CNT words in WORDS. */
413 free_words (char *words[], size_t word_cnt)
417 for (idx = 0; idx < word_cnt; idx++)
421 /* Flags an error that the command whose name is given by the
422 WORD_CNT words in WORDS is unknown. */
424 unknown_command_error (char *const words[], size_t word_cnt)
427 lex_error (_("expecting command name"));
434 for (i = 0; i < word_cnt; i++)
437 ds_put_char (&s, ' ');
438 ds_put_cstr (&s, words[i]);
441 msg (SE, _("Unknown command %s."), ds_cstr (&s));
447 /* Parse the command name and return a pointer to the corresponding
448 struct command if successful.
449 If not successful, return a null pointer. */
450 static const struct command *
451 parse_command_name (void)
455 int complete_word_cnt;
458 if (token == T_EXP || token == '*' || token == '[')
459 return find_command ("COMMENT");
462 word_cnt = complete_word_cnt = 0;
463 while (token == T_ID || (dash_possible && token == '-'))
467 assert (word_cnt < sizeof words / sizeof *words);
470 words[word_cnt] = ds_xstrdup (&tokstr);
471 str_uppercase (words[word_cnt]);
473 else if (token == '-')
474 words[word_cnt] = xstrdup ("-");
477 cmd_match_cnt = count_matching_commands (words, word_cnt,
479 if (cmd_match_cnt == 0)
481 else if (cmd_match_cnt == 1)
483 const struct command *command = get_complete_match (words, word_cnt);
486 if (!(command->flags & F_KEEP_FINAL_TOKEN))
488 free_words (words, word_cnt);
492 else /* cmd_match_cnt > 1 */
494 /* Do we have a complete command name so far? */
495 if (get_complete_match (words, word_cnt) != NULL)
496 complete_word_cnt = word_cnt;
501 /* If we saw a complete command name earlier, drop back to
503 if (complete_word_cnt)
505 int pushback_word_cnt;
506 const struct command *command;
508 /* Get the command. */
509 command = get_complete_match (words, complete_word_cnt);
510 assert (command != NULL);
512 /* Figure out how many words we want to keep.
513 We normally want to swallow the entire command. */
514 pushback_word_cnt = complete_word_cnt + 1;
515 if (command->flags & F_KEEP_FINAL_TOKEN)
518 /* FIXME: We only support one-token pushback. */
519 assert (pushback_word_cnt + 1 >= word_cnt);
521 while (word_cnt > pushback_word_cnt)
524 if (strcmp (words[word_cnt], "-"))
525 lex_put_back_id (words[word_cnt]);
528 free (words[word_cnt]);
531 free_words (words, word_cnt);
535 /* We didn't get a valid command name. */
536 unknown_command_error (words, word_cnt);
537 free_words (words, word_cnt);
541 /* Returns true if COMMAND is allowed in STATE,
543 If COMMAND is not allowed, emits an appropriate error
546 verify_valid_command (const struct command *command, enum cmd_state state)
548 if ((state == CMD_STATE_INITIAL && command->states & S_INITIAL)
549 || (state == CMD_STATE_DATA && command->states & S_DATA)
550 || (state == CMD_STATE_INPUT_PROGRAM
551 && command->states & S_INPUT_PROGRAM)
552 || (state == CMD_STATE_FILE_TYPE && command->states & S_FILE_TYPE))
555 if (state == CMD_STATE_INITIAL || state == CMD_STATE_DATA)
557 const char *allowed[3];
562 if (command->states & S_INITIAL)
563 allowed[allowed_cnt++] = _("before the active file has been defined");
564 else if (command->states & S_DATA)
565 allowed[allowed_cnt++] = _("after the active file has been defined");
566 if (command->states & S_INPUT_PROGRAM)
567 allowed[allowed_cnt++] = _("inside INPUT PROGRAM");
568 if (command->states & S_FILE_TYPE)
569 allowed[allowed_cnt++] = _("inside FILE TYPE");
571 if (allowed_cnt == 1)
572 s = xstrdup (allowed[0]);
573 else if (allowed_cnt == 2)
574 s = xasprintf (_("%s or %s"), allowed[0], allowed[1]);
575 else if (allowed_cnt == 3)
576 s = xasprintf (_("%s, %s, or %s"), allowed[0], allowed[1], allowed[2]);
580 msg (SE, _("%s is allowed only %s."), command->name, s);
584 else if (state == CMD_STATE_INPUT_PROGRAM)
585 msg (SE, _("%s is not allowed inside INPUT PROGRAM."), command->name);
586 else if (state == CMD_STATE_FILE_TYPE)
587 msg (SE, _("%s is not allowed inside FILE TYPE."), command->name);
592 /* Readline command name completion. */
595 static char *command_generator (const char *text, int state);
597 /* Returns a set of completions for TEXT.
598 This is of the proper form for assigning to
599 rl_attempted_completion_function. */
601 pspp_attempted_completion_function (const char *text,
602 int start, int end UNUSED)
606 /* Complete command name at start of line. */
607 return rl_completion_matches (text, command_generator);
611 /* Otherwise don't do any completion. */
612 rl_attempted_completion_over = 1;
617 /* If STATE is 0, returns the first command name matching TEXT.
618 Otherwise, returns the next command name matching TEXT.
619 Returns a null pointer when no matches are left. */
621 command_generator (const char *text, int state)
623 static const struct command *cmd;
628 for (; cmd < commands + command_cnt; cmd++)
629 if (!memcasecmp (cmd->name, text, strlen (text))
630 && (!(cmd->flags & F_TESTING) || get_testing_mode ())
631 && (!(cmd->flags & F_ENHANCED) || get_syntax () == ENHANCED))
632 return xstrdup (cmd++->name);
636 #endif /* HAVE_READLINE */
638 /* Simple commands. */
640 /* Parse and execute FINISH command. */
647 /* Parses the N command. */
649 cmd_n_of_cases (void)
654 if (!lex_force_int ())
658 if (!lex_match_id ("ESTIMATED"))
659 dict_set_case_limit (default_dict, x);
661 return lex_end_of_command ();
664 /* Parses, performs the EXECUTE procedure. */
668 if (!procedure (NULL, NULL))
669 return CMD_CASCADING_FAILURE;
670 return lex_end_of_command ();
673 /* Parses, performs the ERASE command. */
677 if (get_safer_mode ())
679 msg (SE, _("This command not allowed when the SAFER option is set."));
683 if (!lex_force_match_id ("FILE"))
686 if (!lex_force_string ())
689 if (remove (ds_cstr (&tokstr)) == -1)
691 msg (SW, _("Error removing `%s': %s."),
692 ds_cstr (&tokstr), strerror (errno));
700 /* Spawn a shell process. */
711 const char *shell_fn;
717 for (i = 3; i < 20; i++)
721 shell_fn = getenv ("SHELL");
722 if (shell_fn == NULL)
723 shell_fn = "/bin/sh";
726 const char *cp = strrchr (shell_fn, '/');
727 cp = cp ? &cp[1] : shell_fn;
728 shell_process = local_alloc (strlen (cp) + 8);
729 strcpy (shell_process, "-");
730 strcat (shell_process, cp);
731 if (strcmp (cp, "sh"))
732 shell_process[0] = '+';
735 execl (shell_fn, shell_process, NULL);
741 msg (SE, _("Couldn't fork: %s."), strerror (errno));
746 while (wait (NULL) != pid)
753 /* Parses the HOST command argument and executes the specified
754 command. Returns a suitable command return code. */
761 /* Handle either a string argument or a full-line argument. */
763 int c = lex_look_ahead ();
765 if (c == '\'' || c == '"')
768 if (!lex_force_string ())
770 cmd = ds_cstr (&tokstr);
775 cmd = lex_rest_of_line (NULL);
781 /* Execute the command. */
782 if (system (cmd) == -1)
783 msg (SE, _("Error executing command: %s."), strerror (errno));
785 /* Finish parsing. */
792 lex_error (_("expecting end of command"));
802 /* Parses, performs the HOST command. */
808 if (get_safer_mode ())
810 msg (SE, _("This command not allowed when the SAFER option is set."));
815 /* Figure out whether to invoke an interactive shell or to execute a
816 single shell command. */
817 if (lex_look_ahead () == '.')
820 code = shell () ? CMD_FAILURE : CMD_SUCCESS;
823 code = run_command ();
825 /* Make sure that the system has a command interpreter, then run a
827 if (system (NULL) != 0)
828 code = run_command ();
831 msg (SE, _("No operating system support for this command."));
839 /* Parses, performs the NEW FILE command. */
843 discard_variables ();
845 return lex_end_of_command ();
848 /* Parses a comment. */