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/string-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. */
47 struct macro_expansion_stack
49 /* Points to an outer stack entry, or NULL if this is the outermost. */
50 const struct macro_expansion_stack *next;
52 /* A macro name or !IF, !DO, etc. */
55 /* Location of the macro definition, if available. */
56 const char *file_name;
61 /* Reports an error during macro expansion. STACK is the stack for reporting
62 the location of the error, MT is the optional token at which the error was
63 detected, and FORMAT along with the varargs is the message to report. */
64 static void PRINTF_FORMAT (3, 4)
65 macro_error (const struct macro_expansion_stack *stack,
66 const struct macro_token *mt,
67 const char *format, ...)
69 struct msg_stack **ms = NULL;
70 size_t allocated_ms = 0;
73 for (const struct macro_expansion_stack *p = stack; p; p = p->next)
75 if (n_ms >= allocated_ms)
76 ms = x2nrealloc (ms, &allocated_ms, sizeof *ms);
78 /* TRANSLATORS: These strings are used for explaining the context of an
79 error. The "While expanding" message appears first, followed by zero
80 or more of the "inside expansion" messages. `innermost',
81 `next_inner`, etc., are names of macros, and `foobar' is a piece of
84 foo.sps:12: At `foobar' in the expansion of 'innermost',
85 foo.sps:23: inside the expansion of 'next_inner',
86 foo.sps:34: inside the expansion of 'next_inner2',
87 foo.sps:45: inside the expansion of 'outermost',
88 foo.sps:76: This is the actual error message. */
92 if (mt && mt->representation.length)
95 str_ellipsize (mt->representation, syntax, sizeof syntax);
96 description = xasprintf (_("At `%s' in the expansion of `%s',"),
100 description = xasprintf (_("In the expansion of `%s',"), p->name);
103 description = xasprintf (_("inside the expansion of `%s',"), p->name);
105 ms[n_ms] = xmalloc (sizeof *ms[n_ms]);
106 *ms[n_ms] = (struct msg_stack) {
108 .file_name = xstrdup_if_nonnull (p->file_name),
109 .first_line = p->first_line,
110 .last_line = p->last_line,
112 .description = description,
118 va_start (args, format);
119 char *s = xvasprintf (format, args);
122 struct msg *m = xmalloc (sizeof *m);
124 .category = MSG_C_SYNTAX,
125 .severity = MSG_S_ERROR,
134 macro_token_copy (struct macro_token *dst, const struct macro_token *src)
136 token_copy (&dst->token, &src->token);
137 ss_alloc_substring (&dst->representation, src->representation);
141 macro_token_uninit (struct macro_token *mt)
143 token_uninit (&mt->token);
144 ss_dealloc (&mt->representation);
148 macro_token_to_representation (struct macro_token *mt, struct string *s)
150 ds_put_substring (s, mt->representation);
153 is_macro_keyword (struct substring s)
155 static struct stringi_set keywords = STRINGI_SET_INITIALIZER (keywords);
156 if (stringi_set_is_empty (&keywords))
158 static const char *kws[] = {
179 for (size_t i = 0; i < sizeof kws / sizeof *kws; i++)
180 stringi_set_insert (&keywords, kws[i]);
183 ss_ltrim (&s, ss_cstr ("!"));
184 return stringi_set_contains_len (&keywords, s.string, s.length);
188 macro_tokens_copy (struct macro_tokens *dst, const struct macro_tokens *src)
190 *dst = (struct macro_tokens) {
191 .mts = xmalloc (src->n * sizeof *dst->mts),
195 for (size_t i = 0; i < src->n; i++)
196 macro_token_copy (&dst->mts[i], &src->mts[i]);
200 macro_tokens_uninit (struct macro_tokens *mts)
202 for (size_t i = 0; i < mts->n; i++)
203 macro_token_uninit (&mts->mts[i]);
208 macro_tokens_add_uninit (struct macro_tokens *mts)
210 if (mts->n >= mts->allocated)
211 mts->mts = x2nrealloc (mts->mts, &mts->allocated, sizeof *mts->mts);
212 return &mts->mts[mts->n++];
216 macro_tokens_add (struct macro_tokens *mts, const struct macro_token *mt)
218 macro_token_copy (macro_tokens_add_uninit (mts), mt);
221 /* Tokenizes SRC according to MODE and appends the tokens to MTS. Uses STACK,
222 if nonull, for error reporting. */
224 macro_tokens_from_string__ (struct macro_tokens *mts, const struct substring src,
225 enum segmenter_mode mode,
226 const struct macro_expansion_stack *stack)
230 struct segmenter segmenter;
231 struct substring body;
234 struct state state = {
235 .segmenter = segmenter_init (mode, true),
238 struct state saved = state;
240 while (state.body.length > 0)
242 struct macro_token mt = {
243 .token = { .type = T_STOP },
244 .representation = { .string = state.body.string },
246 struct token *token = &mt.token;
248 struct scanner scanner;
249 scanner_init (&scanner, token);
253 enum segment_type type;
254 int seg_len = segmenter_push (&state.segmenter, state.body.string,
255 state.body.length, true, &type);
256 assert (seg_len >= 0);
258 struct substring segment = ss_head (state.body, seg_len);
259 ss_advance (&state.body, seg_len);
261 enum scan_result result = scanner_push (&scanner, type, segment, token);
262 if (result == SCAN_SAVE)
264 else if (result == SCAN_BACK)
269 else if (result == SCAN_DONE)
273 /* We have a token in 'token'. */
274 mt.representation.length = state.body.string - mt.representation.string;
275 if (is_scan_type (token->type))
277 if (token->type != SCAN_SKIP)
279 char *s = scan_token_to_error (token);
282 mt.token.type = T_STRING;
283 macro_error (stack, &mt, "%s", s);
291 macro_tokens_add (mts, &mt);
292 token_uninit (token);
296 /* Tokenizes SRC according to MODE and appends the tokens to MTS. */
298 macro_tokens_from_string (struct macro_tokens *mts, const struct substring src,
299 enum segmenter_mode mode)
301 macro_tokens_from_string__ (mts, src, mode, NULL);
305 macro_tokens_print (const struct macro_tokens *mts, FILE *stream)
307 for (size_t i = 0; i < mts->n; i++)
308 token_print (&mts->mts[i].token, stream);
313 TC_ENDCMD, /* No space before or after (new-line after). */
314 TC_BINOP, /* Space on both sides. */
315 TC_COMMA, /* Space afterward. */
316 TC_ID, /* Don't need spaces except sequentially. */
317 TC_PUNCT, /* Don't need spaces except sequentially. */
321 needs_space (enum token_class prev, enum token_class next)
323 /* Don't need a space before or after the end of a command.
324 (A new-line is needed afterward as a special case.) */
325 if (prev == TC_ENDCMD || next == TC_ENDCMD)
328 /* Binary operators always have a space on both sides. */
329 if (prev == TC_BINOP || next == TC_BINOP)
332 /* A comma always has a space afterward. */
333 if (prev == TC_COMMA)
336 /* Otherwise, PREV is TC_ID or TC_PUNCT, which only need a space if there are
337 two or them in a row. */
341 static enum token_class
342 classify_token (enum token_type type)
394 /* Appends a syntax representation of the tokens in MTS to S. If OFS and LEN
395 are nonnull, sets OFS[i] to the offset within S of the start of token 'i' in
396 MTS and LEN[i] to its length. OFS[i] + LEN[i] is not necessarily OFS[i + 1]
397 because some tokens are separated by white space. */
399 macro_tokens_to_representation (struct macro_tokens *mts, struct string *s,
400 size_t *ofs, size_t *len)
402 assert ((ofs != NULL) == (len != NULL));
407 for (size_t i = 0; i < mts->n; i++)
411 enum token_type prev = mts->mts[i - 1].token.type;
412 enum token_type next = mts->mts[i].token.type;
414 if (prev == T_ENDCMD)
415 ds_put_byte (s, '\n');
418 enum token_class pc = classify_token (prev);
419 enum token_class nc = classify_token (next);
420 if (needs_space (pc, nc))
421 ds_put_byte (s, ' ');
426 ofs[i] = s->ss.length;
427 macro_token_to_representation (&mts->mts[i], s);
429 len[i] = s->ss.length - ofs[i];
434 macro_destroy (struct macro *m)
441 for (size_t i = 0; i < m->n_params; i++)
443 struct macro_param *p = &m->params[i];
446 macro_tokens_uninit (&p->def);
454 token_uninit (&p->charend);
458 token_uninit (&p->enclose[0]);
459 token_uninit (&p->enclose[1]);
467 macro_tokens_uninit (&m->body);
472 macro_set_create (void)
474 struct macro_set *set = xmalloc (sizeof *set);
475 *set = (struct macro_set) {
476 .macros = HMAP_INITIALIZER (set->macros),
482 macro_set_destroy (struct macro_set *set)
487 struct macro *macro, *next;
488 HMAP_FOR_EACH_SAFE (macro, next, struct macro, hmap_node, &set->macros)
490 hmap_delete (&set->macros, ¯o->hmap_node);
491 macro_destroy (macro);
493 hmap_destroy (&set->macros);
498 hash_macro_name (const char *name)
500 return utf8_hash_case_string (name, 0);
503 static struct macro *
504 macro_set_find__ (struct macro_set *set, const char *name)
506 if (macro_set_is_empty (set))
510 HMAP_FOR_EACH_WITH_HASH (macro, struct macro, hmap_node,
511 hash_macro_name (name), &set->macros)
512 if (!utf8_strcasecmp (macro->name, name))
519 macro_set_find (const struct macro_set *set, const char *name)
521 return macro_set_find__ (CONST_CAST (struct macro_set *, set), name);
524 /* Adds M to SET. M replaces any existing macro with the same name. Takes
527 macro_set_add (struct macro_set *set, struct macro *m)
529 struct macro *victim = macro_set_find__ (set, m->name);
532 hmap_delete (&set->macros, &victim->hmap_node);
533 macro_destroy (victim);
536 hmap_insert (&set->macros, &m->hmap_node, hash_macro_name (m->name));
539 /* Macro call parsing.. */
546 /* Accumulating tokens in mc->params toward the end of any type of
550 /* Expecting the opening delimiter of an ARG_ENCLOSE argument. */
553 /* Expecting a keyword for a keyword argument. */
556 /* Expecting an equal sign for a keyword argument. */
559 /* Macro fully parsed and ready for expansion. */
563 /* Parsing macro calls. This is a FSM driven by macro_call_create() and
564 macro_call_add() to identify the macro being called and obtain its
565 arguments. 'state' identifies the FSM state. */
568 const struct macro_set *macros;
569 const struct macro *macro;
570 struct macro_tokens **args;
574 const struct macro_param *param; /* Parameter currently being parsed. */
577 /* Completes macro expansion by initializing arguments that weren't supplied to
580 mc_finished (struct macro_call *mc)
582 mc->state = MC_FINISHED;
583 for (size_t i = 0; i < mc->macro->n_params; i++)
585 mc->args[i] = &mc->macro->params[i].def;
590 mc_next_arg (struct macro_call *mc)
594 assert (!mc->macro->n_params);
595 return mc_finished (mc);
597 else if (mc->param->positional)
600 if (mc->param >= &mc->macro->params[mc->macro->n_params])
601 return mc_finished (mc);
604 mc->state = (!mc->param->positional ? MC_KEYWORD
605 : mc->param->arg_type == ARG_ENCLOSE ? MC_ENCLOSE
612 for (size_t i = 0; i < mc->macro->n_params; i++)
615 mc->state = MC_KEYWORD;
618 return mc_finished (mc);
623 mc_error (struct macro_call *mc)
625 mc->state = MC_ERROR;
630 mc_add_arg (struct macro_call *mc, const struct macro_token *mt)
632 const struct macro_param *p = mc->param;
634 const struct token *token = &mt->token;
635 if ((token->type == T_ENDCMD || token->type == T_STOP)
636 && p->arg_type != ARG_CMDEND)
638 msg (SE, _("Unexpected end of command reading argument %s "
639 "to macro %s."), mc->param->name, mc->macro->name);
641 return mc_error (mc);
646 struct macro_tokens **argp = &mc->args[p - mc->macro->params];
648 *argp = xzalloc (sizeof **argp);
649 struct macro_tokens *arg = *argp;
650 if (p->arg_type == ARG_N_TOKENS)
652 macro_tokens_add (arg, mt);
653 if (arg->n >= p->n_tokens)
654 return mc_next_arg (mc);
657 else if (p->arg_type == ARG_CMDEND)
659 if (token->type == T_ENDCMD || token->type == T_STOP)
660 return mc_next_arg (mc);
661 macro_tokens_add (arg, mt);
666 const struct token *end
667 = p->arg_type == ARG_CHAREND ? &p->charend : &p->enclose[1];
668 if (token_equal (token, end))
669 return mc_next_arg (mc);
670 macro_tokens_add (arg, mt);
676 mc_expected (struct macro_call *mc, const struct macro_token *actual,
677 const struct token *expected)
679 const struct substring actual_s
680 = (actual->representation.length ? actual->representation
681 : ss_cstr (_("<end of input>")));
682 char *expected_s = token_to_string (expected);
683 msg (SE, _("Found `%.*s' while expecting `%s' reading argument %s "
685 (int) actual_s.length, actual_s.string, expected_s,
686 mc->param->name, mc->macro->name);
689 return mc_error (mc);
693 mc_enclose (struct macro_call *mc, const struct macro_token *mt)
695 const struct token *token = &mt->token;
698 if (token_equal (&mc->param->enclose[0], token))
704 return mc_expected (mc, mt, &mc->param->enclose[0]);
707 static const struct macro_param *
708 macro_find_parameter_by_name (const struct macro *m, struct substring name)
710 ss_ltrim (&name, ss_cstr ("!"));
712 for (size_t i = 0; i < m->n_params; i++)
714 const struct macro_param *p = &m->params[i];
715 struct substring p_name = ss_cstr (p->name + 1);
716 if (!utf8_strncasecmp (p_name.string, p_name.length,
717 name.string, name.length))
724 mc_keyword (struct macro_call *mc, const struct macro_token *mt)
726 const struct token *token = &mt->token;
727 if (token->type != T_ID)
728 return mc_finished (mc);
730 const struct macro_param *p = macro_find_parameter_by_name (mc->macro,
734 size_t arg_index = p - mc->macro->params;
736 if (mc->args[arg_index])
739 _("Argument %s multiply specified in call to macro %s."),
740 p->name, mc->macro->name);
741 return mc_error (mc);
745 mc->state = MC_EQUALS;
749 return mc_finished (mc);
753 mc_equals (struct macro_call *mc, const struct macro_token *mt)
755 const struct token *token = &mt->token;
758 if (token->type == T_EQUALS)
764 return mc_expected (mc, mt, &(struct token) { .type = T_EQUALS });
767 /* If TOKEN is the first token of a call to a macro in MACROS, create a new
768 macro expander, initializes *MCP to it. Returns 0 if more tokens are needed
769 and should be added via macro_call_add() or 1 if the caller should next call
770 macro_call_get_expansion().
772 If TOKEN is not the first token of a macro call, returns -1 and sets *MCP to
775 macro_call_create (const struct macro_set *macros,
776 const struct token *token,
777 struct macro_call **mcp)
779 const struct macro *macro = (token->type == T_ID || token->type == T_MACRO_ID
780 ? macro_set_find (macros, token->string.string)
788 struct macro_call *mc = xmalloc (sizeof *mc);
789 *mc = (struct macro_call) {
793 .state = (!macro->n_params ? MC_FINISHED
794 : !macro->params[0].positional ? MC_KEYWORD
795 : macro->params[0].arg_type == ARG_ENCLOSE ? MC_ENCLOSE
797 .args = macro->n_params ? xcalloc (macro->n_params, sizeof *mc->args) : NULL,
798 .param = macro->params,
802 return mc->state == MC_FINISHED ? 1 : 0;
806 macro_call_destroy (struct macro_call *mc)
811 for (size_t i = 0; i < mc->macro->n_params; i++)
813 struct macro_tokens *a = mc->args[i];
814 if (a && a != &mc->macro->params[i].def)
816 macro_tokens_uninit (a);
824 /* Adds TOKEN to the collection of tokens in MC that potentially need to be
827 Returns -1 if the tokens added do not actually invoke a macro. The caller
828 should consume the first token without expanding it. (Later tokens might
829 invoke a macro so it's best to feed the second token into a new expander.)
831 Returns 0 if the macro expander needs more tokens, for macro arguments or to
832 decide whether this is actually a macro invocation. The caller should call
833 macro_call_add() again with the next token.
835 Returns a positive number to indicate that the returned number of tokens
836 invoke a macro. The number returned might be less than the number of tokens
837 added because it can take a few tokens of lookahead to determine whether the
838 macro invocation is finished. The caller should call
839 macro_call_get_expansion() to obtain the expansion. */
841 macro_call_add (struct macro_call *mc, const struct macro_token *mt)
849 return mc_add_arg (mc, mt);
852 return mc_enclose (mc, mt);
855 return mc_keyword (mc, mt);
858 return mc_equals (mc, mt);
865 /* Macro expansion. */
867 struct macro_expander
869 const struct macro_set *macros;
870 const struct macro *macro;
871 struct macro_tokens **args;
872 enum segmenter_mode segmenter_mode;
875 /* Each argument to a macro function is one of:
877 - A quoted string or other single literal token.
879 - An argument to the macro being expanded, e.g. !1 or a named argument.
883 - A function invocation.
885 Each function invocation yields a character sequence to be turned into a
886 sequence of tokens. The case where that character sequence is a single
887 quoted string is an important special case.
889 struct parse_macro_function_ctx
891 const struct macro_token *input;
893 int nesting_countdown;
894 const struct macro_set *macros;
895 const struct macro_expander *me;
896 const struct macro_expansion_stack *stack;
897 struct string_map *vars;
902 macro_expand (const struct macro_tokens *, int nesting_countdown,
903 const struct macro_set *,
904 const struct macro_expander *, struct string_map *vars,
905 const struct macro_expansion_stack *stack,
906 bool *expand, bool *break_,
907 struct macro_tokens *exp);
910 expand_macro_function (struct parse_macro_function_ctx *ctx,
911 struct string *output, size_t *input_consumed);
913 /* Returns true if the pair of tokens starting at offset OFS within MTS are !*,
916 is_bang_star (const struct macro_token *mts, size_t n, size_t ofs)
919 && mts[ofs].token.type == T_MACRO_ID
920 && ss_equals (mts[ofs].token.string, ss_cstr ("!"))
921 && mts[ofs + 1].token.type == T_ASTERISK);
925 parse_function_arg (struct parse_macro_function_ctx *ctx,
926 size_t i, struct string *farg)
928 const struct macro_token *tokens = ctx->input;
929 const struct token *token = &tokens[i].token;
930 if (token->type == T_MACRO_ID && ctx->me->macro)
932 const struct macro_param *param = macro_find_parameter_by_name (
933 ctx->me->macro, token->string);
936 size_t param_idx = param - ctx->me->macro->params;
937 const struct macro_tokens *marg = ctx->me->args[param_idx];
938 for (size_t i = 0; i < marg->n; i++)
941 ds_put_byte (farg, ' ');
942 ds_put_substring (farg, marg->mts[i].representation);
947 if (is_bang_star (ctx->input, ctx->n_input, i))
949 for (size_t i = 0; i < ctx->me->macro->n_params; i++)
951 if (!ctx->me->macro->params[i].positional)
954 const struct macro_tokens *marg = ctx->me->args[i];
955 for (size_t j = 0; j < marg->n; j++)
958 ds_put_byte (farg, ' ');
959 ds_put_substring (farg, marg->mts[j].representation);
967 const char *value = string_map_find__ (ctx->vars,
968 token->string.string,
969 token->string.length);
972 ds_put_cstr (farg, value);
977 struct parse_macro_function_ctx subctx = {
978 .input = &ctx->input[i],
979 .n_input = ctx->n_input - i,
980 .nesting_countdown = ctx->nesting_countdown,
981 .macros = ctx->macros,
985 .expand = ctx->expand,
987 size_t subinput_consumed;
988 if (expand_macro_function (&subctx, farg, &subinput_consumed))
989 return subinput_consumed;
992 ds_put_substring (farg, tokens[i].representation);
997 parse_macro_function (struct parse_macro_function_ctx *ctx,
998 struct string_array *args,
999 struct substring function,
1000 int min_args, int max_args,
1001 size_t *input_consumed)
1003 const struct macro_token *tokens = ctx->input;
1004 size_t n_tokens = ctx->n_input;
1007 || tokens[0].token.type != T_MACRO_ID
1008 || !ss_equals_case (tokens[0].token.string, function)) /* XXX abbrevs allowed */
1011 if (n_tokens < 2 || tokens[1].token.type != T_LPAREN)
1013 macro_error (ctx->stack, n_tokens > 1 ? &tokens[1] : NULL,
1014 _("`(' expected following %s."), function.string);
1018 string_array_init (args);
1020 for (size_t i = 2;; )
1023 goto unexpected_end;
1024 if (tokens[i].token.type == T_RPAREN)
1026 *input_consumed = i + 1;
1027 if (args->n < min_args || args->n > max_args)
1029 macro_error (ctx->stack, &tokens[i],
1030 _("Wrong number of arguments to macro function %s."),
1037 struct string s = DS_EMPTY_INITIALIZER;
1038 i += parse_function_arg (ctx, i, &s);
1042 goto unexpected_end;
1044 string_array_append_nocopy (args, ds_steal_cstr (&s));
1046 if (tokens[i].token.type == T_COMMA)
1048 else if (tokens[i].token.type != T_RPAREN)
1050 macro_error (ctx->stack, &tokens[i],
1051 _("`,' or `)' expected in call to macro function %s."),
1058 macro_error (ctx->stack, NULL, _("Missing `)' in call to macro function %s."),
1062 string_array_destroy (args);
1067 unquote_string (const char *s, enum segmenter_mode segmenter_mode,
1068 struct string *content)
1070 struct string_lexer slex;
1071 string_lexer_init (&slex, s, strlen (s), segmenter_mode, true);
1073 struct token token1;
1074 if (!string_lexer_next (&slex, &token1))
1077 if (token1.type != T_STRING)
1079 token_uninit (&token1);
1083 struct token token2;
1084 if (string_lexer_next (&slex, &token2))
1086 token_uninit (&token1);
1087 token_uninit (&token2);
1091 ds_put_substring (content, token1.string);
1092 token_uninit (&token1);
1097 unquote_string_in_place (const char *s, enum segmenter_mode segmenter_mode,
1100 ds_init_empty (tmp);
1101 return unquote_string (s, segmenter_mode, tmp) ? ds_cstr (tmp) : s;
1105 parse_integer (const char *s, int *np)
1110 long int n = strtol (s, &tail, 10);
1111 *np = n < INT_MIN ? INT_MIN : n > INT_MAX ? INT_MAX : n;
1112 tail += strspn (tail, CC_SPACES);
1113 return *tail == '\0' && errno != ERANGE && n == *np;
1117 expand_macro_function (struct parse_macro_function_ctx *ctx,
1118 struct string *output,
1119 size_t *input_consumed)
1121 struct string_array args;
1123 if (parse_macro_function (ctx, &args, ss_cstr ("!LENGTH"), 1, 1,
1125 ds_put_format (output, "%zu", strlen (args.strings[0]));
1126 else if (parse_macro_function (ctx, &args, ss_cstr ("!BLANKS"), 1, 1,
1130 if (!parse_integer (args.strings[0], &n))
1132 macro_error (ctx->stack, NULL,
1133 _("Argument to !BLANKS must be non-negative integer "
1134 "(not \"%s\")."), args.strings[0]);
1135 string_array_destroy (&args);
1139 ds_put_byte_multiple (output, ' ', n);
1141 else if (parse_macro_function (ctx, &args, ss_cstr ("!CONCAT"), 1, INT_MAX,
1144 for (size_t i = 0; i < args.n; i++)
1145 if (!unquote_string (args.strings[i], ctx->me->segmenter_mode, output))
1146 ds_put_cstr (output, args.strings[i]);
1148 else if (parse_macro_function (ctx, &args, ss_cstr ("!HEAD"), 1, 1,
1152 const char *s = unquote_string_in_place (args.strings[0],
1153 ctx->me->segmenter_mode, &tmp);
1155 struct macro_tokens mts = { .n = 0 };
1156 macro_tokens_from_string__ (&mts, ss_cstr (s), ctx->me->segmenter_mode,
1159 ds_put_substring (output, mts.mts[0].representation);
1160 macro_tokens_uninit (&mts);
1163 else if (parse_macro_function (ctx, &args, ss_cstr ("!INDEX"), 2, 2,
1166 const char *haystack = args.strings[0];
1167 const char *needle = strstr (haystack, args.strings[1]);
1168 ds_put_format (output, "%zu", needle ? needle - haystack + 1 : 0);
1170 else if (parse_macro_function (ctx, &args, ss_cstr ("!QUOTE"), 1, 1,
1173 if (unquote_string (args.strings[0], ctx->me->segmenter_mode, NULL))
1174 ds_put_cstr (output, args.strings[0]);
1177 ds_extend (output, strlen (args.strings[0]) + 2);
1178 ds_put_byte (output, '\'');
1179 for (const char *p = args.strings[0]; *p; p++)
1182 ds_put_byte (output, '\'');
1183 ds_put_byte (output, *p);
1185 ds_put_byte (output, '\'');
1188 else if (parse_macro_function (ctx, &args, ss_cstr ("!SUBSTR"), 2, 3,
1192 if (!parse_integer (args.strings[1], &start) || start < 1)
1194 macro_error (ctx->stack, NULL,
1195 _("Second argument of !SUBSTR must be "
1196 "positive integer (not \"%s\")."),
1198 string_array_destroy (&args);
1202 int count = INT_MAX;
1203 if (args.n > 2 && (!parse_integer (args.strings[2], &count) || count < 0))
1205 macro_error (ctx->stack, NULL,
1206 _("Third argument of !SUBSTR must be "
1207 "non-negative integer (not \"%s\")."),
1209 string_array_destroy (&args);
1213 struct substring s = ss_cstr (args.strings[0]);
1214 ds_put_substring (output, ss_substr (s, start - 1, count));
1216 else if (parse_macro_function (ctx, &args, ss_cstr ("!TAIL"), 1, 1,
1220 const char *s = unquote_string_in_place (args.strings[0],
1221 ctx->me->segmenter_mode, &tmp);
1223 struct macro_tokens mts = { .n = 0 };
1224 macro_tokens_from_string__ (&mts, ss_cstr (s), ctx->me->segmenter_mode,
1228 struct macro_tokens tail = { .mts = mts.mts + 1, .n = mts.n - 1 };
1229 macro_tokens_to_representation (&tail, output, NULL, NULL);
1231 macro_tokens_uninit (&mts);
1234 else if (parse_macro_function (ctx, &args, ss_cstr ("!UNQUOTE"), 1, 1,
1237 if (!unquote_string (args.strings[0], ctx->me->segmenter_mode, output))
1238 ds_put_cstr (output, args.strings[0]);
1240 else if (parse_macro_function (ctx, &args, ss_cstr ("!UPCASE"), 1, 1,
1244 const char *s = unquote_string_in_place (args.strings[0],
1245 ctx->me->segmenter_mode, &tmp);
1246 char *upper = utf8_to_upper (s);
1247 ds_put_cstr (output, upper);
1251 else if (parse_macro_function (ctx, &args, ss_cstr ("!EVAL"), 1, 1,
1254 struct macro_tokens mts = { .n = 0 };
1255 macro_tokens_from_string__ (&mts, ss_cstr (args.strings[0]),
1256 ctx->me->segmenter_mode, ctx->stack);
1257 struct macro_tokens exp = { .n = 0 };
1258 macro_expand (&mts, ctx->nesting_countdown - 1,
1259 ctx->macros, ctx->me, ctx->vars,
1260 &(struct macro_expansion_stack) {
1263 }, ctx->expand, NULL, &exp);
1264 macro_tokens_to_representation (&exp, output, NULL, NULL);
1265 macro_tokens_uninit (&exp);
1266 macro_tokens_uninit (&mts);
1268 else if (ctx->n_input > 0
1269 && ctx->input[0].token.type == T_MACRO_ID
1270 && ss_equals_case (ctx->input[0].token.string, ss_cstr ("!NULL")))
1272 *input_consumed = 1;
1278 string_array_destroy (&args);
1284 int nesting_countdown;
1285 const struct macro_set *macros;
1286 const struct macro_expander *me;
1287 const struct macro_expansion_stack *stack;
1288 struct string_map *vars;
1292 static char *macro_evaluate_or (const struct expr_context *ctx,
1293 const struct macro_token **tokens,
1294 const struct macro_token *end);
1297 macro_evaluate_literal (const struct expr_context *ctx,
1298 const struct macro_token **tokens,
1299 const struct macro_token *end)
1301 const struct macro_token *p = *tokens;
1304 if (p->token.type == T_LPAREN)
1307 char *value = macro_evaluate_or (ctx, &p, end);
1310 if (p >= end || p->token.type != T_RPAREN)
1313 macro_error (ctx->stack, p < end ? p : NULL,
1314 _("Expecting ')' in macro expression."));
1321 else if (p->token.type == T_RPAREN)
1323 macro_error (ctx->stack, p, _("Expecting literal or function invocation "
1324 "in macro expression."));
1328 struct parse_macro_function_ctx fctx = {
1331 .nesting_countdown = ctx->nesting_countdown,
1332 .macros = ctx->macros,
1334 .stack = ctx->stack,
1336 .expand = ctx->expand,
1338 struct string function_output = DS_EMPTY_INITIALIZER;
1339 size_t function_consumed = parse_function_arg (&fctx, 0, &function_output);
1340 struct string unquoted = DS_EMPTY_INITIALIZER;
1341 if (unquote_string (ds_cstr (&function_output), ctx->me->segmenter_mode,
1344 ds_swap (&function_output, &unquoted);
1345 ds_destroy (&unquoted);
1347 *tokens = p + function_consumed;
1348 return ds_steal_cstr (&function_output);
1351 /* Returns true if MT is valid as a macro operator. Only operators written as
1352 symbols (e.g. <>) are usable in macro expressions, not operator written as
1353 letters (e.g. EQ). */
1355 is_macro_operator (const struct macro_token *mt)
1357 return (mt->representation.length > 0
1358 && !c_isalpha (mt->representation.string[0]));
1361 static enum token_type
1362 parse_relational_op (const struct macro_token *mt)
1364 switch (mt->token.type)
1374 return is_macro_operator (mt) ? mt->token.type : T_STOP;
1377 return (ss_equals_case (mt->token.string, ss_cstr ("!EQ")) ? T_EQ
1378 : ss_equals_case (mt->token.string, ss_cstr ("!NE")) ? T_NE
1379 : ss_equals_case (mt->token.string, ss_cstr ("!LT")) ? T_LT
1380 : ss_equals_case (mt->token.string, ss_cstr ("!GT")) ? T_GT
1381 : ss_equals_case (mt->token.string, ss_cstr ("!LE")) ? T_LE
1382 : ss_equals_case (mt->token.string, ss_cstr ("!GE")) ? T_GE
1391 macro_evaluate_relational (const struct expr_context *ctx,
1392 const struct macro_token **tokens,
1393 const struct macro_token *end)
1395 const struct macro_token *p = *tokens;
1396 char *lhs = macro_evaluate_literal (ctx, &p, end);
1400 enum token_type op = p >= end ? T_STOP : parse_relational_op (p);
1408 char *rhs = macro_evaluate_literal (ctx, &p, end);
1415 struct string lhs_tmp, rhs_tmp;
1416 int cmp = strcmp (unquote_string_in_place (lhs, ctx->me->segmenter_mode,
1418 unquote_string_in_place (rhs, ctx->me->segmenter_mode,
1420 ds_destroy (&lhs_tmp);
1421 ds_destroy (&rhs_tmp);
1426 bool b = (op == T_EQUALS || op == T_EQ ? !cmp
1428 : op == T_LT ? cmp < 0
1429 : op == T_GT ? cmp > 0
1430 : op == T_LE ? cmp <= 0
1431 : /* T_GE */ cmp >= 0);
1434 return xstrdup (b ? "1" : "0");
1438 macro_evaluate_not (const struct expr_context *ctx,
1439 const struct macro_token **tokens,
1440 const struct macro_token *end)
1442 const struct macro_token *p = *tokens;
1444 unsigned int negations = 0;
1446 && (ss_equals_case (p->representation, ss_cstr ("!NOT"))
1447 || ss_equals (p->representation, ss_cstr ("~"))))
1453 char *operand = macro_evaluate_relational (ctx, &p, end);
1454 if (!operand || !negations)
1460 bool b = strcmp (operand, "0") ^ (negations & 1);
1463 return xstrdup (b ? "1" : "0");
1467 macro_evaluate_and (const struct expr_context *ctx,
1468 const struct macro_token **tokens,
1469 const struct macro_token *end)
1471 const struct macro_token *p = *tokens;
1472 char *lhs = macro_evaluate_not (ctx, &p, end);
1477 && (ss_equals_case (p->representation, ss_cstr ("!AND"))
1478 || ss_equals (p->representation, ss_cstr ("&"))))
1481 char *rhs = macro_evaluate_not (ctx, &p, end);
1488 bool b = strcmp (lhs, "0") && strcmp (rhs, "0");
1491 lhs = xstrdup (b ? "1" : "0");
1498 macro_evaluate_or (const struct expr_context *ctx,
1499 const struct macro_token **tokens,
1500 const struct macro_token *end)
1502 const struct macro_token *p = *tokens;
1503 char *lhs = macro_evaluate_and (ctx, &p, end);
1508 && (ss_equals_case (p->representation, ss_cstr ("!OR"))
1509 || ss_equals (p->representation, ss_cstr ("|"))))
1512 char *rhs = macro_evaluate_and (ctx, &p, end);
1519 bool b = strcmp (lhs, "0") || strcmp (rhs, "0");
1522 lhs = xstrdup (b ? "1" : "0");
1529 macro_evaluate_expression (const struct macro_token **tokens, size_t n_tokens,
1530 int nesting_countdown,
1531 const struct macro_set *macros,
1532 const struct macro_expander *me,
1533 const struct macro_expansion_stack *stack,
1534 struct string_map *vars, bool *expand)
1536 const struct expr_context ctx = {
1537 .nesting_countdown = nesting_countdown,
1544 return macro_evaluate_or (&ctx, tokens, *tokens + n_tokens);
1548 macro_evaluate_number (const struct macro_token **tokens, size_t n_tokens,
1549 int nesting_countdown,
1550 const struct macro_set *macros,
1551 const struct macro_expander *me,
1552 const struct macro_expansion_stack *stack,
1553 struct string_map *vars,
1554 bool *expand, double *number)
1556 char *s = macro_evaluate_expression (tokens, n_tokens, nesting_countdown,
1557 macros, me, stack, vars, expand);
1561 struct macro_tokens mts = { .n = 0 };
1562 macro_tokens_from_string__ (&mts, ss_cstr (s), me->segmenter_mode, stack);
1563 if (mts.n != 1 || !token_is_number (&mts.mts[0].token))
1565 macro_error (stack, mts.n > 0 ? &mts.mts[0] : NULL,
1566 _("Macro expression must evaluate to "
1567 "a number (not \"%s\")."), s);
1569 macro_tokens_uninit (&mts);
1573 *number = token_number (&mts.mts[0].token);
1575 macro_tokens_uninit (&mts);
1579 static const struct macro_token *
1580 find_ifend_clause (const struct macro_token *p, const struct macro_token *end)
1583 for (; p < end; p++)
1585 if (p->token.type != T_MACRO_ID)
1588 if (ss_equals_case (p->token.string, ss_cstr ("!IF")))
1590 else if (ss_equals_case (p->token.string, ss_cstr ("!IFEND")))
1596 else if (ss_equals_case (p->token.string, ss_cstr ("!ELSE")) && !nesting)
1603 macro_expand_if (const struct macro_token *tokens, size_t n_tokens,
1604 int nesting_countdown, const struct macro_set *macros,
1605 const struct macro_expander *me,
1606 const struct macro_expansion_stack *stack,
1607 struct string_map *vars,
1608 bool *expand, bool *break_, struct macro_tokens *exp)
1610 const struct macro_token *p = tokens;
1611 const struct macro_token *end = tokens + n_tokens;
1613 if (p >= end || !ss_equals_case (p->token.string, ss_cstr ("!IF")))
1617 char *result = macro_evaluate_expression (&p, end - p,
1620 stack, vars, expand);
1623 bool b = strcmp (result, "0");
1627 || p->token.type != T_MACRO_ID
1628 || !ss_equals_case (p->token.string, ss_cstr ("!THEN")))
1630 macro_error (stack, p < end ? p : NULL,
1631 _("!THEN expected in macro !IF construct."));
1635 const struct macro_token *start_then = p + 1;
1636 const struct macro_token *end_then = find_ifend_clause (start_then, end);
1639 macro_error (stack, NULL,
1640 _("!ELSE or !IFEND expected in macro !IF construct."));
1644 const struct macro_token *start_else, *end_if;
1645 if (ss_equals_case (end_then->token.string, ss_cstr ("!ELSE")))
1647 start_else = end_then + 1;
1648 end_if = find_ifend_clause (start_else, end);
1650 || !ss_equals_case (end_if->token.string, ss_cstr ("!IFEND")))
1652 macro_error (stack, end_if ? end_if : NULL,
1653 _("!IFEND expected in macro !IF construct."));
1663 const struct macro_token *start;
1668 n = end_then - start_then;
1670 else if (start_else)
1673 n = end_if - start_else;
1683 struct macro_tokens mts = {
1684 .mts = CONST_CAST (struct macro_token *, start),
1687 macro_expand (&mts, nesting_countdown, macros, me, vars,
1688 &(struct macro_expansion_stack) {
1692 expand, break_, exp);
1694 return (end_if + 1) - tokens;
1698 macro_parse_let (const struct macro_token *tokens, size_t n_tokens,
1699 int nesting_countdown, const struct macro_set *macros,
1700 const struct macro_expander *me,
1701 const struct macro_expansion_stack *stack,
1702 struct string_map *vars, bool *expand)
1704 const struct macro_token *p = tokens;
1705 const struct macro_token *end = tokens + n_tokens;
1707 if (p >= end || !ss_equals_case (p->token.string, ss_cstr ("!LET")))
1711 if (p >= end || p->token.type != T_MACRO_ID)
1713 macro_error (stack, p < end ? p : NULL,
1714 _("Expected macro variable name following !LET."));
1717 const struct substring var_name = p->token.string;
1718 if (is_macro_keyword (var_name)
1719 || (me->macro && macro_find_parameter_by_name (me->macro, var_name)))
1721 macro_error (stack, p < end ? p : NULL,
1722 _("Cannot use argument name or macro keyword "
1723 "\"%.*s\" as !LET variable."),
1724 (int) var_name.length, var_name.string);
1729 if (p >= end || p->token.type != T_EQUALS)
1731 macro_error (stack, p < end ? p : NULL,
1732 _("Expected `=' following !LET."));
1737 char *value = macro_evaluate_expression (&p, end - p, nesting_countdown,
1738 macros, me, stack, vars, expand);
1742 string_map_replace_nocopy (vars, ss_xstrdup (var_name), value);
1746 static const struct macro_token *
1747 find_doend (const struct macro_expansion_stack *stack,
1748 const struct macro_token *p, const struct macro_token *end)
1751 for (; p < end; p++)
1753 if (p->token.type != T_MACRO_ID)
1756 if (ss_equals_case (p->token.string, ss_cstr ("!DO")))
1758 else if (ss_equals_case (p->token.string, ss_cstr ("!DOEND")))
1765 macro_error (stack, NULL, _("Missing !DOEND."));
1770 macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
1771 int nesting_countdown, const struct macro_set *macros,
1772 const struct macro_expander *me,
1773 const struct macro_expansion_stack *stack,
1774 struct string_map *vars,
1775 bool *expand, struct macro_tokens *exp)
1777 const struct macro_token *p = tokens;
1778 const struct macro_token *end = tokens + n_tokens;
1780 if (p >= end || !ss_equals_case (p->token.string, ss_cstr ("!DO")))
1784 if (p >= end || p->token.type != T_MACRO_ID)
1786 macro_error (stack, p < end ? p : NULL,
1787 _("Expected macro variable name following !DO."));
1790 const struct substring var_name = p->token.string;
1791 if (is_macro_keyword (var_name)
1792 || (me->macro && macro_find_parameter_by_name (me->macro, var_name)))
1794 macro_error (stack, p, _("Cannot use argument name or macro "
1795 "keyword as !DO variable."));
1800 struct macro_expansion_stack next_stack = {
1801 .name = "!DO", .next = stack,
1803 int miterate = settings_get_miterate ();
1804 if (p < end && p->token.type == T_MACRO_ID
1805 && ss_equals_case (p->token.string, ss_cstr ("!IN")))
1808 char *list = macro_evaluate_expression (&p, end - p, nesting_countdown,
1809 macros, me, &next_stack, vars,
1814 struct macro_tokens items = { .n = 0 };
1815 macro_tokens_from_string__ (&items, ss_cstr (list), me->segmenter_mode,
1819 const struct macro_token *do_end = find_doend (stack, p, end);
1822 macro_tokens_uninit (&items);
1826 const struct macro_tokens inner = {
1827 .mts = CONST_CAST (struct macro_token *, p),
1830 for (size_t i = 0; i < items.n; i++)
1834 macro_error (stack, NULL,
1835 _("!DO loop over list exceeded "
1836 "maximum number of iterations %d. "
1837 "(Use SET MITERATE to change the limit.)"),
1841 string_map_replace_nocopy (vars, ss_xstrdup (var_name),
1842 ss_xstrdup (items.mts[i].representation));
1844 bool break_ = false;
1845 macro_expand (&inner, nesting_countdown, macros,
1846 me, vars, &next_stack, expand, &break_, 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, nesting_countdown,
1857 macros, me, &next_stack,
1858 vars, expand, &first))
1861 if (p >= end || p->token.type != T_MACRO_ID
1862 || !ss_equals_case (p->token.string, ss_cstr ("!TO")))
1864 macro_error (stack, p < end ? p : NULL,
1865 _("Expected !TO in numerical !DO loop."));
1871 if (!macro_evaluate_number (&p, end - p, nesting_countdown,
1872 macros, me, &next_stack,
1873 vars, expand, &last))
1877 if (p < end && p->token.type == T_MACRO_ID
1878 && ss_equals_case (p->token.string, ss_cstr ("!BY")))
1881 if (!macro_evaluate_number (&p, end - p, nesting_countdown,
1882 macros, me, &next_stack,
1888 macro_error (stack, NULL, _("!BY value cannot be zero."));
1893 const struct macro_token *do_end = find_doend (stack, p, end);
1896 const struct macro_tokens inner = {
1897 .mts = CONST_CAST (struct macro_token *, p),
1901 if ((by > 0 && first <= last) || (by < 0 && first >= last))
1904 for (double index = first;
1905 by > 0 ? (index <= last) : (index >= last);
1910 macro_error (stack, NULL,
1911 _("Numerical !DO loop exceeded "
1912 "maximum number of iterations %d. "
1913 "(Use SET MITERATE to change the limit.)"),
1918 char index_s[DBL_BUFSIZE_BOUND];
1919 c_dtoastr (index_s, sizeof index_s, 0, 0, index);
1920 string_map_replace_nocopy (vars, ss_xstrdup (var_name),
1923 bool break_ = false;
1924 macro_expand (&inner, nesting_countdown,
1925 macros, me, vars, &next_stack, expand, &break_,
1932 return do_end - tokens + 1;
1936 macro_error (stack, p < end ? p : NULL,
1937 _("Expected `=' or !IN in !DO loop."));
1943 macro_expand (const struct macro_tokens *mts, int nesting_countdown,
1944 const struct macro_set *macros,
1945 const struct macro_expander *me, struct string_map *vars,
1946 const struct macro_expansion_stack *stack,
1947 bool *expand, bool *break_, struct macro_tokens *exp)
1949 if (nesting_countdown <= 0)
1951 macro_error (stack, NULL, _("Maximum nesting level %d exceeded. "
1952 "(Use SET MNEST to change the limit.)"),
1953 settings_get_mnest ());
1954 for (size_t i = 0; i < mts->n; i++)
1955 macro_tokens_add (exp, &mts->mts[i]);
1959 struct string_map own_vars = STRING_MAP_INITIALIZER (own_vars);
1963 for (size_t i = 0; i < mts->n && (!break_ || !*break_); i++)
1965 const struct macro_token *mt = &mts->mts[i];
1966 const struct token *token = &mt->token;
1967 if (token->type == T_MACRO_ID && me->macro)
1969 const struct macro_param *param = macro_find_parameter_by_name (
1970 me->macro, token->string);
1973 const struct macro_tokens *arg = me->args[param - me->macro->params];
1974 if (*expand && param->expand_arg)
1976 struct macro_expander subme = {
1977 .macros = me->macros,
1980 .segmenter_mode = me->segmenter_mode,
1982 macro_expand (arg, nesting_countdown,
1983 macros, &subme, NULL,
1984 &(struct macro_expansion_stack) {
1985 .name = param->name,
1987 }, expand, break_, exp);
1990 for (size_t i = 0; i < arg->n; i++)
1991 macro_tokens_add (exp, &arg->mts[i]);
1995 if (is_bang_star (mts->mts, mts->n, i))
1997 for (size_t j = 0; j < me->macro->n_params; j++)
1999 const struct macro_param *param = &me->macro->params[j];
2000 if (!param->positional)
2003 const struct macro_tokens *arg = me->args[j];
2004 if (*expand && param->expand_arg)
2006 struct macro_expander subme = {
2007 .macros = me->macros,
2010 .segmenter_mode = me->segmenter_mode,
2012 macro_expand (arg, nesting_countdown,
2013 macros, &subme, NULL,
2014 &(struct macro_expansion_stack) {
2017 }, expand, break_, exp);
2020 for (size_t k = 0; k < arg->n; k++)
2021 macro_tokens_add (exp, &arg->mts[k]);
2027 size_t n = macro_expand_if (&mts->mts[i], mts->n - i,
2030 vars, expand, break_, exp);
2038 if (token->type == T_MACRO_ID && vars)
2040 const char *value = string_map_find__ (vars, token->string.string,
2041 token->string.length);
2044 macro_tokens_from_string__ (exp, ss_cstr (value),
2045 me->segmenter_mode, stack);
2052 struct macro_call *submc;
2053 int retval = macro_call_create (macros, token, &submc);
2054 for (size_t j = 1; !retval; j++)
2056 const struct macro_token endcmd
2057 = { .token = { .type = T_ENDCMD } };
2058 retval = macro_call_add (
2059 submc, i + j < mts->n ? &mts->mts[i + j] : &endcmd);
2064 struct macro_expander subme = {
2065 .macros = submc->macros,
2066 .macro = submc->macro,
2067 .args = submc->args,
2068 .segmenter_mode = me->segmenter_mode,
2070 macro_expand (&submc->macro->body, nesting_countdown - 1,
2071 macros, &subme, NULL,
2072 &(struct macro_expansion_stack) {
2073 .name = submc->macro->name,
2074 .file_name = submc->macro->file_name,
2075 .first_line = submc->macro->first_line,
2076 .last_line = submc->macro->last_line,
2078 }, expand, break_, exp);
2079 macro_call_destroy (submc);
2083 macro_call_destroy (submc);
2086 if (token->type != T_MACRO_ID)
2088 macro_tokens_add (exp, mt);
2092 if (ss_equals_case (token->string, ss_cstr ("!break")))
2095 macro_error (stack, mt, _("!BREAK outside !DO."));
2103 struct parse_macro_function_ctx ctx = {
2104 .input = &mts->mts[i],
2105 .n_input = mts->n - i,
2106 .nesting_countdown = nesting_countdown,
2113 struct string function_output = DS_EMPTY_INITIALIZER;
2114 size_t function_consumed;
2115 if (expand_macro_function (&ctx, &function_output, &function_consumed))
2117 i += function_consumed - 1;
2119 macro_tokens_from_string__ (exp, function_output.ss,
2120 me->segmenter_mode, stack);
2121 ds_destroy (&function_output);
2126 size_t n = macro_parse_let (&mts->mts[i], mts->n - i,
2128 macros, me, stack, vars, expand);
2135 n = macro_expand_do (&mts->mts[i], mts->n - i,
2136 nesting_countdown, macros, me, stack,
2144 if (ss_equals_case (token->string, ss_cstr ("!onexpand")))
2146 else if (ss_equals_case (token->string, ss_cstr ("!offexpand")))
2149 macro_tokens_add (exp, mt);
2151 if (vars == &own_vars)
2152 string_map_destroy (&own_vars);
2156 macro_call_expand (struct macro_call *mc, enum segmenter_mode segmenter_mode,
2157 struct macro_tokens *exp)
2159 assert (mc->state == MC_FINISHED);
2161 struct macro_expander me = {
2162 .macros = mc->macros,
2165 .segmenter_mode = segmenter_mode,
2169 struct macro_expansion_stack stack = {
2170 .name = mc->macro->name,
2171 .file_name = mc->macro->file_name,
2172 .first_line = mc->macro->first_line,
2173 .last_line = mc->macro->last_line,
2175 macro_expand (&mc->macro->body, settings_get_mnest (),
2176 mc->macros, &me, NULL, &stack, &expand, NULL, exp);