X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fvalue-labels.c;h=92a2db48ea87e82340dfec28fb3d3d2ab486d7a6;hb=f335cbe3c9591fdc809c197983c8cc3e2d622f1f;hp=dc18a707f6b9c4274aefe3b9fad5f0ef2ed14f3f;hpb=2322678e8fddbbf158b01b2720db2636404bba3b;p=pspp-builds.git diff --git a/src/data/value-labels.c b/src/data/value-labels.c index dc18a707..92a2db48 100644 --- a/src/data/value-labels.c +++ b/src/data/value-labels.c @@ -18,13 +18,17 @@ 02110-1301, USA. */ #include + #include "value-labels.h" -#include "message.h" + #include -#include "alloc.h" -#include "compiler.h" -#include "hash.h" -#include "str.h" + +#include +#include +#include +#include +#include +#include static hsh_compare_func compare_int_val_lab; static hsh_hash_func hash_int_val_lab; @@ -43,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) { @@ -76,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. */ @@ -94,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); } } @@ -507,11 +547,9 @@ value_to_string (const union value *val, const struct variable *var) s = val_labs_find (var->val_labs, *val); if (s == NULL) { - static char buf[256]; - if (var->width != 0) - str_copy_buf_trunc (buf, sizeof buf, val->s, var->width); - else - snprintf(buf, 100, "%g", val->f); + static char buf[MAX_STRING + 1]; + data_out (buf, &var->print, val); + buf[var->print.w] = '\0'; s = buf; }