format: New function fmt_from_u32().
authorBen Pfaff <blp@cs.stanford.edu>
Mon, 26 Nov 2018 00:39:55 +0000 (16:39 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 25 Dec 2018 19:44:44 +0000 (11:44 -0800)
This functionality will be useful for reading SPV files as well as SAV
files.

src/data/format.c
src/data/format.h
src/data/sys-file-reader.c

index 5a347d4d58e18acc904abf03f099252c14f71a1b..a2cb1310624dc35b8b0f126a9cc909378047506c 100644 (file)
@@ -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
index d05e4436215b8d17a76507bcf9cda3be2da77186..d52848fadced368466f84b073e807906f40a0aef 100644 (file)
@@ -20,6 +20,7 @@
 /* Display format types. */
 
 #include <stdbool.h>
+#include <stdint.h>
 #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);
index b4923230cf3629ff980142da4290efa1822d4b8a..af8f1b457678e60c5a927969e737d39cc169c4f9 100644 (file)
@@ -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);