1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2021 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "language/lexer/macro.h"
25 #include "data/settings.h"
26 #include "language/lexer/lexer.h"
27 #include "language/lexer/segment.h"
28 #include "language/lexer/scan.h"
29 #include "libpspp/assertion.h"
30 #include "libpspp/cast.h"
31 #include "libpspp/i18n.h"
32 #include "libpspp/message.h"
33 #include "libpspp/str.h"
34 #include "libpspp/string-array.h"
35 #include "libpspp/stringi-map.h"
36 #include "libpspp/stringi-set.h"
38 #include "gl/c-ctype.h"
39 #include "gl/ftoastr.h"
42 #define _(msgid) gettext (msgid)
44 /* An entry in the stack of macros and macro directives being expanded. The
45 stack is maintained as a linked list. Entries are not dynamically allocated
46 but on the program stack.
48 The outermost entry, where 'next' is NULL, represents the source location of
49 the call to the macro. */
50 struct macro_expansion_stack
52 const struct macro_expansion_stack *next; /* Next outer stack entry. */
53 const char *name; /* A macro name or !IF, !DO, etc. */
54 const struct msg_location *location; /* Source location if available. */
57 /* Reports an error during macro expansion. STACK is the stack for reporting
58 the location of the error, MT is the optional token at which the error was
59 detected, and FORMAT along with the varargs is the message to report. */
60 static void PRINTF_FORMAT (3, 0)
61 macro_error_valist (const struct macro_expansion_stack *stack,
62 const struct macro_token *mt, const char *format,
65 struct msg_stack **ms = NULL;
66 size_t allocated_ms = 0;
69 const struct macro_expansion_stack *p;
70 for (p = stack; p && p->next; p = p->next)
72 if (n_ms >= allocated_ms)
73 ms = x2nrealloc (ms, &allocated_ms, sizeof *ms);
75 /* TRANSLATORS: These strings are used for explaining the context of an
76 error. The "While expanding" message appears first, followed by zero
77 or more of the "inside expansion" messages. `innermost',
78 `next_inner`, etc., are names of macros, and `foobar' is a piece of
81 foo.sps:12: At `foobar' in the expansion of 'innermost',
82 foo.sps:23: inside the expansion of 'next_inner',
83 foo.sps:34: inside the expansion of 'next_inner2',
84 foo.sps:45: inside the expansion of 'outermost',
85 foo.sps:76: This is the actual error message. */
89 if (mt && mt->syntax.length)
92 str_ellipsize (mt->syntax, syntax, sizeof syntax);
93 description = xasprintf (_("At `%s' in the expansion of `%s',"),
97 description = xasprintf (_("In the expansion of `%s',"), p->name);
100 description = xasprintf (_("inside the expansion of `%s',"), p->name);
102 ms[n_ms] = xmalloc (sizeof *ms[n_ms]);
103 *ms[n_ms] = (struct msg_stack) {
104 .location = msg_location_dup (p->location),
105 .description = description,
110 struct msg *m = xmalloc (sizeof *m);
112 .category = MSG_C_SYNTAX,
113 .severity = MSG_S_ERROR,
116 .location = msg_location_dup (p ? p->location : NULL),
117 .text = xvasprintf (format, args),
122 /* Reports an error during macro expansion. STACK is the stack for reporting
123 the location of the error, MT is the optional token at which the error was
124 detected, and FORMAT along with the varargs is the message to report. */
125 static void PRINTF_FORMAT (3, 4)
126 macro_error (const struct macro_expansion_stack *stack,
127 const struct macro_token *mt, const char *format, ...)
130 va_start (args, format);
131 macro_error_valist (stack, mt, format, args);
136 macro_token_copy (struct macro_token *dst, const struct macro_token *src)
138 token_copy (&dst->token, &src->token);
139 ss_alloc_substring (&dst->syntax, src->syntax);
143 macro_token_uninit (struct macro_token *mt)
145 token_uninit (&mt->token);
146 ss_dealloc (&mt->syntax);
150 macro_token_to_syntax (struct macro_token *mt, struct string *s)
152 ds_put_substring (s, mt->syntax);
155 is_macro_keyword (struct substring s)
157 static struct stringi_set keywords = STRINGI_SET_INITIALIZER (keywords);
158 if (stringi_set_is_empty (&keywords))
160 static const char *kws[] = {
181 for (size_t i = 0; i < sizeof kws / sizeof *kws; i++)
182 stringi_set_insert (&keywords, kws[i]);
185 ss_ltrim (&s, ss_cstr ("!"));
186 return stringi_set_contains_len (&keywords, s.string, s.length);
190 macro_tokens_copy (struct macro_tokens *dst, const struct macro_tokens *src)
192 *dst = (struct macro_tokens) {
193 .mts = xmalloc (src->n * sizeof *dst->mts),
197 for (size_t i = 0; i < src->n; i++)
198 macro_token_copy (&dst->mts[i], &src->mts[i]);
202 macro_tokens_uninit (struct macro_tokens *mts)
204 for (size_t i = 0; i < mts->n; i++)
205 macro_token_uninit (&mts->mts[i]);
210 macro_tokens_add_uninit (struct macro_tokens *mts)
212 if (mts->n >= mts->allocated)
213 mts->mts = x2nrealloc (mts->mts, &mts->allocated, sizeof *mts->mts);
214 return &mts->mts[mts->n++];
218 macro_tokens_add (struct macro_tokens *mts, const struct macro_token *mt)
220 macro_token_copy (macro_tokens_add_uninit (mts), mt);
223 /* Tokenizes SRC according to MODE and appends the tokens to MTS. Uses STACK,
224 if nonull, for error reporting. */
226 macro_tokens_from_string__ (struct macro_tokens *mts, const struct substring src,
227 enum segmenter_mode mode,
228 const struct macro_expansion_stack *stack)
230 struct segmenter segmenter = segmenter_init (mode, true);
231 struct substring body = src;
233 while (body.length > 0)
235 struct macro_token mt = {
236 .token = { .type = T_STOP },
237 .syntax = { .string = body.string },
239 struct token *token = &mt.token;
241 enum segment_type type;
242 int seg_len = segmenter_push (&segmenter, body.string,
243 body.length, true, &type);
244 assert (seg_len >= 0);
246 struct substring segment = ss_head (body, seg_len);
247 enum tokenize_result result = token_from_segment (type, segment, token);
248 ss_advance (&body, seg_len);
256 mt.syntax.length = body.string - mt.syntax.string;
257 macro_tokens_add (mts, &mt);
261 mt.syntax.length = body.string - mt.syntax.string;
262 macro_error (stack, &mt, "%s", token->string.string);
266 token_uninit (token);
270 /* Tokenizes SRC according to MODE and appends the tokens to MTS. */
272 macro_tokens_from_string (struct macro_tokens *mts, const struct substring src,
273 enum segmenter_mode mode)
275 macro_tokens_from_string__ (mts, src, mode, NULL);
279 macro_tokens_print (const struct macro_tokens *mts, FILE *stream)
281 for (size_t i = 0; i < mts->n; i++)
282 token_print (&mts->mts[i].token, stream);
287 TC_ENDCMD, /* No space before or after (new-line after). */
288 TC_BINOP, /* Space on both sides. */
289 TC_COMMA, /* Space afterward. */
290 TC_ID, /* Don't need spaces except sequentially. */
291 TC_PUNCT, /* Don't need spaces except sequentially. */
295 needs_space (enum token_class prev, enum token_class next)
297 /* Don't need a space before or after the end of a command.
298 (A new-line is needed afterward as a special case.) */
299 if (prev == TC_ENDCMD || next == TC_ENDCMD)
302 /* Binary operators always have a space on both sides. */
303 if (prev == TC_BINOP || next == TC_BINOP)
306 /* A comma always has a space afterward. */
307 if (prev == TC_COMMA)
310 /* Otherwise, PREV is TC_ID or TC_PUNCT, which only need a space if there are
311 two or them in a row. */
315 static enum token_class
316 classify_token (enum token_type type)
372 /* Appends syntax for the tokens in MTS to S. If OFS and LEN are nonnull, sets
373 OFS[i] to the offset within S of the start of token 'i' in MTS and LEN[i] to
374 its length. OFS[i] + LEN[i] is not necessarily OFS[i + 1] because some
375 tokens are separated by white space. */
377 macro_tokens_to_syntax (struct macro_tokens *mts, struct string *s,
378 size_t *ofs, size_t *len)
380 assert ((ofs != NULL) == (len != NULL));
385 for (size_t i = 0; i < mts->n; i++)
389 enum token_type prev = mts->mts[i - 1].token.type;
390 enum token_type next = mts->mts[i].token.type;
392 if (prev == T_ENDCMD)
393 ds_put_byte (s, '\n');
396 enum token_class pc = classify_token (prev);
397 enum token_class nc = classify_token (next);
398 if (needs_space (pc, nc))
399 ds_put_byte (s, ' ');
404 ofs[i] = s->ss.length;
405 macro_token_to_syntax (&mts->mts[i], s);
407 len[i] = s->ss.length - ofs[i];
412 macro_destroy (struct macro *m)
418 msg_location_destroy (m->location);
419 for (size_t i = 0; i < m->n_params; i++)
421 struct macro_param *p = &m->params[i];
424 macro_tokens_uninit (&p->def);
425 token_uninit (&p->start);
426 token_uninit (&p->end);
429 macro_tokens_uninit (&m->body);
434 macro_set_create (void)
436 struct macro_set *set = xmalloc (sizeof *set);
437 *set = (struct macro_set) {
438 .macros = HMAP_INITIALIZER (set->macros),
444 macro_set_destroy (struct macro_set *set)
449 struct macro *macro, *next;
450 HMAP_FOR_EACH_SAFE (macro, next, struct macro, hmap_node, &set->macros)
452 hmap_delete (&set->macros, ¯o->hmap_node);
453 macro_destroy (macro);
455 hmap_destroy (&set->macros);
460 hash_macro_name (const char *name)
462 return utf8_hash_case_string (name, 0);
465 static struct macro *
466 macro_set_find__ (struct macro_set *set, const char *name)
468 if (macro_set_is_empty (set))
472 HMAP_FOR_EACH_WITH_HASH (macro, struct macro, hmap_node,
473 hash_macro_name (name), &set->macros)
474 if (!utf8_strcasecmp (macro->name, name))
481 macro_set_find (const struct macro_set *set, const char *name)
483 return macro_set_find__ (CONST_CAST (struct macro_set *, set), name);
486 /* Adds M to SET. M replaces any existing macro with the same name. Takes
489 macro_set_add (struct macro_set *set, struct macro *m)
491 struct macro *victim = macro_set_find__ (set, m->name);
494 hmap_delete (&set->macros, &victim->hmap_node);
495 macro_destroy (victim);
498 hmap_insert (&set->macros, &m->hmap_node, hash_macro_name (m->name));
501 /* Macro call parsing. */
505 /* Accumulating tokens in mc->params toward the end of any type of
509 /* Expecting the opening delimiter of an ARG_ENCLOSE argument. */
512 /* Expecting a keyword for a keyword argument. */
515 /* Expecting an equal sign for a keyword argument. */
518 /* Macro fully parsed and ready for expansion. */
522 /* Parsing macro calls. This is a FSM driven by macro_call_create() and
523 macro_call_add() to identify the macro being called and obtain its
524 arguments. 'state' identifies the FSM state. */
527 const struct macro_set *macros;
528 const struct macro *macro;
529 struct macro_tokens **args;
530 const struct macro_expansion_stack *stack;
531 const struct macro_expander *me;
535 const struct macro_param *param; /* Parameter currently being parsed. */
538 static bool macro_expand_arg (const struct token *,
539 const struct macro_expander *,
540 struct macro_tokens *exp);
542 /* Completes macro expansion by initializing arguments that weren't supplied to
545 mc_finished (struct macro_call *mc)
547 mc->state = MC_FINISHED;
548 for (size_t i = 0; i < mc->macro->n_params; i++)
550 mc->args[i] = &mc->macro->params[i].def;
555 mc_next_arg (struct macro_call *mc)
559 assert (!mc->macro->n_params);
560 return mc_finished (mc);
562 else if (mc->param->positional)
565 if (mc->param >= &mc->macro->params[mc->macro->n_params])
566 return mc_finished (mc);
569 mc->state = (!mc->param->positional ? MC_KEYWORD
570 : mc->param->arg_type == ARG_ENCLOSE ? MC_ENCLOSE
577 for (size_t i = 0; i < mc->macro->n_params; i++)
580 mc->state = MC_KEYWORD;
583 return mc_finished (mc);
587 static void PRINTF_FORMAT (3, 4)
588 mc_error (const struct macro_call *mc, const struct msg_location *loc,
589 const char *format, ...)
592 va_start (args, format);
595 const struct macro_expansion_stack stack = { .location = loc };
596 macro_error_valist (&stack, NULL, format, args);
599 macro_error_valist (mc->stack, NULL, format, args);
604 mc_add_arg (struct macro_call *mc, const struct macro_token *mt,
605 const struct msg_location *loc)
607 const struct macro_param *p = mc->param;
608 struct macro_tokens **argp = &mc->args[p - mc->macro->params];
610 const struct token *token = &mt->token;
611 if (token->type == T_ENDCMD || token->type == T_STOP)
618 /* This is OK, it's the expected way to end the argument. */
623 ngettext (_("Reached end of command expecting %zu "
624 "more token in argument %s to macro %s."),
625 _("Reached end of command expecting %zu "
626 "more tokens in argument %s to macro %s."),
627 p->n_tokens - (*argp)->n),
628 p->n_tokens - (*argp)->n, p->name, mc->macro->name);
634 char *end = token_to_string (&p->end);
635 mc_error (mc, loc, _("Reached end of command expecting \"%s\" "
636 "in argument %s to macro %s."),
637 end, p->name, mc->macro->name);
644 /* The end of a command ends the current argument, precludes any further
645 arguments, and is not itself part of the argument. */
646 return mc_finished (mc);
652 *argp = xzalloc (sizeof **argp);
654 bool add_token; /* Should we add 'mt' to the current arg? */
655 bool next_arg; /* Should we advance to the next arg? */
659 next_arg = (*argp)->n + 1 >= p->n_tokens;
665 next_arg = token_equal (token, &p->end);
666 add_token = !next_arg;
680 if (!macro_expand_arg (&mt->token, mc->me, *argp))
681 macro_tokens_add (*argp, mt);
683 return next_arg ? mc_next_arg (mc) : 0;
687 mc_expected (struct macro_call *mc, const struct macro_token *actual,
688 const struct msg_location *loc, const struct token *expected)
690 const struct substring actual_s = (actual->syntax.length ? actual->syntax
691 : ss_cstr (_("<end of input>")));
692 char *expected_s = token_to_string (expected);
694 _("Found `%.*s' while expecting `%s' reading argument %s "
696 (int) actual_s.length, actual_s.string, expected_s,
697 mc->param->name, mc->macro->name);
700 return mc_finished (mc);
704 mc_enclose (struct macro_call *mc, const struct macro_token *mt,
705 const struct msg_location *loc)
707 const struct token *token = &mt->token;
708 const struct macro_param *p = mc->param;
709 if (token_equal (&p->start, token))
713 struct macro_tokens **argp = &mc->args[p - mc->macro->params];
715 *argp = xzalloc (sizeof **argp);
719 else if (p->positional && (token->type == T_ENDCMD || token->type == T_STOP))
720 return mc_finished (mc);
722 return mc_expected (mc, mt, loc, &p->start);
725 static const struct macro_param *
726 macro_find_parameter_by_name (const struct macro *m, struct substring name)
731 ss_ltrim (&name, ss_cstr ("!"));
733 for (size_t i = 0; i < m->n_params; i++)
735 const struct macro_param *p = &m->params[i];
736 struct substring p_name = ss_cstr (p->name + 1);
737 if (!utf8_strncasecmp (p_name.string, p_name.length,
738 name.string, name.length))
745 mc_keyword (struct macro_call *mc, const struct macro_token *mt,
746 const struct msg_location *loc)
748 const struct token *token = &mt->token;
749 if (token->type != T_ID)
750 return mc_finished (mc);
752 const struct macro_param *p = macro_find_parameter_by_name (mc->macro,
756 struct macro_tokens **argp = &mc->args[p - mc->macro->params];
759 _("Argument %s multiply specified in call to macro %s."),
760 p->name, mc->macro->name);
762 *argp = xzalloc (sizeof **argp);
765 mc->state = MC_EQUALS;
769 return mc_finished (mc);
773 mc_equals (struct macro_call *mc, const struct macro_token *mt,
774 const struct msg_location *loc)
776 if (mt->token.type == T_EQUALS)
779 mc->state = mc->param->arg_type == ARG_ENCLOSE ? MC_ENCLOSE : MC_ARG;
783 return mc_expected (mc, mt, loc, &(struct token) { .type = T_EQUALS });
787 macro_call_create__ (const struct macro_set *macros,
788 const struct macro_expansion_stack *stack,
789 const struct macro_expander *me,
790 const struct token *token,
791 struct macro_call **mcp)
793 const struct macro *macro = (token->type == T_ID || token->type == T_MACRO_ID
794 ? macro_set_find (macros, token->string.string)
802 struct macro_call *mc = xmalloc (sizeof *mc);
803 *mc = (struct macro_call) {
807 .state = (!macro->n_params ? MC_FINISHED
808 : !macro->params[0].positional ? MC_KEYWORD
809 : macro->params[0].arg_type == ARG_ENCLOSE ? MC_ENCLOSE
811 .args = macro->n_params ? xcalloc (macro->n_params, sizeof *mc->args) : NULL,
812 .param = macro->params,
818 return mc->state == MC_FINISHED ? 1 : 0;
821 /* If TOKEN is the first token of a call to a macro in MACROS, create a new
822 macro expander, initializes *MCP to it. Returns 0 if more tokens are needed
823 and should be added via macro_call_add() or 1 if the caller should next call
826 If TOKEN is not the first token of a macro call, returns -1 and sets *MCP to
829 macro_call_create (const struct macro_set *macros,
830 const struct token *token,
831 struct macro_call **mcp)
833 return macro_call_create__ (macros, NULL, NULL, token, mcp);
837 macro_call_destroy (struct macro_call *mc)
842 for (size_t i = 0; i < mc->macro->n_params; i++)
844 struct macro_tokens *a = mc->args[i];
845 if (a && a != &mc->macro->params[i].def)
847 macro_tokens_uninit (a);
855 /* Adds TOKEN to the collection of tokens in MC that potentially need to be
858 Returns -1 if the tokens added do not actually invoke a macro. The caller
859 should consume the first token without expanding it. (Later tokens might
860 invoke a macro so it's best to feed the second token into a new expander.)
862 Returns 0 if the macro expander needs more tokens, for macro arguments or to
863 decide whether this is actually a macro invocation. The caller should call
864 macro_call_add() again with the next token.
866 Returns a positive number to indicate that the returned number of tokens
867 invoke a macro. The number returned might be less than the number of tokens
868 added because it can take a few tokens of lookahead to determine whether the
869 macro invocation is finished. The caller should call macro_call_expand() to
870 obtain the expansion. */
872 macro_call_add (struct macro_call *mc, const struct macro_token *mt,
873 const struct msg_location *loc)
878 return mc_add_arg (mc, mt, loc);
881 return mc_enclose (mc, mt, loc);
884 return mc_keyword (mc, mt, loc);
887 return mc_equals (mc, mt, loc);
894 /* Macro expansion. */
896 struct macro_expander
898 /* Always available. */
899 const struct macro_set *macros; /* Macros to expand recursively. */
900 enum segmenter_mode segmenter_mode; /* Mode for tokenization. */
901 int nesting_countdown; /* Remaining nesting levels. */
902 const struct macro_expansion_stack *stack; /* Stack for error reporting. */
903 bool *expand; /* May macro calls be expanded? */
904 struct stringi_map *vars; /* Variables from !do and !let. */
906 /* Only nonnull if inside a !DO loop. */
907 bool *break_; /* Set to true to break out of loop. */
909 /* Only nonnull if expanding a macro (and not, say, a macro argument). */
910 const struct macro *macro;
911 struct macro_tokens **args;
915 macro_expand (const struct macro_token *mts, size_t n_mts,
916 const struct macro_expander *, struct macro_tokens *);
919 expand_macro_function (const struct macro_expander *me,
920 const struct macro_token *input, size_t n_input,
921 struct string *output);
923 /* Parses one function argument from the N_INPUT tokens in INPUT
924 Each argument to a macro function is one of:
926 - A quoted string or other single literal token.
928 - An argument to the macro being expanded, e.g. !1 or a named argument.
932 - A function invocation.
934 Each function invocation yields a character sequence to be turned into a
935 sequence of tokens. The case where that character sequence is a single
936 quoted string is an important special case.
939 parse_function_arg (const struct macro_expander *me,
940 const struct macro_token *input, size_t n_input,
943 assert (n_input > 0);
945 const struct token *token = &input[0].token;
946 if (token->type == T_MACRO_ID && me->macro)
948 const struct macro_param *param = macro_find_parameter_by_name (
949 me->macro, token->string);
952 size_t param_idx = param - me->macro->params;
953 macro_tokens_to_syntax (me->args[param_idx], farg, NULL, NULL);
957 if (ss_equals (token->string, ss_cstr ("!*")))
959 for (size_t i = 0; i < me->macro->n_params; i++)
961 if (!me->macro->params[i].positional)
964 ds_put_byte (farg, ' ');
965 macro_tokens_to_syntax (me->args[i], farg, NULL, NULL);
970 const char *var = stringi_map_find__ (me->vars,
971 token->string.string,
972 token->string.length);
975 ds_put_cstr (farg, var);
979 size_t n_function = expand_macro_function (me, input, n_input, farg);
984 ds_put_substring (farg, input[0].syntax);
989 parse_function_args (const struct macro_expander *me,
990 const struct macro_token *mts, size_t n,
991 const char *function,
992 struct string_array *args)
994 assert (n >= 2 && mts[1].token.type == T_LPAREN);
996 for (size_t i = 2; i < n; )
998 if (mts[i].token.type == T_RPAREN)
1001 struct string s = DS_EMPTY_INITIALIZER;
1002 i += parse_function_arg (me, mts + i, n - i, &s);
1003 string_array_append_nocopy (args, ds_steal_cstr (&s));
1007 else if (mts[i].token.type == T_COMMA)
1009 else if (mts[i].token.type != T_RPAREN)
1011 macro_error (me->stack, &mts[i],
1012 _("`,' or `)' expected in call to macro function %s."),
1018 macro_error (me->stack, NULL, _("Missing `)' in call to macro function %s."),
1024 unquote_string (const char *s, enum segmenter_mode segmenter_mode,
1025 struct string *content)
1027 struct string_lexer slex;
1028 string_lexer_init (&slex, s, strlen (s), segmenter_mode, true);
1030 struct token token1;
1031 if (string_lexer_next (&slex, &token1) != SLR_TOKEN
1032 || token1.type != T_STRING)
1034 token_uninit (&token1);
1038 struct token token2;
1039 if (string_lexer_next (&slex, &token2) != SLR_END)
1041 token_uninit (&token1);
1042 token_uninit (&token2);
1047 ds_put_substring (content, token1.string);
1048 token_uninit (&token1);
1053 unquote_string_in_place (const char *s, enum segmenter_mode segmenter_mode,
1056 ds_init_empty (tmp);
1057 return unquote_string (s, segmenter_mode, tmp) ? ds_cstr (tmp) : s;
1061 parse_integer (const char *s, int *np)
1066 long int n = strtol (s, &tail, 10);
1067 *np = n < INT_MIN ? INT_MIN : n > INT_MAX ? INT_MAX : n;
1068 tail += strspn (tail, CC_SPACES);
1069 return *tail == '\0' && errno != ERANGE && n == *np;
1073 expand_macro_function (const struct macro_expander *me,
1074 const struct macro_token *input, size_t n_input,
1075 struct string *output)
1077 if (!n_input || input[0].token.type != T_MACRO_ID)
1080 struct macro_function
1086 enum macro_function_id
1100 static const struct macro_function mfs[] = {
1101 [MF_BLANKS] = { "!BLANKS", 1, 1 },
1102 [MF_CONCAT] = { "!CONCAT", 1, INT_MAX },
1103 [MF_EVAL] = { "!EVAL", 1, 1 },
1104 [MF_HEAD] = { "!HEAD", 1, 1 },
1105 [MF_INDEX] = { "!INDEX", 2, 2 },
1106 [MF_LENGTH] = { "!LENGTH", 1, 1 },
1107 [MF_QUOTE] = { "!QUOTE", 1, 1 },
1108 [MF_SUBSTR] = { "!SUBSTR", 2, 3 },
1109 [MF_TAIL] = { "!TAIL", 1, 1 },
1110 [MF_UNQUOTE] = { "!UNQUOTE", 1, 1 },
1111 [MF_UPCASE] = { "!UPCASE", 1, 1 },
1114 if (lex_id_match_n (ss_cstr ("!NULL"), input[0].token.string, 4))
1117 if (n_input < 2 || input[1].token.type != T_LPAREN)
1119 /* Only consider macro functions when the name is followed by '('. */
1123 /* Is this a macro function name? */
1124 const struct macro_function *mf;
1125 for (mf = mfs; ; mf++)
1127 if (mf >= mfs + sizeof mfs / sizeof *mfs)
1129 /* Not a macro function. */
1133 if (lex_id_match_n (ss_cstr (mf->name), input[0].token.string, 4))
1137 enum macro_function_id id = mf - mfs;
1139 struct string_array args = STRING_ARRAY_INITIALIZER;
1140 size_t n_consumed = parse_function_args (me, input, n_input, mf->name, &args);
1143 string_array_destroy (&args);
1147 if (args.n < mf->min_args || args.n > mf->max_args)
1149 if (mf->min_args == 1 && mf->max_args == 1)
1150 macro_error (me->stack, NULL,
1151 _("Macro function %s takes one argument (not %zu)."),
1153 else if (mf->min_args == 2 && mf->max_args == 2)
1154 macro_error (me->stack, NULL,
1155 _("Macro function %s takes two arguments (not %zu)."),
1157 else if (mf->min_args == 2 && mf->max_args == 3)
1158 macro_error (me->stack, NULL,
1159 _("Macro function %s takes two or three arguments "
1162 else if (mf->min_args == 1 && mf->max_args == INT_MAX)
1163 macro_error (me->stack, NULL,
1164 _("Macro function %s needs at least one argument."),
1168 string_array_destroy (&args);
1175 ds_put_format (output, "%zu", strlen (args.strings[0]));
1181 if (!parse_integer (args.strings[0], &n))
1183 macro_error (me->stack, NULL,
1184 _("Argument to !BLANKS must be non-negative integer "
1185 "(not \"%s\")."), args.strings[0]);
1186 string_array_destroy (&args);
1190 ds_put_byte_multiple (output, ' ', n);
1195 for (size_t i = 0; i < args.n; i++)
1196 if (!unquote_string (args.strings[i], me->segmenter_mode, output))
1197 ds_put_cstr (output, args.strings[i]);
1203 const char *s = unquote_string_in_place (args.strings[0],
1204 me->segmenter_mode, &tmp);
1206 struct macro_tokens mts = { .n = 0 };
1207 macro_tokens_from_string__ (&mts, ss_cstr (s), me->segmenter_mode,
1210 ds_put_substring (output, mts.mts[0].syntax);
1211 macro_tokens_uninit (&mts);
1218 const char *haystack = args.strings[0];
1219 const char *needle = strstr (haystack, args.strings[1]);
1220 ds_put_format (output, "%zu", needle ? needle - haystack + 1 : 0);
1225 if (unquote_string (args.strings[0], me->segmenter_mode, NULL))
1226 ds_put_cstr (output, args.strings[0]);
1229 ds_extend (output, strlen (args.strings[0]) + 2);
1230 ds_put_byte (output, '\'');
1231 for (const char *p = args.strings[0]; *p; p++)
1234 ds_put_byte (output, '\'');
1235 ds_put_byte (output, *p);
1237 ds_put_byte (output, '\'');
1244 if (!parse_integer (args.strings[1], &start) || start < 1)
1246 macro_error (me->stack, NULL,
1247 _("Second argument of !SUBSTR must be "
1248 "positive integer (not \"%s\")."),
1250 string_array_destroy (&args);
1254 int count = INT_MAX;
1255 if (args.n > 2 && (!parse_integer (args.strings[2], &count) || count < 0))
1257 macro_error (me->stack, NULL,
1258 _("Third argument of !SUBSTR must be "
1259 "non-negative integer (not \"%s\")."),
1261 string_array_destroy (&args);
1265 struct substring s = ss_cstr (args.strings[0]);
1266 ds_put_substring (output, ss_substr (s, start - 1, count));
1273 const char *s = unquote_string_in_place (args.strings[0],
1274 me->segmenter_mode, &tmp);
1276 struct macro_tokens mts = { .n = 0 };
1277 macro_tokens_from_string__ (&mts, ss_cstr (s), me->segmenter_mode,
1281 struct macro_tokens tail = { .mts = mts.mts + 1, .n = mts.n - 1 };
1282 macro_tokens_to_syntax (&tail, output, NULL, NULL);
1284 macro_tokens_uninit (&mts);
1290 if (!unquote_string (args.strings[0], me->segmenter_mode, output))
1291 ds_put_cstr (output, args.strings[0]);
1297 const char *s = unquote_string_in_place (args.strings[0],
1298 me->segmenter_mode, &tmp);
1299 char *upper = utf8_to_upper (s);
1300 ds_put_cstr (output, upper);
1308 struct macro_tokens mts = { .n = 0 };
1309 macro_tokens_from_string__ (&mts, ss_cstr (args.strings[0]),
1310 me->segmenter_mode, me->stack);
1311 struct macro_tokens exp = { .n = 0 };
1312 struct macro_expansion_stack stack = {
1316 struct macro_expander subme = *me;
1317 subme.break_ = NULL;
1318 subme.stack = &stack;
1320 macro_expand (mts.mts, mts.n, &subme, &exp);
1321 macro_tokens_to_syntax (&exp, output, NULL, NULL);
1322 macro_tokens_uninit (&exp);
1323 macro_tokens_uninit (&mts);
1331 string_array_destroy (&args);
1335 static char *macro_evaluate_or (const struct macro_expander *me,
1336 const struct macro_token **tokens,
1337 const struct macro_token *end);
1340 macro_evaluate_literal (const struct macro_expander *me,
1341 const struct macro_token **tokens,
1342 const struct macro_token *end)
1344 const struct macro_token *p = *tokens;
1347 if (p->token.type == T_LPAREN)
1350 char *value = macro_evaluate_or (me, &p, end);
1353 if (p >= end || p->token.type != T_RPAREN)
1356 macro_error (me->stack, p < end ? p : NULL,
1357 _("Expecting ')' in macro expression."));
1364 else if (p->token.type == T_RPAREN)
1366 macro_error (me->stack, p, _("Expecting literal or function invocation "
1367 "in macro expression."));
1371 struct string function_output = DS_EMPTY_INITIALIZER;
1372 size_t function_consumed = parse_function_arg (me, p, end - p,
1374 struct string unquoted = DS_EMPTY_INITIALIZER;
1375 if (unquote_string (ds_cstr (&function_output), me->segmenter_mode,
1378 ds_swap (&function_output, &unquoted);
1379 ds_destroy (&unquoted);
1381 *tokens = p + function_consumed;
1382 return ds_steal_cstr (&function_output);
1385 /* Returns true if MT is valid as a macro operator. Only operators written as
1386 symbols (e.g. <>) are usable in macro expressions, not operator written as
1387 letters (e.g. EQ). */
1389 is_macro_operator (const struct macro_token *mt)
1391 return mt->syntax.length > 0 && !c_isalpha (mt->syntax.string[0]);
1394 static enum token_type
1395 parse_relational_op (const struct macro_token *mt)
1397 switch (mt->token.type)
1407 return is_macro_operator (mt) ? mt->token.type : T_STOP;
1410 return (ss_equals_case (mt->token.string, ss_cstr ("!EQ")) ? T_EQ
1411 : ss_equals_case (mt->token.string, ss_cstr ("!NE")) ? T_NE
1412 : ss_equals_case (mt->token.string, ss_cstr ("!LT")) ? T_LT
1413 : ss_equals_case (mt->token.string, ss_cstr ("!GT")) ? T_GT
1414 : ss_equals_case (mt->token.string, ss_cstr ("!LE")) ? T_LE
1415 : ss_equals_case (mt->token.string, ss_cstr ("!GE")) ? T_GE
1424 macro_evaluate_relational (const struct macro_expander *me,
1425 const struct macro_token **tokens,
1426 const struct macro_token *end)
1428 const struct macro_token *p = *tokens;
1429 char *lhs = macro_evaluate_literal (me, &p, end);
1433 enum token_type op = p >= end ? T_STOP : parse_relational_op (p);
1441 char *rhs = macro_evaluate_literal (me, &p, end);
1448 struct string lhs_tmp, rhs_tmp;
1449 int cmp = strcmp (unquote_string_in_place (lhs, me->segmenter_mode,
1451 unquote_string_in_place (rhs, me->segmenter_mode,
1453 ds_destroy (&lhs_tmp);
1454 ds_destroy (&rhs_tmp);
1459 bool b = (op == T_EQUALS || op == T_EQ ? !cmp
1461 : op == T_LT ? cmp < 0
1462 : op == T_GT ? cmp > 0
1463 : op == T_LE ? cmp <= 0
1464 : /* T_GE */ cmp >= 0);
1467 return xstrdup (b ? "1" : "0");
1471 macro_evaluate_not (const struct macro_expander *me,
1472 const struct macro_token **tokens,
1473 const struct macro_token *end)
1475 const struct macro_token *p = *tokens;
1477 unsigned int negations = 0;
1479 && (ss_equals_case (p->syntax, ss_cstr ("!NOT"))
1480 || ss_equals (p->syntax, ss_cstr ("~"))))
1486 char *operand = macro_evaluate_relational (me, &p, end);
1487 if (!operand || !negations)
1493 bool b = strcmp (operand, "0") ^ (negations & 1);
1496 return xstrdup (b ? "1" : "0");
1500 macro_evaluate_and (const struct macro_expander *me,
1501 const struct macro_token **tokens,
1502 const struct macro_token *end)
1504 const struct macro_token *p = *tokens;
1505 char *lhs = macro_evaluate_not (me, &p, end);
1510 && (ss_equals_case (p->syntax, ss_cstr ("!AND"))
1511 || ss_equals (p->syntax, ss_cstr ("&"))))
1514 char *rhs = macro_evaluate_not (me, &p, end);
1521 bool b = strcmp (lhs, "0") && strcmp (rhs, "0");
1524 lhs = xstrdup (b ? "1" : "0");
1531 macro_evaluate_or (const struct macro_expander *me,
1532 const struct macro_token **tokens,
1533 const struct macro_token *end)
1535 const struct macro_token *p = *tokens;
1536 char *lhs = macro_evaluate_and (me, &p, end);
1541 && (ss_equals_case (p->syntax, ss_cstr ("!OR"))
1542 || ss_equals (p->syntax, ss_cstr ("|"))))
1545 char *rhs = macro_evaluate_and (me, &p, end);
1552 bool b = strcmp (lhs, "0") || strcmp (rhs, "0");
1555 lhs = xstrdup (b ? "1" : "0");
1562 macro_evaluate_expression (const struct macro_token **tokens, size_t n_tokens,
1563 const struct macro_expander *me)
1565 return macro_evaluate_or (me, tokens, *tokens + n_tokens);
1569 macro_evaluate_number (const struct macro_token **tokens, size_t n_tokens,
1570 const struct macro_expander *me,
1573 char *s = macro_evaluate_expression (tokens, n_tokens, me);
1577 struct macro_tokens mts = { .n = 0 };
1578 macro_tokens_from_string__ (&mts, ss_cstr (s), me->segmenter_mode, me->stack);
1579 if (mts.n != 1 || !token_is_number (&mts.mts[0].token))
1581 macro_error (me->stack, mts.n > 0 ? &mts.mts[0] : NULL,
1582 _("Macro expression must evaluate to "
1583 "a number (not \"%s\")."), s);
1585 macro_tokens_uninit (&mts);
1589 *number = token_number (&mts.mts[0].token);
1591 macro_tokens_uninit (&mts);
1595 static const struct macro_token *
1596 find_ifend_clause (const struct macro_token *p, const struct macro_token *end)
1599 for (; p < end; p++)
1601 if (p->token.type != T_MACRO_ID)
1604 if (ss_equals_case (p->token.string, ss_cstr ("!IF")))
1606 else if (lex_id_match_n (p->token.string, ss_cstr ("!IFEND"), 4))
1612 else if (lex_id_match_n (p->token.string, ss_cstr ("!ELSE"), 4)
1620 macro_expand_if (const struct macro_token *tokens, size_t n_tokens,
1621 const struct macro_expander *me,
1622 struct macro_tokens *exp)
1624 const struct macro_token *p = tokens;
1625 const struct macro_token *end = tokens + n_tokens;
1627 if (p >= end || !ss_equals_case (p->token.string, ss_cstr ("!IF")))
1631 char *result = macro_evaluate_expression (&p, end - p, me);
1634 bool b = strcmp (result, "0");
1638 || p->token.type != T_MACRO_ID
1639 || !lex_id_match_n (p->token.string, ss_cstr ("!THEN"), 4))
1641 macro_error (me->stack, p < end ? p : NULL,
1642 _("!THEN expected in macro !IF construct."));
1646 const struct macro_token *start_then = p + 1;
1647 const struct macro_token *end_then = find_ifend_clause (start_then, end);
1650 macro_error (me->stack, NULL,
1651 _("!ELSE or !IFEND expected in macro !IF construct."));
1655 const struct macro_token *start_else, *end_if;
1656 if (lex_id_match_n (end_then->token.string, ss_cstr ("!ELSE"), 4))
1658 start_else = end_then + 1;
1659 end_if = find_ifend_clause (start_else, end);
1661 || !lex_id_match_n (end_if->token.string, ss_cstr ("!IFEND"), 4))
1663 macro_error (me->stack, end_if ? end_if : NULL,
1664 _("!IFEND expected in macro !IF construct."));
1674 const struct macro_token *start;
1679 n = end_then - start_then;
1681 else if (start_else)
1684 n = end_if - start_else;
1694 struct macro_expansion_stack stack = {
1698 struct macro_expander subme = *me;
1699 subme.stack = &stack;
1700 macro_expand (start, n, &subme, exp);
1702 return (end_if + 1) - tokens;
1706 macro_parse_let (const struct macro_token *tokens, size_t n_tokens,
1707 const struct macro_expander *me)
1709 const struct macro_token *p = tokens;
1710 const struct macro_token *end = tokens + n_tokens;
1712 if (p >= end || !ss_equals_case (p->token.string, ss_cstr ("!LET")))
1716 if (p >= end || p->token.type != T_MACRO_ID)
1718 macro_error (me->stack, p < end ? p : NULL,
1719 _("Expected macro variable name following !LET."));
1722 const struct substring var_name = p->token.string;
1723 if (is_macro_keyword (var_name)
1724 || macro_find_parameter_by_name (me->macro, var_name))
1726 macro_error (me->stack, p < end ? p : NULL,
1727 _("Cannot use argument name or macro keyword "
1728 "\"%.*s\" as !LET variable."),
1729 (int) var_name.length, var_name.string);
1734 if (p >= end || p->token.type != T_EQUALS)
1736 macro_error (me->stack, p < end ? p : NULL,
1737 _("Expected `=' following !LET."));
1742 char *value = macro_evaluate_expression (&p, end - p, me);
1746 stringi_map_replace_nocopy (me->vars, ss_xstrdup (var_name), value);
1750 static const struct macro_token *
1751 find_doend (const struct macro_expansion_stack *stack,
1752 const struct macro_token *p, const struct macro_token *end)
1755 for (; p < end; p++)
1757 if (p->token.type != T_MACRO_ID)
1760 if (ss_equals_case (p->token.string, ss_cstr ("!DO")))
1762 else if (lex_id_match_n (p->token.string, ss_cstr ("!DOEND"), 4))
1769 macro_error (stack, NULL, _("Missing !DOEND."));
1774 macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
1775 const struct macro_expander *me,
1776 struct macro_tokens *exp)
1778 const struct macro_token *p = tokens;
1779 const struct macro_token *end = tokens + n_tokens;
1781 if (p >= end || !ss_equals_case (p->token.string, ss_cstr ("!DO")))
1785 if (p >= end || p->token.type != T_MACRO_ID)
1787 macro_error (me->stack, p < end ? p : NULL,
1788 _("Expected macro variable name following !DO."));
1791 const struct substring var_name = p->token.string;
1792 if (is_macro_keyword (var_name)
1793 || macro_find_parameter_by_name (me->macro, var_name))
1795 macro_error (me->stack, p, _("Cannot use argument name or macro "
1796 "keyword as !DO variable."));
1801 struct macro_expansion_stack substack = {
1805 bool break_ = false;
1806 struct macro_expander subme = *me;
1807 subme.break_ = &break_;
1808 subme.stack = &substack;
1810 int miterate = settings_get_miterate ();
1811 if (p < end && p->token.type == T_MACRO_ID
1812 && ss_equals_case (p->token.string, ss_cstr ("!IN")))
1815 char *list = macro_evaluate_expression (&p, end - p, &subme);
1819 struct macro_tokens items = { .n = 0 };
1820 macro_tokens_from_string__ (&items, ss_cstr (list), me->segmenter_mode,
1824 const struct macro_token *do_end = find_doend (subme.stack, p, end);
1827 macro_tokens_uninit (&items);
1831 for (size_t i = 0; i < items.n && !break_; i++)
1835 macro_error (&substack, NULL,
1836 _("!DO loop over list exceeded "
1837 "maximum number of iterations %d. "
1838 "(Use SET MITERATE to change the limit.)"),
1842 stringi_map_replace_nocopy (me->vars, ss_xstrdup (var_name),
1843 ss_xstrdup (items.mts[i].syntax));
1845 macro_expand (p, do_end - p, &subme, exp);
1847 macro_tokens_uninit (&items);
1848 return do_end - tokens + 1;
1850 else if (p < end && p->token.type == T_EQUALS)
1854 if (!macro_evaluate_number (&p, end - p, &subme, &first))
1857 if (p >= end || p->token.type != T_MACRO_ID
1858 || !ss_equals_case (p->token.string, ss_cstr ("!TO")))
1860 macro_error (subme.stack, p < end ? p : NULL,
1861 _("Expected !TO in numerical !DO loop."));
1867 if (!macro_evaluate_number (&p, end - p, &subme, &last))
1871 if (p < end && p->token.type == T_MACRO_ID
1872 && ss_equals_case (p->token.string, ss_cstr ("!BY")))
1875 if (!macro_evaluate_number (&p, end - p, &subme, &by))
1880 macro_error (subme.stack, NULL, _("!BY value cannot be zero."));
1885 const struct macro_token *do_end = find_doend (subme.stack, p, end);
1888 if ((by > 0 && first <= last) || (by < 0 && first >= last))
1891 for (double index = first;
1892 by > 0 ? (index <= last) : (index >= last) && !break_;
1897 macro_error (subme.stack, NULL,
1898 _("Numerical !DO loop exceeded "
1899 "maximum number of iterations %d. "
1900 "(Use SET MITERATE to change the limit.)"),
1905 char index_s[DBL_BUFSIZE_BOUND];
1906 c_dtoastr (index_s, sizeof index_s, 0, 0, index);
1907 stringi_map_replace_nocopy (me->vars, ss_xstrdup (var_name),
1910 macro_expand (p, do_end - p, &subme, exp);
1914 return do_end - tokens + 1;
1918 macro_error (me->stack, p < end ? p : NULL,
1919 _("Expected `=' or !IN in !DO loop."));
1925 macro_expand_arg__ (const struct macro_expander *me, size_t idx,
1926 struct macro_tokens *exp)
1928 const struct macro_param *param = &me->macro->params[idx];
1929 const struct macro_tokens *arg = me->args[idx];
1931 if (*me->expand && param->expand_arg)
1933 struct stringi_map vars = STRINGI_MAP_INITIALIZER (vars);
1934 struct macro_expansion_stack stack = {
1935 .name = param->name,
1938 struct macro_expander subme = {
1939 .macros = me->macros,
1942 .segmenter_mode = me->segmenter_mode,
1943 .expand = me->expand,
1946 .nesting_countdown = me->nesting_countdown,
1949 macro_expand (arg->mts, arg->n, &subme, exp);
1950 stringi_map_destroy (&vars);
1953 for (size_t i = 0; i < arg->n; i++)
1954 macro_tokens_add (exp, &arg->mts[i]);
1958 macro_expand_arg (const struct token *token, const struct macro_expander *me,
1959 struct macro_tokens *exp)
1961 if (!me || token->type != T_MACRO_ID)
1964 /* Macro arguments. */
1967 const struct macro_param *param = macro_find_parameter_by_name (
1968 me->macro, token->string);
1971 macro_expand_arg__ (me, param - me->macro->params, exp);
1974 else if (ss_equals (token->string, ss_cstr ("!*")))
1976 for (size_t j = 0; j < me->macro->n_params; j++)
1977 macro_expand_arg__ (me, j, exp);
1982 /* Variables set by !DO or !LET. */
1983 const char *var = stringi_map_find__ (me->vars, token->string.string,
1984 token->string.length);
1987 macro_tokens_from_string__ (exp, ss_cstr (var),
1988 me->segmenter_mode, me->stack);
1996 macro_expand__ (const struct macro_token *mts, size_t n,
1997 const struct macro_expander *me,
1998 struct macro_tokens *exp)
2000 const struct token *token = &mts[0].token;
2002 /* Recursive macro calls. */
2005 struct macro_call *submc;
2006 int n_call = macro_call_create__ (me->macros, me->stack, me,
2008 for (size_t j = 1; !n_call; j++)
2010 const struct macro_token endcmd
2011 = { .token = { .type = T_ENDCMD } };
2012 n_call = macro_call_add (submc, j < n ? &mts[j] : &endcmd, NULL);
2016 struct stringi_map vars = STRINGI_MAP_INITIALIZER (vars);
2017 struct macro_expansion_stack stack = {
2018 .name = submc->macro->name,
2019 .location = submc->macro->location,
2022 struct macro_expander subme = {
2023 .macros = submc->macros,
2024 .macro = submc->macro,
2025 .args = submc->args,
2026 .segmenter_mode = me->segmenter_mode,
2027 .expand = me->expand,
2030 .nesting_countdown = me->nesting_countdown - 1,
2033 const struct macro_tokens *body = &submc->macro->body;
2034 macro_expand (body->mts, body->n, &subme, exp);
2035 macro_call_destroy (submc);
2036 stringi_map_destroy (&vars);
2040 macro_call_destroy (submc);
2043 if (token->type != T_MACRO_ID)
2045 macro_tokens_add (exp, &mts[0]);
2049 /* Parameters and macro variables. */
2050 if (macro_expand_arg (token, me, exp))
2053 /* Macro functions. */
2054 struct string function_output = DS_EMPTY_INITIALIZER;
2055 size_t n_function = expand_macro_function (me, mts, n, &function_output);
2058 macro_tokens_from_string__ (exp, function_output.ss,
2059 me->segmenter_mode, me->stack);
2060 ds_destroy (&function_output);
2065 size_t n_if = macro_expand_if (mts, n, me, exp);
2069 size_t n_let = macro_parse_let (mts, n, me);
2073 size_t n_do = macro_expand_do (mts, n, me, exp);
2077 if (lex_id_match_n (token->string, ss_cstr ("!break"), 4))
2082 macro_error (me->stack, &mts[0], _("!BREAK outside !DO."));
2084 else if (lex_id_match_n (token->string, ss_cstr ("!onexpand"), 4))
2086 else if (lex_id_match_n (token->string, ss_cstr ("!offexpand"), 4))
2087 *me->expand = false;
2089 macro_tokens_add (exp, &mts[0]);
2094 macro_expand (const struct macro_token *mts, size_t n,
2095 const struct macro_expander *me,
2096 struct macro_tokens *exp)
2098 if (me->nesting_countdown <= 0)
2100 macro_error (me->stack, NULL, _("Maximum nesting level %d exceeded. "
2101 "(Use SET MNEST to change the limit.)"),
2102 settings_get_mnest ());
2103 for (size_t i = 0; i < n; i++)
2104 macro_tokens_add (exp, &mts[i]);
2108 for (size_t i = 0; i < n; )
2110 if (me->break_ && *me->break_)
2113 size_t consumed = macro_expand__ (&mts[i], n - i, me, exp);
2114 assert (consumed > 0 && i + consumed <= n);
2120 macro_call_expand (struct macro_call *mc, enum segmenter_mode segmenter_mode,
2121 const struct msg_location *call_loc,
2122 struct macro_tokens *exp)
2124 assert (mc->state == MC_FINISHED);
2127 struct stringi_map vars = STRINGI_MAP_INITIALIZER (vars);
2128 struct macro_expansion_stack stack0 = {
2129 .location = call_loc,
2131 struct macro_expansion_stack stack1 = {
2133 .name = mc->macro->name,
2134 .location = mc->macro->location,
2136 struct macro_expander me = {
2137 .macros = mc->macros,
2140 .segmenter_mode = segmenter_mode,
2144 .nesting_countdown = settings_get_mnest (),
2148 const struct macro_tokens *body = &mc->macro->body;
2149 macro_expand (body->mts, body->n, &me, exp);
2151 stringi_map_destroy (&vars);