varnish-cache/lib/libvcc/vcc_expr.c
0
/*-
1
 * Copyright (c) 2006 Verdens Gang AS
2
 * Copyright (c) 2006-2011 Varnish Software AS
3
 * All rights reserved.
4
 *
5
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6
 *
7
 * SPDX-License-Identifier: BSD-2-Clause
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in the
16
 *    documentation and/or other materials provided with the distribution.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 *
30
 */
31
32
#include "config.h"
33
34
#include <math.h>
35
#include <stdarg.h>
36
#include <stdlib.h>
37
#include <string.h>
38
39
#include "vcc_compile.h"
40
#include "vjsn.h"
41
42
struct expr {
43
        unsigned        magic;
44
#define EXPR_MAGIC      0x38c794ab
45
        vcc_type_t      fmt;
46
        struct vsb      *vsb;
47
        uint8_t         constant;
48
#define EXPR_VAR        (1<<0)
49
#define EXPR_CONST      (1<<1)
50
#define EXPR_STR_CONST  (1<<2)          // Last string elem is "..."
51
        struct token    *t1, *t2;
52
        struct symbol   *instance;
53
        int             nstr;
54
};
55
56
/*--------------------------------------------------------------------
57
 * Facility for carrying expressions around and do text-processing on
58
 * them.
59
 */
60
61
static inline int
62 97342
vcc_isconst(const struct expr *e)
63
{
64 97342
        AN(e->constant);
65 97342
        return (e->constant & EXPR_CONST);
66
}
67
68
static inline int
69 1147823
vcc_islit(const struct expr *e)
70
{
71 1147823
        AN(e->constant);
72 1147823
        return (e->constant & EXPR_STR_CONST);
73
}
74
75
static const char *
76 1139
vcc_utype(vcc_type_t t)
77
{
78 1139
        if (t == STRINGS || t->stringform)
79 306
                t = STRING;
80 1139
        return (t->name);
81
}
82
83
static vcc_type_t
84 10610465
vcc_stringstype(vcc_type_t t)
85
{
86 10610465
        return (t->stringform ? STRINGS : t);
87
}
88
89
90
static void vcc_expr0(struct vcc *tl, struct expr **e, vcc_type_t fmt);
91
static void vcc_expr_cor(struct vcc *tl, struct expr **e, vcc_type_t fmt);
92
static void vcc_expr_typecheck(struct vcc *tl, struct expr **e, vcc_type_t fmt,
93
    struct token *t1);
94
95
static struct expr *
96 10078620
vcc_new_expr(vcc_type_t fmt)
97
{
98
        struct expr *e;
99
100 10078620
        ALLOC_OBJ(e, EXPR_MAGIC);
101 10078620
        AN(e);
102 10078620
        e->vsb = VSB_new_auto();
103 10078620
        e->fmt = fmt;
104 10078620
        e->constant = EXPR_VAR;
105 10078620
        return (e);
106
}
107
108
static struct expr * v_printflike_(2, 3)
109 2673828
vcc_mk_expr(vcc_type_t fmt, const char *str, ...)
110
{
111
        va_list ap;
112
        struct expr *e;
113
114 2673828
        e = vcc_new_expr(fmt);
115 2673828
        va_start(ap, str);
116 2673828
        VSB_vprintf(e->vsb, str, ap);
117 2673828
        va_end(ap);
118 2673828
        AZ(VSB_finish(e->vsb));
119 2673828
        return (e);
120
}
121
122
static void
123 12846135
vcc_delete_expr(struct expr *e)
124
{
125 12846135
        if (e == NULL)
126 2782033
                return;
127 10064102
        CHECK_OBJ(e, EXPR_MAGIC);
128 10064102
        VSB_destroy(&e->vsb);
129 10064102
        FREE_OBJ(e);
130 12846135
}
131
132
/*--------------------------------------------------------------------
133
 * We want to get the indentation right in the emitted C code so we have
134
 * to represent it symbolically until we are ready to render.
135
 *
136
 * Many of the operations have very schematic output syntaxes, so we
137
 * use the same facility to simplify the text-processing of emitting
138
 * a given operation on two subexpressions.
139
 *
140
 * We use '\v' as the magic escape character.
141
 *      \v1  insert subexpression 1
142
 *      \v2  insert subexpression 2
143
 *      \vS  insert subexpression 1(STRINGS) as STRING
144
 *      \vs  insert subexpression 2(STRINGS) as STRING
145
 *      \vT  insert subexpression 1(STRINGS) as STRANDS
146
 *      \vt  insert subexpression 2(STRINGS) as STRANDS
147
 *      \v+  increase indentation
148
 *      \v-  decrease indentation
149
 *      anything else is literal
150
 *
151
 * When editing, we check if any of the subexpressions contain a newline
152
 * and issue it as an indented block of so.
153
 *
154
 * XXX: check line lengths in edit, should pass indent in for this
155
 */
156
157
static void
158 856205
vcc_strands_edit(const struct expr *e1, const struct expr *e2)
159
{
160
161 856205
        assert(e2->fmt == STRANDS || e2->fmt == STRINGS);
162
163 856205
        if (e2->fmt == STRANDS)
164 68
                VSB_cat(e1->vsb, VSB_data(e2->vsb));
165 856137
        else if (e2->nstr == 0)
166 0
                VSB_printf(e1->vsb, "vrt_null_strands");
167 856137
        else if (e2->nstr == 1)
168 757588
                VSB_printf(e1->vsb, "TOSTRAND(%s)", VSB_data(e2->vsb));
169
        else {
170 197098
                VSB_printf(e1->vsb, "TOSTRANDS(%d,\v+\n%s\v-)",
171 98549
                   e2->nstr, VSB_data(e2->vsb));
172
        }
173 856205
}
174
175
static struct expr *
176 5646125
vcc_expr_edit(struct vcc *tl, vcc_type_t fmt, const char *p, struct expr *e1,
177
    struct expr *e2)
178
{
179
        struct expr *e, *e3;
180 5646125
        int nl = 1;
181
182 5646125
        (void) tl;
183
184 5646125
        AN(e1);
185 5646125
        e = vcc_new_expr(fmt);
186 66421788
        while (*p != '\0') {
187 60775663
                if (*p != '\v') {
188 50406360
                        if (*p != '\n' || !nl)
189 50405544
                                VSB_putc(e->vsb, *p);
190 50406360
                        nl = (*p == '\n');
191 50406360
                        p++;
192 50406360
                        continue;
193
                }
194 10369303
                assert(*p == '\v');
195 10369303
                switch (*++p) {
196 902870
                case '+': VSB_cat(e->vsb, "\v+"); nl = 0; break;
197 956131
                case '-': VSB_cat(e->vsb, "\v-"); nl = 0; break;
198
                case 'S':
199
                case 's':
200 204306
                        e3 = (*p == 'S' ? e1 : e2);
201 204306
                        AN(e3);
202 204306
                        assert(e1->fmt == STRINGS);
203 204306
                        if (e3->nstr > 1) {
204 442
                                VSB_cat(e->vsb,
205
                                    "\nVRT_STRANDS_string(ctx,\v+\n");
206 442
                                vcc_strands_edit(e, e3);
207 442
                                VSB_cat(e->vsb,
208
                                    "\v-\n)\n");
209 442
                        } else {
210 203864
                                VSB_cat(e->vsb, VSB_data(e3->vsb));
211
                        }
212 204306
                        break;
213
                case 'T':
214
                case 't':
215 855763
                        e3 = (*p == 'T' ? e1 : e2);
216 855763
                        AN(e3);
217 855763
                        vcc_strands_edit(e, e3);
218 855763
                        break;
219
                case '1':
220 4586583
                        VSB_cat(e->vsb, VSB_data(e1->vsb));
221 4586583
                        break;
222
                case '2':
223 2863650
                        AN(e2);
224 2863650
                        VSB_cat(e->vsb, VSB_data(e2->vsb));
225 2863650
                        break;
226
                default:
227 0
                        WRONG("Illegal edit in VCC expression");
228 0
                }
229 10369303
                p++;
230
        }
231 5646125
        AZ(VSB_finish(e->vsb));
232 5646125
        e->t1 = e1->t1;
233 5646125
        e->t2 = e1->t2;
234 5646125
        if (e2 != NULL)
235 2864177
                e->t2 = e2->t2;
236 5646125
        vcc_delete_expr(e1);
237 5646125
        vcc_delete_expr(e2);
238 5646125
        return (e);
239
}
240
241
/*--------------------------------------------------------------------
242
 * Expand finished expression into C-source code
243
 */
