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