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)
368 /* Appends syntax for the tokens in MTS to S. If OFS and LEN are nonnull, sets
369 OFS[i] to the offset within S of the start of token 'i' in MTS and LEN[i] to
370 its length. OFS[i] + LEN[i] is not necessarily OFS[i + 1] because some
371 tokens are separated by white space. */
373 macro_tokens_to_syntax (struct macro_tokens *mts, struct string *s,
374 size_t *ofs, size_t *len)
376 assert ((ofs != NULL) == (len != NULL));
381 for (size_t i = 0; i < mts->n; i++)
385 enum token_type prev = mts->mts[i - 1].token.type;
386 enum token_type next = mts->mts[i].token.type;
388 if (prev == T_ENDCMD)
389 ds_put_byte (s, '\n');
392 enum token_class pc = classify_token (prev);
393 enum token_class nc = classify_token (next);
394 if (needs_space (pc, nc))
395 ds_put_byte (s, ' ');
400 ofs[i] = s->ss.length;
401 macro_token_to_syntax (&mts->mts[i], s);
403 len[i] = s->ss.length - ofs[i];
408 macro_destroy (struct macro *m)
414 msg_location_destroy (m->location);
415 for (size_t i = 0; i < m->n_params; i++)
417 struct macro_param *p = &m->params[i];
420 macro_tokens_uninit (&p->def);
421 token_uninit (&p->start);
422 token_uninit (&p->end);
425 macro_tokens_uninit (&m->body);
430 macro_set_create (void)
432 struct macro_set *set = xmalloc (sizeof *set);
433 *set = (struct macro_set) {
434 .macros = HMAP_INITIALIZER (set->macros),
440 macro_set_destroy (struct macro_set *set)
445 struct macro *macro, *next;
446 HMAP_FOR_EACH_SAFE (macro, next, struct macro, hmap_node, &set->macros)
448 hmap_delete (&set->macros, ¯o->hmap_node);
449 macro_destroy (macro);
451 hmap_destroy (&set->macros);
456 hash_macro_name (const char *name)
458 return utf8_hash_case_string (name, 0);
461 static struct macro *
462 macro_set_find__ (struct macro_set *set, const char *name)
464 if (macro_set_is_empty (set))
468 HMAP_FOR_EACH_WITH_HASH (macro, struct macro, hmap_node,
469 hash_macro_name (name), &set->macros)
470 if (!utf8_strcasecmp (macro->name, name))
477 macro_set_find (const struct macro_set *set, const char *name)
479 return macro_set_find__ (CONST_CAST (struct macro_set *, set), name);
482 /* Adds M to SET. M replaces any existing macro with the same name. Takes
485 macro_set_add (struct macro_set *set, struct macro *m)
487 struct macro *victim = macro_set_find__ (set, m->name);
490 hmap_delete (&set->macros, &victim->hmap_node);
491 macro_destroy (victim);
494 hmap_insert (&set->macros, &m->hmap_node, hash_macro_name (m->name));
497 /* Macro call parsing. */
504 /* Accumulating tokens in mc->params toward the end of any type of
508 /* Expecting the opening delimiter of an ARG_ENCLOSE argument. */
511 /* Expecting a keyword for a keyword argument. */
514 /* Expecting an equal sign for a keyword argument. */
517 /* Macro fully parsed and ready for expansion. */
521 /* Parsing macro calls. This is a FSM driven by macro_call_create() and
522 macro_call_add() to identify the macro being called and obtain its
523 arguments. 'state' identifies the FSM state. */
526 const struct macro_set *macros;
527 const struct macro *macro;
528 struct macro_tokens **args;
529 const struct macro_expansion_stack *stack;
530 const struct macro_expander *me;
534 const struct macro_param *param; /* Parameter currently being parsed. */
537 static bool macro_expand_arg (const struct token *,
538 const struct macro_expander *,
539 struct macro_tokens *exp);
541 /* Completes macro expansion by initializing arguments that weren't supplied to
544 mc_finished (struct macro_call *mc)
546 mc->state = MC_FINISHED;
547 for (size_t i = 0; i < mc->macro->n_params; i++)
549 mc->args[i] = &mc->macro->params[i].def;
554 mc_next_arg (struct macro_call *mc)
558 assert (!mc->macro->n_params);
559 return mc_finished (mc);
561 else if (mc->param->positional)
564 if (mc->param >= &mc->macro->params[mc->macro->n_params])
565 return mc_finished (mc);
568 mc->state = (!mc->param->positional ? MC_KEYWORD
569 : mc->param->arg_type == ARG_ENCLOSE ? MC_ENCLOSE
576 for (size_t i = 0; i < mc->macro->n_params; i++)
579 mc->state = MC_KEYWORD;
582 return mc_finished (mc);
586 static void PRINTF_FORMAT (3, 4)
587 mc_error (const struct macro_call *mc, const struct msg_location *loc,
588 const char *format, ...)
591 va_start (args, format);
594 const struct macro_expansion_stack stack = { .location = loc };
595 macro_error_valist (&stack, NULL, format, args);
598 macro_error_valist (mc->stack, NULL, format, args);
603 mc_add_arg (struct macro_call *mc, const struct macro_token *mt,
604 const struct msg_location *loc)
606 const struct macro_param *p = mc->param;
607 struct macro_tokens **argp = &mc->args[p - mc->macro->params];
609 const struct token *token = &mt->token;
610 if (token->type == T_ENDCMD || token->type == T_STOP)
617 /* This is OK, it's the expected way to end the argument. */
622 ngettext (_("Reached end of command expecting %zu "
623 "more token in argument %s to macro %s."),
624 _("Reached end of command expecting %zu "
625 "more tokens in argument %s to macro %s."),
626 p->n_tokens - (*argp)->n),
627 p->n_tokens - (*argp)->n, p->name, mc->macro->name);
633 char *end = token_to_string (&p->end);
634 mc_error (mc, loc, _("Reached end of command expecting \"%s\" "
635 "in argument %s to macro %s."),
636 end, p->name, mc->macro->name);
643 /* The end of a command ends the current argument, precludes any further
644 arguments, and is not itself part of the argument. */
645 return mc_finished (mc);
651 *argp = xzalloc (sizeof **argp);
653 bool add_token; /* Should we add 'mt' to the current arg? */
654 bool next_arg; /* Should we advance to the next arg? */
658 next_arg = (*argp)->n + 1 >= p->n_tokens;
664 next_arg = token_equal (token, &p->end);
665 add_token = !next_arg;
679 if (!macro_expand_arg (&mt->token, mc->me, *argp))
680 macro_tokens_add (*argp, mt);
682 return next_arg ? mc_next_arg (mc) : 0;
686 mc_expected (struct macro_call *mc, const struct macro_token *actual,
687 const struct msg_location *loc, const struct token *expected)
689 const struct substring actual_s = (actual->syntax.length ? actual->syntax
690 : ss_cstr (_("<end of input>")));
691 char *expected_s = token_to_string (expected);
693 _("Found `%.*s' while expecting `%s' reading argument %s "
695 (int) actual_s.length, actual_s.string, expected_s,
696 mc->param->name, mc->macro->name);
699 mc->state = MC_ERROR;
704 mc_enclose (struct macro_call *mc, const struct macro_token *mt,
705 const struct msg_location *loc)
709 const struct token *token = &mt->token;
710 const struct macro_param *p = mc->param;
711 if (token_equal (&p->start, token))
713 struct macro_tokens **argp = &mc->args[p - mc->macro->params];
714 *argp = xzalloc (sizeof **argp);
718 else if (p->positional && (token->type == T_ENDCMD || token->type == T_STOP))
719 return mc_finished (mc);
721 return mc_expected (mc, mt, loc, &p->start);
724 static const struct macro_param *
725 macro_find_parameter_by_name (const struct macro *m, struct substring name)
730 ss_ltrim (&name, ss_cstr ("!"));
732 for (size_t i = 0; i < m->n_params; i++)
734 const struct macro_param *p = &m->params[i];
735 struct substring p_name = ss_cstr (p->name + 1);
736 if (!utf8_strncasecmp (p_name.string, p_name.length,
737 name.string, name.length))
744 mc_keyword (struct macro_call *mc, const struct macro_token *mt,
745 const struct msg_location *loc)
747 const struct token *token = &mt->token;
748 if (token->type != T_ID)
749 return mc_finished (mc);
751 const struct macro_param *p = macro_find_parameter_by_name (mc->macro,
755 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);
761 mc->state = MC_ERROR;
765 *argp = xzalloc (sizeof **argp);
768 mc->state = MC_EQUALS;
772 return mc_finished (mc);
776 mc_equals (struct macro_call *mc, const struct macro_token *mt,
777 const struct msg_location *loc)
779 const struct token *token = &mt->token;
782 if (token->type == T_EQUALS)
784 mc->state = mc->param->arg_type == ARG_ENCLOSE ? MC_ENCLOSE : MC_ARG;
788 return mc_expected (mc, mt, loc, &(struct token) { .type = T_EQUALS });
792 macro_call_create__ (const struct macro_set *macros,
793 const struct macro_expansion_stack *stack,
794 const struct macro_expander *me,
795 const struct token *token,
796 struct macro_call **mcp)
798 const struct macro *macro = (token->type == T_ID || token->type == T_MACRO_ID
799 ? macro_set_find (macros, token->string.string)
807 struct macro_call *mc = xmalloc (sizeof *mc);
808 *mc = (struct macro_call) {
812 .state = (!macro->n_params ? MC_FINISHED
813 : !macro->params[0].positional ? MC_KEYWORD
814 : macro->params[0].arg_type == ARG_ENCLOSE ? MC_ENCLOSE
816 .args = macro->n_params ? xcalloc (macro->n_params, sizeof *mc->args) : NULL,
817 .param = macro->params,
823 return mc->state == MC_FINISHED ? 1 : 0;
826 /* If TOKEN is the first token of a call to a macro in MACROS, create a new
827 macro expander, initializes *MCP to it. Returns 0 if more tokens are needed
828 and should be added via macro_call_add() or 1 if the caller should next call
829 macro_call_get_expansion().
831 If TOKEN is not the first token of a macro call, returns -1 and sets *MCP to
834 macro_call_create (const struct macro_set *macros,
835 const struct token *token,
836 struct macro_call **mcp)
838 return macro_call_create__ (macros, NULL, NULL, token, mcp);
842 macro_call_destroy (struct macro_call *mc)
847 for (size_t i = 0; i < mc->macro->n_params; i++)
849 struct macro_tokens *a = mc->args[i];
850 if (a && a != &mc->macro->params[i].def)
852 macro_tokens_uninit (a);
860 /* Adds TOKEN to the collection of tokens in MC that potentially need to be
863 Returns -1 if the tokens added do not actually invoke a macro. The caller
864 should consume the first token without expanding it. (Later tokens might
865 invoke a macro so it's best to feed the second token into a new expander.)
867 Returns 0 if the macro expander needs more tokens, for macro arguments or to
868 decide whether this is actually a macro invocation. The caller should call
869 macro_call_add() again with the next token.
871 Returns a positive number to indicate that the returned number of tokens
872 invoke a macro. The number returned might be less than the number of tokens
873 added because it can take a few tokens of lookahead to determine whether the
874 macro invocation is finished. The caller should call
875 macro_call_get_expansion() to obtain the expansion. */
877 macro_call_add (struct macro_call *mc, const struct macro_token *mt,
878 const struct msg_location *loc)
886 return mc_add_arg (mc, mt, loc);
889 return mc_enclose (mc, mt, loc);
892 return mc_keyword (mc, mt, loc);
895 return mc_equals (mc, mt, loc);
902 /* Macro expansion. */
904 struct macro_expander
906 /* Always available. */
907 const struct macro_set *macros; /* Macros to expand recursively. */
908 enum segmenter_mode segmenter_mode; /* Mode for tokenization. */
909 int nesting_countdown; /* Remaining nesting levels. */
910 const struct macro_expansion_stack *stack; /* Stack for error reporting. */
911 bool *expand; /* May macro calls be expanded? */
912 struct stringi_map *vars; /* Variables from !do and !let. */
914 /* Only nonnull if inside a !DO loop. */
915 bool *break_; /* Set to true to break out of loop. */
917 /* Only nonnull if expanding a macro (and not, say, a macro argument). */
918 const struct macro *macro;
919 struct macro_tokens **args;
923 macro_expand (const struct macro_token *mts, size_t n_mts,
924 const struct macro_expander *, struct macro_tokens *);
927 expand_macro_function (const struct macro_expander *me,
928 const struct macro_token *input, size_t n_input,
929 struct string *output);
931 /* Parses one function argument from the N_INPUT tokens in INPUT
932 Each argument to a macro function is one of:
934 - A quoted string or other single literal token.
936 - An argument to the macro being expanded, e.g. !1 or a named argument.
940 - A function invocation.
942 Each function invocation yields a character sequence to be turned into a
943 sequence of tokens. The case where that character sequence is a single
944 quoted string is an important special case.
947 parse_function_arg (const struct macro_expander *me,
948 const struct macro_token *input, size_t n_input,
951 assert (n_input > 0);
953 const struct token *token = &input[0].token;
954 if (token->type == T_MACRO_ID && me->macro)
956 const struct macro_param *param = macro_find_parameter_by_name (
957 me->macro, token->string);
960 size_t param_idx = param - me->macro->params;
961 macro_tokens_to_syntax (me->args[param_idx], farg, NULL, NULL);
965 if (ss_equals (token->string, ss_cstr ("!*")))
967 for (size_t i = 0; i < me->macro->n_params; i++)
969 if (!me->macro->params[i].positional)
972 ds_put_byte (farg, ' ');
973 macro_tokens_to_syntax (me->args[i], farg, NULL, NULL);
978 const char *var = stringi_map_find__ (me->vars,
979 token->string.string,
980 token->string.length);
983 ds_put_cstr (farg, var);
987 size_t n_function = expand_macro_function (me, input, n_input, farg);
992 ds_put_substring (farg, input[0].syntax);
997 parse_function_args (const struct macro_expander *me,
998 const struct macro_token *mts, size_t n,
999 const char *function,
1000 struct string_array *args)
1002 if (n < 2 || mts[1].token.type != T_LPAREN)
1004 macro_error (me->stack, n > 1 ? &mts[1] : NULL,
1005 _("`(' expected following %s."), function);
1009 for (size_t i = 2; i < n; )
1011 if (mts[i].token.type == T_RPAREN)
1014 struct string s = DS_EMPTY_INITIALIZER;
1015 i += parse_function_arg (me, mts + i, n - i, &s);
1016 string_array_append_nocopy (args, ds_steal_cstr (&s));
1020 else if (mts[i].token.type == T_COMMA)
1022 else if (mts[i].token.type != T_RPAREN)
1024 macro_error (me->stack, &mts[i],
1025 _("`,' or `)' expected in call to macro function %s."),
1031 macro_error (me->stack, NULL, _("Missing `)' in call to macro function %s."),
1037 unquote_string (const char *s, enum segmenter_mode segmenter_mode,
1038 struct string *content)
1040 struct string_lexer slex;
1041 string_lexer_init (&slex, s, strlen (s), segmenter_mode, true);
1043 struct token token1;
1044 if (string_lexer_next (&slex, &token1) != SLR_TOKEN
1045 || token1.type != T_STRING)
1047 token_uninit (&token1);
1051 struct token token2;
1052 if (string_lexer_next (&slex, &token2) != SLR_END)
1054 token_uninit (&token1);
1055 token_uninit (&token2);
1059 ds_put_substring (content, token1.string);
1060 token_uninit (&token1);
1065 unquote_string_in_place (const char *s, enum segmenter_mode segmenter_mode,
1068 ds_init_empty (tmp);
1069 return unquote_string (s, segmenter_mode, tmp) ? ds_cstr (tmp) : s;
1073 parse_integer (const char *s, int *np)
1078 long int n = strtol (s, &tail, 10);
1079 *np = n < INT_MIN ? INT_MIN : n > INT_MAX ? INT_MAX : n;
1080 tail += strspn (tail, CC_SPACES);
1081 return *tail == '\0' && errno != ERANGE && n == *np;
1085 expand_macro_function (const struct macro_expander *me,
1086 const struct macro_token *input, size_t n_input,
1087 struct string *output)
1089 if (!n_input || input[0].token.type != T_MACRO_ID)
1092 struct macro_function
1098 enum macro_function_id
1113 static const struct macro_function mfs[] = {
1114 [MF_BLANKS] = { "!BLANKS", 1, 1 },
1115 [MF_CONCAT] = { "!CONCAT", 1, INT_MAX },
1116 [MF_EVAL] = { "!EVAL", 1, 1 },
1117 [MF_HEAD] = { "!HEAD", 1, 1 },
1118 [MF_INDEX] = { "!INDEX", 2, 2 },
1119 [MF_LENGTH] = { "!LENGTH", 1, 1 },
1120 [MF_NULL] = { "!NULL", 0, 0 },
1121 [MF_QUOTE] = { "!QUOTE", 1, 1 },
1122 [MF_SUBSTR] = { "!SUBSTR", 2, 3 },
1123 [MF_TAIL] = { "!TAIL", 1, 1 },
1124 [MF_UNQUOTE] = { "!UNQUOTE", 1, 1 },
1125 [MF_UPCASE] = { "!UPCASE", 1, 1 },
1128 /* Is this a macro function? */
1129 const struct macro_function *mf;
1130 for (mf = mfs; ; mf++)
1132 if (mf >= mfs + sizeof mfs / sizeof *mfs)
1134 /* Not a macro function. */
1138 if (lex_id_match_n (ss_cstr (mf->name), input[0].token.string, 4))
1142 enum macro_function_id id = mf - mfs;
1146 struct string_array args = STRING_ARRAY_INITIALIZER;
1147 size_t n_consumed = parse_function_args (me, input, n_input, mf->name, &args);
1151 if (args.n < mf->min_args || args.n > mf->max_args)
1153 if (mf->min_args == 1 && mf->max_args == 1)
1154 macro_error (me->stack, NULL,
1155 _("Macro function %s takes one argument (not %zu)."),
1157 else if (mf->min_args == 2 && mf->max_args == 2)
1158 macro_error (me->stack, NULL,
1159 _("Macro function %s takes two arguments (not %zu)."),
1161 else if (mf->min_args == 2 && mf->max_args == 3)
1162 macro_error (me->stack, NULL,
1163 _("Macro function %s takes two or three arguments "
1166 else if (mf->min_args == 1 && mf->max_args == INT_MAX)
1167 macro_error (me->stack, NULL,
1168 _("Macro function %s needs at least one argument."),
1178 ds_put_format (output, "%zu", strlen (args.strings[0]));
1184 if (!parse_integer (args.strings[0], &n))
1186 macro_error (me->stack, NULL,
1187 _("Argument to !BLANKS must be non-negative integer "
1188 "(not \"%s\")."), args.strings[0]);
1189 string_array_destroy (&args);
1193 ds_put_byte_multiple (output, ' ', n);
1198 for (size_t i = 0; i < args.n; i++)
1199 if (!unquote_string (args.strings[i], me->segmenter_mode, output))
1200 ds_put_cstr (output, args.strings[i]);
1206 const char *s = unquote_string_in_place (args.strings[0],
1207 me->segmenter_mode, &tmp);
1209 struct macro_tokens mts = { .n = 0 };
1210 macro_tokens_from_string__ (&mts, ss_cstr (s), me->segmenter_mode,
1213 ds_put_substring (output, mts.mts[0].syntax);
1214 macro_tokens_uninit (&mts);
1221 const char *haystack = args.strings[0];
1222 const char *needle = strstr (haystack, args.strings[1]);
1223 ds_put_format (output, "%zu", needle ? needle - haystack + 1 : 0);
1228 if (unquote_string (args.strings[0], me->segmenter_mode, NULL))
1229 ds_put_cstr (output, args.strings[0]);
1232 ds_extend (output, strlen (args.strings[0]) + 2);
1233 ds_put_byte (output, '\'');
1234 for (const char *p = args.strings[0]; *p; p++)
1237 ds_put_byte (output, '\'');
1238 ds_put_byte (output, *p);
1240 ds_put_byte (output, '\'');
1247 if (!parse_integer (args.strings[1], &start) || start < 1)
1249 macro_error (me->stack, NULL,
1250 _("Second argument of !SUBSTR must be "
1251 "positive integer (not \"%s\")."),
1253 string_array_destroy (&args);
1257 int count = INT_MAX;
1258 if (args.n > 2 && (!parse_integer (args.strings[2], &count) || count < 0))
1260 macro_error (me->stack, NULL,
1261 _("Third argument of !SUBSTR must be "
1262 "non-negative integer (not \"%s\")."),
1264 string_array_destroy (&args);
1268 struct substring s = ss_cstr (args.strings[0]);
1269 ds_put_substring (output, ss_substr (s, start - 1, count));
1276 const char *s = unquote_string_in_place (args.strings[0],
1277 me->segmenter_mode, &tmp);
1279 struct macro_tokens mts = { .n = 0 };
1280 macro_tokens_from_string__ (&mts, ss_cstr (s), me->segmenter_mode,
1284 struct macro_tokens tail = { .mts = mts.mts + 1, .n = mts.n - 1 };
1285 macro_tokens_to_syntax (&tail, output, NULL, NULL);
1287 macro_tokens_uninit (&mts);
1293 if (!unquote_string (args.strings[0], me->segmenter_mode, output))
1294 ds_put_cstr (output, args.strings[0]);
1300 const char *s = unquote_string_in_place (args.strings[0],
1301 me->segmenter_mode, &tmp);
1302 char *upper = utf8_to_upper (s);
1303 ds_put_cstr (output, upper);
1311 struct macro_tokens mts = { .n = 0 };
1312 macro_tokens_from_string__ (&mts, ss_cstr (args.strings[0]),
1313 me->segmenter_mode, me->stack);
1314 struct macro_tokens exp = { .n = 0 };
1315 struct macro_expansion_stack stack = {
1319 struct macro_expander subme = *me;
1320 subme.break_ = NULL;
1321 subme.stack = &stack;
1323 macro_expand (mts.mts, mts.n, &subme, &exp);
1324 macro_tokens_to_syntax (&exp, output, NULL, NULL);
1325 macro_tokens_uninit (&exp);
1326 macro_tokens_uninit (&mts);
1334 string_array_destroy (&args);
1338 static char *macro_evaluate_or (const struct macro_expander *me,
1339 const struct macro_token **tokens,
1340 const struct macro_token *end);
1343 macro_evaluate_literal (const struct macro_expander *me,
1344 const struct macro_token **tokens,
1345 const struct macro_token *end)
1347 const struct macro_token *p = *tokens;
1350 if (p->token.type == T_LPAREN)
1353 char *value = macro_evaluate_or (me, &p, end);
1356 if (p >= end || p->token.type != T_RPAREN)
1359 macro_error (me->stack, p < end ? p : NULL,
1360 _("Expecting ')' in macro expression."));
1367 else if (p->token.type == T_RPAREN)
1369 macro_error (me->stack, p, _("Expecting literal or function invocation "
1370 "in macro expression."));
1374 struct string function_output = DS_EMPTY_INITIALIZER;
1375 size_t function_consumed = parse_function_arg (me, p, end - p,
1377 struct string unquoted = DS_EMPTY_INITIALIZER;
1378 if (unquote_string (ds_cstr (&function_output), me->segmenter_mode,
1381 ds_swap (&function_output, &unquoted);
1382 ds_destroy (&unquoted);
1384 *tokens = p + function_consumed;
1385 return ds_steal_cstr (&function_output);
1388 /* Returns true if MT is valid as a macro operator. Only operators written as
1389 symbols (e.g. <>) are usable in macro expressions, not operator written as
1390 letters (e.g. EQ). */
1392 is_macro_operator (const struct macro_token *mt)
1394 return mt->syntax.length > 0 && !c_isalpha (mt->syntax.string[0]);
1397 static enum token_type
1398 parse_relational_op (const struct macro_token *mt)
1400 switch (mt->token.type)
1410 return is_macro_operator (mt) ? mt->token.type : T_STOP;
1413 return (ss_equals_case (mt->token.string, ss_cstr ("!EQ")) ? T_EQ
1414 : ss_equals_case (mt->token.string, ss_cstr ("!NE")) ? T_NE
1415 : ss_equals_case (mt->token.string, ss_cstr ("!LT")) ? T_LT
1416 : ss_equals_case (mt->token.string, ss_cstr ("!GT")) ? T_GT
1417 : ss_equals_case (mt->token.string, ss_cstr ("!LE")) ? T_LE
1418 : ss_equals_case (mt->token.string, ss_cstr ("!GE")) ? T_GE
1427 macro_evaluate_relational (const struct macro_expander *me,
1428 const struct macro_token **tokens,
1429 const struct macro_token *end)
1431 const struct macro_token *p = *tokens;
1432 char *lhs = macro_evaluate_literal (me, &p, end);
1436 enum token_type op = p >= end ? T_STOP : parse_relational_op (p);
1444 char *rhs = macro_evaluate_literal (me, &p, end);
1451 struct string lhs_tmp, rhs_tmp;
1452 int cmp = strcmp (unquote_string_in_place (lhs, me->segmenter_mode,
1454 unquote_string_in_place (rhs, me->segmenter_mode,
1456 ds_destroy (&lhs_tmp);
1457 ds_destroy (&rhs_tmp);
1462 bool b = (op == T_EQUALS || op == T_EQ ? !cmp
1464 : op == T_LT ? cmp < 0
1465 : op == T_GT ? cmp > 0
1466 : op == T_LE ? cmp <= 0
1467 : /* T_GE */ cmp >= 0);
1470 return xstrdup (b ? "1" : "0");
1474 macro_evaluate_not (const struct macro_expander *me,
1475 const struct macro_token **tokens,
1476 const struct macro_token *end)
1478 const struct macro_token *p = *tokens;
1480 unsigned int negations = 0;
1482 && (ss_equals_case (p->syntax, ss_cstr ("!NOT"))
1483 || ss_equals (p->syntax, ss_cstr ("~"))))
1489 char *operand = macro_evaluate_relational (me, &p, end);
1490 if (!operand || !negations)
1496 bool b = strcmp (operand, "0") ^ (negations & 1);
1499 return xstrdup (b ? "1" : "0");
1503 macro_evaluate_and (const struct macro_expander *me,
1504 const struct macro_token **tokens,
1505 const struct macro_token *end)
1507 const struct macro_token *p = *tokens;
1508 char *lhs = macro_evaluate_not (me, &p, end);
1513 && (ss_equals_case (p->syntax, ss_cstr ("!AND"))
1514 || ss_equals (p->syntax, ss_cstr ("&"))))
1517 char *rhs = macro_evaluate_not (me, &p, end);
1524 bool b = strcmp (lhs, "0") && strcmp (rhs, "0");
1527 lhs = xstrdup (b ? "1" : "0");
1534 macro_evaluate_or (const struct macro_expander *me,
1535 const struct macro_token **tokens,
1536 const struct macro_token *end)
1538 const struct macro_token *p = *tokens;
1539 char *lhs = macro_evaluate_and (me, &p, end);
1544 && (ss_equals_case (p->syntax, ss_cstr ("!OR"))
1545 || ss_equals (p->syntax, ss_cstr ("|"))))
1548 char *rhs = macro_evaluate_and (me, &p, end);
1555 bool b = strcmp (lhs, "0") || strcmp (rhs, "0");
1558 lhs = xstrdup (b ? "1" : "0");
1565 macro_evaluate_expression (const struct macro_token **tokens, size_t n_tokens,
1566 const struct macro_expander *me)
1568 return macro_evaluate_or (me, tokens, *tokens + n_tokens);
1572 macro_evaluate_number (const struct macro_token **tokens, size_t n_tokens,
1573 const struct macro_expander *me,
1576 char *s = macro_evaluate_expression (tokens, n_tokens, me);
1580 struct macro_tokens mts = { .n = 0 };
1581 macro_tokens_from_string__ (&mts, ss_cstr (s), me->segmenter_mode, me->stack);
1582 if (mts.n != 1 || !token_is_number (&mts.mts[0].token))
1584 macro_error (me->stack, mts.n > 0 ? &mts.mts[0] : NULL,
1585 _("Macro expression must evaluate to "
1586 "a number (not \"%s\")."), s);
1588 macro_tokens_uninit (&mts);
1592 *number = token_number (&mts.mts[0].token);
1594 macro_tokens_uninit (&mts);
1598 static const struct macro_token *
1599 find_ifend_clause (const struct macro_token *p, const struct macro_token *end)
1602 for (; p < end; p++)
1604 if (p->token.type != T_MACRO_ID)
1607 if (ss_equals_case (p->token.string, ss_cstr ("!IF")))
1609 else if (lex_id_match_n (p->token.string, ss_cstr ("!IFEND"), 4))
1615 else if (lex_id_match_n (p->token.string, ss_cstr ("!ELSE"), 4)
1623 macro_expand_if (const struct macro_token *tokens, size_t n_tokens,
1624 const struct macro_expander *me,
1625 struct macro_tokens *exp)
1627 const struct macro_token *p = tokens;
1628 const struct macro_token *end = tokens + n_tokens;
1630 if (p >= end || !ss_equals_case (p->token.string, ss_cstr ("!IF")))
1634 char *result = macro_evaluate_expression (&p, end - p, me);
1637 bool b = strcmp (result, "0");
1641 || p->token.type != T_MACRO_ID
1642 || !lex_id_match_n (p->token.string, ss_cstr ("!THEN"), 4))
1644 macro_error (me->stack, p < end ? p : NULL,
1645 _("!THEN expected in macro !IF construct."));
1649 const struct macro_token *start_then = p + 1;
1650 const struct macro_token *end_then = find_ifend_clause (start_then, end);
1653 macro_error (me->stack, NULL,
1654 _("!ELSE or !IFEND expected in macro !IF construct."));
1658 const struct macro_token *start_else, *end_if;
1659 if (lex_id_match_n (end_then->token.string, ss_cstr ("!ELSE"), 4))
1661 start_else = end_then + 1;
1662 end_if = find_ifend_clause (start_else, end);
1664 || !lex_id_match_n (end_if->token.string, ss_cstr ("!IFEND"), 4))
1666 macro_error (me->stack, end_if ? end_if : NULL,
1667 _("!IFEND expected in macro !IF construct."));
1677 const struct macro_token *start;
1682 n = end_then - start_then;
1684 else if (start_else)
1687 n = end_if - start_else;
1697 struct macro_expansion_stack stack = {
1701 struct macro_expander subme = *me;
1702 subme.stack = &stack;
1703 macro_expand (start, n, &subme, exp);
1705 return (end_if + 1) - tokens;
1709 macro_parse_let (const struct macro_token *tokens, size_t n_tokens,
1710 const struct macro_expander *me)
1712 const struct macro_token *p = tokens;
1713 const struct macro_token *end = tokens + n_tokens;
1715 if (p >= end || !ss_equals_case (p->token.string, ss_cstr ("!LET")))
1719 if (p >= end || p->token.type != T_MACRO_ID)
1721 macro_error (me->stack, p < end ? p : NULL,
1722 _("Expected macro variable name following !LET."));
1725 const struct substring var_name = p->token.string;
1726 if (is_macro_keyword (var_name)
1727 || macro_find_parameter_by_name (me->macro, var_name))
1729 macro_error (me->stack, p < end ? p : NULL,
1730 _("Cannot use argument name or macro keyword "
1731 "\"%.*s\" as !LET variable."),
1732 (int) var_name.length, var_name.string);
1737 if (p >= end || p->token.type != T_EQUALS)
1739 macro_error (me->stack, p < end ? p : NULL,
1740 _("Expected `=' following !LET."));
1745 char *value = macro_evaluate_expression (&p, end - p, me);
1749 stringi_map_replace_nocopy (me->vars, ss_xstrdup (var_name), value);
1753 static const struct macro_token *
1754 find_doend (const struct macro_expansion_stack *stack,
1755 const struct macro_token *p, const struct macro_token *end)
1758 for (; p < end; p++)
1760 if (p->token.type != T_MACRO_ID)
1763 if (ss_equals_case (p->token.string, ss_cstr ("!DO")))
1765 else if (lex_id_match_n (p->token.string, ss_cstr ("!DOEND"), 4))
1772 macro_error (stack, NULL, _("Missing !DOEND."));
1777 macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
1778 const struct macro_expander *me,
1779 struct macro_tokens *exp)
1781 const struct macro_token *p = tokens;
1782 const struct macro_token *end = tokens + n_tokens;
1784 if (p >= end || !ss_equals_case (p->token.string, ss_cstr ("!DO")))
1788 if (p >= end || p->token.type != T_MACRO_ID)
1790 macro_error (me->stack, p < end ? p : NULL,
1791 _("Expected macro variable name following !DO."));
1794 const struct substring var_name = p->token.string;
1795 if (is_macro_keyword (var_name)
1796 || macro_find_parameter_by_name (me->macro, var_name))
1798 macro_error (me->stack, p, _("Cannot use argument name or macro "
1799 "keyword as !DO variable."));
1804 struct macro_expansion_stack substack = {
1808 bool break_ = false;
1809 struct macro_expander subme = *me;
1810 subme.break_ = &break_;
1811 subme.stack = &substack;
1813 int miterate = settings_get_miterate ();
1814 if (p < end && p->token.type == T_MACRO_ID
1815 && ss_equals_case (p->token.string, ss_cstr ("!IN")))
1818 char *list = macro_evaluate_expression (&p, end - p, &subme);
1822 struct macro_tokens items = { .n = 0 };
1823 macro_tokens_from_string__ (&items, ss_cstr (list), me->segmenter_mode,
1827 const struct macro_token *do_end = find_doend (subme.stack, p, end);
1830 macro_tokens_uninit (&items);
1834 for (size_t i = 0; i < items.n && !break_; i++)
1838 macro_error (&substack, NULL,
1839 _("!DO loop over list exceeded "
1840 "maximum number of iterations %d. "
1841 "(Use SET MITERATE to change the limit.)"),
1845 stringi_map_replace_nocopy (me->vars, ss_xstrdup (var_name),
1846 ss_xstrdup (items.mts[i].syntax));
1848 macro_expand (p, do_end - p, &subme, exp);
1850 return do_end - tokens + 1;
1852 else if (p < end && p->token.type == T_EQUALS)
1856 if (!macro_evaluate_number (&p, end - p, &subme, &first))
1859 if (p >= end || p->token.type != T_MACRO_ID
1860 || !ss_equals_case (p->token.string, ss_cstr ("!TO")))
1862 macro_error (subme.stack, p < end ? p : NULL,
1863 _("Expected !TO in numerical !DO loop."));
1869 if (!macro_evaluate_number (&p, end - p, &subme, &last))
1873 if (p < end && p->token.type == T_MACRO_ID
1874 && ss_equals_case (p->token.string, ss_cstr ("!BY")))
1877 if (!macro_evaluate_number (&p, end - p, &subme, &by))
1882 macro_error (subme.stack, NULL, _("!BY value cannot be zero."));
1887 const struct macro_token *do_end = find_doend (subme.stack, p, end);
1890 if ((by > 0 && first <= last) || (by < 0 && first >= last))
1893 for (double index = first;
1894 by > 0 ? (index <= last) : (index >= last) && !break_;
1899 macro_error (subme.stack, NULL,
1900 _("Numerical !DO loop exceeded "
1901 "maximum number of iterations %d. "
1902 "(Use SET MITERATE to change the limit.)"),
1907 char index_s[DBL_BUFSIZE_BOUND];
1908 c_dtoastr (index_s, sizeof index_s, 0, 0, index);
1909 stringi_map_replace_nocopy (me->vars, ss_xstrdup (var_name),
1912 macro_expand (p, do_end - p, &subme, exp);
1916 return do_end - tokens + 1;
1920 macro_error (me->stack, p < end ? p : NULL,
1921 _("Expected `=' or !IN in !DO loop."));
1927 macro_expand_arg__ (const struct macro_expander *me, size_t idx,
1928 struct macro_tokens *exp)
1930 const struct macro_param *param = &me->macro->params[idx];
1931 const struct macro_tokens *arg = me->args[idx];
1933 if (*me->expand && param->expand_arg)
1935 struct stringi_map vars = STRINGI_MAP_INITIALIZER (vars);
1936 struct macro_expansion_stack stack = {
1937 .name = param->name,
1940 struct macro_expander subme = {
1941 .macros = me->macros,
1944 .segmenter_mode = me->segmenter_mode,
1945 .expand = me->expand,
1948 .nesting_countdown = me->nesting_countdown,
1951 macro_expand (arg->mts, arg->n, &subme, exp);
1952 stringi_map_destroy (&vars);
1955 for (size_t i = 0; i < arg->n; i++)
1956 macro_tokens_add (exp, &arg->mts[i]);
1960 macro_expand_arg (const struct token *token, const struct macro_expander *me,
1961 struct macro_tokens *exp)
1963 if (!me || token->type != T_MACRO_ID)
1966 /* Macro arguments. */
1969 const struct macro_param *param = macro_find_parameter_by_name (
1970 me->macro, token->string);
1973 macro_expand_arg__ (me, param - me->macro->params, exp);
1976 else if (ss_equals (token->string, ss_cstr ("!*")))
1978 for (size_t j = 0; j < me->macro->n_params; j++)
1979 macro_expand_arg__ (me, j, exp);
1984 /* Variables set by !DO or !LET. */
1985 const char *var = stringi_map_find__ (me->vars, token->string.string,
1986 token->string.length);
1989 macro_tokens_from_string__ (exp, ss_cstr (var),
1990 me->segmenter_mode, me->stack);
1998 macro_expand__ (const struct macro_token *mts, size_t n,
1999 const struct macro_expander *me,
2000 struct macro_tokens *exp)
2002 const struct token *token = &mts[0].token;
2004 /* Recursive macro calls. */
2007 struct macro_call *submc;
2008 int n_call = macro_call_create__ (me->macros, me->stack, me,
2010 for (size_t j = 1; !n_call; j++)
2012 const struct macro_token endcmd
2013 = { .token = { .type = T_ENDCMD } };
2014 n_call = macro_call_add (submc, j < n ? &mts[j] : &endcmd, NULL);
2018 struct stringi_map vars = STRINGI_MAP_INITIALIZER (vars);
2019 struct macro_expansion_stack stack = {
2020 .name = submc->macro->name,
2021 .location = submc->macro->location,
2024 struct macro_expander subme = {
2025 .macros = submc->macros,
2026 .macro = submc->macro,
2027 .args = submc->args,
2028 .segmenter_mode = me->segmenter_mode,
2029 .expand = me->expand,
2032 .nesting_countdown = me->nesting_countdown - 1,
2035 const struct macro_tokens *body = &submc->macro->body;
2036 macro_expand (body->mts, body->n, &subme, exp);
2037 macro_call_destroy (submc);
2038 stringi_map_destroy (&vars);
2042 macro_call_destroy (submc);
2045 if (token->type != T_MACRO_ID)
2047 macro_tokens_add (exp, &mts[0]);
2051 /* Parameters and macro variables. */
2052 if (macro_expand_arg (token, me, exp))
2055 /* Macro functions. */
2056 struct string function_output = DS_EMPTY_INITIALIZER;
2057 size_t n_function = expand_macro_function (me, mts, n, &function_output);
2060 macro_tokens_from_string__ (exp, function_output.ss,
2061 me->segmenter_mode, me->stack);
2062 ds_destroy (&function_output);
2067 size_t n_if = macro_expand_if (mts, n, me, exp);
2071 size_t n_let = macro_parse_let (mts, n, me);
2075 size_t n_do = macro_expand_do (mts, n, me, exp);
2079 if (lex_id_match_n (token->string, ss_cstr ("!break"), 4))
2084 macro_error (me->stack, &mts[0], _("!BREAK outside !DO."));
2086 else if (lex_id_match_n (token->string, ss_cstr ("!onexpand"), 4))
2088 else if (lex_id_match_n (token->string, ss_cstr ("!offexpand"), 4))
2089 *me->expand = false;
2091 macro_tokens_add (exp, &mts[0]);
2096 macro_expand (const struct macro_token *mts, size_t n,
2097 const struct macro_expander *me,
2098 struct macro_tokens *exp)
2100 if (me->nesting_countdown <= 0)
2102 macro_error (me->stack, NULL, _("Maximum nesting level %d exceeded. "
2103 "(Use SET MNEST to change the limit.)"),
2104 settings_get_mnest ());
2105 for (size_t i = 0; i < n; i++)
2106 macro_tokens_add (exp, &mts[i]);
2110 for (size_t i = 0; i < n; )
2112 if (me->break_ && *me->break_)
2115 size_t consumed = macro_expand__ (&mts[i], n - i, me, exp);
2116 assert (consumed > 0 && i + consumed <= n);
2122 macro_call_expand (struct macro_call *mc, enum segmenter_mode segmenter_mode,
2123 const struct msg_location *call_loc,
2124 struct macro_tokens *exp)
2126 assert (mc->state == MC_FINISHED);
2129 struct stringi_map vars = STRINGI_MAP_INITIALIZER (vars);
2130 struct macro_expansion_stack stack0 = {
2131 .location = call_loc,
2133 struct macro_expansion_stack stack1 = {
2135 .name = mc->macro->name,
2136 .location = mc->macro->location,
2138 struct macro_expander me = {
2139 .macros = mc->macros,
2142 .segmenter_mode = segmenter_mode,
2146 .nesting_countdown = settings_get_mnest (),
2150 const struct macro_tokens *body = &mc->macro->body;
2151 macro_expand (body->mts, body->n, &me, exp);
2153 stringi_map_destroy (&vars);