more tests ctables3
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 26 Dec 2021 07:26:55 +0000 (23:26 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 26 Dec 2021 07:26:55 +0000 (23:26 -0800)
src/data/format.c
src/data/format.h
src/language/expressions/operations.def
src/language/expressions/parse.c
tests/language/expressions/evaluate.at

index f323424d0868fbf128629bbf845e7bb94726a813..79c6240a9125423ec986148a82d067701c4e048c 100644 (file)
@@ -334,10 +334,11 @@ fmt_default_for_width (int width)
           : fmt_for_output (FMT_A, width, 0));
 }
 
-/* Checks whether SPEC is valid for USE and returns nonzero if so.
-   Otherwise, emits an error message and returns zero. */
-bool
-fmt_check (const struct fmt_spec *spec, enum fmt_use use)
+/* Checks whether SPEC is valid for USE and returns NULL if so.  Otherwise,
+   returns a malloc()'d string that describes the error.  The caller must
+   eventually free() the string. */
+char *
+fmt_check__ (const struct fmt_spec *spec, enum fmt_use use)
 {
   char str[FMT_STRING_LEN_MAX + 1];
   int min_w, max_w, max_d;
@@ -346,107 +347,115 @@ fmt_check (const struct fmt_spec *spec, enum fmt_use use)
   fmt_to_string (spec, str);
 
   if (use == FMT_FOR_INPUT && !fmt_usable_for_input (spec->type))
-    {
-      msg (SE, _("Format %s may not be used for input."), str);
-      return false;
-    }
+    return xasprintf (_("Format %s may not be used for input."), str);
 
   if (spec->w % fmt_step_width (spec->type))
     {
       assert (fmt_step_width (spec->type) == 2);
-      if (use == FMT_FOR_INPUT)
-        msg (SE, _("Input format %s specifies width %d, "
-                   "but %s requires an even width."),
-             str, spec->w, fmt_name (spec->type));
-      else
-        msg (SE, _("Output format %s specifies width %d, "
-                   "but %s requires an even width."),
-             str, spec->w, fmt_name (spec->type));
-      return false;
+      return (use == FMT_FOR_INPUT
+              ? xasprintf (_("Input format %s specifies width %d, "
+                             "but %s requires an even width."),
+                           str, spec->w, fmt_name (spec->type))
+              : xasprintf (_("Output format %s specifies width %d, "
+                             "but %s requires an even width."),
+                           str, spec->w, fmt_name (spec->type)));
     }
 
   min_w = fmt_min_width (spec->type, use);
   max_w = fmt_max_width (spec->type, use);
   if (spec->w < min_w || spec->w > max_w)
-    {
-      if (use == FMT_FOR_INPUT)
-        msg (SE, _("Input format %s specifies width %d, but "
-                   "%s requires a width between %d and %d."),
-             str, spec->w, fmt_name (spec->type), min_w, max_w);
-      else
-        msg (SE, _("Output format %s specifies width %d, but "
-                   "%s requires a width between %d and %d."),
-             str, spec->w, fmt_name (spec->type), min_w, max_w);
-      return false;
-    }
+    return (use == FMT_FOR_INPUT
+            ? xasprintf (_("Input format %s specifies width %d, but "
+                           "%s requires a width between %d and %d."),
+                         str, spec->w, fmt_name (spec->type), min_w, max_w)
+            : xasprintf (_("Output format %s specifies width %d, but "
+                           "%s requires a width between %d and %d."),
+                         str, spec->w, fmt_name (spec->type), min_w, max_w));
 
   max_d = fmt_max_decimals (spec->type, spec->w, use);
   if (!fmt_takes_decimals (spec->type) && spec->d != 0)
-    {
-      if (use == FMT_FOR_INPUT)
-        msg (SE, ngettext ("Input format %s specifies %d decimal place, but "
-                           "%s does not allow any decimals.",
-                           "Input format %s specifies %d decimal places, but "
-                           "%s does not allow any decimals.",
+    return (use == FMT_FOR_INPUT
+            ? xasprintf (ngettext (
+                           "Input format %s specifies %d decimal "
+                           "place, but %s does not allow any decimals.",
+                           "Input format %s specifies %d decimal "
+                           "places, but %s does not allow any "
+                           "decimals.",
                            spec->d),
-             str, spec->d, fmt_name (spec->type));
-      else
-        msg (SE, ngettext ("Output format %s specifies %d decimal place, but "
-                           "%s does not allow any decimals.",
+                         str, spec->d, fmt_name (spec->type))
+            : xasprintf (ngettext (
+                           "Output format %s specifies %d decimal "
+                           "place, but %s does not allow any decimals.",
                            "Output format %s specifies %d decimal places, but "
                            "%s does not allow any decimals.",
                            spec->d),
-             str, spec->d, fmt_name (spec->type));
-      return false;
-    }
+                         str, spec->d, fmt_name (spec->type)));
   else if (spec->d > max_d)
     {
       if (max_d > 0)
-        {
-          if (use == FMT_FOR_INPUT)
-            msg (SE, ngettext ("Input format %s specifies %d decimal place, "
+        return (use == FMT_FOR_INPUT
+                ? xasprintf (ngettext (
+                               "Input format %s specifies %d decimal place, "
                                "but the given width allows at most "
                                "%d decimals.",
                                "Input format %s specifies %d decimal places, "
                                "but the given width allows at most "
                                "%d decimals.",
                                spec->d),
-                 str, spec->d, max_d);
-          else
-            msg (SE, ngettext ("Output format %s specifies %d decimal place, "
+                             str, spec->d, max_d)
+                : xasprintf (ngettext (
+                               "Output format %s specifies %d decimal place, "
                                "but the given width allows at most "
                                "%d decimals.",
                                "Output format %s specifies %d decimal places, "
                                "but the given width allows at most "
                                "%d decimals.",
                                spec->d),
-                 str, spec->d, max_d);
-        }
+                             str, spec->d, max_d));
       else
-        {
-          if (use == FMT_FOR_INPUT)
-            msg (SE, ngettext ("Input format %s specifies %d decimal place, "
+        return (use == FMT_FOR_INPUT
+                ? xasprintf (ngettext (
+                               "Input format %s specifies %d decimal place, "
                                "but the given width does not allow "
                                "for any decimals.",
                                "Input format %s specifies %d decimal places, "
                                "but the given width does not allow "
                                "for any decimals.",
                                spec->d),
-                 str, spec->d);
-          else
-            msg (SE, ngettext ("Output format %s specifies %d decimal place, "
+                             str, spec->d)
+                : xasprintf (ngettext (
+                               "Output format %s specifies %d decimal place, "
                                "but the given width does not allow "
                                "for any decimals.",
                                "Output format %s specifies %d decimal places, "
                                "but the given width does not allow "
                                "for any decimals.",
                                spec->d),
-                 str, spec->d);
-        }
+                             str, spec->d));
+    }
+
+  return NULL;
+}
+
+static bool
+fmt_emit_and_free_error (char *error)
+{
+  if (error)
+    {
+      msg (SE, "%s", error);
+      free (error);
       return false;
     }
+  else
+    return true;
+}
 
-  return true;
+/* Checks whether SPEC is valid for USE and returns nonzero if so.  Otherwise,
+   emits an error message for the current source location and returns zero. */
+bool
+fmt_check (const struct fmt_spec *spec, enum fmt_use use)
+{
+  return fmt_emit_and_free_error (fmt_check__ (spec, use));
 }
 
 /* Checks whether SPEC is valid as an input format and returns
@@ -466,23 +475,52 @@ fmt_check_output (const struct fmt_spec *spec)
   return fmt_check (spec, FMT_FOR_OUTPUT);
 }
 
+/* Checks that FORMAT is appropriate for a variable of the given VAR_TYPE and
+   returns NULL if so.  Otherwise returns a malloc()'d error message that the
+   calelr must eventually free(). */
+char *
+fmt_check_type_compat__ (const struct fmt_spec *format, enum val_type var_type)
+{
+  assert (val_type_is_valid (var_type));
+  if ((var_type == VAL_STRING) != (fmt_is_string (format->type) != 0))
+    {
+      char str[FMT_STRING_LEN_MAX + 1];
+      return xasprintf (_("%s variables are not compatible with %s format %s."),
+                        var_type == VAL_STRING ? _("String") : _("Numeric"),
+                        var_type == VAL_STRING ? _("numeric") : _("string"),
+                        fmt_to_string (format, str));
+    }
+  return NULL;
+}
+
 /* Checks that FORMAT is appropriate for a variable of the given
    VAR_TYPE and returns true if so.  Otherwise returns false and
    emits an error message. */
 bool
 fmt_check_type_compat (const struct fmt_spec *format, enum val_type var_type)
 {
-  assert (val_type_is_valid (var_type));
-  if ((var_type == VAL_STRING) != (fmt_is_string (format->type) != 0))
+  return fmt_emit_and_free_error (fmt_check_type_compat__ (format, var_type));
+}
+
+/* Checks that FORMAT is appropriate for a variable of the given WIDTH and
+   returns NULL if so.  Otherwise returns a malloc()'d error message that the
+   calelr must eventually free(). */
+char *
+fmt_check_width_compat__ (const struct fmt_spec *format, int width)
+{
+  char *error = fmt_check_type_compat__ (format, val_type_from_width (width));
+  if (error)
+    return error;
+
+  if (fmt_var_width (format) != width)
     {
       char str[FMT_STRING_LEN_MAX + 1];
-      msg (SE, _("%s variables are not compatible with %s format %s."),
-           var_type == VAL_STRING ? _("String") : _("Numeric"),
-           var_type == VAL_STRING ? _("numeric") : _("string"),
-           fmt_to_string (format, str));
-      return false;
+      return xasprintf (_("String variable with width %d is not compatible "
+                          "with format %s."),
+                        width, fmt_to_string (format, str));
     }
-  return true;
+
+  return NULL;
 }
 
 /* Checks that FORMAT is appropriate for a variable of the given
@@ -491,17 +529,7 @@ fmt_check_type_compat (const struct fmt_spec *format, enum val_type var_type)
 bool
 fmt_check_width_compat (const struct fmt_spec *format, int width)
 {
-  if (!fmt_check_type_compat (format, val_type_from_width (width)))
-    return false;
-  if (fmt_var_width (format) != width)
-    {
-      char str[FMT_STRING_LEN_MAX + 1];
-      msg (SE, _("String variable with width %d is not compatible with "
-                 "format %s."),
-           width, fmt_to_string (format, str));
-      return false;
-    }
-  return true;
+  return fmt_emit_and_free_error (fmt_check_width_compat__ (format, width));
 }
 
 /* Returns the width corresponding to FORMAT.  The return value
index 4cde16b17a0b1352356f6b522c602bc18150b70e..d6779d4b3f5f6dccab20e952d55006cf835eaf0e 100644 (file)
@@ -25,6 +25,7 @@
 #include "libpspp/str.h"
 
 struct fmt_settings;
+struct msg_location;
 
 /* How a format is going to be used. */
 enum fmt_use
@@ -96,6 +97,10 @@ bool fmt_check_output (const struct fmt_spec *);
 bool fmt_check_type_compat (const struct fmt_spec *, enum val_type);
 bool fmt_check_width_compat (const struct fmt_spec *, int var_width);
 
+char *fmt_check__ (const struct fmt_spec *, enum fmt_use);
+char *fmt_check_type_compat__ (const struct fmt_spec *, enum val_type);
+char *fmt_check_width_compat__ (const struct fmt_spec *, int var_width);
+
 /* Working with formats. */
 int fmt_var_width (const struct fmt_spec *);
 char *fmt_to_string (const struct fmt_spec *, char s[FMT_STRING_LEN_MAX + 1]);
index 431a10ca9f1d7115da186dcebc2aae6d622cf6b9..2ba42b7e4af16cb8c38b5a1b7bd98d8273f93178 100644 (file)
@@ -796,10 +796,10 @@ absorb_miss string function STRING (x, no_format f)
   return dst;
 }
 
-absorb_miss string function STRUNC (string s, n)
+absorb_miss string function STRUNC (string s, integer n)
 {
-  if (n < 1 || n == SYSMIS)
-    return empty_string;
+  if (n < 1)
+    return n == INT_MIN ? s : empty_string;
 
   if (n < s.length)
     s.length = n;
index 24aaecf7f12c98fe0c632073d38c58d163b76137..1e3844a6cf1a1d0541407a634ee1d44f2714cb05 100644 (file)
@@ -1268,16 +1268,15 @@ put_invocation (struct string *s,
 
 static void
 no_match (struct expression *e, const char *func_name, struct expr_node *node,
-          const struct operation *first, const struct operation *last)
+          const struct operation *ops, size_t n)
 {
   struct string s;
-  const struct operation *f;
 
   ds_init_empty (&s);
 
-  if (last - first == 1)
+  if (n == 1)
     {
-      ds_put_format (&s, _("Type mismatch invoking %s as "), first->prototype);
+      ds_put_format (&s, _("Type mismatch invoking %s as "), ops->prototype);
       put_invocation (&s, func_name, node);
     }
   else
@@ -1286,13 +1285,33 @@ no_match (struct expression *e, const char *func_name, struct expr_node *node,
       put_invocation (&s, func_name, node);
       ds_put_cstr (&s, _(" does not match any known function.  Candidates are:"));
 
-      for (f = first; f < last; f++)
-        ds_put_format (&s, "\n%s", f->prototype);
+      for (size_t i = 0; i < n; i++)
+        ds_put_format (&s, "\n%s", ops[i].prototype);
     }
   ds_put_byte (&s, '.');
 
   msg_at (SE, expr_location (e, node), "%s", ds_cstr (&s));
 
+  if (n == 1 && ops->n_args == node->n_args)
+    {
+      for (size_t i = 0; i < ops->n_args; i++)
+        if ((ops->args[i] == OP_ni_format
+             || ops->args[i] == OP_no_format)
+            && expr_node_returns (node->args[i]) == OP_format)
+          {
+            const struct fmt_spec *f = &node->args[i]->format;
+            char *error = fmt_check__ (f, (ops->args[i] == OP_ni_format
+                                           ? FMT_FOR_INPUT : FMT_FOR_OUTPUT));
+            if (!error)
+              error = fmt_check_type_compat__ (f, VAL_NUMERIC);
+            if (error)
+              {
+                msg_at (SN, expr_location (e, node->args[i]), "%s", error);
+                free (error);
+              }
+          }
+    }
+
   ds_destroy (&s);
 }
 
@@ -1366,7 +1385,7 @@ parse_function (struct lexer *lexer, struct expression *e)
   const struct operation *f = match_function (n, first, last);
   if (!f)
     {
-      no_match (e, ds_cstr (&func_name), n, first, last);
+      no_match (e, ds_cstr (&func_name), n, first, last - first);
       goto fail;
     }
   n->type = f - operations;
index 1f38517c55552a3ef1e715a8783ba6b4909bca60..5a1282c827fa14bc780fde0986d4cbd885eebbcb 100644 (file)
@@ -3382,6 +3382,11 @@ NUMBER(string, num_input_format) as number(string, format).
     7 | DEBUG EVALUATE /number("123", a8).
       |                 ^~~~~~~~~~~~~~~~~
 
+evaluate.sps:7.31-7.32: note: DEBUG EVALUATE: Numeric variables are not
+compatible with string format A8.
+    7 | DEBUG EVALUATE /number("123", a8).
+      |                               ^~
+
 number("123", a8) => error
 
 evaluate.sps:8.17-8.37: error: DEBUG EVALUATE: Type mismatch invoking
@@ -3389,6 +3394,11 @@ NUMBER(string, num_input_format) as number(string, format).
     8 | DEBUG EVALUATE /number("123", cca1.2).
       |                 ^~~~~~~~~~~~~~~~~~~~~
 
+evaluate.sps:8.31-8.36: note: DEBUG EVALUATE: Format CCA1.2 may not be used for
+input.
+    8 | DEBUG EVALUATE /number("123", cca1.2).
+      |                               ^~~~~~
+
 number("123", cca1.2) => error
 ])
 done
@@ -3783,6 +3793,35 @@ for opt in OPT NOOPT; do
     AS_BOX([$opt])
     sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
     AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
+string(123.56, f5.1) => "123.6"
+
+string($sysmis, f5.1) => "   . "
+
+evaluate.sps:5.17-5.33: error: DEBUG EVALUATE: Type mismatch invoking
+STRING(number, num_output_format) as string(string, format).
+    5 | DEBUG EVALUATE /string("abc", A5).
+      |                 ^~~~~~~~~~~~~~~~~
+
+evaluate.sps:5.31-5.32: note: DEBUG EVALUATE: Numeric variables are not
+compatible with string format A5.
+    5 | DEBUG EVALUATE /string("abc", A5).
+      |                               ^~
+
+string("abc", A5) => error
+
+evaluate.sps:6.17-6.31: error: DEBUG EVALUATE: Type mismatch invoking
+STRING(number, num_output_format) as string(number, format).
+    6 | DEBUG EVALUATE /string(123, e1).
+      |                 ^~~~~~~~~~~~~~~
+
+evaluate.sps:6.29-6.30: note: DEBUG EVALUATE: Output format E1.0 specifies
+width 1, but E requires a width between 6 and 40.
+    6 | DEBUG EVALUATE /string(123, e1).
+      |                             ^~
+
+string(123, e1) => error
+
+string(123, e6.0) => "1E+002"
 ])
 done
 AT_CLEANUP
@@ -3800,8 +3839,11 @@ DEBUG EVALUATE /strunc('a c   ', 3).
 DEBUG EVALUATE /strunc('a c   ', 2).
 DEBUG EVALUATE /strunc('a c   ', 1).
 DEBUG EVALUATE /strunc('a c   ', 0).
+
+DEBUG EVALUATE /strunc('a c   ', 0.75).
 DEBUG EVALUATE /strunc('a c   ', -1).
 DEBUG EVALUATE /strunc('a c   ', $sysmis).
+
 DEBUG EVALUATE /strunc('  abc  ', 9).
 DEBUG EVALUATE /strunc('  abc  ', 8).
 DEBUG EVALUATE /strunc('  abc  ', 7).
@@ -3811,6 +3853,8 @@ DEBUG EVALUATE /strunc('  abc  ', 4).
 DEBUG EVALUATE /strunc('  abc  ', 3).
 DEBUG EVALUATE /strunc('  abc  ', 2).
 DEBUG EVALUATE /strunc('  abc  ', 1).
+
+DEBUG EVALUATE /strunc('  abc  ', 1.5).
 DEBUG EVALUATE /strunc('  abc  ', -1).
 DEBUG EVALUATE /strunc('  abc  ', $sysmis).
 ])
