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 226880
vcc_isconst(const struct expr *e)
63
{
64 226880
        AN(e->constant);
65 226880
        return (e->constant & EXPR_CONST);
66
}
67
68
static inline int
69 2674760
vcc_islit(const struct expr *e)
70
{
71 2674760
        AN(e->constant);
72 2674760
        return (e->constant & EXPR_STR_CONST);
73
}
74
75
static const char *
76 2680
vcc_utype(vcc_type_t t)
77
{
78 2680
        if (t == STRINGS || t->stringform)
79 720
                t = STRING;
80 2680
        return (t->name);
81
}
82
83
static vcc_type_t
84 24722480
vcc_stringstype(vcc_type_t t)
85
{
86 24722480
        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 23486200
vcc_new_expr(vcc_type_t fmt)
97
{
98
        struct expr *e;
99
100 23486200
        ALLOC_OBJ(e, EXPR_MAGIC);
101 23486200
        AN(e);
102 23486200
        e->vsb = VSB_new_auto();
103 23486200
        e->fmt = fmt;
104 23486200
        e->constant = EXPR_VAR;
105 23486200
        return (e);
106
}
107
108
static struct expr * v_printflike_(2, 3)
109 6231200
vcc_mk_expr(vcc_type_t fmt, const char *str, ...)
110
{
111
        va_list ap;
112
        struct expr *e;
113
114 6231200
        e = vcc_new_expr(fmt);
115 6231200
        va_start(ap, str);
116 6231200
        VSB_vprintf(e->vsb, str, ap);
117 6231200
        va_end(ap);
118 6231200
        AZ(VSB_finish(e->vsb));
119 6231200
        return (e);
120
}
121
122
static void
123 29934720
vcc_delete_expr(struct expr *e)
124
{
125 29934720
        if (e == NULL)
126 6482680
                return;
127 23452040
        CHECK_OBJ(e, EXPR_MAGIC);
128 23452040
        VSB_destroy(&e->vsb);
129 23452040
        FREE_OBJ(e);
130 29934720
}
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 1994200
vcc_strands_edit(const struct expr *e1, const struct expr *e2)
159
{
160
161 1994200
        assert(e2->fmt == STRANDS || e2->fmt == STRINGS);
162
163 1994200
        if (e2->fmt == STRANDS)
164 160
                VSB_cat(e1->vsb, VSB_data(e2->vsb));
165 1994040
        else if (e2->nstr == 0)
166 0
                VSB_printf(e1->vsb, "vrt_null_strands");
167 1994040
        else if (e2->nstr == 1)
168 1764360
                VSB_printf(e1->vsb, "TOSTRAND(%s)", VSB_data(e2->vsb));
169
        else {
170 459360
                VSB_printf(e1->vsb, "TOSTRANDS(%d,\v+\n%s\v-)",
171 229680
                   e2->nstr, VSB_data(e2->vsb));
172
        }
173 1994200
}
174
175
static struct expr *
176 13157480
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 13157480
        int nl = 1;
181
182 13157480
        (void) tl;
183
184 13157480
        AN(e1);
185 13157480
        e = vcc_new_expr(fmt);
186 154789240
        while (*p != '\0') {
187 141631760
                if (*p != '\v') {
188 117467120
                        if (*p != '\n' || !nl)
189 117465200
                                VSB_putc(e->vsb, *p);
190 117467120
                        nl = (*p == '\n');
191 117467120
                        p++;
192 117467120
                        continue;
193
                }
194 24164640
                assert(*p == '\v');
195 24164640
                switch (*++p) {
196 2103640
                case '+': VSB_cat(e->vsb, "\v+"); nl = 0; break;
197 2228520
                case '-': VSB_cat(e->vsb, "\v-"); nl = 0; break;
198
                case 'S':
199
                case 's':
200 476080
                        e3 = (*p == 'S' ? e1 : e2);
201 476080
                        AN(e3);
202 476080
                        assert(e1->fmt == STRINGS);
203 476080
                        if (e3->nstr > 1) {
204 1040
                                VSB_cat(e->vsb,
205
                                    "\nVRT_STRANDS_string(ctx,\v+\n");
206 1040
                                vcc_strands_edit(e, e3);
207 1040
                                VSB_cat(e->vsb,
208
                                    "\v-\n)\n");
209 1040
                        } else {
210 475040
                                VSB_cat(e->vsb, VSB_data(e3->vsb));
211
                        }
212 476080
                        break;
213
                case 'T':
214
                case 't':
215 1993160
                        e3 = (*p == 'T' ? e1 : e2);
216 1993160
                        AN(e3);
217 1993160
                        vcc_strands_edit(e, e3);
218 1993160
                        break;
219
                case '1':
220 10689480
                        VSB_cat(e->vsb, VSB_data(e1->vsb));
221 10689480
                        break;
222
                case '2':
223 6673760
                        AN(e2);
224 6673760
                        VSB_cat(e->vsb, VSB_data(e2->vsb));
225 6673760
                        break;
226
                default:
227 0
                        WRONG("Illegal edit in VCC expression");
228 0
                }
229 24164640
                p++;
230
        }
231 13157480
        AZ(VSB_finish(e->vsb));
232 13157480
        e->t1 = e1->t1;
233 13157480
        e->t2 = e1->t2;
234 13157480
        if (e2 != NULL)
235 6675000
                e->t2 = e2->t2;
236 13157480
        vcc_delete_expr(e1);
237 13157480
        vcc_delete_expr(e2);
238 13157480
        return (e);
239
}
240
241
/*--------------------------------------------------------------------
242
 * Expand finished expression into C-source code
243
 */
244
245
static void
246 3619480
vcc_expr_fmt(struct vsb *d, int ind, const struct expr *e1)
247
{
248
        char *p;
249
        int i;
250
251 3619480
        if (!e1->fmt->noindent) {
252 32201920
                for (i = 0; i < ind; i++)
253 28804400
                        VSB_putc(d, ' ');
254 3397520
        }
255 3619480
        p = VSB_data(e1->vsb);
256 354230086
        while (*p != '\0') {
257 350610766
                if (*p == '\n') {
258 10646320
                        VSB_putc(d, '\n');
259 10646320
                        if (*++p == '\0')
260 160
                                break;
261 114068880
                        for (i = 0; i < ind; i++)
262 103422720
                                VSB_putc(d, ' ');
263 350610606
                } else if (*p != '\v') {
264 335046606
                        VSB_putc(d, *p++);
265 335046606
                } else {
266 4917840
                        switch (*++p) {
267 2458920
                        case '+': ind += INDENT; break;
268 2458920
                        case '-': ind -= INDENT; break;
269 0
                        default:  WRONG("Illegal format in VCC expression");
270 0
                        }
271 4917840
                        p++;
272
                }
273
        }
274 3619480
}
275
276
/*--------------------------------------------------------------------
277
 */
278
279
static void
280 2772040
vcc_expr_tobool(struct vcc *tl, struct expr **e)
281
{
282
283 2772040
        if ((*e)->fmt == BOOL)
284 2104120
                return;
285 667920
        if ((*e)->fmt == BACKEND || (*e)->fmt == INT)
286 400
                *e = vcc_expr_edit(tl, BOOL, "(\v1 != 0)", *e, NULL);
287 667520
        else if ((*e)->fmt == DURATION)
288 80
                *e = vcc_expr_edit(tl, BOOL, "(\v1 > 0)", *e, NULL);
289 667440
        else if ((*e)->fmt == STRINGS)
290 667200
                *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 2772040
}
297
298
/*--------------------------------------------------------------------
299
 */
300
301
static void
302 2168120
vcc_expr_tostring(struct vcc *tl, struct expr **e)
303
{
304
        const char *p;
305 2168120
        uint8_t constant = EXPR_VAR;
306
307 2168120
        CHECK_OBJ_NOTNULL(*e, EXPR_MAGIC);
308 2168120
        assert((*e)->fmt != STRINGS);
309
310 2168120
        p = (*e)->fmt->tostring;
311 2168120
        if (p != NULL) {
312 2168080
                AN(*p);
313 2168080
                *e = vcc_expr_edit(tl, STRINGS, p, *e, NULL);
314 2168080
                (*e)->constant = constant;
315 2168080
                (*e)->nstr = 1;
316 2168080
        } else {
317 80
                VSB_printf(tl->sb,
318
                    "Cannot convert %s to STRING.\n",
319 40
                    vcc_utype((*e)->fmt));
320 40
                vcc_ErrWhere2(tl, (*e)->t1, tl->t);
321
        }
322 2168120
}
323
324
/*--------------------------------------------------------------------
325
 */
