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