@@ -3819,13 +3863,70 @@ for opt in OPT NOOPT; do
     AS_BOX([$opt])
     sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
     AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
+strunc('a c   ', 9) => "a c"
+
+strunc('a c   ', 7) => "a c"
+
+strunc('a c   ', 6) => "a c"
+
+strunc('a c   ', 5) => "a c"
+
+strunc('a c   ', 4) => "a c"
+
+strunc('a c   ', 3) => "a c"
+
+strunc('a c   ', 2) => "a"
+
+strunc('a c   ', 1) => "a"
+
+strunc('a c   ', 0) => ""
+
+evaluate.sps:13.34-13.37: error: DEBUG EVALUATE: Treating unexpected non-
+integer value 0.75 as missing.
+   13 | DEBUG EVALUATE /strunc('a c   ', 0.75).
+      |                                  ^~~~
+
+strunc('a c   ', 0.75) => "a c   "
+
+strunc('a c   ', -1) => ""
+
+strunc('a c   ', $sysmis) => "a c   "
+
+strunc('  abc  ', 9) => "  abc"
+
+strunc('  abc  ', 8) => "  abc"
+
+strunc('  abc  ', 7) => "  abc"
+
+strunc('  abc  ', 6) => "  abc"
+
+strunc('  abc  ', 5) => "  abc"
+
+strunc('  abc  ', 4) => "  ab"
+
+strunc('  abc  ', 3) => "  a"
+
+strunc('  abc  ', 2) => ""
+
+strunc('  abc  ', 1) => ""
+
+evaluate.sps:27.35-27.37: error: DEBUG EVALUATE: Treating unexpected non-
+integer value 1.5 as missing.
+   27 | DEBUG EVALUATE /strunc('  abc  ', 1.5).
+      |                                   ^~~
+
+strunc('  abc  ', 1.5) => "  abc  "
+
+strunc('  abc  ', -1) => ""
+
+strunc('  abc  ', $sysmis) => "  abc  "
 ])
 done
 AT_CLEANUP
 
 AT_SETUP([expressions - SUBSTR])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /substr('abcdefgh', -5).
 DEBUG EVALUATE /substr('abcdefgh', 0).
