Beginning of VFM cleanup.
[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 #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
205       && case_source_is_class (vfm_source, &file_type_source_class)
206       && !FILE_TYPE_okay (cp))
207     return CMD_FAILURE;
208
209   /* Certain state transitions are not allowed.  Check for these. */
210   assert (pgm_state >= 0 && pgm_state < STATE_ERROR);
211   if (cp->transition[pgm_state] == STATE_ERROR)
212     {
213       static const char *state_name[4] =
214       {
215         N_("%s is not allowed (1) before a command to specify the "
216            "input program, such as DATA LIST, (2) between FILE TYPE "
217            "and END FILE TYPE, (3) between INPUT PROGRAM and END "
218            "INPUT PROGRAM."),
219         N_("%s is not allowed within an input program."),
220         N_("%s is only allowed within an input program."),
221         N_("%s is only allowed within an input program."),
222       };
223
224       msg (SE, gettext (state_name[pgm_state]), cp->cmd);
225       return CMD_FAILURE;
226     }
227
228 #if DEBUGGING
229   if (cp->func != cmd_remark)
230     printf (_("%s command beginning\n"), cp->cmd);
231 #endif
232
233   /* The structured output manager numbers all its tables.  Increment
234      the major table number for each separate procedure. */
235   som_new_series ();
236   
237   {
238     int result;
239     
240     /* Call the command dispatcher.  Save and restore the name of
241        the current command around this call. */
242     {
243       const char *prev_proc;
244       
245       prev_proc = cur_proc;
246       cur_proc = cp->cmd;
247       result = cp->func ();
248       cur_proc = prev_proc;
249     }
250     
251     /* Perform the state transition if the command completed
252        successfully (at least in part). */
253     if (result != CMD_FAILURE)
254       {
255         pgm_state = cp->transition[pgm_state];
256
257         if (pgm_state == STATE_ERROR)
258           {
259             discard_variables ();
260             pgm_state = STATE_INIT;
261           }
262       }
263
264 #if DEBUGGING
265     if (cp->func != cmd_remark)
266       printf (_("%s command completed\n\n"), cp->cmd);
267 #endif
268
269     /* Pass the command's success value up to the caller. */
270     return result;
271   }
272 }
273
274 /* Parse the command name and return a pointer to the corresponding
275    struct command if successful.
276    If not successful, return a null pointer. */
277 static struct command *
278 figure_out_command (void)
279 {
280   static const char *unk =
281     N_("The identifier(s) specified do not form a valid command name:");
282
283   static const char *inc = 
284     N_("The identifier(s) specified do not form a complete command name:");
285
286   struct command *cp;
287
288   /* Parse the INCLUDE short form.
289      Note that `@' is a valid character in identifiers. */
290   if (tokid[0] == '@')
291     return &cmd_table[0];
292
293   /* Find a command whose first word matches this identifier.
294      If it is the only command that begins with this word, return
295      it. */
296   for (cp = cmd_table; cp->cmd[0]; cp++)
297     if (lex_id_match (cp->word[0], tokid))
298       break;
299
300   if (cp->cmd[0] == '\0')
301     {
302       msg (SE, "%s %s.", gettext (unk), ds_value (&tokstr));
303       return NULL;
304     }
305
306   if (cp->next == NULL)
307     return cp;
308   
309   /* We know that there is more than one command starting with this
310      word.  Read the next word in the command name. */
311   {
312     struct command *ocp = cp;
313     
314     /* Verify that the next token is an identifier, because we
315        must disambiguate this command name. */
316     lex_get ();
317     if (token != T_ID)
318       {
319         /* If there's a command whose name is the first word only,
320            return it.  This happens with, i.e., PRINT vs. PRINT
321            SPACE. */
322         if (ocp->word[1] == NULL)
323           return ocp;
324         
325         msg (SE, "%s %s.", gettext (inc), ds_value (&tokstr));
326         return NULL;
327       }
328
329     for (; cp; cp = cp->next)
330       if (cp->word[1] && lex_id_match (cp->word[1], tokid))
331         break;
332
333     if (cp == NULL)
334       {
335         /* No match.  If there's a command whose name is the first
336            word only, return it.  This happens with, i.e., PRINT
337            vs. PRINT SPACE. */
338         if (ocp->word[1] == NULL)
339           return ocp;
340         
341         msg (SE, "%s %s %s.", gettext (unk), ocp->word[0], tokid);
342         return NULL;
343       }
344   
345     /* Check whether the next token is an identifier.
346        If not, bail. */
347     if (!isalpha ((unsigned char) (lex_look_ahead ())))
348       {
349         /* Check whether there is an unambiguous interpretation.
350            If not, give an error. */
351         if (cp->word[2]
352             && cp->next
353             && !strcmp (cp->word[1], cp->next->word[1]))
354           {
355             msg (SE, "%s %s %s.", gettext (inc), ocp->word[0], ocp->word[1]);
356             return NULL;
357           }
358         else
359           return cp;
360       }
361   }
362   
363   /* If this command can have a third word, disambiguate based on it. */
364   if (cp->word[2]
365       || (cp->next
366           && cp->next->word[2]
367           && !strcmp (cp->word[1], cp->next->word[1])))
368     {
369       struct command *ocp = cp;
370       
371       lex_get ();
372       assert (token == T_ID);
373
374       /* Try to find a command with this third word.
375          If found, bail. */
376       for (; cp; cp = cp->next)
377         if (cp->word[2]
378             && !strcmp (cp->word[1], ocp->word[1])
379             && lex_id_match (cp->word[2], tokid))
380           break;
381
382       if (cp != NULL)
383         return cp;
384
385       /* If no command with this third word found, make sure that
386          there's a command with those first two words but without a
387          third word. */
388       cp = ocp;
389       if (cp->word[2])
390         {
391           msg (SE, "%s %s %s %s.",
392                gettext (unk), ocp->word[0], ocp->word[1], ds_value (&tokstr));
393           return 0;
394         }
395     }
396
397   return cp;
398 }
399 \f
400 /* Simple commands. */
401
402 /* Parse and execute EXIT command. */
403 int
404 cmd_exit (void)
405 {
406   if (getl_reading_script)
407     {
408       msg (SE, _("This command is not accepted in a syntax file.  "
409            "Instead, use FINISH to terminate a syntax file."));
410       lex_get ();
411     }
412   else
413     finished = 1;
414
415   return CMD_SUCCESS;
416 }
417
418 /* Parse and execute FINISH command. */
419 int
420 cmd_finish (void)
421 {
422   /* Do not check for `.'
423      Do not fetch any extra tokens. */
424   if (getl_interactive)
425     {
426       msg (SM, _("This command is not executed "
427            "in interactive mode.  Instead, PSPP drops "
428            "down to the command prompt.  Use EXIT if you really want "
429            "to quit."));
430       getl_close_all ();
431     }
432   else
433     finished = 1;
434
435   return CMD_SUCCESS;
436 }
437
438 /* Extracts a null-terminated 8-or-fewer-character PREFIX from STRING.
439    PREFIX is converted to lowercase.  Removes trailing spaces from
440    STRING as a side effect.  */
441 static void
442 extract_prefix (char *string, char *prefix)
443 {
444   /* Length of STRING. */
445   int len;
446
447   /* Points to the null terminator in STRING (`end pointer'). */
448   char *ep;
449
450   /* Strip spaces from end of STRING. */
451   len = strlen (string);
452   while (len && isspace ((unsigned char) string[len - 1]))
453     string[--len] = 0;
454
455   /* Find null terminator. */
456   ep = memchr (string, '\0', 8);
457   if (!ep)
458     ep = &string[8];
459
460   /* Copy prefix, converting to lowercase. */
461   while (string < ep)
462     *prefix++ = tolower ((unsigned char) (*string++));
463   *prefix = 0;
464 }
465
466 /* Prints STRING on the console and to the listing file, replacing \n
467    by newline. */
468 static void
469 output_line (char *string)
470 {
471   /* Location of \n in line read in. */
472   char *cp;
473
474   cp = strstr (string, "\\n");
475   while (cp)
476     {
477       *cp = 0;
478       tab_output_text (TAB_LEFT | TAT_NOWRAP, string);
479       string = &cp[2];
480       cp = strstr (string, "\\n");
481     }
482   tab_output_text (TAB_LEFT | TAT_NOWRAP, string);
483 }
484
485 /* Parse and execute REMARK command. */
486 int
487 cmd_remark ()
488 {
489   /* Points to the line read in. */
490   char *s;
491
492   /* Index into s. */
493   char *cp;
494
495   /* 8-character sentinel used to terminate remark. */
496   char sentinel[9];
497
498   /* Beginning of line used to compare with SENTINEL. */
499   char prefix[9];
500
501   som_blank_line ();
502   
503   s = lex_rest_of_line (NULL);
504   if (*s == '-')
505     {
506       output_line (&s[1]);
507       return CMD_SUCCESS;
508     }
509
510   /* Read in SENTINEL from end of current line. */
511   cp = s;
512   while (isspace ((unsigned char) *cp))
513     cp++;
514   extract_prefix (cp, sentinel);
515   if (sentinel[0] == 0)
516     {
517       msg (SE, _("The sentinel may not be the empty string."));
518       return CMD_FAILURE;
519     }
520
521   /* Read in other lines until we encounter the sentinel. */
522   while (getl_read_line ())
523     {
524       extract_prefix (ds_value (&getl_buf), prefix);
525       if (!strcmp (sentinel, prefix))
526         break;
527
528       /* Output the line. */
529       output_line (ds_value (&getl_buf));
530     }
531
532   /* Calling lex_entire_line() forces the sentinel line to be
533      discarded. */
534   getl_prompt = GETL_PRPT_STANDARD;
535   lex_entire_line ();
536
537   return CMD_SUCCESS;
538 }
539
540 /* Parses the N command. */
541 int
542 cmd_n_of_cases (void)
543 {
544   /* Value for N. */
545   int x;
546
547   lex_match_id ("N");
548   lex_match_id ("OF");
549   lex_match_id ("CASES");
550   if (!lex_force_int ())
551     return CMD_FAILURE;
552   x = lex_integer ();
553   lex_get ();
554   if (!lex_match_id ("ESTIMATED"))
555     dict_set_case_limit (default_dict, x);
556
557   return lex_end_of_command ();
558 }
559
560 /* Parses, performs the EXECUTE procedure. */
561 int
562 cmd_execute (void)
563 {
564   lex_match_id ("EXECUTE");
565   procedure (NULL, NULL, NULL, NULL);
566   return lex_end_of_command ();
567 }
568
569
570 #define assert_not_safer() \
571   do { \
572    if (set_safer) \
573     { \
574       msg (SE, _("This command not allowed when the SAFER option is set.")); \
575       return CMD_FAILURE; \
576     } \
577 } while(0) 
578
579
580
581 /* Parses, performs the ERASE command. */
582 int
583 cmd_erase (void)
584 {
585
586   assert_not_safer();
587   
588   lex_match_id ("ERASE");
589   if (!lex_force_match_id ("FILE"))
590     return CMD_FAILURE;
591   lex_match ('=');
592   if (!lex_force_string ())
593     return CMD_FAILURE;
594
595   if (remove (ds_value (&tokstr)) == -1)
596     {
597       msg (SW, _("Error removing `%s': %s."),
598            ds_value (&tokstr), strerror (errno));
599       return CMD_FAILURE;
600     }
601
602   return CMD_SUCCESS;
603 }
604
605 #ifdef unix
606 /* Spawn a shell process. */
607 static int
608 shell (void)
609 {
610   int pid;
611   
612   pid = fork ();
613   switch (pid)
614     {
615     case 0:
616       {
617         const char *shell_fn;
618         char *shell_process;
619         
620         {
621           int i;
622           
623           for (i = 3; i < 20; i++)
624             close (i);
625         }
626
627         shell_fn = getenv ("SHELL");
628         if (shell_fn == NULL)
629           shell_fn = "/bin/sh";
630         
631         {
632           const char *cp = strrchr (shell_fn, '/');
633           cp = cp ? &cp[1] : shell_fn;
634           shell_process = local_alloc (strlen (cp) + 8);
635           strcpy (shell_process, "-");
636           strcat (shell_process, cp);
637           if (strcmp (cp, "sh"))
638             shell_process[0] = '+';
639         }
640         
641         execl (shell_fn, shell_process, NULL);
642
643         err_hcf (1);
644       }
645
646     case -1:
647       msg (SE, _("Couldn't fork: %s."), strerror (errno));
648       return 0;
649
650     default:
651       assert (pid > 0);
652       while (wait (NULL) != pid)
653         ;
654       return 1;
655     }
656 }
657 #endif /* unix */
658
659 /* Parses the HOST command argument and executes the specified
660    command.  Returns a suitable command return code. */
661 static int
662 run_command (void)
663 {
664   char *cmd;
665   int string;
666
667   /* Handle either a string argument or a full-line argument. */
668   {
669     int c = lex_look_ahead ();
670
671     if (c == '\'' || c == '"')
672       {
673         lex_get ();
674         if (!lex_force_string ())
675           return CMD_FAILURE;
676         cmd = ds_value (&tokstr);
677         string = 1;
678       }
679     else
680       {
681         cmd = lex_rest_of_line (NULL);
682         string = 0;
683       }
684   }
685
686   /* Execute the command. */
687   if (system (cmd) == -1)
688     msg (SE, _("Error executing command: %s."), strerror (errno));
689
690   /* Finish parsing. */
691   if (string)
692     {
693       lex_get ();
694
695       if (token != '.')
696         {
697           lex_error (_("expecting end of command"));
698           return CMD_TRAILING_GARBAGE;
699         }
700     }
701   else
702     token = '.';
703
704   return CMD_SUCCESS;
705 }
706
707 /* Parses, performs the HOST command. */
708 int
709 cmd_host (void)
710 {
711   int code;
712
713   assert_not_safer();
714   
715   lex_match_id ("HOST");
716
717 #ifdef unix
718   /* Figure out whether to invoke an interactive shell or to execute a
719      single shell command. */
720   if (lex_look_ahead () == '.')
721     {
722       lex_get ();
723       code = shell () ? CMD_PART_SUCCESS_MAYBE : CMD_SUCCESS;
724     }
725   else
726     code = run_command ();
727 #else /* !unix */
728   /* Make sure that the system has a command interpreter, then run a
729      command. */
730   if (system (NULL) != 0)
731     success = run_command ();
732   else
733     {
734       msg (SE, _("No operating system support for this command."));
735       success = CMD_FAILURE;
736     }
737 #endif /* !unix */
738
739   return code ? CMD_FAILURE : CMD_SUCCESS;
740 }
741
742 /* Parses, performs the NEW FILE command. */
743 int
744 cmd_new_file (void)
745 {
746   lex_match_id ("NEW");
747   lex_match_id ("FILE");
748   
749   discard_variables ();
750
751   return lex_end_of_command ();
752 }
753
754 /* Parses, performs the CLEAR TRANSFORMATIONS command. */
755 int
756 cmd_clear_transformations (void)
757 {
758   lex_match_id ("CLEAR");
759   lex_match_id ("TRANSFORMATIONS");
760
761   if (getl_reading_script)
762     {
763       msg (SW, _("This command is not valid in a syntax file."));
764       return CMD_FAILURE;
765     }
766
767   cancel_transformations ();
768
769   return CMD_SUCCESS;
770 }