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 60676
vcc_isconst(const struct expr *e)
63
{
64 60676
        AN(e->constant);
65 60676
        return (e->constant & EXPR_CONST);
66
}
67
68
static inline int
69 714967
vcc_islit(const struct expr *e)
70
{
71 714967
        AN(e->constant);
72 714967
        return (e->constant & EXPR_STR_CONST);
73
}
74
75
static const char *
76 737
vcc_utype(vcc_type_t t)
77
{
78 737
        if (t == STRINGS || t->stringform)
79 198
                t = STRING;
80 737
        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 6014954
vcc_new_expr(vcc_type_t fmt)
90
{
91
        struct expr *e;
92
93 6014954
        ALLOC_OBJ(e, EXPR_MAGIC);
94 6014954
        AN(e);
95 6014954
        e->vsb = VSB_new_auto();
96 6014954
        e->fmt = fmt;
97 6014954
        e->constant = EXPR_VAR;
98 6014954
        return (e);
99
}
100
101
static struct expr * v_printflike_(2, 3)
102 1548349
vcc_mk_expr(vcc_type_t fmt, const char *str, ...)
103
{
104
        va_list ap;
105
        struct expr *e;
106
107 1548349
        e = vcc_new_expr(fmt);
108 1548349
        va_start(ap, str);
109 1548349
        VSB_vprintf(e->vsb, str, ap);
110 1548349
        va_end(ap);
111 1548349
        AZ(VSB_finish(e->vsb));
112 1548349
        return (e);
113
}
114
115
static void
116 7680189
vcc_delete_expr(struct expr *e)
117
{
118 7680189
        if (e == NULL)
119 1674629
                return;
120 6005560
        CHECK_OBJ(e, EXPR_MAGIC);
121 6005560
        VSB_destroy(&e->vsb);
122 6005560
        FREE_OBJ(e);
123 7680189
}
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 533181
vcc_strands_edit(const struct expr *e1, const struct expr *e2)
152
{
153
154 533181
        if (e2->nstr == 1) {
155 471735
                VSB_printf(e1->vsb, "TOSTRAND(%s)", VSB_data(e2->vsb));
156 471735
                return;
157
        }
158
159 122892
        VSB_printf(e1->vsb, "TOSTRANDS(%d,\v+\n%s\v-)",
160 61446
            e2->nstr, VSB_data(e2->vsb));
161 533181
}
162
163
static struct expr *
164 3371060
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 3371060
        int nl = 1;
169
170 3371060
        (void) tl;
171
172 3371060
        AN(e1);
173 3371060
        e = vcc_new_expr(fmt);
174 40291922
        while (*p != '\0') {
175 36920862
                if (*p != '\v') {
176 30813123
                        if (*p != '\n' || !nl)
177 30812595
                                VSB_putc(e->vsb, *p);
178 30813123
                        nl = (*p == '\n');
179 30813123
                        p++;
180 30813123
                        continue;
181
                }
182 6107739
                assert(*p == '\v');
183 6107739
                switch (*++p) {
184 503107
                case '+': VSB_cat(e->vsb, "\v+"); nl = 0; break;
185 537086
                case '-': VSB_cat(e->vsb, "\v-"); nl = 0; break;
186
                case 'S':
187
                case 's':
188 127281
                        e3 = (*p == 'S' ? e1 : e2);
189 127281
                        AN(e3);
190 127281
                        assert(e1->fmt == STRINGS);
191 127281
                        if (e3->nstr > 1) {
192 286
                                VSB_cat(e->vsb,
193
                                    "\nVRT_STRANDS_string(ctx,\v+\n");
194 286
                                vcc_strands_edit(e, e3);
195 286
                                VSB_cat(e->vsb,
196
                                    "\v-\n)\n");
197 286
                        } else {
198 126995
                                VSB_cat(e->vsb, VSB_data(e3->vsb));
199
                        }
200 127281
                        break;
201
                case 'T':
202
                case 't':
203 532895
                        e3 = (*p == 'T' ? e1 : e2);
204 532895
                        AN(e3);
205 532895
                        vcc_strands_edit(e, e3);
206 532895
                        break;
207
                case '1':
208 2711192
                        VSB_cat(e->vsb, VSB_data(e1->vsb));
209 2711192
                        break;
210
                case '2':
211 1696178
                        AN(e2);
212 1696178
                        VSB_cat(e->vsb, VSB_data(e2->vsb));
213 1696178
                        break;
214
                default:
215 0
                        WRONG("Illegal edit in VCC expression");
216 0
                }
217 6107739
                p++;
218
        }
219 3371060
        AZ(VSB_finish(e->vsb));
220 3371060
        e->t1 = e1->t1;
221 3371060
        e->t2 = e1->t2;
222 3371060
        if (e2 != NULL)
223 1696486
                e->t2 = e2->t2;
224 3371060
        vcc_delete_expr(e1);
225 3371060
        vcc_delete_expr(e2);
226 3371060
        return (e);
227
}
228
229
/*--------------------------------------------------------------------
230
 * Expand finished expression into C-source code
231
 */
232
233
static void
234 937992
vcc_expr_fmt(struct vsb *d, int ind, const struct expr *e1)
235
{
236
        char *p;
237
        int i;
238
239 937992
        if (!e1->fmt->noindent) {
240 8341894
                for (i = 0; i < ind; i++)
241 7463214
                        VSB_putc(d, ' ');
242 878680
        }
243 937992
        p = VSB_data(e1->vsb);
244 92377008
        while (*p != '\0') {
245 91439060
                if (*p == '\n') {
246 2729430
                        VSB_putc(d, '\n');
247 2729430
                        if (*++p == '\0')
248 44
                                break;
249 29328200
                        for (i = 0; i < ind; i++)
250 26598814
                                VSB_putc(d, ' ');
251 91439016
                } else if (*p != '\v') {
252 87512170
                        VSB_putc(d, *p++);
253 87512170
                } else {
254 1197460
                        switch (*++p) {
255 598730
                        case '+': ind += INDENT; break;
256 598730
                        case '-': ind -= INDENT; break;
257 0
                        default:  WRONG("Illegal format in VCC expression");
258 0
                        }
259 1197460
                        p++;
260
                }
261
        }
262 937992
}
263
264
/*--------------------------------------------------------------------
265
 */
266
267
static void
268 681670
vcc_expr_tobool(struct vcc *tl, struct expr **e)
269
{
270
271 681670
        if ((*e)->fmt == BOOL)
272 503228
                return;
273 178442
        if ((*e)->fmt == BACKEND || (*e)->fmt == INT)
274 110
                *e = vcc_expr_edit(tl, BOOL, "(\v1 != 0)", *e, NULL);
275 178332
        else if ((*e)->fmt == DURATION)
276 22
                *e = vcc_expr_edit(tl, BOOL, "(\v1 > 0)", *e, NULL);
277 178310
        else if ((*e)->fmt == STRINGS)
278 178244
                *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 681670
}
285
286
/*--------------------------------------------------------------------
287
 */
288
289
static void
290 579425
vcc_expr_tostring(struct vcc *tl, struct expr **e, vcc_type_t fmt)
291
{
292
        const char *p;
293 579425
        uint8_t constant = EXPR_VAR;
294
295 579425
        CHECK_OBJ_NOTNULL(*e, EXPR_MAGIC);
296 579425
        assert(fmt == STRINGS || fmt->stringform);
297 579425
        assert(fmt != (*e)->fmt);
298
299 579425
        p = (*e)->fmt->tostring;
300 579425
        if (p != NULL) {
301 579414
                AN(*p);
302 579414
                *e = vcc_expr_edit(tl, fmt, p, *e, NULL);
303 579414
                (*e)->constant = constant;
304 579414
                (*e)->nstr = 1;
305 579414
        } else {
306 22
                VSB_printf(tl->sb,
307
                    "Cannot convert %s to STRING.\n",
308 11
                    vcc_utype((*e)->fmt));
309 11
                vcc_ErrWhere2(tl, (*e)->t1, tl->t);
310
        }
311 579425
}
312
313
/*--------------------------------------------------------------------
314
 */
315
316
void v_matchproto_(sym_expr_t)
317 4499
vcc_Eval_Handle(struct vcc *tl, struct expr **e, struct token *t,
318
    struct symbol *sym, vcc_type_t type)
