X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fpor-file-reader.c;h=a9b1de8193f18e34b6b30f3aee0077e8ce85e45d;hb=847f28dc2b47bda50561ff1547af42053a56eb78;hp=377241ef33b861fce3b773610030cef761660d8e;hpb=7a2039fb1ebfd48013ab259b28091e74e7f50588;p=pspp-builds.git diff --git a/src/data/por-file-reader.c b/src/data/por-file-reader.c index 377241ef..a9b1de81 100644 --- a/src/data/por-file-reader.c +++ b/src/data/por-file-reader.c @@ -1,6 +1,5 @@ /* PSPP - computes sample statistics. Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. - Written by Ben Pfaff . Code for parsing floating-point numbers adapted from GNU C library. @@ -36,6 +35,7 @@ #include "dictionary.h" #include "file-handle-def.h" #include "format.h" +#include "missing-values.h" #include #include #include @@ -89,18 +89,18 @@ error (struct pfm_reader *r, const char *msg, ...) struct string text; va_list args; - ds_init (&text); - ds_printf (&text, _("portable file %s corrupt at offset %ld: "), - fh_get_file_name (r->fh), ftell (r->file)); + ds_init_empty (&text); + ds_put_format (&text, _("portable file %s corrupt at offset %ld: "), + fh_get_file_name (r->fh), ftell (r->file)); va_start (args, msg); - ds_vprintf (&text, msg, args); + ds_put_vformat (&text, msg, args); va_end (args); m.category = MSG_GENERAL; m.severity = MSG_ERROR; m.where.file_name = NULL; m.where.line_number = 0; - m.text = ds_c_str (&text); + m.text = ds_cstr (&text); msg_emit (&m); @@ -282,7 +282,7 @@ read_float (struct pfm_reader *r) /* Check that we had some digits. */ if (!got_digit) - error (r, "Number expected."); + error (r, _("Number expected.")); /* Get exponent if any. */ if (r->cc == '+' || r->cc == '-') @@ -421,7 +421,7 @@ read_version_data (struct pfm_reader *r, struct pfm_read_info *info) /* Read file. */ if (!match (r, 'A')) - error (r, "Unrecognized version code `%c'.", r->cc); + error (r, _("Unrecognized version code `%c'."), r->cc); date = read_pool_string (r); time = read_pool_string (r); product = match (r, '1') ? read_pool_string (r) : empty_string; @@ -430,9 +430,9 @@ read_version_data (struct pfm_reader *r, struct pfm_read_info *info) /* Validate file. */ if (strlen (date) != 8) - error (r, _("Bad date string length %d."), strlen (date)); + error (r, _("Bad date string length %d."), (int) strlen (date)); if (strlen (time) != 6) - error (r, _("Bad time string length %d."), strlen (time)); + error (r, _("Bad time string length %d."), (int) strlen (time)); /* Save file info. */ if (info != NULL) @@ -464,22 +464,34 @@ read_version_data (struct pfm_reader *r, struct pfm_read_info *info) /* Translates a format specification read from portable file R as the three integers INTS into a normal format specifier FORMAT, checking that the format is appropriate for variable V. */ -static void +static struct fmt_spec convert_format (struct pfm_reader *r, const int portable_format[3], - struct fmt_spec *format, struct variable *v) + struct variable *v) { - format->type = translate_fmt (portable_format[0]); - if (format->type == -1) + struct fmt_spec format; + bool ok; + + if (!fmt_from_io (portable_format[0], &format.type)) error (r, _("%s: Bad format specifier byte (%d)."), - v->name, portable_format[0]); - format->w = portable_format[1]; - format->d = portable_format[2]; - - if (!check_output_specifier (format, false) - || !check_specifier_width (format, v->width, false)) - error (r, _("%s variable %s has invalid format specifier %s."), - v->type == NUMERIC ? _("Numeric") : _("String"), - v->name, fmt_to_string (format)); + var_get_name (v), portable_format[0]); + format.w = portable_format[1]; + format.d = portable_format[2]; + + msg_disable (); + ok = (fmt_check_output (&format) + && fmt_check_width_compat (&format, var_get_width (v))); + msg_enable (); + + if (!ok) + { + char fmt_string[FMT_STRING_LEN_MAX + 1]; + error (r, _("%s variable %s has invalid format specifier %s."), + var_is_numeric (v) ? _("Numeric") : _("String"), + var_get_name (v), fmt_to_string (&format, fmt_string)); + format = fmt_default_for_width (var_get_width (v)); + } + + return format; } static union value parse_value (struct pfm_reader *, struct variable *); @@ -515,6 +527,8 @@ read_variables (struct pfm_reader *r, struct dictionary *dict) char name[256]; int fmt[6]; struct variable *v; + struct missing_values miss; + struct fmt_spec print, write; int j; if (!match (r, '7')) @@ -534,39 +548,44 @@ read_variables (struct pfm_reader *r, struct dictionary *dict) str_uppercase (name); if (width < 0 || width > 255) - error (r, "Bad width %d for variable %s.", width, name); + error (r, _("Bad width %d for variable %s."), width, name); v = dict_create_var (dict, name, width); if (v == NULL) error (r, _("Duplicate variable name %s."), name); - convert_format (r, &fmt[0], &v->print, v); - convert_format (r, &fmt[3], &v->write, v); + print = convert_format (r, &fmt[0], v); + write = convert_format (r, &fmt[3], v); + var_set_print_format (v, &print); + var_set_write_format (v, &write); /* Range missing values. */ + mv_init (&miss, var_get_width (v)); if (match (r, 'B')) { double x = read_float (r); double y = read_float (r); - mv_add_num_range (&v->miss, x, y); + mv_add_num_range (&miss, x, y); } else if (match (r, 'A')) - mv_add_num_range (&v->miss, read_float (r), HIGHEST); + mv_add_num_range (&miss, read_float (r), HIGHEST); else if (match (r, '9')) - mv_add_num_range (&v->miss, LOWEST, read_float (r)); + mv_add_num_range (&miss, LOWEST, read_float (r)); /* Single missing values. */ while (match (r, '8')) { union value value = parse_value (r, v); - mv_add_value (&v->miss, &value); + mv_add_value (&miss, &value); } + var_set_missing_values (v, &miss); + if (match (r, 'C')) { char label[256]; read_string (r, label); - v->label = xstrdup (label); + var_set_label (v, label); } } @@ -587,7 +606,7 @@ parse_value (struct pfm_reader *r, struct variable *vv) { union value v; - if (vv->type == ALPHA) + if (var_is_alpha (vv)) { char string[256]; read_string (r, string); @@ -623,10 +642,10 @@ read_value_label (struct pfm_reader *r, struct dictionary *dict) if (v[i] == NULL) error (r, _("Unknown variable %s while parsing value labels."), name); - if (v[0]->width != v[i]->width) + if (var_get_width (v[0]) != var_get_width (v[i])) error (r, _("Cannot assign value labels to %s and %s, which " "have different variable types or widths."), - v[0]->name, v[i]->name); + var_get_name (v[0]), var_get_name (v[i])); } n_labels = read_int (r); @@ -644,15 +663,15 @@ read_value_label (struct pfm_reader *r, struct dictionary *dict) { struct variable *var = v[j]; - if (!val_labs_replace (var->val_labs, val, label)) + if (!var_add_value_label (var, &val, label)) continue; - if (var->type == NUMERIC) + if (var_is_numeric (var)) error (r, _("Duplicate label for value %g for variable %s."), - val.f, var->name); + val.f, var_get_name (var)); else error (r, _("Duplicate label for value `%.*s' for variable %s."), - var->width, val.s, var->name); + var_get_width (var), val.s, var_get_name (var)); } } } @@ -679,14 +698,14 @@ pfm_read_case (struct pfm_reader *r, struct ccase *c) if (width == 0) { - case_data_rw (c, idx)->f = read_float (r); + case_data_rw_idx (c, idx)->f = read_float (r); idx++; } else { char string[256]; read_string (r, string); - buf_copy_str_rpad (case_data_rw (c, idx)->s, width, string); + buf_copy_str_rpad (case_data_rw_idx (c, idx)->s, width, string); idx += DIV_RND_UP (width, MAX_SHORT_STRING); } }