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