Patch #6262. New developers guide and resulting fixes and cleanups.
[pspp-builds.git] / src / data / sys-file-reader.c
index baa0c0e617d048dc64a791693c4bd476f5294bb3..1d172adefd46a65d9751832ffc10a7df3cf90efc 100644 (file)
@@ -42,6 +42,7 @@
 #include <data/file-name.h>
 #include <data/format.h>
 #include <data/missing-values.h>
+#include <data/short-names.h>
 #include <data/value-labels.h>
 #include <data/variable.h>
 #include <data/value.h>
@@ -66,6 +67,7 @@ struct sfm_reader
 
     /* File state. */
     struct file_handle *fh;     /* File handle. */
+    struct fh_lock *lock;       /* Mutual exclusion for file handle. */
     FILE *file;                 /* File stream. */
     bool error;                 /* I/O or corruption error? */
     size_t value_cnt;           /* Number of "union value"s in struct case. */
@@ -179,39 +181,40 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
   int claimed_oct_cnt;
   int rec_type;
 
-  if (!fh_open (fh, FH_REF_FILE, "system file", "rs"))
-    return NULL;
-
   *dict = dict_create ();
 
   /* Create and initialize reader. */
   r = pool_create_container (struct sfm_reader, pool);
-  r->fh = fh;
-  r->file = fn_open (fh_get_file_name (fh), "rb");
+  r->fh = fh_ref (fh);
+  r->lock = NULL;
+  r->file = NULL;
   r->error = false;
   r->oct_cnt = 0;
   r->has_long_var_names = false;
   r->opcode_idx = sizeof r->opcodes;
 
+  /* TRANSLATORS: this fragment will be interpolated into
+     messages in fh_lock() that identify types of files. */
+  r->lock = fh_lock (fh, FH_REF_FILE, N_("system file"), FH_ACC_READ, false);
+  if (r->lock == NULL)
+    goto error;
+
+  r->file = fn_open (fh_get_file_name (fh), "rb");
+  if (r->file == NULL)
+    {
+      msg (ME, _("Error opening \"%s\" for reading as a system file: %s."),
+           fh_get_file_name (r->fh), strerror (errno));
+      goto error;
+    }
+
   /* Initialize info. */
   if (info == NULL)
     info = &local_info;
   memset (info, 0, sizeof *info);
 
   if (setjmp (r->bail_out))
-    {
-      close_reader (r);
-      dict_destroy (*dict);
-      *dict = NULL;
-      return NULL;
-    }
+    goto error;
 
-  if (r->file == NULL)
-    {
-      msg (ME, _("Error opening \"%s\" for reading as a system file: %s."),
-           fh_get_file_name (r->fh), strerror (errno));
-      longjmp (r->bail_out, 1);
-    }
 
   /* Read header. */
   read_header (r, *dict, &weight_idx, &claimed_oct_cnt, info);
@@ -261,8 +264,8 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
       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];
+         char short_name[SHORT_NAME_LEN + 1];
+         char long_name[SHORT_NAME_LEN + 1];
 
          strcpy (short_name, var_get_name (var));
 
@@ -305,6 +308,12 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
     (NULL, r->value_cnt,
      r->case_cnt == -1 ? CASENUMBER_MAX: r->case_cnt,
                                        &sys_file_casereader_class, r);
+
+error:
+  close_reader (r);
+  dict_destroy (*dict);
+  *dict = NULL;
+  return NULL;
 }
 
 /* Closes a system file after we're done with it.
@@ -329,8 +338,8 @@ close_reader (struct sfm_reader *r)
       r->file = NULL;
     }
 
-  if (r->fh != NULL)
-    fh_close (r->fh, "system file", "rs");
+  fh_unlock (r->lock);
+  fh_unref (r->fh);
 
   error = r->error;
   pool_destroy (r->pool);
@@ -509,8 +518,8 @@ read_variable_record (struct sfm_reader *r, struct dictionary *dict,
 
       len = read_int (r);
       if (len >= sizeof label)
-        sys_error (r, _("Variable %s has label of invalid length %u."),
-                   name, (unsigned int) len);
+        sys_error (r, _("Variable %s has label of invalid length %zu."),
+                   name, len);
       read_string (r, label, len + 1);
       var_set_label (var, label);
 
@@ -534,7 +543,7 @@ read_variable_record (struct sfm_reader *r, struct dictionary *dict,
             {
               double low = read_float (r);
               double high = read_float (r);
-              mv_add_num_range (&mv, low, high);
+              mv_add_range (&mv, low, high);
               missing_value_code = -missing_value_code - 2;
             }
           for (i = 0; i < missing_value_code; i++)
@@ -608,7 +617,7 @@ parse_format_spec (struct sfm_reader *r, unsigned int s,
   bool ok;
 
   if (!fmt_from_io (raw_type, &f.type))
-    sys_error (r, _("Unknown variable format %d."), (int) raw_type);
+    sys_error (r, _("Unknown variable format %"PRIu8"."), raw_type);
   f.w = w;
   f.d = d;
 
@@ -769,9 +778,9 @@ read_machine_integer_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 (%u) or count (%u) field on record type 7, "
+    sys_error (r, _("Bad size (%zu) or count (%zu) field on record type 7, "
                     "subtype 3."),
-               (unsigned int) size, (unsigned int) count);
+                size, count);
 
   /* Save version info. */
   info->version_major = version_major;
@@ -819,8 +828,8 @@ read_machine_float_info (struct sfm_reader *r, size_t size, size_t count)
   double lowest = read_float (r);
 
   if (size != 8 || count != 3)
-    sys_error (r, _("Bad size (%u) or count (%u) on extension 4."),
-               (unsigned int) size, (unsigned int) count);
+    sys_error (r, _("Bad size (%zu) or count (%zu) on extension 4."),
+               size, count);
 
   if (sysmis != SYSMIS)
     sys_warn (r, _("File specifies unexpected value %g as SYSMIS."), sysmis);
@@ -841,8 +850,8 @@ 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 (%u) or count (%u) on extension 11."),
-               (unsigned int) size, (unsigned int) count);
+    sys_error (r, _("Bad size (%zu) or count (%zu) on extension 11."),
+               size, count);
 
   for (i = 0; i < n_vars; ++i)
     {
@@ -1082,8 +1091,8 @@ read_value_labels (struct sfm_reader *r,
   var_cnt = read_int (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 (%u)."),
-               var_cnt, (unsigned int) dict_get_var_cnt (dict));
+                    "is not between 1 and the number of variables (%zu)."),
+               var_cnt, dict_get_var_cnt (dict));
 
   /* Read the list of variables. */
   var = pool_nalloc (subpool, var_cnt, sizeof *var);