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