244
245
static void
246 1553766
vcc_expr_fmt(struct vsb *d, int ind, const struct expr *e1)
247
{
248
        char *p;
249
        int i;
250
251 1553766
        if (!e1->fmt->noindent) {
252 13823958
                for (i = 0; i < ind; i++)
253 12365460
                        VSB_putc(d, ' ');
254 1458498
        }
255 1553766
        p = VSB_data(e1->vsb);
256 151999118
        while (*p != '\0') {
257 150445420
                if (*p == '\n') {
258 4567696
                        VSB_putc(d, '\n');
259 4567696
                        if (*++p == '\0')
260 68
                                break;
261 48938682
                        for (i = 0; i < ind; i++)
262 44371054
                                VSB_putc(d, ' ');
263 150445352
                } else if (*p != '\v') {
264 143767752
                        VSB_putc(d, *p++);
265 143767752
                } else {
266 2109972
                        switch (*++p) {
267 1054986
                        case '+': ind += INDENT; break;
268 1054986
                        case '-': ind -= INDENT; break;
269 0
                        default:  WRONG("Illegal format in VCC expression");
270 0
                        }
271 2109972
                        p++;
272
                }
273
        }
274 1553766
}
275
276
/*--------------------------------------------------------------------
277
 */
278
279
static void
280 1189711
vcc_expr_tobool(struct vcc *tl, struct expr **e)
281
{
282
283 1189711
        if ((*e)->fmt == BOOL)
284 903074
                return;
285 286637
        if ((*e)->fmt == BACKEND || (*e)->fmt == INT)
286 170
                *e = vcc_expr_edit(tl, BOOL, "(\v1 != 0)", *e, NULL);
287 286467
        else if ((*e)->fmt == DURATION)
288 34
                *e = vcc_expr_edit(tl, BOOL, "(\v1 > 0)", *e, NULL);
289 286433
        else if ((*e)->fmt == STRINGS)
290 286331
                *e = vcc_expr_edit(tl, BOOL, "VRT_Strands2Bool(\vT)", *e, NULL);
291
        /*
292
         * We do not provide automatic folding from REAL to BOOL
293
         * because comparing to zero is seldom an exact science
294
         * and we want to force people to explicitly get it right.
295
         */
296 1189711
}
297
298
/*--------------------------------------------------------------------
299
 */
300
301
static void
302 930495
vcc_expr_tostring(struct vcc *tl, struct expr **e)
303
{
304
        const char *p;
305 930495
        uint8_t constant = EXPR_VAR;
306
307 930495
        CHECK_OBJ_NOTNULL(*e, EXPR_MAGIC);
308 930495
        assert((*e)->fmt != STRINGS);
309
310 930495
        p = (*e)->fmt->tostring;
311 930495
        if (p != NULL) {
312 930478
                AN(*p);
313 930478
                *e = vcc_expr_edit(tl, STRINGS, p, *e, NULL);
314 930478
                (*e)->constant = constant;
315 930478
                (*e)->nstr = 1;
316 930478
        } else {
317 34
                VSB_printf(tl->sb,
318
                    "Cannot convert %s to STRING.\n",
319 17
                    vcc_utype((*e)->fmt));
320 17
                vcc_ErrWhere2(tl, (*e)->t1, tl->t);
321
        }
322 930495
}
323
324
/*--------------------------------------------------------------------
325
 */
326
327
void v_matchproto_(sym_expr_t)
328 7038
vcc_Eval_Handle(struct vcc *tl, struct expr **e, struct token *t,
329
    struct symbol *sym, vcc_type_t type)
330
{
331
332 7038
        (void)t;
333 7038
        (void)tl;
334 7038
        AN(sym->rname);
335 7038
        AZ(type->stringform);
336
337 7123
        if (sym->type->tostring == NULL &&
338 85
            sym->type != STRING && type == STRINGS) {
339 0
                *e = vcc_mk_expr(STRINGS, "\"%s\"", sym->name);
340 0
                (*e)->nstr = 1;
341 0
                (*e)->constant |= EXPR_CONST | EXPR_STR_CONST;
342 0
        } else {
343 7038
                *e = vcc_mk_expr(sym->type, "%s", sym->rname);
344 7038
                (*e)->constant = EXPR_VAR;
345 7038
                (*e)->nstr = 1;
346 7038
                if ((*e)->fmt == STRING)
347 0
                        (*e)->fmt = STRINGS;
348
        }
349 7038
}
350
351
void v_matchproto_(sym_expr_t)
352 391
vcc_Eval_Sub(struct vcc *tl, struct expr **e, struct token *t,
353
    struct symbol *sym, vcc_type_t type)
354
{
355
356 391
        (void)t;
357 391
        (void)tl;
358 391
        AN(sym->rname);
359 391
        AZ(type->stringform);
360
361 391
        assert (sym->type == SUB);
362
363 391
        if (type == SUB) {
364 340
                *e = vcc_mk_expr(sym->type, "%s", sym->rname);
365 340
                (*e)->constant = EXPR_CONST;
366 340
                return;
367
        }
368
369 102
        VSB_printf(tl->sb, "Symbol '%s' can only be used as a %s expression\n",
370 51
            sym->name, sym->type->name);
371 51
        vcc_ErrWhere(tl, tl->t);
372 391
}
373
374
/*--------------------------------------------------------------------
375
 */
376
377
void v_matchproto_(sym_expr_t)
378 2123759
vcc_Eval_Var(struct vcc *tl, struct expr **e, struct token *t,
379
    struct symbol *sym, vcc_type_t type)
380
{
381
382 2123759
        (void)type;
383 2123759
        vcc_AddUses(tl, t, NULL, sym, XREF_READ);
384 2123759
        ERRCHK(tl);
385 2123759
        *e = vcc_mk_expr(sym->type, "%s", sym->rname);
386 2123759
        (*e)->constant = EXPR_VAR;
387 2123759
        (*e)->nstr = 1;
388 2123759
        if ((*e)->fmt == STRING)
389 958154
                (*e)->fmt = STRINGS;
390 2123759
}
391
392
void v_matchproto_(sym_expr_t)
393 187
vcc_Eval_ProtectedHeader(struct vcc *tl, struct expr **e, struct token *t,
394
    struct symbol *sym, vcc_type_t type)
395
{
396
397 187
        AN(sym);
398 187
        AZ(sym->lorev);
399
400 187
        vcc_Header_Fh(tl, sym);
401 187
        sym->eval = vcc_Eval_Var;
402 187
        vcc_Eval_Var(tl, e, t, sym, type);
403 187
}
404
405
/*--------------------------------------------------------------------
406
 */
407
408
static struct expr *
409 2924
vcc_priv_arg(struct vcc *tl, const char *p, struct symbol *sym)
410
{
411
        char buf[64];
412
        struct inifin *ifp;
413 2924
        const char *f = NULL;
414
415 2924
        AN(sym);
416 2924
        AN(sym->vmod_name);
417
418 2924
        if (!strcmp(p, "PRIV_VCL"))
419 255
                return (vcc_mk_expr(VOID, "&vmod_priv_%s", sym->vmod_name));
420
421 2669
        if (!strcmp(p, "PRIV_CALL")) {
422 374
                bprintf(buf, "vmod_priv_%u", tl->unique++);
423 374
                ifp = New_IniFin(tl);
424 374
                Fh(tl, 0, "static struct vmod_priv %s;\n", buf);
425 374
                VSB_printf(ifp->fin, "\tVRT_priv_fini(ctx, &%s);", buf);
426 374
                return (vcc_mk_expr(VOID, "&%s", buf));
427
        }
428
429 2295
        if (!strcmp(p, "PRIV_TASK"))
430 2159
                f = "task";
431 136
        else if (!strcmp(p, "PRIV_TOP")) {
432 136
                f = "top";
433 136
                sym->r_methods &= VCL_MET_TASK_C;
434 136
        } else {
435 0
                WRONG("Wrong PRIV_ type");
436
        }
437 2295
        AN(f);
438
439 2295
        return (vcc_mk_expr(VOID, "VRT_priv_%s(ctx, &VGC_vmod_%s)",
440 2295
            f, sym->vmod_name));
441 2924
}
442
443
struct func_arg {
444
        vcc_type_t              type;
445
        const struct vjsn_val   *enums;
446
        const char              *name;
447
        const char              *val;
448
        struct expr             *result;
449
        int                     avail;
450
        int                     optional;
451
        VTAILQ_ENTRY(func_arg)  list;
452
};
453
454
static struct expr *
455 30889
vcc_do_enum(struct vcc *tl, const char *cfunc, int len, const char *ptr)
456
{
457
        const char *r;
458
459 30889
        (void)tl;
460 30889
        r = strchr(cfunc, '.');
461 30889
        AN(r);
462 30889
        return (vcc_mk_expr(VOID, "*%.*s.enum_%.*s",
463 30889
            (int)(r - cfunc), cfunc, len, ptr));
464
}
465
466
static void
467 67541
vcc_do_arg(struct vcc *tl, const char *cfunc, struct func_arg *fa)
468
{
469
        struct expr *e2;
470
        struct vjsn_val *vv;
471
472 67541
        if (fa->type == ENUM) {
473 22695
                ExpectErr(tl, ID);
474 22695
                ERRCHK(tl);
475 77656
                VTAILQ_FOREACH(vv, &fa->enums->children, list)
476 77622
                        if (vcc_IdIs(tl->t, vv->value))
477 22661
                                break;
478 22695
                if (vv == NULL) {
479 34
                        VSB_cat(tl->sb, "Wrong enum value.");
480 34
                        VSB_cat(tl->sb, "  Expected one of:\n");
481 170
                        VTAILQ_FOREACH(vv, &fa->enums->children, list)
482 136
                                VSB_printf(tl->sb, "\t%s\n", vv->value);
483 34
                        vcc_ErrWhere(tl, tl->t);
484 34
                        return;
485
                }
486 22661
                fa->result = vcc_do_enum(tl, cfunc, PF(tl->t));
487 22661
                SkipToken(tl, ID);
488 22661
        } else {
489 44846
                if (fa->type == SUB)
490 340
                        tl->subref++;
491 44846
                vcc_expr0(tl, &e2, fa->type);
492 44846
                ERRCHK(tl);
493 44710
                assert(e2->fmt == fa->type);
494 44710
                fa->result = e2;
495
        }
496 67371
        fa->avail = 1;
497 67541
}
498
499
static void
500 46750
vcc_func(struct vcc *tl, struct expr **e, const void *priv,
501
    const char *extra, struct symbol *sym)
