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