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 237600
vcc_isconst(const struct expr *e)
63
{
64 237600
        AN(e->constant);
65 237600
        return (e->constant & EXPR_CONST);
66
}
67
68
static inline int
69 2802760
vcc_islit(const struct expr *e)
70
{
71 2802760
        AN(e->constant);
72 2802760
        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 24289920
vcc_stringstype(vcc_type_t t)
85
{
86 24289920
        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 27388160
vcc_new_expr(vcc_type_t fmt)
97
{
98
        struct expr *e;
99
100 27388160
        ALLOC_OBJ(e, EXPR_MAGIC);
101 27388160
        AN(e);
102 27388160
        e->vsb = VSB_new_auto();
103 27388160
        e->fmt = fmt;
104 27388160
        e->constant = EXPR_VAR;
105 27388160
        return (e);
106
}
107
108
static struct expr * v_printflike_(2, 3)
109 7337480
vcc_mk_expr(vcc_type_t fmt, const char *str, ...)
110
{
111
        va_list ap;
112
        struct expr *e;
113
114 7337480
        e = vcc_new_expr(fmt);
115 7337480
        va_start(ap, str);
116 7337480
        VSB_vprintf(e->vsb, str, ap);
117 7337480
        va_end(ap);
118 7337480
        AZ(VSB_finish(e->vsb));
119 7337480
        return (e);
120
}
121
122
static void
123 35658200
vcc_delete_expr(struct expr *e)
124
{
125 35658200
        if (e == NULL)
126 8304200
                return;
127 27354000
        CHECK_OBJ(e, EXPR_MAGIC);
128 27354000
        VSB_destroy(&e->vsb);
129 27354000
        FREE_OBJ(e);
130 35658200
}
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 2438240
vcc_strands_edit(const struct expr *e1, const struct expr *e2)
159
{
160
161 2438240
        assert(e2->fmt == STRANDS || e2->fmt == STRINGS);
162
163 2438240
        if (e2->fmt == STRANDS)
164 160
                VSB_cat(e1->vsb, VSB_data(e2->vsb));
165 2438080
        else if (e2->nstr == 0)
166 0
                VSB_printf(e1->vsb, "vrt_null_strands");
167 2438080
        else if (e2->nstr == 1)
168 2197680
                VSB_printf(e1->vsb, "TOSTRAND(%s)", VSB_data(e2->vsb));
169
        else {
170 480800
                VSB_printf(e1->vsb, "TOSTRANDS(%d,\v+\n%s\v-)",
171 240400
                   e2->nstr, VSB_data(e2->vsb));
172
        }
173 2438240
}
174
175
static struct expr *
176 15410080
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 15410080
        int nl = 1;
181
182 15410080
        (void) tl;
183
184 15410080
        AN(e1);
185 15410080
        e = vcc_new_expr(fmt);
186 174490880
        while (*p != '\0') {
187 159080800
                if (*p != '\v') {
188 131563240
                        if (*p != '\n' || !nl)
189 131561240
                                VSB_putc(e->vsb, *p);
190 131563240
                        nl = (*p == '\n');
191 131563240
                        p++;
192 131563240
                        continue;
193
                }
194 27517560
                assert(*p == '\v');
195 27517560
                switch (*++p) {
196 2436840
                case '+': VSB_cat(e->vsb, "\v+"); nl = 0; break;
197 2564560
                case '-': VSB_cat(e->vsb, "\v-"); nl = 0; break;
198
                case 'S':
199
                case 's':
200 846320
                        e3 = (*p == 'S' ? e1 : e2);
201 846320
                        AN(e3);
202 846320
                        assert(e1->fmt == STRINGS);
203 846320
                        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 845280
                                VSB_cat(e->vsb, VSB_data(e3->vsb));
211
                        }
212 846320
                        break;
213
                case 'T':
214
                case 't':
215 2437200
                        e3 = (*p == 'T' ? e1 : e2);
216 2437200
                        AN(e3);
217 2437200
                        vcc_strands_edit(e, e3);
218 2437200
                        break;
219
                case '1':
220 12127800
                        VSB_cat(e->vsb, VSB_data(e1->vsb));
221 12127800
                        break;
222
                case '2':
223 7104840
                        AN(e2);
224 7104840
                        VSB_cat(e->vsb, VSB_data(e2->vsb));
225 7104840
                        break;
226
                default:
227 0
                        WRONG("Illegal edit in VCC expression");
228 0
                }
229 27517560
                p++;
230
        }
231 15410080
        AZ(VSB_finish(e->vsb));
232 15410080
        e->t1 = e1->t1;
233 15410080
        e->t2 = e1->t2;
234 15410080
        if (e2 != NULL)
235 7106080
                e->t2 = e2->t2;
236 15410080
        vcc_delete_expr(e1);
237 15410080
        vcc_delete_expr(e2);
238 15410080
        return (e);
239
}
240
241
/*--------------------------------------------------------------------
242
 * Expand finished expression into C-source code
243
 */
244
245
static void
246 4837760
vcc_expr_fmt(struct vsb *d, int ind, const struct expr *e1)
247
{
248
        char *p;
249
        int i;
250
251 4837760
        if (!e1->fmt->noindent) {
252 46396800
                for (i = 0; i < ind; i++)
253 41791760
                        VSB_putc(d, ' ');
254 4605040
        }
255 4837760
        p = VSB_data(e1->vsb);
256 412631617
        while (*p != '\0') {
257 407794017
                if (*p == '\n') {
258 11615480
                        VSB_putc(d, '\n');
259 11615480
                        if (*++p == '\0')
260 160
                                break;
261 124138120
                        for (i = 0; i < ind; i++)
262 112522800
                                VSB_putc(d, ' ');
263 407793857
                } else if (*p != '\v') {
264 390567177
                        VSB_putc(d, *p++);
265 390567177
                } else {
266 5611360
                        switch (*++p) {
267 2805680
                        case '+': ind += INDENT; break;
268 2805680
                        case '-': ind -= INDENT; break;
269 0
                        default:  WRONG("Illegal format in VCC expression");
270 0
                        }
271 5611360
                        p++;
272
                }
273
        }
274 4837760
}
275
276
/*--------------------------------------------------------------------
277
 */
278
279
static void
280 3485360
vcc_expr_tobool(struct vcc *tl, struct expr **e)
281
{
282
283 3485360
        if ((*e)->fmt == BOOL)
284 2553160
                return;
285 932200
        if ((*e)->fmt == BACKEND || (*e)->fmt == INT)
286 400
                *e = vcc_expr_edit(tl, BOOL, "(\v1 != 0)", *e, NULL);
287 931800
        else if ((*e)->fmt == DURATION)
288 80
                *e = vcc_expr_edit(tl, BOOL, "(\v1 > 0)", *e, NULL);
289 931720
        else if ((*e)->fmt == STRINGS)
290 931480
                *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 3485360
}
297
298
/*--------------------------------------------------------------------
299
 */
300
301
static void
302 2504640
vcc_expr_tostring(struct vcc *tl, struct expr **e)
303
{
304
        const char *p;
305 2504640
        uint8_t constant = EXPR_VAR;
306
307 2504640
        CHECK_OBJ_NOTNULL(*e, EXPR_MAGIC);
308 2504640
        assert((*e)->fmt != STRINGS);
309
310 2504640
        p = (*e)->fmt->tostring;
311 2504640
        if (p != NULL) {
312 2504600
                AN(*p);
313 2504600
                *e = vcc_expr_edit(tl, STRINGS, p, *e, NULL);
314 2504600
                (*e)->constant = constant;
315 2504600
                (*e)->nstr = 1;
316 2504600
        } 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 2504640
}
323
324
/*--------------------------------------------------------------------
325
 */
326
327
void v_matchproto_(sym_expr_t)
328 17240
vcc_Eval_Handle(struct vcc *tl, struct expr **e, struct token *t,
329
    struct symbol *sym, vcc_type_t type)
