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
21 #include <libpspp/message.h>
22 #include <language/command.h>
28 #include <libpspp/alloc.h>
29 #include <libpspp/compiler.h>
30 #include <data/dictionary.h>
31 #include <libpspp/message.h>
32 #include <language/lexer/lexer.h>
33 #include <data/settings.h>
34 #include <output/manager.h>
35 #include <libpspp/str.h>
36 #include <output/table.h>
37 #include <data/variable.h>
38 #include <procedure.h>
45 #define _(msgid) gettext (msgid)
46 #define N_(msgid) msgid
48 /* Global variables. */
50 /* A STATE_* constant giving the current program state. */
53 /* Static variables. */
55 /* A single command. */
58 const char *name; /* Command name. */
59 int transition[4]; /* Transitions to make from each state. */
60 int (*func) (void); /* Function to call. */
61 int skip_entire_name; /* If zero, we don't skip the
62 final token in the command name. */
63 short debug; /* Set if this cmd available only in test mode*/
66 /* Define the command array. */
67 #define DEFCMD(NAME, T1, T2, T3, T4, FUNC) \
68 {NAME, {T1, T2, T3, T4}, FUNC, 1, 0},
69 #define DBGCMD(NAME, T1, T2, T3, T4, FUNC) \
70 {NAME, {T1, T2, T3, T4}, FUNC, 1, 1},
71 #define SPCCMD(NAME, T1, T2, T3, T4, FUNC) \
72 {NAME, {T1, T2, T3, T4}, FUNC, 0, 0},
73 #define UNIMPL(NAME, T1, T2, T3, T4, DESC) \
74 {NAME, {T1, T2, T3, T4}, NULL, 1, 0},
75 static const struct command commands[] =
77 #include "command.def"
84 /* Complete the line using the name of a command,
85 * based upon the current prg_state
88 pspp_completion_function (const char *text, int state)
91 const struct command *cmd = 0;
95 if ( state + skip >= sizeof(commands)/ sizeof(struct command))
101 cmd = &commands[state + skip];
103 if ( cmd->transition[pgm_state] == STATE_ERROR || ( cmd->debug && ! get_testing_mode () ) )
109 if ( text == 0 || 0 == strncasecmp (cmd->name, text, strlen(text)))
118 return xstrdup(cmd->name);
123 #define COMMAND_CNT (sizeof commands / sizeof *commands)
125 /* Command parser. */
127 static const struct command *parse_command_name (void);
129 /* Determines whether command C is appropriate to call in this
130 part of a FILE TYPE structure. */
132 FILE_TYPE_okay (const struct command *c UNUSED)
137 if (c->func != cmd_record_type
138 && c->func != cmd_data_list
139 && c->func != cmd_repeating_data
140 && c->func != cmd_end_file_type)
141 msg (SE, _("%s not allowed inside FILE TYPE/END FILE TYPE."), c->name);
143 else if (c->func == cmd_repeating_data && fty.type == FTY_GROUPED)
144 msg (SE, _("%s not allowed inside FILE TYPE GROUPED/END FILE TYPE."),
146 else if (!fty.had_rec_type && c->func != cmd_record_type)
147 msg (SE, _("RECORD TYPE must be the first command inside a "
148 "FILE TYPE structure."));
152 if (c->func == cmd_record_type)
153 fty.had_rec_type = 1;
163 /* Parses an entire PSPP command. This includes everything from the
164 command name to the terminating dot. Does most of its work by
165 passing it off to the respective command dispatchers. Only called
166 by parse() in main.c. */
170 const struct command *cp; /* Iterator used to find the proper command. */
173 /* The generic alloca package performs garbage collection when it is
174 called with an argument of zero. */
176 #endif /* C_ALLOCA */
178 /* Null commands can result from extra empty lines. */
182 /* Parse comments. */
183 if ((token == T_ID && !strcasecmp (tokid, "COMMENT"))
184 || token == T_EXP || token == '*' || token == '[')
190 /* Otherwise the line must begin with a command name, which is
191 always an ID token. */
194 lex_error (_("expecting command name"));
198 /* Parse the command name. */
199 cp = parse_command_name ();
202 if (cp->func == NULL)
204 msg (SE, _("%s is not yet implemented."), cp->name);
205 while (token && token != '.')
210 /* If we're in a FILE TYPE structure, only certain commands can be
212 if (pgm_state == STATE_INPUT
213 && case_source_is_class (vfm_source, &file_type_source_class)
214 && !FILE_TYPE_okay (cp))
217 /* Certain state transitions are not allowed. Check for these. */
218 assert (pgm_state >= 0 && pgm_state < STATE_ERROR);
219 if (cp->transition[pgm_state] == STATE_ERROR)
221 static const char *state_name[4] =
223 N_("%s is not allowed (1) before a command to specify the "
224 "input program, such as DATA LIST, (2) between FILE TYPE "
225 "and END FILE TYPE, (3) between INPUT PROGRAM and END "
227 N_("%s is not allowed within an input program."),
228 N_("%s is only allowed within an input program."),
229 N_("%s is only allowed within an input program."),
232 msg (SE, gettext (state_name[pgm_state]), cp->name);
236 /* The structured output manager numbers all its tables. Increment
237 the major table number for each separate procedure. */
243 /* Call the command dispatcher. */
244 msg_set_command_name (cp->name);
245 tab_set_command_name (cp->name);
246 result = cp->func ();
247 msg_set_command_name (NULL);
248 tab_set_command_name (NULL);
250 /* Perform the state transition if the command completed
251 successfully (at least in part). */
252 if (result != CMD_FAILURE && result != CMD_CASCADING_FAILURE)
254 pgm_state = cp->transition[pgm_state];
256 if (pgm_state == STATE_ERROR)
258 discard_variables ();
259 pgm_state = STATE_INIT;
263 /* Pass the command's success value up to the caller. */
269 match_strings (const char *a, size_t a_len,
270 const char *b, size_t b_len)
272 size_t match_len = 0;
274 while (a_len > 0 && b_len > 0)
276 /* Mismatch always returns zero. */
277 if (toupper ((unsigned char) *a++) != toupper ((unsigned char) *b++))
289 /* Returns the first character in the first word in STRING,
290 storing the word's length in *WORD_LEN. If no words remain,
291 returns a null pointer and stores 0 in *WORD_LEN. Words are
292 sequences of alphanumeric characters or single
293 non-alphanumeric characters. Words are delimited by
296 find_word (const char *string, size_t *word_len)
298 /* Skip whitespace and asterisks. */
299 while (isspace ((unsigned char) *string))
309 /* Special one-character word? */
310 if (!isalnum ((unsigned char) *string))
316 /* Alphanumeric word. */
318 while (isalnum ((unsigned char) string[*word_len]))
324 /* Returns nonzero if strings A and B can be confused based on
325 their first three letters. */
327 conflicting_3char_prefixes (const char *a, const char *b)
329 size_t aw_len, bw_len;
332 aw = find_word (a, &aw_len);
333 bw = find_word (b, &bw_len);
334 assert (aw != NULL && bw != NULL);
336 /* Words that are the same don't conflict. */
337 if (aw_len == bw_len && !buf_compare_case (aw, bw, aw_len))
340 /* Words that are otherwise the same in the first three letters
342 return ((aw_len > 3 && bw_len > 3)
343 || (aw_len == 3 && bw_len > 3)
344 || (bw_len == 3 && aw_len > 3)) && !buf_compare_case (aw, bw, 3);
347 /* Returns nonzero if CMD can be confused with another command
348 based on the first three letters of its first word. */
350 conflicting_3char_prefix_command (const struct command *cmd)
352 assert (cmd >= commands && cmd < commands + COMMAND_CNT);
354 return ((cmd > commands
355 && conflicting_3char_prefixes (cmd[-1].name, cmd[0].name))
356 || (cmd < commands + COMMAND_CNT
357 && conflicting_3char_prefixes (cmd[0].name, cmd[1].name)));
360 /* Ways that a set of words can match a command name. */
363 MISMATCH, /* Not a match. */
364 PARTIAL_MATCH, /* The words begin the command name. */
365 COMPLETE_MATCH /* The words are the command name. */
368 /* Figures out how well the WORD_CNT words in WORDS match CMD,
369 and returns the appropriate enum value. If WORDS are a
370 partial match for CMD and the next word in CMD is a dash, then
371 *DASH_POSSIBLE is set to 1 if DASH_POSSIBLE is non-null;
372 otherwise, *DASH_POSSIBLE is unchanged. */
373 static enum command_match
374 cmd_match_words (const struct command *cmd,
375 char *const words[], size_t word_cnt,
382 for (word = find_word (cmd->name, &word_len), word_idx = 0;
383 word != NULL && word_idx < word_cnt;
384 word = find_word (word + word_len, &word_len), word_idx++)
385 if (word_len != strlen (words[word_idx])
386 || buf_compare_case (word, words[word_idx], word_len))
388 size_t match_chars = match_strings (word, word_len,
390 strlen (words[word_idx]));
391 if (match_chars == 0)
396 else if (match_chars == 1 || match_chars == 2)
398 /* One- and two-character abbreviations are not
402 else if (match_chars == 3)
404 /* Three-character abbreviations are acceptable
405 in the first word of a command if there are
406 no name conflicts. They are always
407 acceptable after the first word. */
408 if (word_idx == 0 && conflicting_3char_prefix_command (cmd))
411 else /* match_chars > 3 */
413 /* Four-character and longer abbreviations are
414 always acceptable. */
418 if (word == NULL && word_idx == word_cnt)
420 /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR"}. */
421 return COMPLETE_MATCH;
423 else if (word == NULL)
425 /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR", "BAZ"}. */
430 /* cmd->name = "FOO BAR BAZ", words[] = {"FOO", "BAR"}. */
431 if (word[0] == '-' && dash_possible != NULL)
433 return PARTIAL_MATCH;
437 /* Returns the number of commands for which the WORD_CNT words in
438 WORDS are a partial or complete match. If some partial match
439 has a dash as the next word, then *DASH_POSSIBLE is set to 1,
440 otherwise it is set to 0. */
442 count_matching_commands (char *const words[], size_t word_cnt,
445 const struct command *cmd;
450 for (cmd = commands; cmd < commands + COMMAND_CNT; cmd++)
451 if (cmd_match_words (cmd, words, word_cnt, dash_possible) != MISMATCH)
454 return cmd_match_count;
457 /* Returns the command for which the WORD_CNT words in WORDS are
458 a complete match. Returns a null pointer if no such command
460 static const struct command *
461 get_complete_match (char *const words[], size_t word_cnt)
463 const struct command *cmd;
465 for (cmd = commands; cmd < commands + COMMAND_CNT; cmd++)
466 if (cmd_match_words (cmd, words, word_cnt, NULL) == COMPLETE_MATCH)
472 /* Frees the WORD_CNT words in WORDS. */
474 free_words (char *words[], size_t word_cnt)
478 for (idx = 0; idx < word_cnt; idx++)
482 /* Flags an error that the command whose name is given by the
483 WORD_CNT words in WORDS is unknown. */
485 unknown_command_error (char *const words[], size_t word_cnt)
492 for (idx = 0; idx < word_cnt; idx++)
493 words_len += strlen (words[idx]);
495 cp = name = xmalloc (words_len + word_cnt + 16);
496 for (idx = 0; idx < word_cnt; idx++)
500 cp = stpcpy (cp, words[idx]);
504 msg (SE, _("Unknown command %s."), name);
510 /* Parse the command name and return a pointer to the corresponding
511 struct command if successful.
512 If not successful, return a null pointer. */
513 static const struct command *
514 parse_command_name (void)
518 int complete_word_cnt;
522 word_cnt = complete_word_cnt = 0;
523 while (token == T_ID || (dash_possible && token == '-'))
527 assert (word_cnt < sizeof words / sizeof *words);
529 words[word_cnt] = xstrdup (ds_c_str (&tokstr));
531 words[word_cnt] = xstrdup ("-");
532 str_uppercase (words[word_cnt]);
535 cmd_match_cnt = count_matching_commands (words, word_cnt,
537 if (cmd_match_cnt == 0)
539 else if (cmd_match_cnt == 1)
541 const struct command *command = get_complete_match (words, word_cnt);
544 if (command->skip_entire_name)
546 if ( command->debug & !get_testing_mode () )
548 free_words (words, word_cnt);
552 else /* cmd_match_cnt > 1 */
554 /* Do we have a complete command name so far? */
555 if (get_complete_match (words, word_cnt) != NULL)
556 complete_word_cnt = word_cnt;
561 /* If we saw a complete command name earlier, drop back to
563 if (complete_word_cnt)
565 int pushback_word_cnt;
566 const struct command *command;
568 /* Get the command. */
569 command = get_complete_match (words, complete_word_cnt);
570 assert (command != NULL);
572 /* Figure out how many words we want to keep.
573 We normally want to swallow the entire command. */
574 pushback_word_cnt = complete_word_cnt + 1;
575 if (!command->skip_entire_name)
578 /* FIXME: We only support one-token pushback. */
579 assert (pushback_word_cnt + 1 >= word_cnt);
581 while (word_cnt > pushback_word_cnt)
584 if (strcmp (words[word_cnt], "-"))
585 lex_put_back_id (words[word_cnt]);
588 free (words[word_cnt]);
591 if ( command->debug && !get_testing_mode () )
594 free_words (words, word_cnt);
599 unknown_command_error (words, word_cnt);
600 free_words (words, word_cnt);
604 /* Simple commands. */
606 /* Parse and execute FINISH command. */
613 /* Parses the N command. */
615 cmd_n_of_cases (void)
620 if (!lex_force_int ())
624 if (!lex_match_id ("ESTIMATED"))
625 dict_set_case_limit (default_dict, x);
627 return lex_end_of_command ();
630 /* Parses, performs the EXECUTE procedure. */
634 if (!procedure (NULL, NULL))
635 return CMD_CASCADING_FAILURE;
636 return lex_end_of_command ();
639 /* Parses, performs the ERASE command. */
643 if (get_safer_mode ())
645 msg (SE, _("This command not allowed when the SAFER option is set."));
649 if (!lex_force_match_id ("FILE"))
652 if (!lex_force_string ())
655 if (remove (ds_c_str (&tokstr)) == -1)
657 msg (SW, _("Error removing `%s': %s."),
658 ds_c_str (&tokstr), strerror (errno));
666 /* Spawn a shell process. */
677 const char *shell_fn;
683 for (i = 3; i < 20; i++)
687 shell_fn = getenv ("SHELL");
688 if (shell_fn == NULL)
689 shell_fn = "/bin/sh";
692 const char *cp = strrchr (shell_fn, '/');
693 cp = cp ? &cp[1] : shell_fn;
694 shell_process = local_alloc (strlen (cp) + 8);
695 strcpy (shell_process, "-");
696 strcat (shell_process, cp);
697 if (strcmp (cp, "sh"))
698 shell_process[0] = '+';
701 execl (shell_fn, shell_process, NULL);
707 msg (SE, _("Couldn't fork: %s."), strerror (errno));
712 while (wait (NULL) != pid)
719 /* Parses the HOST command argument and executes the specified
720 command. Returns a suitable command return code. */
727 /* Handle either a string argument or a full-line argument. */
729 int c = lex_look_ahead ();
731 if (c == '\'' || c == '"')
734 if (!lex_force_string ())
736 cmd = ds_c_str (&tokstr);
741 cmd = lex_rest_of_line (NULL);
747 /* Execute the command. */
748 if (system (cmd) == -1)
749 msg (SE, _("Error executing command: %s."), strerror (errno));
751 /* Finish parsing. */
758 lex_error (_("expecting end of command"));
759 return CMD_TRAILING_GARBAGE;
768 /* Parses, performs the HOST command. */
774 if (get_safer_mode ())
776 msg (SE, _("This command not allowed when the SAFER option is set."));
781 /* Figure out whether to invoke an interactive shell or to execute a
782 single shell command. */
783 if (lex_look_ahead () == '.')
786 code = shell () ? CMD_PART_SUCCESS_MAYBE : CMD_SUCCESS;
789 code = run_command ();
791 /* Make sure that the system has a command interpreter, then run a
793 if (system (NULL) != 0)
794 code = run_command ();
797 msg (SE, _("No operating system support for this command."));
805 /* Parses, performs the NEW FILE command. */
809 discard_variables ();
811 return lex_end_of_command ();
814 /* Parses, performs the CLEAR TRANSFORMATIONS command. */
816 cmd_clear_transformations (void)
818 cancel_transformations ();
819 /* FIXME: what about variables created by transformations?
820 They need to be properly initialized. */