/* PSPP - binary encodings for categorical variables.
Copyright (C) 2005 Free Software Foundation, Inc.
- Written by Jason H Stover <jason@sakla.net>.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
'cat_var'.
*/
#include <config.h>
+
+#include <assert.h>
#include <stdlib.h>
+#include <string.h>
+
#include <libpspp/alloc.h>
#include <libpspp/message.h>
#include "category.h"
-#include "cat-routines.h"
-#include <string.h>
+#include "value.h"
#include "variable.h"
+#define CAT_VALUE_NOT_FOUND -2
+
#define N_INITIAL_CATEGORIES 1
+/*
+ This structure contains the observed values of a
+ categorical variable.
+ */
+struct cat_vals
+{
+ union value *vals;
+ size_t n_categories;
+ size_t n_allocated_categories; /* This is used only during
+ initialization to keep
+ track of the number of
+ values stored.
+ */
+};
+
void
-cat_stored_values_create (struct variable *v)
+cat_stored_values_create (const struct variable *v)
{
- if (v->obs_vals == NULL)
+ if (!var_has_obs_vals (v))
{
- v->obs_vals = xmalloc (sizeof (*v->obs_vals));
- v->obs_vals->n_categories = 0;
- v->obs_vals->n_allocated_categories = N_INITIAL_CATEGORIES;
- v->obs_vals->vals =
- xnmalloc (N_INITIAL_CATEGORIES, sizeof *v->obs_vals->vals);
+ struct cat_vals *obs_vals = xmalloc (sizeof *obs_vals);
+
+ obs_vals->n_categories = 0;
+ obs_vals->n_allocated_categories = N_INITIAL_CATEGORIES;
+ obs_vals->vals = xnmalloc (N_INITIAL_CATEGORIES, sizeof *obs_vals->vals);
+ var_set_obs_vals (v, obs_vals);
}
}
void
-cat_stored_values_destroy (struct variable *v)
+cat_stored_values_destroy (struct cat_vals *obs_vals)
{
- assert (v != NULL);
-
- if (v->obs_vals != NULL)
+ if (obs_vals != NULL)
{
- if (v->obs_vals->n_allocated_categories > 0)
- {
- free (v->obs_vals->vals);
- v->obs_vals->vals = NULL;
- }
- free (v->obs_vals);
- v->obs_vals = NULL;
+ if (obs_vals->n_allocated_categories > 0)
+ free (obs_vals->vals);
+ free (obs_vals);
}
}
size_t
cat_value_find (const struct variable *v, const union value *val)
{
+ struct cat_vals *obs_vals = var_get_obs_vals (v);
size_t i;
const union value *candidate;
- assert (val != NULL);
- assert (v != NULL);
- assert (v->obs_vals != NULL);
- for (i = 0; i < v->obs_vals->n_categories; i++)
+ for (i = 0; i < obs_vals->n_categories; i++)
{
- candidate = v->obs_vals->vals + i;
+ candidate = obs_vals->vals + i;
assert (candidate != NULL);
- if (!compare_values (candidate, val, v->width))
+ if (!compare_values (candidate, val, var_get_width (v)))
{
return i;
}
Add the new value unless it is already present.
*/
void
-cat_value_update (struct variable *v, const union value *val)
+cat_value_update (const struct variable *v, const union value *val)
{
- struct cat_vals *cv;
-
- if (v->type == ALPHA)
+ if (var_is_alpha (v))
{
- assert (val != NULL);
- assert (v != NULL);
- cv = v->obs_vals;
+ struct cat_vals *cv = var_get_obs_vals (v);
if (cat_value_find (v, val) == CAT_VALUE_NOT_FOUND)
{
if (cv->n_categories >= cv->n_allocated_categories)
}
}
-union value *
-cat_subscript_to_value (const size_t s, struct variable *v)
+const union value *
+cat_subscript_to_value (const size_t s, const struct variable *v)
{
- assert (v->obs_vals != NULL);
- if (s < v->obs_vals->n_categories)
- {
- return (v->obs_vals->vals + s);
- }
- else
- {
- return NULL;
- }
+ struct cat_vals *obs_vals = var_get_obs_vals (v);
+ return s < obs_vals->n_categories ? obs_vals->vals + s : NULL;
}
/*
Return the number of categories of a categorical variable.
*/
-size_t
+size_t
cat_get_n_categories (const struct variable *v)
{
- return v->obs_vals->n_categories;
+ return var_get_obs_vals (v)->n_categories;
}