@@ -3883,7 +3984,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - UPCASE])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /upcase('abcdefghijklmnopqrstuvwxyz!@%&*089').
 DEBUG EVALUATE /upcase('').
@@ -3900,7 +4001,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - TIME.DAYS])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /time.days(1).
 DEBUG EVALUATE /time.days(-1).
@@ -3919,7 +4020,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - TIME.HMS])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /time.hms(4,50,38).
 DEBUG EVALUATE /time.hms(12,31,35).
@@ -3960,7 +4061,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - CTIME.*])
 AT_KEYWORDS([expression expressions evaluate ctime])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /ctime.days(106272).
 DEBUG EVALUATE /ctime.hours(106272).
@@ -4012,7 +4113,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - DATE.DMY])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /date.dmy('a',1,2).
 DEBUG EVALUATE /date.dmy(1,'a',2).
@@ -4029,7 +4130,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - YRMOD])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 dnl FIXME: check out-of-range and nearly out-of-range values
 DEBUG EVALUATE /yrmoda(1582,10,15).
@@ -4068,7 +4169,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - DATE.MDY])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 ])
 
@@ -4129,7 +4230,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - DATE.MOYR])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /ctime.days(date.moyr(1,2000)).
 DEBUG EVALUATE /ctime.days(date.moyr(2,2000)).
