950d801f00b2c1ef5ef8ffcb45a69002771f5b17
[pspp-builds.git] / src / language / 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., 51 Franklin Street, Fifth Floor, Boston, MA
18    02110-1301, USA. */
19
20 #include <config.h>
21 #include "message.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 "dictionary.h"
29 #include "message.h"
30 #include "lexer.h"
31 #include "settings.h"
32 #include "manager.h"
33 #include "str.h"
34 #include "table.h"
35 #include "variable.h"
36 #include "procedure.h"
37
38 #if HAVE_UNISTD_H
39 #include <unistd.h>
40 #endif
41
42 #if HAVE_SYS_WAIT_H
43 #include <sys/wait.h>
44 #endif
45
46 #include "gettext.h"
47 #define _(msgid) gettext (msgid)
48 #define N_(msgid) msgid
49 \f
50 /* Global variables. */
51
52 /* A STATE_* constant giving the current program state. */
53 int pgm_state;
54 \f
55 /* Static variables. */
56
57 /* A single command. */
58 struct command
59   {
60     const char *name;           /* Command name. */
61     int transition[4];          /* Transitions to make from each state. */
62     int (*func) (void);         /* Function to call. */
63     int skip_entire_name;       /* If zero, we don't skip the
64                                    final token in the command name. */
65     short debug;                /* Set if this cmd available only in test mode*/
66   };
67
68 /* Define the command array. */
69 #define DEFCMD(NAME, T1, T2, T3, T4, FUNC)              \
70         {NAME, {T1, T2, T3, T4}, FUNC, 1, 0},
71 #define DBGCMD(NAME, T1, T2, T3, T4, FUNC)              \
72         {NAME, {T1, T2, T3, T4}, FUNC, 1, 1},
73 #define SPCCMD(NAME, T1, T2, T3, T4, FUNC)              \
74         {NAME, {T1, T2, T3, T4}, FUNC, 0, 0},
75 #define UNIMPL(NAME, T1, T2, T3, T4, DESC)              \
76         {NAME, {T1, T2, T3, T4}, NULL, 1, 0},
77 static const struct command commands[] = 
78   {
79 #include "command.def"
80   };
81 #undef DEFCMD
82 #undef DBGCMD
83 #undef UNIMPL
84
85
86 /* Complete the line using the name of a command, 
87  * based upon the current prg_state
88  */
89 char * 
90 pspp_completion_function (const char *text,   int state)
91 {
92   static int skip=0;
93   const struct command *cmd = 0;
94   
95   for(;;)
96     {
97       if ( state + skip >= sizeof(commands)/ sizeof(struct command))
98         {
99           skip = 0;
100           return 0;
101         }
102
103       cmd = &commands[state + skip];
104   
105       if ( cmd->transition[pgm_state] == STATE_ERROR || ( cmd->debug  &&  ! get_testing_mode () ) ) 
106         {
107           skip++; 
108           continue;
109         }
110       
111       if ( text == 0 || 0 == strncasecmp (cmd->name, text, strlen(text)))
112         {
113           break;
114         }
115
116       skip++;
117     }
118   
119
120   return xstrdup(cmd->name);
121 }
122
123
124
125 #define COMMAND_CNT (sizeof commands / sizeof *commands)
126 \f
127 /* Command parser. */
128
129 static const struct command *parse_command_name (void);
130
131 /* Determines whether command C is appropriate to call in this
132    part of a FILE TYPE structure. */
133 static int
134 FILE_TYPE_okay (const struct command *c UNUSED)
135 #if 0
136 {
137   int okay = 0;
138   
139   if (c->func != cmd_record_type
140       && c->func != cmd_data_list
141       && c->func != cmd_repeating_data
142       && c->func != cmd_end_file_type)
143     msg (SE, _("%s not allowed inside FILE TYPE/END FILE TYPE."), c->name);
144   /* FIXME */
145   else if (c->func == cmd_repeating_data && fty.type == FTY_GROUPED)
146     msg (SE, _("%s not allowed inside FILE TYPE GROUPED/END FILE TYPE."),
147          c->name);
148   else if (!fty.had_rec_type && c->func != cmd_record_type)
149     msg (SE, _("RECORD TYPE must be the first command inside a "
150                       "FILE TYPE structure."));
151   else
152     okay = 1;
153
154   if (c->func == cmd_record_type)
155     fty.had_rec_type = 1;
156
157   return okay;
158 }
159 #else
160 {
161   return 1;
162 }
163 #endif
164
165 /* Parses an entire PSPP command.  This includes everything from the
166    command name to the terminating dot.  Does most of its work by
167    passing it off to the respective command dispatchers.  Only called
168    by parse() in main.c. */
169 int
170 cmd_parse (void)
171 {
172   const struct command *cp;     /* Iterator used to find the proper command. */
173
174 #if C_ALLOCA
175   /* The generic alloca package performs garbage collection when it is
176      called with an argument of zero. */
177   alloca (0);
178 #endif /* C_ALLOCA */
179
180   /* Null commands can result from extra empty lines. */
181   if (token == '.')
182     return CMD_SUCCESS;
183
184   /* Parse comments. */
185   if ((token == T_ID && !strcasecmp (tokid, "COMMENT"))
186       || token == T_EXP || token == '*' || token == '[')
187     {
188       lex_skip_comment ();
189       return CMD_SUCCESS;
190     }
191
192   /* Otherwise the line must begin with a command name, which is
193      always an ID token. */
194   if (token != T_ID)
195     {
196       lex_error (_("expecting command name"));
197       return CMD_FAILURE;
198     }
199
200   /* Parse the command name. */
201   cp = parse_command_name ();
202   if (cp == NULL)
203     return CMD_FAILURE;
204   if (cp->func == NULL)
205     {
206       msg (SE, _("%s is not yet implemented."), cp->name);
207       while (token && token != '.')
208         lex_get ();
209       return CMD_SUCCESS;
210     }
211
212   /* If we're in a FILE TYPE structure, only certain commands can be
213      allowed. */
214   if (pgm_state == STATE_INPUT
215       && case_source_is_class (vfm_source, &file_type_source_class)
216       && !FILE_TYPE_okay (cp))
217     return CMD_FAILURE;
218
219   /* Certain state transitions are not allowed.  Check for these. */
220   assert (pgm_state >= 0 && pgm_state < STATE_ERROR);
221   if (cp->transition[pgm_state] == STATE_ERROR)
222     {
223       static const char *state_name[4] =
224       {
225         N_("%s is not allowed (1) before a command to specify the "
226            "input program, such as DATA LIST, (2) between FILE TYPE "
227            "and END FILE TYPE, (3) between INPUT PROGRAM and END "
228            "INPUT PROGRAM."),
229         N_("%s is not allowed within an input program."),
230         N_("%s is only allowed within an input program."),
231         N_("%s is only allowed within an input program."),
232       };
233
234       msg (SE, gettext (state_name[pgm_state]), cp->name);
235       return CMD_FAILURE;
236     }
237
238   /* The structured output manager numbers all its tables.  Increment
239      the major table number for each separate procedure. */
240   som_new_series ();
241   
242   {
243     int result;
244     
245     /* Call the command dispatcher. */
246     err_set_command_name (cp->name);
247     tab_set_command_name (cp->name);
248     result = cp->func ();
249     err_set_command_name (NULL);
250     tab_set_command_name (NULL);
251     
252     /* Perform the state transition if the command completed
253        successfully (at least in part). */
254     if (result != CMD_FAILURE && result != CMD_CASCADING_FAILURE)
255       {
256         pgm_state = cp->transition[pgm_state];
257
258         if (pgm_state == STATE_ERROR)
259           {
260             discard_variables ();
261             pgm_state = STATE_INIT;
262           }
263       }
264
265     /* Pass the command's success value up to the caller. */
266     return result;
267   }
268 }
269
270 static size_t
271 match_strings (const char *a, size_t a_len,
272                const char *b, size_t b_len) 
273 {
274   size_t match_len = 0;
275   
276   while (a_len > 0 && b_len > 0) 
277     {
278       /* Mismatch always returns zero. */
279       if (toupper ((unsigned char) *a++) != toupper ((unsigned char) *b++))
280         return 0;
281
282       /* Advance. */
283       a_len--;
284       b_len--;
285       match_len++;
286     }
287
288   return match_len;
289 }
290
291 /* Returns the first character in the first word in STRING,
292    storing the word's length in *WORD_LEN.  If no words remain,
293    returns a null pointer and stores 0 in *WORD_LEN.  Words are
294    sequences of alphanumeric characters or single
295    non-alphanumeric characters.  Words are delimited by
296    spaces. */
297 static const char *
298 find_word (const char *string, size_t *word_len) 
299 {
300   /* Skip whitespace and asterisks. */
301   while (isspace ((unsigned char) *string))
302     string++;
303
304   /* End of string? */
305   if (*string == '\0') 
306     {
307       *word_len = 0;
308       return NULL;
309     }
310
311   /* Special one-character word? */
312   if (!isalnum ((unsigned char) *string)) 
313     {
314       *word_len = 1;
315       return string;
316     }
317
318   /* Alphanumeric word. */
319   *word_len = 1;
320   while (isalnum ((unsigned char) string[*word_len]))
321     (*word_len)++;
322
323   return string;
324 }
325
326 /* Returns nonzero if strings A and B can be confused based on
327    their first three letters. */
328 static int
329 conflicting_3char_prefixes (const char *a, const char *b) 
330 {
331   size_t aw_len, bw_len;
332   const char *aw, *bw;
333
334   aw = find_word (a, &aw_len);
335   bw = find_word (b, &bw_len);
336   assert (aw != NULL && bw != NULL);
337
338   /* Words that are the same don't conflict. */
339   if (aw_len == bw_len && !buf_compare_case (aw, bw, aw_len))
340     return 0;
341   
342   /* Words that are otherwise the same in the first three letters
343      do conflict. */
344   return ((aw_len > 3 && bw_len > 3)
345           || (aw_len == 3 && bw_len > 3)
346           || (bw_len == 3 && aw_len > 3)) && !buf_compare_case (aw, bw, 3);
347 }
348
349 /* Returns nonzero if CMD can be confused with another command
350    based on the first three letters of its first word. */
351 static int
352 conflicting_3char_prefix_command (const struct command *cmd) 
353 {
354   assert (cmd >= commands && cmd < commands + COMMAND_CNT);
355
356   return ((cmd > commands
357            && conflicting_3char_prefixes (cmd[-1].name, cmd[0].name))
358           || (cmd < commands + COMMAND_CNT
359               && conflicting_3char_prefixes (cmd[0].name, cmd[1].name)));
360 }
361
362 /* Ways that a set of words can match a command name. */
363 enum command_match
364   {
365     MISMATCH,           /* Not a match. */
366     PARTIAL_MATCH,      /* The words begin the command name. */
367     COMPLETE_MATCH      /* The words are the command name. */
368   };
369
370 /* Figures out how well the WORD_CNT words in WORDS match CMD,
371    and returns the appropriate enum value.  If WORDS are a
372    partial match for CMD and the next word in CMD is a dash, then
373    *DASH_POSSIBLE is set to 1 if DASH_POSSIBLE is non-null;
374    otherwise, *DASH_POSSIBLE is unchanged. */
375 static enum command_match
376 cmd_match_words (const struct command *cmd,
377                  char *const words[], size_t word_cnt,
378                  int *dash_possible)
379 {
380   const char *word;
381   size_t word_len;
382   size_t word_idx;
383
384   for (word = find_word (cmd->name, &word_len), word_idx = 0;
385        word != NULL && word_idx < word_cnt;
386        word = find_word (word + word_len, &word_len), word_idx++)
387     if (word_len != strlen (words[word_idx])
388         || buf_compare_case (word, words[word_idx], word_len))
389       {
390         size_t match_chars = match_strings (word, word_len,
391                                             words[word_idx],
392                                             strlen (words[word_idx]));
393         if (match_chars == 0) 
394           {
395             /* Mismatch. */
396             return MISMATCH;
397           }
398         else if (match_chars == 1 || match_chars == 2) 
399           {
400             /* One- and two-character abbreviations are not
401                acceptable. */
402             return MISMATCH; 
403           }
404         else if (match_chars == 3) 
405           {
406             /* Three-character abbreviations are acceptable
407                in the first word of a command if there are
408                no name conflicts.  They are always
409                acceptable after the first word. */
410             if (word_idx == 0 && conflicting_3char_prefix_command (cmd))
411               return MISMATCH;
412           }
413         else /* match_chars > 3 */ 
414           {
415             /* Four-character and longer abbreviations are
416                always acceptable.  */
417           }
418       }
419
420   if (word == NULL && word_idx == word_cnt) 
421     {
422       /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR"}. */
423       return COMPLETE_MATCH;
424     }
425   else if (word == NULL) 
426     {
427       /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR", "BAZ"}. */
428       return MISMATCH; 
429     }
430   else 
431     {
432       /* cmd->name = "FOO BAR BAZ", words[] = {"FOO", "BAR"}. */
433       if (word[0] == '-' && dash_possible != NULL)
434         *dash_possible = 1;
435       return PARTIAL_MATCH; 
436     }
437 }
438
439 /* Returns the number of commands for which the WORD_CNT words in
440    WORDS are a partial or complete match.  If some partial match
441    has a dash as the next word, then *DASH_POSSIBLE is set to 1,
442    otherwise it is set to 0. */
443 static int
444 count_matching_commands (char *const words[], size_t word_cnt,
445                          int *dash_possible) 
446 {
447   const struct command *cmd;
448   int cmd_match_count;
449
450   cmd_match_count = 0;
451   *dash_possible = 0;
452   for (cmd = commands; cmd < commands + COMMAND_CNT; cmd++) 
453     if (cmd_match_words (cmd, words, word_cnt, dash_possible) != MISMATCH) 
454       cmd_match_count++; 
455
456   return cmd_match_count;
457 }
458
459 /* Returns the command for which the WORD_CNT words in WORDS are
460    a complete match.  Returns a null pointer if no such command
461    exists. */
462 static const struct command *
463 get_complete_match (char *const words[], size_t word_cnt) 
464 {
465   const struct command *cmd;
466   
467   for (cmd = commands; cmd < commands + COMMAND_CNT; cmd++) 
468     if (cmd_match_words (cmd, words, word_cnt, NULL) == COMPLETE_MATCH) 
469       return cmd; 
470   
471   return NULL;
472 }
473
474 /* Frees the WORD_CNT words in WORDS. */
475 static void
476 free_words (char *words[], size_t word_cnt) 
477 {
478   size_t idx;
479   
480   for (idx = 0; idx < word_cnt; idx++)
481     free (words[idx]);
482 }
483
484 /* Flags an error that the command whose name is given by the
485    WORD_CNT words in WORDS is unknown. */
486 static void
487 unknown_command_error (char *const words[], size_t word_cnt) 
488 {
489   size_t idx;
490   size_t words_len;
491   char *name, *cp;
492
493   words_len = 0;
494   for (idx = 0; idx < word_cnt; idx++)
495     words_len += strlen (words[idx]);
496
497   cp = name = xmalloc (words_len + word_cnt + 16);
498   for (idx = 0; idx < word_cnt; idx++) 
499     {
500       if (idx != 0)
501         *cp++ = ' ';
502       cp = stpcpy (cp, words[idx]);
503     }
504   *cp = '\0';
505
506   msg (SE, _("Unknown command %s."), name);
507
508   free (name);
509 }
510
511
512 /* Parse the command name and return a pointer to the corresponding
513    struct command if successful.
514    If not successful, return a null pointer. */
515 static const struct command *
516 parse_command_name (void)
517 {
518   char *words[16];
519   int word_cnt;
520   int complete_word_cnt;
521   int dash_possible;
522
523   dash_possible = 0;
524   word_cnt = complete_word_cnt = 0;
525   while (token == T_ID || (dash_possible && token == '-')) 
526     {
527       int cmd_match_cnt;
528       
529       assert (word_cnt < sizeof words / sizeof *words);
530       if (token == T_ID)
531         words[word_cnt] = xstrdup (ds_c_str (&tokstr));
532       else
533         words[word_cnt] = xstrdup ("-");
534       str_uppercase (words[word_cnt]);
535       word_cnt++;
536
537       cmd_match_cnt = count_matching_commands (words, word_cnt,
538                                                &dash_possible);
539       if (cmd_match_cnt == 0) 
540         break;
541       else if (cmd_match_cnt == 1) 
542         {
543           const struct command *command = get_complete_match (words, word_cnt);
544           if (command != NULL) 
545             {
546               if (command->skip_entire_name)
547                 lex_get ();
548               if ( command->debug & !get_testing_mode () ) 
549                 goto error;
550               free_words (words, word_cnt);
551               return command;
552             }
553         }
554       else /* cmd_match_cnt > 1 */
555         {
556           /* Do we have a complete command name so far? */
557           if (get_complete_match (words, word_cnt) != NULL)
558             complete_word_cnt = word_cnt;
559         }
560       lex_get ();
561     }
562
563   /* If we saw a complete command name earlier, drop back to
564      it. */
565   if (complete_word_cnt) 
566     {
567       int pushback_word_cnt;
568       const struct command *command;
569
570       /* Get the command. */
571       command = get_complete_match (words, complete_word_cnt);
572       assert (command != NULL);
573
574       /* Figure out how many words we want to keep.
575          We normally want to swallow the entire command. */
576       pushback_word_cnt = complete_word_cnt + 1;
577       if (!command->skip_entire_name)
578         pushback_word_cnt--;
579       
580       /* FIXME: We only support one-token pushback. */
581       assert (pushback_word_cnt + 1 >= word_cnt);
582
583       while (word_cnt > pushback_word_cnt) 
584         {
585           word_cnt--;
586           if (strcmp (words[word_cnt], "-")) 
587             lex_put_back_id (words[word_cnt]);
588           else
589             lex_put_back ('-');
590           free (words[word_cnt]);
591         }
592
593       if ( command->debug && !get_testing_mode () ) 
594         goto error;
595
596       free_words (words, word_cnt);
597       return command;
598     }
599
600 error:
601   unknown_command_error (words, word_cnt);
602   free_words (words, word_cnt);
603   return NULL;
604 }
605 \f
606 /* Simple commands. */
607
608 /* Parse and execute FINISH command. */
609 int
610 cmd_finish (void)
611 {
612   return CMD_EOF;
613 }
614
615 /* Parses the N command. */
616 int
617 cmd_n_of_cases (void)
618 {
619   /* Value for N. */
620   int x;
621
622   if (!lex_force_int ())
623     return CMD_FAILURE;
624   x = lex_integer ();
625   lex_get ();
626   if (!lex_match_id ("ESTIMATED"))
627     dict_set_case_limit (default_dict, x);
628
629   return lex_end_of_command ();
630 }
631
632 /* Parses, performs the EXECUTE procedure. */
633 int
634 cmd_execute (void)
635 {
636   if (!procedure (NULL, NULL))
637     return CMD_CASCADING_FAILURE;
638   return lex_end_of_command ();
639 }
640
641 /* Parses, performs the ERASE command. */
642 int
643 cmd_erase (void)
644 {
645   if (get_safer_mode ()) 
646     { 
647       msg (SE, _("This command not allowed when the SAFER option is set.")); 
648       return CMD_FAILURE; 
649     } 
650   
651   if (!lex_force_match_id ("FILE"))
652     return CMD_FAILURE;
653   lex_match ('=');
654   if (!lex_force_string ())
655     return CMD_FAILURE;
656
657   if (remove (ds_c_str (&tokstr)) == -1)
658     {
659       msg (SW, _("Error removing `%s': %s."),
660            ds_c_str (&tokstr), strerror (errno));
661       return CMD_FAILURE;
662     }
663
664   return CMD_SUCCESS;
665 }
666
667 #ifdef unix
668 /* Spawn a shell process. */
669 static int
670 shell (void)
671 {
672   int pid;
673   
674   pid = fork ();
675   switch (pid)
676     {
677     case 0:
678       {
679         const char *shell_fn;
680         char *shell_process;
681         
682         {
683           int i;
684           
685           for (i = 3; i < 20; i++)
686             close (i);
687         }
688
689         shell_fn = getenv ("SHELL");
690         if (shell_fn == NULL)
691           shell_fn = "/bin/sh";
692         
693         {
694           const char *cp = strrchr (shell_fn, '/');
695           cp = cp ? &cp[1] : shell_fn;
696           shell_process = local_alloc (strlen (cp) + 8);
697           strcpy (shell_process, "-");
698           strcat (shell_process, cp);
699           if (strcmp (cp, "sh"))
700             shell_process[0] = '+';
701         }
702         
703         execl (shell_fn, shell_process, NULL);
704
705         _exit (1);
706       }
707
708     case -1:
709       msg (SE, _("Couldn't fork: %s."), strerror (errno));
710       return 0;
711
712     default:
713       assert (pid > 0);
714       while (wait (NULL) != pid)
715         ;
716       return 1;
717     }
718 }
719 #endif /* unix */
720
721 /* Parses the HOST command argument and executes the specified
722    command.  Returns a suitable command return code. */
723 static int
724 run_command (void)
725 {
726   const char *cmd;
727   int string;
728
729   /* Handle either a string argument or a full-line argument. */
730   {
731     int c = lex_look_ahead ();
732
733     if (c == '\'' || c == '"')
734       {
735         lex_get ();
736         if (!lex_force_string ())
737           return CMD_FAILURE;
738         cmd = ds_c_str (&tokstr);
739         string = 1;
740       }
741     else
742       {
743         cmd = lex_rest_of_line (NULL);
744         lex_discard_line ();
745         string = 0;
746       }
747   }
748
749   /* Execute the command. */
750   if (system (cmd) == -1)
751     msg (SE, _("Error executing command: %s."), strerror (errno));
752
753   /* Finish parsing. */
754   if (string)
755     {
756       lex_get ();
757
758       if (token != '.')
759         {
760           lex_error (_("expecting end of command"));
761           return CMD_TRAILING_GARBAGE;
762         }
763     }
764   else
765     token = '.';
766
767   return CMD_SUCCESS;
768 }
769
770 /* Parses, performs the HOST command. */
771 int
772 cmd_host (void)
773 {
774   int code;
775
776   if (get_safer_mode ()) 
777     { 
778       msg (SE, _("This command not allowed when the SAFER option is set.")); 
779       return CMD_FAILURE; 
780     } 
781
782 #ifdef unix
783   /* Figure out whether to invoke an interactive shell or to execute a
784      single shell command. */
785   if (lex_look_ahead () == '.')
786     {
787       lex_get ();
788       code = shell () ? CMD_PART_SUCCESS_MAYBE : CMD_SUCCESS;
789     }
790   else
791     code = run_command ();
792 #else /* !unix */
793   /* Make sure that the system has a command interpreter, then run a
794      command. */
795   if (system (NULL) != 0)
796     code = run_command ();
797   else
798     {
799       msg (SE, _("No operating system support for this command."));
800       code = CMD_FAILURE;
801     }
802 #endif /* !unix */
803
804   return code;
805 }
806
807 /* Parses, performs the NEW FILE command. */
808 int
809 cmd_new_file (void)
810 {
811   discard_variables ();
812
813   return lex_end_of_command ();
814 }
815
816 /* Parses, performs the CLEAR TRANSFORMATIONS command. */
817 int
818 cmd_clear_transformations (void)
819 {
820   cancel_transformations ();
821   /* FIXME: what about variables created by transformations?
822      They need to be properly initialized. */
823
824   return CMD_SUCCESS;
825 }