502
{
503
        vcc_type_t rfmt;
504
        const char *cfunc;
505
        struct expr *e1;
506
        struct func_arg *fa, *fa2;
507
        VTAILQ_HEAD(,func_arg) head;
508
        struct token *tf, *t1;
509
        const struct vjsn_val *vv, *vvp;
510
        const char *sa, *extra_sep;
511
        char ssa[64];
512
        int n;
513
514 46750
        CAST_OBJ_NOTNULL(vv, priv, VJSN_VAL_MAGIC);
515 46750
        assert(vjsn_is_array(vv));
516 46750
        vv = VTAILQ_FIRST(&vv->children);
517 46750
        rfmt = VCC_Type(VTAILQ_FIRST(&vv->children)->value);
518 46750
        AN(rfmt);
519 46750
        vv = VTAILQ_NEXT(vv, list);
520 46750
        cfunc = vv->value;
521 46750
        vv = VTAILQ_NEXT(vv, list);
522 46750
        sa = vv->value;
523 46750
        if (*sa == '\0') {
524 39899
                sa = NULL;
525 39899
        }
526 46750
        vv = VTAILQ_NEXT(vv, list);
527 46750
        if (sym->kind == SYM_METHOD) {
528 13158
                if (*e == NULL) {
529 34
                        VSB_cat(tl->sb, "Syntax error.");
530 34
                        tl->err = 1;
531 34
                        return;
532
                }
533 13124
                vcc_NextToken(tl);
534 13124
                AZ(extra);
535 13124
                AN((*e)->instance);
536 13124
                extra = (*e)->instance->rname;
537 13124
        }
538 46716
        tf = VTAILQ_PREV(tl->t, tokenhead, list);
539 46716
        SkipToken(tl, '(');
540 46716
        if (extra == NULL) {
541 30175
                extra = "";
542 30175
                extra_sep = "";
543 30175
        } else {
544 16541
                AN(*extra);
545 16541
                extra_sep = ", ";
546
        }
547 46716
        VTAILQ_INIT(&head);
548 156621
        for (;vv != NULL; vv = VTAILQ_NEXT(vv, list)) {
549 109905
                assert(vjsn_is_array(vv));
550 109905
                fa = calloc(1, sizeof *fa);
551 109905
                AN(fa);
552 109905
                VTAILQ_INSERT_TAIL(&head, fa, list);
553
554 109905
                vvp = VTAILQ_FIRST(&vv->children);
555 109905
                if (!memcmp(vvp->value, "PRIV_", 5)) {
556 2924
                        fa->result = vcc_priv_arg(tl, vvp->value, sym);
557 2924
                        vvp = VTAILQ_NEXT(vvp, list);
558 2924
                        if (vvp != NULL)
559 51
                                fa->name = vvp->value;
560 2924
                        continue;
561
                }
562 106981
                fa->type = VCC_Type(vvp->value);
563 106981
                AN(fa->type);
564 106981
                vvp = VTAILQ_NEXT(vvp, list);
565 106981
                if (vvp != NULL) {
566 100300
                        fa->name = vvp->value;
567 100300
                        vvp = VTAILQ_NEXT(vvp, list);
568 100300
                        if (vvp != NULL) {
569 73508
                                fa->val = vvp->value;
570 73508
                                vvp = VTAILQ_NEXT(vvp, list);
571 73508
                                if (vvp != NULL) {
572 59755
                                        fa->enums = vvp;
573 59755
                                        vvp = VTAILQ_NEXT(vvp, list);
574 59755
                                }
575 73508
                        }
576 100300
                }
577 106981
                if (sa != NULL && vvp != NULL && vjsn_is_true(vvp)) {
578 30957
                        fa->optional = 1;
579 30957
                        vvp = VTAILQ_NEXT(vvp, list);
580 30957
                }
581 106981
                AZ(vvp);
582 106981
        }
583
584 75327
        VTAILQ_FOREACH(fa, &head, list) {
585 67558
                if (tl->t->tok == ')')
586 1513
                        break;
587 66045
                if (fa->result != NULL)
588 2091
                        continue;
589 63954
                if (tl->t->tok == ID) {
590 47056
                        t1 = VTAILQ_NEXT(tl->t, list);
591 47056
                        if (t1->tok == '=')
592 12784
                                break;
593 34272
                }
594 51170
                vcc_do_arg(tl, cfunc, fa);
595 51170
                if (tl->err)
596 340
                        VSB_printf(tl->sb, "Expected argument: %s %s\n\n",
597 170
                            fa->type->name,
598 170
                            fa->name ? fa->name : "(unnamed argument)");
599 51170
                ERRCHK(tl);
600 51000
                if (tl->t->tok == ')')
601 24480
                        break;
602 26520
                SkipToken(tl, ',');
603 26520
        }
604 50167
        while (tl->t->tok == ID) {
605 53278
                VTAILQ_FOREACH(fa, &head, list) {
606 53261
                        if (fa->name == NULL)
607 204
                                continue;
608 53057
                        if (vcc_IdIs(tl->t, fa->name))
609 16388
                                break;
610 36669
                }
611 16405
                if (fa == NULL) {
612 34
                        VSB_printf(tl->sb, "Unknown argument '%.*s'\n",
613 17
                            PF(tl->t));
614 17
                        vcc_ErrWhere(tl, tl->t);
615 17
                        return;
616
                }
617 16388
                if (fa->result != NULL) {
618 17
                        AN(fa->name);
619 34
                        VSB_printf(tl->sb, "Argument '%s' already used\n",
620 17
                            fa->name);
621 17
                        vcc_ErrWhere(tl, tl->t);
622 17
                        return;
623
                }
624 16371
                vcc_NextToken(tl);
625 16371
                SkipToken(tl, '=');
626 16371
                vcc_do_arg(tl, cfunc, fa);
627 16371
                ERRCHK(tl);
628 16371
                if (tl->t->tok == ')')
629 12750
                        break;
630 3621
                SkipToken(tl, ',');
631
        }
632
633 46512
        if (sa != NULL)
634 13566
                e1 = vcc_mk_expr(rfmt, "%s(ctx%s%s,\v+\n&(%s)\v+ {\n",
635 6783
                    cfunc, extra_sep, extra, sa);
636
        else
637 79458
                e1 = vcc_mk_expr(rfmt, "%s(ctx%s%s\v+",
638 39729
                    cfunc, extra_sep, extra);
639 46512
        n = 0;
640 155856
        VTAILQ_FOREACH_SAFE(fa, &head, list, fa2) {
641 109344
                n++;
642 109344
                if (fa->optional) {
643 30855
                        AN(fa->name);
644 30855
                        bprintf(ssa, "\v1.valid_%s = %d,\n",
645
                            fa->name, fa->avail);
646 30855
                        e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, NULL);
647 30855
                }
648 109344
                if (fa->result == NULL && fa->type == ENUM && fa->val != NULL)
649 8228
                        fa->result = vcc_do_enum(tl, cfunc, strlen(fa->val), fa->val);
650 109344
                if (fa->result == NULL && fa->val != NULL)
651 10166
                        fa->result = vcc_mk_expr(fa->type, "%s", fa->val);
652 109344
                if (fa->result != NULL && sa != NULL) {
653 14722
                        if (fa->name)
654 14365
                                bprintf(ssa, "\v1.%s = \v2,\n", fa->name);
655
                        else
656 357
                                bprintf(ssa, "\v1.arg%d = \v2,\n", n);
657 14722
                        e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, fa->result);
658 109344
                } else if (fa->result != NULL) {
659 147764
                        e1 = vcc_expr_edit(tl, e1->fmt, "\v1,\n\v2",
660 73882
                            e1, fa->result);
661 94622
                } else if (!fa->optional) {
662 17
                        if (fa->name)
663 34
                                VSB_printf(tl->sb, "Argument '%s' missing\n",
664 17
                                    fa->name);
665
                        else
666 0
                                VSB_printf(tl->sb, "Argument %d missing\n", n);
667 17
                        vcc_ErrWhere(tl, tl->t);
668 17
                }
