d4c130aa64bce968c62d38f373d4304b243b8178
[pspp-builds.git] / src / command.c
1 /* PSPP - computes sample statistics.
2    Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
3    Written by Ben Pfaff <blp@gnu.org>.
4
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.
9
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.
14
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
18    02111-1307, USA. */
19
20 /* AIX requires this to be the first thing in the file.  */
21 #include <config.h>
22 #if __GNUC__
23 #define alloca __builtin_alloca
24 #else
25 #if HAVE_ALLOCA_H
26 #include <alloca.h>
27 #else
28 #ifdef _AIX
29 #pragma alloca
30 #else
31 #ifndef alloca                  /* predefined by HP cc +Olibcalls */
32 char *alloca ();
33 #endif
34 #endif
35 #endif
36 #endif
37
38 #include <assert.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <ctype.h>
42 #include <errno.h>
43 #include "alloc.h"
44 #include "command.h"
45 #include "error.h"
46 #include "getline.h"
47 #include "lexer.h"
48 #include "main.h"
49 #include "settings.h"
50 #include "som.h"
51 #include "str.h"
52 #include "tab.h"
53 #include "var.h"
54 #include "vfm.h"
55
56 #if HAVE_UNISTD_H
57 #include <unistd.h>
58 #endif
59
60 #if HAVE_SYS_WAIT_H
61 #include <sys/wait.h>
62 #endif
63
64 #include "debug-print.h"
65 \f
66 /* Global variables. */
67
68 /* A STATE_* constant giving the current program state. */
69 int pgm_state;
70
71 /* The name of the procedure currently executing, if any. */
72 const char *cur_proc;
73 \f
74 /* Static variables. */
75
76 /* A single command. */
77 struct command
78   {
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. */
83
84     /* Calculated at startup time. */
85     char *word[3];              /* cmd[], divided into individual words. */
86     struct command *next;       /* Next command with same word[0]. */
87   };
88
89 /* Prototype all the command functions. */
90 #define DEFCMD(NAME, T1, T2, T3, T4, FUNC)      \
91         int FUNC (void);
92 #define UNIMPL(NAME, T1, T2, T3, T4)
93 #include "command.def"
94 #undef DEFCMD
95 #undef UNIMPL
96
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[] = 
103   {
104 #include "command.def"
105     {"", {ERRO, ERRO, ERRO, ERRO}, NULL, {NULL, NULL, NULL}, NULL},
106   };
107 #undef DEFCMD
108 #undef UNIMPL
109 \f
110 /* Command parser. */
111
112 static struct command *figure_out_command (void);
113
114 /* Breaks the `cmd' member of C into individual words and sets C's
115    word[] member appropriately. */
116 static void
117 split_words (struct command *c)
118 {
119   char *cmd, *save;
120   int i;
121
122   cmd = xstrdup (c->cmd);
123   for (i = 0; i < 3; i++)
124     cmd = c->word[i] = strtok_r (i == 0 ? cmd : NULL, " -", &save);
125 }
126
127 /* Initializes the command parser. */
128 void
129 cmd_init (void)
130 {
131   struct command *c;
132
133   /* Break up command names into words. */
134   for (c = cmd_table; c->cmd[0]; c++)
135     split_words (c);
136
137   /* Make chains of commands having the same first word. */
138   for (c = cmd_table; c->cmd[0]; c++)
139     {
140       struct command *first;
141       for (first = c; c[1].word[0] && !strcmp (c[0].word[0], c[1].word[0]); c++)
142         c->next = c + 1;
143
144       c->next = NULL;
145     }
146 }
147
148 /* Determines whether command C is appropriate to call in this
149    part of a FILE TYPE structure. */
150 static int
151 FILE_TYPE_okay (struct command *c)
152 {
153   int okay = 0;
154   
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);
160 #if 0
161   /* FIXME */
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."),
164          c->cmd);
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."));
168 #endif
169   else
170     okay = 1;
171
172 #if 0
173   if (c->func == cmd_record_type)
174     fty.had_rec_type = 1;
175 #endif
176
177   return okay;
178 }
179
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. */
184 int
185 cmd_parse (void)
186 {
187   struct command *cp;   /* Iterator used to find the proper command. */
188
189 #if C_ALLOCA
190   /* The generic alloca package performs garbage collection when it is
191      called with an argument of zero. */
192   alloca (0);
193 #endif /* C_ALLOCA */
194
195   /* Null commands can result from extra empty lines. */
196   if (token == '.')
197     return CMD_SUCCESS;
198
199   /* Parse comments. */
200   if ((token == T_ID && !strcmp (tokid, "COMMENT"))
201       || token == T_EXP || token == '*' || token == '[')
202     {
203       lex_skip_comment ();
204       return CMD_SUCCESS;
205     }
206
207   /* Otherwise the line must begin with a command name, which is
208      always an ID token. */
209   if (token != T_ID)
210     {
211       msg (SE, _("This line does not begin with a valid command name."));
212       return CMD_FAILURE;
213     }
214
215   /* Parse the command name. */
216   cp = figure_out_command ();
217   if (cp == NULL)
218     return CMD_FAILURE;
219   if (cp->func == NULL)
220     {
221       msg (SE, _("%s is not yet implemented."), cp->cmd);
222       while (token && token != '.')
223         lex_get ();
224       return CMD_SUCCESS;
225     }
226
227   /* If we're in a FILE TYPE structure, only certain commands can be
228      allowed. */
229   if (pgm_state == STATE_INPUT && vfm_source == &file_type_source
230       && !FILE_TYPE_okay (cp))
231     return CMD_FAILURE;
232
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)
236     {
237       static const char *state_name[4] =
238       {
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 "
242            "INPUT PROGRAM."),
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."),
246       };
247
248       msg (SE, gettext (state_name[pgm_state]), cp->cmd);
249       return CMD_FAILURE;
250     }
251
252 #if DEBUGGING
253   if (cp->func != cmd_remark)
254     printf (_("%s command beginning\n"), cp->cmd);
255 #endif
256
257   /* The structured output manager numbers all its tables.  Increment
258      the major table number for each separate procedure. */
259   som_new_series ();
260   
261   {
262     int result;
263     
264     /* Call the command dispatcher.  Save and restore the name of
265        the current command around this call. */
266     {
267       const char *prev_proc;
268       
269       prev_proc = cur_proc;
270       cur_proc = cp->cmd;
271       result = cp->func ();
272       cur_proc = prev_proc;
273     }
274     
275     /* Perform the state transition if the command completed
276        successfully (at least in part). */
277     if (result != 0)
278       {
279         pgm_state = cp->transition[pgm_state];
280
281         if (pgm_state == STATE_ERROR)
282           {
283             discard_variables ();
284             pgm_state = STATE_INIT;
285           }
286       }
287
288 #if DEBUGGING
289     if (cp->func != cmd_remark)
290       printf (_("%s command completed\n\n"), cp->cmd);
291 #endif
292
293     /* Pass the command's success value up to the caller. */
294     return result;
295   }
296 }
297
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)
303 {
304   static const char *unk =
305     N_("The identifier(s) specified do not form a valid command name:");
306
307   static const char *inc = 
308     N_("The identifier(s) specified do not form a complete command name:");
309
310   struct command *cp;
311
312   /* Parse the INCLUDE short form.
313      Note that `@' is a valid character in identifiers. */
314   if (tokid[0] == '@')
315     return &cmd_table[0];
316
317   /* Find a command whose first word matches this identifier.
318      If it is the only command that begins with this word, return
319      it. */
320   for (cp = cmd_table; cp->cmd[0]; cp++)
321     if (lex_id_match (cp->word[0], tokid))
322       break;
323
324   if (cp->cmd[0] == '\0')
325     {
326       msg (SE, "%s %s.", gettext (unk), ds_value (&tokstr));
327       return NULL;
328     }
329
330   if (cp->next == NULL)
331     return cp;
332   
333   /* We know that there is more than one command starting with this
334      word.  Read the next word in the command name. */
335   {
336     struct command *ocp = cp;
337     
338     /* Verify that the next token is an identifier, because we
339        must disambiguate this command name. */
340     lex_get ();
341     if (token != T_ID)
342       {
343         /* If there's a command whose name is the first word only,
344            return it.  This happens with, i.e., PRINT vs. PRINT
345            SPACE. */
346         if (ocp->word[1] == NULL)
347           return ocp;
348         
349         msg (SE, "%s %s.", gettext (inc), ds_value (&tokstr));
350         return NULL;
351       }
352
353     for (; cp; cp = cp->next)
354       if (cp->word[1] && lex_id_match (cp->word[1], tokid))
355         break;
356
357     if (cp == NULL)
358       {
359         /* No match.  If there's a command whose name is the first
360            word only, return it.  This happens with, i.e., PRINT
361            vs. PRINT SPACE. */
362         if (ocp->word[1] == NULL)
363           return ocp;
364         
365         msg (SE, "%s %s %s.", gettext (unk), ocp->word[0], tokid);
366         return NULL;
367       }
368   
369     /* Check whether the next token is an identifier.
370        If not, bail. */
371     if (!isalpha ((unsigned char) (lex_look_ahead ())))
372       {
373         /* Check whether there is an unambiguous interpretation.
374            If not, give an error. */
375         if (cp->word[2]
376             && cp->next
377             && !strcmp (cp->word[1], cp->next->word[1]))
378           {
379             msg (SE, "%s %s %s.", gettext (inc), ocp->word[0], ocp->word[1]);
380             return NULL;
381           }
382         else
383           return cp;
384       }
385   }
386   
387   /* If this command can have a third word, disambiguate based on it. */
388   if (cp->word[2]
389       || (cp->next
390           && cp->next->word[2]
391           && !strcmp (cp->word[1], cp->next->word[1])))
392     {
393       struct command *ocp = cp;
394       
395       lex_get ();
396       assert (token == T_ID);
397
398       /* Try to find a command with this third word.
399          If found, bail. */
400       for (; cp; cp = cp->next)
401         if (cp->word[2]
402             && !strcmp (cp->word[1], ocp->word[1])
403             && lex_id_match (cp->word[2], tokid))
404           break;
405
406       if (cp != NULL)
407         return cp;
408
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
411          third word. */
412       cp = ocp;
413       if (cp->word[2])
414         {
415           msg (SE, "%s %s %s %s.",
416                gettext (unk), ocp->word[0], ocp->word[1], ds_value (&tokstr));
417           return 0;
418         }
419     }
420
421   return cp;
422 }
423 \f
424 /* Simple commands. */
425
426 /* Parse and execute EXIT command. */
427 int
428 cmd_exit (void)
429 {
430   if (getl_reading_script)
431     {
432       msg (SE, _("This command is not accepted in a syntax file.  "
433            "Instead, use FINISH to terminate a syntax file."));
434       lex_get ();
435     }
436   else
437     finished = 1;
438
439   return CMD_SUCCESS;
440 }
441
442 /* Parse and execute FINISH command. */
443 int
444 cmd_finish (void)
445 {
446   /* Do not check for `.'
447      Do not fetch any extra tokens. */
448   if (getl_interactive)
449     {
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 "
453            "to quit."));
454       getl_close_all ();
455     }
456   else
457     finished = 1;
458
459   return CMD_SUCCESS;
460 }
461
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.  */
465 static void
466 extract_prefix (char *string, char *prefix)
467 {
468   /* Length of STRING. */
469   int len;
470
471   /* Points to the null terminator in STRING (`end pointer'). */
472   char *ep;
473
474   /* Strip spaces from end of STRING. */
475   len = strlen (string);
476   while (len && isspace ((unsigned char) string[len - 1]))
477     string[--len] = 0;
478
479   /* Find null terminator. */
480   ep = memchr (string, '\0', 8);
481   if (!ep)
482     ep = &string[8];
483
484   /* Copy prefix, converting to lowercase. */
485   while (string < ep)
486     *prefix++ = tolower ((unsigned char) (*string++));
487   *prefix = 0;
488 }
489
490 /* Prints STRING on the console and to the listing file, replacing \n
491    by newline. */
492 static void
493 output_line (char *string)
494 {
495   /* Location of \n in line read in. */
496   char *cp;
497
498   cp = strstr (string, "\\n");
499   while (cp)
500     {
501       *cp = 0;
502       tab_output_text (TAB_LEFT | TAT_NOWRAP, string);
503       string = &cp[2];
504       cp = strstr (string, "\\n");
505     }
506   tab_output_text (TAB_LEFT | TAT_NOWRAP, string);
507 }
508
509 /* Parse and execute REMARK command. */
510 int
511 cmd_remark ()
512 {
513   /* Points to the line read in. */
514   char *s;
515
516   /* Index into s. */
517   char *cp;
518
519   /* 8-character sentinel used to terminate remark. */
520   char sentinel[9];
521
522   /* Beginning of line used to compare with SENTINEL. */
523   char prefix[9];
524
525   som_blank_line ();
526   
527   s = lex_rest_of_line (NULL);
528   if (*s == '-')
529     {
530       output_line (&s[1]);
531       return CMD_SUCCESS;
532     }
533
534   /* Read in SENTINEL from end of current line. */
535   cp = s;
536   while (isspace ((unsigned char) *cp))
537     cp++;
538   extract_prefix (cp, sentinel);
539   if (sentinel[0] == 0)
540     {
541       msg (SE, _("The sentinel may not be the empty string."));
542       return CMD_FAILURE;
543     }
544
545   /* Read in other lines until we encounter the sentinel. */
546   while (getl_read_line ())
547     {
548       extract_prefix (ds_value (&getl_buf), prefix);
549       if (!strcmp (sentinel, prefix))
550         break;
551
552       /* Output the line. */
553       output_line (ds_value (&getl_buf));
554     }
555
556   /* Calling lex_entire_line() forces the sentinel line to be
557      discarded. */
558   getl_prompt = GETL_PRPT_STANDARD;
559   lex_entire_line ();
560
561   return CMD_SUCCESS;
562 }
563
564 /* Parses the N command. */
565 int
566 cmd_n_of_cases (void)
567 {
568   /* Value for N. */
569   int x;
570
571   lex_match_id ("N");
572   lex_match_id ("OF");
573   lex_match_id ("CASES");
574   if (!lex_force_int ())
575     return CMD_FAILURE;
576   x = lex_integer ();
577   lex_get ();
578   if (!lex_match_id ("ESTIMATED"))
579     default_dict.N = x;
580
581   return lex_end_of_command ();
582 }
583
584 /* Parses, performs the EXECUTE procedure. */
585 int
586 cmd_execute (void)
587 {
588   lex_match_id ("EXECUTE");
589   procedure (NULL, NULL, NULL);
590   return lex_end_of_command ();
591 }
592
593 /* Parses, performs the ERASE command. */
594 int
595 cmd_erase (void)
596 {
597   if (set_safer)
598     {
599       msg (SE, _("This command not allowed when the SAFER option is set."));
600       return CMD_FAILURE;
601     }
602   
603   lex_match_id ("ERASE");
604   if (!lex_force_match_id ("FILE"))
605     return CMD_FAILURE;
606   lex_match ('=');
607   if (!lex_force_string ())
608     return CMD_FAILURE;
609
610   if (remove (ds_value (&tokstr)) == -1)
611     {
612       msg (SW, _("Error removing `%s': %s."),
613            ds_value (&tokstr), strerror (errno));
614       return CMD_FAILURE;
615     }
616
617   return lex_end_of_command ();
618 }
619
620 #if unix
621 /* Spawn a shell process. */
622 static int
623 shell (void)
624 {
625   int pid;
626   
627   pid = fork ();
628   switch (pid)
629     {
630     case 0:
631       {
632         const char *shell_fn;
633         char *shell_process;
634         
635         {
636           int i;
637           
638           for (i = 3; i < 20; i++)
639             close (i);
640         }
641
642         shell_fn = getenv ("SHELL");
643         if (shell_fn == NULL)
644           shell_fn = "/bin/sh";
645         
646         {
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] = '+';
654         }
655         
656         execl (shell_fn, shell_process, NULL);
657
658         err_hcf (1);
659       }
660
661     case -1:
662       msg (SE, _("Couldn't fork: %s."), strerror (errno));
663       return 0;
664
665     default:
666       assert (pid > 0);
667       while (wait (NULL) != pid)
668         ;
669       return 1;
670     }
671 }
672 #endif /* unix */
673
674 /* Parses the HOST command argument and executes the specified
675    command.  Returns a suitable command return code. */
676 static int
677 run_command (void)
678 {
679   char *cmd;
680   int string;
681
682   /* Handle either a string argument or a full-line argument. */
683   {
684     int c = lex_look_ahead ();
685
686     if (c == '\'' || c == '"')
687       {
688         lex_get ();
689         if (!lex_force_string ())
690           return CMD_FAILURE;
691         cmd = ds_value (&tokstr);
692         string = 1;
693       }
694     else
695       {
696         cmd = lex_rest_of_line (NULL);
697         string = 0;
698       }
699   }
700
701   /* Execute the command. */
702   if (system (cmd) == -1)
703     msg (SE, _("Error executing command: %s."), strerror (errno));
704
705   /* Finish parsing. */
706   if (string)
707     {
708       lex_get ();
709
710       if (token != '.')
711         {
712           lex_error (_("expecting end of command"));
713           return CMD_TRAILING_GARBAGE;
714         }
715     }
716   else
717     token = '.';
718
719   return CMD_SUCCESS;
720 }
721
722 /* Parses, performs the HOST command. */
723 int
724 cmd_host (void)
725 {
726   int code;
727
728   if (set_safer)
729     {
730       msg (SE, _("This command not allowed when the SAFER option is set."));
731       return CMD_FAILURE;
732     }
733   
734   lex_match_id ("HOST");
735
736 #if unix
737   /* Figure out whether to invoke an interactive shell or to execute a
738      single shell command. */
739   if (lex_look_ahead () == '.')
740     {
741       lex_get ();
742       code = shell () ? CMD_PART_SUCCESS_MAYBE : CMD_SUCCESS;
743     }
744   else
745     code = run_command ();
746 #else /* !unix */
747   /* Make sure that the system has a command interpreter, then run a
748      command. */
749   if (system (NULL) != 0)
750     success = run_command ();
751   else
752     {
753       msg (SE, _("No operating system support for this command."));
754       success = CMD_FAILURE;
755     }
756 #endif /* !unix */
757
758   return code ? CMD_FAILURE : CMD_SUCCESS;
759 }
760
761 /* Parses, performs the NEW FILE command. */
762 int
763 cmd_new_file (void)
764 {
765   lex_match_id ("NEW");
766   lex_match_id ("FILE");
767   
768   discard_variables ();
769
770   return lex_end_of_command ();
771 }
772
773 /* Parses, performs the CLEAR TRANSFORMATIONS command. */
774 int
775 cmd_clear_transformations (void)
776 {
777   lex_match_id ("CLEAR");
778   lex_match_id ("TRANSFORMATIONS");
779
780   if (getl_reading_script)
781     {
782       msg (SW, _("This command is not valid in a syntax file."));
783       return CMD_FAILURE;
784     }
785
786   cancel_transformations ();
787
788   return CMD_SUCCESS;
789 }