02111-1307, USA. */
#include <config.h>
-#include <assert.h>
+#include "dictionary.h"
#include <stdlib.h>
#include "algorithm.h"
#include "alloc.h"
+#include "case.h"
+#include "error.h"
#include "hash.h"
#include "misc.h"
#include "str.h"
d->var = NULL;
d->var_cnt = d->var_cap = 0;
- d->name_tab = hsh_create (8, compare_variables, hash_variable, NULL, NULL);
+ d->name_tab = hsh_create (8, compare_var_names, hash_var_name, NULL, NULL);
d->next_value_idx = 0;
d->split = NULL;
d->split_cnt = 0;
for (i = 0; i < d->var_cnt; i++)
{
struct variable *v = d->var[i];
+ var_clear_aux (v);
val_labs_destroy (v->val_labs);
free (v->label);
free (v);
dict_clear_vectors (d);
}
+/* Destroys the aux data for every variable in D, by calling
+ var_clear_aux() for each variable. */
+void
+dict_clear_aux (struct dictionary *d)
+{
+ int i;
+
+ assert (d != NULL);
+
+ for (i = 0; i < d->var_cnt; i++)
+ var_clear_aux (d->var[i]);
+}
+
/* Clears a dictionary and destroys it. */
void
dict_destroy (struct dictionary *d)
v->write = v->print;
v->val_labs = val_labs_create (v->width);
v->label = NULL;
+ v->aux = NULL;
+ v->aux_dtor = NULL;
/* Update dictionary. */
if (d->var_cnt >= d->var_cap)
/* Compares two double pointers to variables, which should point
to elements of a struct dictionary's `var' member array. */
static int
-compare_variable_dblptrs (const void *a_, const void *b_, void *aux UNUSED)
+compare_var_ptrs (const void *a_, const void *b_, void *aux UNUSED)
{
struct variable *const *a = a_;
struct variable *const *b = b_;
- if (a > b)
- return 1;
- else if (a < b)
- return -1;
- else
- return 0;
+ return *a < *b ? -1 : *a > *b;
}
/* Deletes variable V from dictionary D and frees V.
assert (dict_contains_var (d, v));
assert (d->var[v->index] == v);
- /* Remove v from splits, weight, filter variables. */
+ /* Delete aux data. */
+ var_clear_aux (v);
+
+ /* Remove V from splits, weight, filter variables. */
d->split_cnt = remove_equal (d->split, d->split_cnt, sizeof *d->split,
- &v,
- compare_variable_dblptrs, NULL);
+ &v, compare_var_ptrs, NULL);
if (d->weight == v)
d->weight = NULL;
if (d->filter == v)
d->filter = NULL;
dict_clear_vectors (d);
- /* Remove v from var array. */
+ /* Remove V from var array. */
+ remove_element (d->var, d->var_cnt, sizeof *d->var, v->index);
d->var_cnt--;
- memmove (d->var + v->index, d->var + v->index + 1,
- (d->var_cnt - v->index) * sizeof *d->var);
/* Update index. */
for (i = v->index; i < d->var_cnt; i++)
return d->weight;
}
-/* Returns the value of D's weighting variable in case C, except
- that a negative weight is returned as 0. Returns 1 if the
- dictionary is unweighted. */
+/* Returns the value of D's weighting variable in case C, except that a
+ negative 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 nonzero. The function will set warn_on_invalid to zero
+ if an invalid weight is found. */
double
-dict_get_case_weight (const struct dictionary *d, const struct ccase *c)
+dict_get_case_weight (const struct dictionary *d, const struct ccase *c,
+ int *warn_on_invalid)
{
assert (d != NULL);
assert (c != NULL);
return 1.0;
else
{
- double w = c->data[d->weight->fv].f;
- if (w < 0.0)
+ double w = case_num (c, d->weight->fv);
+ if ( w < 0.0 || w == SYSMIS || is_num_user_missing(w, d->weight) )
w = 0.0;
+ if ( w == 0.0 && *warn_on_invalid ) {
+ *warn_on_invalid = 0;
+ msg (SW, _("At least one case in the data file had a weight value "
+ "that was user-missing, system-missing, zero, or "
+ "negative. These case(s) were ignored."));
+ }
return w;
}
}
{
size_t i;
+ d->next_value_idx = 0;
for (i = 0; i < d->var_cnt; )
{
struct variable *v = d->var[i];
}
}
+/* Copies values from SRC, which represents a case arranged
+ according to dictionary D, to DST, which represents a case
+ arranged according to the dictionary that will be produced by
+ dict_compact_values(D). */
+void
+dict_compact_case (const struct dictionary *d,
+ struct ccase *dst, const struct ccase *src)
+{
+ size_t i;
+ size_t value_idx;
+
+ value_idx = 0;
+ for (i = 0; i < d->var_cnt; i++)
+ {
+ struct variable *v = d->var[i];
+
+ if (dict_class_from_id (v->name) != DC_SCRATCH)
+ {
+ case_copy (dst, value_idx, src, v->fv, v->nv);
+ value_idx += v->nv;
+ }
+ }
+}
+
/* Returns the number of values that would be used by a case if
dict_compact_values() were called. */
size_t