@@ -4156,7 +4257,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - DATE.QYR])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /ctime.days(date.qyr(1,2000)).
 DEBUG EVALUATE /ctime.days(date.qyr(2,2000)).
@@ -4180,7 +4281,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - DATE.WKYR])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /ctime.days(date.wkyr(1,2000)).
 DEBUG EVALUATE /ctime.days(date.wkyr(15,1999)).
@@ -4204,7 +4305,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - DATE.YRDAY])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /ctime.days(date.yrday(2000,1)).
 DEBUG EVALUATE /ctime.days(date.yrday(2000,100)).
@@ -4229,7 +4330,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - XDATE.DATE])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /xdate.date(date.mdy(6,10,1648) + time.hms(0,0,0)) / 86400.
 DEBUG EVALUATE /xdate.date(date.mdy(6,30,1680) + time.hms(4,50,38)) / 86400.
@@ -4265,7 +4366,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - XDATE.HOUR])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /xdate.hour(date.mdy(6,10,1648) + time.hms(0,0,0)).
 DEBUG EVALUATE /xdate.hour(date.mdy(6,30,1680) + time.hms(4,50,38)).
@@ -4303,7 +4404,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - XDATE.JDAY])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /xdate.jday(date.mdy(6,10,1648) + time.hms(0,0,0)).
 DEBUG EVALUATE /xdate.jday(date.mdy(6,30,1680) + time.hms(4,50,38)).
