1 /* PSPP - computes sample statistics.
2 Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include "dictionary.h"
24 #include "algorithm.h"
32 #include "value-labels.h"
38 struct variable **var; /* Variables. */
39 size_t var_cnt, var_cap; /* Number of variables, capacity. */
40 struct hsh_table *name_tab; /* Variable index by name. */
41 int next_value_idx; /* Index of next `union value' to allocate. */
42 struct variable **split; /* SPLIT FILE vars. */
43 size_t split_cnt; /* SPLIT FILE count. */
44 struct variable *weight; /* WEIGHT variable. */
45 struct variable *filter; /* FILTER variable. */
46 int case_limit; /* Current case limit (N command). */
47 char *label; /* File label. */
48 char *documents; /* Documents, as a string. */
49 struct vector **vector; /* Vectors of variables. */
50 size_t vector_cnt; /* Number of vectors. */
53 /* Creates and returns a new dictionary. */
57 struct dictionary *d = xmalloc (sizeof *d);
60 d->var_cnt = d->var_cap = 0;
61 d->name_tab = hsh_create (8, compare_var_names, hash_var_name, NULL, NULL);
62 d->next_value_idx = 0;
76 /* Creates and returns a (deep) copy of an existing
79 dict_clone (const struct dictionary *s)
88 for (i = 0; i < s->var_cnt; i++)
90 struct variable *sv = s->var[i];
91 struct variable *dv = dict_clone_var_assert (d, sv, sv->name);
92 var_set_short_name (dv, sv->short_name);
95 d->next_value_idx = s->next_value_idx;
97 d->split_cnt = s->split_cnt;
100 d->split = xmalloc (d->split_cnt * sizeof *d->split);
101 for (i = 0; i < d->split_cnt; i++)
102 d->split[i] = dict_lookup_var_assert (d, s->split[i]->name);
105 if (s->weight != NULL)
106 d->weight = dict_lookup_var_assert (d, s->weight->name);
108 if (s->filter != NULL)
109 d->filter = dict_lookup_var_assert (d, s->filter->name);
111 d->case_limit = s->case_limit;
112 dict_set_label (d, dict_get_label (s));
113 dict_set_documents (d, dict_get_documents (s));
115 d->vector_cnt = s->vector_cnt;
116 d->vector = xmalloc (d->vector_cnt * sizeof *d->vector);
117 for (i = 0; i < s->vector_cnt; i++)
119 struct vector *sv = s->vector[i];
120 struct vector *dv = d->vector[i] = xmalloc (sizeof *dv);
124 strcpy (dv->name, sv->name);
126 dv->var = xmalloc (dv->cnt * sizeof *dv->var);
127 for (j = 0; j < dv->cnt; j++)
128 dv->var[j] = d->var[sv->var[j]->index];
134 /* Clears the contents from a dictionary without destroying the
135 dictionary itself. */
137 dict_clear (struct dictionary *d)
139 /* FIXME? Should we really clear case_limit, label, documents?
140 Others are necessarily cleared by deleting all the variables.*/
145 for (i = 0; i < d->var_cnt; i++)
147 struct variable *v = d->var[i];
149 val_labs_destroy (v->val_labs);
155 d->var_cnt = d->var_cap = 0;
156 hsh_clear (d->name_tab);
157 d->next_value_idx = 0;
168 dict_clear_vectors (d);
171 /* Destroys the aux data for every variable in D, by calling
172 var_clear_aux() for each variable. */
174 dict_clear_aux (struct dictionary *d)
180 for (i = 0; i < d->var_cnt; i++)
181 var_clear_aux (d->var[i]);
184 /* Clears a dictionary and destroys it. */
186 dict_destroy (struct dictionary *d)
191 hsh_destroy (d->name_tab);
196 /* Returns the number of variables in D. */
198 dict_get_var_cnt (const struct dictionary *d)
205 /* Returns the variable in D with index IDX, which must be
206 between 0 and the count returned by dict_get_var_cnt(),
209 dict_get_var (const struct dictionary *d, size_t idx)
212 assert (idx < d->var_cnt);
217 /* Sets *VARS to an array of pointers to variables in D and *CNT
218 to the number of variables in *D. By default all variables
219 are returned, but bits may be set in EXCLUDE_CLASSES to
220 exclude ordinary, system, and/or scratch variables. */
222 dict_get_vars (const struct dictionary *d, struct variable ***vars,
223 size_t *cnt, unsigned exclude_classes)
229 assert (vars != NULL);
230 assert (cnt != NULL);
231 assert ((exclude_classes & ~((1u << DC_ORDINARY)
233 | (1u << DC_SCRATCH))) == 0);
236 for (i = 0; i < d->var_cnt; i++)
237 if (!(exclude_classes & (1u << dict_class_from_id (d->var[i]->name))))
240 *vars = xmalloc (count * sizeof **vars);
242 for (i = 0; i < d->var_cnt; i++)
243 if (!(exclude_classes & (1u << dict_class_from_id (d->var[i]->name))))
244 (*vars)[(*cnt)++] = d->var[i];
245 assert (*cnt == count);
249 /* Creates and returns a new variable in D with the given NAME
250 and WIDTH. Returns a null pointer if the given NAME would
251 duplicate that of an existing variable in the dictionary. */
253 dict_create_var (struct dictionary *d, const char *name, int width)
258 assert (name != NULL);
260 assert (strlen (name) >= 1);
261 assert (strlen (name) <= LONG_NAME_LEN);
263 assert (width >= 0 && width < 256);
265 /* Make sure there's not already a variable by that name. */
266 if (dict_lookup_var (d, name) != NULL)
269 /* Allocate and initialize variable. */
270 v = xmalloc (sizeof *v);
271 str_copy_trunc (v->name, sizeof v->name, name);
272 v->type = width == 0 ? NUMERIC : ALPHA;
274 v->fv = d->next_value_idx;
275 v->nv = width == 0 ? 1 : DIV_RND_UP (width, 8);
277 v->reinit = dict_class_from_id (v->name) != DC_SCRATCH;
278 v->index = d->var_cnt;
279 v->miss_type = MISSING_NONE;
280 if (v->type == NUMERIC)
283 v->alignment = ALIGN_RIGHT;
284 v->display_width = 8;
285 v->measure = MEASURE_SCALE;
289 v->print = make_output_format (FMT_A, v->width, 0);
290 v->alignment = ALIGN_LEFT;
291 v->display_width = 8;
292 v->measure = MEASURE_NOMINAL;
295 v->val_labs = val_labs_create (v->width);
297 var_clear_short_name (v);
301 /* Update dictionary. */
302 if (d->var_cnt >= d->var_cap)
304 d->var_cap = 8 + 2 * d->var_cap;
305 d->var = xrealloc (d->var, d->var_cap * sizeof *d->var);
307 d->var[v->index] = v;
309 hsh_force_insert (d->name_tab, v);
311 d->next_value_idx += v->nv;
316 /* Creates and returns a new variable in D with the given NAME
317 and WIDTH. Assert-fails if the given NAME would duplicate
318 that of an existing variable in the dictionary. */
320 dict_create_var_assert (struct dictionary *d, const char *name, int width)
322 struct variable *v = dict_create_var (d, name, width);
327 /* Creates and returns a new variable in D with name NAME, as a
328 copy of existing variable OV, which need not be in D or in any
329 dictionary. Returns a null pointer if the given NAME would
330 duplicate that of an existing variable in the dictionary. */
332 dict_clone_var (struct dictionary *d, const struct variable *ov,
339 assert (name != NULL);
341 assert (strlen (name) >= 1);
342 assert (strlen (name) <= LONG_NAME_LEN);
344 nv = dict_create_var (d, name, ov->width);
348 /* Copy most members not copied via dict_create_var().
349 short_name[] is intentionally not copied, because there is
350 no reason to give a new variable with potentially a new name
351 the same short name. */
353 nv->reinit = ov->reinit;
354 nv->miss_type = ov->miss_type;
355 memcpy (nv->missing, ov->missing, sizeof nv->missing);
356 nv->print = ov->print;
357 nv->write = ov->write;
358 val_labs_destroy (nv->val_labs);
359 nv->val_labs = val_labs_copy (ov->val_labs);
360 if (ov->label != NULL)
361 nv->label = xstrdup (ov->label);
362 nv->measure = ov->measure;
363 nv->display_width = ov->display_width;
364 nv->alignment = ov->alignment;
369 /* Creates and returns a new variable in D with name NAME, as a
370 copy of existing variable OV, which need not be in D or in any
371 dictionary. Assert-fails if the given NAME would duplicate
372 that of an existing variable in the dictionary. */
374 dict_clone_var_assert (struct dictionary *d, const struct variable *ov,
377 struct variable *v = dict_clone_var (d, ov, name);
382 /* Returns the variable named NAME in D, or a null pointer if no
383 variable has that name. */
385 dict_lookup_var (const struct dictionary *d, const char *name)
390 assert (name != NULL);
392 str_copy_trunc (v.name, sizeof v.name, name);
393 return hsh_find (d->name_tab, &v);
396 /* Returns the variable named NAME in D. Assert-fails if no
397 variable has that name. */
399 dict_lookup_var_assert (const struct dictionary *d, const char *name)
401 struct variable *v = dict_lookup_var (d, name);
406 /* Returns nonzero if variable V is in dictionary D. */
408 dict_contains_var (const struct dictionary *d, const struct variable *v)
413 return v->index >= 0 && v->index < d->var_cnt && d->var[v->index] == v;
416 /* Compares two double pointers to variables, which should point
417 to elements of a struct dictionary's `var' member array. */
419 compare_var_ptrs (const void *a_, const void *b_, void *aux UNUSED)
421 struct variable *const *a = a_;
422 struct variable *const *b = b_;
424 return *a < *b ? -1 : *a > *b;
427 /* Deletes variable V from dictionary D and frees V.
429 This is a very bad idea if there might be any pointers to V
430 from outside D. In general, no variable in default_dict
431 should be deleted when any transformations are active, because
432 those transformations might reference the deleted variable.
433 The safest time to delete a variable is just after a procedure
434 has been executed, as done by MODIFY VARS.
436 Pointers to V within D are not a problem, because
437 dict_delete_var() knows to remove V from split variables,
438 weights, filters, etc. */
440 dict_delete_var (struct dictionary *d, struct variable *v)
446 assert (dict_contains_var (d, v));
448 /* Delete aux data. */
451 /* Remove V from splits, weight, filter variables. */
452 d->split_cnt = remove_equal (d->split, d->split_cnt, sizeof *d->split,
453 &v, compare_var_ptrs, NULL);
458 dict_clear_vectors (d);
460 /* Remove V from var array. */
461 remove_element (d->var, d->var_cnt, sizeof *d->var, v->index);
465 for (i = v->index; i < d->var_cnt; i++)
466 d->var[i]->index = i;
468 /* Update name hash. */
469 hsh_force_delete (d->name_tab, v);
472 val_labs_destroy (v->val_labs);
477 /* Deletes the COUNT variables listed in VARS from D. This is
478 unsafe; see the comment on dict_delete_var() for details. */
480 dict_delete_vars (struct dictionary *d,
481 struct variable *const *vars, size_t count)
483 /* FIXME: this can be done in O(count) time, but this algorithm
486 assert (count == 0 || vars != NULL);
489 dict_delete_var (d, *vars++);
492 /* Moves V to 0-based position IDX in D. Other variables in D,
493 if any, retain their relative positions. Runs in time linear
494 in the distance moved. */
496 dict_reorder_var (struct dictionary *d, struct variable *v,
499 size_t min_idx, max_idx;
504 assert (dict_contains_var (d, v));
505 assert (new_index < d->var_cnt);
507 move_element (d->var, d->var_cnt, sizeof *d->var, v->index, new_index);
509 min_idx = min (v->index, new_index);
510 max_idx = max (v->index, new_index);
511 for (i = min_idx; i <= max_idx; i++)
512 d->var[i]->index = i;
515 /* Reorders the variables in D, placing the COUNT variables
516 listed in ORDER in that order at the beginning of D. The
517 other variables in D, if any, retain their relative
520 dict_reorder_vars (struct dictionary *d,
521 struct variable *const *order, size_t count)
523 struct variable **new_var;
527 assert (count == 0 || order != NULL);
528 assert (count <= d->var_cnt);
530 new_var = xmalloc (d->var_cnt * sizeof *new_var);
531 memcpy (new_var, order, count * sizeof *new_var);
532 for (i = 0; i < count; i++)
534 assert (d->var[order[i]->index] != NULL);
535 d->var[order[i]->index] = NULL;
538 for (i = 0; i < d->var_cnt; i++)
539 if (d->var[i] != NULL)
541 assert (count < d->var_cnt);
542 new_var[count] = d->var[i];
543 new_var[count]->index = count;
550 /* Changes the name of V in D to name NEW_NAME. Assert-fails if
551 a variable named NEW_NAME is already in D, except that
552 NEW_NAME may be the same as V's existing name. */
554 dict_rename_var (struct dictionary *d, struct variable *v,
555 const char *new_name)
559 assert (new_name != NULL);
560 assert (var_is_valid_name (new_name, false));
561 assert (dict_contains_var (d, v));
562 assert (!compare_var_names (v->name, new_name, NULL)
563 || dict_lookup_var (d, new_name) == NULL);
565 hsh_force_delete (d->name_tab, v);
566 str_copy_trunc (v->name, sizeof v->name, new_name);
567 hsh_force_insert (d->name_tab, v);
569 if (get_algorithm () == ENHANCED)
570 var_clear_short_name (v);
573 /* Renames COUNT variables specified in VARS to the names given
574 in NEW_NAMES within dictionary D. If the renaming would
575 result in a duplicate variable name, returns zero and stores a
576 name that would be duplicated into *ERR_NAME (if ERR_NAME is
577 non-null). Otherwise, the renaming is successful, and nonzero
580 dict_rename_vars (struct dictionary *d,
581 struct variable **vars, char **new_names,
582 size_t count, char **err_name)
589 assert (count == 0 || vars != NULL);
590 assert (count == 0 || new_names != NULL);
592 /* Remove the variables to be renamed from the name hash,
593 save their names, and rename them. */
594 old_names = xmalloc (count * sizeof *old_names);
595 for (i = 0; i < count; i++)
597 assert (d->var[vars[i]->index] == vars[i]);
598 assert (var_is_valid_name (new_names[i], false));
599 hsh_force_delete (d->name_tab, vars[i]);
600 old_names[i] = xstrdup (vars[i]->name);
601 strcpy (vars[i]->name, new_names[i]);
604 /* Add the renamed variables back into the name hash,
605 checking for conflicts. */
606 for (i = 0; i < count; i++)
608 assert (new_names[i] != NULL);
609 assert (*new_names[i] != '\0');
610 assert (strlen (new_names[i]) >= 1);
611 assert (strlen (new_names[i]) <= LONG_NAME_LEN);
613 if (hsh_insert (d->name_tab, vars[i]) != NULL)
615 /* There is a name conflict.
616 Back out all the name changes that have already
617 taken place, and indicate failure. */
619 if (err_name != NULL)
620 *err_name = new_names[i];
622 for (i = 0; i < fail_idx; i++)
623 hsh_force_delete (d->name_tab, vars[i]);
625 for (i = 0; i < count; i++)
627 strcpy (vars[i]->name, old_names[i]);
628 hsh_force_insert (d->name_tab, vars[i]);
636 /* Clear short names. */
637 if (get_algorithm () == ENHANCED)
638 for (i = 0; i < count; i++)
639 var_clear_short_name (vars[i]);
642 /* Free the old names we kept around. */
643 for (i = 0; i < count; i++)
650 /* Returns the weighting variable in dictionary D, or a null
651 pointer if the dictionary is unweighted. */
653 dict_get_weight (const struct dictionary *d)
656 assert (d->weight == NULL || dict_contains_var (d, d->weight));
661 /* Returns the value of D's weighting variable in case C, except that a
662 negative weight is returned as 0. Returns 1 if the dictionary is
663 unweighted. Will warn about missing, negative, or zero values if
664 warn_on_invalid is nonzero. The function will set warn_on_invalid to zero
665 if an invalid weight is found. */
667 dict_get_case_weight (const struct dictionary *d, const struct ccase *c,
668 int *warn_on_invalid)
673 if (d->weight == NULL)
677 double w = case_num (c, d->weight->fv);
678 if ( w < 0.0 || w == SYSMIS || is_num_user_missing(w, d->weight) )
680 if ( w == 0.0 && *warn_on_invalid ) {
681 *warn_on_invalid = 0;
682 msg (SW, _("At least one case in the data file had a weight value "
683 "that was user-missing, system-missing, zero, or "
684 "negative. These case(s) were ignored."));
690 /* Sets the weighting variable of D to V, or turning off
691 weighting if V is a null pointer. */
693 dict_set_weight (struct dictionary *d, struct variable *v)
696 assert (v == NULL || dict_contains_var (d, v));
697 assert (v == NULL || v->type == NUMERIC);
702 /* Returns the filter variable in dictionary D (see cmd_filter())
703 or a null pointer if the dictionary is unfiltered. */
705 dict_get_filter (const struct dictionary *d)
708 assert (d->filter == NULL || dict_contains_var (d, d->filter));
713 /* Sets V as the filter variable for dictionary D. Passing a
714 null pointer for V turn off filtering. */
716 dict_set_filter (struct dictionary *d, struct variable *v)
719 assert (v == NULL || dict_contains_var (d, v));
724 /* Returns the case limit for dictionary D, or zero if the number
725 of cases is unlimited (see cmd_n()). */
727 dict_get_case_limit (const struct dictionary *d)
731 return d->case_limit;
734 /* Sets CASE_LIMIT as the case limit for dictionary D. Zero for
735 CASE_LIMIT indicates no limit. */
737 dict_set_case_limit (struct dictionary *d, int case_limit)
740 assert (case_limit >= 0);
742 d->case_limit = case_limit;
745 /* Returns the index of the next value to be added to D. This
746 value is the number of `union value's that need to be
747 allocated to store a case for dictionary D. */
749 dict_get_next_value_idx (const struct dictionary *d)
753 return d->next_value_idx;
756 /* Returns the number of bytes needed to store a case for
759 dict_get_case_size (const struct dictionary *d)
763 return sizeof (union value) * dict_get_next_value_idx (d);
766 /* Deletes scratch variables in dictionary D and reassigns values
767 so that fragmentation is eliminated. */
769 dict_compact_values (struct dictionary *d)
773 d->next_value_idx = 0;
774 for (i = 0; i < d->var_cnt; )
776 struct variable *v = d->var[i];
778 if (dict_class_from_id (v->name) != DC_SCRATCH)
780 v->fv = d->next_value_idx;
781 d->next_value_idx += v->nv;
785 dict_delete_var (d, v);
789 /* Copies values from SRC, which represents a case arranged
790 according to dictionary D, to DST, which represents a case
791 arranged according to the dictionary that will be produced by
792 dict_compact_values(D). */
794 dict_compact_case (const struct dictionary *d,
795 struct ccase *dst, const struct ccase *src)
801 for (i = 0; i < d->var_cnt; i++)
803 struct variable *v = d->var[i];
805 if (dict_class_from_id (v->name) != DC_SCRATCH)
807 case_copy (dst, value_idx, src, v->fv, v->nv);
813 /* Returns the number of values that would be used by a case if
814 dict_compact_values() were called. */
816 dict_get_compacted_value_cnt (const struct dictionary *d)
822 for (i = 0; i < d->var_cnt; i++)
823 if (dict_class_from_id (d->var[i]->name) != DC_SCRATCH)
824 cnt += d->var[i]->nv;
828 /* Creates and returns an array mapping from a dictionary index
829 to the `fv' that the corresponding variable will have after
830 calling dict_compact_values(). Scratch variables receive -1
831 for `fv' because dict_compact_values() will delete them. */
833 dict_get_compacted_idx_to_fv (const struct dictionary *d)
836 size_t next_value_idx;
839 idx_to_fv = xmalloc (d->var_cnt * sizeof *idx_to_fv);
841 for (i = 0; i < d->var_cnt; i++)
843 struct variable *v = d->var[i];
845 if (dict_class_from_id (v->name) != DC_SCRATCH)
847 idx_to_fv[i] = next_value_idx;
848 next_value_idx += v->nv;
856 /* Returns the SPLIT FILE vars (see cmd_split_file()). Call
857 dict_get_split_cnt() to determine how many SPLIT FILE vars
858 there are. Returns a null pointer if and only if there are no
860 struct variable *const *
861 dict_get_split_vars (const struct dictionary *d)
868 /* Returns the number of SPLIT FILE vars. */
870 dict_get_split_cnt (const struct dictionary *d)
877 /* Sets CNT split vars SPLIT in dictionary D. */
879 dict_set_split_vars (struct dictionary *d,
880 struct variable *const *split, size_t cnt)
883 assert (cnt == 0 || split != NULL);
886 d->split = xrealloc (d->split, cnt * sizeof *d->split);
887 memcpy (d->split, split, cnt * sizeof *d->split);
890 /* Returns the file label for D, or a null pointer if D is
891 unlabeled (see cmd_file_label()). */
893 dict_get_label (const struct dictionary *d)
900 /* Sets D's file label to LABEL, truncating it to a maximum of 60
903 dict_set_label (struct dictionary *d, const char *label)
910 else if (strlen (label) < 60)
911 d->label = xstrdup (label);
914 d->label = xmalloc (61);
915 memcpy (d->label, label, 60);
920 /* Returns the documents for D, or a null pointer if D has no
921 documents (see cmd_document()).. */
923 dict_get_documents (const struct dictionary *d)
930 /* Sets the documents for D to DOCUMENTS, or removes D's
931 documents if DOCUMENT is a null pointer. */
933 dict_set_documents (struct dictionary *d, const char *documents)
938 if (documents == NULL)
941 d->documents = xstrdup (documents);
944 /* Creates in D a vector named NAME that contains CNT variables
945 VAR (see cmd_vector()). Returns nonzero if successful, or
946 zero if a vector named NAME already exists in D. */
948 dict_create_vector (struct dictionary *d,
950 struct variable **var, size_t cnt)
952 struct vector *vector;
956 assert (name != NULL);
957 assert (var_is_valid_name (name, false));
958 assert (var != NULL);
961 if (dict_lookup_vector (d, name) != NULL)
964 d->vector = xrealloc (d->vector, (d->vector_cnt + 1) * sizeof *d->vector);
965 vector = d->vector[d->vector_cnt] = xmalloc (sizeof *vector);
966 vector->idx = d->vector_cnt++;
967 str_copy_trunc (vector->name, sizeof vector->name, name);
968 vector->var = xmalloc (cnt * sizeof *var);
969 for (i = 0; i < cnt; i++)
971 assert (dict_contains_var (d, var[i]));
972 vector->var[i] = var[i];
979 /* Returns the vector in D with index IDX, which must be less
980 than dict_get_vector_cnt (D). */
981 const struct vector *
982 dict_get_vector (const struct dictionary *d, size_t idx)
985 assert (idx < d->vector_cnt);
987 return d->vector[idx];
990 /* Returns the number of vectors in D. */
992 dict_get_vector_cnt (const struct dictionary *d)
996 return d->vector_cnt;
999 /* Looks up and returns the vector within D with the given
1001 const struct vector *
1002 dict_lookup_vector (const struct dictionary *d, const char *name)
1007 assert (name != NULL);
1009 for (i = 0; i < d->vector_cnt; i++)
1010 if (!strcasecmp (d->vector[i]->name, name))
1011 return d->vector[i];
1015 /* Deletes all vectors from D. */
1017 dict_clear_vectors (struct dictionary *d)
1023 for (i = 0; i < d->vector_cnt; i++)
1025 free (d->vector[i]->var);
1026 free (d->vector[i]);
1033 /* Compares two strings. */
1035 compare_strings (const void *a, const void *b, void *aux UNUSED)
1037 return strcmp (a, b);
1040 /* Hashes a string. */
1042 hash_string (const void *s, void *aux UNUSED)
1044 return hsh_hash_string (s);
1047 /* Assigns a valid, unique short_name[] to each variable in D.
1048 Each variable whose actual name is short has highest priority
1049 for that short name. Otherwise, variables with an existing
1050 short_name[] have the next highest priority for a given short
1051 name; if it is already taken, then the variable is treated as
1052 if short_name[] had been empty. Otherwise, long names are
1053 truncated to form short names. If that causes conflicts,
1054 variables are renamed as PREFIX_A, PREFIX_B, and so on. */
1056 dict_assign_short_names (struct dictionary *d)
1058 struct hsh_table *short_names;
1061 /* Give variables whose names are short the corresponding short
1062 names, and clear short_names[] that conflict with a variable
1064 for (i = 0; i < d->var_cnt; i++)
1066 struct variable *v = d->var[i];
1067 if (strlen (v->name) <= SHORT_NAME_LEN)
1068 var_set_short_name (v, v->name);
1069 else if (dict_lookup_var (d, v->short_name) != NULL)
1070 var_clear_short_name (v);
1073 /* Each variable with an assigned short_name[] now gets it
1074 unless there is a conflict. */
1075 short_names = hsh_create (d->var_cnt, compare_strings, hash_string,
1077 for (i = 0; i < d->var_cnt; i++)
1079 struct variable *v = d->var[i];
1080 if (v->short_name[0] && hsh_insert (short_names, v->short_name) != NULL)
1081 var_clear_short_name (v);
1084 /* Now assign short names to remaining variables. */
1085 for (i = 0; i < d->var_cnt; i++)
1087 struct variable *v = d->var[i];
1088 if (v->short_name[0] == '\0')
1092 /* Form initial short_name. */
1093 var_set_short_name (v, v->name);
1095 /* Try _A, _B, ... _AA, _AB, etc., if needed. */
1096 for (sfx = 0; hsh_insert (short_names, v->short_name) != NULL; sfx++)
1097 var_set_short_name_suffix (v, v->name, sfx);
1101 /* Get rid of hash table. */
1102 hsh_destroy (short_names);