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