@@ -4340,7 +4441,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - XDATE.MDAY])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /xdate.mday(date.mdy(6,10,1648) + time.hms(0,0,0)).
 DEBUG EVALUATE /xdate.mday(date.mdy(6,30,1680) + time.hms(4,50,38)).
@@ -4374,7 +4475,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - XDATE.MINUTE])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /xdate.minute(date.mdy(6,10,1648) + time.hms(0,0,0)).
 DEBUG EVALUATE /xdate.minute(date.mdy(6,30,1680) + time.hms(4,50,38)).
@@ -4408,7 +4509,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - XDATE.MONTH])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /xdate.month(date.mdy(6,10,1648) + time.hms(0,0,0)).
 DEBUG EVALUATE /xdate.month(date.mdy(6,30,1680) + time.hms(4,50,38)).
@@ -4442,7 +4543,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - XDATE.QUARTER])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /xdate.quarter(date.mdy(6,10,1648) + time.hms(0,0,0)).
 DEBUG EVALUATE /xdate.quarter(date.mdy(6,30,1680) + time.hms(4,50,38)).
@@ -4476,7 +4577,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - XDATE.SECOND])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /xdate.second(date.mdy(6,10,1648) + time.hms(0,0,0)).
 DEBUG EVALUATE /xdate.second(date.mdy(6,30,1680) + time.hms(4,50,38)).
