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