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