X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fvalue-labels.c;h=6d7f19c17d7ee191862b29c454c7ef62540a8ad5;hb=cf5e75010ed9fa9b8eb75a71d1419d40e1a8ddd8;hp=6d8f517510c59f62f7b29b852f4dd1107e01da45;hpb=b9c499c2d6893dd5a6b0ac6e9d405e5095fc79af;p=pspp-builds.git diff --git a/src/data/value-labels.c b/src/data/value-labels.c index 6d8f5175..6d7f19c1 100644 --- a/src/data/value-labels.c +++ b/src/data/value-labels.c @@ -58,7 +58,7 @@ val_labs_clone (const struct val_labs *vls) copy = val_labs_create (vls->width); HMAP_FOR_EACH (label, struct val_lab, node, &vls->labels) - val_labs_add (copy, &label->value, label->label); + val_labs_add (copy, &label->value, label->escaped_label); return copy; } @@ -114,6 +114,7 @@ val_labs_clear (struct val_labs *vls) hmap_delete (&vls->labels, &label->node); value_destroy (&label->value, vls->width); intern_unref (label->label); + intern_unref (label->escaped_label); free (label); } } @@ -133,18 +134,48 @@ val_labs_count (const struct val_labs *vls) return vls == NULL ? 0 : hmap_count (&vls->labels); } +static void +set_label (struct val_lab *lab, const char *escaped_label) +{ + lab->escaped_label = intern_new (escaped_label); + if (strstr (escaped_label, "\\n") == NULL) + lab->label = intern_ref (lab->escaped_label); + else + { + struct string s; + const char *p; + + ds_init_empty (&s); + ds_extend (&s, intern_strlen (lab->escaped_label)); + for (p = escaped_label; *p != '\0'; p++) + { + char c = *p; + if (c == '\\' && p[1] == 'n') + { + c = '\n'; + p++; + } + ds_put_byte (&s, c); + } + lab->label = intern_new (ds_cstr (&s)); + ds_destroy (&s); + } +} + static void do_add_val_lab (struct val_labs *vls, const union value *value, - const char *label) + const char *escaped_label) { struct val_lab *lab = xmalloc (sizeof *lab); value_clone (&lab->value, value, vls->width); - lab->label = intern_new (label); + set_label (lab, escaped_label); hmap_insert (&vls->labels, &lab->node, value_hash (value, vls->width, 0)); } -/* If VLS does not already contain a value label for VALUE, adds - LABEL for it and returns true. Otherwise, returns false. */ +/* If VLS does not already contain a value label for VALUE, adds the UTF-8 + encoded LABEL for it and returns true. Otherwise, returns false. + + In LABEL, the two-byte sequence "\\n" is interpreted as a new-line. */ bool val_labs_add (struct val_labs *vls, const union value *value, const char *label) @@ -160,7 +191,9 @@ val_labs_add (struct val_labs *vls, const union value *value, } /* Sets LABEL as the value label for VALUE in VLS, replacing any - existing label for VALUE. */ + existing label for VALUE. + + In LABEL, the two-byte sequence "\\n" is interpreted as a new-line. */ void val_labs_replace (struct val_labs *vls, const union value *value, const char *label) @@ -169,7 +202,8 @@ val_labs_replace (struct val_labs *vls, const union value *value, if (vl != NULL) { intern_unref (vl->label); - vl->label = intern_new (label); + intern_unref (vl->escaped_label); + set_label (vl, label); } else do_add_val_lab (vls, value, label); @@ -182,12 +216,14 @@ val_labs_remove (struct val_labs *vls, struct val_lab *label) hmap_delete (&vls->labels, &label->node); value_destroy (&label->value, vls->width); intern_unref (label->label); + intern_unref (label->escaped_label); free (label); } -/* Searches VLS for a value label for VALUE. If successful, - returns the string used as the label; otherwise, returns a - null pointer. Returns a null pointer if VLS is null. */ +/* Searches VLS for a value label for VALUE. If successful, returns the string + used as the label, as a UTF-8 encoded string in a format suitable for + output. Otherwise, returns a null pointer. Returns a null pointer if VLS + is null. */ const char * val_labs_find (const struct val_labs *vls, const union value *value) {