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 224480
vcc_isconst(const struct expr *e)
63
{
64 224480
        AN(e->constant);
65 224480
        return (e->constant & EXPR_CONST);
66
}
67
68
static inline int
69 2645960
vcc_islit(const struct expr *e)
70
{
71 2645960
        AN(e->constant);
72 2645960
        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 void vcc_expr0(struct vcc *tl, struct expr **e, vcc_type_t fmt);
84
static void vcc_expr_cor(struct vcc *tl, struct expr **e, vcc_type_t fmt);
85
static void vcc_expr_typecheck(struct vcc *tl, struct expr **e, vcc_type_t fmt,
86
    struct token *t1);
87
88
static struct expr *
89 22252920
vcc_new_expr(vcc_type_t fmt)
90
{
91
        struct expr *e;
92
93 22252920
        ALLOC_OBJ(e, EXPR_MAGIC);
94 22252920
        AN(e);
95 22252920
        e->vsb = VSB_new_auto();
96 22252920
        e->fmt = fmt;
97 22252920
        e->constant = EXPR_VAR;
98 22252920
        return (e);
99
}
100
101
static struct expr * v_printflike_(2, 3)
102 5727920
vcc_mk_expr(vcc_type_t fmt, const char *str, ...)
103
{
104
        va_list ap;
105
        struct expr *e;
106
107 5727920
        e = vcc_new_expr(fmt);
108 5727920
        va_start(ap, str);
109 5727920
        VSB_vprintf(e->vsb, str, ap);
110 5727920
        va_end(ap);
111 5727920
        AZ(VSB_finish(e->vsb));
112 5727920
        return (e);
113
}
114
115
static void
116 28414400
vcc_delete_expr(struct expr *e)
117
{
118 28414400
        if (e == NULL)
119 6195640
                return;
120 22218760
        CHECK_OBJ(e, EXPR_MAGIC);
121 22218760
        VSB_destroy(&e->vsb);
122 22218760
        FREE_OBJ(e);
123 28414400
}
124
125
/*--------------------------------------------------------------------
126
 * We want to get the indentation right in the emitted C code so we have
127
 * to represent it symbolically until we are ready to render.
128
 *
129
 * Many of the operations have very schematic output syntaxes, so we
130
 * use the same facility to simplify the text-processing of emitting
131
 * a given operation on two subexpressions.
132
 *
133
 * We use '\v' as the magic escape character.
134
 *      \v1  insert subexpression 1
135
 *      \v2  insert subexpression 2
136
 *      \vS  insert subexpression 1(STRINGS) as STRING
137
 *      \vs  insert subexpression 2(STRINGS) as STRING
138
 *      \vT  insert subexpression 1(STRINGS) as STRANDS
139
 *      \vt  insert subexpression 2(STRINGS) as STRANDS
140
 *      \v+  increase indentation
141
 *      \v-  decrease indentation
142
 *      anything else is literal
143
 *
144
 * When editing, we check if any of the subexpressions contain a newline
145
 * and issue it as an indented block of so.
146
 *
147
 * XXX: check line lengths in edit, should pass indent in for this
148
 */
149
150
static void
151 1972920
vcc_strands_edit(const struct expr *e1, const struct expr *e2)
152
{
153
154 1972920
        if (e2->nstr == 1) {
155 1745640
                VSB_printf(e1->vsb, "TOSTRAND(%s)", VSB_data(e2->vsb));
156 1745640
                return;
157
        }
158
159 454560
        VSB_printf(e1->vsb, "TOSTRANDS(%d,\v+\n%s\v-)",
160 227280
            e2->nstr, VSB_data(e2->vsb));
161 1972920
}
162
163
static struct expr *
164 12471400
vcc_expr_edit(struct vcc *tl, vcc_type_t fmt, const char *p, struct expr *e1,
165
    struct expr *e2)
166
{
167
        struct expr *e, *e3;
168 12471400
        int nl = 1;
169
170 12471400
        (void) tl;
171
172 12471400
        AN(e1);
173 12471400
        e = vcc_new_expr(fmt);
174 149100640
        while (*p != '\0') {
175 136629240
                if (*p != '\v') {
176 114032920
                        if (*p != '\n' || !nl)
177 114031000
                                VSB_putc(e->vsb, *p);
178 114032920
                        nl = (*p == '\n');
179 114032920
                        p++;
180 114032920
                        continue;
181
                }
182 22596320
                assert(*p == '\v');
183 22596320
                switch (*++p) {
184 1862440
                case '+': VSB_cat(e->vsb, "\v+"); nl = 0; break;
185 1986520
                case '-': VSB_cat(e->vsb, "\v-"); nl = 0; break;
186
                case 'S':
187
                case 's':
188 470840
                        e3 = (*p == 'S' ? e1 : e2);
189 470840
                        AN(e3);
190 470840
                        assert(e1->fmt == STRINGS);
191 470840
                        if (e3->nstr > 1) {
192 1040
                                VSB_cat(e->vsb,
193
                                    "\nVRT_STRANDS_string(ctx,\v+\n");
194 1040
                                vcc_strands_edit(e, e3);
195 1040
                                VSB_cat(e->vsb,
196
                                    "\v-\n)\n");
197 1040
                        } else {
198 469800
                                VSB_cat(e->vsb, VSB_data(e3->vsb));
199
                        }
200 470840
                        break;
201
                case 'T':
202
                case 't':
203 1971880
                        e3 = (*p == 'T' ? e1 : e2);
204 1971880
                        AN(e3);
205 1971880
                        vcc_strands_edit(e, e3);
206 1971880
                        break;
207
                case '1':
208 10029800
                        VSB_cat(e->vsb, VSB_data(e1->vsb));
209 10029800
                        break;
210
                case '2':
211 6274840
                        AN(e2);
212 6274840
                        VSB_cat(e->vsb, VSB_data(e2->vsb));
213 6274840
                        break;
214
                default:
215 0
                        WRONG("Illegal edit in VCC expression");
216 0
                }
217 22596320
                p++;
218
        }
219 12471400
        AZ(VSB_finish(e->vsb));
220 12471400
        e->t1 = e1->t1;
221 12471400
        e->t2 = e1->t2;
222 12471400
        if (e2 != NULL)
223 6275960
                e->t2 = e2->t2;
224 12471400
        vcc_delete_expr(e1);
225 12471400
        vcc_delete_expr(e2);
226 12471400
        return (e);
227
}
228
229
/*--------------------------------------------------------------------
230
 * Expand finished expression into C-source code
231
 */
232
233
static void
234 3471320
vcc_expr_fmt(struct vsb *d, int ind, const struct expr *e1)
235
{
236
        char *p;
237
        int i;
238
239 3471320
        if (!e1->fmt->noindent) {
240 30871920
                for (i = 0; i < ind; i++)
241 27620160
                        VSB_putc(d, ' ');
242 3251760
        }
243 3471320
        p = VSB_data(e1->vsb);
244 341845526
        while (*p != '\0') {
245 338374366
                if (*p == '\n') {
246 10096800
                        VSB_putc(d, '\n');
247 10096800
                        if (*++p == '\0')
248 160
                                break;
249 108495040
                        for (i = 0; i < ind; i++)
250 98398400
                                VSB_putc(d, ' ');
251 338374206
                } else if (*p != '\v') {
252 323848526
                        VSB_putc(d, *p++);
253 323848526
                } else {
254 4429040
                        switch (*++p) {
255 2214520
                        case '+': ind += INDENT; break;
256 2214520
                        case '-': ind -= INDENT; break;
257 0
                        default:  WRONG("Illegal format in VCC expression");
258 0
                        }
259 4429040
                        p++;
260
                }
261
        }
262 3471320
}
263
264
/*--------------------------------------------------------------------
265
 */
266
267
static void
268 2523120
vcc_expr_tobool(struct vcc *tl, struct expr **e)
269
{
270
271 2523120
        if ((*e)->fmt == BOOL)
272 1862640
                return;
273 660480
        if ((*e)->fmt == BACKEND || (*e)->fmt == INT)
274 400
                *e = vcc_expr_edit(tl, BOOL, "(\v1 != 0)", *e, NULL);
275 660080
        else if ((*e)->fmt == DURATION)
276 80
                *e = vcc_expr_edit(tl, BOOL, "(\v1 > 0)", *e, NULL);
277 660000
        else if ((*e)->fmt == STRINGS)
278 659760
                *e = vcc_expr_edit(tl, BOOL, "VRT_Strands2Bool(\vT)", *e, NULL);
279
        /*
280
         * We do not provide automatic folding from REAL to BOOL
281
         * because comparing to zero is seldom an exact science
282
         * and we want to force people to explicitly get it right.
283
         */
284 2523120
}
285
286
/*--------------------------------------------------------------------
287
 */
288
289
static void
290 2145080
vcc_expr_tostring(struct vcc *tl, struct expr **e)
291
{
292
        const char *p;
293 2145080
        uint8_t constant = EXPR_VAR;
294
295 2145080
        CHECK_OBJ_NOTNULL(*e, EXPR_MAGIC);
296 2145080
        assert((*e)->fmt != STRINGS);
297
298 2145080
        p = (*e)->fmt->tostring;
299 2145080
        if (p != NULL) {
300 2145040
                AN(*p);
301 2145040
                *e = vcc_expr_edit(tl, STRINGS, p, *e, NULL);
302 2145040
                (*e)->constant = constant;
303 2145040
                (*e)->nstr = 1;
304 2145040
        } else {
305 80
                VSB_printf(tl->sb,
306
                    "Cannot convert %s to STRING.\n",
307 40
                    vcc_utype((*e)->fmt));
308 40
                vcc_ErrWhere2(tl, (*e)->t1, tl->t);
309
        }
310 2145080
}
311
312
/*--------------------------------------------------------------------
313
 */
314
315
void v_matchproto_(sym_expr_t)
316 16360
vcc_Eval_Handle(struct vcc *tl, struct expr **e, struct token *t,
317
    struct symbol *sym, vcc_type_t type)
318
{
319
320 16360
        (void)t;
321 16360
        (void)tl;
322 16360
        AN(sym->rname);
323 16360
        AZ(type->stringform);
324
325 16560
        if (sym->type->tostring == NULL &&
326 200
            sym->type != STRING && type == STRINGS) {
327 0
                *e = vcc_mk_expr(STRINGS, "\"%s\"", sym->name);
328 0
                (*e)->nstr = 1;
329 0
                (*e)->constant |= EXPR_CONST | EXPR_STR_CONST;
330 0
        } else {
331 16360
                *e = vcc_mk_expr(sym->type, "%s", sym->rname);
332 16360
                (*e)->constant = EXPR_VAR;
333 16360
                (*e)->nstr = 1;
334 16360
                if ((*e)->fmt == STRING)
335 0
                        (*e)->fmt = STRINGS;
336
        }
337 16360
}
338
339
void v_matchproto_(sym_expr_t)
340 920
vcc_Eval_Sub(struct vcc *tl, struct expr **e, struct token *t,
341
    struct symbol *sym, vcc_type_t type)
342
{
343
344 920
        (void)t;
345 920
        (void)tl;
346 920
        AN(sym->rname);
347 920
        AZ(type->stringform);
348
349 920
        assert (sym->type == SUB);
350
351 920
        if (type == SUB) {
352 800
                *e = vcc_mk_expr(sym->type, "%s", sym->rname);
353 800
                (*e)->constant = EXPR_CONST;
354 800
                return;
355
        }
356
357 240
        VSB_printf(tl->sb, "Symbol '%s' can only be used as a %s expression\n",
358 120
            sym->name, sym->type->name);
359 120
        vcc_ErrWhere(tl, tl->t);
360 920
}
361
362
/*--------------------------------------------------------------------
363
 */
364
365
void v_matchproto_(sym_expr_t)
366 4675840
vcc_Eval_Var(struct vcc *tl, struct expr **e, struct token *t,
367
    struct symbol *sym, vcc_type_t type)
368
{
369
370 4675840
        (void)type;
371 4675840
        vcc_AddUses(tl, t, NULL, sym, XREF_READ);
372 4675840
        ERRCHK(tl);
373 4675840
        *e = vcc_mk_expr(sym->type, "%s", sym->rname);
374 4675840
        (*e)->constant = EXPR_VAR;
375 4675840
        (*e)->nstr = 1;
376 4675840
        if ((*e)->fmt == STRING)
377 2208080
                (*e)->fmt = STRINGS;
378 4675840
}
379
380
void v_matchproto_(sym_expr_t)
381 400
vcc_Eval_ProtectedHeader(struct vcc *tl, struct expr **e, struct token *t,
382
    struct symbol *sym, vcc_type_t type)
383
{
384
385 400
        AN(sym);
386 400
        AZ(sym->lorev);
387
388 400
        vcc_Header_Fh(tl, sym);
389 400
        sym->eval = vcc_Eval_Var;
390 400
        vcc_Eval_Var(tl, e, t, sym, type);
391 400
}
392
393
/*--------------------------------------------------------------------
394
 */
395
396
static struct expr *
397 6880
vcc_priv_arg(struct vcc *tl, const char *p, struct symbol *sym)
398
{
399
        char buf[64];
400
        struct inifin *ifp;
401 6880
        const char *f = NULL;
402
403 6880
        AN(sym);
404 6880
        AN(sym->vmod_name);
405
406 6880
        if (!strcmp(p, "PRIV_VCL"))
407 600
                return (vcc_mk_expr(VOID, "&vmod_priv_%s", sym->vmod_name));
408
409 6280
        if (!strcmp(p, "PRIV_CALL")) {
410 880
                bprintf(buf, "vmod_priv_%u", tl->unique++);
411 880
                ifp = New_IniFin(tl);
412 880
                Fh(tl, 0, "static struct vmod_priv %s;\n", buf);
413 880
                VSB_printf(ifp->fin, "\tVRT_priv_fini(ctx, &%s);", buf);
414 880
                return (vcc_mk_expr(VOID, "&%s", buf));
415
        }
416
417 5400
        if (!strcmp(p, "PRIV_TASK"))
418 5080
                f = "task";
419 320
        else if (!strcmp(p, "PRIV_TOP")) {
420 320
                f = "top";
421 320
                sym->r_methods &= VCL_MET_TASK_C;
422 320
        } else {
423 0
                WRONG("Wrong PRIV_ type");
424
        }
425 5400
        AN(f);
426
427 5400
        return (vcc_mk_expr(VOID, "VRT_priv_%s(ctx, &VGC_vmod_%s)",
428 5400
            f, sym->vmod_name));
429 6880
}
430
431
struct func_arg {
432
        vcc_type_t              type;
433
        const struct vjsn_val   *enums;
434
        const char              *cname;
435
        const char              *name;
436
        const char              *val;
437
        struct expr             *result;
438
        int                     avail;
439
        int                     optional;
440
        VTAILQ_ENTRY(func_arg)  list;
441
};
442
443
static void
444 72360
vcc_do_enum(struct vcc *tl, struct func_arg *fa, int len, const char *ptr)
445
{
446
        const char *r;
447
448 72360
        (void)tl;
449 72360
        r = strchr(fa->cname, '.');
450 72360
        AN(r);
451 72360
        fa->result = vcc_mk_expr(VOID, "*%.*s.enum_%.*s",
452 72360
            (int)(r - fa->cname), fa->cname, len, ptr);
453 72360
}
454
455
static void
456 157440
vcc_do_arg(struct vcc *tl, struct func_arg *fa)
457
{
458
        struct expr *e2;
459
        struct vjsn_val *vv;
460
461 157440
        if (fa->type == ENUM) {
462 53160
                ExpectErr(tl, ID);
463 53160
                ERRCHK(tl);
464 182000
                VTAILQ_FOREACH(vv, &fa->enums->children, list)
465 181920
                        if (vcc_IdIs(tl->t, vv->value))
466 53080
                                break;
467 53160
                if (vv == NULL) {
468 80
                        VSB_cat(tl->sb, "Wrong enum value.");
469 80
                        VSB_cat(tl->sb, "  Expected one of:\n");
470 400
                        VTAILQ_FOREACH(vv, &fa->enums->children, list)
471 320
                                VSB_printf(tl->sb, "\t%s\n", vv->value);
472 80
                        vcc_ErrWhere(tl, tl->t);
473 80
                        return;
474
                }
475 53080
                vcc_do_enum(tl, fa, PF(tl->t));
476 53080
                SkipToken(tl, ID);
477 53080
        } else {
478 104280
                if (fa->type == SUB)
479 800
                        tl->subref++;
480 104280
                vcc_expr0(tl, &e2, fa->type);
481 104280
                ERRCHK(tl);
482 103960
                assert(e2->fmt == fa->type);
483 103960
                fa->result = e2;
484
        }
485 157040
        fa->avail = 1;
486 157440
}
487
488
static void
489 108800
vcc_func(struct vcc *tl, struct expr **e, const void *priv,
490
    const char *extra, struct symbol *sym)
491
{
492
        vcc_type_t rfmt;
493
        const char *cfunc;
494
        struct expr *e1;
495
        struct func_arg *fa, *fa2;
496
        VTAILQ_HEAD(,func_arg) head;
497
        struct token *tf, *t1;
498
        const struct vjsn_val *vv, *vvp;
499
        const char *sa, *extra_sep;
500
        char ssa[64];
501
        int n;
502
503 108800
        CAST_OBJ_NOTNULL(vv, priv, VJSN_VAL_MAGIC);
504 108800
        assert(vjsn_is_array(vv));
505 108800
        vv = VTAILQ_FIRST(&vv->children);
506 108800
        rfmt = VCC_Type(VTAILQ_FIRST(&vv->children)->value);
507 108800
        AN(rfmt);
508 108800
        vv = VTAILQ_NEXT(vv, list);
509 108800
        cfunc = vv->value;
510 108800
        vv = VTAILQ_NEXT(vv, list);
511 108800
        sa = vv->value;
512 108800
        if (*sa == '\0') {
513 92720
                sa = NULL;
514 92720
        }
515 108800
        vv = VTAILQ_NEXT(vv, list);
516 108800
        if (sym->kind == SYM_METHOD) {
517 30960
                if (*e == NULL) {
518 80
                        VSB_cat(tl->sb, "Syntax error.");
519 80
                        tl->err = 1;
520 80
                        return;
521
                }
522 30880
                vcc_NextToken(tl);
523 30880
                AZ(extra);
524 30880
                AN((*e)->instance);
525 30880
                extra = (*e)->instance->rname;
526 30880
        }
527 108720
        tf = VTAILQ_PREV(tl->t, tokenhead, list);
528 108720
        SkipToken(tl, '(');
529 108720
        if (extra == NULL) {
530 69800
                extra = "";
531 69800
                extra_sep = "";
532 69800
        } else {
533 38920
                AN(*extra);
534 38920
                extra_sep = ", ";
535
        }
536 108720
        VTAILQ_INIT(&head);
537 365080
        for (;vv != NULL; vv = VTAILQ_NEXT(vv, list)) {
538 256360
                assert(vjsn_is_array(vv));
539 256360
                fa = calloc(1, sizeof *fa);
540 256360
                AN(fa);
541 256360
                fa->cname = cfunc;
542 256360
                VTAILQ_INSERT_TAIL(&head, fa, list);
543
544 256360
                vvp = VTAILQ_FIRST(&vv->children);
545 256360
                if (!memcmp(vvp->value, "PRIV_", 5)) {
546 6880
                        fa->result = vcc_priv_arg(tl, vvp->value, sym);
547 6880
                        vvp = VTAILQ_NEXT(vvp, list);
548 6880
                        if (vvp != NULL)
549 120
                                fa->name = vvp->value;
550 6880
                        continue;
551
                }
552 249480
                fa->type = VCC_Type(vvp->value);
553 249480
                AN(fa->type);
554 249480
                vvp = VTAILQ_NEXT(vvp, list);
555 249480
                if (vvp != NULL) {
556 233760
                        fa->name = vvp->value;
557 233760
                        vvp = VTAILQ_NEXT(vvp, list);
558 233760
                        if (vvp != NULL) {
559 171960
                                fa->val = vvp->value;
560 171960
                                vvp = VTAILQ_NEXT(vvp, list);
561 171960
                                if (vvp != NULL) {
562 140080
                                        fa->enums = vvp;
563 140080
                                        vvp = VTAILQ_NEXT(vvp, list);
564 140080
                                }
565 171960
                        }
566 233760
                }
567 249480
                if (sa != NULL && vvp != NULL && vjsn_is_true(vvp)) {
568 72640
                        fa->optional = 1;
569 72640
                        vvp = VTAILQ_NEXT(vvp, list);
570 72640
                }
571 249480
                AZ(vvp);
572 249480
        }
573
574 175600
        VTAILQ_FOREACH(fa, &head, list) {
575 157440
                if (tl->t->tok == ')')
576 3520
                        break;
577 153920
                if (fa->result != NULL)
578 4920
                        continue;
579 149000
                if (tl->t->tok == ID) {
580 109640
                        t1 = VTAILQ_NEXT(tl->t, list);
581 109640
                        if (t1->tok == '=')
582 30000
                                break;
583 79640
                }
584 119000
                vcc_do_arg(tl, fa);
585 119000
                if (tl->err)
586 800
                        VSB_printf(tl->sb, "Expected argument: %s %s\n\n",
587 400
                            fa->type->name,
588 400
                            fa->name ? fa->name : "(unnamed argument)");
589 119000
                ERRCHK(tl);
590 118600
                if (tl->t->tok == ')')
591 56640
                        break;
592 61960
                SkipToken(tl, ',');
593 61960
        }
594 116840
        while (tl->t->tok == ID) {
595 125120
                VTAILQ_FOREACH(fa, &head, list) {
596 125080
                        if (fa->name == NULL)
597 480
                                continue;
598 124600
                        if (vcc_IdIs(tl->t, fa->name))
599 38480
                                break;
600 86120
                }
601 38520
                if (fa == NULL) {
602 80
                        VSB_printf(tl->sb, "Unknown argument '%.*s'\n",
603 40
                            PF(tl->t));
604 40
                        vcc_ErrWhere(tl, tl->t);
605 40
                        return;
606
                }
607 38480
                if (fa->result != NULL) {
608 40
                        AN(fa->name);
609 80
                        VSB_printf(tl->sb, "Argument '%s' already used\n",
610 40
                            fa->name);
611 40
                        vcc_ErrWhere(tl, tl->t);
612 40
                        return;
613
                }
614 38440
                vcc_NextToken(tl);
615 38440
                SkipToken(tl, '=');
616 38440
                vcc_do_arg(tl, fa);
617 38440
                ERRCHK(tl);
618 38440
                if (tl->t->tok == ')')
619 29920
                        break;
620 8520
                SkipToken(tl, ',');
621
        }
622
623 108240
        if (sa != NULL)
624 31840
                e1 = vcc_mk_expr(rfmt, "%s(ctx%s%s,\v+\n&(%s)\v+ {\n",
625 15920
                    cfunc, extra_sep, extra, sa);
626
        else
627 184640
                e1 = vcc_mk_expr(rfmt, "%s(ctx%s%s\v+",
628 92320
                    cfunc, extra_sep, extra);
629 108240
        n = 0;
630 363280
        VTAILQ_FOREACH_SAFE(fa, &head, list, fa2) {
631 255040
                n++;
632 255040
                if (fa->optional) {
633 72400
                        AN(fa->name);
634 72400
                        bprintf(ssa, "\v1.valid_%s = %d,\n",
635
                            fa->name, fa->avail);
636 72400
                        e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, NULL);
637 72400
                }
638 255040
                if (fa->result == NULL && fa->type == ENUM && fa->val != NULL)
639 19280
                        vcc_do_enum(tl, fa, strlen(fa->val), fa->val);
640 255040
                if (fa->result == NULL && fa->val != NULL)
641 23440
                        fa->result = vcc_mk_expr(fa->type, "%s", fa->val);
642 255040
                if (fa->result != NULL && sa != NULL) {
643 34600
                        if (fa->name)
644 33760
                                bprintf(ssa, "\v1.%s = \v2,\n", fa->name);
645
                        else
646 840
                                bprintf(ssa, "\v1.arg%d = \v2,\n", n);
647 34600
                        e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, fa->result);
648 255040
                } else if (fa->result != NULL) {
649 343680
                        e1 = vcc_expr_edit(tl, e1->fmt, "\v1,\n\v2",
650 171840
                            e1, fa->result);
651 220440
                } else if (!fa->optional) {
652 40
                        if (fa->name)
653 80
                                VSB_printf(tl->sb, "Argument '%s' missing\n",
654 40
                                    fa->name);
655
                        else
656 0
                                VSB_printf(tl->sb, "Argument %d missing\n", n);
657 40
                        vcc_ErrWhere(tl, tl->t);
658 40
                }
659 255040
                free(fa);
660 255040
        }
