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