From 038deb761907154dd916c6625aa20600f823a84c Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 12 Apr 2011 06:48:08 -0700 Subject: [PATCH] value-parser: Make parse_value() accept variable's print format also. Previously commands such as VALUE LABELS required numeric values to be given as plain numbers, but this makes it difficult to add meaningful value labels for variables with date and time formats. This commit allows values for this command and a few others to be given in a variable's print format instead. Bug #18497. --- src/language/dictionary/value-labels.c | 2 +- src/language/expressions/evaluate.c | 2 +- src/language/lexer/value-parser.c | 15 ++++++------- src/language/lexer/value-parser.h | 5 +++-- src/language/stats/npar.c | 4 ++-- src/language/stats/roc.c | 2 +- src/language/stats/t-test.q | 4 ++-- tests/language/dictionary/value-labels.at | 26 +++++++++++++++++++++++ 8 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/language/dictionary/value-labels.c b/src/language/dictionary/value-labels.c index 57124ebe..2dfe0885 100644 --- a/src/language/dictionary/value-labels.c +++ b/src/language/dictionary/value-labels.c @@ -131,7 +131,7 @@ get_label (struct lexer *lexer, struct variable **vars, size_t var_cnt, /* Set value. */ value_init (&value, width); - if (!parse_value (lexer, &value, width)) + if (!parse_value (lexer, &value, vars[0])) { value_destroy (&value, width); return 0; diff --git a/src/language/expressions/evaluate.c b/src/language/expressions/evaluate.c index 3df9a6c9..56deb9a5 100644 --- a/src/language/expressions/evaluate.c +++ b/src/language/expressions/evaluate.c @@ -174,7 +174,7 @@ cmd_debug_evaluate (struct lexer *lexer, struct dataset *dsother UNUSED) else c = case_unshare_and_resize (c, dict_get_proto (d)); - if (!parse_value (lexer, case_data_rw (c, v), var_get_width (v))) + if (!parse_value (lexer, case_data_rw (c, v), v)) NOT_REACHED (); if (!lex_force_match (lexer, T_RPAREN)) diff --git a/src/language/lexer/value-parser.c b/src/language/lexer/value-parser.c index ff2701e8..74478cfa 100644 --- a/src/language/lexer/value-parser.c +++ b/src/language/lexer/value-parser.c @@ -129,18 +129,15 @@ parse_number (struct lexer *lexer, double *x, const enum fmt_type *format) } } -/* Parses the current token from LEXER into value V, which must - already have been initialized with the specified WIDTH. - Returns true if successful, false otherwise. */ +/* Parses the current token from LEXER into value V, which must already have + been initialized with the specified VAR's WIDTH. Returns true if + successful, false otherwise. */ bool -parse_value (struct lexer *lexer, union value *v, int width) +parse_value (struct lexer *lexer, union value *v, const struct variable *var) { + int width = var_get_width (var); if (width == 0) - { - if (!lex_force_num (lexer)) - return false; - v->f = lex_tokval (lexer); - } + return parse_number (lexer, &v->f, &var_get_print_format (var)->type); else if (lex_force_string (lexer)) { const char *s = lex_tokcstr (lexer); diff --git a/src/language/lexer/value-parser.h b/src/language/lexer/value-parser.h index 4f9004a3..94b2cdc1 100644 --- a/src/language/lexer/value-parser.h +++ b/src/language/lexer/value-parser.h @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2005, 2009 Free Software Foundation, Inc. + Copyright (C) 2005, 2009, 2011 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,9 +21,10 @@ struct lexer; enum fmt_type; +struct variable; union value; bool parse_num_range (struct lexer *, double *x, double *y, const enum fmt_type *fmt); -bool parse_value (struct lexer *, union value *, int width); +bool parse_value (struct lexer *, union value *, const struct variable *); #endif /* value-parser.h */ diff --git a/src/language/stats/npar.c b/src/language/stats/npar.c index 3d977a7d..2bc42934 100644 --- a/src/language/stats/npar.c +++ b/src/language/stats/npar.c @@ -1027,7 +1027,7 @@ parse_n_sample_related_test (struct lexer *lexer, return false; value_init (&nst->val1, var_get_width (nst->indep_var)); - if ( ! parse_value (lexer, &nst->val1, var_get_width (nst->indep_var))) + if ( ! parse_value (lexer, &nst->val1, nst->indep_var)) { value_destroy (&nst->val1, var_get_width (nst->indep_var)); return false; @@ -1036,7 +1036,7 @@ parse_n_sample_related_test (struct lexer *lexer, lex_match (lexer, T_COMMA); value_init (&nst->val2, var_get_width (nst->indep_var)); - if ( ! parse_value (lexer, &nst->val2, var_get_width (nst->indep_var))) + if ( ! parse_value (lexer, &nst->val2, nst->indep_var)) { value_destroy (&nst->val2, var_get_width (nst->indep_var)); return false; diff --git a/src/language/stats/roc.c b/src/language/stats/roc.c index b6596ec7..471b946e 100644 --- a/src/language/stats/roc.c +++ b/src/language/stats/roc.c @@ -113,7 +113,7 @@ cmd_roc (struct lexer *lexer, struct dataset *ds) } value_init (&roc.state_value, var_get_width (roc.state_var)); - parse_value (lexer, &roc.state_value, var_get_width (roc.state_var)); + parse_value (lexer, &roc.state_value, roc.state_var); if ( !lex_force_match (lexer, T_RPAREN)) diff --git a/src/language/stats/t-test.q b/src/language/stats/t-test.q index 4b082fe7..d26fc8a4 100644 --- a/src/language/stats/t-test.q +++ b/src/language/stats/t-test.q @@ -295,14 +295,14 @@ tts_custom_groups (struct lexer *lexer, struct dataset *ds, n_values = 0; else { - if (!parse_value (lexer, &proc->g_value[0], width)) + if (!parse_value (lexer, &proc->g_value[0], proc->indep_var)) return 0; lex_match (lexer, T_COMMA); if (lex_match (lexer, T_RPAREN)) n_values = 1; else { - if (!parse_value (lexer, &proc->g_value[1], width) + if (!parse_value (lexer, &proc->g_value[1], proc->indep_var) || !lex_force_match (lexer, T_RPAREN)) return 0; n_values = 2; diff --git a/tests/language/dictionary/value-labels.at b/tests/language/dictionary/value-labels.at index c6c48db4..feec9d86 100644 --- a/tests/language/dictionary/value-labels.at +++ b/tests/language/dictionary/value-labels.at @@ -1,5 +1,31 @@ AT_BANNER([VALUE LABELS]) +AT_SETUP([VALUE LABELS date formats]) +AT_DATA([value-labels.sps], [dnl +DATA LIST LIST NOTABLE /ad (adate10) dt (datetime20). +VALUE LABELS ad 'july 10, 1982' 'label 1' + '1-2-93' 'label 2' + '5-4-2003' 'label 3' + /dt '12 Apr 2011 06:09:56' 'label 4'. +DISPLAY DICTIONARY. +]) +AT_CHECK([pspp -O format=csv value-labels.sps], [0], [dnl +Variable,Description,,Position +ad,Format: ADATE10,,1 +,Measure: Scale,, +,Display Alignment: Right,, +,Display Width: 8,, +,07/10/1982,label 1, +,01/02/1993,label 2, +,05/04/2003,label 3, +dt,Format: DATETIME20.0,,2 +,Measure: Scale,, +,Display Alignment: Right,, +,Display Width: 8,, +,12-APR-2011 06:09:56,label 4, +]) +AT_CLEANUP + dnl Tests for a bug which caused VALUE LABELS to dnl crash when given invalid syntax. AT_SETUP([VALUE LABELS invalid syntax bug]) -- 2.30.2