dictionary: Limit split file variables to 8, for compatibility.
[pspp] / src / data / dictionary.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011, 2012, 2013, 2014,
3    2015, 2020 Free Software Foundation, Inc.
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU 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, see <http://www.gnu.org/licenses/>. */
17
18 #include <config.h>
19
20 #include "data/dictionary.h"
21
22 #include <stdint.h>
23 #include <stdlib.h>
24 #include <ctype.h>
25 #include <unistr.h>
26
27 #include "data/attributes.h"
28 #include "data/case.h"
29 #include "data/identifier.h"
30 #include "data/mrset.h"
31 #include "data/settings.h"
32 #include "data/value-labels.h"
33 #include "data/vardict.h"
34 #include "data/variable.h"
35 #include "data/vector.h"
36 #include "libpspp/array.h"
37 #include "libpspp/assertion.h"
38 #include "libpspp/compiler.h"
39 #include "libpspp/hash-functions.h"
40 #include "libpspp/hmap.h"
41 #include "libpspp/i18n.h"
42 #include "libpspp/message.h"
43 #include "libpspp/misc.h"
44 #include "libpspp/pool.h"
45 #include "libpspp/str.h"
46 #include "libpspp/string-array.h"
47 #include "libpspp/ll.h"
48
49 #include "gl/intprops.h"
50 #include "gl/minmax.h"
51 #include "gl/xalloc.h"
52 #include "gl/xmemdup0.h"
53
54 #include "gettext.h"
55 #define _(msgid) gettext (msgid)
56
57 /* A dictionary. */
58 struct dictionary
59   {
60     int ref_cnt;
61     struct vardict_info *vars;  /* Variables. */
62     size_t n_vars;              /* Number of variables. */
63     size_t allocated_vars;      /* Allocated space in 'vars'. */
64     struct caseproto *proto;    /* Prototype for dictionary cases
65                                    (updated lazily). */
66     struct hmap name_map;       /* Variable index by name. */
67     int next_value_idx;         /* Index of next `union value' to allocate. */
68     const struct variable **split;    /* SPLIT FILE vars. */
69     size_t n_splits;            /* SPLIT FILE count. */
70     enum split_type split_type;
71     struct variable *weight;    /* WEIGHT variable. */
72     struct variable *filter;    /* FILTER variable. */
73     casenumber case_limit;      /* Current case limit (N command). */
74     char *label;                /* File label. */
75     struct string_array documents; /* Documents. */
76     struct vector **vector;     /* Vectors of variables. */
77     size_t n_vectors;           /* Number of vectors. */
78     struct attrset attributes;  /* Custom attributes. */
79     struct mrset **mrsets;      /* Multiple response sets. */
80     size_t n_mrsets;            /* Number of multiple response sets. */
81
82     /* Whether variable names must be valid identifiers.  Normally, this is
83        true, but sometimes a dictionary is prepared for external use
84        (e.g. output to a CSV file) where names don't have to be valid. */
85     bool names_must_be_ids;
86
87     char *encoding;             /* Character encoding of string data */
88
89     const struct dict_callbacks *callbacks; /* Callbacks on dictionary
90                                                modification */
91     void *cb_data ;                  /* Data passed to callbacks */
92
93     void (*changed) (struct dictionary *, void *); /* Generic change callback */
94     void *changed_data;
95   };
96
97 static void dict_unset_split_var (struct dictionary *, struct variable *, bool);
98 static void dict_unset_mrset_var (struct dictionary *, struct variable *);
99
100 /* Compares two double pointers to variables, which should point
101    to elements of a struct dictionary's `var' member array. */
102 static int
103 compare_var_ptrs (const void *a_, const void *b_, const void *aux UNUSED)
104 {
105   struct variable *const *a = a_;
106   struct variable *const *b = b_;
107
108   return *a < *b ? -1 : *a > *b;
109 }
110
111 static void
112 unindex_var (struct dictionary *d, struct vardict_info *vardict)
113 {
114   hmap_delete (&d->name_map, &vardict->name_node);
115 }
116
117 /* This function assumes that vardict->name_node.hash is valid, that is, that
118    its name has not changed since it was hashed (rename_var() updates this
119    hash along with the name itself). */
120 static void
121 reindex_var (struct dictionary *d, struct vardict_info *vardict, bool skip_callbacks)
122 {
123   struct variable *old = (d->callbacks && d->callbacks->var_changed
124                           ? var_clone (vardict->var)
125                           : NULL);
126
127   struct variable *var = vardict->var;
128   var_set_vardict (var, vardict);
129   hmap_insert_fast (&d->name_map, &vardict->name_node,
130                     vardict->name_node.hash);
131
132   if (! skip_callbacks)
133     {
134       if (d->changed) d->changed (d, d->changed_data);
135       if (old)
136         {
137           d->callbacks->var_changed (d, var_get_dict_index (var), VAR_TRAIT_POSITION, old, d->cb_data);
138           var_unref (old);
139         }
140     }
141 }
142
143 /* Sets the case_index in V's vardict to CASE_INDEX. */
144 static void
145 set_var_case_index (struct variable *v, int case_index)
146 {
147   var_get_vardict (v)->case_index = case_index;
148 }
149
150 /* Removes the dictionary variables with indexes from FROM to TO (exclusive)
151    from name_map. */
152 static void
153 unindex_vars (struct dictionary *d, size_t from, size_t to)
154 {
155   size_t i;
156
157   for (i = from; i < to; i++)
158     unindex_var (d, &d->vars[i]);
159 }
160
161 /* Re-sets the dict_index in the dictionary variables with
162    indexes from FROM to TO (exclusive). */
163 static void
164 reindex_vars (struct dictionary *d, size_t from, size_t to, bool skip_callbacks)
165 {
166   size_t i;
167
168   for (i = from; i < to; i++)
169     reindex_var (d, &d->vars[i], skip_callbacks);
170 }
171
172 \f
173
174 /* Returns the encoding for data in dictionary D.  The return value is a
175    nonnull string that contains an IANA character set name. */
176 const char *
177 dict_get_encoding (const struct dictionary *d)
178 {
179   return d->encoding ;
180 }
181
182 /* Returns true if UTF-8 string ID is an acceptable identifier in DICT's
183    encoding, false otherwise.  If ISSUE_ERROR is true, issues an explanatory
184    error message on failure. */
185 bool
186 dict_id_is_valid (const struct dictionary *dict, const char *id,
187                   bool issue_error)
188 {
189   return (!dict->names_must_be_ids
190           || id_is_valid (id, dict->encoding, issue_error));
191 }
192
193 void
194 dict_set_change_callback (struct dictionary *d,
195                           void (*changed) (struct dictionary *, void*),
196                           void *data)
197 {
198   d->changed = changed;
199   d->changed_data = data;
200 }
201
202 /* Discards dictionary D's caseproto.  (It will be regenerated
203    lazily, on demand.) */
204 static void
205 invalidate_proto (struct dictionary *d)
206 {
207   caseproto_unref (d->proto);
208   d->proto = NULL;
209 }
210
211 /* Print a representation of dictionary D to stdout, for
212    debugging purposes. */
213 void
214 dict_dump (const struct dictionary *d)
215 {
216   int i;
217   for (i = 0 ; i < d->n_vars ; ++i)
218     {
219       const struct variable *v = d->vars[i].var;
220       printf ("Name: %s;\tdict_idx: %zu; case_idx: %zu\n",
221               var_get_name (v),
222               var_get_dict_index (v),
223               var_get_case_index (v));
224
225     }
226 }
227
228 /* Associate CALLBACKS with DICT.  Callbacks will be invoked whenever
229    the dictionary or any of the variables it contains are modified.
230    Each callback will get passed CALLBACK_DATA.
231    Any callback may be NULL, in which case it'll be ignored.
232 */
233 void
234 dict_set_callbacks (struct dictionary *dict,
235                     const struct dict_callbacks *callbacks,
236                     void *callback_data)
237 {
238   dict->callbacks = callbacks;
239   dict->cb_data = callback_data;
240 }
241
242 /* Shallow copy the callbacks from SRC to DEST */
243 void
244 dict_copy_callbacks (struct dictionary *dest,
245                      const struct dictionary *src)
246 {
247   dest->callbacks = src->callbacks;
248   dest->cb_data = src->cb_data;
249 }
250
251 /* Creates and returns a new dictionary with the specified ENCODING. */
252 struct dictionary *
253 dict_create (const char *encoding)
254 {
255   struct dictionary *d = xmalloc (sizeof *d);
256
257   *d = (struct dictionary) {
258     .encoding = xstrdup (encoding),
259     .names_must_be_ids = true,
260     .name_map = HMAP_INITIALIZER (d->name_map),
261     .attributes = ATTRSET_INITIALIZER (d->attributes),
262     .split_type = SPLIT_NONE,
263     .ref_cnt = 1,
264   };
265
266   return d;
267 }
268
269 /* Creates and returns a (deep) copy of an existing
270    dictionary.
271
272    The new dictionary's case indexes are copied from the old
273    dictionary.  If the new dictionary won't be used to access
274    cases produced with the old dictionary, then the new
275    dictionary's case indexes should be compacted with
276    dict_compact_values to save space.
277
278    Callbacks are not cloned. */
279 struct dictionary *
280 dict_clone (const struct dictionary *s)
281 {
282   struct dictionary *d;
283   size_t i;
284
285   d = dict_create (s->encoding);
286   dict_set_names_must_be_ids (d, dict_get_names_must_be_ids (s));
287
288   for (i = 0; i < s->n_vars; i++)
289     {
290       struct variable *sv = s->vars[i].var;
291       struct variable *dv = dict_clone_var_assert (d, sv);
292       size_t i;
293
294       for (i = 0; i < var_get_n_short_names (sv); i++)
295         var_set_short_name (dv, i, var_get_short_name (sv, i));
296
297       var_get_vardict (dv)->case_index = var_get_vardict (sv)->case_index;
298     }
299
300   d->next_value_idx = s->next_value_idx;
301
302   d->n_splits = s->n_splits;
303   if (d->n_splits > 0)
304     {
305        d->split = xnmalloc (d->n_splits, sizeof *d->split);
306        for (i = 0; i < d->n_splits; i++)
307          d->split[i] = dict_lookup_var_assert (d, var_get_name (s->split[i]));
308     }
309   d->split_type = s->split_type;
310
311   if (s->weight != NULL)
312     dict_set_weight (d, dict_lookup_var_assert (d, var_get_name (s->weight)));
313
314   if (s->filter != NULL)
315     dict_set_filter (d, dict_lookup_var_assert (d, var_get_name (s->filter)));
316
317   d->case_limit = s->case_limit;
318   dict_set_label (d, dict_get_label (s));
319   dict_set_documents (d, dict_get_documents (s));
320
321   d->n_vectors = s->n_vectors;
322   d->vector = xnmalloc (d->n_vectors, sizeof *d->vector);
323   for (i = 0; i < s->n_vectors; i++)
324     d->vector[i] = vector_clone (s->vector[i], s, d);
325
326   dict_set_attributes (d, dict_get_attributes (s));
327
328   for (i = 0; i < s->n_mrsets; i++)
329     {
330       const struct mrset *old = s->mrsets[i];
331       struct mrset *new;
332       size_t j;
333
334       /* Clone old mrset, then replace vars from D by vars from S. */
335       new = mrset_clone (old);
336       for (j = 0; j < new->n_vars; j++)
337         new->vars[j] = dict_lookup_var_assert (d, var_get_name (new->vars[j]));
338
339       dict_add_mrset (d, new);
340     }
341
342   return d;
343 }
344
345
346 \f
347 /* Returns the SPLIT FILE vars (see cmd_split_file()).  Call
348    dict_get_n_splits() to determine how many SPLIT FILE vars
349    there are.  Returns a null pointer if and only if there are no
350    SPLIT FILE vars. */
351 const struct variable *const *
352 dict_get_split_vars (const struct dictionary *d)
353 {
354   return d->split;
355 }
356
357 /* Returns the number of SPLIT FILE vars. */
358 size_t
359 dict_get_n_splits (const struct dictionary *d)
360 {
361   return d->n_splits;
362 }
363
364 /* Removes variable V, which must be in D, from D's set of split
365    variables. */
366 static void
367 dict_unset_split_var (struct dictionary *d, struct variable *v, bool skip_callbacks)
368 {
369   int orig_count;
370
371   assert (dict_contains_var (d, v));
372
373   orig_count = d->n_splits;
374   d->n_splits = remove_equal (d->split, d->n_splits, sizeof *d->split,
375                                &v, compare_var_ptrs, NULL);
376   if (orig_count != d->n_splits && !skip_callbacks)
377     {
378       if (d->changed) d->changed (d, d->changed_data);
379       /* We changed the set of split variables so invoke the
380          callback. */
381       if (d->callbacks &&  d->callbacks->split_changed)
382         d->callbacks->split_changed (d, d->cb_data);
383     }
384 }
385
386
387 /* Sets N split vars SPLIT in dictionary D.  N is silently capped to a maximum
388    of MAX_SPLITS. */
389 static void
390 dict_set_split_vars__ (struct dictionary *d,
391                        struct variable *const *split, size_t n,
392                        enum split_type type, bool skip_callbacks)
393 {
394   if (n > MAX_SPLITS)
395     n = MAX_SPLITS;
396   assert (n == 0 || split != NULL);
397
398   d->n_splits = n;
399   d->split_type = type == SPLIT_NONE ? SPLIT_LAYERED : type;
400   if (n > 0)
401    {
402     d->split = xnrealloc (d->split, n, sizeof *d->split) ;
403     memcpy (d->split, split, n * sizeof *d->split);
404    }
405   else
406    {
407     free (d->split);
408     d->split = NULL;
409    }
410
411  if (!skip_callbacks)
412     {
413       if (d->changed) d->changed (d, d->changed_data);
414       if (d->callbacks &&  d->callbacks->split_changed)
415         d->callbacks->split_changed (d, d->cb_data);
416     }
417 }
418
419 /* Sets N split vars SPLIT in dictionary D. */
420 void
421 dict_set_split_vars (struct dictionary *d,
422                      struct variable *const *split, size_t n,
423                      enum split_type type)
424 {
425   dict_set_split_vars__ (d, split, n, type, false);
426 }
427
428 void
429 dict_clear_split_vars (struct dictionary *d)
430 {
431   dict_set_split_vars (d, NULL, 0, SPLIT_NONE);
432 }
433 \f
434
435 /* Deletes variable V from dictionary D and frees V.
436
437    This is a very bad idea if there might be any pointers to V
438    from outside D.  In general, no variable in the active dataset's
439    dictionary should be deleted when any transformations are
440    active on the dictionary's dataset, because those
441    transformations might reference the deleted variable.  The
442    safest time to delete a variable is just after a procedure has
443    been executed, as done by DELETE VARIABLES.
444
445    Pointers to V within D are not a problem, because
446    dict_delete_var() knows to remove V from split variables,
447    weights, filters, etc. */
448 static void
449 dict_delete_var__ (struct dictionary *d, struct variable *v, bool skip_callbacks)
450 {
451   int dict_index = var_get_dict_index (v);
452   const int case_index = var_get_case_index (v);
453
454   assert (dict_contains_var (d, v));
455
456   dict_unset_split_var (d, v, skip_callbacks);
457   dict_unset_mrset_var (d, v);
458
459   if (d->weight == v)
460     dict_set_weight (d, NULL);
461
462   if (d->filter == v)
463     dict_set_filter (d, NULL);
464
465   dict_clear_vectors (d);
466
467   /* Remove V from var array. */
468   unindex_vars (d, dict_index, d->n_vars);
469   remove_element (d->vars, d->n_vars, sizeof *d->vars, dict_index);
470   d->n_vars--;
471
472   /* Update dict_index for each affected variable. */
473   reindex_vars (d, dict_index, d->n_vars, skip_callbacks);
474
475   /* Free memory. */
476   var_clear_vardict (v);
477
478   if (! skip_callbacks)
479     {
480       if (d->changed) d->changed (d, d->changed_data);
481       if (d->callbacks &&  d->callbacks->var_deleted)
482         d->callbacks->var_deleted (d, v, dict_index, case_index, d->cb_data);
483     }
484
485   invalidate_proto (d);
486   var_unref (v);
487 }
488
489 /* Deletes variable V from dictionary D and frees V.
490
491    This is a very bad idea if there might be any pointers to V
492    from outside D.  In general, no variable in the active dataset's
493    dictionary should be deleted when any transformations are
494    active on the dictionary's dataset, because those
495    transformations might reference the deleted variable.  The
496    safest time to delete a variable is just after a procedure has
497    been executed, as done by DELETE VARIABLES.
498
499    Pointers to V within D are not a problem, because
500    dict_delete_var() knows to remove V from split variables,
501    weights, filters, etc. */
502 void
503 dict_delete_var (struct dictionary *d, struct variable *v)
504 {
505   dict_delete_var__ (d, v, false);
506 }
507
508
509 /* Deletes the COUNT variables listed in VARS from D.  This is
510    unsafe; see the comment on dict_delete_var() for details. */
511 void
512 dict_delete_vars (struct dictionary *d,
513                   struct variable *const *vars, size_t count)
514 {
515   /* FIXME: this can be done in O(count) time, but this algorithm
516      is O(count**2). */
517   assert (count == 0 || vars != NULL);
518
519   while (count-- > 0)
520     dict_delete_var (d, *vars++);
521 }
522
523 /* Deletes the COUNT variables in D starting at index IDX.  This
524    is unsafe; see the comment on dict_delete_var() for
525    details. Deleting consecutive vars will result in less callbacks
526    compared to iterating over dict_delete_var.
527    A simple while loop over dict_delete_var will
528    produce (d->n_vars - IDX) * COUNT variable changed callbacks
529    plus COUNT variable delete callbacks.
530    This here produces d->n_vars - IDX variable changed callbacks
531    plus COUNT variable delete callbacks. */
532 void
533 dict_delete_consecutive_vars (struct dictionary *d, size_t idx, size_t count)
534 {
535   assert (idx + count <= d->n_vars);
536
537   /* We need to store the variable and the corresponding case_index
538      for the delete callbacks later. We store them in a linked list.*/
539   struct delvar {
540     struct ll ll;
541     struct variable *var;
542     int case_index;
543   };
544   struct ll_list list = LL_INITIALIZER (list);
545
546   for (size_t i = idx; i < idx + count; i++)
547     {
548       struct delvar *dv = xmalloc (sizeof (struct delvar));
549       assert (dv);
550       struct variable *v = d->vars[i].var;
551
552       dict_unset_split_var (d, v, false);
553       dict_unset_mrset_var (d, v);
554
555       if (d->weight == v)
556         dict_set_weight (d, NULL);
557
558       if (d->filter == v)
559         dict_set_filter (d, NULL);
560
561       dv->var = v;
562       dv->case_index = var_get_case_index (v);
563       ll_push_tail (&list, (struct ll *)dv);
564     }
565
566   dict_clear_vectors (d);
567
568   /* Remove variables from var array. */
569   unindex_vars (d, idx, d->n_vars);
570   remove_range (d->vars, d->n_vars, sizeof *d->vars, idx, count);
571   d->n_vars -= count;
572
573   /* Reindexing will result variable-changed callback */
574   reindex_vars (d, idx, d->n_vars, false);
575
576   invalidate_proto (d);
577   if (d->changed) d->changed (d, d->changed_data);
578
579   /* Now issue the variable delete callbacks and delete
580      the variables. The vardict is not valid at this point
581      anymore. That is the reason why we stored the
582      caseindex before reindexing. */
583   for (size_t vi = idx; vi < idx + count; vi++)
584     {
585       struct delvar *dv = (struct delvar *) ll_pop_head (&list);
586       var_clear_vardict (dv->var);
587       if (d->callbacks &&  d->callbacks->var_deleted)
588         d->callbacks->var_deleted (d, dv->var, vi, dv->case_index, d->cb_data);
589       var_unref (dv->var);
590       free (dv);
591     }
592 }
593
594 /* Deletes scratch variables from dictionary D. */
595 void
596 dict_delete_scratch_vars (struct dictionary *d)
597 {
598   int i;
599
600   /* FIXME: this can be done in O(count) time, but this algorithm
601      is O(count**2). */
602   for (i = 0; i < d->n_vars;)
603     if (var_get_dict_class (d->vars[i].var) == DC_SCRATCH)
604       dict_delete_var (d, d->vars[i].var);
605     else
606       i++;
607 }
608
609 \f
610
611 /* Clears the contents from a dictionary without destroying the
612    dictionary itself. */
613 static void
614 dict_clear__ (struct dictionary *d, bool skip_callbacks)
615 {
616   /* FIXME?  Should we really clear case_limit, label, documents?
617      Others are necessarily cleared by deleting all the variables.*/
618   while (d->n_vars > 0)
619     {
620       dict_delete_var__ (d, d->vars[d->n_vars - 1].var, skip_callbacks);
621     }
622
623   free (d->vars);
624   d->vars = NULL;
625   d->n_vars = d->allocated_vars = 0;
626   invalidate_proto (d);
627   hmap_clear (&d->name_map);
628   d->next_value_idx = 0;
629   dict_set_split_vars__ (d, NULL, 0, SPLIT_NONE, skip_callbacks);
630
631   if (skip_callbacks)
632     {
633       d->weight = NULL;
634       d->filter = NULL;
635     }
636   else
637     {
638       dict_set_weight (d, NULL);
639       dict_set_filter (d, NULL);
640     }
641   d->case_limit = 0;
642   free (d->label);
643   d->label = NULL;
644   string_array_clear (&d->documents);
645   dict_clear_vectors (d);
646   attrset_clear (&d->attributes);
647 }
648
649 /* Clears the contents from a dictionary without destroying the
650    dictionary itself. */
651 void
652 dict_clear (struct dictionary *d)
653 {
654   dict_clear__ (d, false);
655 }
656
657 /* Clears a dictionary and destroys it. */
658 static void
659 _dict_destroy (struct dictionary *d)
660 {
661   /* In general, we don't want callbacks occurring, if the dictionary
662      is being destroyed */
663   d->callbacks  = NULL ;
664
665   dict_clear__ (d, true);
666   string_array_destroy (&d->documents);
667   hmap_destroy (&d->name_map);
668   attrset_destroy (&d->attributes);
669   dict_clear_mrsets (d);
670   free (d->encoding);
671   free (d);
672 }
673
674 struct dictionary *
675 dict_ref (struct dictionary *d)
676 {
677   d->ref_cnt++;
678   return d;
679 }
680
681 void
682 dict_unref (struct dictionary *d)
683 {
684   if (d == NULL)
685     return;
686   d->ref_cnt--;
687   assert (d->ref_cnt >= 0);
688   if (d->ref_cnt == 0)
689     _dict_destroy (d);
690 }
691
692 /* Returns the number of variables in D. */
693 size_t
694 dict_get_n_vars (const struct dictionary *d)
695 {
696   return d->n_vars;
697 }
698
699 /* Returns the variable in D with dictionary index IDX, which
700    must be between 0 and the count returned by
701    dict_get_n_vars(), exclusive. */
702 struct variable *
703 dict_get_var (const struct dictionary *d, size_t idx)
704 {
705   assert (idx < d->n_vars);
706
707   return d->vars[idx].var;
708 }
709
710 /* Sets *VARS to an array of pointers to variables in D and *N
711    to the number of variables in *D.  All variables are returned
712    except for those, if any, in the classes indicated by EXCLUDE.
713    (There is no point in putting DC_SYSTEM in EXCLUDE as
714    dictionaries never include system variables.) */
715 void
716 dict_get_vars (const struct dictionary *d, const struct variable ***vars,
717                size_t *n, enum dict_class exclude)
718 {
719   dict_get_vars_mutable (d, (struct variable ***) vars, n, exclude);
720 }
721
722 /* Sets *VARS to an array of pointers to variables in D and *N
723    to the number of variables in *D.  All variables are returned
724    except for those, if any, in the classes indicated by EXCLUDE.
725    (There is no point in putting DC_SYSTEM in EXCLUDE as
726    dictionaries never include system variables.) */
727 void
728 dict_get_vars_mutable (const struct dictionary *d, struct variable ***vars,
729                        size_t *n, enum dict_class exclude)
730 {
731   size_t count;
732   size_t i;
733
734   assert (exclude == (exclude & DC_ALL));
735
736   count = 0;
737   for (i = 0; i < d->n_vars; i++)
738     {
739       enum dict_class class = var_get_dict_class (d->vars[i].var);
740       if (!(class & exclude))
741         count++;
742     }
743
744   *vars = xnmalloc (count, sizeof **vars);
745   *n = 0;
746   for (i = 0; i < d->n_vars; i++)
747     {
748       enum dict_class class = var_get_dict_class (d->vars[i].var);
749       if (!(class & exclude))
750         (*vars)[(*n)++] = d->vars[i].var;
751     }
752   assert (*n == count);
753 }
754
755 static struct variable *
756 add_var_with_case_index (struct dictionary *d, struct variable *v,
757                          int case_index)
758 {
759   struct vardict_info *vardict;
760
761   assert (case_index >= d->next_value_idx);
762
763   /* Update dictionary. */
764   if (d->n_vars >= d->allocated_vars)
765     {
766       size_t i;
767
768       d->vars = x2nrealloc (d->vars, &d->allocated_vars, sizeof *d->vars);
769       hmap_clear (&d->name_map);
770       for (i = 0; i < d->n_vars; i++)
771         {
772           var_set_vardict (d->vars[i].var, &d->vars[i]);
773           hmap_insert_fast (&d->name_map, &d->vars[i].name_node,
774                             d->vars[i].name_node.hash);
775         }
776     }
777
778   vardict = &d->vars[d->n_vars++];
779   vardict->dict = d;
780   vardict->var = v;
781   hmap_insert (&d->name_map, &vardict->name_node,
782                utf8_hash_case_string (var_get_name (v), 0));
783   vardict->case_index = case_index;
784   var_set_vardict (v, vardict);
785
786   if (d->changed) d->changed (d, d->changed_data);
787   if (d->callbacks &&  d->callbacks->var_added)
788     d->callbacks->var_added (d, var_get_dict_index (v), d->cb_data);
789
790   invalidate_proto (d);
791   d->next_value_idx = case_index + 1;
792
793   return v;
794 }
795
796 static struct variable *
797 add_var (struct dictionary *d, struct variable *v)
798 {
799   return add_var_with_case_index (d, v, d->next_value_idx);
800 }
801
802 /* Creates and returns a new variable in D with the given NAME
803    and WIDTH.  Returns a null pointer if the given NAME would
804    duplicate that of an existing variable in the dictionary. */
805 struct variable *
806 dict_create_var (struct dictionary *d, const char *name, int width)
807 {
808   return (dict_lookup_var (d, name) == NULL
809           ? dict_create_var_assert (d, name, width)
810           : NULL);
811 }
812
813 /* Creates and returns a new variable in D with the given NAME
814    and WIDTH.  Assert-fails if the given NAME would duplicate
815    that of an existing variable in the dictionary. */
816 struct variable *
817 dict_create_var_assert (struct dictionary *d, const char *name, int width)
818 {
819   assert (dict_lookup_var (d, name) == NULL);
820   return add_var (d, var_create (name, width));
821 }
822
823 /* Creates and returns a new variable in D, as a copy of existing variable
824    OLD_VAR, which need not be in D or in any dictionary.  Returns a null
825    pointer if OLD_VAR's name would duplicate that of an existing variable in
826    the dictionary. */
827 struct variable *
828 dict_clone_var (struct dictionary *d, const struct variable *old_var)
829 {
830   return dict_clone_var_as (d, old_var, var_get_name (old_var));
831 }
832
833 /* Creates and returns a new variable in D, as a copy of existing variable
834    OLD_VAR, which need not be in D or in any dictionary.  Assert-fails if
835    OLD_VAR's name would duplicate that of an existing variable in the
836    dictionary. */
837 struct variable *
838 dict_clone_var_assert (struct dictionary *d, const struct variable *old_var)
839 {
840   return dict_clone_var_as_assert (d, old_var, var_get_name (old_var));
841 }
842
843 /* Creates and returns a new variable in D with name NAME, as a copy of
844    existing variable OLD_VAR, which need not be in D or in any dictionary.
845    Returns a null pointer if the given NAME would duplicate that of an existing
846    variable in the dictionary. */
847 struct variable *
848 dict_clone_var_as (struct dictionary *d, const struct variable *old_var,
849                    const char *name)
850 {
851   return (dict_lookup_var (d, name) == NULL
852           ? dict_clone_var_as_assert (d, old_var, name)
853           : NULL);
854 }
855
856 /* Creates and returns a new variable in D with name NAME, as a copy of
857    existing variable OLD_VAR, which need not be in D or in any dictionary.
858    Assert-fails if the given NAME would duplicate that of an existing variable
859    in the dictionary. */
860 struct variable *
861 dict_clone_var_as_assert (struct dictionary *d, const struct variable *old_var,
862                           const char *name)
863 {
864   struct variable *new_var = var_clone (old_var);
865   assert (dict_lookup_var (d, name) == NULL);
866   var_set_name (new_var, name);
867   return add_var (d, new_var);
868 }
869
870 struct variable *
871 dict_clone_var_in_place_assert (struct dictionary *d,
872                                 const struct variable *old_var)
873 {
874   assert (dict_lookup_var (d, var_get_name (old_var)) == NULL);
875   return add_var_with_case_index (d, var_clone (old_var),
876                                   var_get_case_index (old_var));
877 }
878
879 /* Returns the variable named NAME in D, or a null pointer if no
880    variable has that name. */
881 struct variable *
882 dict_lookup_var (const struct dictionary *d, const char *name)
883 {
884   struct vardict_info *vardict;
885
886   HMAP_FOR_EACH_WITH_HASH (vardict, struct vardict_info, name_node,
887                            utf8_hash_case_string (name, 0), &d->name_map)
888     {
889       struct variable *var = vardict->var;
890       if (!utf8_strcasecmp (var_get_name (var), name))
891         return var;
892     }
893
894   return NULL;
895 }
896
897 /* Returns the variable named NAME in D.  Assert-fails if no
898    variable has that name. */
899 struct variable *
900 dict_lookup_var_assert (const struct dictionary *d, const char *name)
901 {
902   struct variable *v = dict_lookup_var (d, name);
903   assert (v != NULL);
904   return v;
905 }
906
907 /* Returns true if variable V is in dictionary D,
908    false otherwise. */
909 bool
910 dict_contains_var (const struct dictionary *d, const struct variable *v)
911 {
912   return (var_has_vardict (v)
913           && vardict_get_dictionary (var_get_vardict (v)) == d);
914 }
915
916 /* Moves V to 0-based position IDX in D.  Other variables in D,
917    if any, retain their relative positions.  Runs in time linear
918    in the distance moved. */
919 void
920 dict_reorder_var (struct dictionary *d, struct variable *v, size_t new_index)
921 {
922   size_t old_index = var_get_dict_index (v);
923
924   assert (new_index < d->n_vars);
925
926   unindex_vars (d, MIN (old_index, new_index), MAX (old_index, new_index) + 1);
927   move_element (d->vars, d->n_vars, sizeof *d->vars, old_index, new_index);
928   reindex_vars (d, MIN (old_index, new_index), MAX (old_index, new_index) + 1, false);
929 }
930
931 /* Reorders the variables in D, placing the COUNT variables
932    listed in ORDER in that order at the beginning of D.  The
933    other variables in D, if any, retain their relative
934    positions. */
935 void
936 dict_reorder_vars (struct dictionary *d,
937                    struct variable *const *order, size_t count)
938 {
939   struct vardict_info *new_var;
940   size_t i;
941
942   assert (count == 0 || order != NULL);
943   assert (count <= d->n_vars);
944
945   new_var = xnmalloc (d->allocated_vars, sizeof *new_var);
946
947   /* Add variables in ORDER to new_var. */
948   for (i = 0; i < count; i++)
949     {
950       struct vardict_info *old_var;
951
952       assert (dict_contains_var (d, order[i]));
953
954       old_var = var_get_vardict (order[i]);
955       new_var[i] = *old_var;
956       old_var->dict = NULL;
957     }
958
959   /* Add remaining variables to new_var. */
960   for (i = 0; i < d->n_vars; i++)
961     if (d->vars[i].dict != NULL)
962       new_var[count++] = d->vars[i];
963   assert (count == d->n_vars);
964
965   /* Replace old vardicts by new ones. */
966   free (d->vars);
967   d->vars = new_var;
968
969   hmap_clear (&d->name_map);
970   reindex_vars (d, 0, d->n_vars, false);
971 }
972
973 /* Changes the name of variable V that is currently in a dictionary to
974    NEW_NAME. */
975 static void
976 rename_var (struct variable *v, const char *new_name)
977 {
978   struct vardict_info *vardict = var_get_vardict (v);
979   var_clear_vardict (v);
980   var_set_name (v, new_name);
981   vardict->name_node.hash = utf8_hash_case_string (new_name, 0);
982   var_set_vardict (v, vardict);
983 }
984
985 /* Tries to changes the name of V in D to name NEW_NAME.  Returns true if
986    successful, false if a variable (other than V) with the given name already
987    exists in D. */
988 bool
989 dict_try_rename_var (struct dictionary *d, struct variable *v,
990                      const char *new_name)
991 {
992   struct variable *conflict = dict_lookup_var (d, new_name);
993   if (conflict && v != conflict)
994     return false;
995
996   struct variable *old = var_clone (v);
997   unindex_var (d, var_get_vardict (v));
998   rename_var (v, new_name);
999   reindex_var (d, var_get_vardict (v), false);
1000
1001   if (settings_get_algorithm () == ENHANCED)
1002     var_clear_short_names (v);
1003
1004   if (d->changed) d->changed (d, d->changed_data);
1005   if (d->callbacks &&  d->callbacks->var_changed)
1006     d->callbacks->var_changed (d, var_get_dict_index (v), VAR_TRAIT_NAME, old, d->cb_data);
1007
1008   var_unref (old);
1009
1010   return true;
1011 }
1012
1013 /* Changes the name of V in D to name NEW_NAME.  Assert-fails if
1014    a variable named NEW_NAME is already in D, except that
1015    NEW_NAME may be the same as V's existing name. */
1016 void
1017 dict_rename_var (struct dictionary *d, struct variable *v,
1018                  const char *new_name)
1019 {
1020   bool ok UNUSED = dict_try_rename_var (d, v, new_name);
1021   assert (ok);
1022 }
1023
1024 /* Renames COUNT variables specified in VARS to the names given
1025    in NEW_NAMES within dictionary D.  If the renaming would
1026    result in a duplicate variable name, returns false and stores a
1027    name that would be duplicated into *ERR_NAME (if ERR_NAME is
1028    non-null).  Otherwise, the renaming is successful, and true
1029    is returned. */
1030 bool
1031 dict_rename_vars (struct dictionary *d,
1032                   struct variable **vars, char **new_names, size_t count,
1033                   char **err_name)
1034 {
1035   struct pool *pool;
1036   char **old_names;
1037   size_t i;
1038
1039   assert (count == 0 || vars != NULL);
1040   assert (count == 0 || new_names != NULL);
1041
1042   /* Save the names of the variables to be renamed. */
1043   pool = pool_create ();
1044   old_names = pool_nalloc (pool, count, sizeof *old_names);
1045   for (i = 0; i < count; i++)
1046     old_names[i] = pool_strdup (pool, var_get_name (vars[i]));
1047
1048   /* Remove the variables to be renamed from the name hash,
1049      and rename them. */
1050   for (i = 0; i < count; i++)
1051     {
1052       unindex_var (d, var_get_vardict (vars[i]));
1053       rename_var (vars[i], new_names[i]);
1054     }
1055
1056   /* Add the renamed variables back into the name hash,
1057      checking for conflicts. */
1058   for (i = 0; i < count; i++)
1059     {
1060       if (dict_lookup_var (d, var_get_name (vars[i])) != NULL)
1061         {
1062           /* There is a name conflict.
1063              Back out all the name changes that have already
1064              taken place, and indicate failure. */
1065           size_t fail_idx = i;
1066           if (err_name != NULL)
1067             *err_name = new_names[i];
1068
1069           for (i = 0; i < fail_idx; i++)
1070             unindex_var (d, var_get_vardict (vars[i]));
1071
1072           for (i = 0; i < count; i++)
1073             {
1074               rename_var (vars[i], old_names[i]);
1075               reindex_var (d, var_get_vardict (vars[i]), false);
1076             }
1077
1078           pool_destroy (pool);
1079           return false;
1080         }
1081       reindex_var (d, var_get_vardict (vars[i]), false);
1082     }
1083
1084   /* Clear short names. */
1085   if (settings_get_algorithm () == ENHANCED)
1086     for (i = 0; i < count; i++)
1087       var_clear_short_names (vars[i]);
1088
1089   pool_destroy (pool);
1090   return true;
1091 }
1092
1093 /* Returns true if a variable named NAME may be inserted in DICT;
1094    that is, if there is not already a variable with that name in
1095    DICT and if NAME is not a reserved word.  (The caller's checks
1096    have already verified that NAME is otherwise acceptable as a
1097    variable name.) */
1098 static bool
1099 var_name_is_insertable (const struct dictionary *dict, const char *name)
1100 {
1101   return (dict_lookup_var (dict, name) == NULL
1102           && lex_id_to_token (ss_cstr (name)) == T_ID);
1103 }
1104
1105 static char *
1106 make_hinted_name (const struct dictionary *dict, const char *hint)
1107 {
1108   size_t hint_len = strlen (hint);
1109   bool dropped = false;
1110   char *root, *rp;
1111   size_t ofs;
1112   int mblen;
1113
1114   if (hint_len > ID_MAX_LEN)
1115     hint_len = ID_MAX_LEN;
1116
1117   /* The allocation size here is OK: characters that are copied directly fit
1118      OK, and characters that are not copied directly are replaced by a single
1119      '_' byte.  If u8_mbtouc() replaces bad input by 0xfffd, then that will get
1120      replaced by '_' too.  */
1121   root = rp = xmalloc (hint_len + 1);
1122   for (ofs = 0; ofs < hint_len; ofs += mblen)
1123     {
1124       ucs4_t uc;
1125
1126       mblen = u8_mbtouc (&uc, CHAR_CAST (const uint8_t *, hint + ofs),
1127                          hint_len - ofs);
1128       if (rp == root
1129           ? lex_uc_is_id1 (uc) && uc != '$'
1130           : lex_uc_is_idn (uc))
1131         {
1132           if (dropped)
1133             {
1134               *rp++ = '_';
1135               dropped = false;
1136             }
1137           rp += u8_uctomb (CHAR_CAST (uint8_t *, rp), uc, 6);
1138         }
1139       else if (rp != root)
1140         dropped = true;
1141     }
1142   *rp = '\0';
1143
1144   if (root[0] != '\0')
1145     {
1146       unsigned long int i;
1147
1148       if (var_name_is_insertable (dict, root))
1149         return root;
1150
1151       for (i = 0; i < ULONG_MAX; i++)
1152         {
1153           char suffix[INT_BUFSIZE_BOUND (i) + 1];
1154           char *name;
1155
1156           suffix[0] = '_';
1157           if (!str_format_26adic (i + 1, true, &suffix[1], sizeof suffix - 1))
1158             NOT_REACHED ();
1159
1160           name = utf8_encoding_concat (root, suffix, dict->encoding, 64);
1161           if (var_name_is_insertable (dict, name))
1162             {
1163               free (root);
1164               return name;
1165             }
1166           free (name);
1167         }
1168     }
1169
1170   free (root);
1171
1172   return NULL;
1173 }
1174
1175 static char *
1176 make_numeric_name (const struct dictionary *dict, unsigned long int *num_start)
1177 {
1178   unsigned long int number;
1179
1180   for (number = num_start != NULL ? MAX (*num_start, 1) : 1;
1181        number < ULONG_MAX;
1182        number++)
1183     {
1184       char name[3 + INT_STRLEN_BOUND (number) + 1];
1185
1186       sprintf (name, "VAR%03lu", number);
1187       if (dict_lookup_var (dict, name) == NULL)
1188         {
1189           if (num_start != NULL)
1190             *num_start = number + 1;
1191           return xstrdup (name);
1192         }
1193     }
1194
1195   NOT_REACHED ();
1196 }
1197
1198
1199 /* Devises and returns a variable name unique within DICT.  The variable name
1200    is owned by the caller, which must free it with free() when it is no longer
1201    needed.
1202
1203    HINT, if it is non-null, is used as a suggestion that will be
1204    modified for suitability as a variable name and for
1205    uniqueness.
1206
1207    If HINT is null or entirely unsuitable, a name in the form
1208    "VAR%03d" will be generated, where the smallest unused integer
1209    value is used.  If NUM_START is non-null, then its value is
1210    used as the minimum numeric value to check, and it is updated
1211    to the next value to be checked.
1212 */
1213 char *
1214 dict_make_unique_var_name (const struct dictionary *dict, const char *hint,
1215                            unsigned long int *num_start)
1216 {
1217   if (hint != NULL)
1218     {
1219       char *hinted_name = make_hinted_name (dict, hint);
1220       if (hinted_name != NULL)
1221         return hinted_name;
1222     }
1223
1224   return make_numeric_name (dict, num_start);
1225 }
1226
1227 /* Returns whether variable names must be valid identifiers.  Normally, this is
1228    true, but sometimes a dictionary is prepared for external use (e.g. output
1229    to a CSV file) where names don't have to be valid. */
1230 bool
1231 dict_get_names_must_be_ids (const struct dictionary *d)
1232 {
1233   return d->names_must_be_ids;
1234 }
1235
1236 /* Sets whether variable names must be valid identifiers.  Normally, this is
1237    true, but sometimes a dictionary is prepared for external use (e.g. output
1238    to a CSV file) where names don't have to be valid.
1239
1240    Changing this setting from false to true doesn't make the dictionary check
1241    all the existing variable names, so it can cause an invariant violation. */
1242 void
1243 dict_set_names_must_be_ids (struct dictionary *d, bool names_must_be_ids)
1244 {
1245   d->names_must_be_ids = names_must_be_ids;
1246 }
1247
1248 /* Returns the weighting variable in dictionary D, or a null
1249    pointer if the dictionary is unweighted. */
1250 struct variable *
1251 dict_get_weight (const struct dictionary *d)
1252 {
1253   assert (d->weight == NULL || dict_contains_var (d, d->weight));
1254
1255   return d->weight;
1256 }
1257
1258 /* Returns the value of D's weighting variable in case C, except
1259    that a negative weight is returned as 0.  Returns 1 if the
1260    dictionary is unweighted.  Will warn about missing, negative,
1261    or zero values if *WARN_ON_INVALID is true.  The function will
1262    set *WARN_ON_INVALID to false if an invalid weight is
1263    found. */
1264 double
1265 dict_get_case_weight (const struct dictionary *d, const struct ccase *c,
1266                       bool *warn_on_invalid)
1267 {
1268   assert (c != NULL);
1269
1270   if (d->weight == NULL)
1271     return 1.0;
1272   else
1273     {
1274       double w = case_num (c, d->weight);
1275
1276       return var_force_valid_weight (d->weight, w, warn_on_invalid);
1277     }
1278 }
1279
1280 /* Returns the format to use for weights. */
1281 const struct fmt_spec *
1282 dict_get_weight_format (const struct dictionary *d)
1283 {
1284   return d->weight ? var_get_print_format (d->weight) : &F_8_0;
1285 }
1286
1287 /* Sets the weighting variable of D to V, or turning off
1288    weighting if V is a null pointer. */
1289 void
1290 dict_set_weight (struct dictionary *d, struct variable *v)
1291 {
1292   assert (v == NULL || dict_contains_var (d, v));
1293   assert (v == NULL || var_is_numeric (v));
1294
1295   d->weight = v;
1296
1297   if (d->changed) d->changed (d, d->changed_data);
1298   if (d->callbacks &&  d->callbacks->weight_changed)
1299     d->callbacks->weight_changed (d,
1300                                   v ? var_get_dict_index (v) : -1,
1301                                   d->cb_data);
1302 }
1303
1304 /* Returns the filter variable in dictionary D (see cmd_filter())
1305    or a null pointer if the dictionary is unfiltered. */
1306 struct variable *
1307 dict_get_filter (const struct dictionary *d)
1308 {
1309   assert (d->filter == NULL || dict_contains_var (d, d->filter));
1310
1311   return d->filter;
1312 }
1313
1314 /* Sets V as the filter variable for dictionary D.  Passing a
1315    null pointer for V turn off filtering. */
1316 void
1317 dict_set_filter (struct dictionary *d, struct variable *v)
1318 {
1319   assert (v == NULL || dict_contains_var (d, v));
1320   assert (v == NULL || var_is_numeric (v));
1321
1322   d->filter = v;
1323
1324   if (d->changed) d->changed (d, d->changed_data);
1325   if (d->callbacks && d->callbacks->filter_changed)
1326     d->callbacks->filter_changed (d,
1327                                   v ? var_get_dict_index (v) : -1,
1328                                       d->cb_data);
1329 }
1330
1331 /* Returns the case limit for dictionary D, or zero if the number
1332    of cases is unlimited. */
1333 casenumber
1334 dict_get_case_limit (const struct dictionary *d)
1335 {
1336   return d->case_limit;
1337 }
1338
1339 /* Sets CASE_LIMIT as the case limit for dictionary D.  Use
1340    0 for CASE_LIMIT to indicate no limit. */
1341 void
1342 dict_set_case_limit (struct dictionary *d, casenumber case_limit)
1343 {
1344   d->case_limit = case_limit;
1345 }
1346
1347 /* Returns the prototype used for cases created by dictionary D. */
1348 const struct caseproto *
1349 dict_get_proto (const struct dictionary *d_)
1350 {
1351   struct dictionary *d = CONST_CAST (struct dictionary *, d_);
1352   if (d->proto == NULL)
1353     {
1354       size_t i;
1355
1356       d->proto = caseproto_create ();
1357       d->proto = caseproto_reserve (d->proto, d->n_vars);
1358       for (i = 0; i < d->n_vars; i++)
1359         d->proto = caseproto_set_width (d->proto,
1360                                         var_get_case_index (d->vars[i].var),
1361                                         var_get_width (d->vars[i].var));
1362     }
1363   return d->proto;
1364 }
1365
1366 /* Returns the case index of the next value to be added to D.
1367    This value is the number of `union value's that need to be
1368    allocated to store a case for dictionary D. */
1369 int
1370 dict_get_next_value_idx (const struct dictionary *d)
1371 {
1372   return d->next_value_idx;
1373 }
1374
1375 /* Returns the number of bytes needed to store a case for
1376    dictionary D. */
1377 size_t
1378 dict_get_case_size (const struct dictionary *d)
1379 {
1380   return sizeof (union value) * dict_get_next_value_idx (d);
1381 }
1382
1383 /* Reassigns values in dictionary D so that fragmentation is
1384    eliminated. */
1385 void
1386 dict_compact_values (struct dictionary *d)
1387 {
1388   size_t i;
1389
1390   d->next_value_idx = 0;
1391   for (i = 0; i < d->n_vars; i++)
1392     {
1393       struct variable *v = d->vars[i].var;
1394       set_var_case_index (v, d->next_value_idx++);
1395     }
1396   invalidate_proto (d);
1397 }
1398
1399 /* Returns the number of values occupied by the variables in
1400    dictionary D.  All variables are considered if EXCLUDE_CLASSES
1401    is 0, or it may contain one or more of (1u << DC_ORDINARY),
1402    (1u << DC_SYSTEM), or (1u << DC_SCRATCH) to exclude the
1403    corresponding type of variable.
1404
1405    The return value may be less than the number of values in one
1406    of dictionary D's cases (as returned by
1407    dict_get_next_value_idx) even if E is 0, because there may be
1408    gaps in D's cases due to deleted variables. */
1409 size_t
1410 dict_count_values (const struct dictionary *d, unsigned int exclude_classes)
1411 {
1412   assert ((exclude_classes & ~((1u << DC_ORDINARY)
1413                                | (1u << DC_SYSTEM)
1414                                | (1u << DC_SCRATCH))) == 0);
1415
1416   size_t n = 0;
1417   for (size_t i = 0; i < d->n_vars; i++)
1418     {
1419       enum dict_class class = var_get_dict_class (d->vars[i].var);
1420       if (!(exclude_classes & (1u << class)))
1421         n++;
1422     }
1423   return n;
1424 }
1425
1426 /* Returns the case prototype that would result after deleting
1427    all variables from D that are not in one of the
1428    EXCLUDE_CLASSES and compacting the dictionary with
1429    dict_compact().
1430
1431    The caller must unref the returned caseproto when it is no
1432    longer needed. */
1433 struct caseproto *
1434 dict_get_compacted_proto (const struct dictionary *d,
1435                           unsigned int exclude_classes)
1436 {
1437   struct caseproto *proto;
1438   size_t i;
1439
1440   assert ((exclude_classes & ~((1u << DC_ORDINARY)
1441                                | (1u << DC_SYSTEM)
1442                                | (1u << DC_SCRATCH))) == 0);
1443
1444   proto = caseproto_create ();
1445   for (i = 0; i < d->n_vars; i++)
1446     {
1447       struct variable *v = d->vars[i].var;
1448       if (!(exclude_classes & (1u << var_get_dict_class (v))))
1449         proto = caseproto_add_width (proto, var_get_width (v));
1450     }
1451   return proto;
1452 }
1453 /* Returns the file label for D, or a null pointer if D is
1454    unlabeled (see cmd_file_label()). */
1455 const char *
1456 dict_get_label (const struct dictionary *d)
1457 {
1458   return d->label;
1459 }
1460
1461 /* Sets D's file label to LABEL, truncating it to at most 60 bytes in D's
1462    encoding.
1463
1464    Removes D's label if LABEL is null or the empty string. */
1465 void
1466 dict_set_label (struct dictionary *d, const char *label)
1467 {
1468   free (d->label);
1469   if (label == NULL || label[0] == '\0')
1470     d->label = NULL;
1471   else
1472     d->label = utf8_encoding_trunc (label, d->encoding, 60);
1473 }
1474
1475 /* Returns the documents for D, as an UTF-8 encoded string_array.  The
1476    return value is always nonnull; if there are no documents then the
1477    string_arary is empty.*/
1478 const struct string_array *
1479 dict_get_documents (const struct dictionary *d)
1480 {
1481   return &d->documents;
1482 }
1483
1484 /* Replaces the documents for D by NEW_DOCS, a UTF-8 encoded string_array. */
1485 void
1486 dict_set_documents (struct dictionary *d, const struct string_array *new_docs)
1487 {
1488   /* Swap out the old documents, instead of destroying them immediately, to
1489      allow the new documents to include pointers into the old ones. */
1490   struct string_array old_docs = STRING_ARRAY_INITIALIZER;
1491   string_array_swap (&d->documents, &old_docs);
1492
1493   for (size_t i = 0; i < new_docs->n; i++)
1494     dict_add_document_line (d, new_docs->strings[i], false);
1495
1496   string_array_destroy (&old_docs);
1497 }
1498
1499 /* Replaces the documents for D by UTF-8 encoded string NEW_DOCS, dividing it
1500    into individual lines at new-line characters.  Each line is truncated to at
1501    most DOC_LINE_LENGTH bytes in D's encoding. */
1502 void
1503 dict_set_documents_string (struct dictionary *d, const char *new_docs)
1504 {
1505   const char *s;
1506
1507   dict_clear_documents (d);
1508   for (s = new_docs; *s != '\0';)
1509     {
1510       size_t len = strcspn (s, "\n");
1511       char *line = xmemdup0 (s, len);
1512       dict_add_document_line (d, line, false);
1513       free (line);
1514
1515       s += len;
1516       if (*s == '\n')
1517         s++;
1518     }
1519 }
1520
1521 /* Drops the documents from dictionary D. */
1522 void
1523 dict_clear_documents (struct dictionary *d)
1524 {
1525   string_array_clear (&d->documents);
1526 }
1527
1528 /* Appends the UTF-8 encoded LINE to the documents in D.  LINE will be
1529    truncated so that it is no more than 80 bytes in the dictionary's
1530    encoding.  If this causes some text to be lost, and ISSUE_WARNING is true,
1531    then a warning will be issued. */
1532 bool
1533 dict_add_document_line (struct dictionary *d, const char *line,
1534                         bool issue_warning)
1535 {
1536   size_t trunc_len;
1537   bool truncated;
1538
1539   trunc_len = utf8_encoding_trunc_len (line, d->encoding, DOC_LINE_LENGTH);
1540   truncated = line[trunc_len] != '\0';
1541   if (truncated && issue_warning)
1542     {
1543       /* TRANSLATORS: "bytes" is correct, not characters due to UTF encoding */
1544       msg (SW, _("Truncating document line to %d bytes."), DOC_LINE_LENGTH);
1545     }
1546
1547   string_array_append_nocopy (&d->documents, xmemdup0 (line, trunc_len));
1548
1549   return !truncated;
1550 }
1551
1552 /* Returns the number of document lines in dictionary D. */
1553 size_t
1554 dict_get_document_n_lines (const struct dictionary *d)
1555 {
1556   return d->documents.n;
1557 }
1558
1559 /* Returns document line number IDX in dictionary D.  The caller must not
1560    modify or free the returned string. */
1561 const char *
1562 dict_get_document_line (const struct dictionary *d, size_t idx)
1563 {
1564   assert (idx < d->documents.n);
1565   return d->documents.strings[idx];
1566 }
1567
1568 /* Creates in D a vector named NAME that contains the N
1569    variables in VAR.  Returns true if successful, or false if a
1570    vector named NAME already exists in D. */
1571 bool
1572 dict_create_vector (struct dictionary *d,
1573                     const char *name,
1574                     struct variable **var, size_t n)
1575 {
1576   assert (n > 0);
1577   for (size_t i = 0; i < n; i++)
1578     assert (dict_contains_var (d, var[i]));
1579
1580   if (dict_lookup_vector (d, name) == NULL)
1581     {
1582       d->vector = xnrealloc (d->vector, d->n_vectors + 1, sizeof *d->vector);
1583       d->vector[d->n_vectors++] = vector_create (name, var, n);
1584       return true;
1585     }
1586   else
1587     return false;
1588 }
1589
1590 /* Creates in D a vector named NAME that contains the N
1591    variables in VAR.  A vector named NAME must not already exist
1592    in D. */
1593 void
1594 dict_create_vector_assert (struct dictionary *d,
1595                            const char *name,
1596                            struct variable **var, size_t n)
1597 {
1598   assert (dict_lookup_vector (d, name) == NULL);
1599   dict_create_vector (d, name, var, n);
1600 }
1601
1602 /* Returns the vector in D with index IDX, which must be less
1603    than dict_get_n_vectors (D). */
1604 const struct vector *
1605 dict_get_vector (const struct dictionary *d, size_t idx)
1606 {
1607   assert (idx < d->n_vectors);
1608
1609   return d->vector[idx];
1610 }
1611
1612 /* Returns the number of vectors in D. */
1613 size_t
1614 dict_get_n_vectors (const struct dictionary *d)
1615 {
1616   return d->n_vectors;
1617 }
1618
1619 /* Looks up and returns the vector within D with the given
1620    NAME. */
1621 const struct vector *
1622 dict_lookup_vector (const struct dictionary *d, const char *name)
1623 {
1624   size_t i;
1625   for (i = 0; i < d->n_vectors; i++)
1626     if (!utf8_strcasecmp (vector_get_name (d->vector[i]), name))
1627       return d->vector[i];
1628   return NULL;
1629 }
1630
1631 /* Deletes all vectors from D. */
1632 void
1633 dict_clear_vectors (struct dictionary *d)
1634 {
1635   size_t i;
1636
1637   for (i = 0; i < d->n_vectors; i++)
1638     vector_destroy (d->vector[i]);
1639   free (d->vector);
1640
1641   d->vector = NULL;
1642   d->n_vectors = 0;
1643 }
1644 \f
1645 /* Multiple response sets. */
1646
1647 /* Returns the multiple response set in DICT with index IDX, which must be
1648    between 0 and the count returned by dict_get_n_mrsets(), exclusive. */
1649 const struct mrset *
1650 dict_get_mrset (const struct dictionary *dict, size_t idx)
1651 {
1652   assert (idx < dict->n_mrsets);
1653   return dict->mrsets[idx];
1654 }
1655
1656 /* Returns the number of multiple response sets in DICT. */
1657 size_t
1658 dict_get_n_mrsets (const struct dictionary *dict)
1659 {
1660   return dict->n_mrsets;
1661 }
1662
1663 /* Looks for a multiple response set named NAME in DICT.  If it finds one,
1664    returns its index; otherwise, returns SIZE_MAX. */
1665 static size_t
1666 dict_lookup_mrset_idx (const struct dictionary *dict, const char *name)
1667 {
1668   size_t i;
1669
1670   for (i = 0; i < dict->n_mrsets; i++)
1671     if (!utf8_strcasecmp (name, dict->mrsets[i]->name))
1672       return i;
1673
1674   return SIZE_MAX;
1675 }
1676
1677 /* Looks for a multiple response set named NAME in DICT.  If it finds one,
1678    returns it; otherwise, returns NULL. */
1679 const struct mrset *
1680 dict_lookup_mrset (const struct dictionary *dict, const char *name)
1681 {
1682   size_t idx = dict_lookup_mrset_idx (dict, name);
1683   return idx != SIZE_MAX ? dict->mrsets[idx] : NULL;
1684 }
1685
1686 /* Adds MRSET to DICT, replacing any existing set with the same name.  Returns
1687    true if a set was replaced, false if none existed with the specified name.
1688
1689    Ownership of MRSET is transferred to DICT. */
1690 bool
1691 dict_add_mrset (struct dictionary *dict, struct mrset *mrset)
1692 {
1693   size_t idx;
1694
1695   assert (mrset_ok (mrset, dict));
1696
1697   idx = dict_lookup_mrset_idx (dict, mrset->name);
1698   if (idx == SIZE_MAX)
1699     {
1700       dict->mrsets = xrealloc (dict->mrsets,
1701                                (dict->n_mrsets + 1) * sizeof *dict->mrsets);
1702       dict->mrsets[dict->n_mrsets++] = mrset;
1703       return true;
1704     }
1705   else
1706     {
1707       mrset_destroy (dict->mrsets[idx]);
1708       dict->mrsets[idx] = mrset;
1709       return false;
1710     }
1711 }
1712
1713 /* Looks for a multiple response set in DICT named NAME.  If found, removes it
1714    from DICT and returns true.  If none is found, returns false without
1715    modifying DICT.
1716
1717    Deleting one multiple response set causes the indexes of other sets within
1718    DICT to change. */
1719 bool
1720 dict_delete_mrset (struct dictionary *dict, const char *name)
1721 {
1722   size_t idx = dict_lookup_mrset_idx (dict, name);
1723   if (idx != SIZE_MAX)
1724     {
1725       mrset_destroy (dict->mrsets[idx]);
1726       dict->mrsets[idx] = dict->mrsets[--dict->n_mrsets];
1727       return true;
1728     }
1729   else
1730     return false;
1731 }
1732
1733 /* Deletes all multiple response sets from DICT. */
1734 void
1735 dict_clear_mrsets (struct dictionary *dict)
1736 {
1737   size_t i;
1738
1739   for (i = 0; i < dict->n_mrsets; i++)
1740     mrset_destroy (dict->mrsets[i]);
1741   free (dict->mrsets);
1742   dict->mrsets = NULL;
1743   dict->n_mrsets = 0;
1744 }
1745
1746 /* Removes VAR, which must be in DICT, from DICT's multiple response sets. */
1747 static void
1748 dict_unset_mrset_var (struct dictionary *dict, struct variable *var)
1749 {
1750   size_t i;
1751
1752   assert (dict_contains_var (dict, var));
1753
1754   for (i = 0; i < dict->n_mrsets;)
1755     {
1756       struct mrset *mrset = dict->mrsets[i];
1757       size_t j;
1758
1759       for (j = 0; j < mrset->n_vars;)
1760         if (mrset->vars[j] == var)
1761           remove_element (mrset->vars, mrset->n_vars--,
1762                           sizeof *mrset->vars, j);
1763         else
1764           j++;
1765
1766       if (mrset->n_vars < 2)
1767         {
1768           mrset_destroy (mrset);
1769           dict->mrsets[i] = dict->mrsets[--dict->n_mrsets];
1770         }
1771       else
1772         i++;
1773     }
1774 }
1775 \f
1776 /* Returns D's attribute set.  The caller may examine or modify
1777    the attribute set, but must not destroy it.  Destroying D or
1778    calling dict_set_attributes for D will also destroy D's
1779    attribute set. */
1780 struct attrset *
1781 dict_get_attributes (const struct dictionary *d)
1782 {
1783   return CONST_CAST (struct attrset *, &d->attributes);
1784 }
1785
1786 /* Replaces D's attributes set by a copy of ATTRS. */
1787 void
1788 dict_set_attributes (struct dictionary *d, const struct attrset *attrs)
1789 {
1790   attrset_destroy (&d->attributes);
1791   attrset_clone (&d->attributes, attrs);
1792 }
1793
1794 /* Returns true if D has at least one attribute in its attribute
1795    set, false if D's attribute set is empty. */
1796 bool
1797 dict_has_attributes (const struct dictionary *d)
1798 {
1799   return attrset_count (&d->attributes) > 0;
1800 }
1801
1802 /* Called from variable.c to notify the dictionary that some property (indicated
1803    by WHAT) of the variable has changed.  OLDVAR is a copy of V as it existed
1804    prior to the change.  OLDVAR is destroyed by this function.
1805 */
1806 void
1807 dict_var_changed (const struct variable *v, unsigned int what, struct variable *oldvar)
1808 {
1809   if (var_has_vardict (v))
1810     {
1811       const struct vardict_info *vardict = var_get_vardict (v);
1812       struct dictionary *d = vardict->dict;
1813
1814       if (NULL == d)
1815         return;
1816
1817       if (what & (VAR_TRAIT_WIDTH | VAR_TRAIT_POSITION))
1818         invalidate_proto (d);
1819
1820       if (d->changed) d->changed (d, d->changed_data);
1821       if (d->callbacks && d->callbacks->var_changed)
1822         d->callbacks->var_changed (d, var_get_dict_index (v), what, oldvar, d->cb_data);
1823     }
1824   var_unref (oldvar);
1825 }
1826
1827
1828 \f
1829 /* Dictionary used to contain "internal variables". */
1830 static struct dictionary *internal_dict;
1831
1832 /* Create a variable of the specified WIDTH to be used for internal
1833    calculations only.  The variable is assigned case index CASE_IDX. */
1834 struct variable *
1835 dict_create_internal_var (int case_idx, int width)
1836 {
1837   if (internal_dict == NULL)
1838     internal_dict = dict_create ("UTF-8");
1839
1840   for (;;)
1841     {
1842       static int counter = INT_MAX / 2;
1843       struct variable *var;
1844       char name[64];
1845
1846       if (++counter == INT_MAX)
1847         counter = INT_MAX / 2;
1848
1849       sprintf (name, "$internal%d", counter);
1850       var = dict_create_var (internal_dict, name, width);
1851       if (var != NULL)
1852         {
1853           set_var_case_index (var, case_idx);
1854           return var;
1855         }
1856     }
1857 }
1858
1859 /* Destroys VAR, which must have been created with
1860    dict_create_internal_var(). */
1861 void
1862 dict_destroy_internal_var (struct variable *var)
1863 {
1864   if (var != NULL)
1865     {
1866       dict_delete_var (internal_dict, var);
1867
1868       /* Destroy internal_dict if it has no variables left, just so that
1869          valgrind --leak-check --show-reachable won't show internal_dict. */
1870       if (dict_get_n_vars (internal_dict) == 0)
1871         {
1872           dict_unref (internal_dict);
1873           internal_dict = NULL;
1874         }
1875     }
1876 }
1877 \f
1878 int
1879 vardict_get_dict_index (const struct vardict_info *vardict)
1880 {
1881   return vardict - vardict->dict->vars;
1882 }