326
327
void v_matchproto_(sym_expr_t)
328 16400
vcc_Eval_Handle(struct vcc *tl, struct expr **e, struct token *t,
329
    struct symbol *sym, vcc_type_t type)
330
{
331
332 16400
        (void)t;
333 16400
        (void)tl;
334 16400
        AN(sym->rname);
335 16400
        AZ(type->stringform);
336
337 16600
        if (sym->type->tostring == NULL &&
338 200
            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 16400
                *e = vcc_mk_expr(sym->type, "%s", sym->rname);
344 16400
                (*e)->constant = EXPR_VAR;
345 16400
                (*e)->nstr = 1;
346 16400
                if ((*e)->fmt == STRING)
347 0
                        (*e)->fmt = STRINGS;
348
        }
349 16400
}
350
351
void v_matchproto_(sym_expr_t)
352 920
vcc_Eval_Sub(struct vcc *tl, struct expr **e, struct token *t,
353
    struct symbol *sym, vcc_type_t type)
354
{
355
356 920
        (void)t;
357 920
        (void)tl;
358 920
        AN(sym->rname);
359 920
        AZ(type->stringform);
360
361 920
        assert (sym->type == SUB);
362
363 920
        if (type == SUB) {
364 800
                *e = vcc_mk_expr(sym->type, "%s", sym->rname);
365 800
                (*e)->constant = EXPR_CONST;
366 800
                return;
367
        }
368
369 240
        VSB_printf(tl->sb, "Symbol '%s' can only be used as a %s expression\n",
370 120
            sym->name, sym->type->name);
371 120
        vcc_ErrWhere(tl, tl->t);
372 920
}
373
374
/*--------------------------------------------------------------------
375
 */
376
377
void v_matchproto_(sym_expr_t)
378 4947960
vcc_Eval_Var(struct vcc *tl, struct expr **e, struct token *t,
379
    struct symbol *sym, vcc_type_t type)
380
{
381
382 4947960
        (void)type;
383 4947960
        vcc_AddUses(tl, t, NULL, sym, XREF_READ);
384 4947960
        ERRCHK(tl);
385 4947960
        *e = vcc_mk_expr(sym->type, "%s", sym->rname);
386 4947960
        (*e)->constant = EXPR_VAR;
387 4947960
        (*e)->nstr = 1;
388 4947960
        if ((*e)->fmt == STRING)
389 2232200
                (*e)->fmt = STRINGS;
390 4947960
}
391
392
void v_matchproto_(sym_expr_t)
393 400
vcc_Eval_ProtectedHeader(struct vcc *tl, struct expr **e, struct token *t,
394
    struct symbol *sym, vcc_type_t type)
395
{
396
397 400
        AN(sym);
398 400
        AZ(sym->lorev);
399
400 400
        vcc_Header_Fh(tl, sym);
401 400
        sym->eval = vcc_Eval_Var;
402 400
        vcc_Eval_Var(tl, e, t, sym, type);
403 400
}
404
405
/*--------------------------------------------------------------------
406
 */
407
408
static struct expr *
409 6880
vcc_priv_arg(struct vcc *tl, const char *p, struct symbol *sym)
410
{
411
        char buf[64];
412
        struct inifin *ifp;
413 6880
        const char *f = NULL;
414
415 6880
        AN(sym);
416 6880
        AN(sym->vmod_name);
417
418 6880
        if (!strcmp(p, "PRIV_VCL"))
419 600
                return (vcc_mk_expr(VOID, "&vmod_priv_%s", sym->vmod_name));
420
421 6280
        if (!strcmp(p, "PRIV_CALL")) {
422 880
                bprintf(buf, "vmod_priv_%u", tl->unique++);
423 880
                ifp = New_IniFin(tl);
424 880
                Fh(tl, 0, "static struct vmod_priv %s;\n", buf);
425 880
                VSB_printf(ifp->fin, "\tVRT_priv_fini(ctx, &%s);", buf);
426 880
                return (vcc_mk_expr(VOID, "&%s", buf));
427
        }
428
429 5400
        if (!strcmp(p, "PRIV_TASK"))
430 5080
                f = "task";
431 320
        else if (!strcmp(p, "PRIV_TOP")) {
432 320
                f = "top";
433 320
                sym->r_methods &= VCL_MET_TASK_C;
434 320
        } else {
435 0
                WRONG("Wrong PRIV_ type");
436
        }
437 5400
        AN(f);
438
439 5400
        return (vcc_mk_expr(VOID, "VRT_priv_%s(ctx, &VGC_vmod_%s)",
440 5400
            f, sym->vmod_name));
441 6880
}
442
443
struct func_arg {
444
        vcc_type_t              type;
445
        const struct vjsn_val   *enums;
446
        const char              *cname;
447
        const char              *name;
448
        const char              *val;
449
        struct expr             *result;
450
        int                     avail;
451
        int                     optional;
452
        VTAILQ_ENTRY(func_arg)  list;
453
};
454
455
static struct expr *
456 72680
vcc_do_enum(struct vcc *tl, const char *cfunc, int len, const char *ptr)
457
{
458
        const char *r;
459
460 72680
        (void)tl;
461 72680
        r = strchr(cfunc, '.');
462 72680
        AN(r);
463 72680
        return (vcc_mk_expr(VOID, "*%.*s.enum_%.*s",
464 72680
            (int)(r - cfunc), cfunc, len, ptr));
465
}
466
467
static void
468 158320
vcc_do_arg(struct vcc *tl, const char *cfunc, struct func_arg *fa)
469
{
470
        struct expr *e2;
471
        struct vjsn_val *vv;
472
473 158320
        if (fa->type == ENUM) {
474 53400
                ExpectErr(tl, ID);
475 53400
                ERRCHK(tl);
476 182720
                VTAILQ_FOREACH(vv, &fa->enums->children, list)
477 182640
                        if (vcc_IdIs(tl->t, vv->value))
478 53320
                                break;
479 53400
                if (vv == NULL) {
480 80
                        VSB_cat(tl->sb, "Wrong enum value.");
481 80
                        VSB_cat(tl->sb, "  Expected one of:\n");
482 400
                        VTAILQ_FOREACH(vv, &fa->enums->children, list)
483 320
                                VSB_printf(tl->sb, "\t%s\n", vv->value);
484 80
                        vcc_ErrWhere(tl, tl->t);
485 80
                        return;
486
                }
487 53320
                fa->result = vcc_do_enum(tl, cfunc, PF(tl->t));
488 53320
                SkipToken(tl, ID);
489 53320
        } else {
490 104920
                if (fa->type == SUB)
491 800
                        tl->subref++;
492 104920
                vcc_expr0(tl, &e2, fa->type);
493 104920
                ERRCHK(tl);
494 104600
                assert(e2->fmt == fa->type);
495 104600
                fa->result = e2;
496
        }
497 157920
        fa->avail = 1;
498 158320
}
499
500
static void
501 109560
vcc_func(struct vcc *tl, struct expr **e, const void *priv,
502
    const char *extra, struct symbol *sym)
