From cea3f4f0364025ca9f9dc7c10cb38b8f534688d9 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 24 Dec 2018 21:46:11 -0800 Subject: [PATCH] missing-values: New function mv_to_string(). This seems like something that should be handled by the missing value code, not by SYSFILE INFO. --- src/data/missing-values.c | 40 +++++++++++++++++++++++++ src/data/missing-values.h | 3 ++ src/language/dictionary/sys-file-info.c | 37 +++-------------------- 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/src/data/missing-values.c b/src/data/missing-values.c index 9aba57e0e0..742ddd2acf 100644 --- a/src/data/missing-values.c +++ b/src/data/missing-values.c @@ -24,8 +24,11 @@ #include "data/variable.h" #include "libpspp/assertion.h" #include "libpspp/cast.h" +#include "libpspp/i18n.h" #include "libpspp/str.h" +#include "gl/minmax.h" + /* Types of user-missing values. Invisible--use access functions defined below instead. */ enum mv_type @@ -470,3 +473,40 @@ mv_is_str_missing (const struct missing_values *mv, const uint8_t s[], assert (mv->width > 0); return class & MV_USER && is_str_user_missing (mv, s); } + +char * +mv_to_string (const struct missing_values *mv, const char *encoding) +{ + struct string s = DS_EMPTY_INITIALIZER; + if (mv_has_range (mv)) + { + double x, y; + mv_get_range (mv, &x, &y); + if (x == LOWEST) + ds_put_format (&s, "LOWEST THRU %.*g", DBL_DIG + 1, y); + else if (y == HIGHEST) + ds_put_format (&s, "%.*g THRU HIGHEST", DBL_DIG + 1, x); + else + ds_put_format (&s, "%.*g THRU %.*g", + DBL_DIG + 1, x, + DBL_DIG + 1, y); + } + for (size_t j = 0; j < mv_n_values (mv); j++) + { + const union value *value = mv_get_value (mv, j); + if (!ds_is_empty (&s)) + ds_put_cstr (&s, "; "); + if (!mv->width) + ds_put_format (&s, "%.*g", DBL_DIG + 1, value->f); + else + { + char *mvs = recode_string ( + "UTF-8", encoding, + CHAR_CAST (char *, value_str (value, mv->width)), + MIN (mv->width, MV_MAX_STRING)); + ds_put_format (&s, "\"%s\"", mvs); + free (mvs); + } + } + return ds_is_empty (&s) ? NULL : ds_steal_cstr (&s); +} diff --git a/src/data/missing-values.h b/src/data/missing-values.h index 511ebd7ddd..c4d5695074 100644 --- a/src/data/missing-values.h +++ b/src/data/missing-values.h @@ -103,4 +103,7 @@ bool mv_replace_value (struct missing_values *, const union value *, int idx); bool mv_add_range (struct missing_values *, double low, double high); void mv_pop_range (struct missing_values *, double *low, double *high); +/* Formatting. */ +char *mv_to_string (const struct missing_values *, const char *encoding); + #endif /* data/missing-values.h */ diff --git a/src/language/dictionary/sys-file-info.c b/src/language/dictionary/sys-file-info.c index 8f0a4c2b69..baea6274af 100644 --- a/src/language/dictionary/sys-file-info.c +++ b/src/language/dictionary/sys-file-info.c @@ -497,41 +497,12 @@ display_variables (const struct variable **vl, size_t n, int flags) { const struct missing_values *mv = var_get_missing_values (v); - struct string s = DS_EMPTY_INITIALIZER; - if (mv_has_range (mv)) + char *s = mv_to_string (mv, var_get_encoding (v)); + if (s) { - double x, y; - mv_get_range (mv, &x, &y); - if (x == LOWEST) - ds_put_format (&s, "LOWEST THRU %.*g", DBL_DIG + 1, y); - else if (y == HIGHEST) - ds_put_format (&s, "%.*g THRU HIGHEST", DBL_DIG + 1, x); - else - ds_put_format (&s, "%.*g THRU %.*g", - DBL_DIG + 1, x, - DBL_DIG + 1, y); + tab_text (t, x, y, TAB_LEFT, s); + free (s); } - for (size_t j = 0; j < mv_n_values (mv); j++) - { - const union value *value = mv_get_value (mv, j); - if (!ds_is_empty (&s)) - ds_put_cstr (&s, "; "); - if (var_is_numeric (v)) - ds_put_format (&s, "%.*g", DBL_DIG + 1, value->f); - else - { - int width = var_get_width (v); - int mv_width = MIN (width, MV_MAX_STRING); - - ds_put_byte (&s, '"'); - memcpy (ds_put_uninit (&s, mv_width), - value_str (value, width), mv_width); - ds_put_byte (&s, '"'); - } - } - if (!ds_is_empty (&s)) - tab_text (t, x, y, TAB_LEFT, ds_cstr (&s)); - ds_destroy (&s); x++; assert (x == nc); -- 2.30.2