more tests
[pspp] / src / language / expressions / parse.c
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;