Implemented the SHOW command and massaged the SET command to fit
[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);
566   return lex_end_of_command ();
567 }
568
569 /* Parses, performs the ERASE command. */
570 int
571 cmd_erase (void)
572 {
573
574   if ( safer_mode() ) 
575     { 
576       msg (SE, _("This command not allowed when the SAFER option is set.")); 
577       return CMD_FAILURE; 
578     } 
579
580   
581   lex_match_id ("ERASE");
582   if (!lex_force_match_id ("FILE"))
583     return CMD_FAILURE;
584   lex_match ('=');
585   if (!lex_force_string ())
586     return CMD_FAILURE;
587
588   if (remove (ds_value (&tokstr)) == -1)
589     {
590       msg (SW, _("Error removing `%s': %s."),
591            ds_value (&tokstr), strerror (errno));
592       return CMD_FAILURE;
593     }
594
595   return CMD_SUCCESS;
596 }
597
598 #ifdef unix
599 /* Spawn a shell process. */
600 static int
601 shell (void)
602 {
603   int pid;
604   
605   pid = fork ();
606   switch (pid)
607     {
608     case 0:
609       {
610         const char *shell_fn;
611         char *shell_process;
612         
613         {
614           int i;
615           
616           for (i = 3; i < 20; i++)
617             close (i);
618         }
619
620         shell_fn = getenv ("SHELL");
621         if (shell_fn == NULL)
622           shell_fn = "/bin/sh";
623         
624         {
625           const char *cp = strrchr (shell_fn, '/');
626           cp = cp ? &cp[1] : shell_fn;
627           shell_process = local_alloc (strlen (cp) + 8);
628           strcpy (shell_process, "-");
629           strcat (shell_process, cp);
630           if (strcmp (cp, "sh"))
631             shell_process[0] = '+';
632         }
633         
634         execl (shell_fn, shell_process, NULL);
635
636         err_hcf (1);
637       }
638
639     case -1:
640       msg (SE, _("Couldn't fork: %s."), strerror (errno));
641       return 0;
642
643     default:
644       assert (pid > 0);
645       while (wait (NULL) != pid)
646         ;
647       return 1;
648     }
649 }
650 #endif /* unix */
651
652 /* Parses the HOST command argument and executes the specified
653    command.  Returns a suitable command return code. */
654 static int
655 run_command (void)
656 {
657   char *cmd;
658   int string;
659
660   /* Handle either a string argument or a full-line argument. */
661   {
662     int c = lex_look_ahead ();
663
664     if (c == '\'' || c == '"')
665       {
666         lex_get ();
667         if (!lex_force_string ())
668           return CMD_FAILURE;
669         cmd = ds_value (&tokstr);
670         string = 1;
671       }
672     else
673       {
674         cmd = lex_rest_of_line (NULL);
675         string = 0;
676       }
677   }
678
679   /* Execute the command. */
680   if (system (cmd) == -1)
681     msg (SE, _("Error executing command: %s."), strerror (errno));
682
683   /* Finish parsing. */
684   if (string)
685     {
686       lex_get ();
687
688       if (token != '.')
689         {
690           lex_error (_("expecting end of command"));
691           return CMD_TRAILING_GARBAGE;
692         }
693     }
694   else
695     token = '.';
696
697   return CMD_SUCCESS;
698 }
699
700 /* Parses, performs the HOST command. */
701 int
702 cmd_host (void)
703 {
704   int code;
705
706   if ( safer_mode() ) 
707     { 
708       msg (SE, _("This command not allowed when the SAFER option is set.")); 
709       return CMD_FAILURE; 
710     } 
711
712   lex_match_id ("HOST");
713
714 #ifdef unix
715   /* Figure out whether to invoke an interactive shell or to execute a
716      single shell command. */
717   if (lex_look_ahead () == '.')
718     {
719       lex_get ();
720       code = shell () ? CMD_PART_SUCCESS_MAYBE : CMD_SUCCESS;
721     }
722   else
723     code = run_command ();
724 #else /* !unix */
725   /* Make sure that the system has a command interpreter, then run a
726      command. */
727   if (system (NULL) != 0)
728     success = run_command ();
729   else
730     {
731       msg (SE, _("No operating system support for this command."));
732       success = CMD_FAILURE;
733     }
734 #endif /* !unix */
735
736   return code ? CMD_FAILURE : CMD_SUCCESS;
737 }
738
739 /* Parses, performs the NEW FILE command. */
740 int
741 cmd_new_file (void)
742 {
743   lex_match_id ("NEW");
744   lex_match_id ("FILE");
745   
746   discard_variables ();
747
748   return lex_end_of_command ();
749 }
750
751 /* Parses, performs the CLEAR TRANSFORMATIONS command. */
752 int
753 cmd_clear_transformations (void)
754 {
755   lex_match_id ("CLEAR");
756   lex_match_id ("TRANSFORMATIONS");
757
758   if (getl_reading_script)
759     {
760       msg (SW, _("This command is not valid in a syntax file."));
761       return CMD_FAILURE;
762     }
763
764   cancel_transformations ();
765
766   return CMD_SUCCESS;
767 }