503
{
504
        vcc_type_t rfmt;
505
        const char *cfunc;
506
        struct expr *e1;
507
        struct func_arg *fa, *fa2;
508
        VTAILQ_HEAD(,func_arg) head;
509
        struct token *tf, *t1;
510
        const struct vjsn_val *vv, *vvp;
511
        const char *sa, *extra_sep;
512
        char ssa[64];
513
        int n;
514
515 109560
        CAST_OBJ_NOTNULL(vv, priv, VJSN_VAL_MAGIC);
516 109560
        assert(vjsn_is_array(vv));
517 109560
        vv = VTAILQ_FIRST(&vv->children);
518 109560
        rfmt = VCC_Type(VTAILQ_FIRST(&vv->children)->value);
519 109560
        AN(rfmt);
520 109560
        vv = VTAILQ_NEXT(vv, list);
521 109560
        cfunc = vv->value;
522 109560
        vv = VTAILQ_NEXT(vv, list);
523 109560
        sa = vv->value;
524 109560
        if (*sa == '\0') {
525 93440
                sa = NULL;
526 93440
        }
527 109560
        vv = VTAILQ_NEXT(vv, list);
528 109560
        if (sym->kind == SYM_METHOD) {
529 30960
                if (*e == NULL) {
530 80
                        VSB_cat(tl->sb, "Syntax error.");
531 80
                        tl->err = 1;
532 80
                        return;
533
                }
534 30880
                vcc_NextToken(tl);
535 30880
                AZ(extra);
536 30880
                AN((*e)->instance);
537 30880
                extra = (*e)->instance->rname;
538 30880
        }
539 109480
        tf = VTAILQ_PREV(tl->t, tokenhead, list);
540 109480
        SkipToken(tl, '(');
541 109480
        if (extra == NULL) {
542 70560
                extra = "";
543 70560
                extra_sep = "";
544 70560
        } else {
545 38920
                AN(*extra);
546 38920
                extra_sep = ", ";
547
        }
548 109480
        VTAILQ_INIT(&head);
549 367280
        for (;vv != NULL; vv = VTAILQ_NEXT(vv, list)) {
550 257800
                assert(vjsn_is_array(vv));
551 257800
                fa = calloc(1, sizeof *fa);
552 257800
                AN(fa);
553 257800
                VTAILQ_INSERT_TAIL(&head, fa, list);
554
555 257800
                vvp = VTAILQ_FIRST(&vv->children);
556 257800
                if (!memcmp(vvp->value, "PRIV_", 5)) {
557 6880
                        fa->result = vcc_priv_arg(tl, vvp->value, sym);
558 6880
                        vvp = VTAILQ_NEXT(vvp, list);
559 6880
                        if (vvp != NULL)
560 120
                                fa->name = vvp->value;
561 6880
                        continue;
562
                }
563 250920
                fa->type = VCC_Type(vvp->value);
564 250920
                AN(fa->type);
565 250920
                vvp = VTAILQ_NEXT(vvp, list);
566 250920
                if (vvp != NULL) {
567 235200
                        fa->name = vvp->value;
568 235200
                        vvp = VTAILQ_NEXT(vvp, list);
569 235200
                        if (vvp != NULL) {
570 172760
                                fa->val = vvp->value;
571 172760
                                vvp = VTAILQ_NEXT(vvp, list);
572 172760
                                if (vvp != NULL) {
573 140600
                                        fa->enums = vvp;
574 140600
                                        vvp = VTAILQ_NEXT(vvp, list);
575 140600
                                }
576 172760
                        }
577 235200
                }
578 250920
                if (sa != NULL && vvp != NULL && vjsn_is_true(vvp)) {
579 72840
                        fa->optional = 1;
580 72840
                        vvp = VTAILQ_NEXT(vvp, list);
581 72840
                }
582 250920
                AZ(vvp);
583 250920
        }
584
585 176600
        VTAILQ_FOREACH(fa, &head, list) {
586 158360
                if (tl->t->tok == ')')
587 3560
                        break;
588 154800
                if (fa->result != NULL)
589 4920
                        continue;
590 149880
                if (tl->t->tok == ID) {
591 110320
                        t1 = VTAILQ_NEXT(tl->t, list);
592 110320
                        if (t1->tok == '=')
593 30080
                                break;
594 80240
                }
595 119800
                vcc_do_arg(tl, cfunc, fa);
596 119800
                if (tl->err)
597 800
                        VSB_printf(tl->sb, "Expected argument: %s %s\n\n",
598 400
                            fa->type->name,
599 400
                            fa->name ? fa->name : "(unnamed argument)");
600 119800
                ERRCHK(tl);
601 119400
                if (tl->t->tok == ')')
602 57200
                        break;
603 62200
                SkipToken(tl, ',');
604 62200
        }
605 117600
        while (tl->t->tok == ID) {
606 125360
                VTAILQ_FOREACH(fa, &head, list) {
607 125320
                        if (fa->name == NULL)
608 480
                                continue;
609 124840
                        if (vcc_IdIs(tl->t, fa->name))
610 38560
                                break;
611 86280
                }
612 38600
                if (fa == NULL) {
613 80
                        VSB_printf(tl->sb, "Unknown argument '%.*s'\n",
614 40
                            PF(tl->t));
615 40
                        vcc_ErrWhere(tl, tl->t);
616 40
                        return;
617
                }
618 38560
                if (fa->result != NULL) {
619 40
                        AN(fa->name);
620 80
                        VSB_printf(tl->sb, "Argument '%s' already used\n",
621 40
                            fa->name);
622 40
                        vcc_ErrWhere(tl, tl->t);
623 40
                        return;
624
                }
625 38520
                vcc_NextToken(tl);
626 38520
                SkipToken(tl, '=');
627 38520
                vcc_do_arg(tl, cfunc, fa);
628 38520
                ERRCHK(tl);
629 38520
                if (tl->t->tok == ')')
630 30000
                        break;
631 8520
                SkipToken(tl, ',');
632
        }
633
634 109000
        if (sa != NULL)
635 31920
                e1 = vcc_mk_expr(rfmt, "%s(ctx%s%s,\v+\n&(%s)\v+ {\n",
636 15960
                    cfunc, extra_sep, extra, sa);
637
        else
638 186080
                e1 = vcc_mk_expr(rfmt, "%s(ctx%s%s\v+",
639 93040
                    cfunc, extra_sep, extra);
640 109000
        n = 0;
641 365480
        VTAILQ_FOREACH_SAFE(fa, &head, list, fa2) {
642 256480
                n++;
643 256480
                if (fa->optional) {
644 72600
                        AN(fa->name);
645 72600
                        bprintf(ssa, "\v1.valid_%s = %d,\n",
646
                            fa->name, fa->avail);
647 72600
                        e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, NULL);
648 72600
                }
649 256480
                if (fa->result == NULL && fa->type == ENUM && fa->val != NULL)
650 19360
                        fa->result = vcc_do_enum(tl, cfunc, strlen(fa->val), fa->val);
651 256480
                if (fa->result == NULL && fa->val != NULL)
652 23720
                        fa->result = vcc_mk_expr(fa->type, "%s", fa->val);
653 256480
                if (fa->result != NULL && sa != NULL) {
654 34640
                        if (fa->name)
655 33800
                                bprintf(ssa, "\v1.%s = \v2,\n", fa->name);
656
                        else
657 840
                                bprintf(ssa, "\v1.arg%d = \v2,\n", n);
658 34640
                        e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, fa->result);
659 256480
                } else if (fa->result != NULL) {
660 346080
                        e1 = vcc_expr_edit(tl, e1->fmt, "\v1,\n\v2",
661 173040
                            e1, fa->result);
662 221840
                } else if (!fa->optional) {
663 40
                        if (fa->name)
664 80
                                VSB_printf(tl->sb, "Argument '%s' missing\n",
665 40
                                    fa->name);
666
                        else
667 0
                                VSB_printf(tl->sb, "Argument %d missing\n", n);
668 40
                        vcc_ErrWhere(tl, tl->t);
669 40
                }
670 256480
                free(fa);
671 256480
        }
672 109000
        if (sa != NULL) {
673 15960
                *e = vcc_expr_edit(tl, e1->fmt, "\v1\v-\n}\v-\n)", e1, NULL);
674 15960
        } else {
675 93040
                *e = vcc_expr_edit(tl, e1->fmt, "\v1\v-\n)", e1, NULL);
676
        }
677 109000
        SkipToken(tl, ')');
678 108960
        vcc_AddUses(tl, tf, NULL, sym, XREF_READ);
679 109560
}
680
681
682
/*--------------------------------------------------------------------
683
 */
684
685
void
686 8040
vcc_Eval_Func(struct vcc *tl, const struct vjsn_val *spec,
687
    const char *extra, struct symbol *sym)
688
{
689 8040
        struct expr *e = NULL;
690
691 8040
        vcc_func(tl, &e, spec, extra, sym);
692 8040
        if (tl->err)
693 0
                VSB_cat(tl->sb, "While compiling function call:\n");
694 8040
        ERRCHK(tl);
695 8040
        vcc_expr_fmt(tl->fb, tl->indent, e);
696 8040
        VSB_cat(tl->fb, ";\n");
697 8040
        vcc_delete_expr(e);
698 8040
}
699
700
/*--------------------------------------------------------------------
701
 */
702
703
void v_matchproto_(sym_expr_t)
704 82840
vcc_Eval_SymFunc(struct vcc *tl, struct expr **e, struct token *t,
705
    struct symbol *sym, vcc_type_t fmt)
