From d9f3677d790ba79e58efef7aceda64cfaae451f3 Mon Sep 17 00:00:00 2001
From: Ben Pfaff <blp@cs.stanford.edu>
Date: Mon, 19 Jul 2021 22:19:41 -0700
Subject: [PATCH] macro: Properly parse !ENCLOSE keyword arguments.

The opening delimiter was being included in the argument.

Thanks to Frans Houweling for reporting this bug.
---
 src/language/lexer/macro.c       |   4 +-
 tests/language/control/define.at | 170 ++++++++++++++++++++++++++++++-
 2 files changed, 170 insertions(+), 4 deletions(-)

diff --git a/src/language/lexer/macro.c b/src/language/lexer/macro.c
index 85706ce3a4..22e92ca05e 100644
--- a/src/language/lexer/macro.c
+++ b/src/language/lexer/macro.c
@@ -510,7 +510,7 @@ macro_set_add (struct macro_set *set, struct macro *m)
   hmap_insert (&set->macros, &m->hmap_node, hash_macro_name (m->name));
 }
 
-/* Macro call parsing.. */
+/* Macro call parsing. */
 
 enum mc_state
   {
@@ -752,7 +752,7 @@ mc_equals (struct macro_call *mc, const struct macro_token *mt,
 
   if (token->type == T_EQUALS)
     {
-      mc->state = MC_ARG;
+      mc->state = mc->param->arg_type == ARG_ENCLOSE ? MC_ENCLOSE : MC_ARG;
       return 0;
     }
 
diff --git a/tests/language/control/define.at b/tests/language/control/define.at
index 255a0dc285..26df856673 100644
--- a/tests/language/control/define.at
+++ b/tests/language/control/define.at
@@ -340,7 +340,7 @@ note: unexpanded token "="
 ])
 AT_CLEANUP
 
-AT_SETUP([macro expansion - !CHAREND('/') keyword arguments])
+AT_SETUP([macro expansion - !CHAREND keyword arguments])
 AT_KEYWORDS([CHAREND])
 AT_DATA([define.sps], [dnl
 DEFINE !k(arg1 = !CHAREND('/')
@@ -365,7 +365,7 @@ k(, )
 ])
 AT_CLEANUP
 
-AT_SETUP([macro expansion - !CHAREND('/') keyword arguments - negative])
+AT_SETUP([macro expansion - !CHAREND keyword arguments - negative])
 AT_KEYWORDS([CHAREND])
 AT_DATA([define.sps], [dnl
 DEFINE !k(arg1 = !CHAREND('/')
@@ -428,6 +428,172 @@ note: unexpanded token "y"
 ])
 AT_CLEANUP
 
+AT_SETUP([macro expansion - !ENCLOSE keyword arguments])
+AT_KEYWORDS([ENCLOSE])
+AT_DATA([define.sps], [dnl
+DEFINE !k(arg1 = !ENCLOSE('(',')')
+         /arg2 = !ENCLOSE('{','}'))
+k(!arg1, !arg2)
+!ENDDEFINE.
+DEBUG EXPAND.
+!k arg1=(x) arg2={y}.
+!k arg1=(x).
+!k arg2={y}.
+!k.
+])
+AT_CAPTURE_FILE([define.sps])
+AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
+k(x, y)
+
+k(x, )
+
+k(, y)
+
+k(, )
+])
+AT_CLEANUP
+
+AT_SETUP([macro expansion - !ENCLOSE keyword arguments - negative])
+AT_KEYWORDS([ENCLOSE])
+AT_DATA([define.sps], [dnl
+DEFINE !k(arg1 = !ENCLOSE('(',')')
+         /arg2 = !ENCLOSE('{','}'))
+k(!arg1, !arg2)
+!ENDDEFINE.
+DEBUG EXPAND.
+!k arg1.
+!k arg1=.
+!k arg1=x.
+!k arg1=(x.
+!k arg1=(x) arg2.
+!k arg1=(x) arg2=.
+!k arg1=(x) arg2=y.
+!k arg1=(x) arg2=(y.
+])
+AT_CAPTURE_FILE([define.sps])
+AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
+define.sps:6.8: error: DEBUG EXPAND: Found `.' while expecting `=' reading
+argument !arg1 to macro !k.
+
+note: unexpanded token "!k"
+
+note: unexpanded token "arg1"
+
+define.sps:7.9: error: DEBUG EXPAND: Found `.' while expecting `@{:@' reading
+argument !arg1 to macro !k.
+
+note: unexpanded token "!k"
+
+note: unexpanded token "arg1"
+
+note: unexpanded token "="
+
+define.sps:8.9: error: DEBUG EXPAND: Found `x' while expecting `@{:@' reading
+argument !arg1 to macro !k.
+
+note: unexpanded token "!k"
+
+note: unexpanded token "arg1"
+
+note: unexpanded token "="
+
+note: unexpanded token "x"
+
+define.sps:9.11: error: DEBUG EXPAND: Unexpected end of command reading
+argument !arg1 to macro !k.
+
+note: unexpanded token "!k"
+
+note: unexpanded token "arg1"
+
+note: unexpanded token "="
+
+note: unexpanded token "@{:@"
+
+note: unexpanded token "x"
+
+define.sps:10.17: error: DEBUG EXPAND: Found `.' while expecting `=' reading
+argument !arg2 to macro !k.
+
+note: unexpanded token "!k"
+
+note: unexpanded token "arg1"
+
+note: unexpanded token "="
+
+note: unexpanded token "@{:@"
+
+note: unexpanded token "x"
+
+note: unexpanded token "@:}@"
+
+note: unexpanded token "arg2"
+
+define.sps:11.18: error: DEBUG EXPAND: Found `.' while expecting `{' reading
+argument !arg2 to macro !k.
+
+note: unexpanded token "!k"
+
+note: unexpanded token "arg1"
+
+note: unexpanded token "="
+
+note: unexpanded token "@{:@"
+
+note: unexpanded token "x"
+
+note: unexpanded token "@:}@"
+
+note: unexpanded token "arg2"
+
+note: unexpanded token "="
+
+define.sps:12.18: error: DEBUG EXPAND: Found `y' while expecting `{' reading
+argument !arg2 to macro !k.
+
+note: unexpanded token "!k"
+
+note: unexpanded token "arg1"
+
+note: unexpanded token "="
+
+note: unexpanded token "@{:@"
+
+note: unexpanded token "x"
+
+note: unexpanded token "@:}@"
+
+note: unexpanded token "arg2"
+
+note: unexpanded token "="
+
+note: unexpanded token "y"
+
+define.sps:13.18: error: DEBUG EXPAND: Found `@{:@' while expecting `{' reading
+argument !arg2 to macro !k.
+
+note: unexpanded token "!k"
+
+note: unexpanded token "arg1"
+
+note: unexpanded token "="
+
+note: unexpanded token "@{:@"
+
+note: unexpanded token "x"
+
+note: unexpanded token "@:}@"
+
+note: unexpanded token "arg2"
+
+note: unexpanded token "="
+
+note: unexpanded token "@{:@"
+
+note: unexpanded token "y"
+])
+AT_CLEANUP
+
 dnl Keep this test in sync with the examples for !BLANKS in the manual.
 AT_SETUP([macro expansion - !BLANKS])
 AT_KEYWORDS([BLANKS])
-- 
2.30.2