Miscellaneous cleanup to categorical values, linreg and design matrix code.
[pspp-builds.git] / src / data / sys-file-reader.c
index d62dfc7bd6a411944da841e25a2a98e6221f9de9..87ba172d5801e7043dbd9391ff529b5336938f19 100644 (file)
@@ -1,6 +1,5 @@
 /* PSPP - computes sample statistics.
    Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
-   Written by Ben Pfaff <blp@gnu.org>.
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -77,6 +76,7 @@ struct sfm_reader
     int value_cnt;             /* Number of 8-byte units per case. */
     struct sfm_var *vars;       /* Variables. */
     size_t var_cnt;             /* Number of variables. */
+    bool has_long_var_names;    /* File has a long variable name map */
     bool has_vls;               /* File has one or more very long strings? */
 
     /* Decompression. */
@@ -193,6 +193,7 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
   r->error = false;
   r->value_cnt = 0;
   r->has_vls = false;
+  r->has_long_var_names = false;
   r->opcode_idx = sizeof r->opcodes;
 
   if (setjmp (r->bail_out)) 
@@ -251,6 +252,31 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
       rec_type = read_int32 (r);
     }
 
+
+  if ( ! r->has_long_var_names )
+    {
+      int i;
+      for (i = 0; i < dict_get_var_cnt (*dict); i++)
+       {
+         struct variable *var = dict_get_var (*dict, i);
+         char short_name [SHORT_NAME_LEN + 1];
+         char long_name [SHORT_NAME_LEN + 1];
+
+         strcpy (short_name, var_get_name (var));
+
+         strcpy (long_name, short_name);
+         str_lowercase (long_name);
+
+         /* Set long name.  Renaming a variable may clear the short
+            name, but we want to retain it, so re-set it
+            explicitly. */
+         dict_rename_var (*dict, var, long_name);
+         var_set_short_name (var, short_name);
+       }
+
+      r->has_long_var_names = true;
+    }
+
   /* Read record 999 data, which is just filler. */
   read_int32 (r);
 
@@ -473,8 +499,8 @@ read_variable_record (struct sfm_reader *r, struct dictionary *dict,
 
       len = read_int32 (r);
       if (len >= sizeof label)
-        sys_error (r, _("Variable %s has label of invalid length %d."),
-                   name, len);
+        sys_error (r, _("Variable %s has label of invalid length %u."),
+                   name, (unsigned int) len);
       read_string (r, label, len + 1);
       var_set_label (var, label);
       
@@ -737,9 +763,9 @@ read_machine_int32_info (struct sfm_reader *r, size_t size, size_t count)
   int expected_integer_format;
 
   if (size != 4 || count != 8)
-    sys_error (r, _("Bad size (%d) or count (%d) field on record type 7, "
+    sys_error (r, _("Bad size (%u) or count (%u) field on record type 7, "
                     "subtype 3."),
-               size, count);
+               (unsigned int) size, (unsigned int) count);
 
   /* Check floating point format. */
   if (r->float_format == FLOAT_IEEE_DOUBLE_BE
@@ -782,8 +808,8 @@ read_machine_flt64_info (struct sfm_reader *r, size_t size, size_t count)
   double lowest = read_flt64 (r);
 
   if (size != 8 || count != 3)
-    sys_error (r, _("Bad size (%d) or count (%d) on extension 4."),
-               size, count);
+    sys_error (r, _("Bad size (%u) or count (%u) on extension 4."),
+               (unsigned int) size, (unsigned int) count);
 
   if (sysmis != SYSMIS)
     sys_warn (r, _("File specifies unexpected value %g as SYSMIS."), sysmis);
@@ -804,17 +830,21 @@ read_display_parameters (struct sfm_reader *r, size_t size, size_t count,
   int i;
 
   if (count % 3 || n_vars != dict_get_var_cnt (dict)) 
-    sys_error (r, _("Bad size (%d) or count (%d) on extension 11."),
-               size, count);
+    sys_error (r, _("Bad size (%u) or count (%u) on extension 11."),
+               (unsigned int) size, (unsigned int) count);
 
   for (i = 0; i < n_vars; ++i) 
     {
       int measure = read_int32 (r);
       int width = read_int32 (r);
       int align = read_int32 (r);
-      struct variable *v;
+      struct variable *v = dict_get_var (dict, i);
+
+      /* spss v14 sometimes seems to set string variables' measure to zero */
+      if ( 0 == measure && var_is_alpha (v) ) measure = 1;
+
 
-      if (!measure_is_valid (measure) || !alignment_is_valid (align))
+      if (measure < 1 || measure > 3 || align < 0 || align > 2)
         {
           if (!warned)
             sys_warn (r, _("Invalid variable display parameters.  "
@@ -823,10 +853,13 @@ read_display_parameters (struct sfm_reader *r, size_t size, size_t count,
           continue;
         }
 
-      v = dict_get_var (dict, i);
-      var_set_measure (v, measure);
+      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);
+      var_set_alignment (v, (align == 0 ? ALIGN_LEFT
+                             : align == 1 ? ALIGN_RIGHT
+                             : ALIGN_CENTRE));
     }
 }
 
@@ -874,6 +907,7 @@ read_long_var_name_map (struct sfm_reader *r, size_t size, size_t count,
       var_set_short_name (var, short_name);
     }
   close_variable_to_value_map (r, map);
+  r->has_long_var_names = true;
 }
 
 /* Reads record type 7, subtype 14, which gives the real length
@@ -1000,8 +1034,8 @@ read_value_labels (struct sfm_reader *r,
   var_cnt = read_int32 (r);
   if (var_cnt < 1 || var_cnt > dict_get_var_cnt (dict))
     sys_error (r, _("Number of variables associated with a value label (%d) "
-                    "is not between 1 and the number of variables (%d)."),
-               var_cnt, dict_get_var_cnt (dict));
+                    "is not between 1 and the number of variables (%u)."),
+               var_cnt, (unsigned int) dict_get_var_cnt (dict));
 
   /* Read the list of variables. */
   var = pool_nalloc (subpool, var_cnt, sizeof *var);