expressions: Fix value of $TIME variable and add a test.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 13 Mar 2022 17:55:30 +0000 (10:55 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 13 Mar 2022 17:55:30 +0000 (10:55 -0700)
Thanks to Frans Houweling for reporting this bug.
Bug #62003.

src/language/expressions/evaluate.c
src/language/expressions/parse.c
tests/language/expressions/parse.at

index 09f237e0cd4e3664a0a57353ce2b0f0d2292becf..8b47f445ee050df33f112c25a2c85a526d9f7a4d 100644 (file)
@@ -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);
index 0789fb294d39933fa1f54f2a4fc4fb92c7b72d95..d06d633d5b02fa4eb40273a02e2d7bbb64e90714 100644 (file)
@@ -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);
index bb3dc3db1383bee7dfb0bf6ec344e6d2e93ad496..0ea9486eed3745a5f5e7ccbea8e1b88d9b639c7f 100644 (file)
@@ -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