661 108240
        if (sa != NULL) {
662 15920
                *e = vcc_expr_edit(tl, e1->fmt, "\v1\v-\n}\v-\n)", e1, NULL);
663 15920
        } else {
664 92320
                *e = vcc_expr_edit(tl, e1->fmt, "\v1\v-\n)", e1, NULL);
665
        }
666 108240
        SkipToken(tl, ')');
667 108200
        vcc_AddUses(tl, tf, NULL, sym, XREF_READ);
668 108800
}
669
670
671
/*--------------------------------------------------------------------
672
 */
673
674
void
675 8040
vcc_Eval_Func(struct vcc *tl, const struct vjsn_val *spec,
676
    const char *extra, struct symbol *sym)
677
{
678 8040
        struct expr *e = NULL;
679
680 8040
        vcc_func(tl, &e, spec, extra, sym);
681 8040
        if (tl->err)
682 0
                VSB_cat(tl->sb, "While compiling function call:\n");
683 8040
        ERRCHK(tl);
684 8040
        vcc_expr_fmt(tl->fb, tl->indent, e);
685 8040
        VSB_cat(tl->fb, ";\n");
686 8040
        vcc_delete_expr(e);
687 8040
}
688
689
/*--------------------------------------------------------------------
690
 */
691
692
void v_matchproto_(sym_expr_t)
693 82560
vcc_Eval_SymFunc(struct vcc *tl, struct expr **e, struct token *t,
694
    struct symbol *sym, vcc_type_t fmt)