330
{
331
332 17240
        (void)t;
333 17240
        (void)tl;
334 17240
        AN(sym->rname);
335 17240
        AZ(type->stringform);
336
337 17240
        if (sym->type->tostring == NULL &&
338 0
            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 17240
                *e = vcc_mk_expr(sym->type, "%s", sym->rname);
344 17240
                (*e)->constant = EXPR_VAR;
345 17240
                (*e)->nstr = 1;
346 17240
                if ((*e)->fmt == STRING)
347 0
                        (*e)->fmt = STRINGS;
348
        }
349 17240
}
350
351
void v_matchproto_(sym_expr_t)
352 1000
vcc_Eval_Sub(struct vcc *tl, struct expr **e, struct token *t,
353
    struct symbol *sym, vcc_type_t type)
354
{
355
356 1000
        (void)t;
357 1000
        (void)tl;
358 1000
        AN(sym->rname);
359 1000
        AZ(type->stringform);
360
361 1000
        assert (sym->type == SUB);
362
363 1000
        if (type == SUB) {
364 880
                *e = vcc_mk_expr(sym->type, "%s", sym->rname);
365 880
                (*e)->constant = EXPR_CONST;
366 880
                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 1000
}
373
374
/*--------------------------------------------------------------------
375
 */
376
377
void v_matchproto_(sym_expr_t)
378 5650440
vcc_Eval_Var(struct vcc *tl, struct expr **e, struct token *t,
379
    struct symbol *sym, vcc_type_t type)
380
{
381
382 5650440
        (void)type;
383 5650440
        vcc_AddUses(tl, t, NULL, sym, XREF_READ);
384 5650440
        ERRCHK(tl);
385 5650440
        *e = vcc_mk_expr(sym->type, "%s", sym->rname);
386 5650440
        (*e)->constant = EXPR_VAR;
387 5650440
        (*e)->nstr = 1;
388 5650440
        if ((*e)->fmt == STRING)
389 2223960
                (*e)->fmt = STRINGS;
390 5650440
}
391
392
void v_matchproto_(sym_expr_t)
393 440
vcc_Eval_ProtectedHeader(struct vcc *tl, struct expr **e, struct token *t,
394
    struct symbol *sym, vcc_type_t type)
395
{
396
397 440
        AN(sym);
398 440
        AZ(sym->lorev);
399
400 440
        vcc_Header_Fh(tl, sym);
401 440
        sym->eval = vcc_Eval_Var;
402 440
        vcc_Eval_Var(tl, e, t, sym, type);
403 440
}
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 73040
vcc_do_enum(struct vcc *tl, const char *cfunc, int len, const char *ptr)
457
{
458
        const char *r;
459
460 73040
        (void)tl;
461 73040
        r = strchr(cfunc, '.');
462 73040
        AN(r);
463 73040
        return (vcc_mk_expr(VOID, "*%.*s.enum_%.*s",
464 73040
            (int)(r - cfunc), cfunc, len, ptr));
465
}
466
467
static void
468 161280
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 161280
        if (fa->type == ENUM) {
474 53760
                ExpectErr(tl, ID);
475 53760
                ERRCHK(tl);
476 186880
                VTAILQ_FOREACH(vv, &fa->enums->children, list)
477 186800
                        if (vcc_IdIs(tl->t, vv->value))
478 53680
                                break;
479 53760
                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 53680
                fa->result = vcc_do_enum(tl, cfunc, PF(tl->t));
488 53680
                SkipToken(tl, ID);
489 53680
        } else {
490 107520
                if (fa->type == SUB)
491 880
                        tl->subref++;
492 107520
                vcc_expr0(tl, &e2, fa->type);
493 107520
                ERRCHK(tl);
494 107200
                assert(e2->fmt == fa->type);
495 107200
                fa->result = e2;
496
        }
497 160880
        fa->avail = 1;
498 161280
}
499
500
static void
501 111920
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 111920
        CAST_OBJ_NOTNULL(vv, priv, VJSN_VAL_MAGIC);
516 111920
        assert(vjsn_is_array(vv));
517 111920
        vv = VTAILQ_FIRST(&vv->children);
518 111920
        rfmt = VCC_Type(VTAILQ_FIRST(&vv->children)->value);
519 111920
        AN(rfmt);
520 111920
        vv = VTAILQ_NEXT(vv, list);
521 111920
        cfunc = vv->value;
522 111920
        vv = VTAILQ_NEXT(vv, list);
523 111920
        sa = vv->value;
524 111920
        if (*sa == '\0') {
525 95320
                sa = NULL;
526 95320
        }
527 111920
        vv = VTAILQ_NEXT(vv, list);
528 111920
        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 111840
        tf = VTAILQ_PREV(tl->t, tokenhead, list);
540 111840
        SkipToken(tl, '(');
541 111840
        if (extra == NULL) {
542 72920
                extra = "";
543 72920
                extra_sep = "";
544 72920
        } else {
545 38920
                AN(*extra);
546 38920
                extra_sep = ", ";
547
        }
548 111840
        VTAILQ_INIT(&head);
549 382520
        for (;vv != NULL; vv = VTAILQ_NEXT(vv, list)) {
550 270680
                assert(vjsn_is_array(vv));
551 270680
                fa = calloc(1, sizeof *fa);
552 270680
                AN(fa);
553 270680
                VTAILQ_INSERT_TAIL(&head, fa, list);
554
555 270680
                vvp = VTAILQ_FIRST(&vv->children);
556 270680
                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 6880
                                fa->cname = fa->name = vvp->value;
561 6880
                        continue;
562
                }
563 263800
                fa->type = VCC_Type(vvp->value);
564 263800
                AN(fa->type);
565 263800
                vvp = VTAILQ_NEXT(vvp, list);
566 263800
                if (vvp != NULL) {
567 263800
                        fa->name = vvp->value;
568 263800
                        vvp = VTAILQ_NEXT(vvp, list);
569 263800
                        AN(vvp); /* vmod_syntax 2.0 */
570 263800
                        fa->cname = vvp->value;
571 263800
                        vvp = VTAILQ_NEXT(vvp, list);
572 263800
                        if (vvp != NULL) {
573 183840
                                fa->val = vvp->value;
574 183840
                                vvp = VTAILQ_NEXT(vvp, list);
575 183840
                                if (vvp != NULL) {
576 150880
                                        fa->enums = vvp;
577 150880
                                        vvp = VTAILQ_NEXT(vvp, list);
578 150880
                                }
579 183840
                        }
580 263800
                }
581 263800
                if (sa != NULL && vvp != NULL && vjsn_is_true(vvp)) {
582 82760
                        fa->optional = 1;
583 82760
                        vvp = VTAILQ_NEXT(vvp, list);
584 82760
                }
585 263800
                AZ(vvp);
586 263800
        }
587
588 179400
        VTAILQ_FOREACH(fa, &head, list) {
589 161000
                if (tl->t->tok == ')')
590 3560
                        break;
591 157440
                if (fa->result != NULL)
592 4920
                        continue;
593 152520
                if (tl->t->tok == ID) {
594 111760
                        t1 = VTAILQ_NEXT(tl->t, list);
595 111760
                        if (t1->tok == '=')
596 30400
                                break;
597 81360
                }
598 122120
                vcc_do_arg(tl, cfunc, fa);
599 122120
                if (tl->err)
600 800
                        VSB_printf(tl->sb, "Expected argument: %s %s\n\n",
601 400
                            fa->type->name,
602 400
                            fa->name ? fa->name : "(unnamed argument)");
603 122120
                ERRCHK(tl);
604 121720
                if (tl->t->tok == ')')
605 59080
                        break;
606 62640
                SkipToken(tl, ',');
607 62640
        }
