X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fdictionary.c;h=ebe6a5e5d100b829f22e5943c12c0027755ebb59;hb=3a61659a8fc11c51ad5af02b20f5613dcde50382;hp=d2d93c3bd2f535d59dac071f0ce4fbe2f57d7772;hpb=985c40f2a83588b25f0e6fe7f7d82863c5d34d43;p=pspp-builds.git diff --git a/src/data/dictionary.c b/src/data/dictionary.c index d2d93c3b..ebe6a5e5 100644 --- a/src/data/dictionary.c +++ b/src/data/dictionary.c @@ -18,22 +18,25 @@ 02110-1301, USA. */ #include + #include "dictionary.h" + #include #include -#include -#include + #include "case.h" -#include "category.h" #include "cat-routines.h" +#include "category.h" +#include "settings.h" +#include "value-labels.h" +#include "variable.h" +#include +#include #include -#include #include +#include #include -#include "settings.h" #include -#include "value-labels.h" -#include "variable.h" #include "gettext.h" #define _(msgid) gettext (msgid) @@ -49,16 +52,13 @@ struct dictionary size_t split_cnt; /* SPLIT FILE count. */ struct variable *weight; /* WEIGHT variable. */ struct variable *filter; /* FILTER variable. */ - int case_limit; /* Current case limit (N command). */ + size_t case_limit; /* Current case limit (N command). */ char *label; /* File label. */ char *documents; /* Documents, as a string. */ struct vector **vector; /* Vectors of variables. */ size_t vector_cnt; /* Number of vectors. */ }; -/* Active file dictionary. */ -struct dictionary *default_dict; - /* Creates and returns a new dictionary. */ struct dictionary * dict_create (void) @@ -267,7 +267,7 @@ dict_create_var (struct dictionary *d, const char *name, int width) assert (d != NULL); assert (name != NULL); - assert (width >= 0 && width < 256); + assert (width >= 0 && width <= MAX_STRING); assert (var_is_plausible_name(name,0)); @@ -281,21 +281,20 @@ dict_create_var (struct dictionary *d, const char *name, int width) v->type = width == 0 ? NUMERIC : ALPHA; v->width = width; v->fv = d->next_value_idx; - v->nv = width == 0 ? 1 : DIV_RND_UP (width, 8); - v->init = 1; - v->reinit = dict_class_from_id (v->name) != DC_SCRATCH; + v->nv = width == 0 ? 1 : DIV_RND_UP (width, MAX_SHORT_STRING); + v->leave = dict_class_from_id (v->name) == DC_SCRATCH; v->index = d->var_cnt; mv_init (&v->miss, width); if (v->type == NUMERIC) { - v->print = f8_2; + v->print = fmt_for_output (FMT_F, 8, 2); v->alignment = ALIGN_RIGHT; v->display_width = 8; v->measure = MEASURE_SCALE; } else { - v->print = make_output_format (FMT_A, v->width, 0); + v->print = fmt_for_output (FMT_A, v->width, 0); v->alignment = ALIGN_LEFT; v->display_width = 8; v->measure = MEASURE_NOMINAL; @@ -359,8 +358,7 @@ dict_clone_var (struct dictionary *d, const struct variable *ov, 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->init = 1; - nv->reinit = ov->reinit; + nv->leave = ov->leave; mv_copy (&nv->miss, &ov->miss); nv->print = ov->print; nv->write = ov->write; @@ -426,7 +424,7 @@ dict_contains_var (const struct dictionary *d, const struct variable *v) /* Compares two double pointers to variables, which should point to elements of a struct dictionary's `var' member array. */ static int -compare_var_ptrs (const void *a_, const void *b_, void *aux UNUSED) +compare_var_ptrs (const void *a_, const void *b_, const void *aux UNUSED) { struct variable *const *a = a_; struct variable *const *b = b_; @@ -437,8 +435,8 @@ compare_var_ptrs (const void *a_, const void *b_, void *aux UNUSED) /* Deletes variable V from dictionary D and frees V. This is a very bad idea if there might be any pointers to V - from outside D. In general, no variable in default_dict - should be deleted when any transformations are active, because + from outside D. In general, no variable in should be deleted when + any transformations are active on the dictionary's dataset, because those transformations might reference the deleted variable. The safest time to delete a variable is just after a procedure has been executed, as done by MODIFY VARS. @@ -689,11 +687,11 @@ dict_get_weight (const struct dictionary *d) /* Returns the value of D's weighting variable in case C, except that a negative weight is returned as 0. Returns 1 if the dictionary is unweighted. Will warn about missing, negative, or zero values if - warn_on_invalid is nonzero. The function will set warn_on_invalid to zero + warn_on_invalid is true. The function will set warn_on_invalid to false if an invalid weight is found. */ double dict_get_case_weight (const struct dictionary *d, const struct ccase *c, - int *warn_on_invalid) + bool *warn_on_invalid) { assert (d != NULL); assert (c != NULL); @@ -706,7 +704,7 @@ dict_get_case_weight (const struct dictionary *d, const struct ccase *c, if (w < 0.0 || mv_is_num_missing (&d->weight->miss, w)) w = 0.0; if ( w == 0.0 && *warn_on_invalid ) { - *warn_on_invalid = 0; + *warn_on_invalid = false; msg (SW, _("At least one case in the data file had a weight value " "that was user-missing, system-missing, zero, or " "negative. These case(s) were ignored.")); @@ -750,8 +748,8 @@ dict_set_filter (struct dictionary *d, struct variable *v) } /* Returns the case limit for dictionary D, or zero if the number - of cases is unlimited (see cmd_n()). */ -int + of cases is unlimited. */ +size_t dict_get_case_limit (const struct dictionary *d) { assert (d != NULL); @@ -759,13 +757,12 @@ dict_get_case_limit (const struct dictionary *d) return d->case_limit; } -/* Sets CASE_LIMIT as the case limit for dictionary D. Zero for - CASE_LIMIT indicates no limit. */ +/* Sets CASE_LIMIT as the case limit for dictionary D. Use + 0 for CASE_LIMIT to indicate no limit. */ void -dict_set_case_limit (struct dictionary *d, int case_limit) +dict_set_case_limit (struct dictionary *d, size_t case_limit) { assert (d != NULL); - assert (case_limit >= 0); d->case_limit = case_limit; } @@ -858,19 +855,44 @@ dict_get_compacted_idx_to_fv (const struct dictionary *d) } /* Returns true if a case for dictionary D would be smaller after - compaction, false otherwise. Compacting a case eliminates + compacting, false otherwise. Compacting a case eliminates "holes" between values and after the last value. Holes are created by deleting variables (or by scratch variables). The return value may differ from whether compacting a case - from dictionary D would *change* the case: compaction could + from dictionary D would *change* the case: compacting could rearrange values even if it didn't reduce space requirements. */ bool -dict_needs_compaction (const struct dictionary *d) +dict_compacting_would_shrink (const struct dictionary *d) { return dict_get_compacted_value_cnt (d) < dict_get_next_value_idx (d); } + +/* Returns true if a case for dictionary D would change after + compacting, false otherwise. Compacting a case eliminates + "holes" between values and after the last value. Holes are + created by deleting variables (or by scratch variables). + + The return value may differ from whether compacting a case + from dictionary D would *shrink* the case: compacting could + rearrange values without reducing space requirements. */ +bool +dict_compacting_would_change (const struct dictionary *d) +{ + size_t case_idx; + size_t i; + + case_idx = 0; + for (i = 0; i < dict_get_var_cnt (d); i++) + { + struct variable *v = dict_get_var (d, i); + if (v->fv != case_idx) + return true; + case_idx += v->nv; + } + return false; +} /* How to copy a contiguous range of values between cases. */ struct copy_map @@ -1142,14 +1164,14 @@ dict_clear_vectors (struct dictionary *d) /* Compares two strings. */ static int -compare_strings (const void *a, const void *b, void *aux UNUSED) +compare_strings (const void *a, const void *b, const void *aux UNUSED) { return strcmp (a, b); } /* Hashes a string. */ static unsigned -hash_string (const void *s, void *aux UNUSED) +hash_string (const void *s, const void *aux UNUSED) { return hsh_hash_string (s); }