695
{
696
697 82560
        (void)t;
698 82560
        (void)fmt;
699 82560
        assert(sym->kind == SYM_FUNC || sym->kind == SYM_METHOD);
700 82560
        AN(sym->eval_priv);
701
702 82560
        vcc_func(tl, e, sym->eval_priv, sym->extra, sym);
703 82560
        ERRCHK(tl);
704 82160
        if ((*e)->fmt == STRING) {
705 29960
                (*e)->fmt = STRINGS;
706 29960
                (*e)->nstr = 1;
707 29960
        }
708 82560
}
709
710
/*--------------------------------------------------------------------
711
 */
712
713
static void
714 703800
vcc_number(struct vcc *tl, struct expr **e, vcc_type_t fmt, const char *sign)
715
{
716
        VCL_INT vi;
717
        struct expr *e1;
718
        struct token *t;
719
720 703800
        assert(fmt != VOID);
721 703800
        if (fmt == BYTES) {
722 1880
                vcc_ByteVal(tl, &vi);
723 1880
                ERRCHK(tl);
724 1800
                e1 = vcc_mk_expr(BYTES, "%ju", (intmax_t)vi);
725 1800
        } else {
726 701920
                t = tl->t;
727 701920
                vcc_NextToken(tl);
728 701920
                if (tl->t->tok == ID) {
729 228040
                        e1 = vcc_mk_expr(DURATION, "%s%.3f * %g",
730 228040
                            sign, t->num, vcc_DurationUnit(tl));
731 228040
                        ERRCHK(tl);
732 701880
                } else if (fmt == REAL || t->tok == FNUM) {
733 6160
                        e1 = vcc_mk_expr(REAL, "%s%.3f", sign, t->num);
734 6160
                } else {
735 467720
                        e1 = vcc_mk_expr(INT, "%s%.0f", sign, t->num);
736
                }
737
        }
738 703680
        e1->constant = EXPR_CONST;
739 703680
        *e = e1;
740 703800
}
741
742
/*--------------------------------------------------------------------
743
 * SYNTAX:
744
 *    Expr5:
745
 *      '(' ExprCor ')'
746
 *      symbol
747
 *      CNUM
748
 *      FNUM
749
 *      CSTR
750
 *      CBLOB
751
 */