706
{
707
708 82840
        (void)t;
709 82840
        (void)fmt;
710 82840
        assert(sym->kind == SYM_FUNC || sym->kind == SYM_METHOD);
711 82840
        AN(sym->eval_priv);
712
713 82840
        vcc_func(tl, e, sym->eval_priv, sym->extra, sym);
714 82840
        ERRCHK(tl);
715 82440
        if ((*e)->fmt == STRING) {
716 30040
                (*e)->fmt = STRINGS;
717 30040
                (*e)->nstr = 1;
718 30040
        }
719 82840
}
720
721
/*--------------------------------------------------------------------
722
 */
723
724
static void
725 932360
vcc_number(struct vcc *tl, struct expr **e, vcc_type_t fmt, const char *sign)
726
{
727
        VCL_INT vi;
728
        struct expr *e1;
729
        struct token *t;
730
731 932360
        assert(fmt != VOID);
732 932360
        if (fmt == BYTES) {
733 1920
                vcc_ByteVal(tl, &vi);
734 1920
                ERRCHK(tl);
735 1840
                e1 = vcc_mk_expr(BYTES, "%ju", (intmax_t)vi);
736 1840
        } else {
737 930440
                t = tl->t;
738 930440
                vcc_NextToken(tl);
739 930440
                if (tl->t->tok == ID) {
740 230440
                        e1 = vcc_mk_expr(DURATION, "%s%.3f * %g",
741 230440
                            sign, t->num, vcc_DurationUnit(tl));
742 230440
                        ERRCHK(tl);
743 930400
                } else if (fmt == REAL || t->tok == FNUM) {
744 6160
                        e1 = vcc_mk_expr(REAL, "%s%.3f", sign, t->num);
745 6160
                } else {
746 693840
                        e1 = vcc_mk_expr(INT, "%s%.0f", sign, t->num);
747
                }
748
        }
749 932240
        e1->constant = EXPR_CONST;
750 932240
        *e = e1;
751 932360
}
752
753
/*--------------------------------------------------------------------
754
 * SYNTAX:
755
 *    Expr5:
756
 *      '(' ExprCor ')'
757
 *      symbol
758
 *      CNUM
759
 *      FNUM
760
 *      CSTR
761
 *      CBLOB
762
 */
763
764
static void
765 10283720
vcc_expr5(struct vcc *tl, struct expr **e, vcc_type_t fmt)
766
{
767
        struct expr *e1, *e2;
768
        const char *ip, *sign;
769
        struct token *t, *t1;
770
        struct symbol *sym;
771
772 10283720
        sign = "";
773 10283720
        *e = NULL;
774 10283720
        if (tl->t->tok == '(') {
775 112160
                SkipToken(tl, '(');
776 112160
                vcc_expr_cor(tl, &e2, fmt);
777 112160
                ERRCHK(tl);
778 112160
                SkipToken(tl, ')');
779 112160
                if (e2->fmt == STRINGS)
780 240
                        *e = e2;
781
                else
782 111920
                        *e = vcc_expr_edit(tl, e2->fmt, "(\v1)", e2, NULL);
783 112160
                return;
784
        }
785 10171560
        switch (tl->t->tok) {
786
        case ID:
787 5170920
                t = tl->t;
788 5170920
                t1 = vcc_PeekToken(tl);
789 5170920
                AN(t1);
790 5170920
                sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
791
                    SYMTAB_PARTIAL_NOERR, XREF_REF);
792 5170920
                if (sym == NULL && fmt->global_pfx != NULL && t1->tok != '.') {
793 360
                        sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
794
                            SYMTAB_CREATE, XREF_REF);
795 360
                        ERRCHK(tl);
796 280
                        AN(sym);
797 280
                        VCC_GlobalSymbol(sym, fmt);
798 280
                }
799 5170840
                ERRCHK(tl);
800 5170840
                if (sym == NULL)
801 480
                        AZ(VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
802
                            SYMTAB_PARTIAL, XREF_REF));
803 5170840
                ERRCHK(tl);
804 5170360
                AN(sym);
805 5170360
                if (sym->kind == SYM_INSTANCE) {
806 30960
                        AZ(*e);
807 30960
                        *e = vcc_new_expr(sym->type);
808 30960
                        (*e)->instance = sym;
809 30960
                        return;
810
                }
811 5139400
                if (sym->kind == SYM_FUNC && sym->type == VOID) {
812 40
                        VSB_cat(tl->sb, "Function returns VOID:\n");
813 40
                        vcc_ErrWhere(tl, tl->t);
814 40
                        return;
815
                }
816 5139360
                if (sym->eval != NULL) {
817 5139240
                        AN(sym->eval);
818 5139240
                        AZ(*e);
819 5139240
                        sym->eval(tl, e, t, sym, fmt);
820 5139240
                        if (tl->err) {
821 640
                                VSB_cat(tl->sb,
822
                                    "While compiling function call:\n\n");
823 640
                                vcc_ErrWhere2(tl, t, tl->t);
824 640
                        }
825 5139240
                        ERRCHK(tl);
826
                        /* Unless asked for a HEADER, fold to string here */
827 5138600
                        if (*e && fmt != HEADER && (*e)->fmt == HEADER) {
828 1367040
                                vcc_expr_tostring(tl, e);
829 1367040
                                ERRCHK(tl);
830 1367040
                        }
831 5138600
                        return;
832
                }
833 240
                VSB_printf(tl->sb,
834
                    "Symbol '%.*s' type (%s) cannot be used in expression.\n",
835 120
                    PF(t), sym->kind->name);
836 120
                vcc_ErrWhere(tl, t);
837 120
                if (sym->def_b != NULL) {
838 40
                        VSB_cat(tl->sb, "That symbol was defined here:\n");
839 40
                        vcc_ErrWhere(tl, sym->def_b);
840 40
                }
841 120
                return;
842
        case CSTR:
843 4067680
                assert(fmt != VOID);
844 4067680
                if (fmt == IP) {
845 1200
                        if (*tl->t->dec == '/') {
846
                                /*
847
                                 * On some platforms (e.g. FreeBSD),
848
                                 * getaddrinfo(3) may resolve a path to a
849
                                 * sockaddr_un if it happens to exist and
850
                                 * is a socket. So don't let that happen.
851
                                 */
852 40
                                VSB_cat(tl->sb,
853
                                    "Cannot convert to an IP address: ");
854 40
                                vcc_ErrToken(tl, tl->t);
855 40
                                vcc_ErrWhere(tl, tl->t);
856 40
                                return;
857
                        }
858 2320
                        Resolve_Sockaddr(tl, tl->t->dec, "80",
859
                            &ip, NULL, &ip, NULL, NULL, 1,
860 1160
                            tl->t, "IP constant");
861 1160
                        ERRCHK(tl);
862 1040
                        e1 = vcc_mk_expr(IP, "%s", ip);
863 1040
                        ERRCHK(tl);
864 4067520
                } else if (fmt == REGEX) {
865 336880
                        e1 = vcc_new_expr(REGEX);
866 336880
                        vcc_regexp(tl, e1->vsb);
867 336880
                        AZ(VSB_finish(e1->vsb));
868 336880
                } else {
869 3729600
                        e1 = vcc_new_expr(STRINGS);
870 3729600
                        EncToken(e1->vsb, tl->t);
871 3729600
                        AZ(VSB_finish(e1->vsb));
872 3729600
                        e1->constant |= EXPR_STR_CONST;
873 3729600
                        e1->nstr = 1;
874
                }
875 4067520
                e1->t1 = tl->t;
876 4067520
                e1->constant |= EXPR_CONST;
877 4067520
                vcc_NextToken(tl);
878 4067520
                *e = e1;
879 4067520
                return;
880
        case '-':
881 2480
                if (fmt != INT &&
882 640
                    fmt != REAL &&
883 160
                    fmt != DURATION &&
884 40
                    fmt != STRINGS)
885 0
                        break;
886 2440
                vcc_NextToken(tl);
887 2440
                if (tl->t->tok != FNUM && tl->t->tok != CNUM) {
888 360
                        vcc_expr_cor(tl, &e1, fmt);
889 360
                        ERRCHK(tl);
890 360
                        *e = vcc_expr_edit(tl, e1->fmt, "-(\v1)", e1, NULL);
891 360
                        return;
892
                }
893 2080
                sign = "-";
894
                /* FALLTHROUGH */
895
        case FNUM:
896
        case CNUM:
