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