752
753
static void
754 9736320
vcc_expr5(struct vcc *tl, struct expr **e, vcc_type_t fmt)
755
{
756
        struct expr *e1, *e2;
757
        const char *ip, *sign;
758
        struct token *t, *t1;
759
        struct symbol *sym;
760
761 9736320
        sign = "";
762 9736320
        *e = NULL;
763 9736320
        if (tl->t->tok == '(') {
764 110880
                SkipToken(tl, '(');
765 110880
                vcc_expr_cor(tl, &e2, fmt);
766 110880
                ERRCHK(tl);
767 110880
                SkipToken(tl, ')');
768 110880
                if (e2->fmt == STRINGS)
769 240
                        *e = e2;
770
                else
771 110640
                        *e = vcc_expr_edit(tl, e2->fmt, "(\v1)", e2, NULL);
772 110880
                return;
773
        }
774 9625440
        switch (tl->t->tok) {
775
        case ID:
776 4897280
                t = tl->t;
777 4897280
                t1 = vcc_PeekToken(tl);
778 4897280
                AN(t1);
779 4897280
                sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
780
                    SYMTAB_PARTIAL_NOERR, XREF_REF);
781 4897280
                if (sym == NULL && fmt->global_pfx != NULL && t1->tok != '.') {
782 360
                        sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
783
                            SYMTAB_CREATE, XREF_REF);
784 360
                        ERRCHK(tl);
785 280
                        AN(sym);
786 280
                        VCC_GlobalSymbol(sym, fmt);
787 280
                }
788 4897200
                ERRCHK(tl);
789 4897200
                if (sym == NULL)
790 480
                        AZ(VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
791
                            SYMTAB_PARTIAL, XREF_REF));
792 4897200
                ERRCHK(tl);
793 4896720
                AN(sym);
794 4896720
                if (sym->kind == SYM_INSTANCE) {
795 30960
                        AZ(*e);
796 30960
                        *e = vcc_new_expr(sym->type);
797 30960
                        (*e)->instance = sym;
798 30960
                        return;
799
                }
800 4865760
                if (sym->kind == SYM_FUNC && sym->type == VOID) {
801 40
                        VSB_cat(tl->sb, "Function returns VOID:\n");
802 40
                        vcc_ErrWhere(tl, tl->t);
803 40
                        return;
804
                }
805 4865720
                if (sym->eval != NULL) {
806 4865600
                        AN(sym->eval);
807 4865600
                        AZ(*e);
808 4865600
                        sym->eval(tl, e, t, sym, fmt);
809 4865600
                        if (tl->err) {
810 640
                                VSB_cat(tl->sb,
811
                                    "While compiling function call:\n\n");
812 640
                                vcc_ErrWhere2(tl, t, tl->t);
813 640
                        }
814 4865600
                        ERRCHK(tl);
815
                        /* Unless asked for a HEADER, fold to string here */
816 4864960
                        if (*e && fmt != HEADER && (*e)->fmt == HEADER) {
817 1352200
                                vcc_expr_tostring(tl, e);
818 1352200
                                ERRCHK(tl);
819 1352200
                        }
820 4864960
                        return;
821
                }
822 240
                VSB_printf(tl->sb,
823
                    "Symbol '%.*s' type (%s) can not be used in expression.\n",
824 120
                    PF(t), sym->kind->name);
825 120
                vcc_ErrWhere(tl, t);
826 120
                if (sym->def_b != NULL) {
827 40
                        VSB_cat(tl->sb, "That symbol was defined here:\n");
828 40
                        vcc_ErrWhere(tl, sym->def_b);
829 40
                }
830 120
                return;
831
        case CSTR:
832 4023760
                assert(fmt != VOID);
833 4023760
                if (fmt == IP) {
834 1200
                        if (*tl->t->dec == '/') {
835
                                /*
836
                                 * On some platforms (e.g. FreeBSD),
837
                                 * getaddrinfo(3) may resolve a path to a
838
                                 * sockaddr_un if it happens to exist and
839
                                 * is a socket. So don't let that happen.
840
                                 */
841 40
                                VSB_cat(tl->sb,
842
                                    "Cannot convert to an IP address: ");
843 40
                                vcc_ErrToken(tl, tl->t);
844 40
                                vcc_ErrWhere(tl, tl->t);
845 40
                                return;
846
                        }
847 2320
                        Resolve_Sockaddr(tl, tl->t->dec, "80",
848
                            &ip, NULL, &ip, NULL, NULL, 1,
849 1160
                            tl->t, "IP constant");
850 1160
                        ERRCHK(tl);
851 1040
                        e1 = vcc_mk_expr(IP, "%s", ip);
852 1040
                        ERRCHK(tl);
853 4023600
                } else if (fmt == REGEX) {
854 333280
                        e1 = vcc_new_expr(REGEX);
855 333280
                        vcc_regexp(tl, e1->vsb);
856 333280
                        AZ(VSB_finish(e1->vsb));
857 333280
                } else {
858 3689280
                        e1 = vcc_new_expr(STRINGS);
859 3689280
                        EncToken(e1->vsb, tl->t);
860 3689280
                        AZ(VSB_finish(e1->vsb));
861 3689280
                        e1->constant |= EXPR_STR_CONST;
862 3689280
                        e1->nstr = 1;
863
                }
864 4023600
                e1->t1 = tl->t;
865 4023600
                e1->constant |= EXPR_CONST;
866 4023600
                vcc_NextToken(tl);
867 4023600
                *e = e1;
868 4023600
                return;
869
        case '-':
870 2480
                if (fmt != INT &&
871 640
                    fmt != REAL &&
872 160
                    fmt != DURATION &&
873 40
                    fmt != STRINGS)
