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 */
64 #include "debug-print.h"
66 /* Global variables. */
68 /* A STATE_* constant giving the current program state. */
71 /* The name of the procedure currently executing, if any. */
74 /* Static variables. */
76 /* A single command. */
79 /* Initialized statically. */
80 char cmd[22]; /* Command name. */
81 int transition[4]; /* Transitions to make from each state. */
82 int (*func) (void); /* Function to call. */
84 /* Calculated at startup time. */
85 char *word[3]; /* cmd[], divided into individual words. */
86 struct command *next; /* Next command with same word[0]. */
89 /* Prototype all the command functions. */
90 #define DEFCMD(NAME, T1, T2, T3, T4, FUNC) \
92 #define UNIMPL(NAME, T1, T2, T3, T4)
93 #include "command.def"
97 /* Define the command array. */
98 #define DEFCMD(NAME, T1, T2, T3, T4, FUNC) \
99 {NAME, {T1, T2, T3, T4}, FUNC, {NULL, NULL, NULL}, NULL},
100 #define UNIMPL(NAME, T1, T2, T3, T4) \
101 {NAME, {T1, T2, T3, T4}, NULL, {NULL, NULL, NULL}, NULL},
102 static struct command cmd_table[] =
104 #include "command.def"
105 {"", {ERRO, ERRO, ERRO, ERRO}, NULL, {NULL, NULL, NULL}, NULL},
110 /* Command parser. */
112 static struct command *figure_out_command (void);
114 /* Breaks the `cmd' member of C into individual words and sets C's
115 word[] member appropriately. */
117 split_words (struct command *c)
122 cmd = xstrdup (c->cmd);
123 for (i = 0; i < 3; i++)
124 cmd = c->word[i] = strtok_r (i == 0 ? cmd : NULL, " -", &save);
127 /* Initializes the command parser. */
133 /* Break up command names into words. */
134 for (c = cmd_table; c->cmd[0]; c++)
137 /* Make chains of commands having the same first word. */
138 for (c = cmd_table; c->cmd[0]; c++)
140 struct command *first;
141 for (first = c; c[1].word[0] && !strcmp (c[0].word[0], c[1].word[0]); c++)
148 /* Determines whether command C is appropriate to call in this
149 part of a FILE TYPE structure. */
151 FILE_TYPE_okay (struct command *c)
155 if (c->func != cmd_record_type
156 && c->func != cmd_data_list
157 && c->func != cmd_repeating_data
158 && c->func != cmd_end_file_type)
159 msg (SE, _("%s not allowed inside FILE TYPE/END FILE TYPE."), c->cmd);
162 else if (c->func == cmd_repeating_data && fty.type == FTY_GROUPED)
163 msg (SE, _("%s not allowed inside FILE TYPE GROUPED/END FILE TYPE."),
165 else if (!fty.had_rec_type && c->func != cmd_record_type)
166 msg (SE, _("RECORD TYPE must be the first command inside a "
167 "FILE TYPE structure."));
173 if (c->func == cmd_record_type)
174 fty.had_rec_type = 1;
180 /* Parses an entire PSPP command. This includes everything from the
181 command name to the terminating dot. Does most of its work by
182 passing it off to the respective command dispatchers. Only called
183 by parse() in main.c. */
187 struct command *cp; /* Iterator used to find the proper command. */
190 /* The generic alloca package performs garbage collection when it is
191 called with an argument of zero. */
193 #endif /* C_ALLOCA */
195 /* Null commands can result from extra empty lines. */
199 /* Parse comments. */
200 if ((token == T_ID && !strcmp (tokid, "COMMENT"))
201 || token == T_EXP || token == '*' || token == '[')
207 /* Otherwise the line must begin with a command name, which is
208 always an ID token. */
211 msg (SE, _("This line does not begin with a valid command name."));
215 /* Parse the command name. */
216 cp = figure_out_command ();
219 if (cp->func == NULL)
221 msg (SE, _("%s is not yet implemented."), cp->cmd);
222 while (token && token != '.')
227 /* If we're in a FILE TYPE structure, only certain commands can be
229 if (pgm_state == STATE_INPUT && vfm_source == &file_type_source
230 && !FILE_TYPE_okay (cp))
233 /* Certain state transitions are not allowed. Check for these. */
234 assert (pgm_state >= 0 && pgm_state < STATE_ERROR);
235 if (cp->transition[pgm_state] == STATE_ERROR)
237 static const char *state_name[4] =
239 N_("%s is not allowed (1) before a command to specify the "
240 "input program, such as DATA LIST, (2) between FILE TYPE "
241 "and END FILE TYPE, (3) between INPUT PROGRAM and END "
243 N_("%s is not allowed within an input program."),
244 N_("%s is only allowed within an input program."),
245 N_("%s is only allowed within an input program."),
248 msg (SE, gettext (state_name[pgm_state]), cp->cmd);
253 if (cp->func != cmd_remark)
254 printf (_("%s command beginning\n"), cp->cmd);
257 /* The structured output manager numbers all its tables. Increment
258 the major table number for each separate procedure. */
264 /* Call the command dispatcher. Save and restore the name of
265 the current command around this call. */
267 const char *prev_proc;
269 prev_proc = cur_proc;
271 result = cp->func ();
272 cur_proc = prev_proc;
275 /* Perform the state transition if the command completed
276 successfully (at least in part). */
279 pgm_state = cp->transition[pgm_state];
281 if (pgm_state == STATE_ERROR)
283 discard_variables ();
284 pgm_state = STATE_INIT;
289 if (cp->func != cmd_remark)
290 printf (_("%s command completed\n\n"), cp->cmd);
293 /* Pass the command's success value up to the caller. */
298 /* Parse the command name and return a pointer to the corresponding
299 struct command if successful.
300 If not successful, return a null pointer. */
301 static struct command *
302 figure_out_command (void)
304 static const char *unk =
305 N_("The identifier(s) specified do not form a valid command name:");
307 static const char *inc =
308 N_("The identifier(s) specified do not form a complete command name:");
312 /* Parse the INCLUDE short form.
313 Note that `@' is a valid character in identifiers. */
315 return &cmd_table[0];
317 /* Find a command whose first word matches this identifier.
318 If it is the only command that begins with this word, return
320 for (cp = cmd_table; cp->cmd[0]; cp++)
321 if (lex_id_match (cp->word[0], tokid))
324 if (cp->cmd[0] == '\0')
326 msg (SE, "%s %s.", gettext (unk), ds_value (&tokstr));
330 if (cp->next == NULL)
333 /* We know that there is more than one command starting with this
334 word. Read the next word in the command name. */
336 struct command *ocp = cp;
338 /* Verify that the next token is an identifier, because we
339 must disambiguate this command name. */
343 /* If there's a command whose name is the first word only,
344 return it. This happens with, i.e., PRINT vs. PRINT
346 if (ocp->word[1] == NULL)
349 msg (SE, "%s %s.", gettext (inc), ds_value (&tokstr));
353 for (; cp; cp = cp->next)
354 if (cp->word[1] && lex_id_match (cp->word[1], tokid))
359 /* No match. If there's a command whose name is the first
360 word only, return it. This happens with, i.e., PRINT
362 if (ocp->word[1] == NULL)
365 msg (SE, "%s %s %s.", gettext (unk), ocp->word[0], tokid);
369 /* Check whether the next token is an identifier.
371 if (!isalpha ((unsigned char) (lex_look_ahead ())))
373 /* Check whether there is an unambiguous interpretation.
374 If not, give an error. */
377 && !strcmp (cp->word[1], cp->next->word[1]))
379 msg (SE, "%s %s %s.", gettext (inc), ocp->word[0], ocp->word[1]);
387 /* If this command can have a third word, disambiguate based on it. */
391 && !strcmp (cp->word[1], cp->next->word[1])))
393 struct command *ocp = cp;
396 assert (token == T_ID);
398 /* Try to find a command with this third word.
400 for (; cp; cp = cp->next)
402 && !strcmp (cp->word[1], ocp->word[1])
403 && lex_id_match (cp->word[2], tokid))
409 /* If no command with this third word found, make sure that
410 there's a command with those first two words but without a
415 msg (SE, "%s %s %s %s.",
416 gettext (unk), ocp->word[0], ocp->word[1], ds_value (&tokstr));
424 /* Simple commands. */
426 /* Parse and execute EXIT command. */
430 if (getl_reading_script)
432 msg (SE, _("This command is not accepted in a syntax file. "
433 "Instead, use FINISH to terminate a syntax file."));
442 /* Parse and execute FINISH command. */
446 /* Do not check for `.'
447 Do not fetch any extra tokens. */
448 if (getl_interactive)
450 msg (SM, _("This command is not executed "
451 "in interactive mode. Instead, PSPP drops "
452 "down to the command prompt. Use EXIT if you really want "
462 /* Extracts a null-terminated 8-or-fewer-character PREFIX from STRING.
463 PREFIX is converted to lowercase. Removes trailing spaces from
464 STRING as a side effect. */
466 extract_prefix (char *string, char *prefix)
468 /* Length of STRING. */
471 /* Points to the null terminator in STRING (`end pointer'). */
474 /* Strip spaces from end of STRING. */
475 len = strlen (string);
476 while (len && isspace ((unsigned char) string[len - 1]))
479 /* Find null terminator. */
480 ep = memchr (string, '\0', 8);
484 /* Copy prefix, converting to lowercase. */
486 *prefix++ = tolower ((unsigned char) (*string++));
490 /* Prints STRING on the console and to the listing file, replacing \n
493 output_line (char *string)
495 /* Location of \n in line read in. */
498 cp = strstr (string, "\\n");
502 tab_output_text (TAB_LEFT | TAT_NOWRAP, string);
504 cp = strstr (string, "\\n");
506 tab_output_text (TAB_LEFT | TAT_NOWRAP, string);
509 /* Parse and execute REMARK command. */
513 /* Points to the line read in. */
519 /* 8-character sentinel used to terminate remark. */
522 /* Beginning of line used to compare with SENTINEL. */
527 s = lex_rest_of_line (NULL);
534 /* Read in SENTINEL from end of current line. */
536 while (isspace ((unsigned char) *cp))
538 extract_prefix (cp, sentinel);
539 if (sentinel[0] == 0)
541 msg (SE, _("The sentinel may not be the empty string."));
545 /* Read in other lines until we encounter the sentinel. */
546 while (getl_read_line ())
548 extract_prefix (ds_value (&getl_buf), prefix);
549 if (!strcmp (sentinel, prefix))
552 /* Output the line. */
553 output_line (ds_value (&getl_buf));
556 /* Calling lex_entire_line() forces the sentinel line to be
558 getl_prompt = GETL_PRPT_STANDARD;
564 /* Parses the N command. */
566 cmd_n_of_cases (void)
573 lex_match_id ("CASES");
574 if (!lex_force_int ())
578 if (!lex_match_id ("ESTIMATED"))
581 return lex_end_of_command ();
584 /* Parses, performs the EXECUTE procedure. */
588 lex_match_id ("EXECUTE");
589 procedure (NULL, NULL, NULL);
590 return lex_end_of_command ();
593 /* Parses, performs the ERASE command. */
599 msg (SE, _("This command not allowed when the SAFER option is set."));
603 lex_match_id ("ERASE");
604 if (!lex_force_match_id ("FILE"))
607 if (!lex_force_string ())
610 if (remove (ds_value (&tokstr)) == -1)
612 msg (SW, _("Error removing `%s': %s."),
613 ds_value (&tokstr), strerror (errno));
617 return lex_end_of_command ();
621 /* Spawn a shell process. */
632 const char *shell_fn;
638 for (i = 3; i < 20; i++)
642 shell_fn = getenv ("SHELL");
643 if (shell_fn == NULL)
644 shell_fn = "/bin/sh";
647 const char *cp = strrchr (shell_fn, '/');
648 cp = cp ? &cp[1] : shell_fn;
649 shell_process = local_alloc (strlen (cp) + 8);
650 strcpy (shell_process, "-");
651 strcat (shell_process, cp);
652 if (strcmp (cp, "sh"))
653 shell_process[0] = '+';
656 execl (shell_fn, shell_process, NULL);
662 msg (SE, _("Couldn't fork: %s."), strerror (errno));
667 while (wait (NULL) != pid)
674 /* Parses the HOST command argument and executes the specified
675 command. Returns a suitable command return code. */
682 /* Handle either a string argument or a full-line argument. */
684 int c = lex_look_ahead ();
686 if (c == '\'' || c == '"')
689 if (!lex_force_string ())
691 cmd = ds_value (&tokstr);
696 cmd = lex_rest_of_line (NULL);
701 /* Execute the command. */
702 if (system (cmd) == -1)
703 msg (SE, _("Error executing command: %s."), strerror (errno));
705 /* Finish parsing. */
712 lex_error (_("expecting end of command"));
713 return CMD_TRAILING_GARBAGE;
722 /* Parses, performs the HOST command. */
730 msg (SE, _("This command not allowed when the SAFER option is set."));
734 lex_match_id ("HOST");
737 /* Figure out whether to invoke an interactive shell or to execute a
738 single shell command. */
739 if (lex_look_ahead () == '.')
742 code = shell () ? CMD_PART_SUCCESS_MAYBE : CMD_SUCCESS;
745 code = run_command ();
747 /* Make sure that the system has a command interpreter, then run a
749 if (system (NULL) != 0)
750 success = run_command ();
753 msg (SE, _("No operating system support for this command."));
754 success = CMD_FAILURE;
758 return code ? CMD_FAILURE : CMD_SUCCESS;
761 /* Parses, performs the NEW FILE command. */
765 lex_match_id ("NEW");
766 lex_match_id ("FILE");
768 discard_variables ();
770 return lex_end_of_command ();
773 /* Parses, performs the CLEAR TRANSFORMATIONS command. */
775 cmd_clear_transformations (void)
777 lex_match_id ("CLEAR");
778 lex_match_id ("TRANSFORMATIONS");
780 if (getl_reading_script)
782 msg (SW, _("This command is not valid in a syntax file."));
786 cancel_transformations ();