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