319
{
320
321 4499
        (void)t;
322 4499
        (void)tl;
323 4499
        AN(sym->rname);
324 4499
        AZ(type->stringform);
325
326 4554
        if (sym->type->tostring == NULL &&
327 55
            sym->type != STRING && type == STRINGS) {
328 0
                *e = vcc_mk_expr(STRINGS, "\"%s\"", sym->name);
329 0
                (*e)->nstr = 1;
330 0
                (*e)->constant |= EXPR_CONST | EXPR_STR_CONST;
331 0
        } else {
332 4499
                *e = vcc_mk_expr(sym->type, "%s", sym->rname);
333 4499
                (*e)->constant = EXPR_VAR;
334 4499
                (*e)->nstr = 1;
335 4499
                if ((*e)->fmt == STRING)
336 0
                        (*e)->fmt = STRINGS;
337
        }
338 4499
}
339
340
void v_matchproto_(sym_expr_t)
341 253
vcc_Eval_Sub(struct vcc *tl, struct expr **e, struct token *t,
342
    struct symbol *sym, vcc_type_t type)
343
{
344
345 253
        (void)t;
346 253
        (void)tl;
347 253
        AN(sym->rname);
348 253
        AZ(type->stringform);
349
350 253
        assert (sym->type == SUB);
351
352 253
        if (type == SUB) {
353 220
                *e = vcc_mk_expr(sym->type, "%s", sym->rname);
354 220
                (*e)->constant = EXPR_CONST;
355 220
                return;
356
        }
357
358 66
        VSB_printf(tl->sb, "Symbol '%s' can only be used as a %s expression\n",
359 33
            sym->name, sym->type->name);
360 33
        vcc_ErrWhere(tl, tl->t);
361 253
}
362
363
/*--------------------------------------------------------------------
364
 */
365
366
void v_matchproto_(sym_expr_t)
367 1263251
vcc_Eval_Var(struct vcc *tl, struct expr **e, struct token *t,
368
    struct symbol *sym, vcc_type_t type)
369
{
370
371 1263251
        (void)type;
372 1263251
        vcc_AddUses(tl, t, NULL, sym, XREF_READ);
373 1263251
        ERRCHK(tl);
374 1263251
        *e = vcc_mk_expr(sym->type, "%s", sym->rname);
375 1263251
        (*e)->constant = EXPR_VAR;
376 1263251
        (*e)->nstr = 1;
377 1263251
        if ((*e)->fmt == STRING)
378 596640
                (*e)->fmt = STRINGS;
379 1263251
}
380
381
void v_matchproto_(sym_expr_t)
382 110
vcc_Eval_ProtectedHeader(struct vcc *tl, struct expr **e, struct token *t,
383
    struct symbol *sym, vcc_type_t type)
384
{
385
386 110
        AN(sym);
387 110
        AZ(sym->lorev);
388
389 110
        vcc_Header_Fh(tl, sym);
390 110
        sym->eval = vcc_Eval_Var;
391 110
        vcc_Eval_Var(tl, e, t, sym, type);
392 110
}
393
394
/*--------------------------------------------------------------------
395
 */
396
397
static struct expr *
398 1892
vcc_priv_arg(struct vcc *tl, const char *p, struct symbol *sym)
399
{
400
        char buf[64];
401
        struct inifin *ifp;
402 1892
        const char *f = NULL;
403 1892
        struct procprivhead *marklist = NULL;
404
405 1892
        AN(sym);
406 1892
        AN(sym->vmod_name);
407
408 1892
        if (!strcmp(p, "PRIV_VCL"))
409 165
                return (vcc_mk_expr(VOID, "&vmod_priv_%s", sym->vmod_name));
410
411 1727
        if (!strcmp(p, "PRIV_CALL")) {
412 242
                bprintf(buf, "vmod_priv_%u", tl->unique++);
413 242
                ifp = New_IniFin(tl);
414 242
                Fh(tl, 0, "static struct vmod_priv %s;\n", buf);
415 242
                VSB_printf(ifp->fin, "\tVRT_priv_fini(ctx, &%s);", buf);
416 242
                return (vcc_mk_expr(VOID, "&%s", buf));
417
        }
418
419 1485
        if (!strcmp(p, "PRIV_TASK")) {
420 1397
                f = "task";
421 1397
                marklist = &tl->curproc->priv_tasks;
422 1485
        } else if (!strcmp(p, "PRIV_TOP")) {
423 88
                f = "top";
424 88
                sym->r_methods &= VCL_MET_TASK_C;
425 88
                marklist = &tl->curproc->priv_tops;
426 88
        } else {
427 0
                WRONG("Wrong PRIV_ type");
428
        }
429 1485
        AN(f);
430 1485
        AN(marklist);
431 1485
        bprintf(buf, "ARG_priv_%s_%s", f, sym->vmod_name);
432
433 1485
        if (vcc_MarkPriv(tl, marklist, sym->vmod_name) == NULL)
434 946
                VSB_printf(tl->curproc->prologue,
435
                           "  struct vmod_priv *%s = "
436
                           "VRT_priv_%s(ctx, &VGC_vmod_%s);\n"
437
                           "  if (%s == NULL) {\n"
438
                           "    VRT_fail(ctx, \"failed to get %s priv "
439
                           "for vmod %s\");\n"
440
                           "    return;\n"
441
                           "  }\n",
442 473
                           buf, f, sym->vmod_name, buf, f, sym->vmod_name);
443 1485
        return (vcc_mk_expr(VOID, "%s", buf));
444 1892
}
445
446
struct func_arg {
447
        vcc_type_t              type;
448
        const struct vjsn_val   *enums;
449
        const char              *cname;
450
        const char              *name;
451
        const char              *val;
452
        struct expr             *result;
453
        int                     avail;
454
        int                     optional;
455
        VTAILQ_ENTRY(func_arg)  list;
456
};
457
458
static void
459 19899
vcc_do_enum(struct vcc *tl, struct func_arg *fa, int len, const char *ptr)
460
{
461
        const char *r;
462
463 19899
        (void)tl;
464 19899
        r = strchr(fa->cname, '.');
465 19899
        AN(r);
466 19899
        fa->result = vcc_mk_expr(VOID, "*%.*s.enum_%.*s",
467 19899
            (int)(r - fa->cname), fa->cname, len, ptr);
468 19899
}
469
470
static void
471 43164
vcc_do_arg(struct vcc *tl, struct func_arg *fa)
472
{
473
        struct expr *e2;
474
        struct vjsn_val *vv;
475
476 43164
        if (fa->type == ENUM) {
477 14619
                ExpectErr(tl, ID);
478 14619
                ERRCHK(tl);
479 50050
                VTAILQ_FOREACH(vv, &fa->enums->children, list)
480 50028
                        if (vcc_IdIs(tl->t, vv->value))
481 14597
                                break;
482 14619
                if (vv == NULL) {
483 22
                        VSB_cat(tl->sb, "Wrong enum value.");
484 22
                        VSB_cat(tl->sb, "  Expected one of:\n");
485 110
                        VTAILQ_FOREACH(vv, &fa->enums->children, list)
486 88
                                VSB_printf(tl->sb, "\t%s\n", vv->value);
487 22
                        vcc_ErrWhere(tl, tl->t);
488 22
                        return;
489
                }
490 14597
                vcc_do_enum(tl, fa, PF(tl->t));
491 14597
                SkipToken(tl, ID);
492 14597
        } else {
493 28545
                if (fa->type == SUB)
494 220
                        tl->subref++;
495 28545
                vcc_expr0(tl, &e2, fa->type);
496 28545
                ERRCHK(tl);
497 28457
                assert(e2->fmt == fa->type);
498 28457
                fa->result = e2;
499
        }
500 43054
        fa->avail = 1;
501 43164
}
502
503
static void
504 29810
vcc_func(struct vcc *tl, struct expr **e, const void *priv,
505
    const char *extra, struct symbol *sym)
