From 759eaa063b918bd7defe91e53d3ce102901b3e53 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 25 Nov 2018 16:39:55 -0800 Subject: [PATCH] format: New function fmt_from_u32(). This functionality will be useful for reading SPV files as well as SAV files. --- src/data/format.c | 34 ++++++++++++++++++++++++++++++++++ src/data/format.h | 2 ++ src/data/sys-file-reader.c | 15 +-------------- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/data/format.c b/src/data/format.c index 5a347d4d58..a2cb131062 100644 --- a/src/data/format.c +++ b/src/data/format.c @@ -895,6 +895,40 @@ fmt_from_io (int io, enum fmt_type *fmt_type) } } +/* Translate U32, which is in the form found in SAV and SPV files, into a + format specification, and stores the new specification in *F. + + If LOOSE is false, checks that the format specification is appropriate as an + output format for a variable with the given WIDTH and reports an error if + not. If LOOSE is true, instead adjusts the format's width and decimals as + necessary to be suitable. + + Return true if successful, false if there was an error.. */ +bool +fmt_from_u32 (uint32_t u32, int width, bool loose, struct fmt_spec *f) +{ + uint8_t raw_type = u32 >> 16; + uint8_t w = u32 >> 8; + uint8_t d = u32; + + msg_disable (); + f->w = w; + f->d = d; + bool ok = fmt_from_io (raw_type, &f->type); + if (ok) + { + if (loose) + fmt_fix_output (f); + else + ok = fmt_check_output (f); + } + if (ok) + ok = fmt_check_width_compat (f, width); + msg_enable (); + + return ok; +} + /* Returns true if TYPE may be used as an input format, false otherwise. */ bool diff --git a/src/data/format.h b/src/data/format.h index d05e443621..d52848fadc 100644 --- a/src/data/format.h +++ b/src/data/format.h @@ -20,6 +20,7 @@ /* Display format types. */ #include +#include #include "data/val-type.h" #include "libpspp/str.h" @@ -133,6 +134,7 @@ bool fmt_usable_for_input (enum fmt_type) PURE_FUNCTION; int fmt_to_io (enum fmt_type) PURE_FUNCTION; bool fmt_from_io (int io, enum fmt_type *); +bool fmt_from_u32 (uint32_t, int var_width, bool loose, struct fmt_spec *); const char *fmt_date_template (enum fmt_type, int width) PURE_FUNCTION; const char *fmt_gui_name (enum fmt_type); diff --git a/src/data/sys-file-reader.c b/src/data/sys-file-reader.c index b4923230cf..af8f1b4576 100644 --- a/src/data/sys-file-reader.c +++ b/src/data/sys-file-reader.c @@ -1544,22 +1544,9 @@ parse_format_spec (struct sfm_reader *r, off_t pos, unsigned int format, int *n_warnings) { const int max_warnings = 8; - uint8_t raw_type = format >> 16; - uint8_t w = format >> 8; - uint8_t d = format; struct fmt_spec f; - bool ok; - - f.w = w; - f.d = d; - msg_disable (); - ok = (fmt_from_io (raw_type, &f.type) - && fmt_check_output (&f) - && fmt_check_width_compat (&f, var_get_width (v))); - msg_enable (); - - if (ok) + if (fmt_from_u32 (format, var_get_width (v), false, &f)) { if (which == PRINT_FORMAT) var_set_print_format (v, &f); -- 2.30.2