* get.c (parse_read_command): Compact the values in the target
[pspp-builds.git] / 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 /* Reassigns values in dictionary D so that fragmentation is
828    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; i++)
836     {
837       struct variable *v = d->var[i];
838       set_var_case_index (v, d->next_value_idx);
839       d->next_value_idx += var_get_value_cnt (v);
840     }
841 }
842
843 /*
844    Reassigns case indices for D, increasing each index above START by
845    the value PADDING.
846 */
847 static void
848 dict_pad_values (struct dictionary *d, int start, int padding)
849 {
850   size_t i;
851
852   if ( padding <= 0 ) 
853         return;
854
855   for (i = 0; i < d->var_cnt; ++i)
856     {
857       struct variable *v = d->var[i];
858
859       int index = var_get_case_index (v);
860
861       if ( index >= start)
862         set_var_case_index (v, index + padding);
863     }
864
865   d->next_value_idx += padding;
866 }
867
868
869 /* Returns the number of values occupied by the variables in
870    dictionary D.  All variables are considered if EXCLUDE_CLASSES
871    is 0, or it may contain one or more of (1u << DC_ORDINARY),
872    (1u << DC_SYSTEM), or (1u << DC_SCRATCH) to exclude the
873    corresponding type of variable.
874
875    The return value may be less than the number of values in one
876    of dictionary D's cases (as returned by
877    dict_get_next_value_idx) even if E is 0, because there may be
878    gaps in D's cases due to deleted variables. */
879 size_t
880 dict_count_values (const struct dictionary *d, unsigned int exclude_classes)
881 {
882   size_t i;
883   size_t cnt;
884
885   assert ((exclude_classes & ~((1u << DC_ORDINARY)
886                                | (1u << DC_SYSTEM)
887                                | (1u << DC_SCRATCH))) == 0);
888
889   cnt = 0;
890   for (i = 0; i < d->var_cnt; i++)
891     {
892       enum dict_class class = dict_class_from_id (var_get_name (d->var[i]));
893       if (!(exclude_classes & (1u << class)))
894         cnt += var_get_value_cnt (d->var[i]);
895     }
896   return cnt;
897 }
898 \f
899 /* Returns the SPLIT FILE vars (see cmd_split_file()).  Call
900    dict_get_split_cnt() to determine how many SPLIT FILE vars
901    there are.  Returns a null pointer if and only if there are no
902    SPLIT FILE vars. */
903 const struct variable *const *
904 dict_get_split_vars (const struct dictionary *d)
905 {
906   assert (d != NULL);
907
908   return d->split;
909 }
910
911 /* Returns the number of SPLIT FILE vars. */
912 size_t
913 dict_get_split_cnt (const struct dictionary *d)
914 {
915   assert (d != NULL);
916
917   return d->split_cnt;
918 }
919
920 /* Removes variable V from the set of split variables in dictionary D */
921 void
922 dict_unset_split_var (struct dictionary *d,
923                       struct variable *v)
924 {
925   const int count = d->split_cnt;
926   d->split_cnt = remove_equal (d->split, d->split_cnt, sizeof *d->split,
927                                &v, compare_var_ptrs, NULL);
928
929   if ( count == d->split_cnt)
930     return;
931
932   if ( d->callbacks &&  d->callbacks->split_changed )
933     d->callbacks->split_changed (d, d->cb_data);
934 }
935
936 /* Sets CNT split vars SPLIT in dictionary D. */
937 void
938 dict_set_split_vars (struct dictionary *d,
939                      struct variable *const *split, size_t cnt)
940 {
941   assert (d != NULL);
942   assert (cnt == 0 || split != NULL);
943
944   d->split_cnt = cnt;
945   d->split = cnt > 0 ? xnrealloc (d->split, cnt, sizeof *d->split) : NULL;
946   memcpy (d->split, split, cnt * sizeof *d->split);
947
948   if ( d->callbacks &&  d->callbacks->split_changed )
949     d->callbacks->split_changed (d, d->cb_data);
950 }
951
952 /* Returns the file label for D, or a null pointer if D is
953    unlabeled (see cmd_file_label()). */
954 const char *
955 dict_get_label (const struct dictionary *d)
956 {
957   assert (d != NULL);
958
959   return d->label;
960 }
961
962 /* Sets D's file label to LABEL, truncating it to a maximum of 60
963    characters. */
964 void
965 dict_set_label (struct dictionary *d, const char *label)
966 {
967   assert (d != NULL);
968
969   free (d->label);
970   if (label == NULL)
971     d->label = NULL;
972   else if (strlen (label) < 60)
973     d->label = xstrdup (label);
974   else
975     {
976       d->label = xmalloc (61);
977       memcpy (d->label, label, 60);
978       d->label[60] = '\0';
979     }
980 }
981
982 /* Returns the documents for D, or a null pointer if D has no
983    documents.  If the return value is nonnull, then the string
984    will be an exact multiple of DOC_LINE_LENGTH bytes in length,
985    with each segment corresponding to one line. */
986 const char *
987 dict_get_documents (const struct dictionary *d)
988 {
989   return ds_is_empty (&d->documents) ? NULL : ds_cstr (&d->documents);
990 }
991
992 /* Sets the documents for D to DOCUMENTS, or removes D's
993    documents if DOCUMENT is a null pointer.  If DOCUMENTS is
994    nonnull, then it should be an exact multiple of
995    DOC_LINE_LENGTH bytes in length, with each segment
996    corresponding to one line. */
997 void
998 dict_set_documents (struct dictionary *d, const char *documents)
999 {
1000   size_t remainder;
1001
1002   ds_assign_cstr (&d->documents, documents != NULL ? documents : "");
1003
1004   /* In case the caller didn't get it quite right, pad out the
1005      final line with spaces. */
1006   remainder = ds_length (&d->documents) % DOC_LINE_LENGTH;
1007   if (remainder != 0)
1008     ds_put_char_multiple (&d->documents, ' ', DOC_LINE_LENGTH - remainder);
1009 }
1010
1011 /* Drops the documents from dictionary D. */
1012 void
1013 dict_clear_documents (struct dictionary *d)
1014 {
1015   ds_clear (&d->documents);
1016 }
1017
1018 /* Appends LINE to the documents in D.  LINE will be truncated or
1019    padded on the right with spaces to make it exactly
1020    DOC_LINE_LENGTH bytes long. */
1021 void
1022 dict_add_document_line (struct dictionary *d, const char *line)
1023 {
1024   if (strlen (line) > DOC_LINE_LENGTH)
1025     {
1026       /* Note to translators: "bytes" is correct, not characters */
1027       msg (SW, _("Truncating document line to %d bytes."), DOC_LINE_LENGTH);
1028     }
1029   buf_copy_str_rpad (ds_put_uninit (&d->documents, DOC_LINE_LENGTH),
1030                      DOC_LINE_LENGTH, line);
1031 }
1032
1033 /* Returns the number of document lines in dictionary D. */
1034 size_t
1035 dict_get_document_line_cnt (const struct dictionary *d)
1036 {
1037   return ds_length (&d->documents) / DOC_LINE_LENGTH;
1038 }
1039
1040 /* Copies document line number IDX from dictionary D into
1041    LINE, trimming off any trailing white space. */
1042 void
1043 dict_get_document_line (const struct dictionary *d,
1044                         size_t idx, struct string *line)
1045 {
1046   assert (idx < dict_get_document_line_cnt (d));
1047   ds_assign_substring (line, ds_substr (&d->documents, idx * DOC_LINE_LENGTH,
1048                                         DOC_LINE_LENGTH));
1049   ds_rtrim (line, ss_cstr (CC_SPACES));
1050 }
1051
1052 /* Creates in D a vector named NAME that contains the CNT
1053    variables in VAR.  Returns true if successful, or false if a
1054    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   size_t i;
1061
1062   assert (var != NULL);
1063   assert (cnt > 0);
1064   for (i = 0; i < cnt; i++)
1065     assert (dict_contains_var (d, var[i]));
1066
1067   if (dict_lookup_vector (d, name) == NULL)
1068     {
1069       d->vector = xnrealloc (d->vector, d->vector_cnt + 1, sizeof *d->vector);
1070       d->vector[d->vector_cnt++] = vector_create (name, var, cnt);
1071       return true;
1072     }
1073   else
1074     return false;
1075 }
1076
1077 /* Creates in D a vector named NAME that contains the CNT
1078    variables in VAR.  A vector named NAME must not already exist
1079    in D. */
1080 void
1081 dict_create_vector_assert (struct dictionary *d,
1082                            const char *name,
1083                            struct variable **var, size_t cnt)
1084 {
1085   assert (dict_lookup_vector (d, name) == NULL);
1086   dict_create_vector (d, name, var, cnt);
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   for (i = 0; i < d->vector_cnt; i++)
1116     if (!strcasecmp (vector_get_name (d->vector[i]), name))
1117       return d->vector[i];
1118   return NULL;
1119 }
1120
1121 /* Deletes all vectors from D. */
1122 void
1123 dict_clear_vectors (struct dictionary *d)
1124 {
1125   size_t i;
1126
1127   for (i = 0; i < d->vector_cnt; i++)
1128     vector_destroy (d->vector[i]);
1129   free (d->vector);
1130
1131   d->vector = NULL;
1132   d->vector_cnt = 0;
1133 }
1134
1135 /* Called from variable.c to notify the dictionary that some property of
1136    the variable has changed */
1137 void
1138 dict_var_changed (const struct variable *v)
1139 {
1140   if ( var_has_vardict (v))
1141     {
1142       const struct vardict_info *vdi = var_get_vardict (v);
1143       struct dictionary *d;
1144
1145       d = vdi->dict;
1146
1147       if ( d->callbacks && d->callbacks->var_changed )
1148         d->callbacks->var_changed (d, var_get_dict_index (v), d->cb_data);
1149     }
1150 }
1151
1152
1153 /* Called from variable.c to notify the dictionary that the variable's width
1154    has changed */
1155 void
1156 dict_var_resized (const struct variable *v, int delta)
1157 {
1158   if ( var_has_vardict (v))
1159     {
1160       const struct vardict_info *vdi = var_get_vardict (v);
1161       struct dictionary *d;
1162
1163       d = vdi->dict;
1164
1165       dict_pad_values (d, var_get_case_index(v) + 1, delta);
1166
1167       if ( d->callbacks && d->callbacks->var_resized )
1168         d->callbacks->var_resized (d, var_get_dict_index (v), delta, d->cb_data);
1169     }
1170 }