506
{
507
        vcc_type_t rfmt;
508
        const char *cfunc;
509
        struct expr *e1;
510
        struct func_arg *fa, *fa2;
511
        VTAILQ_HEAD(,func_arg) head;
512
        struct token *tf, *t1;
513
        const struct vjsn_val *vv, *vvp;
514
        const char *sa, *extra_sep;
515
        char ssa[64];
516
        int n;
517
518 29810
        CAST_OBJ_NOTNULL(vv, priv, VJSN_VAL_MAGIC);
519 29810
        assert(vjsn_is_array(vv));
520 29810
        vv = VTAILQ_FIRST(&vv->children);
521 29810
        rfmt = VCC_Type(VTAILQ_FIRST(&vv->children)->value);
522 29810
        AN(rfmt);
523 29810
        vv = VTAILQ_NEXT(vv, list);
524 29810
        cfunc = vv->value;
525 29810
        vv = VTAILQ_NEXT(vv, list);
526 29810
        sa = vv->value;
527 29810
        if (*sa == '\0') {
528 25421
                sa = NULL;
529 25421
        }
530 29810
        vv = VTAILQ_NEXT(vv, list);
531 29810
        if (sym->kind == SYM_METHOD) {
532 8514
                if (*e == NULL) {
533 22
                        VSB_cat(tl->sb, "Syntax error.");
534 22
                        tl->err = 1;
535 22
                        return;
536
                }
537 8492
                vcc_NextToken(tl);
538 8492
                AZ(extra);
539 8492
                AN((*e)->instance);
540 8492
                extra = (*e)->instance->rname;
541 8492
        }
542 29788
        tf = VTAILQ_PREV(tl->t, tokenhead, list);
543 29788
        SkipToken(tl, '(');
544 29788
        if (extra == NULL) {
545 19085
                extra = "";
546 19085
                extra_sep = "";
547 19085
        } else {
548 10703
                AN(*extra);
549 10703
                extra_sep = ", ";
550
        }
551 29788
        VTAILQ_INIT(&head);
552 100012
        for (;vv != NULL; vv = VTAILQ_NEXT(vv, list)) {
553 70224
                assert(vjsn_is_array(vv));
554 70224
                fa = calloc(1, sizeof *fa);
555 70224
                AN(fa);
556 70224
                fa->cname = cfunc;
557 70224
                VTAILQ_INSERT_TAIL(&head, fa, list);
558
559 70224
                vvp = VTAILQ_FIRST(&vv->children);
560 70224
                if (!memcmp(vvp->value, "PRIV_", 5)) {
561 1892
                        fa->result = vcc_priv_arg(tl, vvp->value, sym);
562 1892
                        vvp = VTAILQ_NEXT(vvp, list);
563 1892
                        if (vvp != NULL)
564 33
                                fa->name = vvp->value;
565 1892
                        continue;
566
                }
567 68332
                fa->type = VCC_Type(vvp->value);
568 68332
                AN(fa->type);
569 68332
                vvp = VTAILQ_NEXT(vvp, list);
570 68332
                if (vvp != NULL) {
571 64009
                        fa->name = vvp->value;
572 64009
                        vvp = VTAILQ_NEXT(vvp, list);
573 64009
                        if (vvp != NULL) {
574 47058
                                fa->val = vvp->value;
575 47058
                                vvp = VTAILQ_NEXT(vvp, list);
576 47058
                                if (vvp != NULL) {
577 38390
                                        fa->enums = vvp;
578 38390
                                        vvp = VTAILQ_NEXT(vvp, list);
579 38390
                                }
580 47058
                        }
581 64009
                }
582 68332
                if (sa != NULL && vvp != NULL && vjsn_is_true(vvp)) {
583 19844
                        fa->optional = 1;
584 19844
                        vvp = VTAILQ_NEXT(vvp, list);
585 19844
                }
586 68332
                AZ(vvp);
587 68332
        }
588
589 48147
        VTAILQ_FOREACH(fa, &head, list) {
590 43153
                if (tl->t->tok == ')')
591 946
                        break;
592 42207
                if (fa->result != NULL)
593 1353
                        continue;
594 40854
                if (tl->t->tok == ID) {
595 30096
                        t1 = VTAILQ_NEXT(tl->t, list);
596 30096
                        if (t1->tok == '=')
597 8239
                                break;
598 21857
                }
599 32615
                vcc_do_arg(tl, fa);
600 32615
                if (tl->err)
601 220
                        VSB_printf(tl->sb, "Expected argument: %s %s\n\n",
602 110
                            fa->type->name,
603 110
                            fa->name ? fa->name : "(unnamed argument)");
604 32615
                ERRCHK(tl);
605 32505
                if (tl->t->tok == ')')
606 15499
                        break;
607 17006
                SkipToken(tl, ',');
608 17006
        }
609 32010
        while (tl->t->tok == ID) {
610 34353
                VTAILQ_FOREACH(fa, &head, list) {
611 34342
                        if (fa->name == NULL)
612 132
                                continue;
613 34210
                        if (vcc_IdIs(tl->t, fa->name))
614 10560
                                break;
615 23650
                }
616 10571
                if (fa == NULL) {
617 22
                        VSB_printf(tl->sb, "Unknown argument '%.*s'\n",
618 11
                            PF(tl->t));
619 11
                        vcc_ErrWhere(tl, tl->t);
620 11
                        return;
621
                }
622 10560
                if (fa->result != NULL) {
623 11
                        AN(fa->name);
624 22
                        VSB_printf(tl->sb, "Argument '%s' already used\n",
625 11
                            fa->name);
626 11
                        vcc_ErrWhere(tl, tl->t);
627 11
                        return;
628
                }
629 10549
                vcc_NextToken(tl);
630 10549
                SkipToken(tl, '=');
631 10549
                vcc_do_arg(tl, fa);
632 10549
                ERRCHK(tl);
633 10549
                if (tl->t->tok == ')')
634 8217
                        break;
635 2332
                SkipToken(tl, ',');
636
        }
637
638 29656
        if (sa != NULL)
639 8690
                e1 = vcc_mk_expr(rfmt, "%s(ctx%s%s,\v+\n&(%s)\v+ {\n",
640 4345
                    cfunc, extra_sep, extra, sa);
641
        else
642 50622
                e1 = vcc_mk_expr(rfmt, "%s(ctx%s%s\v+",
643 25311
                    cfunc, extra_sep, extra);
644 29656
        n = 0;
645 99517
        VTAILQ_FOREACH_SAFE(fa, &head, list, fa2) {
646 69861
                n++;
647 69861
                if (fa->optional) {
648 19778
                        AN(fa->name);
649 19778
                        bprintf(ssa, "\v1.valid_%s = %d,\n",
650
                            fa->name, fa->avail);
651 19778
                        e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, NULL);
652 19778
                }
653 69861
                if (fa->result == NULL && fa->type == ENUM && fa->val != NULL)
654 5302
                        vcc_do_enum(tl, fa, strlen(fa->val), fa->val);
655 69861
                if (fa->result == NULL && fa->val != NULL)
656 6369
                        fa->result = vcc_mk_expr(fa->type, "%s", fa->val);
657 69861
                if (fa->result != NULL && sa != NULL) {
658 9449
                        if (fa->name)
659 9218
                                bprintf(ssa, "\v1.%s = \v2,\n", fa->name);
660
                        else
661 231
                                bprintf(ssa, "\v1.arg%d = \v2,\n", n);
662 9449
                        e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, fa->result);
663 69861
                } else if (fa->result != NULL) {
664 94226
                        e1 = vcc_expr_edit(tl, e1->fmt, "\v1,\n\v2",
665 47113
                            e1, fa->result);
666 60412
                } else if (!fa->optional) {
667 11
                        if (fa->name)
668 22
                                VSB_printf(tl->sb, "Argument '%s' missing\n",
669 11
                                    fa->name);
670
                        else
671 0
                                VSB_printf(tl->sb, "Argument %d missing\n", n);
672 11
                        vcc_ErrWhere(tl, tl->t);
673 11
                }
674 69861
                free(fa);
675 69861
        }
676 29656
        if (sa != NULL) {
677 4345
                *e = vcc_expr_edit(tl, e1->fmt, "\v1\v-\n}\v-\n)", e1, NULL);
678 4345
        } else {
679 25311
                *e = vcc_expr_edit(tl, e1->fmt, "\v1\v-\n)", e1, NULL);
680
        }
681 29656
        SkipToken(tl, ')');
682 29645
        vcc_AddUses(tl, tf, NULL, sym, XREF_READ);
683 29810
}
684
685
686
/*--------------------------------------------------------------------
687
 */
688
689
void
690 2211
vcc_Eval_Func(struct vcc *tl, const struct vjsn_val *spec,
691
    const char *extra, struct symbol *sym)
692
{
693 2211
        struct expr *e = NULL;
694
695 2211
        vcc_func(tl, &e, spec, extra, sym);
696 2211
        if (tl->err)
697 0
                VSB_cat(tl->sb, "While compiling function call:\n");
698 2211
        ERRCHK(tl);
699 2211
        vcc_expr_fmt(tl->fb, tl->indent, e);
700 2211
        VSB_cat(tl->fb, ";\n");
701 2211
        vcc_delete_expr(e);
702 2211
}
703
704
/*--------------------------------------------------------------------
705
 */
