de77be80e8f95596e67c291309590691b84b2377
[pspp-builds.git] / src / 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 #include "error.h"
22 #include "command.h"
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <ctype.h>
26 #include <errno.h>
27 #include "alloc.h"
28 #include "dictionary.h"
29 #include "error.h"
30 #include "glob.h"
31 #include "getline.h"
32 #include "lexer.h"
33 #include "main.h"
34 #include "settings.h"
35 #include "som.h"
36 #include "str.h"
37 #include "tab.h"
38 #include "var.h"
39 #include "vfm.h"
40
41 #if HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44
45 #if HAVE_SYS_WAIT_H
46 #include <sys/wait.h>
47 #endif
48 \f
49 /* Global variables. */
50
51 /* A STATE_* constant giving the current program state. */
52 int pgm_state;
53
54 /* The name of the procedure currently executing, if any. */
55 const char *cur_proc;
56 \f
57 /* Static variables. */
58
59 /* A single command. */
60 struct command
61   {
62     const char *name;           /* Command name. */
63     int transition[4];          /* Transitions to make from each state. */
64     int (*func) (void);         /* Function to call. */
65     int skip_entire_name;       /* If zero, we don't skip the
66                                    final token in the command name. */
67     short debug;                /* Set if this cmd available only in test mode*/
68   };
69
70 /* Define the command array. */
71 #define DEFCMD(NAME, T1, T2, T3, T4, FUNC)              \
72         {NAME, {T1, T2, T3, T4}, FUNC, 1, 0},
73 #define DBGCMD(NAME, T1, T2, T3, T4, FUNC)              \
74         {NAME, {T1, T2, T3, T4}, FUNC, 1, 1},
75 #define SPCCMD(NAME, T1, T2, T3, T4, FUNC)              \
76         {NAME, {T1, T2, T3, T4}, FUNC, 0, 0},
77 #define UNIMPL(NAME, T1, T2, T3, T4, DESC)              \
78         {NAME, {T1, T2, T3, T4}, NULL, 1, 0},
79 static const struct command commands[] = 
80   {
81 #include "command.def"
82   };
83 #undef DEFCMD
84 #undef DBGCMD
85 #undef UNIMPL
86
87
88 /* Complete the line using the name of a command, 
89  * based upon the current prg_state
90  */
91 char * 
92 pspp_completion_function (const char *text,   int state)
93 {
94   static int skip=0;
95   const struct command *cmd = 0;
96   
97   for(;;)
98     {
99       if ( state + skip >= sizeof(commands)/ sizeof(struct command))
100         {
101           skip = 0;
102           return 0;
103         }
104
105       cmd = &commands[state + skip];
106   
107       if ( cmd->transition[pgm_state] == STATE_ERROR || ( cmd->debug  &&  ! test_mode ) ) 
108         {
109           skip++; 
110           continue;
111         }
112       
113       if ( text == 0 || 0 == strncasecmp (cmd->name, text, strlen(text)))
114         {
115           break;
116         }
117
118       skip++;
119     }
120   
121
122   return xstrdup(cmd->name);
123
124 }
125
126
127
128 #define COMMAND_CNT (sizeof commands / sizeof *commands)
129 \f
130 /* Command parser. */
131
132 static const struct command *parse_command_name (void);
133
134 /* Determines whether command C is appropriate to call in this
135    part of a FILE TYPE structure. */
136 static int
137 FILE_TYPE_okay (const struct command *c UNUSED)
138 #if 0
139 {
140   int okay = 0;
141   
142   if (c->func != cmd_record_type
143       && c->func != cmd_data_list
144       && c->func != cmd_repeating_data
145       && c->func != cmd_end_file_type)
146     msg (SE, _("%s not allowed inside FILE TYPE/END FILE TYPE."), c->name);
147   /* FIXME */
148   else if (c->func == cmd_repeating_data && fty.type == FTY_GROUPED)
149     msg (SE, _("%s not allowed inside FILE TYPE GROUPED/END FILE TYPE."),
150          c->name);
151   else if (!fty.had_rec_type && c->func != cmd_record_type)
152     msg (SE, _("RECORD TYPE must be the first command inside a "
153                       "FILE TYPE structure."));
154   else
155     okay = 1;
156
157   if (c->func == cmd_record_type)
158     fty.had_rec_type = 1;
159
160   return okay;
161 }
162 #else
163 {
164   return 1;
165 }
166 #endif
167
168 /* Parses an entire PSPP command.  This includes everything from the
169    command name to the terminating dot.  Does most of its work by
170    passing it off to the respective command dispatchers.  Only called
171    by parse() in main.c. */
172 int
173 cmd_parse (void)
174 {
175   const struct command *cp;     /* Iterator used to find the proper command. */
176
177 #if C_ALLOCA
178   /* The generic alloca package performs garbage collection when it is
179      called with an argument of zero. */
180   alloca (0);
181 #endif /* C_ALLOCA */
182
183   /* Null commands can result from extra empty lines. */
184   if (token == '.')
185     return CMD_SUCCESS;
186
187   /* Parse comments. */
188   if ((token == T_ID && !strcasecmp (tokid, "COMMENT"))
189       || token == T_EXP || token == '*' || token == '[')
190     {
191       lex_skip_comment ();
192       return CMD_SUCCESS;
193     }
194
195   /* Otherwise the line must begin with a command name, which is
196      always an ID token. */
197   if (token != T_ID)
198     {
199       lex_error (_("expecting command name"));
200       return CMD_FAILURE;
201     }
202
203   /* Parse the command name. */
204   cp = parse_command_name ();
205   if (cp == NULL)
206     return CMD_FAILURE;
207   if (cp->func == NULL)
208     {
209       msg (SE, _("%s is not yet implemented."), cp->name);
210       while (token && token != '.')
211         lex_get ();
212       return CMD_SUCCESS;
213     }
214
215   /* If we're in a FILE TYPE structure, only certain commands can be
216      allowed. */
217   if (pgm_state == STATE_INPUT
218       && case_source_is_class (vfm_source, &file_type_source_class)
219       && !FILE_TYPE_okay (cp))
220     return CMD_FAILURE;
221
222   /* Certain state transitions are not allowed.  Check for these. */
223   assert (pgm_state >= 0 && pgm_state < STATE_ERROR);
224   if (cp->transition[pgm_state] == STATE_ERROR)
225     {
226       static const char *state_name[4] =
227       {
228         N_("%s is not allowed (1) before a command to specify the "
229            "input program, such as DATA LIST, (2) between FILE TYPE "
230            "and END FILE TYPE, (3) between INPUT PROGRAM and END "
231            "INPUT PROGRAM."),
232         N_("%s is not allowed within an input program."),
233         N_("%s is only allowed within an input program."),
234         N_("%s is only allowed within an input program."),
235       };
236
237       msg (SE, gettext (state_name[pgm_state]), cp->name);
238       return CMD_FAILURE;
239     }
240
241   /* The structured output manager numbers all its tables.  Increment
242      the major table number for each separate procedure. */
243   som_new_series ();
244   
245   {
246     int result;
247     
248     /* Call the command dispatcher.  Save and restore the name of
249        the current command around this call. */
250     {
251       const char *prev_proc;
252       
253       prev_proc = cur_proc;
254       cur_proc = cp->name;
255       result = cp->func ();
256       cur_proc = prev_proc;
257     }
258     
259     /* Perform the state transition if the command completed
260        successfully (at least in part). */
261     if (result != CMD_FAILURE)
262       {
263         pgm_state = cp->transition[pgm_state];
264
265         if (pgm_state == STATE_ERROR)
266           {
267             discard_variables ();
268             pgm_state = STATE_INIT;
269           }
270       }
271
272     /* Pass the command's success value up to the caller. */
273     return result;
274   }
275 }
276
277 static size_t
278 match_strings (const char *a, size_t a_len,
279                const char *b, size_t b_len) 
280 {
281   size_t match_len = 0;
282   
283   while (a_len > 0 && b_len > 0) 
284     {
285       /* Mismatch always returns zero. */
286       if (toupper ((unsigned char) *a++) != toupper ((unsigned char) *b++))
287         return 0;
288
289       /* Advance. */
290       a_len--;
291       b_len--;
292       match_len++;
293     }
294
295   return match_len;
296 }
297
298 /* Returns the first character in the first word in STRING,
299    storing the word's length in *WORD_LEN.  If no words remain,
300    returns a null pointer and stores 0 in *WORD_LEN.  Words are
301    sequences of alphanumeric characters or single
302    non-alphanumeric characters.  Words are delimited by
303    spaces. */
304 static const char *
305 find_word (const char *string, size_t *word_len) 
306 {
307   /* Skip whitespace and asterisks. */
308   while (isspace ((unsigned char) *string))
309     string++;
310
311   /* End of string? */
312   if (*string == '\0') 
313     {
314       *word_len = 0;
315       return NULL;
316     }
317
318   /* Special one-character word? */
319   if (!isalnum ((unsigned char) *string)) 
320     {
321       *word_len = 1;
322       return string;
323     }
324
325   /* Alphanumeric word. */
326   *word_len = 1;
327   while (isalnum ((unsigned char) string[*word_len]))
328     (*word_len)++;
329
330   return string;
331 }
332
333 /* Returns nonzero if strings A and B can be confused based on
334    their first three letters. */
335 static int
336 conflicting_3char_prefixes (const char *a, const char *b) 
337 {
338   size_t aw_len, bw_len;
339   const char *aw, *bw;
340
341   aw = find_word (a, &aw_len);
342   bw = find_word (b, &bw_len);
343   assert (aw != NULL && bw != NULL);
344
345   /* Words that are the same don't conflict. */
346   if (aw_len == bw_len && !buf_compare_case (aw, bw, aw_len))
347     return 0;
348   
349   /* Words that are otherwise the same in the first three letters
350      do conflict. */
351   return ((aw_len > 3 && bw_len > 3)
352           || (aw_len == 3 && bw_len > 3)
353           || (bw_len == 3 && aw_len > 3)) && !buf_compare_case (aw, bw, 3);
354 }
355
356 /* Returns nonzero if CMD can be confused with another command
357    based on the first three letters of its first word. */
358 static int
359 conflicting_3char_prefix_command (const struct command *cmd) 
360 {
361   assert (cmd >= commands && cmd < commands + COMMAND_CNT);
362
363   return ((cmd > commands
364            && conflicting_3char_prefixes (cmd[-1].name, cmd[0].name))
365           || (cmd < commands + COMMAND_CNT
366               && conflicting_3char_prefixes (cmd[0].name, cmd[1].name)));
367 }
368
369 /* Ways that a set of words can match a command name. */
370 enum command_match
371   {
372     MISMATCH,           /* Not a match. */
373     PARTIAL_MATCH,      /* The words begin the command name. */
374     COMPLETE_MATCH      /* The words are the command name. */
375   };
376
377 /* Figures out how well the WORD_CNT words in WORDS match CMD,
378    and returns the appropriate enum value.  If WORDS are a
379    partial match for CMD and the next word in CMD is a dash, then
380    *DASH_POSSIBLE is set to 1 if DASH_POSSIBLE is non-null;
381    otherwise, *DASH_POSSIBLE is unchanged. */
382 static enum command_match
383 cmd_match_words (const struct command *cmd,
384                  char *const words[], size_t word_cnt,
385                  int *dash_possible)
386 {
387   const char *word;
388   size_t word_len;
389   size_t word_idx;
390
391   for (word = find_word (cmd->name, &word_len), word_idx = 0;
392        word != NULL && word_idx < word_cnt;
393        word = find_word (word + word_len, &word_len), word_idx++)
394     if (word_len != strlen (words[word_idx])
395         || buf_compare_case (word, words[word_idx], word_len))
396       {
397         size_t match_chars = match_strings (word, word_len,
398                                             words[word_idx],
399                                             strlen (words[word_idx]));
400         if (match_chars == 0) 
401           {
402             /* Mismatch. */
403             return MISMATCH;
404           }
405         else if (match_chars == 1 || match_chars == 2) 
406           {
407             /* One- and two-character abbreviations are not
408                acceptable. */
409             return MISMATCH; 
410           }
411         else if (match_chars == 3) 
412           {
413             /* Three-character abbreviations are acceptable
414                in the first word of a command if there are
415                no name conflicts.  They are always
416                acceptable after the first word. */
417             if (word_idx == 0 && conflicting_3char_prefix_command (cmd))
418               return MISMATCH;
419           }
420         else /* match_chars > 3 */ 
421           {
422             /* Four-character and longer abbreviations are
423                always acceptable.  */
424           }
425       }
426
427   if (word == NULL && word_idx == word_cnt) 
428     {
429       /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR"}. */
430       return COMPLETE_MATCH;
431     }
432   else if (word == NULL) 
433     {
434       /* cmd->name = "FOO BAR", words[] = {"FOO", "BAR", "BAZ"}. */
435       return MISMATCH; 
436     }
437   else 
438     {
439       /* cmd->name = "FOO BAR BAZ", words[] = {"FOO", "BAR"}. */
440       if (word[0] == '-' && dash_possible != NULL)
441         *dash_possible = 1;
442       return PARTIAL_MATCH; 
443     }
444 }
445
446 /* Returns the number of commands for which the WORD_CNT words in
447    WORDS are a partial or complete match.  If some partial match
448    has a dash as the next word, then *DASH_POSSIBLE is set to 1,
449    otherwise it is set to 0. */
450 static int
451 count_matching_commands (char *const words[], size_t word_cnt,
452                          int *dash_possible) 
453 {
454   const struct command *cmd;
455   int cmd_match_count;
456
457   cmd_match_count = 0;
458   *dash_possible = 0;
459   for (cmd = commands; cmd < commands + COMMAND_CNT; cmd++) 
460     if (cmd_match_words (cmd, words, word_cnt, dash_possible) != MISMATCH) 
461       cmd_match_count++; 
462
463   return cmd_match_count;
464 }
465
466 /* Returns the command for which the WORD_CNT words in WORDS are
467    a complete match.  Returns a null pointer if no such command
468    exists. */
469 static const struct command *
470 get_complete_match (char *const words[], size_t word_cnt) 
471 {
472   const struct command *cmd;
473   
474   for (cmd = commands; cmd < commands + COMMAND_CNT; cmd++) 
475     if (cmd_match_words (cmd, words, word_cnt, NULL) == COMPLETE_MATCH) 
476       return cmd; 
477   
478   return NULL;
479 }
480
481 /* Frees the WORD_CNT words in WORDS. */
482 static void
483 free_words (char *words[], size_t word_cnt) 
484 {
485   size_t idx;
486   
487   for (idx = 0; idx < word_cnt; idx++)
488     free (words[idx]);
489 }
490
491 /* Flags an error that the command whose name is given by the
492    WORD_CNT words in WORDS is unknown. */
493 static void
494 unknown_command_error (char *const words[], size_t word_cnt) 
495 {
496   size_t idx;
497   size_t words_len;
498   char *name, *cp;
499
500   words_len = 0;
501   for (idx = 0; idx < word_cnt; idx++)
502     words_len += strlen (words[idx]);
503
504   cp = name = xmalloc (words_len + word_cnt + 16);
505   for (idx = 0; idx < word_cnt; idx++) 
506     {
507       if (idx != 0)
508         *cp++ = ' ';
509       cp = stpcpy (cp, words[idx]);
510     }
511   *cp = '\0';
512
513   msg (SE, _("Unknown command %s."), name);
514
515   free (name);
516 }
517
518
519 /* Parse the command name and return a pointer to the corresponding
520    struct command if successful.
521    If not successful, return a null pointer. */
522 static const struct command *
523 parse_command_name (void)
524 {
525   char *words[16];
526   int word_cnt;
527   int complete_word_cnt;
528   int dash_possible;
529
530   dash_possible = 0;
531   word_cnt = complete_word_cnt = 0;
532   while (token == T_ID || (dash_possible && token == '-')) 
533     {
534       int cmd_match_cnt;
535       
536       assert (word_cnt < sizeof words / sizeof *words);
537       if (token == T_ID)
538         words[word_cnt++] = xstrdup (ds_c_str (&tokstr));
539       else
540         words[word_cnt++] = xstrdup ("-");
541
542       cmd_match_cnt = count_matching_commands (words, word_cnt,
543                                                &dash_possible);
544       if (cmd_match_cnt == 0) 
545         break;
546       else if (cmd_match_cnt == 1) 
547         {
548           const struct command *command = get_complete_match (words, word_cnt);
549           if (command != NULL) 
550             {
551               if (command->skip_entire_name)
552                 lex_get ();
553               if ( command->debug & !test_mode ) 
554                 goto error;
555               free_words (words, word_cnt);
556               return command;
557             }
558         }
559       else /* cmd_match_cnt > 1 */
560         {
561           /* Do we have a complete command name so far? */
562           if (get_complete_match (words, word_cnt) != NULL)
563             complete_word_cnt = word_cnt;
564         }
565       lex_get ();
566     }
567
568   /* If we saw a complete command name earlier, drop back to
569      it. */
570   if (complete_word_cnt) 
571     {
572       int pushback_word_cnt;
573       const struct command *command;
574
575       /* Get the command. */
576       command = get_complete_match (words, complete_word_cnt);
577       assert (command != NULL);
578
579       /* Figure out how many words we want to keep.
580          We normally want to swallow the entire command. */
581       pushback_word_cnt = complete_word_cnt + 1;
582       if (!command->skip_entire_name)
583         pushback_word_cnt--;
584       
585       /* FIXME: We only support one-token pushback. */
586       assert (pushback_word_cnt + 1 >= word_cnt);
587
588       while (word_cnt > pushback_word_cnt) 
589         {
590           word_cnt--;
591           if (strcmp (words[word_cnt], "-")) 
592             lex_put_back_id (words[word_cnt]);
593           else
594             lex_put_back ('-');
595           free (words[word_cnt]);
596         }
597
598       if ( command->debug && !test_mode ) 
599         goto error;
600
601       free_words (words, word_cnt);
602       return command;
603     }
604
605 error:
606   unknown_command_error (words, word_cnt);
607   free_words (words, word_cnt);
608   return NULL;
609 }
610 \f
611 /* Simple commands. */
612
613 /* Parse and execute EXIT command. */
614 int
615 cmd_exit (void)
616 {
617   if (getl_reading_script)
618     {
619       msg (SE, _("This command is not accepted in a syntax file.  "
620            "Instead, use FINISH to terminate a syntax file."));
621       lex_get ();
622     }
623   else
624     finished = 1;
625
626   return CMD_SUCCESS;
627 }
628
629 /* Parse and execute FINISH command. */
630 int
631 cmd_finish (void)
632 {
633   /* Do not check for `.'
634      Do not fetch any extra tokens. */
635   if (getl_interactive)
636     {
637       msg (SM, _("This command is not executed "
638            "in interactive mode.  Instead, PSPP drops "
639            "down to the command prompt.  Use EXIT if you really want "
640            "to quit."));
641       getl_close_all ();
642     }
643   else
644     finished = 1;
645
646   return CMD_SUCCESS;
647 }
648
649 /* Parses the N command. */
650 int
651 cmd_n_of_cases (void)
652 {
653   /* Value for N. */
654   int x;
655
656   if (!lex_force_int ())
657     return CMD_FAILURE;
658   x = lex_integer ();
659   lex_get ();
660   if (!lex_match_id ("ESTIMATED"))
661     dict_set_case_limit (default_dict, x);
662
663   return lex_end_of_command ();
664 }
665
666 /* Parses, performs the EXECUTE procedure. */
667 int
668 cmd_execute (void)
669 {
670   procedure (NULL, NULL);
671   return lex_end_of_command ();
672 }
673
674 /* Parses, performs the ERASE command. */
675 int
676 cmd_erase (void)
677 {
678   if ( safer_mode() ) 
679     { 
680       msg (SE, _("This command not allowed when the SAFER option is set.")); 
681       return CMD_FAILURE; 
682     } 
683   
684   if (!lex_force_match_id ("FILE"))
685     return CMD_FAILURE;
686   lex_match ('=');
687   if (!lex_force_string ())
688     return CMD_FAILURE;
689
690   if (remove (ds_c_str (&tokstr)) == -1)
691     {
692       msg (SW, _("Error removing `%s': %s."),
693            ds_c_str (&tokstr), strerror (errno));
694       return CMD_FAILURE;
695     }
696
697   return CMD_SUCCESS;
698 }
699
700 #ifdef unix
701 /* Spawn a shell process. */
702 static int
703 shell (void)
704 {
705   int pid;
706   
707   pid = fork ();
708   switch (pid)
709     {
710     case 0:
711       {
712         const char *shell_fn;
713         char *shell_process;
714         
715         {
716           int i;
717           
718           for (i = 3; i < 20; i++)
719             close (i);
720         }
721
722         shell_fn = getenv ("SHELL");
723         if (shell_fn == NULL)
724           shell_fn = "/bin/sh";
725         
726         {
727           const char *cp = strrchr (shell_fn, '/');
728           cp = cp ? &cp[1] : shell_fn;
729           shell_process = local_alloc (strlen (cp) + 8);
730           strcpy (shell_process, "-");
731           strcat (shell_process, cp);
732           if (strcmp (cp, "sh"))
733             shell_process[0] = '+';
734         }
735         
736         execl (shell_fn, shell_process, NULL);
737
738         err_hcf (1);
739       }
740
741     case -1:
742       msg (SE, _("Couldn't fork: %s."), strerror (errno));
743       return 0;
744
745     default:
746       assert (pid > 0);
747       while (wait (NULL) != pid)
748         ;
749       return 1;
750     }
751 }
752 #endif /* unix */
753
754 /* Parses the HOST command argument and executes the specified
755    command.  Returns a suitable command return code. */
756 static int
757 run_command (void)
758 {
759   const char *cmd;
760   int string;
761
762   /* Handle either a string argument or a full-line argument. */
763   {
764     int c = lex_look_ahead ();
765
766     if (c == '\'' || c == '"')
767       {
768         lex_get ();
769         if (!lex_force_string ())
770           return CMD_FAILURE;
771         cmd = ds_c_str (&tokstr);
772         string = 1;
773       }
774     else
775       {
776         cmd = lex_rest_of_line (NULL);
777         lex_discard_line ();
778         string = 0;
779       }
780   }
781
782   /* Execute the command. */
783   if (system (cmd) == -1)
784     msg (SE, _("Error executing command: %s."), strerror (errno));
785
786   /* Finish parsing. */
787   if (string)
788     {
789       lex_get ();
790
791       if (token != '.')
792         {
793           lex_error (_("expecting end of command"));
794           return CMD_TRAILING_GARBAGE;
795         }
796     }
797   else
798     token = '.';
799
800   return CMD_SUCCESS;
801 }
802
803 /* Parses, performs the HOST command. */
804 int
805 cmd_host (void)
806 {
807   int code;
808
809   if ( safer_mode() ) 
810     { 
811       msg (SE, _("This command not allowed when the SAFER option is set.")); 
812       return CMD_FAILURE; 
813     } 
814
815 #ifdef unix
816   /* Figure out whether to invoke an interactive shell or to execute a
817      single shell command. */
818   if (lex_look_ahead () == '.')
819     {
820       lex_get ();
821       code = shell () ? CMD_PART_SUCCESS_MAYBE : CMD_SUCCESS;
822     }
823   else
824     code = run_command ();
825 #else /* !unix */
826   /* Make sure that the system has a command interpreter, then run a
827      command. */
828   if (system (NULL) != 0)
829     code = run_command ();
830   else
831     {
832       msg (SE, _("No operating system support for this command."));
833       code = CMD_FAILURE;
834     }
835 #endif /* !unix */
836
837   return code ? CMD_FAILURE : CMD_SUCCESS;
838 }
839
840 /* Parses, performs the NEW FILE command. */
841 int
842 cmd_new_file (void)
843 {
844   discard_variables ();
845
846   return lex_end_of_command ();
847 }
848
849 /* Parses, performs the CLEAR TRANSFORMATIONS command. */
850 int
851 cmd_clear_transformations (void)
852 {
853   if (getl_reading_script)
854     {
855       msg (SW, _("This command is not valid in a syntax file."));
856       return CMD_FAILURE;
857     }
858
859   cancel_transformations ();
860   /* FIXME: what about variables created by transformations?
861      They need to be properly initialized. */
862
863   return CMD_SUCCESS;
864 }