64c4f8ac10977547da5f50b3669ffe9e7940884a
[pspp-builds.git] / src / data / dictionary.c
1 /* PSPP - computes sample statistics.
2    Copyright (C) 1997-9, 2000, 2006, 2007 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or
5    modify it under the terms of the GNU General Public License as
6    published by the Free Software Foundation; either version 2 of the
7    License, or (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful, but
10    WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    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, write to the Free Software
16    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17    02110-1301, USA. */
18
19 #include <config.h>
20
21 #include "dictionary.h"
22
23 #include <stdlib.h>
24 #include <ctype.h>
25
26 #include "case.h"
27 #include "category.h"
28 #include "settings.h"
29 #include "value-labels.h"
30 #include "vardict.h"
31 #include "variable.h"
32 #include "vector.h"
33 #include <libpspp/alloc.h>
34 #include <libpspp/array.h>
35 #include <libpspp/compiler.h>
36 #include <libpspp/hash.h>
37 #include <libpspp/message.h>
38 #include <libpspp/misc.h>
39 #include <libpspp/pool.h>
40 #include <libpspp/str.h>
41
42 #include "minmax.h"
43
44 #include "gettext.h"
45 #define _(msgid) gettext (msgid)
46
47 /* A dictionary. */
48 struct dictionary
49   {
50     struct variable **var;      /* Variables. */
51     size_t var_cnt, var_cap;    /* Number of variables, capacity. */
52     struct hsh_table *name_tab; /* Variable index by name. */
53     int next_value_idx;         /* Index of next `union value' to allocate. */
54     const struct variable **split;    /* SPLIT FILE vars. */
55     size_t split_cnt;           /* SPLIT FILE count. */
56     struct variable *weight;    /* WEIGHT variable. */
57     struct variable *filter;    /* FILTER variable. */
58     size_t case_limit;          /* Current case limit (N command). */
59     char *label;                /* File label. */
60     struct string documents;    /* Documents, as a string. */
61     struct vector **vector;     /* Vectors of variables. */
62     size_t vector_cnt;          /* Number of vectors. */
63     const struct dict_callbacks *callbacks; /* Callbacks on dictionary
64                                                modification */
65     void *cb_data ;                  /* Data passed to callbacks */
66   };
67
68
69 /* Associate CALLBACKS with DICT.  Callbacks will be invoked whenever
70    the dictionary or any of the variables it contains are modified.
71    Each callback will get passed CALLBACK_DATA.
72    Any callback may be NULL, in which case it'll be ignored.
73 */
74 void
75 dict_set_callbacks (struct dictionary *dict,
76                     const struct dict_callbacks *callbacks,
77                     void *callback_data)
78 {
79   dict->callbacks = callbacks;
80   dict->cb_data = callback_data;
81 }
82
83 /* Shallow copy the callbacks from SRC to DEST */
84 void
85 dict_copy_callbacks (struct dictionary *dest,
86                      const struct dictionary *src)
87 {
88   dest->callbacks = src->callbacks;
89   dest->cb_data = src->cb_data;
90 }
91
92 /* Creates and returns a new dictionary. */
93 struct dictionary *
94 dict_create (void)
95 {
96   struct dictionary *d = xzalloc (sizeof *d);
97
98   d->name_tab = hsh_create (8, compare_vars_by_name, hash_var_by_name,
99                             NULL, NULL);
100   return d;
101 }
102
103 /* Creates and returns a (deep) copy of an existing
104    dictionary. */
105 struct dictionary *
106 dict_clone (const struct dictionary *s)
107 {
108   struct dictionary *d;
109   size_t i;
110
111   assert (s != NULL);
112
113   d = dict_create ();
114
115   for (i = 0; i < s->var_cnt; i++)
116     {
117       struct variable *sv = s->var[i];
118       struct variable *dv = dict_clone_var_assert (d, sv, var_get_name (sv));
119       var_set_short_name (dv, var_get_short_name (sv));
120     }
121
122   d->next_value_idx = s->next_value_idx;
123
124   d->split_cnt = s->split_cnt;
125   if (d->split_cnt > 0)
126     {
127       d->split = xnmalloc (d->split_cnt, sizeof *d->split);
128       for (i = 0; i < d->split_cnt; i++)
129         d->split[i] = dict_lookup_var_assert (d, var_get_name (s->split[i]));
130     }
131
132   if (s->weight != NULL)
133     dict_set_weight (d, dict_lookup_var_assert (d, var_get_name (s->weight)));
134
135   if (s->filter != NULL)
136     dict_set_filter (d, dict_lookup_var_assert (d, var_get_name (s->filter)));
137
138   d->case_limit = s->case_limit;
139   dict_set_label (d, dict_get_label (s));
140   dict_set_documents (d, dict_get_documents (s));
141
142   d->vector_cnt = s->vector_cnt;
143   d->vector = xnmalloc (d->vector_cnt, sizeof *d->vector);
144   for (i = 0; i < s->vector_cnt; i++)
145     d->vector[i] = vector_clone (s->vector[i], s, d);
146
147   return d;
148 }
149
150 /* Clears the contents from a dictionary without destroying the
151    dictionary itself. */
152 void
153 dict_clear (struct dictionary *d)
154 {
155   /* FIXME?  Should we really clear case_limit, label, documents?
156      Others are necessarily cleared by deleting all the variables.*/
157   assert (d != NULL);
158
159   while (d->var_cnt > 0 )
160     {
161       var_clear_vardict (d->var[d->var_cnt - 1]);
162       var_destroy (d->var[d->var_cnt -1]);
163
164       d->var_cnt--;
165
166       if (d->callbacks &&  d->callbacks->var_deleted )
167         d->callbacks->var_deleted (d, d->var_cnt, d->cb_data);
168     }
169   free (d->var);
170   d->var = NULL;
171   d->var_cnt = d->var_cap = 0;
172   hsh_clear (d->name_tab);
173   d->next_value_idx = 0;
174   dict_set_split_vars (d, NULL, 0);
175   dict_set_weight (d, NULL);
176   dict_set_filter (d, NULL);
177   d->case_limit = 0;
178   free (d->label);
179   d->label = NULL;
180   ds_destroy (&d->documents);
181   dict_clear_vectors (d);
182 }
183
184 /* Destroys the aux data for every variable in D, by calling
185    var_clear_aux() for each variable. */
186 void
187 dict_clear_aux (struct dictionary *d)
188 {
189   int i;
190
191   assert (d != NULL);
192
193   for (i = 0; i < d->var_cnt; i++)
194     var_clear_aux (d->var[i]);
195 }
196
197 /* Clears a dictionary and destroys it. */
198 void
199 dict_destroy (struct dictionary *d)
200 {
201   if (d != NULL)
202     {
203       /* In general, we don't want callbacks occuring, if the dictionary
204          is being destroyed */
205       d->callbacks  = NULL ;
206
207       dict_clear (d);
208       hsh_destroy (d->name_tab);
209       free (d);
210     }
211 }
212
213 /* Returns the number of variables in D. */
214 size_t
215 dict_get_var_cnt (const struct dictionary *d)
216 {
217   assert (d != NULL);
218
219   return d->var_cnt;
220 }
221
222 /* Returns the variable in D with dictionary index IDX, which
223    must be between 0 and the count returned by
224    dict_get_var_cnt(), exclusive. */
225 struct variable *
226 dict_get_var (const struct dictionary *d, size_t idx)
227 {
228   assert (d != NULL);
229   assert (idx < d->var_cnt);
230
231   return d->var[idx];
232 }
233
234 inline void
235 dict_get_vars (const struct dictionary *d, const struct variable ***vars,
236                size_t *cnt, unsigned exclude_classes)
237 {
238   dict_get_vars_mutable (d, (struct variable ***) vars, cnt, exclude_classes);
239 }
240
241 /* Sets *VARS to an array of pointers to variables in D and *CNT
242    to the number of variables in *D.  All variables are returned
243    if EXCLUDE_CLASSES is 0, or it may contain one or more of (1u
244    << DC_ORDINARY), (1u << DC_SYSTEM), or (1u << DC_SCRATCH) to
245    exclude the corresponding type of variable. */
246 void
247 dict_get_vars_mutable (const struct dictionary *d, struct variable ***vars,
248                size_t *cnt, unsigned exclude_classes)
249 {
250   size_t count;
251   size_t i;
252
253   assert (d != NULL);
254   assert (vars != NULL);
255   assert (cnt != NULL);
256   assert ((exclude_classes & ~((1u << DC_ORDINARY)
257                                | (1u << DC_SYSTEM)
258                                | (1u << DC_SCRATCH))) == 0);
259
260   count = 0;
261   for (i = 0; i < d->var_cnt; i++)
262     {
263       enum dict_class class = dict_class_from_id (var_get_name (d->var[i]));
264       if (!(exclude_classes & (1u << class)))
265         count++;
266     }
267
268   *vars = xnmalloc (count, sizeof **vars);
269   *cnt = 0;
270   for (i = 0; i < d->var_cnt; i++)
271     {
272       enum dict_class class = dict_class_from_id (var_get_name (d->var[i]));
273       if (!(exclude_classes & (1u << class)))
274         (*vars)[(*cnt)++] = d->var[i];
275     }
276   assert (*cnt == count);
277 }
278
279 static struct variable *
280 add_var (struct dictionary *d, struct variable *v)
281 {
282   /* Add dictionary info to variable. */
283   struct vardict_info vdi;
284   vdi.case_index = d->next_value_idx;
285   vdi.dict_index = d->var_cnt;
286   vdi.dict = d;
287   var_set_vardict (v, &vdi);
288
289   /* Update dictionary. */
290   if (d->var_cnt >= d->var_cap)
291     {
292       d->var_cap = 8 + 2 * d->var_cap;
293       d->var = xnrealloc (d->var, d->var_cap, sizeof *d->var);
294     }
295   d->var[d->var_cnt++] = v;
296   hsh_force_insert (d->name_tab, v);
297
298   if ( d->callbacks &&  d->callbacks->var_added )
299     d->callbacks->var_added (d, var_get_dict_index (v), d->cb_data);
300
301   d->next_value_idx += var_get_value_cnt (v);
302
303   return v;
304 }
305
306 /* Creates and returns a new variable in D with the given NAME
307    and WIDTH.  Returns a null pointer if the given NAME would
308    duplicate that of an existing variable in the dictionary. */
309 struct variable *
310 dict_create_var (struct dictionary *d, const char *name, int width)
311 {
312   return (dict_lookup_var (d, name) == NULL
313           ? dict_create_var_assert (d, name, width)
314           : NULL);
315 }
316
317 /* Creates and returns a new variable in D with the given NAME
318    and WIDTH.  Assert-fails if the given NAME would duplicate
319    that of an existing variable in the dictionary. */
320 struct variable *
321 dict_create_var_assert (struct dictionary *d, const char *name, int width)
322 {
323   assert (dict_lookup_var (d, name) == NULL);
324   return add_var (d, var_create (name, width));
325 }
326
327 /* Creates and returns a new variable in D with name NAME, as a
328    copy of existing variable OLD_VAR, which need not be in D or
329    in any dictionary.  Returns a null pointer if the given NAME
330    would duplicate that of an existing variable in the
331    dictionary. */
332 struct variable *
333 dict_clone_var (struct dictionary *d, const struct variable *old_var,
334                 const char *name)
335 {
336   return (dict_lookup_var (d, name) == NULL
337           ? dict_clone_var_assert (d, old_var, name)
338           : NULL);
339 }
340
341 /* Creates and returns a new variable in D with name NAME, as a
342    copy of existing variable OLD_VAR, which need not be in D or
343    in any dictionary.  Assert-fails if the given NAME would
344    duplicate that of an existing variable in the dictionary. */
345 struct variable *
346 dict_clone_var_assert (struct dictionary *d, const struct variable *old_var,
347                        const char *name)
348 {
349   struct variable *new_var = var_clone (old_var);
350   assert (dict_lookup_var (d, name) == NULL);
351   var_set_name (new_var, name);
352   return add_var (d, new_var);
353 }
354
355 /* Returns the variable named NAME in D, or a null pointer if no
356    variable has that name. */
357 struct variable *
358 dict_lookup_var (const struct dictionary *d, const char *name)
359 {
360   struct variable *target ;
361   struct variable *result ;
362
363   if ( ! var_is_valid_name (name, false))
364     return NULL;
365
366   target = var_create (name, 0);
367   result = hsh_find (d->name_tab, target);
368   var_destroy (target);
369
370   return result;
371 }
372
373 /* Returns the variable named NAME in D.  Assert-fails if no
374    variable has that name. */
375 struct variable *
376 dict_lookup_var_assert (const struct dictionary *d, const char *name)
377 {
378   struct variable *v = dict_lookup_var (d, name);
379   assert (v != NULL);
380   return v;
381 }
382
383 /* Returns true if variable V is in dictionary D,
384    false otherwise. */
385 bool
386 dict_contains_var (const struct dictionary *d, const struct variable *v)
387 {
388   if (var_has_vardict (v))
389     {
390       const struct vardict_info *vdi = var_get_vardict (v);
391       return (vdi->dict_index >= 0
392               && vdi->dict_index < d->var_cnt
393               && d->var[vdi->dict_index] == v);
394     }
395   else
396     return false;
397 }
398
399 /* Compares two double pointers to variables, which should point
400    to elements of a struct dictionary's `var' member array. */
401 static int
402 compare_var_ptrs (const void *a_, const void *b_, const void *aux UNUSED)
403 {
404   struct variable *const *a = a_;
405   struct variable *const *b = b_;
406
407   return *a < *b ? -1 : *a > *b;
408 }
409
410 /* Sets the dict_index in V's vardict to DICT_INDEX. */
411 static void
412 set_var_dict_index (struct variable *v, int dict_index)
413 {
414   struct vardict_info vdi = *var_get_vardict (v);
415   struct dictionary *d = vdi.dict;
416   vdi.dict_index = dict_index;
417   var_set_vardict (v, &vdi);
418
419   if ( d->callbacks &&  d->callbacks->var_changed )
420     d->callbacks->var_changed (d, dict_index, d->cb_data);
421 }
422
423 /* Sets the case_index in V's vardict to DICT_INDEX. */
424 static void
425 set_var_case_index (struct variable *v, int case_index)
426 {
427   struct vardict_info vdi = *var_get_vardict (v);
428   vdi.case_index = case_index;
429   var_set_vardict (v, &vdi);
430 }
431
432 /* Re-sets the dict_index in the dictionary variables with
433    indexes from FROM to TO (exclusive). */
434 static void
435 reindex_vars (struct dictionary *d, size_t from, size_t to)
436 {
437   size_t i;
438
439   for (i = from; i < to; i++)
440     set_var_dict_index (d->var[i], i);
441 }
442
443 /* Deletes variable V from dictionary D and frees V.
444
445    This is a very bad idea if there might be any pointers to V
446    from outside D.  In general, no variable in the active file's
447    dictionary should be deleted when any transformations are
448    active on the dictionary's dataset, because those
449    transformations might reference the deleted variable.  The
450    safest time to delete a variable is just after a procedure has
451    been executed, as done by MODIFY VARS.
452
453    Pointers to V within D are not a problem, because
454    dict_delete_var() knows to remove V from split variables,
455    weights, filters, etc. */
456 void
457 dict_delete_var (struct dictionary *d, struct variable *v)
458 {
459   int dict_index = var_get_dict_index (v);
460
461   assert (dict_contains_var (d, v));
462
463   /* Delete aux data. */
464   var_clear_aux (v);
465
466   dict_unset_split_var (d, v);
467
468   if (d->weight == v)
469     dict_set_weight (d, NULL);
470
471   if (d->filter == v)
472     dict_set_filter (d, NULL);
473
474   dict_clear_vectors (d);
475
476   /* Remove V from var array. */
477   remove_element (d->var, d->var_cnt, sizeof *d->var, dict_index);
478   d->var_cnt--;
479
480   /* Update dict_index for each affected variable. */
481   reindex_vars (d, dict_index, d->var_cnt);
482
483   /* Update name hash. */
484   hsh_force_delete (d->name_tab, v);
485
486
487   /* Free memory. */
488   var_clear_vardict (v);
489   var_destroy (v);
490
491   if (d->callbacks &&  d->callbacks->var_deleted )
492     d->callbacks->var_deleted (d, dict_index, d->cb_data);
493 }
494
495 /* Deletes the COUNT variables listed in VARS from D.  This is
496    unsafe; see the comment on dict_delete_var() for details. */
497 void
498 dict_delete_vars (struct dictionary *d,
499                   struct variable *const *vars, size_t count)
500 {
501   /* FIXME: this can be done in O(count) time, but this algorithm
502      is O(count**2). */
503   assert (d != NULL);
504   assert (count == 0 || vars != NULL);
505
506   while (count-- > 0)
507     dict_delete_var (d, *vars++);
508 }
509
510 /* Deletes the COUNT variables in D starting at index IDX.  This
511    is unsafe; see the comment on dict_delete_var() for
512    details. */
513 void
514 dict_delete_consecutive_vars (struct dictionary *d, size_t idx, size_t count)
515 {
516   /* FIXME: this can be done in O(count) time, but this algorithm
517      is O(count**2). */
518   assert (idx + count <= d->var_cnt);
519
520   while (count-- > 0)
521     dict_delete_var (d, d->var[idx]);
522 }
523
524 /* Deletes scratch variables from dictionary D. */
525 void
526 dict_delete_scratch_vars (struct dictionary *d)
527 {
528   int i;
529
530   /* FIXME: this can be done in O(count) time, but this algorithm
531      is O(count**2). */
532   assert (d != NULL);
533
534   for (i = 0; i < d->var_cnt; )
535     if (dict_class_from_id (var_get_name (d->var[i])) == DC_SCRATCH)
536       dict_delete_var (d, d->var[i]);
537     else
538       i++;
539 }
540
541 /* Moves V to 0-based position IDX in D.  Other variables in D,
542    if any, retain their relative positions.  Runs in time linear
543    in the distance moved. */
544 void
545 dict_reorder_var (struct dictionary *d, struct variable *v, size_t new_index)
546 {
547   size_t old_index = var_get_dict_index (v);
548
549   assert (new_index < d->var_cnt);
550   move_element (d->var, d->var_cnt, sizeof *d->var, old_index, new_index);
551   reindex_vars (d, MIN (old_index, new_index), MAX (old_index, new_index) + 1);
552 }
553
554 /* Reorders the variables in D, placing the COUNT variables
555    listed in ORDER in that order at the beginning of D.  The
556    other variables in D, if any, retain their relative
557    positions. */
558 void
559 dict_reorder_vars (struct dictionary *d,
560                    struct variable *const *order, size_t count)
561 {
562   struct variable **new_var;
563   size_t i;
564
565   assert (d != NULL);
566   assert (count == 0 || order != NULL);
567   assert (count <= d->var_cnt);
568
569   new_var = xnmalloc (d->var_cnt, sizeof *new_var);
570   memcpy (new_var, order, count * sizeof *new_var);
571   for (i = 0; i < count; i++)
572     {
573       size_t index = var_get_dict_index (order[i]);
574       assert (d->var[index] == order[i]);
575       d->var[index] = NULL;
576       set_var_dict_index (order[i], i);
577     }
578   for (i = 0; i < d->var_cnt; i++)
579     if (d->var[i] != NULL)
580       {
581         assert (count < d->var_cnt);
582         new_var[count] = d->var[i];
583         set_var_dict_index (new_var[count], count);
584         count++;
585       }
586   free (d->var);
587   d->var = new_var;
588 }
589
590 /* Changes the name of variable V in dictionary D to NEW_NAME. */
591 static void
592 rename_var (struct dictionary *d, struct variable *v, const char *new_name)
593 {
594   struct vardict_info vdi;
595
596   assert (dict_contains_var (d, v));
597
598   vdi = *var_get_vardict (v);
599   var_clear_vardict (v);
600   var_set_name (v, new_name);
601   var_set_vardict (v, &vdi);
602 }
603
604 /* Changes the name of V in D to name NEW_NAME.  Assert-fails if
605    a variable named NEW_NAME is already in D, except that
606    NEW_NAME may be the same as V's existing name. */
607 void
608 dict_rename_var (struct dictionary *d, struct variable *v,
609                  const char *new_name)
610 {
611   assert (!strcasecmp (var_get_name (v), new_name)
612           || dict_lookup_var (d, new_name) == NULL);
613
614   hsh_force_delete (d->name_tab, v);
615   rename_var (d, v, new_name);
616   hsh_force_insert (d->name_tab, v);
617
618   if (get_algorithm () == ENHANCED)
619     var_clear_short_name (v);
620
621   if ( d->callbacks &&  d->callbacks->var_changed )
622     d->callbacks->var_changed (d, var_get_dict_index (v), d->cb_data);
623 }
624
625 /* Renames COUNT variables specified in VARS to the names given
626    in NEW_NAMES within dictionary D.  If the renaming would
627    result in a duplicate variable name, returns false and stores a
628    name that would be duplicated into *ERR_NAME (if ERR_NAME is
629    non-null).  Otherwise, the renaming is successful, and true
630    is returned. */
631 bool
632 dict_rename_vars (struct dictionary *d,
633                   struct variable **vars, char **new_names, size_t count,
634                   char **err_name)
635 {
636   struct pool *pool;
637   char **old_names;
638   size_t i;
639
640   assert (count == 0 || vars != NULL);
641   assert (count == 0 || new_names != NULL);
642
643   /* Save the names of the variables to be renamed. */
644   pool = pool_create ();
645   old_names = pool_nalloc (pool, count, sizeof *old_names);
646   for (i = 0; i < count; i++)
647     old_names[i] = pool_strdup (pool, var_get_name (vars[i]));
648
649   /* Remove the variables to be renamed from the name hash,
650      and rename them. */
651   for (i = 0; i < count; i++)
652     {
653       hsh_force_delete (d->name_tab, vars[i]);
654       rename_var (d, vars[i], new_names[i]);
655     }
656
657   /* Add the renamed variables back into the name hash,
658      checking for conflicts. */
659   for (i = 0; i < count; i++)
660     if (hsh_insert (d->name_tab, vars[i]) != NULL)
661       {
662         /* There is a name conflict.
663            Back out all the name changes that have already
664            taken place, and indicate failure. */
665         size_t fail_idx = i;
666         if (err_name != NULL)
667           *err_name = new_names[i];
668
669         for (i = 0; i < fail_idx; i++)
670           hsh_force_delete (d->name_tab, vars[i]);
671
672         for (i = 0; i < count; i++)
673           {
674             rename_var (d, vars[i], old_names[i]);
675             hsh_force_insert (d->name_tab, vars[i]);
676           }
677
678         pool_destroy (pool);
679         return false;
680       }
681
682   /* Clear short names. */
683   if (get_algorithm () == ENHANCED)
684     for (i = 0; i < count; i++)
685       var_clear_short_name (vars[i]);
686
687   pool_destroy (pool);
688   return true;
689 }
690
691 /* Returns the weighting variable in dictionary D, or a null
692    pointer if the dictionary is unweighted. */
693 struct variable *
694 dict_get_weight (const struct dictionary *d)
695 {
696   assert (d != NULL);
697   assert (d->weight == NULL || dict_contains_var (d, d->weight));
698
699   return d->weight;
700 }
701
702 /* Returns the value of D's weighting variable in case C, except that a
703    negative weight is returned as 0.  Returns 1 if the dictionary is
704    unweighted. Will warn about missing, negative, or zero values if
705    warn_on_invalid is true. The function will set warn_on_invalid to false
706    if an invalid weight is found. */
707 double
708 dict_get_case_weight (const struct dictionary *d, const struct ccase *c,
709                       bool *warn_on_invalid)
710 {
711   assert (d != NULL);
712   assert (c != NULL);
713
714   if (d->weight == NULL)
715     return 1.0;
716   else
717     {
718       double w = case_num (c, d->weight);
719       if (w < 0.0 || var_is_num_missing (d->weight, w, MV_ANY))
720         w = 0.0;
721       if ( w == 0.0 && warn_on_invalid != NULL && *warn_on_invalid ) {
722           *warn_on_invalid = false;
723           msg (SW, _("At least one case in the data file had a weight value "
724                      "that was user-missing, system-missing, zero, or "
725                      "negative.  These case(s) were ignored."));
726       }
727       return w;
728     }
729 }
730
731 /* Sets the weighting variable of D to V, or turning off
732    weighting if V is a null pointer. */
733 void
734 dict_set_weight (struct dictionary *d, struct variable *v)
735 {
736   assert (d != NULL);
737   assert (v == NULL || dict_contains_var (d, v));
738   assert (v == NULL || var_is_numeric (v));
739
740   d->weight = v;
741
742   if ( d->callbacks &&  d->callbacks->weight_changed )
743     d->callbacks->weight_changed (d,
744                                   v ? var_get_dict_index (v) : -1,
745                                   d->cb_data);
746 }
747
748 /* Returns the filter variable in dictionary D (see cmd_filter())
749    or a null pointer if the dictionary is unfiltered. */
750 struct variable *
751 dict_get_filter (const struct dictionary *d)
752 {
753   assert (d != NULL);
754   assert (d->filter == NULL || dict_contains_var (d, d->filter));
755
756   return d->filter;
757 }
758
759 /* Sets V as the filter variable for dictionary D.  Passing a
760    null pointer for V turn off filtering. */
761 void
762 dict_set_filter (struct dictionary *d, struct variable *v)
763 {
764   assert (d != NULL);
765   assert (v == NULL || dict_contains_var (d, v));
766
767   d->filter = v;
768
769   if ( d->callbacks && d->callbacks->filter_changed )
770     d->callbacks->filter_changed (d,
771                                   v ? var_get_dict_index (v) : -1,
772                                   d->cb_data);
773 }
774
775 /* Returns the case limit for dictionary D, or zero if the number
776    of cases is unlimited. */
777 size_t
778 dict_get_case_limit (const struct dictionary *d)
779 {
780   assert (d != NULL);
781
782   return d->case_limit;
783 }
784
785 /* Sets CASE_LIMIT as the case limit for dictionary D.  Use
786    0 for CASE_LIMIT to indicate no limit. */
787 void
788 dict_set_case_limit (struct dictionary *d, size_t case_limit)
789 {
790   assert (d != NULL);
791
792   d->case_limit = case_limit;
793 }
794
795 /* Returns the case index of the next value to be added to D.
796    This value is the number of `union value's that need to be
797    allocated to store a case for dictionary D. */
798 int
799 dict_get_next_value_idx (const struct dictionary *d)
800 {
801   assert (d != NULL);
802
803   return d->next_value_idx;
804 }
805
806 /* Returns the number of bytes needed to store a case for
807    dictionary D. */
808 size_t
809 dict_get_case_size (const struct dictionary *d)
810 {
811   assert (d != NULL);
812
813   return sizeof (union value) * dict_get_next_value_idx (d);
814 }
815
816 /* Deletes scratch variables in dictionary D and reassigns values
817    so that fragmentation is eliminated. */
818 void
819 dict_compact_values (struct dictionary *d)
820 {
821   size_t i;
822
823   d->next_value_idx = 0;
824   for (i = 0; i < d->var_cnt; )
825     {
826       struct variable *v = d->var[i];
827
828       if (dict_class_from_id (var_get_name (v)) != DC_SCRATCH)
829         {
830           set_var_case_index (v, d->next_value_idx);
831           d->next_value_idx += var_get_value_cnt (v);
832           i++;
833         }
834       else
835         dict_delete_var (d, v);
836     }
837 }
838
839 /* Returns the number of values that would be used by a case if
840    dict_compact_values() were called. */
841 size_t
842 dict_get_compacted_value_cnt (const struct dictionary *d)
843 {
844   size_t i;
845   size_t cnt;
846
847   cnt = 0;
848   for (i = 0; i < d->var_cnt; i++)
849     if (dict_class_from_id (var_get_name (d->var[i])) != DC_SCRATCH)
850       cnt += var_get_value_cnt (d->var[i]);
851   return cnt;
852 }
853
854 /* Creates and returns an array mapping from a dictionary index
855    to the case index that the corresponding variable will have
856    after calling dict_compact_values().  Scratch variables
857    receive -1 for case index because dict_compact_values() will
858    delete them. */
859 int *
860 dict_get_compacted_dict_index_to_case_index (const struct dictionary *d)
861 {
862   size_t i;
863   size_t next_value_idx;
864   int *map;
865
866   map = xnmalloc (d->var_cnt, sizeof *map);
867   next_value_idx = 0;
868   for (i = 0; i < d->var_cnt; i++)
869     {
870       struct variable *v = d->var[i];
871
872       if (dict_class_from_id (var_get_name (v)) != DC_SCRATCH)
873         {
874           map[i] = next_value_idx;
875           next_value_idx += var_get_value_cnt (v);
876         }
877       else
878         map[i] = -1;
879     }
880   return map;
881 }
882
883 /* Returns true if a case for dictionary D would be smaller after
884    compacting, false otherwise.  Compacting a case eliminates
885    "holes" between values and after the last value.  Holes are
886    created by deleting variables (or by scratch variables).
887
888    The return value may differ from whether compacting a case
889    from dictionary D would *change* the case: compacting could
890    rearrange values even if it didn't reduce space
891    requirements. */
892 bool
893 dict_compacting_would_shrink (const struct dictionary *d)
894 {
895   return dict_get_compacted_value_cnt (d) < dict_get_next_value_idx (d);
896 }
897
898 /* Returns true if a case for dictionary D would change after
899    compacting, false otherwise.  Compacting a case eliminates
900    "holes" between values and after the last value.  Holes are
901    created by deleting variables (or by scratch variables).
902
903    The return value may differ from whether compacting a case
904    from dictionary D would *shrink* the case: compacting could
905    rearrange values without reducing space requirements. */
906 bool
907 dict_compacting_would_change (const struct dictionary *d)
908 {
909   size_t case_idx;
910   size_t i;
911
912   case_idx = 0;
913   for (i = 0; i < dict_get_var_cnt (d); i++)
914     {
915       struct variable *v = dict_get_var (d, i);
916       if (var_get_case_index (v) != case_idx)
917         return true;
918       case_idx += var_get_value_cnt (v);
919     }
920   return false;
921 }
922 \f
923 /* How to copy a contiguous range of values between cases. */
924 struct copy_map
925   {
926     size_t src_idx;             /* Starting value index in source case. */
927     size_t dst_idx;             /* Starting value index in target case. */
928     size_t cnt;                 /* Number of values. */
929   };
930
931 /* How to compact a case. */
932 struct dict_compactor
933   {
934     struct copy_map *maps;      /* Array of mappings. */
935     size_t map_cnt;             /* Number of mappings. */
936   };
937
938 /* Creates and returns a dict_compactor that can be used to
939    compact cases for dictionary D.
940
941    Compacting a case eliminates "holes" between values and after
942    the last value.  Holes are created by deleting variables (or
943    by scratch variables). */
944 struct dict_compactor *
945 dict_make_compactor (const struct dictionary *d)
946 {
947   struct dict_compactor *compactor;
948   struct copy_map *map;
949   size_t map_allocated;
950   size_t value_idx;
951   size_t i;
952
953   compactor = xmalloc (sizeof *compactor);
954   compactor->maps = NULL;
955   compactor->map_cnt = 0;
956   map_allocated = 0;
957
958   value_idx = 0;
959   map = NULL;
960   for (i = 0; i < d->var_cnt; i++)
961     {
962       struct variable *v = d->var[i];
963
964       if (dict_class_from_id (var_get_name (v)) == DC_SCRATCH)
965         continue;
966       if (map != NULL && map->src_idx + map->cnt == var_get_case_index (v))
967         map->cnt += var_get_value_cnt (v);
968       else
969         {
970           if (compactor->map_cnt == map_allocated)
971             compactor->maps = x2nrealloc (compactor->maps, &map_allocated,
972                                           sizeof *compactor->maps);
973           map = &compactor->maps[compactor->map_cnt++];
974           map->src_idx = var_get_case_index (v);
975           map->dst_idx = value_idx;
976           map->cnt = var_get_value_cnt (v);
977         }
978       value_idx += var_get_value_cnt (v);
979     }
980
981   return compactor;
982 }
983
984 /* Compacts SRC by copying it to DST according to the scheme in
985    COMPACTOR.
986
987    Compacting a case eliminates "holes" between values and after
988    the last value.  Holes are created by deleting variables (or
989    by scratch variables). */
990 void
991 dict_compactor_compact (const struct dict_compactor *compactor,
992                         struct ccase *dst, const struct ccase *src)
993 {
994   size_t i;
995
996   for (i = 0; i < compactor->map_cnt; i++)
997     {
998       const struct copy_map *map = &compactor->maps[i];
999       case_copy (dst, map->dst_idx, src, map->src_idx, map->cnt);
1000     }
1001 }
1002
1003 /* Destroys COMPACTOR. */
1004 void
1005 dict_compactor_destroy (struct dict_compactor *compactor)
1006 {
1007   if (compactor != NULL)
1008     {
1009       free (compactor->maps);
1010       free (compactor);
1011     }
1012 }
1013
1014 /* Returns the SPLIT FILE vars (see cmd_split_file()).  Call
1015    dict_get_split_cnt() to determine how many SPLIT FILE vars
1016    there are.  Returns a null pointer if and only if there are no
1017    SPLIT FILE vars. */
1018 const struct variable *const *
1019 dict_get_split_vars (const struct dictionary *d)
1020 {
1021   assert (d != NULL);
1022
1023   return d->split;
1024 }
1025
1026 /* Returns the number of SPLIT FILE vars. */
1027 size_t
1028 dict_get_split_cnt (const struct dictionary *d)
1029 {
1030   assert (d != NULL);
1031
1032   return d->split_cnt;
1033 }
1034
1035 /* Removes variable V from the set of split variables in dictionary D */
1036 void
1037 dict_unset_split_var (struct dictionary *d,
1038                       struct variable *v)
1039 {
1040   const int count = d->split_cnt;
1041   d->split_cnt = remove_equal (d->split, d->split_cnt, sizeof *d->split,
1042                                &v, compare_var_ptrs, NULL);
1043
1044   if ( count == d->split_cnt)
1045     return;
1046
1047   if ( d->callbacks &&  d->callbacks->split_changed )
1048     d->callbacks->split_changed (d, d->cb_data);
1049 }
1050
1051 /* Sets CNT split vars SPLIT in dictionary D. */
1052 void
1053 dict_set_split_vars (struct dictionary *d,
1054                      struct variable *const *split, size_t cnt)
1055 {
1056   assert (d != NULL);
1057   assert (cnt == 0 || split != NULL);
1058
1059   d->split_cnt = cnt;
1060   d->split = cnt > 0 ? xnrealloc (d->split, cnt, sizeof *d->split) : NULL;
1061   memcpy (d->split, split, cnt * sizeof *d->split);
1062
1063   if ( d->callbacks &&  d->callbacks->split_changed )
1064     d->callbacks->split_changed (d, d->cb_data);
1065 }
1066
1067 /* Returns the file label for D, or a null pointer if D is
1068    unlabeled (see cmd_file_label()). */
1069 const char *
1070 dict_get_label (const struct dictionary *d)
1071 {
1072   assert (d != NULL);
1073
1074   return d->label;
1075 }
1076
1077 /* Sets D's file label to LABEL, truncating it to a maximum of 60
1078    characters. */
1079 void
1080 dict_set_label (struct dictionary *d, const char *label)
1081 {
1082   assert (d != NULL);
1083
1084   free (d->label);
1085   if (label == NULL)
1086     d->label = NULL;
1087   else if (strlen (label) < 60)
1088     d->label = xstrdup (label);
1089   else
1090     {
1091       d->label = xmalloc (61);
1092       memcpy (d->label, label, 60);
1093       d->label[60] = '\0';
1094     }
1095 }
1096
1097 /* Returns the documents for D, or a null pointer if D has no
1098    documents.  If the return value is nonnull, then the string
1099    will be an exact multiple of DOC_LINE_LENGTH bytes in length,
1100    with each segment corresponding to one line. */
1101 const char *
1102 dict_get_documents (const struct dictionary *d)
1103 {
1104   return ds_is_empty (&d->documents) ? NULL : ds_cstr (&d->documents);
1105 }
1106
1107 /* Sets the documents for D to DOCUMENTS, or removes D's
1108    documents if DOCUMENT is a null pointer.  If DOCUMENTS is
1109    nonnull, then it should be an exact multiple of
1110    DOC_LINE_LENGTH bytes in length, with each segment
1111    corresponding to one line. */
1112 void
1113 dict_set_documents (struct dictionary *d, const char *documents)
1114 {
1115   size_t remainder;
1116
1117   ds_assign_cstr (&d->documents, documents != NULL ? documents : "");
1118
1119   /* In case the caller didn't get it quite right, pad out the
1120      final line with spaces. */
1121   remainder = ds_length (&d->documents) % DOC_LINE_LENGTH;
1122   if (remainder != 0)
1123     ds_put_char_multiple (&d->documents, ' ', DOC_LINE_LENGTH - remainder);
1124 }
1125
1126 /* Drops the documents from dictionary D. */
1127 void
1128 dict_clear_documents (struct dictionary *d)
1129 {
1130   ds_clear (&d->documents);
1131 }
1132
1133 /* Appends LINE to the documents in D.  LINE will be truncated or
1134    padded on the right with spaces to make it exactly
1135    DOC_LINE_LENGTH bytes long. */
1136 void
1137 dict_add_document_line (struct dictionary *d, const char *line)
1138 {
1139   if (strlen (line) > DOC_LINE_LENGTH)
1140     {
1141       /* Note to translators: "bytes" is correct, not characters */
1142       msg (SW, _("Truncating document line to %d bytes."), DOC_LINE_LENGTH);
1143     }
1144   buf_copy_str_rpad (ds_put_uninit (&d->documents, DOC_LINE_LENGTH),
1145                      DOC_LINE_LENGTH, line);
1146 }
1147
1148 /* Returns the number of document lines in dictionary D. */
1149 size_t
1150 dict_get_document_line_cnt (const struct dictionary *d)
1151 {
1152   return ds_length (&d->documents) / DOC_LINE_LENGTH;
1153 }
1154
1155 /* Copies document line number IDX from dictionary D into
1156    LINE, trimming off any trailing white space. */
1157 void
1158 dict_get_document_line (const struct dictionary *d,
1159                         size_t idx, struct string *line)
1160 {
1161   assert (idx < dict_get_document_line_cnt (d));
1162   ds_assign_substring (line, ds_substr (&d->documents, idx * DOC_LINE_LENGTH,
1163                                         DOC_LINE_LENGTH));
1164   ds_rtrim (line, ss_cstr (CC_SPACES));
1165 }
1166
1167 /* Creates in D a vector named NAME that contains the CNT
1168    variables in VAR.  Returns true if successful, or false if a
1169    vector named NAME already exists in D. */
1170 bool
1171 dict_create_vector (struct dictionary *d,
1172                     const char *name,
1173                     struct variable **var, size_t cnt)
1174 {
1175   size_t i;
1176
1177   assert (var != NULL);
1178   assert (cnt > 0);
1179   for (i = 0; i < cnt; i++)
1180     assert (dict_contains_var (d, var[i]));
1181
1182   if (dict_lookup_vector (d, name) == NULL)
1183     {
1184       d->vector = xnrealloc (d->vector, d->vector_cnt + 1, sizeof *d->vector);
1185       d->vector[d->vector_cnt++] = vector_create (name, var, cnt);
1186       return true;
1187     }
1188   else
1189     return false;
1190 }
1191
1192 /* Creates in D a vector named NAME that contains the CNT
1193    variables in VAR.  A vector named NAME must not already exist
1194    in D. */
1195 void
1196 dict_create_vector_assert (struct dictionary *d,
1197                            const char *name,
1198                            struct variable **var, size_t cnt)
1199 {
1200   assert (dict_lookup_vector (d, name) == NULL);
1201   dict_create_vector (d, name, var, cnt);
1202 }
1203
1204 /* Returns the vector in D with index IDX, which must be less
1205    than dict_get_vector_cnt (D). */
1206 const struct vector *
1207 dict_get_vector (const struct dictionary *d, size_t idx)
1208 {
1209   assert (d != NULL);
1210   assert (idx < d->vector_cnt);
1211
1212   return d->vector[idx];
1213 }
1214
1215 /* Returns the number of vectors in D. */
1216 size_t
1217 dict_get_vector_cnt (const struct dictionary *d)
1218 {
1219   assert (d != NULL);
1220
1221   return d->vector_cnt;
1222 }
1223
1224 /* Looks up and returns the vector within D with the given
1225    NAME. */
1226 const struct vector *
1227 dict_lookup_vector (const struct dictionary *d, const char *name)
1228 {
1229   size_t i;
1230   for (i = 0; i < d->vector_cnt; i++)
1231     if (!strcasecmp (vector_get_name (d->vector[i]), name))
1232       return d->vector[i];
1233   return NULL;
1234 }
1235
1236 /* Deletes all vectors from D. */
1237 void
1238 dict_clear_vectors (struct dictionary *d)
1239 {
1240   size_t i;
1241
1242   for (i = 0; i < d->vector_cnt; i++)
1243     vector_destroy (d->vector[i]);
1244   free (d->vector);
1245
1246   d->vector = NULL;
1247   d->vector_cnt = 0;
1248 }
1249
1250 /* Compares two strings. */
1251 static int
1252 compare_strings (const void *a, const void *b, const void *aux UNUSED)
1253 {
1254   return strcmp (a, b);
1255 }
1256
1257 /* Hashes a string. */
1258 static unsigned
1259 hash_string (const void *s, const void *aux UNUSED)
1260 {
1261   return hsh_hash_string (s);
1262 }
1263
1264
1265 /* Sets V's short name to BASE, followed by a suffix of the form
1266    _A, _B, _C, ..., _AA, _AB, etc. according to the value of
1267    SUFFIX_NUMBER.  Truncates BASE as necessary to fit. */
1268 static void
1269 set_var_short_name_suffix (struct variable *v, const char *base,
1270                            int suffix_number)
1271 {
1272   char suffix[SHORT_NAME_LEN + 1];
1273   char short_name[SHORT_NAME_LEN + 1];
1274   char *start, *end;
1275   int len, ofs;
1276
1277   assert (v != NULL);
1278   assert (suffix_number >= 0);
1279
1280   /* Set base name. */
1281   var_set_short_name (v, base);
1282
1283   /* Compose suffix. */
1284   start = end = suffix + sizeof suffix - 1;
1285   *end = '\0';
1286   do
1287     {
1288       *--start = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[suffix_number % 26];
1289       if (start <= suffix + 1)
1290         msg (SE, _("Variable suffix too large."));
1291       suffix_number /= 26;
1292     }
1293   while (suffix_number > 0);
1294   *--start = '_';
1295
1296   /* Append suffix to V's short name. */
1297   str_copy_trunc (short_name, sizeof short_name, base);
1298   len = end - start;
1299   if (len + strlen (short_name) > SHORT_NAME_LEN)
1300     ofs = SHORT_NAME_LEN - len;
1301   else
1302     ofs = strlen (short_name);
1303   strcpy (short_name + ofs, start);
1304
1305   /* Set name. */
1306   var_set_short_name (v, short_name);
1307 }
1308
1309 /* Assigns a valid, unique short_name[] to each variable in D.
1310    Each variable whose actual name is short has highest priority
1311    for that short name.  Otherwise, variables with an existing
1312    short_name[] have the next highest priority for a given short
1313    name; if it is already taken, then the variable is treated as
1314    if short_name[] had been empty.  Otherwise, long names are
1315    truncated to form short names.  If that causes conflicts,
1316    variables are renamed as PREFIX_A, PREFIX_B, and so on. */
1317 void
1318 dict_assign_short_names (struct dictionary *d)
1319 {
1320   struct hsh_table *short_names;
1321   size_t i;
1322
1323   /* Give variables whose names are short the corresponding short
1324      names, and clear short_names[] that conflict with a variable
1325      name. */
1326   for (i = 0; i < d->var_cnt; i++)
1327     {
1328       struct variable *v = d->var[i];
1329       const char *short_name = var_get_short_name (v);
1330       if (strlen (var_get_name (v)) <= SHORT_NAME_LEN)
1331         var_set_short_name (v, var_get_name (v));
1332       else if (short_name != NULL && dict_lookup_var (d, short_name) != NULL)
1333         var_clear_short_name (v);
1334     }
1335
1336   /* Each variable with an assigned short_name[] now gets it
1337      unless there is a conflict. */
1338   short_names = hsh_create (d->var_cnt, compare_strings, hash_string,
1339                             NULL, NULL);
1340   for (i = 0; i < d->var_cnt; i++)
1341     {
1342       struct variable *v = d->var[i];
1343       const char *name = var_get_short_name (v);
1344       if (name != NULL && hsh_insert (short_names, (char *) name) != NULL)
1345         var_clear_short_name (v);
1346     }
1347
1348   /* Now assign short names to remaining variables. */
1349   for (i = 0; i < d->var_cnt; i++)
1350     {
1351       struct variable *v = d->var[i];
1352       const char *name = var_get_short_name (v);
1353       if (name == NULL)
1354         {
1355           /* Form initial short_name from the variable name, then
1356              try _A, _B, ... _AA, _AB, etc., if needed.*/
1357           int trial = 0;
1358           do
1359             {
1360               if (trial == 0)
1361                 var_set_short_name (v, var_get_name (v));
1362               else
1363                 set_var_short_name_suffix (v, var_get_name (v), trial - 1);
1364
1365               trial++;
1366             }
1367           while (hsh_insert (short_names, (char *) var_get_short_name (v))
1368                  != NULL);
1369         }
1370     }
1371
1372   /* Get rid of hash table. */
1373   hsh_destroy (short_names);
1374 }
1375
1376
1377 /* Called from variable.c to notify the dictionary that some property of
1378    the variable has changed */
1379 void
1380 dict_var_changed (const struct variable *v)
1381 {
1382   if ( var_has_vardict (v))
1383     {
1384       const struct vardict_info *vdi = var_get_vardict (v);
1385       struct dictionary *d;
1386
1387       d = vdi->dict;
1388
1389       if ( d->callbacks && d->callbacks->var_changed )
1390         d->callbacks->var_changed (d, var_get_dict_index (v), d->cb_data);
1391     }
1392 }