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