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