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