@@ -4510,7 +4611,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - XDATE.TDAY])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /xdate.tday(date.mdy(6,10,1648) + time.hms(0,0,0)).
 DEBUG EVALUATE /xdate.tday(date.mdy(6,30,1680) + time.hms(4,50,38)).
@@ -4544,7 +4645,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - XDATE.TIME])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /xdate.time(date.mdy(6,10,1648) + time.hms(0,0,0)).
 DEBUG EVALUATE /xdate.time(date.mdy(6,30,1680) + time.hms(4,50,38)).
@@ -4578,7 +4679,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - XDATE.WEEK])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /xdate.week(date.mdy(6,10,1648) + time.hms(0,0,0)).
 DEBUG EVALUATE /xdate.week(date.mdy(6,30,1680) + time.hms(4,50,38)).
@@ -4612,7 +4713,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - XDATE.WKDAY])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /xdate.wkday(date.mdy(6,10,1648)).
 DEBUG EVALUATE /xdate.wkday(date.mdy(6,30,1680)).
@@ -4646,7 +4747,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - XDATE.YEAR])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /xdate.year(date.mdy(6,10,1648) + time.hms(0,0,0)).
 DEBUG EVALUATE /xdate.year(date.mdy(6,30,1680) + time.hms(4,50,38)).
