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