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