From fbbed1cd111e66f8321f4362fb1ec3fbb93f99aa Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 13 Mar 2022 10:55:30 -0700 Subject: [PATCH] expressions: Fix value of $TIME variable and add a test. Thanks to Frans Houweling for reporting this bug. Bug #62003. --- src/language/expressions/evaluate.c | 22 +++++++++++++++++++++- src/language/expressions/parse.c | 2 +- tests/language/expressions/parse.at | 8 +++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/language/expressions/evaluate.c b/src/language/expressions/evaluate.c index 09f237e0cd..8b47f445ee 100644 --- a/src/language/expressions/evaluate.c +++ b/src/language/expressions/evaluate.c @@ -24,6 +24,7 @@ #include "libpspp/assertion.h" #include "libpspp/message.h" #include "language/expressions/helpers.h" +#include "language/lexer/format-parser.h" #include "language/lexer/value-parser.h" #include "libpspp/pool.h" #include "output/driver.h" @@ -124,6 +125,8 @@ cmd_debug_evaluate (struct lexer *lexer, struct dataset *dsother UNUSED) char *name = NULL; char *title = NULL; + struct fmt_spec format; + bool has_format = false; struct expression *expr; @@ -219,6 +222,15 @@ cmd_debug_evaluate (struct lexer *lexer, struct dataset *dsother UNUSED) dict_create_vector_assert (d, "V", vars, n); free (vars); } + else if (lex_match_id (lexer, "FORMAT")) + { + lex_match (lexer, T_EQUALS); + if (!parse_format_specifier (lexer, &format) + || !fmt_check_output (&format) + || !fmt_check_type_compat (&format, VAL_NUMERIC)) + goto done; + has_format = true; + } else break; } @@ -258,7 +270,15 @@ cmd_debug_evaluate (struct lexer *lexer, struct dataset *dsother UNUSED) case OP_num_vec_elem: { double d = expr_evaluate_num (expr, c, 0); - if (d == SYSMIS) + if (has_format) + { + char *output = data_out (&(const union value) { .f = d }, + NULL, &format, + settings_get_fmt_settings ()); + output_log ("%s => %s", title, output); + free (output); + } + else if (d == SYSMIS) output_log ("%s => sysmis", title); else output_log ("%s => %.2f", title, d); diff --git a/src/language/expressions/parse.c b/src/language/expressions/parse.c index 0789fb294d..d06d633d5b 100644 --- a/src/language/expressions/parse.c +++ b/src/language/expressions/parse.c @@ -901,7 +901,7 @@ parse_sysvar (struct lexer *lexer, struct expression *e) struct tm *tm = localtime (&time); return expr_allocate_number (e, ymd_to_offset (tm->tm_year + 1900, tm->tm_mon + 1, - tm->tm_mday) + tm->tm_mday) * DAY_S + tm->tm_hour * 60 * 60. + tm->tm_min * 60. + tm->tm_sec); diff --git a/tests/language/expressions/parse.at b/tests/language/expressions/parse.at index bb3dc3db13..0ea9486eed 100644 --- a/tests/language/expressions/parse.at +++ b/tests/language/expressions/parse.at @@ -420,7 +420,7 @@ $SYSMIS => sysmis AT_CLEANUP # This test will fail if the current date changes during the test. -AT_SETUP([system variables - $DATE $DATE11]) +AT_SETUP([system variables - $DATE $DATE11 $JDATE $TIME]) AT_KEYWORDS([expression expressions parse]) # Get the date in the formats that $DATE and $DATE11 support. date=$(date +%d-%^b-%y) @@ -441,11 +441,17 @@ AS_CASE([$date11], AT_DATA([parse.sps], [dnl DEBUG EVALUATE /$DATE. DEBUG EVALUATE /$DATE11. +DEBUG EVALUATE FORMAT=DATE9 /$JDATE * 86400. +DEBUG EVALUATE FORMAT=DATE9 /$TIME. ]) AT_CHECK_UNQUOTED([pspp --testing-mode parse.sps], [0], [dnl \$DATE => "$date" \$DATE11 => "$date11" + +\$JDATE * 86400 => $date + +\$TIME => $date ]) AT_CLEANUP -- 2.30.2