584ee7f2fd3ed29e3d4880761c7176814e55c62c
[pspp] / src / language / lexer / macro.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2021 Free Software Foundation, Inc.
3
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.
8
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.
13
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/>. */
16
17 #include <config.h>
18
19 #include "language/lexer/macro.h"
20
21 #include <limits.h>
22 #include <stdlib.h>
23
24 #include "data/settings.h"
25 #include "language/lexer/segment.h"
26 #include "language/lexer/scan.h"
27 #include "libpspp/assertion.h"
28 #include "libpspp/i18n.h"
29 #include "libpspp/message.h"
30 #include "libpspp/str.h"
31
32 #include "gettext.h"
33 #define _(msgid) gettext (msgid)
34
35 void
36 macro_token_copy (struct macro_token *dst, const struct macro_token *src)
37 {
38   token_copy (&dst->token, &src->token);
39   ss_alloc_substring (&dst->representation, src->representation);
40 }
41
42 void
43 macro_token_uninit (struct macro_token *mt)
44 {
45   token_uninit (&mt->token);
46   ss_dealloc (&mt->representation);
47 }
48
49 void
50 macro_token_to_representation (struct macro_token *mt, struct string *s)
51 {
52   ds_put_substring (s, mt->representation);
53 }
54
55 void
56 macro_tokens_copy (struct macro_tokens *dst, const struct macro_tokens *src)
57 {
58   *dst = (struct macro_tokens) {
59     .mts = xmalloc (src->n * sizeof *dst->mts),
60     .n = src->n,
61     .allocated = src->n,
62   };
63   for (size_t i = 0; i < src->n; i++)
64     macro_token_copy (&dst->mts[i], &src->mts[i]);
65 }
66
67 void
68 macro_tokens_uninit (struct macro_tokens *mts)
69 {
70   for (size_t i = 0; i < mts->n; i++)
71     macro_token_uninit (&mts->mts[i]);
72   free (mts->mts);
73 }
74
75 struct macro_token *
76 macro_tokens_add_uninit (struct macro_tokens *mts)
77 {
78   if (mts->n >= mts->allocated)
79     mts->mts = x2nrealloc (mts->mts, &mts->allocated, sizeof *mts->mts);
80   return &mts->mts[mts->n++];
81 }
82
83 void
84 macro_tokens_add (struct macro_tokens *mts, const struct macro_token *mt)
85 {
86   macro_token_copy (macro_tokens_add_uninit (mts), mt);
87 }
88
89 void
90 macro_tokens_from_string (struct macro_tokens *mts, const struct substring src,
91                           enum segmenter_mode mode)
92 {
93   struct state
94     {
95       struct segmenter segmenter;
96       struct substring body;
97     };
98
99   struct state state = {
100     .segmenter = SEGMENTER_INIT (mode),
101     .body = src,
102   };
103   struct state saved = state;
104
105   while (state.body.length > 0)
106     {
107       struct macro_token mt = {
108         .token = { .type = T_STOP },
109         .representation = { .string = state.body.string },
110       };
111       struct token *token = &mt.token;
112
113       struct scanner scanner;
114       scanner_init (&scanner, token);
115
116       for (;;)
117         {
118           enum segment_type type;
119           int seg_len = segmenter_push (&state.segmenter, state.body.string,
120                                         state.body.length, true, &type);
121           assert (seg_len >= 0);
122
123           struct substring segment = ss_head (state.body, seg_len);
124           ss_advance (&state.body, seg_len);
125
126           enum scan_result result = scanner_push (&scanner, type, segment, token);
127           if (result == SCAN_SAVE)
128             saved = state;
129           else if (result == SCAN_BACK)
130             {
131               state = saved;
132               break;
133             }
134           else if (result == SCAN_DONE)
135             break;
136         }
137
138       /* We have a token in 'token'. */
139       if (is_scan_type (token->type))
140         {
141           if (token->type != SCAN_SKIP)
142             {
143               /* XXX report error */
144             }
145         }
146       else
147         {
148           mt.representation.length = state.body.string - mt.representation.string;
149           macro_tokens_add (mts, &mt);
150         }
151       token_uninit (token);
152     }
153 }
154
155 void
156 macro_tokens_print (const struct macro_tokens *mts, FILE *stream)
157 {
158   for (size_t i = 0; i < mts->n; i++)
159     token_print (&mts->mts[i].token, stream);
160 }
161
162 enum token_class
163   {
164     TC_ENDCMD,                  /* No space before or after (new-line after). */
165     TC_BINOP,                   /* Space on both sides. */
166     TC_COMMA,                   /* Space afterward. */
167     TC_ID,                      /* Don't need spaces except sequentially. */
168     TC_PUNCT,                   /* Don't need spaces except sequentially. */
169   };
170
171 static bool
172 needs_space (enum token_class prev, enum token_class next)
173 {
174   /* Don't need a space before or after the end of a command.
175      (A new-line is needed afterward as a special case.) */
176   if (prev == TC_ENDCMD || next == TC_ENDCMD)
177     return false;
178
179   /* Binary operators always have a space on both sides. */
180   if (prev == TC_BINOP || next == TC_BINOP)
181     return true;
182
183   /* A comma always has a space afterward. */
184   if (prev == TC_COMMA)
185     return true;
186
187   /* Otherwise, PREV is TC_ID or TC_PUNCT, which only need a space if there are
188      two or them in a row. */
189   return prev == next;
190 }
191
192 static enum token_class
193 classify_token (enum token_type type)
194 {
195   switch (type)
196     {
197     case T_ID:
198     case T_MACRO_ID:
199     case T_POS_NUM:
200     case T_NEG_NUM:
201     case T_STRING:
202       return TC_ID;
203
204     case T_STOP:
205       return TC_PUNCT;
206
207     case T_ENDCMD:
208       return TC_ENDCMD;
209
210     case T_LPAREN:
211     case T_RPAREN:
212     case T_LBRACK:
213     case T_RBRACK:
214       return TC_PUNCT;
215
216     case T_PLUS:
217     case T_DASH:
218     case T_ASTERISK:
219     case T_SLASH:
220     case T_EQUALS:
221     case T_AND:
222     case T_OR:
223     case T_NOT:
224     case T_EQ:
225     case T_GE:
226     case T_GT:
227     case T_LE:
228     case T_LT:
229     case T_NE:
230     case T_ALL:
231     case T_BY:
232     case T_TO:
233     case T_WITH:
234     case T_EXP:
235     case T_MACRO_PUNCT:
236       return TC_BINOP;
237
238     case T_COMMA:
239       return TC_COMMA;
240     }
241
242   NOT_REACHED ();
243 }
244
245 void
246 macro_tokens_to_representation (struct macro_tokens *mts, struct string *s)
247 {
248   if (!mts->n)
249     return;
250
251   macro_token_to_representation (&mts->mts[0], s);
252   for (size_t i = 1; i < mts->n; i++)
253     {
254       enum token_type prev = mts->mts[i - 1].token.type;
255       enum token_type next = mts->mts[i].token.type;
256
257       if (prev == T_ENDCMD)
258         ds_put_byte (s, '\n');
259       else
260         {
261           enum token_class pc = classify_token (prev);
262           enum token_class nc = classify_token (next);
263           if (needs_space (pc, nc))
264             ds_put_byte (s, ' ');
265         }
266
267       macro_token_to_representation (&mts->mts[i], s);
268     }
269 }
270
271 void
272 macro_destroy (struct macro *m)
273 {
274   if (!m)
275     return;
276
277   free (m->name);
278   for (size_t i = 0; i < m->n_params; i++)
279     {
280       struct macro_param *p = &m->params[i];
281       free (p->name);
282
283       macro_tokens_uninit (&p->def);
284
285       switch (p->arg_type)
286         {
287         case ARG_N_TOKENS:
288           break;
289
290         case ARG_CHAREND:
291           token_uninit (&p->charend);
292           break;
293
294         case ARG_ENCLOSE:
295           token_uninit (&p->enclose[0]);
296           token_uninit (&p->enclose[1]);
297           break;
298
299         case ARG_CMDEND:
300           break;
301         }
302     }
303   free (m->params);
304   macro_tokens_uninit (&m->body);
305   free (m);
306 }
307 \f
308 struct macro_set *
309 macro_set_create (void)
310 {
311   struct macro_set *set = xmalloc (sizeof *set);
312   *set = (struct macro_set) {
313     .macros = HMAP_INITIALIZER (set->macros),
314   };
315   return set;
316 }
317
318 void
319 macro_set_destroy (struct macro_set *set)
320 {
321   if (!set)
322     return;
323
324   struct macro *macro, *next;
325   HMAP_FOR_EACH_SAFE (macro, next, struct macro, hmap_node, &set->macros)
326     {
327       hmap_delete (&set->macros, &macro->hmap_node);
328       macro_destroy (macro);
329     }
330   hmap_destroy (&set->macros);
331   free (set);
332 }
333
334 static unsigned int
335 hash_macro_name (const char *name)
336 {
337   return utf8_hash_case_string (name, 0);
338 }
339
340 static struct macro *
341 macro_set_find__ (struct macro_set *set, const char *name)
342 {
343   struct macro *macro;
344   HMAP_FOR_EACH_WITH_HASH (macro, struct macro, hmap_node,
345                            hash_macro_name (name), &set->macros)
346     if (!utf8_strcasecmp (macro->name, name))
347       return macro;
348
349   return NULL;
350 }
351
352 const struct macro *
353 macro_set_find (const struct macro_set *set, const char *name)
354 {
355   return macro_set_find__ (CONST_CAST (struct macro_set *, set), name);
356 }
357
358 /* Adds M to SET.  M replaces any existing macro with the same name.  Takes
359    ownership of M. */
360 void
361 macro_set_add (struct macro_set *set, struct macro *m)
362 {
363   struct macro *victim = macro_set_find__ (set, m->name);
364   if (victim)
365     {
366       hmap_delete (&set->macros, &victim->hmap_node);
367       macro_destroy (victim);
368     }
369
370   hmap_insert (&set->macros, &m->hmap_node, hash_macro_name (m->name));
371 }
372 \f
373 enum me_state
374   {
375     /* Error state. */
376     ME_ERROR,
377
378     /* Accumulating tokens in me->params toward the end of any type of
379        argument. */
380     ME_ARG,
381
382     /* Expecting the opening delimiter of an ARG_ENCLOSE argument. */
383     ME_ENCLOSE,
384
385     /* Expecting a keyword for a keyword argument. */
386     ME_KEYWORD,
387
388     /* Expecting an equal sign for a keyword argument. */
389     ME_EQUALS,
390   };
391
392
393 struct macro_expander
394   {
395     const struct macro_set *macros;
396
397     enum me_state state;
398     size_t n_tokens;
399
400     const struct macro *macro;
401     struct macro_tokens **args;
402     const struct macro_param *param;
403   };
404
405 static int
406 me_finished (struct macro_expander *me)
407 {
408   for (size_t i = 0; i < me->macro->n_params; i++)
409     if (!me->args[i])
410       {
411         me->args[i] = xmalloc (sizeof *me->args[i]);
412         macro_tokens_copy (me->args[i], &me->macro->params[i].def);
413       }
414   return me->n_tokens;
415 }
416
417 static int
418 me_next_arg (struct macro_expander *me)
419 {
420   if (!me->param)
421     {
422       assert (!me->macro->n_params);
423       return me_finished (me);
424     }
425   else if (me->param->positional)
426     {
427       me->param++;
428       if (me->param >= &me->macro->params[me->macro->n_params])
429         return me_finished (me);
430       else
431         {
432           me->state = (!me->param->positional ? ME_KEYWORD
433                        : me->param->arg_type == ARG_ENCLOSE ? ME_ENCLOSE
434                        : ME_ARG);
435           return 0;
436         }
437     }
438   else
439     {
440       for (size_t i = 0; i < me->macro->n_params; i++)
441         if (!me->args[i])
442           {
443             me->state = ME_KEYWORD;
444             return 0;
445           }
446       return me_finished (me);
447     }
448 }
449
450 static int
451 me_error (struct macro_expander *me)
452 {
453   me->state = ME_ERROR;
454   return -1;
455 }
456
457 static int
458 me_add_arg (struct macro_expander *me, const struct macro_token *mt)
459 {
460   const struct macro_param *p = me->param;
461
462   const struct token *token = &mt->token;
463   if ((token->type == T_ENDCMD || token->type == T_STOP)
464       && p->arg_type != ARG_CMDEND)
465     {
466       msg (SE, _("Unexpected end of command reading argument %s "
467                  "to macro %s."), me->param->name, me->macro->name);
468
469       return me_error (me);
470     }
471
472   me->n_tokens++;
473
474   struct macro_tokens **argp = &me->args[p - me->macro->params];
475   if (!*argp)
476     *argp = xzalloc (sizeof **argp);
477   struct macro_tokens *arg = *argp;
478   if (p->arg_type == ARG_N_TOKENS)
479     {
480       macro_tokens_add (arg, mt);
481       if (arg->n >= p->n_tokens)
482         return me_next_arg (me);
483       return 0;
484     }
485   else if (p->arg_type == ARG_CMDEND)
486     {
487       if (token->type == T_ENDCMD || token->type == T_STOP)
488         return me_next_arg (me);
489       macro_tokens_add (arg, mt);
490       return 0;
491     }
492   else
493     {
494       const struct token *end
495         = p->arg_type == ARG_CHAREND ? &p->charend : &p->enclose[1];
496       if (token_equal (token, end))
497         return me_next_arg (me);
498       macro_tokens_add (arg, mt);
499       return 0;
500     }
501 }
502
503 static int
504 me_expected (struct macro_expander *me, const struct macro_token *actual,
505              const struct token *expected)
506 {
507   const struct substring actual_s
508     = (actual->representation.length ? actual->representation
509        : ss_cstr (_("<end of input>")));
510   char *expected_s = token_to_string (expected);
511   msg (SE, _("Found `%.*s' while expecting `%s' reading argument %s "
512              "to macro %s."),
513        (int) actual_s.length, actual_s.string, expected_s,
514        me->param->name, me->macro->name);
515   free (expected_s);
516
517   return me_error (me);
518 }
519
520 static int
521 me_enclose (struct macro_expander *me, const struct macro_token *mt)
522 {
523   const struct token *token = &mt->token;
524   me->n_tokens++;
525
526   if (token_equal (&me->param->enclose[0], token))
527     {
528       me->state = ME_ARG;
529       return 0;
530     }
531
532   return me_expected (me, mt, &me->param->enclose[0]);
533 }
534
535 static const struct macro_param *
536 macro_find_parameter_by_name (const struct macro *m, struct substring name)
537 {
538   if (ss_first (name) == '!')
539     ss_advance (&name, 1);
540
541   for (size_t i = 0; i < m->n_params; i++)
542     {
543       const struct macro_param *p = &m->params[i];
544       struct substring p_name = ss_cstr (p->name + 1);
545       if (!utf8_strncasecmp (p_name.string, p_name.length,
546                              name.string, name.length))
547         return p;
548     }
549   return NULL;
550 }
551
552 static int
553 me_keyword (struct macro_expander *me, const struct macro_token *mt)
554 {
555   const struct token *token = &mt->token;
556   if (token->type != T_ID)
557     return me_finished (me);
558
559   const struct macro_param *p = macro_find_parameter_by_name (me->macro,
560                                                               token->string);
561   if (p)
562     {
563       size_t arg_index = p - me->macro->params;
564       me->param = p;
565       if (me->args[arg_index])
566         {
567           msg (SE,
568                _("Argument %s multiply specified in call to macro %s."),
569                p->name, me->macro->name);
570           return me_error (me);
571         }
572
573       me->n_tokens++;
574       me->state = ME_EQUALS;
575       return 0;
576     }
577
578   return me_finished (me);
579 }
580
581 static int
582 me_equals (struct macro_expander *me, const struct macro_token *mt)
583 {
584   const struct token *token = &mt->token;
585   me->n_tokens++;
586
587   if (token->type == T_EQUALS)
588     {
589       me->state = ME_ARG;
590       return 0;
591     }
592
593   return me_expected (me, mt, &(struct token) { .type = T_EQUALS });
594 }
595
596 int
597 macro_expander_create (const struct macro_set *macros,
598                        const struct token *token,
599                        struct macro_expander **mep)
600 {
601   *mep = NULL;
602   if (macro_set_is_empty (macros))
603     return -1;
604   if (token->type != T_ID && token->type != T_MACRO_ID)
605     return -1;
606
607   const struct macro *macro = macro_set_find (macros, token->string.string);
608   if (!macro)
609     return -1;
610
611   struct macro_expander *me = xmalloc (sizeof *me);
612   *me = (struct macro_expander) {
613     .macros = macros,
614     .n_tokens = 1,
615     .macro = macro,
616   };
617   *mep = me;
618
619   if (!macro->n_params)
620     return 1;
621   else
622     {
623       me->state = (!macro->params[0].positional ? ME_KEYWORD
624                    : macro->params[0].arg_type == ARG_ENCLOSE ? ME_ENCLOSE
625                    : ME_ARG);
626       me->args = xcalloc (macro->n_params, sizeof *me->args);
627       me->param = macro->params;
628       return 0;
629     }
630 }
631
632 void
633 macro_expander_destroy (struct macro_expander *me)
634 {
635   if (!me)
636     return;
637
638   for (size_t i = 0; i < me->macro->n_params; i++)
639     if (me->args[i])
640       {
641         macro_tokens_uninit (me->args[i]);
642         free (me->args[i]);
643       }
644   free (me->args);
645   free (me);
646 }
647
648 /* Adds TOKEN to the collection of tokens in ME that potentially need to be
649    macro expanded.
650
651    Returns -1 if the tokens added do not actually invoke a macro.  The caller
652    should consume the first token without expanding it.
653
654    Returns 0 if the macro expander needs more tokens, for macro arguments or to
655    decide whether this is actually a macro invocation.  The caller should call
656    macro_expander_add() again with the next token.
657
658    Returns a positive number to indicate that the returned number of tokens
659    invoke a macro.  The number returned might be less than the number of tokens
660    added because it can take a few tokens of lookahead to determine whether the
661    macro invocation is finished.  The caller should call
662    macro_expander_get_expansion() to obtain the expansion. */
663 int
664 macro_expander_add (struct macro_expander *me, const struct macro_token *mt)
665 {
666   switch (me->state)
667     {
668     case ME_ERROR:
669       return -1;
670
671     case ME_ARG:
672       return me_add_arg (me, mt);
673
674     case ME_ENCLOSE:
675       return me_enclose (me, mt);
676
677     case ME_KEYWORD:
678       return me_keyword (me, mt);
679
680     case ME_EQUALS:
681       return me_equals (me, mt);
682
683     default:
684       NOT_REACHED ();
685     }
686 }
687
688 /* Each argument to a macro function is one of:
689
690        - A quoted string or other single literal token.
691
692        - An argument to the macro being expanded, e.g. !1 or a named argument.
693
694        - !*.
695
696        - A function invocation.
697
698    Each function invocation yields a character sequence to be turned into a
699    sequence of tokens.  The case where that character sequence is a single
700    quoted string is an important special case.
701 */
702 struct parse_macro_function_ctx
703   {
704     struct macro_token *input;
705     size_t n_input;
706     int nesting_countdown;
707     const struct macro_set *macros;
708     const struct macro_expander *me;
709     bool *expand;
710   };
711
712 static void
713 macro_expand (const struct macro_tokens *,
714               int nesting_countdown, const struct macro_set *,
715               const struct macro_expander *, bool *expand, struct macro_tokens *exp);
716
717 static bool
718 expand_macro_function (struct parse_macro_function_ctx *ctx,
719                        struct macro_token *output,
720                        size_t *input_consumed);
721
722 static size_t
723 parse_function_arg (struct parse_macro_function_ctx *ctx,
724                     size_t i, struct macro_token *farg)
725 {
726   struct macro_token *tokens = ctx->input;
727   const struct token *token = &tokens[i].token;
728   if (token->type == T_MACRO_ID)
729     {
730       const struct macro_param *param = macro_find_parameter_by_name (
731         ctx->me->macro, token->string);
732       if (param)
733         {
734           size_t param_idx = param - ctx->me->macro->params;
735           const struct macro_tokens *marg = ctx->me->args[param_idx];
736           if (marg->n == 1)
737             macro_token_copy (farg, &marg->mts[0]);
738           else
739             {
740               struct string s = DS_EMPTY_INITIALIZER;
741               for (size_t i = 0; i < marg->n; i++)
742                 {
743                   if (i)
744                     ds_put_byte (&s, ' ');
745                   ds_put_substring (&s, marg->mts[i].representation);
746                 }
747
748               struct substring s_copy;
749               ss_alloc_substring (&s_copy, s.ss);
750
751               *farg = (struct macro_token) {
752                 .token = { .type = T_MACRO_ID, .string = s.ss },
753                 .representation = s_copy,
754               };
755             }
756           return 1;
757         }
758
759       struct parse_macro_function_ctx subctx = {
760         .input = &ctx->input[i],
761         .n_input = ctx->n_input - i,
762         .nesting_countdown = ctx->nesting_countdown,
763         .macros = ctx->macros,
764         .me = ctx->me,
765         .expand = ctx->expand,
766       };
767       size_t subinput_consumed;
768       if (expand_macro_function (&subctx, farg, &subinput_consumed))
769         return subinput_consumed;
770     }
771
772   macro_token_copy (farg, &tokens[i]);
773   return 1;
774 }
775
776 static bool
777 parse_macro_function (struct parse_macro_function_ctx *ctx,
778                       struct macro_tokens *args,
779                       struct substring function,
780                       int min_args, int max_args,
781                       size_t *input_consumed)
782 {
783   struct macro_token *tokens = ctx->input;
784   size_t n_tokens = ctx->n_input;
785
786   if (!n_tokens
787       || tokens[0].token.type != T_MACRO_ID
788       || !ss_equals_case (tokens[0].token.string, function))
789     return false;
790
791   if (n_tokens < 2 || tokens[1].token.type != T_LPAREN)
792     {
793       printf ("`(' expected following %s'\n", function.string);
794       return false;
795     }
796
797   *args = (struct macro_tokens) { .n = 0 };
798
799   for (size_t i = 2;; )
800     {
801       if (i >= n_tokens)
802         goto unexpected_end;
803       if (tokens[i].token.type == T_RPAREN)
804         {
805           *input_consumed = i + 1;
806           if (args->n < min_args || args->n > max_args)
807             {
808               printf ("Wrong number of arguments to %s.\n", function.string);
809               goto error;
810             }
811           return true;
812         }
813
814       i += parse_function_arg (ctx, i, macro_tokens_add_uninit (args));
815       if (i >= n_tokens)
816         goto unexpected_end;
817
818       if (tokens[i].token.type == T_COMMA)
819         i++;
820       else if (tokens[i].token.type != T_RPAREN)
821         {
822           printf ("Expecting `,' or `)' in %s invocation.", function.string);
823           goto error;
824         }
825     }
826
827 unexpected_end:
828   printf ("Missing closing parenthesis in arguments to %s.\n",
829           function.string);
830   /* Fall through. */
831 error:
832   macro_tokens_uninit (args);
833   return false;
834 }
835
836 static bool
837 expand_macro_function (struct parse_macro_function_ctx *ctx,
838                        struct macro_token *output,
839                        size_t *input_consumed)
840 {
841   struct macro_tokens args;
842
843   if (parse_macro_function (ctx, &args, ss_cstr ("!length"), 1, 1,
844                             input_consumed))
845     {
846       size_t length = args.mts[0].representation.length;
847       *output = (struct macro_token) {
848         .token = { .type = T_POS_NUM, .number = length },
849         .representation = ss_cstr (xasprintf ("%zu", length)),
850       };
851     }
852   else if (parse_macro_function (ctx, &args, ss_cstr ("!blanks"), 1, 1,
853                                  input_consumed))
854     {
855       /* XXX this isn't right, it might be a character string containing a
856          positive integer, e.g. via !CONCAT. */
857       if (args.mts[0].token.type != T_POS_NUM)
858         {
859           printf ("argument to !BLANKS must be positive integer\n");
860           macro_tokens_uninit (&args);
861           return false;
862         }
863
864       struct string s = DS_EMPTY_INITIALIZER;
865       ds_put_byte_multiple (&s, ' ', args.mts[0].token.number);
866
867       struct substring s_copy;
868       ss_alloc_substring (&s_copy, s.ss);
869
870       *output = (struct macro_token) {
871         .token = { .type = T_ID, .string = s.ss },
872         .representation = s_copy,
873       };
874     }
875   else if (parse_macro_function (ctx, &args, ss_cstr ("!concat"), 1, INT_MAX,
876                                  input_consumed))
877     {
878       struct string s;
879       bool all_strings = true;
880       for (size_t i = 0; i < args.n; i++)
881         {
882           if (args.mts[i].token.type == T_STRING)
883             ds_put_substring (&s, args.mts[i].token.string);
884           else
885             {
886               all_strings = false;
887               ds_put_substring (&s, args.mts[i].representation);
888             }
889         }
890
891       if (all_strings)
892         {
893           *output = (struct macro_token) {
894             .token = { .type = T_STRING, .string = s.ss },
895           };
896           output->representation = ss_cstr (token_to_string (&output->token));
897         }
898       else
899         {
900           *output = (struct macro_token) {
901             .token = { .type = T_MACRO_ID /*XXX*/, .string = s.ss },
902           };
903           ss_alloc_substring (&output->representation, s.ss);
904         }
905     }
906   else if (parse_macro_function (ctx, &args, ss_cstr ("!quote"), 1, 1,
907                                  input_consumed))
908     {
909       if (args.mts[0].token.type == T_STRING)
910         macro_token_copy (output, &args.mts[0]);
911       else
912         {
913           *output = (struct macro_token) { .token = { .type = T_STRING } };
914           ss_alloc_substring (&output->token.string, args.mts[0].representation);
915           output->representation = ss_cstr (token_to_string (&output->token));
916         }
917     }
918   else if (parse_macro_function (ctx, &args, ss_cstr ("!unquote"), 1, 1,
919                                  input_consumed))
920     {
921       if (args.mts[0].token.type == T_STRING)
922         {
923           *output = (struct macro_token) { .token = { .type = T_MACRO_ID } };
924           ss_alloc_substring (&output->token.string, args.mts[0].token.string);
925           output->representation = ss_cstr (token_to_string (&output->token));
926         }
927       else
928         macro_token_copy (output, &args.mts[0]);
929     }
930   else
931     return false;
932
933   macro_tokens_uninit (&args);
934   return true;
935 }
936
937 static void
938 macro_expand (const struct macro_tokens *mts,
939               int nesting_countdown, const struct macro_set *macros,
940               const struct macro_expander *me, bool *expand,
941               struct macro_tokens *exp)
942 {
943   /* Macro expansion:
944
945      - Macro names in macro bodies are not expanded by default.  !EVAL()
946        expands them.
947
948      - Macro names in arguments to macro invocations (outside of macro bodies)
949        are expanded by default, unless !NOEXPAND. */
950   if (nesting_countdown <= 0)
951     {
952       printf ("maximum nesting level exceeded\n");
953       for (size_t i = 0; i < mts->n; i++)
954         macro_tokens_add (exp, &mts->mts[i]);
955       return;
956     }
957
958   for (size_t i = 0; i < mts->n; i++)
959     {
960       const struct macro_token *mt = &mts->mts[i];
961       const struct token *token = &mt->token;
962       if (token->type == T_MACRO_ID && me)
963         {
964           const struct macro_param *param = macro_find_parameter_by_name (
965             me->macro, token->string);
966           if (param)
967             {
968               const struct macro_tokens *arg = me->args[param - me->macro->params];
969               //macro_tokens_print (arg, stdout);
970               if (*expand && param->expand_arg)
971                 macro_expand (arg, nesting_countdown, macros, NULL, expand, exp);
972               else
973                 for (size_t i = 0; i < arg->n; i++)
974                   macro_tokens_add (exp, &arg->mts[i]);
975               continue;
976             }
977         }
978
979       if (*expand)
980         {
981           struct macro_expander *subme;
982           int retval = macro_expander_create (macros, token, &subme);
983           for (size_t j = 1; !retval; j++)
984             {
985               const struct macro_token endcmd = { .token = { .type = T_ENDCMD } };
986               retval = macro_expander_add (
987                 subme, i + j < mts->n ? &mts->mts[i + j] : &endcmd);
988             }
989           if (retval > 0)
990             {
991               i += retval - 1;
992               macro_expand (&subme->macro->body, nesting_countdown - 1, macros,
993                             subme, expand, exp);
994               macro_expander_destroy (subme);
995               continue;
996             }
997
998           macro_expander_destroy (subme);
999         }
1000
1001       if (token->type != T_MACRO_ID)
1002         {
1003           macro_tokens_add (exp, mt);
1004           continue;
1005         }
1006
1007       /* Maybe each arg should just be a string, either a quoted string or a
1008          non-quoted string containing tokens. */
1009       struct parse_macro_function_ctx ctx = {
1010         .input = &mts->mts[i],
1011         .n_input = mts->n - i,
1012         .nesting_countdown = nesting_countdown,
1013         .macros = macros,
1014         .me = me,
1015         .expand = expand,
1016       };
1017       struct macro_token function_output;
1018       size_t function_consumed;
1019       if (expand_macro_function (&ctx, &function_output, &function_consumed))
1020         {
1021           i += function_consumed - 1;
1022
1023           if (function_output.token.type == T_MACRO_ID)
1024             macro_tokens_from_string (exp, function_output.token.string,
1025                                       SEG_MODE_INTERACTIVE /* XXX */);
1026           else
1027             macro_tokens_add (exp, &function_output);
1028           macro_token_uninit (&function_output);
1029
1030           continue;
1031         }
1032
1033       if (ss_equals_case (token->string, ss_cstr ("!onexpand")))
1034         *expand = true;
1035       else if (ss_equals_case (token->string, ss_cstr ("!offexpand")))
1036         *expand = false;
1037       else
1038         macro_tokens_add (exp, mt);
1039     }
1040 }
1041
1042 void
1043 macro_expander_get_expansion (struct macro_expander *me, struct macro_tokens *exp)
1044 {
1045 #if 0
1046   for (size_t i = 0; i < me->macro->n_params; i++)
1047     {
1048       printf ("%s:\n", me->macro->params[i].name);
1049       macro_tokens_print (me->args[i], stdout);
1050     }
1051 #endif
1052
1053   bool expand = true;
1054   macro_expand (&me->macro->body, settings_get_mnest (),
1055                 me->macros, me, &expand, exp);
1056
1057 #if 0
1058   printf ("expansion:\n");
1059   macro_tokens_print (exp, stdout);
1060 #endif
1061 }
1062