X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fsys-file-reader.c;h=1882943003572ef8b9b28a1d2c73a7a94bd7a776;hb=bc0e3fee279da2813183ab2cd17fced06eae09e8;hp=de9ae0d655f831e7097f696581bca5164ca8be8d;hpb=9f4661992f4b481c6dafa6fd53c94ecfe7b3af8c;p=pspp-builds.git diff --git a/src/data/sys-file-reader.c b/src/data/sys-file-reader.c index de9ae0d6..18829430 100644 --- a/src/data/sys-file-reader.c +++ b/src/data/sys-file-reader.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -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); @@ -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++) @@ -836,19 +845,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 @@ -856,16 +882,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; } @@ -873,10 +896,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); } }