669 109344
                free(fa);
670 109344
        }
671 46512
        if (sa != NULL) {
672 6783
                *e = vcc_expr_edit(tl, e1->fmt, "\v1\v-\n}\v-\n)", e1, NULL);
673 6783
        } else {
674 39729
                *e = vcc_expr_edit(tl, e1->fmt, "\v1\v-\n)", e1, NULL);
675
        }
676 46512
        SkipToken(tl, ')');
677 46495
        vcc_AddUses(tl, tf, NULL, sym, XREF_READ);
678 46750
}
679
680
681
/*--------------------------------------------------------------------
682
 */
683
684
void
685 3417
vcc_Eval_Func(struct vcc *tl, const struct vjsn_val *spec,
686
    const char *extra, struct symbol *sym)
687
{
688 3417
        struct expr *e = NULL;
689
690 3417
        vcc_func(tl, &e, spec, extra, sym);
691 3417
        if (tl->err)
692 0
                VSB_cat(tl->sb, "While compiling function call:\n");
693 3417
        ERRCHK(tl);
694 3417
        vcc_expr_fmt(tl->fb, tl->indent, e);
695 3417
        VSB_cat(tl->fb, ";\n");
696 3417
        vcc_delete_expr(e);
697 3417
}
698
699
/*--------------------------------------------------------------------
700
 */
701
702
void v_matchproto_(sym_expr_t)
703 35309
vcc_Eval_SymFunc(struct vcc *tl, struct expr **e, struct token *t,
704
    struct symbol *sym, vcc_type_t fmt)
705
{
706
707 35309
        (void)t;
708 35309
        (void)fmt;
709 35309
        assert(sym->kind == SYM_FUNC || sym->kind == SYM_METHOD);
710 35309
        AN(sym->eval_priv);
711
712 35309
        vcc_func(tl, e, sym->eval_priv, sym->extra, sym);
713 35309
        ERRCHK(tl);
714 35139
        if ((*e)->fmt == STRING) {
715 12784
                (*e)->fmt = STRINGS;
716 12784
                (*e)->nstr = 1;
717 12784
        }
718 35309
}
719
720
/*--------------------------------------------------------------------
721
 */
722
723
static void
724 400129
vcc_number(struct vcc *tl, struct expr **e, vcc_type_t fmt, const char *sign)
725
{
726
        VCL_INT vi;
727
        struct expr *e1;
728
        struct token *t;
729
730 400129
        assert(fmt != VOID);
731 400129
        if (fmt == BYTES) {
732 816
                vcc_ByteVal(tl, &vi);
733 816
                ERRCHK(tl);
734 782
                e1 = vcc_mk_expr(BYTES, "%ju", (intmax_t)vi);
735 782
        } else {
736 399313
                t = tl->t;
737 399313
                vcc_NextToken(tl);
738 399313
                if (tl->t->tok == ID) {
739 98906
                        e1 = vcc_mk_expr(DURATION, "%s%.3f * %g",
740 98906
                            sign, t->num, vcc_DurationUnit(tl));
741 98906
                        ERRCHK(tl);
742 399296
                } else if (fmt == REAL || t->tok == FNUM) {
743 2618
                        e1 = vcc_mk_expr(REAL, "%s%.3f", sign, t->num);
744 2618
                } else {
745 297789
                        e1 = vcc_mk_expr(INT, "%s%.0f", sign, t->num);
746
                }
747
        }
748 400078
        e1->constant = EXPR_CONST;
749 400078
        *e = e1;
750 400129
}
751
752
/*--------------------------------------------------------------------
753
 * SYNTAX:
754
 *    Expr5:
755
 *      '(' ExprCor ')'
756
 *      symbol
757
 *      CNUM
758
 *      FNUM
759
 *      CSTR
760
 *      CBLOB
761
 */
762
763
static void
764 4413693
vcc_expr5(struct vcc *tl, struct expr **e, vcc_type_t fmt)
765
{
766
        struct expr *e1, *e2;
767
        const char *ip, *sign;
768
        struct token *t, *t1;
769
        struct symbol *sym;
770
771 4413693
        sign = "";
772 4413693
        *e = NULL;
773 4413693
        if (tl->t->tok == '(') {
774 48161
                SkipToken(tl, '(');
775 48161
                vcc_expr_cor(tl, &e2, fmt);
776 48161
                ERRCHK(tl);
777 48161
                SkipToken(tl, ')');
778 48161
                if (e2->fmt == STRINGS)
779 102
                        *e = e2;
780
                else
781 48059
                        *e = vcc_expr_edit(tl, e2->fmt, "(\v1)", e2, NULL);
782 48161
                return;
783
        }
784 4365532
        switch (tl->t->tok) {
785
        case ID:
786 2219163
                t = tl->t;
787 2219163
                t1 = vcc_PeekToken(tl);
788 2219163
                AN(t1);
789 2219163
                sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
790
                    SYMTAB_PARTIAL_NOERR, XREF_REF);
791 2219163
                if (sym == NULL && fmt->global_pfx != NULL && t1->tok != '.') {
792 153
                        sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
793
                            SYMTAB_CREATE, XREF_REF);
794 153
                        ERRCHK(tl);
795 119
                        AN(sym);
796 119
                        VCC_GlobalSymbol(sym, fmt);
797 119
                }
798 2219129
                ERRCHK(tl);
799 2219129
                if (sym == NULL)
800 204
                        AZ(VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
801
                            SYMTAB_PARTIAL, XREF_REF));
802 2219129
                ERRCHK(tl);
803 2218925
                AN(sym);
804 2218925
                if (sym->kind == SYM_INSTANCE) {
805 13158
                        AZ(*e);
806 13158
                        *e = vcc_new_expr(sym->type);
807 13158
                        (*e)->instance = sym;
808 13158
                        return;
809
                }
810 2205767
                if (sym->kind == SYM_FUNC && sym->type == VOID) {
811 17
                        VSB_cat(tl->sb, "Function returns VOID:\n");
812 17
                        vcc_ErrWhere(tl, tl->t);
813 17
                        return;
814
                }
815 2205750
                if (sym->eval != NULL) {
816 2205699
                        AN(sym->eval);
817 2205699
                        AZ(*e);
818 2205699
                        sym->eval(tl, e, t, sym, fmt);
819 2205699
                        if (tl->err) {
820 272
                                VSB_cat(tl->sb,
821
                                    "While compiling function call:\n\n");
822 272
                                vcc_ErrWhere2(tl, t, tl->t);
823 272
                        }
824 2205699
                        ERRCHK(tl);
825
                        /* Unless asked for a HEADER, fold to string here */
826 2205427
                        if (*e && fmt != HEADER && (*e)->fmt == HEADER) {
827 586619
                                vcc_expr_tostring(tl, e);
828 586619
                                ERRCHK(tl);
829 586619
                        }
830 2205427
                        return;
831
                }
832 102
                VSB_printf(tl->sb,
833
                    "Symbol '%.*s' type (%s) cannot be used in expression.\n",
834 51
                    PF(t), sym->kind->name);
835 51
                vcc_ErrWhere(tl, t);
836 51
                if (sym->def_b != NULL) {
837 17
                        VSB_cat(tl->sb, "That symbol was defined here:\n");
838 17
                        vcc_ErrWhere(tl, sym->def_b);
839 17
                }
840 51
                return;
841
        case CSTR:
842 1745985
                assert(fmt != VOID);