874 0
                        break;
875 2440
                vcc_NextToken(tl);
876 2440
                if (tl->t->tok != FNUM && tl->t->tok != CNUM) {
877 360
                        vcc_expr_cor(tl, &e1, fmt);
878 360
                        ERRCHK(tl);
879 360
                        *e = vcc_expr_edit(tl, e1->fmt, "-(\v1)", e1, NULL);
880 360
                        return;
881
                }
882 2080
                sign = "-";
883
                /* FALLTHROUGH */
884
        case FNUM:
885
        case CNUM:
886 703800
                vcc_number(tl, e, fmt, sign);
887 703800
                return;
888
        case CBLOB:
889 80
                e1 = vcc_new_expr(BLOB);
890 80
                VSB_printf(e1->vsb, "%s", tl->t->dec);
891 80
                AZ(VSB_finish(e1->vsb));
892 80
                e1->constant |= EXPR_STR_CONST;
893 80
                e1->t1 = tl->t;
894 80
                vcc_NextToken(tl);
895 80
                *e = e1;
896 80
                return;
897
        default:
898 160
                break;
899
        }
900 160
        VSB_cat(tl->sb, "Unknown token ");
901 160
        vcc_ErrToken(tl, tl->t);
902 160
        VSB_printf(tl->sb, " when looking for %s\n\n", vcc_utype(fmt));
903 160
        vcc_ErrWhere(tl, tl->t);
904 9736320
}
905
906
/*--------------------------------------------------------------------
907
 * SYNTAX:
908
 *    Expr4:
909
 *      Expr5 [ '.' (type_attribute | type_method()) ]*
910
 */
911
912
void
913 110200
vcc_Eval_TypeMethod(struct vcc *tl, struct expr **e, struct token *t,
914
    struct symbol *sym, vcc_type_t fmt)
915
{
916
        const char *impl;
917
918 110200
        (void)t;
919 110200
        impl = VCC_Type_EvalMethod(tl, sym);
920 110200
        ERRCHK(tl);
921 110200
        AN(impl);
922 110200
        *e = vcc_expr_edit(tl, fmt, impl, *e, NULL);
923 110200
}
924
925
static void
926 9736320
vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt)
927
{
928
        struct symbol *sym;
929
930 9736320
        *e = NULL;
931 9736320
        vcc_expr5(tl, e, fmt);
932 9736320
        ERRCHK(tl);
933 9734400
        AN(*e);
934 9875480
        while (tl->t->tok == '.') {
935 141200
                vcc_NextToken(tl);
936 141200
                ExpectErr(tl, ID);
937
938 141160
                sym = VCC_TypeSymbol(tl, SYM_METHOD, (*e)->fmt);
939 141160
                if (sym == NULL) {
940 80
                        VSB_cat(tl->sb, "Unknown property ");
941 80
                        vcc_ErrToken(tl, tl->t);
942 80
                        VSB_printf(tl->sb, " for type %s\n", (*e)->fmt->name);
943 80
                        vcc_ErrWhere(tl, tl->t);
944 80
                        return;
945
                }
946
947 141080
                AN(sym->eval);
948 141080
                sym->eval(tl, e, tl->t, sym, sym->type);
949 141080
                ERRCHK(tl);
950 141080
                if ((*e)->fmt == STRING) {
951 109760
                        (*e)->fmt = STRINGS;
952 109760
                        (*e)->nstr = 1;
953 109760
                }
954
        }
955 9736320
}
956
957
/*--------------------------------------------------------------------
958
 * SYNTAX:
959
 *    ExprMul:
960
 *      Expr4 { {'*'|'/'|'%'} Expr4 } *
961
 */
962
963
static void
964 9388280
vcc_expr_mul(struct vcc *tl, struct expr **e, vcc_type_t fmt)
965
{
966
        struct expr *e2;
967
        vcc_type_t f2;
968
        struct token *tk;
969
        char buf[24];
970
971 9388280
        *e = NULL;
972 9388280
        vcc_expr4(tl, e, fmt);
973 9388280
        ERRCHK(tl);
974 9386520
        AN(*e);
975
976 9387960
        while (tl->t->tok == '*' || tl->t->tok == '/' || tl->t->tok == '%') {
977 1600
                if (tl->t->tok == '%' && ((*e)->fmt != INT)) {
978 40
                        VSB_cat(tl->sb, "Operator % only possible on INT.\n");
979 40
                        vcc_ErrWhere(tl, tl->t);
980 40
                        return;
981
                }
982 1560
                f2 = (*e)->fmt->multype;
983 1560
                if (f2 == NULL) {
984 80
                        VSB_printf(tl->sb,
985
                            "Operator %.*s not possible on type %s.\n",
986 40
                            PF(tl->t), vcc_utype((*e)->fmt));
987 40
                        vcc_ErrWhere(tl, tl->t);
988 40
                        return;
989
                }
990 1520
                tk = tl->t;
991 1520
                vcc_NextToken(tl);
992 1520
                vcc_expr4(tl, &e2, f2);
993 1520
                ERRCHK(tl);
994 1520
                if (e2->fmt != INT && e2->fmt != f2) {
995 160
                        VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
996 80
                            vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
997 80
                        vcc_ErrWhere(tl, tk);
998 80
                        return;
999
                }
1000 1440
                bprintf(buf, "(\v1%c\v2)", tk->tok);
1001 1440
                *e = vcc_expr_edit(tl, (*e)->fmt, buf, *e, e2);
1002
        }
1003 9388280
}
1004
1005
/*--------------------------------------------------------------------
1006
 * SYNTAX:
1007
 *    ExprAdd:
1008
 *      ExprMul { {'+'|'-'} ExprMul } *
1009
 */
