In system files, fix error message when floating-point format cannot
[pspp-builds.git] / src / data / sys-file-reader.c
index 1d172adefd46a65d9751832ffc10a7df3cf90efc..d5b5b15f6ff2bbf1ae4c40e859620e7a16b3fa96 100644 (file)
@@ -88,7 +88,7 @@ struct sfm_reader
     size_t opcode_idx;          /* Next opcode to interpret, 8 if none left. */
   };
 
-static struct casereader_class sys_file_casereader_class;
+static const struct casereader_class sys_file_casereader_class;
 
 static bool close_reader (struct sfm_reader *);
 
@@ -425,10 +425,9 @@ read_header (struct sfm_reader *r, struct dictionary *dict,
   read_bytes (r, raw_bias, sizeof raw_bias);
   if (float_identify (100.0, raw_bias, sizeof raw_bias, &r->float_format) == 0)
     {
-      sys_warn (r, _("Compression bias (%g) is not the usual "
+      sys_warn (r, _("Compression bias is not the usual "
                      "value of 100, or system file uses unrecognized "
-                     "floating-point format."),
-                r->bias);
+                     "floating-point format."));
       if (r->integer_format == INTEGER_MSB_FIRST)
         r->float_format = FLOAT_IEEE_DOUBLE_BE;
       else
@@ -549,11 +548,14 @@ read_variable_record (struct sfm_reader *r, struct dictionary *dict,
           for (i = 0; i < missing_value_code; i++)
             mv_add_num (&mv, read_float (r));
         }
-      else if (var_get_width (var) <= MAX_SHORT_STRING)
+      else
         {
           if (missing_value_code < 1 || missing_value_code > 3)
             sys_error (r, _("String missing value indicator field is not "
                             "0, 1, 2, or 3."));
+          if (var_is_long_string (var))
+            sys_warn (r, _("Ignoring missing values on long string variable "
+                           "%s, which PSPP does not yet support."), name);
           for (i = 0; i < missing_value_code; i++)
             {
               char string[9];
@@ -561,10 +563,8 @@ read_variable_record (struct sfm_reader *r, struct dictionary *dict,
               mv_add_str (&mv, string);
             }
         }
-      else
-        sys_error (r, _("Long string variable %s may not have missing "
-                        "values."), name);
-      var_set_missing_values (var, &mv);
+      if (!var_is_long_string (var))
+        var_set_missing_values (var, &mv);
     }
 
   /* Set formats. */
@@ -752,6 +752,18 @@ read_extension_record (struct sfm_reader *r, struct dictionary *dict,
          SPSS 14. */
       break;
 
+    case 20:
+      /* New in SPSS 16.  Contains a single string that describes
+         the character encoding, e.g. "windows-1252". */
+      break;
+
+    case 21:
+      /* New in SPSS 16.  Encodes value labels for long string
+         variables. */
+      sys_warn (r, _("Ignoring value labels for long string variables, "
+                     "which PSPP does not yet support."));
+      break;
+
     default:
       sys_warn (r, _("Unrecognized record type 7, subtype %d."), subtype);
       break;
@@ -811,7 +823,7 @@ read_machine_integer_info (struct sfm_reader *r, size_t size, size_t count,
     NOT_REACHED ();
   if (integer_representation != expected_integer_format)
     {
-      static const char *endian[] = {N_("little-endian"), N_("big-endian")};
+      static const char *const endian[] = {N_("little-endian"), N_("big-endian")};
       sys_warn (r, _("Integer format indicated by system file (%s) "
                      "differs from expected (%s)."),
                 gettext (endian[integer_representation == 1]),
@@ -845,19 +857,36 @@ static void
 read_display_parameters (struct sfm_reader *r, size_t size, size_t count,
                          struct dictionary *dict)
 {
-  const size_t n_vars = count / 3 ;
+  size_t n_vars;
+  bool includes_width;
   bool warned = false;
-  int i;
+  size_t i;
 
-  if (count % 3 || n_vars != dict_get_var_cnt (dict))
-    sys_error (r, _("Bad size (%zu) or count (%zu) on extension 11."),
-               size, count);
+  if (size != 4)
+    {
+      sys_warn (r, _("Bad size %zu on extension 11."), size);
+      skip_bytes (r, size * count);
+      return;
+    }
+
+  n_vars = dict_get_var_cnt (dict);
+  if (count == 3 * n_vars)
+    includes_width = true;
+  else if (count == 2 * n_vars)
+    includes_width = false;
+  else
+    {
+      sys_warn (r, _("Extension 11 has bad count %zu (for %zu variables)."),
+                count, n_vars);
+      skip_bytes (r, size * count);
+      return;
+    }
 
   for (i = 0; i < n_vars; ++i)
     {
       struct variable *v = dict_get_var (dict, i);
       int measure = read_int (r);
-      int width = read_int (r);
+      int width = includes_width ? read_int (r) : 0;
       int align = read_int (r);
 
       /* SPSS 14 sometimes seems to set string variables' measure
@@ -865,16 +894,13 @@ read_display_parameters (struct sfm_reader *r, size_t size, size_t count,
       if (0 == measure && var_is_alpha (v))
         measure = 1;
 
-      /* Older versions (SPSS 9.0) sometimes set the display width
-        to zero.  This causes confusion especially in the GUI */
-      if (0 == width)
-       width = 8;
-
       if (measure < 1 || measure > 3 || align < 0 || align > 2)
         {
           if (!warned)
-            sys_warn (r, _("Invalid variable display parameters.  "
-                           "Default parameters substituted."));
+            sys_warn (r, _("Invalid variable display parameters "
+                           "for variable %zu (%s).  "
+                           "Default parameters substituted."),
+                      i, var_get_name (v));
           warned = true;
           continue;
         }
@@ -882,10 +908,15 @@ read_display_parameters (struct sfm_reader *r, size_t size, size_t count,
       var_set_measure (v, (measure == 1 ? MEASURE_NOMINAL
                            : measure == 2 ? MEASURE_ORDINAL
                            : MEASURE_SCALE));
-      var_set_display_width (v, width);
       var_set_alignment (v, (align == 0 ? ALIGN_LEFT
                              : align == 1 ? ALIGN_RIGHT
                              : ALIGN_CENTRE));
+
+      /* Older versions (SPSS 9.0) sometimes set the display
+        width to zero.  This causes confusion in the GUI, so
+        only set the width if it is nonzero. */
+      if (width > 0)
+        var_set_display_width (v, width);
     }
 }
 
@@ -1697,7 +1728,7 @@ skip_bytes (struct sfm_reader *r, size_t bytes)
     }
 }
 \f
-static struct casereader_class sys_file_casereader_class =
+static const struct casereader_class sys_file_casereader_class =
   {
     sys_file_casereader_read,
     sys_file_casereader_destroy,