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/segment.h"
27 #include "language/lexer/scan.h"
28 #include "libpspp/assertion.h"
29 #include "libpspp/i18n.h"
30 #include "libpspp/message.h"
31 #include "libpspp/str.h"
32 #include "libpspp/string-array.h"
35 #define _(msgid) gettext (msgid)
38 macro_token_copy (struct macro_token *dst, const struct macro_token *src)
40 token_copy (&dst->token, &src->token);
41 ss_alloc_substring (&dst->representation, src->representation);
45 macro_token_uninit (struct macro_token *mt)
47 token_uninit (&mt->token);
48 ss_dealloc (&mt->representation);
52 macro_token_to_representation (struct macro_token *mt, struct string *s)
54 ds_put_substring (s, mt->representation);
58 macro_tokens_copy (struct macro_tokens *dst, const struct macro_tokens *src)
60 *dst = (struct macro_tokens) {
61 .mts = xmalloc (src->n * sizeof *dst->mts),
65 for (size_t i = 0; i < src->n; i++)
66 macro_token_copy (&dst->mts[i], &src->mts[i]);
70 macro_tokens_uninit (struct macro_tokens *mts)
72 for (size_t i = 0; i < mts->n; i++)
73 macro_token_uninit (&mts->mts[i]);
78 macro_tokens_add_uninit (struct macro_tokens *mts)
80 if (mts->n >= mts->allocated)
81 mts->mts = x2nrealloc (mts->mts, &mts->allocated, sizeof *mts->mts);
82 return &mts->mts[mts->n++];
86 macro_tokens_add (struct macro_tokens *mts, const struct macro_token *mt)
88 macro_token_copy (macro_tokens_add_uninit (mts), mt);
92 macro_tokens_from_string (struct macro_tokens *mts, const struct substring src,
93 enum segmenter_mode mode)
97 struct segmenter segmenter;
98 struct substring body;
101 struct state state = {
102 .segmenter = SEGMENTER_INIT (mode),
105 struct state saved = state;
107 while (state.body.length > 0)
109 struct macro_token mt = {
110 .token = { .type = T_STOP },
111 .representation = { .string = state.body.string },
113 struct token *token = &mt.token;
115 struct scanner scanner;
116 scanner_init (&scanner, token);
120 enum segment_type type;
121 int seg_len = segmenter_push (&state.segmenter, state.body.string,
122 state.body.length, true, &type);
123 assert (seg_len >= 0);
125 struct substring segment = ss_head (state.body, seg_len);
126 ss_advance (&state.body, seg_len);
128 enum scan_result result = scanner_push (&scanner, type, segment, token);
129 if (result == SCAN_SAVE)
131 else if (result == SCAN_BACK)
136 else if (result == SCAN_DONE)
140 /* We have a token in 'token'. */
141 if (is_scan_type (token->type))
143 if (token->type != SCAN_SKIP)
146 /* XXX report error */
151 mt.representation.length = state.body.string - mt.representation.string;
152 macro_tokens_add (mts, &mt);
154 token_uninit (token);
159 macro_tokens_print (const struct macro_tokens *mts, FILE *stream)
161 for (size_t i = 0; i < mts->n; i++)
162 token_print (&mts->mts[i].token, stream);
167 TC_ENDCMD, /* No space before or after (new-line after). */
168 TC_BINOP, /* Space on both sides. */
169 TC_COMMA, /* Space afterward. */
170 TC_ID, /* Don't need spaces except sequentially. */
171 TC_PUNCT, /* Don't need spaces except sequentially. */
175 needs_space (enum token_class prev, enum token_class next)
177 /* Don't need a space before or after the end of a command.
178 (A new-line is needed afterward as a special case.) */
179 if (prev == TC_ENDCMD || next == TC_ENDCMD)
182 /* Binary operators always have a space on both sides. */
183 if (prev == TC_BINOP || next == TC_BINOP)
186 /* A comma always has a space afterward. */
187 if (prev == TC_COMMA)
190 /* Otherwise, PREV is TC_ID or TC_PUNCT, which only need a space if there are
191 two or them in a row. */
195 static enum token_class
196 classify_token (enum token_type type)
249 macro_tokens_to_representation (struct macro_tokens *mts, struct string *s)
254 macro_token_to_representation (&mts->mts[0], s);
255 for (size_t i = 1; i < mts->n; i++)
257 enum token_type prev = mts->mts[i - 1].token.type;
258 enum token_type next = mts->mts[i].token.type;
260 if (prev == T_ENDCMD)
261 ds_put_byte (s, '\n');
264 enum token_class pc = classify_token (prev);
265 enum token_class nc = classify_token (next);
266 if (needs_space (pc, nc))
267 ds_put_byte (s, ' ');
270 macro_token_to_representation (&mts->mts[i], s);
275 macro_destroy (struct macro *m)
281 for (size_t i = 0; i < m->n_params; i++)
283 struct macro_param *p = &m->params[i];
286 macro_tokens_uninit (&p->def);
294 token_uninit (&p->charend);
298 token_uninit (&p->enclose[0]);
299 token_uninit (&p->enclose[1]);
307 macro_tokens_uninit (&m->body);
312 macro_set_create (void)
314 struct macro_set *set = xmalloc (sizeof *set);
315 *set = (struct macro_set) {
316 .macros = HMAP_INITIALIZER (set->macros),
322 macro_set_destroy (struct macro_set *set)
327 struct macro *macro, *next;
328 HMAP_FOR_EACH_SAFE (macro, next, struct macro, hmap_node, &set->macros)
330 hmap_delete (&set->macros, ¯o->hmap_node);
331 macro_destroy (macro);
333 hmap_destroy (&set->macros);
338 hash_macro_name (const char *name)
340 return utf8_hash_case_string (name, 0);
343 static struct macro *
344 macro_set_find__ (struct macro_set *set, const char *name)
347 HMAP_FOR_EACH_WITH_HASH (macro, struct macro, hmap_node,
348 hash_macro_name (name), &set->macros)
349 if (!utf8_strcasecmp (macro->name, name))
356 macro_set_find (const struct macro_set *set, const char *name)
358 return macro_set_find__ (CONST_CAST (struct macro_set *, set), name);
361 /* Adds M to SET. M replaces any existing macro with the same name. Takes
364 macro_set_add (struct macro_set *set, struct macro *m)
366 struct macro *victim = macro_set_find__ (set, m->name);
369 hmap_delete (&set->macros, &victim->hmap_node);
370 macro_destroy (victim);
373 hmap_insert (&set->macros, &m->hmap_node, hash_macro_name (m->name));
381 /* Accumulating tokens in me->params toward the end of any type of
385 /* Expecting the opening delimiter of an ARG_ENCLOSE argument. */
388 /* Expecting a keyword for a keyword argument. */
391 /* Expecting an equal sign for a keyword argument. */
396 struct macro_expander
398 const struct macro_set *macros;
403 const struct macro *macro;
404 struct macro_tokens **args;
405 const struct macro_param *param;
409 me_finished (struct macro_expander *me)
411 for (size_t i = 0; i < me->macro->n_params; i++)
414 me->args[i] = xmalloc (sizeof *me->args[i]);
415 macro_tokens_copy (me->args[i], &me->macro->params[i].def);
421 me_next_arg (struct macro_expander *me)
425 assert (!me->macro->n_params);
426 return me_finished (me);
428 else if (me->param->positional)
431 if (me->param >= &me->macro->params[me->macro->n_params])
432 return me_finished (me);
435 me->state = (!me->param->positional ? ME_KEYWORD
436 : me->param->arg_type == ARG_ENCLOSE ? ME_ENCLOSE
443 for (size_t i = 0; i < me->macro->n_params; i++)
446 me->state = ME_KEYWORD;
449 return me_finished (me);
454 me_error (struct macro_expander *me)
456 me->state = ME_ERROR;
461 me_add_arg (struct macro_expander *me, const struct macro_token *mt)
463 const struct macro_param *p = me->param;
465 const struct token *token = &mt->token;
466 if ((token->type == T_ENDCMD || token->type == T_STOP)
467 && p->arg_type != ARG_CMDEND)
469 msg (SE, _("Unexpected end of command reading argument %s "
470 "to macro %s."), me->param->name, me->macro->name);
472 return me_error (me);
477 struct macro_tokens **argp = &me->args[p - me->macro->params];
479 *argp = xzalloc (sizeof **argp);
480 struct macro_tokens *arg = *argp;
481 if (p->arg_type == ARG_N_TOKENS)
483 macro_tokens_add (arg, mt);
484 if (arg->n >= p->n_tokens)
485 return me_next_arg (me);
488 else if (p->arg_type == ARG_CMDEND)
490 if (token->type == T_ENDCMD || token->type == T_STOP)
491 return me_next_arg (me);
492 macro_tokens_add (arg, mt);
497 const struct token *end
498 = p->arg_type == ARG_CHAREND ? &p->charend : &p->enclose[1];
499 if (token_equal (token, end))
500 return me_next_arg (me);
501 macro_tokens_add (arg, mt);
507 me_expected (struct macro_expander *me, const struct macro_token *actual,
508 const struct token *expected)
510 const struct substring actual_s
511 = (actual->representation.length ? actual->representation
512 : ss_cstr (_("<end of input>")));
513 char *expected_s = token_to_string (expected);
514 msg (SE, _("Found `%.*s' while expecting `%s' reading argument %s "
516 (int) actual_s.length, actual_s.string, expected_s,
517 me->param->name, me->macro->name);
520 return me_error (me);
524 me_enclose (struct macro_expander *me, const struct macro_token *mt)
526 const struct token *token = &mt->token;
529 if (token_equal (&me->param->enclose[0], token))
535 return me_expected (me, mt, &me->param->enclose[0]);
538 static const struct macro_param *
539 macro_find_parameter_by_name (const struct macro *m, struct substring name)
541 if (ss_first (name) == '!')
542 ss_advance (&name, 1);
544 for (size_t i = 0; i < m->n_params; i++)
546 const struct macro_param *p = &m->params[i];
547 struct substring p_name = ss_cstr (p->name + 1);
548 if (!utf8_strncasecmp (p_name.string, p_name.length,
549 name.string, name.length))
556 me_keyword (struct macro_expander *me, const struct macro_token *mt)
558 const struct token *token = &mt->token;
559 if (token->type != T_ID)
560 return me_finished (me);
562 const struct macro_param *p = macro_find_parameter_by_name (me->macro,
566 size_t arg_index = p - me->macro->params;
568 if (me->args[arg_index])
571 _("Argument %s multiply specified in call to macro %s."),
572 p->name, me->macro->name);
573 return me_error (me);
577 me->state = ME_EQUALS;
581 return me_finished (me);
585 me_equals (struct macro_expander *me, const struct macro_token *mt)
587 const struct token *token = &mt->token;
590 if (token->type == T_EQUALS)
596 return me_expected (me, mt, &(struct token) { .type = T_EQUALS });
600 macro_expander_create (const struct macro_set *macros,
601 const struct token *token,
602 struct macro_expander **mep)
605 if (macro_set_is_empty (macros))
607 if (token->type != T_ID && token->type != T_MACRO_ID)
610 const struct macro *macro = macro_set_find (macros, token->string.string);
614 struct macro_expander *me = xmalloc (sizeof *me);
615 *me = (struct macro_expander) {
622 if (!macro->n_params)
626 me->state = (!macro->params[0].positional ? ME_KEYWORD
627 : macro->params[0].arg_type == ARG_ENCLOSE ? ME_ENCLOSE
629 me->args = xcalloc (macro->n_params, sizeof *me->args);
630 me->param = macro->params;
636 macro_expander_destroy (struct macro_expander *me)
641 for (size_t i = 0; i < me->macro->n_params; i++)
644 macro_tokens_uninit (me->args[i]);
651 /* Adds TOKEN to the collection of tokens in ME that potentially need to be
654 Returns -1 if the tokens added do not actually invoke a macro. The caller
655 should consume the first token without expanding it.
657 Returns 0 if the macro expander needs more tokens, for macro arguments or to
658 decide whether this is actually a macro invocation. The caller should call
659 macro_expander_add() again with the next token.
661 Returns a positive number to indicate that the returned number of tokens
662 invoke a macro. The number returned might be less than the number of tokens
663 added because it can take a few tokens of lookahead to determine whether the
664 macro invocation is finished. The caller should call
665 macro_expander_get_expansion() to obtain the expansion. */
667 macro_expander_add (struct macro_expander *me, const struct macro_token *mt)
675 return me_add_arg (me, mt);
678 return me_enclose (me, mt);
681 return me_keyword (me, mt);
684 return me_equals (me, mt);
691 /* Each argument to a macro function is one of:
693 - A quoted string or other single literal token.
695 - An argument to the macro being expanded, e.g. !1 or a named argument.
699 - A function invocation.
701 Each function invocation yields a character sequence to be turned into a
702 sequence of tokens. The case where that character sequence is a single
703 quoted string is an important special case.
705 struct parse_macro_function_ctx
707 struct macro_token *input;
709 int nesting_countdown;
710 const struct macro_set *macros;
711 const struct macro_expander *me;
716 macro_expand (const struct macro_tokens *,
717 int nesting_countdown, const struct macro_set *,
718 const struct macro_expander *, bool *expand, struct macro_tokens *exp);
721 expand_macro_function (struct parse_macro_function_ctx *ctx,
722 struct string *output, size_t *input_consumed);
724 /* Returns true if the pair of tokens starting at offset OFS within MTS are !*,
727 is_bang_star (const struct macro_token *mts, size_t n, size_t ofs)
730 && mts[ofs].token.type == T_MACRO_ID
731 && ss_equals (mts[ofs].token.string, ss_cstr ("!"))
732 && mts[ofs + 1].token.type == T_ASTERISK);
736 parse_function_arg (struct parse_macro_function_ctx *ctx,
737 size_t i, struct string *farg)
739 struct macro_token *tokens = ctx->input;
740 const struct token *token = &tokens[i].token;
741 if (token->type == T_MACRO_ID)
743 const struct macro_param *param = macro_find_parameter_by_name (
744 ctx->me->macro, token->string);
747 size_t param_idx = param - ctx->me->macro->params;
748 const struct macro_tokens *marg = ctx->me->args[param_idx];
749 for (size_t i = 0; i < marg->n; i++)
752 ds_put_byte (farg, ' ');
753 ds_put_substring (farg, marg->mts[i].representation);
758 if (is_bang_star (ctx->input, ctx->n_input, i))
760 for (size_t i = 0; i < ctx->me->macro->n_params; i++)
762 if (!ctx->me->macro->params[i].positional)
765 const struct macro_tokens *marg = ctx->me->args[i];
766 for (size_t j = 0; j < marg->n; j++)
769 ds_put_byte (farg, ' ');
770 ds_put_substring (farg, marg->mts[j].representation);
776 struct parse_macro_function_ctx subctx = {
777 .input = &ctx->input[i],
778 .n_input = ctx->n_input - i,
779 .nesting_countdown = ctx->nesting_countdown,
780 .macros = ctx->macros,
782 .expand = ctx->expand,
784 size_t subinput_consumed;
785 if (expand_macro_function (&subctx, farg, &subinput_consumed))
786 return subinput_consumed;
789 ds_put_substring (farg, tokens[i].representation);
794 parse_macro_function (struct parse_macro_function_ctx *ctx,
795 struct string_array *args,
796 struct substring function,
797 int min_args, int max_args,
798 size_t *input_consumed)
800 struct macro_token *tokens = ctx->input;
801 size_t n_tokens = ctx->n_input;
804 || tokens[0].token.type != T_MACRO_ID
805 || !ss_equals_case (tokens[0].token.string, function))
808 if (n_tokens < 2 || tokens[1].token.type != T_LPAREN)
810 printf ("`(' expected following %s'\n", function.string);
814 string_array_init (args);
816 for (size_t i = 2;; )
820 if (tokens[i].token.type == T_RPAREN)
822 *input_consumed = i + 1;
823 if (args->n < min_args || args->n > max_args)
825 printf ("Wrong number of arguments to %s.\n", function.string);
831 struct string s = DS_EMPTY_INITIALIZER;
832 i += parse_function_arg (ctx, i, &s);
838 string_array_append_nocopy (args, ds_steal_cstr (&s));
840 if (tokens[i].token.type == T_COMMA)
842 else if (tokens[i].token.type != T_RPAREN)
844 printf ("Expecting `,' or `)' in %s invocation.", function.string);
850 printf ("Missing closing parenthesis in arguments to %s.\n",
854 string_array_destroy (args);
859 unquote_string (const char *s, struct string *content)
861 struct string_lexer slex;
862 string_lexer_init (&slex, s, strlen (s), SEG_MODE_INTERACTIVE /* XXX */);
865 if (!string_lexer_next (&slex, &token1))
868 if (token1.type != T_STRING)
870 token_uninit (&token1);
875 if (string_lexer_next (&slex, &token2))
877 token_uninit (&token1);
878 token_uninit (&token2);
882 ds_put_substring (content, token1.string);
883 token_uninit (&token1);
888 unquote_string_in_place (const char *s, struct string *tmp)
891 return unquote_string (s, tmp) ? ds_cstr (tmp) : s;
895 parse_integer (const char *s, int *np)
900 long int n = strtol (s, &tail, 10);
901 *np = n < INT_MIN ? INT_MIN : n > INT_MAX ? INT_MAX : n;
902 tail += strspn (tail, CC_SPACES);
903 return *tail == '\0' && errno != ERANGE && n == *np;
907 expand_macro_function (struct parse_macro_function_ctx *ctx,
908 struct string *output,
909 size_t *input_consumed)
911 struct string_array args;
913 if (parse_macro_function (ctx, &args, ss_cstr ("!length"), 1, 1,
915 ds_put_format (output, "%zu", strlen (args.strings[0]));
916 else if (parse_macro_function (ctx, &args, ss_cstr ("!blanks"), 1, 1,
920 if (!parse_integer (args.strings[0], &n))
922 printf ("argument to !BLANKS must be non-negative integer (not \"%s\")\n", args.strings[0]);
923 string_array_destroy (&args);
927 ds_put_byte_multiple (output, ' ', n);
929 else if (parse_macro_function (ctx, &args, ss_cstr ("!concat"), 1, INT_MAX,
932 for (size_t i = 0; i < args.n; i++)
933 if (!unquote_string (args.strings[i], output))
934 ds_put_cstr (output, args.strings[i]);
936 else if (parse_macro_function (ctx, &args, ss_cstr ("!head"), 1, 1,
940 const char *s = unquote_string_in_place (args.strings[0], &tmp);
942 struct macro_tokens mts = { .n = 0 };
943 macro_tokens_from_string (&mts, ss_cstr (s), SEG_MODE_INTERACTIVE /* XXX */);
945 ds_put_substring (output, mts.mts[0].representation);
946 macro_tokens_uninit (&mts);
949 else if (parse_macro_function (ctx, &args, ss_cstr ("!index"), 2, 2,
952 const char *haystack = args.strings[0];
953 const char *needle = strstr (haystack, args.strings[1]);
954 ds_put_format (output, "%zu", needle ? needle - haystack + 1 : 0);
956 else if (parse_macro_function (ctx, &args, ss_cstr ("!quote"), 1, 1,
959 if (unquote_string (args.strings[0], NULL))
960 ds_put_cstr (output, args.strings[0]);
963 ds_extend (output, strlen (args.strings[0]) + 2);
964 ds_put_byte (output, '\'');
965 for (const char *p = args.strings[0]; *p; p++)
968 ds_put_byte (output, '\'');
969 ds_put_byte (output, *p);
971 ds_put_byte (output, '\'');
974 else if (parse_macro_function (ctx, &args, ss_cstr ("!substr"), 2, 3,
978 if (!parse_integer (args.strings[1], &start) || start < 1)
980 printf ("second argument to !SUBSTR must be positive integer (not \"%s\")\n", args.strings[1]);
981 string_array_destroy (&args);
986 if (args.n > 2 && (!parse_integer (args.strings[2], &count) || count < 0))
988 printf ("third argument to !SUBSTR must be non-negative integer (not \"%s\")\n", args.strings[1]);
989 string_array_destroy (&args);
993 struct substring s = ss_cstr (args.strings[0]);
994 ds_put_substring (output, ss_substr (s, start - 1, count));
996 else if (parse_macro_function (ctx, &args, ss_cstr ("!tail"), 1, 1,
1000 const char *s = unquote_string_in_place (args.strings[0], &tmp);
1002 struct macro_tokens mts = { .n = 0 };
1003 macro_tokens_from_string (&mts, ss_cstr (s), SEG_MODE_INTERACTIVE /* XXX */);
1006 struct macro_tokens tail = { .mts = mts.mts + 1, .n = mts.n - 1 };
1007 macro_tokens_to_representation (&tail, output);
1009 macro_tokens_uninit (&mts);
1012 else if (parse_macro_function (ctx, &args, ss_cstr ("!unquote"), 1, 1,
1015 if (!unquote_string (args.strings[0], output))
1016 ds_put_cstr (output, args.strings[0]);
1018 else if (parse_macro_function (ctx, &args, ss_cstr ("!upcase"), 1, 1,
1022 const char *s = unquote_string_in_place (args.strings[0], &tmp);
1023 char *upper = utf8_to_upper (s);
1024 ds_put_cstr (output, upper);
1028 else if (parse_macro_function (ctx, &args, ss_cstr ("!eval"), 1, 1,
1031 struct macro_tokens mts = { .n = 0 };
1032 macro_tokens_from_string (&mts, ss_cstr (args.strings[0]),
1033 SEG_MODE_INTERACTIVE /* XXX */);
1034 struct macro_tokens exp = { .n = 0 };
1035 macro_expand (&mts, ctx->nesting_countdown - 1, ctx->macros,
1036 ctx->me, ctx->expand, &exp);
1037 macro_tokens_to_representation (&exp, output);
1038 macro_tokens_uninit (&exp);
1039 macro_tokens_uninit (&mts);
1041 else if (ctx->n_input > 0
1042 && ctx->input[0].token.type == T_MACRO_ID
1043 && ss_equals_case (ctx->input[0].token.string, ss_cstr ("!null")))
1045 *input_consumed = 1;
1051 string_array_destroy (&args);
1056 macro_expand (const struct macro_tokens *mts,
1057 int nesting_countdown, const struct macro_set *macros,
1058 const struct macro_expander *me, bool *expand,
1059 struct macro_tokens *exp)
1061 if (nesting_countdown <= 0)
1063 printf ("maximum nesting level exceeded\n");
1064 for (size_t i = 0; i < mts->n; i++)
1065 macro_tokens_add (exp, &mts->mts[i]);
1069 for (size_t i = 0; i < mts->n; i++)
1071 const struct macro_token *mt = &mts->mts[i];
1072 const struct token *token = &mt->token;
1073 if (token->type == T_MACRO_ID && me)
1075 const struct macro_param *param = macro_find_parameter_by_name (
1076 me->macro, token->string);
1079 const struct macro_tokens *arg = me->args[param - me->macro->params];
1080 //macro_tokens_print (arg, stdout);
1081 if (*expand && param->expand_arg)
1082 macro_expand (arg, nesting_countdown, macros, NULL, expand, exp);
1084 for (size_t i = 0; i < arg->n; i++)
1085 macro_tokens_add (exp, &arg->mts[i]);
1089 if (is_bang_star (mts->mts, mts->n, i))
1091 for (size_t j = 0; j < me->macro->n_params; j++)
1093 const struct macro_param *param = &me->macro->params[j];
1094 if (!param->positional)
1097 const struct macro_tokens *arg = me->args[j];
1098 if (*expand && param->expand_arg)
1099 macro_expand (arg, nesting_countdown, macros, NULL, expand, exp);
1101 for (size_t k = 0; k < arg->n; k++)
1102 macro_tokens_add (exp, &arg->mts[k]);
1111 struct macro_expander *subme;
1112 int retval = macro_expander_create (macros, token, &subme);
1113 for (size_t j = 1; !retval; j++)
1115 const struct macro_token endcmd = { .token = { .type = T_ENDCMD } };
1116 retval = macro_expander_add (
1117 subme, i + j < mts->n ? &mts->mts[i + j] : &endcmd);
1122 macro_expand (&subme->macro->body, nesting_countdown - 1, macros,
1123 subme, expand, exp);
1124 macro_expander_destroy (subme);
1128 macro_expander_destroy (subme);
1131 if (token->type != T_MACRO_ID)
1133 macro_tokens_add (exp, mt);
1137 /* Maybe each arg should just be a string, either a quoted string or a
1138 non-quoted string containing tokens. */
1139 struct parse_macro_function_ctx ctx = {
1140 .input = &mts->mts[i],
1141 .n_input = mts->n - i,
1142 .nesting_countdown = nesting_countdown,
1147 struct string function_output = DS_EMPTY_INITIALIZER;
1148 size_t function_consumed;
1149 if (expand_macro_function (&ctx, &function_output, &function_consumed))
1151 i += function_consumed - 1;
1153 macro_tokens_from_string (exp, function_output.ss,
1154 SEG_MODE_INTERACTIVE /* XXX */);
1155 ds_destroy (&function_output);
1160 if (ss_equals_case (token->string, ss_cstr ("!onexpand")))
1162 else if (ss_equals_case (token->string, ss_cstr ("!offexpand")))
1165 macro_tokens_add (exp, mt);
1170 macro_expander_get_expansion (struct macro_expander *me, struct macro_tokens *exp)
1173 for (size_t i = 0; i < me->macro->n_params; i++)
1175 printf ("%s:\n", me->macro->params[i].name);
1176 macro_tokens_print (me->args[i], stdout);
1181 macro_expand (&me->macro->body, settings_get_mnest (),
1182 me->macros, me, &expand, exp);
1185 printf ("expansion:\n");
1186 macro_tokens_print (exp, stdout);