Assorted improvements to diagnostics.
[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_FAILURE:
59     case CMD_NOT_IMPLEMENTED:
60     case CMD_CASCADING_FAILURE:
61       return true;
62
63     default:
64       return false;
65     }
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 = 1 << CMD_STATE_INITIAL,
90     S_DATA = 1 << CMD_STATE_DATA,
91     S_INPUT_PROGRAM = 1 << CMD_STATE_INPUT_PROGRAM,
92     S_FILE_TYPE = 1 << CMD_STATE_FILE_TYPE,
93     S_NESTED_DATA = 1 << CMD_STATE_NESTED_DATA,
94     S_NESTED_INPUT_PROGRAM = 1 << CMD_STATE_NESTED_INPUT_PROGRAM,
95
96     S_NESTED_ANY = S_NESTED_DATA | S_NESTED_INPUT_PROGRAM,
97     S_ANY = S_INITIAL | S_DATA | S_INPUT_PROGRAM | S_FILE_TYPE | S_NESTED_ANY,
98   };
99
100 /* Other command requirements. */
101 enum flags
102   {
103     F_ENHANCED = 1 << 0,        /* Allowed only in enhanced syntax mode. */
104     F_TESTING = 1 << 1,         /* Allowed only in testing mode. */
105     F_ABBREV = 1 << 2           /* Not a candidate for name completion. */
106   };
107
108 /* A single command. */
109 struct command
110   {
111     enum states states;         /* States in which command is allowed. */
112     enum flags flags;           /* Other command requirements. */
113     const char *name;           /* Command name. */
114     int (*function) (struct lexer *, struct dataset *); /* Function to call. */
115   };
116
117 /* Define the command array. */
118 #define DEF_CMD(STATES, FLAGS, NAME, FUNCTION) {STATES, FLAGS, NAME, FUNCTION},
119 #define UNIMPL_CMD(NAME, DESCRIPTION) {S_ANY, 0, NAME, NULL},
120 static const struct command commands[] =
121   {
122 #include "command.def"
123   };
124 #undef DEF_CMD
125 #undef UNIMPL_CMD
126
127 static const size_t n_commands = sizeof commands / sizeof *commands;
128
129 static bool in_correct_state (const struct command *, enum cmd_state);
130 static char *report_state_mismatch (const struct command *, enum cmd_state);
131 static void set_completion_state (enum cmd_state);
132 \f
133 /* Command parser. */
134
135 static const struct command *parse_command_name (struct lexer *,
136                                                  int *n_tokens);
137 static enum cmd_result do_parse_command (struct lexer *, struct dataset *, enum cmd_state);
138
139 /* Parses an entire command, from command name to terminating
140    dot.  On failure, skips to the terminating dot.
141    Returns the command's success or failure result. */
142 enum cmd_result
143 cmd_parse_in_state (struct lexer *lexer, struct dataset *ds,
144                     enum cmd_state state)
145 {
146   struct session *session = dataset_session (ds);
147   int result;
148
149   result = do_parse_command (lexer, ds, state);
150
151   ds = session_active_dataset (session);
152   assert (!proc_is_open (ds));
153   unset_cmd_algorithm ();
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                              dataset_has_source (ds) &&
166                              dict_get_n_vars (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,
175                   struct dataset *ds, enum cmd_state state)
176 {
177   const struct command *command = NULL;
178   size_t nesting_level = SIZE_MAX;
179   enum cmd_result result;
180   int n_tokens;
181
182   /* Read the command's first token. */
183   set_completion_state (state);
184   if (lex_token (lexer) == T_STOP)
185     {
186       result = CMD_EOF;
187       goto finish;
188     }
189   else if (lex_token (lexer) == T_ENDCMD)
190     {
191       /* Null commands can result from extra empty lines. */
192       result = CMD_SUCCESS;
193       goto finish;
194     }
195
196   /* Parse the command name. */
197   command = parse_command_name (lexer, &n_tokens);
198   if (command == NULL)
199     {
200       result = CMD_FAILURE;
201       goto finish;
202     }
203
204   nesting_level = output_open_group (group_item_create_nocopy (
205                                        utf8_to_title (command->name),
206                                        utf8_to_title (command->name)));
207
208   int end = n_tokens - 1;
209   if (command->function == NULL)
210     {
211       lex_ofs_error (lexer, 0, end, _("%s is not yet implemented."),
212                      command->name);
213       result = CMD_NOT_IMPLEMENTED;
214     }
215   else if ((command->flags & F_TESTING) && !settings_get_testing_mode ())
216     {
217       lex_ofs_error (lexer, 0, end, _("%s may be used only in testing mode."),
218                      command->name);
219       result = CMD_FAILURE;
220     }
221   else if ((command->flags & F_ENHANCED) && settings_get_syntax () != ENHANCED)
222     {
223       lex_ofs_error (lexer, 0, end,
224                      _("%s may be used only in enhanced syntax mode."),
225                      command->name);
226       result = CMD_FAILURE;
227     }
228   else if (!in_correct_state (command, state))
229     {
230       char *message = report_state_mismatch (command, state);
231       lex_ofs_error (lexer, 0, end, "%s", message);
232       free (message);
233
234       result = CMD_FAILURE;
235     }
236   else
237     {
238       /* Execute command. */
239       int i;
240
241       for (i = 0; i < n_tokens; i++)
242         lex_get (lexer);
243       result = command->function (lexer, ds);
244     }
245
246   assert (cmd_result_is_valid (result));
247
248 finish:
249   if (cmd_result_is_failure (result))
250     lex_interactive_reset (lexer);
251   else if (result == CMD_SUCCESS)
252     result = lex_end_of_command (lexer);
253
254   lex_discard_rest_of_command (lexer);
255   if (result != CMD_EOF && result != CMD_FINISH)
256     while (lex_token (lexer) == T_ENDCMD)
257       lex_get (lexer);
258
259   if (nesting_level != SIZE_MAX)
260     output_close_groups (nesting_level);
261
262   return result;
263 }
264
265 static int
266 find_best_match (struct substring s, const struct command **matchp)
267 {
268   const struct command *cmd;
269   struct command_matcher cm;
270   int missing_words;
271
272   command_matcher_init (&cm, s);
273   for (cmd = commands; cmd < &commands[n_commands]; cmd++)
274     command_matcher_add (&cm, ss_cstr (cmd->name), CONST_CAST (void *, cmd));
275
276   *matchp = command_matcher_get_match (&cm);
277   missing_words = command_matcher_get_missing_words (&cm);
278
279   command_matcher_destroy (&cm);
280
281   return missing_words;
282 }
283
284 static bool
285 parse_command_word (struct lexer *lexer, struct string *s, int n)
286 {
287   bool need_space = ds_last (s) != EOF && ds_last (s) != '-';
288
289   switch (lex_next_token (lexer, n))
290     {
291     case T_DASH:
292       ds_put_byte (s, '-');
293       return true;
294
295     case T_ID:
296       if (need_space)
297         ds_put_byte (s, ' ');
298       ds_put_cstr (s, lex_next_tokcstr (lexer, n));
299       return true;
300
301     case T_POS_NUM:
302       if (lex_next_is_integer (lexer, n))
303         {
304           int integer = lex_next_integer (lexer, n);
305           if (integer >= 0)
306             {
307               if (need_space)
308                 ds_put_byte (s, ' ');
309               ds_put_format (s, "%ld", lex_next_integer (lexer, n));
310               return true;
311             }
312         }
313       return false;
314
315     default:
316       return false;
317     }
318 }
319
320 /* Parses the command name.  On success returns a pointer to the corresponding
321    struct command and stores the number of tokens in the command name into
322    *N_TOKENS.  On failure, returns a null pointer and stores the number of
323    tokens required to determine that no command name was present into
324    *N_TOKENS. */
325 static const struct command *
326 parse_command_name (struct lexer *lexer, int *n_tokens)
327 {
328   const struct command *command;
329   int missing_words;
330   struct string s;
331   int word;
332
333   command = NULL;
334   missing_words = 0;
335   ds_init_empty (&s);
336   word = 0;
337   while (parse_command_word (lexer, &s, word))
338     {
339       missing_words = find_best_match (ds_ss (&s), &command);
340       if (missing_words <= 0)
341         break;
342       word++;
343     }
344
345   if (command == NULL && missing_words > 0)
346     {
347       ds_put_cstr (&s, " .");
348       missing_words = find_best_match (ds_ss (&s), &command);
349       ds_truncate (&s, ds_length (&s) - 2);
350     }
351
352   *n_tokens = (word + 1) + missing_words;
353   if (command == NULL)
354     {
355       if (ds_is_empty (&s))
356         lex_error (lexer, _("Syntax error expecting command name."));
357       else
358         lex_ofs_error (lexer, 0, *n_tokens - 1,
359                        _("Unknown command `%s'."), ds_cstr (&s));
360     }
361
362   ds_destroy (&s);
363
364   return command;
365 }
366
367 /* Returns true if COMMAND is allowed in STATE,
368    false otherwise. */
369 static bool
370 in_correct_state (const struct command *command, enum cmd_state state)
371 {
372   return command->states & (1 << state);
373 }
374
375 /* Returns an appropriate error message for trying to invoke
376    COMMAND in STATE. */
377 static char *
378 report_state_mismatch (const struct command *command, enum cmd_state state)
379 {
380   assert (!in_correct_state (command, state));
381
382   switch (state)
383     {
384     case CMD_STATE_INITIAL:
385     case CMD_STATE_DATA:
386       switch ((int) command->states
387               & (S_INITIAL | S_DATA | S_INPUT_PROGRAM | S_FILE_TYPE))
388         {
389           /* One allowed state. */
390         case S_INITIAL:
391           return xasprintf (_("%s is allowed only before the active dataset has "
392                               "been defined."), command->name);
393         case S_DATA:
394           return xasprintf (_("%s is allowed only after the active dataset has "
395                               "been defined."), command->name);
396         case S_INPUT_PROGRAM:
397           return xasprintf (_("%s is allowed only inside %s."),
398                             command->name, "INPUT PROGRAM");
399         case S_FILE_TYPE:
400           return xasprintf (_("%s is allowed only inside %s."), command->name, "FILE TYPE");
401
402           /* Two allowed states. */
403         case S_INITIAL | S_DATA:
404           NOT_REACHED ();
405         case S_INITIAL | S_INPUT_PROGRAM:
406           return xasprintf (_("%s is allowed only before the active dataset "
407                               "has been defined or inside %s."),
408                             command->name, "INPUT PROGRAM");
409         case S_INITIAL | S_FILE_TYPE:
410           return xasprintf (_("%s is allowed only before the active dataset "
411                               "has been defined or inside %s."),
412                             command->name, "FILE TYPE");
413         case S_DATA | S_INPUT_PROGRAM:
414           return xasprintf (_("%s is allowed only after the active dataset "
415                               "has been defined or inside %s."),
416                             command->name, "INPUT PROGRAM");
417         case S_DATA | S_FILE_TYPE:
418           return xasprintf (_("%s is allowed only after the active dataset "
419                               "has been defined or inside %s."),
420                             command->name, "FILE TYPE");
421         case S_INPUT_PROGRAM | S_FILE_TYPE:
422           return xasprintf (_("%s is allowed only inside %s or inside %s."),
423                             command->name, "INPUT PROGRAM", "FILE TYPE");
424
425           /* Three allowed states. */
426         case S_DATA | S_INPUT_PROGRAM | S_FILE_TYPE:
427           return xasprintf (_("%s is allowed only after the active dataset has "
428                               "been defined, inside INPUT PROGRAM, or inside "
429                               "FILE TYPE."), command->name);
430         case S_INITIAL | S_INPUT_PROGRAM | S_FILE_TYPE:
431           return xasprintf (_("%s is allowed only before the active dataset "
432                               "has been defined, inside INPUT PROGRAM, or "
433                               "inside FILE TYPE."), command->name);
434         case S_INITIAL | S_DATA | S_FILE_TYPE:
435           NOT_REACHED ();
436         case S_INITIAL | S_DATA | S_INPUT_PROGRAM:
437           NOT_REACHED ();
438
439           /* Four allowed states. */
440         case S_INITIAL | S_DATA | S_INPUT_PROGRAM | S_FILE_TYPE:
441           NOT_REACHED ();
442
443         default:
444           NOT_REACHED ();
445         }
446       break;
447
448     case CMD_STATE_INPUT_PROGRAM:
449       return xasprintf (_("%s is not allowed inside %s."),
450                         command->name, "INPUT PROGRAM");
451
452     case CMD_STATE_FILE_TYPE:
453       return xasprintf (_("%s is not allowed inside %s."),
454                         command->name, "FILE TYPE");
455
456     case CMD_STATE_NESTED_DATA:
457     case CMD_STATE_NESTED_INPUT_PROGRAM:
458       switch ((int) command->states & S_NESTED_ANY)
459         {
460         case 0:
461           return xasprintf (_("%s is not allowed inside DO IF or LOOP."),
462                             command->name);
463
464         case S_NESTED_DATA:
465           return xasprintf (_("In INPUT PROGRAM, "
466                               "%s is not allowed inside DO IF or LOOP."),
467                             command->name);
468
469         default:
470           NOT_REACHED ();
471         }
472     }
473
474   NOT_REACHED ();
475 }
476 \f
477 /* Command name completion. */
478
479 static enum cmd_state completion_state = CMD_STATE_INITIAL;
480
481 static void
482 set_completion_state (enum cmd_state state)
483 {
484   completion_state = state;
485 }
486
487 /* Returns the next possible completion of a command name that
488    begins with PREFIX, in the current command state, or a null
489    pointer if no completions remain.
490    Before calling the first time, set *CMD to a null pointer. */
491 const char *
492 cmd_complete (const char *prefix, const struct command **cmd)
493 {
494   if (*cmd == NULL)
495     *cmd = commands;
496
497   for (; *cmd < commands + n_commands; (*cmd)++)
498     if (!memcasecmp ((*cmd)->name, prefix, strlen (prefix))
499         && (!((*cmd)->flags & F_TESTING) || settings_get_testing_mode ())
500         && (!((*cmd)->flags & F_ENHANCED) || settings_get_syntax () == ENHANCED)
501         && !((*cmd)->flags & F_ABBREV)
502         && ((*cmd)->function != NULL)
503         && in_correct_state (*cmd, completion_state))
504       return (*cmd)++->name;
505
506   return NULL;
507 }
508 \f
509 /* Simple commands. */
510
511 /* Parse and execute FINISH command. */
512 int
513 cmd_finish (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
514 {
515   return CMD_FINISH;
516 }
517
518 /* Parses the N command. */
519 int
520 cmd_n_of_cases (struct lexer *lexer, struct dataset *ds)
521 {
522   if (!lex_force_int_range (lexer, "N OF CASES", 1, LONG_MAX))
523     return CMD_FAILURE;
524   long n = lex_integer (lexer);
525   lex_get (lexer);
526   if (!lex_match_id (lexer, "ESTIMATED"))
527     dict_set_case_limit (dataset_dict (ds), n);
528
529   return CMD_SUCCESS;
530 }
531
532 /* Parses, performs the EXECUTE procedure. */
533 int
534 cmd_execute (struct lexer *lexer UNUSED, struct dataset *ds)
535 {
536   bool ok = casereader_destroy (proc_open (ds));
537   if (!proc_commit (ds) || !ok)
538     return CMD_CASCADING_FAILURE;
539   return CMD_SUCCESS;
540 }
541
542 /* Parses, performs the ERASE command. */
543 int
544 cmd_erase (struct lexer *lexer, struct dataset *ds UNUSED)
545 {
546   char *filename;
547   int retval;
548
549   if (settings_get_safer_mode ())
550     {
551       lex_ofs_error (lexer, 0, 0,
552                      _("This command not allowed when the %s option is set."),
553                      "SAFER");
554       return CMD_FAILURE;
555     }
556
557   if (!lex_force_match_id (lexer, "FILE"))
558     return CMD_FAILURE;
559   lex_match (lexer, T_EQUALS);
560   if (!lex_force_string (lexer))
561     return CMD_FAILURE;
562
563   filename = utf8_to_filename (lex_tokcstr (lexer));
564   retval = remove (filename);
565   free (filename);
566
567   if (retval == -1)
568     {
569       msg (SW, _("Error removing `%s': %s."),
570            lex_tokcstr (lexer), strerror (errno));
571       return CMD_FAILURE;
572     }
573   lex_get (lexer);
574
575   return CMD_SUCCESS;
576 }
577
578 /* Parses, performs the NEW FILE command. */
579 int
580 cmd_new_file (struct lexer *lexer UNUSED, struct dataset *ds)
581 {
582   dataset_clear (ds);
583   return CMD_SUCCESS;
584 }