718f268e658505dd3c74f7e76cbafd3c28ad011e
[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/segment.h"
27 #include "language/lexer/scan.h"
28 #include "libpspp/assertion.h"
29 #include "libpspp/cast.h"
30 #include "libpspp/i18n.h"
31 #include "libpspp/message.h"
32 #include "libpspp/str.h"
33 #include "libpspp/string-array.h"
34
35 #include "gl/c-ctype.h"
36
37 #include "gettext.h"
38 #define _(msgid) gettext (msgid)
39
40 void
41 macro_token_copy (struct macro_token *dst, const struct macro_token *src)
42 {
43   token_copy (&dst->token, &src->token);
44   ss_alloc_substring (&dst->representation, src->representation);
45 }
46
47 void
48 macro_token_uninit (struct macro_token *mt)
49 {
50   token_uninit (&mt->token);
51   ss_dealloc (&mt->representation);
52 }
53
54 void
55 macro_token_to_representation (struct macro_token *mt, struct string *s)
56 {
57   ds_put_substring (s, mt->representation);
58 }
59
60 void
61 macro_tokens_copy (struct macro_tokens *dst, const struct macro_tokens *src)
62 {
63   *dst = (struct macro_tokens) {
64     .mts = xmalloc (src->n * sizeof *dst->mts),
65     .n = src->n,
66     .allocated = src->n,
67   };
68   for (size_t i = 0; i < src->n; i++)
69     macro_token_copy (&dst->mts[i], &src->mts[i]);
70 }
71
72 void
73 macro_tokens_uninit (struct macro_tokens *mts)
74 {
75   for (size_t i = 0; i < mts->n; i++)
76     macro_token_uninit (&mts->mts[i]);
77   free (mts->mts);
78 }
79
80 struct macro_token *
81 macro_tokens_add_uninit (struct macro_tokens *mts)
82 {
83   if (mts->n >= mts->allocated)
84     mts->mts = x2nrealloc (mts->mts, &mts->allocated, sizeof *mts->mts);
85   return &mts->mts[mts->n++];
86 }
87
88 void
89 macro_tokens_add (struct macro_tokens *mts, const struct macro_token *mt)
90 {
91   macro_token_copy (macro_tokens_add_uninit (mts), mt);
92 }
93
94 void
95 macro_tokens_from_string (struct macro_tokens *mts, const struct substring src,
96                           enum segmenter_mode mode)
97 {
98   struct state
99     {
100       struct segmenter segmenter;
101       struct substring body;
102     };
103
104   struct state state = {
105     .segmenter = SEGMENTER_INIT (mode),
106     .body = src,
107   };
108   struct state saved = state;
109
110   while (state.body.length > 0)
111     {
112       struct macro_token mt = {
113         .token = { .type = T_STOP },
114         .representation = { .string = state.body.string },
115       };
116       struct token *token = &mt.token;
117
118       struct scanner scanner;
119       scanner_init (&scanner, token);
120
121       for (;;)
122         {
123           enum segment_type type;
124           int seg_len = segmenter_push (&state.segmenter, state.body.string,
125                                         state.body.length, true, &type);
126           assert (seg_len >= 0);
127
128           struct substring segment = ss_head (state.body, seg_len);
129           ss_advance (&state.body, seg_len);
130
131           enum scan_result result = scanner_push (&scanner, type, segment, token);
132           if (result == SCAN_SAVE)
133             saved = state;
134           else if (result == SCAN_BACK)
135             {
136               state = saved;
137               break;
138             }
139           else if (result == SCAN_DONE)
140             break;
141         }
142
143       /* We have a token in 'token'. */
144       if (is_scan_type (token->type))
145         {
146           if (token->type != SCAN_SKIP)
147             {
148               printf ("error\n");
149               /* XXX report error */
150             }
151         }
152       else
153         {
154           mt.representation.length = state.body.string - mt.representation.string;
155           macro_tokens_add (mts, &mt);
156         }
157       token_uninit (token);
158     }
159 }
160
161 void
162 macro_tokens_print (const struct macro_tokens *mts, FILE *stream)
163 {
164   for (size_t i = 0; i < mts->n; i++)
165     token_print (&mts->mts[i].token, stream);
166 }
167
168 enum token_class
169   {
170     TC_ENDCMD,                  /* No space before or after (new-line after). */
171     TC_BINOP,                   /* Space on both sides. */
172     TC_COMMA,                   /* Space afterward. */
173     TC_ID,                      /* Don't need spaces except sequentially. */
174     TC_PUNCT,                   /* Don't need spaces except sequentially. */
175   };
176
177 static bool
178 needs_space (enum token_class prev, enum token_class next)
179 {
180   /* Don't need a space before or after the end of a command.
181      (A new-line is needed afterward as a special case.) */
182   if (prev == TC_ENDCMD || next == TC_ENDCMD)
183     return false;
184
185   /* Binary operators always have a space on both sides. */
186   if (prev == TC_BINOP || next == TC_BINOP)
187     return true;
188
189   /* A comma always has a space afterward. */
190   if (prev == TC_COMMA)
191     return true;
192
193   /* Otherwise, PREV is TC_ID or TC_PUNCT, which only need a space if there are
194      two or them in a row. */
195   return prev == next;
196 }
197
198 static enum token_class
199 classify_token (enum token_type type)
200 {
201   switch (type)
202     {
203     case T_ID:
204     case T_MACRO_ID:
205     case T_POS_NUM:
206     case T_NEG_NUM:
207     case T_STRING:
208       return TC_ID;
209
210     case T_STOP:
211       return TC_PUNCT;
212
213     case T_ENDCMD:
214       return TC_ENDCMD;
215
216     case T_LPAREN:
217     case T_RPAREN:
218     case T_LBRACK:
219     case T_RBRACK:
220       return TC_PUNCT;
221
222     case T_PLUS:
223     case T_DASH:
224     case T_ASTERISK:
225     case T_SLASH:
226     case T_EQUALS:
227     case T_AND:
228     case T_OR:
229     case T_NOT:
230     case T_EQ:
231     case T_GE:
232     case T_GT:
233     case T_LE:
234     case T_LT:
235     case T_NE:
236     case T_ALL:
237     case T_BY:
238     case T_TO:
239     case T_WITH:
240     case T_EXP:
241     case T_MACRO_PUNCT:
242       return TC_BINOP;
243
244     case T_COMMA:
245       return TC_COMMA;
246     }
247
248   NOT_REACHED ();
249 }
250
251 void
252 macro_tokens_to_representation (struct macro_tokens *mts, struct string *s)
253 {
254   if (!mts->n)
255     return;
256
257   macro_token_to_representation (&mts->mts[0], s);
258   for (size_t i = 1; i < mts->n; i++)
259     {
260       enum token_type prev = mts->mts[i - 1].token.type;
261       enum token_type next = mts->mts[i].token.type;
262
263       if (prev == T_ENDCMD)
264         ds_put_byte (s, '\n');
265       else
266         {
267           enum token_class pc = classify_token (prev);
268           enum token_class nc = classify_token (next);
269           if (needs_space (pc, nc))
270             ds_put_byte (s, ' ');
271         }
272
273       macro_token_to_representation (&mts->mts[i], s);
274     }
275 }
276
277 void
278 macro_destroy (struct macro *m)
279 {
280   if (!m)
281     return;
282
283   free (m->name);
284   for (size_t i = 0; i < m->n_params; i++)
285     {
286       struct macro_param *p = &m->params[i];
287       free (p->name);
288
289       macro_tokens_uninit (&p->def);
290
291       switch (p->arg_type)
292         {
293         case ARG_N_TOKENS:
294           break;
295
296         case ARG_CHAREND:
297           token_uninit (&p->charend);
298           break;
299
300         case ARG_ENCLOSE:
301           token_uninit (&p->enclose[0]);
302           token_uninit (&p->enclose[1]);
303           break;
304
305         case ARG_CMDEND:
306           break;
307         }
308     }
309   free (m->params);
310   macro_tokens_uninit (&m->body);
311   free (m);
312 }
313 \f
314 struct macro_set *
315 macro_set_create (void)
316 {
317   struct macro_set *set = xmalloc (sizeof *set);
318   *set = (struct macro_set) {
319     .macros = HMAP_INITIALIZER (set->macros),
320   };
321   return set;
322 }
323
324 void
325 macro_set_destroy (struct macro_set *set)
326 {
327   if (!set)
328     return;
329
330   struct macro *macro, *next;
331   HMAP_FOR_EACH_SAFE (macro, next, struct macro, hmap_node, &set->macros)
332     {
333       hmap_delete (&set->macros, &macro->hmap_node);
334       macro_destroy (macro);
335     }
336   hmap_destroy (&set->macros);
337   free (set);
338 }
339
340 static unsigned int
341 hash_macro_name (const char *name)
342 {
343   return utf8_hash_case_string (name, 0);
344 }
345
346 static struct macro *
347 macro_set_find__ (struct macro_set *set, const char *name)
348 {
349   struct macro *macro;
350   HMAP_FOR_EACH_WITH_HASH (macro, struct macro, hmap_node,
351                            hash_macro_name (name), &set->macros)
352     if (!utf8_strcasecmp (macro->name, name))
353       return macro;
354
355   return NULL;
356 }
357
358 const struct macro *
359 macro_set_find (const struct macro_set *set, const char *name)
360 {
361   return macro_set_find__ (CONST_CAST (struct macro_set *, set), name);
362 }
363
364 /* Adds M to SET.  M replaces any existing macro with the same name.  Takes
365    ownership of M. */
366 void
367 macro_set_add (struct macro_set *set, struct macro *m)
368 {
369   struct macro *victim = macro_set_find__ (set, m->name);
370   if (victim)
371     {
372       hmap_delete (&set->macros, &victim->hmap_node);
373       macro_destroy (victim);
374     }
375
376   hmap_insert (&set->macros, &m->hmap_node, hash_macro_name (m->name));
377 }
378 \f
379 enum me_state
380   {
381     /* Error state. */
382     ME_ERROR,
383
384     /* Accumulating tokens in me->params toward the end of any type of
385        argument. */
386     ME_ARG,
387
388     /* Expecting the opening delimiter of an ARG_ENCLOSE argument. */
389     ME_ENCLOSE,
390
391     /* Expecting a keyword for a keyword argument. */
392     ME_KEYWORD,
393
394     /* Expecting an equal sign for a keyword argument. */
395     ME_EQUALS,
396   };
397
398
399 struct macro_expander
400   {
401     const struct macro_set *macros;
402
403     enum me_state state;
404     size_t n_tokens;
405
406     const struct macro *macro;
407     struct macro_tokens **args;
408     const struct macro_param *param;
409   };
410
411 static int
412 me_finished (struct macro_expander *me)
413 {
414   for (size_t i = 0; i < me->macro->n_params; i++)
415     if (!me->args[i])
416       {
417         me->args[i] = xmalloc (sizeof *me->args[i]);
418         macro_tokens_copy (me->args[i], &me->macro->params[i].def);
419       }
420   return me->n_tokens;
421 }
422
423 static int
424 me_next_arg (struct macro_expander *me)
425 {
426   if (!me->param)
427     {
428       assert (!me->macro->n_params);
429       return me_finished (me);
430     }
431   else if (me->param->positional)
432     {
433       me->param++;
434       if (me->param >= &me->macro->params[me->macro->n_params])
435         return me_finished (me);
436       else
437         {
438           me->state = (!me->param->positional ? ME_KEYWORD
439                        : me->param->arg_type == ARG_ENCLOSE ? ME_ENCLOSE
440                        : ME_ARG);
441           return 0;
442         }
443     }
444   else
445     {
446       for (size_t i = 0; i < me->macro->n_params; i++)
447         if (!me->args[i])
448           {
449             me->state = ME_KEYWORD;
450             return 0;
451           }
452       return me_finished (me);
453     }
454 }
455
456 static int
457 me_error (struct macro_expander *me)
458 {
459   me->state = ME_ERROR;
460   return -1;
461 }
462
463 static int
464 me_add_arg (struct macro_expander *me, const struct macro_token *mt)
465 {
466   const struct macro_param *p = me->param;
467
468   const struct token *token = &mt->token;
469   if ((token->type == T_ENDCMD || token->type == T_STOP)
470       && p->arg_type != ARG_CMDEND)
471     {
472       msg (SE, _("Unexpected end of command reading argument %s "
473                  "to macro %s."), me->param->name, me->macro->name);
474
475       return me_error (me);
476     }
477
478   me->n_tokens++;
479
480   struct macro_tokens **argp = &me->args[p - me->macro->params];
481   if (!*argp)
482     *argp = xzalloc (sizeof **argp);
483   struct macro_tokens *arg = *argp;
484   if (p->arg_type == ARG_N_TOKENS)
485     {
486       macro_tokens_add (arg, mt);
487       if (arg->n >= p->n_tokens)
488         return me_next_arg (me);
489       return 0;
490     }
491   else if (p->arg_type == ARG_CMDEND)
492     {
493       if (token->type == T_ENDCMD || token->type == T_STOP)
494         return me_next_arg (me);
495       macro_tokens_add (arg, mt);
496       return 0;
497     }
498   else
499     {
500       const struct token *end
501         = p->arg_type == ARG_CHAREND ? &p->charend : &p->enclose[1];
502       if (token_equal (token, end))
503         return me_next_arg (me);
504       macro_tokens_add (arg, mt);
505       return 0;
506     }
507 }
508
509 static int
510 me_expected (struct macro_expander *me, const struct macro_token *actual,
511              const struct token *expected)
512 {
513   const struct substring actual_s
514     = (actual->representation.length ? actual->representation
515        : ss_cstr (_("<end of input>")));
516   char *expected_s = token_to_string (expected);
517   msg (SE, _("Found `%.*s' while expecting `%s' reading argument %s "
518              "to macro %s."),
519        (int) actual_s.length, actual_s.string, expected_s,
520        me->param->name, me->macro->name);
521   free (expected_s);
522
523   return me_error (me);
524 }
525
526 static int
527 me_enclose (struct macro_expander *me, const struct macro_token *mt)
528 {
529   const struct token *token = &mt->token;
530   me->n_tokens++;
531
532   if (token_equal (&me->param->enclose[0], token))
533     {
534       me->state = ME_ARG;
535       return 0;
536     }
537
538   return me_expected (me, mt, &me->param->enclose[0]);
539 }
540
541 static const struct macro_param *
542 macro_find_parameter_by_name (const struct macro *m, struct substring name)
543 {
544   if (ss_first (name) == '!')
545     ss_advance (&name, 1);
546
547   for (size_t i = 0; i < m->n_params; i++)
548     {
549       const struct macro_param *p = &m->params[i];
550       struct substring p_name = ss_cstr (p->name + 1);
551       if (!utf8_strncasecmp (p_name.string, p_name.length,
552                              name.string, name.length))
553         return p;
554     }
555   return NULL;
556 }
557
558 static int
559 me_keyword (struct macro_expander *me, const struct macro_token *mt)
560 {
561   const struct token *token = &mt->token;
562   if (token->type != T_ID)
563     return me_finished (me);
564
565   const struct macro_param *p = macro_find_parameter_by_name (me->macro,
566                                                               token->string);
567   if (p)
568     {
569       size_t arg_index = p - me->macro->params;
570       me->param = p;
571       if (me->args[arg_index])
572         {
573           msg (SE,
574                _("Argument %s multiply specified in call to macro %s."),
575                p->name, me->macro->name);
576           return me_error (me);
577         }
578
579       me->n_tokens++;
580       me->state = ME_EQUALS;
581       return 0;
582     }
583
584   return me_finished (me);
585 }
586
587 static int
588 me_equals (struct macro_expander *me, const struct macro_token *mt)
589 {
590   const struct token *token = &mt->token;
591   me->n_tokens++;
592
593   if (token->type == T_EQUALS)
594     {
595       me->state = ME_ARG;
596       return 0;
597     }
598
599   return me_expected (me, mt, &(struct token) { .type = T_EQUALS });
600 }
601
602 int
603 macro_expander_create (const struct macro_set *macros,
604                        const struct token *token,
605                        struct macro_expander **mep)
606 {
607   *mep = NULL;
608   if (macro_set_is_empty (macros))
609     return -1;
610   if (token->type != T_ID && token->type != T_MACRO_ID)
611     return -1;
612
613   const struct macro *macro = macro_set_find (macros, token->string.string);
614   if (!macro)
615     return -1;
616
617   struct macro_expander *me = xmalloc (sizeof *me);
618   *me = (struct macro_expander) {
619     .macros = macros,
620     .n_tokens = 1,
621     .macro = macro,
622   };
623   *mep = me;
624
625   if (!macro->n_params)
626     return 1;
627   else
628     {
629       me->state = (!macro->params[0].positional ? ME_KEYWORD
630                    : macro->params[0].arg_type == ARG_ENCLOSE ? ME_ENCLOSE
631                    : ME_ARG);
632       me->args = xcalloc (macro->n_params, sizeof *me->args);
633       me->param = macro->params;
634       return 0;
635     }
636 }
637
638 void
639 macro_expander_destroy (struct macro_expander *me)
640 {
641   if (!me)
642     return;
643
644   for (size_t i = 0; i < me->macro->n_params; i++)
645     if (me->args[i])
646       {
647         macro_tokens_uninit (me->args[i]);
648         free (me->args[i]);
649       }
650   free (me->args);
651   free (me);
652 }
653
654 /* Adds TOKEN to the collection of tokens in ME that potentially need to be
655    macro expanded.
656
657    Returns -1 if the tokens added do not actually invoke a macro.  The caller
658    should consume the first token without expanding it.
659
660    Returns 0 if the macro expander needs more tokens, for macro arguments or to
661    decide whether this is actually a macro invocation.  The caller should call
662    macro_expander_add() again with the next token.
663
664    Returns a positive number to indicate that the returned number of tokens
665    invoke a macro.  The number returned might be less than the number of tokens
666    added because it can take a few tokens of lookahead to determine whether the
667    macro invocation is finished.  The caller should call
668    macro_expander_get_expansion() to obtain the expansion. */
669 int
670 macro_expander_add (struct macro_expander *me, const struct macro_token *mt)
671 {
672   switch (me->state)
673     {
674     case ME_ERROR:
675       return -1;
676
677     case ME_ARG:
678       return me_add_arg (me, mt);
679
680     case ME_ENCLOSE:
681       return me_enclose (me, mt);
682
683     case ME_KEYWORD:
684       return me_keyword (me, mt);
685
686     case ME_EQUALS:
687       return me_equals (me, mt);
688
689     default:
690       NOT_REACHED ();
691     }
692 }
693
694 /* Each argument to a macro function is one of:
695
696        - A quoted string or other single literal token.
697
698        - An argument to the macro being expanded, e.g. !1 or a named argument.
699
700        - !*.
701
702        - A function invocation.
703
704    Each function invocation yields a character sequence to be turned into a
705    sequence of tokens.  The case where that character sequence is a single
706    quoted string is an important special case.
707 */
708 struct parse_macro_function_ctx
709   {
710     const struct macro_token *input;
711     size_t n_input;
712     int nesting_countdown;
713     const struct macro_set *macros;
714     const struct macro_expander *me;
715     bool *expand;
716   };
717
718 static void
719 macro_expand (const struct macro_tokens *,
720               int nesting_countdown, const struct macro_set *,
721               const struct macro_expander *, bool *expand, struct macro_tokens *exp);
722
723 static bool
724 expand_macro_function (struct parse_macro_function_ctx *ctx,
725                        struct string *output, size_t *input_consumed);
726
727 /* Returns true if the pair of tokens starting at offset OFS within MTS are !*,
728    false otherwise. */
729 static bool
730 is_bang_star (const struct macro_token *mts, size_t n, size_t ofs)
731 {
732   return (ofs + 1 < n
733           && mts[ofs].token.type == T_MACRO_ID
734           && ss_equals (mts[ofs].token.string, ss_cstr ("!"))
735           && mts[ofs + 1].token.type == T_ASTERISK);
736 }
737
738 static size_t
739 parse_function_arg (struct parse_macro_function_ctx *ctx,
740                     size_t i, struct string *farg)
741 {
742   const struct macro_token *tokens = ctx->input;
743   const struct token *token = &tokens[i].token;
744   if (token->type == T_MACRO_ID)
745     {
746       const struct macro_param *param = macro_find_parameter_by_name (
747         ctx->me->macro, token->string);
748       if (param)
749         {
750           size_t param_idx = param - ctx->me->macro->params;
751           const struct macro_tokens *marg = ctx->me->args[param_idx];
752           for (size_t i = 0; i < marg->n; i++)
753             {
754               if (i)
755                 ds_put_byte (farg, ' ');
756               ds_put_substring (farg, marg->mts[i].representation);
757             }
758           return 1;
759         }
760
761       if (is_bang_star (ctx->input, ctx->n_input, i))
762         {
763           for (size_t i = 0; i < ctx->me->macro->n_params; i++)
764             {
765               if (!ctx->me->macro->params[i].positional)
766                 break;
767
768               const struct macro_tokens *marg = ctx->me->args[i];
769               for (size_t j = 0; j < marg->n; j++)
770                 {
771                   if (i || j)
772                     ds_put_byte (farg, ' ');
773                   ds_put_substring (farg, marg->mts[j].representation);
774                 }
775             }
776           return 2;
777         }
778
779       struct parse_macro_function_ctx subctx = {
780         .input = &ctx->input[i],
781         .n_input = ctx->n_input - i,
782         .nesting_countdown = ctx->nesting_countdown,
783         .macros = ctx->macros,
784         .me = ctx->me,
785         .expand = ctx->expand,
786       };
787       size_t subinput_consumed;
788       if (expand_macro_function (&subctx, farg, &subinput_consumed))
789         return subinput_consumed;
790     }
791
792   ds_put_substring (farg, tokens[i].representation);
793   return 1;
794 }
795
796 static bool
797 parse_macro_function (struct parse_macro_function_ctx *ctx,
798                       struct string_array *args,
799                       struct substring function,
800                       int min_args, int max_args,
801                       size_t *input_consumed)
802 {
803   const struct macro_token *tokens = ctx->input;
804   size_t n_tokens = ctx->n_input;
805
806   if (!n_tokens
807       || tokens[0].token.type != T_MACRO_ID
808       || !ss_equals_case (tokens[0].token.string, function))
809     return false;
810
811   if (n_tokens < 2 || tokens[1].token.type != T_LPAREN)
812     {
813       printf ("`(' expected following %s'\n", function.string);
814       return false;
815     }
816
817   string_array_init (args);
818
819   for (size_t i = 2;; )
820     {
821       if (i >= n_tokens)
822         goto unexpected_end;
823       if (tokens[i].token.type == T_RPAREN)
824         {
825           *input_consumed = i + 1;
826           if (args->n < min_args || args->n > max_args)
827             {
828               printf ("Wrong number of arguments to %s.\n", function.string);
829               goto error;
830             }
831           return true;
832         }
833
834       struct string s = DS_EMPTY_INITIALIZER;
835       i += parse_function_arg (ctx, i, &s);
836       if (i >= n_tokens)
837         {
838           ds_destroy (&s);
839           goto unexpected_end;
840         }
841       string_array_append_nocopy (args, ds_steal_cstr (&s));
842
843       if (tokens[i].token.type == T_COMMA)
844         i++;
845       else if (tokens[i].token.type != T_RPAREN)
846         {
847           printf ("Expecting `,' or `)' in %s invocation.", function.string);
848           goto error;
849         }
850     }
851
852 unexpected_end:
853   printf ("Missing closing parenthesis in arguments to %s.\n",
854           function.string);
855   /* Fall through. */
856 error:
857   string_array_destroy (args);
858   return false;
859 }
860
861 static bool
862 unquote_string (const char *s, struct string *content)
863 {
864   struct string_lexer slex;
865   string_lexer_init (&slex, s, strlen (s), SEG_MODE_INTERACTIVE /* XXX */);
866
867   struct token token1;
868   if (!string_lexer_next (&slex, &token1))
869     return false;
870
871   if (token1.type != T_STRING)
872     {
873       token_uninit (&token1);
874       return false;
875     }
876
877   struct token token2;
878   if (string_lexer_next (&slex, &token2))
879     {
880       token_uninit (&token1);
881       token_uninit (&token2);
882       return false;
883     }
884
885   ds_put_substring (content, token1.string);
886   token_uninit (&token1);
887   return true;
888 }
889
890 static const char *
891 unquote_string_in_place (const char *s, struct string *tmp)
892 {
893   ds_init_empty (tmp);
894   return unquote_string (s, tmp) ? ds_cstr (tmp) : s;
895 }
896
897 static bool
898 parse_integer (const char *s, int *np)
899 {
900   errno = 0;
901
902   char *tail;
903   long int n = strtol (s, &tail, 10);
904   *np = n < INT_MIN ? INT_MIN : n > INT_MAX ? INT_MAX : n;
905   tail += strspn (tail, CC_SPACES);
906   return *tail == '\0' && errno != ERANGE && n == *np;
907 }
908
909 static bool
910 expand_macro_function (struct parse_macro_function_ctx *ctx,
911                        struct string *output,
912                        size_t *input_consumed)
913 {
914   struct string_array args;
915
916   if (parse_macro_function (ctx, &args, ss_cstr ("!length"), 1, 1,
917                             input_consumed))
918     ds_put_format (output, "%zu", strlen (args.strings[0]));
919   else if (parse_macro_function (ctx, &args, ss_cstr ("!blanks"), 1, 1,
920                                  input_consumed))
921     {
922       int n;
923       if (!parse_integer (args.strings[0], &n))
924         {
925           printf ("argument to !BLANKS must be non-negative integer (not \"%s\")\n", args.strings[0]);
926           string_array_destroy (&args);
927           return false;
928         }
929
930       ds_put_byte_multiple (output, ' ', n);
931     }
932   else if (parse_macro_function (ctx, &args, ss_cstr ("!concat"), 1, INT_MAX,
933                                  input_consumed))
934     {
935       for (size_t i = 0; i < args.n; i++)
936         if (!unquote_string (args.strings[i], output))
937           ds_put_cstr (output, args.strings[i]);
938     }
939   else if (parse_macro_function (ctx, &args, ss_cstr ("!head"), 1, 1,
940                                  input_consumed))
941     {
942       struct string tmp;
943       const char *s = unquote_string_in_place (args.strings[0], &tmp);
944
945       struct macro_tokens mts = { .n = 0 };
946       macro_tokens_from_string (&mts, ss_cstr (s), SEG_MODE_INTERACTIVE /* XXX */);
947       if (mts.n > 0)
948         ds_put_substring (output, mts.mts[0].representation);
949       macro_tokens_uninit (&mts);
950       ds_destroy (&tmp);
951     }
952   else if (parse_macro_function (ctx, &args, ss_cstr ("!index"), 2, 2,
953                                  input_consumed))
954     {
955       const char *haystack = args.strings[0];
956       const char *needle = strstr (haystack, args.strings[1]);
957       ds_put_format (output, "%zu", needle ? needle - haystack + 1 : 0);
958     }
959   else if (parse_macro_function (ctx, &args, ss_cstr ("!quote"), 1, 1,
960                                  input_consumed))
961     {
962       if (unquote_string (args.strings[0], NULL))
963         ds_put_cstr (output, args.strings[0]);
964       else
965         {
966           ds_extend (output, strlen (args.strings[0]) + 2);
967           ds_put_byte (output, '\'');
968           for (const char *p = args.strings[0]; *p; p++)
969             {
970               if (*p == '\'')
971                 ds_put_byte (output, '\'');
972               ds_put_byte (output, *p);
973             }
974           ds_put_byte (output, '\'');
975         }
976     }
977   else if (parse_macro_function (ctx, &args, ss_cstr ("!substr"), 2, 3,
978                                  input_consumed))
979     {
980       int start;
981       if (!parse_integer (args.strings[1], &start) || start < 1)
982         {
983           printf ("second argument to !SUBSTR must be positive integer (not \"%s\")\n", args.strings[1]);
984           string_array_destroy (&args);
985           return false;
986         }
987
988       int count = INT_MAX;
989       if (args.n > 2 && (!parse_integer (args.strings[2], &count) || count < 0))
990         {
991           printf ("third argument to !SUBSTR must be non-negative integer (not \"%s\")\n", args.strings[1]);
992           string_array_destroy (&args);
993           return false;
994         }
995
996       struct substring s = ss_cstr (args.strings[0]);
997       ds_put_substring (output, ss_substr (s, start - 1, count));
998     }
999   else if (parse_macro_function (ctx, &args, ss_cstr ("!tail"), 1, 1,
1000                                  input_consumed))
1001     {
1002       struct string tmp;
1003       const char *s = unquote_string_in_place (args.strings[0], &tmp);
1004
1005       struct macro_tokens mts = { .n = 0 };
1006       macro_tokens_from_string (&mts, ss_cstr (s), SEG_MODE_INTERACTIVE /* XXX */);
1007       if (mts.n > 1)
1008         {
1009           struct macro_tokens tail = { .mts = mts.mts + 1, .n = mts.n - 1 };
1010           macro_tokens_to_representation (&tail, output);
1011         }
1012       macro_tokens_uninit (&mts);
1013       ds_destroy (&tmp);
1014     }
1015   else if (parse_macro_function (ctx, &args, ss_cstr ("!unquote"), 1, 1,
1016                                  input_consumed))
1017     {
1018       if (!unquote_string (args.strings[0], output))
1019         ds_put_cstr (output, args.strings[0]);
1020     }
1021   else if (parse_macro_function (ctx, &args, ss_cstr ("!upcase"), 1, 1,
1022                                  input_consumed))
1023     {
1024       struct string tmp;
1025       const char *s = unquote_string_in_place (args.strings[0], &tmp);
1026       char *upper = utf8_to_upper (s);
1027       ds_put_cstr (output, upper);
1028       free (upper);
1029       ds_destroy (&tmp);
1030     }
1031   else if (parse_macro_function (ctx, &args, ss_cstr ("!eval"), 1, 1,
1032                                  input_consumed))
1033     {
1034       struct macro_tokens mts = { .n = 0 };
1035       macro_tokens_from_string (&mts, ss_cstr (args.strings[0]),
1036                                 SEG_MODE_INTERACTIVE /* XXX */);
1037       struct macro_tokens exp = { .n = 0 };
1038       macro_expand (&mts, ctx->nesting_countdown - 1, ctx->macros,
1039                     ctx->me, ctx->expand, &exp);
1040       macro_tokens_to_representation (&exp, output);
1041       macro_tokens_uninit (&exp);
1042       macro_tokens_uninit (&mts);
1043     }
1044   else if (ctx->n_input > 0
1045            && ctx->input[0].token.type == T_MACRO_ID
1046            && ss_equals_case (ctx->input[0].token.string, ss_cstr ("!null")))
1047     {
1048       *input_consumed = 1;
1049       return true;
1050     }
1051   else
1052     return false;
1053
1054   string_array_destroy (&args);
1055   return true;
1056 }
1057
1058 struct expr_context
1059   {
1060     int nesting_countdown;
1061     const struct macro_set *macros;
1062     const struct macro_expander *me;
1063     bool *expand;
1064   };
1065
1066 static char *macro_evaluate_or (const struct expr_context *ctx,
1067                                 const struct macro_token **tokens,
1068                                 const struct macro_token *end);
1069
1070 static char *
1071 macro_evaluate_literal (const struct expr_context *ctx,
1072                         const struct macro_token **tokens,
1073                         const struct macro_token *end)
1074 {
1075   const struct macro_token *p = *tokens;
1076   if (p >= end)
1077     return NULL;
1078   if (p->token.type == T_LPAREN)
1079     {
1080       p++;
1081       char *value = macro_evaluate_or (ctx, &p, end);
1082       if (!value)
1083         return NULL;
1084       if (p >= end || p->token.type != T_RPAREN)
1085         {
1086           free (value);
1087           printf ("expecting ')' in macro expression\n");
1088           return NULL;
1089         }
1090       p++;
1091       *tokens = p;
1092       return value;
1093     }
1094
1095   struct parse_macro_function_ctx fctx = {
1096     .input = p,
1097     .n_input = end - p,
1098     .nesting_countdown = ctx->nesting_countdown,
1099     .macros = ctx->macros,
1100     .me = ctx->me,
1101     .expand = ctx->expand,
1102   };
1103   struct string function_output = DS_EMPTY_INITIALIZER;
1104   size_t function_consumed = parse_function_arg (&fctx, 0, &function_output);
1105   *tokens = p + function_consumed;
1106   return ds_steal_cstr (&function_output);
1107 }
1108
1109 /* Returns true if MT is valid as a macro operator.  Only operators written as
1110    symbols (e.g. <>) are usable in macro expressions, not operator written as
1111    letters (e.g. EQ). */
1112 static bool
1113 is_macro_operator (const struct macro_token *mt)
1114 {
1115   return (mt->representation.length > 0
1116           && !c_isalpha (mt->representation.string[0]));
1117 }
1118
1119 static enum token_type
1120 parse_relational_op (const struct macro_token *mt)
1121 {
1122   switch (mt->token.type)
1123     {
1124     case T_EQUALS:
1125       return T_EQ;
1126
1127     case T_NE:
1128     case T_LT:
1129     case T_GT:
1130     case T_LE:
1131     case T_GE:
1132       return is_macro_operator (mt) ? mt->token.type : T_STOP;
1133
1134     case T_MACRO_ID:
1135       return (ss_equals_case (mt->token.string, ss_cstr ("!EQ")) ? T_EQ
1136               : ss_equals_case (mt->token.string, ss_cstr ("!NE")) ? T_NE
1137               : ss_equals_case (mt->token.string, ss_cstr ("!LT")) ? T_LT
1138               : ss_equals_case (mt->token.string, ss_cstr ("!GT")) ? T_GT
1139               : ss_equals_case (mt->token.string, ss_cstr ("!LE")) ? T_LE
1140               : ss_equals_case (mt->token.string, ss_cstr ("!GE")) ? T_GE
1141               : T_STOP);
1142
1143     default:
1144       return T_STOP;
1145     }
1146 }
1147
1148 static char *
1149 macro_evaluate_relational (const struct expr_context *ctx,
1150                         const struct macro_token **tokens,
1151                         const struct macro_token *end)
1152 {
1153   const struct macro_token *p = *tokens;
1154   char *lhs = macro_evaluate_literal (ctx, &p, end);
1155   if (!lhs)
1156     return NULL;
1157
1158   enum token_type op = p >= end ? T_STOP : parse_relational_op (p);
1159   if (op == T_STOP)
1160     {
1161       *tokens = p;
1162       return lhs;
1163     }
1164   p++;
1165
1166   char *rhs = macro_evaluate_literal (ctx, &p, end);
1167   if (!rhs)
1168     {
1169       free (lhs);
1170       return NULL;
1171     }
1172
1173   struct string lhs_tmp, rhs_tmp;
1174   int cmp = strcmp/*XXX*/ (unquote_string_in_place (lhs, &lhs_tmp),
1175                            unquote_string_in_place (rhs, &rhs_tmp));
1176   ds_destroy (&lhs_tmp);
1177   ds_destroy (&rhs_tmp);
1178
1179   free (lhs);
1180   free (rhs);
1181
1182   bool b = (op == T_EQUALS || op == T_EQ ? !cmp
1183             : op == T_NE ? cmp
1184             : op == T_LT ? cmp < 0
1185             : op == T_GT ? cmp > 0
1186             : op == T_LE ? cmp <= 0
1187             :/*op == T_GE*/cmp >= 0);
1188
1189   *tokens = p;
1190   return xstrdup (b ? "1" : "0");
1191 }
1192
1193 static char *
1194 macro_evaluate_not (const struct expr_context *ctx,
1195                     const struct macro_token **tokens,
1196                     const struct macro_token *end)
1197 {
1198   const struct macro_token *p = *tokens;
1199
1200   unsigned int negations = 0;
1201   while (p < end
1202          && (ss_equals_case (p->representation, ss_cstr ("!NOT"))
1203              || ss_equals (p->representation, ss_cstr ("~"))))
1204     {
1205       p++;
1206       negations++;
1207     }
1208
1209   char *operand = macro_evaluate_relational (ctx, &p, end);
1210   if (!operand || !negations)
1211     {
1212       *tokens = p;
1213       return operand;
1214     }
1215
1216   bool b = strcmp (operand, "0") ^ (negations & 1);
1217   free (operand);
1218   *tokens = p;
1219   return xstrdup (b ? "1" : "0");
1220 }
1221
1222 static char *
1223 macro_evaluate_and (const struct expr_context *ctx,
1224                     const struct macro_token **tokens,
1225                     const struct macro_token *end)
1226 {
1227   const struct macro_token *p = *tokens;
1228   char *lhs = macro_evaluate_not (ctx, &p, end);
1229   if (!lhs)
1230     return NULL;
1231
1232   while (p < end
1233          && (ss_equals_case (p->representation, ss_cstr ("!AND"))
1234              || ss_equals (p->representation, ss_cstr ("&"))))
1235     {
1236       p++;
1237       char *rhs = macro_evaluate_not (ctx, &p, end);
1238       if (!rhs)
1239         {
1240           free (lhs);
1241           return NULL;
1242         }
1243
1244       bool b = strcmp (lhs, "0") && strcmp (rhs, "0");
1245       free (lhs);
1246       free (rhs);
1247       lhs = xstrdup (b ? "1" : "0");
1248     }
1249   *tokens = p;
1250   return lhs;
1251 }
1252
1253 static char *
1254 macro_evaluate_or (const struct expr_context *ctx,
1255                    const struct macro_token **tokens,
1256                    const struct macro_token *end)
1257 {
1258   const struct macro_token *p = *tokens;
1259   char *lhs = macro_evaluate_and (ctx, &p, end);
1260   if (!lhs)
1261     return NULL;
1262
1263   while (p < end
1264          && (ss_equals_case (p->representation, ss_cstr ("!OR"))
1265              || ss_equals (p->representation, ss_cstr ("|"))))
1266     {
1267       p++;
1268       char *rhs = macro_evaluate_and (ctx, &p, end);
1269       if (!rhs)
1270         {
1271           free (lhs);
1272           return NULL;
1273         }
1274
1275       bool b = strcmp (lhs, "0") || strcmp (rhs, "0");
1276       free (lhs);
1277       free (rhs);
1278       lhs = xstrdup (b ? "1" : "0");
1279     }
1280   *tokens = p;
1281   return lhs;
1282 }
1283
1284 static char *
1285 macro_evaluate_expression (const struct macro_token **tokens, size_t n_tokens,
1286                            int nesting_countdown, const struct macro_set *macros,
1287                            const struct macro_expander *me, bool *expand)
1288 {
1289   const struct expr_context ctx = {
1290     .nesting_countdown = nesting_countdown,
1291     .macros = macros,
1292     .me = me,
1293     .expand = expand,
1294   };
1295   return macro_evaluate_or (&ctx, tokens, *tokens + n_tokens);
1296 }
1297
1298 static const struct macro_token *
1299 find_ifend_clause (const struct macro_token *p, const struct macro_token *end)
1300 {
1301   size_t nesting = 0;
1302   for (; p < end; p++)
1303     {
1304       if (p->token.type != T_MACRO_ID)
1305         continue;
1306
1307       if (ss_equals_case (p->token.string, ss_cstr ("!IF")))
1308         nesting++;
1309       else if (ss_equals_case (p->token.string, ss_cstr ("!IFEND")))
1310         {
1311           if (!nesting)
1312             return p;
1313           nesting--;
1314         }
1315       else if (ss_equals_case (p->token.string, ss_cstr ("!ELSE")) && !nesting)
1316         return p;
1317     }
1318   return NULL;
1319 }
1320
1321 static size_t
1322 macro_expand_if (const struct macro_token *tokens, size_t n_tokens,
1323                  int nesting_countdown, const struct macro_set *macros,
1324                  const struct macro_expander *me, bool *expand,
1325                  struct macro_tokens *exp)
1326 {
1327   const struct macro_token *p = tokens;
1328   const struct macro_token *end = tokens + n_tokens;
1329
1330   if (p >= end || !ss_equals_case (p->token.string, ss_cstr ("!IF")))
1331     return 0;
1332
1333   p++;
1334   char *result = macro_evaluate_expression (&p, end - p,
1335                                             nesting_countdown, macros, me, expand);
1336   if (!result)
1337     return 0;
1338   bool b = strcmp (result, "0");
1339   free (result);
1340
1341   if (p >= end
1342       || p->token.type != T_MACRO_ID
1343       || !ss_equals_case (p->token.string, ss_cstr ("!THEN")))
1344     {
1345       printf ("!THEN expected\n");
1346       return 0;
1347     }
1348
1349   const struct macro_token *start_then = p + 1;
1350   const struct macro_token *end_then = find_ifend_clause (start_then, end);
1351   if (!end_then)
1352     {
1353       printf ("!ELSE or !IFEND expected\n");
1354       return 0;
1355     }
1356
1357   const struct macro_token *start_else, *end_if;
1358   if (ss_equals_case (end_then->token.string, ss_cstr ("!ELSE")))
1359     {
1360       start_else = end_then + 1;
1361       end_if = find_ifend_clause (start_else, end);
1362       if (!end_if
1363           || !ss_equals_case (end_if->token.string, ss_cstr ("!IFEND")))
1364         {
1365           printf ("!IFEND expected\n");
1366           return 0;
1367         }
1368     }
1369   else
1370     {
1371       start_else = NULL;
1372       end_if = end_then;
1373     }
1374
1375   const struct macro_token *start;
1376   size_t n;
1377   if (b)
1378     {
1379       start = start_then;
1380       n = end_then - start_then;
1381     }
1382   else if (start_else)
1383     {
1384       start = start_else;
1385       n = end_if - start_else;
1386     }
1387   else
1388     {
1389       start = NULL;
1390       n = 0;
1391     }
1392
1393   if (n)
1394     {
1395       struct macro_tokens mts = {
1396         .mts = CONST_CAST (struct macro_token *, start),
1397         .n = n,
1398       };
1399       macro_expand (&mts, nesting_countdown, macros, me, expand, exp);
1400     }
1401   return (end_if + 1) - tokens;
1402 }
1403
1404 static void
1405 macro_expand (const struct macro_tokens *mts,
1406               int nesting_countdown, const struct macro_set *macros,
1407               const struct macro_expander *me, bool *expand,
1408               struct macro_tokens *exp)
1409 {
1410   if (nesting_countdown <= 0)
1411     {
1412       printf ("maximum nesting level exceeded\n");
1413       for (size_t i = 0; i < mts->n; i++)
1414         macro_tokens_add (exp, &mts->mts[i]);
1415       return;
1416     }
1417
1418   for (size_t i = 0; i < mts->n; i++)
1419     {
1420       const struct macro_token *mt = &mts->mts[i];
1421       const struct token *token = &mt->token;
1422       if (token->type == T_MACRO_ID && me)
1423         {
1424           const struct macro_param *param = macro_find_parameter_by_name (
1425             me->macro, token->string);
1426           if (param)
1427             {
1428               const struct macro_tokens *arg = me->args[param - me->macro->params];
1429               //macro_tokens_print (arg, stdout);
1430               if (*expand && param->expand_arg)
1431                 macro_expand (arg, nesting_countdown, macros, NULL, expand, exp);
1432               else
1433                 for (size_t i = 0; i < arg->n; i++)
1434                   macro_tokens_add (exp, &arg->mts[i]);
1435               continue;
1436             }
1437
1438           if (is_bang_star (mts->mts, mts->n, i))
1439             {
1440               for (size_t j = 0; j < me->macro->n_params; j++)
1441                 {
1442                   const struct macro_param *param = &me->macro->params[j];
1443                   if (!param->positional)
1444                     break;
1445
1446                   const struct macro_tokens *arg = me->args[j];
1447                   if (*expand && param->expand_arg)
1448                     macro_expand (arg, nesting_countdown, macros, NULL, expand, exp);
1449                   else
1450                     for (size_t k = 0; k < arg->n; k++)
1451                       macro_tokens_add (exp, &arg->mts[k]);
1452                 }
1453               i++;
1454               continue;
1455             }
1456
1457           size_t n = macro_expand_if (&mts->mts[i], mts->n - i,
1458                                       nesting_countdown, macros, me, expand,
1459                                       exp);
1460           if (n > 0)
1461             {
1462               i += n - 1;
1463               continue;
1464             }
1465         }
1466
1467       if (*expand)
1468         {
1469           struct macro_expander *subme;
1470           int retval = macro_expander_create (macros, token, &subme);
1471           for (size_t j = 1; !retval; j++)
1472             {
1473               const struct macro_token endcmd = { .token = { .type = T_ENDCMD } };
1474               retval = macro_expander_add (
1475                 subme, i + j < mts->n ? &mts->mts[i + j] : &endcmd);
1476             }
1477           if (retval > 0)
1478             {
1479               i += retval - 1;
1480               macro_expand (&subme->macro->body, nesting_countdown - 1, macros,
1481                             subme, expand, exp);
1482               macro_expander_destroy (subme);
1483               continue;
1484             }
1485
1486           macro_expander_destroy (subme);
1487         }
1488
1489       if (token->type != T_MACRO_ID)
1490         {
1491           macro_tokens_add (exp, mt);
1492           continue;
1493         }
1494
1495       struct parse_macro_function_ctx ctx = {
1496         .input = &mts->mts[i],
1497         .n_input = mts->n - i,
1498         .nesting_countdown = nesting_countdown,
1499         .macros = macros,
1500         .me = me,
1501         .expand = expand,
1502       };
1503       struct string function_output = DS_EMPTY_INITIALIZER;
1504       size_t function_consumed;
1505       if (expand_macro_function (&ctx, &function_output, &function_consumed))
1506         {
1507           i += function_consumed - 1;
1508
1509           macro_tokens_from_string (exp, function_output.ss,
1510                                     SEG_MODE_INTERACTIVE /* XXX */);
1511           ds_destroy (&function_output);
1512
1513           continue;
1514         }
1515
1516       if (ss_equals_case (token->string, ss_cstr ("!onexpand")))
1517         *expand = true;
1518       else if (ss_equals_case (token->string, ss_cstr ("!offexpand")))
1519         *expand = false;
1520       else
1521         macro_tokens_add (exp, mt);
1522     }
1523 }
1524
1525 void
1526 macro_expander_get_expansion (struct macro_expander *me, struct macro_tokens *exp)
1527 {
1528 #if 0
1529   for (size_t i = 0; i < me->macro->n_params; i++)
1530     {
1531       printf ("%s:\n", me->macro->params[i].name);
1532       macro_tokens_print (me->args[i], stdout);
1533     }
1534 #endif
1535
1536   bool expand = true;
1537   macro_expand (&me->macro->body, settings_get_mnest (),
1538                 me->macros, me, &expand, exp);
1539
1540 #if 0
1541   printf ("expansion:\n");
1542   macro_tokens_print (exp, stdout);
1543 #endif
1544 }
1545