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