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/settings.h>
32 #include <data/variable.h>
33 #include <language/lexer/lexer.h>
34 #include <libpspp/alloc.h>
35 #include <libpspp/compiler.h>
36 #include <libpspp/message.h>
37 #include <libpspp/message.h>
38 #include <libpspp/str.h>
39 #include <output/manager.h>
40 #include <output/table.h>
41 #include <procedure.h>
48 #include <readline/readline.h>
52 #define _(msgid) gettext (msgid)
53 #define N_(msgid) msgid
55 /* Returns true if RESULT indicates success,
58 cmd_result_is_success (enum cmd_result result)
60 return (result == CMD_SUCCESS || result == CMD_EOF
61 || result == CMD_QUIT || result == CMD_END_SUBLOOP);
64 /* Returns true if RESULT indicates failure,
67 cmd_result_is_failure (enum cmd_result result)
69 return !cmd_result_is_success (result);
72 /* Command processing states. */
75 S_INITIAL = 0x01, /* Allowed before active file defined. */
76 S_DATA = 0x02, /* Allowed after active file defined. */
77 S_INPUT_PROGRAM = 0x04, /* Allowed in INPUT PROGRAM. */
78 S_FILE_TYPE = 0x08, /* Allowed in FILE TYPE. */
79 S_ANY = 0x0f /* Allowed anywhere. */
82 /* Other command requirements. */
85 F_ENHANCED = 0x10, /* Allowed only in enhanced syntax mode. */
86 F_TESTING = 0x20, /* Allowed only in testing mode. */
87 F_KEEP_FINAL_TOKEN = 0x40 /* Don't skip final token in command name. */
90 /* A single command. */
93 enum states states; /* States in which command is allowed. */
94 enum flags flags; /* Other command requirements. */
95 const char *name; /* Command name. */
96 int (*function) (void); /* Function to call. */
99 /* Define the command array. */
100 #define DEF_CMD(STATES, FLAGS, NAME, FUNCTION) {STATES, FLAGS, NAME, FUNCTION},
101 #define UNIMPL_CMD(NAME, DESCRIPTION) {S_ANY, 0, NAME, NULL},
102 static const struct command commands[] =
104 #include "command.def"
109 static const size_t command_cnt = sizeof commands / sizeof *commands;
111 static bool verify_valid_command (const struct command *, enum cmd_state);
112 static const struct command *find_command (const char *name);
114 /* Command parser. */
116 static const struct command *parse_command_name (void);
117 static enum cmd_result do_parse_command (enum cmd_state);
119 /* Parses an entire command, from command name to terminating
120 dot. On failure, skips to the terminating dot.
121 Returns the command's success or failure result. */
123 cmd_parse (enum cmd_state state)
129 result = do_parse_command (state);
130 if (cmd_result_is_failure (result))
131 lex_discard_rest_of_command ();
133 unset_cmd_algorithm ();
134 dict_clear_aux (default_dict);
139 /* Parses an entire command, from command name to terminating
141 static enum cmd_result
142 do_parse_command (enum cmd_state state)
144 const struct command *command;
145 enum cmd_result result;
147 /* Null commands can result from extra empty lines. */
151 /* Parse the command name. */
152 command = parse_command_name ();
155 else if (command->function == NULL)
156 return CMD_NOT_IMPLEMENTED;
157 else if ((command->flags & F_TESTING) && !get_testing_mode ())
159 msg (SE, _("%s may be used only in testing mode."), command->name);
162 else if ((command->flags & F_ENHANCED) && get_syntax () != ENHANCED)
164 msg (SE, _("%s may be used only in enhanced syntax mode."),
168 else if (!verify_valid_command (command, state))
171 /* Execute command. */
172 msg_set_command_name (command->name);
173 tab_set_command_name (command->name);
174 result = command->function ();
175 tab_set_command_name (NULL);
176 msg_set_command_name (NULL);
182 match_strings (const char *a, size_t a_len,
183 const char *b, size_t b_len)
185 size_t match_len = 0;
187 while (a_len > 0 && b_len > 0)
189 /* Mismatch always returns zero. */
190 if (toupper ((unsigned char) *a++) != toupper ((unsigned char) *b++))
202 /* Returns the first character in the first word in STRING,
203 storing the word's length in *WORD_LEN. If no words remain,
204 returns a null pointer and stores 0 in *WORD_LEN. Words are
205 sequences of alphanumeric characters or single
206 non-alphanumeric characters. Words are delimited by
209 find_word (const char *string, size_t *word_len)
211 /* Skip whitespace and asterisks. */
212 while (isspace ((unsigned char) *string))
222 /* Special one-character word? */
223 if (!isalnum ((unsigned char) *string))
229 /* Alphanumeric word. */
231 while (isalnum ((unsigned char) string[*word_len]))
237 /* Returns nonzero if strings A and B can be confused based on
238 their first three letters. */
240 conflicting_3char_prefixes (const char *a, const char *b)
242 size_t aw_len, bw_len;
245 aw = find_word (a, &aw_len);
246 bw = find_word (b, &bw_len);
247 assert (aw != NULL && bw != NULL);
249 /* Words that are the same don't conflict. */
250 if (aw_len == bw_len && !buf_compare_case (aw, bw, aw_len))
253 /* Words that are otherwise the same in the first three letters
255 return ((aw_len > 3 && bw_len > 3)
256 || (aw_len == 3 && bw_len > 3)
257 || (bw_len == 3 && aw_len > 3)) && !buf_compare_case (aw, bw, 3);
260 /* Returns nonzero if CMD can be confused with another command
261 based on the first three letters of its first word. */
263 conflicting_3char_prefix_command (const struct command *cmd)
265 assert (cmd >= commands && cmd < commands + command_cnt);
267 return ((cmd > commands
268 && conflicting_3char_prefixes (cmd[-1].name, cmd[0].name))
269 || (cmd < commands + command_cnt
270 && conflicting_3char_prefixes (cmd[0].name, cmd[1].name)));
273 /* Ways that a set of words can match a command name. */
276 MISMATCH, /* Not a match. */
277 PARTIAL_MATCH, /* The words begin the command name. */
278 COMPLETE_MATCH /* The words are the command name. */
281 /* Figures out how well the WORD_CNT words in WORDS match CMD,
282 and returns the appropriate enum value. If WORDS are a
283 partial match for CMD and the next word in CMD is a dash, then
284 *DASH_POSSIBLE is set to 1 if DASH_POSSIBLE is non-null;
285 otherwise, *DASH_POSSIBLE is unchanged. */
286 static enum command_match
287 cmd_match_words (const struct command *cmd,
288 char *const words[], size_t word_cnt,
295 for (word = find_word (cmd->name, &word_len), word_idx = 0;
296 word != NULL && word_idx < word_cnt;
297 word = find_word (word + word_len, &word_len), word_idx++)
298 if (word_len != strlen (words[word_idx])
299 || buf_compare_case (word, words[word_idx], word_len))
301 size_t match_chars = match_strings (word, word_len,
303 strlen (words[word_idx]));
304 if (match_chars == 0)
309 else if (match_chars == 1 || match_chars == 2)
311 /* One- and two-character abbreviations are not
315 else if (match_chars == 3)
317 /* Three-character abbreviations are acceptable
318 in the first word of a command if there are
319 no name conflicts. They are always
320 acceptable after the first word. */
321 if (word_idx == 0 && conflicting_3char_prefix_command (cmd))
324 else /* match_chars > 3 */
326 /* Four-character and longer abbreviations are
327 always acceptable. */
331 if (word == NULL && word_idx == word_cnt)
333 /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR"}. */
334 return COMPLETE_MATCH;
336 else if (word == NULL)
338 /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR", "BAZ"}. */
343 /* cmd->name = "FOO BAR BAZ", words[] = {"FOO", "BAR"}. */
344 if (word[0] == '-' && dash_possible != NULL)
346 return PARTIAL_MATCH;
350 /* Returns the number of commands for which the WORD_CNT words in
351 WORDS are a partial or complete match. If some partial match
352 has a dash as the next word, then *DASH_POSSIBLE is set to 1,
353 otherwise it is set to 0. */
355 count_matching_commands (char *const words[], size_t word_cnt,
358 const struct command *cmd;
363 for (cmd = commands; cmd < commands + command_cnt; cmd++)
364 if (cmd_match_words (cmd, words, word_cnt, dash_possible) != MISMATCH)
367 return cmd_match_count;
370 /* Returns the command for which the WORD_CNT words in WORDS are
371 a complete match. Returns a null pointer if no such command
373 static const struct command *
374 get_complete_match (char *const words[], size_t word_cnt)
376 const struct command *cmd;
378 for (cmd = commands; cmd < commands + command_cnt; cmd++)
379 if (cmd_match_words (cmd, words, word_cnt, NULL) == COMPLETE_MATCH)
385 /* Returns the command with the given exact NAME.
386 Aborts if no such command exists. */
387 static const struct command *
388 find_command (const char *name)
390 const struct command *cmd;
392 for (cmd = commands; cmd < commands + command_cnt; cmd++)
393 if (!strcmp (cmd->name, name))
398 /* Frees the WORD_CNT words in WORDS. */
400 free_words (char *words[], size_t word_cnt)
404 for (idx = 0; idx < word_cnt; idx++)
408 /* Flags an error that the command whose name is given by the
409 WORD_CNT words in WORDS is unknown. */
411 unknown_command_error (char *const words[], size_t word_cnt)
414 lex_error (_("expecting command name"));
421 for (i = 0; i < word_cnt; i++)
425 ds_puts (&s, words[i]);
428 msg (SE, _("Unknown command %s."), ds_c_str (&s));
434 /* Parse the command name and return a pointer to the corresponding
435 struct command if successful.
436 If not successful, return a null pointer. */
437 static const struct command *
438 parse_command_name (void)
442 int complete_word_cnt;
445 if (token == T_EXP || token == '*' || token == '[')
446 return find_command ("COMMENT");
449 word_cnt = complete_word_cnt = 0;
450 while (token == T_ID || (dash_possible && token == '-'))
454 assert (word_cnt < sizeof words / sizeof *words);
457 words[word_cnt] = xstrdup (ds_c_str (&tokstr));
458 str_uppercase (words[word_cnt]);
460 else if (token == '-')
461 words[word_cnt] = xstrdup ("-");
464 cmd_match_cnt = count_matching_commands (words, word_cnt,
466 if (cmd_match_cnt == 0)
468 else if (cmd_match_cnt == 1)
470 const struct command *command = get_complete_match (words, word_cnt);
473 if (!(command->flags & F_KEEP_FINAL_TOKEN))
475 free_words (words, word_cnt);
479 else /* cmd_match_cnt > 1 */
481 /* Do we have a complete command name so far? */
482 if (get_complete_match (words, word_cnt) != NULL)
483 complete_word_cnt = word_cnt;
488 /* If we saw a complete command name earlier, drop back to
490 if (complete_word_cnt)
492 int pushback_word_cnt;
493 const struct command *command;
495 /* Get the command. */
496 command = get_complete_match (words, complete_word_cnt);
497 assert (command != NULL);
499 /* Figure out how many words we want to keep.
500 We normally want to swallow the entire command. */
501 pushback_word_cnt = complete_word_cnt + 1;
502 if (command->flags & F_KEEP_FINAL_TOKEN)
505 /* FIXME: We only support one-token pushback. */
506 assert (pushback_word_cnt + 1 >= word_cnt);
508 while (word_cnt > pushback_word_cnt)
511 if (strcmp (words[word_cnt], "-"))
512 lex_put_back_id (words[word_cnt]);
515 free (words[word_cnt]);
518 free_words (words, word_cnt);
522 /* We didn't get a valid command name. */
523 unknown_command_error (words, word_cnt);
524 free_words (words, word_cnt);
528 /* Returns true if COMMAND is allowed in STATE,
530 If COMMAND is not allowed, emits an appropriate error
533 verify_valid_command (const struct command *command, enum cmd_state state)
535 if ((state == CMD_STATE_INITIAL && command->states & S_INITIAL)
536 || (state == CMD_STATE_DATA && command->states & S_DATA)
537 || (state == CMD_STATE_INPUT_PROGRAM
538 && command->states & S_INPUT_PROGRAM)
539 || (state == CMD_STATE_FILE_TYPE && command->states & S_FILE_TYPE))
542 if (state == CMD_STATE_INITIAL || state == CMD_STATE_DATA)
544 const char *allowed[3];
549 if (command->states & S_INITIAL)
550 allowed[allowed_cnt++] = _("before the active file has been defined");
551 else if (command->states & S_DATA)
552 allowed[allowed_cnt++] = _("after the active file has been defined");
553 if (command->states & S_INPUT_PROGRAM)
554 allowed[allowed_cnt++] = _("inside INPUT PROGRAM");
555 if (command->states & S_FILE_TYPE)
556 allowed[allowed_cnt++] = _("inside FILE TYPE");
558 if (allowed_cnt == 1)
559 s = xstrdup (allowed[0]);
560 else if (allowed_cnt == 2)
561 s = xasprintf (_("%s or %s"), allowed[0], allowed[1]);
562 else if (allowed_cnt == 3)
563 s = xasprintf (_("%s, %s, or %s"), allowed[0], allowed[1], allowed[2]);
567 msg (SE, _("%s is allowed only %s."), command->name, s);
571 else if (state == CMD_STATE_INPUT_PROGRAM)
572 msg (SE, _("%s is not allowed inside INPUT PROGRAM."), command->name);
573 else if (state == CMD_STATE_FILE_TYPE)
574 msg (SE, _("%s is not allowed inside FILE TYPE."), command->name);
579 /* Readline command name completion. */
582 static char *command_generator (const char *text, int state);
584 /* Returns a set of completions for TEXT.
585 This is of the proper form for assigning to
586 rl_attempted_completion_function. */
588 pspp_attempted_completion_function (const char *text,
589 int start, int end UNUSED)
593 /* Complete command name at start of line. */
594 return rl_completion_matches (text, command_generator);
598 /* Otherwise don't do any completion. */
599 rl_attempted_completion_over = 1;
604 /* If STATE is 0, returns the first command name matching TEXT.
605 Otherwise, returns the next command name matching TEXT.
606 Returns a null pointer when no matches are left. */
608 command_generator (const char *text, int state)
610 static const struct command *cmd;
615 for (; cmd < commands + command_cnt; cmd++)
616 if (!memcasecmp (cmd->name, text, strlen (text))
617 && (!(cmd->flags & F_TESTING) || get_testing_mode ())
618 && (!(cmd->flags & F_ENHANCED) || get_syntax () == ENHANCED))
619 return xstrdup (cmd++->name);
623 #endif /* HAVE_READLINE */
625 /* Simple commands. */
627 /* Parse and execute FINISH command. */
634 /* Parses the N command. */
636 cmd_n_of_cases (void)
641 if (!lex_force_int ())
645 if (!lex_match_id ("ESTIMATED"))
646 dict_set_case_limit (default_dict, x);
648 return lex_end_of_command ();
651 /* Parses, performs the EXECUTE procedure. */
655 if (!procedure (NULL, NULL))
656 return CMD_CASCADING_FAILURE;
657 return lex_end_of_command ();
660 /* Parses, performs the ERASE command. */
664 if (get_safer_mode ())
666 msg (SE, _("This command not allowed when the SAFER option is set."));
670 if (!lex_force_match_id ("FILE"))
673 if (!lex_force_string ())
676 if (remove (ds_c_str (&tokstr)) == -1)
678 msg (SW, _("Error removing `%s': %s."),
679 ds_c_str (&tokstr), strerror (errno));
687 /* Spawn a shell process. */
698 const char *shell_fn;
704 for (i = 3; i < 20; i++)
708 shell_fn = getenv ("SHELL");
709 if (shell_fn == NULL)
710 shell_fn = "/bin/sh";
713 const char *cp = strrchr (shell_fn, '/');
714 cp = cp ? &cp[1] : shell_fn;
715 shell_process = local_alloc (strlen (cp) + 8);
716 strcpy (shell_process, "-");
717 strcat (shell_process, cp);
718 if (strcmp (cp, "sh"))
719 shell_process[0] = '+';
722 execl (shell_fn, shell_process, NULL);
728 msg (SE, _("Couldn't fork: %s."), strerror (errno));
733 while (wait (NULL) != pid)
740 /* Parses the HOST command argument and executes the specified
741 command. Returns a suitable command return code. */
748 /* Handle either a string argument or a full-line argument. */
750 int c = lex_look_ahead ();
752 if (c == '\'' || c == '"')
755 if (!lex_force_string ())
757 cmd = ds_c_str (&tokstr);
762 cmd = lex_rest_of_line (NULL);
768 /* Execute the command. */
769 if (system (cmd) == -1)
770 msg (SE, _("Error executing command: %s."), strerror (errno));
772 /* Finish parsing. */
779 lex_error (_("expecting end of command"));
789 /* Parses, performs the HOST command. */
795 if (get_safer_mode ())
797 msg (SE, _("This command not allowed when the SAFER option is set."));
802 /* Figure out whether to invoke an interactive shell or to execute a
803 single shell command. */
804 if (lex_look_ahead () == '.')
807 code = shell () ? CMD_FAILURE : CMD_SUCCESS;
810 code = run_command ();
812 /* Make sure that the system has a command interpreter, then run a
814 if (system (NULL) != 0)
815 code = run_command ();
818 msg (SE, _("No operating system support for this command."));
826 /* Parses, performs the NEW FILE command. */
830 discard_variables ();
832 return lex_end_of_command ();
835 /* Parses a comment. */