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