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