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