5f68de3fdd289b22a052d5e97f51f66894bdec0a
[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 <errno.h>
22 #include <limits.h>
23 #include <stdlib.h>
24
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/cast.h"
30 #include "libpspp/i18n.h"
31 #include "libpspp/message.h"
32 #include "libpspp/str.h"
33 #include "libpspp/string-array.h"
34 #include "libpspp/string-map.h"
35 #include "libpspp/stringi-set.h"
36
37 #include "gl/c-ctype.h"
38 #include "gl/ftoastr.h"
39
40 #include "gettext.h"
41 #define _(msgid) gettext (msgid)
42
43 void
44 macro_token_copy (struct macro_token *dst, const struct macro_token *src)
45 {
46   token_copy (&dst->token, &src->token);
47   ss_alloc_substring (&dst->representation, src->representation);
48 }
49
50 void
51 macro_token_uninit (struct macro_token *mt)
52 {
53   token_uninit (&mt->token);
54   ss_dealloc (&mt->representation);
55 }
56
57 void
58 macro_token_to_representation (struct macro_token *mt, struct string *s)
59 {
60   ds_put_substring (s, mt->representation);
61 }
62
63 bool
64 is_macro_keyword (struct substring s)
65 {
66   static struct stringi_set keywords = STRINGI_SET_INITIALIZER (keywords);
67   if (stringi_set_is_empty (&keywords))
68     {
69       static const char *kws[] = {
70         "BREAK",
71         "CHAREND",
72         "CMDEND",
73         "DEFAULT",
74         "DO",
75         "DOEND",
76         "ELSE",
77         "ENCLOSE",
78         "ENDDEFINE",
79         "IF",
80         "IFEND",
81         "IN",
82         "LET",
83         "NOEXPAND",
84         "OFFEXPAND",
85         "ONEXPAND",
86         "POSITIONAL",
87         "THEN",
88         "TOKENS",
89       };
90       for (size_t i = 0; i < sizeof kws / sizeof *kws; i++)
91         stringi_set_insert (&keywords, kws[i]);
92     }
93
94   ss_ltrim (&s, ss_cstr ("!"));
95   return stringi_set_contains_len (&keywords, s.string, s.length);
96 }
97
98 void
99 macro_tokens_copy (struct macro_tokens *dst, const struct macro_tokens *src)
100 {
101   *dst = (struct macro_tokens) {
102     .mts = xmalloc (src->n * sizeof *dst->mts),
103     .n = src->n,
104     .allocated = src->n,
105   };
106   for (size_t i = 0; i < src->n; i++)
107     macro_token_copy (&dst->mts[i], &src->mts[i]);
108 }
109
110 void
111 macro_tokens_uninit (struct macro_tokens *mts)
112 {
113   for (size_t i = 0; i < mts->n; i++)
114     macro_token_uninit (&mts->mts[i]);
115   free (mts->mts);
116 }
117
118 struct macro_token *
119 macro_tokens_add_uninit (struct macro_tokens *mts)
120 {
121   if (mts->n >= mts->allocated)
122     mts->mts = x2nrealloc (mts->mts, &mts->allocated, sizeof *mts->mts);
123   return &mts->mts[mts->n++];
124 }
125
126 void
127 macro_tokens_add (struct macro_tokens *mts, const struct macro_token *mt)
128 {
129   macro_token_copy (macro_tokens_add_uninit (mts), mt);
130 }
131
132 void
133 macro_tokens_from_string (struct macro_tokens *mts, const struct substring src,
134                           enum segmenter_mode mode)
135 {
136   struct state
137     {
138       struct segmenter segmenter;
139       struct substring body;
140     };
141
142   struct state state = {
143     .segmenter = segmenter_init (mode, true),
144     .body = src,
145   };
146   struct state saved = state;
147
148   while (state.body.length > 0)
149     {
150       struct macro_token mt = {
151         .token = { .type = T_STOP },
152         .representation = { .string = state.body.string },
153       };
154       struct token *token = &mt.token;
155
156       struct scanner scanner;
157       scanner_init (&scanner, token);
158
159       for (;;)
160         {
161           enum segment_type type;
162           int seg_len = segmenter_push (&state.segmenter, state.body.string,
163                                         state.body.length, true, &type);
164           assert (seg_len >= 0);
165
166           struct substring segment = ss_head (state.body, seg_len);
167           ss_advance (&state.body, seg_len);
168
169           enum scan_result result = scanner_push (&scanner, type, segment, token);
170           if (result == SCAN_SAVE)
171             saved = state;
172           else if (result == SCAN_BACK)
173             {
174               state = saved;
175               break;
176             }
177           else if (result == SCAN_DONE)
178             break;
179         }
180
181       /* We have a token in 'token'. */
182       if (is_scan_type (token->type))
183         {
184           if (token->type != SCAN_SKIP)
185             {
186               printf ("error\n");
187               /* XXX report error */
188             }
189         }
190       else
191         {
192           mt.representation.length = state.body.string - mt.representation.string;
193           macro_tokens_add (mts, &mt);
194         }
195       token_uninit (token);
196     }
197 }
198
199 void
200 macro_tokens_print (const struct macro_tokens *mts, FILE *stream)
201 {
202   for (size_t i = 0; i < mts->n; i++)
203     token_print (&mts->mts[i].token, stream);
204 }
205
206 enum token_class
207   {
208     TC_ENDCMD,                  /* No space before or after (new-line after). */
209     TC_BINOP,                   /* Space on both sides. */
210     TC_COMMA,                   /* Space afterward. */
211     TC_ID,                      /* Don't need spaces except sequentially. */
212     TC_PUNCT,                   /* Don't need spaces except sequentially. */
213   };
214
215 static bool
216 needs_space (enum token_class prev, enum token_class next)
217 {
218   /* Don't need a space before or after the end of a command.
219      (A new-line is needed afterward as a special case.) */
220   if (prev == TC_ENDCMD || next == TC_ENDCMD)
221     return false;
222
223   /* Binary operators always have a space on both sides. */
224   if (prev == TC_BINOP || next == TC_BINOP)
225     return true;
226
227   /* A comma always has a space afterward. */
228   if (prev == TC_COMMA)
229     return true;
230
231   /* Otherwise, PREV is TC_ID or TC_PUNCT, which only need a space if there are
232      two or them in a row. */
233   return prev == next;
234 }
235
236 static enum token_class
237 classify_token (enum token_type type)
238 {
239   switch (type)
240     {
241     case T_ID:
242     case T_MACRO_ID:
243     case T_POS_NUM:
244     case T_NEG_NUM:
245     case T_STRING:
246       return TC_ID;
247
248     case T_STOP:
249       return TC_PUNCT;
250
251     case T_ENDCMD:
252       return TC_ENDCMD;
253
254     case T_LPAREN:
255     case T_RPAREN:
256     case T_LBRACK:
257     case T_RBRACK:
258       return TC_PUNCT;
259
260     case T_PLUS:
261     case T_DASH:
262     case T_ASTERISK:
263     case T_SLASH:
264     case T_EQUALS:
265     case T_AND:
266     case T_OR:
267     case T_NOT:
268     case T_EQ:
269     case T_GE:
270     case T_GT:
271     case T_LE:
272     case T_LT:
273     case T_NE:
274     case T_ALL:
275     case T_BY:
276     case T_TO:
277     case T_WITH:
278     case T_EXP:
279     case T_MACRO_PUNCT:
280       return TC_BINOP;
281
282     case T_COMMA:
283       return TC_COMMA;
284     }
285
286   NOT_REACHED ();
287 }
288
289 void
290 macro_tokens_to_representation (struct macro_tokens *mts, struct string *s,
291                                 size_t *ofs, size_t *len)
292 {
293   assert ((ofs != NULL) == (len != NULL));
294
295   if (!mts->n)
296     return;
297
298   for (size_t i = 0; i < mts->n; i++)
299     {
300       if (i > 0)
301         {
302           enum token_type prev = mts->mts[i - 1].token.type;
303           enum token_type next = mts->mts[i].token.type;
304
305           if (prev == T_ENDCMD)
306             ds_put_byte (s, '\n');
307           else
308             {
309               enum token_class pc = classify_token (prev);
310               enum token_class nc = classify_token (next);
311               if (needs_space (pc, nc))
312                 ds_put_byte (s, ' ');
313             }
314         }
315
316       if (ofs)
317         ofs[i] = s->ss.length;
318       macro_token_to_representation (&mts->mts[i], s);
319       if (len)
320         len[i] = s->ss.length - ofs[i];
321     }
322 }
323
324 void
325 macro_destroy (struct macro *m)
326 {
327   if (!m)
328     return;
329
330   free (m->name);
331   for (size_t i = 0; i < m->n_params; i++)
332     {
333       struct macro_param *p = &m->params[i];
334       free (p->name);
335
336       macro_tokens_uninit (&p->def);
337
338       switch (p->arg_type)
339         {
340         case ARG_N_TOKENS:
341           break;
342
343         case ARG_CHAREND:
344           token_uninit (&p->charend);
345           break;
346
347         case ARG_ENCLOSE:
348           token_uninit (&p->enclose[0]);
349           token_uninit (&p->enclose[1]);
350           break;
351
352         case ARG_CMDEND:
353           break;
354         }
355     }
356   free (m->params);
357   macro_tokens_uninit (&m->body);
358   free (m);
359 }
360 \f
361 struct macro_set *
362 macro_set_create (void)
363 {
364   struct macro_set *set = xmalloc (sizeof *set);
365   *set = (struct macro_set) {
366     .macros = HMAP_INITIALIZER (set->macros),
367   };
368   return set;
369 }
370
371 void
372 macro_set_destroy (struct macro_set *set)
373 {
374   if (!set)
375     return;
376
377   struct macro *macro, *next;
378   HMAP_FOR_EACH_SAFE (macro, next, struct macro, hmap_node, &set->macros)
379     {
380       hmap_delete (&set->macros, &macro->hmap_node);
381       macro_destroy (macro);
382     }
383   hmap_destroy (&set->macros);
384   free (set);
385 }
386
387 static unsigned int
388 hash_macro_name (const char *name)
389 {
390   return utf8_hash_case_string (name, 0);
391 }
392
393 static struct macro *
394 macro_set_find__ (struct macro_set *set, const char *name)
395 {
396   struct macro *macro;
397   HMAP_FOR_EACH_WITH_HASH (macro, struct macro, hmap_node,
398                            hash_macro_name (name), &set->macros)
399     if (!utf8_strcasecmp (macro->name, name))
400       return macro;
401
402   return NULL;
403 }
404
405 const struct macro *
406 macro_set_find (const struct macro_set *set, const char *name)
407 {
408   return macro_set_find__ (CONST_CAST (struct macro_set *, set), name);
409 }
410
411 /* Adds M to SET.  M replaces any existing macro with the same name.  Takes
412    ownership of M. */
413 void
414 macro_set_add (struct macro_set *set, struct macro *m)
415 {
416   struct macro *victim = macro_set_find__ (set, m->name);
417   if (victim)
418     {
419       hmap_delete (&set->macros, &victim->hmap_node);
420       macro_destroy (victim);
421     }
422
423   hmap_insert (&set->macros, &m->hmap_node, hash_macro_name (m->name));
424 }
425 \f
426 struct macro_expansion_stack
427   {
428     const struct macro_expansion_stack *next;
429     const char *name;
430   };
431
432
433 enum me_state
434   {
435     /* Error state. */
436     ME_ERROR,
437
438     /* Accumulating tokens in me->params toward the end of any type of
439        argument. */
440     ME_ARG,
441
442     /* Expecting the opening delimiter of an ARG_ENCLOSE argument. */
443     ME_ENCLOSE,
444
445     /* Expecting a keyword for a keyword argument. */
446     ME_KEYWORD,
447
448     /* Expecting an equal sign for a keyword argument. */
449     ME_EQUALS,
450   };
451
452
453 struct macro_expander
454   {
455     const struct macro_set *macros;
456
457     enum me_state state;
458     size_t n_tokens;
459
460     const struct macro *macro;
461     struct macro_tokens **args;
462     const struct macro_param *param;
463   };
464
465 static int
466 me_finished (struct macro_expander *me)
467 {
468   for (size_t i = 0; i < me->macro->n_params; i++)
469     if (!me->args[i])
470       {
471         me->args[i] = xmalloc (sizeof *me->args[i]);
472         macro_tokens_copy (me->args[i], &me->macro->params[i].def);
473       }
474   return me->n_tokens;
475 }
476
477 static int
478 me_next_arg (struct macro_expander *me)
479 {
480   if (!me->param)
481     {
482       assert (!me->macro->n_params);
483       return me_finished (me);
484     }
485   else if (me->param->positional)
486     {
487       me->param++;
488       if (me->param >= &me->macro->params[me->macro->n_params])
489         return me_finished (me);
490       else
491         {
492           me->state = (!me->param->positional ? ME_KEYWORD
493                        : me->param->arg_type == ARG_ENCLOSE ? ME_ENCLOSE
494                        : ME_ARG);
495           return 0;
496         }
497     }
498   else
499     {
500       for (size_t i = 0; i < me->macro->n_params; i++)
501         if (!me->args[i])
502           {
503             me->state = ME_KEYWORD;
504             return 0;
505           }
506       return me_finished (me);
507     }
508 }
509
510 static int
511 me_error (struct macro_expander *me)
512 {
513   me->state = ME_ERROR;
514   return -1;
515 }
516
517 static int
518 me_add_arg (struct macro_expander *me, const struct macro_token *mt)
519 {
520   const struct macro_param *p = me->param;
521
522   const struct token *token = &mt->token;
523   if ((token->type == T_ENDCMD || token->type == T_STOP)
524       && p->arg_type != ARG_CMDEND)
525     {
526       msg (SE, _("Unexpected end of command reading argument %s "
527                  "to macro %s."), me->param->name, me->macro->name);
528
529       return me_error (me);
530     }
531
532   me->n_tokens++;
533
534   struct macro_tokens **argp = &me->args[p - me->macro->params];
535   if (!*argp)
536     *argp = xzalloc (sizeof **argp);
537   struct macro_tokens *arg = *argp;
538   if (p->arg_type == ARG_N_TOKENS)
539     {
540       macro_tokens_add (arg, mt);
541       if (arg->n >= p->n_tokens)
542         return me_next_arg (me);
543       return 0;
544     }
545   else if (p->arg_type == ARG_CMDEND)
546     {
547       if (token->type == T_ENDCMD || token->type == T_STOP)
548         return me_next_arg (me);
549       macro_tokens_add (arg, mt);
550       return 0;
551     }
552   else
553     {
554       const struct token *end
555         = p->arg_type == ARG_CHAREND ? &p->charend : &p->enclose[1];
556       if (token_equal (token, end))
557         return me_next_arg (me);
558       macro_tokens_add (arg, mt);
559       return 0;
560     }
561 }
562
563 static int
564 me_expected (struct macro_expander *me, const struct macro_token *actual,
565              const struct token *expected)
566 {
567   const struct substring actual_s
568     = (actual->representation.length ? actual->representation
569        : ss_cstr (_("<end of input>")));
570   char *expected_s = token_to_string (expected);
571   msg (SE, _("Found `%.*s' while expecting `%s' reading argument %s "
572              "to macro %s."),
573        (int) actual_s.length, actual_s.string, expected_s,
574        me->param->name, me->macro->name);
575   free (expected_s);
576
577   return me_error (me);
578 }
579
580 static int
581 me_enclose (struct macro_expander *me, const struct macro_token *mt)
582 {
583   const struct token *token = &mt->token;
584   me->n_tokens++;
585
586   if (token_equal (&me->param->enclose[0], token))
587     {
588       me->state = ME_ARG;
589       return 0;
590     }
591
592   return me_expected (me, mt, &me->param->enclose[0]);
593 }
594
595 static const struct macro_param *
596 macro_find_parameter_by_name (const struct macro *m, struct substring name)
597 {
598   ss_ltrim (&name, ss_cstr ("!"));
599
600   for (size_t i = 0; i < m->n_params; i++)
601     {
602       const struct macro_param *p = &m->params[i];
603       struct substring p_name = ss_cstr (p->name + 1);
604       if (!utf8_strncasecmp (p_name.string, p_name.length,
605                              name.string, name.length))
606         return p;
607     }
608   return NULL;
609 }
610
611 static int
612 me_keyword (struct macro_expander *me, const struct macro_token *mt)
613 {
614   const struct token *token = &mt->token;
615   if (token->type != T_ID)
616     return me_finished (me);
617
618   const struct macro_param *p = macro_find_parameter_by_name (me->macro,
619                                                               token->string);
620   if (p)
621     {
622       size_t arg_index = p - me->macro->params;
623       me->param = p;
624       if (me->args[arg_index])
625         {
626           msg (SE,
627                _("Argument %s multiply specified in call to macro %s."),
628                p->name, me->macro->name);
629           return me_error (me);
630         }
631
632       me->n_tokens++;
633       me->state = ME_EQUALS;
634       return 0;
635     }
636
637   return me_finished (me);
638 }
639
640 static int
641 me_equals (struct macro_expander *me, const struct macro_token *mt)
642 {
643   const struct token *token = &mt->token;
644   me->n_tokens++;
645
646   if (token->type == T_EQUALS)
647     {
648       me->state = ME_ARG;
649       return 0;
650     }
651
652   return me_expected (me, mt, &(struct token) { .type = T_EQUALS });
653 }
654
655 int
656 macro_expander_create (const struct macro_set *macros,
657                        const struct token *token,
658                        struct macro_expander **mep)
659 {
660   *mep = NULL;
661   if (macro_set_is_empty (macros))
662     return -1;
663   if (token->type != T_ID && token->type != T_MACRO_ID)
664     return -1;
665
666   const struct macro *macro = macro_set_find (macros, token->string.string);
667   if (!macro)
668     return -1;
669
670   struct macro_expander *me = xmalloc (sizeof *me);
671   *me = (struct macro_expander) {
672     .macros = macros,
673     .n_tokens = 1,
674     .macro = macro,
675   };
676   *mep = me;
677
678   if (!macro->n_params)
679     return 1;
680   else
681     {
682       me->state = (!macro->params[0].positional ? ME_KEYWORD
683                    : macro->params[0].arg_type == ARG_ENCLOSE ? ME_ENCLOSE
684                    : ME_ARG);
685       me->args = xcalloc (macro->n_params, sizeof *me->args);
686       me->param = macro->params;
687       return 0;
688     }
689 }
690
691 void
692 macro_expander_destroy (struct macro_expander *me)
693 {
694   if (!me)
695     return;
696
697   for (size_t i = 0; i < me->macro->n_params; i++)
698     if (me->args[i])
699       {
700         macro_tokens_uninit (me->args[i]);
701         free (me->args[i]);
702       }
703   free (me->args);
704   free (me);
705 }
706
707 /* Adds TOKEN to the collection of tokens in ME that potentially need to be
708    macro expanded.
709
710    Returns -1 if the tokens added do not actually invoke a macro.  The caller
711    should consume the first token without expanding it.
712
713    Returns 0 if the macro expander needs more tokens, for macro arguments or to
714    decide whether this is actually a macro invocation.  The caller should call
715    macro_expander_add() again with the next token.
716
717    Returns a positive number to indicate that the returned number of tokens
718    invoke a macro.  The number returned might be less than the number of tokens
719    added because it can take a few tokens of lookahead to determine whether the
720    macro invocation is finished.  The caller should call
721    macro_expander_get_expansion() to obtain the expansion. */
722 int
723 macro_expander_add (struct macro_expander *me, const struct macro_token *mt)
724 {
725   switch (me->state)
726     {
727     case ME_ERROR:
728       return -1;
729
730     case ME_ARG:
731       return me_add_arg (me, mt);
732
733     case ME_ENCLOSE:
734       return me_enclose (me, mt);
735
736     case ME_KEYWORD:
737       return me_keyword (me, mt);
738
739     case ME_EQUALS:
740       return me_equals (me, mt);
741
742     default:
743       NOT_REACHED ();
744     }
745 }
746
747 /* Each argument to a macro function is one of:
748
749        - A quoted string or other single literal token.
750
751        - An argument to the macro being expanded, e.g. !1 or a named argument.
752
753        - !*.
754
755        - A function invocation.
756
757    Each function invocation yields a character sequence to be turned into a
758    sequence of tokens.  The case where that character sequence is a single
759    quoted string is an important special case.
760 */
761 struct parse_macro_function_ctx
762   {
763     const struct macro_token *input;
764     size_t n_input;
765     int nesting_countdown;
766     const struct macro_set *macros;
767     const struct macro_expander *me;
768     const struct macro_expansion_stack *stack;
769     struct string_map *vars;
770     bool *expand;
771   };
772
773 static void
774 macro_expand (const struct macro_tokens *,
775               int nesting_countdown, const struct macro_set *,
776               const struct macro_expander *, struct string_map *vars,
777               const struct macro_expansion_stack *stack,
778               bool *expand, bool *break_,
779               struct macro_tokens *exp);
780
781 static bool
782 expand_macro_function (struct parse_macro_function_ctx *ctx,
783                        struct string *output, size_t *input_consumed);
784
785 /* Returns true if the pair of tokens starting at offset OFS within MTS are !*,
786    false otherwise. */
787 static bool
788 is_bang_star (const struct macro_token *mts, size_t n, size_t ofs)
789 {
790   return (ofs + 1 < n
791           && mts[ofs].token.type == T_MACRO_ID
792           && ss_equals (mts[ofs].token.string, ss_cstr ("!"))
793           && mts[ofs + 1].token.type == T_ASTERISK);
794 }
795
796 static size_t
797 parse_function_arg (struct parse_macro_function_ctx *ctx,
798                     size_t i, struct string *farg)
799 {
800   const struct macro_token *tokens = ctx->input;
801   const struct token *token = &tokens[i].token;
802   if (token->type == T_MACRO_ID)
803     {
804       const struct macro_param *param = macro_find_parameter_by_name (
805         ctx->me->macro, token->string);
806       if (param)
807         {
808           size_t param_idx = param - ctx->me->macro->params;
809           const struct macro_tokens *marg = ctx->me->args[param_idx];
810           for (size_t i = 0; i < marg->n; i++)
811             {
812               if (i)
813                 ds_put_byte (farg, ' ');
814               ds_put_substring (farg, marg->mts[i].representation);
815             }
816           return 1;
817         }
818
819       if (is_bang_star (ctx->input, ctx->n_input, i))
820         {
821           for (size_t i = 0; i < ctx->me->macro->n_params; i++)
822             {
823               if (!ctx->me->macro->params[i].positional)
824                 break;
825
826               const struct macro_tokens *marg = ctx->me->args[i];
827               for (size_t j = 0; j < marg->n; j++)
828                 {
829                   if (i || j)
830                     ds_put_byte (farg, ' ');
831                   ds_put_substring (farg, marg->mts[j].representation);
832                 }
833             }
834           return 2;
835         }
836
837       if (ctx->vars)
838         {
839           const char *value = string_map_find__ (ctx->vars,
840                                                  token->string.string,
841                                                  token->string.length);
842           if (value)
843             {
844               ds_put_cstr (farg, value);
845               return 1;
846             }
847         }
848
849       struct parse_macro_function_ctx subctx = {
850         .input = &ctx->input[i],
851         .n_input = ctx->n_input - i,
852         .nesting_countdown = ctx->nesting_countdown,
853         .macros = ctx->macros,
854         .me = ctx->me,
855         .stack = ctx->stack,
856         .vars = ctx->vars,
857         .expand = ctx->expand,
858       };
859       size_t subinput_consumed;
860       if (expand_macro_function (&subctx, farg, &subinput_consumed))
861         return subinput_consumed;
862     }
863
864   ds_put_substring (farg, tokens[i].representation);
865   return 1;
866 }
867
868 static bool
869 parse_macro_function (struct parse_macro_function_ctx *ctx,
870                       struct string_array *args,
871                       struct substring function,
872                       int min_args, int max_args,
873                       size_t *input_consumed)
874 {
875   const struct macro_token *tokens = ctx->input;
876   size_t n_tokens = ctx->n_input;
877
878   if (!n_tokens
879       || tokens[0].token.type != T_MACRO_ID
880       || !ss_equals_case (tokens[0].token.string, function)) /* XXX abbrevs allowed */
881     return false;
882
883   if (n_tokens < 2 || tokens[1].token.type != T_LPAREN)
884     {
885       printf ("`(' expected following %s'\n", function.string);
886       return false;
887     }
888
889   string_array_init (args);
890
891   for (size_t i = 2;; )
892     {
893       if (i >= n_tokens)
894         goto unexpected_end;
895       if (tokens[i].token.type == T_RPAREN)
896         {
897           *input_consumed = i + 1;
898           if (args->n < min_args || args->n > max_args)
899             {
900               printf ("Wrong number of arguments to %s.\n", function.string);
901               goto error;
902             }
903           return true;
904         }
905
906       struct string s = DS_EMPTY_INITIALIZER;
907       i += parse_function_arg (ctx, i, &s);
908       if (i >= n_tokens)
909         {
910           ds_destroy (&s);
911           goto unexpected_end;
912         }
913       string_array_append_nocopy (args, ds_steal_cstr (&s));
914
915       if (tokens[i].token.type == T_COMMA)
916         i++;
917       else if (tokens[i].token.type != T_RPAREN)
918         {
919           printf ("Expecting `,' or `)' in %s invocation.", function.string);
920           goto error;
921         }
922     }
923
924 unexpected_end:
925   printf ("Missing closing parenthesis in arguments to %s.\n",
926           function.string);
927   /* Fall through. */
928 error:
929   string_array_destroy (args);
930   return false;
931 }
932
933 static bool
934 unquote_string (const char *s, struct string *content)
935 {
936   struct string_lexer slex;
937   string_lexer_init (&slex, s, strlen (s), SEG_MODE_INTERACTIVE /* XXX */,
938                      true);
939
940   struct token token1;
941   if (!string_lexer_next (&slex, &token1))
942     return false;
943
944   if (token1.type != T_STRING)
945     {
946       token_uninit (&token1);
947       return false;
948     }
949
950   struct token token2;
951   if (string_lexer_next (&slex, &token2))
952     {
953       token_uninit (&token1);
954       token_uninit (&token2);
955       return false;
956     }
957
958   ds_put_substring (content, token1.string);
959   token_uninit (&token1);
960   return true;
961 }
962
963 static const char *
964 unquote_string_in_place (const char *s, struct string *tmp)
965 {
966   ds_init_empty (tmp);
967   return unquote_string (s, tmp) ? ds_cstr (tmp) : s;
968 }
969
970 static bool
971 parse_integer (const char *s, int *np)
972 {
973   errno = 0;
974
975   char *tail;
976   long int n = strtol (s, &tail, 10);
977   *np = n < INT_MIN ? INT_MIN : n > INT_MAX ? INT_MAX : n;
978   tail += strspn (tail, CC_SPACES);
979   return *tail == '\0' && errno != ERANGE && n == *np;
980 }
981
982 static bool
983 expand_macro_function (struct parse_macro_function_ctx *ctx,
984                        struct string *output,
985                        size_t *input_consumed)
986 {
987   struct string_array args;
988
989   if (parse_macro_function (ctx, &args, ss_cstr ("!length"), 1, 1,
990                             input_consumed))
991     ds_put_format (output, "%zu", strlen (args.strings[0]));
992   else if (parse_macro_function (ctx, &args, ss_cstr ("!blanks"), 1, 1,
993                                  input_consumed))
994     {
995       int n;
996       if (!parse_integer (args.strings[0], &n))
997         {
998           printf ("argument to !BLANKS must be non-negative integer (not \"%s\")\n", args.strings[0]);
999           string_array_destroy (&args);
1000           return false;
1001         }
1002
1003       ds_put_byte_multiple (output, ' ', n);
1004     }
1005   else if (parse_macro_function (ctx, &args, ss_cstr ("!concat"), 1, INT_MAX,
1006                                  input_consumed))
1007     {
1008       for (size_t i = 0; i < args.n; i++)
1009         if (!unquote_string (args.strings[i], output))
1010           ds_put_cstr (output, args.strings[i]);
1011     }
1012   else if (parse_macro_function (ctx, &args, ss_cstr ("!head"), 1, 1,
1013                                  input_consumed))
1014     {
1015       struct string tmp;
1016       const char *s = unquote_string_in_place (args.strings[0], &tmp);
1017
1018       struct macro_tokens mts = { .n = 0 };
1019       macro_tokens_from_string (&mts, ss_cstr (s), SEG_MODE_INTERACTIVE /* XXX */);
1020       if (mts.n > 0)
1021         ds_put_substring (output, mts.mts[0].representation);
1022       macro_tokens_uninit (&mts);
1023       ds_destroy (&tmp);
1024     }
1025   else if (parse_macro_function (ctx, &args, ss_cstr ("!index"), 2, 2,
1026                                  input_consumed))
1027     {
1028       const char *haystack = args.strings[0];
1029       const char *needle = strstr (haystack, args.strings[1]);
1030       ds_put_format (output, "%zu", needle ? needle - haystack + 1 : 0);
1031     }
1032   else if (parse_macro_function (ctx, &args, ss_cstr ("!quote"), 1, 1,
1033                                  input_consumed))
1034     {
1035       if (unquote_string (args.strings[0], NULL))
1036         ds_put_cstr (output, args.strings[0]);
1037       else
1038         {
1039           ds_extend (output, strlen (args.strings[0]) + 2);
1040           ds_put_byte (output, '\'');
1041           for (const char *p = args.strings[0]; *p; p++)
1042             {
1043               if (*p == '\'')
1044                 ds_put_byte (output, '\'');
1045               ds_put_byte (output, *p);
1046             }
1047           ds_put_byte (output, '\'');
1048         }
1049     }
1050   else if (parse_macro_function (ctx, &args, ss_cstr ("!substr"), 2, 3,
1051                                  input_consumed))
1052     {
1053       int start;
1054       if (!parse_integer (args.strings[1], &start) || start < 1)
1055         {
1056           printf ("second argument to !SUBSTR must be positive integer (not \"%s\")\n", args.strings[1]);
1057           string_array_destroy (&args);
1058           return false;
1059         }
1060
1061       int count = INT_MAX;
1062       if (args.n > 2 && (!parse_integer (args.strings[2], &count) || count < 0))
1063         {
1064           printf ("third argument to !SUBSTR must be non-negative integer (not \"%s\")\n", args.strings[1]);
1065           string_array_destroy (&args);
1066           return false;
1067         }
1068
1069       struct substring s = ss_cstr (args.strings[0]);
1070       ds_put_substring (output, ss_substr (s, start - 1, count));
1071     }
1072   else if (parse_macro_function (ctx, &args, ss_cstr ("!tail"), 1, 1,
1073                                  input_consumed))
1074     {
1075       struct string tmp;
1076       const char *s = unquote_string_in_place (args.strings[0], &tmp);
1077
1078       struct macro_tokens mts = { .n = 0 };
1079       macro_tokens_from_string (&mts, ss_cstr (s), SEG_MODE_INTERACTIVE /* XXX */);
1080       if (mts.n > 1)
1081         {
1082           struct macro_tokens tail = { .mts = mts.mts + 1, .n = mts.n - 1 };
1083           macro_tokens_to_representation (&tail, output, NULL, NULL);
1084         }
1085       macro_tokens_uninit (&mts);
1086       ds_destroy (&tmp);
1087     }
1088   else if (parse_macro_function (ctx, &args, ss_cstr ("!unquote"), 1, 1,
1089                                  input_consumed))
1090     {
1091       if (!unquote_string (args.strings[0], output))
1092         ds_put_cstr (output, args.strings[0]);
1093     }
1094   else if (parse_macro_function (ctx, &args, ss_cstr ("!upcase"), 1, 1,
1095                                  input_consumed))
1096     {
1097       struct string tmp;
1098       const char *s = unquote_string_in_place (args.strings[0], &tmp);
1099       char *upper = utf8_to_upper (s);
1100       ds_put_cstr (output, upper);
1101       free (upper);
1102       ds_destroy (&tmp);
1103     }
1104   else if (parse_macro_function (ctx, &args, ss_cstr ("!eval"), 1, 1,
1105                                  input_consumed))
1106     {
1107       struct macro_tokens mts = { .n = 0 };
1108       macro_tokens_from_string (&mts, ss_cstr (args.strings[0]),
1109                                 SEG_MODE_INTERACTIVE /* XXX */);
1110       struct macro_tokens exp = { .n = 0 };
1111       macro_expand (&mts, ctx->nesting_countdown - 1, ctx->macros, ctx->me,
1112                     ctx->vars,
1113                     &(struct macro_expansion_stack) {
1114                       .name = "!EVAL",
1115                       .next = ctx->stack,
1116                     }, ctx->expand, NULL, &exp);
1117       macro_tokens_to_representation (&exp, output, NULL, NULL);
1118       macro_tokens_uninit (&exp);
1119       macro_tokens_uninit (&mts);
1120     }
1121   else if (ctx->n_input > 0
1122            && ctx->input[0].token.type == T_MACRO_ID
1123            && ss_equals_case (ctx->input[0].token.string, ss_cstr ("!null")))
1124     {
1125       *input_consumed = 1;
1126       return true;
1127     }
1128   else
1129     return false;
1130
1131   string_array_destroy (&args);
1132   return true;
1133 }
1134
1135 struct expr_context
1136   {
1137     int nesting_countdown;
1138     const struct macro_set *macros;
1139     const struct macro_expander *me;
1140     const struct macro_expansion_stack *stack;
1141     struct string_map *vars;
1142     bool *expand;
1143   };
1144
1145 static char *macro_evaluate_or (const struct expr_context *ctx,
1146                                 const struct macro_token **tokens,
1147                                 const struct macro_token *end);
1148
1149 static char *
1150 macro_evaluate_literal (const struct expr_context *ctx,
1151                         const struct macro_token **tokens,
1152                         const struct macro_token *end)
1153 {
1154   const struct macro_token *p = *tokens;
1155   if (p >= end)
1156     return NULL;
1157   if (p->token.type == T_LPAREN)
1158     {
1159       p++;
1160       char *value = macro_evaluate_or (ctx, &p, end);
1161       if (!value)
1162         return NULL;
1163       if (p >= end || p->token.type != T_RPAREN)
1164         {
1165           free (value);
1166           printf ("expecting ')' in macro expression\n");
1167           return NULL;
1168         }
1169       p++;
1170       *tokens = p;
1171       return value;
1172     }
1173
1174   struct parse_macro_function_ctx fctx = {
1175     .input = p,
1176     .n_input = end - p,
1177     .nesting_countdown = ctx->nesting_countdown,
1178     .macros = ctx->macros,
1179     .me = ctx->me,
1180     .stack = ctx->stack,
1181     .vars = ctx->vars,
1182     .expand = ctx->expand,
1183   };
1184   struct string function_output = DS_EMPTY_INITIALIZER;
1185   size_t function_consumed = parse_function_arg (&fctx, 0, &function_output);
1186   struct string unquoted = DS_EMPTY_INITIALIZER;
1187   if (unquote_string (ds_cstr (&function_output), &unquoted))
1188     {
1189       ds_swap (&function_output, &unquoted);
1190       ds_destroy (&unquoted);
1191     }
1192   *tokens = p + function_consumed;
1193   return ds_steal_cstr (&function_output);
1194 }
1195
1196 /* Returns true if MT is valid as a macro operator.  Only operators written as
1197    symbols (e.g. <>) are usable in macro expressions, not operator written as
1198    letters (e.g. EQ). */
1199 static bool
1200 is_macro_operator (const struct macro_token *mt)
1201 {
1202   return (mt->representation.length > 0
1203           && !c_isalpha (mt->representation.string[0]));
1204 }
1205
1206 static enum token_type
1207 parse_relational_op (const struct macro_token *mt)
1208 {
1209   switch (mt->token.type)
1210     {
1211     case T_EQUALS:
1212       return T_EQ;
1213
1214     case T_NE:
1215     case T_LT:
1216     case T_GT:
1217     case T_LE:
1218     case T_GE:
1219       return is_macro_operator (mt) ? mt->token.type : T_STOP;
1220
1221     case T_MACRO_ID:
1222       return (ss_equals_case (mt->token.string, ss_cstr ("!EQ")) ? T_EQ
1223               : ss_equals_case (mt->token.string, ss_cstr ("!NE")) ? T_NE
1224               : ss_equals_case (mt->token.string, ss_cstr ("!LT")) ? T_LT
1225               : ss_equals_case (mt->token.string, ss_cstr ("!GT")) ? T_GT
1226               : ss_equals_case (mt->token.string, ss_cstr ("!LE")) ? T_LE
1227               : ss_equals_case (mt->token.string, ss_cstr ("!GE")) ? T_GE
1228               : T_STOP);
1229
1230     default:
1231       return T_STOP;
1232     }
1233 }
1234
1235 static char *
1236 macro_evaluate_relational (const struct expr_context *ctx,
1237                            const struct macro_token **tokens,
1238                            const struct macro_token *end)
1239 {
1240   const struct macro_token *p = *tokens;
1241   char *lhs = macro_evaluate_literal (ctx, &p, end);
1242   if (!lhs)
1243     return NULL;
1244
1245   enum token_type op = p >= end ? T_STOP : parse_relational_op (p);
1246   if (op == T_STOP)
1247     {
1248       *tokens = p;
1249       return lhs;
1250     }
1251   p++;
1252
1253   char *rhs = macro_evaluate_literal (ctx, &p, end);
1254   if (!rhs)
1255     {
1256       free (lhs);
1257       return NULL;
1258     }
1259
1260   struct string lhs_tmp, rhs_tmp;
1261   int cmp = strcmp/*XXX*/ (unquote_string_in_place (lhs, &lhs_tmp),
1262                            unquote_string_in_place (rhs, &rhs_tmp));
1263   ds_destroy (&lhs_tmp);
1264   ds_destroy (&rhs_tmp);
1265
1266   free (lhs);
1267   free (rhs);
1268
1269   bool b = (op == T_EQUALS || op == T_EQ ? !cmp
1270             : op == T_NE ? cmp
1271             : op == T_LT ? cmp < 0
1272             : op == T_GT ? cmp > 0
1273             : op == T_LE ? cmp <= 0
1274             :/*op == T_GE*/cmp >= 0);
1275
1276   *tokens = p;
1277   return xstrdup (b ? "1" : "0");
1278 }
1279
1280 static char *
1281 macro_evaluate_not (const struct expr_context *ctx,
1282                     const struct macro_token **tokens,
1283                     const struct macro_token *end)
1284 {
1285   const struct macro_token *p = *tokens;
1286
1287   unsigned int negations = 0;
1288   while (p < end
1289          && (ss_equals_case (p->representation, ss_cstr ("!NOT"))
1290              || ss_equals (p->representation, ss_cstr ("~"))))
1291     {
1292       p++;
1293       negations++;
1294     }
1295
1296   char *operand = macro_evaluate_relational (ctx, &p, end);
1297   if (!operand || !negations)
1298     {
1299       *tokens = p;
1300       return operand;
1301     }
1302
1303   bool b = strcmp (operand, "0") ^ (negations & 1);
1304   free (operand);
1305   *tokens = p;
1306   return xstrdup (b ? "1" : "0");
1307 }
1308
1309 static char *
1310 macro_evaluate_and (const struct expr_context *ctx,
1311                     const struct macro_token **tokens,
1312                     const struct macro_token *end)
1313 {
1314   const struct macro_token *p = *tokens;
1315   char *lhs = macro_evaluate_not (ctx, &p, end);
1316   if (!lhs)
1317     return NULL;
1318
1319   while (p < end
1320          && (ss_equals_case (p->representation, ss_cstr ("!AND"))
1321              || ss_equals (p->representation, ss_cstr ("&"))))
1322     {
1323       p++;
1324       char *rhs = macro_evaluate_not (ctx, &p, end);
1325       if (!rhs)
1326         {
1327           free (lhs);
1328           return NULL;
1329         }
1330
1331       bool b = strcmp (lhs, "0") && strcmp (rhs, "0");
1332       free (lhs);
1333       free (rhs);
1334       lhs = xstrdup (b ? "1" : "0");
1335     }
1336   *tokens = p;
1337   return lhs;
1338 }
1339
1340 static char *
1341 macro_evaluate_or (const struct expr_context *ctx,
1342                    const struct macro_token **tokens,
1343                    const struct macro_token *end)
1344 {
1345   const struct macro_token *p = *tokens;
1346   char *lhs = macro_evaluate_and (ctx, &p, end);
1347   if (!lhs)
1348     return NULL;
1349
1350   while (p < end
1351          && (ss_equals_case (p->representation, ss_cstr ("!OR"))
1352              || ss_equals (p->representation, ss_cstr ("|"))))
1353     {
1354       p++;
1355       char *rhs = macro_evaluate_and (ctx, &p, end);
1356       if (!rhs)
1357         {
1358           free (lhs);
1359           return NULL;
1360         }
1361
1362       bool b = strcmp (lhs, "0") || strcmp (rhs, "0");
1363       free (lhs);
1364       free (rhs);
1365       lhs = xstrdup (b ? "1" : "0");
1366     }
1367   *tokens = p;
1368   return lhs;
1369 }
1370
1371 static char *
1372 macro_evaluate_expression (const struct macro_token **tokens, size_t n_tokens,
1373                            int nesting_countdown, const struct macro_set *macros,
1374                            const struct macro_expander *me,
1375                            const struct macro_expansion_stack *stack,
1376                            struct string_map *vars, bool *expand)
1377 {
1378   const struct expr_context ctx = {
1379     .nesting_countdown = nesting_countdown,
1380     .macros = macros,
1381     .me = me,
1382     .stack = stack,
1383     .vars = vars,
1384     .expand = expand,
1385   };
1386   return macro_evaluate_or (&ctx, tokens, *tokens + n_tokens);
1387 }
1388
1389 static bool
1390 macro_evaluate_number (const struct macro_token **tokens, size_t n_tokens,
1391                        int nesting_countdown, const struct macro_set *macros,
1392                        const struct macro_expander *me,
1393                        const struct macro_expansion_stack *stack,
1394                        struct string_map *vars,
1395                        bool *expand, double *number)
1396 {
1397   char *s = macro_evaluate_expression (tokens, n_tokens, nesting_countdown,
1398                                        macros, me, stack, vars, expand);
1399   if (!s)
1400     return false;
1401
1402   struct macro_tokens mts = { .n = 0 };
1403   macro_tokens_from_string (&mts, ss_cstr (s), SEG_MODE_INTERACTIVE /* XXX */);
1404   if (mts.n != 1 || !token_is_number (&mts.mts[0].token))
1405     {
1406       macro_tokens_print (&mts, stdout);
1407       printf ("expression must evaluate to a number (not %s)\n", s);
1408       free (s);
1409       macro_tokens_uninit (&mts);
1410       return false;
1411     }
1412
1413   *number = token_number (&mts.mts[0].token);
1414   free (s);
1415   macro_tokens_uninit (&mts);
1416   return true;
1417 }
1418
1419 static const struct macro_token *
1420 find_ifend_clause (const struct macro_token *p, const struct macro_token *end)
1421 {
1422   size_t nesting = 0;
1423   for (; p < end; p++)
1424     {
1425       if (p->token.type != T_MACRO_ID)
1426         continue;
1427
1428       if (ss_equals_case (p->token.string, ss_cstr ("!IF")))
1429         nesting++;
1430       else if (ss_equals_case (p->token.string, ss_cstr ("!IFEND")))
1431         {
1432           if (!nesting)
1433             return p;
1434           nesting--;
1435         }
1436       else if (ss_equals_case (p->token.string, ss_cstr ("!ELSE")) && !nesting)
1437         return p;
1438     }
1439   return NULL;
1440 }
1441
1442 static size_t
1443 macro_expand_if (const struct macro_token *tokens, size_t n_tokens,
1444                  int nesting_countdown, const struct macro_set *macros,
1445                  const struct macro_expander *me,
1446                  const struct macro_expansion_stack *stack,
1447                  struct string_map *vars,
1448                  bool *expand, bool *break_, struct macro_tokens *exp)
1449 {
1450   const struct macro_token *p = tokens;
1451   const struct macro_token *end = tokens + n_tokens;
1452
1453   if (p >= end || !ss_equals_case (p->token.string, ss_cstr ("!IF")))
1454     return 0;
1455
1456   p++;
1457   char *result = macro_evaluate_expression (&p, end - p,
1458                                             nesting_countdown, macros, me,
1459                                             stack, vars, expand);
1460   if (!result)
1461     return 0;
1462   bool b = strcmp (result, "0");
1463   free (result);
1464
1465   if (p >= end
1466       || p->token.type != T_MACRO_ID
1467       || !ss_equals_case (p->token.string, ss_cstr ("!THEN")))
1468     {
1469       printf ("!THEN expected\n");
1470       return 0;
1471     }
1472
1473   const struct macro_token *start_then = p + 1;
1474   const struct macro_token *end_then = find_ifend_clause (start_then, end);
1475   if (!end_then)
1476     {
1477       printf ("!ELSE or !IFEND expected\n");
1478       return 0;
1479     }
1480
1481   const struct macro_token *start_else, *end_if;
1482   if (ss_equals_case (end_then->token.string, ss_cstr ("!ELSE")))
1483     {
1484       start_else = end_then + 1;
1485       end_if = find_ifend_clause (start_else, end);
1486       if (!end_if
1487           || !ss_equals_case (end_if->token.string, ss_cstr ("!IFEND")))
1488         {
1489           printf ("!IFEND expected\n");
1490           return 0;
1491         }
1492     }
1493   else
1494     {
1495       start_else = NULL;
1496       end_if = end_then;
1497     }
1498
1499   const struct macro_token *start;
1500   size_t n;
1501   if (b)
1502     {
1503       start = start_then;
1504       n = end_then - start_then;
1505     }
1506   else if (start_else)
1507     {
1508       start = start_else;
1509       n = end_if - start_else;
1510     }
1511   else
1512     {
1513       start = NULL;
1514       n = 0;
1515     }
1516
1517   if (n)
1518     {
1519       struct macro_tokens mts = {
1520         .mts = CONST_CAST (struct macro_token *, start),
1521         .n = n,
1522       };
1523       macro_expand (&mts, nesting_countdown, macros, me, vars,
1524                     &(struct macro_expansion_stack) {
1525                       .name = "!IF",
1526                       .next = stack,
1527                     },
1528                     expand, break_, exp);
1529     }
1530   return (end_if + 1) - tokens;
1531 }
1532
1533 static void PRINTF_FORMAT (2, 3)
1534 macro_error (const struct macro_expansion_stack *stack,
1535              const char *format, ...)
1536 {
1537   va_list args;
1538   va_start (args, format);
1539   char *s = xvasprintf (format, args);
1540   va_end (args);
1541
1542   /* foo.sps:12: While expanding macro 'innermost',
1543      foo.sps:23: inside expansion of 'next_inner',
1544      foo.sps:34: inside expansion of 'next_inner2',
1545      foo.sps:45: inside expansion of 'outermost':
1546      error. */
1547   struct string header = DS_EMPTY_INITIALIZER;
1548   ds_put_format (&header, "While expanding \"%s\"", stack->name);
1549   while ((stack = stack->next) != NULL)
1550     ds_put_format (&header, ", inside expansion of \"%s\"", stack->name);
1551
1552   msg (SE, "%s: %s", ds_cstr (&header), s);
1553
1554   ds_destroy (&header);
1555   free (s);
1556 }
1557
1558 static size_t
1559 macro_parse_let (const struct macro_token *tokens, size_t n_tokens,
1560                  int nesting_countdown, const struct macro_set *macros,
1561                  const struct macro_expander *me,
1562                  const struct macro_expansion_stack *stack,
1563                  struct string_map *vars, bool *expand)
1564 {
1565   const struct macro_token *p = tokens;
1566   const struct macro_token *end = tokens + n_tokens;
1567
1568   if (p >= end || !ss_equals_case (p->token.string, ss_cstr ("!LET")))
1569     return 0;
1570   p++;
1571
1572   if (p >= end || p->token.type != T_MACRO_ID)
1573     {
1574       macro_error (stack, "expected macro variable name following !LET");
1575       return 0;
1576     }
1577   const struct substring var_name = p->token.string;
1578   if (is_macro_keyword (var_name)
1579       || macro_find_parameter_by_name (me->macro, var_name))
1580     {
1581       printf ("cannot use argument name or macro keyword %.*s as !LET variable\n", (int) var_name.length, var_name.string);
1582       return 0;
1583     }
1584   p++;
1585
1586   if (p >= end || p->token.type != T_EQUALS)
1587     {
1588       printf ("expected = following !LET\n");
1589       return 0;
1590     }
1591   p++;
1592
1593   char *value = macro_evaluate_expression (&p, end - p,
1594                                            nesting_countdown, macros, me, stack,
1595                                            vars, expand);
1596   if (!value)
1597     return 0;
1598
1599   string_map_replace_nocopy (vars, ss_xstrdup (var_name), value);
1600   return p - tokens;
1601 }
1602
1603 static const struct macro_token *
1604 find_doend (const struct macro_token *p, const struct macro_token *end)
1605 {
1606   size_t nesting = 0;
1607   for (; p < end; p++)
1608     {
1609       if (p->token.type != T_MACRO_ID)
1610         continue;
1611
1612       if (ss_equals_case (p->token.string, ss_cstr ("!DO")))
1613         nesting++;
1614       else if (ss_equals_case (p->token.string, ss_cstr ("!DOEND")))
1615         {
1616           if (!nesting)
1617             return p;
1618           nesting--;
1619         }
1620     }
1621   printf ("missing !DOEND\n");
1622   return NULL;
1623 }
1624
1625 static size_t
1626 macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
1627                  int nesting_countdown, const struct macro_set *macros,
1628                  const struct macro_expander *me,
1629                  const struct macro_expansion_stack *stack,
1630                  struct string_map *vars,
1631                  bool *expand, struct macro_tokens *exp)
1632 {
1633   const struct macro_token *p = tokens;
1634   const struct macro_token *end = tokens + n_tokens;
1635
1636   if (p >= end || !ss_equals_case (p->token.string, ss_cstr ("!DO")))
1637     return 0;
1638   p++;
1639
1640   if (p >= end || p->token.type != T_MACRO_ID)
1641     {
1642       printf ("expected macro variable name following !DO\n");
1643       return 0;
1644     }
1645   const struct substring var_name = p->token.string;
1646   if (is_macro_keyword (var_name)
1647       || macro_find_parameter_by_name (me->macro, var_name))
1648     {
1649       printf ("cannot use argument name or macro keyword %.*s as !DO variable\n", (int) var_name.length, var_name.string);
1650       return 0;
1651     }
1652   p++;
1653
1654   struct macro_expansion_stack next_stack = {
1655     .name = "!DO", .next = stack,
1656   };
1657   int miterate = settings_get_miterate ();
1658   if (p < end && p->token.type == T_MACRO_ID
1659       && ss_equals_case (p->token.string, ss_cstr ("!IN")))
1660     {
1661       p++;
1662       char *list = macro_evaluate_expression (&p, end - p,
1663                                               nesting_countdown, macros, me,
1664                                               &next_stack, vars, expand);
1665       if (!list)
1666         return 0;
1667
1668       struct macro_tokens items = { .n = 0 };
1669       macro_tokens_from_string (&items, ss_cstr (list),
1670                                 SEG_MODE_INTERACTIVE /* XXX */);
1671       free (list);
1672
1673       const struct macro_token *do_end = find_doend (p, end);
1674       if (!do_end)
1675         {
1676           macro_tokens_uninit (&items);
1677           return 0;
1678         }
1679
1680       const struct macro_tokens inner = {
1681         .mts = CONST_CAST (struct macro_token *, p),
1682         .n = do_end - p
1683       };
1684       for (size_t i = 0; i < items.n; i++)
1685         {
1686           if (i >= miterate)
1687             {
1688               printf ("exceeded maximum number of iterations %d\n", miterate);
1689               break;
1690             }
1691           string_map_replace_nocopy (vars, ss_xstrdup (var_name),
1692                                      ss_xstrdup (items.mts[i].representation));
1693
1694           bool break_ = false;
1695           macro_expand (&inner, nesting_countdown, macros,
1696                         me, vars, &next_stack, expand, &break_, exp);
1697           if (break_)
1698             break;
1699         }
1700       return do_end - tokens + 1;
1701     }
1702   else if (p < end && p->token.type == T_EQUALS)
1703     {
1704       p++;
1705       double first;
1706       if (!macro_evaluate_number (&p, end - p, nesting_countdown, macros, me,
1707                                   &next_stack, vars, expand, &first))
1708         return 0;
1709
1710       if (p >= end || p->token.type != T_MACRO_ID
1711           || !ss_equals_case (p->token.string, ss_cstr ("!TO")))
1712         {
1713           printf ("expecting !TO\n");
1714           return 0;
1715         }
1716       p++;
1717
1718       double last;
1719       if (!macro_evaluate_number (&p, end - p, nesting_countdown, macros, me,
1720                                   &next_stack, vars, expand, &last))
1721         return 0;
1722
1723       double by = 1.0;
1724       if (p < end && p->token.type == T_MACRO_ID
1725           && ss_equals_case (p->token.string, ss_cstr ("!BY")))
1726         {
1727           p++;
1728           if (!macro_evaluate_number (&p, end - p, nesting_countdown, macros, me,
1729                                       &next_stack, vars, expand, &by))
1730             return 0;
1731
1732           if (by == 0.0)
1733             {
1734               printf ("!BY value cannot be zero\n");
1735               return 0;
1736             }
1737         }
1738
1739       const struct macro_token *do_end = find_doend (p, end);
1740       if (!do_end)
1741         return 0;
1742       const struct macro_tokens inner = {
1743         .mts = CONST_CAST (struct macro_token *, p),
1744         .n = do_end - p
1745       };
1746
1747       if ((by > 0 && first <= last) || (by < 0 && first >= last))
1748         {
1749           int i = 0;
1750           for (double index = first;
1751                by > 0 ? (index <= last) : (index >= last);
1752                index += by)
1753             {
1754               if (i++ > miterate)
1755                 {
1756                   printf ("exceeded maximum number of iterations %d\n",
1757                           miterate);
1758                   break;
1759                 }
1760
1761               char index_s[DBL_BUFSIZE_BOUND];
1762               c_dtoastr (index_s, sizeof index_s, 0, 0, index);
1763               string_map_replace_nocopy (vars, ss_xstrdup (var_name),
1764                                          xstrdup (index_s));
1765
1766               bool break_ = false;
1767               macro_expand (&inner, nesting_countdown, macros,
1768                             me, vars, &next_stack, expand, &break_, exp);
1769               if (break_)
1770                 break;
1771             }
1772         }
1773
1774       return do_end - tokens + 1;
1775     }
1776   else
1777     {
1778       printf ("expecting = or !IN in !DO loop\n");
1779       return 0;
1780     }
1781 }
1782
1783 static void
1784 macro_expand (const struct macro_tokens *mts,
1785               int nesting_countdown, const struct macro_set *macros,
1786               const struct macro_expander *me, struct string_map *vars,
1787               const struct macro_expansion_stack *stack,
1788               bool *expand, bool *break_, struct macro_tokens *exp)
1789 {
1790   if (nesting_countdown <= 0)
1791     {
1792       printf ("maximum nesting level exceeded\n");
1793       for (size_t i = 0; i < mts->n; i++)
1794         macro_tokens_add (exp, &mts->mts[i]);
1795       return;
1796     }
1797
1798   struct string_map own_vars = STRING_MAP_INITIALIZER (own_vars);
1799   if (!vars)
1800     vars = &own_vars;
1801
1802   for (size_t i = 0; i < mts->n && (!break_ || !*break_); i++)
1803     {
1804       const struct macro_token *mt = &mts->mts[i];
1805       const struct token *token = &mt->token;
1806       if (token->type == T_MACRO_ID && me)
1807         {
1808           const struct macro_param *param = macro_find_parameter_by_name (
1809             me->macro, token->string);
1810           if (param)
1811             {
1812               const struct macro_tokens *arg = me->args[param - me->macro->params];
1813               //macro_tokens_print (arg, stdout);
1814               if (*expand && param->expand_arg)
1815                 macro_expand (arg, nesting_countdown, macros, NULL, NULL,
1816                               &(struct macro_expansion_stack) {
1817                                 .name = param->name,
1818                                 .next = stack,
1819                               }, expand, break_, exp);
1820               else
1821                 for (size_t i = 0; i < arg->n; i++)
1822                   macro_tokens_add (exp, &arg->mts[i]);
1823               continue;
1824             }
1825
1826           if (is_bang_star (mts->mts, mts->n, i))
1827             {
1828               for (size_t j = 0; j < me->macro->n_params; j++)
1829                 {
1830                   const struct macro_param *param = &me->macro->params[j];
1831                   if (!param->positional)
1832                     break;
1833
1834                   const struct macro_tokens *arg = me->args[j];
1835                   if (*expand && param->expand_arg)
1836                     macro_expand (arg, nesting_countdown, macros, NULL, NULL,
1837                                   &(struct macro_expansion_stack) {
1838                                     .name = "!*",
1839                                     .next = stack,
1840                                   }, expand, break_, exp);
1841                   else
1842                     for (size_t k = 0; k < arg->n; k++)
1843                       macro_tokens_add (exp, &arg->mts[k]);
1844                 }
1845               i++;
1846               continue;
1847             }
1848
1849           size_t n = macro_expand_if (&mts->mts[i], mts->n - i,
1850                                       nesting_countdown, macros, me, stack,
1851                                       vars, expand, break_, exp);
1852           if (n > 0)
1853             {
1854               i += n - 1;
1855               continue;
1856             }
1857         }
1858
1859       if (token->type == T_MACRO_ID && vars)
1860         {
1861           const char *value = string_map_find__ (vars, token->string.string,
1862                                                  token->string.length);
1863           if (value)
1864             {
1865               macro_tokens_from_string (exp, ss_cstr (value),
1866                                         SEG_MODE_INTERACTIVE /* XXX */);
1867               continue;
1868             }
1869         }
1870
1871       if (*expand)
1872         {
1873           struct macro_expander *subme;
1874           int retval = macro_expander_create (macros, token, &subme);
1875           for (size_t j = 1; !retval; j++)
1876             {
1877               const struct macro_token endcmd = { .token = { .type = T_ENDCMD } };
1878               retval = macro_expander_add (
1879                 subme, i + j < mts->n ? &mts->mts[i + j] : &endcmd);
1880             }
1881           if (retval > 0)
1882             {
1883               i += retval - 1;
1884               macro_expand (&subme->macro->body, nesting_countdown - 1, macros,
1885                             subme, NULL,
1886                             &(struct macro_expansion_stack) {
1887                               .name = subme->macro->name,
1888                               .next = stack,
1889                             }, expand, break_, exp);
1890               macro_expander_destroy (subme);
1891               continue;
1892             }
1893
1894           macro_expander_destroy (subme);
1895         }
1896
1897       if (token->type != T_MACRO_ID)
1898         {
1899           macro_tokens_add (exp, mt);
1900           continue;
1901         }
1902
1903       if (ss_equals_case (token->string, ss_cstr ("!break")))
1904         {
1905           if (!break_)
1906             printf ("!BREAK outside !DO\n");
1907           else
1908             {
1909               *break_ = true;
1910               break;
1911             }
1912         }
1913
1914       struct parse_macro_function_ctx ctx = {
1915         .input = &mts->mts[i],
1916         .n_input = mts->n - i,
1917         .nesting_countdown = nesting_countdown,
1918         .macros = macros,
1919         .me = me,
1920         .stack = stack,
1921         .vars = vars,
1922         .expand = expand,
1923       };
1924       struct string function_output = DS_EMPTY_INITIALIZER;
1925       size_t function_consumed;
1926       if (expand_macro_function (&ctx, &function_output, &function_consumed))
1927         {
1928           i += function_consumed - 1;
1929
1930           macro_tokens_from_string (exp, function_output.ss,
1931                                     SEG_MODE_INTERACTIVE /* XXX */);
1932           ds_destroy (&function_output);
1933
1934           continue;
1935         }
1936
1937       size_t n = macro_parse_let (&mts->mts[i], mts->n - i,
1938                                   nesting_countdown, macros, me, stack,
1939                                   vars, expand);
1940       if (n > 0)
1941         {
1942           i += n - 1;
1943           continue;
1944         }
1945
1946       n = macro_expand_do (&mts->mts[i], mts->n - i,
1947                            nesting_countdown, macros, me, stack, vars,
1948                            expand, exp);
1949       if (n > 0)
1950         {
1951           i += n - 1;
1952           continue;
1953         }
1954
1955       if (ss_equals_case (token->string, ss_cstr ("!onexpand")))
1956         *expand = true;
1957       else if (ss_equals_case (token->string, ss_cstr ("!offexpand")))
1958         *expand = false;
1959       else
1960         macro_tokens_add (exp, mt);
1961     }
1962   if (vars == &own_vars)
1963     string_map_destroy (&own_vars);
1964 }
1965
1966 void
1967 macro_expander_get_expansion (struct macro_expander *me, struct macro_tokens *exp)
1968 {
1969   bool expand = true;
1970   struct macro_expansion_stack stack = { .name = me->macro->name };
1971   macro_expand (&me->macro->body, settings_get_mnest (),
1972                 me->macros, me, NULL, &stack, &expand, NULL, exp);
1973 }
1974