608 120280
        while (tl->t->tok == ID) {
609 128960
                VTAILQ_FOREACH(fa, &head, list) {
610 128920
                        if (fa->name == NULL)
611 480
                                continue;
612 128440
                        if (vcc_IdIs(tl->t, fa->name))
613 39200
                                break;
614 89240
                }
615 39240
                if (fa == NULL) {
616 80
                        VSB_printf(tl->sb, "Unknown argument '%.*s'\n",
617 40
                            PF(tl->t));
618 40
                        vcc_ErrWhere(tl, tl->t);
619 40
                        return;
620
                }
621 39200
                if (fa->result != NULL) {
622 40
                        AN(fa->name);
623 80
                        VSB_printf(tl->sb, "Argument '%s' already used\n",
624 40
                            fa->name);
625 40
                        vcc_ErrWhere(tl, tl->t);
626 40
                        return;
627
                }
628 39160
                vcc_NextToken(tl);
629 39160
                SkipToken(tl, '=');
630 39160
                vcc_do_arg(tl, cfunc, fa);
631 39160
                ERRCHK(tl);
632 39160
                if (tl->t->tok == ')')
633 30320
                        break;
634 8840
                SkipToken(tl, ',');
635
        }
636
637 111360
        if (sa != NULL)
638 32880
                e1 = vcc_mk_expr(rfmt, "%s(ctx%s%s,\v+\n&(%s)\v+ {\n",
639 16440
                    cfunc, extra_sep, extra, sa);
640
        else
641 189840
                e1 = vcc_mk_expr(rfmt, "%s(ctx%s%s\v+",
642 94920
                    cfunc, extra_sep, extra);
643 111360
        n = 0;
644 379200
        VTAILQ_FOREACH_SAFE(fa, &head, list, fa2) {
645 267840
                n++;
646 267840
                if (fa->optional) {
647 81000
                        AN(fa->cname);
648 81000
                        bprintf(ssa, "\v1.valid_%s = %d,\n",
649
                            fa->cname, fa->avail);
650 81000
                        e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, NULL);
651 81000
                }
652 267840
                if (fa->result == NULL && fa->type == ENUM && fa->val != NULL)
653 19360
                        fa->result = vcc_do_enum(tl, cfunc, strlen(fa->val), fa->val);
654 267840
                if (fa->result == NULL && fa->val != NULL)
655 24520
                        fa->result = vcc_mk_expr(fa->type, "%s", fa->val);
656 267840
                if (fa->result != NULL && sa != NULL) {
657 35520
                        if (fa->cname)
658 34680
                                bprintf(ssa, "\v1.%s = \v2,\n", fa->cname);
659
                        else
660 840
                                bprintf(ssa, "\v1.arg%d = \v2,\n", n);
661 35520
                        e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, fa->result);
662 267840
                } else if (fa->result != NULL) {
663 351840
                        e1 = vcc_expr_edit(tl, e1->fmt, "\v1,\n\v2",
664 175920
                            e1, fa->result);
665 232320
                } else if (!fa->optional) {
666 40
                        if (fa->name)
667 80
                                VSB_printf(tl->sb, "Argument '%s' missing\n",
668 40
                                    fa->name);
669
                        else
670 0
                                VSB_printf(tl->sb, "Argument %d missing\n", n);
671 40
                        vcc_ErrWhere(tl, tl->t);
672 40
                }
673 267840
                free(fa);
674 267840
        }
675 111360
        if (sa != NULL) {
676 16440
                *e = vcc_expr_edit(tl, e1->fmt, "\v1\v-\n}\v-\n)", e1, NULL);
677 16440
        } else {
678 94920
                *e = vcc_expr_edit(tl, e1->fmt, "\v1\v-\n)", e1, NULL);
679
        }
680 111360
        SkipToken(tl, ')');
681 111320
        vcc_AddUses(tl, tf, NULL, sym, XREF_READ);
682 111920
}
683
684
685
/*--------------------------------------------------------------------
686
 */
687
688
void
689 8040
vcc_Eval_Func(struct vcc *tl, const struct vjsn_val *spec,
690
    const char *extra, struct symbol *sym)
691
{
692 8040
        struct expr *e = NULL;
693
694 8040
        vcc_func(tl, &e, spec, extra, sym);
695 8040
        if (tl->err)
696 0
                VSB_cat(tl->sb, "While compiling function call:\n");
697 8040
        ERRCHK(tl);
698 8040
        vcc_expr_fmt(tl->fb, tl->indent, e);
699 8040
        VSB_cat(tl->fb, ";\n");
700 8040
        vcc_delete_expr(e);
701 8040
}
702
703
/*--------------------------------------------------------------------
704
 */
705
706
void v_matchproto_(sym_expr_t)
707 84240
vcc_Eval_SymFunc(struct vcc *tl, struct expr **e, struct token *t,
708
    struct symbol *sym, vcc_type_t fmt)
709
{
710
711 84240
        (void)t;
712 84240
        (void)fmt;
713 84240
        assert(sym->kind == SYM_FUNC || sym->kind == SYM_METHOD);
714 84240
        AN(sym->eval_priv);
715
716 84240
        vcc_func(tl, e, sym->eval_priv, sym->extra, sym);
717 84240
        ERRCHK(tl);
718 83840
        if ((*e)->fmt == STRING) {
719 30400
                (*e)->fmt = STRINGS;
720 30400
                (*e)->nstr = 1;
721 30400
        }
722 84240
}
723
724
/*--------------------------------------------------------------------
725
 */
726
727
static void
728 1326240
vcc_number(struct vcc *tl, struct expr **e, vcc_type_t fmt, const char *sign)
729
{
730
        VCL_INT vi;
731
        struct expr *e1;
732
        struct token *t;
733
734 1326240
        assert(fmt != VOID);
735 1326240
        if (fmt == BYTES) {
736 2000
                vcc_ByteVal(tl, &vi);
737 2000
                ERRCHK(tl);
738 1920
                e1 = vcc_mk_expr(BYTES, "%ju", (intmax_t)vi);
739 1920
        } else {
740 1324240
                t = tl->t;
741 1324240
                vcc_NextToken(tl);
742 1324240
                if (tl->t->tok == ID) {
743 126640
                        e1 = vcc_mk_expr(DURATION, "%s%.3f * %g",
744 126640
                            sign, t->num, vcc_DurationUnit(tl));
745 126640
                        ERRCHK(tl);
746 1324200
                } else if (fmt == REAL || t->tok == FNUM) {
747 7200
                        e1 = vcc_mk_expr(REAL, "%s%.3f", sign, t->num);
748 7200
                } else {
749 1190400
                        e1 = vcc_mk_expr(INT, "%s%.0fLL", sign, t->num);
750
                }
751
        }
752 1326120
        e1->constant = EXPR_CONST;
753 1326120
        *e = e1;
754 1326240
}
755
756
/*--------------------------------------------------------------------
757
 * SYNTAX:
758
 *    Expr5:
759
 *      '(' ExprCor ')'
760
 *      symbol
761
 *      CNUM
762
 *      FNUM
763
 *      CSTR
764
 *      CBLOB
765
 */
766
767
static void
768 11936720
vcc_expr5(struct vcc *tl, struct expr **e, vcc_type_t fmt)
769
{
770
        struct expr *e1, *e2;
771
        const char *ip, *sign;
772
        struct token *t, *t1;
773
        struct symbol *sym;
774
775 11936720
        sign = "";
776 11936720
        *e = NULL;
777 11936720
        if (tl->t->tok == '(') {
778 117880
                SkipToken(tl, '(');
779 117880
                vcc_expr_cor(tl, &e2, fmt);
780 117880
                ERRCHK(tl);
781 117880
                SkipToken(tl, ')');
782 117880
                if (e2->fmt == STRINGS)
783 240
                        *e = e2;
784
                else
785 117640
                        *e = vcc_expr_edit(tl, e2->fmt, "(\v1)", e2, NULL);
786 117880
                return;
787
        }
788 11818840
        switch (tl->t->tok) {
789
        case ID:
790 5881240
                t = tl->t;
791 5881240
                t1 = vcc_PeekToken(tl);
792 5881240
                AN(t1);
793 5881240
                sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
794
                    SYMTAB_PARTIAL_NOERR, XREF_REF);
795 5881240
                if (sym == NULL && fmt->global_pfx != NULL && t1->tok != '.') {
796 360
                        sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
797
                            SYMTAB_CREATE, XREF_REF);
798 360
                        ERRCHK(tl);
799 280
                        AN(sym);
800 280
                        VCC_GlobalSymbol(sym, fmt);
801 280
                }
