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