From cac0d191514553fede1858bf3dceee9073e60c1a Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 11 Apr 2011 22:48:08 -0700 Subject: [PATCH] FORMATS: Allow setting formats of string variables. Thanks to John Darrington for reporting this bug. Bug #22012. --- doc/variables.texi | 20 +++---- src/language/dictionary/formats.c | 19 +++---- tests/automake.mk | 1 + tests/language/dictionary/formats.at | 80 ++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 22 deletions(-) create mode 100644 tests/language/dictionary/formats.at diff --git a/doc/variables.texi b/doc/variables.texi index dcb7ba7d..dbb3f228 100644 --- a/doc/variables.texi +++ b/doc/variables.texi @@ -127,19 +127,20 @@ FILE LABEL}. @vindex FORMATS @display -FORMATS var_list (fmt_spec). +FORMATS var_list (fmt_spec) [var_list (fmt_spec)]@dots{}. @end display @cmd{FORMATS} set both print and write formats for the specified -numeric variables to the specified format specification. +variables to the specified format specification. @xref{Input and Output Formats}. Specify a list of variables followed by a format specification in parentheses. The print and write formats of the specified variables -will be changed. +will be changed. All of the variables listed together must have +the same type and, for string variables, the same width. -Additional lists of variables and formats may be included if they are -delimited by a slash (@samp{/}). +Additional lists of variables and formats may be included following +the first one. @cmd{FORMATS} takes effect immediately. It is not affected by conditional and looping structures such as @cmd{DO IF} or @cmd{LOOP}. @@ -406,11 +407,11 @@ response sets are currently used only by third party software. @vindex PRINT FORMATS @display -PRINT FORMATS var_list (fmt_spec). +PRINT FORMATS var_list (fmt_spec) [var_list (fmt_spec)]@dots{}. @end display @cmd{PRINT FORMATS} sets the print formats for the specified -numeric variables to the specified format specification. +variables to the specified format specification. Its syntax is identical to that of @cmd{FORMATS} (@pxref{FORMATS}), but @cmd{PRINT FORMATS} sets only print formats, not write formats. @@ -655,11 +656,10 @@ Variables within a vector may be referenced in expressions using @vindex WRITE FORMATS @display -WRITE FORMATS var_list (fmt_spec). +WRITE FORMATS var_list (fmt_spec) [var_list (fmt_spec)]@dots{}. @end display -@cmd{WRITE FORMATS} sets the write formats for the specified numeric -variables +@cmd{WRITE FORMATS} sets the write formats for the specified variables to the specified format specification. Its syntax is identical to that of FORMATS (@pxref{FORMATS}), but @cmd{WRITE FORMATS} sets only write formats, not print formats. diff --git a/src/language/dictionary/formats.c b/src/language/dictionary/formats.c index 9f943be2..718344ac 100644 --- a/src/language/dictionary/formats.c +++ b/src/language/dictionary/formats.c @@ -67,23 +67,18 @@ internal_cmd_formats (struct lexer *lexer, struct dataset *ds, int which) struct variable **v; size_t cv; - /* Format to set the variables to. */ - struct fmt_spec f; - - /* Numeric or string. */ - int type; - - /* Counter. */ - size_t i; - for (;;) { + struct fmt_spec f; + int width; + size_t i; + if (lex_token (lexer) == T_ENDCMD) break; - if (!parse_variables (lexer, dataset_dict (ds), &v, &cv, PV_NUMERIC)) + if (!parse_variables (lexer, dataset_dict (ds), &v, &cv, PV_SAME_WIDTH)) return CMD_FAILURE; - type = var_get_type (v[0]); + width = var_get_width (v[0]); if (!lex_match (lexer, T_LPAREN)) { @@ -92,7 +87,7 @@ internal_cmd_formats (struct lexer *lexer, struct dataset *ds, int which) } if (!parse_format_specifier (lexer, &f) || !fmt_check_output (&f) - || !fmt_check_type_compat (&f, VAL_NUMERIC)) + || !fmt_check_width_compat (&f, width)) goto fail; if (!lex_match (lexer, T_RPAREN)) diff --git a/tests/automake.mk b/tests/automake.mk index 0b7fcb24..b261a8cd 100644 --- a/tests/automake.mk +++ b/tests/automake.mk @@ -307,6 +307,7 @@ TESTSUITE_AT = \ tests/language/data-io/save-translate.at \ tests/language/data-io/update.at \ tests/language/dictionary/attributes.at \ + tests/language/dictionary/formats.at \ tests/language/dictionary/missing-values.at \ tests/language/dictionary/mrsets.at \ tests/language/dictionary/rename-variables.at \ diff --git a/tests/language/dictionary/formats.at b/tests/language/dictionary/formats.at new file mode 100644 index 00000000..4bdf089f --- /dev/null +++ b/tests/language/dictionary/formats.at @@ -0,0 +1,80 @@ +AT_BANNER([FORMATS]) + +AT_SETUP([FORMATS positive tests]) +AT_DATA([formats.sps], [dnl +DATA LIST LIST /a b c * x (A1) y (A2) z (A3). +DISPLAY VARIABLES. +FORMATS a (COMMA10) b (N4). +DISPLAY VARIABLES. +FORMATS c (E8.1) x (A1) y (AHEX4) z (A3). +DISPLAY VARIABLES. +]) +AT_CHECK([pspp -o pspp.csv formats.sps]) +AT_CHECK([grep -E -v 'Measure|Display' pspp.csv], [0], [dnl +Table: Reading free-form data from INLINE. +Variable,Format +a,F8.0 +b,F8.0 +c,F8.0 +x,A1 +y,A2 +z,A3 + +Variable,Description,,Position +a,Format: F8.2,,1 +b,Format: F8.2,,2 +c,Format: F8.2,,3 +x,Format: A1,,4 +y,Format: A2,,5 +z,Format: A3,,6 + +Variable,Description,,Position +a,Format: COMMA10.0,,1 +b,Format: N4.0,,2 +c,Format: F8.2,,3 +x,Format: A1,,4 +y,Format: A2,,5 +z,Format: A3,,6 + +Variable,Description,,Position +a,Format: COMMA10.0,,1 +b,Format: N4.0,,2 +c,Format: E8.1,,3 +x,Format: A1,,4 +y,Format: AHEX4,,5 +z,Format: A3,,6 +]) +AT_CLEANUP + +AT_SETUP([FORMATS negative tests]) +AT_DATA([formats.sps], [dnl +DATA LIST LIST /a b c * x (A1) y (A2) z (A3). +FORMATS a (E6.1). +FORMATS a y (F4). +FORMATS x (A2). +FORMATS y (AHEX2). +FORMATS x y (A2). +]) +AT_CHECK([pspp -O format=csv formats.sps], [1], [dnl +Table: Reading free-form data from INLINE. +Variable,Format +a,F8.0 +b,F8.0 +c,F8.0 +x,A1 +y,A2 +z,A3 + +"formats.sps:2: error: FORMATS: Output format E6.1 specifies 1 decimal place, but the given width does not allow for any decimals." + +formats.sps:3: error: FORMATS: a and y are not the same type. All variables in this variable list must be of the same type. y will be omitted from the list. + +formats.sps:4: error: FORMATS: String variable with width 1 is not compatible with format A2. + +formats.sps:5: error: FORMATS: String variable with width 2 is not compatible with format AHEX2. + +formats.sps:6: error: FORMATS: x and y are string variables with different widths. All variables in this variable list must have the same width. y will be omitted from the list. + +formats.sps:6: error: FORMATS: String variable with width 1 is not compatible with format A2. +]) +AT_CLEANUP -- 2.30.2