802 5881160
                ERRCHK(tl);
803 5881160
                if (sym == NULL)
804 480
                        AZ(VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
805
                            SYMTAB_PARTIAL, XREF_REF));
806 5881160
                ERRCHK(tl);
807 5880680
                AN(sym);
808 5880680
                if (sym->kind == SYM_INSTANCE) {
809 30960
                        AZ(*e);
810 30960
                        *e = vcc_new_expr(sym->type);
811 30960
                        (*e)->instance = sym;
812 30960
                        return;
813
                }
814 5849720
                if (sym->kind == SYM_FUNC && sym->type == VOID) {
815 40
                        VSB_cat(tl->sb, "Function returns VOID:\n");
816 40
                        vcc_ErrWhere(tl, tl->t);
817 40
                        return;
818
                }
819 5849680
                if (sym->eval != NULL) {
820 5849560
                        AN(sym->eval);
821 5849560
                        AZ(*e);
822 5849560
                        sym->eval(tl, e, t, sym, fmt);
823 5849560
                        if (tl->err) {
824 640
                                VSB_cat(tl->sb,
825
                                    "While compiling function call:\n\n");
826 640
                                vcc_ErrWhere2(tl, t, tl->t);
827 640
                        }
828 5849560
                        ERRCHK(tl);
829
                        /* Unless asked for a HEADER, fold to string here */
830 5848920
                        if (*e && fmt != HEADER && (*e)->fmt == HEADER) {
831 1664240
                                vcc_expr_tostring(tl, e);
832 1664240
                                ERRCHK(tl);
833 1664240
                        }
834 5848920
                        return;
835
                }
836 240
                VSB_printf(tl->sb,
837
                    "Symbol '%.*s' type (%s) cannot be used in expression.\n",
838 120
                    PF(t), sym->kind->name);
839 120
                vcc_ErrWhere(tl, t);
840 120
                if (sym->def_b != NULL) {
841 40
                        VSB_cat(tl->sb, "That symbol was defined here:\n");
842 40
                        vcc_ErrWhere(tl, sym->def_b);
843 40
                }
844 120
                return;
845
        case CSTR:
846 4610760
                assert(fmt != VOID);
847 4610760
                if (fmt == IP) {
848 1200
                        if (*tl->t->dec == '/') {
849
                                /*
850
                                 * On some platforms (e.g. FreeBSD),
851
                                 * getaddrinfo(3) may resolve a path to a
852
                                 * sockaddr_un if it happens to exist and
853
                                 * is a socket. So don't let that happen.
854
                                 */
855 40
                                VSB_cat(tl->sb,
856
                                    "Cannot convert to an IP address: ");
857 40
                                vcc_ErrToken(tl, tl->t);
858 40
                                vcc_ErrWhere(tl, tl->t);
859 40
                                return;
860
                        }
861 2320
                        Resolve_Sockaddr(tl, tl->t->dec, "80",
862
                            &ip, NULL, &ip, NULL, NULL, 1,
863 1160
                            tl->t, "IP constant");
864 1160
                        ERRCHK(tl);
865 1040
                        e1 = vcc_mk_expr(IP, "%s", ip);
866 1040
                        ERRCHK(tl);
867 4610600
                } else if (fmt == REGEX) {
868 353120
                        e1 = vcc_new_expr(REGEX);
869 353120
                        vcc_regexp(tl, e1->vsb);
870 353120
                        AZ(VSB_finish(e1->vsb));
871 353120
                } else {
872 4256440
                        e1 = vcc_new_expr(STRINGS);
873 4256440
                        EncToken(e1->vsb, tl->t);
874 4256440
                        AZ(VSB_finish(e1->vsb));
875 4256440
                        e1->constant |= EXPR_STR_CONST;
876 4256440
                        e1->nstr = 1;
877
                }
878 4610600
                e1->t1 = tl->t;
879 4610600
                e1->constant |= EXPR_CONST;
880 4610600
                vcc_NextToken(tl);
881 4610600
                *e = e1;
882 4610600
                return;
883
        case '-':
884 2480
                if (fmt != INT &&
885 640
                    fmt != REAL &&
886 160
                    fmt != DURATION &&
887 40
                    fmt != STRINGS)
888 0
                        break;
889 2440
                vcc_NextToken(tl);
890 2440
                if (tl->t->tok != FNUM && tl->t->tok != CNUM) {
891 360
                        vcc_expr_cor(tl, &e1, fmt);
892 360
                        ERRCHK(tl);
893 360
                        *e = vcc_expr_edit(tl, e1->fmt, "-(\v1)", e1, NULL);
894 360
                        return;
895
                }
896 2080
                sign = "-";
897
                /* FALLTHROUGH */
898
        case FNUM:
899
        case CNUM:
900 1326240
                vcc_number(tl, e, fmt, sign);
901 1326240
                return;
902
        case CBLOB:
903 80
                e1 = vcc_new_expr(BLOB);
904 80
                VSB_printf(e1->vsb, "%s", tl->t->dec);
905 80
                AZ(VSB_finish(e1->vsb));
906 80
                e1->constant |= EXPR_STR_CONST;
907 80
                e1->t1 = tl->t;
908 80
                vcc_NextToken(tl);
909 80
                *e = e1;
910 80
                return;
911
        default:
912 160
                break;
913
        }
914 160
        VSB_cat(tl->sb, "Unknown token ");
915 160
        vcc_ErrToken(tl, tl->t);
916 160
        VSB_printf(tl->sb, " when looking for %s\n\n", vcc_utype(fmt));
917 160
        vcc_ErrWhere(tl, tl->t);
918 11936720
}
919
920
/*--------------------------------------------------------------------
921
 * SYNTAX:
922
 *    Expr4:
923
 *      Expr5 [ '.' (type_attribute | type_method()) ]*
924
 */
925
926
void
927 116720
vcc_Eval_TypeMethod(struct vcc *tl, struct expr **e, struct token *t,
928
    struct symbol *sym, vcc_type_t fmt)
929
{
930
        const char *impl;
931
932 116720
        (void)t;
933 116720
        impl = VCC_Type_EvalMethod(tl, sym);
934 116720
        ERRCHK(tl);
935 116720
        AN(impl);
936 116720
        *e = vcc_expr_edit(tl, fmt, impl, *e, NULL);
937 116720
}
938
939
static void
940 11936720
vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt)
941
{
942
        struct symbol *sym;
943
944 11936720
        *e = NULL;
945 11936720
        vcc_expr5(tl, e, fmt);
946 11936720
        ERRCHK(tl);
947 11934800
        AN(*e);
948 12082400
        while (tl->t->tok == '.') {
949 147720
                vcc_NextToken(tl);
950 147720
                ExpectErr(tl, ID);
951
952 147680
                sym = VCC_TypeSymbol(tl, SYM_METHOD, (*e)->fmt);
953 147680
                if (sym == NULL) {
954 80
                        VSB_cat(tl->sb, "Unknown property ");
955 80
                        vcc_ErrToken(tl, tl->t);
956 80
                        VSB_printf(tl->sb, " for type %s\n", (*e)->fmt->name);
957 80
                        vcc_ErrWhere(tl, tl->t);
958 80
                        return;
959
                }
960
961 147600
                AN(sym->eval);
962 147600
                sym->eval(tl, e, tl->t, sym, sym->type);
963 147600
                ERRCHK(tl);
964 147600
                if ((*e)->fmt == STRING) {
965 116280
                        (*e)->fmt = STRINGS;
966 116280
                        (*e)->nstr = 1;
967 116280
                }
968
        }
969 11936720
}
970
971
/*--------------------------------------------------------------------
972
 * SYNTAX:
973
 *    ExprMul:
974
 *      Expr4 { {'*'|'/'|'%'} Expr4 } *
975
 */
