int next_value_idx; /* Index of next `union value' to allocate. */
const struct variable **split; /* SPLIT FILE vars. */
size_t n_splits; /* SPLIT FILE count. */
+ enum split_type split_type;
struct variable *weight; /* WEIGHT variable. */
struct variable *filter; /* FILTER variable. */
casenumber case_limit; /* Current case limit (N command). */
struct dictionary *
dict_create (const char *encoding)
{
- struct dictionary *d = XZALLOC (struct dictionary);
+ struct dictionary *d = xmalloc (sizeof *d);
- d->encoding = xstrdup (encoding);
- d->names_must_be_ids = true;
- hmap_init (&d->name_map);
- attrset_init (&d->attributes);
- d->ref_cnt = 1;
+ *d = (struct dictionary) {
+ .encoding = xstrdup (encoding),
+ .names_must_be_ids = true,
+ .name_map = HMAP_INITIALIZER (d->name_map),
+ .attributes = ATTRSET_INITIALIZER (d->attributes),
+ .split_type = SPLIT_NONE,
+ .ref_cnt = 1,
+ };
return d;
}
if (d->n_splits > 0)
{
d->split = xnmalloc (d->n_splits, sizeof *d->split);
- for (i = 0; i < d->n_splits; i++)
- d->split[i] = dict_lookup_var_assert (d, var_get_name (s->split[i]));
+ for (i = 0; i < d->n_splits; i++)
+ d->split[i] = dict_lookup_var_assert (d, var_get_name (s->split[i]));
}
+ d->split_type = s->split_type;
if (s->weight != NULL)
dict_set_weight (d, dict_lookup_var_assert (d, var_get_name (s->weight)));
}
-/* Sets N split vars SPLIT in dictionary D. */
+/* Sets N split vars SPLIT in dictionary D. N is silently capped to a maximum
+ of MAX_SPLITS. */
static void
dict_set_split_vars__ (struct dictionary *d,
struct variable *const *split, size_t n,
- bool skip_callbacks)
+ enum split_type type, bool skip_callbacks)
{
+ if (n > MAX_SPLITS)
+ n = MAX_SPLITS;
assert (n == 0 || split != NULL);
d->n_splits = n;
+ d->split_type = type == SPLIT_NONE ? SPLIT_LAYERED : type;
if (n > 0)
{
d->split = xnrealloc (d->split, n, sizeof *d->split) ;
}
}
+enum split_type
+dict_get_split_type (const struct dictionary *d)
+{
+ return d->split_type;
+}
+
/* Sets N split vars SPLIT in dictionary D. */
void
dict_set_split_vars (struct dictionary *d,
- struct variable *const *split, size_t n)
+ struct variable *const *split, size_t n,
+ enum split_type type)
{
- dict_set_split_vars__ (d, split, n, false);
+ dict_set_split_vars__ (d, split, n, type, false);
}
+void
+dict_clear_split_vars (struct dictionary *d)
+{
+ dict_set_split_vars (d, NULL, 0, SPLIT_NONE);
+}
\f
/* Deletes variable V from dictionary D and frees V.
invalidate_proto (d);
hmap_clear (&d->name_map);
d->next_value_idx = 0;
- dict_set_split_vars__ (d, NULL, 0, skip_callbacks);
+ dict_set_split_vars__ (d, NULL, 0, SPLIT_NONE, skip_callbacks);
if (skip_callbacks)
{
}
/* Returns the value of D's weighting variable in case C, except
- that a negative weight is returned as 0. Returns 1 if the
+ that a negative or missing weight is returned as 0. Returns 1 if the
dictionary is unweighted. Will warn about missing, negative,
or zero values if *WARN_ON_INVALID is true. The function will
set *WARN_ON_INVALID to false if an invalid weight is
}
}
+/* Like dict_get_case_weight(), but additionally rounds each weight to the
+ nearest integer. */
+double
+dict_get_rounded_case_weight (const struct dictionary *d,
+ const struct ccase *c, bool *warn_on_invalid)
+{
+ return floor (dict_get_case_weight (d, c, warn_on_invalid) + 0.5);
+}
+
/* Returns the format to use for weights. */
const struct fmt_spec *
dict_get_weight_format (const struct dictionary *d)