Added callback for when the weights on a dictionary change.
[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   if ( d->callbacks && d->callbacks->weight_changed )
741     d->callbacks->weight_changed (d,
742                                   v ? var_get_dict_index (v) : -1,
743                                   d->cb_data);
744 }
745
746 /* Returns the filter variable in dictionary D (see cmd_filter())
747    or a null pointer if the dictionary is unfiltered. */
748 struct variable *
749 dict_get_filter (const struct dictionary *d) 
750 {
751   assert (d != NULL);
752   assert (d->filter == NULL || dict_contains_var (d, d->filter));
753   
754   return d->filter;
755 }
756
757 /* Sets V as the filter variable for dictionary D.  Passing a
758    null pointer for V turn off filtering. */
759 void
760 dict_set_filter (struct dictionary *d, struct variable *v)
761 {
762   assert (d != NULL);
763   assert (v == NULL || dict_contains_var (d, v));
764
765   d->filter = v;
766 }
767
768 /* Returns the case limit for dictionary D, or zero if the number
769    of cases is unlimited. */
770 size_t
771 dict_get_case_limit (const struct dictionary *d) 
772 {
773   assert (d != NULL);
774
775   return d->case_limit;
776 }
777
778 /* Sets CASE_LIMIT as the case limit for dictionary D.  Use
779    0 for CASE_LIMIT to indicate no limit. */
780 void
781 dict_set_case_limit (struct dictionary *d, size_t case_limit) 
782 {
783   assert (d != NULL);
784
785   d->case_limit = case_limit;
786 }
787
788 /* Returns the case index of the next value to be added to D.
789    This value is the number of `union value's that need to be
790    allocated to store a case for dictionary D. */
791 int
792 dict_get_next_value_idx (const struct dictionary *d) 
793 {
794   assert (d != NULL);
795
796   return d->next_value_idx;
797 }
798
799 /* Returns the number of bytes needed to store a case for
800    dictionary D. */
801 size_t
802 dict_get_case_size (const struct dictionary *d) 
803 {
804   assert (d != NULL);
805
806   return sizeof (union value) * dict_get_next_value_idx (d);
807 }
808
809 /* Deletes scratch variables in dictionary D and reassigns values
810    so that fragmentation is eliminated. */
811 void
812 dict_compact_values (struct dictionary *d) 
813 {
814   size_t i;
815
816   d->next_value_idx = 0;
817   for (i = 0; i < d->var_cnt; )
818     {
819       struct variable *v = d->var[i];
820
821       if (dict_class_from_id (var_get_name (v)) != DC_SCRATCH) 
822         {
823           set_var_case_index (v, d->next_value_idx);
824           d->next_value_idx += var_get_value_cnt (v);
825           i++;
826         }
827       else
828         dict_delete_var (d, v);
829     }
830 }
831
832 /* Returns the number of values that would be used by a case if
833    dict_compact_values() were called. */
834 size_t
835 dict_get_compacted_value_cnt (const struct dictionary *d) 
836 {
837   size_t i;
838   size_t cnt;
839
840   cnt = 0;
841   for (i = 0; i < d->var_cnt; i++)
842     if (dict_class_from_id (var_get_name (d->var[i])) != DC_SCRATCH) 
843       cnt += var_get_value_cnt (d->var[i]);
844   return cnt;
845 }
846
847 /* Creates and returns an array mapping from a dictionary index
848    to the case index that the corresponding variable will have
849    after calling dict_compact_values().  Scratch variables
850    receive -1 for case index because dict_compact_values() will
851    delete them. */
852 int *
853 dict_get_compacted_dict_index_to_case_index (const struct dictionary *d) 
854 {
855   size_t i;
856   size_t next_value_idx;
857   int *map;
858   
859   map = xnmalloc (d->var_cnt, sizeof *map);
860   next_value_idx = 0;
861   for (i = 0; i < d->var_cnt; i++)
862     {
863       struct variable *v = d->var[i];
864
865       if (dict_class_from_id (var_get_name (v)) != DC_SCRATCH) 
866         {
867           map[i] = next_value_idx;
868           next_value_idx += var_get_value_cnt (v);
869         }
870       else 
871         map[i] = -1;
872     }
873   return map;
874 }
875
876 /* Returns true if a case for dictionary D would be smaller after
877    compacting, false otherwise.  Compacting a case eliminates
878    "holes" between values and after the last value.  Holes are
879    created by deleting variables (or by scratch variables).
880
881    The return value may differ from whether compacting a case
882    from dictionary D would *change* the case: compacting could
883    rearrange values even if it didn't reduce space
884    requirements. */
885 bool
886 dict_compacting_would_shrink (const struct dictionary *d) 
887 {
888   return dict_get_compacted_value_cnt (d) < dict_get_next_value_idx (d);
889 }
890
891 /* Returns true if a case for dictionary D would change after
892    compacting, false otherwise.  Compacting a case eliminates
893    "holes" between values and after the last value.  Holes are
894    created by deleting variables (or by scratch variables).
895
896    The return value may differ from whether compacting a case
897    from dictionary D would *shrink* the case: compacting could
898    rearrange values without reducing space requirements. */
899 bool
900 dict_compacting_would_change (const struct dictionary *d) 
901 {
902   size_t case_idx;
903   size_t i;
904
905   case_idx = 0;
906   for (i = 0; i < dict_get_var_cnt (d); i++) 
907     {
908       struct variable *v = dict_get_var (d, i);
909       if (var_get_case_index (v) != case_idx)
910         return true;
911       case_idx += var_get_value_cnt (v);
912     }
913   return false;
914 }
915 \f
916 /* How to copy a contiguous range of values between cases. */
917 struct copy_map
918   {
919     size_t src_idx;             /* Starting value index in source case. */
920     size_t dst_idx;             /* Starting value index in target case. */
921     size_t cnt;                 /* Number of values. */
922   };
923
924 /* How to compact a case. */
925 struct dict_compactor 
926   {
927     struct copy_map *maps;      /* Array of mappings. */
928     size_t map_cnt;             /* Number of mappings. */
929   };
930
931 /* Creates and returns a dict_compactor that can be used to
932    compact cases for dictionary D.
933
934    Compacting a case eliminates "holes" between values and after
935    the last value.  Holes are created by deleting variables (or
936    by scratch variables). */
937 struct dict_compactor *
938 dict_make_compactor (const struct dictionary *d)
939 {
940   struct dict_compactor *compactor;
941   struct copy_map *map;
942   size_t map_allocated;
943   size_t value_idx;
944   size_t i;
945
946   compactor = xmalloc (sizeof *compactor);
947   compactor->maps = NULL;
948   compactor->map_cnt = 0;
949   map_allocated = 0;
950
951   value_idx = 0;
952   map = NULL;
953   for (i = 0; i < d->var_cnt; i++) 
954     {
955       struct variable *v = d->var[i];
956
957       if (dict_class_from_id (var_get_name (v)) == DC_SCRATCH)
958         continue;
959       if (map != NULL && map->src_idx + map->cnt == var_get_case_index (v)) 
960         map->cnt += var_get_value_cnt (v);
961       else 
962         {
963           if (compactor->map_cnt == map_allocated)
964             compactor->maps = x2nrealloc (compactor->maps, &map_allocated,
965                                           sizeof *compactor->maps);
966           map = &compactor->maps[compactor->map_cnt++];
967           map->src_idx = var_get_case_index (v);
968           map->dst_idx = value_idx;
969           map->cnt = var_get_value_cnt (v);
970         }
971       value_idx += var_get_value_cnt (v);
972     }
973
974   return compactor;
975 }
976
977 /* Compacts SRC by copying it to DST according to the scheme in
978    COMPACTOR.
979
980    Compacting a case eliminates "holes" between values and after
981    the last value.  Holes are created by deleting variables (or
982    by scratch variables). */
983 void
984 dict_compactor_compact (const struct dict_compactor *compactor,
985                         struct ccase *dst, const struct ccase *src) 
986 {
987   size_t i;
988
989   for (i = 0; i < compactor->map_cnt; i++) 
990     {
991       const struct copy_map *map = &compactor->maps[i];
992       case_copy (dst, map->dst_idx, src, map->src_idx, map->cnt);
993     }
994 }
995
996 /* Destroys COMPACTOR. */
997 void
998 dict_compactor_destroy (struct dict_compactor *compactor) 
999 {
1000   if (compactor != NULL) 
1001     {
1002       free (compactor->maps);
1003       free (compactor);
1004     }
1005 }
1006
1007 /* Returns the SPLIT FILE vars (see cmd_split_file()).  Call
1008    dict_get_split_cnt() to determine how many SPLIT FILE vars
1009    there are.  Returns a null pointer if and only if there are no
1010    SPLIT FILE vars. */
1011 struct variable *const *
1012 dict_get_split_vars (const struct dictionary *d) 
1013 {
1014   assert (d != NULL);
1015   
1016   return d->split;
1017 }
1018
1019 /* Returns the number of SPLIT FILE vars. */
1020 size_t
1021 dict_get_split_cnt (const struct dictionary *d) 
1022 {
1023   assert (d != NULL);
1024
1025   return d->split_cnt;
1026 }
1027
1028 /* Sets CNT split vars SPLIT in dictionary D. */
1029 void
1030 dict_set_split_vars (struct dictionary *d,
1031                      struct variable *const *split, size_t cnt)
1032 {
1033   assert (d != NULL);
1034   assert (cnt == 0 || split != NULL);
1035
1036   d->split_cnt = cnt;
1037   d->split = xnrealloc (d->split, cnt, sizeof *d->split);
1038   memcpy (d->split, split, cnt * sizeof *d->split);
1039 }
1040
1041 /* Returns the file label for D, or a null pointer if D is
1042    unlabeled (see cmd_file_label()). */
1043 const char *
1044 dict_get_label (const struct dictionary *d) 
1045 {
1046   assert (d != NULL);
1047
1048   return d->label;
1049 }
1050
1051 /* Sets D's file label to LABEL, truncating it to a maximum of 60
1052    characters. */
1053 void
1054 dict_set_label (struct dictionary *d, const char *label) 
1055 {
1056   assert (d != NULL);
1057
1058   free (d->label);
1059   if (label == NULL)
1060     d->label = NULL;
1061   else if (strlen (label) < 60)
1062     d->label = xstrdup (label);
1063   else 
1064     {
1065       d->label = xmalloc (61);
1066       memcpy (d->label, label, 60);
1067       d->label[60] = '\0';
1068     }
1069 }
1070
1071 /* Returns the documents for D, or a null pointer if D has no
1072    documents (see cmd_document()).. */
1073 const char *
1074 dict_get_documents (const struct dictionary *d) 
1075 {
1076   assert (d != NULL);
1077
1078   return d->documents;
1079 }
1080
1081 /* Sets the documents for D to DOCUMENTS, or removes D's
1082    documents if DOCUMENT is a null pointer. */
1083 void
1084 dict_set_documents (struct dictionary *d, const char *documents)
1085 {
1086   assert (d != NULL);
1087
1088   free (d->documents);
1089   if (documents == NULL)
1090     d->documents = NULL;
1091   else
1092     d->documents = xstrdup (documents);
1093 }
1094
1095 /* Creates in D a vector named NAME that contains the CNT
1096    variables in VAR.  Returns true if successful, or false if a
1097    vector named NAME already exists in D. */
1098 bool
1099 dict_create_vector (struct dictionary *d,
1100                     const char *name,
1101                     struct variable **var, size_t cnt) 
1102 {
1103   size_t i;
1104
1105   assert (var != NULL);
1106   assert (cnt > 0);
1107   for (i = 0; i < cnt; i++)
1108     assert (dict_contains_var (d, var[i]));
1109   
1110   if (dict_lookup_vector (d, name) == NULL)
1111     {
1112       d->vector = xnrealloc (d->vector, d->vector_cnt + 1, sizeof *d->vector);
1113       d->vector[d->vector_cnt++] = vector_create (name, var, cnt);
1114       return true; 
1115     }
1116   else
1117     return false;
1118 }
1119
1120 /* Returns the vector in D with index IDX, which must be less
1121    than dict_get_vector_cnt (D). */
1122 const struct vector *
1123 dict_get_vector (const struct dictionary *d, size_t idx) 
1124 {
1125   assert (d != NULL);
1126   assert (idx < d->vector_cnt);
1127
1128   return d->vector[idx];
1129 }
1130
1131 /* Returns the number of vectors in D. */
1132 size_t
1133 dict_get_vector_cnt (const struct dictionary *d) 
1134 {
1135   assert (d != NULL);
1136
1137   return d->vector_cnt;
1138 }
1139
1140 /* Looks up and returns the vector within D with the given
1141    NAME. */
1142 const struct vector *
1143 dict_lookup_vector (const struct dictionary *d, const char *name) 
1144 {
1145   size_t i;
1146   for (i = 0; i < d->vector_cnt; i++)
1147     if (!strcasecmp (vector_get_name (d->vector[i]), name))
1148       return d->vector[i];
1149   return NULL;
1150 }
1151
1152 /* Deletes all vectors from D. */
1153 void
1154 dict_clear_vectors (struct dictionary *d) 
1155 {
1156   size_t i;
1157   
1158   for (i = 0; i < d->vector_cnt; i++)
1159     vector_destroy (d->vector[i]);
1160   free (d->vector);
1161
1162   d->vector = NULL;
1163   d->vector_cnt = 0;
1164 }
1165
1166 /* Compares two strings. */
1167 static int
1168 compare_strings (const void *a, const void *b, const void *aux UNUSED) 
1169 {
1170   return strcmp (a, b);
1171 }
1172
1173 /* Hashes a string. */
1174 static unsigned
1175 hash_string (const void *s, const void *aux UNUSED) 
1176 {
1177   return hsh_hash_string (s);
1178 }
1179
1180
1181 /* Sets V's short name to BASE, followed by a suffix of the form
1182    _A, _B, _C, ..., _AA, _AB, etc. according to the value of
1183    SUFFIX_NUMBER.  Truncates BASE as necessary to fit. */
1184 static void
1185 set_var_short_name_suffix (struct variable *v, const char *base,
1186                            int suffix_number)
1187 {
1188   char suffix[SHORT_NAME_LEN + 1];
1189   char short_name[SHORT_NAME_LEN + 1];
1190   char *start, *end;
1191   int len, ofs;
1192
1193   assert (v != NULL);
1194   assert (suffix_number >= 0);
1195
1196   /* Set base name. */
1197   var_set_short_name (v, base);
1198
1199   /* Compose suffix. */
1200   start = end = suffix + sizeof suffix - 1;
1201   *end = '\0';
1202   do 
1203     {
1204       *--start = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[suffix_number % 26];
1205       if (start <= suffix + 1)
1206         msg (SE, _("Variable suffix too large."));
1207       suffix_number /= 26;
1208     }
1209   while (suffix_number > 0);
1210   *--start = '_';
1211
1212   /* Append suffix to V's short name. */
1213   str_copy_trunc (short_name, sizeof short_name, base);
1214   len = end - start;
1215   if (len + strlen (short_name) > SHORT_NAME_LEN)
1216     ofs = SHORT_NAME_LEN - len;
1217   else
1218     ofs = strlen (short_name);
1219   strcpy (short_name + ofs, start);
1220
1221   /* Set name. */
1222   var_set_short_name (v, short_name);
1223 }
1224
1225 /* Assigns a valid, unique short_name[] to each variable in D.
1226    Each variable whose actual name is short has highest priority
1227    for that short name.  Otherwise, variables with an existing
1228    short_name[] have the next highest priority for a given short
1229    name; if it is already taken, then the variable is treated as
1230    if short_name[] had been empty.  Otherwise, long names are
1231    truncated to form short names.  If that causes conflicts,
1232    variables are renamed as PREFIX_A, PREFIX_B, and so on. */
1233 void
1234 dict_assign_short_names (struct dictionary *d) 
1235 {
1236   struct hsh_table *short_names;
1237   size_t i;
1238
1239   /* Give variables whose names are short the corresponding short
1240      names, and clear short_names[] that conflict with a variable
1241      name. */
1242   for (i = 0; i < d->var_cnt; i++)
1243     {
1244       struct variable *v = d->var[i];
1245       const char *short_name = var_get_short_name (v);
1246       if (strlen (var_get_name (v)) <= SHORT_NAME_LEN)
1247         var_set_short_name (v, var_get_name (v));
1248       else if (short_name != NULL && dict_lookup_var (d, short_name) != NULL)
1249         var_clear_short_name (v);
1250     }
1251
1252   /* Each variable with an assigned short_name[] now gets it
1253      unless there is a conflict. */
1254   short_names = hsh_create (d->var_cnt, compare_strings, hash_string,
1255                             NULL, NULL);
1256   for (i = 0; i < d->var_cnt; i++)
1257     {
1258       struct variable *v = d->var[i];
1259       const char *name = var_get_short_name (v);
1260       if (name != NULL && hsh_insert (short_names, (char *) name) != NULL)
1261         var_clear_short_name (v);
1262     }
1263   
1264   /* Now assign short names to remaining variables. */
1265   for (i = 0; i < d->var_cnt; i++)
1266     {
1267       struct variable *v = d->var[i];
1268       const char *name = var_get_short_name (v);
1269       if (name == NULL) 
1270         {
1271           /* Form initial short_name from the variable name, then
1272              try _A, _B, ... _AA, _AB, etc., if needed.*/
1273           int trial = 0;
1274           do
1275             {
1276               if (trial == 0)
1277                 var_set_short_name (v, var_get_name (v));
1278               else
1279                 set_var_short_name_suffix (v, var_get_name (v), trial - 1);
1280
1281               trial++;
1282             }
1283           while (hsh_insert (short_names, (char *) var_get_short_name (v))
1284                  != NULL);
1285         } 
1286     }
1287
1288   /* Get rid of hash table. */
1289   hsh_destroy (short_names);
1290 }
1291
1292
1293 /* Called from variable.c to notify the dictionary that some property of 
1294    the variable has changed */
1295 void
1296 dict_var_changed (const struct variable *v)
1297 {
1298   if ( var_has_vardict (v))
1299     {
1300       const struct vardict_info *vdi = var_get_vardict (v);
1301       struct dictionary *d;
1302
1303       d = vdi->dict;
1304
1305       if ( d->callbacks && d->callbacks->var_changed )
1306         d->callbacks->var_changed (d, var_get_dict_index (v), d->cb_data);
1307     }
1308 }