897 932360
                vcc_number(tl, e, fmt, sign);
898 932360
                return;
899
        case CBLOB:
900 80
                e1 = vcc_new_expr(BLOB);
901 80
                VSB_printf(e1->vsb, "%s", tl->t->dec);
902 80
                AZ(VSB_finish(e1->vsb));
903 80
                e1->constant |= EXPR_STR_CONST;
904 80
                e1->t1 = tl->t;
905 80
                vcc_NextToken(tl);
906 80
                *e = e1;
907 80
                return;
908
        default:
909 160
                break;
910
        }
911 160
        VSB_cat(tl->sb, "Unknown token ");
912 160
        vcc_ErrToken(tl, tl->t);
913 160
        VSB_printf(tl->sb, " when looking for %s\n\n", vcc_utype(fmt));
914 160
        vcc_ErrWhere(tl, tl->t);
915 10283720
}
916
917
/*--------------------------------------------------------------------
918
 * SYNTAX:
919
 *    Expr4:
920
 *      Expr5 [ '.' (type_attribute | type_method()) ]*
921
 */
922
923
void
924 111400
vcc_Eval_TypeMethod(struct vcc *tl, struct expr **e, struct token *t,
925
    struct symbol *sym, vcc_type_t fmt)
926
{
927
        const char *impl;
928
929 111400
        (void)t;
930 111400
        impl = VCC_Type_EvalMethod(tl, sym);
931 111400
        ERRCHK(tl);
932 111400
        AN(impl);
933 111400
        *e = vcc_expr_edit(tl, fmt, impl, *e, NULL);
934 111400
}
935
936
static void
937 10283720
vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt)
938
{
939
        struct symbol *sym;
940
941 10283720
        *e = NULL;
942 10283720
        vcc_expr5(tl, e, fmt);
943 10283720
        ERRCHK(tl);
944 10281800
        AN(*e);
945 10424080
        while (tl->t->tok == '.') {
946 142400
                vcc_NextToken(tl);
947 142400
                ExpectErr(tl, ID);
948
949 142360
                sym = VCC_TypeSymbol(tl, SYM_METHOD, (*e)->fmt);
950 142360
                if (sym == NULL) {
951 80
                        VSB_cat(tl->sb, "Unknown property ");
952 80
                        vcc_ErrToken(tl, tl->t);
953 80
                        VSB_printf(tl->sb, " for type %s\n", (*e)->fmt->name);
954 80
                        vcc_ErrWhere(tl, tl->t);
955 80
                        return;
956
                }
957
958 142280
                AN(sym->eval);
959 142280
                sym->eval(tl, e, tl->t, sym, sym->type);
960 142280
                ERRCHK(tl);
961 142280
                if ((*e)->fmt == STRING) {
962 110960
                        (*e)->fmt = STRINGS;
963 110960
                        (*e)->nstr = 1;
964 110960
                }
965
        }
966 10283720
}
967
968
/*--------------------------------------------------------------------
969
 * SYNTAX:
970
 *    ExprMul:
971
 *      Expr4 { {'*'|'/'|'%'} Expr4 } *
972
 */
973
974
static void
975 9932040
vcc_expr_mul(struct vcc *tl, struct expr **e, vcc_type_t fmt)
976
{
977
        struct expr *e2;
978
        vcc_type_t f2;
979
        struct token *tk;
980
        char buf[24];
981
982 9932040
        *e = NULL;
983 9932040
        vcc_expr4(tl, e, fmt);
984 9932040
        ERRCHK(tl);
985 9930280
        AN(*e);
986
987 9931760
        while (tl->t->tok == '*' || tl->t->tok == '/' || tl->t->tok == '%') {
988 1640
                if (tl->t->tok == '%' && ((*e)->fmt != INT)) {
989 40
                        VSB_cat(tl->sb, "Operator % only possible on INT.\n");
990 40
                        vcc_ErrWhere(tl, tl->t);
991 40
                        return;
992
                }
993 1600
                f2 = (*e)->fmt->multype;
994 1600
                if (f2 == NULL) {
995 80
                        VSB_printf(tl->sb,
996
                            "Operator %.*s not possible on type %s.\n",
997 40
                            PF(tl->t), vcc_utype((*e)->fmt));
998 40
                        vcc_ErrWhere(tl, tl->t);
999 40
                        return;
1000
                }
1001 1560
                tk = tl->t;
1002 1560
                vcc_NextToken(tl);
1003 1560
                vcc_expr4(tl, &e2, f2);
1004 1560
                ERRCHK(tl);
1005 1560
                if (e2->fmt != INT && e2->fmt != f2) {
1006 160
                        VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
1007 80
                            vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1008 80
                        vcc_ErrWhere(tl, tk);
1009 80
                        return;
1010
                }
1011 1480
                bprintf(buf, "(\v1%c\v2)", tk->tok);
1012 1480
                *e = vcc_expr_edit(tl, (*e)->fmt, buf, *e, e2);
1013
        }
1014 9932040
}
1015
1016
/*--------------------------------------------------------------------
1017
 * SYNTAX:
1018
 *    ExprAdd:
1019
 *      ExprMul { {'+'|'-'} ExprMul } *
1020
 */
