treewide: Replace <name>_cnt by n_<name>s and <name>_cap by allocated_<name>.
[pspp] / src / language / command.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU 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, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18
19 #include "language/command.h"
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <ctype.h>
24 #include <errno.h>
25
26 #include "data/casereader.h"
27 #include "data/dataset.h"
28 #include "data/dictionary.h"
29 #include "data/session.h"
30 #include "data/settings.h"
31 #include "data/variable.h"
32 #include "language/lexer/command-name.h"
33 #include "language/lexer/lexer.h"
34 #include "libpspp/assertion.h"
35 #include "libpspp/compiler.h"
36 #include "libpspp/i18n.h"
37 #include "libpspp/message.h"
38 #include "libpspp/str.h"
39 #include "output/driver.h"
40 #include "output/output-item.h"
41
42 #include "xmalloca.h"
43
44 #include "gettext.h"
45 #define _(msgid) gettext (msgid)
46 #define N_(msgid) msgid
47 \f
48 /* Returns true if RESULT is a valid "enum cmd_result",
49    false otherwise. */
50 static inline bool
51 cmd_result_is_valid (enum cmd_result result)
52 {
53   switch (result)
54     {
55     case CMD_SUCCESS:
56     case CMD_EOF:
57     case CMD_FINISH:
58     case CMD_DATA_LIST:
59     case CMD_END_CASE:
60     case CMD_END_FILE:
61     case CMD_FAILURE:
62     case CMD_NOT_IMPLEMENTED:
63     case CMD_CASCADING_FAILURE:
64       return true;
65
66     default:
67       return false;
68     }
69 }
70
71 /* Returns true if RESULT indicates success,
72    false otherwise. */
73 bool
74 cmd_result_is_success (enum cmd_result result)
75 {
76   assert (cmd_result_is_valid (result));
77   return result > 0;
78 }
79
80 /* Returns true if RESULT indicates failure,
81    false otherwise. */
82 bool
83 cmd_result_is_failure (enum cmd_result result)
84 {
85   assert (cmd_result_is_valid (result));
86   return result < 0;
87 }
88 \f
89 /* Command processing states. */
90 enum states
91   {
92     S_INITIAL = 0x01,         /* Allowed before active dataset defined. */
93     S_DATA = 0x02,            /* Allowed after active dataset defined. */
94     S_INPUT_PROGRAM = 0x04,   /* Allowed in INPUT PROGRAM. */
95     S_FILE_TYPE = 0x08,       /* Allowed in FILE TYPE. */
96     S_ANY = 0x0f              /* Allowed anywhere. */
97   };
98
99 /* Other command requirements. */
100 enum flags
101   {
102     F_ENHANCED = 0x10,        /* Allowed only in enhanced syntax mode. */
103     F_TESTING = 0x20,         /* Allowed only in testing mode. */
104     F_ABBREV = 0x80           /* Not a candidate for name completion. */
105   };
106
107 /* A single command. */
108 struct command
109   {
110     enum states states;         /* States in which command is allowed. */
111     enum flags flags;           /* Other command requirements. */
112     const char *name;           /* Command name. */
113     int (*function) (struct lexer *, struct dataset *); /* Function to call. */
114   };
115
116 /* Define the command array. */
117 #define DEF_CMD(STATES, FLAGS, NAME, FUNCTION) {STATES, FLAGS, NAME, FUNCTION},
118 #define UNIMPL_CMD(NAME, DESCRIPTION) {S_ANY, 0, NAME, NULL},
119 static const struct command commands[] =
120   {
121 #include "command.def"
122   };
123 #undef DEF_CMD
124 #undef UNIMPL_CMD
125
126 static const size_t n_commands = sizeof commands / sizeof *commands;
127
128 static bool in_correct_state (const struct command *, enum cmd_state);
129 static bool report_state_mismatch (const struct command *, enum cmd_state);
130 static void set_completion_state (enum cmd_state);
131 \f
132 /* Command parser. */
133
134 static const struct command *parse_command_name (struct lexer *,
135                                                  int *n_tokens);
136 static enum cmd_result do_parse_command (struct lexer *, struct dataset *, enum cmd_state);
137
138 /* Parses an entire command, from command name to terminating
139    dot.  On failure, skips to the terminating dot.
140    Returns the command's success or failure result. */
141 enum cmd_result
142 cmd_parse_in_state (struct lexer *lexer, struct dataset *ds,
143                     enum cmd_state state)
144 {
145   struct session *session = dataset_session (ds);
146   int result;
147
148   result = do_parse_command (lexer, ds, state);
149
150   ds = session_active_dataset (session);
151   assert (!proc_is_open (ds));
152   unset_cmd_algorithm ();
153   if (!dataset_end_of_command (ds))
154     result = CMD_CASCADING_FAILURE;
155
156   return result;
157 }
158
159 enum cmd_result
160 cmd_parse (struct lexer *lexer, struct dataset *ds)
161 {
162   const struct dictionary *dict = dataset_dict (ds);
163   return cmd_parse_in_state (lexer, ds,
164                              dataset_has_source (ds) &&
165                              dict_get_n_vars (dict) > 0 ?
166                              CMD_STATE_DATA : CMD_STATE_INITIAL);
167 }
168
169
170 /* Parses an entire command, from command name to terminating
171    dot. */
172 static enum cmd_result
173 do_parse_command (struct lexer *lexer,
174                   struct dataset *ds, enum cmd_state state)
175 {
176   const struct command *command = NULL;
177   size_t nesting_level = SIZE_MAX;
178   enum cmd_result result;
179   int n_tokens;
180
181   /* Read the command's first token. */
182   set_completion_state (state);
183   if (lex_token (lexer) == T_STOP)
184     {
185       result = CMD_EOF;
186       goto finish;
187     }
188   else if (lex_token (lexer) == T_ENDCMD)
189     {
190       /* Null commands can result from extra empty lines. */
191       result = CMD_SUCCESS;
192       goto finish;
193     }
194
195   /* Parse the command name. */
196   command = parse_command_name (lexer, &n_tokens);
197   if (command == NULL)
198     {
199       result = CMD_FAILURE;
200       goto finish;
201     }
202
203   nesting_level = output_open_group (group_item_create_nocopy (
204                                        utf8_to_title (command->name),
205                                        utf8_to_title (command->name)));
206
207   if (command->function == NULL)
208     {
209       msg (SE, _("%s is not yet implemented."), command->name);
210       result = CMD_NOT_IMPLEMENTED;
211     }
212   else if ((command->flags & F_TESTING) && !settings_get_testing_mode ())
213     {
214       msg (SE, _("%s may be used only in testing mode."), command->name);
215       result = CMD_FAILURE;
216     }
217   else if ((command->flags & F_ENHANCED) && settings_get_syntax () != ENHANCED)
218     {
219       msg (SE, _("%s may be used only in enhanced syntax mode."),
220            command->name);
221       result = CMD_FAILURE;
222     }
223   else if (!in_correct_state (command, state))
224     {
225       report_state_mismatch (command, state);
226       result = CMD_FAILURE;
227     }
228   else
229     {
230       /* Execute command. */
231       int i;
232
233       for (i = 0; i < n_tokens; i++)
234         lex_get (lexer);
235       result = command->function (lexer, ds);
236     }
237
238   assert (cmd_result_is_valid (result));
239
240 finish:
241   if (cmd_result_is_failure (result))
242     lex_interactive_reset (lexer);
243   else if (result == CMD_SUCCESS)
244     result = lex_end_of_command (lexer);
245
246   lex_discard_rest_of_command (lexer);
247   if (result != CMD_EOF && result != CMD_FINISH)
248     while (lex_token (lexer) == T_ENDCMD)
249       lex_get (lexer);
250
251   if (nesting_level != SIZE_MAX)
252     output_close_groups (nesting_level);
253
254   return result;
255 }
256
257 static int
258 find_best_match (struct substring s, const struct command **matchp)
259 {
260   const struct command *cmd;
261   struct command_matcher cm;
262   int missing_words;
263
264   command_matcher_init (&cm, s);
265   for (cmd = commands; cmd < &commands[n_commands]; cmd++)
266     command_matcher_add (&cm, ss_cstr (cmd->name), CONST_CAST (void *, cmd));
267
268   *matchp = command_matcher_get_match (&cm);
269   missing_words = command_matcher_get_missing_words (&cm);
270
271   command_matcher_destroy (&cm);
272
273   return missing_words;
274 }
275
276 static bool
277 parse_command_word (struct lexer *lexer, struct string *s, int n)
278 {
279   bool need_space = ds_last (s) != EOF && ds_last (s) != '-';
280
281   switch (lex_next_token (lexer, n))
282     {
283     case T_DASH:
284       ds_put_byte (s, '-');
285       return true;
286
287     case T_ID:
288       if (need_space)
289         ds_put_byte (s, ' ');
290       ds_put_cstr (s, lex_next_tokcstr (lexer, n));
291       return true;
292
293     case T_POS_NUM:
294       if (lex_next_is_integer (lexer, n))
295         {
296           int integer = lex_next_integer (lexer, n);
297           if (integer >= 0)
298             {
299               if (need_space)
300                 ds_put_byte (s, ' ');
301               ds_put_format (s, "%ld", lex_next_integer (lexer, n));
302               return true;
303             }
304         }
305       return false;
306
307     default:
308       return false;
309     }
310 }
311
312 /* Parses the command name.  On success returns a pointer to the corresponding
313    struct command and stores the number of tokens in the command name into
314    *N_TOKENS.  On failure, returns a null pointer and stores the number of
315    tokens required to determine that no command name was present into
316    *N_TOKENS. */
317 static const struct command *
318 parse_command_name (struct lexer *lexer, int *n_tokens)
319 {
320   const struct command *command;
321   int missing_words;
322   struct string s;
323   int word;
324
325   command = NULL;
326   missing_words = 0;
327   ds_init_empty (&s);
328   word = 0;
329   while (parse_command_word (lexer, &s, word))
330     {
331       missing_words = find_best_match (ds_ss (&s), &command);
332       if (missing_words <= 0)
333         break;
334       word++;
335     }
336
337   if (command == NULL && missing_words > 0)
338     {
339       ds_put_cstr (&s, " .");
340       missing_words = find_best_match (ds_ss (&s), &command);
341       ds_truncate (&s, ds_length (&s) - 2);
342     }
343
344   if (command == NULL)
345     {
346       if (ds_is_empty (&s))
347         lex_error (lexer, _("expecting command name"));
348       else
349         msg (SE, _("Unknown command `%s'."), ds_cstr (&s));
350     }
351
352   ds_destroy (&s);
353
354   *n_tokens = (word + 1) + missing_words;
355   return command;
356 }
357
358 /* Returns true if COMMAND is allowed in STATE,
359    false otherwise. */
360 static bool
361 in_correct_state (const struct command *command, enum cmd_state state)
362 {
363   return ((state == CMD_STATE_INITIAL && command->states & S_INITIAL)
364           || (state == CMD_STATE_DATA && command->states & S_DATA)
365           || (state == CMD_STATE_INPUT_PROGRAM
366               && command->states & S_INPUT_PROGRAM)
367           || (state == CMD_STATE_FILE_TYPE && command->states & S_FILE_TYPE));
368 }
369
370 /* Emits an appropriate error message for trying to invoke
371    COMMAND in STATE. */
372 static bool
373 report_state_mismatch (const struct command *command, enum cmd_state state)
374 {
375   assert (!in_correct_state (command, state));
376   if (state == CMD_STATE_INITIAL || state == CMD_STATE_DATA)
377     {
378       switch ((int) command->states)
379         {
380           /* One allowed state. */
381         case S_INITIAL:
382           msg (SE, _("%s is allowed only before the active dataset has "
383                      "been defined."), command->name);
384           break;
385         case S_DATA:
386           msg (SE, _("%s is allowed only after the active dataset has "
387                      "been defined."), command->name);
388           break;
389         case S_INPUT_PROGRAM:
390           msg (SE, _("%s is allowed only inside %s."),
391                command->name, "INPUT PROGRAM");
392           break;
393         case S_FILE_TYPE:
394           msg (SE, _("%s is allowed only inside %s."), command->name, "FILE TYPE");
395           break;
396
397           /* Two allowed states. */
398         case S_INITIAL | S_DATA:
399           NOT_REACHED ();
400         case S_INITIAL | S_INPUT_PROGRAM:
401           msg (SE, _("%s is allowed only before the active dataset has been defined or inside %s."),
402                command->name, "INPUT PROGRAM");
403           break;
404         case S_INITIAL | S_FILE_TYPE:
405           msg (SE, _("%s is allowed only before the active dataset has been defined or inside %s."),
406                command->name, "FILE TYPE");
407           break;
408         case S_DATA | S_INPUT_PROGRAM:
409           msg (SE, _("%s is allowed only after the active dataset has been defined or inside %s."),
410                command->name, "INPUT PROGRAM");
411           break;
412         case S_DATA | S_FILE_TYPE:
413           msg (SE, _("%s is allowed only after the active dataset has been defined or inside %s."),
414                command->name, "FILE TYPE");
415           break;
416         case S_INPUT_PROGRAM | S_FILE_TYPE:
417           msg (SE, _("%s is allowed only inside %s or inside %s."), command->name,
418                "INPUT PROGRAM", "FILE TYPE");
419           break;
420
421           /* Three allowed states. */
422         case S_DATA | S_INPUT_PROGRAM | S_FILE_TYPE:
423           msg (SE, _("%s is allowed only after the active dataset has "
424                      "been defined, inside INPUT PROGRAM, or inside "
425                      "FILE TYPE."), command->name);
426           break;
427         case S_INITIAL | S_INPUT_PROGRAM | S_FILE_TYPE:
428           msg (SE, _("%s is allowed only before the active dataset has "
429                      "been defined, inside INPUT PROGRAM, or inside "
430                      "FILE TYPE."), command->name);
431           break;
432         case S_INITIAL | S_DATA | S_FILE_TYPE:
433           NOT_REACHED ();
434         case S_INITIAL | S_DATA | S_INPUT_PROGRAM:
435           NOT_REACHED ();
436
437           /* Four allowed states. */
438         case S_INITIAL | S_DATA | S_INPUT_PROGRAM | S_FILE_TYPE:
439           NOT_REACHED ();
440
441         default:
442           NOT_REACHED ();
443         }
444     }
445   else if (state == CMD_STATE_INPUT_PROGRAM)
446     msg (SE, _("%s is not allowed inside %s."),
447          command->name, "INPUT PROGRAM");
448   else if (state == CMD_STATE_FILE_TYPE)
449     msg (SE, _("%s is not allowed inside %s."), command->name, "FILE TYPE");
450
451   return false;
452 }
453 \f
454 /* Command name completion. */
455
456 static enum cmd_state completion_state = CMD_STATE_INITIAL;
457
458 static void
459 set_completion_state (enum cmd_state state)
460 {
461   completion_state = state;
462 }
463
464 /* Returns the next possible completion of a command name that
465    begins with PREFIX, in the current command state, or a null
466    pointer if no completions remain.
467    Before calling the first time, set *CMD to a null pointer. */
468 const char *
469 cmd_complete (const char *prefix, const struct command **cmd)
470 {
471   if (*cmd == NULL)
472     *cmd = commands;
473
474   for (; *cmd < commands + n_commands; (*cmd)++)
475     if (!memcasecmp ((*cmd)->name, prefix, strlen (prefix))
476         && (!((*cmd)->flags & F_TESTING) || settings_get_testing_mode ())
477         && (!((*cmd)->flags & F_ENHANCED) || settings_get_syntax () == ENHANCED)
478         && !((*cmd)->flags & F_ABBREV)
479         && ((*cmd)->function != NULL)
480         && in_correct_state (*cmd, completion_state))
481       return (*cmd)++->name;
482
483   return NULL;
484 }
485 \f
486 /* Simple commands. */
487
488 /* Parse and execute FINISH command. */
489 int
490 cmd_finish (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
491 {
492   return CMD_FINISH;
493 }
494
495 /* Parses the N command. */
496 int
497 cmd_n_of_cases (struct lexer *lexer, struct dataset *ds)
498 {
499   if (!lex_force_int_range (lexer, "N OF CASES", 1, LONG_MAX))
500     return CMD_FAILURE;
501   long n = lex_integer (lexer);
502   lex_get (lexer);
503   if (!lex_match_id (lexer, "ESTIMATED"))
504     dict_set_case_limit (dataset_dict (ds), n);
505
506   return CMD_SUCCESS;
507 }
508
509 /* Parses, performs the EXECUTE procedure. */
510 int
511 cmd_execute (struct lexer *lexer UNUSED, struct dataset *ds)
512 {
513   bool ok = casereader_destroy (proc_open (ds));
514   if (!proc_commit (ds) || !ok)
515     return CMD_CASCADING_FAILURE;
516   return CMD_SUCCESS;
517 }
518
519 /* Parses, performs the ERASE command. */
520 int
521 cmd_erase (struct lexer *lexer, struct dataset *ds UNUSED)
522 {
523   char *filename;
524   int retval;
525
526   if (settings_get_safer_mode ())
527     {
528       msg (SE, _("This command not allowed when the %s option is set."), "SAFER");
529       return CMD_FAILURE;
530     }
531
532   if (!lex_force_match_id (lexer, "FILE"))
533     return CMD_FAILURE;
534   lex_match (lexer, T_EQUALS);
535   if (!lex_force_string (lexer))
536     return CMD_FAILURE;
537
538   filename = utf8_to_filename (lex_tokcstr (lexer));
539   retval = remove (filename);
540   free (filename);
541
542   if (retval == -1)
543     {
544       msg (SW, _("Error removing `%s': %s."),
545            lex_tokcstr (lexer), strerror (errno));
546       return CMD_FAILURE;
547     }
548   lex_get (lexer);
549
550   return CMD_SUCCESS;
551 }
552
553 /* Parses, performs the NEW FILE command. */
554 int
555 cmd_new_file (struct lexer *lexer UNUSED, struct dataset *ds)
556 {
557   dataset_clear (ds);
558   return CMD_SUCCESS;
559 }