sys-file-reader: Reduce invalid format from error to warning.
authorBen Pfaff <blp@cs.stanford.edu>
Thu, 23 Jun 2011 05:13:40 +0000 (22:13 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Thu, 23 Jun 2011 05:13:40 +0000 (22:13 -0700)
gaby jongenelen <geebie21@gmail.com> provided a .sav file
written by "MS Windows Release 13.0 spssio32.dll" that had
zeros in the "write" format field for several numeric
variables.  Until now, PSPP treated this as an error and
rejected the file.  This commit changes the error to a warning
and suppresses the diagnostic entirely for this case of a
zero value.

doc/dev/system-file-format.texi
src/data/sys-file-reader.c
tests/data/sys-file-reader.at

index 6276b6de859f999f376e9ab139a80bb8ab3e4dd4..7b0eff9f79823f0bb623e10d2f1da8c22922eff7 100644 (file)
@@ -391,6 +391,11 @@ Format types are defined as follows:
 @end multitable
 @end quotation
 
+A few system files have been observed in the wild with invalid
+@code{write} fields, in particular with value 0.  Readers should
+probably treat invalid @code{print} or @code{write} fields as some
+default format.
+
 @node Value Labels Records
 @section Value Labels Records
 
index 00db5b2f9594da4cc95ca47634c97826eb0e8b8b..9ec176f09f494f9562548918db80b61b31fa36f1 100644 (file)
@@ -1052,16 +1052,15 @@ parse_format_spec (struct sfm_reader *r, off_t pos, unsigned int format,
   uint8_t w = format >> 8;
   uint8_t d = format;
   struct fmt_spec f;
-
   bool ok;
 
-  if (!fmt_from_io (raw_type, &f.type))
-    sys_error (r, pos, _("Unknown variable format %"PRIu8"."), raw_type);
   f.w = w;
   f.d = d;
 
   msg_disable ();
-  ok = fmt_check_output (&f) && fmt_check_width_compat (&f, var_get_width (v));
+  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)
@@ -1071,14 +1070,20 @@ parse_format_spec (struct sfm_reader *r, off_t pos, unsigned int format,
       else
         var_set_write_format (v, &f);
     }
+  else if (format == 0)
+    {
+      /* Actually observed in the wild.  No point in warning about it. */
+    }
   else if (++*n_warnings <= max_warnings)
     {
-      char fmt_string[FMT_STRING_LEN_MAX + 1];
-      sys_warn (r, pos, _("%s variable %s has invalid %s format %s."),
-                var_is_numeric (v) ? _("Numeric") : _("String"),
-                var_get_name (v),
-                which == PRINT_FORMAT ? _("print") : _("write"),
-                fmt_to_string (&f, fmt_string));
+      if (which == PRINT_FORMAT)
+        sys_warn (r, pos, _("Variable %s with width %d has invalid print "
+                            "format 0x%x."),
+                  var_get_name (v), var_get_width (v), format);
+      else
+        sys_warn (r, pos, _("Variable %s with width %d has invalid write "
+                            "format 0x%x."),
+                  var_get_name (v), var_get_width (v), format);
 
       if (*n_warnings == max_warnings)
         sys_warn (r, -1, _("Suppressing further invalid format warnings."));
index ca45de3792770e57e628ec1ea41ae2cfe908b9cc..cdf6366e94fe4baaf6bf153e4a5a92a78b70cbe5 100644 (file)
@@ -1612,40 +1612,17 @@ do
 done
 AT_CLEANUP
 
-AT_SETUP([unknown variable format])
+AT_SETUP([invalid variable format])
 AT_KEYWORDS([sack synthetic system file negative])
 AT_DATA([sys-file.sack], [dnl
 dnl File header.
 "$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
-2; 1; 1; 0; -1; 100.0; "01 Jan 11"; "20:53:52"; s64 ""; i8 0 *3;
-
-dnl Numeric variable.
-2; 0; 0; 0; >>0xff0800<< *2; s8 "VAR1";
-
-dnl End of dictionary.
-999; 0;
-])
-for variant in \
-       "be fcf94b3ff11b7e2ff50c226b609cff1e" \
-       "le 88fc97cc80d5a170e53a7cc89e204b0d"
-do
-  set $variant
-  AT_CHECK_UNQUOTED([sack --$[1] sys-file.sack > sys-file.sav], [0], [], [$[2]
-])
-  AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
-])
-  AT_CHECK([pspp -O format=csv sys-file.sps], [1], 
-   [error: `sys-file.sav' near offset 0xc0: Unknown variable format 255.
-])
-done
-AT_CLEANUP
+2; 4; 1; 0; -1; 100.0; "01 Jan 11"; "20:53:52"; s64 ""; i8 0 *3;
 
-AT_SETUP([invalid numeric variable format])
-AT_KEYWORDS([sack synthetic system file negative])
-AT_DATA([sys-file.sack], [dnl
-dnl File header.
-"$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
-2; 3; 1; 0; -1; 100.0; "01 Jan 11"; "20:53:52"; s64 ""; i8 0 *3;
+dnl Numeric variable, invalid format types.
+dnl No warning is issued for type 0 because it has been observed in real
+dnl system files.
+2; 0; 0; 0; >>0xff0800; 0<<; s8 "NUM1";
 
 dnl Numeric variable, string formats.
 2; 0; 0; 0; >>0x010800<<; >>0x021000<<; s8 "VAR1";
@@ -1660,26 +1637,28 @@ dnl End of dictionary.
 999; 0;
 ])
 for variant in \
-       "be 0c36a39ec9118eb4a83f10a9483b5a37" \
-       "le 1d498d60eeb2c88e0479f113fb3ffe4b"
+       "be c6ef5d8fded46443aba89adfafe15cad" \
+       "le fccaf1764c973892f2d5adbcc2c36fb7"
 do
   set $variant
   AT_CHECK_UNQUOTED([sack --$[1] sys-file.sack > sys-file.sav], [0], [], [$[2]
 ])
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 ])
-  AT_CHECK([pspp -O format=csv sys-file.sps], [0], 
-   [warning: `sys-file.sav' near offset 0xc0: Numeric variable VAR1 has invalid print format A8.
+  AT_CHECK([pspp -O format=csv sys-file.sps], [0], [dnl
+warning: `sys-file.sav' near offset 0xc0: Variable NUM1 with width 0 has invalid print format 0xff0800.
+
+warning: `sys-file.sav' near offset 0xe0: Variable VAR1 with width 0 has invalid print format 0x10800.
 
-warning: `sys-file.sav' near offset 0xc4: Numeric variable VAR1 has invalid write format AHEX16.
+warning: `sys-file.sav' near offset 0xe4: Variable VAR1 with width 0 has invalid write format 0x21000.
 
-warning: `sys-file.sav' near offset 0xe0: String variable STR1 has invalid print format F8.0.
+warning: `sys-file.sav' near offset 0x100: Variable STR1 with width 4 has invalid print format 0x50800.
 
-warning: `sys-file.sav' near offset 0xe4: String variable STR1 has invalid write format E10.1.
+warning: `sys-file.sav' near offset 0x104: Variable STR1 with width 4 has invalid write format 0x110a01.
 
-warning: `sys-file.sav' near offset 0x100: String variable STR2 has invalid print format A8.
+warning: `sys-file.sav' near offset 0x120: Variable STR2 with width 4 has invalid print format 0x10800.
 
-warning: `sys-file.sav' near offset 0x104: String variable STR2 has invalid write format AHEX4.
+warning: `sys-file.sav' near offset 0x124: Variable STR2 with width 4 has invalid write format 0x20400.
 ])
 done
 AT_CLEANUP