macro: Fix crash for !QUOTE of a quoted string.
authorBen Pfaff <blp@cs.stanford.edu>
Wed, 1 Sep 2021 17:02:26 +0000 (10:02 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Wed, 1 Sep 2021 17:02:26 +0000 (10:02 -0700)
This revealed that the tests didn't include anything for !QUOTE and
!UNQUOTE, even though the manual had lots of examples.  I added a test for
these and for !NULL, which had also been forgotten.

Thanks to Frans Houweling for reporting the bug.

doc/flow-control.texi
src/language/lexer/macro.c
tests/language/control/define.at

index d3235612b9fddb04ec0e42a1c697ae3e4afd0e17..23539bcfb67e24b420f4b6669a95172a05178051 100644 (file)
@@ -578,6 +578,8 @@ Expands to a number token representing the number of characters in
 @deffn {Macro Function} !NULL
 Expands to an empty character sequence.
 
+@c Keep these examples in sync with the test for !NULL in
+@c tests/language/control/define.at:
 @example
 !NULL                        @expansion{} @r{empty}
 !QUOTE(!NULL)                @expansion{} ''
@@ -596,6 +598,8 @@ to the string's contents, with the quotes removed and any doubled
 quote marks reduced to singletons.  If the argument was not a quoted
 string, @code{!UNQUOTE} expands to the argument unchanged.
 
+@c Keep these examples in sync with the test for !QUOTE and !UNQUOTE in
+@c tests/language/control/define.at:
 @example
 !QUOTE(123.0)                @expansion{} '123.0'
 !QUOTE( 123 )                @expansion{} '123'
index 742b8771ac8d353ed113cf97367ce59ff59da10c..814740bfac4e29bea9dc1365864c725034acbad0 100644 (file)
@@ -1038,7 +1038,8 @@ unquote_string (const char *s, enum segmenter_mode segmenter_mode,
       return false;
     }
 
-  ds_put_substring (content, token1.string);
+  if (content)
+    ds_put_substring (content, token1.string);
   token_uninit (&token1);
   return true;
 }
index 9a7594b81bda47ca3d243dfe621f3449def4360d..204ed2efd37f1b183f263923b530777a9dfe1436 100644 (file)
@@ -880,6 +880,72 @@ AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
 ])
 AT_CLEANUP
 
+dnl Keep this test in sync with the examples for !NULL in the manual.
+AT_SETUP([macro expansion - !NULL])
+AT_KEYWORDS([NULL])
+AT_DATA([define.sps], [dnl
+DEFINE !n()
+!NULL.
+!QUOTE(!NULL).
+!ENDDEFINE.
+DEBUG EXPAND.
+!n.
+])
+AT_CAPTURE_FILE([define.sps])
+AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
+.
+''.
+])
+AT_CLEANUP
+
+dnl Keep this test in sync with the examples for !QUOTE and !UNQUOTE in the manual.
+AT_SETUP([macro expansion - !QUOTE and !UNQUOTE])
+AT_KEYWORDS([QUOTE UNQUOTE])
+AT_DATA([define.sps], [dnl
+DEFINE !q(!POS !CMDEND)
+!QUOTE(123.0).
+!QUOTE( 123 ).
+!QUOTE('a b c').
+!QUOTE("a b c").
+!QUOTE(!1).
+
+!UNQUOTE(123.0).
+!UNQUOTE( 123 ).
+!UNQUOTE('a b c').
+!UNQUOTE("a b c").
+!UNQUOTE(!1).
+
+!QUOTE(!UNQUOTE(123.0)).
+!QUOTE(!UNQUOTE( 123 )).
+!QUOTE(!UNQUOTE('a b c')).
+!QUOTE(!UNQUOTE("a b c")).
+!QUOTE(!UNQUOTE(!1)).
+!ENDDEFINE.
+DEBUG EXPAND.
+!q a 'b' c.
+])
+AT_CAPTURE_FILE([define.sps])
+AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
+'123.0'.
+'123'.
+'a b c'.
+"a b c".
+'a ''b'' c'.
+
+123.0.
+123.
+a b c.
+a b c.
+a 'b' c.
+
+'123.0'.
+'123'.
+'a b c'.
+'a b c'.
+'a ''b'' c'.
+])
+AT_CLEANUP
+
 dnl Keep this test in sync with the examples for !SUBSTR in the manual.
 AT_SETUP([macro expansion - !SUBSTR])
 AT_KEYWORDS([SUBSTR])