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 /* Define the command array. */
90 #define DEFCMD(NAME, T1, T2, T3, T4, FUNC) \
91 {NAME, {T1, T2, T3, T4}, FUNC, {NULL, NULL, NULL}, NULL},
92 #define UNIMPL(NAME, T1, T2, T3, T4) \
93 {NAME, {T1, T2, T3, T4}, NULL, {NULL, NULL, NULL}, NULL},
94 static struct command cmd_table[] =
96 #include "command.def"
97 {"", {ERRO, ERRO, ERRO, ERRO}, NULL, {NULL, NULL, NULL}, NULL},
102 /* Command parser. */
104 static struct command *figure_out_command (void);
106 /* Breaks the `cmd' member of C into individual words and sets C's
107 word[] member appropriately. */
109 split_words (struct command *c)
114 cmd = xstrdup (c->cmd);
115 for (i = 0; i < 3; i++)
116 cmd = c->word[i] = strtok_r (i == 0 ? cmd : NULL, " -", &save);
119 /* Initializes the command parser. */
125 /* Break up command names into words. */
126 for (c = cmd_table; c->cmd[0]; c++)
129 /* Make chains of commands having the same first word. */
130 for (c = cmd_table; c->cmd[0]; c++)
132 struct command *first;
133 for (first = c; c[1].word[0] && !strcmp (c[0].word[0], c[1].word[0]); c++)
140 /* Determines whether command C is appropriate to call in this
141 part of a FILE TYPE structure. */
143 FILE_TYPE_okay (struct command *c)
147 if (c->func != cmd_record_type
148 && c->func != cmd_data_list
149 && c->func != cmd_repeating_data
150 && c->func != cmd_end_file_type)
151 msg (SE, _("%s not allowed inside FILE TYPE/END FILE TYPE."), c->cmd);
154 else if (c->func == cmd_repeating_data && fty.type == FTY_GROUPED)
155 msg (SE, _("%s not allowed inside FILE TYPE GROUPED/END FILE TYPE."),
157 else if (!fty.had_rec_type && c->func != cmd_record_type)
158 msg (SE, _("RECORD TYPE must be the first command inside a "
159 "FILE TYPE structure."));
165 if (c->func == cmd_record_type)
166 fty.had_rec_type = 1;
172 /* Parses an entire PSPP command. This includes everything from the
173 command name to the terminating dot. Does most of its work by
174 passing it off to the respective command dispatchers. Only called
175 by parse() in main.c. */
179 struct command *cp; /* Iterator used to find the proper command. */
182 /* The generic alloca package performs garbage collection when it is
183 called with an argument of zero. */
185 #endif /* C_ALLOCA */
187 /* Null commands can result from extra empty lines. */
191 /* Parse comments. */
192 if ((token == T_ID && !strcmp (tokid, "COMMENT"))
193 || token == T_EXP || token == '*' || token == '[')
199 /* Otherwise the line must begin with a command name, which is
200 always an ID token. */
203 msg (SE, _("This line does not begin with a valid command name."));
207 /* Parse the command name. */
208 cp = figure_out_command ();
211 if (cp->func == NULL)
213 msg (SE, _("%s is not yet implemented."), cp->cmd);
214 while (token && token != '.')
219 /* If we're in a FILE TYPE structure, only certain commands can be
221 if (pgm_state == STATE_INPUT && vfm_source == &file_type_source
222 && !FILE_TYPE_okay (cp))
225 /* Certain state transitions are not allowed. Check for these. */
226 assert (pgm_state >= 0 && pgm_state < STATE_ERROR);
227 if (cp->transition[pgm_state] == STATE_ERROR)
229 static const char *state_name[4] =
231 N_("%s is not allowed (1) before a command to specify the "
232 "input program, such as DATA LIST, (2) between FILE TYPE "
233 "and END FILE TYPE, (3) between INPUT PROGRAM and END "
235 N_("%s is not allowed within an input program."),
236 N_("%s is only allowed within an input program."),
237 N_("%s is only allowed within an input program."),
240 msg (SE, gettext (state_name[pgm_state]), cp->cmd);
245 if (cp->func != cmd_remark)
246 printf (_("%s command beginning\n"), cp->cmd);
249 /* The structured output manager numbers all its tables. Increment
250 the major table number for each separate procedure. */
256 /* Call the command dispatcher. Save and restore the name of
257 the current command around this call. */
259 const char *prev_proc;
261 prev_proc = cur_proc;
263 result = cp->func ();
264 cur_proc = prev_proc;
267 /* Perform the state transition if the command completed
268 successfully (at least in part). */
271 pgm_state = cp->transition[pgm_state];
273 if (pgm_state == STATE_ERROR)
275 discard_variables ();
276 pgm_state = STATE_INIT;
281 if (cp->func != cmd_remark)
282 printf (_("%s command completed\n\n"), cp->cmd);
285 /* Pass the command's success value up to the caller. */
290 /* Parse the command name and return a pointer to the corresponding
291 struct command if successful.
292 If not successful, return a null pointer. */
293 static struct command *
294 figure_out_command (void)
296 static const char *unk =
297 N_("The identifier(s) specified do not form a valid command name:");
299 static const char *inc =
300 N_("The identifier(s) specified do not form a complete command name:");
304 /* Parse the INCLUDE short form.
305 Note that `@' is a valid character in identifiers. */
307 return &cmd_table[0];
309 /* Find a command whose first word matches this identifier.
310 If it is the only command that begins with this word, return
312 for (cp = cmd_table; cp->cmd[0]; cp++)
313 if (lex_id_match (cp->word[0], tokid))
316 if (cp->cmd[0] == '\0')
318 msg (SE, "%s %s.", gettext (unk), ds_value (&tokstr));
322 if (cp->next == NULL)
325 /* We know that there is more than one command starting with this
326 word. Read the next word in the command name. */
328 struct command *ocp = cp;
330 /* Verify that the next token is an identifier, because we
331 must disambiguate this command name. */
335 /* If there's a command whose name is the first word only,
336 return it. This happens with, i.e., PRINT vs. PRINT
338 if (ocp->word[1] == NULL)
341 msg (SE, "%s %s.", gettext (inc), ds_value (&tokstr));
345 for (; cp; cp = cp->next)
346 if (cp->word[1] && lex_id_match (cp->word[1], tokid))
351 /* No match. If there's a command whose name is the first
352 word only, return it. This happens with, i.e., PRINT
354 if (ocp->word[1] == NULL)
357 msg (SE, "%s %s %s.", gettext (unk), ocp->word[0], tokid);
361 /* Check whether the next token is an identifier.
363 if (!isalpha ((unsigned char) (lex_look_ahead ())))
365 /* Check whether there is an unambiguous interpretation.
366 If not, give an error. */
369 && !strcmp (cp->word[1], cp->next->word[1]))
371 msg (SE, "%s %s %s.", gettext (inc), ocp->word[0], ocp->word[1]);
379 /* If this command can have a third word, disambiguate based on it. */
383 && !strcmp (cp->word[1], cp->next->word[1])))
385 struct command *ocp = cp;
388 assert (token == T_ID);
390 /* Try to find a command with this third word.
392 for (; cp; cp = cp->next)
394 && !strcmp (cp->word[1], ocp->word[1])
395 && lex_id_match (cp->word[2], tokid))
401 /* If no command with this third word found, make sure that
402 there's a command with those first two words but without a
407 msg (SE, "%s %s %s %s.",
408 gettext (unk), ocp->word[0], ocp->word[1], ds_value (&tokstr));
416 /* Simple commands. */
418 /* Parse and execute EXIT command. */
422 if (getl_reading_script)
424 msg (SE, _("This command is not accepted in a syntax file. "
425 "Instead, use FINISH to terminate a syntax file."));
434 /* Parse and execute FINISH command. */
438 /* Do not check for `.'
439 Do not fetch any extra tokens. */
440 if (getl_interactive)
442 msg (SM, _("This command is not executed "
443 "in interactive mode. Instead, PSPP drops "
444 "down to the command prompt. Use EXIT if you really want "
454 /* Extracts a null-terminated 8-or-fewer-character PREFIX from STRING.
455 PREFIX is converted to lowercase. Removes trailing spaces from
456 STRING as a side effect. */
458 extract_prefix (char *string, char *prefix)
460 /* Length of STRING. */
463 /* Points to the null terminator in STRING (`end pointer'). */
466 /* Strip spaces from end of STRING. */
467 len = strlen (string);
468 while (len && isspace ((unsigned char) string[len - 1]))
471 /* Find null terminator. */
472 ep = memchr (string, '\0', 8);
476 /* Copy prefix, converting to lowercase. */
478 *prefix++ = tolower ((unsigned char) (*string++));
482 /* Prints STRING on the console and to the listing file, replacing \n
485 output_line (char *string)
487 /* Location of \n in line read in. */
490 cp = strstr (string, "\\n");
494 tab_output_text (TAB_LEFT | TAT_NOWRAP, string);
496 cp = strstr (string, "\\n");
498 tab_output_text (TAB_LEFT | TAT_NOWRAP, string);
501 /* Parse and execute REMARK command. */
505 /* Points to the line read in. */
511 /* 8-character sentinel used to terminate remark. */
514 /* Beginning of line used to compare with SENTINEL. */
519 s = lex_rest_of_line (NULL);
526 /* Read in SENTINEL from end of current line. */
528 while (isspace ((unsigned char) *cp))
530 extract_prefix (cp, sentinel);
531 if (sentinel[0] == 0)
533 msg (SE, _("The sentinel may not be the empty string."));
537 /* Read in other lines until we encounter the sentinel. */
538 while (getl_read_line ())
540 extract_prefix (ds_value (&getl_buf), prefix);
541 if (!strcmp (sentinel, prefix))
544 /* Output the line. */
545 output_line (ds_value (&getl_buf));
548 /* Calling lex_entire_line() forces the sentinel line to be
550 getl_prompt = GETL_PRPT_STANDARD;
556 /* Parses the N command. */
558 cmd_n_of_cases (void)
565 lex_match_id ("CASES");
566 if (!lex_force_int ())
570 if (!lex_match_id ("ESTIMATED"))
571 dict_set_case_limit (default_dict, x);
573 return lex_end_of_command ();
576 /* Parses, performs the EXECUTE procedure. */
580 lex_match_id ("EXECUTE");
581 procedure (NULL, NULL, NULL);
582 return lex_end_of_command ();
585 /* Parses, performs the ERASE command. */
591 msg (SE, _("This command not allowed when the SAFER option is set."));
595 lex_match_id ("ERASE");
596 if (!lex_force_match_id ("FILE"))
599 if (!lex_force_string ())
602 if (remove (ds_value (&tokstr)) == -1)
604 msg (SW, _("Error removing `%s': %s."),
605 ds_value (&tokstr), strerror (errno));
609 return lex_end_of_command ();
613 /* Spawn a shell process. */
624 const char *shell_fn;
630 for (i = 3; i < 20; i++)
634 shell_fn = getenv ("SHELL");
635 if (shell_fn == NULL)
636 shell_fn = "/bin/sh";
639 const char *cp = strrchr (shell_fn, '/');
640 cp = cp ? &cp[1] : shell_fn;
641 shell_process = local_alloc (strlen (cp) + 8);
642 strcpy (shell_process, "-");
643 strcat (shell_process, cp);
644 if (strcmp (cp, "sh"))
645 shell_process[0] = '+';
648 execl (shell_fn, shell_process, NULL);
654 msg (SE, _("Couldn't fork: %s."), strerror (errno));
659 while (wait (NULL) != pid)
666 /* Parses the HOST command argument and executes the specified
667 command. Returns a suitable command return code. */
674 /* Handle either a string argument or a full-line argument. */
676 int c = lex_look_ahead ();
678 if (c == '\'' || c == '"')
681 if (!lex_force_string ())
683 cmd = ds_value (&tokstr);
688 cmd = lex_rest_of_line (NULL);
693 /* Execute the command. */
694 if (system (cmd) == -1)
695 msg (SE, _("Error executing command: %s."), strerror (errno));
697 /* Finish parsing. */
704 lex_error (_("expecting end of command"));
705 return CMD_TRAILING_GARBAGE;
714 /* Parses, performs the HOST command. */
722 msg (SE, _("This command not allowed when the SAFER option is set."));
726 lex_match_id ("HOST");
729 /* Figure out whether to invoke an interactive shell or to execute a
730 single shell command. */
731 if (lex_look_ahead () == '.')
734 code = shell () ? CMD_PART_SUCCESS_MAYBE : CMD_SUCCESS;
737 code = run_command ();
739 /* Make sure that the system has a command interpreter, then run a
741 if (system (NULL) != 0)
742 success = run_command ();
745 msg (SE, _("No operating system support for this command."));
746 success = CMD_FAILURE;
750 return code ? CMD_FAILURE : CMD_SUCCESS;
753 /* Parses, performs the NEW FILE command. */
757 lex_match_id ("NEW");
758 lex_match_id ("FILE");
760 discard_variables ();
762 return lex_end_of_command ();
765 /* Parses, performs the CLEAR TRANSFORMATIONS command. */
767 cmd_clear_transformations (void)
769 lex_match_id ("CLEAR");
770 lex_match_id ("TRANSFORMATIONS");
772 if (getl_reading_script)
774 msg (SW, _("This command is not valid in a syntax file."));
778 cancel_transformations ();