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