976
977
static void
978 11568520
vcc_expr_mul(struct vcc *tl, struct expr **e, vcc_type_t fmt)
979
{
980
        struct expr *e2;
981
        vcc_type_t f2;
982
        struct token *tk;
983
        char buf[24];
984
985 11568520
        *e = NULL;
986 11568520
        vcc_expr4(tl, e, fmt);
987 11568520
        ERRCHK(tl);
988 11566760
        AN(*e);
989
990 11568400
        while (tl->t->tok == '*' || tl->t->tok == '/' || tl->t->tok == '%') {
991 1800
                if (tl->t->tok == '%' && ((*e)->fmt != INT)) {
992 40
                        VSB_cat(tl->sb, "Operator % only possible on INT.\n");
993 40
                        vcc_ErrWhere(tl, tl->t);
994 40
                        return;
995
                }
996 1760
                f2 = (*e)->fmt->multype;
997 1760
                if (f2 == NULL) {
998 80
                        VSB_printf(tl->sb,
999
                            "Operator %.*s not possible on type %s.\n",
1000 40
                            PF(tl->t), vcc_utype((*e)->fmt));
1001 40
                        vcc_ErrWhere(tl, tl->t);
1002 40
                        return;
1003
                }
1004 1720
                tk = tl->t;
1005 1720
                vcc_NextToken(tl);
1006 1720
                vcc_expr4(tl, &e2, f2);
1007 1720
                ERRCHK(tl);
1008 1720
                if (e2->fmt != INT && e2->fmt != f2) {
1009 160
                        VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
1010 80
                            vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1011 80
                        vcc_ErrWhere(tl, tk);
1012 80
                        return;
1013
                }
1014 1640
                bprintf(buf, "(\v1%c\v2)", tk->tok);
1015 1640
                *e = vcc_expr_edit(tl, (*e)->fmt, buf, *e, e2);
1016
        }
1017 11568520
}
1018
1019
/*--------------------------------------------------------------------
1020
 * SYNTAX:
1021
 *    ExprAdd:
1022
 *      ExprMul { {'+'|'-'} ExprMul } *
1023
 */