706
707
void v_matchproto_(sym_expr_t)
708 22605
vcc_Eval_SymFunc(struct vcc *tl, struct expr **e, struct token *t,
709
    struct symbol *sym, vcc_type_t fmt)
710
{
711
712 22605
        (void)t;
713 22605
        (void)fmt;
714 22605
        assert(sym->kind == SYM_FUNC || sym->kind == SYM_METHOD);
715 22605
        AN(sym->eval_priv);
716
717 22605
        vcc_func(tl, e, sym->eval_priv, sym->extra, sym);
718 22605
        ERRCHK(tl);
719 22495
        if ((*e)->fmt == STRING) {
720 8239
                (*e)->fmt = STRINGS;
721 8239
                (*e)->nstr = 1;
722 8239
        }
723 22605
}
724
725
/*--------------------------------------------------------------------
726
 */
727
728
static void
729 190036
vcc_number(struct vcc *tl, struct expr **e, vcc_type_t fmt, const char *sign)
730
{
731
        VCL_INT vi;
732
        struct expr *e1;
733
        struct token *t;
734
735 190036
        assert(fmt != VOID);
736 190036
        if (fmt == BYTES) {
737 517
                vcc_ByteVal(tl, &vi);
738 517
                ERRCHK(tl);
739 495
                e1 = vcc_mk_expr(BYTES, "%ju", (intmax_t)vi);
740 495
        } else {
741 189519
                t = tl->t;
742 189519
                vcc_NextToken(tl);
743 189519
                if (tl->t->tok == ID) {
744 61446
                        e1 = vcc_mk_expr(DURATION, "%s%.3f * %g",
745 61446
                            sign, t->num, vcc_DurationUnit(tl));
746 61446
                        ERRCHK(tl);
747 189508
                } else if (fmt == REAL || t->tok == FNUM) {
748 1694
                        e1 = vcc_mk_expr(REAL, "%s%.3f", sign, t->num);
749 1694
                } else {
750 126379
                        e1 = vcc_mk_expr(INT, "%s%.0f", sign, t->num);
751
                }
752
        }
753 190003
        e1->constant = EXPR_CONST;
754 190003
        *e = e1;
755 190036
}
756
757
/*--------------------------------------------------------------------
758
 * SYNTAX:
759
 *    Expr5:
760
 *      '(' ExprCor ')'
761
 *      symbol
762
 *      CNUM
763
 *      FNUM
764
 *      CSTR
765
 *      CBLOB
766
 */
767
768
static void
769 2631024
vcc_expr5(struct vcc *tl, struct expr **e, vcc_type_t fmt)
770
{
771
        struct expr *e1, *e2;
772
        const char *ip, *sign;
773
        struct token *t, *t1;
774
        struct symbol *sym;
775
776 2631024
        sign = "";
777 2631024
        *e = NULL;
778 2631024
        if (tl->t->tok == '(') {
779 29964
                SkipToken(tl, '(');
780 29964
                vcc_expr_cor(tl, &e2, fmt);
781 29964
                ERRCHK(tl);
782 29964
                SkipToken(tl, ')');
783 29964
                if (e2->fmt == STRINGS)
784 66
                        *e = e2;
785
                else
786 29898
                        *e = vcc_expr_edit(tl, e2->fmt, "(\v1)", e2, NULL);
787 29964
                return;
788
        }
789 2601060
        switch (tl->t->tok) {
790
        case ID:
791 1323520
                t = tl->t;
792 1323520
                t1 = vcc_PeekToken(tl);
793 1323520
                AN(t1);
794 1323520
                sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
795
                    SYMTAB_PARTIAL_NOERR, XREF_REF);
796 1323520
                if (sym == NULL && fmt->global_pfx != NULL && t1->tok != '.') {
797 99
                        sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
798
                            SYMTAB_CREATE, XREF_REF);
799 99
                        ERRCHK(tl);
800 77
                        AN(sym);
801 77
                        VCC_GlobalSymbol(sym, fmt);
802 77
                }
803 1323498
                ERRCHK(tl);
804 1323498
                if (sym == NULL)
805 132
                        AZ(VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
806
                            SYMTAB_PARTIAL, XREF_REF));
807 1323498
                ERRCHK(tl);
808 1323366
                AN(sym);
809 1323366
                if (sym->kind == SYM_INSTANCE) {
810 8514
                        AZ(*e);
811 8514
                        *e = vcc_new_expr(sym->type);
812 8514
                        (*e)->instance = sym;
813 8514
                        return;
814
                }
815 1314852
                if (sym->kind == SYM_FUNC && sym->type == VOID) {
816 11
                        VSB_cat(tl->sb, "Function returns VOID:\n");
817 11
                        vcc_ErrWhere(tl, tl->t);
818 11
                        return;
819
                }
820 1314841
                if (sym->eval != NULL) {
821 1314808
                        AN(sym->eval);
822 1314808
                        AZ(*e);
823 1314808
                        sym->eval(tl, e, t, sym, fmt);
824 1314808
                        if (tl->err) {
825 176
                                VSB_cat(tl->sb,
826
                                    "While compiling function call:\n\n");
827 176
                                vcc_ErrWhere2(tl, t, tl->t);
828 176
                        }
829 1314808
                        ERRCHK(tl);
830
                        /* Unless asked for a HEADER, fold to string here */
831 1314632
                        if (*e && fmt != HEADER && (*e)->fmt == HEADER) {
832 365420
                                vcc_expr_tostring(tl, e, STRINGS);
833 365420
                                ERRCHK(tl);
834 365420
                        }
835 1314632
                        return;
836
                }
837 66
                VSB_printf(tl->sb,
838
                    "Symbol '%.*s' type (%s) can not be used in expression.\n",
839 33
                    PF(t), sym->kind->name);
840 33
                vcc_ErrWhere(tl, t);
841 33
                if (sym->def_b != NULL) {
842 11
                        VSB_cat(tl->sb, "That symbol was defined here:\n");
843 11
                        vcc_ErrWhere(tl, sym->def_b);
844 11
                }
845 33
                return;
846
        case CSTR:
847 1087339
                assert(fmt != VOID);
848 1087339
                if (fmt == IP) {
849 330
                        if (*tl->t->dec == '/') {
850
                                /*
851
                                 * On some platforms (e.g. FreeBSD),
852
                                 * getaddrinfo(3) may resolve a path to a
853
                                 * sockaddr_un if it happens to exist and
854
                                 * is a socket. So don't let that happen.
855
                                 */
856 11
                                VSB_cat(tl->sb,
857
                                    "Cannot convert to an IP address: ");
858 11
                                vcc_ErrToken(tl, tl->t);
859 11
                                vcc_ErrWhere(tl, tl->t);
860 11
                                return;
861
                        }
862 638
                        Resolve_Sockaddr(tl, tl->t->dec, "80",
863
                            &ip, NULL, &ip, NULL, NULL, 1,
864 319
                            tl->t, "IP constant");
865 319
                        ERRCHK(tl);
866 286
                        e1 = vcc_mk_expr(IP, "%s", ip);
867 286
                        ERRCHK(tl);
868 1087295
                } else if (fmt == REGEX) {
869 90057
                        e1 = vcc_new_expr(REGEX);
870 90057
                        vcc_regexp(tl, e1->vsb);
871 90057
                        AZ(VSB_finish(e1->vsb));
872 90057
                } else {
873 996952
                        e1 = vcc_new_expr(STRINGS);
874 996952
                        EncToken(e1->vsb, tl->t);
875 996952
                        AZ(VSB_finish(e1->vsb));
876 996952
                        e1->constant |= EXPR_STR_CONST;
877 996952
                        e1->nstr = 1;
878
                }
879 1087295
                e1->t1 = tl->t;
880 1087295
                e1->constant |= EXPR_CONST;
881 1087295
                vcc_NextToken(tl);
882 1087295
                *e = e1;
883 1087295
                return;
884
        case '-':
885 660
                if (fmt != INT &&
886 154
                    fmt != REAL &&
887 22
                    fmt != DURATION &&
888 11
                    fmt != STRINGS)
889 0
                        break;
890 649
                vcc_NextToken(tl);
