Added very rudimentatry support for commmand line completion
[pspp] / 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 "dictionary.h"
29 #include "error.h"
30 #include "getline.h"
31 #include "lexer.h"
32 #include "main.h"
33 #include "settings.h"
34 #include "som.h"
35 #include "str.h"
36 #include "tab.h"
37 #include "var.h"
38 #include "vfm.h"
39
40 #if HAVE_UNISTD_H
41 #include <unistd.h>
42 #endif
43
44 #if HAVE_SYS_WAIT_H
45 #include <sys/wait.h>
46 #endif
47 \f
48 /* Global variables. */
49
50 /* A STATE_* constant giving the current program state. */
51 int pgm_state;
52
53 /* The name of the procedure currently executing, if any. */
54 const char *cur_proc;
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   };
67
68 /* Define the command array. */
69 #define DEFCMD(NAME, T1, T2, T3, T4, FUNC)              \
70         {NAME, {T1, T2, T3, T4}, FUNC, 1},
71 #define SPCCMD(NAME, T1, T2, T3, T4, FUNC)              \
72         {NAME, {T1, T2, T3, T4}, FUNC, 0},
73 #define UNIMPL(NAME, T1, T2, T3, T4)                    \
74         {NAME, {T1, T2, T3, T4}, NULL, 1},
75 static const struct command commands[] = 
76   {
77 #include "command.def"
78   };
79 #undef DEFCMD
80 #undef UNIMPL
81
82
83 /* Complete the line using the name of a command, 
84  * based upon the current prg_state
85  */
86 char * 
87 pspp_completion_function (const char *text,   int state)
88 {
89   static int skip=0;
90   const struct command *cmd = 0;
91   
92   for(;;)
93     {
94       if ( state + skip >= sizeof(commands)/ sizeof(struct command))
95         {
96           skip = 0;
97           return 0;
98         }
99
100       cmd = &commands[state + skip];
101   
102       if ( cmd->transition[pgm_state] == STATE_ERROR ) 
103         {
104           skip++; 
105           continue;
106         }
107       
108       if ( text == 0 || 0 == strncasecmp (cmd->name, text, strlen(text)))
109         {
110           break;
111         }
112
113       skip++;
114     }
115   
116
117   return xstrdup(cmd->name);
118
119 }
120
121
122
123 #define COMMAND_CNT (sizeof commands / sizeof *commands)
124 \f
125 /* Command parser. */
126
127 static const struct command *parse_command_name (void);
128
129 /* Determines whether command C is appropriate to call in this
130    part of a FILE TYPE structure. */
131 static int
132 FILE_TYPE_okay (const struct command *c)
133 {
134   int okay = 0;
135   
136   if (c->func != cmd_record_type
137       && c->func != cmd_data_list
138       && c->func != cmd_repeating_data
139       && c->func != cmd_end_file_type)
140     msg (SE, _("%s not allowed inside FILE TYPE/END FILE TYPE."), c->name);
141 #if 0
142   /* FIXME */
143   else if (c->func == cmd_repeating_data && fty.type == FTY_GROUPED)
144     msg (SE, _("%s not allowed inside FILE TYPE GROUPED/END FILE TYPE."),
145          c->name);
146   else if (!fty.had_rec_type && c->func != cmd_record_type)
147     msg (SE, _("RECORD TYPE must be the first command inside a "
148                       "FILE TYPE structure."));
149 #endif
150   else
151     okay = 1;
152
153 #if 0
154   if (c->func == cmd_record_type)
155     fty.had_rec_type = 1;
156 #endif
157
158   return okay;
159 }
160
161 /* Parses an entire PSPP command.  This includes everything from the
162    command name to the terminating dot.  Does most of its work by
163    passing it off to the respective command dispatchers.  Only called
164    by parse() in main.c. */
165 int
166 cmd_parse (void)
167 {
168   const struct command *cp;     /* Iterator used to find the proper command. */
169
170 #if C_ALLOCA
171   /* The generic alloca package performs garbage collection when it is
172      called with an argument of zero. */
173   alloca (0);
174 #endif /* C_ALLOCA */
175
176   /* Null commands can result from extra empty lines. */
177   if (token == '.')
178     return CMD_SUCCESS;
179
180   /* Parse comments. */
181   if ((token == T_ID && !strcmp (tokid, "COMMENT"))
182       || token == T_EXP || token == '*' || token == '[')
183     {
184       lex_skip_comment ();
185       return CMD_SUCCESS;
186     }
187
188   /* Otherwise the line must begin with a command name, which is
189      always an ID token. */
190   if (token != T_ID)
191     {
192       lex_error (_("expecting command name"));
193       return CMD_FAILURE;
194     }
195
196   /* Parse the command name. */
197   cp = parse_command_name ();
198   if (cp == NULL)
199     return CMD_FAILURE;
200   if (cp->func == NULL)
201     {
202       msg (SE, _("%s is not yet implemented."), cp->name);
203       while (token && token != '.')
204         lex_get ();
205       return CMD_SUCCESS;
206     }
207
208   /* If we're in a FILE TYPE structure, only certain commands can be
209      allowed. */
210   if (pgm_state == STATE_INPUT
211       && case_source_is_class (vfm_source, &file_type_source_class)
212       && !FILE_TYPE_okay (cp))
213     return CMD_FAILURE;
214
215   /* Certain state transitions are not allowed.  Check for these. */
216   assert (pgm_state >= 0 && pgm_state < STATE_ERROR);
217   if (cp->transition[pgm_state] == STATE_ERROR)
218     {
219       static const char *state_name[4] =
220       {
221         N_("%s is not allowed (1) before a command to specify the "
222            "input program, such as DATA LIST, (2) between FILE TYPE "
223            "and END FILE TYPE, (3) between INPUT PROGRAM and END "
224            "INPUT PROGRAM."),
225         N_("%s is not allowed within an input program."),
226         N_("%s is only allowed within an input program."),
227         N_("%s is only allowed within an input program."),
228       };
229
230       msg (SE, gettext (state_name[pgm_state]), cp->name);
231       return CMD_FAILURE;
232     }
233
234   /* The structured output manager numbers all its tables.  Increment
235      the major table number for each separate procedure. */
236   som_new_series ();
237   
238   {
239     int result;
240     
241     /* Call the command dispatcher.  Save and restore the name of
242        the current command around this call. */
243     {
244       const char *prev_proc;
245       
246       prev_proc = cur_proc;
247       cur_proc = cp->name;
248       result = cp->func ();
249       cur_proc = prev_proc;
250     }
251     
252     /* Perform the state transition if the command completed
253        successfully (at least in part). */
254     if (result != CMD_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 (*a++ != *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 (*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 && !memcmp (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)) && !memcmp (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         || memcmp (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
535       cmd_match_cnt = count_matching_commands (words, word_cnt,
536                                                &dash_possible);
537       if (cmd_match_cnt == 0) 
538         break;
539       else if (cmd_match_cnt == 1) 
540         {
541           const struct command *command = get_complete_match (words, word_cnt);
542           if (command != NULL) 
543             {
544               if (command->skip_entire_name)
545                 lex_get ();
546               free_words (words, word_cnt);
547               return command;
548             }
549         }
550       else /* cmd_match_cnt > 1 */
551         {
552           /* Do we have a complete command name so far? */
553           if (get_complete_match (words, word_cnt) != NULL)
554             complete_word_cnt = word_cnt;
555         }
556       lex_get ();
557     }
558
559   /* If we saw a complete command name earlier, drop back to
560      it. */
561   if (complete_word_cnt) 
562     {
563       int pushback_word_cnt;
564       const struct command *command;
565
566       /* Get the command. */
567       command = get_complete_match (words, complete_word_cnt);
568       assert (command != NULL);
569
570       /* Figure out how many words we want to keep.
571          We normally want to swallow the entire command. */
572       pushback_word_cnt = complete_word_cnt + 1;
573       if (!command->skip_entire_name)
574         pushback_word_cnt--;
575       
576       /* FIXME: We only support one-token pushback. */
577       assert (pushback_word_cnt + 1 >= word_cnt);
578
579       while (word_cnt > pushback_word_cnt) 
580         {
581           word_cnt--;
582           if (strcmp (words[word_cnt], "-")) 
583             lex_put_back_id (words[word_cnt]);
584           else
585             lex_put_back ('-');
586           free (words[word_cnt]);
587         }
588
589       free_words (words, word_cnt);
590       return command;
591     }
592
593   unknown_command_error (words, word_cnt);
594   free_words (words, word_cnt);
595   return NULL;
596 }
597 \f
598 /* Simple commands. */
599
600 /* Parse and execute EXIT command. */
601 int
602 cmd_exit (void)
603 {
604   if (getl_reading_script)
605     {
606       msg (SE, _("This command is not accepted in a syntax file.  "
607            "Instead, use FINISH to terminate a syntax file."));
608       lex_get ();
609     }
610   else
611     finished = 1;
612
613   return CMD_SUCCESS;
614 }
615
616 /* Parse and execute FINISH command. */
617 int
618 cmd_finish (void)
619 {
620   /* Do not check for `.'
621      Do not fetch any extra tokens. */
622   if (getl_interactive)
623     {
624       msg (SM, _("This command is not executed "
625            "in interactive mode.  Instead, PSPP drops "
626            "down to the command prompt.  Use EXIT if you really want "
627            "to quit."));
628       getl_close_all ();
629     }
630   else
631     finished = 1;
632
633   return CMD_SUCCESS;
634 }
635
636 /* Parses the N command. */
637 int
638 cmd_n_of_cases (void)
639 {
640   /* Value for N. */
641   int x;
642
643   if (!lex_force_int ())
644     return CMD_FAILURE;
645   x = lex_integer ();
646   lex_get ();
647   if (!lex_match_id ("ESTIMATED"))
648     dict_set_case_limit (default_dict, x);
649
650   return lex_end_of_command ();
651 }
652
653 /* Parses, performs the EXECUTE procedure. */
654 int
655 cmd_execute (void)
656 {
657   procedure (NULL, NULL);
658   return lex_end_of_command ();
659 }
660
661 /* Parses, performs the ERASE command. */
662 int
663 cmd_erase (void)
664 {
665   if ( safer_mode() ) 
666     { 
667       msg (SE, _("This command not allowed when the SAFER option is set.")); 
668       return CMD_FAILURE; 
669     } 
670   
671   if (!lex_force_match_id ("FILE"))
672     return CMD_FAILURE;
673   lex_match ('=');
674   if (!lex_force_string ())
675     return CMD_FAILURE;
676
677   if (remove (ds_c_str (&tokstr)) == -1)
678     {
679       msg (SW, _("Error removing `%s': %s."),
680            ds_c_str (&tokstr), strerror (errno));
681       return CMD_FAILURE;
682     }
683
684   return CMD_SUCCESS;
685 }
686
687 #ifdef unix
688 /* Spawn a shell process. */
689 static int
690 shell (void)
691 {
692   int pid;
693   
694   pid = fork ();
695   switch (pid)
696     {
697     case 0:
698       {
699         const char *shell_fn;
700         char *shell_process;
701         
702         {
703           int i;
704           
705           for (i = 3; i < 20; i++)
706             close (i);
707         }
708
709         shell_fn = getenv ("SHELL");
710         if (shell_fn == NULL)
711           shell_fn = "/bin/sh";
712         
713         {
714           const char *cp = strrchr (shell_fn, '/');
715           cp = cp ? &cp[1] : shell_fn;
716           shell_process = local_alloc (strlen (cp) + 8);
717           strcpy (shell_process, "-");
718           strcat (shell_process, cp);
719           if (strcmp (cp, "sh"))
720             shell_process[0] = '+';
721         }
722         
723         execl (shell_fn, shell_process, NULL);
724
725         err_hcf (1);
726       }
727
728     case -1:
729       msg (SE, _("Couldn't fork: %s."), strerror (errno));
730       return 0;
731
732     default:
733       assert (pid > 0);
734       while (wait (NULL) != pid)
735         ;
736       return 1;
737     }
738 }
739 #endif /* unix */
740
741 /* Parses the HOST command argument and executes the specified
742    command.  Returns a suitable command return code. */
743 static int
744 run_command (void)
745 {
746   const char *cmd;
747   int string;
748
749   /* Handle either a string argument or a full-line argument. */
750   {
751     int c = lex_look_ahead ();
752
753     if (c == '\'' || c == '"')
754       {
755         lex_get ();
756         if (!lex_force_string ())
757           return CMD_FAILURE;
758         cmd = ds_c_str (&tokstr);
759         string = 1;
760       }
761     else
762       {
763         cmd = lex_rest_of_line (NULL);
764         lex_discard_line ();
765         string = 0;
766       }
767   }
768
769   /* Execute the command. */
770   if (system (cmd) == -1)
771     msg (SE, _("Error executing command: %s."), strerror (errno));
772
773   /* Finish parsing. */
774   if (string)
775     {
776       lex_get ();
777
778       if (token != '.')
779         {
780           lex_error (_("expecting end of command"));
781           return CMD_TRAILING_GARBAGE;
782         }
783     }
784   else
785     token = '.';
786
787   return CMD_SUCCESS;
788 }
789
790 /* Parses, performs the HOST command. */
791 int
792 cmd_host (void)
793 {
794   int code;
795
796   if ( safer_mode() ) 
797     { 
798       msg (SE, _("This command not allowed when the SAFER option is set.")); 
799       return CMD_FAILURE; 
800     } 
801
802 #ifdef unix
803   /* Figure out whether to invoke an interactive shell or to execute a
804      single shell command. */
805   if (lex_look_ahead () == '.')
806     {
807       lex_get ();
808       code = shell () ? CMD_PART_SUCCESS_MAYBE : CMD_SUCCESS;
809     }
810   else
811     code = run_command ();
812 #else /* !unix */
813   /* Make sure that the system has a command interpreter, then run a
814      command. */
815   if (system (NULL) != 0)
816     code = run_command ();
817   else
818     {
819       msg (SE, _("No operating system support for this command."));
820       code = CMD_FAILURE;
821     }
822 #endif /* !unix */
823
824   return code ? CMD_FAILURE : CMD_SUCCESS;
825 }
826
827 /* Parses, performs the NEW FILE command. */
828 int
829 cmd_new_file (void)
830 {
831   discard_variables ();
832
833   return lex_end_of_command ();
834 }
835
836 /* Parses, performs the CLEAR TRANSFORMATIONS command. */
837 int
838 cmd_clear_transformations (void)
839 {
840   if (getl_reading_script)
841     {
842       msg (SW, _("This command is not valid in a syntax file."));
843       return CMD_FAILURE;
844     }
845
846   cancel_transformations ();
847   /* FIXME: what about variables created by transformations?
848      They need to be properly initialized. */
849
850   return CMD_SUCCESS;
851 }