1024
1025
static const struct adds {
1026
        unsigned        op;
1027
        vcc_type_t      a;
1028
        vcc_type_t      b;
1029
        vcc_type_t      fmt;
1030
} vcc_adds[] = {
1031
        { '+', BYTES,           BYTES,          BYTES },
1032
        { '-', BYTES,           BYTES,          BYTES },
1033
        { '+', DURATION,        DURATION,       DURATION },
1034
        { '-', DURATION,        DURATION,       DURATION },
1035
        { '+', INT,             INT,            INT },
1036
        { '-', INT,             INT,            INT },
1037
        { '+', INT,             REAL,           REAL },
1038
        { '-', INT,             REAL,           REAL },
1039
        { '+', REAL,            INT,            REAL },
1040
        { '-', REAL,            INT,            REAL },
1041
        { '+', REAL,            REAL,           REAL },
1042
        { '-', REAL,            REAL,           REAL },
1043
        { '-', TIME,            TIME,           DURATION },
1044
        { '+', TIME,            DURATION,       TIME },
1045
        { '-', TIME,            DURATION,       TIME },
1046
1047
        { EOI, VOID,            VOID,           VOID }
1048
};
1049
1050
static void
1051 8764400
vcc_expr_add(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1052
{
1053
        const struct adds *ap;
1054
        struct expr  *e2;
1055
        struct token *tk;
1056
        int lit, n;
1057
1058 8764400
        *e = NULL;
1059 8764400
        vcc_expr_mul(tl, e, fmt);
1060 8764400
        ERRCHK(tl);
1061
1062 11566160
        while (tl->t->tok == '+' || tl->t->tok == '-') {
1063 2804120
                tk = tl->t;
1064 44833040
                for (ap = vcc_adds; ap->op != EOI; ap++)
1065 42032240
                        if (tk->tok == ap->op && (*e)->fmt == ap->a)
1066 3320
                                break;
1067 2804120
                vcc_NextToken(tl);
1068 2804120
                if (ap->op == EOI && fmt == STRINGS)
1069 20240
                        vcc_expr_mul(tl, &e2, STRINGS);
1070
                else
1071 2783880
                        vcc_expr_mul(tl, &e2, (*e)->fmt);
1072 2804120
                ERRCHK(tl);
1073
1074 44838560
                for (ap = vcc_adds; ap->op != EOI; ap++)
1075 42037360
                        if (tk->tok == ap->op && (*e)->fmt == ap->a &&
1076 42037360
                            e2->fmt == ap->b)
1077 2920
                                break;
1078
1079 2804120
                if (ap->op == '+') {
1080 2120
                        *e = vcc_expr_edit(tl, ap->fmt, "(\v1 + \v2)", *e, e2);
1081 2804120
                } else if (ap->op == '-') {
1082 800
                        *e = vcc_expr_edit(tl, ap->fmt, "(\v1 - \v2)", *e, e2);
1083 2802640
                } else if (tk->tok == '+' &&
1084 2801160
                    ((*e)->fmt == STRINGS || fmt == STRINGS)) {
1085 2800760
                        if ((*e)->fmt != STRINGS)
1086 240
                                vcc_expr_tostring(tl, e);
1087 2800760
                        if (e2->fmt != STRINGS)
1088 697320
                                vcc_expr_tostring(tl, &e2);
1089 2800760
                        if (vcc_islit(*e) && vcc_isconst(e2)) {
1090 2000
                                lit = vcc_islit(e2);
1091 4000
                                *e = vcc_expr_edit(tl, STRINGS,
1092 2000
                                    "\v1\n\v2", *e, e2);
1093 2000
                                (*e)->constant = EXPR_CONST;
1094 2000
                                (*e)->nstr = 1;
1095 2000
                                if (lit)
1096 2000
                                        (*e)->constant |= EXPR_STR_CONST;
1097 2000
                        } else {
1098 2798760
                                n = (*e)->nstr + e2->nstr;
1099 5597520
                                *e = vcc_expr_edit(tl, STRINGS,
1100 2798760
                                    "\v1,\n\v2", *e, e2);
1101 2798760
                                (*e)->constant = EXPR_VAR;
1102 2798760
                                (*e)->nstr = n;
1103
                        }
1104 2800760
                } else {
1105 880
                        VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
1106 440
                            vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1107 440
                        vcc_ErrWhere2(tl, tk, tl->t);
1108 440
                        return;
1109
                }
1110
        }
1111 8764400
}
1112
1113
/*--------------------------------------------------------------------
1114
 * SYNTAX:
1115
 *    ExprCmp:
1116
 *      ExprAdd
1117
 *      ExprAdd Relation ExprAdd
1118
 *      ExprAdd(STRING) '~' CString
1119
 *      ExprAdd(STRING) '!~' CString
1120
 *      ExprAdd(IP) '==' ExprAdd(IP)
1121
 *      ExprAdd(IP) '!=' ExprAdd(IP)
1122
 *      ExprAdd(IP) '~' ACL
1123
 *      ExprAdd(IP) '!~' ACL
1124
 */
1125
1126
struct cmps;
1127
1128
typedef void cmp_f(struct vcc *, struct expr **, const struct cmps *);
1129
1130
struct cmps {
1131
        vcc_type_t              fmt;
1132
        unsigned                token;
1133
        cmp_f                   *func;
1134
        const char              *emit;
1135
};
1136
1137
static void v_matchproto_(cmp_f)
1138 585560
cmp_simple(struct vcc *tl, struct expr **e, const struct cmps *cp)
1139
{
1140
        struct expr *e2;
1141
        struct token *tk;
1142
1143 585560
        tk = tl->t;
1144 585560
        vcc_NextToken(tl);
1145 585560
        vcc_expr_add(tl, &e2, (*e)->fmt);
1146 585560
        ERRCHK(tl);
1147
1148 585440
        if (e2->fmt != (*e)->fmt) {
1149 160
                VSB_printf(tl->sb,
1150
                    "Comparison of different types: %s '%.*s' %s\n",
1151 80
                    vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1152 80
                vcc_ErrWhere(tl, tk);
1153 80
        } else
1154 585360
                *e = vcc_expr_edit(tl, BOOL, cp->emit, *e, e2);
1155 585560
}
1156
1157
static void v_matchproto_(cmp_f)
1158 351280
cmp_regexp(struct vcc *tl, struct expr **e, const struct cmps *cp)
1159
{
1160
        struct token *t1;
1161
        struct expr *e2;
1162
        char buf[128];
1163
1164 351280
        *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
1165 351280
        vcc_NextToken(tl);
1166 351280
        t1 = tl->t;
1167 351280
        vcc_expr4(tl, &e2, REGEX);
1168 351280
        ERRCHK(tl);
1169 351120
        vcc_expr_typecheck(tl, &e2, REGEX, t1);
1170 351120
        ERRCHK(tl);
1171 351080
        bprintf(buf, "%sVRT_re_match(ctx, \v1, \v2)", cp->emit);
1172 351080
        *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1173 351280
}
1174
1175
static void v_matchproto_(cmp_f)
1176 1880
cmp_acl(struct vcc *tl, struct expr **e, const struct cmps *cp)
1177
{
1178
        struct token *t1;
1179
        struct expr *e2;
1180
        char buf[256];
1181
1182 1880
        vcc_NextToken(tl);
1183 1880
        t1 = tl->t;
1184 1880
        vcc_expr4(tl, &e2, ACL);
1185 1880
        ERRCHK(tl);
1186 1760
        vcc_expr_typecheck(tl, &e2, ACL, t1);
1187 1760
        ERRCHK(tl);
1188 1640
        bprintf(buf, "%sVRT_acl_match(ctx, \v1, \v2)", cp->emit);
1189 1640
        *e = vcc_expr_edit(tl, BOOL, buf, e2, *e);
1190 1880
}
1191
1192
static void v_matchproto_(cmp_f)
1193 1525320
cmp_string(struct vcc *tl, struct expr **e, const struct cmps *cp)
1194
{
1195
        struct expr *e2;
1196
        struct token *tk;
1197
        char buf[128];
1198
1199 1525320
        tk = tl->t;
1200 1525320
        vcc_NextToken(tl);
1201 1525320
        vcc_expr_add(tl, &e2, STRINGS);
1202 1525320
        ERRCHK(tl);
1203 1525320
        if (vcc_stringstype(e2->fmt) != STRINGS) {
1204 240
                VSB_printf(tl->sb,
1205
                    "Comparison of different types: %s '%.*s' %s\n",
1206 120
                    vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1207 120
                vcc_ErrWhere(tl, tk);
1208 1525320
        } else if ((*e)->nstr == 1 && e2->nstr == 1) {
1209 1523960
                bprintf(buf, "(%s VRT_strcmp(\v1, \v2))", cp->emit);
1210 1523960
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1211 1523960
        } else {
1212 1240
                bprintf(buf, "(%s VRT_CompareStrands(\vT, \vt))", cp->emit);
1213 1240
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1214
        }
1215 1525320
}
1216
1217
#define PTR_REL(typ)                                                            \
1218
        {typ,           T_EQ,           cmp_simple, "!VPI_PtrCmp(\v1, \v2)" },  \
1219
        {typ,           T_NEQ,          cmp_simple, "VPI_PtrCmp(\v1, \v2)" }
1220
1221
#define IDENT_REL(typ)                                                  \
1222
        {typ,           T_EQ,           cmp_simple, "(\v1 == \v2)" },   \
1223
        {typ,           T_NEQ,          cmp_simple, "(\v1 != \v2)" }
1224
1225
#define NUM_REL(typ)                                                    \
1226
        IDENT_REL(typ),                                                 \
1227
        {typ,           T_LEQ,          cmp_simple, "(\v1 <= \v2)" },   \
1228
        {typ,           T_GEQ,          cmp_simple, "(\v1 >= \v2)" },   \
1229
        {typ,           '<',            cmp_simple, "(\v1 < \v2)" },    \
1230
        {typ,           '>',            cmp_simple, "(\v1 > \v2)" }
1231
1232
static const struct cmps vcc_cmps[] = {
1233
        NUM_REL(INT),
1234
        NUM_REL(DURATION),
1235
        NUM_REL(BYTES),
1236
        NUM_REL(REAL),
1237
        NUM_REL(TIME),
1238
        PTR_REL(BACKEND),
1239
        PTR_REL(ACL),
1240
        PTR_REL(PROBE),
1241
        IDENT_REL(STEVEDORE),
1242
        IDENT_REL(SUB),
1243
        IDENT_REL(INSTANCE),
1244
1245
        {BOOL,          T_EQ,           cmp_simple, "((!(\v1)) == (!(\v2)))" },
1246
        {BOOL,          T_NEQ,          cmp_simple, "((!(\v1)) != (!(\v2)))" },
1247
        {IP,            T_EQ,           cmp_simple, "!VRT_ipcmp(ctx, \v1, \v2)" },
1248
        {IP,            T_NEQ,          cmp_simple, "VRT_ipcmp(ctx, \v1, \v2)" },
1249
1250
        {IP,            '~',            cmp_acl, "" },
1251
        {IP,            T_NOMATCH,      cmp_acl, "!" },
1252
1253
        {STRINGS,       T_EQ,           cmp_string, "0 =="},
1254
        {STRINGS,       T_NEQ,          cmp_string, "0 !="},
1255
        {STRINGS,       '<',            cmp_string, "0 > "},
1256
        {STRINGS,       '>',            cmp_string, "0 < "},
1257
        {STRINGS,       T_LEQ,          cmp_string, "0 >="},
1258
        {STRINGS,       T_GEQ,          cmp_string, "0 <="},
1259
1260
        {STRINGS,       '~',            cmp_regexp, "" },
1261
        {STRINGS,       T_NOMATCH,      cmp_regexp, "!" },
1262
1263
        {VOID,          0,              NULL, NULL}
1264
};
1265
1266
#undef IDENT_REL
1267
#undef NUM_REL
1268
1269
static void
1270 6653520
vcc_expr_cmp(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1271
{
1272
        const struct cmps *cp;
1273
        struct token *tk;
1274
1275 6653520
        *e = NULL;
1276 6653520
        vcc_expr_add(tl, e, fmt);
1277 6653520
        ERRCHK(tl);
1278 6651280
        tk = tl->t;
1279
1280 335895120
        for (cp = vcc_cmps; cp->fmt != VOID; cp++) {
1281 331707880
                if (tl->t->tok != cp->token)
1282 308943280
                        continue;
1283 22764600
                if (vcc_stringstype((*e)->fmt) != cp->fmt)
1284 20300560
                        continue;
1285 2464040
                AN(cp->func);
1286 2464040
                cp->func(tl, e, cp);
1287 2464040
                return;
1288
        }
1289
1290 4187240
        switch (tk->tok) {
1291
        case T_EQ:
1292
        case T_NEQ:
1293
        case '<':
1294
        case T_LEQ:
1295
        case '>':
1296
        case T_GEQ:
1297
        case '~':
1298
        case T_NOMATCH:
1299 160
                VSB_printf(tl->sb, "Operator %.*s not possible on %s\n",
1300 80
                    PF(tl->t), vcc_utype((*e)->fmt));
1301 80
                vcc_ErrWhere(tl, tl->t);
1302 80
                return;
1303
        default:
1304 4187160
                break;
1305
        }
1306 6653520
}
1307
1308
/*--------------------------------------------------------------------
1309
 * SYNTAX:
1310
 *    ExprNot:
1311
 *      '!' ExprCmp
1312
 */
1313
1314
static void
1315 6653520
vcc_expr_not(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1316
{
1317
        struct token *tk;
1318
1319 6653520
        *e = NULL;
1320 6653520
        tk = tl->t;
1321 6653520
        if (tl->t->tok == '!')
1322 582520
                vcc_NextToken(tl);
1323 6653520
        vcc_expr_cmp(tl, e, fmt);
1324 6653520
        ERRCHK(tl);
1325 6650440
        if (tk->tok != '!')
1326 6067960
                return;
1327 582480
        vcc_expr_tobool(tl, e);
1328 582480
        ERRCHK(tl);
1329 582480
        if ((*e)->fmt != BOOL) {
1330 40
                VSB_cat(tl->sb, "'!' must be followed by BOOL, found ");
1331 40
                VSB_printf(tl->sb, "%s.\n", vcc_utype((*e)->fmt));
1332 40
                vcc_ErrWhere2(tl, tk, tl->t);
1333 40
        } else {
1334 582440
                *e = vcc_expr_edit(tl, BOOL, "!(\v1)", *e, NULL);
1335
        }
1336 6653520
}
1337
1338
/*--------------------------------------------------------------------
1339
 * CAND and COR are identical save for a few details, but they are
1340
 * stacked so handling them in the same function is not simpler.
1341
 * Instead have them both call this helper function to do everything.
1342
 */
1343
1344
typedef void upfunc(struct vcc *tl, struct expr **e, vcc_type_t fmt);
1345
1346
static void
1347 10177160
vcc_expr_bin_bool(struct vcc *tl, struct expr **e, vcc_type_t fmt,
1348
    unsigned ourtok, upfunc *up, const char *tokstr)
1349
{
1350
        struct expr *e2;
1351
        struct token *tk;
1352
        char buf[32];
1353
1354 10177160
        *e = NULL;
1355 10177160
        tk = tl->t;
1356 10177160
        up(tl, e, fmt);
1357 10177160
        ERRCHK(tl);
1358 10170840
        if (tl->t->tok != ourtok)
1359 9358480
                return;
1360 812360
        vcc_expr_tobool(tl, e);
1361 812360
        ERRCHK(tl);
1362 812360
        if ((*e)->fmt != BOOL) {
1363 160
                VSB_printf(tl->sb,
1364
                    "'%s' must be preceded by BOOL,"
1365 80
                    " found %s.\n", tokstr, vcc_utype((*e)->fmt));
1366 80
                vcc_ErrWhere2(tl, tk, tl->t);
1367 80
                return;
1368
        }
1369 812280
        *e = vcc_expr_edit(tl, BOOL, "(\v+\n\v1", *e, NULL);
1370 2435360
        while (tl->t->tok == ourtok) {
1371 1623160
                vcc_NextToken(tl);
1372 1623160
                tk = tl->t;
1373 1623160
                up(tl, &e2, fmt);
1374 1623160
                ERRCHK(tl);
1375 1623160
                vcc_expr_tobool(tl, &e2);
1376 1623160
                ERRCHK(tl);
1377 1623160
                if (e2->fmt != BOOL) {
1378 160
                        VSB_printf(tl->sb,
1379
                            "'%s' must be followed by BOOL,"
1380 80
                            " found %s.\n", tokstr, vcc_utype(e2->fmt));
1381 80
                        vcc_ErrWhere2(tl, tk, tl->t);
1382 80
                        vcc_delete_expr(e2);
1383 80
                        return;
1384
                }
1385 1623080
                bprintf(buf, "\v1\v-\n%s\v+\n\v2", tokstr);
1386 1623080
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1387
        }
1388 812200
        *e = vcc_expr_edit(tl, BOOL, "\v1\v-\n)", *e, NULL);
1389 10177160
}
1390
1391
/*--------------------------------------------------------------------
1392
 * SYNTAX:
1393
 *    ExprCand:
1394
 *      ExprNot { '&&' ExprNot } *
1395
 */
1396
1397
static void
1398 5146800
vcc_expr_cand(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1399
{
1400
1401 5146800
        vcc_expr_bin_bool(tl, e, fmt, T_CAND, vcc_expr_not, "&&");
1402 5146800
}
1403
1404
/*--------------------------------------------------------------------
1405
 * SYNTAX:
1406
 *    ExprCOR:
1407
 *      ExprCand { '||' ExprCand } *
1408
 */
1409
1410
static void
1411 5030360
vcc_expr_cor(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1412
{
1413
1414 5030360
        vcc_expr_bin_bool(tl, e, fmt, T_COR, vcc_expr_cand, "||");
1415 5030360
}
1416
1417
/*--------------------------------------------------------------------
1418
 * This function is the entry-point for getting an expression with
1419
 * a particular type, ready for inclusion in the VGC.
1420
 */
1421
1422
static void
1423 4912120
vcc_expr0(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1424
{
1425
        struct token *t1;
1426
1427 4912120
        assert(fmt != VOID);
1428 4912120
        assert(fmt != STRINGS);
1429 4912120
        *e = NULL;
1430 4912120
        t1 = tl->t;
1431 4912120
        if (fmt->stringform)
1432 1650760
                vcc_expr_cor(tl, e, STRINGS);
1433
        else
1434 3261360
                vcc_expr_cor(tl, e, fmt);
1435 4912120
        ERRCHK(tl);
1436
1437 4908840
        if ((*e)->fmt == fmt)
1438 2559160
                return;
1439
1440 2349680
        if ((*e)->fmt != STRINGS && fmt->stringform)
1441 142800
                vcc_expr_tostring(tl, e);
1442
1443 2349680
        if ((*e)->fmt->stringform) {
1444 0
                VSB_printf(tl->sb, "Cannot convert type %s(%s) to %s(%s)\n",
1445 0
                    vcc_utype((*e)->fmt), (*e)->fmt->name,
1446 0
                    vcc_utype(fmt), fmt->name);
1447 0
                vcc_ErrWhere2(tl, t1, tl->t);
1448 0
                return;
1449
        }
1450
1451 2349680
        if (fmt == BODY && !(*e)->fmt->bodyform)
1452 40
                vcc_expr_tostring(tl, e);
1453
1454 2349680
        if (fmt == BODY && (*e)->fmt->bodyform) {
1455 232720
                if ((*e)->fmt == STRINGS)
1456 232560
                        *e = vcc_expr_edit(tl, BODY, "STRING, 0, \vT", *e, NULL);
1457 160
                else if ((*e)->fmt == BLOB)
1458 160
                        *e = vcc_expr_edit(tl, BODY, "BLOB, 0, \v1", *e, NULL);
1459
                else
1460 0
                        WRONG("Unhandled bodyform");
1461 232720
        }
1462
1463 2349680
        if ((*e)->fmt == STRINGS && fmt->stringform) {
1464 1649440
                if (fmt == STRING)
1465 495040
                        *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
1466 1154400
                else if (fmt == STRANDS)
1467 1154400
                        *e = vcc_expr_edit(tl, STRANDS, "\vT", (*e), NULL);
1468
                else
1469 0
                        WRONG("Unhandled stringform");
1470 1649440
        }
1471
1472 2349680
        if (fmt == BOOL) {
1473 467360
                vcc_expr_tobool(tl, e);
1474 467360
                ERRCHK(tl);
1475 467360
        }
1476
1477 2349680
        vcc_expr_typecheck(tl, e, fmt, t1);
1478 4912120
}
1479
1480
static void
1481 2702560
vcc_expr_typecheck(struct vcc *tl, struct expr **e, vcc_type_t fmt,
1482
    struct token *t1)
1483
{
1484
1485 2702560
        assert(fmt != VOID);
1486 2702560
        assert(fmt != STRINGS);
1487
1488 2702560
        if (fmt != (*e)->fmt)  {
1489 720
                VSB_printf(tl->sb, "Expression has type %s, expected %s\n",
1490 360
                    vcc_utype((*e)->fmt), vcc_utype(fmt));
1491 360
                vcc_ErrWhere2(tl, t1, tl->t);
1492 360
        }
1493 2702560
}
1494
1495
/*--------------------------------------------------------------------
1496
 * This function parses and emits the C-code to evaluate an expression
1497
 *
1498
 * We know up front what kind of type we want the expression to be,
1499
 * and this function is the backstop if that doesn't succeed.
1500
 */
1501
1502
void
1503 4800080
vcc_Expr(struct vcc *tl, vcc_type_t fmt)
1504
{
1505 4800080
        struct expr *e = NULL;
1506
1507 4800080
        assert(fmt != VOID);
1508 4800080
        assert(fmt != STRINGS);
1509 4800080
        vcc_expr0(tl, &e, fmt);
1510 4800080
        ERRCHK(tl);
1511 4796960
        assert(e->fmt == fmt);
1512
1513 4796960
        vcc_expr_fmt(tl->fb, tl->indent, e);
1514 4796960
        VSB_cat(tl->fb, "\n");
1515 4796960
        vcc_delete_expr(e);
1516 4800080
}
1517
1518
/*--------------------------------------------------------------------
1519
 */
1520
1521
void v_matchproto_(sym_act_f)
1522 19640
vcc_Act_Call(struct vcc *tl, struct token *t, struct symbol *sym)
1523
{
1524
1525
        struct expr *e;
1526
1527 19640
        e = NULL;
1528 19640
        vcc_func(tl, &e, sym->eval_priv, sym->extra, sym);
1529 19640
        if (!tl->err) {
1530 19440
                vcc_expr_fmt(tl->fb, tl->indent, e);
1531 19440
                SkipToken(tl, ';');
1532 19440
                VSB_cat(tl->fb, ";\n");
1533 19640
        } else if (t != tl->t) {
1534 200
                VSB_cat(tl->sb, "While compiling function call:\n\n");
1535 200
                vcc_ErrWhere2(tl, t, tl->t);
1536 200
        }
1537 19640
        vcc_delete_expr(e);
1538 19640
}
1539
1540
void v_matchproto_(sym_act_f)
1541 13360
vcc_Act_Obj(struct vcc *tl, struct token *t, struct symbol *sym)
1542
{
1543
1544 13360
        struct expr *e = NULL;
1545
1546 13360
        assert(sym->kind == SYM_INSTANCE);
1547 13360
        ExpectErr(tl, '.');
1548 13320
        tl->t = t;
1549 13320
        vcc_expr4(tl, &e, sym->type);
1550 13320
        ERRCHK(tl);
1551 13320
        vcc_expr_fmt(tl->fb, tl->indent, e);
1552 13320
        vcc_delete_expr(e);
1553 13320
        SkipToken(tl, ';');
1554 13320
        VSB_cat(tl->fb, ";\n");
1555 13360
}
1556
1557
/*--------------------------------------------------------------------
1558
 */
1559
1560
static void v_matchproto_(sym_expr_t)
1561 1520
vcc_Eval_Regsub(struct vcc *tl, struct expr **e, struct token *t,
1562
    struct symbol *sym, vcc_type_t fmt)
1563
{
1564
        struct expr *e2, *e3;
1565 1520
        int all = sym->eval_priv == NULL ? 0 : 1;
1566
        char buf[128];
1567
1568 1520
        (void)t;
1569 1520
        (void)fmt;
1570 1520
        SkipToken(tl, '(');
1571 1520
        vcc_expr0(tl, &e2, STRING);
1572 1520
        ERRCHK(tl);
1573 1520
        SkipToken(tl, ',');
1574 1520
        vcc_expr0(tl, &e3, REGEX);
1575 1520
        ERRCHK(tl);
1576
1577 1480
        bprintf(buf, "VRT_regsub(ctx, %d,\v+\n\v1,\n\v2", all);
1578 1480
        *e = vcc_expr_edit(tl, STRING, buf, e2, e3);
1579 1480
        SkipToken(tl, ',');
1580 1480
        vcc_expr0(tl, &e2, STRING);
1581 1480
        ERRCHK(tl);
1582 1480
        *e = vcc_expr_edit(tl, STRINGS, "\v1,\n\v2)\v-", *e, e2);
1583 1480
        (*e)->nstr = 1;
1584 1480
        SkipToken(tl, ')');
1585 1520
}
1586
1587
/*--------------------------------------------------------------------
1588
 */
1589
1590
static void v_matchproto_(sym_expr_t)
1591 125840
vcc_Eval_BoolConst(struct vcc *tl, struct expr **e, struct token *t,
1592
    struct symbol *sym, vcc_type_t fmt)
1593
{
1594
1595 125840
        (void)t;
1596 125840
        (void)tl;
1597 125840
        (void)fmt;
1598 125840
        *e = vcc_mk_expr(BOOL, "(0==%d)", sym->eval_priv == NULL ? 1 : 0);
1599 125840
        (*e)->constant = EXPR_CONST;
1600 125840
}
1601
1602
/*--------------------------------------------------------------------
1603
 */
1604
1605
static void v_matchproto_(sym_expr_t)
1606 160
vcc_Eval_Default(struct vcc *tl, struct expr **e, struct token *t,
1607
    struct symbol *sym, vcc_type_t fmt)
1608
{
1609 160
        (void)e;
1610 160
        (void)fmt;
1611 160
        (void)sym;
1612 160
        (void)t;
1613
1614 160
        if (fmt->default_sym == NULL) {
1615 80
                VSB_cat(tl->sb, "Symbol 'default' is a reserved word.\n");
1616 80
                vcc_ErrWhere(tl, t);
1617 80
                return;
1618
        }
1619
1620 80
        *e = vcc_mk_expr(fmt, "%s", fmt->default_sym->rname);
1621 160
}
1622
1623
/*--------------------------------------------------------------------
1624
 */
1625
1626
void
1627 125560
vcc_Expr_Init(struct vcc *tl)
1628
{
1629
        struct symbol *sym;
1630
1631 125560
        sym = VCC_MkSym(tl, "regsub", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1632 125560
        AN(sym);
1633 125560
        sym->type = STRING;
1634 125560
        sym->eval = vcc_Eval_Regsub;
1635 125560
        sym->eval_priv = NULL;
1636
1637 125560
        sym = VCC_MkSym(tl, "regsuball", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1638 125560
        AN(sym);
1639 125560
        sym->type = STRING;
1640 125560
        sym->eval = vcc_Eval_Regsub;
1641 125560
        sym->eval_priv = sym;
1642
1643 125560
        sym = VCC_MkSym(tl, "true", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1644 125560
        AN(sym);
1645 125560
        sym->type = BOOL;
1646 125560
        sym->eval = vcc_Eval_BoolConst;
1647 125560
        sym->eval_priv = sym;
1648
1649 125560
        sym = VCC_MkSym(tl, "false", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1650 125560
        AN(sym);
1651 125560
        sym->type = BOOL;
1652 125560
        sym->eval = vcc_Eval_BoolConst;
1653 125560
        sym->eval_priv = NULL;
1654
1655 125560
        sym = VCC_MkSym(tl, "default", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1656 125560
        AN(sym);
1657 125560
        sym->type = DEFAULT;
1658 125560
        sym->eval = vcc_Eval_Default;
1659 125560
}