{
struct variable *sv = s->var[i];
struct variable *dv = dict_clone_var_assert (d, sv, var_get_name (sv));
- var_set_short_name (dv, var_get_short_name (sv));
+ size_t i;
+
+ for (i = 0; i < var_get_short_name_cnt (sv); i++)
+ var_set_short_name (dv, i, var_get_short_name (sv, i));
}
d->next_value_idx = s->next_value_idx;
while (d->var_cnt > 0 )
{
- var_clear_vardict (d->var[d->var_cnt - 1]);
- var_destroy (d->var[d->var_cnt -1]);
+ struct variable *v = d->var[d->var_cnt - 1];
+ int dict_index = var_get_dict_index (v);
+ int case_index = var_get_case_index (v);
+ int val_cnt = var_get_value_cnt (v);
+
+ var_clear_vardict (v);
+ var_destroy (v);
d->var_cnt--;
if (d->callbacks && d->callbacks->var_deleted )
- d->callbacks->var_deleted (d, d->var_cnt, d->cb_data);
+ d->callbacks->var_deleted (d,
+ dict_index, case_index, val_cnt,
+ d->cb_data);
}
+
free (d->var);
d->var = NULL;
d->var_cnt = d->var_cap = 0;
d->callbacks->var_changed (d, dict_index, d->cb_data);
}
-/* Sets the case_index in V's vardict to DICT_INDEX. */
+/* Sets the case_index in V's vardict to CASE_INDEX. */
static void
set_var_case_index (struct variable *v, int case_index)
{
dict_delete_var (struct dictionary *d, struct variable *v)
{
int dict_index = var_get_dict_index (v);
+ const int case_index = var_get_case_index (v);
+ const int val_cnt = var_get_value_cnt (v);
assert (dict_contains_var (d, v));
var_destroy (v);
if (d->callbacks && d->callbacks->var_deleted )
- d->callbacks->var_deleted (d, dict_index, d->cb_data);
+ d->callbacks->var_deleted (d, dict_index, case_index, val_cnt, d->cb_data);
}
/* Deletes the COUNT variables listed in VARS from D. This is
hsh_force_insert (d->name_tab, v);
if (get_algorithm () == ENHANCED)
- var_clear_short_name (v);
+ var_clear_short_names (v);
if ( d->callbacks && d->callbacks->var_changed )
d->callbacks->var_changed (d, var_get_dict_index (v), d->cb_data);
/* Clear short names. */
if (get_algorithm () == ENHANCED)
for (i = 0; i < count; i++)
- var_clear_short_name (vars[i]);
+ var_clear_short_names (vars[i]);
pool_destroy (pool);
return true;
}
}
+
+/*
+ Reassigns case indices for D, increasing each index above START by
+ the value PADDING.
+*/
+static void
+dict_pad_values (struct dictionary *d, int start, int padding)
+{
+ size_t i;
+
+ if ( padding <= 0 )
+ return;
+
+ for (i = 0; i < d->var_cnt; ++i)
+ {
+ struct variable *v = d->var[i];
+
+ int index = var_get_case_index (v);
+
+ if ( index >= start)
+ set_var_case_index (v, index + padding);
+ }
+
+ d->next_value_idx += padding;
+}
+
+
/* Returns the number of values that would be used by a case if
dict_compact_values() were called. */
size_t
d->vector_cnt = 0;
}
-/* Compares two strings. */
-static int
-compare_strings (const void *a, const void *b, const void *aux UNUSED)
-{
- return strcmp (a, b);
-}
-
-/* Hashes a string. */
-static unsigned
-hash_string (const void *s, const void *aux UNUSED)
-{
- return hsh_hash_string (s);
-}
-
-
-/* Sets V's short name to BASE, followed by a suffix of the form
- _A, _B, _C, ..., _AA, _AB, etc. according to the value of
- SUFFIX_NUMBER. Truncates BASE as necessary to fit. */
-static void
-set_var_short_name_suffix (struct variable *v, const char *base,
- int suffix_number)
-{
- char suffix[SHORT_NAME_LEN + 1];
- char short_name[SHORT_NAME_LEN + 1];
- char *start, *end;
- int len, ofs;
-
- assert (v != NULL);
- assert (suffix_number >= 0);
-
- /* Set base name. */
- var_set_short_name (v, base);
-
- /* Compose suffix. */
- start = end = suffix + sizeof suffix - 1;
- *end = '\0';
- do
- {
- *--start = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[suffix_number % 26];
- if (start <= suffix + 1)
- msg (SE, _("Variable suffix too large."));
- suffix_number /= 26;
- }
- while (suffix_number > 0);
- *--start = '_';
-
- /* Append suffix to V's short name. */
- str_copy_trunc (short_name, sizeof short_name, base);
- len = end - start;
- if (len + strlen (short_name) > SHORT_NAME_LEN)
- ofs = SHORT_NAME_LEN - len;
- else
- ofs = strlen (short_name);
- strcpy (short_name + ofs, start);
-
- /* Set name. */
- var_set_short_name (v, short_name);
-}
-
-/* Assigns a valid, unique short_name[] to each variable in D.
- Each variable whose actual name is short has highest priority
- for that short name. Otherwise, variables with an existing
- short_name[] have the next highest priority for a given short
- name; if it is already taken, then the variable is treated as
- if short_name[] had been empty. Otherwise, long names are
- truncated to form short names. If that causes conflicts,
- variables are renamed as PREFIX_A, PREFIX_B, and so on. */
+/* Called from variable.c to notify the dictionary that some property of
+ the variable has changed */
void
-dict_assign_short_names (struct dictionary *d)
+dict_var_changed (const struct variable *v)
{
- struct hsh_table *short_names;
- size_t i;
-
- /* Give variables whose names are short the corresponding short
- names, and clear short_names[] that conflict with a variable
- name. */
- for (i = 0; i < d->var_cnt; i++)
+ if ( var_has_vardict (v))
{
- struct variable *v = d->var[i];
- const char *short_name = var_get_short_name (v);
- if (strlen (var_get_name (v)) <= SHORT_NAME_LEN)
- var_set_short_name (v, var_get_name (v));
- else if (short_name != NULL && dict_lookup_var (d, short_name) != NULL)
- var_clear_short_name (v);
- }
+ const struct vardict_info *vdi = var_get_vardict (v);
+ struct dictionary *d;
- /* Each variable with an assigned short_name[] now gets it
- unless there is a conflict. */
- short_names = hsh_create (d->var_cnt, compare_strings, hash_string,
- NULL, NULL);
- for (i = 0; i < d->var_cnt; i++)
- {
- struct variable *v = d->var[i];
- const char *name = var_get_short_name (v);
- if (name != NULL && hsh_insert (short_names, (char *) name) != NULL)
- var_clear_short_name (v);
- }
+ d = vdi->dict;
- /* Now assign short names to remaining variables. */
- for (i = 0; i < d->var_cnt; i++)
- {
- struct variable *v = d->var[i];
- const char *name = var_get_short_name (v);
- if (name == NULL)
- {
- /* Form initial short_name from the variable name, then
- try _A, _B, ... _AA, _AB, etc., if needed.*/
- int trial = 0;
- do
- {
- if (trial == 0)
- var_set_short_name (v, var_get_name (v));
- else
- set_var_short_name_suffix (v, var_get_name (v), trial - 1);
-
- trial++;
- }
- while (hsh_insert (short_names, (char *) var_get_short_name (v))
- != NULL);
- }
+ if ( d->callbacks && d->callbacks->var_changed )
+ d->callbacks->var_changed (d, var_get_dict_index (v), d->cb_data);
}
-
- /* Get rid of hash table. */
- hsh_destroy (short_names);
}
-/* Called from variable.c to notify the dictionary that some property of
- the variable has changed */
+/* Called from variable.c to notify the dictionary that the variable's width
+ has changed */
void
-dict_var_changed (const struct variable *v)
+dict_var_resized (const struct variable *v, int delta)
{
if ( var_has_vardict (v))
{
d = vdi->dict;
- if ( d->callbacks && d->callbacks->var_changed )
- d->callbacks->var_changed (d, var_get_dict_index (v), d->cb_data);
+ dict_pad_values (d, var_get_case_index(v) + 1, delta);
+
+ if ( d->callbacks && d->callbacks->var_resized )
+ d->callbacks->var_resized (d, var_get_dict_index (v), delta, d->cb_data);
}
}