843 1745985
                if (fmt == IP) {
844 510
                        if (*tl->t->dec == '/') {
845
                                /*
846
                                 * On some platforms (e.g. FreeBSD),
847
                                 * getaddrinfo(3) may resolve a path to a
848
                                 * sockaddr_un if it happens to exist and
849
                                 * is a socket. So don't let that happen.
850
                                 */
851 17
                                VSB_cat(tl->sb,
852
                                    "Cannot convert to an IP address: ");
853 17
                                vcc_ErrToken(tl, tl->t);
854 17
                                vcc_ErrWhere(tl, tl->t);
855 17
                                return;
856
                        }
857 986
                        Resolve_Sockaddr(tl, tl->t->dec, "80",
858
                            &ip, NULL, &ip, NULL, NULL, 1,
859 493
                            tl->t, "IP constant");
860 493
                        ERRCHK(tl);
861 442
                        e1 = vcc_mk_expr(IP, "%s", ip);
862 442
                        ERRCHK(tl);
863 1745917
                } else if (fmt == REGEX) {
864 144602
                        e1 = vcc_new_expr(REGEX);
865 144602
                        vcc_regexp(tl, e1->vsb);
866 144602
                        AZ(VSB_finish(e1->vsb));
867 144602
                } else {
868 1600873
                        e1 = vcc_new_expr(STRINGS);
869 1600873
                        EncToken(e1->vsb, tl->t);
870 1600873
                        AZ(VSB_finish(e1->vsb));
871 1600873
                        e1->constant |= EXPR_STR_CONST;
872 1600873
                        e1->nstr = 1;
873
                }
874 1745917
                e1->t1 = tl->t;
875 1745917
                e1->constant |= EXPR_CONST;
876 1745917
                vcc_NextToken(tl);
877 1745917
                *e = e1;
878 1745917
                return;
879
        case '-':
880 1054
                if (fmt != INT &&
881 272
                    fmt != REAL &&
882 68
                    fmt != DURATION &&
883 17
                    fmt != STRINGS)
884 0
                        break;
885 1037
                vcc_NextToken(tl);
886 1037
                if (tl->t->tok != FNUM && tl->t->tok != CNUM) {
887 153
                        vcc_expr_cor(tl, &e1, fmt);
888 153
                        ERRCHK(tl);
889 153
                        *e = vcc_expr_edit(tl, e1->fmt, "-(\v1)", e1, NULL);
890 153
                        return;
891
                }
892 884
                sign = "-";
893
                /* FALLTHROUGH */
894
        case FNUM:
895
        case CNUM:
896 400129
                vcc_number(tl, e, fmt, sign);
897 400129
                return;
898
        case CBLOB:
899 34
                e1 = vcc_new_expr(BLOB);
900 34
                VSB_printf(e1->vsb, "%s", tl->t->dec);
901 34
                AZ(VSB_finish(e1->vsb));
902 34
                e1->constant |= EXPR_STR_CONST;
903 34
                e1->t1 = tl->t;
904 34
                vcc_NextToken(tl);
905 34
                *e = e1;
906 34
                return;
907
        default:
908 68
                break;
909
        }
910 68
        VSB_cat(tl->sb, "Unknown token ");
911 68
        vcc_ErrToken(tl, tl->t);
912 68
        VSB_printf(tl->sb, " when looking for %s\n\n", vcc_utype(fmt));
913 68
        vcc_ErrWhere(tl, tl->t);
914 4413693
}
915
916
/*--------------------------------------------------------------------
917
 * SYNTAX:
918
 *    Expr4:
919
 *      Expr5 [ '.' (type_attribute | type_method()) ]*
920
 */
921
922
void
923 47804
vcc_Eval_TypeMethod(struct vcc *tl, struct expr **e, struct token *t,
924
    struct symbol *sym, vcc_type_t fmt)
925
{
926
        const char *impl;
927
928 47804
        (void)t;
929 47804
        impl = VCC_Type_EvalMethod(tl, sym);
930 47804
        ERRCHK(tl);
931 47804
        AN(impl);
932 47804
        *e = vcc_expr_edit(tl, fmt, impl, *e, NULL);
933 47804
}
934
935
static void
936 4413693
vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt)
937
{
938
        struct symbol *sym;
939
940 4413693
        *e = NULL;
941 4413693
        vcc_expr5(tl, e, fmt);
942 4413693
        ERRCHK(tl);
943 4412877
        AN(*e);
944 4473805
        while (tl->t->tok == '.') {
945 60979
                vcc_NextToken(tl);
946 60979
                ExpectErr(tl, ID);
947
948 60962
                sym = VCC_TypeSymbol(tl, SYM_METHOD, (*e)->fmt);
949 60962
                if (sym == NULL) {
950 34
                        VSB_cat(tl->sb, "Unknown property ");
951 34
                        vcc_ErrToken(tl, tl->t);
952 34
                        VSB_printf(tl->sb, " for type %s\n", (*e)->fmt->name);
953 34
                        vcc_ErrWhere(tl, tl->t);
954 34
                        return;
955
                }
956
957 60928
                AN(sym->eval);
958 60928
                sym->eval(tl, e, tl->t, sym, sym->type);
959 60928
                ERRCHK(tl);
960 60928
                if ((*e)->fmt == STRING) {
961 47617
                        (*e)->fmt = STRINGS;
962 47617
                        (*e)->nstr = 1;
963 47617
                }
964
        }
965 4413693
}
966
967
/*--------------------------------------------------------------------
968
 * SYNTAX:
969
 *    ExprMul:
970
 *      Expr4 { {'*'|'/'|'%'} Expr4 } *
971
 */
972
973
static void
974 4262767
vcc_expr_mul(struct vcc *tl, struct expr **e, vcc_type_t fmt)
975
{
976
        struct expr *e2;
977
        vcc_type_t f2;
978
        struct token *tk;
979
        char buf[24];
980
981 4262767
        *e = NULL;
982 4262767
        vcc_expr4(tl, e, fmt);
983 4262767
        ERRCHK(tl);
984 4262019
        AN(*e);
985
986 4262648
        while (tl->t->tok == '*' || tl->t->tok == '/' || tl->t->tok == '%') {
987 697
                if (tl->t->tok == '%' && ((*e)->fmt != INT)) {
988 17
                        VSB_cat(tl->sb, "Operator % only possible on INT.\n");
989 17
                        vcc_ErrWhere(tl, tl->t);
990 17
                        return;
991
                }
992 680
                f2 = (*e)->fmt->multype;
993 680
                if (f2 == NULL) {
994 34
                        VSB_printf(tl->sb,
995
                            "Operator %.*s not possible on type %s.\n",
996 17
                            PF(tl->t), vcc_utype((*e)->fmt));
997 17
                        vcc_ErrWhere(tl, tl->t);
998 17
                        return;
999
                }
1000 663
                tk = tl->t;
1001 663
                vcc_NextToken(tl);
1002 663
                vcc_expr4(tl, &e2, f2);
1003 663
                ERRCHK(tl);
1004 663
                if (e2->fmt != INT && e2->fmt != f2) {
1005 68
                        VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
1006 34
                            vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1007 34
                        vcc_ErrWhere(tl, tk);
1008 34
                        return;
1009
                }
1010 629
                bprintf(buf, "(\v1%c\v2)", tk->tok);
1011 629
                *e = vcc_expr_edit(tl, (*e)->fmt, buf, *e, e2);
1012
        }
1013 4262767
}
1014
1015
/*--------------------------------------------------------------------
1016
 * SYNTAX:
1017
 *    ExprAdd:
1018
 *      ExprMul { {'+'|'-'} ExprMul } *
1019
 */
