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