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