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