9ce3c46505b682b6388fc8a755b6c13628ebef31
[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_LAYERED,
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. */
388 static void
389 dict_set_split_vars__ (struct dictionary *d,
390                        struct variable *const *split, size_t n,
391                        enum split_type type, bool skip_callbacks)
392 {
393   assert (n == 0 || split != NULL);
394
395   d->n_splits = n;
396   d->split_type = type;
397   if (n > 0)
398    {
399     d->split = xnrealloc (d->split, n, sizeof *d->split) ;
400     memcpy (d->split, split, n * sizeof *d->split);
401    }
402   else
403    {
404     free (d->split);
405     d->split = NULL;
406    }
407
408  if (!skip_callbacks)
409     {
410       if (d->changed) d->changed (d, d->changed_data);
411       if (d->callbacks &&  d->callbacks->split_changed)
412         d->callbacks->split_changed (d, d->cb_data);
413     }
414 }
415
416 enum split_type
417 dict_get_split_type (const struct dictionary *d)
418 {
419   return d->split_type;
420 }
421
422 /* Sets N split vars SPLIT in dictionary D. */
423 void
424 dict_set_split_vars (struct dictionary *d,
425                      struct variable *const *split, size_t n,
426                      enum split_type type)
427 {
428   dict_set_split_vars__ (d, split, n, type, false);
429 }
430
431 void
432 dict_clear_split_vars (struct dictionary *d)
433 {
434   dict_set_split_vars (d, NULL, 0, SPLIT_LAYERED);
435 }
436 \f
437
438 /* Deletes variable V from dictionary D and frees V.
439
440    This is a very bad idea if there might be any pointers to V
441    from outside D.  In general, no variable in the active dataset's
442    dictionary should be deleted when any transformations are
443    active on the dictionary's dataset, because those
444    transformations might reference the deleted variable.  The
445    safest time to delete a variable is just after a procedure has
446    been executed, as done by DELETE VARIABLES.
447
448    Pointers to V within D are not a problem, because
449    dict_delete_var() knows to remove V from split variables,
450    weights, filters, etc. */
451 static void
452 dict_delete_var__ (struct dictionary *d, struct variable *v, bool skip_callbacks)
453 {
454   int dict_index = var_get_dict_index (v);
455   const int case_index = var_get_case_index (v);
456
457   assert (dict_contains_var (d, v));
458
459   dict_unset_split_var (d, v, skip_callbacks);
460   dict_unset_mrset_var (d, v);
461
462   if (d->weight == v)
463     dict_set_weight (d, NULL);
464
465   if (d->filter == v)
466     dict_set_filter (d, NULL);
467
468   dict_clear_vectors (d);
469
470   /* Remove V from var array. */
471   unindex_vars (d, dict_index, d->n_vars);
472   remove_element (d->vars, d->n_vars, sizeof *d->vars, dict_index);
473   d->n_vars--;
474
475   /* Update dict_index for each affected variable. */
476   reindex_vars (d, dict_index, d->n_vars, skip_callbacks);
477
478   /* Free memory. */
479   var_clear_vardict (v);
480
481   if (! skip_callbacks)
482     {
483       if (d->changed) d->changed (d, d->changed_data);
484       if (d->callbacks &&  d->callbacks->var_deleted)
485         d->callbacks->var_deleted (d, v, dict_index, case_index, d->cb_data);
486     }
487
488   invalidate_proto (d);
489   var_unref (v);
490 }
491
492 /* Deletes variable V from dictionary D and frees V.
493
494    This is a very bad idea if there might be any pointers to V
495    from outside D.  In general, no variable in the active dataset's
496    dictionary should be deleted when any transformations are
497    active on the dictionary's dataset, because those
498    transformations might reference the deleted variable.  The
499    safest time to delete a variable is just after a procedure has
500    been executed, as done by DELETE VARIABLES.
501
502    Pointers to V within D are not a problem, because
503    dict_delete_var() knows to remove V from split variables,
504    weights, filters, etc. */
505 void
506 dict_delete_var (struct dictionary *d, struct variable *v)
507 {
508   dict_delete_var__ (d, v, false);
509 }
510
511
512 /* Deletes the COUNT variables listed in VARS from D.  This is
513    unsafe; see the comment on dict_delete_var() for details. */
514 void
515 dict_delete_vars (struct dictionary *d,
516                   struct variable *const *vars, size_t count)
517 {
518   /* FIXME: this can be done in O(count) time, but this algorithm
519      is O(count**2). */
520   assert (count == 0 || vars != NULL);
521
522   while (count-- > 0)
523     dict_delete_var (d, *vars++);
524 }
525
526 /* Deletes the COUNT variables in D starting at index IDX.  This
527    is unsafe; see the comment on dict_delete_var() for
528    details. Deleting consecutive vars will result in less callbacks
529    compared to iterating over dict_delete_var.
530    A simple while loop over dict_delete_var will
531    produce (d->n_vars - IDX) * COUNT variable changed callbacks
532    plus COUNT variable delete callbacks.
533    This here produces d->n_vars - IDX variable changed callbacks
534    plus COUNT variable delete callbacks. */
535 void
536 dict_delete_consecutive_vars (struct dictionary *d, size_t idx, size_t count)
537 {
538   assert (idx + count <= d->n_vars);
539
540   /* We need to store the variable and the corresponding case_index
541      for the delete callbacks later. We store them in a linked list.*/
542   struct delvar {
543     struct ll ll;
544     struct variable *var;
545     int case_index;
546   };
547   struct ll_list list = LL_INITIALIZER (list);
548
549   for (size_t i = idx; i < idx + count; i++)
550     {
551       struct delvar *dv = xmalloc (sizeof (struct delvar));
552       assert (dv);
553       struct variable *v = d->vars[i].var;
554
555       dict_unset_split_var (d, v, false);
556       dict_unset_mrset_var (d, v);
557
558       if (d->weight == v)
559         dict_set_weight (d, NULL);
560
561       if (d->filter == v)
562         dict_set_filter (d, NULL);
563
564       dv->var = v;
565       dv->case_index = var_get_case_index (v);
566       ll_push_tail (&list, (struct ll *)dv);
567     }
568
569   dict_clear_vectors (d);
570
571   /* Remove variables from var array. */
572   unindex_vars (d, idx, d->n_vars);
573   remove_range (d->vars, d->n_vars, sizeof *d->vars, idx, count);
574   d->n_vars -= count;
575
576   /* Reindexing will result variable-changed callback */
577   reindex_vars (d, idx, d->n_vars, false);
578
579   invalidate_proto (d);
580   if (d->changed) d->changed (d, d->changed_data);
581
582   /* Now issue the variable delete callbacks and delete
583      the variables. The vardict is not valid at this point
584      anymore. That is the reason why we stored the
585      caseindex before reindexing. */
586   for (size_t vi = idx; vi < idx + count; vi++)
587     {
588       struct delvar *dv = (struct delvar *) ll_pop_head (&list);
589       var_clear_vardict (dv->var);
590       if (d->callbacks &&  d->callbacks->var_deleted)
591         d->callbacks->var_deleted (d, dv->var, vi, dv->case_index, d->cb_data);
592       var_unref (dv->var);
593       free (dv);
594     }
595 }
596
597 /* Deletes scratch variables from dictionary D. */
598 void
599 dict_delete_scratch_vars (struct dictionary *d)
600 {
601   int i;
602
603   /* FIXME: this can be done in O(count) time, but this algorithm
604      is O(count**2). */
605   for (i = 0; i < d->n_vars;)
606     if (var_get_dict_class (d->vars[i].var) == DC_SCRATCH)
607       dict_delete_var (d, d->vars[i].var);
608     else
609       i++;
610 }
611
612 \f
613
614 /* Clears the contents from a dictionary without destroying the
615    dictionary itself. */
616 static void
617 dict_clear__ (struct dictionary *d, bool skip_callbacks)
618 {
619   /* FIXME?  Should we really clear case_limit, label, documents?
620      Others are necessarily cleared by deleting all the variables.*/
621   while (d->n_vars > 0)
622     {
623       dict_delete_var__ (d, d->vars[d->n_vars - 1].var, skip_callbacks);
624     }
625
626   free (d->vars);
627   d->vars = NULL;
628   d->n_vars = d->allocated_vars = 0;
629   invalidate_proto (d);
630   hmap_clear (&d->name_map);
631   d->next_value_idx = 0;
632   dict_set_split_vars__ (d, NULL, 0, SPLIT_LAYERED, skip_callbacks);
633
634   if (skip_callbacks)
635     {
636       d->weight = NULL;
637       d->filter = NULL;
638     }
639   else
640     {
641       dict_set_weight (d, NULL);
642       dict_set_filter (d, NULL);
643     }
644   d->case_limit = 0;
645   free (d->label);
646   d->label = NULL;
647   string_array_clear (&d->documents);
648   dict_clear_vectors (d);
649   attrset_clear (&d->attributes);
650 }
651
652 /* Clears the contents from a dictionary without destroying the
653    dictionary itself. */
654 void
655 dict_clear (struct dictionary *d)
656 {
657   dict_clear__ (d, false);
658 }
659
660 /* Clears a dictionary and destroys it. */
661 static void
662 _dict_destroy (struct dictionary *d)
663 {
664   /* In general, we don't want callbacks occurring, if the dictionary
665      is being destroyed */
666   d->callbacks  = NULL ;
667
668   dict_clear__ (d, true);
669   string_array_destroy (&d->documents);
670   hmap_destroy (&d->name_map);
671   attrset_destroy (&d->attributes);
672   dict_clear_mrsets (d);
673   free (d->encoding);
674   free (d);
675 }
676
677 struct dictionary *
678 dict_ref (struct dictionary *d)
679 {
680   d->ref_cnt++;
681   return d;
682 }
683
684 void
685 dict_unref (struct dictionary *d)
686 {
687   if (d == NULL)
688     return;
689   d->ref_cnt--;
690   assert (d->ref_cnt >= 0);
691   if (d->ref_cnt == 0)
692     _dict_destroy (d);
693 }
694
695 /* Returns the number of variables in D. */
696 size_t
697 dict_get_n_vars (const struct dictionary *d)
698 {
699   return d->n_vars;
700 }
701
702 /* Returns the variable in D with dictionary index IDX, which
703    must be between 0 and the count returned by
704    dict_get_n_vars(), exclusive. */
705 struct variable *
706 dict_get_var (const struct dictionary *d, size_t idx)
707 {
708   assert (idx < d->n_vars);
709
710   return d->vars[idx].var;
711 }
712
713 /* Sets *VARS to an array of pointers to variables in D and *N
714    to the number of variables in *D.  All variables are returned
715    except for those, if any, in the classes indicated by EXCLUDE.
716    (There is no point in putting DC_SYSTEM in EXCLUDE as
717    dictionaries never include system variables.) */
718 void
719 dict_get_vars (const struct dictionary *d, const struct variable ***vars,
720                size_t *n, enum dict_class exclude)
721 {
722   dict_get_vars_mutable (d, (struct variable ***) vars, n, exclude);
723 }
724
725 /* Sets *VARS to an array of pointers to variables in D and *N
726    to the number of variables in *D.  All variables are returned
727    except for those, if any, in the classes indicated by EXCLUDE.
728    (There is no point in putting DC_SYSTEM in EXCLUDE as
729    dictionaries never include system variables.) */
730 void
731 dict_get_vars_mutable (const struct dictionary *d, struct variable ***vars,
732                        size_t *n, enum dict_class exclude)
733 {
734   size_t count;
735   size_t i;
736
737   assert (exclude == (exclude & DC_ALL));
738
739   count = 0;
740   for (i = 0; i < d->n_vars; i++)
741     {
742       enum dict_class class = var_get_dict_class (d->vars[i].var);
743       if (!(class & exclude))
744         count++;
745     }
746
747   *vars = xnmalloc (count, sizeof **vars);
748   *n = 0;
749   for (i = 0; i < d->n_vars; i++)
750     {
751       enum dict_class class = var_get_dict_class (d->vars[i].var);
752       if (!(class & exclude))
753         (*vars)[(*n)++] = d->vars[i].var;
754     }
755   assert (*n == count);
756 }
757
758 static struct variable *
759 add_var_with_case_index (struct dictionary *d, struct variable *v,
760                          int case_index)
761 {
762   struct vardict_info *vardict;
763
764   assert (case_index >= d->next_value_idx);
765
766   /* Update dictionary. */
767   if (d->n_vars >= d->allocated_vars)
768     {
769       size_t i;
770
771       d->vars = x2nrealloc (d->vars, &d->allocated_vars, sizeof *d->vars);
772       hmap_clear (&d->name_map);
773       for (i = 0; i < d->n_vars; i++)
774         {
775           var_set_vardict (d->vars[i].var, &d->vars[i]);
776           hmap_insert_fast (&d->name_map, &d->vars[i].name_node,
777                             d->vars[i].name_node.hash);
778         }
779     }
780
781   vardict = &d->vars[d->n_vars++];
782   vardict->dict = d;
783   vardict->var = v;
784   hmap_insert (&d->name_map, &vardict->name_node,
785                utf8_hash_case_string (var_get_name (v), 0));
786   vardict->case_index = case_index;
787   var_set_vardict (v, vardict);
788
789   if (d->changed) d->changed (d, d->changed_data);
790   if (d->callbacks &&  d->callbacks->var_added)
791     d->callbacks->var_added (d, var_get_dict_index (v), d->cb_data);
792
793   invalidate_proto (d);
794   d->next_value_idx = case_index + 1;
795
796   return v;
797 }
798
799 static struct variable *
800 add_var (struct dictionary *d, struct variable *v)
801 {
802   return add_var_with_case_index (d, v, d->next_value_idx);
803 }
804
805 /* Creates and returns a new variable in D with the given NAME
806    and WIDTH.  Returns a null pointer if the given NAME would
807    duplicate that of an existing variable in the dictionary. */
808 struct variable *
809 dict_create_var (struct dictionary *d, const char *name, int width)
810 {
811   return (dict_lookup_var (d, name) == NULL
812           ? dict_create_var_assert (d, name, width)
813           : NULL);
814 }
815
816 /* Creates and returns a new variable in D with the given NAME
817    and WIDTH.  Assert-fails if the given NAME would duplicate
818    that of an existing variable in the dictionary. */
819 struct variable *
820 dict_create_var_assert (struct dictionary *d, const char *name, int width)
821 {
822   assert (dict_lookup_var (d, name) == NULL);
823   return add_var (d, var_create (name, width));
824 }
825
826 /* Creates and returns a new variable in D, as a copy of existing variable
827    OLD_VAR, which need not be in D or in any dictionary.  Returns a null
828    pointer if OLD_VAR's name would duplicate that of an existing variable in
829    the dictionary. */
830 struct variable *
831 dict_clone_var (struct dictionary *d, const struct variable *old_var)
832 {
833   return dict_clone_var_as (d, old_var, var_get_name (old_var));
834 }
835
836 /* Creates and returns a new variable in D, as a copy of existing variable
837    OLD_VAR, which need not be in D or in any dictionary.  Assert-fails if
838    OLD_VAR's name would duplicate that of an existing variable in the
839    dictionary. */
840 struct variable *
841 dict_clone_var_assert (struct dictionary *d, const struct variable *old_var)
842 {
843   return dict_clone_var_as_assert (d, old_var, var_get_name (old_var));
844 }
845
846 /* Creates and returns a new variable in D with name NAME, as a copy of
847    existing variable OLD_VAR, which need not be in D or in any dictionary.
848    Returns a null pointer if the given NAME would duplicate that of an existing
849    variable in the dictionary. */
850 struct variable *
851 dict_clone_var_as (struct dictionary *d, const struct variable *old_var,
852                    const char *name)
853 {
854   return (dict_lookup_var (d, name) == NULL
855           ? dict_clone_var_as_assert (d, old_var, name)
856           : NULL);
857 }
858
859 /* Creates and returns a new variable in D with name NAME, as a copy of
860    existing variable OLD_VAR, which need not be in D or in any dictionary.
861    Assert-fails if the given NAME would duplicate that of an existing variable
862    in the dictionary. */
863 struct variable *
864 dict_clone_var_as_assert (struct dictionary *d, const struct variable *old_var,
865                           const char *name)
866 {
867   struct variable *new_var = var_clone (old_var);
868   assert (dict_lookup_var (d, name) == NULL);
869   var_set_name (new_var, name);
870   return add_var (d, new_var);
871 }
872
873 struct variable *
874 dict_clone_var_in_place_assert (struct dictionary *d,
875                                 const struct variable *old_var)
876 {
877   assert (dict_lookup_var (d, var_get_name (old_var)) == NULL);
878   return add_var_with_case_index (d, var_clone (old_var),
879                                   var_get_case_index (old_var));
880 }
881
882 /* Returns the variable named NAME in D, or a null pointer if no
883    variable has that name. */
884 struct variable *
885 dict_lookup_var (const struct dictionary *d, const char *name)
886 {
887   struct vardict_info *vardict;
888
889   HMAP_FOR_EACH_WITH_HASH (vardict, struct vardict_info, name_node,
890                            utf8_hash_case_string (name, 0), &d->name_map)
891     {
892       struct variable *var = vardict->var;
893       if (!utf8_strcasecmp (var_get_name (var), name))
894         return var;
895     }
896
897   return NULL;
898 }
899
900 /* Returns the variable named NAME in D.  Assert-fails if no
901    variable has that name. */
902 struct variable *
903 dict_lookup_var_assert (const struct dictionary *d, const char *name)
904 {
905   struct variable *v = dict_lookup_var (d, name);
906   assert (v != NULL);
907   return v;
908 }
909
910 /* Returns true if variable V is in dictionary D,
911    false otherwise. */
912 bool
913 dict_contains_var (const struct dictionary *d, const struct variable *v)
914 {
915   return (var_has_vardict (v)
916           && vardict_get_dictionary (var_get_vardict (v)) == d);
917 }
918
919 /* Moves V to 0-based position IDX in D.  Other variables in D,
920    if any, retain their relative positions.  Runs in time linear
921    in the distance moved. */
922 void
923 dict_reorder_var (struct dictionary *d, struct variable *v, size_t new_index)
924 {
925   size_t old_index = var_get_dict_index (v);
926
927   assert (new_index < d->n_vars);
928
929   unindex_vars (d, MIN (old_index, new_index), MAX (old_index, new_index) + 1);
930   move_element (d->vars, d->n_vars, sizeof *d->vars, old_index, new_index);
931   reindex_vars (d, MIN (old_index, new_index), MAX (old_index, new_index) + 1, false);
932 }
933
934 /* Reorders the variables in D, placing the COUNT variables
935    listed in ORDER in that order at the beginning of D.  The
936    other variables in D, if any, retain their relative
937    positions. */
938 void
939 dict_reorder_vars (struct dictionary *d,
940                    struct variable *const *order, size_t count)
941 {
942   struct vardict_info *new_var;
943   size_t i;
944
945   assert (count == 0 || order != NULL);
946   assert (count <= d->n_vars);
947
948   new_var = xnmalloc (d->allocated_vars, sizeof *new_var);
949
950   /* Add variables in ORDER to new_var. */
951   for (i = 0; i < count; i++)
952     {
953       struct vardict_info *old_var;
954
955       assert (dict_contains_var (d, order[i]));
956
957       old_var = var_get_vardict (order[i]);
958       new_var[i] = *old_var;
959       old_var->dict = NULL;
960     }
961
962   /* Add remaining variables to new_var. */
963   for (i = 0; i < d->n_vars; i++)
964     if (d->vars[i].dict != NULL)
965       new_var[count++] = d->vars[i];
966   assert (count == d->n_vars);
967
968   /* Replace old vardicts by new ones. */
969   free (d->vars);
970   d->vars = new_var;
971
972   hmap_clear (&d->name_map);
973   reindex_vars (d, 0, d->n_vars, false);
974 }
975
976 /* Changes the name of variable V that is currently in a dictionary to
977    NEW_NAME. */
978 static void
979 rename_var (struct variable *v, const char *new_name)
980 {
981   struct vardict_info *vardict = var_get_vardict (v);
982   var_clear_vardict (v);
983   var_set_name (v, new_name);
984   vardict->name_node.hash = utf8_hash_case_string (new_name, 0);
985   var_set_vardict (v, vardict);
986 }
987
988 /* Tries to changes the name of V in D to name NEW_NAME.  Returns true if
989    successful, false if a variable (other than V) with the given name already
990    exists in D. */
991 bool
992 dict_try_rename_var (struct dictionary *d, struct variable *v,
993                      const char *new_name)
994 {
995   struct variable *conflict = dict_lookup_var (d, new_name);
996   if (conflict && v != conflict)
997     return false;
998
999   struct variable *old = var_clone (v);
1000   unindex_var (d, var_get_vardict (v));
1001   rename_var (v, new_name);
1002   reindex_var (d, var_get_vardict (v), false);
1003
1004   if (settings_get_algorithm () == ENHANCED)
1005     var_clear_short_names (v);
1006
1007   if (d->changed) d->changed (d, d->changed_data);
1008   if (d->callbacks &&  d->callbacks->var_changed)
1009     d->callbacks->var_changed (d, var_get_dict_index (v), VAR_TRAIT_NAME, old, d->cb_data);
1010
1011   var_unref (old);
1012
1013   return true;
1014 }
1015
1016 /* Changes the name of V in D to name NEW_NAME.  Assert-fails if
1017    a variable named NEW_NAME is already in D, except that
1018    NEW_NAME may be the same as V's existing name. */
1019 void
1020 dict_rename_var (struct dictionary *d, struct variable *v,
1021                  const char *new_name)
1022 {
1023   bool ok UNUSED = dict_try_rename_var (d, v, new_name);
1024   assert (ok);
1025 }
1026
1027 /* Renames COUNT variables specified in VARS to the names given
1028    in NEW_NAMES within dictionary D.  If the renaming would
1029    result in a duplicate variable name, returns false and stores a
1030    name that would be duplicated into *ERR_NAME (if ERR_NAME is
1031    non-null).  Otherwise, the renaming is successful, and true
1032    is returned. */
1033 bool
1034 dict_rename_vars (struct dictionary *d,
1035                   struct variable **vars, char **new_names, size_t count,
1036                   char **err_name)
1037 {
1038   struct pool *pool;
1039   char **old_names;
1040   size_t i;
1041
1042   assert (count == 0 || vars != NULL);
1043   assert (count == 0 || new_names != NULL);
1044
1045   /* Save the names of the variables to be renamed. */
1046   pool = pool_create ();
1047   old_names = pool_nalloc (pool, count, sizeof *old_names);
1048   for (i = 0; i < count; i++)
1049     old_names[i] = pool_strdup (pool, var_get_name (vars[i]));
1050
1051   /* Remove the variables to be renamed from the name hash,
1052      and rename them. */
1053   for (i = 0; i < count; i++)
1054     {
1055       unindex_var (d, var_get_vardict (vars[i]));
1056       rename_var (vars[i], new_names[i]);
1057     }
1058
1059   /* Add the renamed variables back into the name hash,
1060      checking for conflicts. */
1061   for (i = 0; i < count; i++)
1062     {
1063       if (dict_lookup_var (d, var_get_name (vars[i])) != NULL)
1064         {
1065           /* There is a name conflict.
1066              Back out all the name changes that have already
1067              taken place, and indicate failure. */
1068           size_t fail_idx = i;
1069           if (err_name != NULL)
1070             *err_name = new_names[i];
1071
1072           for (i = 0; i < fail_idx; i++)
1073             unindex_var (d, var_get_vardict (vars[i]));
1074
1075           for (i = 0; i < count; i++)
1076             {
1077               rename_var (vars[i], old_names[i]);
1078               reindex_var (d, var_get_vardict (vars[i]), false);
1079             }
1080
1081           pool_destroy (pool);
1082           return false;
1083         }
1084       reindex_var (d, var_get_vardict (vars[i]), false);
1085     }
1086
1087   /* Clear short names. */
1088   if (settings_get_algorithm () == ENHANCED)
1089     for (i = 0; i < count; i++)
1090       var_clear_short_names (vars[i]);
1091
1092   pool_destroy (pool);
1093   return true;
1094 }
1095
1096 /* Returns true if a variable named NAME may be inserted in DICT;
1097    that is, if there is not already a variable with that name in
1098    DICT and if NAME is not a reserved word.  (The caller's checks
1099    have already verified that NAME is otherwise acceptable as a
1100    variable name.) */
1101 static bool
1102 var_name_is_insertable (const struct dictionary *dict, const char *name)
1103 {
1104   return (dict_lookup_var (dict, name) == NULL
1105           && lex_id_to_token (ss_cstr (name)) == T_ID);
1106 }
1107
1108 static char *
1109 make_hinted_name (const struct dictionary *dict, const char *hint)
1110 {
1111   size_t hint_len = strlen (hint);
1112   bool dropped = false;
1113   char *root, *rp;
1114   size_t ofs;
1115   int mblen;
1116
1117   if (hint_len > ID_MAX_LEN)
1118     hint_len = ID_MAX_LEN;
1119
1120   /* The allocation size here is OK: characters that are copied directly fit
1121      OK, and characters that are not copied directly are replaced by a single
1122      '_' byte.  If u8_mbtouc() replaces bad input by 0xfffd, then that will get
1123      replaced by '_' too.  */
1124   root = rp = xmalloc (hint_len + 1);
1125   for (ofs = 0; ofs < hint_len; ofs += mblen)
1126     {
1127       ucs4_t uc;
1128
1129       mblen = u8_mbtouc (&uc, CHAR_CAST (const uint8_t *, hint + ofs),
1130                          hint_len - ofs);
1131       if (rp == root
1132           ? lex_uc_is_id1 (uc) && uc != '$'
1133           : lex_uc_is_idn (uc))
1134         {
1135           if (dropped)
1136             {
1137               *rp++ = '_';
1138               dropped = false;
1139             }
1140           rp += u8_uctomb (CHAR_CAST (uint8_t *, rp), uc, 6);
1141         }
1142       else if (rp != root)
1143         dropped = true;
1144     }
1145   *rp = '\0';
1146
1147   if (root[0] != '\0')
1148     {
1149       unsigned long int i;
1150
1151       if (var_name_is_insertable (dict, root))
1152         return root;
1153
1154       for (i = 0; i < ULONG_MAX; i++)
1155         {
1156           char suffix[INT_BUFSIZE_BOUND (i) + 1];
1157           char *name;
1158
1159           suffix[0] = '_';
1160           if (!str_format_26adic (i + 1, true, &suffix[1], sizeof suffix - 1))
1161             NOT_REACHED ();
1162
1163           name = utf8_encoding_concat (root, suffix, dict->encoding, 64);
1164           if (var_name_is_insertable (dict, name))
1165             {
1166               free (root);
1167               return name;
1168             }
1169           free (name);
1170         }
1171     }
1172
1173   free (root);
1174
1175   return NULL;
1176 }
1177
1178 static char *
1179 make_numeric_name (const struct dictionary *dict, unsigned long int *num_start)
1180 {
1181   unsigned long int number;
1182
1183   for (number = num_start != NULL ? MAX (*num_start, 1) : 1;
1184        number < ULONG_MAX;
1185        number++)
1186     {
1187       char name[3 + INT_STRLEN_BOUND (number) + 1];
1188
1189       sprintf (name, "VAR%03lu", number);
1190       if (dict_lookup_var (dict, name) == NULL)
1191         {
1192           if (num_start != NULL)
1193             *num_start = number + 1;
1194           return xstrdup (name);
1195         }
1196     }
1197
1198   NOT_REACHED ();
1199 }
1200
1201
1202 /* Devises and returns a variable name unique within DICT.  The variable name
1203    is owned by the caller, which must free it with free() when it is no longer
1204    needed.
1205
1206    HINT, if it is non-null, is used as a suggestion that will be
1207    modified for suitability as a variable name and for
1208    uniqueness.
1209
1210    If HINT is null or entirely unsuitable, a name in the form
1211    "VAR%03d" will be generated, where the smallest unused integer
1212    value is used.  If NUM_START is non-null, then its value is
1213    used as the minimum numeric value to check, and it is updated
1214    to the next value to be checked.
1215 */
1216 char *
1217 dict_make_unique_var_name (const struct dictionary *dict, const char *hint,
1218                            unsigned long int *num_start)
1219 {
1220   if (hint != NULL)
1221     {
1222       char *hinted_name = make_hinted_name (dict, hint);
1223       if (hinted_name != NULL)
1224         return hinted_name;
1225     }
1226
1227   return make_numeric_name (dict, num_start);
1228 }
1229
1230 /* Returns whether variable names must be valid identifiers.  Normally, this is
1231    true, but sometimes a dictionary is prepared for external use (e.g. output
1232    to a CSV file) where names don't have to be valid. */
1233 bool
1234 dict_get_names_must_be_ids (const struct dictionary *d)
1235 {
1236   return d->names_must_be_ids;
1237 }
1238
1239 /* Sets whether variable names must be valid identifiers.  Normally, this is
1240    true, but sometimes a dictionary is prepared for external use (e.g. output
1241    to a CSV file) where names don't have to be valid.
1242
1243    Changing this setting from false to true doesn't make the dictionary check
1244    all the existing variable names, so it can cause an invariant violation. */
1245 void
1246 dict_set_names_must_be_ids (struct dictionary *d, bool names_must_be_ids)
1247 {
1248   d->names_must_be_ids = names_must_be_ids;
1249 }
1250
1251 /* Returns the weighting variable in dictionary D, or a null
1252    pointer if the dictionary is unweighted. */
1253 struct variable *
1254 dict_get_weight (const struct dictionary *d)
1255 {
1256   assert (d->weight == NULL || dict_contains_var (d, d->weight));
1257
1258   return d->weight;
1259 }
1260
1261 /* Returns the value of D's weighting variable in case C, except
1262    that a negative weight is returned as 0.  Returns 1 if the
1263    dictionary is unweighted.  Will warn about missing, negative,
1264    or zero values if *WARN_ON_INVALID is true.  The function will
1265    set *WARN_ON_INVALID to false if an invalid weight is
1266    found. */
1267 double
1268 dict_get_case_weight (const struct dictionary *d, const struct ccase *c,
1269                       bool *warn_on_invalid)
1270 {
1271   assert (c != NULL);
1272
1273   if (d->weight == NULL)
1274     return 1.0;
1275   else
1276     {
1277       double w = case_num (c, d->weight);
1278
1279       return var_force_valid_weight (d->weight, w, warn_on_invalid);
1280     }
1281 }
1282
1283 /* Returns the format to use for weights. */
1284 const struct fmt_spec *
1285 dict_get_weight_format (const struct dictionary *d)
1286 {
1287   return d->weight ? var_get_print_format (d->weight) : &F_8_0;
1288 }
1289
1290 /* Sets the weighting variable of D to V, or turning off
1291    weighting if V is a null pointer. */
1292 void
1293 dict_set_weight (struct dictionary *d, struct variable *v)
1294 {
1295   assert (v == NULL || dict_contains_var (d, v));
1296   assert (v == NULL || var_is_numeric (v));
1297
1298   d->weight = v;
1299
1300   if (d->changed) d->changed (d, d->changed_data);
1301   if (d->callbacks &&  d->callbacks->weight_changed)
1302     d->callbacks->weight_changed (d,
1303                                   v ? var_get_dict_index (v) : -1,
1304                                   d->cb_data);
1305 }
1306
1307 /* Returns the filter variable in dictionary D (see cmd_filter())
1308    or a null pointer if the dictionary is unfiltered. */
1309 struct variable *
1310 dict_get_filter (const struct dictionary *d)
1311 {
1312   assert (d->filter == NULL || dict_contains_var (d, d->filter));
1313
1314   return d->filter;
1315 }
1316
1317 /* Sets V as the filter variable for dictionary D.  Passing a
1318    null pointer for V turn off filtering. */
1319 void
1320 dict_set_filter (struct dictionary *d, struct variable *v)
1321 {
1322   assert (v == NULL || dict_contains_var (d, v));
1323   assert (v == NULL || var_is_numeric (v));
1324
1325   d->filter = v;
1326
1327   if (d->changed) d->changed (d, d->changed_data);
1328   if (d->callbacks && d->callbacks->filter_changed)
1329     d->callbacks->filter_changed (d,
1330                                   v ? var_get_dict_index (v) : -1,
1331                                       d->cb_data);
1332 }
1333
1334 /* Returns the case limit for dictionary D, or zero if the number
1335    of cases is unlimited. */
1336 casenumber
1337 dict_get_case_limit (const struct dictionary *d)
1338 {
1339   return d->case_limit;
1340 }
1341
1342 /* Sets CASE_LIMIT as the case limit for dictionary D.  Use
1343    0 for CASE_LIMIT to indicate no limit. */
1344 void
1345 dict_set_case_limit (struct dictionary *d, casenumber case_limit)
1346 {
1347   d->case_limit = case_limit;
1348 }
1349
1350 /* Returns the prototype used for cases created by dictionary D. */
1351 const struct caseproto *
1352 dict_get_proto (const struct dictionary *d_)
1353 {
1354   struct dictionary *d = CONST_CAST (struct dictionary *, d_);
1355   if (d->proto == NULL)
1356     {
1357       size_t i;
1358
1359       d->proto = caseproto_create ();
1360       d->proto = caseproto_reserve (d->proto, d->n_vars);
1361       for (i = 0; i < d->n_vars; i++)
1362         d->proto = caseproto_set_width (d->proto,
1363                                         var_get_case_index (d->vars[i].var),
1364                                         var_get_width (d->vars[i].var));
1365     }
1366   return d->proto;
1367 }
1368
1369 /* Returns the case index of the next value to be added to D.
1370    This value is the number of `union value's that need to be
1371    allocated to store a case for dictionary D. */
1372 int
1373 dict_get_next_value_idx (const struct dictionary *d)
1374 {
1375   return d->next_value_idx;
1376 }
1377
1378 /* Returns the number of bytes needed to store a case for
1379    dictionary D. */
1380 size_t
1381 dict_get_case_size (const struct dictionary *d)
1382 {
1383   return sizeof (union value) * dict_get_next_value_idx (d);
1384 }
1385
1386 /* Reassigns values in dictionary D so that fragmentation is
1387    eliminated. */
1388 void
1389 dict_compact_values (struct dictionary *d)
1390 {
1391   size_t i;
1392
1393   d->next_value_idx = 0;
1394   for (i = 0; i < d->n_vars; i++)
1395     {
1396       struct variable *v = d->vars[i].var;
1397       set_var_case_index (v, d->next_value_idx++);
1398     }
1399   invalidate_proto (d);
1400 }
1401
1402 /* Returns the number of values occupied by the variables in
1403    dictionary D.  All variables are considered if EXCLUDE_CLASSES
1404    is 0, or it may contain one or more of (1u << DC_ORDINARY),
1405    (1u << DC_SYSTEM), or (1u << DC_SCRATCH) to exclude the
1406    corresponding type of variable.
1407
1408    The return value may be less than the number of values in one
1409    of dictionary D's cases (as returned by
1410    dict_get_next_value_idx) even if E is 0, because there may be
1411    gaps in D's cases due to deleted variables. */
1412 size_t
1413 dict_count_values (const struct dictionary *d, unsigned int exclude_classes)
1414 {
1415   assert ((exclude_classes & ~((1u << DC_ORDINARY)
1416                                | (1u << DC_SYSTEM)
1417                                | (1u << DC_SCRATCH))) == 0);
1418
1419   size_t n = 0;
1420   for (size_t i = 0; i < d->n_vars; i++)
1421     {
1422       enum dict_class class = var_get_dict_class (d->vars[i].var);
1423       if (!(exclude_classes & (1u << class)))
1424         n++;
1425     }
1426   return n;
1427 }
1428
1429 /* Returns the case prototype that would result after deleting
1430    all variables from D that are not in one of the
1431    EXCLUDE_CLASSES and compacting the dictionary with
1432    dict_compact().
1433
1434    The caller must unref the returned caseproto when it is no
1435    longer needed. */
1436 struct caseproto *
1437 dict_get_compacted_proto (const struct dictionary *d,
1438                           unsigned int exclude_classes)
1439 {
1440   struct caseproto *proto;
1441   size_t i;
1442
1443   assert ((exclude_classes & ~((1u << DC_ORDINARY)
1444                                | (1u << DC_SYSTEM)
1445                                | (1u << DC_SCRATCH))) == 0);
1446
1447   proto = caseproto_create ();
1448   for (i = 0; i < d->n_vars; i++)
1449     {
1450       struct variable *v = d->vars[i].var;
1451       if (!(exclude_classes & (1u << var_get_dict_class (v))))
1452         proto = caseproto_add_width (proto, var_get_width (v));
1453     }
1454   return proto;
1455 }
1456 /* Returns the file label for D, or a null pointer if D is
1457    unlabeled (see cmd_file_label()). */
1458 const char *
1459 dict_get_label (const struct dictionary *d)
1460 {
1461   return d->label;
1462 }
1463
1464 /* Sets D's file label to LABEL, truncating it to at most 60 bytes in D's
1465    encoding.
1466
1467    Removes D's label if LABEL is null or the empty string. */
1468 void
1469 dict_set_label (struct dictionary *d, const char *label)
1470 {
1471   free (d->label);
1472   if (label == NULL || label[0] == '\0')
1473     d->label = NULL;
1474   else
1475     d->label = utf8_encoding_trunc (label, d->encoding, 60);
1476 }
1477
1478 /* Returns the documents for D, as an UTF-8 encoded string_array.  The
1479    return value is always nonnull; if there are no documents then the
1480    string_arary is empty.*/
1481 const struct string_array *
1482 dict_get_documents (const struct dictionary *d)
1483 {
1484   return &d->documents;
1485 }
1486
1487 /* Replaces the documents for D by NEW_DOCS, a UTF-8 encoded string_array. */
1488 void
1489 dict_set_documents (struct dictionary *d, const struct string_array *new_docs)
1490 {
1491   /* Swap out the old documents, instead of destroying them immediately, to
1492      allow the new documents to include pointers into the old ones. */
1493   struct string_array old_docs = STRING_ARRAY_INITIALIZER;
1494   string_array_swap (&d->documents, &old_docs);
1495
1496   for (size_t i = 0; i < new_docs->n; i++)
1497     dict_add_document_line (d, new_docs->strings[i], false);
1498
1499   string_array_destroy (&old_docs);
1500 }
1501
1502 /* Replaces the documents for D by UTF-8 encoded string NEW_DOCS, dividing it
1503    into individual lines at new-line characters.  Each line is truncated to at
1504    most DOC_LINE_LENGTH bytes in D's encoding. */
1505 void
1506 dict_set_documents_string (struct dictionary *d, const char *new_docs)
1507 {
1508   const char *s;
1509
1510   dict_clear_documents (d);
1511   for (s = new_docs; *s != '\0';)
1512     {
1513       size_t len = strcspn (s, "\n");
1514       char *line = xmemdup0 (s, len);
1515       dict_add_document_line (d, line, false);
1516       free (line);
1517
1518       s += len;
1519       if (*s == '\n')
1520         s++;
1521     }
1522 }
1523
1524 /* Drops the documents from dictionary D. */
1525 void
1526 dict_clear_documents (struct dictionary *d)
1527 {
1528   string_array_clear (&d->documents);
1529 }
1530
1531 /* Appends the UTF-8 encoded LINE to the documents in D.  LINE will be
1532    truncated so that it is no more than 80 bytes in the dictionary's
1533    encoding.  If this causes some text to be lost, and ISSUE_WARNING is true,
1534    then a warning will be issued. */
1535 bool
1536 dict_add_document_line (struct dictionary *d, const char *line,
1537                         bool issue_warning)
1538 {
1539   size_t trunc_len;
1540   bool truncated;
1541
1542   trunc_len = utf8_encoding_trunc_len (line, d->encoding, DOC_LINE_LENGTH);
1543   truncated = line[trunc_len] != '\0';
1544   if (truncated && issue_warning)
1545     {
1546       /* TRANSLATORS: "bytes" is correct, not characters due to UTF encoding */
1547       msg (SW, _("Truncating document line to %d bytes."), DOC_LINE_LENGTH);
1548     }
1549
1550   string_array_append_nocopy (&d->documents, xmemdup0 (line, trunc_len));
1551
1552   return !truncated;
1553 }
1554
1555 /* Returns the number of document lines in dictionary D. */
1556 size_t
1557 dict_get_document_n_lines (const struct dictionary *d)
1558 {
1559   return d->documents.n;
1560 }
1561
1562 /* Returns document line number IDX in dictionary D.  The caller must not
1563    modify or free the returned string. */
1564 const char *
1565 dict_get_document_line (const struct dictionary *d, size_t idx)
1566 {
1567   assert (idx < d->documents.n);
1568   return d->documents.strings[idx];
1569 }
1570
1571 /* Creates in D a vector named NAME that contains the N
1572    variables in VAR.  Returns true if successful, or false if a
1573    vector named NAME already exists in D. */
1574 bool
1575 dict_create_vector (struct dictionary *d,
1576                     const char *name,
1577                     struct variable **var, size_t n)
1578 {
1579   assert (n > 0);
1580   for (size_t i = 0; i < n; i++)
1581     assert (dict_contains_var (d, var[i]));
1582
1583   if (dict_lookup_vector (d, name) == NULL)
1584     {
1585       d->vector = xnrealloc (d->vector, d->n_vectors + 1, sizeof *d->vector);
1586       d->vector[d->n_vectors++] = vector_create (name, var, n);
1587       return true;
1588     }
1589   else
1590     return false;
1591 }
1592
1593 /* Creates in D a vector named NAME that contains the N
1594    variables in VAR.  A vector named NAME must not already exist
1595    in D. */
1596 void
1597 dict_create_vector_assert (struct dictionary *d,
1598                            const char *name,
1599                            struct variable **var, size_t n)
1600 {
1601   assert (dict_lookup_vector (d, name) == NULL);
1602   dict_create_vector (d, name, var, n);
1603 }
1604
1605 /* Returns the vector in D with index IDX, which must be less
1606    than dict_get_n_vectors (D). */
1607 const struct vector *
1608 dict_get_vector (const struct dictionary *d, size_t idx)
1609 {
1610   assert (idx < d->n_vectors);
1611
1612   return d->vector[idx];
1613 }
1614
1615 /* Returns the number of vectors in D. */
1616 size_t
1617 dict_get_n_vectors (const struct dictionary *d)
1618 {
1619   return d->n_vectors;
1620 }
1621
1622 /* Looks up and returns the vector within D with the given
1623    NAME. */
1624 const struct vector *
1625 dict_lookup_vector (const struct dictionary *d, const char *name)
1626 {
1627   size_t i;
1628   for (i = 0; i < d->n_vectors; i++)
1629     if (!utf8_strcasecmp (vector_get_name (d->vector[i]), name))
1630       return d->vector[i];
1631   return NULL;
1632 }
1633
1634 /* Deletes all vectors from D. */
1635 void
1636 dict_clear_vectors (struct dictionary *d)
1637 {
1638   size_t i;
1639
1640   for (i = 0; i < d->n_vectors; i++)
1641     vector_destroy (d->vector[i]);
1642   free (d->vector);
1643
1644   d->vector = NULL;
1645   d->n_vectors = 0;
1646 }
1647 \f
1648 /* Multiple response sets. */
1649
1650 /* Returns the multiple response set in DICT with index IDX, which must be
1651    between 0 and the count returned by dict_get_n_mrsets(), exclusive. */
1652 const struct mrset *
1653 dict_get_mrset (const struct dictionary *dict, size_t idx)
1654 {
1655   assert (idx < dict->n_mrsets);
1656   return dict->mrsets[idx];
1657 }
1658
1659 /* Returns the number of multiple response sets in DICT. */
1660 size_t
1661 dict_get_n_mrsets (const struct dictionary *dict)
1662 {
1663   return dict->n_mrsets;
1664 }
1665
1666 /* Looks for a multiple response set named NAME in DICT.  If it finds one,
1667    returns its index; otherwise, returns SIZE_MAX. */
1668 static size_t
1669 dict_lookup_mrset_idx (const struct dictionary *dict, const char *name)
1670 {
1671   size_t i;
1672
1673   for (i = 0; i < dict->n_mrsets; i++)
1674     if (!utf8_strcasecmp (name, dict->mrsets[i]->name))
1675       return i;
1676
1677   return SIZE_MAX;
1678 }
1679
1680 /* Looks for a multiple response set named NAME in DICT.  If it finds one,
1681    returns it; otherwise, returns NULL. */
1682 const struct mrset *
1683 dict_lookup_mrset (const struct dictionary *dict, const char *name)
1684 {
1685   size_t idx = dict_lookup_mrset_idx (dict, name);
1686   return idx != SIZE_MAX ? dict->mrsets[idx] : NULL;
1687 }
1688
1689 /* Adds MRSET to DICT, replacing any existing set with the same name.  Returns
1690    true if a set was replaced, false if none existed with the specified name.
1691
1692    Ownership of MRSET is transferred to DICT. */
1693 bool
1694 dict_add_mrset (struct dictionary *dict, struct mrset *mrset)
1695 {
1696   size_t idx;
1697
1698   assert (mrset_ok (mrset, dict));
1699
1700   idx = dict_lookup_mrset_idx (dict, mrset->name);
1701   if (idx == SIZE_MAX)
1702     {
1703       dict->mrsets = xrealloc (dict->mrsets,
1704                                (dict->n_mrsets + 1) * sizeof *dict->mrsets);
1705       dict->mrsets[dict->n_mrsets++] = mrset;
1706       return true;
1707     }
1708   else
1709     {
1710       mrset_destroy (dict->mrsets[idx]);
1711       dict->mrsets[idx] = mrset;
1712       return false;
1713     }
1714 }
1715
1716 /* Looks for a multiple response set in DICT named NAME.  If found, removes it
1717    from DICT and returns true.  If none is found, returns false without
1718    modifying DICT.
1719
1720    Deleting one multiple response set causes the indexes of other sets within
1721    DICT to change. */
1722 bool
1723 dict_delete_mrset (struct dictionary *dict, const char *name)
1724 {
1725   size_t idx = dict_lookup_mrset_idx (dict, name);
1726   if (idx != SIZE_MAX)
1727     {
1728       mrset_destroy (dict->mrsets[idx]);
1729       dict->mrsets[idx] = dict->mrsets[--dict->n_mrsets];
1730       return true;
1731     }
1732   else
1733     return false;
1734 }
1735
1736 /* Deletes all multiple response sets from DICT. */
1737 void
1738 dict_clear_mrsets (struct dictionary *dict)
1739 {
1740   size_t i;
1741
1742   for (i = 0; i < dict->n_mrsets; i++)
1743     mrset_destroy (dict->mrsets[i]);
1744   free (dict->mrsets);
1745   dict->mrsets = NULL;
1746   dict->n_mrsets = 0;
1747 }
1748
1749 /* Removes VAR, which must be in DICT, from DICT's multiple response sets. */
1750 static void
1751 dict_unset_mrset_var (struct dictionary *dict, struct variable *var)
1752 {
1753   size_t i;
1754
1755   assert (dict_contains_var (dict, var));
1756
1757   for (i = 0; i < dict->n_mrsets;)
1758     {
1759       struct mrset *mrset = dict->mrsets[i];
1760       size_t j;
1761
1762       for (j = 0; j < mrset->n_vars;)
1763         if (mrset->vars[j] == var)
1764           remove_element (mrset->vars, mrset->n_vars--,
1765                           sizeof *mrset->vars, j);
1766         else
1767           j++;
1768
1769       if (mrset->n_vars < 2)
1770         {
1771           mrset_destroy (mrset);
1772           dict->mrsets[i] = dict->mrsets[--dict->n_mrsets];
1773         }
1774       else
1775         i++;
1776     }
1777 }
1778 \f
1779 /* Returns D's attribute set.  The caller may examine or modify
1780    the attribute set, but must not destroy it.  Destroying D or
1781    calling dict_set_attributes for D will also destroy D's
1782    attribute set. */
1783 struct attrset *
1784 dict_get_attributes (const struct dictionary *d)
1785 {
1786   return CONST_CAST (struct attrset *, &d->attributes);
1787 }
1788
1789 /* Replaces D's attributes set by a copy of ATTRS. */
1790 void
1791 dict_set_attributes (struct dictionary *d, const struct attrset *attrs)
1792 {
1793   attrset_destroy (&d->attributes);
1794   attrset_clone (&d->attributes, attrs);
1795 }
1796
1797 /* Returns true if D has at least one attribute in its attribute
1798    set, false if D's attribute set is empty. */
1799 bool
1800 dict_has_attributes (const struct dictionary *d)
1801 {
1802   return attrset_count (&d->attributes) > 0;
1803 }
1804
1805 /* Called from variable.c to notify the dictionary that some property (indicated
1806    by WHAT) of the variable has changed.  OLDVAR is a copy of V as it existed
1807    prior to the change.  OLDVAR is destroyed by this function.
1808 */
1809 void
1810 dict_var_changed (const struct variable *v, unsigned int what, struct variable *oldvar)
1811 {
1812   if (var_has_vardict (v))
1813     {
1814       const struct vardict_info *vardict = var_get_vardict (v);
1815       struct dictionary *d = vardict->dict;
1816
1817       if (NULL == d)
1818         return;
1819
1820       if (what & (VAR_TRAIT_WIDTH | VAR_TRAIT_POSITION))
1821         invalidate_proto (d);
1822
1823       if (d->changed) d->changed (d, d->changed_data);
1824       if (d->callbacks && d->callbacks->var_changed)
1825         d->callbacks->var_changed (d, var_get_dict_index (v), what, oldvar, d->cb_data);
1826     }
1827   var_unref (oldvar);
1828 }
1829
1830
1831 \f
1832 /* Dictionary used to contain "internal variables". */
1833 static struct dictionary *internal_dict;
1834
1835 /* Create a variable of the specified WIDTH to be used for internal
1836    calculations only.  The variable is assigned case index CASE_IDX. */
1837 struct variable *
1838 dict_create_internal_var (int case_idx, int width)
1839 {
1840   if (internal_dict == NULL)
1841     internal_dict = dict_create ("UTF-8");
1842
1843   for (;;)
1844     {
1845       static int counter = INT_MAX / 2;
1846       struct variable *var;
1847       char name[64];
1848
1849       if (++counter == INT_MAX)
1850         counter = INT_MAX / 2;
1851
1852       sprintf (name, "$internal%d", counter);
1853       var = dict_create_var (internal_dict, name, width);
1854       if (var != NULL)
1855         {
1856           set_var_case_index (var, case_idx);
1857           return var;
1858         }
1859     }
1860 }
1861
1862 /* Destroys VAR, which must have been created with
1863    dict_create_internal_var(). */
1864 void
1865 dict_destroy_internal_var (struct variable *var)
1866 {
1867   if (var != NULL)
1868     {
1869       dict_delete_var (internal_dict, var);
1870
1871       /* Destroy internal_dict if it has no variables left, just so that
1872          valgrind --leak-check --show-reachable won't show internal_dict. */
1873       if (dict_get_n_vars (internal_dict) == 0)
1874         {
1875           dict_unref (internal_dict);
1876           internal_dict = NULL;
1877         }
1878     }
1879 }
1880 \f
1881 int
1882 vardict_get_dict_index (const struct vardict_info *vardict)
1883 {
1884   return vardict - vardict->dict->vars;
1885 }