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