1010
1011
static const struct adds {
1012
        unsigned        op;
1013
        vcc_type_t      a;
1014
        vcc_type_t      b;
1015
        vcc_type_t      fmt;
1016
} vcc_adds[] = {
1017
        { '+', BYTES,           BYTES,          BYTES },
1018
        { '-', BYTES,           BYTES,          BYTES },
1019
        { '+', DURATION,        DURATION,       DURATION },
1020
        { '-', DURATION,        DURATION,       DURATION },
1021
        { '+', INT,             INT,            INT },
1022
        { '-', INT,             INT,            INT },
1023
        { '+', INT,             REAL,           REAL },
1024
        { '-', INT,             REAL,           REAL },
1025
        { '+', REAL,            INT,            REAL },
1026
        { '-', REAL,            INT,            REAL },
1027
        { '+', REAL,            REAL,           REAL },
1028
        { '-', REAL,            REAL,           REAL },
1029
        { '-', TIME,            TIME,           DURATION },
1030
        { '+', TIME,            DURATION,       TIME },
1031
        { '-', TIME,            DURATION,       TIME },
1032
1033
        { EOI, VOID,            VOID,           VOID }
1034
};
1035
1036
static void
1037 6741280
vcc_expr_add(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1038
{
1039
        const struct adds *ap;
1040
        struct expr  *e2;
1041
        struct token *tk;
1042
        int lit, n;
1043
1044 6741280
        *e = NULL;
1045 6741280
        vcc_expr_mul(tl, e, fmt);
1046 6741280
        ERRCHK(tl);
1047
1048 9385920
        while (tl->t->tok == '+' || tl->t->tok == '-') {
1049 2647000
                tk = tl->t;
1050 42322680
                for (ap = vcc_adds; ap->op != EOI; ap++)
1051 39678600
                        if (tk->tok == ap->op && (*e)->fmt == ap->a)
1052 2920
                                break;
1053 2647000
                vcc_NextToken(tl);
1054 2647000
                if (ap->op == EOI && fmt == STRINGS)
1055 20080
                        vcc_expr_mul(tl, &e2, STRINGS);
1056
                else
1057 2626920
                        vcc_expr_mul(tl, &e2, (*e)->fmt);
1058 2647000
                ERRCHK(tl);
1059
1060 42327560
                for (ap = vcc_adds; ap->op != EOI; ap++)
1061 39683080
                        if (tk->tok == ap->op && (*e)->fmt == ap->a &&
1062 39683080
                            e2->fmt == ap->b)
1063 2520
                                break;
1064
1065 2647000
                if (ap->op == '+') {
1066 1760
                        *e = vcc_expr_edit(tl, ap->fmt, "(\v1 + \v2)", *e, e2);
1067 2647000
                } else if (ap->op == '-') {
1068 760
                        *e = vcc_expr_edit(tl, ap->fmt, "(\v1 - \v2)", *e, e2);
1069 2645840
                } else if (tk->tok == '+' &&
1070 2644440
                    ((*e)->fmt == STRINGS || fmt == STRINGS)) {
1071 2644040
                        if ((*e)->fmt != STRINGS)
1072 200
                                vcc_expr_tostring(tl, e);
1073 2644040
                        if (e2->fmt != STRINGS)
1074 658160
                                vcc_expr_tostring(tl, &e2);
1075 2644040
                        if (vcc_islit(*e) && vcc_isconst(e2)) {
1076 1920
                                lit = vcc_islit(e2);
1077 3840
                                *e = vcc_expr_edit(tl, STRINGS,
1078 1920
                                    "\v1\n\v2", *e, e2);
1079 1920
                                (*e)->constant = EXPR_CONST;
1080 1920
                                (*e)->nstr = 1;
1081 1920
                                if (lit)
1082 1920
                                        (*e)->constant |= EXPR_STR_CONST;
1083 1920
                        } else {
1084 2642120
                                n = (*e)->nstr + e2->nstr;
1085 5284240
                                *e = vcc_expr_edit(tl, STRINGS,
1086 2642120
                                    "\v1,\n\v2", *e, e2);
1087 2642120
                                (*e)->constant = EXPR_VAR;
1088 2642120
                                (*e)->nstr = n;
1089
                        }
1090 2644040
                } else {
1091 880
                        VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
1092 440
                            vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1093 440
                        vcc_ErrWhere2(tl, tk, tl->t);
1094 440
                        return;
1095
                }
1096
        }
1097
1098
        /* No concatenation, finalize string. */
1099 6738920
        if ((*e)->fmt->stringform)
1100 240
                vcc_expr_tostring(tl, e);
1101 6741280
}
1102
1103
/*--------------------------------------------------------------------
1104
 * SYNTAX:
1105
 *    ExprCmp:
1106
 *      ExprAdd
1107
 *      ExprAdd Relation ExprAdd
1108
 *      ExprAdd(STRING) '~' CString
1109
 *      ExprAdd(STRING) '!~' CString
1110
 *      ExprAdd(IP) '==' ExprAdd(IP)
1111
 *      ExprAdd(IP) '!=' ExprAdd(IP)
1112
 *      ExprAdd(IP) '~' ACL
1113
 *      ExprAdd(IP) '!~' ACL
1114
 */
1115
1116
struct cmps;
1117
1118
typedef void cmp_f(struct vcc *, struct expr **, const struct cmps *);
1119
1120
struct cmps {
1121
        vcc_type_t              fmt;
1122
        unsigned                token;
1123
        cmp_f                   *func;
1124
        const char              *emit;
1125
};
1126
1127
static void v_matchproto_(cmp_f)
1128 224160
cmp_simple(struct vcc *tl, struct expr **e, const struct cmps *cp)
1129
{
1130
        struct expr *e2;
1131
        struct token *tk;
1132
1133 224160
        tk = tl->t;
1134 224160
        vcc_NextToken(tl);
1135 224160
        vcc_expr_add(tl, &e2, (*e)->fmt);
1136 224160
        ERRCHK(tl);
1137
1138 224040
        if (e2->fmt != (*e)->fmt) {
1139 160
                VSB_printf(tl->sb,
1140
                    "Comparison of different types: %s '%.*s' %s\n",
1141 80
                    vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1142 80
                vcc_ErrWhere(tl, tk);
1143 80
        } else
1144 223960
                *e = vcc_expr_edit(tl, BOOL, cp->emit, *e, e2);
1145 224160
}
1146
1147
static void v_matchproto_(cmp_f)
1148 331480
cmp_regexp(struct vcc *tl, struct expr **e, const struct cmps *cp)
1149
{
1150
        struct token *t1;
1151
        struct expr *e2;
1152
        char buf[128];
1153
1154 331480
        *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
1155 331480
        vcc_NextToken(tl);
1156 331480
        t1 = tl->t;
1157 331480
        vcc_expr4(tl, &e2, REGEX);
1158 331480
        ERRCHK(tl);
1159 331320
        vcc_expr_typecheck(tl, &e2, REGEX, t1);
1160 331320
        ERRCHK(tl);
1161 331280
        bprintf(buf, "%sVRT_re_match(ctx, \v1, \v2)", cp->emit);
1162 331280
        *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1163 331480
}
1164
1165
static void v_matchproto_(cmp_f)
1166 1720
cmp_acl(struct vcc *tl, struct expr **e, const struct cmps *cp)
1167
{
1168
        struct token *t1;
1169
        struct expr *e2;
1170
        char buf[256];
1171
1172 1720
        vcc_NextToken(tl);
1173 1720
        t1 = tl->t;
1174 1720
        vcc_expr4(tl, &e2, ACL);
1175 1720
        ERRCHK(tl);
1176 1600
        vcc_expr_typecheck(tl, &e2, ACL, t1);
1177 1600
        ERRCHK(tl);
1178 1480
        bprintf(buf, "%sVRT_acl_match(ctx, \v1, \v2)", cp->emit);
1179 1480
        *e = vcc_expr_edit(tl, BOOL, buf, e2, *e);
1180 1720
}
1181
1182
static void v_matchproto_(cmp_f)
1183 1549080
cmp_string(struct vcc *tl, struct expr **e, const struct cmps *cp)
1184
{
1185
        struct expr *e2;
1186
        struct token *tk;
1187
        char buf[128];
1188
1189 1549080
        tk = tl->t;
1190 1549080
        vcc_NextToken(tl);
1191 1549080
        vcc_expr_add(tl, &e2, STRINGS);
1192 1549080
        ERRCHK(tl);
1193 1549080
        if (e2->fmt != STRINGS) {
1194 240
                VSB_printf(tl->sb,
1195
                    "Comparison of different types: %s '%.*s' %s\n",
1196 120
                    vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1197 120
                vcc_ErrWhere(tl, tk);
1198 1549080
        } else if ((*e)->nstr == 1 && e2->nstr == 1) {
1199 1547840
                bprintf(buf, "(%s VRT_strcmp(\v1, \v2))", cp->emit);
1200 1547840
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1201 1547840
        } else {
1202 1120
                bprintf(buf, "(%s VRT_CompareStrands(\vT, \vt))", cp->emit);
1203 1120
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1204
        }
1205 1549080
}
1206
1207
#define IDENT_REL(typ)                                                  \
1208
        {typ,           T_EQ,           cmp_simple, "(\v1 == \v2)" },   \
1209
        {typ,           T_NEQ,          cmp_simple, "(\v1 != \v2)" }
1210
1211
#define NUM_REL(typ)                                                    \
1212
        IDENT_REL(typ),                                                 \
1213
        {typ,           T_LEQ,          cmp_simple, "(\v1 <= \v2)" },   \
1214
        {typ,           T_GEQ,          cmp_simple, "(\v1 >= \v2)" },   \
1215
        {typ,           '<',            cmp_simple, "(\v1 < \v2)" },    \
1216
        {typ,           '>',            cmp_simple, "(\v1 > \v2)" }
1217
1218
static const struct cmps vcc_cmps[] = {
1219
        NUM_REL(INT),
1220
        NUM_REL(DURATION),
1221
        NUM_REL(BYTES),
1222
        NUM_REL(REAL),
1223
        NUM_REL(TIME),
1224
        IDENT_REL(BACKEND),
1225
        IDENT_REL(ACL),
1226
        IDENT_REL(PROBE),
1227
        IDENT_REL(STEVEDORE),
1228
        IDENT_REL(SUB),
1229
        IDENT_REL(INSTANCE),
1230
1231
        {BOOL,          T_EQ,           cmp_simple, "((!(\v1)) == (!(\v2)))" },
1232
        {BOOL,          T_NEQ,          cmp_simple, "((!(\v1)) != (!(\v2)))" },
1233
        {IP,            T_EQ,           cmp_simple, "!VRT_ipcmp(ctx, \v1, \v2)" },
1234
        {IP,            T_NEQ,          cmp_simple, "VRT_ipcmp(ctx, \v1, \v2)" },
1235
1236
        {IP,            '~',            cmp_acl, "" },
1237
        {IP,            T_NOMATCH,      cmp_acl, "!" },
1238
1239
        {STRINGS,       T_EQ,           cmp_string, "0 =="},
1240
        {STRINGS,       T_NEQ,          cmp_string, "0 !="},
1241
        {STRINGS,       '<',            cmp_string, "0 > "},
1242
        {STRINGS,       '>',            cmp_string, "0 < "},
1243
        {STRINGS,       T_LEQ,          cmp_string, "0 >="},
1244
        {STRINGS,       T_GEQ,          cmp_string, "0 <="},
1245
1246
        {STRINGS,       '~',            cmp_regexp, "" },
1247
        {STRINGS,       T_NOMATCH,      cmp_regexp, "!" },
1248
1249
        {VOID,          0,              NULL, NULL}
1250
};
1251
1252
#undef IDENT_REL
1253
#undef NUM_REL
1254
1255
static void
1256 4968040
vcc_expr_cmp(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1257
{
1258
        const struct cmps *cp;
1259
        struct token *tk;
1260
1261 4968040
        *e = NULL;
1262 4968040
        vcc_expr_add(tl, e, fmt);
1263 4968040
        ERRCHK(tl);
1264 4965800
        tk = tl->t;
1265
1266 259437640
        for (cp = vcc_cmps; cp->fmt != VOID; cp++) {
1267 256578280
                if (tl->t->tok != cp->token)
1268 233890520
                        continue;
1269 22687760
                if ((*e)->fmt != cp->fmt)
1270 20581320
                        continue;
1271 2106440
                AN(cp->func);
1272 2106440
                cp->func(tl, e, cp);
1273 2106440
                return;
1274
        }
1275
1276 2859360
        switch (tk->tok) {
1277
        case T_EQ:
1278
        case T_NEQ:
1279
        case '<':
1280
        case T_LEQ:
1281
        case '>':
1282
        case T_GEQ:
1283
        case '~':
1284
        case T_NOMATCH:
1285 160
                VSB_printf(tl->sb, "Operator %.*s not possible on %s\n",
1286 80
                    PF(tl->t), vcc_utype((*e)->fmt));
1287 80
                vcc_ErrWhere(tl, tl->t);
1288 80
                return;
1289
        default:
1290 2859280
                break;
1291
        }
1292 4968040
}
1293
1294
/*--------------------------------------------------------------------
1295
 * SYNTAX:
1296
 *    ExprNot:
1297
 *      '!' ExprCmp
1298
 */
1299
1300
static void
1301 4968040
vcc_expr_not(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1302
{
1303
        struct token *tk;
1304
1305 4968040
        *e = NULL;
1306 4968040
        tk = tl->t;
1307 4968040
        if (tl->t->tok == '!')
1308 221760
                vcc_NextToken(tl);
1309 4968040
        vcc_expr_cmp(tl, e, fmt);
1310 4968040
        ERRCHK(tl);
1311 4964960
        if (tk->tok != '!')
1312 4743240
                return;
1313 221720
        vcc_expr_tobool(tl, e);
1314 221720
        ERRCHK(tl);
1315 221720
        if ((*e)->fmt != BOOL) {
1316 40
                VSB_cat(tl->sb, "'!' must be followed by BOOL, found ");
1317 40
                VSB_printf(tl->sb, "%s.\n", vcc_utype((*e)->fmt));
1318 40
                vcc_ErrWhere2(tl, tk, tl->t);
1319 40
        } else {
1320 221680
                *e = vcc_expr_edit(tl, BOOL, "!(\v1)", *e, NULL);
1321
        }
1322 4968040
}
1323
1324
/*--------------------------------------------------------------------
1325
 * CAND and COR are identical save for a few details, but they are
1326
 * stacked so handling them in the same function is not simpler.
1327
 * Instead have them both call this helper function to do everything.
1328
 */
1329
1330
typedef void upfunc(struct vcc *tl, struct expr **e, vcc_type_t fmt);
1331
1332
static void
1333 7419920
vcc_expr_bin_bool(struct vcc *tl, struct expr **e, vcc_type_t fmt,
1334
    unsigned ourtok, upfunc *up, const char *tokstr)
1335
{
1336
        struct expr *e2;
1337
        struct token *tk;
1338
        char buf[32];
1339
1340 7419920
        *e = NULL;
1341 7419920
        tk = tl->t;
1342 7419920
        up(tl, e, fmt);
1343 7419920
        ERRCHK(tl);
1344 7413600
        if (tl->t->tok != ourtok)
1345 6865720
                return;
1346 547880
        vcc_expr_tobool(tl, e);
1347 547880
        ERRCHK(tl);
1348 547880
        if ((*e)->fmt != BOOL) {
1349 160
                VSB_printf(tl->sb,
1350
                    "'%s' must be preceeded by BOOL,"
1351 80
                    " found %s.\n", tokstr, vcc_utype((*e)->fmt));
1352 80
                vcc_ErrWhere2(tl, tk, tl->t);
1353 80
                return;
1354
        }
1355 547800
        *e = vcc_expr_edit(tl, BOOL, "(\v+\n\v1", *e, NULL);
1356 1860760
        while (tl->t->tok == ourtok) {
1357 1313040
                vcc_NextToken(tl);
1358 1313040
                tk = tl->t;
1359 1313040
                up(tl, &e2, fmt);
1360 1313040
                ERRCHK(tl);
1361 1313040
                vcc_expr_tobool(tl, &e2);
1362 1313040
                ERRCHK(tl);
1363 1313040
                if (e2->fmt != BOOL) {
1364 160
                        VSB_printf(tl->sb,
1365
                            "'%s' must be followed by BOOL,"
1366 80
                            " found %s.\n", tokstr, vcc_utype(e2->fmt));
1367 80
                        vcc_ErrWhere2(tl, tk, tl->t);
1368 80
                        vcc_delete_expr(e2);
1369 80
                        return;
1370
                }
1371 1312960
                bprintf(buf, "\v1\v-\n%s\v+\n\v2", tokstr);
1372 1312960
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1373
        }
1374 547720
        *e = vcc_expr_edit(tl, BOOL, "\v1\v-\n)", *e, NULL);
1375 7419920
}
1376
1377
/*--------------------------------------------------------------------
1378
 * SYNTAX:
1379
 *    ExprCand:
1380
 *      ExprNot { '&&' ExprNot } *
1381
 */
1382
1383
static void
1384 3764920
vcc_expr_cand(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1385
{
1386
1387 3764920
        vcc_expr_bin_bool(tl, e, fmt, T_CAND, vcc_expr_not, "&&");
1388 3764920
}
1389
1390
/*--------------------------------------------------------------------
1391
 * SYNTAX:
1392
 *    ExprCOR:
1393
 *      ExprCand { '||' ExprCand } *
1394
 */
1395
1396
static void
1397 3655000
vcc_expr_cor(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1398
{
1399
1400 3655000
        vcc_expr_bin_bool(tl, e, fmt, T_COR, vcc_expr_cand, "||");
1401 3655000
}
1402
1403
/*--------------------------------------------------------------------
1404
 * This function is the entry-point for getting an expression with
1405
 * a particular type, ready for inclusion in the VGC.
1406
 */
1407
1408
static void
1409 3543760
vcc_expr0(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1410
{
1411
        struct token *t1;
1412
1413 3543760
        assert(fmt != VOID);
1414 3543760
        assert(fmt != STRINGS);
1415 3543760
        *e = NULL;
1416 3543760
        t1 = tl->t;
1417 3543760
        if (fmt->stringform)
1418 1121200
                vcc_expr_cor(tl, e, STRINGS);
1419
        else
1420 2422560
                vcc_expr_cor(tl, e, fmt);
1421 3543760
        ERRCHK(tl);
1422
1423 3540480
        if ((*e)->fmt == fmt)
1424 1760200
                return;
1425
1426 1780280
        if ((*e)->fmt != STRINGS && fmt->stringform)
1427 134240
                vcc_expr_tostring(tl, e);
1428
1429 1780280
        if ((*e)->fmt->stringform) {
1430 0
                VSB_printf(tl->sb, "Cannot convert type %s(%s) to %s(%s)\n",
1431 0
                    vcc_utype((*e)->fmt), (*e)->fmt->name,
1432 0
                    vcc_utype(fmt), fmt->name);
1433 0
                vcc_ErrWhere2(tl, t1, tl->t);
1434 0
                return;
1435
        }
1436
1437 1780280
        if (fmt == BODY && !(*e)->fmt->bodyform)
1438 40
                vcc_expr_tostring(tl, e);
1439
1440 1780280
        if (fmt == BODY && (*e)->fmt->bodyform) {
1441 219560
                if ((*e)->fmt == STRINGS)
1442 219400
                        *e = vcc_expr_edit(tl, BODY, "STRING, 0, \vT", *e, NULL);
1443 160
                else if ((*e)->fmt == BLOB)
1444 160
                        *e = vcc_expr_edit(tl, BODY, "BLOB, 0, \v1", *e, NULL);
1445
                else
1446 0
                        WRONG("Unhandled bodyform");
1447 219560
        }
1448
1449 1780280
        if ((*e)->fmt == STRINGS && fmt->stringform) {
1450 1120080
                if (fmt == STRING)
1451 139360
                        *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
1452 980720
                else if (fmt == STRANDS)
1453 980720
                        *e = vcc_expr_edit(tl, STRANDS, "\vT", (*e), NULL);
1454
                else
1455 0
                        WRONG("Unhandled stringform");
1456 1120080
        }
1457
1458 1780280
        if (fmt == BOOL) {
1459 440480
                vcc_expr_tobool(tl, e);
1460 440480
                ERRCHK(tl);
1461 440480
        }
1462
1463 1780280
        vcc_expr_typecheck(tl, e, fmt, t1);
1464 3543760
}
1465
1466
static void
1467 2113200
vcc_expr_typecheck(struct vcc *tl, struct expr **e, vcc_type_t fmt,
1468
    struct token *t1)
1469
{
1470
1471 2113200
        assert(fmt != VOID);
1472 2113200
        assert(fmt != STRINGS);
1473
1474 2113200
        if (fmt != (*e)->fmt)  {
1475 720
                VSB_printf(tl->sb, "Expression has type %s, expected %s\n",
1476 360
                    vcc_utype((*e)->fmt), vcc_utype(fmt));
1477 360
                vcc_ErrWhere2(tl, t1, tl->t);
1478 360
        }
1479 2113200
}
1480
1481
/*--------------------------------------------------------------------
1482
 * This function parses and emits the C-code to evaluate an expression
1483
 *
1484
 * We know up front what kind of type we want the expression to be,
1485
 * and this function is the backstop if that doesn't succeed.
1486
 */
1487
1488
void
1489 3435080
vcc_Expr(struct vcc *tl, vcc_type_t fmt)
1490
{
1491 3435080
        struct expr *e = NULL;
1492
1493 3435080
        assert(fmt != VOID);
1494 3435080
        assert(fmt != STRINGS);
1495 3435080
        vcc_expr0(tl, &e, fmt);
1496 3435080
        ERRCHK(tl);
1497 3431960
        assert(e->fmt == fmt);
1498
1499 3431960
        vcc_expr_fmt(tl->fb, tl->indent, e);
1500 3431960
        VSB_cat(tl->fb, "\n");
1501 3431960
        vcc_delete_expr(e);
1502 3435080
}
1503
1504
/*--------------------------------------------------------------------
1505
 */
1506
1507
void v_matchproto_(sym_act_f)
1508 18200
vcc_Act_Call(struct vcc *tl, struct token *t, struct symbol *sym)
1509
{
1510
1511
        struct expr *e;
1512
1513 18200
        e = NULL;
1514 18200
        vcc_func(tl, &e, sym->eval_priv, sym->extra, sym);
1515 18200
        if (!tl->err) {
1516 18000
                vcc_expr_fmt(tl->fb, tl->indent, e);
1517 18000
                SkipToken(tl, ';');
1518 18000
                VSB_cat(tl->fb, ";\n");
1519 18200
        } else if (t != tl->t) {
1520 200
                VSB_cat(tl->sb, "While compiling function call:\n\n");
1521 200
                vcc_ErrWhere2(tl, t, tl->t);
1522 200
        }
1523 18200
        vcc_delete_expr(e);
1524 18200
}
1525
1526
void v_matchproto_(sym_act_f)
1527 13360
vcc_Act_Obj(struct vcc *tl, struct token *t, struct symbol *sym)
1528
{
1529
1530 13360
        struct expr *e = NULL;
1531
1532 13360
        assert(sym->kind == SYM_INSTANCE);
1533 13360
        ExpectErr(tl, '.');
1534 13320
        tl->t = t;
1535 13320
        vcc_expr4(tl, &e, sym->type);
1536 13320
        ERRCHK(tl);
1537 13320
        vcc_expr_fmt(tl->fb, tl->indent, e);
1538 13320
        vcc_delete_expr(e);
1539 13320
        SkipToken(tl, ';');
1540 13320
        VSB_cat(tl->fb, ";\n");
1541 13360
}
1542
1543
/*--------------------------------------------------------------------
1544
 */
1545
1546
static void v_matchproto_(sym_expr_t)
1547 1480
vcc_Eval_Regsub(struct vcc *tl, struct expr **e, struct token *t,
1548
    struct symbol *sym, vcc_type_t fmt)
1549
{
1550
        struct expr *e2, *e3;
1551 1480
        int all = sym->eval_priv == NULL ? 0 : 1;
1552
        char buf[128];
1553
1554 1480
        (void)t;
1555 1480
        (void)fmt;
1556 1480
        SkipToken(tl, '(');
1557 1480
        vcc_expr0(tl, &e2, STRING);
1558 1480
        ERRCHK(tl);
1559 1480
        SkipToken(tl, ',');
1560 1480
        vcc_expr0(tl, &e3, REGEX);
1561 1480
        ERRCHK(tl);
1562
1563 1440
        bprintf(buf, "VRT_regsub(ctx, %d,\v+\n\v1,\n\v2", all);
1564 1440
        *e = vcc_expr_edit(tl, STRING, buf, e2, e3);
1565 1440
        SkipToken(tl, ',');
1566 1440
        vcc_expr0(tl, &e2, STRING);
1567 1440
        ERRCHK(tl);
1568 1440
        *e = vcc_expr_edit(tl, STRINGS, "\v1,\n\v2)\v-", *e, e2);
1569 1440
        (*e)->nstr = 1;
1570 1440
        SkipToken(tl, ')');
1571 1480
}
1572
1573
/*--------------------------------------------------------------------
1574
 */
1575
1576
static void v_matchproto_(sym_expr_t)
1577 119160
vcc_Eval_BoolConst(struct vcc *tl, struct expr **e, struct token *t,
1578
    struct symbol *sym, vcc_type_t fmt)
1579
{
1580
1581 119160
        (void)t;
1582 119160
        (void)tl;
1583 119160
        (void)fmt;
1584 119160
        *e = vcc_mk_expr(BOOL, "(0==%d)", sym->eval_priv == NULL ? 1 : 0);
1585 119160
        (*e)->constant = EXPR_CONST;
1586 119160
}
1587
1588
/*--------------------------------------------------------------------
1589
 */
1590
1591
static void v_matchproto_(sym_expr_t)
1592 160
vcc_Eval_Default(struct vcc *tl, struct expr **e, struct token *t,
1593
    struct symbol *sym, vcc_type_t fmt)
1594
{
1595 160
        (void)e;
1596 160
        (void)fmt;
1597 160
        (void)sym;
1598 160
        (void)t;
1599
1600 160
        if (fmt == PROBE)
1601 0
                *e = vcc_mk_expr(PROBE, "%s", vcc_default_probe(tl));
1602 160
        else if (fmt == BACKEND)
1603 80
                *e = vcc_mk_expr(BACKEND, "*(VCL_conf.default_director)");
1604
        else {
1605 80
                VSB_cat(tl->sb, "Symbol 'default' is a reserved word.\n");
1606 80
                vcc_ErrWhere(tl, t);
1607
        }
1608 160
}
1609
1610
/*--------------------------------------------------------------------
1611
 */
1612
1613
void
1614 118600
vcc_Expr_Init(struct vcc *tl)
1615
{
1616
        struct symbol *sym;
1617
1618 118600
        sym = VCC_MkSym(tl, "regsub", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1619 118600
        AN(sym);
1620 118600
        sym->type = STRING;
1621 118600
        sym->eval = vcc_Eval_Regsub;
1622 118600
        sym->eval_priv = NULL;
1623
1624 118600
        sym = VCC_MkSym(tl, "regsuball", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1625 118600
        AN(sym);
1626 118600
        sym->type = STRING;
1627 118600
        sym->eval = vcc_Eval_Regsub;
1628 118600
        sym->eval_priv = sym;
1629
1630 118600
        sym = VCC_MkSym(tl, "true", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1631 118600
        AN(sym);
1632 118600
        sym->type = BOOL;
1633 118600
        sym->eval = vcc_Eval_BoolConst;
1634 118600
        sym->eval_priv = sym;
1635
1636 118600
        sym = VCC_MkSym(tl, "false", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1637 118600
        AN(sym);
1638 118600
        sym->type = BOOL;
1639 118600
        sym->eval = vcc_Eval_BoolConst;
1640 118600
        sym->eval_priv = NULL;
1641
1642 118600
        sym = VCC_MkSym(tl, "default", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1643 118600
        AN(sym);
1644 118600
        sym->type = BACKEND;    // ... can also (sometimes) deliver PROBE
1645 118600
        sym->eval = vcc_Eval_Default;
1646 118600
}