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