@@ -4680,7 +4781,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - DATEDIFF])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /datediff(date.mdy(6,10,1648), date.mdy(6,30,1680), 'years').
 DEBUG EVALUATE /datediff(date.mdy(6,30,1680), date.mdy(7,24,1716), 'years').
@@ -4896,7 +4997,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - DATESUM with non-leap year])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 1, 'months') - date.mdy(1,1,1900)).
 DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 2, 'months') - date.mdy(1,1,1900)).
@@ -4936,7 +5037,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - DATESUM with leap year])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 ])
 
@@ -4976,7 +5077,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - DATESUM])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /ctime.days(datesum(date.mdy(6,10,1648), 1, 'weeks') - date.mdy(6,10,1648)).
 DEBUG EVALUATE /ctime.days(datesum(date.mdy(6,30,1680), 2.5, 'weeks') - date.mdy(6,30,1680)).
@@ -5005,7 +5106,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - DATESUM preserves time of day for units of days and longer])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'days') - (date.mdy(8,2,1819) + time.hms(1,2,3))).
 DEBUG EVALUATE /ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'weeks') - (date.mdy(8,2,1819) + time.hms(1,2,3))).
@@ -5024,7 +5125,7 @@ AT_CLEANUP
 dnl These test values are from Applied Statistics, Algorithm AS 310.
 AT_SETUP([expressions - NCDF.BETA])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /1000 * ncdf.beta(.868,10,20,150).
 DEBUG EVALUATE /1000 * ncdf.beta(.9,10,10,120).
@@ -5053,7 +5154,7 @@ dnl
 dnl Tests correctness of generic optimizations in optimize_tree().
 AT_SETUP([expressions - generic tree optimizations])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE (x=10) /x + 0.
 DEBUG EVALUATE (x=-3) /x - 0.
@@ -5079,7 +5180,7 @@ AT_CLEANUP
 
 AT_SETUP([expressions - negative checks])
 AT_KEYWORDS([expression expressions evaluate])
-AT_DATA([evaluate-base.sps], [
+AT_DATA([evaluate-base.sps], [dnl
 DEBUG EVALUATE SET opt.
 DEBUG EVALUATE /$nonexistent.
 DEBUG EVALUATE /RANGE(1, 2).