891 649
                if (tl->t->tok != FNUM && tl->t->tok != CNUM) {
892 99
                        vcc_expr_cor(tl, &e1, fmt);
893 99
                        ERRCHK(tl);
894 99
                        *e = vcc_expr_edit(tl, e1->fmt, "-(\v1)", e1, NULL);
895 99
                        return;
896
                }
897 550
                sign = "-";
898
                /* FALLTHROUGH */
899
        case FNUM:
900
        case CNUM:
901 190036
                vcc_number(tl, e, fmt, sign);
902 190036
                return;
903
        case CBLOB:
904 22
                e1 = vcc_new_expr(BLOB);
905 22
                VSB_printf(e1->vsb, "%s", tl->t->dec);
906 22
                AZ(VSB_finish(e1->vsb));
907 22
                e1->constant |= EXPR_STR_CONST;
908 22
                e1->t1 = tl->t;
909 22
                vcc_NextToken(tl);
910 22
                *e = e1;
911 22
                return;
912
        default:
913 44
                break;
914
        }
915 44
        VSB_cat(tl->sb, "Unknown token ");
916 44
        vcc_ErrToken(tl, tl->t);
917 44
        VSB_printf(tl->sb, " when looking for %s\n\n", vcc_utype(fmt));
918 44
        vcc_ErrWhere(tl, tl->t);
919 2631024
}
920
921
/*--------------------------------------------------------------------
922
 * SYNTAX:
923
 *    Expr4:
924
 *      Expr5 [ '.' (type_attribute | type_method()) ]*
925
 */
926
927
void
928 29777
vcc_Eval_TypeMethod(struct vcc *tl, struct expr **e, struct token *t,
929
    struct symbol *sym, vcc_type_t fmt)
930
{
931
        const char *impl;
932
933 29777
        (void)t;
934 29777
        impl = VCC_Type_EvalMethod(tl, sym);
935 29777
        ERRCHK(tl);
936 29777
        AN(impl);
937 29777
        *e = vcc_expr_edit(tl, fmt, impl, *e, NULL);
938 29777
}
939
940
static void
941 2631024
vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt)
942
{
943
        struct symbol *sym;
944
945 2631024
        *e = NULL;
946 2631024
        vcc_expr5(tl, e, fmt);
947 2631024
        ERRCHK(tl);
948 2630496
        AN(*e);
949 2668765
        while (tl->t->tok == '.') {
950 38302
                vcc_NextToken(tl);
951 38302
                ExpectErr(tl, ID);
952
953 38291
                sym = VCC_TypeSymbol(tl, SYM_METHOD, (*e)->fmt);
954 38291
                if (sym == NULL) {
955 22
                        VSB_cat(tl->sb, "Unknown property ");
956 22
                        vcc_ErrToken(tl, tl->t);
957 22
                        VSB_printf(tl->sb, " for type %s\n", (*e)->fmt->name);
958 22
                        vcc_ErrWhere(tl, tl->t);
959 22
                        return;
960
                }
961
962 38269
                AN(sym->eval);
963 38269
                sym->eval(tl, e, tl->t, sym, sym->type);
964 38269
                ERRCHK(tl);
965 38269
                if ((*e)->fmt == STRING) {
966 29656
                        (*e)->fmt = STRINGS;
967 29656
                        (*e)->nstr = 1;
968 29656
                }
969
        }
970 2631024
}
971
972
/*--------------------------------------------------------------------
973
 * SYNTAX:
974
 *    ExprMul:
975
 *      Expr4 { {'*'|'/'|'%'} Expr4 } *
976
 */
977
978
static void
979 2536908
vcc_expr_mul(struct vcc *tl, struct expr **e, vcc_type_t fmt)
980
{
981
        struct expr *e2;
982
        vcc_type_t f2;
983
        struct token *tk;
984
        char buf[24];
985
986 2536908
        *e = NULL;
987 2536908
        vcc_expr4(tl, e, fmt);
988 2536908
        ERRCHK(tl);
989 2536424
        AN(*e);
990
991 2536820
        while (tl->t->tok == '*' || tl->t->tok == '/' || tl->t->tok == '%') {
992 440
                if (tl->t->tok == '%' && ((*e)->fmt != INT)) {
993 11
                        VSB_cat(tl->sb, "Operator % only possible on INT.\n");
994 11
                        vcc_ErrWhere(tl, tl->t);
995 11
                        return;
996
                }
997 429
                f2 = (*e)->fmt->multype;
998 429
                if (f2 == NULL) {
999 22
                        VSB_printf(tl->sb,
1000
                            "Operator %.*s not possible on type %s.\n",
1001 11
                            PF(tl->t), vcc_utype((*e)->fmt));
1002 11
                        vcc_ErrWhere(tl, tl->t);
1003 11
                        return;
1004
                }
1005 418
                tk = tl->t;
1006 418
                vcc_NextToken(tl);
1007 418
                vcc_expr4(tl, &e2, f2);
1008 418
                ERRCHK(tl);
1009 418
                if (e2->fmt != INT && e2->fmt != f2) {
1010 44
                        VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
1011 22
                            vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1012 22
                        vcc_ErrWhere(tl, tk);
1013 22
                        return;
1014
                }
1015 396
                bprintf(buf, "(\v1%c\v2)", tk->tok);
1016 396
                *e = vcc_expr_edit(tl, (*e)->fmt, buf, *e, e2);
1017
        }
1018 2536908
}
1019
1020
/*--------------------------------------------------------------------
1021
 * SYNTAX:
1022
 *    ExprAdd:
1023
 *      ExprMul { {'+'|'-'} ExprMul } *
1024
 */
