Reference count struct dictionary.
[pspp] / src / data / sys-file-reader.c
index dbc61345a85869eda4c0d1eb7f0f0aa04fe4c9ce..20ecf048f907e2fbc6bf9a317fb8884c00ba4d53 100644 (file)
@@ -891,7 +891,7 @@ sfm_decode (struct any_reader *r_, const char *encoding,
 
 error:
   sfm_close (r_);
-  dict_destroy (dict);
+  dict_unref (dict);
   *dictp = NULL;
   return NULL;
 }
@@ -1457,11 +1457,13 @@ parse_variable_records (struct sfm_reader *r, struct dictionary *dict,
                                    "`%s' to `%s'."),
                     name, new_name);
           var = rec->var = dict_create_var_assert (dict, new_name, rec->width);
+          var_set_short_name (var, 0, new_name);
           free (new_name);
         }
 
-      /* Set the short name the same as the long name. */
-      var_set_short_name (var, 0, name);
+      /* Set the short name the same as the long name (even if we renamed
+         it). */
+      var_set_short_name (var, 0, var_get_name (var));
 
       /* Get variable label, if any. */
       if (rec->label)
@@ -1760,7 +1762,12 @@ parse_mrsets (struct sfm_reader *r, const struct sfm_extension_record *record,
             }
 
           number = text_get_token (text, ss_cstr (" "), NULL);
-          if (!strcmp (number, "11"))
+          if (!number)
+            sys_warn (r, record->pos,
+                      _("Missing label source value "
+                        "following `E' at offset %zu in MRSETS record."),
+                      text_pos (text));
+          else if (!strcmp (number, "11"))
             mrset->label_from_var_label = true;
           else if (strcmp (number, "1"))
             sys_warn (r, record->pos,
@@ -1995,8 +2002,9 @@ parse_display_parameters (struct sfm_reader *r,
 }
 
 static void
-rename_var_and_save_short_names (struct dictionary *dict, struct variable *var,
-                                 const char *new_name)
+rename_var_and_save_short_names (struct sfm_reader *r, off_t pos,
+                                 struct dictionary *dict,
+                                 struct variable *var, const char *new_name)
 {
   size_t n_short_names;
   char **short_names;
@@ -2014,7 +2022,8 @@ rename_var_and_save_short_names (struct dictionary *dict, struct variable *var,
     }
 
   /* Set long name. */
-  dict_rename_var (dict, var, new_name);
+  if (!dict_try_rename_var (dict, var, new_name))
+    sys_warn (r, pos, _("Duplicate long variable name `%s'."), new_name);
 
   /* Restore short names. */
   for (i = 0; i < n_short_names; i++)
@@ -2048,7 +2057,7 @@ parse_long_var_name_map (struct sfm_reader *r,
           char *new_name;
 
           new_name = utf8_to_lower (var_get_name (var));
-          rename_var_and_save_short_names (dict, var, new_name);
+          rename_var_and_save_short_names (r, -1, dict, var, new_name);
           free (new_name);
        }
 
@@ -2073,16 +2082,7 @@ parse_long_var_name_map (struct sfm_reader *r,
           continue;
         }
 
-      /* Identify any duplicates. */
-      if (utf8_strcasecmp (var_get_short_name (var, 0), long_name)
-          && dict_lookup_var (dict, long_name) != NULL)
-        {
-          sys_warn (r, record->pos,
-                    _("Duplicate long variable name `%s'."), long_name);
-          continue;
-        }
-
-      rename_var_and_save_short_names (dict, var, long_name);
+      rename_var_and_save_short_names (r, record->pos, dict, var, long_name);
     }
   close_text_record (r, text);
 }
@@ -2339,8 +2339,15 @@ parse_attributes (struct sfm_reader *r, struct text_record *text,
           if (text_match (text, ')'))
             break;
         }
-      if (attrs != NULL)
-        attrset_add (attrs, attr);
+      if (attrs != NULL && attribute_get_n_values (attr) > 0)
+        {
+          if (!attrset_try_add (attrs, attr))
+            {
+              text_warn (r, text, _("Duplicate attribute %s."),
+                         attribute_get_name (attr));
+              attribute_destroy (attr);
+            }
+        }
       else
         attribute_destroy (attr);
     }
@@ -2386,7 +2393,7 @@ assign_variable_roles (struct sfm_reader *r, struct dictionary *dict)
       struct variable *var = dict_get_var (dict, i);
       struct attrset *attrs = var_get_attributes (var);
       const struct attribute *attr = attrset_lookup (attrs, "$@Role");
-      if (attr != NULL)
+      if (attr != NULL && attribute_get_n_values (attr) > 0)
         {
           int value = atoi (attribute_get_value (attr, 0));
           enum var_role role;
@@ -3502,7 +3509,7 @@ read_ztrailer (struct sfm_reader *r,
 
   if (fstat (fileno (r->file), &s))
     {
-      sys_error (ME, 0, _("%s: stat failed (%s)."),
+      sys_error (r, 0, _("%s: stat failed (%s)."),
                  fh_get_file_name (r->fh), strerror (errno));
       return false;
     }