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
47 /* Global variables. */
49 /* A STATE_* constant giving the current program state. */
52 /* The name of the procedure currently executing, if any. */
55 /* Static variables. */
57 /* A single command. */
60 const char *name; /* Command name. */
61 int transition[4]; /* Transitions to make from each state. */
62 int (*func) (void); /* Function to call. */
63 int skip_entire_name; /* If zero, we don't skip the
64 final token in the command name. */
67 /* Define the command array. */
68 #define DEFCMD(NAME, T1, T2, T3, T4, FUNC) \
69 {NAME, {T1, T2, T3, T4}, FUNC, 1},
70 #define SPCCMD(NAME, T1, T2, T3, T4, FUNC) \
71 {NAME, {T1, T2, T3, T4}, FUNC, 0},
72 #define UNIMPL(NAME, T1, T2, T3, T4) \
73 {NAME, {T1, T2, T3, T4}, NULL, 1},
74 static const struct command commands[] =
76 #include "command.def"
81 #define COMMAND_CNT (sizeof commands / sizeof *commands)
85 static const struct command *parse_command_name (void);
87 /* Determines whether command C is appropriate to call in this
88 part of a FILE TYPE structure. */
90 FILE_TYPE_okay (const struct command *c)
94 if (c->func != cmd_record_type
95 && c->func != cmd_data_list
96 && c->func != cmd_repeating_data
97 && c->func != cmd_end_file_type)
98 msg (SE, _("%s not allowed inside FILE TYPE/END FILE TYPE."), c->name);
101 else if (c->func == cmd_repeating_data && fty.type == FTY_GROUPED)
102 msg (SE, _("%s not allowed inside FILE TYPE GROUPED/END FILE TYPE."),
104 else if (!fty.had_rec_type && c->func != cmd_record_type)
105 msg (SE, _("RECORD TYPE must be the first command inside a "
106 "FILE TYPE structure."));
112 if (c->func == cmd_record_type)
113 fty.had_rec_type = 1;
119 /* Parses an entire PSPP command. This includes everything from the
120 command name to the terminating dot. Does most of its work by
121 passing it off to the respective command dispatchers. Only called
122 by parse() in main.c. */
126 const struct command *cp; /* Iterator used to find the proper command. */
129 /* The generic alloca package performs garbage collection when it is
130 called with an argument of zero. */
132 #endif /* C_ALLOCA */
134 /* Null commands can result from extra empty lines. */
138 /* Parse comments. */
139 if ((token == T_ID && !strcmp (tokid, "COMMENT"))
140 || token == T_EXP || token == '*' || token == '[')
146 /* Otherwise the line must begin with a command name, which is
147 always an ID token. */
150 lex_error (_("expecting command name"));
154 /* Parse the command name. */
155 cp = parse_command_name ();
158 if (cp->func == NULL)
160 msg (SE, _("%s is not yet implemented."), cp->name);
161 while (token && token != '.')
166 /* If we're in a FILE TYPE structure, only certain commands can be
168 if (pgm_state == STATE_INPUT
169 && case_source_is_class (vfm_source, &file_type_source_class)
170 && !FILE_TYPE_okay (cp))
173 /* Certain state transitions are not allowed. Check for these. */
174 assert (pgm_state >= 0 && pgm_state < STATE_ERROR);
175 if (cp->transition[pgm_state] == STATE_ERROR)
177 static const char *state_name[4] =
179 N_("%s is not allowed (1) before a command to specify the "
180 "input program, such as DATA LIST, (2) between FILE TYPE "
181 "and END FILE TYPE, (3) between INPUT PROGRAM and END "
183 N_("%s is not allowed within an input program."),
184 N_("%s is only allowed within an input program."),
185 N_("%s is only allowed within an input program."),
188 msg (SE, gettext (state_name[pgm_state]), cp->name);
192 /* The structured output manager numbers all its tables. Increment
193 the major table number for each separate procedure. */
199 /* Call the command dispatcher. Save and restore the name of
200 the current command around this call. */
202 const char *prev_proc;
204 prev_proc = cur_proc;
206 result = cp->func ();
207 cur_proc = prev_proc;
210 /* Perform the state transition if the command completed
211 successfully (at least in part). */
212 if (result != CMD_FAILURE)
214 pgm_state = cp->transition[pgm_state];
216 if (pgm_state == STATE_ERROR)
218 discard_variables ();
219 pgm_state = STATE_INIT;
223 /* Pass the command's success value up to the caller. */
229 match_strings (const char *a, size_t a_len,
230 const char *b, size_t b_len)
232 size_t match_len = 0;
234 while (a_len > 0 && b_len > 0)
236 /* Mismatch always returns zero. */
249 /* Returns the first character in the first word in STRING,
250 storing the word's length in *WORD_LEN. If no words remain,
251 returns a null pointer and stores 0 in *WORD_LEN. Words are
252 sequences of alphanumeric characters or single
253 non-alphanumeric characters. Words are delimited by
256 find_word (const char *string, size_t *word_len)
258 /* Skip whitespace and asterisks. */
259 while (isspace (*string))
269 /* Special one-character word? */
270 if (!isalnum ((unsigned char) *string))
276 /* Alphanumeric word. */
278 while (isalnum ((unsigned char) string[*word_len]))
284 /* Returns nonzero if strings A and B can be confused based on
285 their first three letters. */
287 conflicting_3char_prefixes (const char *a, const char *b)
289 size_t aw_len, bw_len;
292 aw = find_word (a, &aw_len);
293 bw = find_word (b, &bw_len);
294 assert (aw != NULL && bw != NULL);
296 return ((aw_len > 3 && bw_len > 3)
297 || (aw_len == 3 && bw_len > 3)
298 || (bw_len == 3 && aw_len > 3)) && !memcmp (aw, bw, 3);
301 /* Returns nonzero if CMD can be confused with another command
302 based on the first three letters of its first word. */
304 conflicting_3char_prefix_command (const struct command *cmd)
306 assert (cmd >= commands && cmd < commands + COMMAND_CNT);
308 return ((cmd > commands
309 && conflicting_3char_prefixes (cmd[-1].name, cmd[0].name))
310 || (cmd < commands + COMMAND_CNT
311 && conflicting_3char_prefixes (cmd[0].name, cmd[1].name)));
314 /* Ways that a set of words can match a command name. */
317 MISMATCH, /* Not a match. */
318 PARTIAL_MATCH, /* The words begin the command name. */
319 COMPLETE_MATCH /* The words are the command name. */
322 /* Figures out how well the WORD_CNT words in WORDS match CMD,
323 and returns the appropriate enum value. If WORDS are a
324 partial match for CMD and the next word in CMD is a dash, then
325 *DASH_POSSIBLE is set to 1 if DASH_POSSIBLE is non-null;
326 otherwise, *DASH_POSSIBLE is unchanged. */
327 static enum command_match
328 cmd_match_words (const struct command *cmd,
329 char *const words[], size_t word_cnt,
336 for (word = find_word (cmd->name, &word_len), word_idx = 0;
337 word != NULL && word_idx < word_cnt;
338 word = find_word (word + word_len, &word_len), word_idx++)
339 if (word_len != strlen (words[word_idx])
340 || memcmp (word, words[word_idx], word_len))
342 size_t match_chars = match_strings (word, word_len,
344 strlen (words[word_idx]));
345 if (match_chars == 0)
350 else if (match_chars == 1 || match_chars == 2)
352 /* One- and two-character abbreviations are not
356 else if (match_chars == 3)
358 /* Three-character abbreviations are acceptable
359 in the first word of a command if there are
360 no name conflicts. They are always
361 acceptable after the first word. */
362 if (word_idx == 0 && conflicting_3char_prefix_command (cmd))
365 else /* match_chars > 3 */
367 /* Four-character and longer abbreviations are
368 always acceptable. */
372 if (word == NULL && word_idx == word_cnt)
374 /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR"}. */
375 return COMPLETE_MATCH;
377 else if (word == NULL)
379 /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR", "BAZ"}. */
384 /* cmd->name = "FOO BAR BAZ", words[] = {"FOO", "BAR"}. */
385 if (word[0] == '-' && dash_possible != NULL)
387 return PARTIAL_MATCH;
391 /* Returns the number of commands for which the WORD_CNT words in
392 WORDS are a partial or complete match. If some partial match
393 has a dash as the next word, then *DASH_POSSIBLE is set to 1,
394 otherwise it is set to 0. */
396 count_matching_commands (char *const words[], size_t word_cnt,
399 const struct command *cmd;
404 for (cmd = commands; cmd < commands + COMMAND_CNT; cmd++)
405 if (cmd_match_words (cmd, words, word_cnt, dash_possible) != MISMATCH)
408 return cmd_match_count;
411 /* Returns the command for which the WORD_CNT words in WORDS are
412 a complete match. Returns a null pointer if no such command
414 static const struct command *
415 get_complete_match (char *const words[], size_t word_cnt)
417 const struct command *cmd;
419 for (cmd = commands; cmd < commands + COMMAND_CNT; cmd++)
420 if (cmd_match_words (cmd, words, word_cnt, NULL) == COMPLETE_MATCH)
426 /* Frees the WORD_CNT words in WORDS. */
428 free_words (char *words[], size_t word_cnt)
432 for (idx = 0; idx < word_cnt; idx++)
436 /* Flags an error that the command whose name is given by the
437 WORD_CNT words in WORDS is unknown. */
439 unknown_command_error (char *const words[], size_t word_cnt)
446 for (idx = 0; idx < word_cnt; idx++)
447 words_len += strlen (words[idx]);
449 cp = name = xmalloc (words_len + word_cnt + 16);
450 for (idx = 0; idx < word_cnt; idx++)
454 cp = stpcpy (cp, words[idx]);
458 msg (SE, _("Unknown command %s."), name);
464 /* Parse the command name and return a pointer to the corresponding
465 struct command if successful.
466 If not successful, return a null pointer. */
467 static const struct command *
468 parse_command_name (void)
472 int complete_word_cnt;
476 word_cnt = complete_word_cnt = 0;
477 while (token == T_ID || (dash_possible && token == '-'))
481 assert (word_cnt < sizeof words / sizeof *words);
483 words[word_cnt++] = xstrdup (ds_value (&tokstr));
485 words[word_cnt++] = xstrdup ("-");
487 cmd_match_cnt = count_matching_commands (words, word_cnt,
489 if (cmd_match_cnt == 0)
491 else if (cmd_match_cnt == 1)
493 const struct command *command = get_complete_match (words, word_cnt);
496 if (command->skip_entire_name)
498 free_words (words, word_cnt);
502 else /* cmd_match_cnt > 1 */
504 /* Do we have a complete command name so far? */
505 if (get_complete_match (words, word_cnt) != NULL)
506 complete_word_cnt = word_cnt;
511 /* If we saw a complete command name earlier, drop back to
513 if (complete_word_cnt)
515 int pushback_word_cnt;
516 const struct command *command;
518 /* Get the command. */
519 command = get_complete_match (words, complete_word_cnt);
520 assert (command != NULL);
522 /* Figure out how many words we want to keep.
523 We normally want to swallow the entire command. */
524 pushback_word_cnt = complete_word_cnt + 1;
525 if (!command->skip_entire_name)
528 /* FIXME: We only support one-token pushback. */
529 assert (pushback_word_cnt + 1 >= word_cnt);
531 while (word_cnt > pushback_word_cnt)
534 if (strcmp (words[word_cnt], "-"))
535 lex_put_back_id (words[word_cnt]);
538 free (words[word_cnt]);
541 free_words (words, word_cnt);
545 unknown_command_error (words, word_cnt);
546 free_words (words, word_cnt);
550 /* Simple commands. */
552 /* Parse and execute EXIT command. */
556 if (getl_reading_script)
558 msg (SE, _("This command is not accepted in a syntax file. "
559 "Instead, use FINISH to terminate a syntax file."));
568 /* Parse and execute FINISH command. */
572 /* Do not check for `.'
573 Do not fetch any extra tokens. */
574 if (getl_interactive)
576 msg (SM, _("This command is not executed "
577 "in interactive mode. Instead, PSPP drops "
578 "down to the command prompt. Use EXIT if you really want "
588 /* Extracts a null-terminated 8-or-fewer-character PREFIX from STRING.
589 PREFIX is converted to lowercase. Removes trailing spaces from
590 STRING as a side effect. */
592 extract_prefix (char *string, char *prefix)
594 /* Length of STRING. */
597 /* Points to the null terminator in STRING (`end pointer'). */
600 /* Strip spaces from end of STRING. */
601 len = strlen (string);
602 while (len && isspace ((unsigned char) string[len - 1]))
605 /* Find null terminator. */
606 ep = memchr (string, '\0', 8);
610 /* Copy prefix, converting to lowercase. */
612 *prefix++ = tolower ((unsigned char) (*string++));
616 /* Prints STRING on the console and to the listing file, replacing \n
619 output_line (char *string)
621 /* Location of \n in line read in. */
624 cp = strstr (string, "\\n");
628 tab_output_text (TAB_LEFT | TAT_NOWRAP, string);
630 cp = strstr (string, "\\n");
632 tab_output_text (TAB_LEFT | TAT_NOWRAP, string);
635 /* Parse and execute REMARK command. */
639 /* Points to the line read in. */
645 /* 8-character sentinel used to terminate remark. */
648 /* Beginning of line used to compare with SENTINEL. */
653 s = lex_rest_of_line (NULL);
660 /* Read in SENTINEL from end of current line. */
662 while (isspace ((unsigned char) *cp))
664 extract_prefix (cp, sentinel);
665 if (sentinel[0] == 0)
667 msg (SE, _("The sentinel may not be the empty string."));
671 /* Read in other lines until we encounter the sentinel. */
672 while (getl_read_line ())
674 extract_prefix (ds_value (&getl_buf), prefix);
675 if (!strcmp (sentinel, prefix))
678 /* Output the line. */
679 output_line (ds_value (&getl_buf));
682 /* Calling lex_entire_line() forces the sentinel line to be
684 getl_prompt = GETL_PRPT_STANDARD;
690 /* Parses the N command. */
692 cmd_n_of_cases (void)
697 if (!lex_force_int ())
701 if (!lex_match_id ("ESTIMATED"))
702 dict_set_case_limit (default_dict, x);
704 return lex_end_of_command ();
707 /* Parses, performs the EXECUTE procedure. */
711 procedure (NULL, NULL);
712 return lex_end_of_command ();
715 /* Parses, performs the ERASE command. */
721 msg (SE, _("This command not allowed when the SAFER option is set."));
725 if (!lex_force_match_id ("FILE"))
728 if (!lex_force_string ())
731 if (remove (ds_value (&tokstr)) == -1)
733 msg (SW, _("Error removing `%s': %s."),
734 ds_value (&tokstr), strerror (errno));
742 /* Spawn a shell process. */
753 const char *shell_fn;
759 for (i = 3; i < 20; i++)
763 shell_fn = getenv ("SHELL");
764 if (shell_fn == NULL)
765 shell_fn = "/bin/sh";
768 const char *cp = strrchr (shell_fn, '/');
769 cp = cp ? &cp[1] : shell_fn;
770 shell_process = local_alloc (strlen (cp) + 8);
771 strcpy (shell_process, "-");
772 strcat (shell_process, cp);
773 if (strcmp (cp, "sh"))
774 shell_process[0] = '+';
777 execl (shell_fn, shell_process, NULL);
783 msg (SE, _("Couldn't fork: %s."), strerror (errno));
788 while (wait (NULL) != pid)
795 /* Parses the HOST command argument and executes the specified
796 command. Returns a suitable command return code. */
803 /* Handle either a string argument or a full-line argument. */
805 int c = lex_look_ahead ();
807 if (c == '\'' || c == '"')
810 if (!lex_force_string ())
812 cmd = ds_value (&tokstr);
817 cmd = lex_rest_of_line (NULL);
822 /* Execute the command. */
823 if (system (cmd) == -1)
824 msg (SE, _("Error executing command: %s."), strerror (errno));
826 /* Finish parsing. */
833 lex_error (_("expecting end of command"));
834 return CMD_TRAILING_GARBAGE;
843 /* Parses, performs the HOST command. */
851 msg (SE, _("This command not allowed when the SAFER option is set."));
856 /* Figure out whether to invoke an interactive shell or to execute a
857 single shell command. */
858 if (lex_look_ahead () == '.')
861 code = shell () ? CMD_PART_SUCCESS_MAYBE : CMD_SUCCESS;
864 code = run_command ();
866 /* Make sure that the system has a command interpreter, then run a
868 if (system (NULL) != 0)
869 success = run_command ();
872 msg (SE, _("No operating system support for this command."));
873 success = CMD_FAILURE;
877 return code ? CMD_FAILURE : CMD_SUCCESS;
880 /* Parses, performs the NEW FILE command. */
884 discard_variables ();
886 return lex_end_of_command ();
889 /* Parses, performs the CLEAR TRANSFORMATIONS command. */
891 cmd_clear_transformations (void)
893 if (getl_reading_script)
895 msg (SW, _("This command is not valid in a syntax file."));
899 cancel_transformations ();
900 /* FIXME: what about variables created by transformations?
901 They need to be properly initialized. */