1025
1026
static const struct adds {
1027
        unsigned        op;
1028
        vcc_type_t      a;
1029
        vcc_type_t      b;
1030
        vcc_type_t      fmt;
1031
} vcc_adds[] = {
1032
        { '+', BYTES,           BYTES,          BYTES },
1033
        { '-', BYTES,           BYTES,          BYTES },
1034
        { '+', DURATION,        DURATION,       DURATION },
1035
        { '-', DURATION,        DURATION,       DURATION },
1036
        { '+', INT,             INT,            INT },
1037
        { '-', INT,             INT,            INT },
1038
        { '+', INT,             REAL,           REAL },
1039
        { '-', INT,             REAL,           REAL },
1040
        { '+', REAL,            INT,            REAL },
1041
        { '-', REAL,            INT,            REAL },
1042
        { '+', REAL,            REAL,           REAL },
1043
        { '-', REAL,            REAL,           REAL },
1044
        { '-', TIME,            TIME,           DURATION },
1045
        { '+', TIME,            DURATION,       TIME },
1046
        { '-', TIME,            DURATION,       TIME },
1047
1048
        { EOI, VOID,            VOID,           VOID }
1049
};
1050
1051
static void
1052 1821655
vcc_expr_add(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1053
{
1054
        const struct adds *ap;
1055
        struct expr  *e2;
1056
        struct token *tk;
1057
        int lit, n;
1058
1059 1821655
        *e = NULL;
1060 1821655
        vcc_expr_mul(tl, e, fmt);
1061 1821655
        ERRCHK(tl);
1062
1063 2536259
        while (tl->t->tok == '+' || tl->t->tok == '-') {
1064 715253
                tk = tl->t;
1065 11435985
                for (ap = vcc_adds; ap->op != EOI; ap++)
1066 10721535
                        if (tk->tok == ap->op && (*e)->fmt == ap->a)
1067 803
                                break;
1068 715253
                vcc_NextToken(tl);
1069 715253
                if (ap->op == EOI && fmt == STRINGS)
1070 5522
                        vcc_expr_mul(tl, &e2, STRINGS);
1071
                else
1072 709731
                        vcc_expr_mul(tl, &e2, (*e)->fmt);
1073 715253
                ERRCHK(tl);
1074
1075 11437327
                for (ap = vcc_adds; ap->op != EOI; ap++)
1076 10722767
                        if (tk->tok == ap->op && (*e)->fmt == ap->a &&
1077 10722767
                            e2->fmt == ap->b)
1078 693
                                break;
1079
1080 715253
                if (ap->op == '+') {
1081 484
                        *e = vcc_expr_edit(tl, ap->fmt, "(\v1 + \v2)", *e, e2);
1082 715253
                } else if (ap->op == '-') {
1083 209
                        *e = vcc_expr_edit(tl, ap->fmt, "(\v1 - \v2)", *e, e2);
1084 714934
                } else if (tk->tok == '+' &&
1085 714549
                    ((*e)->fmt == STRINGS || fmt == STRINGS)) {
1086 714439
                        if ((*e)->fmt != STRINGS)
1087 55
                                vcc_expr_tostring(tl, e, STRINGS);
1088 714439
                        if (e2->fmt != STRINGS)
1089 177826
                                vcc_expr_tostring(tl, &e2, STRINGS);
1090 714439
                        if (vcc_islit(*e) && vcc_isconst(e2)) {
1091 528
                                lit = vcc_islit(e2);
1092 1056
                                *e = vcc_expr_edit(tl, STRINGS,
1093 528
                                    "\v1\n\v2", *e, e2);
1094 528
                                (*e)->constant = EXPR_CONST;
1095 528
                                (*e)->nstr = 1;
1096 528
                                if (lit)
1097 528
                                        (*e)->constant |= EXPR_STR_CONST;
1098 528
                        } else {
1099 713911
                                n = (*e)->nstr + e2->nstr;
1100 1427822
                                *e = vcc_expr_edit(tl, STRINGS,
1101 713911
                                    "\v1,\n\v2", *e, e2);
1102 713911
                                (*e)->constant = EXPR_VAR;
1103 713911
                                (*e)->nstr = n;
1104
                        }
1105 714439
                } else {
1106 242
                        VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
1107 121
                            vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1108 121
                        vcc_ErrWhere2(tl, tk, tl->t);
1109 121
                        return;
1110
                }
1111
        }
1112 1821655
}
1113
1114
/*--------------------------------------------------------------------
1115
 * SYNTAX:
1116
 *    ExprCmp:
1117
 *      ExprAdd
1118
 *      ExprAdd Relation ExprAdd
1119
 *      ExprAdd(STRING) '~' CString
1120
 *      ExprAdd(STRING) '!~' CString
1121
 *      ExprAdd(IP) '==' ExprAdd(IP)
1122
 *      ExprAdd(IP) '!=' ExprAdd(IP)
1123
 *      ExprAdd(IP) '~' ACL
1124
 *      ExprAdd(IP) '!~' ACL
1125
 */
1126
1127
struct cmps;
1128
1129
typedef void cmp_f(struct vcc *, struct expr **, const struct cmps *);
1130
1131
struct cmps {
1132
        vcc_type_t              fmt;
1133
        unsigned                token;
1134
        cmp_f                   *func;
1135
        const char              *emit;
1136
};
1137
1138
static void v_matchproto_(cmp_f)
1139 60533
cmp_simple(struct vcc *tl, struct expr **e, const struct cmps *cp)
1140
{
1141
        struct expr *e2;
1142
        struct token *tk;
1143
1144 60533
        tk = tl->t;
1145 60533
        vcc_NextToken(tl);
1146 60533
        vcc_expr_add(tl, &e2, (*e)->fmt);
1147 60533
        ERRCHK(tl);
1148
1149 60500
        if (e2->fmt != (*e)->fmt) {
1150 44
                VSB_printf(tl->sb,
1151
                    "Comparison of different types: %s '%.*s' %s\n",
1152 22
                    vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1153 22
                vcc_ErrWhere(tl, tk);
1154 22
        } else
1155 60478
                *e = vcc_expr_edit(tl, BOOL, cp->emit, *e, e2);
1156 60533
}
1157
1158
static void v_matchproto_(cmp_f)
1159 89562
cmp_regexp(struct vcc *tl, struct expr **e, const struct cmps *cp)
1160
{
1161
        struct token *t1;
1162
        struct expr *e2;
1163
        char buf[128];
1164
1165 89562
        *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
1166 89562
        vcc_NextToken(tl);
1167 89562
        t1 = tl->t;
1168 89562
        vcc_expr4(tl, &e2, REGEX);
1169 89562
        ERRCHK(tl);
1170 89518
        vcc_expr_typecheck(tl, &e2, REGEX, t1);
1171 89518
        ERRCHK(tl);
1172 89507
        bprintf(buf, "%sVRT_re_match(ctx, \v1, \v2)", cp->emit);
1173 89507
        *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1174 89562
}
1175
1176
static void v_matchproto_(cmp_f)
1177 473
cmp_acl(struct vcc *tl, struct expr **e, const struct cmps *cp)
1178
{
1179
        struct token *t1;
1180
        struct expr *e2;
1181
        char buf[256];
1182
1183 473
        vcc_NextToken(tl);
1184 473
        t1 = tl->t;
1185 473
        vcc_expr4(tl, &e2, ACL);
1186 473
        ERRCHK(tl);
1187 440
        vcc_expr_typecheck(tl, &e2, ACL, t1);
1188 440
        ERRCHK(tl);
1189 407
        bprintf(buf, "%sVRT_acl_match(ctx, \v1, \v2)", cp->emit);
1190 407
        *e = vcc_expr_edit(tl, BOOL, buf, e2, *e);
1191 473
}
1192
1193
static void v_matchproto_(cmp_f)
1194 418528
cmp_string(struct vcc *tl, struct expr **e, const struct cmps *cp)
1195
{
1196
        struct expr *e2;
1197
        struct token *tk;
1198
        char buf[128];
1199
1200 418528
        tk = tl->t;
1201 418528
        vcc_NextToken(tl);
1202 418528
        vcc_expr_add(tl, &e2, STRINGS);
1203 418528
        ERRCHK(tl);
1204 418528
        if (e2->fmt != STRINGS) {
1205 66
                VSB_printf(tl->sb,
1206
                    "Comparison of different types: %s '%.*s' %s\n",
1207 33
                    vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1208 33
                vcc_ErrWhere(tl, tk);
1209 418528
        } else if ((*e)->nstr == 1 && e2->nstr == 1) {
1210 418187
                bprintf(buf, "(%s VRT_strcmp(\v1, \v2))", cp->emit);
1211 418187
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1212 418187
        } else {
1213 308
                bprintf(buf, "(%s VRT_CompareStrands(\vT, \vt))", cp->emit);
1214 308
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1215
        }
1216 418528
}
1217
1218
#define IDENT_REL(typ)                                                  \
1219
        {typ,           T_EQ,           cmp_simple, "(\v1 == \v2)" },   \
1220
        {typ,           T_NEQ,          cmp_simple, "(\v1 != \v2)" }
1221
1222
#define NUM_REL(typ)                                                    \
1223
        IDENT_REL(typ),                                                 \
1224
        {typ,           T_LEQ,          cmp_simple, "(\v1 <= \v2)" },   \
1225
        {typ,           T_GEQ,          cmp_simple, "(\v1 >= \v2)" },   \
1226
        {typ,           '<',            cmp_simple, "(\v1 < \v2)" },    \
1227
        {typ,           '>',            cmp_simple, "(\v1 > \v2)" }
1228
1229
static const struct cmps vcc_cmps[] = {
1230
        NUM_REL(INT),
1231
        NUM_REL(DURATION),
1232
        NUM_REL(BYTES),
1233
        NUM_REL(REAL),
1234
        NUM_REL(TIME),
1235
        IDENT_REL(BACKEND),
1236
        IDENT_REL(ACL),
1237
        IDENT_REL(PROBE),
1238
        IDENT_REL(STEVEDORE),
1239
        IDENT_REL(SUB),
1240
        IDENT_REL(INSTANCE),
1241
1242
        {BOOL,          T_EQ,           cmp_simple, "((!(\v1)) == (!(\v2)))" },
1243
        {BOOL,          T_NEQ,          cmp_simple, "((!(\v1)) != (!(\v2)))" },
1244
        {IP,            T_EQ,           cmp_simple, "!VRT_ipcmp(ctx, \v1, \v2)" },
1245
        {IP,            T_NEQ,          cmp_simple, "VRT_ipcmp(ctx, \v1, \v2)" },
1246
1247
        {IP,            '~',            cmp_acl, "" },
1248
        {IP,            T_NOMATCH,      cmp_acl, "!" },
1249
1250
        {STRINGS,       T_EQ,           cmp_string, "0 =="},
1251
        {STRINGS,       T_NEQ,          cmp_string, "0 !="},
1252
        {STRINGS,       '<',            cmp_string, "0 > "},
1253
        {STRINGS,       '>',            cmp_string, "0 < "},
1254
        {STRINGS,       T_LEQ,          cmp_string, "0 >="},
1255
        {STRINGS,       T_GEQ,          cmp_string, "0 <="},
1256
1257
        {STRINGS,       '~',            cmp_regexp, "" },
1258
        {STRINGS,       T_NOMATCH,      cmp_regexp, "!" },
1259
1260
        {VOID,          0,              NULL, NULL}
1261
};
1262
1263
#undef IDENT_REL
1264
#undef NUM_REL
1265
1266
static void
1267 1342594
vcc_expr_cmp(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1268
{
1269
        const struct cmps *cp;
1270
        struct token *tk;
1271
1272 1342594
        *e = NULL;
1273 1342594
        vcc_expr_add(tl, e, fmt);
1274 1342594
        ERRCHK(tl);
1275 1341978
        tk = tl->t;
1276
1277 70114649
        for (cp = vcc_cmps; cp->fmt != VOID; cp++) {
1278 69341767
                if ((*e)->fmt == cp->fmt && tl->t->tok == cp->token) {
1279 569096
                        AN(cp->func);
1280 569096
                        cp->func(tl, e, cp);
1281 569096
                        return;
1282
                }
1283 68772671
        }
1284
1285 772882
        switch (tk->tok) {
1286
        case T_EQ:
1287
        case T_NEQ:
1288
        case '<':
1289
        case T_LEQ:
1290
        case '>':
1291
        case T_GEQ:
1292
        case '~':
1293
        case T_NOMATCH:
1294 44
                VSB_printf(tl->sb, "Operator %.*s not possible on %s\n",
1295 22
                    PF(tl->t), vcc_utype((*e)->fmt));
1296 22
                vcc_ErrWhere(tl, tl->t);
1297 22
                return;
1298
        default:
1299 772860
                break;
1300
        }
1301 1342594
}
1302
1303
/*--------------------------------------------------------------------
1304
 * SYNTAX:
1305
 *    ExprNot:
1306
 *      '!' ExprCmp
1307
 */
1308
1309
static void
1310 1342594
vcc_expr_not(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1311
{
1312
        struct token *tk;
1313
1314 1342594
        *e = NULL;
1315 1342594
        tk = tl->t;
1316 1342594
        if (tl->t->tok == '!')
1317 59928
                vcc_NextToken(tl);
1318 1342594
        vcc_expr_cmp(tl, e, fmt);
1319 1342594
        ERRCHK(tl);
1320 1341747
        if (tk->tok != '!')
1321 1281830
                return;
1322 59917
        vcc_expr_tobool(tl, e);
1323 59917
        ERRCHK(tl);
1324 59917
        if ((*e)->fmt != BOOL) {
1325 11
                VSB_cat(tl->sb, "'!' must be followed by BOOL, found ");
1326 11
                VSB_printf(tl->sb, "%s.\n", vcc_utype((*e)->fmt));
1327 11
                vcc_ErrWhere2(tl, tk, tl->t);
1328 11
        } else {
1329 59906
                *e = vcc_expr_edit(tl, BOOL, "!(\v1)", *e, NULL);
1330
        }
1331 1342594
}
1332
1333
/*--------------------------------------------------------------------
1334
 * CAND and COR are identical save for a few details, but they are
1335
 * stacked so handling them in the same function is not simpler.
1336
 * Instead have them both call this helper function to do everything.
1337
 */
1338
1339
typedef void upfunc(struct vcc *tl, struct expr **e, vcc_type_t fmt);
1340
1341
static void
1342 2005410
vcc_expr_bin_bool(struct vcc *tl, struct expr **e, vcc_type_t fmt,
1343
    unsigned ourtok, upfunc *up, const char *tokstr)
1344
{
1345
        struct expr *e2;
1346
        struct token *tk;
1347
        char buf[32];
1348
1349 2005410
        *e = NULL;
1350 2005410
        tk = tl->t;
1351 2005410
        up(tl, e, fmt);
1352 2005410
        ERRCHK(tl);
1353 2003672
        if (tl->t->tok != ourtok)
1354 1855656
                return;
1355 148016
        vcc_expr_tobool(tl, e);
1356 148016
        ERRCHK(tl);
1357 148016
        if ((*e)->fmt != BOOL) {
1358 44
                VSB_printf(tl->sb,
1359
                    "'%s' must be preceeded by BOOL,"
1360 22
                    " found %s.\n", tokstr, vcc_utype((*e)->fmt));
1361 22
                vcc_ErrWhere2(tl, tk, tl->t);
1362 22
                return;
1363
        }
1364 147994
        *e = vcc_expr_edit(tl, BOOL, "(\v+\n\v1", *e, NULL);
1365 502711
        while (tl->t->tok == ourtok) {
1366 354739
                vcc_NextToken(tl);
1367 354739
                tk = tl->t;
1368 354739
                up(tl, &e2, fmt);
1369 354739
                ERRCHK(tl);
1370 354739
                vcc_expr_tobool(tl, &e2);
1371 354739
                ERRCHK(tl);
1372 354739
                if (e2->fmt != BOOL) {
1373 44
                        VSB_printf(tl->sb,
1374
                            "'%s' must be followed by BOOL,"
1375 22
                            " found %s.\n", tokstr, vcc_utype(e2->fmt));
1376 22
                        vcc_ErrWhere2(tl, tk, tl->t);
1377 22
                        vcc_delete_expr(e2);
1378 22
                        return;
1379
                }
1380 354717
                bprintf(buf, "\v1\v-\n%s\v+\n\v2", tokstr);
1381 354717
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1382
        }
1383 147972
        *e = vcc_expr_edit(tl, BOOL, "\v1\v-\n)", *e, NULL);
1384 2005410
}
1385
1386
/*--------------------------------------------------------------------
1387
 * SYNTAX:
1388
 *    ExprCand:
1389
 *      ExprNot { '&&' ExprNot } *
1390
 */
1391
1392
static void
1393 1017555
vcc_expr_cand(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1394
{
1395
1396 1017555
        vcc_expr_bin_bool(tl, e, fmt, T_CAND, vcc_expr_not, "&&");
1397 1017555
}
1398
1399
/*--------------------------------------------------------------------
1400
 * SYNTAX:
1401
 *    ExprCOR:
1402
 *      ExprCand { '||' ExprCand } *
1403
 */
1404
1405
static void
1406 987855
vcc_expr_cor(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1407
{
1408
1409 987855
        vcc_expr_bin_bool(tl, e, fmt, T_COR, vcc_expr_cand, "||");
1410 987855
}
1411
1412
/*--------------------------------------------------------------------
1413
 * This function is the entry-point for getting an expression with
1414
 * a particular type, ready for inclusion in the VGC.
1415
 */
1416
1417
static void
1418 957792
vcc_expr0(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1419
{
1420
        struct token *t1;
1421
1422 957792
        assert(fmt != VOID);
1423 957792
        assert(fmt != STRINGS);
1424 957792
        *e = NULL;
1425 957792
        t1 = tl->t;
1426 957792
        if (fmt->stringform)
1427 303160
                vcc_expr_cor(tl, e, STRINGS);
1428
        else
1429 654632
                vcc_expr_cor(tl, e, fmt);
1430 957792
        ERRCHK(tl);
1431
1432 956890
        if ((*e)->fmt == fmt)
1433 475706
                return;
1434
1435 481184
        if ((*e)->fmt != STRINGS && fmt->stringform)
1436 36113
                vcc_expr_tostring(tl, e, STRINGS);
1437
1438 481184
        if ((*e)->fmt->stringform) {
1439 0
                VSB_printf(tl->sb, "Cannot convert type %s(%s) to %s(%s)\n",
1440 0
                    vcc_utype((*e)->fmt), (*e)->fmt->name,
1441 0
                    vcc_utype(fmt), fmt->name);
1442 0
                vcc_ErrWhere2(tl, t1, tl->t);
1443 0
                return;
1444
        }
1445
1446 481184
        if (fmt == BODY && !(*e)->fmt->bodyform)
1447 11
                vcc_expr_tostring(tl, e, STRINGS);
1448
1449 481184
        if (fmt == BODY && (*e)->fmt->bodyform) {
1450 59312
                if ((*e)->fmt == STRINGS)
1451 59268
                        *e = vcc_expr_edit(tl, BODY, "STRING, 0, \vT", *e, NULL);
1452 44
                else if ((*e)->fmt == BLOB)
1453 44
                        *e = vcc_expr_edit(tl, BODY, "BLOB, 0, \v1", *e, NULL);
1454
                else
1455 0
                        WRONG("Unhandled bodyform");
1456 59312
        }
1457
1458 481184
        if ((*e)->fmt == STRINGS && fmt->stringform) {
1459 302830
                if (fmt == STRING)
1460 37719
                        *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
1461 265111
                else if (fmt == STRANDS)
1462 265111
                        *e = vcc_expr_edit(tl, STRANDS, "\vT", (*e), NULL);
1463
                else
1464 0
                        WRONG("Unhandled stringform");
1465 302830
        }
1466
1467 481184
        if (fmt == BOOL) {
1468 118998
                vcc_expr_tobool(tl, e);
1469 118998
                ERRCHK(tl);
1470 118998
        }
1471
1472 481184
        vcc_expr_typecheck(tl, e, fmt, t1);
1473 957792
}
1474
1475
static void
1476 571142
vcc_expr_typecheck(struct vcc *tl, struct expr **e, vcc_type_t fmt,
1477
    struct token *t1)
1478
{
1479
1480 571142
        assert(fmt != VOID);
1481 571142
        assert(fmt != STRINGS);
1482
1483 571142
        if (fmt != (*e)->fmt)  {
1484 198
                VSB_printf(tl->sb, "Expression has type %s, expected %s\n",
1485 99
                    vcc_utype((*e)->fmt), vcc_utype(fmt));
1486 99
                vcc_ErrWhere2(tl, t1, tl->t);
1487 99
        }
1488 571142
}
1489
1490
/*--------------------------------------------------------------------
1491
 * This function parses and emits the C-code to evaluate an expression
1492
 *
1493
 * We know up front what kind of type we want the expression to be,
1494
 * and this function is the backstop if that doesn't succeed.
1495
 */
1496
1497
void
1498 928037
vcc_Expr(struct vcc *tl, vcc_type_t fmt)
1499
{
1500 928037
        struct expr *e = NULL;
1501
1502 928037
        assert(fmt != VOID);
1503 928037
        assert(fmt != STRINGS);
1504 928037
        vcc_expr0(tl, &e, fmt);
1505 928037
        ERRCHK(tl);
1506 927179
        assert(e->fmt == fmt);
1507
1508 927179
        vcc_expr_fmt(tl->fb, tl->indent, e);
1509 927179
        VSB_cat(tl->fb, "\n");
1510 927179
        vcc_delete_expr(e);
1511 928037
}
1512
1513
/*--------------------------------------------------------------------
1514
 */
1515
1516
void v_matchproto_(sym_act_f)
1517 4994
vcc_Act_Call(struct vcc *tl, struct token *t, struct symbol *sym)
1518
{
1519
1520
        struct expr *e;
1521
1522 4994
        e = NULL;
1523 4994
        vcc_func(tl, &e, sym->eval_priv, sym->extra, sym);
1524 4994
        if (!tl->err) {
1525 4939
                vcc_expr_fmt(tl->fb, tl->indent, e);
1526 4939
                SkipToken(tl, ';');
1527 4939
                VSB_cat(tl->fb, ";\n");
1528 4994
        } else if (t != tl->t) {
1529 55
                VSB_cat(tl->sb, "While compiling function call:\n\n");
1530 55
                vcc_ErrWhere2(tl, t, tl->t);
1531 55
        }
1532 4994
        vcc_delete_expr(e);
1533 4994
}
1534
1535
void v_matchproto_(sym_act_f)
1536 3674
vcc_Act_Obj(struct vcc *tl, struct token *t, struct symbol *sym)
1537
{
1538
1539 3674
        struct expr *e = NULL;
1540
1541 3674
        assert(sym->kind == SYM_INSTANCE);
1542 3674
        ExpectErr(tl, '.');
1543 3663
        tl->t = t;
1544 3663
        vcc_expr4(tl, &e, sym->type);
1545 3663
        ERRCHK(tl);
1546 3663
        vcc_expr_fmt(tl->fb, tl->indent, e);
1547 3663
        vcc_delete_expr(e);
1548 3663
        SkipToken(tl, ';');
1549 3663
        VSB_cat(tl->fb, ";\n");
1550 3674
}
1551
1552
/*--------------------------------------------------------------------
1553
 */
1554
1555
static void v_matchproto_(sym_expr_t)
1556 407
vcc_Eval_Regsub(struct vcc *tl, struct expr **e, struct token *t,
1557
    struct symbol *sym, vcc_type_t fmt)
1558
{
1559
        struct expr *e2, *e3;
1560 407
        int all = sym->eval_priv == NULL ? 0 : 1;
1561
        char buf[128];
1562
1563 407
        (void)t;
1564 407
        (void)fmt;
1565 407
        SkipToken(tl, '(');
1566 407
        vcc_expr0(tl, &e2, STRING);
1567 407
        ERRCHK(tl);
1568 407
        SkipToken(tl, ',');
1569 407
        vcc_expr0(tl, &e3, REGEX);
1570 407
        ERRCHK(tl);
1571
1572 396
        bprintf(buf, "VRT_regsub(ctx, %d,\v+\n\v1,\n\v2", all);
1573 396
        *e = vcc_expr_edit(tl, STRING, buf, e2, e3);
1574 396
        SkipToken(tl, ',');
1575 396
        vcc_expr0(tl, &e2, STRING);
1576 396
        ERRCHK(tl);
1577 396
        *e = vcc_expr_edit(tl, STRINGS, "\v1,\n\v2)\v-", *e, e2);
1578 396
        (*e)->nstr = 1;
1579 396
        SkipToken(tl, ')');
1580 407
}
1581
1582
/*--------------------------------------------------------------------
1583
 */
1584
1585
static void v_matchproto_(sym_expr_t)
1586 32241
vcc_Eval_BoolConst(struct vcc *tl, struct expr **e, struct token *t,
1587
    struct symbol *sym, vcc_type_t fmt)
1588
{
1589
1590 32241
        (void)t;
1591 32241
        (void)tl;
1592 32241
        (void)fmt;
1593 32241
        *e = vcc_mk_expr(BOOL, "(0==%d)", sym->eval_priv == NULL ? 1 : 0);
1594 32241
        (*e)->constant = EXPR_CONST;
1595 32241
}
1596
1597
/*--------------------------------------------------------------------
1598
 */
1599
1600
static void v_matchproto_(sym_expr_t)
1601 44
vcc_Eval_Default(struct vcc *tl, struct expr **e, struct token *t,
1602
    struct symbol *sym, vcc_type_t fmt)
1603
{
1604 44
        (void)e;
1605 44
        (void)fmt;
1606 44
        (void)sym;
1607 44
        (void)t;
1608
1609 44
        if (fmt == PROBE)
1610 0
                *e = vcc_mk_expr(PROBE, "%s", vcc_default_probe(tl));
1611 44
        else if (fmt == BACKEND)
1612 22
                *e = vcc_mk_expr(BACKEND, "*(VCL_conf.default_director)");
1613
        else {
1614 22
                VSB_cat(tl->sb, "Symbol 'default' is a reserved word.\n");
1615 22
                vcc_ErrWhere(tl, t);
1616
        }
1617 44
}
1618
1619
/*--------------------------------------------------------------------
1620
 */
1621
1622
void
1623 32087
vcc_Expr_Init(struct vcc *tl)
1624
{
1625
        struct symbol *sym;
1626
1627 32087
        sym = VCC_MkSym(tl, "regsub", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1628 32087
        AN(sym);
1629 32087
        sym->type = STRING;
1630 32087
        sym->eval = vcc_Eval_Regsub;
1631 32087
        sym->eval_priv = NULL;
1632
1633 32087
        sym = VCC_MkSym(tl, "regsuball", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1634 32087
        AN(sym);
1635 32087
        sym->type = STRING;
1636 32087
        sym->eval = vcc_Eval_Regsub;
1637 32087
        sym->eval_priv = sym;
1638
1639 32087
        sym = VCC_MkSym(tl, "true", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1640 32087
        AN(sym);
1641 32087
        sym->type = BOOL;
1642 32087
        sym->eval = vcc_Eval_BoolConst;
1643 32087
        sym->eval_priv = sym;
1644
1645 32087
        sym = VCC_MkSym(tl, "false", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1646 32087
        AN(sym);
1647 32087
        sym->type = BOOL;
1648 32087
        sym->eval = vcc_Eval_BoolConst;
1649 32087
        sym->eval_priv = NULL;
1650
1651 32087
        sym = VCC_MkSym(tl, "default", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1652 32087
        AN(sym);
1653 32087
        sym->type = BACKEND;    // ... can also (sometimes) deliver PROBE
1654 32087
        sym->eval = vcc_Eval_Default;
1655 32087
}