Variable names including numeric suffixes may not exceed 64 characters
in length, and none of the variables may exist prior to @cmd{VECTOR}.
-All the variables in a vector must be the same type.
+All the variables in a vector must be the same type. String variables
+in a vector must all have the same width.
Vectors created with @cmd{VECTOR} disappear after any procedure or
procedure-like command is executed. The variables contained in the
+Sat Dec 9 18:05:59 2006 Ben Pfaff <blp@gnu.org>
+
+ * data-out.c (output_scientific): Fix bad assumption that "buf" is
+ null-terminated.
+
+Sat Dec 9 17:23:23 2006 Ben Pfaff <blp@gnu.org>
+
+ Finish converting struct variable to an opaque type. In this
+ phase, we add remaining setter and getter functions, convert the
+ remaining PSPP code to use them, and do a bunch of cleanup. The
+ resulting changes are pervasive but mostly trivial, and only the
+ notable changes are logged.
+
+ * automake.mk (src_data_libdata_a_SOURCES): Add the new source
+ files.
+
+ * case.c (case_data): Renamed case_data_idx.
+ (case_num): Renamed case_num_idx.
+ (case_str): Renamed case_str_idx.
+ (case_data_rw): Renamed case_data_rw_idx.
+
+ * case.h (case_data): New function with old name and an interface
+ that takes a variable instead of an index, which is easier to
+ use. Updated all callers to use the new interface, or to use the
+ new *_idx function (see above).
+ (case_num): Ditto.
+ (case_str): Ditto.
+ (case_data_rw): Ditto.
+
+ * category.c (cat_stored_values_destroy): Changed interface to
+ take a struct cat_vals * instead of a struct variable *.
+
+ * dictionary.c (dict_clone): Use new vector_clone function.
+ (dict_clear) Use new var_destroy function.
+ (add_var) New function.
+ (dict_create_var) Rewrite in terms of dict_create_var_assert.
+ (dict_create_var_assert) Rewrite in terms of add_var.
+ (dict_clone_var) Rewrite in terms of dict_clone_var_assert.
+ (dict_clone_var_assert) Rewrite in terms of var_clone, add_var.
+ (dict_lookup_var) Use new var_create, var_destroy functions.
+ (dict_contains_var) Rewrite in terms of new vardict functionality.
+ (set_var_dict_index) New function.
+ (set_var_case_index) New function.
+ (reindex_vars) New function.
+ (dict_delete_var) Rewrite in terms of new vardict functionality.
+ (dict_reorder_var) Ditto.
+ (dict_reorder_vars) Ditto.
+ (rename_var) New function.
+ (dict_rename_var) Use rename_var.
+ (dict_rename_vars) Use pool to simplify code. Use rename_var.
+ (dict_get_compacted_idx_to_fv) Rename
+ dict_get_compacted_dict_index_to_case_index, update callers.
+ (dict_create_vector) Use new vector_create function.
+ (dict_clear_vectors) Use new vector_destroy function.
+ (set_var_short_name_suffix) Move here from variable.c, renamed
+ from var_set_short_name_suffix, make static, update caller.
+
+ * sys-file-private.c: New file.
+ (sfm_width_to_bytes) Moved here from variable.c, renamed from
+ width_to_bytes, update callers.
+
+ * sys-file-private.h: New file. Later it will supplant
+ sfm-private.h; for now it supplements it.
+ (macro MIN_VERY_LONG_STRING) New macro.
+ (macro EFFECTIVE_LONG_STRING_LENGTH) New macro, from value.h.
+
+ * sys-file-reader.c: Use MIN_VERY_LONG_STRING - 1 where
+ MAX_LONG_STRING was used before.
+
+ * sys-file-writer.c: Ditto.
+
+ * value-labels.c: Change the paradigm here to be that a null
+ pointer is OK for a struct val_labs * in most cases; it just
+ represents an empty set of value labels.
+ (val_labs_copy) A copy of a null set is a null set.
+ (val_labs_count) A null set has 0 labels.
+ (val_labs_replace) Change return type to void. Rewrite for
+ simplicity.
+ (val_labs_find) A null set does not contain the value.
+ (value_to_string) Moved to variable.c, renamed var_get_value_name,
+ transposed argument order, updated all callers.
+
+ * value.c: New file.
+ (value_dup) Moved here from variable.c.
+ (compare_values) Ditto.
+ (hash_value) Ditto.
+
+ * value.h: (macro MAX_SHORT_STRING) Rewrote for simplicity.
+ (macro MAX_LONG_STRING) Removed, because it was only interesting
+ for system files, not for general code.
+ (macro MAX_VERY_LONG_STRING) Ditto.
+ (macro EFFECTIVE_LONG_STRING_LENGTH) Moved to sys-file-private.h.
+ (macro MAX_ELEMS_PER_VALUE) Removed, as it was unused.
+
+ * vardict.h: New file, for an interface between variables and
+ their dictionaries.
+
+ * variable.c: A lot of functions were moved around, for better
+ organization.
+ (struct variable) Move definition here, from variable.h.
+ (var_type_adj) Removed--makes i18n hard.
+ (var_type_noun) Ditto.
+ (var_create) New function.
+ (var_clone) New function.
+ (var_destroy) New function.
+ (var_set_name) Assert that variable is not in a dictionary.
+ (compare_var_names) Rename compare_vars_by_name and fix a couple
+ of callers who thought the args were strings.
+ (hash_var_name) Rename hash_var_by_name.
+ (compare_var_ptr_names) Rename compare_var_ptrs_by_name.
+ (hash_var_ptr_name) Rename hash_var_ptr_by_name.
+ (var_is_very_long_string) Removed, because it was only interesting
+ to system file code.
+ (var_set_missing_values) Allow the argument to be the wrong width,
+ as long as we can resize it. Simplify callers who were doing the
+ resizing themselves.
+ (var_get_value_labels) New function.
+ (var_has_value_labels) New function.
+ (var_set_value_labels) New function.
+ (alloc_value_labels) New function.
+ (var_add_value_label) New function.
+ (var_replace_value_label) New function.
+ (var_clear_value_labels) New function.
+ (var_lookup_value_label) New function.
+ (var_get_value_name) Moved here from variable.c, renamed from
+ var_get_value_name, transposed argument order, updated all
+ callers.
+ (var_to_string) Moved here, from variable-label.c.
+ (var_set_leave) New function.
+ (var_get_leave) New function.
+ (var_must_leave) New function.
+ (var_set_short_name_suffix) Moved to dictionary.c, renamed
+ set_var_short_name_suffix.
+ (var_get_dict_index) New function.
+ (var_get_case_index) New function.
+ (var_get_obs_vals) New function.
+ (var_set_obs_vals) New function.
+ (var_has_obs_vals) New function.
+ (var_get_vardict) New function.
+ (var_set_vardict) New function.
+ (var_has_vardict) New function.
+ (var_clear_vardict) New function.
+ (value_dup) Moved to value.c.
+ (compare_values) Ditto.
+ (hash_value) Ditto.
+
+ * variable.h: (enum NUMERIC) Rename VAR_NUMERIC, update all users.
+ (enum ALPHA) Rename VAR_STRING, update all users.
+
+ * vector.c: New file.
+ (struct vector) Moved here, from variable.h.
+ (check_widths) New function.
+ (vector_create) New function.
+ (vector_clone) New function.
+ (vector_destroy) New function.
+ (vector_get_name) New function.
+ (vector_get_var) New function.
+ (vector_get_var_cnt) New function.
+ (compare_vector_ptrs_by_name) New function.
+
+ * vector.h: New file.
+
Sun Dec 10 11:32:56 WST 2006 John Darrington <john@darrington.wattle.id.au>
* casefilter.c (casefilter_variable_missing): Avoided comparision of
Mon Dec 4 22:20:17 2006 Ben Pfaff <blp@gnu.org>
- Start converting struct variable to an opaque. In this phase, we
- add a bunch of setter and getter functions and convert most of the
- PSPP code to use them. The resulting changes are pervasive but
- mostly trivial, and only the notable changes are logged.
+ Start converting struct variable to an opaque type. In this
+ phase, we add a bunch of setter and getter functions and convert
+ most of the PSPP code to use them. The resulting changes are
+ pervasive but mostly trivial, and only the notable changes are
+ logged.
* format.c (fmt_equal): New function.
src/data/sfm-private.h \
src/data/storage-stream.c \
src/data/storage-stream.h \
+ src/data/sys-file-private.c \
+ src/data/sys-file-private.h \
src/data/sys-file-reader.c \
src/data/sys-file-reader.h \
src/data/sys-file-writer.c \
src/data/sys-file-writer.h \
src/data/transformations.c \
src/data/transformations.h \
+ src/data/value.c \
src/data/value.h \
src/data/value-labels.c \
src/data/value-labels.h \
src/data/variable.h \
- src/data/variable.c
+ src/data/variable.c \
+ src/data/vector.c \
+ src/data/vector.h
element of C numbered IDX.
The caller must not modify the returned data. */
const union value *
-case_data (const struct ccase *c, size_t idx)
+case_data_idx (const struct ccase *c, size_t idx)
{
assert (c != NULL);
assert (c->case_data != NULL);
/* Returns the numeric value of the `union value' in C numbered
IDX. */
double
-case_num (const struct ccase *c, size_t idx)
+case_num_idx (const struct ccase *c, size_t idx)
{
assert (c != NULL);
assert (c->case_data != NULL);
(Note that the value is not null-terminated.)
The caller must not modify the return value. */
const char *
-case_str (const struct ccase *c, size_t idx)
+case_str_idx (const struct ccase *c, size_t idx)
{
assert (c != NULL);
assert (c->case_data != NULL);
element of C numbered IDX.
The caller is allowed to modify the returned data. */
union value *
-case_data_rw (struct ccase *c, size_t idx)
+case_data_rw_idx (struct ccase *c, size_t idx)
{
assert (c != NULL);
assert (c->case_data != NULL);
if (var_get_width (va) == 0)
{
- double af = case_num (ca, va->fv);
- double bf = case_num (cb, vb->fv);
+ double af = case_num (ca, va);
+ double bf = case_num (cb, vb);
if (af != bf)
return af > bf ? 1 : -1;
}
else
{
- const char *as = case_str (ca, va->fv);
- const char *bs = case_str (cb, vb->fv);
+ const char *as = case_str (ca, va);
+ const char *bs = case_str (cb, vb);
int cmp = memcmp (as, bs, var_get_width (va));
if (cmp != 0)
#include <stddef.h>
#include <stdbool.h>
#include "value.h"
+#include "variable.h"
/* Opaque structure that represents a case. Use accessor
functions instead of accessing any members directly. Use
CASE_INLINE void case_from_values (struct ccase *,
const union value *, size_t);
-CASE_INLINE const union value *case_data (const struct ccase *, size_t idx);
-CASE_INLINE double case_num (const struct ccase *, size_t idx);
-CASE_INLINE const char *case_str (const struct ccase *, size_t idx);
+static inline const union value *case_data (const struct ccase *,
+ const struct variable *);
+static inline double case_num (const struct ccase *, const struct variable *);
+static inline const char *case_str (const struct ccase *,
+ const struct variable *);
+static inline union value *case_data_rw (struct ccase *,
+ const struct variable *);
-CASE_INLINE union value *case_data_rw (struct ccase *, size_t idx);
+CASE_INLINE const union value *case_data_idx (const struct ccase *,
+ size_t idx);
+CASE_INLINE double case_num_idx (const struct ccase *, size_t idx);
+CASE_INLINE const char *case_str_idx (const struct ccase *, size_t idx);
+CASE_INLINE union value *case_data_rw_idx (struct ccase *, size_t idx);
struct variable;
int case_compare (const struct ccase *, const struct ccase *,
}
static inline const union value *
-case_data (const struct ccase *c, size_t idx)
+case_data_idx (const struct ccase *c, size_t idx)
{
return &c->case_data->values[idx];
}
static inline double
-case_num (const struct ccase *c, size_t idx)
+case_num_idx (const struct ccase *c, size_t idx)
{
return c->case_data->values[idx].f;
}
static inline const char *
-case_str (const struct ccase *c, size_t idx)
+case_str_idx (const struct ccase *c, size_t idx)
{
return c->case_data->values[idx].s;
}
static inline union value *
-case_data_rw (struct ccase *c, size_t idx)
+case_data_rw_idx (struct ccase *c, size_t idx)
{
if (c->case_data->ref_cnt > 1)
case_unshare (c);
}
#endif /* !DEBUGGING */
+/* Returns a pointer to the `union value' used for the
+ element of C for variable V.
+ Case C must be drawn from V's dictionary.
+ The caller must not modify the returned data. */
+static inline const union value *
+case_data (const struct ccase *c, const struct variable *v)
+{
+ return case_data_idx (c, var_get_case_index (v));
+}
+
+/* Returns the numeric value of the `union value' in C for
+ variable V.
+ Case C must be drawn from V's dictionary. */
+static inline double
+case_num (const struct ccase *c, const struct variable *v)
+{
+ return case_num_idx (c, var_get_case_index (v));
+}
+
+/* Returns the string value of the `union value' in C for
+ variable V.
+ Case C must be drawn from V's dictionary.
+ (Note that the value is not null-terminated.)
+ The caller must not modify the return value. */
+static inline const char *
+case_str (const struct ccase *c, const struct variable *v)
+{
+ return case_str_idx (c, var_get_case_index (v));
+}
+
+/* Returns a pointer to the `union value' used for the
+ element of C for variable V.
+ Case C must be drawn from V's dictionary.
+ The caller is allowed to modify the returned data. */
+static inline union value *
+case_data_rw (struct ccase *c, const struct variable *v)
+{
+ return case_data_rw_idx (c, var_get_case_index (v));
+}
+
#endif /* case.h */
const struct ccase *c,
const struct variable *var)
{
- const union value *val = case_data (c, var->fv) ;
+ const union value *val = case_data (c, var) ;
- if ( var_get_type (var) != ALPHA && val->f == SYSMIS )
+ if ( var_is_numeric (var) && val->f == SYSMIS )
return true;
if ( filter->exclude_user_missing &&
void cat_create_value_matrix (struct variable *);
-void cat_stored_values_destroy (struct variable *);
+void cat_stored_values_destroy (struct cat_vals *);
#endif
#include <libpspp/alloc.h>
#include <libpspp/message.h>
#include "cat-routines.h"
+#include "value.h"
#include "variable.h"
#define N_INITIAL_CATEGORIES 1
void
cat_stored_values_create (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, var_get_width (v)))
{
void
cat_value_update (struct variable *v, const union value *val)
{
- struct cat_vals *cv;
-
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)
{
- 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;
}
/*
size_t
cat_get_n_categories (const struct variable *v)
{
- return v->obs_vals->n_categories;
+ return var_get_obs_vals (v)->n_categories;
}
#include "calendar.h"
#include "identifier.h"
#include "settings.h"
-#include "variable.h"
+#include "value.h"
#include <libpspp/assertion.h>
#include <libpspp/compiler.h>
#include "calendar.h"
#include "format.h"
#include "settings.h"
-#include "variable.h"
+#include "value.h"
#include <libpspp/assertion.h>
#include <libpspp/float-format.h>
p = mempset (p, ' ', ss_length (style->neg_suffix));
assert (p == buf + format->w);
+ memcpy (output, buf, format->w);
- buf_copy_str_lpad (output, format->w, buf);
return true;
}
\f
#include "category.h"
#include "settings.h"
#include "value-labels.h"
+#include "vardict.h"
#include "variable.h"
+#include "vector.h"
#include <libpspp/alloc.h>
#include <libpspp/array.h>
#include <libpspp/compiler.h>
#include <libpspp/hash.h>
#include <libpspp/message.h>
#include <libpspp/misc.h>
+#include <libpspp/pool.h>
#include <libpspp/str.h>
#include "minmax.h"
d->var = NULL;
d->var_cnt = d->var_cap = 0;
- d->name_tab = hsh_create (8, compare_var_names, hash_var_name, NULL, NULL);
+ d->name_tab = hsh_create (8, compare_vars_by_name, hash_var_by_name,
+ NULL, NULL);
d->next_value_idx = 0;
d->split = NULL;
d->split_cnt = 0;
d->vector_cnt = s->vector_cnt;
d->vector = xnmalloc (d->vector_cnt, sizeof *d->vector);
- for (i = 0; i < s->vector_cnt; i++)
- {
- struct vector *sv = s->vector[i];
- struct vector *dv = d->vector[i] = xmalloc (sizeof *dv);
- int j;
-
- dv->idx = i;
- strcpy (dv->name, sv->name);
- dv->cnt = sv->cnt;
- dv->var = xnmalloc (dv->cnt, sizeof *dv->var);
- for (j = 0; j < dv->cnt; j++)
- dv->var[j] = d->var[sv->var[j]->index];
- }
+ for (i = 0; i < s->vector_cnt; i++)
+ d->vector[i] = vector_clone (s->vector[i], s, d);
return d;
}
assert (d != NULL);
- for (i = 0; i < d->var_cnt; i++)
+ for (i = 0; i < d->var_cnt; i++)
{
- struct variable *v = d->var[i];
- var_clear_aux (v);
- val_labs_destroy (v->val_labs);
- var_clear_label (v);
- free (v->label);
- free (v);
+ var_clear_vardict (d->var[i]);
+ var_destroy (d->var[i]);
}
free (d->var);
d->var = NULL;
return d->var_cnt;
}
-/* Returns the variable in D with index IDX, which must be
- between 0 and the count returned by dict_get_var_cnt(),
- exclusive. */
+/* Returns the variable in D with dictionary index IDX, which
+ must be between 0 and the count returned by
+ dict_get_var_cnt(), exclusive. */
struct variable *
dict_get_var (const struct dictionary *d, size_t idx)
{
assert (*cnt == count);
}
-
-/* Creates and returns a new variable in D with the given NAME
- and WIDTH. Returns a null pointer if the given NAME would
- duplicate that of an existing variable in the dictionary. */
-struct variable *
-dict_create_var (struct dictionary *d, const char *name, int width)
+static struct variable *
+add_var (struct dictionary *d, struct variable *v)
{
- struct variable *v;
-
- assert (d != NULL);
- assert (name != NULL);
-
- assert (width >= 0 && width <= MAX_STRING);
-
- assert (var_is_plausible_name(name,0));
-
- /* Make sure there's not already a variable by that name. */
- if (dict_lookup_var (d, name) != NULL)
- return NULL;
-
- /* Allocate and initialize variable. */
- v = xmalloc (sizeof *v);
- var_set_name (v, name);
- v->width = width;
- v->fv = d->next_value_idx;
- v->leave = dict_class_from_id (var_get_name (v)) == DC_SCRATCH;
- v->index = d->var_cnt;
- mv_init (&v->miss, width);
- if (var_is_numeric (v))
- {
- v->print = fmt_for_output (FMT_F, 8, 2);
- v->alignment = ALIGN_RIGHT;
- v->display_width = 8;
- v->measure = MEASURE_SCALE;
- }
- else
- {
- v->print = fmt_for_output (FMT_A, var_get_width (v), 0);
- v->alignment = ALIGN_LEFT;
- v->display_width = 8;
- v->measure = MEASURE_NOMINAL;
- }
- v->write = v->print;
- v->val_labs = val_labs_create (var_get_width (v));
- v->label = NULL;
- var_clear_short_name (v);
- v->aux = NULL;
- v->aux_dtor = NULL;
- v->obs_vals = NULL;
+ /* Add dictionary info to variable. */
+ struct vardict_info vdi;
+ vdi.case_index = d->next_value_idx;
+ vdi.dict_index = d->var_cnt;
+ var_set_vardict (v, &vdi);
/* Update dictionary. */
if (d->var_cnt >= d->var_cap)
d->var_cap = 8 + 2 * d->var_cap;
d->var = xnrealloc (d->var, d->var_cap, sizeof *d->var);
}
- d->var[v->index] = v;
- d->var_cnt++;
+ d->var[d->var_cnt++] = v;
hsh_force_insert (d->name_tab, v);
d->next_value_idx += var_get_value_cnt (v);
return v;
}
+/* Creates and returns a new variable in D with the given NAME
+ and WIDTH. Returns a null pointer if the given NAME would
+ duplicate that of an existing variable in the dictionary. */
+struct variable *
+dict_create_var (struct dictionary *d, const char *name, int width)
+{
+ return (dict_lookup_var (d, name) == NULL
+ ? dict_create_var_assert (d, name, width)
+ : NULL);
+}
+
/* Creates and returns a new variable in D with the given NAME
and WIDTH. Assert-fails if the given NAME would duplicate
that of an existing variable in the dictionary. */
struct variable *
dict_create_var_assert (struct dictionary *d, const char *name, int width)
{
- struct variable *v = dict_create_var (d, name, width);
- assert (v != NULL);
- return v;
+ assert (dict_lookup_var (d, name) == NULL);
+ return add_var (d, var_create (name, width));
}
/* Creates and returns a new variable in D with name NAME, as a
- copy of existing variable OV, which need not be in D or in any
- dictionary. Returns a null pointer if the given NAME would
- duplicate that of an existing variable in the dictionary. */
+ copy of existing variable OLD_VAR, which need not be in D or
+ in any dictionary. Returns a null pointer if the given NAME
+ would duplicate that of an existing variable in the
+ dictionary. */
struct variable *
-dict_clone_var (struct dictionary *d, const struct variable *ov,
+dict_clone_var (struct dictionary *d, const struct variable *old_var,
const char *name)
{
- struct variable *nv;
-
- assert (d != NULL);
- assert (ov != NULL);
- assert (name != NULL);
-
- assert (strlen (name) >= 1);
- assert (strlen (name) <= LONG_NAME_LEN);
-
- nv = dict_create_var (d, name, var_get_width (ov));
- if (nv == NULL)
- return NULL;
-
- /* Copy most members not copied via dict_create_var().
- short_name[] is intentionally not copied, because there is
- no reason to give a new variable with potentially a new name
- the same short name. */
- nv->leave = var_get_leave (ov);
- var_set_missing_values (nv, var_get_missing_values (ov));
- var_set_print_format (nv, var_get_print_format (ov));
- var_set_write_format (nv, var_get_write_format (ov));
- val_labs_destroy (nv->val_labs);
- nv->val_labs = val_labs_copy (ov->val_labs);
- var_set_label (nv, var_get_label (ov));
- var_set_measure (nv, var_get_measure (ov));
- var_set_display_width (nv, var_get_display_width (ov));
- var_set_alignment (nv, var_get_alignment (ov));
-
- return nv;
+ return (dict_lookup_var (d, name) == NULL
+ ? dict_clone_var_assert (d, old_var, name)
+ : NULL);
}
/* Creates and returns a new variable in D with name NAME, as a
- copy of existing variable OV, which need not be in D or in any
- dictionary. Assert-fails if the given NAME would duplicate
- that of an existing variable in the dictionary. */
+ copy of existing variable OLD_VAR, which need not be in D or
+ in any dictionary. Assert-fails if the given NAME would
+ duplicate that of an existing variable in the dictionary. */
struct variable *
-dict_clone_var_assert (struct dictionary *d, const struct variable *ov,
+dict_clone_var_assert (struct dictionary *d, const struct variable *old_var,
const char *name)
{
- struct variable *v = dict_clone_var (d, ov, name);
- assert (v != NULL);
- return v;
+ struct variable *new_var = var_clone (old_var);
+ assert (dict_lookup_var (d, name) == NULL);
+ var_set_name (new_var, name);
+ return add_var (d, new_var);
}
/* Returns the variable named NAME in D, or a null pointer if no
struct variable *
dict_lookup_var (const struct dictionary *d, const char *name)
{
- struct variable v;
-
- assert (d != NULL);
- assert (name != NULL);
-
- str_copy_trunc (v.name, sizeof v.name, name);
- return hsh_find (d->name_tab, &v);
+ struct variable *target = var_create (name, 0);
+ struct variable *result = hsh_find (d->name_tab, target);
+ var_destroy (target);
+ return result;
}
/* Returns the variable named NAME in D. Assert-fails if no
bool
dict_contains_var (const struct dictionary *d, const struct variable *v)
{
- assert (d != NULL);
- assert (v != NULL);
-
- return v->index >= 0 && v->index < d->var_cnt && d->var[v->index] == v;
+ if (var_has_vardict (v))
+ {
+ const struct vardict_info *vdi = var_get_vardict (v);
+ return (vdi->dict_index >= 0
+ && vdi->dict_index < d->var_cnt
+ && d->var[vdi->dict_index] == v);
+ }
+ else
+ return false;
}
/* Compares two double pointers to variables, which should point
return *a < *b ? -1 : *a > *b;
}
+/* Sets the dict_index in V's vardict to DICT_INDEX. */
+static void
+set_var_dict_index (struct variable *v, int dict_index)
+{
+ struct vardict_info vdi = *var_get_vardict (v);
+ vdi.dict_index = dict_index;
+ var_set_vardict (v, &vdi);
+}
+
+/* Sets the case_index in V's vardict to DICT_INDEX. */
+static void
+set_var_case_index (struct variable *v, int case_index)
+{
+ struct vardict_info vdi = *var_get_vardict (v);
+ vdi.case_index = case_index;
+ var_set_vardict (v, &vdi);
+}
+
+/* Re-sets the dict_index in the dictionary variables with
+ indexes from FROM to TO (exclusive). */
+static void
+reindex_vars (struct dictionary *d, size_t from, size_t to)
+{
+ size_t i;
+
+ for (i = from; i < to; i++)
+ set_var_dict_index (d->var[i], i);
+}
+
/* Deletes variable V from dictionary D and frees V.
This is a very bad idea if there might be any pointers to V
void
dict_delete_var (struct dictionary *d, struct variable *v)
{
- size_t i;
+ int dict_index = var_get_dict_index (v);
- assert (d != NULL);
- assert (v != NULL);
assert (dict_contains_var (d, v));
/* Delete aux data. */
dict_clear_vectors (d);
/* Remove V from var array. */
- remove_element (d->var, d->var_cnt, sizeof *d->var, v->index);
+ remove_element (d->var, d->var_cnt, sizeof *d->var, dict_index);
d->var_cnt--;
- /* Update index. */
- for (i = v->index; i < d->var_cnt; i++)
- d->var[i]->index = i;
+ /* Update dict_index for each affected variable. */
+ reindex_vars (d, dict_index, d->var_cnt);
/* Update name hash. */
hsh_force_delete (d->name_tab, v);
/* Free memory. */
- val_labs_destroy (v->val_labs);
- cat_stored_values_destroy (v);
- free (v->label);
- free (v);
+ var_clear_vardict (v);
+ var_destroy (v);
}
/* Deletes the COUNT variables listed in VARS from D. This is
if any, retain their relative positions. Runs in time linear
in the distance moved. */
void
-dict_reorder_var (struct dictionary *d, struct variable *v,
- size_t new_index)
+dict_reorder_var (struct dictionary *d, struct variable *v, size_t new_index)
{
- size_t min_idx, max_idx;
- size_t i;
-
- assert (d != NULL);
- assert (v != NULL);
- assert (dict_contains_var (d, v));
- assert (new_index < d->var_cnt);
+ size_t old_index = var_get_dict_index (v);
- move_element (d->var, d->var_cnt, sizeof *d->var, v->index, new_index);
-
- min_idx = MIN (v->index, new_index);
- max_idx = MAX (v->index, new_index);
- for (i = min_idx; i <= max_idx; i++)
- d->var[i]->index = i;
+ assert (new_index < d->var_cnt);
+ move_element (d->var, d->var_cnt, sizeof *d->var, old_index, new_index);
+ reindex_vars (d, MIN (old_index, new_index), MAX (old_index, new_index) + 1);
}
/* Reorders the variables in D, placing the COUNT variables
memcpy (new_var, order, count * sizeof *new_var);
for (i = 0; i < count; i++)
{
- assert (d->var[order[i]->index] != NULL);
- d->var[order[i]->index] = NULL;
- order[i]->index = i;
+ size_t index = var_get_dict_index (order[i]);
+ assert (d->var[index] == order[i]);
+ d->var[index] = NULL;
+ set_var_dict_index (order[i], i);
}
for (i = 0; i < d->var_cnt; i++)
if (d->var[i] != NULL)
{
assert (count < d->var_cnt);
new_var[count] = d->var[i];
- new_var[count]->index = count;
+ set_var_dict_index (new_var[count], count);
count++;
}
free (d->var);
d->var = new_var;
}
+/* Changes the name of variable V in dictionary D to NEW_NAME. */
+static void
+rename_var (struct dictionary *d, struct variable *v, const char *new_name)
+{
+ struct vardict_info vdi;
+
+ assert (dict_contains_var (d, v));
+
+ vdi = *var_get_vardict (v);
+ var_clear_vardict (v);
+ var_set_name (v, new_name);
+ var_set_vardict (v, &vdi);
+}
+
/* Changes the name of V in D to name NEW_NAME. Assert-fails if
a variable named NEW_NAME is already in D, except that
NEW_NAME may be the same as V's existing name. */
dict_rename_var (struct dictionary *d, struct variable *v,
const char *new_name)
{
- assert (d != NULL);
- assert (v != NULL);
- assert (new_name != NULL);
- assert (var_is_plausible_name (new_name, false));
- assert (dict_contains_var (d, v));
- assert (!compare_var_names (var_get_name (v), new_name, NULL)
+ assert (!strcasecmp (var_get_name (v), new_name)
|| dict_lookup_var (d, new_name) == NULL);
hsh_force_delete (d->name_tab, v);
- var_set_name (v, new_name);
+ rename_var (d, v, new_name);
hsh_force_insert (d->name_tab, v);
if (get_algorithm () == ENHANCED)
is returned. */
bool
dict_rename_vars (struct dictionary *d,
- struct variable **vars, char **new_names,
- size_t count, char **err_name)
+ struct variable **vars, char **new_names, size_t count,
+ char **err_name)
{
+ struct pool *pool;
char **old_names;
size_t i;
- bool success = true;
- assert (d != NULL);
assert (count == 0 || vars != NULL);
assert (count == 0 || new_names != NULL);
+ /* Save the names of the variables to be renamed. */
+ pool = pool_create ();
+ old_names = pool_nalloc (pool, count, sizeof *old_names);
+ for (i = 0; i < count; i++)
+ old_names[i] = pool_strdup (pool, var_get_name (vars[i]));
+
/* Remove the variables to be renamed from the name hash,
- save their names, and rename them. */
- old_names = xnmalloc (count, sizeof *old_names);
+ and rename them. */
for (i = 0; i < count; i++)
{
- assert (d->var[vars[i]->index] == vars[i]);
- assert (var_is_plausible_name (new_names[i], false));
hsh_force_delete (d->name_tab, vars[i]);
- old_names[i] = xstrdup (var_get_name (vars[i]));
- var_set_name (vars[i], new_names[i]);
+ rename_var (d, vars[i], new_names[i]);
}
/* Add the renamed variables back into the name hash,
checking for conflicts. */
for (i = 0; i < count; i++)
- {
- assert (new_names[i] != NULL);
- assert (*new_names[i] != '\0');
- assert (strlen (new_names[i]) >= 1);
- assert (strlen (new_names[i]) <= LONG_NAME_LEN);
-
- if (hsh_insert (d->name_tab, vars[i]) != NULL)
- {
- /* There is a name conflict.
- Back out all the name changes that have already
- taken place, and indicate failure. */
- size_t fail_idx = i;
- if (err_name != NULL)
- *err_name = new_names[i];
-
- for (i = 0; i < fail_idx; i++)
- hsh_force_delete (d->name_tab, vars[i]);
+ if (hsh_insert (d->name_tab, vars[i]) != NULL)
+ {
+ /* There is a name conflict.
+ Back out all the name changes that have already
+ taken place, and indicate failure. */
+ size_t fail_idx = i;
+ if (err_name != NULL)
+ *err_name = new_names[i];
+
+ for (i = 0; i < fail_idx; i++)
+ hsh_force_delete (d->name_tab, vars[i]);
- for (i = 0; i < count; i++)
- {
- var_set_name (vars[i], old_names[i]);
- hsh_force_insert (d->name_tab, vars[i]);
- }
-
- success = false;
- goto done;
- }
- }
+ for (i = 0; i < count; i++)
+ {
+ rename_var (d, vars[i], old_names[i]);
+ hsh_force_insert (d->name_tab, vars[i]);
+ }
+
+ pool_destroy (pool);
+ return false;
+ }
/* Clear short names. */
if (get_algorithm () == ENHANCED)
for (i = 0; i < count; i++)
var_clear_short_name (vars[i]);
- done:
- /* Free the old names we kept around. */
- for (i = 0; i < count; i++)
- free (old_names[i]);
- free (old_names);
-
- return success;
+ pool_destroy (pool);
+ return true;
}
/* Returns the weighting variable in dictionary D, or a null
return 1.0;
else
{
- double w = case_num (c, d->weight->fv);
+ double w = case_num (c, d->weight);
if (w < 0.0 || var_is_num_missing (d->weight, w))
w = 0.0;
if ( w == 0.0 && *warn_on_invalid ) {
d->case_limit = case_limit;
}
-/* Returns the index of the next value to be added to D. This
- value is the number of `union value's that need to be
+/* Returns the case index of the next value to be added to D.
+ This value is the number of `union value's that need to be
allocated to store a case for dictionary D. */
int
dict_get_next_value_idx (const struct dictionary *d)
if (dict_class_from_id (var_get_name (v)) != DC_SCRATCH)
{
- v->fv = d->next_value_idx;
+ set_var_case_index (v, d->next_value_idx);
d->next_value_idx += var_get_value_cnt (v);
i++;
}
}
/* Creates and returns an array mapping from a dictionary index
- to the `fv' that the corresponding variable will have after
- calling dict_compact_values(). Scratch variables receive -1
- for `fv' because dict_compact_values() will delete them. */
+ to the case index that the corresponding variable will have
+ after calling dict_compact_values(). Scratch variables
+ receive -1 for case index because dict_compact_values() will
+ delete them. */
int *
-dict_get_compacted_idx_to_fv (const struct dictionary *d)
+dict_get_compacted_dict_index_to_case_index (const struct dictionary *d)
{
size_t i;
size_t next_value_idx;
- int *idx_to_fv;
+ int *map;
- idx_to_fv = xnmalloc (d->var_cnt, sizeof *idx_to_fv);
+ map = xnmalloc (d->var_cnt, sizeof *map);
next_value_idx = 0;
for (i = 0; i < d->var_cnt; i++)
{
if (dict_class_from_id (var_get_name (v)) != DC_SCRATCH)
{
- idx_to_fv[i] = next_value_idx;
+ map[i] = next_value_idx;
next_value_idx += var_get_value_cnt (v);
}
else
- idx_to_fv[i] = -1;
+ map[i] = -1;
}
- return idx_to_fv;
+ return map;
}
/* Returns true if a case for dictionary D would be smaller after
for (i = 0; i < dict_get_var_cnt (d); i++)
{
struct variable *v = dict_get_var (d, i);
- if (v->fv != case_idx)
+ if (var_get_case_index (v) != case_idx)
return true;
case_idx += var_get_value_cnt (v);
}
if (dict_class_from_id (var_get_name (v)) == DC_SCRATCH)
continue;
- if (map != NULL && map->src_idx + map->cnt == v->fv)
+ if (map != NULL && map->src_idx + map->cnt == var_get_case_index (v))
map->cnt += var_get_value_cnt (v);
else
{
compactor->maps = x2nrealloc (compactor->maps, &map_allocated,
sizeof *compactor->maps);
map = &compactor->maps[compactor->map_cnt++];
- map->src_idx = v->fv;
+ map->src_idx = var_get_case_index (v);
map->dst_idx = value_idx;
map->cnt = var_get_value_cnt (v);
}
d->documents = xstrdup (documents);
}
-/* Creates in D a vector named NAME that contains CNT variables
- VAR (see cmd_vector()). Returns true if successful, or
- false if a vector named NAME already exists in D. */
+/* Creates in D a vector named NAME that contains the CNT
+ variables in VAR. Returns true if successful, or false if a
+ vector named NAME already exists in D. */
bool
dict_create_vector (struct dictionary *d,
const char *name,
struct variable **var, size_t cnt)
{
- struct vector *vector;
size_t i;
- assert (d != NULL);
- assert (name != NULL);
- assert (var_is_plausible_name (name, false));
assert (var != NULL);
assert (cnt > 0);
-
- if (dict_lookup_vector (d, name) != NULL)
- return false;
-
- d->vector = xnrealloc (d->vector, d->vector_cnt + 1, sizeof *d->vector);
- vector = d->vector[d->vector_cnt] = xmalloc (sizeof *vector);
- vector->idx = d->vector_cnt++;
- str_copy_trunc (vector->name, sizeof vector->name, name);
- vector->var = xnmalloc (cnt, sizeof *var);
for (i = 0; i < cnt; i++)
+ assert (dict_contains_var (d, var[i]));
+
+ if (dict_lookup_vector (d, name) == NULL)
{
- assert (dict_contains_var (d, var[i]));
- vector->var[i] = var[i];
+ d->vector = xnrealloc (d->vector, d->vector_cnt + 1, sizeof *d->vector);
+ d->vector[d->vector_cnt++] = vector_create (name, var, cnt);
+ return true;
}
- vector->cnt = cnt;
-
- return true;
+ else
+ return false;
}
/* Returns the vector in D with index IDX, which must be less
dict_lookup_vector (const struct dictionary *d, const char *name)
{
size_t i;
-
- assert (d != NULL);
- assert (name != NULL);
-
for (i = 0; i < d->vector_cnt; i++)
- if (!strcasecmp (d->vector[i]->name, name))
+ if (!strcasecmp (vector_get_name (d->vector[i]), name))
return d->vector[i];
return NULL;
}
{
size_t i;
- assert (d != NULL);
-
- for (i = 0; i < d->vector_cnt; i++)
- {
- free (d->vector[i]->var);
- free (d->vector[i]);
- }
+ for (i = 0; i < d->vector_cnt; i++)
+ vector_destroy (d->vector[i]);
free (d->vector);
+
d->vector = NULL;
d->vector_cnt = 0;
}
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
if (trial == 0)
var_set_short_name (v, var_get_name (v));
else
- var_set_short_name_suffix (v, var_get_name (v), trial - 1);
+ set_var_short_name_suffix (v, var_get_name (v), trial - 1);
trial++;
}
void dict_compact_values (struct dictionary *);
size_t dict_get_compacted_value_cnt (const struct dictionary *);
-int *dict_get_compacted_idx_to_fv (const struct dictionary *);
+int *dict_get_compacted_dict_index_to_case_index (const struct dictionary *);
bool dict_compacting_would_shrink (const struct dictionary *);
bool dict_compacting_would_change (const struct dictionary *);
#include <data/identifier.h>
#include <data/settings.h>
+#include <data/value.h>
#include <data/variable.h>
#include <libpspp/assertion.h>
#include <libpspp/compiler.h>
TYPE and returns true if so. Otherwise returns false and
emits an error message. */
bool
-fmt_check_type_compat (const struct fmt_spec *format, int var_type)
+fmt_check_type_compat (const struct fmt_spec *format, enum var_type var_type)
{
- assert (var_type == NUMERIC || var_type == ALPHA);
- if ((var_type == ALPHA) != (fmt_is_string (format->type) != 0))
+ assert (var_type_is_valid (var_type));
+ if ((var_type == VAR_STRING) != (fmt_is_string (format->type) != 0))
{
char str[FMT_STRING_LEN_MAX + 1];
msg (SE, _("%s variables are not compatible with %s format %s."),
- var_type == ALPHA ? _("String") : _("Numeric"),
- var_type == ALPHA ? _("numeric") : _("string"),
+ var_type == VAR_STRING ? _("String") : _("Numeric"),
+ var_type == VAR_STRING ? _("numeric") : _("string"),
fmt_to_string (format, str));
return false;
}
bool
fmt_check_width_compat (const struct fmt_spec *format, int width)
{
- if (!fmt_check_type_compat (format, width != 0 ? ALPHA : NUMERIC))
+ if (!fmt_check_type_compat (format, var_type_from_width (width)))
return false;
if (fmt_var_width (format) != width)
{
#include <stdbool.h>
#include <stddef.h>
+#include <data/variable.h>
#include <libpspp/str.h>
/* Format type categories. */
bool fmt_check (const struct fmt_spec *, bool for_input);
bool fmt_check_input (const struct fmt_spec *);
bool fmt_check_output (const struct fmt_spec *);
-bool fmt_check_type_compat (const struct fmt_spec *, int var_type);
+bool fmt_check_type_compat (const struct fmt_spec *, enum var_type);
bool fmt_check_width_compat (const struct fmt_spec *, int var_width);
/* Working with formats. */
contains only spaces in the characters that will be
trimmed. */
bool
-mv_is_resizable (struct missing_values *mv, int width)
+mv_is_resizable (const struct missing_values *mv, int width)
{
assert ((width == 0) == (mv->width == 0));
if (width > MAX_SHORT_STRING && mv->type != MV_NONE)
void mv_pop_range (struct missing_values *, double *low, double *high);
void mv_peek_range (const struct missing_values *, double *low, double *high);
-bool mv_is_resizable (struct missing_values *, int width);
+bool mv_is_resizable (const struct missing_values *, int width);
void mv_resize (struct missing_values *, int width);
typedef bool mv_is_missing_func (const struct missing_values *,
#include "dictionary.h"
#include "file-handle-def.h"
#include "format.h"
+#include "missing-values.h"
#include <libpspp/hash.h>
#include <libpspp/magic.h>
#include <libpspp/misc.h>
{
struct variable *var = v[j];
- if (!val_labs_replace (var->val_labs, val, label))
+ if (!var_add_value_label (var, &val, label))
continue;
if (var_is_numeric (var))
if (width == 0)
{
- case_data_rw (c, idx)->f = read_float (r);
+ case_data_rw_idx (c, idx)->f = read_float (r);
idx++;
}
else
{
char string[256];
read_string (r, string);
- buf_copy_str_rpad (case_data_rw (c, idx)->s, width, string);
+ buf_copy_str_rpad (case_data_rw_idx (c, idx)->s, width, string);
idx += DIV_RND_UP (width, MAX_SHORT_STRING);
}
}
#include <config.h>
#include "por-file-writer.h"
-#include <libpspp/message.h>
+
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
-#include <libpspp/alloc.h>
+
#include "case.h"
#include "dictionary.h"
-#include <libpspp/message.h>
#include "file-handle-def.h"
+#include "format.h"
+#include "missing-values.h"
+#include "stat-macros.h"
+#include "value-labels.h"
+#include "variable.h"
+
+#include <libpspp/alloc.h>
#include <libpspp/hash.h>
#include <libpspp/magic.h>
+#include <libpspp/message.h>
#include <libpspp/misc.h>
-#include "stat-macros.h"
#include <libpspp/str.h>
-#include "value-labels.h"
-#include "variable.h"
#include <libpspp/version.h>
#include "gettext.h"
const struct variable *dv = dict_get_var (dict, i);
struct pfm_var *pv = &w->vars[i];
pv->width = var_get_width (dv);
- pv->fv = dv->fv;
+ pv->fv = var_get_case_index (dv);
}
w->digits = opts.digits;
{
struct val_labs_iterator *j;
struct variable *v = dict_get_var (dict, i);
+ const struct val_labs *val_labs = var_get_value_labels (v);
struct val_lab *vl;
- if (!val_labs_count (v->val_labs))
+ if (val_labs == NULL)
continue;
buf_write (w, "D", 1);
write_int (w, 1);
write_string (w, var_get_short_name (v));
- write_int (w, val_labs_count (v->val_labs));
+ write_int (w, val_labs_count (val_labs));
- for (vl = val_labs_first_sorted (v->val_labs, &j); vl != NULL;
- vl = val_labs_next (v->val_labs, &j))
+ for (vl = val_labs_first_sorted (val_labs, &j); vl != NULL;
+ vl = val_labs_next (val_labs, &j))
{
write_value (w, &vl->value, v);
write_string (w, vl->label);
struct pfm_var *v = &w->vars[i];
if (v->width == 0)
- write_float (w, case_num (c, v->fv));
+ write_float (w, case_num_idx (c, v->fv));
else
{
write_int (w, v->width);
- buf_write (w, case_str (c, v->fv), v->width);
+ buf_write (w, case_str_idx (c, v->fv), v->width);
}
}
for (i = 0; i < var_cnt; i++)
{
struct variable *v = dict_get_var (dict, i);
- union value *value = case_data_rw (trns_case, v->fv);
+ union value *value = case_data_rw (trns_case, v);
if (var_is_numeric (v))
value->f = var_get_leave (v) ? 0.0 : SYSMIS;
if (!var_get_leave (v))
{
if (var_is_numeric (v))
- case_data_rw (c, v->fv)->f = SYSMIS;
+ case_data_rw (c, v)->f = SYSMIS;
else
- memset (case_data_rw (c, v->fv)->s, ' ', var_get_width (v));
+ memset (case_data_rw (c, v)->s, ' ', var_get_width (v));
}
}
}
{
struct variable *filter_var = filter_var_;
- double f = case_num (c, filter_var->fv);
+ double f = case_num (c, filter_var);
return (f != 0.0 && !var_is_num_missing (filter_var, f)
? TRNS_CONTINUE : TRNS_DROP_CASE);
}
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include <config.h>
+#include "sys-file-private.h"
+
+#include <data/value.h>
+#include <libpspp/assertion.h>
+
+/* Return the number of bytes used when writing case_data for a variable
+ of WIDTH */
+int
+sfm_width_to_bytes (int width)
+{
+ assert (width >= 0);
+
+ if (width == 0)
+ return MAX_SHORT_STRING;
+ else if (width < MIN_VERY_LONG_STRING)
+ return ROUND_UP (width, MAX_SHORT_STRING);
+ else
+ {
+ int chunks = width / EFFECTIVE_LONG_STRING_LENGTH ;
+ int remainder = width % EFFECTIVE_LONG_STRING_LENGTH ;
+ int bytes = remainder + (chunks * MIN_VERY_LONG_STRING);
+ return ROUND_UP (bytes, MAX_SHORT_STRING);
+ }
+}
+
+
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ Written by Ben Pfaff <blp@gnu.org>.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#ifndef DATA_SYS_FILE_PRIVATE_H
+#define DATA_SYS_FILE_PRIVATE_H 1
+
+/* This nonsense is required for SPSS compatibility. */
+
+#define MIN_VERY_LONG_STRING 256
+#define EFFECTIVE_LONG_STRING_LENGTH (MIN_VERY_LONG_STRING - 4)
+
+int sfm_width_to_bytes (int width);
+
+#endif /* data/sys-file-private.h */
#include <config.h>
+#include "sys-file-reader.h"
+#include "sfm-private.h"
+#include "sys-file-private.h"
+
#include <stdlib.h>
#include <errno.h>
#include <float.h>
#include <libpspp/hash.h>
#include <libpspp/array.h>
-#include "sys-file-reader.h"
-#include "sfm-private.h"
#include "case.h"
#include "dictionary.h"
#include "file-handle-def.h"
#include "file-name.h"
#include "format.h"
+#include "missing-values.h"
#include "value-labels.h"
-#include "variable.h"
#include "value.h"
+#include "variable.h"
#include "gettext.h"
#define _(msgid) gettext (msgid)
}
/* Identify any duplicates. */
- if ( compare_var_names(short_name, long_name, 0) &&
+ if ( strcasecmp (short_name, long_name) &&
NULL != dict_lookup_var (*dict, long_name))
lose ((ME, _("%s: Duplicate long variable name `%s' "
"within system file."),
else
l -= var_get_width (v);
- idx = v->index;
+ idx = var_get_dict_index (v);
while ( l > 0 )
{
struct variable *v_next;
dict_delete_var(*dict, v_next);
}
- assert ( length > MAX_LONG_STRING );
+ assert ( length >= MIN_VERY_LONG_STRING );
var_set_width (v, length);
}
struct variable *v = dict_get_var (*dict, i);
struct sfm_var *sv = &r->vars[i];
sv->width = var_get_width (v);
- sv->fv = v->fv;
+ sv->fv = var_get_case_index (v);
}
}
for (j = 0; j < n_labels; j++)
{
struct label *label = labels + j;
- if (!val_labs_replace (v->val_labs, label->value, label->label))
+ if (var_add_value_label (v, &label->value, label->label))
continue;
if (var_is_numeric (var[0]))
for (i = 0; i < r->var_cnt; i++)
if (r->vars[i].width == 0)
- bswap_flt64 (&case_data_rw (c, r->vars[i].fv)->f);
+ bswap_flt64 (&case_data_rw_idx (c, r->vars[i].fv)->f);
}
/* Fix up SYSMIS values if needed.
int i;
for (i = 0; i < r->var_cnt; i++)
- if (r->vars[i].width == 0 && case_num (c, i) == r->sysmis)
- case_data_rw (c, r->vars[i].fv)->f = SYSMIS;
+ if (r->vars[i].width == 0 && case_num_idx (c, i) == r->sysmis)
+ case_data_rw_idx (c, r->vars[i].fv)->f = SYSMIS;
}
}
else
flt64 f = *bounce_cur++;
if (r->reverse_endian)
bswap_flt64 (&f);
- case_data_rw (c, sv->fv)->f = f == r->sysmis ? SYSMIS : f;
+ case_data_rw_idx (c, sv->fv)->f = f == r->sysmis ? SYSMIS : f;
}
else
{
int ofs = 0;
while (ofs < sv->width )
{
- const int chunk = MIN (MAX_LONG_STRING, sv->width - ofs);
- memcpy (case_data_rw (c, sv->fv)->s + ofs, bounce_cur, chunk);
+ const int chunk = MIN (MIN_VERY_LONG_STRING - 1,
+ sv->width - ofs);
+ memcpy (case_data_rw_idx (c, sv->fv)->s + ofs,
+ bounce_cur, chunk);
bounce_cur += DIV_RND_UP (chunk, sizeof (flt64));
ofs += chunk;
}
- bounce_cur = bc_start + width_to_bytes(sv->width) / sizeof(flt64);
+ bounce_cur = bc_start + sfm_width_to_bytes (sv->width) / sizeof(flt64);
}
}
#include "sys-file-writer.h"
#include "sfm-private.h"
+#include "sys-file-private.h"
#include <ctype.h>
#include <errno.h>
#include "case.h"
#include "dictionary.h"
#include "file-handle-def.h"
+#include "format.h"
+#include "missing-values.h"
#include "settings.h"
#include "value-labels.h"
#include "variable.h"
var_flt64_cnt (const struct variable *v)
{
assert(sizeof(flt64) == MAX_SHORT_STRING);
- return width_to_bytes(var_get_width (v)) / MAX_SHORT_STRING ;
+ return sfm_width_to_bytes(var_get_width (v)) / MAX_SHORT_STRING ;
}
static inline int
struct sfm_var *sv = &w->vars[i];
sv->width = var_get_width (dv);
/* spss compatibility nonsense */
- if ( var_is_very_long_string (dv) )
+ if ( var_get_width (dv) >= MIN_VERY_LONG_STRING )
w->has_vls = true;
- sv->fv = dv->fv;
+ sv->fv = var_get_case_index (dv);
sv->flt64_cnt = var_flt64_cnt (dv);
}
int wcount = var_get_width (v);
do {
- struct variable var_cont = *v;
+ struct variable *var_cont = var_clone (v);
+ var_set_short_name (var_cont, var_get_short_name (v));
if ( var_is_alpha (v))
{
if ( 0 != count )
{
- var_clear_missing_values (&var_cont);
- var_set_short_name (&var_cont,
+ var_clear_missing_values (var_cont);
+ var_set_short_name (var_cont,
cont_var_name (var_get_short_name (v),
count));
- var_clear_label (&var_cont);
+ var_clear_label (var_cont);
w->var_cnt_vls++;
}
count++;
- if ( wcount > MAX_LONG_STRING )
+ if ( wcount >= MIN_VERY_LONG_STRING )
{
- var_set_width (&var_cont, MAX_LONG_STRING);
+ var_set_width (var_cont, MIN_VERY_LONG_STRING - 1);
wcount -= EFFECTIVE_LONG_STRING_LENGTH;
}
else
{
- var_set_width (&var_cont, wcount);
- wcount -= var_get_width (&var_cont);
+ var_set_width (var_cont, wcount);
+ wcount -= var_get_width (var_cont);
}
}
- write_variable (w, &var_cont);
+ write_variable (w, var_cont);
+ var_destroy (var_cont);
} while(wcount > 0);
}
const char *label = var_get_label (v);
sv.rec_type = 2;
- sv.type = MIN(var_get_width (v), MAX_LONG_STRING);
+ sv.type = MIN (var_get_width (v), MIN_VERY_LONG_STRING - 1);
sv.has_var_label = label != NULL;
mv_copy (&mv, var_get_missing_values (v));
memset (&sv.write, 0, sizeof sv.write);
memset (&sv.name, 0, sizeof sv.name);
- pad_count = DIV_RND_UP (MIN(var_get_width (v), MAX_LONG_STRING),
+ pad_count = DIV_RND_UP (MIN(var_get_width (v), MIN_VERY_LONG_STRING - 1),
(int) sizeof (flt64)) - 1;
for (i = 0; i < pad_count; i++)
buf_write (w, &sv, sizeof sv);
int32_t vars[1] ;
} ATTRIBUTE((packed));
+ const struct val_labs *val_labs;
struct val_labs_iterator *i;
struct value_label_rec *vlr;
struct var_idx_rec vir;
size_t vlr_size;
flt64 *loc;
- if (!val_labs_count (v->val_labs))
+ val_labs = var_get_value_labels (v);
+ if (val_labs == NULL)
return;
/* Pass 1: Count bytes. */
vlr_size = (sizeof (struct value_label_rec)
- + sizeof (flt64) * (val_labs_count (v->val_labs) - 1));
- for (vl = val_labs_first (v->val_labs, &i); vl != NULL;
- vl = val_labs_next (v->val_labs, &i))
+ + sizeof (flt64) * (val_labs_count (val_labs) - 1));
+ for (vl = val_labs_first (val_labs, &i); vl != NULL;
+ vl = val_labs_next (val_labs, &i))
vlr_size += ROUND_UP (strlen (vl->label) + 1, sizeof (flt64));
/* Pass 2: Copy bytes. */
vlr = xmalloc (vlr_size);
vlr->rec_type = 3;
- vlr->n_labels = val_labs_count (v->val_labs);
+ vlr->n_labels = val_labs_count (val_labs);
loc = vlr->labels;
- for (vl = val_labs_first_sorted (v->val_labs, &i); vl != NULL;
- vl = val_labs_next (v->val_labs, &i))
+ for (vl = val_labs_first_sorted (val_labs, &i); vl != NULL;
+ vl = val_labs_next (val_labs, &i))
{
size_t len = strlen (vl->label);
while (wcount > 0)
{
- params.width = wcount > MAX_LONG_STRING ? 32 : wcount;
+ params.width = wcount >= MIN_VERY_LONG_STRING ? 32 : wcount;
buf_write (w, ¶ms, sizeof(params));
{
const struct variable *v = dict_get_var (dict, i);
- if ( var_get_width (v) <= MAX_LONG_STRING )
+ if ( var_get_width (v) < MIN_VERY_LONG_STRING )
continue;
ds_put_format (&vls_length_map, "%s=%05d",
if (v->width == 0)
{
- *bounce_cur = case_num (c, v->fv);
+ *bounce_cur = case_num_idx (c, v->fv);
bounce_cur += v->flt64_cnt;
}
else
{ int ofs = 0;
while (ofs < v->width)
{
- int chunk = MIN (MAX_LONG_STRING, v->width - ofs);
+ int chunk = MIN (MIN_VERY_LONG_STRING - 1, v->width - ofs);
int nv = DIV_RND_UP (chunk, sizeof (flt64));
buf_copy_rpad ((char *) bounce_cur, nv * sizeof (flt64),
- case_data (c, v->fv)->s + ofs, chunk);
+ case_data_idx (c, v->fv)->s + ofs, chunk);
bounce_cur += nv;
ofs += chunk;
}
#include <stdlib.h>
#include <data/data-out.h>
+#include <data/format.h>
+#include <data/value.h>
#include <data/variable.h>
#include <libpspp/alloc.h>
#include <libpspp/compiler.h>
struct val_labs_iterator *i;
struct val_lab *vl;
- assert (vls != NULL);
+ if (vls == NULL)
+ return NULL;
copy = val_labs_create (vls->width);
for (vl = val_labs_first (vls, &i); vl != NULL;
size_t
val_labs_count (const struct val_labs *vls)
{
- assert (vls != NULL);
-
- if (vls->labels == NULL)
- return 0;
- else
- return hsh_count (vls->labels);
+ return vls == NULL || vls->labels == NULL ? 0 : hsh_count (vls->labels);
}
\f
/* One value label in internal format. */
if there wasn't already a value label for VALUE, or true if
there was. Behavior is undefined if VLS's width is greater
than MAX_SHORT_STRING. */
-bool
+void
val_labs_replace (struct val_labs *vls, union value value, const char *label)
{
- struct int_val_lab *ivl;
-
- assert (vls != NULL);
assert (vls->width <= MAX_SHORT_STRING);
- assert (label != NULL);
-
- if (vls->labels == NULL)
+ if (vls->labels != NULL)
{
- val_labs_add (vls, value, label);
- return false;
+ struct int_val_lab *new = create_int_val_lab (vls, value, label);
+ struct int_val_lab *old = hsh_replace (vls->labels, new);
+ if (old != NULL)
+ free_int_val_lab (old, vls);
}
-
- ivl = hsh_replace (vls->labels, create_int_val_lab (vls, value, label));
- if (ivl == NULL)
- return false;
else
- {
- free_int_val_lab (ivl, vls);
- return true;
- }
+ val_labs_add (vls, value, label);
}
/* Removes any value label for VALUE within VLS. Returns true
char *
val_labs_find (const struct val_labs *vls, union value value)
{
- assert (vls != NULL);
-
- if (vls->width > MAX_SHORT_STRING)
- return NULL;
-
- if (vls->labels != NULL)
+ if (vls != NULL
+ && vls->width <= MAX_SHORT_STRING
+ && vls->labels != NULL)
{
struct int_val_lab ivl, *vlp;
free (atom->string);
free (atom);
}
-
-
-/* Get a string representing the value.
- That is, if it has a label, then return that label,
- otherwise, if the value is alpha, then return the string for it,
- else format it and return the formatted string
-*/
-const char *
-value_to_string (const union value *val, const struct variable *var)
-{
- char *s;
-
- assert (val != NULL);
- assert (var != NULL);
-
- s = val_labs_find (var->val_labs, *val);
- if (s == NULL)
- {
- static char buf[MAX_STRING + 1];
- const struct fmt_spec *print = var_get_print_format (var);
- data_out (val, print, buf);
- buf[print->w] = '\0';
- s = buf;
- }
-
- return s;
-}
void val_labs_set_width (struct val_labs *, int new_width);
bool val_labs_add (struct val_labs *, union value, const char *);
-bool val_labs_replace (struct val_labs *, union value, const char *);
+void val_labs_replace (struct val_labs *, union value, const char *);
bool val_labs_remove (struct val_labs *, union value);
char *val_labs_find (const struct val_labs *, union value);
struct val_labs_iterator **);
void val_labs_done (struct val_labs_iterator **);
-/* Return a string representing this value, in the form most
- appropriate from a human factors perspective.
- (IE: the label if it has one, otherwise the alpha/numeric )
-*/
-const char *value_to_string(const union value *, const struct variable *);
-
#endif /* value-labels.h */
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+ Written by Ben Pfaff <blp@gnu.org>.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include <config.h>
+#include "value.h"
+
+#include <libpspp/hash.h>
+#include <libpspp/str.h>
+
+#include "xalloc.h"
+
+/* Duplicate a value.
+ The caller is responsible for freeing the returned value. */
+union value *
+value_dup (const union value *val, int width)
+{
+ return xmemdup (val, MAX (width, sizeof *val));
+}
+
+/* Compares A and B, which both have the given WIDTH, and returns
+ a strcmp()-type result.
+ Only the short string portion of longer strings are
+ compared. */
+int
+compare_values (const union value *a, const union value *b, int width)
+{
+ return (width == 0
+ ? (a->f < b->f ? -1 : a->f > b->f)
+ : memcmp (a->s, b->s, MIN (MAX_SHORT_STRING, width)));
+}
+
+/* Create a hash of V, which has the given WIDTH.
+ Only the short string portion of a longer string is hashed. */
+unsigned
+hash_value (const union value *v, int width)
+{
+ return (width == 0
+ ? hsh_hash_double (v->f)
+ : hsh_hash_bytes (v->s, MIN (MAX_SHORT_STRING, width)));
+}
#define value_h 1
#include <float.h>
-
-#include <config.h>
+#include <libpspp/misc.h>
+#include "minmax.h"
/* Values. */
-/* Max length of a short string value, generally 8 chars. */
-#define MAX_SHORT_STRING ( (SIZEOF_DOUBLE)>=8 ? (SIZEOF_DOUBLE + 1)/2 * 2 : 8 )
-
+/* "Short" strings, which are generally those no more than 8
+ characters wide, can participate in more operations than
+ longer strings. */
+#define MAX_SHORT_STRING (MAX (ROUND_UP (SIZEOF_DOUBLE, 2), 8))
#define MIN_LONG_STRING (MAX_SHORT_STRING + 1)
-
-/* Max string length. */
-#define MAX_LONG_STRING 255
-
-/* This nonsense is required for SPSS compatibility */
-#define EFFECTIVE_LONG_STRING_LENGTH (MAX_LONG_STRING - 3)
-
-#define MAX_VERY_LONG_STRING 32767
-
-#define MAX_STRING MAX_VERY_LONG_STRING
-
+#define MAX_STRING 32767
/* Special values. */
#define SYSMIS (-DBL_MAX)
char s[MAX_SHORT_STRING];
};
-/* Maximum number of `union value's in a single number or string
- value. */
-#define MAX_ELEMS_PER_VALUE (MAX_STRING / sizeof (union value) + 1)
-
-int compare_values (const union value *a, const union value *b, int width);
-
-unsigned hash_value(const union value *v, int width);
-
-
+union value *value_dup (const union value *, int width);
+int compare_values (const union value *, const union value *, int width);
+unsigned hash_value (const union value *, int width);
#endif /* !value.h */
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+ Written by Ben Pfaff <blp@gnu.org>.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#ifndef DATA_VARDICT_H
+#define DATA_VARDICT_H 1
+
+/* Interface between dictionary and variable code.
+ This header file should only be included by variable.c and
+ dictionary.c. */
+
+/* Dictionary data stored in variable. */
+struct vardict_info
+ {
+ int dict_index; /* Dictionary index containing the variable. */
+ int case_index; /* Index into case of variable data. */
+ };
+
+const struct vardict_info *var_get_vardict (const struct variable *);
+void var_set_vardict (struct variable *, const struct vardict_info *);
+bool var_has_vardict (const struct variable *);
+void var_clear_vardict (struct variable *);
+
+#endif /* data/vardict.h */
#include <config.h>
#include "variable.h"
-#include <libpspp/assertion.h>
-#include <libpspp/message.h>
+
#include <stdlib.h>
+
+#include "cat-routines.h"
+#include "category.h"
+#include "data-out.h"
+#include "dictionary.h"
+#include "format.h"
+#include "identifier.h"
+#include "missing-values.h"
+#include "value.h"
+#include "value-labels.h"
+#include "vardict.h"
+
#include <libpspp/alloc.h>
+#include <libpspp/assertion.h>
#include <libpspp/compiler.h>
-#include "dictionary.h"
#include <libpspp/hash.h>
-#include "identifier.h"
+#include <libpspp/message.h>
#include <libpspp/misc.h>
#include <libpspp/str.h>
-#include "value-labels.h"
#include "minmax.h"
#include "gettext.h"
#define _(msgid) gettext (msgid)
+/* A variable. */
+struct variable
+ {
+ /* Dictionary information. */
+ char name[LONG_NAME_LEN + 1]; /* Variable name. Mixed case. */
+ int width; /* 0 for numeric, otherwise string width. */
+ struct missing_values miss; /* Missing values. */
+ struct fmt_spec print; /* Default format for PRINT. */
+ struct fmt_spec write; /* Default format for WRITE. */
+ struct val_labs *val_labs; /* Value labels. */
+ char *label; /* Variable label. */
+
+ /* GUI information. */
+ enum measure measure; /* Nominal, ordinal, or continuous. */
+ int display_width; /* Width of data editor column. */
+ enum alignment alignment; /* Alignment of data in GUI. */
+
+ /* Case information. */
+ bool leave; /* Leave value from case to case? */
+
+ /* Data for use by containing dictionary. */
+ struct vardict_info vardict;
+
+ /* Short name, used only for system and portable file input
+ and output. Upper case only. There is no index for short
+ names. Short names are not necessarily unique. Any
+ variable may have no short name, indicated by an empty
+ string. */
+ char short_name[SHORT_NAME_LEN + 1];
+
+ /* Each command may use these fields as needed. */
+ void *aux;
+ void (*aux_dtor) (struct variable *);
+
+ /* Values of a categorical variable. Procedures need
+ vectors with binary entries, so any variable of type ALPHA will
+ have its values stored here. */
+ struct cat_vals *obs_vals;
+ };
+
/* Returns true if VAR_TYPE is a valid variable type. */
bool
var_type_is_valid (enum var_type var_type)
{
- return var_type == NUMERIC || var_type == ALPHA;
-}
-
-/* Returns an adjective describing the given variable TYPE,
- suitable for use in phrases like "numeric variable". */
-const char *
-var_type_adj (enum var_type type)
-{
- return type == NUMERIC ? _("numeric") : _("string");
+ return var_type == VAR_NUMERIC || var_type == VAR_STRING;
}
-/* Returns a noun describing a value of the given variable TYPE,
- suitable for use in phrases like "a number". */
-const char *
-var_type_noun (enum var_type type)
-{
- return type == NUMERIC ? _("number") : _("string");
-}
-\f
-/* Returns true if M is a valid variable measurement level,
- false otherwise. */
-bool
-measure_is_valid (enum measure m)
-{
- return m == MEASURE_NOMINAL || m == MEASURE_ORDINAL || m == MEASURE_SCALE;
-}
-
-/* Returns true if A is a valid alignment,
- false otherwise. */
-bool
-alignment_is_valid (enum alignment a)
+/* Returns the variable type for the given width. */
+enum var_type
+var_type_from_width (int width)
{
- return a == ALIGN_LEFT || a == ALIGN_RIGHT || a == ALIGN_CENTRE;
+ return width != 0 ? VAR_STRING : VAR_NUMERIC;
}
\f
-/* Assign auxiliary data AUX to variable V, which must not
- already have auxiliary data. Before V's auxiliary data is
- cleared, AUX_DTOR(V) will be called. */
-void *
-var_attach_aux (struct variable *v,
- void *aux, void (*aux_dtor) (struct variable *))
-{
- assert (v->aux == NULL);
- assert (aux != NULL);
- v->aux = aux;
- v->aux_dtor = aux_dtor;
- return aux;
-}
-
-/* Remove auxiliary data, if any, from V, and returns it, without
- calling any associated destructor. */
-void *
-var_detach_aux (struct variable *v)
-{
- void *aux = v->aux;
- assert (aux != NULL);
- v->aux = NULL;
- return aux;
-}
-
-/* Clears auxiliary data, if any, from V, and calls any
- associated destructor. */
-void
-var_clear_aux (struct variable *v)
-{
- assert (v != NULL);
- if (v->aux != NULL)
+/* Creates and returns a new variable with the given NAME and
+ WIDTH and other fields initialized to default values. The
+ variable is not added to a dictionary; for that, use
+ dict_create_var instead. */
+struct variable *
+var_create (const char *name, int width)
+{
+ struct variable *v;
+
+ assert (width >= 0 && width <= MAX_STRING);
+
+ v = xmalloc (sizeof *v);
+ v->vardict.dict_index = v->vardict.case_index = -1;
+ var_set_name (v, name);
+ v->width = width;
+ mv_init (&v->miss, width);
+ v->leave = var_must_leave (v);
+ if (var_is_numeric (v))
{
- if (v->aux_dtor != NULL)
- v->aux_dtor (v);
- v->aux = NULL;
+ v->print = fmt_for_output (FMT_F, 8, 2);
+ v->alignment = ALIGN_RIGHT;
+ v->display_width = 8;
+ v->measure = MEASURE_SCALE;
}
-}
-
-/* This function is appropriate for use an auxiliary data
- destructor (passed as AUX_DTOR to var_attach_aux()) for the
- case where the auxiliary data should be passed to free(). */
-void
-var_dtor_free (struct variable *v)
-{
- free (v->aux);
-}
-
-/* Duplicate a value.
- The caller is responsible for freeing the returned value
-*/
-union value *
-value_dup (const union value *val, int width)
-{
- size_t bytes = MAX(width, sizeof *val);
+ else
+ {
+ v->print = fmt_for_output (FMT_A, var_get_width (v), 0);
+ v->alignment = ALIGN_LEFT;
+ v->display_width = 8;
+ v->measure = MEASURE_NOMINAL;
+ }
+ v->write = v->print;
+ v->val_labs = NULL;
+ v->label = NULL;
+ var_clear_short_name (v);
+ v->aux = NULL;
+ v->aux_dtor = NULL;
+ v->obs_vals = NULL;
- union value *v = xmalloc (bytes);
- memcpy (v, val, bytes);
return v;
}
+/* Creates and returns a clone of OLD_VAR. Most properties of
+ the new variable are copied from OLD_VAR, except:
+ - The variable's short name is not copied, because there is
+ no reason to give a new variable with potentially a new
+ name the same short name.
-/* Compares A and B, which both have the given WIDTH, and returns
- a strcmp()-type result. */
-int
-compare_values (const union value *a, const union value *b, int width)
-{
- if (width == 0)
- return a->f < b->f ? -1 : a->f > b->f;
- else
- return memcmp (a->s, b->s, MIN(MAX_SHORT_STRING, width));
-}
+ - The new variable is not added to OLD_VAR's dictionary by
+ default. Use dict_clone_var, instead, to do that.
-/* Create a hash of v */
-unsigned
-hash_value(const union value *v, int width)
+ - Auxiliary data and obs_vals are not copied. */
+struct variable *
+var_clone (const struct variable *old_var)
{
- unsigned id_hash;
+ struct variable *new_var = var_create (var_get_name (old_var),
+ var_get_width (old_var));
- if ( 0 == width )
- id_hash = hsh_hash_double (v->f);
- else
- id_hash = hsh_hash_bytes (v->s, MIN(MAX_SHORT_STRING, width));
+ var_set_missing_values (new_var, var_get_missing_values (old_var));
+ var_set_print_format (new_var, var_get_print_format (old_var));
+ var_set_write_format (new_var, var_get_write_format (old_var));
+ var_set_value_labels (new_var, var_get_value_labels (old_var));
+ var_set_label (new_var, var_get_label (old_var));
+ var_set_measure (new_var, var_get_measure (old_var));
+ var_set_display_width (new_var, var_get_display_width (old_var));
+ var_set_alignment (new_var, var_get_alignment (old_var));
+ var_set_leave (new_var, var_get_leave (old_var));
- return id_hash;
+ return new_var;
+}
+
+/* Destroys variable V.
+ V must not belong to a dictionary. If it does, use
+ dict_delete_var instead. */
+void
+var_destroy (struct variable *v)
+{
+ if (v != NULL)
+ {
+ assert (!var_has_vardict (v));
+ cat_stored_values_destroy (v->obs_vals);
+ var_clear_aux (v);
+ val_labs_destroy (v->val_labs);
+ var_clear_label (v);
+ free (v);
+ }
}
\f
+/* Variable names. */
+
/* Return variable V's name. */
const char *
var_get_name (const struct variable *v)
return v->name;
}
-/* Sets V's name to NAME. */
+/* Sets V's name to NAME.
+ Do not use this function for a variable in a dictionary. Use
+ dict_rename_var instead. */
void
var_set_name (struct variable *v, const char *name)
{
- assert (name[0] != '\0');
- assert (lex_id_to_token (ss_cstr (name)) == T_ID);
+ assert (v->vardict.dict_index == -1);
+ assert (var_is_plausible_name (name, false));
str_copy_trunc (v->name, sizeof v->name, name);
}
return true;
}
-/*
- Returns true if NAME is an plausible name for a variable,
+/* Returns true if NAME is an plausible name for a variable,
false otherwise. If ISSUE_ERROR is true, issues an
explanatory error message on failure.
This function makes no use of LC_CTYPE.
/* A hsh_compare_func that orders variables A and B by their
names. */
int
-compare_var_names (const void *a_, const void *b_, const void *aux UNUSED)
+compare_vars_by_name (const void *a_, const void *b_, const void *aux UNUSED)
{
const struct variable *a = a_;
const struct variable *b = b_;
- return strcasecmp (var_get_name (a), var_get_name (b));
+ return strcasecmp (a->name, b->name);
}
/* A hsh_hash_func that hashes variable V based on its name. */
unsigned
-hash_var_name (const void *v_, const void *aux UNUSED)
+hash_var_by_name (const void *v_, const void *aux UNUSED)
{
const struct variable *v = v_;
- return hsh_hash_case_string (var_get_name (v));
+ return hsh_hash_case_string (v->name);
}
/* A hsh_compare_func that orders pointers to variables A and B
by their names. */
int
-compare_var_ptr_names (const void *a_, const void *b_, const void *aux UNUSED)
+compare_var_ptrs_by_name (const void *a_, const void *b_,
+ const void *aux UNUSED)
{
struct variable *const *a = a_;
struct variable *const *b = b_;
/* A hsh_hash_func that hashes pointer to variable V based on its
name. */
unsigned
-hash_var_ptr_name (const void *v_, const void *aux UNUSED)
+hash_var_ptr_by_name (const void *v_, const void *aux UNUSED)
{
struct variable *const *v = v_;
return hsh_hash_case_string (var_get_name (*v));
}
\f
-/* Returns the type of a variable with the given WIDTH. */
-static enum var_type
-width_to_type (int width)
-{
- return width == 0 ? NUMERIC : ALPHA;
-}
-
/* Returns the type of variable V. */
enum var_type
var_get_type (const struct variable *v)
{
- return width_to_type (v->width);
+ return var_type_from_width (v->width);
}
/* Returns the width of variable V. */
void
var_set_width (struct variable *v, int new_width)
{
- enum var_type new_type = width_to_type (new_width);
+ enum var_type new_type = var_type_from_width (new_width);
if (mv_is_resizable (&v->miss, new_width))
mv_resize (&v->miss, new_width);
if (var_get_type (v) != new_type)
{
- v->print = (new_type == NUMERIC
+ v->print = (new_type == VAR_NUMERIC
? fmt_for_output (FMT_F, 8, 2)
: fmt_for_output (FMT_A, new_width, 0));
v->write = v->print;
}
- else if (new_type == ALPHA)
+ else if (new_type == VAR_STRING)
{
v->print.w = v->print.type == FMT_AHEX ? new_width * 2 : new_width;
v->write.w = v->write.type == FMT_AHEX ? new_width * 2 : new_width;
bool
var_is_numeric (const struct variable *v)
{
- return var_get_type (v) == NUMERIC;
+ return var_get_type (v) == VAR_NUMERIC;
}
/* Returns true if variable V is a string variable, false
bool
var_is_alpha (const struct variable *v)
{
- return var_get_type (v) == ALPHA;
+ return var_get_type (v) == VAR_STRING;
}
/* Returns true if variable V is a short string variable, false
return v->width > MAX_SHORT_STRING;
}
-/* Returns true if variable V is a very long string variable,
- false otherwise. */
-bool
-var_is_very_long_string (const struct variable *v)
+/* Returns the number of "union value"s need to store a value of
+ variable V. */
+size_t
+var_get_value_cnt (const struct variable *v)
{
- return v->width > MAX_LONG_STRING;
+ return v->width == 0 ? 1 : DIV_RND_UP (v->width, MAX_SHORT_STRING);
}
-
+\f
/* Returns variable V's missing values. */
const struct missing_values *
var_get_missing_values (const struct variable *v)
return &v->miss;
}
-/* Sets variable V's missing values to MISS, which must be of the
- correct width. */
+/* Sets variable V's missing values to MISS, which must be of V's
+ width or at least resizable to V's width.
+ If MISS is null, then V's missing values, if any, are
+ cleared. */
void
var_set_missing_values (struct variable *v, const struct missing_values *miss)
{
if (miss != NULL)
{
- assert (v->width == mv_get_width (miss));
+ assert (mv_is_resizable (miss, v->width));
mv_copy (&v->miss, miss);
+ mv_resize (&v->miss, v->width);
}
else
mv_init (&v->miss, v->width);
return mv_is_value_system_missing (&v->miss, value);
}
\f
+/* Returns variable V's value labels,
+ possibly a null pointer if it has none. */
+const struct val_labs *
+var_get_value_labels (const struct variable *v)
+{
+ return v->val_labs;
+}
+
+/* Returns true if variable V has at least one value label. */
+bool
+var_has_value_labels (const struct variable *v)
+{
+ return val_labs_count (v->val_labs) > 0;
+}
+
+/* Sets variable V's value labels to a copy of VLS,
+ which must have a width equal to V's width or one that can be
+ changed to V's width.
+ If VLS is null, then V's value labels, if any, are removed. */
+void
+var_set_value_labels (struct variable *v, const struct val_labs *vls)
+{
+ val_labs_destroy (v->val_labs);
+ v->val_labs = NULL;
+
+ if (vls != NULL)
+ {
+ assert (val_labs_can_set_width (vls, v->width));
+ v->val_labs = val_labs_copy (vls);
+ val_labs_set_width (v->val_labs, v->width);
+ }
+}
+
+/* Makes sure that V has a set of value labels,
+ by assigning one to it if necessary. */
+static void
+alloc_value_labels (struct variable *v)
+{
+ assert (!var_is_long_string (v));
+ if (v->val_labs == NULL)
+ v->val_labs = val_labs_create (v->width);
+}
+
+/* Attempts to add a value label with the given VALUE and LABEL
+ to V. Returns true if successful, false if VALUE has an
+ existing label.
+ V must not be a long string variable. */
+bool
+var_add_value_label (struct variable *v,
+ const union value *value, const char *label)
+{
+ alloc_value_labels (v);
+ return val_labs_add (v->val_labs, *value, label);
+}
+
+/* Adds or replaces a value label with the given VALUE and LABEL
+ to V.
+ V must not be a long string variable. */
+void
+var_replace_value_label (struct variable *v,
+ const union value *value, const char *label)
+{
+ alloc_value_labels (v);
+ val_labs_replace (v->val_labs, *value, label);
+}
+
+/* Removes V's value labels, if any. */
+void
+var_clear_value_labels (struct variable *v)
+{
+ var_set_value_labels (v, NULL);
+}
+
+/* Returns the label associated with VALUE for variable V,
+ or a null pointer if none. */
+const char *
+var_lookup_value_label (const struct variable *v, const union value *value)
+{
+ return val_labs_find (v->val_labs, *value);
+}
+
+/* Get a string representing VALUE for variable V.
+ That is, if VALUE has a label, return that label,
+ otherwise format VALUE and return the formatted string. */
+const char *
+var_get_value_name (const struct variable *v, const union value *value)
+{
+ const char *name = var_lookup_value_label (v, value);
+ if (name == NULL)
+ {
+ static char buf[MAX_STRING + 1];
+ data_out (value, &v->print, buf);
+ buf[v->print.w] = '\0';
+ name = buf;
+ }
+ return name;
+}
+\f
/* Print and write formats. */
/* Returns V's print format specification. */
var_set_write_format (v, format);
}
\f
+/* Return a string representing this variable, in the form most
+ appropriate from a human factors perspective, that is, its
+ variable label if it has one, otherwise its name. */
+const char *
+var_to_string (const struct variable *v)
+{
+ return v->label != NULL ? v->label : v->name;
+}
+
/* Returns V's variable label, or a null pointer if it has none. */
const char *
var_get_label (const struct variable *v)
return v->label != NULL;
}
\f
+/* Returns true if M is a valid variable measurement level,
+ false otherwise. */
+bool
+measure_is_valid (enum measure m)
+{
+ return m == MEASURE_NOMINAL || m == MEASURE_ORDINAL || m == MEASURE_SCALE;
+}
+
/* Returns V's measurement level. */
enum measure
var_get_measure (const struct variable *v)
assert (measure_is_valid (measure));
v->measure = measure;
}
-
+\f
/* Returns V's display width, which applies only to GUIs. */
int
var_get_display_width (const struct variable *v)
{
v->display_width = display_width;
}
+\f
+/* Returns true if A is a valid alignment,
+ false otherwise. */
+bool
+alignment_is_valid (enum alignment a)
+{
+ return a == ALIGN_LEFT || a == ALIGN_RIGHT || a == ALIGN_CENTRE;
+}
/* Returns V's display alignment, which applies only to GUIs. */
enum alignment
v->alignment = alignment;
}
\f
-/* Returns the number of "union value"s need to store a value of
- variable V. */
-size_t
-var_get_value_cnt (const struct variable *v)
-{
- return v->width == 0 ? 1 : DIV_RND_UP (v->width, MAX_SHORT_STRING);
-}
+/* Whether variables' values should be preserved from case to
+ case. */
-/* Return whether variable V's values should be preserved from
- case to case. */
+/* Returns true if variable V's value should be left from case to
+ case, instead of being reset to 0, system-missing, or blanks. */
bool
var_get_leave (const struct variable *v)
{
return v->leave;
}
+
+/* Sets V's leave setting to LEAVE. */
+void
+var_set_leave (struct variable *v, bool leave)
+{
+ assert (leave || !var_must_leave (v));
+ v->leave = leave;
+}
+
+/* Returns true if V must be left from case to case,
+ false if it can be set either way. */
+bool
+var_must_leave (const struct variable *v)
+{
+ return dict_class_from_id (v->name) == DC_SCRATCH;
+}
\f
/* Returns V's short name, if it has one, or a null pointer
otherwise.
v->short_name[0] = '\0';
}
+\f
+/* Relationship with dictionary. */
-/* 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. */
-void
-var_set_short_name_suffix (struct variable *v, const char *base,
- int suffix_number)
+/* Returns V's index within its dictionary, the value
+ for which "dict_get_var (dict, index)" will return V.
+ V must be in a dictionary. */
+size_t
+var_get_dict_index (const struct variable *v)
{
- char suffix[SHORT_NAME_LEN + 1];
- char short_name[SHORT_NAME_LEN + 1];
- char *start, *end;
- int len, ofs;
+ assert (v->vardict.dict_index != -1);
+ return v->vardict.dict_index;
+}
- assert (v != NULL);
- assert (suffix_number >= 0);
+/* Returns V's index within the case represented by its
+ dictionary, that is, the value for which "case_data_idx (case,
+ index)" will return the data for V in that case.
+ V must be in a dictionary. */
+size_t
+var_get_case_index (const struct variable *v)
+{
+ assert (v->vardict.case_index != -1);
+ return v->vardict.case_index;
+}
+\f
+/* Returns V's auxiliary data, or a null pointer if none has been
+ attached. */
+void *
+var_get_aux (const struct variable *v)
+{
+ return v->aux;
+}
+
+/* Assign auxiliary data AUX to variable V, which must not
+ already have auxiliary data. Before V's auxiliary data is
+ cleared, AUX_DTOR(V) will be called. (var_dtor_free, below,
+ may be appropriate for use as AUX_DTOR.) */
+void *
+var_attach_aux (struct variable *v,
+ void *aux, void (*aux_dtor) (struct variable *))
+{
+ assert (v->aux == NULL);
+ assert (aux != NULL);
+ v->aux = aux;
+ v->aux_dtor = aux_dtor;
+ return aux;
+}
- /* Set base name. */
- var_set_short_name (v, base);
+/* Remove auxiliary data, if any, from V, and return it, without
+ calling any associated destructor. */
+void *
+var_detach_aux (struct variable *v)
+{
+ void *aux = v->aux;
+ assert (aux != NULL);
+ v->aux = NULL;
+ return aux;
+}
- /* Compose suffix. */
- start = end = suffix + sizeof suffix - 1;
- *end = '\0';
- do
+/* Clears auxiliary data, if any, from V, and calls any
+ associated destructor. */
+void
+var_clear_aux (struct variable *v)
+{
+ assert (v != NULL);
+ if (v->aux != NULL)
{
- *--start = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[suffix_number % 26];
- if (start <= suffix + 1)
- msg (SE, _("Variable suffix too large."));
- suffix_number /= 26;
+ if (v->aux_dtor != NULL)
+ v->aux_dtor (v);
+ v->aux = NULL;
}
- 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);
+/* This function is appropriate for use an auxiliary data
+ destructor (passed as AUX_DTOR to var_attach_aux()) for the
+ case where the auxiliary data should be passed to free(). */
+void
+var_dtor_free (struct variable *v)
+{
+ free (v->aux);
}
+\f
+/* Observed categorical values. */
+/* Returns V's observed categorical values,
+ which V must have. */
+struct cat_vals *
+var_get_obs_vals (const struct variable *v)
+{
+ assert (v->obs_vals != NULL);
+ return v->obs_vals;
+}
+/* Sets V's observed categorical values to CAT_VALS. */
+void
+var_set_obs_vals (struct variable *v, struct cat_vals *cat_vals)
+{
+ cat_stored_values_destroy (v->obs_vals);
+ v->obs_vals = cat_vals;
+}
+
+/* Returns true if V has observed categorical values,
+ false otherwise. */
+bool
+var_has_obs_vals (const struct variable *v)
+{
+ return v->obs_vals != NULL;
+}
+\f
/* Returns the dictionary class corresponding to a variable named
NAME. */
enum dict_class
dict_class_from_id (const char *name)
{
- assert (name != NULL);
-
switch (name[0])
{
default:
NOT_REACHED ();
}
}
-
-/* Return the number of bytes used when writing case_data for a variable
- of WIDTH */
-int
-width_to_bytes(int width)
+\f
+/* Returns V's vardict structure. */
+const struct vardict_info *
+var_get_vardict (const struct variable *v)
{
- assert (width >= 0);
+ assert (var_has_vardict (v));
+ return &v->vardict;
+}
- if ( width == 0 )
- return MAX_SHORT_STRING ;
- else if (width <= MAX_LONG_STRING)
- return ROUND_UP (width, MAX_SHORT_STRING);
- else
- {
- int chunks = width / EFFECTIVE_LONG_STRING_LENGTH ;
- int remainder = width % EFFECTIVE_LONG_STRING_LENGTH ;
- int bytes = remainder + (chunks * (MAX_LONG_STRING + 1) );
- return ROUND_UP (bytes, MAX_SHORT_STRING);
- }
+/* Sets V's vardict data to VARDICT. */
+void
+var_set_vardict (struct variable *v, const struct vardict_info *vardict)
+{
+ assert (vardict->dict_index >= 0);
+ assert (vardict->case_index >= 0);
+ v->vardict = *vardict;
}
+/* Returns true if V has vardict data. */
+bool
+var_has_vardict (const struct variable *v)
+{
+ return v->vardict.dict_index != -1;
+}
+/* Clears V's vardict data. */
+void
+var_clear_vardict (struct variable *v)
+{
+ v->vardict.dict_index = v->vardict.case_index = -1;
+}
#if !variable_h
#define variable_h 1
-
#include <stddef.h>
#include "config.h"
#include <stdbool.h>
-#include "category.h"
-#include "format.h"
-#include "missing-values.h"
+
+union value;
/* Variable type. */
enum var_type
{
- NUMERIC, /* A numeric variable. */
- ALPHA /* A string variable. */
+ VAR_NUMERIC, /* A numeric variable. */
+ VAR_STRING /* A string variable. */
};
bool var_type_is_valid (enum var_type);
-const char *var_type_adj (enum var_type);
-const char *var_type_noun (enum var_type);
+enum var_type var_type_from_width (int width);
-/* Alignment of data for display. */
-enum alignment
- {
- ALIGN_LEFT = 0,
- ALIGN_RIGHT = 1,
- ALIGN_CENTRE = 2,
- n_ALIGN
- };
+/* Variables. */
+struct variable *var_create (const char *name, int width);
+struct variable *var_clone (const struct variable *);
+void var_destroy (struct variable *);
-bool alignment_is_valid (enum alignment);
+/* Variable names.
+ Long variable names can be used in most contexts, but a few
+ procedures and file formats are limited to short names. */
+#define SHORT_NAME_LEN 8
+#define LONG_NAME_LEN 64
-/* How data is measured. */
-enum measure
- {
- MEASURE_NOMINAL = 1,
- MEASURE_ORDINAL = 2,
- MEASURE_SCALE = 3,
- n_MEASURES
- };
-
-bool measure_is_valid (enum measure);
-
-/* Maximum lengths of short and long variable names.
- Most operations support long variable names,
- but some file formats are limited to short names. */
-#define SHORT_NAME_LEN 8 /* Short name length. */
-#define LONG_NAME_LEN 64 /* Long name length. */
-
-/* A variable's dictionary entry. */
-struct variable
- {
- /* Dictionary information. */
- char name[LONG_NAME_LEN + 1]; /* Variable name. Mixed case. */
- int width; /* 0 for numeric, otherwise string width. */
- struct missing_values miss; /* Missing values. */
- struct fmt_spec print; /* Default format for PRINT. */
- struct fmt_spec write; /* Default format for WRITE. */
- struct val_labs *val_labs; /* Value labels. */
- char *label; /* Variable label. */
-
- /* GUI information. */
- enum measure measure; /* Nominal, ordinal, or continuous. */
- int display_width; /* Width of data editor column. */
- enum alignment alignment; /* Alignment of data in GUI. */
-
- /* Case information. */
- int fv; /* Index into `value's. */
- bool leave; /* Leave value from case to case? */
-
- /* Data for use by containing dictionary. */
- int index; /* Dictionary index. */
-
- /* Short name, used only for system and portable file input
- and output. Upper case only. There is no index for short
- names. Short names are not necessarily unique. Any
- variable may have no short name, indicated by an empty
- string. */
- char short_name[SHORT_NAME_LEN + 1];
-
- /* Each command may use these fields as needed. */
- void *aux;
- void (*aux_dtor) (struct variable *);
-
- /* Values of a categorical variable. Procedures need
- vectors with binary entries, so any variable of type ALPHA will
- have its values stored here. */
- struct cat_vals *obs_vals;
- };
-
-/* Variable names. */
const char *var_get_name (const struct variable *);
void var_set_name (struct variable *, const char *);
bool var_is_valid_name (const char *, bool issue_error);
bool var_is_plausible_name (const char *name, bool issue_error);
-int compare_var_names (const void *, const void *, const void *);
-unsigned hash_var_name (const void *, const void *);
+
+int compare_vars_by_name (const void *, const void *, const void *);
+unsigned hash_var_by_name (const void *, const void *);
+
+int compare_var_ptrs_by_name (const void *, const void *, const void *);
+unsigned hash_var_ptr_by_name (const void *, const void *);
/* Variable types and widths. */
enum var_type var_get_type (const struct variable *);
bool var_is_alpha (const struct variable *);
bool var_is_short_string (const struct variable *);
bool var_is_long_string (const struct variable *);
-bool var_is_very_long_string (const struct variable *);
+size_t var_get_value_cnt (const struct variable *);
/* Variables' missing values. */
const struct missing_values *var_get_missing_values (const struct variable *);
bool var_is_value_system_missing (const struct variable *,
const union value *);
+/* Value labels. */
+const struct val_labs *var_get_value_labels (const struct variable *);
+bool var_has_value_labels (const struct variable *);
+void var_set_value_labels (struct variable *, const struct val_labs *);
+bool var_add_value_label (struct variable *,
+ const union value *, const char *);
+void var_replace_value_label (struct variable *,
+ const union value *, const char *);
+void var_clear_value_labels (struct variable *);
+const char *var_lookup_value_label (const struct variable *,
+ const union value *);
+const char *var_get_value_name (const struct variable *, const union value *);
+
/* Print and write formats. */
const struct fmt_spec *var_get_print_format (const struct variable *);
void var_set_print_format (struct variable *, const struct fmt_spec *);
void var_set_both_formats (struct variable *, const struct fmt_spec *);
/* Variable labels. */
+const char *var_to_string (const struct variable *);
const char *var_get_label (const struct variable *);
void var_set_label (struct variable *, const char *);
void var_clear_label (struct variable *);
bool var_has_label (const struct variable *);
-/* GUI information. */
+/* How data is measured. */
+enum measure
+ {
+ MEASURE_NOMINAL = 1,
+ MEASURE_ORDINAL = 2,
+ MEASURE_SCALE = 3,
+ n_MEASURES
+ };
+
+bool measure_is_valid (enum measure);
enum measure var_get_measure (const struct variable *);
void var_set_measure (struct variable *, enum measure);
+/* GUI display width. */
int var_get_display_width (const struct variable *);
void var_set_display_width (struct variable *, int display_width);
+/* Alignment of data for display. */
+enum alignment
+ {
+ ALIGN_LEFT = 0,
+ ALIGN_RIGHT = 1,
+ ALIGN_CENTRE = 2,
+ n_ALIGN
+ };
+
+bool alignment_is_valid (enum alignment);
enum alignment var_get_alignment (const struct variable *);
void var_set_alignment (struct variable *, enum alignment);
-/* Variable location in cases. */
-size_t var_get_value_cnt (const struct variable *);
-
/* Whether variables' values should be preserved from case to
case. */
bool var_get_leave (const struct variable *);
+void var_set_leave (struct variable *, bool leave);
+bool var_must_leave (const struct variable *);
/* Short names. */
const char *var_get_short_name (const struct variable *);
void var_set_short_name (struct variable *, const char *);
-void var_set_short_name_suffix (struct variable *, const char *, int suffix);
void var_clear_short_name (struct variable *);
-/* Pointers to `struct variable', by name. */
-int compare_var_ptr_names (const void *, const void *, const void *);
-unsigned hash_var_ptr_name (const void *, const void *);
+/* Relationship with dictionary. */
+size_t var_get_dict_index (const struct variable *);
+size_t var_get_case_index (const struct variable *);
/* Variable auxiliary data. */
+void *var_get_aux (const struct variable *);
void *var_attach_aux (struct variable *,
void *aux, void (*aux_dtor) (struct variable *));
void var_clear_aux (struct variable *);
void *var_detach_aux (struct variable *);
void var_dtor_free (struct variable *);
+/* Observed categorical values. */
+struct cat_vals *var_get_obs_vals (const struct variable *);
+void var_set_obs_vals (struct variable *, struct cat_vals *);
+bool var_has_obs_vals (const struct variable *);
+
/* Classes of variables. */
enum dict_class
{
enum dict_class dict_class_from_id (const char *name);
const char *dict_class_to_name (enum dict_class dict_class);
-\f
-/* Vector of variables. */
-struct vector
- {
- int idx; /* Index for dict_get_vector(). */
- char name[LONG_NAME_LEN + 1]; /* Name. */
- struct variable **var; /* Vector of variables. */
- int cnt; /* Number of variables. */
- };
-
-
-/* Return a string representing this variable, in the form most
- appropriate from a human factors perspective.
- (IE: the label if it has one, otherwise the name )
-*/
-const char * var_to_string(const struct variable *var);
-
-
-int width_to_bytes(int width);
-
-union value * value_dup (const union value *val, int width);
-
#endif /* !variable.h */
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ Written by Ben Pfaff <blp@gnu.org>.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include <config.h>
+#include "vector.h"
+
+#include "dictionary.h"
+
+#include <libpspp/assertion.h>
+#include <libpspp/str.h>
+
+#include "xalloc.h"
+
+/* Vector of variables. */
+struct vector
+ {
+ char name[LONG_NAME_LEN + 1]; /* Name. */
+ struct variable **vars; /* Set of variables. */
+ size_t var_cnt; /* Number of variables. */
+ };
+
+/* Checks that all the variables in VECTOR have consistent
+ width. */
+static void
+check_widths (const struct vector *vector)
+{
+ int width = var_get_width (vector->vars[0]);
+ size_t i;
+
+ for (i = 1; i < vector->var_cnt; i++)
+ assert (width == var_get_width (vector->vars[i]));
+}
+
+/* Creates and returns a new vector with the given NAME
+ that contains the VAR_CNT variables in VARS.
+ All variables in VARS must have the same type and width. */
+struct vector *
+vector_create (const char *name,
+ struct variable **vars, size_t var_cnt)
+{
+ struct vector *vector = xmalloc (sizeof *vector);
+
+ assert (var_cnt > 0);
+ assert (var_is_plausible_name (name, false));
+ str_copy_trunc (vector->name, sizeof vector->name, name);
+
+ vector->vars = xmemdup (vars, var_cnt * sizeof *vector->vars);
+ vector->var_cnt = var_cnt;
+ check_widths (vector);
+
+ return vector;
+}
+
+/* Creates and returns a new vector as a clone of OLD, but that
+ contains variables from NEW_DICT that are in the same position
+ as those in OLD are in OLD_DICT.
+ All variables in the new vector must have the same type and
+ width. */
+struct vector *
+vector_clone (const struct vector *old,
+ const struct dictionary *old_dict,
+ const struct dictionary *new_dict)
+{
+ struct vector *new = xmalloc (sizeof *new);
+ size_t i;
+
+ strcpy (new->name, old->name);
+
+ new->vars = xnmalloc (old->var_cnt, sizeof *new->vars);
+ new->var_cnt = old->var_cnt;
+ for (i = 0; i < new->var_cnt; i++)
+ {
+ assert (dict_contains_var (old_dict, old->vars[i]));
+ new->vars[i] = dict_get_var (new_dict,
+ var_get_dict_index (old->vars[i]));
+ }
+ check_widths (new);
+
+ return new;
+}
+
+/* Destroys VECTOR. */
+void
+vector_destroy (struct vector *vector)
+{
+ free (vector->vars);
+ free (vector);
+}
+
+/* Returns VECTOR's name. */
+const char *
+vector_get_name (const struct vector *vector)
+{
+ return vector->name;
+}
+
+/* Returns the type of the variables in VECTOR. */
+enum var_type vector_get_type (const struct vector *vector)
+{
+ return var_get_type (vector->vars[0]);
+}
+
+/* Returns the variable in VECTOR with the given INDEX. */
+struct variable *
+vector_get_var (const struct vector *vector, size_t index)
+{
+ assert (index < vector->var_cnt);
+ return vector->vars[index];
+}
+
+/* Returns the number of variables in VECTOR. */
+size_t
+vector_get_var_cnt (const struct vector *vector)
+{
+ return vector->var_cnt;
+}
+
+/* Compares two pointers to vectors represented by A and B and
+ returns a strcmp()-type result. */
+int
+compare_vector_ptrs_by_name (const void *a_, const void *b_)
+{
+ struct vector *const *pa = a_;
+ struct vector *const *pb = b_;
+ struct vector *a = *pa;
+ struct vector *b = *pb;
+
+ return strcasecmp (a->name, b->name);
+}
+
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ Written by Ben Pfaff <blp@gnu.org>.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#ifndef DATA_VECTOR_H
+#define DATA_VECTOR_H 1
+
+#include <stddef.h>
+#include <data/variable.h>
+
+struct dictionary;
+
+struct vector *vector_create (const char *name,
+ struct variable **var, size_t var_cnt);
+struct vector *vector_clone (const struct vector *old,
+ const struct dictionary *old_dict,
+ const struct dictionary *new_dict);
+void vector_destroy (struct vector *);
+
+const char *vector_get_name (const struct vector *);
+enum var_type vector_get_type (const struct vector *);
+struct variable *vector_get_var (const struct vector *, size_t idx);
+size_t vector_get_var_cnt (const struct vector *);
+
+int compare_vector_ptrs_by_name (const void *a_, const void *b_);
+
+#endif /* data/vector.h */
#include "control-stack.h"
#include <data/procedure.h>
#include <data/transformations.h>
-#include <data/variable.h>
+#include <data/value.h>
#include <language/command.h>
#include <language/expressions/public.h>
#include <language/lexer/lexer.h>
/* Even if the loop is never entered, set the index
variable to the initial value. */
- case_data_rw (c, loop->index_var->fv)->f = loop->cur;
+ case_data_rw (c, loop->index_var)->f = loop->cur;
/* Throw out pathological cases. */
if (!finite (loop->cur) || !finite (loop->by) || !finite (loop->last)
if ((loop->by > 0.0 && loop->cur > loop->last)
|| (loop->by < 0.0 && loop->cur < loop->last))
goto break_out;
- case_data_rw (c, loop->index_var->fv)->f = loop->cur;
+ case_data_rw (c, loop->index_var)->f = loop->cur;
}
if (loop->loop_condition != NULL
+Sat Dec 9 18:43:34 2006 Ben Pfaff <blp@gnu.org>
+
+ * list.q (cmd_list): Use new var_create, var_destroy functions.
+
Thu Nov 30 21:51:58 2006 Ben Pfaff <blp@gnu.org>
* inpt-pgm.c (cmd_reread): Always return error code upon detecting
/* Create specifier for parsing the variable. */
spec = pool_alloc (dls->pool, sizeof *spec);
spec->input = *f;
- spec->fv = v->fv;
+ spec->fv = var_get_case_index (v);
spec->record = record;
spec->first_column = column;
strcpy (spec->name, var_get_name (v));
spec = pool_alloc (dls->pool, sizeof *spec);
spec->input = input;
- spec->fv = v->fv;
+ spec->fv = var_get_case_index (v);
strcpy (spec->name, var_get_name (v));
ll_push_tail (&dls->specs, &spec->ll);
}
ll_for_each_continue (spec, struct dls_var_spec, ll, &dls->specs)
data_in (ss_substr (line, spec->first_column - 1, spec->input.w),
spec->input.type, spec->input.d, spec->first_column,
- case_data_rw (c, spec->fv), fmt_var_width (&spec->input));
+ case_data_rw_idx (c, spec->fv), fmt_var_width (&spec->input));
dfm_forward_record (dls->reader);
}
data_in (field, spec->input.type, 0,
dfm_get_column (dls->reader, ss_data (field)),
- case_data_rw (c, spec->fv), fmt_var_width (&spec->input));
+ case_data_rw_idx (c, spec->fv), fmt_var_width (&spec->input));
}
return true;
}
{
int width = fmt_var_width (&spec->input);
if (width == 0)
- case_data_rw (c, spec->fv)->f = SYSMIS;
+ case_data_rw_idx (c, spec->fv)->f = SYSMIS;
else
- memset (case_data_rw (c, spec->fv)->s, ' ', width);
+ memset (case_data_rw_idx (c, spec->fv)->s, ' ', width);
}
break;
}
data_in (field, spec->input.type, 0,
dfm_get_column (dls->reader, ss_data (field)),
- case_data_rw (c, spec->fv), fmt_var_width (&spec->input));
+ case_data_rw_idx (c, spec->fv), fmt_var_width (&spec->input));
}
dfm_forward_record (dls->reader);
/* If there was an END subcommand handle it. */
if (dls->end != NULL)
{
- double *end = &case_data_rw (c, dls->end->fv)->f;
+ double *end = &case_data_rw (c, dls->end)->f;
if (retval == TRNS_DROP_CASE)
{
*end = 1.0;
#include <data/case.h>
#include <data/casefile.h>
#include <data/fastfile.h>
+#include <data/format.h>
#include <data/dictionary.h>
#include <data/por-file-writer.h>
#include <data/procedure.h>
*file = f->next;
if (f->in_var != NULL)
- case_data_rw (&mtf->mtf_case, f->in_var->fv)->f = 0.;
+ case_data_rw (&mtf->mtf_case, f->in_var)->f = 0.;
for (i = 0; i < dict_get_var_cnt (f->dict); i++)
{
struct variable *v = dict_get_var (f->dict, i);
struct variable *mv = get_master (v);
if (mv != NULL)
{
- union value *out = case_data_rw (&mtf->mtf_case, mv->fv);
+ union value *out = case_data_rw (&mtf->mtf_case, mv);
if (var_is_numeric (v))
out->f = SYSMIS;
{
struct variable *v = dict_get_var (iter->dict, i);
struct variable *mv = get_master (v);
+ size_t mv_index = mv ? var_get_dict_index (mv) : 0;
- if (mv != NULL && mtf->seq_nums[mv->index] != mtf->seq_num)
+ if (mv != NULL && mtf->seq_nums[mv_index] != mtf->seq_num)
{
const struct ccase *record
= case_is_null (&iter->input) ? c : &iter->input;
- union value *out = case_data_rw (&mtf->mtf_case, mv->fv);
+ union value *out = case_data_rw (&mtf->mtf_case, mv);
- mtf->seq_nums[mv->index] = mtf->seq_num;
+ mtf->seq_nums[mv_index] = mtf->seq_num;
if (var_is_numeric (v))
- out->f = case_num (record, v->fv);
+ out->f = case_num (record, v);
else
- memcpy (out->s, case_str (record, v->fv),
- var_get_width (v));
+ memcpy (out->s, case_str (record, v), var_get_width (v));
}
}
if (iter->in_var != NULL)
- case_data_rw (&mtf->mtf_case, iter->in_var->fv)->f = 1.;
+ case_data_rw (&mtf->mtf_case, iter->in_var)->f = 1.;
if (iter->type == MTF_FILE && iter->handle == NULL)
read_active_file = true;
{
struct variable *v = dict_get_var (iter->dict, i);
struct variable *mv = get_master (v);
+ size_t mv_index = mv ? var_get_dict_index (mv) : 0;
- if (mv != NULL && mtf->seq_nums[mv->index] != mtf->seq_num)
+ if (mv != NULL && mtf->seq_nums[mv_index] != mtf->seq_num)
{
- union value *out = case_data_rw (&mtf->mtf_case, mv->fv);
- mtf->seq_nums[mv->index] = mtf->seq_num;
+ union value *out = case_data_rw (&mtf->mtf_case, mv);
+ mtf->seq_nums[mv_index] = mtf->seq_num;
if (var_is_numeric (v))
out->f = SYSMIS;
}
}
if (iter->in_var != NULL)
- case_data_rw (&mtf->mtf_case, iter->in_var->fv)->f = 0.;
+ case_data_rw (&mtf->mtf_case, iter->in_var)->f = 0.;
}
/* 5. Write the output record. */
if (var_get_width (dv) == var_get_width (mv))
{
- if (val_labs_count (dv->val_labs)
- && !val_labs_count (mv->val_labs))
- {
- val_labs_destroy (mv->val_labs);
- mv->val_labs = val_labs_copy (dv->val_labs);
- }
+ if (var_has_value_labels (dv) && !var_has_value_labels (mv))
+ var_set_value_labels (mv, var_get_value_labels (dv));
if (var_has_missing_values (dv) && !var_has_missing_values (mv))
var_set_missing_values (mv, var_get_missing_values (dv));
}
static struct variable *
get_master (struct variable *v)
{
- return v->aux;
+ return var_get_aux (v);
}
\f
/* Case map.
{
struct variable *v = dict_get_var (d, i);
int *src_fv = xmalloc (sizeof *src_fv);
- *src_fv = v->fv;
+ *src_fv = var_get_case_index (v);
var_attach_aux (v, src_fv, var_dtor_free);
}
}
int *src_fv = (int *) var_detach_aux (v);
size_t idx;
- if (v->fv != *src_fv)
+ if (var_get_case_index (v) != *src_fv)
identity_map = 0;
for (idx = 0; idx < value_cnt; idx++)
{
int src_idx = *src_fv + idx;
- int dst_idx = v->fv + idx;
+ int dst_idx = var_get_case_index (v) + idx;
assert (map->map[dst_idx] == -1);
map->map[dst_idx] = src_idx;
{
int src_idx = map->map[dst_idx];
if (src_idx != -1)
- *case_data_rw (dst, dst_idx) = *case_data (src, src_idx);
+ *case_data_rw_idx (dst, dst_idx) = *case_data_idx (src, src_idx);
}
}
value_init |= var_get_leave (var) ? INP_INIT_ONCE : INP_REINIT;
for (j = 0; j < value_cnt; j++)
- inp->init[j + var->fv] = value_init;
+ inp->init[j + var_get_case_index (var)] = value_init;
}
for (i = 0; i < inp->init_cnt; i++)
assert (inp->init[i] != -1);
switch (inp->init[i])
{
case INP_NUMERIC | INP_INIT_ONCE:
- case_data_rw (c, i)->f = 0.0;
+ case_data_rw_idx (c, i)->f = 0.0;
break;
case INP_NUMERIC | INP_REINIT:
- case_data_rw (c, i)->f = SYSMIS;
+ case_data_rw_idx (c, i)->f = SYSMIS;
break;
case INP_STRING | INP_INIT_ONCE:
case INP_STRING | INP_REINIT:
- memset (case_data_rw (c, i)->s, ' ', sizeof case_data_rw (c, i)->s);
+ memset (case_data_rw_idx (c, i)->s, ' ',
+ sizeof case_data_rw_idx (c, i)->s);
break;
default:
NOT_REACHED ();
case INP_NUMERIC | INP_INIT_ONCE:
break;
case INP_NUMERIC | INP_REINIT:
- case_data_rw (c, i)->f = SYSMIS;
+ case_data_rw_idx (c, i)->f = SYSMIS;
break;
case INP_STRING | INP_INIT_ONCE:
break;
case INP_STRING | INP_REINIT:
- memset (case_data_rw (c, i)->s, ' ', sizeof case_data_rw (c, i)->s);
+ memset (case_data_rw_idx (c, i)->s, ' ',
+ sizeof case_data_rw_idx (c, i)->s);
break;
default:
NOT_REACHED ();
int
cmd_list (struct lexer *lexer, struct dataset *ds)
{
- struct variable casenum_var;
+ struct variable *casenum_var = NULL;
bool ok;
if (!parse_list (lexer, ds, &cmd, NULL))
/* Initialize the case-number variable. */
int width = cmd.last == LONG_MAX ? 5 : intlog10 (cmd.last);
struct fmt_spec format = fmt_for_output (FMT_F, width, 0);
- var_set_name (&casenum_var, "Case#");
- casenum_var.width = 0;
- casenum_var.fv = -1;
- var_set_both_formats (&casenum_var, &format);
+ casenum_var = var_create ("Case#", 0);
+ var_set_both_formats (casenum_var, &format);
/* Add the weight variable at the beginning of the variable list. */
cmd.n_variables++;
cmd.n_variables, sizeof *cmd.v_variables);
memmove (&cmd.v_variables[1], &cmd.v_variables[0],
(cmd.n_variables - 1) * sizeof *cmd.v_variables);
- cmd.v_variables[0] = &casenum_var;
+ cmd.v_variables[0] = casenum_var;
}
determine_layout ();
clean_up ();
+ var_destroy (casenum_var);
+
return ok ? CMD_SUCCESS : CMD_CASCADING_FAILURE;
}
/* Writes case C to output. */
static bool
-list_cases (const struct ccase *c, void *aux UNUSED, const struct dataset *ds UNUSED)
+list_cases (const struct ccase *c, void *aux UNUSED, const struct dataset *ds)
{
struct outp_driver *d;
if (width > print->w)
ds_put_char_multiple(&line_buffer, ' ', width - print->w);
- if (fmt_is_string (print->type) || v->fv != -1)
+ if (fmt_is_string (print->type)
+ || dict_contains_var (dataset_dict (ds), v))
{
- data_out (case_data (c, v->fv), print,
+ data_out (case_data (c, v), print,
ds_put_uninit (&line_buffer, print->w));
}
else
const struct fmt_spec *print = var_get_print_format (v);
char buf[256];
- if (fmt_is_string (print->type) || v->fv != -1)
- data_out (case_data (c, v->fv), print, buf);
+ if (fmt_is_string (print->type)
+ || dict_contains_var (dataset_dict (ds), v))
+ data_out (case_data (c, v), print, buf);
else
{
union value case_idx_value;
for (i = 0; i < split_cnt; i++)
{
- struct mxd_var *mv = split[i]->aux;
- assert (mv != NULL);
+ struct mxd_var *mv = var_get_aux (split[i]);
if (mv->var_type != MXD_CONTINUOUS)
{
msg (SE, _("Split variable %s is already another type."),
for (i = 0; i < mx->n_factors; i++)
{
struct variable *v = mx->factors[i];
- struct mxd_var *mv = v->aux;
- assert (mv != NULL);
+ struct mxd_var *mv = var_get_aux (v);
if (mv->var_type != MXD_CONTINUOUS)
{
msg (SE, _("Factor variable %s is already another type."),
for (i = 0; i < dict_get_var_cnt (dataset_dict (ds)); i++)
{
struct variable *v = dict_get_var (dataset_dict (ds), i);
- struct mxd_var *mv = v->aux;
+ struct mxd_var *mv = var_get_aux (v);
int type = mv->var_type;
assert (type >= 0 && type < MXD_COUNT);
{
struct variable *const *pa = a_;
struct variable *const *pb = b_;
- const struct mxd_var *a = (*pa)->aux;
- const struct mxd_var *b = (*pb)->aux;
+ const struct mxd_var *a = var_get_aux (*pa);
+ const struct mxd_var *b = var_get_aux (*pb);
if (a->var_type != b->var_type)
return a->var_type > b->var_type ? 1 : -1;
{
struct mxd_var *mv;
- assert (v->aux == NULL);
+ assert (var_get_aux (v) == NULL);
mv = xmalloc (sizeof *mv);
mv->var_type = var_type;
mv->sub_type = sub_type;
{
if (!compare)
{
- struct mxd_var *mv = dict_get_split_vars (nr->dict)[0]->aux;
+ struct mxd_var *mv = var_get_aux (dict_get_split_vars (nr->dict)[0]);
nr->split_values[0] = ++mv->sub_type;
}
return true;
int type = content_type[content];
{
- buf_copy_str_rpad (case_data_rw (c, mx->rowtype_->fv)->s, 8,
+ buf_copy_str_rpad (case_data_rw (c, mx->rowtype_)->s, 8,
content_names[content]);
if (type != 1)
- memset (case_data_rw (c, mx->varname_->fv)->s, ' ', 8);
+ memset (case_data_rw (c, mx->varname_)->s, ' ', 8);
}
{
for (j = 0; j < mx->n_continuous; j++)
{
- int fv = dict_get_var (dict, mx->first_continuous + j)->fv;
- case_data_rw (c, fv)->f = *cp;
+ struct variable *v = dict_get_var (dict, mx->first_continuous + j);
+ case_data_rw (c, v)->f = *cp;
cp++;
}
if (type == 1)
- buf_copy_str_rpad (case_data_rw (c, mx->varname_->fv)->s, 8,
+ buf_copy_str_rpad (case_data_rw (c, mx->varname_)->s, 8,
var_get_name (
dict_get_var (dict, mx->first_continuous + i)));
if (!write_case (wc_data))
split_cnt = dict_get_split_cnt (nr->dict);
split = dict_get_split_vars (nr->dict);
for (i = 0; i < split_cnt; i++)
- case_data_rw (c, split[i]->fv)->f = nr->split_values[i];
+ case_data_rw (c, split[i])->f = nr->split_values[i];
}
if (mx->n_factors)
size_t factor;
for (factor = 0; factor < mx->n_factors; factor++)
- case_data_rw (c, mx->factors[factor]->fv)->f
+ case_data_rw (c, mx->factors[factor])->f
= nr->factor_values[factor + cell * mx->n_factors];
}
size_t factor;
for (factor = 0; factor < mx->n_factors; factor++)
- case_data_rw (c, mx->factors[factor]->fv)->f = SYSMIS;
+ case_data_rw (c, mx->factors[factor])->f = SYSMIS;
}
for (content = 0; content <= PROX; content++)
split_cnt = dict_get_split_cnt (wr->dict);
split = dict_get_split_vars (wr->dict);
for (i = 0; i < split_cnt; i++)
- case_data_rw (c, split[i]->fv)->f = wr->split_values[i];
+ case_data_rw (c, split[i])->f = wr->split_values[i];
}
/* Sort the wr->data list. */
size_t factor;
for (factor = 0; factor < mx->n_factors; factor++)
- case_data_rw (c, mx->factors[factor]->fv)->f
- = iter->factors[factor];
+ case_data_rw (c, mx->factors[factor])->f = iter->factors[factor];
}
{
#include <stdlib.h>
#include <data/procedure.h>
+#include <data/value.h>
#include <language/command.h>
#include <language/data-io/data-writer.h>
#include <language/data-io/file-handle.h>
ds_set_length (&trns->line, spec->first_column, ' ');
if (spec->type == PRT_VAR)
{
- const union value *input = case_data (c, spec->var->fv);
+ const union value *input = case_data (c, spec->var);
char *output = ds_put_uninit (&trns->line, spec->format.w);
if (!spec->sysmis_as_spaces || input->f != SYSMIS)
data_out (input, &spec->format, output);
+Sat Dec 9 18:44:26 2006 Ben Pfaff <blp@gnu.org>
+
+ * variable-label.c: Move to src/data/variable.c.
+
+ * vector.c (cmd_vector): Use PV_SAME_WIDTH in parse_variables
+ call, because string variables in a vector must have the same
+ width.
+
Thu Nov 30 22:06:21 2006 Ben Pfaff <blp@gnu.org>
* value-labels.c (get_label): Allow commas between values and
#include <data/any-reader.h>
#include <data/dictionary.h>
#include <data/file-handle-def.h>
+#include <data/missing-values.h>
#include <data/procedure.h>
#include <data/value-labels.h>
#include <data/variable.h>
var_set_label (t, label);
}
- if (val_labs_count (s->val_labs) && var_is_long_string (t))
- msg (SW, _("Cannot add value labels from source file to "
- "long string variable %s."),
- var_get_name (s));
- else if (val_labs_count (s->val_labs))
- {
- if (val_labs_can_set_width (s->val_labs, var_get_width (t)))
+ if (var_has_value_labels (s))
+ {
+ if (!var_is_long_string (t))
{
- val_labs_destroy (t->val_labs);
- t->val_labs = s->val_labs;
- val_labs_set_width (t->val_labs, var_get_width (t));
- s->val_labs = val_labs_create (var_get_width (s));
+ const struct val_labs *value_labels = var_get_value_labels (s);
+ if (val_labs_can_set_width (value_labels, var_get_width (t)))
+ var_set_value_labels (s, value_labels);
}
- }
-
+ else
+ msg (SW, _("Cannot add value labels from source file to "
+ "long string variable %s."),
+ var_get_name (s));
+ }
+
if (var_has_missing_values (s))
{
if (!var_is_long_string (t))
{
- struct missing_values miss;
- mv_copy (&miss, var_get_missing_values (s));
- if (mv_is_resizable (&miss, var_get_width (t)))
- {
- mv_resize (&miss, var_get_width (t));
- var_set_missing_values (t, &miss);
- }
+ const struct missing_values *miss = var_get_missing_values (s);
+ if (mv_is_resizable (miss, var_get_width (t)))
+ var_set_missing_values (t, miss);
}
else
msg (SW, _("Cannot apply missing values from source file to "
}
if (!parse_format_specifier (lexer, &f)
|| !fmt_check_output (&f)
- || !fmt_check_type_compat (&f, NUMERIC))
+ || !fmt_check_type_compat (&f, VAR_NUMERIC))
goto fail;
if (!lex_match (lexer, ')'))
#include <stdlib.h>
#include <data/data-in.h>
+#include <data/missing-values.h>
#include <data/procedure.h>
+#include <data/value.h>
#include <data/variable.h>
#include <language/command.h>
#include <language/lexer/lexer.h>
for (i = 0; i < nv; i++)
{
- if (!mv_is_resizable (&mv, var_get_width (v[i])))
+ if (mv_is_resizable (&mv, var_get_width (v[i])))
+ var_set_missing_values (v[i], &mv);
+ else
{
msg (SE, _("Missing values provided are too long to assign "
"to variable of width %d."),
var_get_width (v[i]));
deferred_errors = true;
}
- else
- {
- struct missing_values tmp;
- mv_copy (&tmp, &mv);
- mv_resize (&tmp, var_get_width (v[i]));
- var_set_missing_values (v[i], &tmp);
- }
}
}
const struct ordering *ordering = ordering_;
int result;
- if (ordering->positional)
- result = a->index < b->index ? -1 : a->index > b->index;
+ if (ordering->positional)
+ {
+ size_t a_index = var_get_dict_index (a);
+ size_t b_index = var_get_dict_index (b);
+ result = a_index < b_index ? -1 : a_index > b_index;
+ }
else
result = strcasecmp (var_get_name (a), var_get_name (b));
if (!ordering->forward)
if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE))
return CMD_CASCADING_FAILURE;
for (i = 0; i < nv; i++)
- v[i]->leave = true;
+ var_set_leave (v[i], true);
free (v);
return lex_end_of_command (lexer);
tab_text (t, 0, i + 1, TAB_LEFT | TAT_PRINTF, "%s", var_get_name (v));
- data_out (case_data (c, v->fv), print, temp_buf);
+ data_out (case_data (c, v), print, temp_buf);
temp_buf[print->w] = 0;
tab_text (t, 1, i + 1, TAT_PRINTF, "%.*s", print->w, temp_buf);
- val_lab = val_labs_find (v->val_labs, *case_data (c, v->fv));
+ val_lab = var_lookup_value_label (v, case_data (c, v));
if (val_lab)
tab_text (t, 2, i + 1, TAB_LEFT, val_lab);
}
#include <data/dictionary.h>
#include <data/file-handle-def.h>
+#include <data/format.h>
+#include <data/missing-values.h>
#include <data/procedure.h>
#include <data/sys-file-reader.h>
#include <data/value-labels.h>
#include <data/variable.h>
+#include <data/vector.h>
#include <language/command.h>
#include <language/data-io/file-handle.h>
#include <language/lexer/lexer.h>
for (r = 1, i = 0; i < dict_get_var_cnt (d); i++)
{
struct variable *v = dict_get_var (d, i);
- const int nvl = val_labs_count (v->val_labs);
+ const int nvl = val_labs_count (var_get_value_labels (v));
if (r + 10 + nvl > nr)
{
}
if (sorted)
- sort (vl, n, sizeof *vl, compare_var_ptr_names, NULL);
+ sort (vl, n, sizeof *vl, compare_var_ptrs_by_name, NULL);
display_variables (vl, n, as);
if (as == AS_DICTIONARY || as == AS_VARIABLES)
{
- int nvl = val_labs_count (v->val_labs);
+ int nvl = val_labs_count (var_get_value_labels (v));
if (r + 10 + nvl > nr)
{
}
if (as != AS_NAMES)
{
- tab_text (t, pc, r, TAT_PRINTF, "%d", v->index + 1);
+ tab_text (t, pc, r, TAT_PRINTF, "%d",
+ (int) var_get_dict_index (v) + 1);
tab_hline (t, TAL_1, 0, nc - 1, r);
}
r++;
/* Put the name, var label, and position into the first row. */
tab_text (t, 0, r, TAB_LEFT, var_get_name (v));
- tab_text (t, 3, r, TAT_PRINTF, "%d", v->index + 1);
+ tab_text (t, 3, r, TAT_PRINTF, "%d", (int) var_get_dict_index (v) + 1);
if (as == AS_DICTIONARY && var_has_label (v))
{
}
/* Value labels. */
- if (as == AS_DICTIONARY && val_labs_count (v->val_labs))
+ if (as == AS_DICTIONARY && var_has_value_labels (v))
{
+ const struct val_labs *val_labs = var_get_value_labels (v);
struct val_labs_iterator *i;
struct val_lab *vl;
int orig_r = r;
#endif
tab_hline (t, TAL_1, 1, 2, r);
- for (vl = val_labs_first_sorted (v->val_labs, &i); vl != NULL;
- vl = val_labs_next (v->val_labs, &i))
+ for (vl = val_labs_first_sorted (val_labs, &i); vl != NULL;
+ vl = val_labs_next (val_labs, &i))
{
char buf[128];
return r;
}
-static int
-compare_vectors_by_name (const void *a_, const void *b_)
-{
- struct vector *const *pa = a_;
- struct vector *const *pb = b_;
- struct vector *a = *pa;
- struct vector *b = *pb;
-
- return strcasecmp (a->name, b->name);
-}
-
/* Display a list of vectors. If SORTED is nonzero then they are
sorted alphabetically. */
static void
for (i = 0; i < nvec; i++)
vl[i] = dict_get_vector (dict, i);
if (sorted)
- qsort (vl, nvec, sizeof *vl, compare_vectors_by_name);
+ qsort (vl, nvec, sizeof *vl, compare_vector_ptrs_by_name);
t = tab_create (1, nvec + 1, 0);
tab_headers (t, 0, 0, 1, 0);
tab_text (t, 0, 0, TAT_TITLE | TAB_LEFT, _("Vector"));
tab_flags (t, SOMF_NO_TITLE);
for (i = 0; i < nvec; i++)
- tab_text (t, 0, i + 1, TAB_LEFT, vl[i]->name);
+ tab_text (t, 0, i + 1, TAB_LEFT, vector_get_name (vl[i]));
tab_submit (t);
free (vl);
/* Erase old value labels if desired. */
for (i = 0; i < var_cnt; i++)
- val_labs_clear (vars[i]->val_labs);
+ var_clear_value_labels (vars[i]);
}
/* Parse all the labels for the VAR_CNT variables in VARS and add
}
for (i = 0; i < var_cnt; i++)
- val_labs_replace (vars[i]->val_labs, value, ds_cstr (&label));
+ var_replace_value_label (vars[i], &value, ds_cstr (&label));
ds_destroy (&label);
-const char *
-var_to_string(const struct variable *var)
-{
- const char *label;
-
- if ( !var )
- return 0;
-
- label = var_get_label (var);
- return label ? label : var_get_name (var);
-}
}
if (!parse_variables (lexer, dict, &v, &nv,
- PV_SAME_TYPE | PV_DUPLICATE))
+ PV_SAME_WIDTH | PV_DUPLICATE))
goto fail;
dict_create_vector (dict, vecnames, v, nv);
case_resize (c, old_value_cnt, dict_get_next_value_idx (d));
if (lex_is_number (lexer))
- case_data_rw (c, v->fv)->f = lex_tokval (lexer);
+ case_data_rw (c, v)->f = lex_tokval (lexer);
else
- memcpy (case_data_rw (c, v->fv)->s, ds_data (lex_tokstr (lexer)),
+ memcpy (case_data_rw (c, v)->s, ds_data (lex_tokstr (lexer)),
var_get_width (v));
lex_get (lexer);
fprintf (stderr, "v<%s>", var_get_name (op->variable));
break;
case OP_vector:
- fprintf (stderr, "vec<%s>", op->vector->name);
+ fprintf (stderr, "vec<%s>", vector_get_name (op->vector));
break;
case OP_integer:
fprintf (stderr, "i<%d>", op->integer);
#include <data/settings.h>
#include <data/value.h>
#include <data/variable.h>
+#include <data/vector.h>
#include <gsl-extras/gsl-extras.h>
#include <language/expressions/public.h>
#include <libpspp/compiler.h>
no_opt boolean function SYSMIS (num_var v)
case c;
{
- return case_num (c, v->fv) == SYSMIS;
+ return case_num (c, v) == SYSMIS;
}
no_opt boolean function VALUE (num_var v)
case c;
{
- return case_num (c, v->fv);
+ return case_num (c, v);
}
no_opt operator VEC_ELEM_NUM (idx)
vector v;
case c;
{
- if (idx >= 1 && idx <= v->cnt)
+ if (idx >= 1 && idx <= vector_get_var_cnt (v))
{
- const struct variable *var = v->var[(int) idx - 1];
- double value = case_num (c, var->fv);
+ const struct variable *var = vector_get_var (v, (size_t) idx - 1);
+ double value = case_num (c, var);
return !var_is_num_user_missing (var, value) ? value : SYSMIS;
}
else
if (idx == SYSMIS)
msg (SE, _("SYSMIS is not a valid index value for vector "
"%s. The result will be set to SYSMIS."),
- v->name);
+ vector_get_name (v));
else
msg (SE, _("%g is not a valid index value for vector %s. "
"The result will be set to SYSMIS."),
- idx, v->name);
+ idx, vector_get_name (v));
return SYSMIS;
}
}
vector v;
case c;
{
- if (idx >= 1 && idx <= v->cnt)
+ if (idx >= 1 && idx <= vector_get_var_cnt (v))
{
- struct variable *var = v->var[(int) idx - 1];
- return copy_string (e, case_str (c, var->fv), var_get_width (var));
+ struct variable *var = vector_get_var (v, (size_t) idx - 1);
+ return copy_string (e, case_str (c, var), var_get_width (var));
}
else
{
if (idx == SYSMIS)
msg (SE, _("SYSMIS is not a valid index value for vector "
"%s. The result will be set to the empty string."),
- v->name);
+ vector_get_name (v));
else
msg (SE, _("%g is not a valid index value for vector %s. "
"The result will be set to the empty string."),
- idx, v->name);
+ idx, vector_get_name (v));
return empty_string;
}
}
case c;
num_var v;
{
- double d = case_num (c, v->fv);
+ double d = case_num (c, v);
return !var_is_num_user_missing (v, d) ? d : SYSMIS;
}
str_var v;
{
struct substring s = alloc_string (e, var_get_width (v));
- memcpy (s.string, case_str (c, v->fv), var_get_width (v));
+ memcpy (s.string, case_str (c, v), var_get_width (v));
return s;
}
struct ccase *c = lagged_case (ds, n_before);
if (c != NULL)
{
- double x = case_num (c, v->fv);
+ double x = case_num (c, v);
return !var_is_num_user_missing (v, x) ? x : SYSMIS;
}
else
struct ccase *c = lagged_case (ds, 1);
if (c != NULL)
{
- double x = case_num (c, v->fv);
+ double x = case_num (c, v);
return !var_is_num_user_missing (v, x) ? x : SYSMIS;
}
else
{
struct ccase *c = lagged_case (ds, n_before);
if (c != NULL)
- return copy_string (e, case_str (c, v->fv), var_get_width (v));
+ return copy_string (e, case_str (c, v), var_get_width (v));
else
return empty_string;
}
{
struct ccase *c = lagged_case (ds, 1);
if (c != NULL)
- return copy_string (e, case_str (c, v->fv), var_get_width (v));
+ return copy_string (e, case_str (c, v), var_get_width (v));
else
return empty_string;
}
case c;
num_var v;
{
- return case_num (c, v->fv) == SYSMIS;
+ return case_num (c, v) == SYSMIS;
}
no_opt operator NUM_VAL ()
case c;
num_var v;
{
- return case_num (c, v->fv);
+ return case_num (c, v);
}
no_opt operator CASENUM ()
msg_disable ();
if ((*node)->type == OP_format
&& fmt_check_input (&(*node)->format.f)
- && fmt_check_type_compat (&(*node)->format.f, NUMERIC))
+ && fmt_check_type_compat (&(*node)->format.f, VAR_NUMERIC))
{
msg_enable ();
if (do_coercion)
msg_disable ();
if ((*node)->type == OP_format
&& fmt_check_output (&(*node)->format.f)
- && fmt_check_type_compat (&(*node)->format.f, NUMERIC))
+ && fmt_check_type_compat (&(*node)->format.f, VAR_NUMERIC))
{
msg_enable ();
if (do_coercion)
|| !lex_match (lexer, ')'))
return NULL;
- return expr_allocate_binary (e, (var_is_numeric (vector->var[0])
+ return expr_allocate_binary (e, (vector_get_type (vector) == VAR_NUMERIC
? OP_VEC_ELEM_NUM : OP_VEC_ELEM_STR),
element, expr_allocate_vector (e, vector));
}
+Sat Dec 9 18:46:11 2006 Ben Pfaff <blp@gnu.org>
+
+ * variable-parser.h: New PV_SAME_WIDTH variable parsing option.
+
+ * variable-parser.c (add_variable): Implement new PV_SAME_WIDTH
+ option.
+ (parse_var_set_vars) Ditto.
+ (array_var_set_lookup_var_idx) Use new var_create, var_destroy
+ functions.
+
Sat Dec 2 21:19:50 2006 Ben Pfaff <blp@gnu.org>
General clean-up.
#include <data/procedure.h>
#include <data/variable.h>
#include <libpspp/alloc.h>
+#include <libpspp/assertion.h>
#include <libpspp/bit-vector.h>
#include <libpspp/hash.h>
#include <libpspp/message.h>
&& dict_class_from_id (add_name) == DC_SCRATCH)
msg (SE, _("Scratch variables (such as %s) are not allowed "
"here."), add_name);
- else if ((pv_opts & PV_SAME_TYPE) && *nv
+ else if ((pv_opts & (PV_SAME_TYPE | PV_SAME_WIDTH)) && *nv
&& var_get_type (add) != var_get_type ((*v)[0]))
msg (SE, _("%s and %s are not the same type. All variables in "
"this variable list must be of the same type. %s "
- "will be omitted from list."),
+ "will be omitted from the list."),
+ var_get_name ((*v)[0]), add_name, add_name);
+ else if ((pv_opts & PV_SAME_WIDTH) && *nv
+ && var_get_width (add) != var_get_width ((*v)[0]))
+ msg (SE, _("%s and %s are string variables with different widths. "
+ "All variables in this variable list must have the "
+ "same width. %s will be omttied from the list."),
var_get_name ((*v)[0]), add_name, add_name);
else if ((pv_opts & PV_NO_DUPLICATE) && included[idx])
msg (SE, _("Variable %s appears twice in variable list."), add_name);
assert (v != NULL);
assert (nv != NULL);
- /* At most one of PV_NUMERIC, PV_STRING, PV_SAME_TYPE may be
- specified. */
- assert ((((pv_opts & PV_NUMERIC) != 0)
- + ((pv_opts & PV_STRING) != 0)
- + ((pv_opts & PV_SAME_TYPE) != 0)) <= 1);
+ /* At most one of PV_NUMERIC, PV_STRING, PV_SAME_TYPE,
+ PV_SAME_WIDTH may be specified. */
+ assert (((pv_opts & PV_NUMERIC) != 0)
+ + ((pv_opts & PV_STRING) != 0)
+ + ((pv_opts & PV_SAME_TYPE) != 0)
+ + ((pv_opts & PV_SAME_WIDTH) != 0) <= 1);
/* PV_DUPLICATE and PV_NO_DUPLICATE are incompatible. */
assert (!(pv_opts & PV_DUPLICATE) || !(pv_opts & PV_NO_DUPLICATE));
size_t i;
included = xcalloc (var_set_get_cnt (vs), sizeof *included);
- for (i = 0; i < *nv; i++)
- included[(*v)[i]->index] = 1;
+ for (i = 0; i < *nv; i++)
+ {
+ size_t index;
+ if (!var_set_lookup_var_idx (vs, var_get_name ((*v)[i]), &index))
+ NOT_REACHED ();
+ included[index] = 1;
+ }
}
else
included = NULL;
struct variable *v = dict_lookup_var (d, name);
if (v != NULL)
{
- *idx = v->index;
+ *idx = var_get_dict_index (v);
return true;
}
else
size_t *idx)
{
struct array_var_set *avs = vs->aux;
- struct variable v, *vp, *const *vpp;
+ struct variable *v, *const *vpp;
- strcpy (v.name, name);
- vp = &v;
- vpp = hsh_find (avs->name_tab, &vp);
+ v = var_create (name, 0);
+ vpp = hsh_find (avs->name_tab, &v);
+ var_destroy (v);
+
if (vpp != NULL)
{
*idx = vpp - avs->var;
avs->var = var;
avs->var_cnt = var_cnt;
avs->name_tab = hsh_create (2 * var_cnt,
- compare_var_ptr_names, hash_var_ptr_name, NULL,
- NULL);
+ compare_var_ptrs_by_name, hash_var_ptr_by_name,
+ NULL, NULL);
for (i = 0; i < var_cnt; i++)
if (hsh_insert (avs->name_tab, (void *) &var[i]) != NULL)
{
PV_NUMERIC = 0020, /* Vars must be numeric. */
PV_STRING = 0040, /* Vars must be string. */
PV_SAME_TYPE = 00100, /* All vars must be the same type. */
- PV_NO_SCRATCH = 00200 /* Disallow scratch variables. */
+ PV_SAME_WIDTH = 00200, /* All vars must be the same type and width. */
+ PV_NO_SCRATCH = 00400 /* Disallow scratch variables. */
};
struct variable *parse_variable (struct lexer *, const struct dictionary *);
+Sat Dec 9 18:47:51 2006 Ben Pfaff <blp@gnu.org>
+
+ * regression.q (is_depvar): Compare variable pointers instead of
+ variable names.
+
Thu Dec 7 15:26:25 WST 2006 John Darrington <john@darrington.wattle.id.au>
* examine.q: Allocated the categorical values for the dependent and
#include <data/casefile.h>
#include <data/dictionary.h>
#include <data/file-handle-def.h>
+#include <data/format.h>
#include <data/procedure.h>
#include <data/settings.h>
#include <data/storage-stream.h>
{
const char *name; /* Aggregation function name. */
size_t n_args; /* Number of arguments. */
- int alpha_type; /* When given ALPHA arguments, output type. */
+ enum var_type alpha_type; /* When given ALPHA arguments, output type. */
struct fmt_spec format; /* Format spec if alpha_type != ALPHA. */
};
/* Attributes of aggregation functions. */
static const struct agr_func agr_func_tab[] =
{
- {"<NONE>", 0, -1, {0, 0, 0}},
- {"SUM", 0, -1, {FMT_F, 8, 2}},
- {"MEAN", 0, -1, {FMT_F, 8, 2}},
- {"SD", 0, -1, {FMT_F, 8, 2}},
- {"MAX", 0, ALPHA, {-1, -1, -1}},
- {"MIN", 0, ALPHA, {-1, -1, -1}},
- {"PGT", 1, NUMERIC, {FMT_F, 5, 1}},
- {"PLT", 1, NUMERIC, {FMT_F, 5, 1}},
- {"PIN", 2, NUMERIC, {FMT_F, 5, 1}},
- {"POUT", 2, NUMERIC, {FMT_F, 5, 1}},
- {"FGT", 1, NUMERIC, {FMT_F, 5, 3}},
- {"FLT", 1, NUMERIC, {FMT_F, 5, 3}},
- {"FIN", 2, NUMERIC, {FMT_F, 5, 3}},
- {"FOUT", 2, NUMERIC, {FMT_F, 5, 3}},
- {"N", 0, NUMERIC, {FMT_F, 7, 0}},
- {"NU", 0, NUMERIC, {FMT_F, 7, 0}},
- {"NMISS", 0, NUMERIC, {FMT_F, 7, 0}},
- {"NUMISS", 0, NUMERIC, {FMT_F, 7, 0}},
- {"FIRST", 0, ALPHA, {-1, -1, -1}},
- {"LAST", 0, ALPHA, {-1, -1, -1}},
- {NULL, 0, -1, {-1, -1, -1}},
- {"N", 0, NUMERIC, {FMT_F, 7, 0}},
- {"NU", 0, NUMERIC, {FMT_F, 7, 0}},
+ {"<NONE>", 0, -1, {0, 0, 0}},
+ {"SUM", 0, -1, {FMT_F, 8, 2}},
+ {"MEAN", 0, -1, {FMT_F, 8, 2}},
+ {"SD", 0, -1, {FMT_F, 8, 2}},
+ {"MAX", 0, VAR_STRING, {-1, -1, -1}},
+ {"MIN", 0, VAR_STRING, {-1, -1, -1}},
+ {"PGT", 1, VAR_NUMERIC, {FMT_F, 5, 1}},
+ {"PLT", 1, VAR_NUMERIC, {FMT_F, 5, 1}},
+ {"PIN", 2, VAR_NUMERIC, {FMT_F, 5, 1}},
+ {"POUT", 2, VAR_NUMERIC, {FMT_F, 5, 1}},
+ {"FGT", 1, VAR_NUMERIC, {FMT_F, 5, 3}},
+ {"FLT", 1, VAR_NUMERIC, {FMT_F, 5, 3}},
+ {"FIN", 2, VAR_NUMERIC, {FMT_F, 5, 3}},
+ {"FOUT", 2, VAR_NUMERIC, {FMT_F, 5, 3}},
+ {"N", 0, VAR_NUMERIC, {FMT_F, 7, 0}},
+ {"NU", 0, VAR_NUMERIC, {FMT_F, 7, 0}},
+ {"NMISS", 0, VAR_NUMERIC, {FMT_F, 7, 0}},
+ {"NUMISS", 0, VAR_NUMERIC, {FMT_F, 7, 0}},
+ {"FIRST", 0, VAR_STRING, {-1, -1, -1}},
+ {"LAST", 0, VAR_STRING, {-1, -1, -1}},
+ {NULL, 0, -1, {-1, -1, -1}},
+ {"N", 0, VAR_NUMERIC, {FMT_F, 7, 0}},
+ {"NU", 0, VAR_NUMERIC, {FMT_F, 7, 0}},
};
/* Missing value types. */
if (lex_token (lexer) == T_STRING)
{
arg[i].c = ds_xstrdup (lex_tokstr (lexer));
- type = ALPHA;
+ type = VAR_STRING;
}
else if (lex_is_number (lexer))
{
arg[i].f = lex_tokval (lexer);
- type = NUMERIC;
- } else {
+ type = VAR_NUMERIC;
+ }
+ else
+ {
msg (SE, _("Missing argument %d to %s."), i + 1,
function->name);
goto error;
v->string = xmalloc (var_get_width (src[i]));
}
- if (function->alpha_type == ALPHA)
+ if (function->alpha_type == VAR_STRING)
destvar = dict_clone_var (agr->dict, v->src, dest[i]);
else
{
assert (var_is_numeric (v->src)
- || function->alpha_type == NUMERIC);
+ || function->alpha_type == VAR_NUMERIC);
destvar = dict_create_var (agr->dict, dest[i], 0);
if (destvar != NULL)
{
for (iter = agr->agr_vars; iter; iter = iter->next)
if (iter->src)
{
- const union value *v = case_data (input, iter->src->fv);
+ const union value *v = case_data (input, iter->src);
int src_width = var_get_width (iter->src);
if (iter->include_missing
{
struct variable *v = agr->break_vars[i];
size_t value_cnt = var_get_value_cnt (v);
- memcpy (case_data_rw (output, value_idx),
- case_data (&agr->break_case, v->fv),
+ memcpy (case_data_rw_idx (output, value_idx),
+ case_data (&agr->break_case, v),
sizeof (union value) * value_cnt);
value_idx += value_cnt;
}
for (i = agr->agr_vars; i; i = i->next)
{
- union value *v = case_data_rw (output, i->dest->fv);
+ union value *v = case_data_rw (output, i->dest);
if (agr->missing == COLUMNWISE && i->missing != 0
&& (i->function & FUNC) != N && (i->function & FUNC) != NU
union arc_value v;
if (var_is_numeric (spec->src))
- v.f = case_num (c, spec->src->fv);
+ v.f = case_num (c, spec->src);
else
- v.c = (char *) case_str (c, spec->src->fv);
+ v.c = (char *) case_str (c, spec->src);
item = hsh_force_find (spec->items, &v);
- case_data_rw (c, spec->dest->fv)->f = item->to;
+ case_data_rw (c, spec->dest)->f = item->to;
}
return TRNS_CONTINUE;
}
union arc_value v, *vp, **vpp;
if (var_is_numeric (arc->src_vars[i]))
- v.f = case_num (c, arc->src_vars[i]->fv);
+ v.f = case_num (c, arc->src_vars[i]);
else
- v.c = (char *) case_str (c, arc->src_vars[i]->fv);
+ v.c = (char *) case_str (c, arc->src_vars[i]);
vpp = (union arc_value **) hsh_probe (arc->src_values[i], &v);
if (*vpp == NULL)
#include <data/case.h>
#include <data/data-out.h>
#include <data/dictionary.h>
+#include <data/format.h>
#include <data/procedure.h>
#include <data/value-labels.h>
#include <data/variable.h>
static inline struct var_range *
get_var_range (struct variable *v)
{
- assert (v != NULL);
- assert (v->aux != NULL);
- return v->aux;
+ return var_get_aux (v);
}
/* Indexes into crosstab.v. */
assert (x != NULL);
for (j = 0; j < x->nvar; j++)
{
- const union value *v = case_data (c, x->vars[j]->fv);
+ const union value *v = case_data (c, x->vars[j]);
if ((cmd.miss == CRS_TABLE && var_is_value_missing (x->vars[j], v))
|| (cmd.miss == CRS_INCLUDE
&& var_is_value_system_missing (x->vars[j], v)))
}
if (var_is_numeric (x->vars[j]))
- te->values[j].f = case_num (c, x->vars[j]->fv);
+ te->values[j].f = case_num (c, x->vars[j]);
else
{
- memcpy (te->values[j].s, case_str (c, x->vars[j]->fv),
+ memcpy (te->values[j].s, case_str (c, x->vars[j]),
var_get_width (x->vars[j]));
/* Necessary in order to simplify comparisons. */
{
struct variable *const v = x->vars[i];
struct var_range *vr = get_var_range (v);
- double value = case_num (c, v->fv);
+ double value = case_num (c, v);
/* Note that the first test also rules out SYSMIS. */
if ((value < vr->min || value >= vr->max)
{
struct variable *row_var = x->vars[ROW_VAR];
- const int row = case_num (c, row_var->fv) - get_var_range (row_var)->min;
+ const int row = case_num (c, row_var) - get_var_range (row_var)->min;
struct variable *col_var = x->vars[COL_VAR];
- const int col = case_num (c, col_var->fv) - get_var_range (col_var)->min;
+ const int col = case_num (c, col_var) - get_var_range (col_var)->min;
const int col_dim = get_var_range (col_var)->count;
struct substring s;
const struct fmt_spec *print = var_get_print_format (var);
- const char *label = val_labs_find (var->val_labs, *v);
+ const char *label = var_lookup_value_label (var, v);
if (label)
{
tab_text (table, c, r, TAB_LEFT, label);
calculating a Z-score. */
struct dsc_z_score
{
- int src_idx; /* Source index into case data. */
- int dst_idx; /* Destination index into case data. */
+ struct variable *src_var; /* Variable on which z-score is based. */
+ struct variable *z_var; /* New z-score variable. */
double mean; /* Distribution mean. */
double std_dev; /* Distribution standard deviation. */
- struct variable *v; /* Variable on which z-score is based. */
};
/* DESCRIPTIVES transformation (for calculating Z-scores). */
assert(t->vars);
for (vars = t->vars; vars < t->vars + t->var_cnt; vars++)
{
- double score = case_num (c, (*vars)->fv);
+ double score = case_num (c, *vars);
if ( score == SYSMIS
|| (!t->include_user_missing
&& var_is_num_user_missing (*vars, score)))
for (z = t->z_scores; z < t->z_scores + t->z_score_cnt; z++)
{
- double input = case_num (c, z->src_idx);
- double *output = &case_data_rw (c, z->dst_idx)->f;
+ double input = case_num (c, z->src_var);
+ double *output = &case_data_rw (c, z->z_var)->f;
if (z->mean == SYSMIS || z->std_dev == SYSMIS
|| all_sysmis || input == SYSMIS
|| (!t->include_user_missing
- && var_is_num_user_missing (z->v, input)))
+ && var_is_num_user_missing (z->src_var, input)))
*output = SYSMIS;
else
*output = (input - z->mean) / z->std_dev;
var_to_string (dv->v)));
z = &t->z_scores[cnt++];
- z->src_idx = dv->v->fv;
- z->dst_idx = dst_var->fv;
+ z->src_var = dv->v;
+ z->z_var = dst_var;
z->mean = dv->stats[DSC_MEAN];
z->std_dev = dv->stats[DSC_STDDEV];
- z->v = dv->v;
}
}
for (i = 0; i < dsc->var_cnt; i++)
{
struct dsc_var *dv = &dsc->vars[i];
- double x = case_num (&c, dv->v->fv);
+ double x = case_num (&c, dv->v);
if (dsc->missing_type != DSC_LISTWISE
&& (x == SYSMIS
for (i = 0; i < dsc->var_cnt; i++)
{
struct dsc_var *dv = &dsc->vars[i];
- double x = case_num (&c, dv->v->fv);
+ double x = case_num (&c, dv->v);
if (dsc->missing_type != DSC_LISTWISE
&& (x == SYSMIS
for (i = 0; i < dsc->var_cnt; i++)
{
struct dsc_var *dv = &dsc->vars[i];
- double x = case_num (c, dv->v->fv);
+ double x = case_num (c, dv->v);
if (x == SYSMIS
|| (!dsc->include_user_missing
union value *indep_vals[2] ;
indep_vals[0] = value_dup (
- case_data (c, fctr->indep_var[0]->fv),
+ case_data (c, fctr->indep_var[0]),
var_get_width (fctr->indep_var[0])
);
if ( fctr->indep_var[1] )
indep_vals[1] = value_dup (
- case_data (c, fctr->indep_var[1]->fv),
+ case_data (c, fctr->indep_var[1]),
var_get_width (fctr->indep_var[1])
);
else
{
const struct variable *var = dependent_vars[v];
union value *val = value_dup (
- case_data (c, var->fv),
+ case_data (c, var),
var_get_width (var)
);
{
const struct variable *var = dependent_vars[v];
union value *val = value_dup (
- case_data (&c, var->fv),
+ case_data (&c, var),
var_get_width (var)
);
{
const struct variable *var = dependent_vars[v];
union value *val = value_dup (
- case_data (&c, var->fv),
+ case_data (&c, var),
var_get_width (var)
);
(i * n_factors ) + count +
heading_rows,
TAB_LEFT | TAT_TITLE,
- value_to_string ((*fs)->id[0],
- fctr->indep_var[0])
+ var_get_value_name (fctr->indep_var[0],
+ (*fs)->id[0])
);
if (fctr->indep_var[1] && count > 0 )
(i * n_factors ) + count +
heading_rows,
TAB_LEFT | TAT_TITLE,
- value_to_string ((*fs)->id[1], fctr->indep_var[1])
+ var_get_value_name (fctr->indep_var[1], (*fs)->id[1])
);
populate_summary (tbl, heading_columns,
tab_text (tbl,
1, row,
TAB_LEFT | TAT_TITLE,
- value_to_string ((*fs)->id[0], fctr->indep_var[0])
+ var_get_value_name (fctr->indep_var[0],
+ (*fs)->id[0])
);
}
if ( fctr->indep_var[1])
tab_text (tbl, 2, row,
TAB_LEFT | TAT_TITLE,
- value_to_string ((*fs)->id[1], fctr->indep_var[1])
+ var_get_value_name (fctr->indep_var[1], (*fs)->id[1])
);
populate_extremes (tbl, heading_columns - 2,
tab_text (tbl,
1, row,
TAB_LEFT | TAT_TITLE,
- value_to_string ((*fs)->id[0], fctr->indep_var[0])
+ var_get_value_name (fctr->indep_var[0],
+ (*fs)->id[0])
);
}
if ( fctr->indep_var[1])
tab_text (tbl, 2, row,
TAB_LEFT | TAT_TITLE,
- value_to_string ((*fs)->id[1], fctr->indep_var[1])
+ var_get_value_name (fctr->indep_var[1], (*fs)->id[1])
);
populate_descriptives (tbl, heading_columns - 2,
tab_text (tbl,
1, row,
TAB_LEFT | TAT_TITLE,
- value_to_string ((*fs)->id[0], fctr->indep_var[0])
+ var_get_value_name (fctr->indep_var[0],
+ (*fs)->id[0])
);
if ( fctr->indep_var[1])
tab_text (tbl, 2, row,
TAB_LEFT | TAT_TITLE,
- value_to_string ((*fs)->id[1], fctr->indep_var[1])
+ var_get_value_name (fctr->indep_var[1], (*fs)->id[1])
);
snprintf (buf2, 100, "%s = %s",
var_to_string (fctr->indep_var[0]),
- value_to_string (fs->id[0], fctr->indep_var[0]));
+ var_get_value_name (fctr->indep_var[0], fs->id[0]));
strcat (buf1, buf2);
{
sprintf (buf2, "; %s = %s)",
var_to_string (fctr->indep_var[1]),
- value_to_string (fs->id[1],
- fctr->indep_var[1]));
+ var_get_value_name (fctr->indep_var[1], fs->id[1]));
strcat (buf1, buf2);
}
else
char buf2[100];
snprintf (buf, 100, "%s",
- value_to_string (fs->id[0], fctr->indep_var[0]));
+ var_get_value_name (fctr->indep_var[0], fs->id[0]));
if ( fctr->indep_var[1] )
{
- sprintf (buf2, ",%s)", value_to_string (fs->id[1], fctr->indep_var[1]) );
+ sprintf (buf2, ",%s)", var_get_value_name (fctr->indep_var[1],
+ fs->id[1]) );
strcat (buf, buf2);
}
flip = pool_create_container (struct flip_pgm, pool);
flip->var = NULL;
- flip->idx_to_fv = dict_get_compacted_idx_to_fv (dict);
+ flip->idx_to_fv = dict_get_compacted_dict_index_to_case_index (dict);
pool_register (flip->pool, free, flip->idx_to_fv);
flip->var_cnt = 0;
flip->case_cnt = 0;
if (flip->new_names != NULL)
{
struct varname *v = pool_alloc (flip->pool, sizeof *v);
+ int fv = flip->idx_to_fv[var_get_dict_index (flip->new_names)];
v->next = NULL;
if (var_is_numeric (flip->new_names))
{
- double f = case_num (c, flip->idx_to_fv[flip->new_names->index]);
+ double f = case_num_idx (c, fv);
if (f == SYSMIS)
strcpy (v->name, "VSYSMIS");
else
{
int width = MIN (var_get_width (flip->new_names), MAX_SHORT_STRING);
- memcpy (v->name, case_str (c, flip->idx_to_fv[flip->new_names->index]),
- width);
+ memcpy (v->name, case_str_idx (c, fv), width);
v->name[width] = 0;
}
{
double out;
- if (var_is_numeric (flip->var[i]))
- out = case_num (c, flip->idx_to_fv[flip->var[i]->index]);
+ if (var_is_numeric (flip->var[i]))
+ {
+ int fv = flip->idx_to_fv[var_get_dict_index (flip->var[i])];
+ out = case_num_idx (c, fv);
+ }
else
out = SYSMIS;
flip->output_buf[i].f = out;
}
for (j = 0; j < flip->case_cnt; j++)
- case_data_rw (c, j)->f = input_buf[j].f;
+ case_data_rw_idx (c, j)->f = input_buf[j].f;
ok = write_case (wc_data);
}
free (input_buf);
#include <data/case.h>
#include <data/dictionary.h>
+#include <data/format.h>
#include <data/procedure.h>
#include <data/settings.h>
#include <data/value-labels.h>
static inline struct var_freqs *
get_var_freqs (const struct variable *v)
{
- assert (v != NULL);
- assert (v->aux != NULL);
- return v->aux;
+ return var_get_aux (v);
}
static void determine_charts (void);
for (i = 0; i < n_variables; i++)
{
const struct variable *v = v_variables[i];
- const union value *val = case_data (c, v->fv);
+ const union value *val = case_data (c, v);
struct var_freqs *vf = get_var_freqs (v);
struct freq_tab *ft = &vf->tab;
sorting a frequency table by FRQ_SORT using VAR_TYPE
variables. */
static hsh_compare_func *
-get_freq_comparator (int frq_sort, int var_type)
+get_freq_comparator (int frq_sort, enum var_type var_type)
{
- /* Note that q2c generates tags beginning with 1000. */
- switch (frq_sort | (var_type << 16))
+ bool is_numeric = var_type == VAR_NUMERIC;
+ switch (frq_sort)
{
- case FRQ_AVALUE | (NUMERIC << 16): return compare_value_numeric_a;
- case FRQ_AVALUE | (ALPHA << 16): return compare_value_alpha_a;
- case FRQ_DVALUE | (NUMERIC << 16): return compare_value_numeric_d;
- case FRQ_DVALUE | (ALPHA << 16): return compare_value_alpha_d;
- case FRQ_AFREQ | (NUMERIC << 16): return compare_freq_numeric_a;
- case FRQ_AFREQ | (ALPHA << 16): return compare_freq_alpha_a;
- case FRQ_DFREQ | (NUMERIC << 16): return compare_freq_numeric_d;
- case FRQ_DFREQ | (ALPHA << 16): return compare_freq_alpha_d;
- default: NOT_REACHED ();
+ case FRQ_AVALUE:
+ return is_numeric ? compare_value_numeric_a : compare_value_alpha_a;
+ case FRQ_DVALUE:
+ return is_numeric ? compare_value_numeric_d : compare_value_alpha_d;
+ case FRQ_AFREQ:
+ return is_numeric ? compare_freq_numeric_a : compare_freq_alpha_a;
+ case FRQ_DFREQ:
+ return is_numeric ? compare_freq_numeric_d : compare_freq_alpha_d;
+ default:
+ NOT_REACHED ();
}
-
- return 0;
}
/* Returns true iff the value in struct freq F is non-missing
struct variable *v = v_variables[i];
struct var_freqs *vf;
- if (v->aux != NULL)
+ if (var_get_aux (v) != NULL)
{
msg (SE, _("Variable %s specified multiple times on VARIABLES "
"subcommand."), var_get_name (v));
}
for (i = 0; i < n; i++)
- if (v[i]->aux == NULL)
+ if (var_get_aux (v[i]) == NULL)
msg (SE, _("Variables %s specified on GROUPED but not on "
"VARIABLES."), var_get_name (v[i]));
else
if (lab)
{
- const char *label = val_labs_find (v->val_labs, f->v[0]);
+ const char *label = var_lookup_value_label (v, &f->v[0]);
if (label != NULL)
tab_text (t, 0, r, TAB_LEFT, label);
}
if (lab)
{
- const char *label = val_labs_find (v->val_labs, f->v[0]);
+ const char *label = var_lookup_value_label (v, &f->v[0]);
if (label != NULL)
tab_text (t, 0, r, TAB_LEFT, label);
}
{
const struct freq *frq = &frq_tab->valid[i];
- slices[i].label = value_to_string(frq->v, var);
+ slices[i].label = var_get_value_name (var, frq->v);
slices[i].magnetude = frq->c;
}
gs = gs_array[count];
tab_text (t, 1, row + count,
- TAB_LEFT | TAT_TITLE ,value_to_string(&gs->id,indep_var));
+ TAB_LEFT | TAT_TITLE, var_get_value_name(indep_var,
+ &gs->id));
/* Now fill in the numbers ... */
group_value = group_values[count];
tab_text (t, count + 2, 1, TAB_CENTER | TAT_TITLE,
- value_to_string(group_value, indep_var));
+ var_get_value_name (indep_var, group_value));
for (i = 0 ; i < cmd.sbc_contrast ; ++i )
{
if ( casefilter_variable_missing (filter, &c, indep_var))
continue;
- indep_val = case_data (&c, indep_var->fv);
+ indep_val = case_data (&c, indep_var);
hsh_insert ( global_group_hash, (void *) indep_val );
{
const struct variable *v = vars[i];
- const union value *val = case_data (&c, v->fv);
+ const union value *val = case_data (&c, v);
struct group_proc *gp = group_proc_get (vars[i]);
struct hsh_table *group_hash = gp->group_hash;
#include "sort-criteria.h"
#include <data/dictionary.h>
+#include <data/format.h>
+#include <data/missing-values.h>
#include <data/procedure.h>
#include <data/variable.h>
#include <data/case.h>
for (i = 0; i < n_splits ; i++)
{
struct variable *v = dict_get_split_vars (dataset_dict (ds))[i];
- criteria.crits[i].fv = v->fv;
+ criteria.crits[i].fv = var_get_case_index (v);
criteria.crits[i].width = var_get_width (v);
criteria.crits[i].dir = SRT_ASCEND;
}
for (i = 0; i < n_group_vars; i++)
{
- criteria.crits[i + n_splits].fv = group_vars[i]->fv;
+ criteria.crits[i + n_splits].fv = var_get_case_index (group_vars[i]);
criteria.crits[i + n_splits].width = var_get_width (group_vars[i]);
criteria.crits[i + n_splits].dir = SRT_ASCEND;
}
/* Sort CF into SORTED_CF. */
reader = casefile_get_destructive_reader (cf) ;
criteria.crits[criteria.crit_cnt - 1] = sc->crits[i];
- assert ( sc->crits[i].fv == src_vars[i]->fv );
+ assert ( sc->crits[i].fv == var_get_case_index (src_vars[i]) );
sorted_cf = sort_execute (reader, &criteria);
casefile_destroy (cf);
if (!casereader_read_xfer (cr, &this_case))
break;
- this_value = case_data (&this_case, fv);
+ this_value = case_data_idx (&this_case, fv);
c = dict_get_case_weight (dict, &this_case, &warn);
lookahead = casereader_clone (cr);
while (casereader_cnum (lookahead) < end
&& casereader_read_xfer (lookahead, &lookahead_case))
{
- const union value *lookahead_value = case_data (&lookahead_case, fv);
+ const union value *lookahead_value = case_data_idx (&lookahead_case, fv);
int diff = compare_values (this_value, lookahead_value, width);
if (diff != 0)
{
for (i = 0; i < n_rank_specs; ++i)
{
- const int dest_idx = rs[i].destvars[dest_var_index]->fv;
+ const struct variable *dst_var = rs[i].destvars[dest_var_index];
if ( value_is_missing (mv, this_value) )
- case_data_rw (&this_case, dest_idx)->f = SYSMIS;
+ case_data_rw (&this_case, dst_var)->f = SYSMIS;
else
- case_data_rw (&this_case, dest_idx)->f =
+ case_data_rw (&this_case, dst_var)->f =
rank_func[rs[i].rfunc](c, cc, cc_1, iter, w);
}
casefile_append_xfer (dest, &this_case);
for (i = 0; i < crit->crit_cnt - 1; i++)
{
struct sort_criterion *c = &crit->crits[i];
- if (compare_values (case_data (a, c->fv), case_data (b, c->fv),
- c->width) != 0)
+ if (compare_values (case_data_idx (a, c->fv),
+ case_data_idx (b, c->fv), c->width) != 0)
return false;
}
struct ccase this_case;
const union value *this_value ;
double w = 0.0;
- this_value = case_data( &group_case, ultimate_crit->fv);
+ this_value = case_data_idx( &group_case, ultimate_crit->fv);
if ( !value_is_missing(mv, this_value) )
w = dict_get_case_weight (dict, &group_case, &warn);
while (casereader_read (lookahead, &this_case))
{
const union value *this_value =
- case_data(&this_case, ultimate_crit->fv);
+ case_data_idx(&this_case, ultimate_crit->fv);
double c = dict_get_case_weight (dict, &this_case, &warn);
if (!same_group (&group_case, &this_case, crit))
{
{
struct variable *key_var = key_var_;
- case_data_rw(cc, key_var->fv)->f = case_num;
+ case_data_rw(cc, key_var)->f = case_num;
return TRNS_CONTINUE;
}
{
struct sort_criteria criteria;
struct sort_criterion restore_criterion ;
- restore_criterion.fv = order->fv;
+ restore_criterion.fv = var_get_case_index (order);
restore_criterion.width = 0;
restore_criterion.dir = SRT_ASCEND;
*/
val = pspp_coeff_get_value (c->coeff[j], v);
- val_s = value_to_string (val, v);
+ val_s = var_get_value_name (v, val);
strncat (tmp, val_s, MAX_STRING);
}
n_vals = (*model->get_vars) (model, vars);
vals = xnmalloc (n_vals, sizeof (*vals));
- output = case_data_rw (c, model->pred->fv);
+ output = case_data_rw (c, model->pred);
assert (output != NULL);
for (i = 0; i < n_vals; i++)
{
- vals[i] = case_data (c, vars[i]->fv);
+ vals[i] = case_data (c, vars[i]);
}
output->f = (*model->predict) ((const struct variable **) vars,
vals, model, n_vals);
n_vals = (*model->get_vars) (model, vars);
vals = xnmalloc (n_vals, sizeof (*vals));
- output = case_data_rw (c, model->resid->fv);
+ output = case_data_rw (c, model->resid);
assert (output != NULL);
for (i = 0; i < n_vals; i++)
{
- vals[i] = case_data (c, vars[i]->fv);
+ vals[i] = case_data (c, vars[i]);
}
- obs = case_data (c, model->depvar->fv);
+ obs = case_data (c, model->depvar);
output->f = (*model->residual) ((const struct variable **) vars,
vals, obs, model, n_vals);
free (vals);
reg_print_categorical_encoding (FILE * fp, pspp_linreg_cache * c)
{
int i;
- size_t j;
int n_vars = 0;
struct variable **varlist;
- struct pspp_coeff *coeff;
- const struct variable *v;
- union value *val;
fprintf (fp, "%s", reg_export_categorical_encode_1);
varlist = xnmalloc (c->n_indeps, sizeof (*varlist));
for (i = 1; i < c->n_indeps; i++) /* c->coeff[0] is the intercept. */
{
- coeff = c->coeff[i];
- v = pspp_coeff_get_var (coeff, 0);
+ struct pspp_coeff *coeff = c->coeff[i];
+ const struct variable *v = pspp_coeff_get_var (coeff, 0);
if (var_is_alpha (v))
{
if (!reg_inserted (v, varlist, n_vars))
for (i = 0; i < n_vars; i++)
{
- coeff = c->coeff[i];
+ size_t n_categories = cat_get_n_categories (varlist[i]);
+ size_t j;
+
fprintf (fp, "%s.name = \"%s\";\n\t",
var_get_name (varlist[i]),
var_get_name (varlist[i]));
fprintf (fp, "%s.n_vals = %d;\n\t",
var_get_name (varlist[i]),
- varlist[i]->obs_vals->n_categories);
+ n_categories);
- for (j = 0; j < varlist[i]->obs_vals->n_categories; j++)
+ for (j = 0; j < n_categories; j++)
{
- val = cat_subscript_to_value ((const size_t) j, varlist[i]);
+ union value *val = cat_subscript_to_value (j, varlist[i]);
fprintf (fp, "%s.values[%d] = \"%s\";\n\t",
var_get_name (varlist[i]), j,
- value_to_string (val, varlist[i]));
+ var_get_value_name (varlist[i], val));
}
}
fprintf (fp, "%s", reg_export_categorical_encode_2);
static bool
is_depvar (size_t k, const struct variable *v)
{
- /*
- compare_var_names returns 0 if the variable
- names match.
- */
- if (!compare_var_names (v, v_variables[k], NULL))
- return true;
-
- return false;
+ return v == v_variables[k];
}
/*
{
row = casereader_cnum (r) - 1;
- val = case_data (&c, v->fv);
+ val = case_data (&c, v);
cat_value_update (v, val);
if (var_is_value_missing (v, val))
{
current case.
*/
{
- val = case_data (&c, v_variables[i]->fv);
+ val = case_data (&c, v_variables[i]);
/*
Independent/dependent variable separation. The
'variables' subcommand specifies a varlist which contains
}
}
}
- val = case_data (&c, cmd.v_dependent[k]->fv);
+ val = case_data (&c, cmd.v_dependent[k]);
gsl_vector_set (Y, row, val->f);
row++;
}
for (; prev_var_cnt < criteria->crit_cnt; prev_var_cnt++)
{
struct sort_criterion *c = &criteria->crits[prev_var_cnt];
- c->fv = (*vars)[prev_var_cnt]->fv;
+ c->fv = var_get_case_index ((*vars)[prev_var_cnt]);
c->width = var_get_width ((*vars)[prev_var_cnt]);
c->dir = direction;
}
static struct pair *pairs=0;
-static int parse_value (struct lexer *lexer, union value * v, int type) ;
+static int parse_value (struct lexer *lexer, union value * v, enum var_type);
/* Structures and Functions for the Statistics Summary Box */
struct ssbox;
struct hsh_table *hash;
struct variable *v;
- hash = hsh_create (n_pairs, compare_var_names, hash_var_name, 0, 0);
+ hash = hsh_create (n_pairs, compare_vars_by_name, hash_var_by_name,
+ 0, 0);
for (i=0; i < n_pairs; ++i)
{
/* Parses the current token (numeric or string, depending on type)
value v and returns success. */
static int
-parse_value (struct lexer *lexer, union value * v, int type )
+parse_value (struct lexer *lexer, union value * v, enum var_type type)
{
- if (type == NUMERIC)
+ if (type == VAR_NUMERIC)
{
if (!lex_force_num (lexer))
return 0;
{
int i;
- char *val_lab0=0;
- char *val_lab1=0;
+ const char *val_lab0;
+ const char *val_lab1;
double indep_value[2];
char prefix[2][3]={"",""};
if ( var_is_numeric (indep_var) )
{
- val_lab0 = val_labs_find( indep_var->val_labs,gp.v.g_value[0]);
- val_lab1 = val_labs_find( indep_var->val_labs,gp.v.g_value[1]);
+ val_lab0 = var_lookup_value_label (indep_var, &gp.v.g_value[0]);
+ val_lab1 = var_lookup_value_label (indep_var, &gp.v.g_value[1]);
}
else
{
if (! casefilter_variable_missing (filter, c, v) )
{
struct group_statistics *gs;
- const union value *val = case_data (c, v->fv);
+ const union value *val = case_data (c, v);
gs = &group_proc_get (cmd->v_variables[i])->ugs;
gs->n += weight;
{
struct group_statistics *gs;
struct variable *v = cmd->v_variables[i];
- const union value *val = case_data (c, v->fv);
+ const union value *val = case_data (c, v);
gs= &group_proc_get (cmd->v_variables[i])->ugs;
struct variable *v0 = pairs[i].v[0];
struct variable *v1 = pairs[i].v[1];
- const union value *val0 = case_data (c, v0->fv);
- const union value *val1 = case_data (c, v1->fv);
+ const union value *val0 = case_data (c, v0);
+ const union value *val1 = case_data (c, v1);
if ( ! casefilter_variable_missing (filter, c, v0) &&
! casefilter_variable_missing (filter, c, v1) )
if ( casefilter_variable_missing (filter, c, indep_var))
return 0;
- gv = case_data (c, indep_var->fv);
+ gv = case_data (c, indep_var);
for(i=0; i< cmd->n_variables ; ++i)
{
struct variable *var = cmd->v_variables[i];
- const union value *val = case_data (c, var->fv);
+ const union value *val = case_data (c, var);
struct hsh_table *grp_hash = group_proc_get (var)->group_hash;
struct group_statistics *gs;
fail_test ("Premature end of casefile.");
for (j = 0; j < value_cnt; j++)
{
- double a = case_num (&read_case, j);
- double b = case_num (&expected_case, j);
+ double a = case_num_idx (&read_case, j);
+ double b = case_num_idx (&expected_case, j);
if (a != b)
fail_test ("Case %lu fails comparison.", (unsigned long) i);
}
int i;
case_create (c, value_cnt);
for (i = 0; i < value_cnt; i++)
- case_data_rw (c, i)->f = case_idx % 257 + i;
+ case_data_rw_idx (c, i)->f = case_idx % 257 + i;
}
static void
fail_test ("Premature end of casefile.");
for (i = 0; i < value_cnt; i++)
{
- double a = case_num (&read_case, i);
- double b = case_num (&expected_case, i);
+ double a = case_num_idx (&read_case, i);
+ double b = case_num_idx (&expected_case, i);
if (a != b)
fail_test ("Case %lu fails comparison.", (unsigned long) case_idx);
}
#include <data/format.h>
#include <data/procedure.h>
#include <data/settings.h>
+#include <data/value.h>
#include <data/variable.h>
#include <language/command.h>
#include <language/lexer/format-parser.h>
+Sat Dec 9 18:48:20 2006 Ben Pfaff <blp@gnu.org>
+
+ * compute.c (struct compute_trns): Remove `fv' member, which was
+ redundant with `variable'.
+
Thu Nov 30 22:46:50 2006 Ben Pfaff <blp@gnu.org>
* compute.c: Fix bug #17422, which reports that a variable created
#include <data/procedure.h>
#include <data/transformations.h>
#include <data/variable.h>
+#include <data/vector.h>
#include <language/command.h>
#include <language/expressions/public.h>
#include <language/lexer/lexer.h>
/* Variable lvalue, if variable != NULL. */
struct variable *variable; /* Destination variable, if any. */
- int fv; /* `value' index of destination variable. */
int width; /* Lvalue string width; 0=numeric. */
/* Vector lvalue, if vector != NULL. */
if (compute->test == NULL
|| expr_evaluate_num (compute->test, c, case_num) == 1.0)
- case_data_rw (c, compute->fv)->f = expr_evaluate_num (compute->rvalue, c,
- case_num);
+ case_data_rw (c, compute->variable)->f
+ = expr_evaluate_num (compute->rvalue, c, case_num);
return TRNS_CONTINUE;
}
index = expr_evaluate_num (compute->element, c, case_num);
rindx = floor (index + EPSILON);
- if (index == SYSMIS || rindx < 1 || rindx > compute->vector->cnt)
+ if (index == SYSMIS
+ || rindx < 1 || rindx > vector_get_var_cnt (compute->vector))
{
if (index == SYSMIS)
- msg (SW, _("When executing COMPUTE: SYSMIS is not a valid value as "
- "an index into vector %s."), compute->vector->name);
+ msg (SW, _("When executing COMPUTE: SYSMIS is not a valid value "
+ "as an index into vector %s."),
+ vector_get_name (compute->vector));
else
msg (SW, _("When executing COMPUTE: %g is not a valid value as "
"an index into vector %s."),
- index, compute->vector->name);
+ index, vector_get_name (compute->vector));
return TRNS_CONTINUE;
}
- case_data_rw (c, compute->vector->var[rindx - 1]->fv)->f
+ case_data_rw (c, vector_get_var (compute->vector, rindx - 1))->f
= expr_evaluate_num (compute->rvalue, c, case_num);
}
if (compute->test == NULL
|| expr_evaluate_num (compute->test, c, case_num) == 1.0)
expr_evaluate_str (compute->rvalue, c, case_num,
- case_data_rw (c, compute->fv)->s, compute->width);
+ case_data_rw (c, compute->variable)->s, compute->width);
return TRNS_CONTINUE;
}
{
msg (SW, _("When executing COMPUTE: SYSMIS is not a valid "
"value as an index into vector %s."),
- compute->vector->name);
+ vector_get_name (compute->vector));
return TRNS_CONTINUE;
}
- else if (rindx < 1 || rindx > compute->vector->cnt)
+ else if (rindx < 1 || rindx > vector_get_var_cnt (compute->vector))
{
msg (SW, _("When executing COMPUTE: %g is not a valid value as "
"an index into vector %s."),
- index, compute->vector->name);
+ index, vector_get_name (compute->vector));
return TRNS_CONTINUE;
}
- vr = compute->vector->var[rindx - 1];
+ vr = vector_get_var (compute->vector, rindx - 1);
expr_evaluate_str (compute->rvalue, c, case_num,
- case_data_rw (c, vr->fv)->s, var_get_width (vr));
+ case_data_rw (c, vr)->s,
+ var_get_width (vr));
}
return TRNS_CONTINUE;
static trns_proc_func *
get_proc_func (const struct lvalue *lvalue)
{
- bool is_numeric = lvalue_get_type (lvalue) == NUMERIC;
+ bool is_numeric = lvalue_get_type (lvalue) == VAR_NUMERIC;
bool is_vector = lvalue_is_vector (lvalue);
return (is_numeric
parse_rvalue (struct lexer *lexer,
const struct lvalue *lvalue, struct dataset *ds)
{
- bool is_numeric = lvalue_get_type (lvalue) == NUMERIC;
+ bool is_numeric = lvalue_get_type (lvalue) == VAR_NUMERIC;
return expr_parse (lexer, ds, is_numeric ? EXPR_NUMBER : EXPR_STRING);
}
{
return (lvalue->variable != NULL
? var_get_type (lvalue->variable)
- : var_get_type (lvalue->vector->var[0]));
+ : vector_get_type (lvalue->vector));
}
/* Returns true if LVALUE has a vector as its target. */
if (lvalue->vector == NULL)
{
compute->variable = lvalue->variable;
- compute->fv = compute->variable->fv;
compute->width = var_get_width (compute->variable);
/* Goofy behavior, but compatible: Turn off LEAVE. */
- if (dict_class_from_id (var_get_name (compute->variable)) != DC_SCRATCH)
- compute->variable->leave = false;
+ if (!var_must_leave (compute->variable))
+ var_set_leave (compute->variable, false);
/* Prevent lvalue_destroy from deleting variable. */
lvalue->is_new_variable = false;
for (i = 0; i < crit->var_cnt; i++)
{
- double x = case_num (c, crit->vars[i]->fv);
+ double x = case_num (c, crit->vars[i]);
if (x == SYSMIS)
counter += crit->count_system_missing;
else if (crit->count_user_missing
{
char **v;
for (v = crit->values.str; v < crit->values.str + crit->value_cnt; v++)
- if (!memcmp (case_str (c, crit->vars[i]->fv), *v,
+ if (!memcmp (case_str (c, crit->vars[i]), *v,
var_get_width (crit->vars[i])))
{
counter++;
counter += count_numeric (crit, c);
else
counter += count_string (crit, c);
- case_data_rw (c, dv->var->fv)->f = counter;
+ case_data_rw (c, dv->var)->f = counter;
}
return TRNS_CONTINUE;
}
/* Ensure that all the output strings are at least as wide
as the widest destination variable. */
- if (trns->dst_type == ALPHA)
+ if (trns->dst_type == VAR_STRING)
enlarge_dst_widths (trns);
/* Create destination variables, if needed.
if (!parse_map_out (lexer, trns->pool, &out))
return false;
- dst_type = out.width == 0 ? NUMERIC : ALPHA;
+ dst_type = var_type_from_width (out.width);
if (have_dst_type && dst_type != trns->dst_type)
{
msg (SE, _("Inconsistent target variable types. "
set_map_in_generic (&in, MAP_CONVERT);
add_mapping (trns, &map_allocated, &in);
- dst_type = NUMERIC;
- if (trns->src_type != ALPHA
- || (have_dst_type && trns->dst_type != NUMERIC))
+ dst_type = VAR_NUMERIC;
+ if (trns->src_type != VAR_STRING
+ || (have_dst_type && trns->dst_type != VAR_NUMERIC))
{
msg (SE, _("CONVERT requires string input values and "
"numeric output values."));
{
if (lex_match_id (lexer, "ELSE"))
set_map_in_generic (in, MAP_ELSE);
- else if (src_type == NUMERIC)
+ else if (src_type == VAR_NUMERIC)
{
if (lex_match_id (lexer, "MISSING"))
set_map_in_generic (in, MAP_MISSING);
{
struct variable *v;
v = trns->dst_vars[i] = dict_lookup_var (dict, trns->dst_names[i]);
- if (v == NULL && trns->dst_type == ALPHA)
+ if (v == NULL && trns->dst_type == VAR_STRING)
{
msg (SE, _("There is no variable named "
"%s. (All string variables specified "
{
msg (SE, _("INTO is required with %s input values "
"and %s output values."),
- var_type_adj (trns->src_type),
- var_type_adj (trns->dst_type));
+ trns->src_type == VAR_NUMERIC ? _("numeric") : _("string"),
+ trns->dst_type == VAR_NUMERIC ? _("numeric") : _("string"));
return false;
}
}
{
msg (SE, _("Type mismatch. Cannot store %s data in "
"%s variable %s."),
- trns->dst_type == ALPHA ? _("string") : _("numeric"),
+ trns->dst_type == VAR_STRING ? _("string") : _("numeric"),
var_is_alpha (v) ? _("string") : _("numeric"),
var_get_name (v));
return false;
struct variable *src_var = trns->src_vars[i];
struct variable *dst_var = trns->dst_vars[i];
- const union value *src_data = case_data (c, src_var->fv);
- union value *dst_data = case_data_rw (c, dst_var->fv);
+ const union value *src_data = case_data (c, src_var);
+ union value *dst_data = case_data_rw (c, dst_var);
const struct map_out *out;
- if (trns->src_type == NUMERIC)
+ if (trns->src_type == VAR_NUMERIC)
out = find_src_numeric (trns, src_data->f, src_var);
else
out = find_src_string (trns, src_data->s, var_get_width (src_var));
- if (trns->dst_type == NUMERIC)
+ if (trns->dst_type == VAR_NUMERIC)
{
if (out != NULL)
dst_data->f = !out->copy_input ? out->value.f : src_data->f;
+Sat Dec 9 18:48:55 2006 Ben Pfaff <blp@gnu.org>
+
+ * misc.h (macro range): Removed, as it was unused.
+
Sat Dec 9 07:19:01 WST 2006 John Darrington <john@darrington.wattle.id.au>
* array.c: Removed gratuitous #include
#include <ieeefp.h> /* Declares finite() under Solaris. */
#endif
-/* Clamps A to be between B and C. */
-#define range(A, B, C) ((A) < (B) ? (B) : ((A) > (C) ? (C) : (A)))
-
/* Divides nonnegative X by positive Y, rounding up. */
#define DIV_RND_UP(X, Y) (((X) + ((Y) - 1)) / (Y))
#include <libpspp/message.h>
#include <data/variable.h>
#include <data/category.h>
+#include <data/value.h>
#include <gsl/gsl_machine.h>
#include <gsl/gsl_vector.h>
}
else if (var_is_alpha (v))
{
- assert (v->obs_vals != NULL);
+ struct cat_vals *obs_vals = var_get_obs_vals (v);
(dm->vars + i)->last_column =
- (dm->vars + i)->first_column + v->obs_vals->n_categories - 2;
- n_cols += v->obs_vals->n_categories - 1;
+ (dm->vars + i)->first_column + obs_vals->n_categories - 2;
+ n_cols += obs_vals->n_categories - 1;
}
}
dm->m = gsl_matrix_calloc (n_data, n_cols);
group_proc_get (struct variable *v)
{
/* This is not ideal, obviously. */
- if (v->aux == NULL)
- var_attach_aux (v, xmalloc (sizeof (struct group_proc)), var_dtor_free);
- return v->aux;
+ struct group_proc *group = var_get_aux (v);
+ if (group == NULL)
+ {
+ group = xmalloc (sizeof (struct group_proc));
+ var_attach_aux (v, group, var_dtor_free);
+ }
+ return group;
}
{
size_t i;
bool warn = false;
- const union value *gv = case_data (c, l->v_indep->fv);
+ const union value *gv = case_data (c, l->v_indep);
struct group_statistics key;
double weight = dict_get_case_weight (dict, c, &warn);
struct variable *var = l->v_dep[i];
struct group_proc *gp = group_proc_get (var);
double levene_z;
- const union value *v = case_data (c, var->fv);
+ const union value *v = case_data (c, var);
struct group_statistics *gs;
gs = hsh_find(gp->group_hash,(void *) &key );
double weight = dict_get_case_weight (dict, c, &warn);
- const union value *gv = case_data (c, l->v_indep->fv);
+ const union value *gv = case_data (c, l->v_indep);
struct group_statistics key;
key.id = *gv;
{
double levene_z;
struct variable *var = l->v_dep[i] ;
- const union value *v = case_data (c, var->fv);
+ const union value *v = case_data (c, var);
struct group_statistics *gs;
gs = hsh_find(group_proc_get (var)->group_hash,(void *) &key );
if (c->width == 0)
{
- double af = case_num (a, c->fv);
- double bf = case_num (b, c->fv);
+ double af = case_num_idx (a, c->fv);
+ double bf = case_num_idx (b, c->fv);
result = af < bf ? -1 : af > bf;
}
else
- result = memcmp (case_str (a, c->fv), case_str (b, c->fv), c->width);
+ result = memcmp (case_str_idx (a, c->fv),
+ case_str_idx (b, c->fv), c->width);
if (result != 0)
return c->dir == SRT_ASCEND ? result : -result;
#include <data/data-out.h>
#include <data/format.h>
-#include <data/variable.h>
+#include <data/value.h>
#include <libpspp/alloc.h>
#include <libpspp/assertion.h>
#include <libpspp/compiler.h>
case_copy (&c, 0, &ff->cases[i], 0, posn);
if ( n_values > 0 )
- memset (case_data_rw(&c, posn), ' ', n_values * MAX_SHORT_STRING) ;
+ memset (case_data_rw_idx(&c, posn), ' ', n_values * MAX_SHORT_STRING) ;
case_copy (&c, posn + n_values,
&ff->cases[i], posn, ff->value_cnt - posn);
+#include <config.h>
+
#include "helper.h"
#include <data/data-in.h>
#include <data/data-out.h>
gtk_widget_set_sensitive(dialog->discrete, FALSE);
gtk_widget_set_sensitive(GTK_WIDGET(dialog->button_range),
- psppire_variable_get_type(dialog->pv) == NUMERIC);
+ psppire_variable_get_type(dialog->pv) == VAR_NUMERIC);
for(i = 0 ; i < 3 ; ++i )
{
flexifile_get_case(FLEXIFILE(cf->flexifile), casenum, &c);
- v = case_data(&c, idx);
+ v = case_data_idx(&c, idx);
case_destroy(&c);
bytes = DIV_RND_UP(width, MAX_SHORT_STRING) * MAX_SHORT_STRING ;
/* Cast away const in flagrant abuse of the casefile */
- memcpy((union value *)case_data(&cc, idx), v, bytes);
+ memcpy((union value *)case_data_idx(&cc, idx), v, bytes);
g_signal_emit(cf, signal[CASE_CHANGED], 0, casenum);
/* Cast away const in flagrant abuse of the casefile */
if (!data_in (input, fmt->type, 0, 0,
- (union value *) case_data(&cc, idx), fmt_var_width (fmt)))
+ (union value *) case_data_idx(&cc, idx), fmt_var_width (fmt)))
g_warning("Cant set value\n");
g_signal_emit(cf, signal[CASE_CHANGED], 0, casenum);
for (v = 0 ; v < psppire_dict_get_var_cnt (ds->dict) ; ++v)
{
const struct PsppireVariable *pv = psppire_dict_get_variable(ds->dict, v);
- if (ALPHA == psppire_variable_get_type(pv) )
+ if (VAR_STRING == psppire_variable_get_type(pv) )
continue;
- case_data_rw (&cc, psppire_variable_get_fv (pv))->f = SYSMIS;
+ case_data_rw_idx (&cc, psppire_variable_get_fv (pv))->f = SYSMIS;
}
result = psppire_case_file_insert_case (ds->case_file, &cc, posn);
const gint index = psppire_variable_get_fv(pv) ;
- if ( psppire_variable_get_type(pv) == NUMERIC)
+ if ( psppire_variable_get_type(pv) == VAR_NUMERIC)
v.f = SYSMIS;
else
memcpy(v.s, "", MAX_SHORT_STRING);
if ( !pv )
return TRUE;
- if ( ALPHA == psppire_variable_get_type(pv) && column == COL_DECIMALS )
+ if ( VAR_STRING == psppire_variable_get_type(pv) && column == COL_DECIMALS )
return FALSE;
write_spec = psppire_variable_get_write_spec(pv);
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
+#include <config.h>
+
#include <string.h>
#include <stdlib.h>
dict_rename_var(pv->dict->dict, pv->v, text);
- psppire_dict_var_changed(pv->dict, pv->v->index);
+ psppire_dict_var_changed(pv->dict, var_get_dict_index (pv->v));
return TRUE;
}
var_set_display_width (pv->v, columns);
- psppire_dict_var_changed(pv->dict, pv->v->index);
+ psppire_dict_var_changed(pv->dict, var_get_dict_index (pv->v));
return TRUE;
}
var_set_label (pv->v, label);
- psppire_dict_var_changed(pv->dict, pv->v->index);
+ psppire_dict_var_changed(pv->dict, var_get_dict_index (pv->v));
return TRUE;
}
old_var_cnt = DIV_RND_UP(var_get_width (pv->v), MAX_SHORT_STRING);
new_var_cnt = DIV_RND_UP(width, MAX_SHORT_STRING);
- pv->v->width = width;
+ var_set_width (pv->v, width);
psppire_dict_resize_variable(pv->dict, pv,
old_var_cnt, new_var_cnt);
else
old_var_cnt = DIV_RND_UP (var_get_width (pv->v), MAX_SHORT_STRING);
- if ( type == NUMERIC )
- pv->v->width = 0;
- else if (var_get_width (pv->v))
- pv->v->width = 1;
+ var_set_width (pv->v, type == VAR_NUMERIC ? 0 : 1);
if ( var_get_width (pv->v) == 0 )
new_var_cnt = 1;
psppire_dict_resize_variable(pv->dict, pv,
old_var_cnt, new_var_cnt);
- psppire_dict_var_changed(pv->dict, pv->v->index);
+ psppire_dict_var_changed(pv->dict, var_get_dict_index (pv->v));
return TRUE;
}
{
msg_enable ();
var_set_both_formats (pv->v, fmt);
- psppire_dict_var_changed(pv->dict, pv->v->index);
+ psppire_dict_var_changed(pv->dict, var_get_dict_index (pv->v));
return TRUE;
}
msg_enable ();
g_return_val_if_fail(pv->dict, FALSE);
g_return_val_if_fail(pv->v, FALSE);
- val_labs_destroy(pv->v->val_labs);
- pv->v->val_labs = val_labs_copy(vls);
+ var_set_value_labels (pv->v, vls);
- psppire_dict_var_changed(pv->dict, pv->v->index);
+ psppire_dict_var_changed(pv->dict, var_get_dict_index (pv->v));
return TRUE;
}
var_set_missing_values (pv->v, miss);
- psppire_dict_var_changed(pv->dict, pv->v->index);
+ psppire_dict_var_changed(pv->dict, var_get_dict_index (pv->v));
return TRUE;
}
var_set_write_format (pv->v, &fmt);
- psppire_dict_var_changed(pv->dict, pv->v->index);
+ psppire_dict_var_changed(pv->dict, var_get_dict_index (pv->v));
return TRUE;
}
var_set_print_format (pv->v, &fmt);
- psppire_dict_var_changed(pv->dict, pv->v->index);
+ psppire_dict_var_changed(pv->dict, var_get_dict_index (pv->v));
return TRUE;
}
var_set_alignment (pv->v, align);
- psppire_dict_var_changed(pv->dict, pv->v->index);
+ psppire_dict_var_changed(pv->dict, var_get_dict_index (pv->v));
return TRUE;
}
var_set_measure (pv->v, measure + 1);
- psppire_dict_var_changed(pv->dict, pv->v->index);
+ psppire_dict_var_changed(pv->dict, var_get_dict_index (pv->v));
return TRUE;
}
g_return_val_if_fail(pv, NULL);
g_return_val_if_fail(pv->v, NULL);
- return pv->v->val_labs;
+ return var_get_value_labels (pv->v);
}
g_return_val_if_fail(pv, -1);
g_return_val_if_fail(pv->v, -1);
- return pv->v->fv;
+ return var_get_case_index (pv->v);
}
g_return_val_if_fail(pv, -1);
g_return_val_if_fail(pv->v, -1);
- return pv->v->index;
+ return var_get_dict_index (pv->v);
}
#include <data/variable.h>
#include "psppire-dict.h"
+struct val_labs;
+
/* Don't use any of these members.
Use accessor functions instead.
*/
/* This module describes the behaviour of the Value Labels dialog box,
used for input of the value labels in the variable sheet */
+#include <config.h>
+
#include <string.h>
#include "helper.h"
{
case COL_WIDTH:
r_min = fmt->d + 1;
- r_max = (psppire_variable_get_type(pv) == ALPHA) ? MAX_STRING : 40;
+ r_max = (psppire_variable_get_type(pv) == VAR_STRING) ? MAX_STRING : 40;
break;
case COL_DECIMALS:
r_min = 0 ;
gint decimals = atoi(gtk_entry_get_text
(GTK_ENTRY(dialog->entry_decimals)));
- gint new_type = NUMERIC;
+ gint new_type = VAR_NUMERIC;
gint new_width = 0;
bool result = false;
struct fmt_spec spec;
switch (dialog->active_button)
{
case BUTTON_STRING:
- new_type = ALPHA;
+ new_type = VAR_STRING;
new_width = width;
result = make_output_format_try(&spec, FMT_A, width, 0);
break;