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 #include "debug-print.h"
49 /* Global variables. */
51 /* A STATE_* constant giving the current program state. */
54 /* The name of the procedure currently executing, if any. */
57 /* Static variables. */
59 /* A single command. */
62 /* Initialized statically. */
63 char cmd[22]; /* Command name. */
64 int transition[4]; /* Transitions to make from each state. */
65 int (*func) (void); /* Function to call. */
67 /* Calculated at startup time. */
68 char *word[3]; /* cmd[], divided into individual words. */
69 struct command *next; /* Next command with same word[0]. */
72 /* Define the command array. */
73 #define DEFCMD(NAME, T1, T2, T3, T4, FUNC) \
74 {NAME, {T1, T2, T3, T4}, FUNC, {NULL, NULL, NULL}, NULL},
75 #define UNIMPL(NAME, T1, T2, T3, T4) \
76 {NAME, {T1, T2, T3, T4}, NULL, {NULL, NULL, NULL}, NULL},
77 static struct command cmd_table[] =
79 #include "command.def"
80 {"", {ERRO, ERRO, ERRO, ERRO}, NULL, {NULL, NULL, NULL}, NULL},
87 static struct command *figure_out_command (void);
89 /* Breaks the `cmd' member of C into individual words and sets C's
90 word[] member appropriately. */
92 split_words (struct command *c)
97 cmd = xstrdup (c->cmd);
98 for (i = 0; i < 3; i++)
99 cmd = c->word[i] = strtok_r (i == 0 ? cmd : NULL, " -", &save);
102 /* Initializes the command parser. */
108 /* Break up command names into words. */
109 for (c = cmd_table; c->cmd[0]; c++)
112 /* Make chains of commands having the same first word. */
113 for (c = cmd_table; c->cmd[0]; c++)
115 struct command *first;
116 for (first = c; c[1].word[0] && !strcmp (c[0].word[0], c[1].word[0]); c++)
123 /* Determines whether command C is appropriate to call in this
124 part of a FILE TYPE structure. */
126 FILE_TYPE_okay (struct command *c)
130 if (c->func != cmd_record_type
131 && c->func != cmd_data_list
132 && c->func != cmd_repeating_data
133 && c->func != cmd_end_file_type)
134 msg (SE, _("%s not allowed inside FILE TYPE/END FILE TYPE."), c->cmd);
137 else if (c->func == cmd_repeating_data && fty.type == FTY_GROUPED)
138 msg (SE, _("%s not allowed inside FILE TYPE GROUPED/END FILE TYPE."),
140 else if (!fty.had_rec_type && c->func != cmd_record_type)
141 msg (SE, _("RECORD TYPE must be the first command inside a "
142 "FILE TYPE structure."));
148 if (c->func == cmd_record_type)
149 fty.had_rec_type = 1;
155 /* Parses an entire PSPP command. This includes everything from the
156 command name to the terminating dot. Does most of its work by
157 passing it off to the respective command dispatchers. Only called
158 by parse() in main.c. */
162 struct command *cp; /* Iterator used to find the proper command. */
165 /* The generic alloca package performs garbage collection when it is
166 called with an argument of zero. */
168 #endif /* C_ALLOCA */
170 /* Null commands can result from extra empty lines. */
174 /* Parse comments. */
175 if ((token == T_ID && !strcmp (tokid, "COMMENT"))
176 || token == T_EXP || token == '*' || token == '[')
182 /* Otherwise the line must begin with a command name, which is
183 always an ID token. */
186 msg (SE, _("This line does not begin with a valid command name."));
190 /* Parse the command name. */
191 cp = figure_out_command ();
194 if (cp->func == NULL)
196 msg (SE, _("%s is not yet implemented."), cp->cmd);
197 while (token && token != '.')
202 /* If we're in a FILE TYPE structure, only certain commands can be
204 if (pgm_state == STATE_INPUT
205 && case_source_is_class (vfm_source, &file_type_source_class)
206 && !FILE_TYPE_okay (cp))
209 /* Certain state transitions are not allowed. Check for these. */
210 assert (pgm_state >= 0 && pgm_state < STATE_ERROR);
211 if (cp->transition[pgm_state] == STATE_ERROR)
213 static const char *state_name[4] =
215 N_("%s is not allowed (1) before a command to specify the "
216 "input program, such as DATA LIST, (2) between FILE TYPE "
217 "and END FILE TYPE, (3) between INPUT PROGRAM and END "
219 N_("%s is not allowed within an input program."),
220 N_("%s is only allowed within an input program."),
221 N_("%s is only allowed within an input program."),
224 msg (SE, gettext (state_name[pgm_state]), cp->cmd);
229 if (cp->func != cmd_remark)
230 printf (_("%s command beginning\n"), cp->cmd);
233 /* The structured output manager numbers all its tables. Increment
234 the major table number for each separate procedure. */
240 /* Call the command dispatcher. Save and restore the name of
241 the current command around this call. */
243 const char *prev_proc;
245 prev_proc = cur_proc;
247 result = cp->func ();
248 cur_proc = prev_proc;
251 /* Perform the state transition if the command completed
252 successfully (at least in part). */
253 if (result != CMD_FAILURE)
255 pgm_state = cp->transition[pgm_state];
257 if (pgm_state == STATE_ERROR)
259 discard_variables ();
260 pgm_state = STATE_INIT;
265 if (cp->func != cmd_remark)
266 printf (_("%s command completed\n\n"), cp->cmd);
269 /* Pass the command's success value up to the caller. */
274 /* Parse the command name and return a pointer to the corresponding
275 struct command if successful.
276 If not successful, return a null pointer. */
277 static struct command *
278 figure_out_command (void)
280 static const char *unk =
281 N_("The identifier(s) specified do not form a valid command name:");
283 static const char *inc =
284 N_("The identifier(s) specified do not form a complete command name:");
288 /* Parse the INCLUDE short form.
289 Note that `@' is a valid character in identifiers. */
291 return &cmd_table[0];
293 /* Find a command whose first word matches this identifier.
294 If it is the only command that begins with this word, return
296 for (cp = cmd_table; cp->cmd[0]; cp++)
297 if (lex_id_match (cp->word[0], tokid))
300 if (cp->cmd[0] == '\0')
302 msg (SE, "%s %s.", gettext (unk), ds_value (&tokstr));
306 if (cp->next == NULL)
309 /* We know that there is more than one command starting with this
310 word. Read the next word in the command name. */
312 struct command *ocp = cp;
314 /* Verify that the next token is an identifier, because we
315 must disambiguate this command name. */
319 /* If there's a command whose name is the first word only,
320 return it. This happens with, i.e., PRINT vs. PRINT
322 if (ocp->word[1] == NULL)
325 msg (SE, "%s %s.", gettext (inc), ds_value (&tokstr));
329 for (; cp; cp = cp->next)
330 if (cp->word[1] && lex_id_match (cp->word[1], tokid))
335 /* No match. If there's a command whose name is the first
336 word only, return it. This happens with, i.e., PRINT
338 if (ocp->word[1] == NULL)
341 msg (SE, "%s %s %s.", gettext (unk), ocp->word[0], tokid);
345 /* Check whether the next token is an identifier.
347 if (!isalpha ((unsigned char) (lex_look_ahead ())))
349 /* Check whether there is an unambiguous interpretation.
350 If not, give an error. */
353 && !strcmp (cp->word[1], cp->next->word[1]))
355 msg (SE, "%s %s %s.", gettext (inc), ocp->word[0], ocp->word[1]);
363 /* If this command can have a third word, disambiguate based on it. */
367 && !strcmp (cp->word[1], cp->next->word[1])))
369 struct command *ocp = cp;
372 assert (token == T_ID);
374 /* Try to find a command with this third word.
376 for (; cp; cp = cp->next)
378 && !strcmp (cp->word[1], ocp->word[1])
379 && lex_id_match (cp->word[2], tokid))
385 /* If no command with this third word found, make sure that
386 there's a command with those first two words but without a
391 msg (SE, "%s %s %s %s.",
392 gettext (unk), ocp->word[0], ocp->word[1], ds_value (&tokstr));
400 /* Simple commands. */
402 /* Parse and execute EXIT command. */
406 if (getl_reading_script)
408 msg (SE, _("This command is not accepted in a syntax file. "
409 "Instead, use FINISH to terminate a syntax file."));
418 /* Parse and execute FINISH command. */
422 /* Do not check for `.'
423 Do not fetch any extra tokens. */
424 if (getl_interactive)
426 msg (SM, _("This command is not executed "
427 "in interactive mode. Instead, PSPP drops "
428 "down to the command prompt. Use EXIT if you really want "
438 /* Extracts a null-terminated 8-or-fewer-character PREFIX from STRING.
439 PREFIX is converted to lowercase. Removes trailing spaces from
440 STRING as a side effect. */
442 extract_prefix (char *string, char *prefix)
444 /* Length of STRING. */
447 /* Points to the null terminator in STRING (`end pointer'). */
450 /* Strip spaces from end of STRING. */
451 len = strlen (string);
452 while (len && isspace ((unsigned char) string[len - 1]))
455 /* Find null terminator. */
456 ep = memchr (string, '\0', 8);
460 /* Copy prefix, converting to lowercase. */
462 *prefix++ = tolower ((unsigned char) (*string++));
466 /* Prints STRING on the console and to the listing file, replacing \n
469 output_line (char *string)
471 /* Location of \n in line read in. */
474 cp = strstr (string, "\\n");
478 tab_output_text (TAB_LEFT | TAT_NOWRAP, string);
480 cp = strstr (string, "\\n");
482 tab_output_text (TAB_LEFT | TAT_NOWRAP, string);
485 /* Parse and execute REMARK command. */
489 /* Points to the line read in. */
495 /* 8-character sentinel used to terminate remark. */
498 /* Beginning of line used to compare with SENTINEL. */
503 s = lex_rest_of_line (NULL);
510 /* Read in SENTINEL from end of current line. */
512 while (isspace ((unsigned char) *cp))
514 extract_prefix (cp, sentinel);
515 if (sentinel[0] == 0)
517 msg (SE, _("The sentinel may not be the empty string."));
521 /* Read in other lines until we encounter the sentinel. */
522 while (getl_read_line ())
524 extract_prefix (ds_value (&getl_buf), prefix);
525 if (!strcmp (sentinel, prefix))
528 /* Output the line. */
529 output_line (ds_value (&getl_buf));
532 /* Calling lex_entire_line() forces the sentinel line to be
534 getl_prompt = GETL_PRPT_STANDARD;
540 /* Parses the N command. */
542 cmd_n_of_cases (void)
549 lex_match_id ("CASES");
550 if (!lex_force_int ())
554 if (!lex_match_id ("ESTIMATED"))
555 dict_set_case_limit (default_dict, x);
557 return lex_end_of_command ();
560 /* Parses, performs the EXECUTE procedure. */
564 lex_match_id ("EXECUTE");
565 procedure (NULL, NULL);
566 return lex_end_of_command ();
569 #define assert_not_safer() \
573 msg (SE, _("This command not allowed when the SAFER option is set.")); \
574 return CMD_FAILURE; \
578 /* Parses, performs the ERASE command. */
585 lex_match_id ("ERASE");
586 if (!lex_force_match_id ("FILE"))
589 if (!lex_force_string ())
592 if (remove (ds_value (&tokstr)) == -1)
594 msg (SW, _("Error removing `%s': %s."),
595 ds_value (&tokstr), strerror (errno));
603 /* Spawn a shell process. */
614 const char *shell_fn;
620 for (i = 3; i < 20; i++)
624 shell_fn = getenv ("SHELL");
625 if (shell_fn == NULL)
626 shell_fn = "/bin/sh";
629 const char *cp = strrchr (shell_fn, '/');
630 cp = cp ? &cp[1] : shell_fn;
631 shell_process = local_alloc (strlen (cp) + 8);
632 strcpy (shell_process, "-");
633 strcat (shell_process, cp);
634 if (strcmp (cp, "sh"))
635 shell_process[0] = '+';
638 execl (shell_fn, shell_process, NULL);
644 msg (SE, _("Couldn't fork: %s."), strerror (errno));
649 while (wait (NULL) != pid)
656 /* Parses the HOST command argument and executes the specified
657 command. Returns a suitable command return code. */
664 /* Handle either a string argument or a full-line argument. */
666 int c = lex_look_ahead ();
668 if (c == '\'' || c == '"')
671 if (!lex_force_string ())
673 cmd = ds_value (&tokstr);
678 cmd = lex_rest_of_line (NULL);
683 /* Execute the command. */
684 if (system (cmd) == -1)
685 msg (SE, _("Error executing command: %s."), strerror (errno));
687 /* Finish parsing. */
694 lex_error (_("expecting end of command"));
695 return CMD_TRAILING_GARBAGE;
704 /* Parses, performs the HOST command. */
712 lex_match_id ("HOST");
715 /* Figure out whether to invoke an interactive shell or to execute a
716 single shell command. */
717 if (lex_look_ahead () == '.')
720 code = shell () ? CMD_PART_SUCCESS_MAYBE : CMD_SUCCESS;
723 code = run_command ();
725 /* Make sure that the system has a command interpreter, then run a
727 if (system (NULL) != 0)
728 success = run_command ();
731 msg (SE, _("No operating system support for this command."));
732 success = CMD_FAILURE;
736 return code ? CMD_FAILURE : CMD_SUCCESS;
739 /* Parses, performs the NEW FILE command. */
743 lex_match_id ("NEW");
744 lex_match_id ("FILE");
746 discard_variables ();
748 return lex_end_of_command ();
751 /* Parses, performs the CLEAR TRANSFORMATIONS command. */
753 cmd_clear_transformations (void)
755 lex_match_id ("CLEAR");
756 lex_match_id ("TRANSFORMATIONS");
758 if (getl_reading_script)
760 msg (SW, _("This command is not valid in a syntax file."));
764 cancel_transformations ();