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