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