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., 59 Temple Place - Suite 330, Boston, MA
28 #include "dictionary.h"
48 /* Global variables. */
50 /* A STATE_* constant giving the current program state. */
53 /* The name of the procedure currently executing, if any. */
56 /* Static variables. */
58 /* A single command. */
61 const char *name; /* Command name. */
62 int transition[4]; /* Transitions to make from each state. */
63 int (*func) (void); /* Function to call. */
64 int skip_entire_name; /* If zero, we don't skip the
65 final token in the command name. */
68 /* Define the command array. */
69 #define DEFCMD(NAME, T1, T2, T3, T4, FUNC) \
70 {NAME, {T1, T2, T3, T4}, FUNC, 1},
71 #define SPCCMD(NAME, T1, T2, T3, T4, FUNC) \
72 {NAME, {T1, T2, T3, T4}, FUNC, 0},
73 #define UNIMPL(NAME, T1, T2, T3, T4) \
74 {NAME, {T1, T2, T3, T4}, NULL, 1},
75 static const struct command commands[] =
77 #include "command.def"
82 #define COMMAND_CNT (sizeof commands / sizeof *commands)
86 static const struct command *parse_command_name (void);
88 /* Determines whether command C is appropriate to call in this
89 part of a FILE TYPE structure. */
91 FILE_TYPE_okay (const struct command *c)
95 if (c->func != cmd_record_type
96 && c->func != cmd_data_list
97 && c->func != cmd_repeating_data
98 && c->func != cmd_end_file_type)
99 msg (SE, _("%s not allowed inside FILE TYPE/END FILE TYPE."), c->name);
102 else if (c->func == cmd_repeating_data && fty.type == FTY_GROUPED)
103 msg (SE, _("%s not allowed inside FILE TYPE GROUPED/END FILE TYPE."),
105 else if (!fty.had_rec_type && c->func != cmd_record_type)
106 msg (SE, _("RECORD TYPE must be the first command inside a "
107 "FILE TYPE structure."));
113 if (c->func == cmd_record_type)
114 fty.had_rec_type = 1;
120 /* Parses an entire PSPP command. This includes everything from the
121 command name to the terminating dot. Does most of its work by
122 passing it off to the respective command dispatchers. Only called
123 by parse() in main.c. */
127 const struct command *cp; /* Iterator used to find the proper command. */
130 /* The generic alloca package performs garbage collection when it is
131 called with an argument of zero. */
133 #endif /* C_ALLOCA */
135 /* Null commands can result from extra empty lines. */
139 /* Parse comments. */
140 if ((token == T_ID && !strcmp (tokid, "COMMENT"))
141 || token == T_EXP || token == '*' || token == '[')
147 /* Otherwise the line must begin with a command name, which is
148 always an ID token. */
151 lex_error (_("expecting command name"));
155 /* Parse the command name. */
156 cp = parse_command_name ();
159 if (cp->func == NULL)
161 msg (SE, _("%s is not yet implemented."), cp->name);
162 while (token && token != '.')
167 /* If we're in a FILE TYPE structure, only certain commands can be
169 if (pgm_state == STATE_INPUT
170 && case_source_is_class (vfm_source, &file_type_source_class)
171 && !FILE_TYPE_okay (cp))
174 /* Certain state transitions are not allowed. Check for these. */
175 assert (pgm_state >= 0 && pgm_state < STATE_ERROR);
176 if (cp->transition[pgm_state] == STATE_ERROR)
178 static const char *state_name[4] =
180 N_("%s is not allowed (1) before a command to specify the "
181 "input program, such as DATA LIST, (2) between FILE TYPE "
182 "and END FILE TYPE, (3) between INPUT PROGRAM and END "
184 N_("%s is not allowed within an input program."),
185 N_("%s is only allowed within an input program."),
186 N_("%s is only allowed within an input program."),
189 msg (SE, gettext (state_name[pgm_state]), cp->name);
193 /* The structured output manager numbers all its tables. Increment
194 the major table number for each separate procedure. */
200 /* Call the command dispatcher. Save and restore the name of
201 the current command around this call. */
203 const char *prev_proc;
205 prev_proc = cur_proc;
207 result = cp->func ();
208 cur_proc = prev_proc;
211 /* Perform the state transition if the command completed
212 successfully (at least in part). */
213 if (result != CMD_FAILURE)
215 pgm_state = cp->transition[pgm_state];
217 if (pgm_state == STATE_ERROR)
219 discard_variables ();
220 pgm_state = STATE_INIT;
224 /* Pass the command's success value up to the caller. */
230 match_strings (const char *a, size_t a_len,
231 const char *b, size_t b_len)
233 size_t match_len = 0;
235 while (a_len > 0 && b_len > 0)
237 /* Mismatch always returns zero. */
250 /* Returns the first character in the first word in STRING,
251 storing the word's length in *WORD_LEN. If no words remain,
252 returns a null pointer and stores 0 in *WORD_LEN. Words are
253 sequences of alphanumeric characters or single
254 non-alphanumeric characters. Words are delimited by
257 find_word (const char *string, size_t *word_len)
259 /* Skip whitespace and asterisks. */
260 while (isspace (*string))
270 /* Special one-character word? */
271 if (!isalnum ((unsigned char) *string))
277 /* Alphanumeric word. */
279 while (isalnum ((unsigned char) string[*word_len]))
285 /* Returns nonzero if strings A and B can be confused based on
286 their first three letters. */
288 conflicting_3char_prefixes (const char *a, const char *b)
290 size_t aw_len, bw_len;
293 aw = find_word (a, &aw_len);
294 bw = find_word (b, &bw_len);
295 assert (aw != NULL && bw != NULL);
297 /* Words that are the same don't conflict. */
298 if (aw_len == bw_len && !memcmp (aw, bw, aw_len))
301 /* Words that are otherwise the same in the first three letters
303 return ((aw_len > 3 && bw_len > 3)
304 || (aw_len == 3 && bw_len > 3)
305 || (bw_len == 3 && aw_len > 3)) && !memcmp (aw, bw, 3);
308 /* Returns nonzero if CMD can be confused with another command
309 based on the first three letters of its first word. */
311 conflicting_3char_prefix_command (const struct command *cmd)
313 assert (cmd >= commands && cmd < commands + COMMAND_CNT);
315 return ((cmd > commands
316 && conflicting_3char_prefixes (cmd[-1].name, cmd[0].name))
317 || (cmd < commands + COMMAND_CNT
318 && conflicting_3char_prefixes (cmd[0].name, cmd[1].name)));
321 /* Ways that a set of words can match a command name. */
324 MISMATCH, /* Not a match. */
325 PARTIAL_MATCH, /* The words begin the command name. */
326 COMPLETE_MATCH /* The words are the command name. */
329 /* Figures out how well the WORD_CNT words in WORDS match CMD,
330 and returns the appropriate enum value. If WORDS are a
331 partial match for CMD and the next word in CMD is a dash, then
332 *DASH_POSSIBLE is set to 1 if DASH_POSSIBLE is non-null;
333 otherwise, *DASH_POSSIBLE is unchanged. */
334 static enum command_match
335 cmd_match_words (const struct command *cmd,
336 char *const words[], size_t word_cnt,
343 for (word = find_word (cmd->name, &word_len), word_idx = 0;
344 word != NULL && word_idx < word_cnt;
345 word = find_word (word + word_len, &word_len), word_idx++)
346 if (word_len != strlen (words[word_idx])
347 || memcmp (word, words[word_idx], word_len))
349 size_t match_chars = match_strings (word, word_len,
351 strlen (words[word_idx]));
352 if (match_chars == 0)
357 else if (match_chars == 1 || match_chars == 2)
359 /* One- and two-character abbreviations are not
363 else if (match_chars == 3)
365 /* Three-character abbreviations are acceptable
366 in the first word of a command if there are
367 no name conflicts. They are always
368 acceptable after the first word. */
369 if (word_idx == 0 && conflicting_3char_prefix_command (cmd))
372 else /* match_chars > 3 */
374 /* Four-character and longer abbreviations are
375 always acceptable. */
379 if (word == NULL && word_idx == word_cnt)
381 /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR"}. */
382 return COMPLETE_MATCH;
384 else if (word == NULL)
386 /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR", "BAZ"}. */
391 /* cmd->name = "FOO BAR BAZ", words[] = {"FOO", "BAR"}. */
392 if (word[0] == '-' && dash_possible != NULL)
394 return PARTIAL_MATCH;
398 /* Returns the number of commands for which the WORD_CNT words in
399 WORDS are a partial or complete match. If some partial match
400 has a dash as the next word, then *DASH_POSSIBLE is set to 1,
401 otherwise it is set to 0. */
403 count_matching_commands (char *const words[], size_t word_cnt,
406 const struct command *cmd;
411 for (cmd = commands; cmd < commands + COMMAND_CNT; cmd++)
412 if (cmd_match_words (cmd, words, word_cnt, dash_possible) != MISMATCH)
415 return cmd_match_count;
418 /* Returns the command for which the WORD_CNT words in WORDS are
419 a complete match. Returns a null pointer if no such command
421 static const struct command *
422 get_complete_match (char *const words[], size_t word_cnt)
424 const struct command *cmd;
426 for (cmd = commands; cmd < commands + COMMAND_CNT; cmd++)
427 if (cmd_match_words (cmd, words, word_cnt, NULL) == COMPLETE_MATCH)
433 /* Frees the WORD_CNT words in WORDS. */
435 free_words (char *words[], size_t word_cnt)
439 for (idx = 0; idx < word_cnt; idx++)
443 /* Flags an error that the command whose name is given by the
444 WORD_CNT words in WORDS is unknown. */
446 unknown_command_error (char *const words[], size_t word_cnt)
453 for (idx = 0; idx < word_cnt; idx++)
454 words_len += strlen (words[idx]);
456 cp = name = xmalloc (words_len + word_cnt + 16);
457 for (idx = 0; idx < word_cnt; idx++)
461 cp = stpcpy (cp, words[idx]);
465 msg (SE, _("Unknown command %s."), name);
471 /* Parse the command name and return a pointer to the corresponding
472 struct command if successful.
473 If not successful, return a null pointer. */
474 static const struct command *
475 parse_command_name (void)
479 int complete_word_cnt;
483 word_cnt = complete_word_cnt = 0;
484 while (token == T_ID || (dash_possible && token == '-'))
488 assert (word_cnt < sizeof words / sizeof *words);
490 words[word_cnt++] = xstrdup (ds_c_str (&tokstr));
492 words[word_cnt++] = xstrdup ("-");
494 cmd_match_cnt = count_matching_commands (words, word_cnt,
496 if (cmd_match_cnt == 0)
498 else if (cmd_match_cnt == 1)
500 const struct command *command = get_complete_match (words, word_cnt);
503 if (command->skip_entire_name)
505 free_words (words, word_cnt);
509 else /* cmd_match_cnt > 1 */
511 /* Do we have a complete command name so far? */
512 if (get_complete_match (words, word_cnt) != NULL)
513 complete_word_cnt = word_cnt;
518 /* If we saw a complete command name earlier, drop back to
520 if (complete_word_cnt)
522 int pushback_word_cnt;
523 const struct command *command;
525 /* Get the command. */
526 command = get_complete_match (words, complete_word_cnt);
527 assert (command != NULL);
529 /* Figure out how many words we want to keep.
530 We normally want to swallow the entire command. */
531 pushback_word_cnt = complete_word_cnt + 1;
532 if (!command->skip_entire_name)
535 /* FIXME: We only support one-token pushback. */
536 assert (pushback_word_cnt + 1 >= word_cnt);
538 while (word_cnt > pushback_word_cnt)
541 if (strcmp (words[word_cnt], "-"))
542 lex_put_back_id (words[word_cnt]);
545 free (words[word_cnt]);
548 free_words (words, word_cnt);
552 unknown_command_error (words, word_cnt);
553 free_words (words, word_cnt);
557 /* Simple commands. */
559 /* Parse and execute EXIT command. */
563 if (getl_reading_script)
565 msg (SE, _("This command is not accepted in a syntax file. "
566 "Instead, use FINISH to terminate a syntax file."));
575 /* Parse and execute FINISH command. */
579 /* Do not check for `.'
580 Do not fetch any extra tokens. */
581 if (getl_interactive)
583 msg (SM, _("This command is not executed "
584 "in interactive mode. Instead, PSPP drops "
585 "down to the command prompt. Use EXIT if you really want "
595 /* Parses the N command. */
597 cmd_n_of_cases (void)
602 if (!lex_force_int ())
606 if (!lex_match_id ("ESTIMATED"))
607 dict_set_case_limit (default_dict, x);
609 return lex_end_of_command ();
612 /* Parses, performs the EXECUTE procedure. */
616 procedure (NULL, NULL);
617 return lex_end_of_command ();
620 /* Parses, performs the ERASE command. */
626 msg (SE, _("This command not allowed when the SAFER option is set."));
630 if (!lex_force_match_id ("FILE"))
633 if (!lex_force_string ())
636 if (remove (ds_c_str (&tokstr)) == -1)
638 msg (SW, _("Error removing `%s': %s."),
639 ds_c_str (&tokstr), strerror (errno));
647 /* Spawn a shell process. */
658 const char *shell_fn;
664 for (i = 3; i < 20; i++)
668 shell_fn = getenv ("SHELL");
669 if (shell_fn == NULL)
670 shell_fn = "/bin/sh";
673 const char *cp = strrchr (shell_fn, '/');
674 cp = cp ? &cp[1] : shell_fn;
675 shell_process = local_alloc (strlen (cp) + 8);
676 strcpy (shell_process, "-");
677 strcat (shell_process, cp);
678 if (strcmp (cp, "sh"))
679 shell_process[0] = '+';
682 execl (shell_fn, shell_process, NULL);
688 msg (SE, _("Couldn't fork: %s."), strerror (errno));
693 while (wait (NULL) != pid)
700 /* Parses the HOST command argument and executes the specified
701 command. Returns a suitable command return code. */
708 /* Handle either a string argument or a full-line argument. */
710 int c = lex_look_ahead ();
712 if (c == '\'' || c == '"')
715 if (!lex_force_string ())
717 cmd = ds_c_str (&tokstr);
722 cmd = lex_rest_of_line (NULL);
728 /* Execute the command. */
729 if (system (cmd) == -1)
730 msg (SE, _("Error executing command: %s."), strerror (errno));
732 /* Finish parsing. */
739 lex_error (_("expecting end of command"));
740 return CMD_TRAILING_GARBAGE;
749 /* Parses, performs the HOST command. */
757 msg (SE, _("This command not allowed when the SAFER option is set."));
762 /* Figure out whether to invoke an interactive shell or to execute a
763 single shell command. */
764 if (lex_look_ahead () == '.')
767 code = shell () ? CMD_PART_SUCCESS_MAYBE : CMD_SUCCESS;
770 code = run_command ();
772 /* Make sure that the system has a command interpreter, then run a
774 if (system (NULL) != 0)
775 code = run_command ();
778 msg (SE, _("No operating system support for this command."));
783 return code ? CMD_FAILURE : CMD_SUCCESS;
786 /* Parses, performs the NEW FILE command. */
790 discard_variables ();
792 return lex_end_of_command ();
795 /* Parses, performs the CLEAR TRANSFORMATIONS command. */
797 cmd_clear_transformations (void)
799 if (getl_reading_script)
801 msg (SW, _("This command is not valid in a syntax file."));
805 cancel_transformations ();
806 /* FIXME: what about variables created by transformations?
807 They need to be properly initialized. */