Fix regression in command name completion reported by John Darrington.
[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
22 #include <language/command.h>
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <ctype.h>
27 #include <errno.h>
28 #include <unistd.h>
29
30 #include <data/dictionary.h>
31 #include <data/procedure.h>
32 #include <data/settings.h>
33 #include <data/variable.h>
34 #include <language/lexer/lexer.h>
35 #include <language/line-buffer.h>
36 #include <libpspp/alloc.h>
37 #include <libpspp/compiler.h>
38 #include <libpspp/message.h>
39 #include <libpspp/message.h>
40 #include <libpspp/str.h>
41 #include <output/manager.h>
42 #include <output/table.h>
43
44 #if HAVE_SYS_WAIT_H
45 #include <sys/wait.h>
46 #endif
47
48 #if HAVE_READLINE
49 #include <readline/readline.h>
50 #endif
51
52 #include "gettext.h"
53 #define _(msgid) gettext (msgid)
54 #define N_(msgid) msgid
55 \f
56 /* Returns true if RESULT is a valid "enum cmd_result",
57    false otherwise. */
58 static inline bool
59 cmd_result_is_valid (enum cmd_result result) 
60 {
61   return (result == CMD_SUCCESS || result == CMD_EOF || result == CMD_FINISH
62           || (result >= CMD_PRIVATE_FIRST && result <= CMD_PRIVATE_LAST)
63           || result == CMD_FAILURE || result == CMD_NOT_IMPLEMENTED
64           || result == CMD_CASCADING_FAILURE);
65 }
66
67 /* Returns true if RESULT indicates success,
68    false otherwise. */
69 bool
70 cmd_result_is_success (enum cmd_result result) 
71 {
72   assert (cmd_result_is_valid (result));
73   return result > 0;
74 }
75
76 /* Returns true if RESULT indicates failure,
77    false otherwise. */
78 bool
79 cmd_result_is_failure (enum cmd_result result) 
80 {
81   assert (cmd_result_is_valid (result));
82   return result < 0;
83 }
84 \f
85 /* Command processing states. */
86 enum states
87   {
88     S_INITIAL = 0x01,         /* Allowed before active file defined. */
89     S_DATA = 0x02,            /* Allowed after active file defined. */
90     S_INPUT_PROGRAM = 0x04,   /* Allowed in INPUT PROGRAM. */
91     S_FILE_TYPE = 0x08,       /* Allowed in FILE TYPE. */
92     S_ANY = 0x0f              /* Allowed anywhere. */
93   };
94
95 /* Other command requirements. */
96 enum flags 
97   {
98     F_ENHANCED = 0x10,        /* Allowed only in enhanced syntax mode. */
99     F_TESTING = 0x20,         /* Allowed only in testing mode. */
100     F_KEEP_FINAL_TOKEN = 0x40 /* Don't skip final token in command name. */
101   };
102
103 /* A single command. */
104 struct command
105   {
106     enum states states;         /* States in which command is allowed. */
107     enum flags flags;           /* Other command requirements. */
108     const char *name;           /* Command name. */
109     int (*function) (void);     /* Function to call. */
110   };
111
112 /* Define the command array. */
113 #define DEF_CMD(STATES, FLAGS, NAME, FUNCTION) {STATES, FLAGS, NAME, FUNCTION},
114 #define UNIMPL_CMD(NAME, DESCRIPTION) {S_ANY, 0, NAME, NULL},
115 static const struct command commands[] = 
116   {
117 #include "command.def"
118   };
119 #undef DEF_CMD
120 #undef UNIMPL_CMD
121
122 static const size_t command_cnt = sizeof commands / sizeof *commands;
123
124 static bool in_correct_state (const struct command *, enum cmd_state);
125 static bool report_state_mismatch (const struct command *, enum cmd_state);
126 static const struct command *find_command (const char *name);
127 static void set_completion_state (enum cmd_state); 
128 \f
129 /* Command parser. */
130
131 static const struct command *parse_command_name (void);
132 static enum cmd_result do_parse_command (enum cmd_state);
133
134 /* Parses an entire command, from command name to terminating
135    dot.  On failure, skips to the terminating dot.
136    Returns the command's success or failure result. */
137 enum cmd_result
138 cmd_parse (enum cmd_state state) 
139 {
140   int result;
141   
142   som_new_series ();
143
144   result = do_parse_command (state);
145   if (cmd_result_is_failure (result)) 
146     lex_discard_rest_of_command ();
147
148   unset_cmd_algorithm ();
149   dict_clear_aux (default_dict);
150
151   return result;
152 }
153
154 /* Parses an entire command, from command name to terminating
155    dot. */
156 static enum cmd_result
157 do_parse_command (enum cmd_state state)
158 {
159   const struct command *command;
160   enum cmd_result result;
161
162   /* Read the command's first token. */
163   getl_set_prompt_style (GETL_PROMPT_FIRST);
164   set_completion_state (state);
165   lex_get ();
166   if (token == T_STOP)
167     return CMD_EOF;
168   else if (token == '.') 
169     {
170       /* Null commands can result from extra empty lines. */
171       return CMD_SUCCESS; 
172     }
173   getl_set_prompt_style (GETL_PROMPT_LATER);
174
175   /* Parse the command name. */
176   command = parse_command_name ();
177   if (command == NULL)
178     return CMD_FAILURE;
179   else if (command->function == NULL)
180     return CMD_NOT_IMPLEMENTED;
181   else if ((command->flags & F_TESTING) && !get_testing_mode ()) 
182     {
183       msg (SE, _("%s may be used only in testing mode."), command->name);
184       return CMD_FAILURE;
185     }
186   else if ((command->flags & F_ENHANCED) && get_syntax () != ENHANCED) 
187     {
188       msg (SE, _("%s may be used only in enhanced syntax mode."),
189            command->name);
190        return CMD_FAILURE;
191     }
192   else if (!in_correct_state (command, state)) 
193     {
194       report_state_mismatch (command, state);
195       return CMD_FAILURE; 
196     }
197
198   /* Execute command. */
199   msg_set_command_name (command->name);
200   tab_set_command_name (command->name);
201   result = command->function ();
202   tab_set_command_name (NULL);
203   msg_set_command_name (NULL);
204     
205   assert (cmd_result_is_valid (result));
206   return result;
207 }
208
209 static size_t
210 match_strings (const char *a, size_t a_len,
211                const char *b, size_t b_len) 
212 {
213   size_t match_len = 0;
214   
215   while (a_len > 0 && b_len > 0) 
216     {
217       /* Mismatch always returns zero. */
218       if (toupper ((unsigned char) *a++) != toupper ((unsigned char) *b++))
219         return 0;
220
221       /* Advance. */
222       a_len--;
223       b_len--;
224       match_len++;
225     }
226
227   return match_len;
228 }
229
230 /* Returns the first character in the first word in STRING,
231    storing the word's length in *WORD_LEN.  If no words remain,
232    returns a null pointer and stores 0 in *WORD_LEN.  Words are
233    sequences of alphanumeric characters or single
234    non-alphanumeric characters.  Words are delimited by
235    spaces. */
236 static const char *
237 find_word (const char *string, size_t *word_len) 
238 {
239   /* Skip whitespace and asterisks. */
240   while (isspace ((unsigned char) *string))
241     string++;
242
243   /* End of string? */
244   if (*string == '\0') 
245     {
246       *word_len = 0;
247       return NULL;
248     }
249
250   /* Special one-character word? */
251   if (!isalnum ((unsigned char) *string)) 
252     {
253       *word_len = 1;
254       return string;
255     }
256
257   /* Alphanumeric word. */
258   *word_len = 1;
259   while (isalnum ((unsigned char) string[*word_len]))
260     (*word_len)++;
261
262   return string;
263 }
264
265 /* Returns nonzero if strings A and B can be confused based on
266    their first three letters. */
267 static int
268 conflicting_3char_prefixes (const char *a, const char *b) 
269 {
270   size_t aw_len, bw_len;
271   const char *aw, *bw;
272
273   aw = find_word (a, &aw_len);
274   bw = find_word (b, &bw_len);
275   assert (aw != NULL && bw != NULL);
276
277   /* Words that are the same don't conflict. */
278   if (aw_len == bw_len && !buf_compare_case (aw, bw, aw_len))
279     return 0;
280   
281   /* Words that are otherwise the same in the first three letters
282      do conflict. */
283   return ((aw_len > 3 && bw_len > 3)
284           || (aw_len == 3 && bw_len > 3)
285           || (bw_len == 3 && aw_len > 3)) && !buf_compare_case (aw, bw, 3);
286 }
287
288 /* Returns nonzero if CMD can be confused with another command
289    based on the first three letters of its first word. */
290 static int
291 conflicting_3char_prefix_command (const struct command *cmd) 
292 {
293   assert (cmd >= commands && cmd < commands + command_cnt);
294
295   return ((cmd > commands
296            && conflicting_3char_prefixes (cmd[-1].name, cmd[0].name))
297           || (cmd < commands + command_cnt
298               && conflicting_3char_prefixes (cmd[0].name, cmd[1].name)));
299 }
300
301 /* Ways that a set of words can match a command name. */
302 enum command_match
303   {
304     MISMATCH,           /* Not a match. */
305     PARTIAL_MATCH,      /* The words begin the command name. */
306     COMPLETE_MATCH      /* The words are the command name. */
307   };
308
309 /* Figures out how well the WORD_CNT words in WORDS match CMD,
310    and returns the appropriate enum value.  If WORDS are a
311    partial match for CMD and the next word in CMD is a dash, then
312    *DASH_POSSIBLE is set to 1 if DASH_POSSIBLE is non-null;
313    otherwise, *DASH_POSSIBLE is unchanged. */
314 static enum command_match
315 cmd_match_words (const struct command *cmd,
316                  char *const words[], size_t word_cnt,
317                  int *dash_possible)
318 {
319   const char *word;
320   size_t word_len;
321   size_t word_idx;
322
323   for (word = find_word (cmd->name, &word_len), word_idx = 0;
324        word != NULL && word_idx < word_cnt;
325        word = find_word (word + word_len, &word_len), word_idx++)
326     if (word_len != strlen (words[word_idx])
327         || buf_compare_case (word, words[word_idx], word_len))
328       {
329         size_t match_chars = match_strings (word, word_len,
330                                             words[word_idx],
331                                             strlen (words[word_idx]));
332         if (match_chars == 0) 
333           {
334             /* Mismatch. */
335             return MISMATCH;
336           }
337         else if (match_chars == 1 || match_chars == 2) 
338           {
339             /* One- and two-character abbreviations are not
340                acceptable. */
341             return MISMATCH; 
342           }
343         else if (match_chars == 3) 
344           {
345             /* Three-character abbreviations are acceptable
346                in the first word of a command if there are
347                no name conflicts.  They are always
348                acceptable after the first word. */
349             if (word_idx == 0 && conflicting_3char_prefix_command (cmd))
350               return MISMATCH;
351           }
352         else /* match_chars > 3 */ 
353           {
354             /* Four-character and longer abbreviations are
355                always acceptable.  */
356           }
357       }
358
359   if (word == NULL && word_idx == word_cnt) 
360     {
361       /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR"}. */
362       return COMPLETE_MATCH;
363     }
364   else if (word == NULL) 
365     {
366       /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR", "BAZ"}. */
367       return MISMATCH; 
368     }
369   else 
370     {
371       /* cmd->name = "FOO BAR BAZ", words[] = {"FOO", "BAR"}. */
372       if (word[0] == '-' && dash_possible != NULL)
373         *dash_possible = 1;
374       return PARTIAL_MATCH; 
375     }
376 }
377
378 /* Returns the number of commands for which the WORD_CNT words in
379    WORDS are a partial or complete match.  If some partial match
380    has a dash as the next word, then *DASH_POSSIBLE is set to 1,
381    otherwise it is set to 0. */
382 static int
383 count_matching_commands (char *const words[], size_t word_cnt,
384                          int *dash_possible) 
385 {
386   const struct command *cmd;
387   int cmd_match_count;
388
389   cmd_match_count = 0;
390   *dash_possible = 0;
391   for (cmd = commands; cmd < commands + command_cnt; cmd++) 
392     if (cmd_match_words (cmd, words, word_cnt, dash_possible) != MISMATCH) 
393       cmd_match_count++; 
394
395   return cmd_match_count;
396 }
397
398 /* Returns the command for which the WORD_CNT words in WORDS are
399    a complete match.  Returns a null pointer if no such command
400    exists. */
401 static const struct command *
402 get_complete_match (char *const words[], size_t word_cnt) 
403 {
404   const struct command *cmd;
405   
406   for (cmd = commands; cmd < commands + command_cnt; cmd++) 
407     if (cmd_match_words (cmd, words, word_cnt, NULL) == COMPLETE_MATCH) 
408       return cmd; 
409   
410   return NULL;
411 }
412
413 /* Returns the command with the given exact NAME.
414    Aborts if no such command exists. */
415 static const struct command *
416 find_command (const char *name) 
417 {
418   const struct command *cmd;
419   
420   for (cmd = commands; cmd < commands + command_cnt; cmd++) 
421     if (!strcmp (cmd->name, name))
422       return cmd;
423   abort ();
424 }
425
426 /* Frees the WORD_CNT words in WORDS. */
427 static void
428 free_words (char *words[], size_t word_cnt) 
429 {
430   size_t idx;
431   
432   for (idx = 0; idx < word_cnt; idx++)
433     free (words[idx]);
434 }
435
436 /* Flags an error that the command whose name is given by the
437    WORD_CNT words in WORDS is unknown. */
438 static void
439 unknown_command_error (char *const words[], size_t word_cnt) 
440 {
441   if (word_cnt == 0) 
442     lex_error (_("expecting command name"));
443   else 
444     {
445       struct string s;
446       size_t i;
447
448       ds_init_empty (&s);
449       for (i = 0; i < word_cnt; i++) 
450         {
451           if (i != 0)
452             ds_put_char (&s, ' ');
453           ds_put_cstr (&s, words[i]);
454         }
455
456       msg (SE, _("Unknown command %s."), ds_cstr (&s));
457
458       ds_destroy (&s);
459     }
460 }
461
462 /* Parse the command name and return a pointer to the corresponding
463    struct command if successful.
464    If not successful, return a null pointer. */
465 static const struct command *
466 parse_command_name (void)
467 {
468   char *words[16];
469   int word_cnt;
470   int complete_word_cnt;
471   int dash_possible;
472
473   if (token == T_EXP || token == '*' || token == '[') 
474     return find_command ("COMMENT");
475
476   dash_possible = 0;
477   word_cnt = complete_word_cnt = 0;
478   while (token == T_ID || (dash_possible && token == '-')) 
479     {
480       int cmd_match_cnt;
481       
482       assert (word_cnt < sizeof words / sizeof *words);
483       if (token == T_ID) 
484         {
485           words[word_cnt] = ds_xstrdup (&tokstr);
486           str_uppercase (words[word_cnt]); 
487         }
488       else if (token == '-')
489         words[word_cnt] = xstrdup ("-");
490       word_cnt++;
491
492       cmd_match_cnt = count_matching_commands (words, word_cnt,
493                                                &dash_possible);
494       if (cmd_match_cnt == 0) 
495         break;
496       else if (cmd_match_cnt == 1) 
497         {
498           const struct command *command = get_complete_match (words, word_cnt);
499           if (command != NULL) 
500             {
501               if (!(command->flags & F_KEEP_FINAL_TOKEN))
502                 lex_get ();
503               free_words (words, word_cnt);
504               return command;
505             }
506         }
507       else /* cmd_match_cnt > 1 */
508         {
509           /* Do we have a complete command name so far? */
510           if (get_complete_match (words, word_cnt) != NULL)
511             complete_word_cnt = word_cnt;
512         }
513       lex_get ();
514     }
515
516   /* If we saw a complete command name earlier, drop back to
517      it. */
518   if (complete_word_cnt) 
519     {
520       int pushback_word_cnt;
521       const struct command *command;
522
523       /* Get the command. */
524       command = get_complete_match (words, complete_word_cnt);
525       assert (command != NULL);
526
527       /* Figure out how many words we want to keep.
528          We normally want to swallow the entire command. */
529       pushback_word_cnt = complete_word_cnt + 1;
530       if (command->flags & F_KEEP_FINAL_TOKEN)
531         pushback_word_cnt--;
532       
533       /* FIXME: We only support one-token pushback. */
534       assert (pushback_word_cnt + 1 >= word_cnt);
535
536       while (word_cnt > pushback_word_cnt) 
537         {
538           word_cnt--;
539           if (strcmp (words[word_cnt], "-")) 
540             lex_put_back_id (words[word_cnt]);
541           else
542             lex_put_back ('-');
543           free (words[word_cnt]);
544         }
545
546       free_words (words, word_cnt);
547       return command;
548     }
549
550   /* We didn't get a valid command name. */
551   unknown_command_error (words, word_cnt);
552   free_words (words, word_cnt);
553   return NULL;
554 }
555
556 /* Returns true if COMMAND is allowed in STATE,
557    false otherwise. */
558 static bool
559 in_correct_state (const struct command *command, enum cmd_state state) 
560 {
561   return ((state == CMD_STATE_INITIAL && command->states & S_INITIAL)
562           || (state == CMD_STATE_DATA && command->states & S_DATA)
563           || (state == CMD_STATE_INPUT_PROGRAM
564               && command->states & S_INPUT_PROGRAM)
565           || (state == CMD_STATE_FILE_TYPE && command->states & S_FILE_TYPE));
566 }
567
568 /* Emits an appropriate error message for trying to invoke
569    COMMAND in STATE. */
570 static bool
571 report_state_mismatch (const struct command *command, enum cmd_state state)
572 {
573   assert (!in_correct_state (command, state));
574   if (state == CMD_STATE_INITIAL || state == CMD_STATE_DATA)
575     {
576       const char *allowed[3];
577       int allowed_cnt;
578       char *s;
579
580       allowed_cnt = 0;
581       if (command->states & S_INITIAL)
582         allowed[allowed_cnt++] = _("before the active file has been defined");
583       else if (command->states & S_DATA)
584         allowed[allowed_cnt++] = _("after the active file has been defined");
585       if (command->states & S_INPUT_PROGRAM)
586         allowed[allowed_cnt++] = _("inside INPUT PROGRAM");
587       if (command->states & S_FILE_TYPE)
588         allowed[allowed_cnt++] = _("inside FILE TYPE");
589
590       if (allowed_cnt == 1)
591         s = xstrdup (allowed[0]);
592       else if (allowed_cnt == 2)
593         s = xasprintf (_("%s or %s"), allowed[0], allowed[1]);
594       else if (allowed_cnt == 3)
595         s = xasprintf (_("%s, %s, or %s"), allowed[0], allowed[1], allowed[2]);
596       else
597         abort ();
598
599       msg (SE, _("%s is allowed only %s."), command->name, s);
600
601       free (s);
602     }
603   else if (state == CMD_STATE_INPUT_PROGRAM)
604     msg (SE, _("%s is not allowed inside INPUT PROGRAM."), command->name);
605   else if (state == CMD_STATE_FILE_TYPE)
606     msg (SE, _("%s is not allowed inside FILE TYPE."), command->name);
607
608   return false;
609 }
610 \f
611 /* Command name completion. */
612
613 static enum cmd_state completion_state = CMD_STATE_INITIAL;
614
615 static void
616 set_completion_state (enum cmd_state state) 
617 {
618   completion_state = state;
619 }
620
621 /* Returns the next possible completion of a command name that
622    begins with PREFIX, in the current command state, or a null
623    pointer if no completions remain.
624    Before calling the first time, set *CMD to a null pointer. */
625 const char *
626 cmd_complete (const char *prefix, const struct command **cmd)
627 {
628   if (*cmd == NULL)
629     *cmd = commands;
630
631   for (; *cmd < commands + command_cnt; (*cmd)++) 
632     if (!memcasecmp ((*cmd)->name, prefix, strlen (prefix))
633         && (!((*cmd)->flags & F_TESTING) || get_testing_mode ())
634         && (!((*cmd)->flags & F_ENHANCED) || get_syntax () == ENHANCED)
635         && ((*cmd)->function != NULL)
636         && in_correct_state (*cmd, completion_state))
637       return (*cmd)++->name;
638
639   return NULL;
640 }
641 \f
642 /* Simple commands. */
643
644 /* Parse and execute FINISH command. */
645 int
646 cmd_finish (void)
647 {
648   return CMD_FINISH;
649 }
650
651 /* Parses the N command. */
652 int
653 cmd_n_of_cases (void)
654 {
655   /* Value for N. */
656   int x;
657
658   if (!lex_force_int ())
659     return CMD_FAILURE;
660   x = lex_integer ();
661   lex_get ();
662   if (!lex_match_id ("ESTIMATED"))
663     dict_set_case_limit (default_dict, x);
664
665   return lex_end_of_command ();
666 }
667
668 /* Parses, performs the EXECUTE procedure. */
669 int
670 cmd_execute (void)
671 {
672   if (!procedure (NULL, NULL))
673     return CMD_CASCADING_FAILURE;
674   return lex_end_of_command ();
675 }
676
677 /* Parses, performs the ERASE command. */
678 int
679 cmd_erase (void)
680 {
681   if (get_safer_mode ()) 
682     { 
683       msg (SE, _("This command not allowed when the SAFER option is set.")); 
684       return CMD_FAILURE; 
685     } 
686   
687   if (!lex_force_match_id ("FILE"))
688     return CMD_FAILURE;
689   lex_match ('=');
690   if (!lex_force_string ())
691     return CMD_FAILURE;
692
693   if (remove (ds_cstr (&tokstr)) == -1)
694     {
695       msg (SW, _("Error removing `%s': %s."),
696            ds_cstr (&tokstr), strerror (errno));
697       return CMD_FAILURE;
698     }
699
700   return CMD_SUCCESS;
701 }
702
703 #ifdef unix
704 /* Spawn a shell process. */
705 static int
706 shell (void)
707 {
708   int pid;
709   
710   pid = fork ();
711   switch (pid)
712     {
713     case 0:
714       {
715         const char *shell_fn;
716         char *shell_process;
717         
718         {
719           int i;
720           
721           for (i = 3; i < 20; i++)
722             close (i);
723         }
724
725         shell_fn = getenv ("SHELL");
726         if (shell_fn == NULL)
727           shell_fn = "/bin/sh";
728         
729         {
730           const char *cp = strrchr (shell_fn, '/');
731           cp = cp ? &cp[1] : shell_fn;
732           shell_process = local_alloc (strlen (cp) + 8);
733           strcpy (shell_process, "-");
734           strcat (shell_process, cp);
735           if (strcmp (cp, "sh"))
736             shell_process[0] = '+';
737         }
738         
739         execl (shell_fn, shell_process, NULL);
740
741         _exit (1);
742       }
743
744     case -1:
745       msg (SE, _("Couldn't fork: %s."), strerror (errno));
746       return 0;
747
748     default:
749       assert (pid > 0);
750       while (wait (NULL) != pid)
751         ;
752       return 1;
753     }
754 }
755 #endif /* unix */
756
757 /* Parses the HOST command argument and executes the specified
758    command.  Returns a suitable command return code. */
759 static int
760 run_command (void)
761 {
762   const char *cmd;
763   int string;
764
765   /* Handle either a string argument or a full-line argument. */
766   {
767     int c = lex_look_ahead ();
768
769     if (c == '\'' || c == '"')
770       {
771         lex_get ();
772         if (!lex_force_string ())
773           return CMD_FAILURE;
774         cmd = ds_cstr (&tokstr);
775         string = 1;
776       }
777     else
778       {
779         cmd = lex_rest_of_line (NULL);
780         lex_discard_line ();
781         string = 0;
782       }
783   }
784
785   /* Execute the command. */
786   if (system (cmd) == -1)
787     msg (SE, _("Error executing command: %s."), strerror (errno));
788
789   /* Finish parsing. */
790   if (string)
791     {
792       lex_get ();
793
794       if (token != '.')
795         {
796           lex_error (_("expecting end of command"));
797           return CMD_FAILURE;
798         }
799     }
800   else
801     token = '.';
802
803   return CMD_SUCCESS;
804 }
805
806 /* Parses, performs the HOST command. */
807 int
808 cmd_host (void)
809 {
810   int code;
811
812   if (get_safer_mode ()) 
813     { 
814       msg (SE, _("This command not allowed when the SAFER option is set.")); 
815       return CMD_FAILURE; 
816     } 
817
818 #ifdef unix
819   /* Figure out whether to invoke an interactive shell or to execute a
820      single shell command. */
821   if (lex_look_ahead () == '.')
822     {
823       lex_get ();
824       code = shell () ? CMD_FAILURE : CMD_SUCCESS;
825     }
826   else
827     code = run_command ();
828 #else /* !unix */
829   /* Make sure that the system has a command interpreter, then run a
830      command. */
831   if (system (NULL) != 0)
832     code = run_command ();
833   else
834     {
835       msg (SE, _("No operating system support for this command."));
836       code = CMD_FAILURE;
837     }
838 #endif /* !unix */
839
840   return code;
841 }
842
843 /* Parses, performs the NEW FILE command. */
844 int
845 cmd_new_file (void)
846 {
847   discard_variables ();
848
849   return lex_end_of_command ();
850 }
851
852 /* Parses a comment. */
853 int
854 cmd_comment (void)
855 {
856   lex_skip_comment ();
857   return CMD_SUCCESS;
858 }