return true;
}
- /* The first 'n_call' tokens starting at 'middle' will be replaced by a
+ /* Now expand the macro.
+
+ We temporarily add the macro call's tokens to the source in case the macro
+ expansion calls msg() to report an error and error processing tries to get
+ the location of the error with, e.g. lex_get_first_line_number(), which
+ would re-enter this code. This is a kluge; it might be cleaner to pass
+ the line number into macro_expander_get_expansion(). */
+ src->middle += n_call;
+ struct macro_tokens expansion = { .n = 0 };
+ macro_expander_get_expansion (me, src->reader->syntax, &expansion);
+ macro_expander_destroy (me);
+ src->middle -= n_call;
+
+ /* Convert the macro expansion into syntax for possible error messages later. */
+ size_t *ofs = xnmalloc (expansion.n, sizeof *ofs);
+ size_t *len = xnmalloc (expansion.n, sizeof *len);
+ struct string s = DS_EMPTY_INITIALIZER;
+ macro_tokens_to_representation (&expansion, &s, ofs, len);
+
+ if (settings_get_mprint ())
+ output_item_submit (text_item_create (TEXT_ITEM_LOG, ds_cstr (&s),
+ _("Macro Expansion")));
+
+ /* The first 'n_call' tokens starting at 'middle' will be replaced by the
macro expansion. There might be more tokens after that, up to 'front'.
Figure out the boundary of the macro call in the syntax, to go into the
& (src->capacity - 1)];
src->front = src->middle;
- /* Now expand the macro. */
- struct macro_tokens expansion = { .n = 0 };
- macro_expander_get_expansion (me, src->reader->syntax, &expansion);
- macro_expander_destroy (me);
-
- /* Convert the macro expansion into syntax for possible error messages later. */
- size_t *ofs = xnmalloc (expansion.n, sizeof *ofs);
- size_t *len = xnmalloc (expansion.n, sizeof *len);
- struct string s = DS_EMPTY_INITIALIZER;
- macro_tokens_to_representation (&expansion, &s, ofs, len);
-
- if (settings_get_mprint ())
- output_item_submit (text_item_create (TEXT_ITEM_LOG, ds_cstr (&s),
- _("Macro Expansion")));
-
/* Append the macro expansion tokens to the lookahead. */
char *macro_rep = ds_steal_cstr (&s);
size_t *ref_cnt = xmalloc (sizeof *ref_cnt);
!SUBSTR(banana, 10, 3).
!ENDDEFINE.],
[!s.],
- [error
+ [define.sps:1-10: At `"ba' in the expansion of `!s',dnl "
+
+define.sps:12: error: DEBUG EXPAND: Unterminated string constant.
nana.
nan.
.
!macro.
])
AT_CHECK([pspp -O format=csv define.sps], [1], [dnl
-maximum nesting level exceeded
+"define.sps:1-3: In the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:1-3: inside the expansion of `!macro',
+define.sps:4: error: DEFINE: Maximum nesting level 50 exceeded. (Use SET MNEST to change the limit.)"
+
define.sps:4.1-4.6: error: Syntax error at `!macro' (in expansion of `!macro'): expecting command name.
])
AT_CLEANUP
!for x=1 y=5.
!for2 x=1 y=5.
])
-AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
-cannot use argument name or macro keyword !x as !DO variable
-cannot use argument name or macro keyword !noexpand as !DO variable
+AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
+define.sps:1-3: At `!x' in the expansion of `!for',
+define.sps:10: error: DEBUG EXPAND: Cannot use argument name or macro keyword
+as !DO variable.
+
!DO 1 = 1 !TO 5 !var !DOEND.
+define.sps:5-7: At `!noexpand' in the expansion of `!for2',
+define.sps:11: error: DEBUG EXPAND: Cannot use argument name or macro keyword
+as !DO variable.
+
!DO !noexpand = 1 !TO 5 !var !DOEND.
])
AT_CLEANUP
!title "non-integer".
!for 1.5 3.5.
])
-AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
-exceeded maximum number of iterations 3
-exceeded maximum number of iterations 3
-exceeded maximum number of iterations 3
+AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
"increasing".
+define.sps:3-5: In the expansion of `!for',
+define.sps:14: error: DEBUG EXPAND: Numerical !DO loop exceeded maximum number
+of iterations 3. (Use SET MITERATE to change the limit.)
+
1 2 3 4.
+define.sps:7-9: In the expansion of `!forby',
+define.sps:15: error: DEBUG EXPAND: Numerical !DO loop exceeded maximum number
+of iterations 3. (Use SET MITERATE to change the limit.)
+
1 2 3 4.
1 3 5.
.
+define.sps:7-9: In the expansion of `!forby',
+define.sps:23: error: DEBUG EXPAND: Numerical !DO loop exceeded maximum number
+of iterations 3. (Use SET MITERATE to change the limit.)
+
5 4 3 2.
5 3 1.
!for 'foo bar baz quux'.
!for.
])
-AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
-exceeded maximum number of iterations 2
-exceeded maximum number of iterations 2
+AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
+define.sps:1-3: In the expansion of `!for',
+define.sps:7: error: DEBUG EXPAND: !DO loop over list exceeded maximum number
+of iterations 2. (Use SET MITERATE to change the limit.)
+
( (a) (b) ).
+define.sps:1-3: In the expansion of `!for',
+define.sps:8: error: DEBUG EXPAND: !DO loop over list exceeded maximum number
+of iterations 2. (Use SET MITERATE to change the limit.)
+
( (foo) (bar) ).
( ).
!macro x=1.
!macro2.
])
-AT_CHECK([pspp --testing-mode define.sps -O format=csv], [0], [dnl
-cannot use argument name or macro keyword !x as !LET variable
-cannot use argument name or macro keyword !do as !LET variable
-expected macro variable name following !DO
+AT_CHECK([pspp --testing-mode define.sps -O format=csv], [1], [dnl
+"define.sps:1-3: At `!x' in the expansion of `!macro',
+define.sps:10: error: DEBUG EXPAND: Cannot use argument name or macro keyword ""!x"" as !LET variable."
+
!LET 1 = 1
+"define.sps:5-7: At `!do' in the expansion of `!macro2',
+define.sps:11: error: DEBUG EXPAND: Cannot use argument name or macro keyword ""!do"" as !LET variable."
+
+"define.sps:5-7: At `=' in the expansion of `!macro2',
+define.sps:11: error: DEBUG EXPAND: Expected macro variable name following !DO."
+
!LET !do = x
])
AT_CLEANUP