Improve error messages by citing syntax in more of them.
[pspp] / src / language / lexer / variable-parser.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2012, 2020 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/lexer/variable-parser.h"
20
21 #include <ctype.h>
22 #include <limits.h>
23 #include <stdbool.h>
24 #include <stdlib.h>
25
26 #include "data/dataset.h"
27 #include "data/dictionary.h"
28 #include "data/variable.h"
29 #include "language/lexer/lexer.h"
30 #include "libpspp/assertion.h"
31 #include "libpspp/cast.h"
32 #include "libpspp/hash-functions.h"
33 #include "libpspp/i18n.h"
34 #include "libpspp/hmapx.h"
35 #include "libpspp/message.h"
36 #include "libpspp/misc.h"
37 #include "libpspp/pool.h"
38 #include "libpspp/str.h"
39 #include "libpspp/stringi-set.h"
40
41 #include "math/interaction.h"
42
43 #include "gl/c-ctype.h"
44 #include "gl/xalloc.h"
45
46 #include "gettext.h"
47 #define _(msgid) gettext (msgid)
48
49 static struct variable *var_set_get_var (const struct var_set *, size_t);
50 static struct variable *var_set_lookup_var (const struct var_set *,
51                                             const char *);
52 static bool var_set_lookup_var_idx (const struct var_set *, const char *,
53                                     size_t *);
54 static bool var_set_get_names_must_be_ids (const struct var_set *);
55
56 static bool
57 is_name_token (const struct lexer *lexer, bool names_must_be_ids)
58 {
59   return (lex_token (lexer) == T_ID
60           || (!names_must_be_ids && lex_token (lexer) == T_STRING));
61 }
62
63 static bool
64 is_vs_name_token (const struct lexer *lexer, const struct var_set *vs)
65 {
66   return is_name_token (lexer, var_set_get_names_must_be_ids (vs));
67 }
68
69 static bool
70 is_dict_name_token (const struct lexer *lexer, const struct dictionary *d)
71 {
72   return is_name_token (lexer, dict_get_names_must_be_ids (d));
73 }
74
75 /* Parses a name as a variable within VS.  Sets *IDX to the
76    variable's index and returns true if successful.  On failure
77    emits an error message and returns false. */
78 static bool
79 parse_vs_variable_idx (struct lexer *lexer, const struct var_set *vs,
80                        size_t *idx)
81 {
82   assert (idx != NULL);
83
84   if (!is_vs_name_token (lexer, vs))
85     {
86       lex_error (lexer, _("Syntax error expecting variable name."));
87       return false;
88     }
89   else if (var_set_lookup_var_idx (vs, lex_tokcstr (lexer), idx))
90     {
91       lex_get (lexer);
92       return true;
93     }
94   else
95     {
96       lex_error (lexer, _("%s is not a variable name."), lex_tokcstr (lexer));
97       return false;
98     }
99 }
100
101 /* Parses a name as a variable within VS and returns the variable
102    if successful.  On failure emits an error message and returns
103    a null pointer. */
104 static struct variable *
105 parse_vs_variable (struct lexer *lexer, const struct var_set *vs)
106 {
107   size_t idx;
108   return parse_vs_variable_idx (lexer, vs, &idx) ? var_set_get_var (vs, idx) : NULL;
109 }
110
111 /* Parses a variable name in dictionary D and returns the
112    variable if successful.  On failure emits an error message and
113    returns a null pointer. */
114 struct variable *
115 parse_variable (struct lexer *lexer, const struct dictionary *d)
116 {
117   struct var_set *vs = var_set_create_from_dict (d);
118   struct variable *var = parse_vs_variable (lexer, vs);
119   var_set_destroy (vs);
120   return var;
121 }
122
123 /* Parses a set of variables from dictionary D given options
124    OPTS.  Resulting list of variables stored in *VAR and the
125    number of variables into *N.  Returns true only if
126    successful.  The dictionary D must contain at least one
127    variable.  */
128 bool
129 parse_variables (struct lexer *lexer, const struct dictionary *d,
130                  struct variable ***var,
131                  size_t *n, int opts)
132 {
133   struct var_set *vs;
134   int success;
135
136   assert (d != NULL);
137   assert (var != NULL);
138   assert (n != NULL);
139
140   vs = var_set_create_from_dict (d);
141   if (var_set_get_n (vs) == 0)
142     {
143       *n = 0;
144       var_set_destroy (vs);
145       return false;
146     }
147   success = parse_var_set_vars (lexer, vs, var, n, opts);
148   var_set_destroy (vs);
149   return success;
150 }
151
152 /* Parses a set of variables from dictionary D given options
153    OPTS.  Resulting list of variables stored in *VARS and the
154    number of variables into *N_VARS.  Returns true only if
155    successful.  Same behavior as parse_variables, except that all
156    allocations are taken from the given POOL. */
157 bool
158 parse_variables_pool (struct lexer *lexer, struct pool *pool,
159                 const struct dictionary *dict,
160                 struct variable ***vars, size_t *n_vars, int opts)
161 {
162   int retval;
163
164   /* PV_APPEND is unsafe because parse_variables would free the
165      existing names on failure, but those names are presumably
166      already in the pool, which would attempt to re-free it
167      later. */
168   assert (!(opts & PV_APPEND));
169
170   retval = parse_variables (lexer, dict, vars, n_vars, opts);
171   if (retval)
172     pool_register (pool, free, *vars);
173   return retval;
174 }
175
176 /* Parses a variable name from VS.  If successful, sets *IDX to
177    the variable's index in VS, *CLASS to the variable's
178    dictionary class, and returns true.  Returns false on
179    failure. */
180 static bool
181 parse_var_idx_class (struct lexer *lexer, const struct var_set *vs,
182                         size_t *idx,
183                         enum dict_class *class)
184 {
185   if (!parse_vs_variable_idx (lexer, vs, idx))
186     return false;
187
188   *class = dict_class_from_id (var_get_name (var_set_get_var (vs, *idx)));
189   return true;
190 }
191
192 /* Add the variable from VS with index IDX to the list of
193    variables V that has *NV elements and room for *MV.
194    Uses and updates INCLUDED to avoid duplicates if indicated by
195    PV_OPTS, which also affects what variables are allowed in
196    appropriate ways. */
197 static void
198 add_variable (struct lexer *lexer,
199               struct variable ***v, size_t *nv, size_t *mv,
200               char *included, int pv_opts,
201               const struct var_set *vs, size_t idx,
202               int start_ofs, int end_ofs)
203 {
204   struct variable *add = var_set_get_var (vs, idx);
205   const char *add_name = var_get_name (add);
206
207   if ((pv_opts & PV_NUMERIC) && !var_is_numeric (add))
208     lex_ofs_msg (lexer, SW, start_ofs, end_ofs,
209                  _("%s is not a numeric variable.  It will not be "
210                    "included in the variable list."), add_name);
211   else if ((pv_opts & PV_STRING) && !var_is_alpha (add))
212     lex_ofs_error (lexer, start_ofs, end_ofs,
213                    _("%s is not a string variable.  It will not be "
214                      "included in the variable list."), add_name);
215   else if ((pv_opts & PV_NO_SCRATCH)
216            && dict_class_from_id (add_name) == DC_SCRATCH)
217     lex_ofs_error (lexer, start_ofs, end_ofs,
218                    _("Scratch variables (such as %s) are not allowed "
219                      "here."), add_name);
220   else if ((pv_opts & (PV_SAME_TYPE | PV_SAME_WIDTH)) && *nv
221            && var_get_type (add) != var_get_type ((*v)[0]))
222     lex_ofs_error (lexer, start_ofs, end_ofs,
223                  _("%s and %s are not the same type.  All variables in "
224                    "this variable list must be of the same type.  %s "
225                    "will be omitted from the list."),
226                  var_get_name ((*v)[0]), add_name, add_name);
227   else if ((pv_opts & PV_SAME_WIDTH) && *nv
228            && var_get_width (add) != var_get_width ((*v)[0]))
229     lex_ofs_error (lexer, start_ofs, end_ofs,
230                  _("%s and %s are string variables with different widths.  "
231                    "All variables in this variable list must have the "
232                    "same width.  %s will be omitted from the list."),
233                  var_get_name ((*v)[0]), add_name, add_name);
234   else if ((pv_opts & PV_NO_DUPLICATE) && included && included[idx])
235     lex_ofs_error (lexer, start_ofs, end_ofs,
236                    _("Variable %s appears twice in variable list."), add_name);
237   else if ((pv_opts & PV_DUPLICATE) || !included || !included[idx])
238     {
239       if (*nv >= *mv)
240         {
241           *mv = 2 * (*nv + 1);
242           *v = xnrealloc (*v, *mv, sizeof **v);
243         }
244       (*v)[(*nv)++] = add;
245       if (included != NULL)
246         included[idx] = 1;
247     }
248 }
249
250 /* Adds the variables in VS with indexes FIRST_IDX through
251    LAST_IDX, inclusive, to the list of variables V that has *NV
252    elements and room for *MV.  Uses and updates INCLUDED to avoid
253    duplicates if indicated by PV_OPTS, which also affects what
254    variables are allowed in appropriate ways. */
255 static void
256 add_variables (struct lexer *lexer,
257                struct variable ***v, size_t *nv, size_t *mv, char *included,
258                int pv_opts,
259                const struct var_set *vs, int first_idx, int last_idx,
260                enum dict_class class,
261                int start_ofs, int end_ofs)
262 {
263   size_t i;
264
265   for (i = first_idx; i <= last_idx; i++)
266     if (dict_class_from_id (var_get_name (var_set_get_var (vs, i))) == class)
267       add_variable (lexer, v, nv, mv, included, pv_opts, vs, i,
268                     start_ofs, end_ofs);
269 }
270
271 /* Note that if parse_variables() returns false, *v is free()'d.
272    Conversely, if parse_variables() returns true, then *nv is
273    nonzero and *v is non-NULL. */
274 bool
275 parse_var_set_vars (struct lexer *lexer, const struct var_set *vs,
276                     struct variable ***v, size_t *nv,
277                     int pv_opts)
278 {
279   size_t mv;
280   char *included;
281
282   assert (vs != NULL);
283   assert (v != NULL);
284   assert (nv != NULL);
285
286   /* At most one of PV_NUMERIC, PV_STRING, PV_SAME_TYPE,
287      PV_SAME_WIDTH may be specified. */
288   assert (((pv_opts & PV_NUMERIC) != 0)
289           + ((pv_opts & PV_STRING) != 0)
290           + ((pv_opts & PV_SAME_TYPE) != 0)
291           + ((pv_opts & PV_SAME_WIDTH) != 0) <= 1);
292
293   /* PV_DUPLICATE and PV_NO_DUPLICATE are incompatible. */
294   assert (!(pv_opts & PV_DUPLICATE) || !(pv_opts & PV_NO_DUPLICATE));
295
296   if (!(pv_opts & PV_APPEND))
297     {
298       *v = NULL;
299       *nv = 0;
300       mv = 0;
301     }
302   else
303     mv = *nv;
304
305   if (!(pv_opts & PV_DUPLICATE))
306     {
307       size_t i;
308
309       included = xcalloc (var_set_get_n (vs), sizeof *included);
310       for (i = 0; i < *nv; i++)
311         {
312           size_t index;
313           if (!var_set_lookup_var_idx (vs, var_get_name ((*v)[i]), &index))
314             NOT_REACHED ();
315           included[index] = 1;
316         }
317     }
318   else
319     included = NULL;
320
321   do
322     {
323       int start_ofs = lex_ofs (lexer);
324       if (lex_match (lexer, T_ALL))
325         add_variables (lexer, v, nv, &mv, included, pv_opts,
326                        vs, 0, var_set_get_n (vs) - 1, DC_ORDINARY,
327                        start_ofs, start_ofs);
328       else
329         {
330           enum dict_class class;
331           size_t first_idx;
332
333           if (!parse_var_idx_class (lexer, vs, &first_idx, &class))
334             goto fail;
335
336           if (!lex_match (lexer, T_TO))
337             add_variable (lexer, v, nv, &mv, included, pv_opts, vs, first_idx,
338                           start_ofs, start_ofs);
339           else
340             {
341               size_t last_idx;
342               enum dict_class last_class;
343               struct variable *first_var, *last_var;
344
345               if (!parse_var_idx_class (lexer, vs, &last_idx, &last_class))
346                 goto fail;
347
348               int end_ofs = lex_ofs (lexer) - 1;
349
350               first_var = var_set_get_var (vs, first_idx);
351               last_var = var_set_get_var (vs, last_idx);
352
353               if (last_idx < first_idx)
354                 {
355                   const char *first_name = var_get_name (first_var);
356                   const char *last_name = var_get_name (last_var);
357                   lex_ofs_error (lexer, start_ofs, end_ofs,
358                                  _("%s TO %s is not valid syntax since %s "
359                                    "precedes %s in the dictionary."),
360                                  first_name, last_name, first_name, last_name);
361                   goto fail;
362                 }
363
364               if (class != last_class)
365                 {
366                   lex_ofs_error (lexer, start_ofs, end_ofs,
367                                  _("With the syntax <a> TO <b>, variables <a> "
368                                    "and <b> must be both regular variables "
369                                    "or both scratch variables."));
370                   struct pair
371                     {
372                       const char *name;
373                       enum dict_class class;
374                       int ofs;
375                     }
376                   pairs[2] = {
377                     { var_get_name (first_var), class, start_ofs },
378                     { var_get_name (last_var), last_class, end_ofs },
379                   };
380                   for (size_t i = 0; i < 2; i++)
381                     switch (pairs[i].class)
382                       {
383                       case DC_ORDINARY:
384                         lex_ofs_msg (lexer, SN, pairs[i].ofs, pairs[i].ofs,
385                                      _("%s is a regular variable."),
386                                      pairs[i].name);
387                         break;
388
389                       case DC_SCRATCH:
390                         lex_ofs_msg (lexer, SN, pairs[i].ofs, pairs[i].ofs,
391                                      _("%s is a scratch variable."),
392                                      pairs[i].name);
393                         break;
394
395                       case DC_SYSTEM:
396                         lex_ofs_msg (lexer, SN, pairs[i].ofs, pairs[i].ofs,
397                                      _("%s is a system variable."),
398                                      pairs[i].name);
399                         break;
400                       }
401                   goto fail;
402                 }
403
404               add_variables (lexer, v, nv, &mv, included, pv_opts,
405                              vs, first_idx, last_idx, class,
406                              start_ofs, lex_ofs (lexer) - 1);
407             }
408         }
409
410       if (pv_opts & PV_SINGLE)
411         break;
412       lex_match (lexer, T_COMMA);
413     }
414   while (lex_token (lexer) == T_ALL
415          || (is_vs_name_token (lexer, vs)
416              && var_set_lookup_var (vs, lex_tokcstr (lexer)) != NULL));
417
418   if (*nv == 0)
419     goto fail;
420
421   free (included);
422   return 1;
423
424 fail:
425   free (included);
426   free (*v);
427   *v = NULL;
428   *nv = 0;
429   return 0;
430 }
431
432 char *
433 parse_DATA_LIST_var (struct lexer *lexer, const struct dictionary *d)
434 {
435   if (!is_dict_name_token (lexer, d))
436     {
437       lex_error (lexer, ("Syntax error expecting variable name."));
438       return NULL;
439     }
440   if (!dict_id_is_valid (d, lex_tokcstr (lexer), true))
441     return NULL;
442
443   char *name = xstrdup (lex_tokcstr (lexer));
444   lex_get (lexer);
445   return name;
446 }
447
448 /* Attempts to break UTF-8 encoded NAME into a root (whose contents are
449    arbitrary except that it does not end in a digit) followed by an integer
450    numeric suffix.  On success, stores the value of the suffix into *NUMBERP,
451    the number of digits in the suffix into *N_DIGITSP, and returns the number
452    of bytes in the root.  On failure, returns 0. */
453 static int
454 extract_numeric_suffix (struct lexer *lexer, int ofs, const char *name,
455                         unsigned long int *numberp, int *n_digitsp)
456 {
457   size_t root_len, n_digits;
458   size_t i;
459
460   /* Count length of root. */
461   root_len = 1;                 /* Valid identifier never starts with digit. */
462   for (i = 1; name[i] != '\0'; i++)
463     if (!c_isdigit (name[i]))
464       root_len = i + 1;
465   n_digits = i - root_len;
466
467   if (n_digits == 0)
468     {
469       lex_ofs_error (lexer, ofs, ofs,
470                      _("`%s' cannot be used with TO because it does not end in "
471                        "a digit."), name);
472       return 0;
473     }
474
475   *numberp = strtoull (name + root_len, NULL, 10);
476   if (*numberp == ULONG_MAX)
477     {
478       lex_ofs_error (lexer, ofs, ofs,
479                      _("Numeric suffix on `%s' is larger than supported with TO."),
480                      name);
481       return 0;
482     }
483   *n_digitsp = n_digits;
484   return root_len;
485 }
486
487 static bool
488 add_var_name (struct lexer *lexer, int start_ofs, int end_ofs, char *name,
489               char ***names, size_t *n_vars, size_t *allocated_vars,
490               struct stringi_set *set, int pv_opts)
491 {
492   if (pv_opts & PV_NO_DUPLICATE && !stringi_set_insert (set, name))
493     {
494       lex_ofs_error (lexer, start_ofs, end_ofs,
495                      _("Variable %s appears twice in variable list."),
496                      name);
497       return false;
498     }
499
500   if (*n_vars >= *allocated_vars)
501     *names = x2nrealloc (*names, allocated_vars, sizeof **names);
502   (*names)[(*n_vars)++] = name;
503   return true;
504 }
505
506 /* Parses a list of variable names according to the DATA LIST version
507    of the TO convention.  */
508 bool
509 parse_DATA_LIST_vars (struct lexer *lexer, const struct dictionary *dict,
510                       char ***namesp, size_t *n_varsp, int pv_opts)
511 {
512   char **names;
513   size_t n_vars;
514   size_t allocated_vars;
515
516   struct stringi_set set;
517
518   char *name1 = NULL;
519   char *name2 = NULL;
520
521   bool ok = false;
522
523   assert ((pv_opts & ~(PV_APPEND | PV_SINGLE
524                        | PV_NO_SCRATCH | PV_NO_DUPLICATE)) == 0);
525   stringi_set_init (&set);
526
527   if (pv_opts & PV_APPEND)
528     {
529       n_vars = allocated_vars = *n_varsp;
530       names = *namesp;
531
532       if (pv_opts & PV_NO_DUPLICATE)
533         {
534           size_t i;
535
536           for (i = 0; i < n_vars; i++)
537             stringi_set_insert (&set, names[i]);
538         }
539     }
540   else
541     {
542       n_vars = allocated_vars = 0;
543       names = NULL;
544     }
545
546   do
547     {
548       int start_ofs = lex_ofs (lexer);
549       name1 = parse_DATA_LIST_var (lexer, dict);
550       if (!name1)
551         goto exit;
552       if (dict_class_from_id (name1) == DC_SCRATCH && pv_opts & PV_NO_SCRATCH)
553         {
554           lex_ofs_error (lexer, start_ofs, start_ofs,
555                          _("Scratch variables not allowed here."));
556           goto exit;
557         }
558       if (lex_match (lexer, T_TO))
559         {
560           unsigned long int num1, num2;
561           int n_digits1, n_digits2;
562           int root_len1, root_len2;
563           unsigned long int number;
564
565           name2 = parse_DATA_LIST_var (lexer, dict);
566           if (!name2)
567             goto exit;
568           int end_ofs = lex_ofs (lexer) - 1;
569
570           root_len1 = extract_numeric_suffix (lexer, start_ofs,
571                                               name1, &num1, &n_digits1);
572           if (root_len1 == 0)
573             goto exit;
574
575           root_len2 = extract_numeric_suffix (lexer, end_ofs,
576                                               name2, &num2, &n_digits2);
577           if (root_len2 == 0)
578             goto exit;
579
580           if (root_len1 != root_len2 || memcasecmp (name1, name2, root_len1))
581             {
582               lex_ofs_error (lexer, start_ofs, end_ofs,
583                              _("Prefixes don't match in use of TO convention."));
584               goto exit;
585             }
586           if (num1 > num2)
587             {
588               lex_ofs_error (lexer, start_ofs, end_ofs,
589                              _("Bad bounds in use of TO convention."));
590               goto exit;
591             }
592
593           for (number = num1; number <= num2; number++)
594             {
595               char *name = xasprintf ("%.*s%0*lu",
596                                       root_len1, name1,
597                                       n_digits1, number);
598               if (!add_var_name (lexer, start_ofs, end_ofs,
599                                  name, &names, &n_vars, &allocated_vars,
600                                  &set, pv_opts))
601                 {
602                   free (name);
603                   goto exit;
604                 }
605             }
606
607           free (name1);
608           name1 = NULL;
609           free (name2);
610           name2 = NULL;
611         }
612       else
613         {
614           if (!add_var_name (lexer, start_ofs, start_ofs,
615                              name1, &names, &n_vars, &allocated_vars,
616                              &set, pv_opts))
617             goto exit;
618           name1 = NULL;
619         }
620
621       lex_match (lexer, T_COMMA);
622
623       if (pv_opts & PV_SINGLE)
624         break;
625     }
626   while (lex_token (lexer) == T_ID);
627   ok = true;
628
629 exit:
630   stringi_set_destroy (&set);
631   if (ok)
632     {
633       *namesp = names;
634       *n_varsp = n_vars;
635     }
636   else
637     {
638       int i;
639       for (i = 0; i < n_vars; i++)
640         free (names[i]);
641       free (names);
642       *namesp = NULL;
643       *n_varsp = 0;
644
645       free (name1);
646       free (name2);
647     }
648   return ok;
649 }
650
651 /* Registers each of the NAMES[0...NNAMES - 1] in POOL, as well
652    as NAMES itself. */
653 static void
654 register_vars_pool (struct pool *pool, char **names, size_t nnames)
655 {
656   size_t i;
657
658   for (i = 0; i < nnames; i++)
659     pool_register (pool, free, names[i]);
660   pool_register (pool, free, names);
661 }
662
663 /* Parses a list of variable names according to the DATA LIST
664    version of the TO convention.  Same args as
665    parse_DATA_LIST_vars(), except that all allocations are taken
666    from the given POOL. */
667 bool
668 parse_DATA_LIST_vars_pool (struct lexer *lexer, const struct dictionary *dict,
669                            struct pool *pool,
670                            char ***names, size_t *nnames, int pv_opts)
671 {
672   int retval;
673
674   /* PV_APPEND is unsafe because parse_DATA_LIST_vars would free
675      the existing names on failure, but those names are
676      presumably already in the pool, which would attempt to
677      re-free it later. */
678   assert (!(pv_opts & PV_APPEND));
679
680   retval = parse_DATA_LIST_vars (lexer, dict, names, nnames, pv_opts);
681   if (retval)
682     register_vars_pool (pool, *names, *nnames);
683   return retval;
684 }
685
686 /* Parses a list of variables where some of the variables may be
687    existing and the rest are to be created.  Same args as
688    parse_DATA_LIST_vars(). */
689 bool
690 parse_mixed_vars (struct lexer *lexer, const struct dictionary *dict,
691                   char ***names, size_t *nnames, int pv_opts)
692 {
693   size_t i;
694
695   assert (names != NULL);
696   assert (nnames != NULL);
697
698   if (!(pv_opts & PV_APPEND))
699     {
700       *names = NULL;
701       *nnames = 0;
702     }
703   while (is_dict_name_token (lexer, dict) || lex_token (lexer) == T_ALL)
704     {
705       if (lex_token (lexer) == T_ALL || dict_lookup_var (dict, lex_tokcstr (lexer)) != NULL)
706         {
707           struct variable **v;
708           size_t nv;
709
710           if (!parse_variables (lexer, dict, &v, &nv, pv_opts))
711             goto fail;
712           *names = xnrealloc (*names, *nnames + nv, sizeof **names);
713           for (i = 0; i < nv; i++)
714             (*names)[*nnames + i] = xstrdup (var_get_name (v[i]));
715           free (v);
716           *nnames += nv;
717         }
718       else if (!parse_DATA_LIST_vars (lexer, dict, names, nnames, PV_APPEND | pv_opts))
719         goto fail;
720     }
721   if (*nnames == 0)
722     goto fail;
723
724   return true;
725
726 fail:
727   for (i = 0; i < *nnames; i++)
728     free ((*names)[i]);
729   free (*names);
730   *names = NULL;
731   *nnames = 0;
732   return false;
733 }
734
735 /* Parses a list of variables where some of the variables may be
736    existing and the rest are to be created.  Same args as
737    parse_mixed_vars(), except that all allocations are taken
738    from the given POOL. */
739 bool
740 parse_mixed_vars_pool (struct lexer *lexer, const struct dictionary *dict, struct pool *pool,
741                        char ***names, size_t *nnames, int pv_opts)
742 {
743   int retval;
744
745   /* PV_APPEND is unsafe because parse_mixed_vars_pool would free
746      the existing names on failure, but those names are
747      presumably already in the pool, which would attempt to
748      re-free it later. */
749   assert (!(pv_opts & PV_APPEND));
750
751   retval = parse_mixed_vars (lexer, dict, names, nnames, pv_opts);
752   if (retval)
753     register_vars_pool (pool, *names, *nnames);
754   return retval;
755 }
756 \f
757 /* Frees the N var_syntax structures in VS, as well as VS itself. */
758 void
759 var_syntax_destroy (struct var_syntax *vs, size_t n)
760 {
761   for (size_t i = 0; i < n; i++)
762     {
763       free (vs[i].first);
764       free (vs[i].last);
765     }
766   free (vs);
767 }
768
769 /* Parses syntax for variables and variable ranges from LEXER.  If successful,
770    initializes *VS to the beginning of an array of var_syntax structs and *N_VS
771    to the number of elements in the array and returns true.  On error, sets *VS
772    to NULL and *N_VS to 0 and returns false. */
773 bool
774 var_syntax_parse (struct lexer *lexer, struct var_syntax **vs, size_t *n_vs)
775 {
776   *vs = NULL;
777   *n_vs = 0;
778
779   if (lex_token (lexer) != T_ID)
780     {
781       lex_error (lexer, _("Syntax error expecting variable name."));
782       goto error;
783     }
784
785   size_t allocated_vs = 0;
786   do
787     {
788       if (allocated_vs >= *n_vs)
789         *vs = x2nrealloc (*vs, &allocated_vs, sizeof **vs);
790       struct var_syntax *new = &(*vs)[(*n_vs)++];
791       *new = (struct var_syntax) {
792         .first = ss_xstrdup (lex_tokss (lexer)),
793         .first_ofs = lex_ofs (lexer)
794       };
795       lex_get (lexer);
796
797       if (lex_match (lexer, T_TO))
798         {
799           if (lex_token (lexer) != T_ID)
800             {
801               lex_error (lexer, _("Syntax error expecting variable name."));
802               goto error;
803             }
804
805           new->last = ss_xstrdup (lex_tokss (lexer));
806           lex_get (lexer);
807         }
808       new->last_ofs = lex_ofs (lexer) - 1;
809     }
810   while (lex_token (lexer) == T_ID);
811   return true;
812
813 error:
814   var_syntax_destroy (*vs, *n_vs);
815   *vs = NULL;
816   *n_vs = 0;
817   return false;
818 }
819
820 /* Looks up the N_VS var syntax structs in VS in DICT, translating them to an
821    array of variables.  If successful, initializes *VARS to the beginning of an
822    array of pointers to variables and *N_VARS to the length of the array and
823    returns true.  On error, sets *VARS to NULL and *N_VARS to 0.
824
825    The LEXER is just used for error messages.
826
827    For the moment, only honors PV_NUMERIC in OPTS. */
828 bool
829 var_syntax_evaluate (struct lexer *lexer,
830                      const struct var_syntax *vs, size_t n_vs,
831                      const struct dictionary *dict,
832                      struct variable ***vars, size_t *n_vars, int opts)
833 {
834   assert (!(opts & ~PV_NUMERIC));
835
836   *vars = NULL;
837   *n_vars = 0;
838
839   size_t allocated_vars = 0;
840   for (size_t i = 0; i < n_vs; i++)
841     {
842       int first_ofs = vs[i].first_ofs;
843       struct variable *first = dict_lookup_var (dict, vs[i].first);
844       if (!first)
845         {
846           lex_ofs_error (lexer, first_ofs, first_ofs,
847                          _("%s is not a variable name."), vs[i].first);
848           goto error;
849         }
850
851       int last_ofs = vs[i].last_ofs;
852       struct variable *last = (vs[i].last
853                                ? dict_lookup_var (dict, vs[i].last)
854                                : first);
855       if (!last)
856         {
857           lex_ofs_error (lexer, last_ofs, last_ofs,
858                          _("%s is not a variable name."), vs[i].last);
859           goto error;
860         }
861
862       size_t first_idx = var_get_dict_index (first);
863       size_t last_idx = var_get_dict_index (last);
864       if (last_idx < first_idx)
865         {
866           lex_ofs_error (lexer, first_ofs, last_ofs,
867                          _("%s TO %s is not valid syntax since %s "
868                            "precedes %s in the dictionary."),
869                          vs[i].first, vs[i].last,
870                          vs[i].first, vs[i].last);
871           goto error;
872         }
873
874       for (size_t j = first_idx; j <= last_idx; j++)
875         {
876           struct variable *v = dict_get_var (dict, j);
877           if (opts & PV_NUMERIC && !var_is_numeric (v))
878             {
879               lex_ofs_error (lexer, first_ofs, last_ofs,
880                              _("%s is not a numeric variable."),
881                              var_get_name (v));
882               goto error;
883             }
884
885           if (*n_vars >= allocated_vars)
886             *vars = x2nrealloc (*vars, &allocated_vars, sizeof **vars);
887           (*vars)[(*n_vars)++] = v;
888         }
889     }
890
891   return true;
892
893 error:
894   free (*vars);
895   *vars = NULL;
896   *n_vars = 0;
897   return false;
898 }
899 \f
900 /* A set of variables. */
901 struct var_set
902   {
903     bool names_must_be_ids;
904     size_t (*get_n) (const struct var_set *);
905     struct variable *(*get_var) (const struct var_set *, size_t idx);
906     bool (*lookup_var_idx) (const struct var_set *, const char *, size_t *);
907     void (*destroy) (struct var_set *);
908     void *aux;
909   };
910
911 /* Returns the number of variables in VS. */
912 size_t
913 var_set_get_n (const struct var_set *vs)
914 {
915   assert (vs != NULL);
916
917   return vs->get_n (vs);
918 }
919
920 /* Return variable with index IDX in VS.
921    IDX must be less than the number of variables in VS. */
922 static struct variable *
923 var_set_get_var (const struct var_set *vs, size_t idx)
924 {
925   assert (vs != NULL);
926   assert (idx < var_set_get_n (vs));
927
928   return vs->get_var (vs, idx);
929 }
930
931 /* Returns the variable in VS named NAME, or a null pointer if VS
932    contains no variable with that name. */
933 struct variable *
934 var_set_lookup_var (const struct var_set *vs, const char *name)
935 {
936   size_t idx;
937   return (var_set_lookup_var_idx (vs, name, &idx)
938           ? var_set_get_var (vs, idx)
939           : NULL);
940 }
941
942 /* If VS contains a variable named NAME, sets *IDX to its index
943    and returns true.  Otherwise, returns false. */
944 bool
945 var_set_lookup_var_idx (const struct var_set *vs, const char *name,
946                         size_t *idx)
947 {
948   assert (vs != NULL);
949   assert (name != NULL);
950
951   return vs->lookup_var_idx (vs, name, idx);
952 }
953
954 /* Destroys VS. */
955 void
956 var_set_destroy (struct var_set *vs)
957 {
958   if (vs != NULL)
959     vs->destroy (vs);
960 }
961
962 static bool
963 var_set_get_names_must_be_ids (const struct var_set *vs)
964 {
965   return vs->names_must_be_ids;
966 }
967 \f
968 /* Returns the number of variables in VS. */
969 static size_t
970 dict_var_set_get_n (const struct var_set *vs)
971 {
972   struct dictionary *d = vs->aux;
973
974   return dict_get_n_vars (d);
975 }
976
977 /* Return variable with index IDX in VS.
978    IDX must be less than the number of variables in VS. */
979 static struct variable *
980 dict_var_set_get_var (const struct var_set *vs, size_t idx)
981 {
982   struct dictionary *d = vs->aux;
983
984   return dict_get_var (d, idx);
985 }
986
987 /* If VS contains a variable named NAME, sets *IDX to its index
988    and returns true.  Otherwise, returns false. */
989 static bool
990 dict_var_set_lookup_var_idx (const struct var_set *vs, const char *name,
991                              size_t *idx)
992 {
993   struct dictionary *d = vs->aux;
994   struct variable *v = dict_lookup_var (d, name);
995   if (v != NULL)
996     {
997       *idx = var_get_dict_index (v);
998       return true;
999     }
1000   else
1001     return false;
1002 }
1003
1004 /* Destroys VS. */
1005 static void
1006 dict_var_set_destroy (struct var_set *vs)
1007 {
1008   free (vs);
1009 }
1010
1011 /* Returns a variable set based on D. */
1012 struct var_set *
1013 var_set_create_from_dict (const struct dictionary *d)
1014 {
1015   struct var_set *vs = xmalloc (sizeof *vs);
1016   vs->names_must_be_ids = dict_get_names_must_be_ids (d);
1017   vs->get_n = dict_var_set_get_n;
1018   vs->get_var = dict_var_set_get_var;
1019   vs->lookup_var_idx = dict_var_set_lookup_var_idx;
1020   vs->destroy = dict_var_set_destroy;
1021   vs->aux = (void *) d;
1022   return vs;
1023 }
1024 \f
1025 /* A variable set based on an array. */
1026 struct array_var_set
1027   {
1028     struct variable *const *var;/* Array of variables. */
1029     size_t n_vars;              /* Number of elements in var. */
1030     struct hmapx vars_by_name;  /* Variables hashed by name. */
1031   };
1032
1033 /* Returns the number of variables in VS. */
1034 static size_t
1035 array_var_set_get_n (const struct var_set *vs)
1036 {
1037   struct array_var_set *avs = vs->aux;
1038
1039   return avs->n_vars;
1040 }
1041
1042 /* Return variable with index IDX in VS.
1043    IDX must be less than the number of variables in VS. */
1044 static struct variable *
1045 array_var_set_get_var (const struct var_set *vs, size_t idx)
1046 {
1047   struct array_var_set *avs = vs->aux;
1048
1049   return CONST_CAST (struct variable *, avs->var[idx]);
1050 }
1051
1052 /* If VS contains a variable named NAME, sets *IDX to its index
1053    and returns true.  Otherwise, returns false. */
1054 static bool
1055 array_var_set_lookup_var_idx (const struct var_set *vs, const char *name,
1056                               size_t *idx)
1057 {
1058   struct array_var_set *avs = vs->aux;
1059   struct hmapx_node *node;
1060   struct variable **varp;
1061
1062   HMAPX_FOR_EACH_WITH_HASH (varp, node, utf8_hash_case_string (name, 0),
1063                             &avs->vars_by_name)
1064     if (!utf8_strcasecmp (name, var_get_name (*varp)))
1065       {
1066         *idx = varp - avs->var;
1067         return true;
1068       }
1069
1070   return false;
1071 }
1072
1073 /* Destroys VS. */
1074 static void
1075 array_var_set_destroy (struct var_set *vs)
1076 {
1077   struct array_var_set *avs = vs->aux;
1078
1079   hmapx_destroy (&avs->vars_by_name);
1080   free (avs);
1081   free (vs);
1082 }
1083
1084 /* Returns a variable set based on the N_VARS variables in VAR. */
1085 struct var_set *
1086 var_set_create_from_array (struct variable *const *var, size_t n_vars)
1087 {
1088   struct var_set *vs;
1089   struct array_var_set *avs;
1090   size_t i;
1091
1092   vs = xmalloc (sizeof *vs);
1093   vs->names_must_be_ids = true;
1094   vs->get_n = array_var_set_get_n;
1095   vs->get_var = array_var_set_get_var;
1096   vs->lookup_var_idx = array_var_set_lookup_var_idx;
1097   vs->destroy = array_var_set_destroy;
1098   vs->aux = avs = xmalloc (sizeof *avs);
1099   avs->var = var;
1100   avs->n_vars = n_vars;
1101   hmapx_init (&avs->vars_by_name);
1102   for (i = 0; i < n_vars; i++)
1103     {
1104       const char *name = var_get_name (var[i]);
1105       size_t idx;
1106
1107       if (array_var_set_lookup_var_idx (vs, name, &idx))
1108         {
1109           var_set_destroy (vs);
1110           return NULL;
1111         }
1112       hmapx_insert (&avs->vars_by_name, CONST_CAST (void *, &avs->var[i]),
1113                     utf8_hash_case_string (name, 0));
1114     }
1115
1116   return vs;
1117 }
1118
1119
1120 /* Match a variable.
1121    If the match succeeds, the variable will be placed in VAR.
1122    Returns true if successful */
1123 bool
1124 lex_match_variable (struct lexer *lexer, const struct dictionary *dict, const struct variable **var)
1125 {
1126   if (lex_token (lexer) !=  T_ID)
1127     return false;
1128
1129   *var = parse_variable_const  (lexer, dict);
1130
1131   if (*var == NULL)
1132     return false;
1133   return true;
1134 }
1135
1136 /* An interaction is a variable followed by {*, BY} followed by an interaction */
1137 static bool
1138 parse_internal_interaction (struct lexer *lexer, const struct dictionary *dict, struct interaction **iact, struct interaction **it)
1139 {
1140   const struct variable *v = NULL;
1141   assert (iact);
1142
1143   switch  (lex_next_token (lexer, 1))
1144     {
1145     case T_ENDCMD:
1146     case T_SLASH:
1147     case T_COMMA:
1148     case T_ID:
1149     case T_BY:
1150     case T_ASTERISK:
1151       break;
1152     default:
1153       return false;
1154       break;
1155     }
1156
1157   if (! lex_match_variable (lexer, dict, &v))
1158     {
1159       if (it)
1160         interaction_destroy (*it);
1161       *iact = NULL;
1162       return false;
1163     }
1164
1165   assert (v);
1166
1167   if (*iact == NULL)
1168     *iact = interaction_create (v);
1169   else
1170     interaction_add_variable (*iact, v);
1171
1172   if (lex_match (lexer, T_ASTERISK) || lex_match (lexer, T_BY))
1173     {
1174       return parse_internal_interaction (lexer, dict, iact, iact);
1175     }
1176
1177   return true;
1178 }
1179
1180 bool
1181 parse_design_interaction (struct lexer *lexer, const struct dictionary *dict, struct interaction **iact)
1182 {
1183   return parse_internal_interaction (lexer, dict, iact, NULL);
1184 }
1185