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