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