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