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