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