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