1021
1022
static const struct adds {
1023
        unsigned        op;
1024
        vcc_type_t      a;
1025
        vcc_type_t      b;
1026
        vcc_type_t      fmt;
1027
} vcc_adds[] = {
1028
        { '+', BYTES,           BYTES,          BYTES },
1029
        { '-', BYTES,           BYTES,          BYTES },
1030
        { '+', DURATION,        DURATION,       DURATION },
1031
        { '-', DURATION,        DURATION,       DURATION },
1032
        { '+', INT,             INT,            INT },
1033
        { '-', INT,             INT,            INT },
1034
        { '+', INT,             REAL,           REAL },
1035
        { '-', INT,             REAL,           REAL },
1036
        { '+', REAL,            INT,            REAL },
1037
        { '-', REAL,            INT,            REAL },
1038
        { '+', REAL,            REAL,           REAL },
1039
        { '-', REAL,            REAL,           REAL },
1040
        { '-', TIME,            TIME,           DURATION },
1041
        { '+', TIME,            DURATION,       TIME },
1042
        { '-', TIME,            DURATION,       TIME },
1043
1044
        { EOI, VOID,            VOID,           VOID }
1045
};
1046
1047
static void
1048 7256160
vcc_expr_add(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1049
{
1050
        const struct adds *ap;
1051
        struct expr  *e2;
1052
        struct token *tk;
1053
        int lit, n;
1054
1055 7256160
        *e = NULL;
1056 7256160
        vcc_expr_mul(tl, e, fmt);
1057 7256160
        ERRCHK(tl);
1058
1059 9929680
        while (tl->t->tok == '+' || tl->t->tok == '-') {
1060 2675880
                tk = tl->t;
1061 42783920
                for (ap = vcc_adds; ap->op != EOI; ap++)
1062 40111040
                        if (tk->tok == ap->op && (*e)->fmt == ap->a)
1063 3000
                                break;
1064 2675880
                vcc_NextToken(tl);
1065 2675880
                if (ap->op == EOI && fmt == STRINGS)
1066 20080
                        vcc_expr_mul(tl, &e2, STRINGS);
1067
                else
1068 2655800
                        vcc_expr_mul(tl, &e2, (*e)->fmt);
1069 2675880
                ERRCHK(tl);
1070
1071 42788800
                for (ap = vcc_adds; ap->op != EOI; ap++)
1072 40115520
                        if (tk->tok == ap->op && (*e)->fmt == ap->a &&
1073 40115520
                            e2->fmt == ap->b)
1074 2600
                                break;
1075
1076 2675880
                if (ap->op == '+') {
1077 1800
                        *e = vcc_expr_edit(tl, ap->fmt, "(\v1 + \v2)", *e, e2);
1078 2675880
                } else if (ap->op == '-') {
1079 800
                        *e = vcc_expr_edit(tl, ap->fmt, "(\v1 - \v2)", *e, e2);
1080 2674680
                } else if (tk->tok == '+' &&
1081 2673240
                    ((*e)->fmt == STRINGS || fmt == STRINGS)) {
1082 2672840
                        if ((*e)->fmt != STRINGS)
1083 200
                                vcc_expr_tostring(tl, e);
1084 2672840
                        if (e2->fmt != STRINGS)
1085 665360
                                vcc_expr_tostring(tl, &e2);
1086 2672840
                        if (vcc_islit(*e) && vcc_isconst(e2)) {
1087 1920
                                lit = vcc_islit(e2);
1088 3840
                                *e = vcc_expr_edit(tl, STRINGS,
1089 1920
                                    "\v1\n\v2", *e, e2);
1090 1920
                                (*e)->constant = EXPR_CONST;
1091 1920
                                (*e)->nstr = 1;
1092 1920
                                if (lit)
1093 1920
                                        (*e)->constant |= EXPR_STR_CONST;
1094 1920
                        } else {
1095 2670920
                                n = (*e)->nstr + e2->nstr;
1096 5341840
                                *e = vcc_expr_edit(tl, STRINGS,
1097 2670920
                                    "\v1,\n\v2", *e, e2);
1098 2670920
                                (*e)->constant = EXPR_VAR;
1099 2670920
                                (*e)->nstr = n;
1100
                        }
1101 2672840
                } else {
1102 880
                        VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
1103 440
                            vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1104 440
                        vcc_ErrWhere2(tl, tk, tl->t);
1105 440
                        return;
1106
                }
1107
        }
1108 7256160
}
1109
1110
/*--------------------------------------------------------------------
1111
 * SYNTAX:
1112
 *    ExprCmp:
1113
 *      ExprAdd
1114
 *      ExprAdd Relation ExprAdd
1115
 *      ExprAdd(STRING) '~' CString
1116
 *      ExprAdd(STRING) '!~' CString
1117
 *      ExprAdd(IP) '==' ExprAdd(IP)
1118
 *      ExprAdd(IP) '!=' ExprAdd(IP)
1119
 *      ExprAdd(IP) '~' ACL
1120
 *      ExprAdd(IP) '!~' ACL
1121
 */
1122
1123
struct cmps;
1124
1125
typedef void cmp_f(struct vcc *, struct expr **, const struct cmps *);
1126
1127
struct cmps {
1128
        vcc_type_t              fmt;
1129
        unsigned                token;
1130
        cmp_f                   *func;
1131
        const char              *emit;
1132
};
1133
1134
static void v_matchproto_(cmp_f)
1135 447600
cmp_simple(struct vcc *tl, struct expr **e, const struct cmps *cp)
1136
{
1137
        struct expr *e2;
1138
        struct token *tk;
1139
1140 447600
        tk = tl->t;
1141 447600
        vcc_NextToken(tl);
1142 447600
        vcc_expr_add(tl, &e2, (*e)->fmt);
1143 447600
        ERRCHK(tl);
1144
1145 447480
        if (e2->fmt != (*e)->fmt) {
1146 160
                VSB_printf(tl->sb,
1147
                    "Comparison of different types: %s '%.*s' %s\n",
1148 80
                    vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1149 80
                vcc_ErrWhere(tl, tk);
1150 80
        } else
1151 447400
                *e = vcc_expr_edit(tl, BOOL, cp->emit, *e, e2);
1152 447600
}
1153
1154
static void v_matchproto_(cmp_f)
1155 335080
cmp_regexp(struct vcc *tl, struct expr **e, const struct cmps *cp)
1156
{
1157
        struct token *t1;
1158
        struct expr *e2;
1159
        char buf[128];
1160
1161 335080
        *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
1162 335080
        vcc_NextToken(tl);
1163 335080
        t1 = tl->t;
1164 335080
        vcc_expr4(tl, &e2, REGEX);
1165 335080
        ERRCHK(tl);
1166 334920
        vcc_expr_typecheck(tl, &e2, REGEX, t1);
1167 334920
        ERRCHK(tl);
1168 334880
        bprintf(buf, "%sVRT_re_match(ctx, \v1, \v2)", cp->emit);
1169 334880
        *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1170 335080
}
1171
1172
static void v_matchproto_(cmp_f)
1173 1720
cmp_acl(struct vcc *tl, struct expr **e, const struct cmps *cp)
1174
{
1175
        struct token *t1;
1176
        struct expr *e2;
1177
        char buf[256];
1178
1179 1720
        vcc_NextToken(tl);
1180 1720
        t1 = tl->t;
1181 1720
        vcc_expr4(tl, &e2, ACL);
1182 1720
        ERRCHK(tl);
1183 1600
        vcc_expr_typecheck(tl, &e2, ACL, t1);
1184 1600
        ERRCHK(tl);
1185 1480
        bprintf(buf, "%sVRT_acl_match(ctx, \v1, \v2)", cp->emit);
1186 1480
        *e = vcc_expr_edit(tl, BOOL, buf, e2, *e);
1187 1720
}
1188
1189
static void v_matchproto_(cmp_f)
1190 1566000
cmp_string(struct vcc *tl, struct expr **e, const struct cmps *cp)
1191
{
1192
        struct expr *e2;
1193
        struct token *tk;
1194
        char buf[128];
1195
1196 1566000
        tk = tl->t;
1197 1566000
        vcc_NextToken(tl);
1198 1566000
        vcc_expr_add(tl, &e2, STRINGS);
1199 1566000
        ERRCHK(tl);
1200 1566000
        if (vcc_stringstype(e2->fmt) != STRINGS) {
1201 240
                VSB_printf(tl->sb,
1202
                    "Comparison of different types: %s '%.*s' %s\n",
1203 120
                    vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1204 120
                vcc_ErrWhere(tl, tk);
1205 1566000
        } else if ((*e)->nstr == 1 && e2->nstr == 1) {
1206 1564640
                bprintf(buf, "(%s VRT_strcmp(\v1, \v2))", cp->emit);
1207 1564640
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1208 1564640
        } else {
1209 1240
                bprintf(buf, "(%s VRT_CompareStrands(\vT, \vt))", cp->emit);
1210 1240
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1211
        }
1212 1566000
}
1213
1214
#define IDENT_REL(typ)                                                  \
1215
        {typ,           T_EQ,           cmp_simple, "(\v1 == \v2)" },   \
1216
        {typ,           T_NEQ,          cmp_simple, "(\v1 != \v2)" }
1217
1218
#define NUM_REL(typ)                                                    \
1219
        IDENT_REL(typ),                                                 \
1220
        {typ,           T_LEQ,          cmp_simple, "(\v1 <= \v2)" },   \
1221
        {typ,           T_GEQ,          cmp_simple, "(\v1 >= \v2)" },   \
1222
        {typ,           '<',            cmp_simple, "(\v1 < \v2)" },    \
1223
        {typ,           '>',            cmp_simple, "(\v1 > \v2)" }
1224
1225
static const struct cmps vcc_cmps[] = {
1226
        NUM_REL(INT),
1227
        NUM_REL(DURATION),
1228
        NUM_REL(BYTES),
1229
        NUM_REL(REAL),
1230
        NUM_REL(TIME),
1231
        IDENT_REL(BACKEND),
1232
        IDENT_REL(ACL),
1233
        IDENT_REL(PROBE),
1234
        IDENT_REL(STEVEDORE),
1235
        IDENT_REL(SUB),
1236
        IDENT_REL(INSTANCE),
1237
1238
        {BOOL,          T_EQ,           cmp_simple, "((!(\v1)) == (!(\v2)))" },
1239
        {BOOL,          T_NEQ,          cmp_simple, "((!(\v1)) != (!(\v2)))" },
1240
        {IP,            T_EQ,           cmp_simple, "!VRT_ipcmp(ctx, \v1, \v2)" },
1241
        {IP,            T_NEQ,          cmp_simple, "VRT_ipcmp(ctx, \v1, \v2)" },
1242
1243
        {IP,            '~',            cmp_acl, "" },
1244
        {IP,            T_NOMATCH,      cmp_acl, "!" },
1245
1246
        {STRINGS,       T_EQ,           cmp_string, "0 =="},
1247
        {STRINGS,       T_NEQ,          cmp_string, "0 !="},
1248
        {STRINGS,       '<',            cmp_string, "0 > "},
1249
        {STRINGS,       '>',            cmp_string, "0 < "},
1250
        {STRINGS,       T_LEQ,          cmp_string, "0 >="},
1251
        {STRINGS,       T_GEQ,          cmp_string, "0 <="},
1252
1253
        {STRINGS,       '~',            cmp_regexp, "" },
1254
        {STRINGS,       T_NOMATCH,      cmp_regexp, "!" },
1255
1256
        {VOID,          0,              NULL, NULL}
1257
};
1258
1259
#undef IDENT_REL
1260
#undef NUM_REL
1261
1262
static void
1263 5242560
vcc_expr_cmp(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1264
{
1265
        const struct cmps *cp;
1266
        struct token *tk;
1267
1268 5242560
        *e = NULL;
1269 5242560
        vcc_expr_add(tl, e, fmt);
1270 5242560
        ERRCHK(tl);
1271 5240320
        tk = tl->t;
1272
1273 262672880
        for (cp = vcc_cmps; cp->fmt != VOID; cp++) {
1274 259782960
                if (tl->t->tok != cp->token)
1275 236626480
                        continue;
1276 23156480
                if (vcc_stringstype((*e)->fmt) != cp->fmt)
1277 20806080
                        continue;
1278 2350400
                AN(cp->func);
1279 2350400
                cp->func(tl, e, cp);
1280 2350400
                return;
1281
        }
1282
1283 2889920
        switch (tk->tok) {
1284
        case T_EQ:
1285
        case T_NEQ:
1286
        case '<':
1287
        case T_LEQ:
1288
        case '>':
1289
        case T_GEQ:
1290
        case '~':
1291
        case T_NOMATCH:
1292 160
                VSB_printf(tl->sb, "Operator %.*s not possible on %s\n",
1293 80
                    PF(tl->t), vcc_utype((*e)->fmt));
1294 80
                vcc_ErrWhere(tl, tl->t);
1295 80
                return;
1296
        default:
1297 2889840
                break;
1298
        }
1299 5242560
}
1300
1301
/*--------------------------------------------------------------------
1302
 * SYNTAX:
1303
 *    ExprNot:
1304
 *      '!' ExprCmp
1305
 */
1306
1307
static void
1308 5242560
vcc_expr_not(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1309
{
1310
        struct token *tk;
1311
1312 5242560
        *e = NULL;
1313 5242560
        tk = tl->t;
1314 5242560
        if (tl->t->tok == '!')
1315 224200
                vcc_NextToken(tl);
1316 5242560
        vcc_expr_cmp(tl, e, fmt);
1317 5242560
        ERRCHK(tl);
1318 5239480
        if (tk->tok != '!')
1319 5015320
                return;
1320 224160
        vcc_expr_tobool(tl, e);
1321 224160
        ERRCHK(tl);
1322 224160
        if ((*e)->fmt != BOOL) {
1323 40
                VSB_cat(tl->sb, "'!' must be followed by BOOL, found ");
1324 40
                VSB_printf(tl->sb, "%s.\n", vcc_utype((*e)->fmt));
1325 40
                vcc_ErrWhere2(tl, tk, tl->t);
1326 40
        } else {
1327 224120
                *e = vcc_expr_edit(tl, BOOL, "!(\v1)", *e, NULL);
1328
        }
1329 5242560
}
1330
1331
/*--------------------------------------------------------------------
1332
 * CAND and COR are identical save for a few details, but they are
1333
 * stacked so handling them in the same function is not simpler.
1334
 * Instead have them both call this helper function to do everything.
1335
 */
1336
1337
typedef void upfunc(struct vcc *tl, struct expr **e, vcc_type_t fmt);
1338
1339
static void
1340 7720320
vcc_expr_bin_bool(struct vcc *tl, struct expr **e, vcc_type_t fmt,
1341
    unsigned ourtok, upfunc *up, const char *tokstr)
1342
{
1343
        struct expr *e2;
1344
        struct token *tk;
1345
        char buf[32];
1346
1347 7720320
        *e = NULL;
1348 7720320
        tk = tl->t;
1349 7720320
        up(tl, e, fmt);
1350 7720320
        ERRCHK(tl);
1351 7714000
        if (tl->t->tok != ourtok)
1352 7049600
                return;
1353 664400
        vcc_expr_tobool(tl, e);
1354 664400
        ERRCHK(tl);
1355 664400
        if ((*e)->fmt != BOOL) {
1356 160
                VSB_printf(tl->sb,
1357
                    "'%s' must be preceded by BOOL,"
1358 80
                    " found %s.\n", tokstr, vcc_utype((*e)->fmt));
1359 80
                vcc_ErrWhere2(tl, tk, tl->t);
1360 80
                return;
1361
        }
1362 664320
        *e = vcc_expr_edit(tl, BOOL, "(\v+\n\v1", *e, NULL);
1363 2102200
        while (tl->t->tok == ourtok) {
1364 1437960
                vcc_NextToken(tl);
1365 1437960
                tk = tl->t;
1366 1437960
                up(tl, &e2, fmt);
1367 1437960
                ERRCHK(tl);
1368 1437960
                vcc_expr_tobool(tl, &e2);
1369 1437960
                ERRCHK(tl);
1370 1437960
                if (e2->fmt != BOOL) {
1371 160
                        VSB_printf(tl->sb,
1372
                            "'%s' must be followed by BOOL,"
1373 80
                            " found %s.\n", tokstr, vcc_utype(e2->fmt));
1374 80
                        vcc_ErrWhere2(tl, tk, tl->t);
1375 80
                        vcc_delete_expr(e2);
1376 80
                        return;
1377
                }
1378 1437880
                bprintf(buf, "\v1\v-\n%s\v+\n\v2", tokstr);
1379 1437880
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1380
        }
1381 664240
        *e = vcc_expr_edit(tl, BOOL, "\v1\v-\n)", *e, NULL);
1382 7720320
}
1383
1384
/*--------------------------------------------------------------------
1385
 * SYNTAX:
1386
 *    ExprCand:
1387
 *      ExprNot { '&&' ExprNot } *
1388
 */
1389
1390
static void
1391 3915720
vcc_expr_cand(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1392
{
1393
1394 3915720
        vcc_expr_bin_bool(tl, e, fmt, T_CAND, vcc_expr_not, "&&");
1395 3915720
}
1396
1397
/*--------------------------------------------------------------------
1398
 * SYNTAX:
1399
 *    ExprCOR:
1400
 *      ExprCand { '||' ExprCand } *
1401
 */
1402
1403
static void
1404 3804600
vcc_expr_cor(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1405
{
1406
1407 3804600
        vcc_expr_bin_bool(tl, e, fmt, T_COR, vcc_expr_cand, "||");
1408 3804600
}
1409
1410
/*--------------------------------------------------------------------
1411
 * This function is the entry-point for getting an expression with
1412
 * a particular type, ready for inclusion in the VGC.
1413
 */
1414
1415
static void
1416 3692080
vcc_expr0(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1417
{
1418
        struct token *t1;
1419
1420 3692080
        assert(fmt != VOID);
1421 3692080
        assert(fmt != STRINGS);
1422 3692080
        *e = NULL;
1423 3692080
        t1 = tl->t;
1424 3692080
        if (fmt->stringform)
1425 1133000
                vcc_expr_cor(tl, e, STRINGS);
1426
        else
1427 2559080
                vcc_expr_cor(tl, e, fmt);
1428 3692080
        ERRCHK(tl);
1429
1430 3688800
        if ((*e)->fmt == fmt)
1431 1889440
                return;
1432
1433 1799360
        if ((*e)->fmt != STRINGS && fmt->stringform)
1434 135480
                vcc_expr_tostring(tl, e);
1435
1436 1799360
        if ((*e)->fmt->stringform) {
1437 0
                VSB_printf(tl->sb, "Cannot convert type %s(%s) to %s(%s)\n",
1438 0
                    vcc_utype((*e)->fmt), (*e)->fmt->name,
1439 0
                    vcc_utype(fmt), fmt->name);
1440 0
                vcc_ErrWhere2(tl, t1, tl->t);
1441 0
                return;
1442
        }
1443
1444 1799360
        if (fmt == BODY && !(*e)->fmt->bodyform)
1445 40
                vcc_expr_tostring(tl, e);
1446
1447 1799360
        if (fmt == BODY && (*e)->fmt->bodyform) {
1448 221960
                if ((*e)->fmt == STRINGS)
1449 221800
                        *e = vcc_expr_edit(tl, BODY, "STRING, 0, \vT", *e, NULL);
1450 160
                else if ((*e)->fmt == BLOB)
1451 160
                        *e = vcc_expr_edit(tl, BODY, "BLOB, 0, \v1", *e, NULL);
1452
                else
1453 0
                        WRONG("Unhandled bodyform");
1454 221960
        }
1455
1456 1799360
        if ((*e)->fmt == STRINGS && fmt->stringform) {
1457 1131720
                if (fmt == STRING)
1458 141000
                        *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
1459 990720
                else if (fmt == STRANDS)
1460 990720
                        *e = vcc_expr_edit(tl, STRANDS, "\vT", (*e), NULL);
1461
                else
1462 0
                        WRONG("Unhandled stringform");
1463 1131720
        }
1464
1465 1799360
        if (fmt == BOOL) {
1466 445520
                vcc_expr_tobool(tl, e);
1467 445520
                ERRCHK(tl);
1468 445520
        }
1469
1470 1799360
        vcc_expr_typecheck(tl, e, fmt, t1);
1471 3692080
}
1472
1473
static void
1474 2135880
vcc_expr_typecheck(struct vcc *tl, struct expr **e, vcc_type_t fmt,
1475
    struct token *t1)
1476
{
1477
1478 2135880
        assert(fmt != VOID);
1479 2135880
        assert(fmt != STRINGS);
1480
1481 2135880
        if (fmt != (*e)->fmt)  {
1482 720
                VSB_printf(tl->sb, "Expression has type %s, expected %s\n",
1483 360
                    vcc_utype((*e)->fmt), vcc_utype(fmt));
1484 360
                vcc_ErrWhere2(tl, t1, tl->t);
1485 360
        }
1486 2135880
}
1487
1488
/*--------------------------------------------------------------------
1489
 * This function parses and emits the C-code to evaluate an expression
1490
 *
1491
 * We know up front what kind of type we want the expression to be,
1492
 * and this function is the backstop if that doesn't succeed.
1493
 */
1494
1495
void
1496 3582760
vcc_Expr(struct vcc *tl, vcc_type_t fmt)
1497
{
1498 3582760
        struct expr *e = NULL;
1499
1500 3582760
        assert(fmt != VOID);
1501 3582760
        assert(fmt != STRINGS);
1502 3582760
        vcc_expr0(tl, &e, fmt);
1503 3582760
        ERRCHK(tl);
1504 3579640
        assert(e->fmt == fmt);
1505
1506 3579640
        vcc_expr_fmt(tl->fb, tl->indent, e);
1507 3579640
        VSB_cat(tl->fb, "\n");
1508 3579640
        vcc_delete_expr(e);
1509 3582760
}
1510
1511
/*--------------------------------------------------------------------
1512
 */
1513
1514
void v_matchproto_(sym_act_f)
1515 18680
vcc_Act_Call(struct vcc *tl, struct token *t, struct symbol *sym)
1516
{
1517
1518
        struct expr *e;
1519
1520 18680
        e = NULL;
1521 18680
        vcc_func(tl, &e, sym->eval_priv, sym->extra, sym);
1522 18680
        if (!tl->err) {
1523 18480
                vcc_expr_fmt(tl->fb, tl->indent, e);
1524 18480
                SkipToken(tl, ';');
1525 18480
                VSB_cat(tl->fb, ";\n");
1526 18680
        } else if (t != tl->t) {
1527 200
                VSB_cat(tl->sb, "While compiling function call:\n\n");
1528 200
                vcc_ErrWhere2(tl, t, tl->t);
1529 200
        }
1530 18680
        vcc_delete_expr(e);
1531 18680
}
1532
1533
void v_matchproto_(sym_act_f)
1534 13360
vcc_Act_Obj(struct vcc *tl, struct token *t, struct symbol *sym)
1535
{
1536
1537 13360
        struct expr *e = NULL;
1538
1539 13360
        assert(sym->kind == SYM_INSTANCE);
1540 13360
        ExpectErr(tl, '.');
1541 13320
        tl->t = t;
1542 13320
        vcc_expr4(tl, &e, sym->type);
1543 13320
        ERRCHK(tl);
1544 13320
        vcc_expr_fmt(tl->fb, tl->indent, e);
1545 13320
        vcc_delete_expr(e);
1546 13320
        SkipToken(tl, ';');
1547 13320
        VSB_cat(tl->fb, ";\n");
1548 13360
}
1549
1550
/*--------------------------------------------------------------------
1551
 */
1552
1553
static void v_matchproto_(sym_expr_t)
1554 1480
vcc_Eval_Regsub(struct vcc *tl, struct expr **e, struct token *t,
1555
    struct symbol *sym, vcc_type_t fmt)
1556
{
1557
        struct expr *e2, *e3;
1558 1480
        int all = sym->eval_priv == NULL ? 0 : 1;
1559
        char buf[128];
1560
1561 1480
        (void)t;
1562 1480
        (void)fmt;
1563 1480
        SkipToken(tl, '(');
1564 1480
        vcc_expr0(tl, &e2, STRING);
1565 1480
        ERRCHK(tl);
1566 1480
        SkipToken(tl, ',');
1567 1480
        vcc_expr0(tl, &e3, REGEX);
1568 1480
        ERRCHK(tl);
1569
1570 1440
        bprintf(buf, "VRT_regsub(ctx, %d,\v+\n\v1,\n\v2", all);
1571 1440
        *e = vcc_expr_edit(tl, STRING, buf, e2, e3);
1572 1440
        SkipToken(tl, ',');
1573 1440
        vcc_expr0(tl, &e2, STRING);
1574 1440
        ERRCHK(tl);
1575 1440
        *e = vcc_expr_edit(tl, STRINGS, "\v1,\n\v2)\v-", *e, e2);
1576 1440
        (*e)->nstr = 1;
1577 1440
        SkipToken(tl, ')');
1578 1480
}
1579
1580
/*--------------------------------------------------------------------
1581
 */
1582
1583
static void v_matchproto_(sym_expr_t)
1584 120360
vcc_Eval_BoolConst(struct vcc *tl, struct expr **e, struct token *t,
1585
    struct symbol *sym, vcc_type_t fmt)
1586
{
1587
1588 120360
        (void)t;
1589 120360
        (void)tl;
1590 120360
        (void)fmt;
1591 120360
        *e = vcc_mk_expr(BOOL, "(0==%d)", sym->eval_priv == NULL ? 1 : 0);
1592 120360
        (*e)->constant = EXPR_CONST;
1593 120360
}
1594
1595
/*--------------------------------------------------------------------
1596
 */
1597
1598
static void v_matchproto_(sym_expr_t)
1599 160
vcc_Eval_Default(struct vcc *tl, struct expr **e, struct token *t,
1600
    struct symbol *sym, vcc_type_t fmt)
1601
{
1602 160
        (void)e;
1603 160
        (void)fmt;
1604 160
        (void)sym;
1605 160
        (void)t;
1606
1607 160
        if (fmt->default_sym == NULL) {
1608 80
                VSB_cat(tl->sb, "Symbol 'default' is a reserved word.\n");
1609 80
                vcc_ErrWhere(tl, t);
1610 80
                return;
1611
        }
1612
1613 80
        *e = vcc_mk_expr(fmt, "%s", fmt->default_sym->rname);
1614 160
}
1615
1616
/*--------------------------------------------------------------------
1617
 */
1618
1619
void
1620 119800
vcc_Expr_Init(struct vcc *tl)
1621
{
1622
        struct symbol *sym;
1623
1624 119800
        sym = VCC_MkSym(tl, "regsub", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1625 119800
        AN(sym);
1626 119800
        sym->type = STRING;
1627 119800
        sym->eval = vcc_Eval_Regsub;
1628 119800
        sym->eval_priv = NULL;
1629
1630 119800
        sym = VCC_MkSym(tl, "regsuball", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1631 119800
        AN(sym);
1632 119800
        sym->type = STRING;
1633 119800
        sym->eval = vcc_Eval_Regsub;
1634 119800
        sym->eval_priv = sym;
1635
1636 119800
        sym = VCC_MkSym(tl, "true", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1637 119800
        AN(sym);
1638 119800
        sym->type = BOOL;
1639 119800
        sym->eval = vcc_Eval_BoolConst;
1640 119800
        sym->eval_priv = sym;
1641
1642 119800
        sym = VCC_MkSym(tl, "false", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1643 119800
        AN(sym);
1644 119800
        sym->type = BOOL;
1645 119800
        sym->eval = vcc_Eval_BoolConst;
1646 119800
        sym->eval_priv = NULL;
1647
1648 119800
        sym = VCC_MkSym(tl, "default", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1649 119800
        AN(sym);
1650 119800
        sym->type = DEFAULT;
1651 119800
        sym->eval = vcc_Eval_Default;
1652 119800
}