From 597dc92521dee8ba43334b9c5ca6a995aaae0ab8 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 17 May 2005 05:46:39 +0000 Subject: [PATCH] Fix rest of PR 13054. --- src/ChangeLog | 32 +++++++++++++++++++++++++++++++- src/aggregate.c | 1 - src/data-list.c | 6 ++---- src/data-out.c | 5 +---- src/dictionary.c | 10 ++-------- src/format.c | 29 +++++++++++++++++++++++++++++ src/format.def | 18 +++++++++--------- src/format.h | 5 +++++ src/get.c | 5 ++--- src/list.q | 6 +++--- src/matrix-data.c | 4 +--- src/sfm-read.c | 35 ++++++++++++++++++++--------------- src/tab.c | 4 +--- 13 files changed, 106 insertions(+), 54 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 9039838e..c111507a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,6 +1,36 @@ -Sun May 15 23:38:10 2005 Ben Pfaff +Mon May 16 22:34:06 2005 Ben Pfaff Fix rest of PR 13054. + + * format.def: Fix EDATE, SDATE, ADATE, JDATE, QYR, MOYR, WKYR, + DATETIME, TIME system/portable file values. + +Mon May 16 22:31:15 2005 Ben Pfaff + + * data-list.c: (parse_free) Use make_input_format(). + + * data-out.c: (num_to_string) Use make_output_format(). + + * dictionary.c: (dict_create_var) Ditto. + + * format.c: (global var f8_2) New var. + (make_input_format) New function. + (make_output_format) New function. + + * get.c: (cmd_match_files) Use make_output_format(). + + * list.q: (cmd_list) Ditto. + + * matrix-data.c: Ditto. + + * sfm-read.c: (parse_format_spec) Check output specifier + thoroughly. + + * tab.c: (tab_float) Use make_output_format(). + +Sun May 15 23:38:10 2005 Ben Pfaff + + Fix more of PR 13054. * format.def: FMT_A should allow 255-character output. FMT_AHEX should allow 510-character input and output. diff --git a/src/aggregate.c b/src/aggregate.c index 7f34309c..47c60f34 100644 --- a/src/aggregate.c +++ b/src/aggregate.c @@ -522,7 +522,6 @@ parse_aggregate_functions (struct agr_proc *agr) /* Create the target variable in the aggregate dictionary. */ { - static const struct fmt_spec f8_2 = {FMT_F, 8, 2}; struct variable *destvar; v->function = func_index; diff --git a/src/data-list.c b/src/data-list.c index a6a68dc6..66fab631 100644 --- a/src/data-list.c +++ b/src/data-list.c @@ -848,10 +848,8 @@ parse_free (struct dls_var_spec **first, struct dls_var_spec **last) else { lex_match ('*'); - input.type = FMT_F; - input.w = 8; - input.d = 0; - output = get_format(); + input = make_input_format (FMT_F, 8, 0); + output = get_format (); } if (input.type == FMT_A || input.type == FMT_AHEX) diff --git a/src/data-out.c b/src/data-out.c index 6439b607..5fce84f6 100644 --- a/src/data-out.c +++ b/src/data-out.c @@ -193,10 +193,7 @@ data_out (char *s, const struct fmt_spec *fp, const union value *v) void num_to_string (double v, char *s, int w, int d) { - struct fmt_spec f; - f.type = FMT_F; - f.w = w; - f.d = d; + struct fmt_spec f = make_output_format (FMT_F, w, d); convert_F (s, &f, v); } diff --git a/src/dictionary.c b/src/dictionary.c index 0fd59e11..6fbd5dfa 100644 --- a/src/dictionary.c +++ b/src/dictionary.c @@ -279,20 +279,14 @@ dict_create_var (struct dictionary *d, const char *name, int width) v->miss_type = MISSING_NONE; if (v->type == NUMERIC) { - v->print.type = FMT_F; - v->print.w = 8; - v->print.d = 2; - + v->print = f8_2; v->alignment = ALIGN_RIGHT; v->display_width = 8; v->measure = MEASURE_SCALE; } else { - v->print.type = FMT_A; - v->print.w = v->width; - v->print.d = 0; - + v->print = make_output_format (FMT_A, v->width, 0); v->alignment = ALIGN_LEFT; v->display_width = 8; v->measure = MEASURE_NOMINAL; diff --git a/src/format.c b/src/format.c index 87be7b08..5e06ab22 100644 --- a/src/format.c +++ b/src/format.c @@ -37,6 +37,9 @@ struct fmt_desc formats[FMT_NUMBER_OF_FORMATS + 1] = {"", -1, -1, -1, -1, -1, 0000, -1, -1}, }; +/* Common formats. */ +const struct fmt_spec f8_2 = {FMT_F, 8, 2}; + /* Parses the alphabetic prefix of the current token as a format specifier name. Returns the corresponding format specifier type if successful, or -1 on failure. If ALLOW_XT is zero, @@ -442,3 +445,29 @@ translate_fmt (int spss) return type; return -1; } + +/* Returns an input format specification with type TYPE, width W, + and D decimals. */ +struct fmt_spec +make_input_format (int type, int w, int d) +{ + struct fmt_spec f; + f.type = type; + f.w = w; + f.d = d; + assert (check_input_specifier (&f, 0)); + return f; +} + +/* Returns an output format specification with type TYPE, width + W, and D decimals. */ +struct fmt_spec +make_output_format (int type, int w, int d) +{ + struct fmt_spec f; + f.type = type; + f.w = w; + f.d = d; + assert (check_output_specifier (&f, 0)); + return f; +} diff --git a/src/format.def b/src/format.def index e6f1725b..0dfc21c0 100644 --- a/src/format.def +++ b/src/format.def @@ -45,15 +45,15 @@ DEFFMT (FMT_CCE, "CCE", 2, -1, -1, 1, 40, 0020, FMT_CCE, 37) /* Date/time formats. */ DEFFMT (FMT_DATE, "DATE", 1, 9, 40, 9, 40, 0001, FMT_DATE, 20) -DEFFMT (FMT_EDATE, "EDATE", 1, 8, 40, 8, 40, 0001, FMT_EDATE, 23) -DEFFMT (FMT_SDATE, "SDATE", 1, 8, 40, 8, 40, 0001, FMT_SDATE, 24) -DEFFMT (FMT_ADATE, "ADATE", 1, 8, 40, 8, 40, 0001, FMT_ADATE, 29) -DEFFMT (FMT_JDATE, "JDATE", 1, 5, 40, 5, 40, 0001, FMT_JDATE, 28) -DEFFMT (FMT_QYR, "QYR", 1, 4, 40, 6, 40, 0001, FMT_QYR, 30) -DEFFMT (FMT_MOYR, "MOYR", 1, 6, 40, 6, 40, 0001, FMT_MOYR, 22) -DEFFMT (FMT_WKYR, "WKYR", 1, 6, 40, 8, 40, 0001, FMT_WKYR, 21) -DEFFMT (FMT_DATETIME, "DATETIME", 2, 17, 40, 17, 40, 0001, FMT_DATETIME, 38) -DEFFMT (FMT_TIME, "TIME", 2, 5, 40, 5, 40, 0001, FMT_TIME, 39) +DEFFMT (FMT_EDATE, "EDATE", 1, 8, 40, 8, 40, 0001, FMT_EDATE, 38) +DEFFMT (FMT_SDATE, "SDATE", 1, 8, 40, 8, 40, 0001, FMT_SDATE, 39) +DEFFMT (FMT_ADATE, "ADATE", 1, 8, 40, 8, 40, 0001, FMT_ADATE, 23) +DEFFMT (FMT_JDATE, "JDATE", 1, 5, 40, 5, 40, 0001, FMT_JDATE, 24) +DEFFMT (FMT_QYR, "QYR", 1, 4, 40, 6, 40, 0001, FMT_QYR, 29) +DEFFMT (FMT_MOYR, "MOYR", 1, 6, 40, 6, 40, 0001, FMT_MOYR, 28) +DEFFMT (FMT_WKYR, "WKYR", 1, 6, 40, 8, 40, 0001, FMT_WKYR, 30) +DEFFMT (FMT_DATETIME, "DATETIME", 2, 17, 40, 17, 40, 0001, FMT_DATETIME, 22) +DEFFMT (FMT_TIME, "TIME", 2, 5, 40, 5, 40, 0001, FMT_TIME, 21) DEFFMT (FMT_DTIME, "DTIME", 2, 11, 40, 8, 40, 0001, FMT_DTIME, 25) DEFFMT (FMT_WKDAY, "WKDAY", 1, 2, 40, 2, 40, 0001, FMT_WKDAY, 26) DEFFMT (FMT_MONTH, "MONTH", 1, 3, 40, 3, 40, 0001, FMT_MONTH, 27) diff --git a/src/format.h b/src/format.h index f1a11a1f..da33f5f3 100644 --- a/src/format.h +++ b/src/format.h @@ -104,6 +104,9 @@ enum fmt_parse_flags FMTP_SUPPRESS_ERRORS = 002 /* 1=Do not emit error messages. */ }; +/* Common formats. */ +extern const struct fmt_spec f8_2; /* F8.2. */ + int parse_format_specifier (struct fmt_spec *input, enum fmt_parse_flags); int parse_format_specifier_name (const char **cp, enum fmt_parse_flags); int check_input_specifier (const struct fmt_spec *spec, int emit_error); @@ -119,5 +122,7 @@ int translate_fmt (int spss); void data_out (char *s, const struct fmt_spec *fp, const union value *v); char *fmt_to_string (const struct fmt_spec *); void num_to_string (double v, char *s, int w, int d); +struct fmt_spec make_input_format (int type, int w, int d); +struct fmt_spec make_output_format (int type, int w, int d); #endif /* !format_h */ diff --git a/src/get.c b/src/get.c index 5ec84482..3300ae64 100644 --- a/src/get.c +++ b/src/get.c @@ -977,8 +977,6 @@ cmd_match_files (void) for (iter = mtf.head; iter != NULL; iter = iter->next) if (iter->in_name != NULL) { - static const struct fmt_spec f1_0 = {FMT_F, 1, 0}; - iter->in_var = dict_create_var (mtf.dict, iter->in_name, 0); if (iter->in_var == NULL) { @@ -987,7 +985,8 @@ cmd_match_files (void) iter->in_var); goto error; } - iter->in_var->print = iter->in_var->write = f1_0; + iter->in_var->print = iter->in_var->write + = make_output_format (FMT_F, 1, 0); } /* MATCH FILES performs an n-way merge on all its input files. diff --git a/src/list.q b/src/list.q index 3add8de1..97f5372d 100644 --- a/src/list.q +++ b/src/list.q @@ -204,9 +204,9 @@ cmd_list (void) strcpy (casenum_var.name, "Case#"); casenum_var.type = NUMERIC; casenum_var.fv = -1; - casenum_var.print.type = FMT_F; - casenum_var.print.w = (cmd.last == LONG_MAX ? 5 : intlog10 (cmd.last)); - casenum_var.print.d = 0; + casenum_var.print = make_output_format (FMT_F, + (cmd.last == LONG_MAX + ? 5 : intlog10 (cmd.last)), 0); /* Add the weight variable at the beginning of the variable list. */ cmd.n_variables++; diff --git a/src/matrix-data.c b/src/matrix-data.c index 776dfa5b..d3cde3e6 100644 --- a/src/matrix-data.c +++ b/src/matrix-data.c @@ -884,9 +884,7 @@ static int di.e = token->string + token->length; di.v = (union value *) &token->number; di.f1 = first_column; - di.format.type = FMT_F; - di.format.w = token->length; - di.format.d = 0; + di.format = make_output_format (FMT_F, token->length, 0); if (!data_in (&di)) return 0; diff --git a/src/sfm-read.c b/src/sfm-read.c index 23abde90..c036739b 100644 --- a/src/sfm-read.c +++ b/src/sfm-read.c @@ -974,27 +974,32 @@ error: /* Translates the format spec from sysfile format to internal format. */ static int -parse_format_spec (struct sfm_reader *r, int32 s, struct fmt_spec *v, struct variable *vv) +parse_format_spec (struct sfm_reader *r, int32 s, + struct fmt_spec *f, struct variable *v) { - v->type = translate_fmt ((s >> 16) & 0xff); - if (v->type == -1) + f->type = translate_fmt ((s >> 16) & 0xff); + if (f->type == -1) lose ((ME, _("%s: Bad format specifier byte (%d)."), handle_get_filename (r->fh), (s >> 16) & 0xff)); - v->w = (s >> 8) & 0xff; - v->d = s & 0xff; + f->w = (s >> 8) & 0xff; + f->d = s & 0xff; - /* FIXME? Should verify the resulting specifier more thoroughly. */ - - if (v->type == -1) - lose ((ME, _("%s: Bad format specifier byte (%d)."), - handle_get_filename (r->fh), (s >> 16) & 0xff)); - if ((vv->type == ALPHA) ^ ((formats[v->type].cat & FCAT_STRING) != 0)) + if ((v->type == ALPHA) ^ ((formats[f->type].cat & FCAT_STRING) != 0)) lose ((ME, _("%s: %s variable %s has %s format specifier %s."), handle_get_filename (r->fh), - vv->type == ALPHA ? _("String") : _("Numeric"), - vv->name, - formats[v->type].cat & FCAT_STRING ? _("string") : _("numeric"), - formats[v->type].name)); + v->type == ALPHA ? _("String") : _("Numeric"), + v->name, + formats[f->type].cat & FCAT_STRING ? _("string") : _("numeric"), + formats[f->type].name)); + + if (!check_output_specifier (f, false) + || !check_specifier_width (f, v->width, false)) + { + msg (ME, _("%s variable %s has invalid format specifier %s."), + v->type == NUMERIC ? _("Numeric") : _("String"), + v->name, fmt_to_string (f)); + *f = v->type == NUMERIC ? f8_2 : make_output_format (FMT_A, v->width, 0); + } return 1; error: diff --git a/src/tab.c b/src/tab.c index 6005ec9c..9f6a9c35 100644 --- a/src/tab.c +++ b/src/tab.c @@ -607,9 +607,7 @@ tab_float (struct tab_table *table, int c, int r, unsigned char opt, assert (r >= 0); assert (r < table->nr); - f.type = FMT_F; - f.w = w; - f.d = d; + f = make_output_format (FMT_F, w, d); #if GLOBAL_DEBUGGING if (c + table->col_ofs < 0 || r + table->row_ofs < 0 -- 2.30.2