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
20 /* AIX requires this to be the first thing in the file. */
23 #define alloca __builtin_alloca
31 #ifndef alloca /* predefined by HP cc +Olibcalls */
65 /*#define DEBUGGING 1*/
66 #include "debug-print.h"
68 /* Global variables. */
70 /* A STATE_* constant giving the current program state. */
73 /* The name of the procedure currently executing, if any. */
76 /* Static variables. */
78 /* A single command. */
81 /* Initialized statically. */
82 char cmd[22]; /* Command name. */
83 int transition[4]; /* Transitions to make from each state. */
84 int (*func) (void); /* Function to call. */
86 /* Calculated at startup time. */
87 char *word[3]; /* cmd[], divided into individual words. */
88 struct command *next; /* Next command with same word[0]. */
91 /* Prototype all the command functions. */
92 #define DEFCMD(NAME, T1, T2, T3, T4, FUNC) \
94 #define UNIMPL(NAME, T1, T2, T3, T4)
95 #include "command.def"
99 /* Define the command array. */
100 #define DEFCMD(NAME, T1, T2, T3, T4, FUNC) \
101 {NAME, {T1, T2, T3, T4}, FUNC, {NULL, NULL, NULL}, NULL},
102 #define UNIMPL(NAME, T1, T2, T3, T4) \
103 {NAME, {T1, T2, T3, T4}, NULL, {NULL, NULL, NULL}, NULL},
104 static struct command cmd_table[] =
106 #include "command.def"
107 {"", {ERRO, ERRO, ERRO, ERRO}, NULL, {NULL, NULL, NULL}, NULL},
112 /* Command parser. */
114 static struct command *figure_out_command (void);
116 /* Breaks the `cmd' member of C into individual words and sets C's
117 word[] member appropriately. */
119 split_words (struct command *c)
124 cmd = xstrdup (c->cmd);
125 for (i = 0; i < 3; i++)
126 cmd = c->word[i] = strtok_r (i == 0 ? cmd : NULL, " -", &save);
129 /* Initializes the command parser. */
135 /* Break up command names into words. */
136 for (c = cmd_table; c->cmd[0]; c++)
139 /* Make chains of commands having the same first word. */
140 for (c = cmd_table; c->cmd[0]; c++)
142 struct command *first;
143 for (first = c; c[1].word[0] && !strcmp (c[0].word[0], c[1].word[0]); c++)
150 /* Determines whether command C is appropriate to call in this
151 part of a FILE TYPE structure. */
153 FILE_TYPE_okay (struct command *c)
157 if (c->func != cmd_record_type
158 && c->func != cmd_data_list
159 && c->func != cmd_repeating_data
160 && c->func != cmd_end_file_type)
161 msg (SE, _("%s not allowed inside FILE TYPE/END FILE TYPE."), c->cmd);
164 else if (c->func == cmd_repeating_data && fty.type == FTY_GROUPED)
165 msg (SE, _("%s not allowed inside FILE TYPE GROUPED/END FILE TYPE."),
167 else if (!fty.had_rec_type && c->func != cmd_record_type)
168 msg (SE, _("RECORD TYPE must be the first command inside a "
169 "FILE TYPE structure."));
175 if (c->func == cmd_record_type)
176 fty.had_rec_type = 1;
182 /* Parses an entire PSPP command. This includes everything from the
183 command name to the terminating dot. Does most of its work by
184 passing it off to the respective command dispatchers. Only called
185 by parse() in main.c. */
189 struct command *cp; /* Iterator used to find the proper command. */
192 /* The generic alloca package performs garbage collection when it is
193 called with an argument of zero. */
195 #endif /* C_ALLOCA */
197 /* Null commands can result from extra empty lines. */
201 /* Parse comments. */
202 if ((token == T_ID && !strcmp (tokid, "COMMENT"))
203 || token == T_EXP || token == '*' || token == '[')
209 /* Otherwise the line must begin with a command name, which is
210 always an ID token. */
213 msg (SE, _("This line does not begin with a valid command name."));
217 /* Parse the command name. */
218 cp = figure_out_command ();
221 if (cp->func == NULL)
223 msg (SE, _("%s is not yet implemented."), cp->cmd);
224 while (token && token != '.')
229 /* If we're in a FILE TYPE structure, only certain commands can be
231 if (pgm_state == STATE_INPUT && vfm_source == &file_type_source
232 && !FILE_TYPE_okay (cp))
235 /* Certain state transitions are not allowed. Check for these. */
236 assert (pgm_state >= 0 && pgm_state < STATE_ERROR);
237 if (cp->transition[pgm_state] == STATE_ERROR)
239 static const char *state_name[4] =
241 N_("%s is not allowed (1) before a command to specify the "
242 "input program, such as DATA LIST, (2) between FILE TYPE "
243 "and END FILE TYPE, (3) between INPUT PROGRAM and END "
245 N_("%s is not allowed within an input program."),
246 N_("%s is only allowed within an input program."),
247 N_("%s is only allowed within an input program."),
250 msg (SE, gettext (state_name[pgm_state]), cp->cmd);
255 if (cp->func != cmd_remark)
256 printf (_("%s command beginning\n"), cp->cmd);
259 /* The structured output manager numbers all its tables. Increment
260 the major table number for each separate procedure. */
266 /* Call the command dispatcher. Save and restore the name of
267 the current command around this call. */
269 const char *prev_proc;
271 prev_proc = cur_proc;
273 result = cp->func ();
274 cur_proc = prev_proc;
277 /* Perform the state transition if the command completed
278 successfully (at least in part). */
281 pgm_state = cp->transition[pgm_state];
283 if (pgm_state == STATE_ERROR)
285 discard_variables ();
286 pgm_state = STATE_INIT;
291 if (cp->func != cmd_remark)
292 printf (_("%s command completed\n\n"), cp->cmd);
295 /* Pass the command's success value up to the caller. */
300 /* Parse the command name and return a pointer to the corresponding
301 struct command if successful.
302 If not successful, return a null pointer. */
303 static struct command *
304 figure_out_command (void)
306 static const char *unk =
307 N_("The identifier(s) specified do not form a valid command name:");
309 static const char *inc =
310 N_("The identifier(s) specified do not form a complete command name:");
314 /* Parse the INCLUDE short form.
315 Note that `@' is a valid character in identifiers. */
317 return &cmd_table[0];
319 /* Find a command whose first word matches this identifier.
320 If it is the only command that begins with this word, return
322 for (cp = cmd_table; cp->cmd[0]; cp++)
323 if (lex_id_match (cp->word[0], tokid))
326 if (cp->cmd[0] == '\0')
328 msg (SE, "%s %s.", gettext (unk), ds_value (&tokstr));
332 if (cp->next == NULL)
335 /* We know that there is more than one command starting with this
336 word. Read the next word in the command name. */
338 struct command *ocp = cp;
340 /* Verify that the next token is an identifier, because we
341 must disambiguate this command name. */
345 /* If there's a command whose name is the first word only,
346 return it. This happens with, i.e., PRINT vs. PRINT
348 if (ocp->word[1] == NULL)
351 msg (SE, "%s %s.", gettext (inc), ds_value (&tokstr));
355 for (; cp; cp = cp->next)
356 if (cp->word[1] && lex_id_match (cp->word[1], tokid))
361 /* No match. If there's a command whose name is the first
362 word only, return it. This happens with, i.e., PRINT
364 if (ocp->word[1] == NULL)
367 msg (SE, "%s %s %s.", gettext (unk), ocp->word[0], tokid);
371 /* Check whether the next token is an identifier.
373 if (!isalpha ((unsigned char) (lex_look_ahead ())))
375 /* Check whether there is an unambiguous interpretation.
376 If not, give an error. */
379 && !strcmp (cp->word[1], cp->next->word[1]))
381 msg (SE, "%s %s %s.", gettext (inc), ocp->word[0], ocp->word[1]);
389 /* If this command can have a third word, disambiguate based on it. */
393 && !strcmp (cp->word[1], cp->next->word[1])))
395 struct command *ocp = cp;
398 assert (token == T_ID);
400 /* Try to find a command with this third word.
402 for (; cp; cp = cp->next)
404 && !strcmp (cp->word[1], ocp->word[1])
405 && lex_id_match (cp->word[2], tokid))
411 /* If no command with this third word found, make sure that
412 there's a command with those first two words but without a
417 msg (SE, "%s %s %s %s.",
418 gettext (unk), ocp->word[0], ocp->word[1], ds_value (&tokstr));
426 /* Simple commands. */
428 /* Parse and execute EXIT command. */
432 if (getl_reading_script)
434 msg (SE, _("This command is not accepted in a syntax file. "
435 "Instead, use FINISH to terminate a syntax file."));
444 /* Parse and execute FINISH command. */
448 /* Do not check for `.'
449 Do not fetch any extra tokens. */
450 if (getl_interactive)
452 msg (SM, _("This command is not executed "
453 "in interactive mode. Instead, PSPP drops "
454 "down to the command prompt. Use EXIT if you really want "
464 /* Extracts a null-terminated 8-or-fewer-character PREFIX from STRING.
465 PREFIX is converted to lowercase. Removes trailing spaces from
466 STRING as a side effect. */
468 extract_prefix (char *string, char *prefix)
470 /* Length of STRING. */
473 /* Points to the null terminator in STRING (`end pointer'). */
476 /* Strip spaces from end of STRING. */
477 len = strlen (string);
478 while (len && isspace ((unsigned char) string[len - 1]))
481 /* Find null terminator. */
482 ep = memchr (string, '\0', 8);
486 /* Copy prefix, converting to lowercase. */
488 *prefix++ = tolower ((unsigned char) (*string++));
492 /* Prints STRING on the console and to the listing file, replacing \n
495 output_line (char *string)
497 /* Location of \n in line read in. */
500 cp = strstr (string, "\\n");
504 tab_output_text (TAB_LEFT | TAT_NOWRAP, string);
506 cp = strstr (string, "\\n");
508 tab_output_text (TAB_LEFT | TAT_NOWRAP, string);
511 /* Parse and execute REMARK command. */
515 /* Points to the line read in. */
521 /* 8-character sentinel used to terminate remark. */
524 /* Beginning of line used to compare with SENTINEL. */
529 s = lex_rest_of_line (NULL);
536 /* Read in SENTINEL from end of current line. */
538 while (isspace ((unsigned char) *cp))
540 extract_prefix (cp, sentinel);
541 if (sentinel[0] == 0)
543 msg (SE, _("The sentinel may not be the empty string."));
547 /* Read in other lines until we encounter the sentinel. */
548 while (getl_read_line ())
550 extract_prefix (ds_value (&getl_buf), prefix);
551 if (!strcmp (sentinel, prefix))
554 /* Output the line. */
555 output_line (ds_value (&getl_buf));
558 /* Calling lex_entire_line() forces the sentinel line to be
560 getl_prompt = GETL_PRPT_STANDARD;
566 /* Parses the N command. */
568 cmd_n_of_cases (void)
575 lex_match_id ("CASES");
576 if (!lex_force_int ())
580 if (!lex_match_id ("ESTIMATED"))
583 return lex_end_of_command ();
586 /* Parses, performs the EXECUTE procedure. */
590 lex_match_id ("EXECUTE");
591 procedure (NULL, NULL, NULL);
592 return lex_end_of_command ();
595 /* Parses, performs the ERASE command. */
601 msg (SE, _("This command not allowed when the SAFER option is set."));
605 lex_match_id ("ERASE");
606 if (!lex_force_match_id ("FILE"))
609 if (!lex_force_string ())
612 if (remove (ds_value (&tokstr)) == -1)
614 msg (SW, _("Error removing `%s': %s."),
615 ds_value (&tokstr), strerror (errno));
619 return lex_end_of_command ();
623 /* Spawn a shell process. */
634 const char *shell_fn;
640 for (i = 3; i < 20; i++)
644 shell_fn = getenv ("SHELL");
645 if (shell_fn == NULL)
646 shell_fn = "/bin/sh";
649 const char *cp = strrchr (shell_fn, '/');
650 cp = cp ? &cp[1] : shell_fn;
651 shell_process = local_alloc (strlen (cp) + 8);
652 strcpy (shell_process, "-");
653 strcat (shell_process, cp);
654 if (strcmp (cp, "sh"))
655 shell_process[0] = '+';
658 execl (shell_fn, shell_process, NULL);
664 msg (SE, _("Couldn't fork: %s."), strerror (errno));
669 while (wait (NULL) != pid)
676 /* Parses the HOST command argument and executes the specified
677 command. Returns a suitable command return code. */
684 /* Handle either a string argument or a full-line argument. */
686 int c = lex_look_ahead ();
688 if (c == '\'' || c == '"')
691 if (!lex_force_string ())
693 cmd = ds_value (&tokstr);
698 cmd = lex_rest_of_line (NULL);
703 /* Execute the command. */
704 if (system (cmd) == -1)
705 msg (SE, _("Error executing command: %s."), strerror (errno));
707 /* Finish parsing. */
714 lex_error (_("expecting end of command"));
715 return CMD_TRAILING_GARBAGE;
724 /* Parses, performs the HOST command. */
732 msg (SE, _("This command not allowed when the SAFER option is set."));
736 lex_match_id ("HOST");
739 /* Figure out whether to invoke an interactive shell or to execute a
740 single shell command. */
741 if (lex_look_ahead () == '.')
744 code = shell () ? CMD_PART_SUCCESS_MAYBE : CMD_SUCCESS;
747 code = run_command ();
749 /* Make sure that the system has a command interpreter, then run a
751 if (system (NULL) != 0)
752 success = run_command ();
755 msg (SE, _("No operating system support for this command."));
756 success = CMD_FAILURE;
760 return code ? CMD_FAILURE : CMD_SUCCESS;
763 /* Parses, performs the NEW FILE command. */
767 lex_match_id ("NEW");
768 lex_match_id ("FILE");
770 discard_variables ();
772 return lex_end_of_command ();
775 /* Parses, performs the CLEAR TRANSFORMATIONS command. */
777 cmd_clear_transformations (void)
779 lex_match_id ("CLEAR");
780 lex_match_id ("TRANSFORMATIONS");
782 if (getl_reading_script)
784 msg (SW, _("This command is not valid in a syntax file."));
788 cancel_transformations ();