1020
1021
static const struct adds {
1022
        unsigned        op;
1023
        vcc_type_t      a;
1024
        vcc_type_t      b;
1025
        vcc_type_t      fmt;
1026
} vcc_adds[] = {
1027
        { '+', BYTES,           BYTES,          BYTES },
1028
        { '-', BYTES,           BYTES,          BYTES },
1029
        { '+', DURATION,        DURATION,       DURATION },
1030
        { '-', DURATION,        DURATION,       DURATION },
1031
        { '+', INT,             INT,            INT },
1032
        { '-', INT,             INT,            INT },
1033
        { '+', INT,             REAL,           REAL },
1034
        { '-', INT,             REAL,           REAL },
1035
        { '+', REAL,            INT,            REAL },
1036
        { '-', REAL,            INT,            REAL },
1037
        { '+', REAL,            REAL,           REAL },
1038
        { '-', REAL,            REAL,           REAL },
1039
        { '-', TIME,            TIME,           DURATION },
1040
        { '+', TIME,            DURATION,       TIME },
1041
        { '-', TIME,            DURATION,       TIME },
1042
1043
        { EOI, VOID,            VOID,           VOID }
1044
};
1045
1046
static void
1047 3114468
vcc_expr_add(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1048
{
1049
        const struct adds *ap;
1050
        struct expr  *e2;
1051
        struct token *tk;
1052
        int lit, n;
1053
1054 3114468
        *e = NULL;
1055 3114468
        vcc_expr_mul(tl, e, fmt);
1056 3114468
        ERRCHK(tl);
1057
1058 4261764
        while (tl->t->tok == '+' || tl->t->tok == '-') {
1059 1148299
                tk = tl->t;
1060 18359966
                for (ap = vcc_adds; ap->op != EOI; ap++)
1061 17212942
                        if (tk->tok == ap->op && (*e)->fmt == ap->a)
1062 1275
                                break;
1063 1148299
                vcc_NextToken(tl);
1064 1148299
                if (ap->op == EOI && fmt == STRINGS)
1065 8568
                        vcc_expr_mul(tl, &e2, STRINGS);
1066
                else
1067 1139731
                        vcc_expr_mul(tl, &e2, (*e)->fmt);
1068 1148299
                ERRCHK(tl);
1069
1070 18362040
                for (ap = vcc_adds; ap->op != EOI; ap++)
1071 17214846
                        if (tk->tok == ap->op && (*e)->fmt == ap->a &&
1072 17214846
                            e2->fmt == ap->b)
1073 1105
                                break;
1074
1075 1148299
                if (ap->op == '+') {
1076 765
                        *e = vcc_expr_edit(tl, ap->fmt, "(\v1 + \v2)", *e, e2);
1077 1148299
                } else if (ap->op == '-') {
1078 340
                        *e = vcc_expr_edit(tl, ap->fmt, "(\v1 - \v2)", *e, e2);
1079 1147789
                } else if (tk->tok == '+' &&
1080 1147177
                    ((*e)->fmt == STRINGS || fmt == STRINGS)) {
1081 1147007
                        if ((*e)->fmt != STRINGS)
1082 85
                                vcc_expr_tostring(tl, e);
1083 1147007
                        if (e2->fmt != STRINGS)
1084 285532
                                vcc_expr_tostring(tl, &e2);
1085 1147007
                        if (vcc_islit(*e) && vcc_isconst(e2)) {
1086 816
                                lit = vcc_islit(e2);
1087 1632
                                *e = vcc_expr_edit(tl, STRINGS,
1088 816
                                    "\v1\n\v2", *e, e2);
1089 816
                                (*e)->constant = EXPR_CONST;
1090 816
                                (*e)->nstr = 1;
1091 816
                                if (lit)
1092 816
                                        (*e)->constant |= EXPR_STR_CONST;
1093 816
                        } else {
1094 1146191
                                n = (*e)->nstr + e2->nstr;
1095 2292382
                                *e = vcc_expr_edit(tl, STRINGS,
1096 1146191
                                    "\v1,\n\v2", *e, e2);
1097 1146191
                                (*e)->constant = EXPR_VAR;
1098 1146191
                                (*e)->nstr = n;
1099
                        }
1100 1147007
                } else {
1101 374
                        VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
1102 187
                            vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1103 187
                        vcc_ErrWhere2(tl, tk, tl->t);
1104 187
                        return;
1105
                }
1106
        }
1107 3114468
}
1108
1109
/*--------------------------------------------------------------------
1110
 * SYNTAX:
1111
 *    ExprCmp:
1112
 *      ExprAdd
1113
 *      ExprAdd Relation ExprAdd
1114
 *      ExprAdd(STRING) '~' CString
1115
 *      ExprAdd(STRING) '!~' CString
1116
 *      ExprAdd(IP) '==' ExprAdd(IP)
1117
 *      ExprAdd(IP) '!=' ExprAdd(IP)
1118
 *      ExprAdd(IP) '~' ACL
1119
 *      ExprAdd(IP) '!~' ACL
1120
 */
1121
1122
struct cmps;
1123
1124
typedef void cmp_f(struct vcc *, struct expr **, const struct cmps *);
1125
1126
struct cmps {
1127
        vcc_type_t              fmt;
1128
        unsigned                token;
1129
        cmp_f                   *func;
1130
        const char              *emit;
1131
};
1132
1133
static void v_matchproto_(cmp_f)
1134 192117
cmp_simple(struct vcc *tl, struct expr **e, const struct cmps *cp)
1135
{
1136
        struct expr *e2;
1137
        struct token *tk;
1138
1139 192117
        tk = tl->t;
1140 192117
        vcc_NextToken(tl);
1141 192117
        vcc_expr_add(tl, &e2, (*e)->fmt);
1142 192117
        ERRCHK(tl);
1143
1144 192066
        if (e2->fmt != (*e)->fmt) {
1145 68
                VSB_printf(tl->sb,
1146
                    "Comparison of different types: %s '%.*s' %s\n",
1147 34
                    vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1148 34
                vcc_ErrWhere(tl, tk);
1149 34
        } else
1150 192032
                *e = vcc_expr_edit(tl, BOOL, cp->emit, *e, e2);
1151 192117
}
1152
1153
static void v_matchproto_(cmp_f)
1154 143837
cmp_regexp(struct vcc *tl, struct expr **e, const struct cmps *cp)
1155
{
1156
        struct token *t1;
1157
        struct expr *e2;
1158
        char buf[128];
1159
1160 143837
        *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
1161 143837
        vcc_NextToken(tl);
1162 143837
        t1 = tl->t;
1163 143837
        vcc_expr4(tl, &e2, REGEX);
1164 143837
        ERRCHK(tl);
1165 143769
        vcc_expr_typecheck(tl, &e2, REGEX, t1);
1166 143769
        ERRCHK(tl);
1167 143752
        bprintf(buf, "%sVRT_re_match(ctx, \v1, \v2)", cp->emit);
1168 143752
        *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1169 143837
}
1170
1171
static void v_matchproto_(cmp_f)
1172 765
cmp_acl(struct vcc *tl, struct expr **e, const struct cmps *cp)
1173
{
1174
        struct token *t1;
1175
        struct expr *e2;
1176
        char buf[256];
1177
1178 765
        vcc_NextToken(tl);
1179 765
        t1 = tl->t;
1180 765
        vcc_expr4(tl, &e2, ACL);
1181 765
        ERRCHK(tl);
1182 714
        vcc_expr_typecheck(tl, &e2, ACL, t1);
1183 714
        ERRCHK(tl);
1184 663
        bprintf(buf, "%sVRT_acl_match(ctx, \v1, \v2)", cp->emit);
1185 663
        *e = vcc_expr_edit(tl, BOOL, buf, e2, *e);
1186 765
}
1187
1188
static void v_matchproto_(cmp_f)
1189 672095
cmp_string(struct vcc *tl, struct expr **e, const struct cmps *cp)
1190
{
1191
        struct expr *e2;
1192
        struct token *tk;
1193
        char buf[128];
1194
1195 672095
        tk = tl->t;
1196 672095
        vcc_NextToken(tl);
1197 672095
        vcc_expr_add(tl, &e2, STRINGS);
1198 672095
        ERRCHK(tl);
1199 672095
        if (vcc_stringstype(e2->fmt) != STRINGS) {
1200 102
                VSB_printf(tl->sb,
1201
                    "Comparison of different types: %s '%.*s' %s\n",
1202 51
                    vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1203 51
                vcc_ErrWhere(tl, tk);
1204 672095
        } else if ((*e)->nstr == 1 && e2->nstr == 1) {
1205 671517
                bprintf(buf, "(%s VRT_strcmp(\v1, \v2))", cp->emit);
1206 671517
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1207 671517
        } else {
1208 527
                bprintf(buf, "(%s VRT_CompareStrands(\vT, \vt))", cp->emit);
1209 527
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1210
        }
1211 672095
}
1212
1213
#define IDENT_REL(typ)                                                  \
1214
        {typ,           T_EQ,           cmp_simple, "(\v1 == \v2)" },   \
1215
        {typ,           T_NEQ,          cmp_simple, "(\v1 != \v2)" }
1216
1217
#define NUM_REL(typ)                                                    \
1218
        IDENT_REL(typ),                                                 \
1219
        {typ,           T_LEQ,          cmp_simple, "(\v1 <= \v2)" },   \
1220
        {typ,           T_GEQ,          cmp_simple, "(\v1 >= \v2)" },   \
1221
        {typ,           '<',            cmp_simple, "(\v1 < \v2)" },    \
1222
        {typ,           '>',            cmp_simple, "(\v1 > \v2)" }
1223
1224
static const struct cmps vcc_cmps[] = {
1225
        NUM_REL(INT),
1226
        NUM_REL(DURATION),
1227
        NUM_REL(BYTES),
1228
        NUM_REL(REAL),
1229
        NUM_REL(TIME),
1230
        IDENT_REL(BACKEND),
1231
        IDENT_REL(ACL),
1232
        IDENT_REL(PROBE),
1233
        IDENT_REL(STEVEDORE),
1234
        IDENT_REL(SUB),
1235
        IDENT_REL(INSTANCE),
1236
1237
        {BOOL,          T_EQ,           cmp_simple, "((!(\v1)) == (!(\v2)))" },
1238
        {BOOL,          T_NEQ,          cmp_simple, "((!(\v1)) != (!(\v2)))" },
1239
        {IP,            T_EQ,           cmp_simple, "!VRT_ipcmp(ctx, \v1, \v2)" },
1240
        {IP,            T_NEQ,          cmp_simple, "VRT_ipcmp(ctx, \v1, \v2)" },
1241
1242
        {IP,            '~',            cmp_acl, "" },
1243
        {IP,            T_NOMATCH,      cmp_acl, "!" },
1244
1245
        {STRINGS,       T_EQ,           cmp_string, "0 =="},
1246
        {STRINGS,       T_NEQ,          cmp_string, "0 !="},
1247
        {STRINGS,       '<',            cmp_string, "0 > "},
1248
        {STRINGS,       '>',            cmp_string, "0 < "},
1249
        {STRINGS,       T_LEQ,          cmp_string, "0 >="},
1250
        {STRINGS,       T_GEQ,          cmp_string, "0 <="},
1251
1252
        {STRINGS,       '~',            cmp_regexp, "" },
1253
        {STRINGS,       T_NOMATCH,      cmp_regexp, "!" },
1254
1255
        {VOID,          0,              NULL, NULL}
1256
};
1257
1258
#undef IDENT_REL
1259
#undef NUM_REL
1260
1261
static void
1262 2250256
vcc_expr_cmp(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1263
{
1264
        const struct cmps *cp;
1265
        struct token *tk;
1266
1267 2250256
        *e = NULL;
1268 2250256
        vcc_expr_add(tl, e, fmt);
1269 2250256
        ERRCHK(tl);
1270 2249304
        tk = tl->t;
1271
1272 112747502
        for (cp = vcc_cmps; cp->fmt != VOID; cp++) {
1273 111507012
                if (tl->t->tok != cp->token)
1274 101568642
                        continue;
1275 9938370
                if (vcc_stringstype((*e)->fmt) != cp->fmt)
1276 8929556
                        continue;
1277 1008814
                AN(cp->func);
1278 1008814
                cp->func(tl, e, cp);
1279 1008814
                return;
1280
        }
1281
1282 1240490
        switch (tk->tok) {
1283
        case T_EQ:
1284
        case T_NEQ:
1285
        case '<':
1286
        case T_LEQ:
1287
        case '>':
1288
        case T_GEQ:
1289
        case '~':
1290
        case T_NOMATCH:
1291 68
                VSB_printf(tl->sb, "Operator %.*s not possible on %s\n",
1292 34
                    PF(tl->t), vcc_utype((*e)->fmt));
1293 34
                vcc_ErrWhere(tl, tl->t);
1294 34
                return;
1295
        default:
1296 1240456
                break;
1297
        }
1298 2250256
}
1299
1300
/*--------------------------------------------------------------------
1301
 * SYNTAX:
1302
 *    ExprNot:
1303
 *      '!' ExprCmp
1304
 */
1305
1306
static void
1307 2250256
vcc_expr_not(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1308
{
1309
        struct token *tk;
1310
1311 2250256
        *e = NULL;
1312 2250256
        tk = tl->t;
1313 2250256
        if (tl->t->tok == '!')
1314 96203
                vcc_NextToken(tl);
1315 2250256
        vcc_expr_cmp(tl, e, fmt);
1316 2250256
        ERRCHK(tl);
1317 2248947
        if (tk->tok != '!')
1318 2152761
                return;
1319 96186
        vcc_expr_tobool(tl, e);
1320 96186
        ERRCHK(tl);
1321 96186
        if ((*e)->fmt != BOOL) {
1322 17
                VSB_cat(tl->sb, "'!' must be followed by BOOL, found ");
1323 17
                VSB_printf(tl->sb, "%s.\n", vcc_utype((*e)->fmt));
1324 17
                vcc_ErrWhere2(tl, tk, tl->t);
1325 17
        } else {
1326 96169
                *e = vcc_expr_edit(tl, BOOL, "!(\v1)", *e, NULL);
1327
        }
1328 2250256
}
1329
1330
/*--------------------------------------------------------------------
1331
 * CAND and COR are identical save for a few details, but they are
1332
 * stacked so handling them in the same function is not simpler.
1333
 * Instead have them both call this helper function to do everything.
1334
 */
1335
1336
typedef void upfunc(struct vcc *tl, struct expr **e, vcc_type_t fmt);
1337
1338
static void
1339 3313895
vcc_expr_bin_bool(struct vcc *tl, struct expr **e, vcc_type_t fmt,
1340
    unsigned ourtok, upfunc *up, const char *tokstr)
1341
{
1342
        struct expr *e2;
1343
        struct token *tk;
1344
        char buf[32];
1345
1346 3313895
        *e = NULL;
1347 3313895
        tk = tl->t;
1348 3313895
        up(tl, e, fmt);
1349 3313895
        ERRCHK(tl);
1350 3311209
        if (tl->t->tok != ourtok)
1351 3026034
                return;
1352 285175
        vcc_expr_tobool(tl, e);
1353 285175
        ERRCHK(tl);
1354 285175
        if ((*e)->fmt != BOOL) {
1355 68
                VSB_printf(tl->sb,
1356
                    "'%s' must be preceded by BOOL,"
1357 34
                    " found %s.\n", tokstr, vcc_utype((*e)->fmt));
1358 34
                vcc_ErrWhere2(tl, tk, tl->t);
1359 34
                return;
1360
        }
1361 285141
        *e = vcc_expr_edit(tl, BOOL, "(\v+\n\v1", *e, NULL);
1362 902258
        while (tl->t->tok == ourtok) {
1363 617151
                vcc_NextToken(tl);
1364 617151
                tk = tl->t;
1365 617151
                up(tl, &e2, fmt);
1366 617151
                ERRCHK(tl);
1367 617151
                vcc_expr_tobool(tl, &e2);
1368 617151
                ERRCHK(tl);
1369 617151
                if (e2->fmt != BOOL) {
1370 68
                        VSB_printf(tl->sb,
1371
                            "'%s' must be followed by BOOL,"
1372 34
                            " found %s.\n", tokstr, vcc_utype(e2->fmt));
1373 34
                        vcc_ErrWhere2(tl, tk, tl->t);
1374 34
                        vcc_delete_expr(e2);
1375 34
                        return;
1376
                }
1377 617117
                bprintf(buf, "\v1\v-\n%s\v+\n\v2", tokstr);
1378 617117
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1379
        }
1380 285107
        *e = vcc_expr_edit(tl, BOOL, "\v1\v-\n)", *e, NULL);
1381 3313895
}
1382
1383
/*--------------------------------------------------------------------
1384
 * SYNTAX:
1385
 *    ExprCand:
1386
 *      ExprNot { '&&' ExprNot } *
1387
 */
1388
1389
static void
1390 1680790
vcc_expr_cand(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1391
{
1392
1393 1680790
        vcc_expr_bin_bool(tl, e, fmt, T_CAND, vcc_expr_not, "&&");
1394 1680790
}
1395
1396
/*--------------------------------------------------------------------
1397
 * SYNTAX:
1398
 *    ExprCOR:
1399
 *      ExprCand { '||' ExprCand } *
1400
 */
1401
1402
static void
1403 1633105
vcc_expr_cor(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1404
{
1405
1406 1633105
        vcc_expr_bin_bool(tl, e, fmt, T_COR, vcc_expr_cand, "||");
1407 1633105
}
1408
1409
/*--------------------------------------------------------------------
1410
 * This function is the entry-point for getting an expression with
1411
 * a particular type, ready for inclusion in the VGC.
1412
 */
1413
1414
static void
1415 1584791
vcc_expr0(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1416
{
1417
        struct token *t1;
1418
1419 1584791
        assert(fmt != VOID);
1420 1584791
        assert(fmt != STRINGS);
1421 1584791
        *e = NULL;
1422 1584791
        t1 = tl->t;
1423 1584791
        if (fmt->stringform)
1424 486591
                vcc_expr_cor(tl, e, STRINGS);
1425
        else
1426 1098200
                vcc_expr_cor(tl, e, fmt);
1427 1584791
        ERRCHK(tl);
1428
1429 1583397
        if ((*e)->fmt == fmt)
1430 810832
                return;
1431
1432 772565
        if ((*e)->fmt != STRINGS && fmt->stringform)
1433 58242
                vcc_expr_tostring(tl, e);
1434
1435 772565
        if ((*e)->fmt->stringform) {
1436 0
                VSB_printf(tl->sb, "Cannot convert type %s(%s) to %s(%s)\n",
1437 0
                    vcc_utype((*e)->fmt), (*e)->fmt->name,
1438 0
                    vcc_utype(fmt), fmt->name);
1439 0
                vcc_ErrWhere2(tl, t1, tl->t);
1440 0
                return;
1441
        }
1442
1443 772565
        if (fmt == BODY && !(*e)->fmt->bodyform)
1444 17
                vcc_expr_tostring(tl, e);
1445
1446 772565
        if (fmt == BODY && (*e)->fmt->bodyform) {
1447 95268
                if ((*e)->fmt == STRINGS)
1448 95200
                        *e = vcc_expr_edit(tl, BODY, "STRING, 0, \vT", *e, NULL);
1449 68
                else if ((*e)->fmt == BLOB)
1450 68
                        *e = vcc_expr_edit(tl, BODY, "BLOB, 0, \v1", *e, NULL);
1451
                else
1452 0
                        WRONG("Unhandled bodyform");
1453 95268
        }
1454
1455 772565
        if ((*e)->fmt == STRINGS && fmt->stringform) {
1456 486030
                if (fmt == STRING)
1457 60469
                        *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
1458 425561
                else if (fmt == STRANDS)
1459 425561
                        *e = vcc_expr_edit(tl, STRANDS, "\vT", (*e), NULL);
1460
                else
1461 0
                        WRONG("Unhandled stringform");
1462 486030
        }
1463
1464 772565
        if (fmt == BOOL) {
1465 191199
                vcc_expr_tobool(tl, e);
1466 191199
                ERRCHK(tl);
1467 191199
        }
1468
1469 772565
        vcc_expr_typecheck(tl, e, fmt, t1);
1470 1584791
}
1471
1472
static void
1473 917048
vcc_expr_typecheck(struct vcc *tl, struct expr **e, vcc_type_t fmt,
1474
    struct token *t1)
1475
{
1476
1477 917048
        assert(fmt != VOID);
1478 917048
        assert(fmt != STRINGS);
1479
1480 917048
        if (fmt != (*e)->fmt)  {
1481 306
                VSB_printf(tl->sb, "Expression has type %s, expected %s\n",
1482 153
                    vcc_utype((*e)->fmt), vcc_utype(fmt));
1483 153
                vcc_ErrWhere2(tl, t1, tl->t);
1484 153
        }
1485 917048
}
1486
1487
/*--------------------------------------------------------------------
1488
 * This function parses and emits the C-code to evaluate an expression
1489
 *
1490
 * We know up front what kind of type we want the expression to be,
1491
 * and this function is the backstop if that doesn't succeed.
1492
 */
1493
1494
void
1495 1538075
vcc_Expr(struct vcc *tl, vcc_type_t fmt)
1496
{
1497 1538075
        struct expr *e = NULL;
1498
1499 1538075
        assert(fmt != VOID);
1500 1538075
        assert(fmt != STRINGS);
1501 1538075
        vcc_expr0(tl, &e, fmt);
1502 1538075
        ERRCHK(tl);
1503 1536749
        assert(e->fmt == fmt);
1504
1505 1536749
        vcc_expr_fmt(tl->fb, tl->indent, e);
1506 1536749
        VSB_cat(tl->fb, "\n");
1507 1536749
        vcc_delete_expr(e);
1508 1538075
}
1509
1510
/*--------------------------------------------------------------------
1511
 */
1512
1513
void v_matchproto_(sym_act_f)
1514 8024
vcc_Act_Call(struct vcc *tl, struct token *t, struct symbol *sym)
1515
{
1516
1517
        struct expr *e;
1518
1519 8024
        e = NULL;
1520 8024
        vcc_func(tl, &e, sym->eval_priv, sym->extra, sym);
1521 8024
        if (!tl->err) {
1522 7939
                vcc_expr_fmt(tl->fb, tl->indent, e);
1523 7939
                SkipToken(tl, ';');
1524 7939
                VSB_cat(tl->fb, ";\n");
1525 8024
        } else if (t != tl->t) {
1526 85
                VSB_cat(tl->sb, "While compiling function call:\n\n");
1527 85
                vcc_ErrWhere2(tl, t, tl->t);
1528 85
        }
1529 8024
        vcc_delete_expr(e);
1530 8024
}
1531
1532
void v_matchproto_(sym_act_f)
1533 5678
vcc_Act_Obj(struct vcc *tl, struct token *t, struct symbol *sym)
1534
{
1535
1536 5678
        struct expr *e = NULL;
1537
1538 5678
        assert(sym->kind == SYM_INSTANCE);
1539 5678
        ExpectErr(tl, '.');
1540 5661
        tl->t = t;
1541 5661
        vcc_expr4(tl, &e, sym->type);
1542 5661
        ERRCHK(tl);
1543 5661
        vcc_expr_fmt(tl->fb, tl->indent, e);
1544 5661
        vcc_delete_expr(e);
1545 5661
        SkipToken(tl, ';');
1546 5661
        VSB_cat(tl->fb, ";\n");
1547 5678
}
1548
1549
/*--------------------------------------------------------------------
1550
 */
1551
1552
static void v_matchproto_(sym_expr_t)
1553 629
vcc_Eval_Regsub(struct vcc *tl, struct expr **e, struct token *t,
1554
    struct symbol *sym, vcc_type_t fmt)
1555
{
1556
        struct expr *e2, *e3;
1557 629
        int all = sym->eval_priv == NULL ? 0 : 1;
1558
        char buf[128];
1559
1560 629
        (void)t;
1561 629
        (void)fmt;
1562 629
        SkipToken(tl, '(');
1563 629
        vcc_expr0(tl, &e2, STRING);
1564 629
        ERRCHK(tl);
1565 629
        SkipToken(tl, ',');
1566 629
        vcc_expr0(tl, &e3, REGEX);
1567 629
        ERRCHK(tl);
1568
1569 612
        bprintf(buf, "VRT_regsub(ctx, %d,\v+\n\v1,\n\v2", all);
1570 612
        *e = vcc_expr_edit(tl, STRING, buf, e2, e3);
1571 612
        SkipToken(tl, ',');
1572 612
        vcc_expr0(tl, &e2, STRING);
1573 612
        ERRCHK(tl);
1574 612
        *e = vcc_expr_edit(tl, STRINGS, "\v1,\n\v2)\v-", *e, e2);
1575 612
        (*e)->nstr = 1;
1576 612
        SkipToken(tl, ')');
1577 629
}
1578
1579
/*--------------------------------------------------------------------
1580
 */
1581
1582
static void v_matchproto_(sym_expr_t)
1583 51629
vcc_Eval_BoolConst(struct vcc *tl, struct expr **e, struct token *t,
1584
    struct symbol *sym, vcc_type_t fmt)
1585
{
1586
1587 51629
        (void)t;
1588 51629
        (void)tl;
1589 51629
        (void)fmt;
1590 51629
        *e = vcc_mk_expr(BOOL, "(0==%d)", sym->eval_priv == NULL ? 1 : 0);
1591 51629
        (*e)->constant = EXPR_CONST;
1592 51629
}
1593
1594
/*--------------------------------------------------------------------
1595
 */
1596
1597
static void v_matchproto_(sym_expr_t)
1598 68
vcc_Eval_Default(struct vcc *tl, struct expr **e, struct token *t,
1599
    struct symbol *sym, vcc_type_t fmt)
1600
{
1601 68
        (void)e;
1602 68
        (void)fmt;
1603 68
        (void)sym;
1604 68
        (void)t;
1605
1606 68
        if (fmt->default_sym == NULL) {
1607 34
                VSB_cat(tl->sb, "Symbol 'default' is a reserved word.\n");
1608 34
                vcc_ErrWhere(tl, t);
1609 34
                return;
1610
        }
1611
1612 34
        *e = vcc_mk_expr(fmt, "%s", fmt->default_sym->rname);
1613 68
}
1614
1615
/*--------------------------------------------------------------------
1616
 */
1617
1618
void
1619 51425
vcc_Expr_Init(struct vcc *tl)
1620
{
1621
        struct symbol *sym;
1622
1623 51425
        sym = VCC_MkSym(tl, "regsub", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1624 51425
        AN(sym);
1625 51425
        sym->type = STRING;
1626 51425
        sym->eval = vcc_Eval_Regsub;
1627 51425
        sym->eval_priv = NULL;
1628
1629 51425
        sym = VCC_MkSym(tl, "regsuball", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1630 51425
        AN(sym);
1631 51425
        sym->type = STRING;
1632 51425
        sym->eval = vcc_Eval_Regsub;
1633 51425
        sym->eval_priv = sym;
1634
1635 51425
        sym = VCC_MkSym(tl, "true", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1636 51425
        AN(sym);
1637 51425
        sym->type = BOOL;
1638 51425
        sym->eval = vcc_Eval_BoolConst;
1639 51425
        sym->eval_priv = sym;
1640
1641 51425
        sym = VCC_MkSym(tl, "false", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1642 51425
        AN(sym);
1643 51425
        sym->type = BOOL;
1644 51425
        sym->eval = vcc_Eval_BoolConst;
1645 51425
        sym->eval_priv = NULL;
1646
1647 51425
        sym = VCC_MkSym(tl, "default", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1648 51425
        AN(sym);
1649 51425
        sym->type = DEFAULT;
1650 51425
        sym->eval = vcc_Eval_Default;
1651 51425
}