From f5eee9d8478b154444bb0eede53fb892b8130974 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 7 May 2006 02:04:12 +0000 Subject: [PATCH] Some more cleanup with value labels. --- src/data/ChangeLog | 7 ++++ src/data/value-labels.c | 48 +++++++++++++++++++--- src/data/value-labels.h | 5 ++- src/language/data-io/ChangeLog | 4 ++ src/language/data-io/get.c | 7 +++- src/language/dictionary/ChangeLog | 5 +++ src/language/dictionary/apply-dictionary.c | 33 +-------------- 7 files changed, 68 insertions(+), 41 deletions(-) diff --git a/src/data/ChangeLog b/src/data/ChangeLog index 0c6215d0..c34816a2 100644 --- a/src/data/ChangeLog +++ b/src/data/ChangeLog @@ -1,3 +1,10 @@ +Sat May 6 19:02:00 2006 Ben Pfaff + + * value-labels.c (val_labs_can_set_width): New function. + (val_labs_set_width) Clear labels if increasing width to long + string. + (val_labs_destroy) Remove unneeded test for null. + Sat May 6 16:14:08 2006 Ben Pfaff * value-labels.h: Remove unneeded dependency on variable.h. diff --git a/src/data/value-labels.c b/src/data/value-labels.c index 594518e0..b9c85d54 100644 --- a/src/data/value-labels.c +++ b/src/data/value-labels.c @@ -47,8 +47,8 @@ struct val_labs }; /* Creates and returns a new, empty set of value labels with the - given WIDTH, which must designate a numeric (0) or short - string (1...MAX_SHORT_STRING inclusive) width. */ + given WIDTH. To actually add any value labels, WIDTH must be + a numeric or short string width. */ struct val_labs * val_labs_create (int width) { @@ -80,16 +80,53 @@ val_labs_copy (const struct val_labs *vls) return copy; } +/* Determines whether VLS's width can be changed to NEW_WIDTH. + Numeric widths cannot be changed at all. + Strings can be widened. They can be shortened only if the + characters that will be truncated are spaces. */ +bool +val_labs_can_set_width (const struct val_labs *vls, int new_width) +{ + assert ((vls->width == 0) == (new_width == 0)); + + if (vls->width == 0) + return new_width == 0; + else if (new_width < vls->width) + { + struct val_labs_iterator *i; + struct val_lab *lab; + + for (lab = val_labs_first (vls, &i); lab != NULL; + lab = val_labs_next (vls, &i)) + { + int j; + + /* We can shorten the value labels only if all the + truncated characters are blanks. */ + for (j = vls->width; j < new_width; j++) + if (lab->value.s[j] != ' ') + { + val_labs_done (&i); + return false; + } + } + return true; + } + else + return true; +} + /* Changes the width of VLS to NEW_WIDTH. If VLS is numeric, NEW_WIDTH must be 0, otherwise it must be within the range 1...MAX_SHORT_STRING inclusive. */ void val_labs_set_width (struct val_labs *vls, int new_width) { - assert (vls != NULL); - assert ((vls->width == 0) == (new_width == 0)); + assert (val_labs_can_set_width (vls, new_width)); vls->width = new_width; + if (new_width > MAX_SHORT_STRING) + val_labs_clear (vls); } /* Destroys VLS. */ @@ -98,8 +135,7 @@ val_labs_destroy (struct val_labs *vls) { if (vls != NULL) { - if (vls->labels != NULL) - hsh_destroy (vls->labels); + hsh_destroy (vls->labels); free (vls); } } diff --git a/src/data/value-labels.h b/src/data/value-labels.h index 595d101a..f0ea0a6d 100644 --- a/src/data/value-labels.h +++ b/src/data/value-labels.h @@ -20,6 +20,7 @@ #ifndef VAL_LABS_H #define VAL_LABS_H 1 +#include #include #include @@ -35,11 +36,13 @@ struct val_lab struct val_labs *val_labs_create (int width); struct val_labs *val_labs_copy (const struct val_labs *); -void val_labs_set_width (struct val_labs *, int new_width); void val_labs_destroy (struct val_labs *); void val_labs_clear (struct val_labs *); size_t val_labs_count (const struct val_labs *); +bool val_labs_can_set_width (const struct val_labs *, int new_width); +void val_labs_set_width (struct val_labs *, int new_width); + int val_labs_add (struct val_labs *, union value, const char *); int val_labs_replace (struct val_labs *, union value, const char *); int val_labs_remove (struct val_labs *, union value); diff --git a/src/language/data-io/ChangeLog b/src/language/data-io/ChangeLog index d03485fe..dc6a346a 100644 --- a/src/language/data-io/ChangeLog +++ b/src/language/data-io/ChangeLog @@ -1,3 +1,7 @@ +Sat May 6 19:03:13 2006 Ben Pfaff + + * get.c: (mtf_merge_dictionary) Fix value label memory leak. + Sat May 6 13:51:16 2006 Ben Pfaff Use a casefile, instead of a case sink, for MATCH FILES output. diff --git a/src/language/data-io/get.c b/src/language/data-io/get.c index cdae7066..eb0a5ceb 100644 --- a/src/language/data-io/get.c +++ b/src/language/data-io/get.c @@ -1540,8 +1540,11 @@ mtf_merge_dictionary (struct dictionary *const m, struct mtf_file *f) if (dv->width == mv->width) { if (val_labs_count (dv->val_labs) - && !val_labs_count (mv->val_labs)) - mv->val_labs = val_labs_copy (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 (!mv_is_empty (&dv->miss) && mv_is_empty (&mv->miss)) mv_copy (&mv->miss, &dv->miss); } diff --git a/src/language/dictionary/ChangeLog b/src/language/dictionary/ChangeLog index 9718f7db..407a92e6 100644 --- a/src/language/dictionary/ChangeLog +++ b/src/language/dictionary/ChangeLog @@ -1,3 +1,8 @@ +Sat May 6 19:03:34 2006 Ben Pfaff + + * apply-dictionary.c: (cmd_apply_dictionary) Use new function + val_labs_can_set_width(). + Sat May 6 10:43:22 2006 Ben Pfaff Continue reforming procedure execution. In this phase, get rid of diff --git a/src/language/dictionary/apply-dictionary.c b/src/language/dictionary/apply-dictionary.c index 1c9e7ef8..e3a77e5d 100644 --- a/src/language/dictionary/apply-dictionary.c +++ b/src/language/dictionary/apply-dictionary.c @@ -91,38 +91,7 @@ cmd_apply_dictionary (void) s->name); else if (val_labs_count (s->val_labs)) { - /* Whether to apply the value labels. */ - int apply = 1; - - if (t->width < s->width) - { - struct val_labs_iterator *i; - struct val_lab *lab; - - for (lab = val_labs_first (s->val_labs, &i); lab != NULL; - lab = val_labs_next (s->val_labs, &i)) - { - int j; - - /* We will apply the value labels only if all - the truncated characters are blanks. */ - for (j = t->width; j < s->width; j++) - if (lab->value.s[j] != ' ') - { - val_labs_done (&i); - apply = 0; - break; - } - } - } - else - { - /* Fortunately, we follow the convention that all value - label values are right-padded with spaces, so it is - unnecessary to bother padding values here. */ - } - - if (apply) + if (val_labs_can_set_width (s->val_labs, t->width)) { val_labs_destroy (t->val_labs); t->val_labs = s->val_labs; -- 2.30.2