849e0210623b56fe601050a81bf35f8bccd15db8
[pspp-builds.git] / src / data / dictionary.c
1 /* PSPP - computes sample statistics.
2    Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
3    Written by Ben Pfaff <blp@gnu.org>.
4
5    This program is free software; you can redistribute it and/or
6    modify it under the terms of the GNU General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18    02110-1301, USA. */
19
20 #include <config.h>
21 #include "dictionary.h"
22 #include <stdlib.h>
23 #include <ctype.h>
24 #include <libpspp/array.h>
25 #include <libpspp/alloc.h>
26 #include "case.h"
27 #include "category.h"
28 #include "cat-routines.h"
29 #include <libpspp/compiler.h>
30 #include <libpspp/message.h>
31 #include <libpspp/hash.h>
32 #include <libpspp/misc.h>
33 #include "settings.h"
34 #include <libpspp/str.h>
35 #include "value-labels.h"
36 #include "variable.h"
37
38 #include "gettext.h"
39 #define _(msgid) gettext (msgid)
40
41 /* A dictionary. */
42 struct dictionary
43   {
44     struct variable **var;      /* Variables. */
45     size_t var_cnt, var_cap;    /* Number of variables, capacity. */
46     struct hsh_table *name_tab; /* Variable index by name. */
47     int next_value_idx;         /* Index of next `union value' to allocate. */
48     struct variable **split;    /* SPLIT FILE vars. */
49     size_t split_cnt;           /* SPLIT FILE count. */
50     struct variable *weight;    /* WEIGHT variable. */
51     struct variable *filter;    /* FILTER variable. */
52     int case_limit;             /* Current case limit (N command). */
53     char *label;                /* File label. */
54     char *documents;            /* Documents, as a string. */
55     struct vector **vector;     /* Vectors of variables. */
56     size_t vector_cnt;          /* Number of vectors. */
57   };
58
59 /* Active file dictionary. */
60 struct dictionary *default_dict;
61
62 /* Creates and returns a new dictionary. */
63 struct dictionary *
64 dict_create (void) 
65 {
66   struct dictionary *d = xmalloc (sizeof *d);
67   
68   d->var = NULL;
69   d->var_cnt = d->var_cap = 0;
70   d->name_tab = hsh_create (8, compare_var_names, hash_var_name, NULL, NULL);
71   d->next_value_idx = 0;
72   d->split = NULL;
73   d->split_cnt = 0;
74   d->weight = NULL;
75   d->filter = NULL;
76   d->case_limit = 0;
77   d->label = NULL;
78   d->documents = NULL;
79   d->vector = NULL;
80   d->vector_cnt = 0;
81
82   return d;
83 }
84
85 /* Creates and returns a (deep) copy of an existing
86    dictionary. */
87 struct dictionary *
88 dict_clone (const struct dictionary *s) 
89 {
90   struct dictionary *d;
91   size_t i;
92
93   assert (s != NULL);
94
95   d = dict_create ();
96
97   for (i = 0; i < s->var_cnt; i++) 
98     {
99       struct variable *sv = s->var[i];
100       struct variable *dv = dict_clone_var_assert (d, sv, sv->name);
101       var_set_short_name (dv, sv->short_name);
102     }
103
104   d->next_value_idx = s->next_value_idx;
105
106   d->split_cnt = s->split_cnt;
107   if (d->split_cnt > 0) 
108     {
109       d->split = xnmalloc (d->split_cnt, sizeof *d->split);
110       for (i = 0; i < d->split_cnt; i++) 
111         d->split[i] = dict_lookup_var_assert (d, s->split[i]->name);
112     }
113
114   if (s->weight != NULL) 
115     d->weight = dict_lookup_var_assert (d, s->weight->name);
116
117   if (s->filter != NULL) 
118     d->filter = dict_lookup_var_assert (d, s->filter->name);
119
120   d->case_limit = s->case_limit;
121   dict_set_label (d, dict_get_label (s));
122   dict_set_documents (d, dict_get_documents (s));
123
124   d->vector_cnt = s->vector_cnt;
125   d->vector = xnmalloc (d->vector_cnt, sizeof *d->vector);
126   for (i = 0; i < s->vector_cnt; i++) 
127     {
128       struct vector *sv = s->vector[i];
129       struct vector *dv = d->vector[i] = xmalloc (sizeof *dv);
130       int j;
131       
132       dv->idx = i;
133       strcpy (dv->name, sv->name);
134       dv->cnt = sv->cnt;
135       dv->var = xnmalloc (dv->cnt, sizeof *dv->var);
136       for (j = 0; j < dv->cnt; j++)
137         dv->var[j] = d->var[sv->var[j]->index];
138     }
139
140   return d;
141 }
142
143 /* Clears the contents from a dictionary without destroying the
144    dictionary itself. */
145 void
146 dict_clear (struct dictionary *d) 
147 {
148   /* FIXME?  Should we really clear case_limit, label, documents?
149      Others are necessarily cleared by deleting all the variables.*/
150   int i;
151
152   assert (d != NULL);
153
154   for (i = 0; i < d->var_cnt; i++) 
155     {
156       struct variable *v = d->var[i];
157       var_clear_aux (v);
158       val_labs_destroy (v->val_labs);
159       free (v->label);
160       free (v); 
161     }
162   free (d->var);
163   d->var = NULL;
164   d->var_cnt = d->var_cap = 0;
165   hsh_clear (d->name_tab);
166   d->next_value_idx = 0;
167   free (d->split);
168   d->split = NULL;
169   d->split_cnt = 0;
170   d->weight = NULL;
171   d->filter = NULL;
172   d->case_limit = 0;
173   free (d->label);
174   d->label = NULL;
175   free (d->documents);
176   d->documents = NULL;
177   dict_clear_vectors (d);
178 }
179
180 /* Destroys the aux data for every variable in D, by calling
181    var_clear_aux() for each variable. */
182 void
183 dict_clear_aux (struct dictionary *d) 
184 {
185   int i;
186   
187   assert (d != NULL);
188   
189   for (i = 0; i < d->var_cnt; i++)
190     var_clear_aux (d->var[i]);
191 }
192
193 /* Clears a dictionary and destroys it. */
194 void
195 dict_destroy (struct dictionary *d)
196 {
197   if (d != NULL) 
198     {
199       dict_clear (d);
200       hsh_destroy (d->name_tab);
201       free (d);
202     }
203 }
204
205 /* Returns the number of variables in D. */
206 size_t
207 dict_get_var_cnt (const struct dictionary *d) 
208 {
209   assert (d != NULL);
210
211   return d->var_cnt;
212 }
213
214 /* Returns the variable in D with index IDX, which must be
215    between 0 and the count returned by dict_get_var_cnt(),
216    exclusive. */
217 struct variable *
218 dict_get_var (const struct dictionary *d, size_t idx) 
219 {
220   assert (d != NULL);
221   assert (idx < d->var_cnt);
222
223   return d->var[idx];
224 }
225
226 /* Sets *VARS to an array of pointers to variables in D and *CNT
227    to the number of variables in *D.  All variables are returned
228    if EXCLUDE_CLASSES is 0, or it may contain one or more of (1u
229    << DC_ORDINARY), (1u << DC_SYSTEM), or (1u << DC_SCRATCH) to
230    exclude the corresponding type of variable. */
231 void
232 dict_get_vars (const struct dictionary *d, struct variable ***vars,
233                size_t *cnt, unsigned exclude_classes)
234 {
235   size_t count;
236   size_t i;
237   
238   assert (d != NULL);
239   assert (vars != NULL);
240   assert (cnt != NULL);
241   assert ((exclude_classes & ~((1u << DC_ORDINARY)
242                                | (1u << DC_SYSTEM)
243                                | (1u << DC_SCRATCH))) == 0);
244   
245   count = 0;
246   for (i = 0; i < d->var_cnt; i++)
247     if (!(exclude_classes & (1u << dict_class_from_id (d->var[i]->name))))
248       count++;
249
250   *vars = xnmalloc (count, sizeof **vars);
251   *cnt = 0;
252   for (i = 0; i < d->var_cnt; i++)
253     if (!(exclude_classes & (1u << dict_class_from_id (d->var[i]->name))))
254       (*vars)[(*cnt)++] = d->var[i];
255   assert (*cnt == count);
256 }
257
258
259 /* Creates and returns a new variable in D with the given NAME
260    and WIDTH.  Returns a null pointer if the given NAME would
261    duplicate that of an existing variable in the dictionary. */
262 struct variable *
263 dict_create_var (struct dictionary *d, const char *name, int width)
264 {
265   struct variable *v;
266
267   assert (d != NULL);
268   assert (name != NULL);
269
270   assert (width >= 0 && width < 256);
271
272   assert (var_is_valid_name(name,0));
273     
274   /* Make sure there's not already a variable by that name. */
275   if (dict_lookup_var (d, name) != NULL)
276     return NULL;
277
278   /* Allocate and initialize variable. */
279   v = xmalloc (sizeof *v);
280   str_copy_trunc (v->name, sizeof v->name, name);
281   v->type = width == 0 ? NUMERIC : ALPHA;
282   v->width = width;
283   v->fv = d->next_value_idx;
284   v->nv = width == 0 ? 1 : DIV_RND_UP (width, 8);
285   v->init = 1;
286   v->reinit = dict_class_from_id (v->name) != DC_SCRATCH;
287   v->index = d->var_cnt;
288   mv_init (&v->miss, width);
289   if (v->type == NUMERIC)
290     {
291       v->print = f8_2;
292       v->alignment = ALIGN_RIGHT;
293       v->display_width = 8;
294       v->measure = MEASURE_SCALE;
295     }
296   else
297     {
298       v->print = make_output_format (FMT_A, v->width, 0);
299       v->alignment = ALIGN_LEFT;
300       v->display_width = 8;
301       v->measure = MEASURE_NOMINAL;
302     }
303   v->write = v->print;
304   v->val_labs = val_labs_create (v->width);
305   v->label = NULL;
306   var_clear_short_name (v);
307   v->aux = NULL;
308   v->aux_dtor = NULL;
309   v->obs_vals = NULL;
310
311   /* Update dictionary. */
312   if (d->var_cnt >= d->var_cap) 
313     {
314       d->var_cap = 8 + 2 * d->var_cap; 
315       d->var = xnrealloc (d->var, d->var_cap, sizeof *d->var);
316     }
317   d->var[v->index] = v;
318   d->var_cnt++;
319   hsh_force_insert (d->name_tab, v);
320
321   d->next_value_idx += v->nv;
322
323   return v;
324 }
325
326 /* Creates and returns a new variable in D with the given NAME
327    and WIDTH.  Assert-fails if the given NAME would duplicate
328    that of an existing variable in the dictionary. */
329 struct variable *
330 dict_create_var_assert (struct dictionary *d, const char *name, int width)
331 {
332   struct variable *v = dict_create_var (d, name, width);
333   assert (v != NULL);
334   return v;
335 }
336
337 /* Creates and returns a new variable in D with name NAME, as a
338    copy of existing variable OV, which need not be in D or in any
339    dictionary.  Returns a null pointer if the given NAME would
340    duplicate that of an existing variable in the dictionary. */
341 struct variable *
342 dict_clone_var (struct dictionary *d, const struct variable *ov,
343                 const char *name)
344 {
345   struct variable *nv;
346
347   assert (d != NULL);
348   assert (ov != NULL);
349   assert (name != NULL);
350
351   assert (strlen (name) >= 1);
352   assert (strlen (name) <= LONG_NAME_LEN);
353
354   nv = dict_create_var (d, name, ov->width);
355   if (nv == NULL)
356     return NULL;
357
358   /* Copy most members not copied via dict_create_var().
359      short_name[] is intentionally not copied, because there is
360      no reason to give a new variable with potentially a new name
361      the same short name. */
362   nv->init = 1;
363   nv->reinit = ov->reinit;
364   mv_copy (&nv->miss, &ov->miss);
365   nv->print = ov->print;
366   nv->write = ov->write;
367   val_labs_destroy (nv->val_labs);
368   nv->val_labs = val_labs_copy (ov->val_labs);
369   if (ov->label != NULL)
370     nv->label = xstrdup (ov->label);
371   nv->measure = ov->measure;
372   nv->display_width = ov->display_width;
373   nv->alignment = ov->alignment;
374
375   return nv;
376 }
377
378 /* Creates and returns a new variable in D with name NAME, as a
379    copy of existing variable OV, which need not be in D or in any
380    dictionary.  Assert-fails if the given NAME would duplicate
381    that of an existing variable in the dictionary. */
382 struct variable *
383 dict_clone_var_assert (struct dictionary *d, const struct variable *ov,
384                        const char *name)
385 {
386   struct variable *v = dict_clone_var (d, ov, name);
387   assert (v != NULL);
388   return v;
389 }
390
391 /* Returns the variable named NAME in D, or a null pointer if no
392    variable has that name. */
393 struct variable *
394 dict_lookup_var (const struct dictionary *d, const char *name)
395 {
396   struct variable v;
397   
398   assert (d != NULL);
399   assert (name != NULL);
400
401   str_copy_trunc (v.name, sizeof v.name, name);
402   return hsh_find (d->name_tab, &v);
403 }
404
405 /* Returns the variable named NAME in D.  Assert-fails if no
406    variable has that name. */
407 struct variable *
408 dict_lookup_var_assert (const struct dictionary *d, const char *name)
409 {
410   struct variable *v = dict_lookup_var (d, name);
411   assert (v != NULL);
412   return v;
413 }
414
415 /* Returns true if variable V is in dictionary D,
416    false otherwise. */
417 bool
418 dict_contains_var (const struct dictionary *d, const struct variable *v)
419 {
420   assert (d != NULL);
421   assert (v != NULL);
422
423   return v->index >= 0 && v->index < d->var_cnt && d->var[v->index] == v;
424 }
425
426 /* Compares two double pointers to variables, which should point
427    to elements of a struct dictionary's `var' member array. */
428 static int
429 compare_var_ptrs (const void *a_, const void *b_, void *aux UNUSED) 
430 {
431   struct variable *const *a = a_;
432   struct variable *const *b = b_;
433
434   return *a < *b ? -1 : *a > *b;
435 }
436
437 /* Deletes variable V from dictionary D and frees V.
438
439    This is a very bad idea if there might be any pointers to V
440    from outside D.  In general, no variable in default_dict
441    should be deleted when any transformations are active, because
442    those transformations might reference the deleted variable.
443    The safest time to delete a variable is just after a procedure
444    has been executed, as done by MODIFY VARS.
445
446    Pointers to V within D are not a problem, because
447    dict_delete_var() knows to remove V from split variables,
448    weights, filters, etc. */
449 void
450 dict_delete_var (struct dictionary *d, struct variable *v) 
451 {
452   size_t i;
453
454   assert (d != NULL);
455   assert (v != NULL);
456   assert (dict_contains_var (d, v));
457
458   /* Delete aux data. */
459   var_clear_aux (v);
460
461   /* Remove V from splits, weight, filter variables. */
462   d->split_cnt = remove_equal (d->split, d->split_cnt, sizeof *d->split,
463                                &v, compare_var_ptrs, NULL);
464   if (d->weight == v)
465     d->weight = NULL;
466   if (d->filter == v)
467     d->filter = NULL;
468   dict_clear_vectors (d);
469
470   /* Remove V from var array. */
471   remove_element (d->var, d->var_cnt, sizeof *d->var, v->index);
472   d->var_cnt--;
473
474   /* Update index. */
475   for (i = v->index; i < d->var_cnt; i++)
476     d->var[i]->index = i;
477
478   /* Update name hash. */
479   hsh_force_delete (d->name_tab, v);
480
481   /* Free memory. */
482   val_labs_destroy (v->val_labs);
483   cat_stored_values_destroy (v);
484   free (v->label);
485   free (v);
486 }
487
488 /* Deletes the COUNT variables listed in VARS from D.  This is
489    unsafe; see the comment on dict_delete_var() for details. */
490 void 
491 dict_delete_vars (struct dictionary *d,
492                   struct variable *const *vars, size_t count) 
493 {
494   /* FIXME: this can be done in O(count) time, but this algorithm
495      is O(count**2). */
496   assert (d != NULL);
497   assert (count == 0 || vars != NULL);
498
499   while (count-- > 0)
500     dict_delete_var (d, *vars++);
501 }
502
503 /* Deletes scratch variables from dictionary D. */
504 void
505 dict_delete_scratch_vars (struct dictionary *d)
506 {
507   int i;
508
509   /* FIXME: this can be done in O(count) time, but this algorithm
510      is O(count**2). */
511   assert (d != NULL);
512
513   for (i = 0; i < d->var_cnt; )
514     if (dict_class_from_id (d->var[i]->name) == DC_SCRATCH)
515       dict_delete_var (d, d->var[i]);
516     else
517       i++;
518 }
519
520 /* Moves V to 0-based position IDX in D.  Other variables in D,
521    if any, retain their relative positions.  Runs in time linear
522    in the distance moved. */
523 void
524 dict_reorder_var (struct dictionary *d, struct variable *v,
525                   size_t new_index) 
526 {
527   size_t min_idx, max_idx;
528   size_t i;
529   
530   assert (d != NULL);
531   assert (v != NULL);
532   assert (dict_contains_var (d, v));
533   assert (new_index < d->var_cnt);
534
535   move_element (d->var, d->var_cnt, sizeof *d->var, v->index, new_index);
536
537   min_idx = min (v->index, new_index);
538   max_idx = max (v->index, new_index);
539   for (i = min_idx; i <= max_idx; i++)
540     d->var[i]->index = i;
541 }
542
543 /* Reorders the variables in D, placing the COUNT variables
544    listed in ORDER in that order at the beginning of D.  The
545    other variables in D, if any, retain their relative
546    positions. */
547 void 
548 dict_reorder_vars (struct dictionary *d,
549                    struct variable *const *order, size_t count) 
550 {
551   struct variable **new_var;
552   size_t i;
553   
554   assert (d != NULL);
555   assert (count == 0 || order != NULL);
556   assert (count <= d->var_cnt);
557
558   new_var = xnmalloc (d->var_cnt, sizeof *new_var);
559   memcpy (new_var, order, count * sizeof *new_var);
560   for (i = 0; i < count; i++) 
561     {
562       assert (d->var[order[i]->index] != NULL);
563       d->var[order[i]->index] = NULL;
564       order[i]->index = i;
565     }
566   for (i = 0; i < d->var_cnt; i++)
567     if (d->var[i] != NULL)
568       {
569         assert (count < d->var_cnt);
570         new_var[count] = d->var[i];
571         new_var[count]->index = count;
572         count++;
573       }
574   free (d->var);
575   d->var = new_var;
576 }
577
578 /* Changes the name of V in D to name NEW_NAME.  Assert-fails if
579    a variable named NEW_NAME is already in D, except that
580    NEW_NAME may be the same as V's existing name. */
581 void 
582 dict_rename_var (struct dictionary *d, struct variable *v,
583                  const char *new_name) 
584 {
585   assert (d != NULL);
586   assert (v != NULL);
587   assert (new_name != NULL);
588   assert (var_is_valid_name (new_name, false));
589   assert (dict_contains_var (d, v));
590   assert (!compare_var_names (v->name, new_name, NULL)
591           || dict_lookup_var (d, new_name) == NULL);
592
593   hsh_force_delete (d->name_tab, v);
594   str_copy_trunc (v->name, sizeof v->name, new_name);
595   hsh_force_insert (d->name_tab, v);
596
597   if (get_algorithm () == ENHANCED)
598     var_clear_short_name (v);
599 }
600
601 /* Renames COUNT variables specified in VARS to the names given
602    in NEW_NAMES within dictionary D.  If the renaming would
603    result in a duplicate variable name, returns false and stores a
604    name that would be duplicated into *ERR_NAME (if ERR_NAME is
605    non-null).  Otherwise, the renaming is successful, and true
606    is returned. */
607 bool
608 dict_rename_vars (struct dictionary *d,
609                   struct variable **vars, char **new_names,
610                   size_t count, char **err_name) 
611 {
612   char **old_names;
613   size_t i;
614   bool success = true;
615
616   assert (d != NULL);
617   assert (count == 0 || vars != NULL);
618   assert (count == 0 || new_names != NULL);
619
620   /* Remove the variables to be renamed from the name hash,
621      save their names, and rename them. */
622   old_names = xnmalloc (count, sizeof *old_names);
623   for (i = 0; i < count; i++) 
624     {
625       assert (d->var[vars[i]->index] == vars[i]);
626       assert (var_is_valid_name (new_names[i], false));
627       hsh_force_delete (d->name_tab, vars[i]);
628       old_names[i] = xstrdup (vars[i]->name);
629       strcpy (vars[i]->name, new_names[i]);
630     }
631
632   /* Add the renamed variables back into the name hash,
633      checking for conflicts. */
634   for (i = 0; i < count; i++)
635     {
636       assert (new_names[i] != NULL);
637       assert (*new_names[i] != '\0');
638       assert (strlen (new_names[i]) >= 1);
639       assert (strlen (new_names[i]) <= LONG_NAME_LEN);
640
641       if (hsh_insert (d->name_tab, vars[i]) != NULL)
642         {
643           /* There is a name conflict.
644              Back out all the name changes that have already
645              taken place, and indicate failure. */
646           size_t fail_idx = i;
647           if (err_name != NULL) 
648             *err_name = new_names[i];
649
650           for (i = 0; i < fail_idx; i++)
651             hsh_force_delete (d->name_tab, vars[i]);
652           
653           for (i = 0; i < count; i++)
654             {
655               strcpy (vars[i]->name, old_names[i]);
656               hsh_force_insert (d->name_tab, vars[i]);
657             }
658
659           success = false;
660           goto done;
661         }
662     }
663
664   /* Clear short names. */
665   if (get_algorithm () == ENHANCED)
666     for (i = 0; i < count; i++)
667       var_clear_short_name (vars[i]);
668
669  done:
670   /* Free the old names we kept around. */
671   for (i = 0; i < count; i++)
672     free (old_names[i]);
673   free (old_names);
674
675   return success;
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 nonzero. The function will set warn_on_invalid to zero
693    if an invalid weight is found. */
694 double
695 dict_get_case_weight (const struct dictionary *d, const struct ccase *c, 
696                       int *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->fv);
706       if (w < 0.0 || mv_is_num_missing (&d->weight->miss, w))
707         w = 0.0;
708       if ( w == 0.0 && *warn_on_invalid ) {
709           *warn_on_invalid = 0;
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 || v->type == NUMERIC);
726
727   d->weight = v;
728 }
729
730 /* Returns the filter variable in dictionary D (see cmd_filter())
731    or a null pointer if the dictionary is unfiltered. */
732 struct variable *
733 dict_get_filter (const struct dictionary *d) 
734 {
735   assert (d != NULL);
736   assert (d->filter == NULL || dict_contains_var (d, d->filter));
737   
738   return d->filter;
739 }
740
741 /* Sets V as the filter variable for dictionary D.  Passing a
742    null pointer for V turn off filtering. */
743 void
744 dict_set_filter (struct dictionary *d, struct variable *v)
745 {
746   assert (d != NULL);
747   assert (v == NULL || dict_contains_var (d, v));
748
749   d->filter = v;
750 }
751
752 /* Returns the case limit for dictionary D, or zero if the number
753    of cases is unlimited (see cmd_n()). */
754 int
755 dict_get_case_limit (const struct dictionary *d) 
756 {
757   assert (d != NULL);
758
759   return d->case_limit;
760 }
761
762 /* Sets CASE_LIMIT as the case limit for dictionary D.  Zero for
763    CASE_LIMIT indicates no limit. */
764 void
765 dict_set_case_limit (struct dictionary *d, int case_limit) 
766 {
767   assert (d != NULL);
768   assert (case_limit >= 0);
769
770   d->case_limit = case_limit;
771 }
772
773 /* Returns the index of the next value to be added to D.  This
774    value is the number of `union value's that need to be
775    allocated to store a case for dictionary D. */
776 int
777 dict_get_next_value_idx (const struct dictionary *d) 
778 {
779   assert (d != NULL);
780
781   return d->next_value_idx;
782 }
783
784 /* Returns the number of bytes needed to store a case for
785    dictionary D. */
786 size_t
787 dict_get_case_size (const struct dictionary *d) 
788 {
789   assert (d != NULL);
790
791   return sizeof (union value) * dict_get_next_value_idx (d);
792 }
793
794 /* Deletes scratch variables in dictionary D and reassigns values
795    so that fragmentation is eliminated. */
796 void
797 dict_compact_values (struct dictionary *d) 
798 {
799   size_t i;
800
801   d->next_value_idx = 0;
802   for (i = 0; i < d->var_cnt; )
803     {
804       struct variable *v = d->var[i];
805
806       if (dict_class_from_id (v->name) != DC_SCRATCH) 
807         {
808           v->fv = d->next_value_idx;
809           d->next_value_idx += v->nv;
810           i++;
811         }
812       else
813         dict_delete_var (d, v);
814     }
815 }
816
817 /* Returns the number of values that would be used by a case if
818    dict_compact_values() were called. */
819 size_t
820 dict_get_compacted_value_cnt (const struct dictionary *d) 
821 {
822   size_t i;
823   size_t cnt;
824
825   cnt = 0;
826   for (i = 0; i < d->var_cnt; i++)
827     if (dict_class_from_id (d->var[i]->name) != DC_SCRATCH) 
828       cnt += d->var[i]->nv;
829   return cnt;
830 }
831
832 /* Creates and returns an array mapping from a dictionary index
833    to the `fv' that the corresponding variable will have after
834    calling dict_compact_values().  Scratch variables receive -1
835    for `fv' because dict_compact_values() will delete them. */
836 int *
837 dict_get_compacted_idx_to_fv (const struct dictionary *d) 
838 {
839   size_t i;
840   size_t next_value_idx;
841   int *idx_to_fv;
842   
843   idx_to_fv = xnmalloc (d->var_cnt, sizeof *idx_to_fv);
844   next_value_idx = 0;
845   for (i = 0; i < d->var_cnt; i++)
846     {
847       struct variable *v = d->var[i];
848
849       if (dict_class_from_id (v->name) != DC_SCRATCH) 
850         {
851           idx_to_fv[i] = next_value_idx;
852           next_value_idx += v->nv;
853         }
854       else 
855         idx_to_fv[i] = -1;
856     }
857   return idx_to_fv;
858 }
859
860 /* Returns true if a case for dictionary D would be smaller after
861    compaction, false otherwise.  Compacting a case eliminates
862    "holes" between values and after the last value.  Holes are
863    created by deleting variables (or by scratch variables).
864
865    The return value may differ from whether compacting a case
866    from dictionary D would *change* the case: compaction could
867    rearrange values even if it didn't reduce space
868    requirements. */
869 bool
870 dict_needs_compaction (const struct dictionary *d) 
871 {
872   return dict_get_compacted_value_cnt (d) < dict_get_next_value_idx (d);
873 }
874 \f
875 /* How to copy a contiguous range of values between cases. */
876 struct copy_map
877   {
878     size_t src_idx;             /* Starting value index in source case. */
879     size_t dst_idx;             /* Starting value index in target case. */
880     size_t cnt;                 /* Number of values. */
881   };
882
883 /* How to compact a case. */
884 struct dict_compactor 
885   {
886     struct copy_map *maps;      /* Array of mappings. */
887     size_t map_cnt;             /* Number of mappings. */
888   };
889
890 /* Creates and returns a dict_compactor that can be used to
891    compact cases for dictionary D.
892
893    Compacting a case eliminates "holes" between values and after
894    the last value.  Holes are created by deleting variables (or
895    by scratch variables). */
896 struct dict_compactor *
897 dict_make_compactor (const struct dictionary *d)
898 {
899   struct dict_compactor *compactor;
900   struct copy_map *map;
901   size_t map_allocated;
902   size_t value_idx;
903   size_t i;
904
905   compactor = xmalloc (sizeof *compactor);
906   compactor->maps = NULL;
907   compactor->map_cnt = 0;
908   map_allocated = 0;
909
910   value_idx = 0;
911   map = NULL;
912   for (i = 0; i < d->var_cnt; i++) 
913     {
914       struct variable *v = d->var[i];
915
916       if (dict_class_from_id (v->name) == DC_SCRATCH)
917         continue;
918       if (map != NULL && map->src_idx + map->cnt == v->fv) 
919         map->cnt += v->nv;
920       else 
921         {
922           if (compactor->map_cnt == map_allocated)
923             compactor->maps = x2nrealloc (compactor->maps, &map_allocated,
924                                           sizeof *compactor->maps);
925           map = &compactor->maps[compactor->map_cnt++];
926           map->src_idx = v->fv;
927           map->dst_idx = value_idx;
928           map->cnt = v->nv;
929         }
930       value_idx += v->nv;
931     }
932
933   return compactor;
934 }
935
936 /* Compacts SRC by copying it to DST according to the scheme in
937    COMPACTOR.
938
939    Compacting a case eliminates "holes" between values and after
940    the last value.  Holes are created by deleting variables (or
941    by scratch variables). */
942 void
943 dict_compactor_compact (const struct dict_compactor *compactor,
944                         struct ccase *dst, const struct ccase *src) 
945 {
946   size_t i;
947
948   for (i = 0; i < compactor->map_cnt; i++) 
949     {
950       const struct copy_map *map = &compactor->maps[i];
951       case_copy (dst, map->dst_idx, src, map->src_idx, map->cnt);
952     }
953 }
954
955 /* Destroys COMPACTOR. */
956 void
957 dict_compactor_destroy (struct dict_compactor *compactor) 
958 {
959   if (compactor != NULL) 
960     {
961       free (compactor->maps);
962       free (compactor);
963     }
964 }
965
966 /* Returns the SPLIT FILE vars (see cmd_split_file()).  Call
967    dict_get_split_cnt() to determine how many SPLIT FILE vars
968    there are.  Returns a null pointer if and only if there are no
969    SPLIT FILE vars. */
970 struct variable *const *
971 dict_get_split_vars (const struct dictionary *d) 
972 {
973   assert (d != NULL);
974   
975   return d->split;
976 }
977
978 /* Returns the number of SPLIT FILE vars. */
979 size_t
980 dict_get_split_cnt (const struct dictionary *d) 
981 {
982   assert (d != NULL);
983
984   return d->split_cnt;
985 }
986
987 /* Sets CNT split vars SPLIT in dictionary D. */
988 void
989 dict_set_split_vars (struct dictionary *d,
990                      struct variable *const *split, size_t cnt)
991 {
992   assert (d != NULL);
993   assert (cnt == 0 || split != NULL);
994
995   d->split_cnt = cnt;
996   d->split = xnrealloc (d->split, cnt, sizeof *d->split);
997   memcpy (d->split, split, cnt * sizeof *d->split);
998 }
999
1000 /* Returns the file label for D, or a null pointer if D is
1001    unlabeled (see cmd_file_label()). */
1002 const char *
1003 dict_get_label (const struct dictionary *d) 
1004 {
1005   assert (d != NULL);
1006
1007   return d->label;
1008 }
1009
1010 /* Sets D's file label to LABEL, truncating it to a maximum of 60
1011    characters. */
1012 void
1013 dict_set_label (struct dictionary *d, const char *label) 
1014 {
1015   assert (d != NULL);
1016
1017   free (d->label);
1018   if (label == NULL)
1019     d->label = NULL;
1020   else if (strlen (label) < 60)
1021     d->label = xstrdup (label);
1022   else 
1023     {
1024       d->label = xmalloc (61);
1025       memcpy (d->label, label, 60);
1026       d->label[60] = '\0';
1027     }
1028 }
1029
1030 /* Returns the documents for D, or a null pointer if D has no
1031    documents (see cmd_document()).. */
1032 const char *
1033 dict_get_documents (const struct dictionary *d) 
1034 {
1035   assert (d != NULL);
1036
1037   return d->documents;
1038 }
1039
1040 /* Sets the documents for D to DOCUMENTS, or removes D's
1041    documents if DOCUMENT is a null pointer. */
1042 void
1043 dict_set_documents (struct dictionary *d, const char *documents)
1044 {
1045   assert (d != NULL);
1046
1047   free (d->documents);
1048   if (documents == NULL)
1049     d->documents = NULL;
1050   else
1051     d->documents = xstrdup (documents);
1052 }
1053
1054 /* Creates in D a vector named NAME that contains CNT variables
1055    VAR (see cmd_vector()).  Returns true if successful, or
1056    false if a vector named NAME already exists in D. */
1057 bool
1058 dict_create_vector (struct dictionary *d,
1059                     const char *name,
1060                     struct variable **var, size_t cnt) 
1061 {
1062   struct vector *vector;
1063   size_t i;
1064
1065   assert (d != NULL);
1066   assert (name != NULL);
1067   assert (var_is_valid_name (name, false));
1068   assert (var != NULL);
1069   assert (cnt > 0);
1070   
1071   if (dict_lookup_vector (d, name) != NULL)
1072     return false;
1073
1074   d->vector = xnrealloc (d->vector, d->vector_cnt + 1, sizeof *d->vector);
1075   vector = d->vector[d->vector_cnt] = xmalloc (sizeof *vector);
1076   vector->idx = d->vector_cnt++;
1077   str_copy_trunc (vector->name, sizeof vector->name, name);
1078   vector->var = xnmalloc (cnt, sizeof *var);
1079   for (i = 0; i < cnt; i++)
1080     {
1081       assert (dict_contains_var (d, var[i]));
1082       vector->var[i] = var[i];
1083     }
1084   vector->cnt = cnt;
1085   
1086   return true;
1087 }
1088
1089 /* Returns the vector in D with index IDX, which must be less
1090    than dict_get_vector_cnt (D). */
1091 const struct vector *
1092 dict_get_vector (const struct dictionary *d, size_t idx) 
1093 {
1094   assert (d != NULL);
1095   assert (idx < d->vector_cnt);
1096
1097   return d->vector[idx];
1098 }
1099
1100 /* Returns the number of vectors in D. */
1101 size_t
1102 dict_get_vector_cnt (const struct dictionary *d) 
1103 {
1104   assert (d != NULL);
1105
1106   return d->vector_cnt;
1107 }
1108
1109 /* Looks up and returns the vector within D with the given
1110    NAME. */
1111 const struct vector *
1112 dict_lookup_vector (const struct dictionary *d, const char *name) 
1113 {
1114   size_t i;
1115
1116   assert (d != NULL);
1117   assert (name != NULL);
1118
1119   for (i = 0; i < d->vector_cnt; i++)
1120     if (!strcasecmp (d->vector[i]->name, name))
1121       return d->vector[i];
1122   return NULL;
1123 }
1124
1125 /* Deletes all vectors from D. */
1126 void
1127 dict_clear_vectors (struct dictionary *d) 
1128 {
1129   size_t i;
1130   
1131   assert (d != NULL);
1132
1133   for (i = 0; i < d->vector_cnt; i++) 
1134     {
1135       free (d->vector[i]->var);
1136       free (d->vector[i]);
1137     }
1138   free (d->vector);
1139   d->vector = NULL;
1140   d->vector_cnt = 0;
1141 }
1142
1143 /* Compares two strings. */
1144 static int
1145 compare_strings (const void *a, const void *b, void *aux UNUSED) 
1146 {
1147   return strcmp (a, b);
1148 }
1149
1150 /* Hashes a string. */
1151 static unsigned
1152 hash_string (const void *s, void *aux UNUSED) 
1153 {
1154   return hsh_hash_string (s);
1155 }
1156
1157 /* Assigns a valid, unique short_name[] to each variable in D.
1158    Each variable whose actual name is short has highest priority
1159    for that short name.  Otherwise, variables with an existing
1160    short_name[] have the next highest priority for a given short
1161    name; if it is already taken, then the variable is treated as
1162    if short_name[] had been empty.  Otherwise, long names are
1163    truncated to form short names.  If that causes conflicts,
1164    variables are renamed as PREFIX_A, PREFIX_B, and so on. */
1165 void
1166 dict_assign_short_names (struct dictionary *d) 
1167 {
1168   struct hsh_table *short_names;
1169   size_t i;
1170
1171   /* Give variables whose names are short the corresponding short
1172      names, and clear short_names[] that conflict with a variable
1173      name. */
1174   for (i = 0; i < d->var_cnt; i++)
1175     {
1176       struct variable *v = d->var[i];
1177       if (strlen (v->name) <= SHORT_NAME_LEN)
1178         var_set_short_name (v, v->name);
1179       else if (dict_lookup_var (d, v->short_name) != NULL)
1180         var_clear_short_name (v);
1181     }
1182
1183   /* Each variable with an assigned short_name[] now gets it
1184      unless there is a conflict. */
1185   short_names = hsh_create (d->var_cnt, compare_strings, hash_string,
1186                             NULL, NULL);
1187   for (i = 0; i < d->var_cnt; i++)
1188     {
1189       struct variable *v = d->var[i];
1190       if (v->short_name[0] && hsh_insert (short_names, v->short_name) != NULL)
1191         var_clear_short_name (v);
1192     }
1193   
1194   /* Now assign short names to remaining variables. */
1195   for (i = 0; i < d->var_cnt; i++)
1196     {
1197       struct variable *v = d->var[i];
1198       if (v->short_name[0] == '\0') 
1199         {
1200           int sfx;
1201
1202           /* Form initial short_name. */
1203           var_set_short_name (v, v->name);
1204
1205           /* Try _A, _B, ... _AA, _AB, etc., if needed. */
1206           for (sfx = 0; hsh_insert (short_names, v->short_name) != NULL; sfx++)
1207             var_set_short_name_suffix (v, v->name, sfx);
1208         } 
1209     }
1210
1211   /* Get rid of hash table. */
1212   hsh_destroy (short_names);
1213 }