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 138000
vcc_isconst(const struct expr *e)
63
{
64 138000
        AN(e->constant);
65 138000
        return (e->constant & EXPR_CONST);
66
}
67
68
static inline int
69 1626125
vcc_islit(const struct expr *e)
70
{
71 1626125
        AN(e->constant);
72 1626125
        return (e->constant & EXPR_STR_CONST);
73
}
74
75
static const char *
76 1675
vcc_utype(vcc_type_t t)
77
{
78 1675
        if (t == STRINGS || t->stringform)
79 450
                t = STRING;
80 1675
        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 13680100
vcc_new_expr(vcc_type_t fmt)
90
{
91
        struct expr *e;
92
93 13680100
        ALLOC_OBJ(e, EXPR_MAGIC);
94 13680100
        AN(e);
95 13680100
        e->vsb = VSB_new_auto();
96 13680100
        e->fmt = fmt;
97 13680100
        e->constant = EXPR_VAR;
98 13680100
        return (e);
99
}
100
101
static struct expr * v_printflike_(2, 3)
102 3521500
vcc_mk_expr(vcc_type_t fmt, const char *str, ...)
103
{
104
        va_list ap;
105
        struct expr *e;
106
107 3521500
        e = vcc_new_expr(fmt);
108 3521500
        va_start(ap, str);
109 3521500
        VSB_vprintf(e->vsb, str, ap);
110 3521500
        va_end(ap);
111 3521500
        AZ(VSB_finish(e->vsb));
112 3521500
        return (e);
113
}
114
115
static void
116 17467375
vcc_delete_expr(struct expr *e)
117
{
118 17467375
        if (e == NULL)
119 3808625
                return;
120 13658750
        CHECK_OBJ(e, EXPR_MAGIC);
121 13658750
        VSB_destroy(&e->vsb);
122 13658750
        FREE_OBJ(e);
123 17467375
}
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 1212625
vcc_strands_edit(const struct expr *e1, const struct expr *e2)
152
{
153
154 1212625
        if (e2->nstr == 1) {
155 1072875
                VSB_printf(e1->vsb, "TOSTRAND(%s)", VSB_data(e2->vsb));
156 1072875
                return;
157
        }
158
159 279500
        VSB_printf(e1->vsb, "TOSTRANDS(%d,\v+\n%s\v-)",
160 139750
            e2->nstr, VSB_data(e2->vsb));
161 1212625
}
162
163
static struct expr *
164 7666925
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 7666925
        int nl = 1;
169
170 7666925
        (void) tl;
171
172 7666925
        AN(e1);
173 7666925
        e = vcc_new_expr(fmt);
174 91638200
        while (*p != '\0') {
175 83971275
                if (*p != '\v') {
176 70080150
                        if (*p != '\n' || !nl)
177 70078950
                                VSB_putc(e->vsb, *p);
178 70080150
                        nl = (*p == '\n');
179 70080150
                        p++;
180 70080150
                        continue;
181
                }
182 13891125
                assert(*p == '\v');
183 13891125
                switch (*++p) {
184 1144275
                case '+': VSB_cat(e->vsb, "\v+"); nl = 0; break;
185 1221500
                case '-': VSB_cat(e->vsb, "\v-"); nl = 0; break;
186
                case 'S':
187
                case 's':
188 289475
                        e3 = (*p == 'S' ? e1 : e2);
189 289475
                        AN(e3);
190 289475
                        assert(e1->fmt == STRINGS);
191 289475
                        if (e3->nstr > 1) {
192 650
                                VSB_cat(e->vsb,
193
                                    "\nVRT_STRANDS_string(ctx,\v+\n");
194 650
                                vcc_strands_edit(e, e3);
195 650
                                VSB_cat(e->vsb,
196
                                    "\v-\n)\n");
197 650
                        } else {
198 288825
                                VSB_cat(e->vsb, VSB_data(e3->vsb));
199
                        }
200 289475
                        break;
201
                case 'T':
202
                case 't':
203 1211975
                        e3 = (*p == 'T' ? e1 : e2);
204 1211975
                        AN(e3);
205 1211975
                        vcc_strands_edit(e, e3);
206 1211975
                        break;
207
                case '1':
208 6166175
                        VSB_cat(e->vsb, VSB_data(e1->vsb));
209 6166175
                        break;
210
                case '2':
211 3857725
                        AN(e2);
212 3857725
                        VSB_cat(e->vsb, VSB_data(e2->vsb));
213 3857725
                        break;
214
                default:
215 0
                        WRONG("Illegal edit in VCC expression");
216 0
                }
217 13891125
                p++;
218
        }
219 7666925
        AZ(VSB_finish(e->vsb));
220 7666925
        e->t1 = e1->t1;
221 7666925
        e->t2 = e1->t2;
222 7666925
        if (e2 != NULL)
223 3858425
                e->t2 = e2->t2;
224 7666925
        vcc_delete_expr(e1);
225 7666925
        vcc_delete_expr(e2);
226 7666925
        return (e);
227
}
228
229
/*--------------------------------------------------------------------
230
 * Expand finished expression into C-source code
231
 */
232
233
static void
234 2133350
vcc_expr_fmt(struct vsb *d, int ind, const struct expr *e1)
235
{
236
        char *p;
237
        int i;
238
239 2133350
        if (!e1->fmt->noindent) {
240 18972600
                for (i = 0; i < ind; i++)
241 16974150
                        VSB_putc(d, ' ');
242 1998450
        }
243 2133350
        p = VSB_data(e1->vsb);
244 210097015
        while (*p != '\0') {
245 207963765
                if (*p == '\n') {
246 6207650
                        VSB_putc(d, '\n');
247 6207650
                        if (*++p == '\0')
248 100
                                break;
249 66702100
                        for (i = 0; i < ind; i++)
250 60494550
                                VSB_putc(d, ' ');
251 207963665
                } else if (*p != '\v') {
252 199032715
                        VSB_putc(d, *p++);
253 199032715
                } else {
254 2723400
                        switch (*++p) {
255 1361700
                        case '+': ind += INDENT; break;
256 1361700
                        case '-': ind -= INDENT; break;
257 0
                        default:  WRONG("Illegal format in VCC expression");
258 0
                        }
259 2723400
                        p++;
260
                }
261
        }
262 2133350
}
263
264
/*--------------------------------------------------------------------
265
 */
266
267
static void
268 1550400
vcc_expr_tobool(struct vcc *tl, struct expr **e)
269
{
270
271 1550400
        if ((*e)->fmt == BOOL)
272 1144550
                return;
273 405850
        if ((*e)->fmt == BACKEND || (*e)->fmt == INT)
274 250
                *e = vcc_expr_edit(tl, BOOL, "(\v1 != 0)", *e, NULL);
275 405600
        else if ((*e)->fmt == DURATION)
276 50
                *e = vcc_expr_edit(tl, BOOL, "(\v1 > 0)", *e, NULL);
277 405550
        else if ((*e)->fmt == STRINGS)
278 405400
                *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 1550400
}
285
286
/*--------------------------------------------------------------------
287
 */
288
289
static void
290 1317825
vcc_expr_tostring(struct vcc *tl, struct expr **e, vcc_type_t fmt)
291
{
292
        const char *p;
293 1317825
        uint8_t constant = EXPR_VAR;
294
295 1317825
        CHECK_OBJ_NOTNULL(*e, EXPR_MAGIC);
296 1317825
        assert(fmt == STRINGS || fmt->stringform);
297 1317825
        assert(fmt != (*e)->fmt);
298
299 1317825
        p = (*e)->fmt->tostring;
300 1317825
        if (p != NULL) {
301 1317800
                AN(*p);
302 1317800
                *e = vcc_expr_edit(tl, fmt, p, *e, NULL);
303 1317800
                (*e)->constant = constant;
304 1317800
                (*e)->nstr = 1;
305 1317800
        } else {
306 50
                VSB_printf(tl->sb,
307
                    "Cannot convert %s to STRING.\n",
308 25
                    vcc_utype((*e)->fmt));
309 25
                vcc_ErrWhere2(tl, (*e)->t1, tl->t);
310
        }
311 1317825
}
312
313
/*--------------------------------------------------------------------
314
 */
315
316
void v_matchproto_(sym_expr_t)
317 10225
vcc_Eval_Handle(struct vcc *tl, struct expr **e, struct token *t,
318
    struct symbol *sym, vcc_type_t type)
319
{
320
321 10225
        (void)t;
322 10225
        (void)tl;
323 10225
        AN(sym->rname);
324 10225
        AZ(type->stringform);
325
326 10350
        if (sym->type->tostring == NULL &&
327 125
            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 10225
                *e = vcc_mk_expr(sym->type, "%s", sym->rname);
333 10225
                (*e)->constant = EXPR_VAR;
334 10225
                (*e)->nstr = 1;
335 10225
                if ((*e)->fmt == STRING)
336 0
                        (*e)->fmt = STRINGS;
337
        }
338 10225
}
339
340
void v_matchproto_(sym_expr_t)
341 575
vcc_Eval_Sub(struct vcc *tl, struct expr **e, struct token *t,
342
    struct symbol *sym, vcc_type_t type)
343
{
344
345 575
        (void)t;
346 575
        (void)tl;
347 575
        AN(sym->rname);
348 575
        AZ(type->stringform);
349
350 575
        assert (sym->type == SUB);
351
352 575
        if (type == SUB) {
353 500
                *e = vcc_mk_expr(sym->type, "%s", sym->rname);
354 500
                (*e)->constant = EXPR_CONST;
355 500
                return;
356
        }
357
358 150
        VSB_printf(tl->sb, "Symbol '%s' can only be used as a %s expression\n",
359 75
            sym->name, sym->type->name);
360 75
        vcc_ErrWhere(tl, tl->t);
361 575
}
362
363
/*--------------------------------------------------------------------
364
 */
365
366
void v_matchproto_(sym_expr_t)
367 2873150
vcc_Eval_Var(struct vcc *tl, struct expr **e, struct token *t,
368
    struct symbol *sym, vcc_type_t type)
369
{
370
371 2873150
        (void)type;
372 2873150
        vcc_AddUses(tl, t, NULL, sym, XREF_READ);
373 2873150
        ERRCHK(tl);
374 2873150
        *e = vcc_mk_expr(sym->type, "%s", sym->rname);
375 2873150
        (*e)->constant = EXPR_VAR;
376 2873150
        (*e)->nstr = 1;
377 2873150
        if ((*e)->fmt == STRING)
378 1357000
                (*e)->fmt = STRINGS;
379 2873150
}
380
381
void v_matchproto_(sym_expr_t)
382 250
vcc_Eval_ProtectedHeader(struct vcc *tl, struct expr **e, struct token *t,
383
    struct symbol *sym, vcc_type_t type)
384
{
385
386 250
        AN(sym);
387 250
        AZ(sym->lorev);
388
389 250
        vcc_Header_Fh(tl, sym);
390 250
        sym->eval = vcc_Eval_Var;
391 250
        vcc_Eval_Var(tl, e, t, sym, type);
392 250
}
393
394
/*--------------------------------------------------------------------
395
 */
396
397
static struct expr *
398 4300
vcc_priv_arg(struct vcc *tl, const char *p, struct symbol *sym)
399
{
400
        char buf[64];
401
        struct inifin *ifp;
402 4300
        const char *f = NULL;
403 4300
        struct procprivhead *marklist = NULL;
404
405 4300
        AN(sym);
406 4300
        AN(sym->vmod_name);
407
408 4300
        if (!strcmp(p, "PRIV_VCL"))
409 375
                return (vcc_mk_expr(VOID, "&vmod_priv_%s", sym->vmod_name));
410
411 3925
        if (!strcmp(p, "PRIV_CALL")) {
412 550
                bprintf(buf, "vmod_priv_%u", tl->unique++);
413 550
                ifp = New_IniFin(tl);
414 550
                Fh(tl, 0, "static struct vmod_priv %s;\n", buf);
415 550
                VSB_printf(ifp->fin, "\tVRT_priv_fini(ctx, &%s);", buf);
416 550
                return (vcc_mk_expr(VOID, "&%s", buf));
417
        }
418
419 3375
        if (!strcmp(p, "PRIV_TASK")) {
420 3175
                f = "task";
421 3175
                marklist = &tl->curproc->priv_tasks;
422 3375
        } else if (!strcmp(p, "PRIV_TOP")) {
423 200
                f = "top";
424 200
                sym->r_methods &= VCL_MET_TASK_C;
425 200
                marklist = &tl->curproc->priv_tops;
426 200
        } else {
427 0
                WRONG("Wrong PRIV_ type");
428
        }
429 3375
        AN(f);
430 3375
        AN(marklist);
431 3375
        bprintf(buf, "ARG_priv_%s_%s", f, sym->vmod_name);
432
433 3375
        if (vcc_MarkPriv(tl, marklist, sym->vmod_name) == NULL)
434 2150
                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 1075
                           buf, f, sym->vmod_name, buf, f, sym->vmod_name);
443 3375
        return (vcc_mk_expr(VOID, "%s", buf));
444 4300
}
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 45225
vcc_do_enum(struct vcc *tl, struct func_arg *fa, int len, const char *ptr)
460
{
461
        const char *r;
462
463 45225
        (void)tl;
464 45225
        r = strchr(fa->cname, '.');
465 45225
        AN(r);
466 45225
        fa->result = vcc_mk_expr(VOID, "*%.*s.enum_%.*s",
467 45225
            (int)(r - fa->cname), fa->cname, len, ptr);
468 45225
}
469
470
static void
471 98100
vcc_do_arg(struct vcc *tl, struct func_arg *fa)
472
{
473
        struct expr *e2;
474
        struct vjsn_val *vv;
475
476 98100
        if (fa->type == ENUM) {
477 33225
                ExpectErr(tl, ID);
478 33225
                ERRCHK(tl);
479 113750
                VTAILQ_FOREACH(vv, &fa->enums->children, list)
480 113700
                        if (vcc_IdIs(tl->t, vv->value))
481 33175
                                break;
482 33225
                if (vv == NULL) {
483 50
                        VSB_cat(tl->sb, "Wrong enum value.");
484 50
                        VSB_cat(tl->sb, "  Expected one of:\n");
485 250
                        VTAILQ_FOREACH(vv, &fa->enums->children, list)
486 200
                                VSB_printf(tl->sb, "\t%s\n", vv->value);
487 50
                        vcc_ErrWhere(tl, tl->t);
488 50
                        return;
489
                }
490 33175
                vcc_do_enum(tl, fa, PF(tl->t));
491 33175
                SkipToken(tl, ID);
492 33175
        } else {
493 64875
                if (fa->type == SUB)
494 500
                        tl->subref++;
495 64875
                vcc_expr0(tl, &e2, fa->type);
496 64875
                ERRCHK(tl);
497 64675
                assert(e2->fmt == fa->type);
498 64675
                fa->result = e2;
499
        }
500 97850
        fa->avail = 1;
501 98100
}
502
503
static void
504 67750
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 67750
        CAST_OBJ_NOTNULL(vv, priv, VJSN_VAL_MAGIC);
519 67750
        assert(vjsn_is_array(vv));
520 67750
        vv = VTAILQ_FIRST(&vv->children);
521 67750
        rfmt = VCC_Type(VTAILQ_FIRST(&vv->children)->value);
522 67750
        AN(rfmt);
523 67750
        vv = VTAILQ_NEXT(vv, list);
524 67750
        cfunc = vv->value;
525 67750
        vv = VTAILQ_NEXT(vv, list);
526 67750
        sa = vv->value;
527 67750
        if (*sa == '\0') {
528 57775
                sa = NULL;
529 57775
        }
530 67750
        vv = VTAILQ_NEXT(vv, list);
531 67750
        if (sym->kind == SYM_METHOD) {
532 19350
                if (*e == NULL) {
533 50
                        VSB_cat(tl->sb, "Syntax error.");
534 50
                        tl->err = 1;
535 50
                        return;
536
                }
537 19300
                vcc_NextToken(tl);
538 19300
                AZ(extra);
539 19300
                AN((*e)->instance);
540 19300
                extra = (*e)->instance->rname;
541 19300
        }
542 67700
        tf = VTAILQ_PREV(tl->t, tokenhead, list);
543 67700
        SkipToken(tl, '(');
544 67700
        if (extra == NULL) {
545 43375
                extra = "";
546 43375
                extra_sep = "";
547 43375
        } else {
548 24325
                AN(*extra);
549 24325
                extra_sep = ", ";
550
        }
551 67700
        VTAILQ_INIT(&head);
552 227300
        for (;vv != NULL; vv = VTAILQ_NEXT(vv, list)) {
553 159600
                assert(vjsn_is_array(vv));
554 159600
                fa = calloc(1, sizeof *fa);
555 159600
                AN(fa);
556 159600
                fa->cname = cfunc;
557 159600
                VTAILQ_INSERT_TAIL(&head, fa, list);
558
559 159600
                vvp = VTAILQ_FIRST(&vv->children);
560 159600
                if (!memcmp(vvp->value, "PRIV_", 5)) {
561 4300
                        fa->result = vcc_priv_arg(tl, vvp->value, sym);
562 4300
                        vvp = VTAILQ_NEXT(vvp, list);
563 4300
                        if (vvp != NULL)
564 75
                                fa->name = vvp->value;
565 4300
                        continue;
566
                }
567 155300
                fa->type = VCC_Type(vvp->value);
568 155300
                AN(fa->type);
569 155300
                vvp = VTAILQ_NEXT(vvp, list);
570 155300
                if (vvp != NULL) {
571 145475
                        fa->name = vvp->value;
572 145475
                        vvp = VTAILQ_NEXT(vvp, list);
573 145475
                        if (vvp != NULL) {
574 106950
                                fa->val = vvp->value;
575 106950
                                vvp = VTAILQ_NEXT(vvp, list);
576 106950
                                if (vvp != NULL) {
577 87250
                                        fa->enums = vvp;
578 87250
                                        vvp = VTAILQ_NEXT(vvp, list);
579 87250
                                }
580 106950
                        }
581 145475
                }
582 155300
                if (sa != NULL && vvp != NULL && vjsn_is_true(vvp)) {
583 45100
                        fa->optional = 1;
584 45100
                        vvp = VTAILQ_NEXT(vvp, list);
585 45100
                }
586 155300
                AZ(vvp);
587 155300
        }
588
589 109425
        VTAILQ_FOREACH(fa, &head, list) {
590 98075
                if (tl->t->tok == ')')
591 2150
                        break;
592 95925
                if (fa->result != NULL)
593 3075
                        continue;
594 92850
                if (tl->t->tok == ID) {
595 68400
                        t1 = VTAILQ_NEXT(tl->t, list);
596 68400
                        if (t1->tok == '=')
597 18725
                                break;
598 49675
                }
599 74125
                vcc_do_arg(tl, fa);
600 74125
                if (tl->err)
601 500
                        VSB_printf(tl->sb, "Expected argument: %s %s\n\n",
602 250
                            fa->type->name,
603 250
                            fa->name ? fa->name : "(unnamed argument)");
604 74125
                ERRCHK(tl);
605 73875
                if (tl->t->tok == ')')
606 35225
                        break;
607 38650
                SkipToken(tl, ',');
608 38650
        }
609 72750
        while (tl->t->tok == ID) {
610 78075
                VTAILQ_FOREACH(fa, &head, list) {
611 78050
                        if (fa->name == NULL)
612 300
                                continue;
613 77750
                        if (vcc_IdIs(tl->t, fa->name))
614 24000
                                break;
615 53750
                }
616 24025
                if (fa == NULL) {
617 50
                        VSB_printf(tl->sb, "Unknown argument '%.*s'\n",
618 25
                            PF(tl->t));
619 25
                        vcc_ErrWhere(tl, tl->t);
620 25
                        return;
621
                }
622 24000
                if (fa->result != NULL) {
623 25
                        AN(fa->name);
624 50
                        VSB_printf(tl->sb, "Argument '%s' already used\n",
625 25
                            fa->name);
626 25
                        vcc_ErrWhere(tl, tl->t);
627 25
                        return;
628
                }
629 23975
                vcc_NextToken(tl);
630 23975
                SkipToken(tl, '=');
631 23975
                vcc_do_arg(tl, fa);
632 23975
                ERRCHK(tl);
633 23975
                if (tl->t->tok == ')')
634 18675
                        break;
635 5300
                SkipToken(tl, ',');
636
        }
637
638 67400
        if (sa != NULL)
639 19750
                e1 = vcc_mk_expr(rfmt, "%s(ctx%s%s,\v+\n&(%s)\v+ {\n",
640 9875
                    cfunc, extra_sep, extra, sa);
641
        else
642 115050
                e1 = vcc_mk_expr(rfmt, "%s(ctx%s%s\v+",
643 57525
                    cfunc, extra_sep, extra);
644 67400
        n = 0;
645 226175
        VTAILQ_FOREACH_SAFE(fa, &head, list, fa2) {
646 158775
                n++;
647 158775
                if (fa->optional) {
648 44950
                        AN(fa->name);
649 44950
                        bprintf(ssa, "\v1.valid_%s = %d,\n",
650
                            fa->name, fa->avail);
651 44950
                        e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, NULL);
652 44950
                }
653 158775
                if (fa->result == NULL && fa->type == ENUM && fa->val != NULL)
654 12050
                        vcc_do_enum(tl, fa, strlen(fa->val), fa->val);
655 158775
                if (fa->result == NULL && fa->val != NULL)
656 14475
                        fa->result = vcc_mk_expr(fa->type, "%s", fa->val);
657 158775
                if (fa->result != NULL && sa != NULL) {
658 21475
                        if (fa->name)
659 20950
                                bprintf(ssa, "\v1.%s = \v2,\n", fa->name);
660
                        else
661 525
                                bprintf(ssa, "\v1.arg%d = \v2,\n", n);
662 21475
                        e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, fa->result);
663 158775
                } else if (fa->result != NULL) {
664 214150
                        e1 = vcc_expr_edit(tl, e1->fmt, "\v1,\n\v2",
665 107075
                            e1, fa->result);
666 137300
                } else if (!fa->optional) {
667 25
                        if (fa->name)
668 50
                                VSB_printf(tl->sb, "Argument '%s' missing\n",
669 25
                                    fa->name);
670
                        else
671 0
                                VSB_printf(tl->sb, "Argument %d missing\n", n);
672 25
                        vcc_ErrWhere(tl, tl->t);
673 25
                }
674 158775
                free(fa);
675 158775
        }
676 67400
        if (sa != NULL) {
677 9875
                *e = vcc_expr_edit(tl, e1->fmt, "\v1\v-\n}\v-\n)", e1, NULL);
678 9875
        } else {
679 57525
                *e = vcc_expr_edit(tl, e1->fmt, "\v1\v-\n)", e1, NULL);
680
        }
681 67400
        SkipToken(tl, ')');
682 67375
        vcc_AddUses(tl, tf, NULL, sym, XREF_READ);
683 67750
}
684
685
686
/*--------------------------------------------------------------------
687
 */
688
689
void
690 5025
vcc_Eval_Func(struct vcc *tl, const struct vjsn_val *spec,
691
    const char *extra, struct symbol *sym)
692
{
693 5025
        struct expr *e = NULL;
694
695 5025
        vcc_func(tl, &e, spec, extra, sym);
696 5025
        if (tl->err)
697 0
                VSB_cat(tl->sb, "While compiling function call:\n");
698 5025
        ERRCHK(tl);
699 5025
        vcc_expr_fmt(tl->fb, tl->indent, e);
700 5025
        VSB_cat(tl->fb, ";\n");
701 5025
        vcc_delete_expr(e);
702 5025
}
703
704
/*--------------------------------------------------------------------
705
 */
706
707
void v_matchproto_(sym_expr_t)
708 51375
vcc_Eval_SymFunc(struct vcc *tl, struct expr **e, struct token *t,
709
    struct symbol *sym, vcc_type_t fmt)
710
{
711
712 51375
        (void)t;
713 51375
        (void)fmt;
714 51375
        assert(sym->kind == SYM_FUNC || sym->kind == SYM_METHOD);
715 51375
        AN(sym->eval_priv);
716
717 51375
        vcc_func(tl, e, sym->eval_priv, sym->extra, sym);
718 51375
        ERRCHK(tl);
719 51125
        if ((*e)->fmt == STRING) {
720 18725
                (*e)->fmt = STRINGS;
721 18725
                (*e)->nstr = 1;
722 18725
        }
723 51375
}
724
725
/*--------------------------------------------------------------------
726
 */
727
728
static void
729 432250
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 432250
        assert(fmt != VOID);
736 432250
        if (fmt == BYTES) {
737 1175
                vcc_ByteVal(tl, &vi);
738 1175
                ERRCHK(tl);
739 1125
                e1 = vcc_mk_expr(BYTES, "%ju", (intmax_t)vi);
740 1125
        } else {
741 431075
                t = tl->t;
742 431075
                vcc_NextToken(tl);
743 431075
                if (tl->t->tok == ID) {
744 139800
                        e1 = vcc_mk_expr(DURATION, "%s%.3f * %g",
745 139800
                            sign, t->num, vcc_DurationUnit(tl));
746 139800
                        ERRCHK(tl);
747 431050
                } else if (fmt == REAL || t->tok == FNUM) {
748 3850
                        e1 = vcc_mk_expr(REAL, "%s%.3f", sign, t->num);
749 3850
                } else {
750 287425
                        e1 = vcc_mk_expr(INT, "%s%.0f", sign, t->num);
751
                }
752
        }
753 432175
        e1->constant = EXPR_CONST;
754 432175
        *e = e1;
755 432250
}
756
757
/*--------------------------------------------------------------------
758
 * SYNTAX:
759
 *    Expr5:
760
 *      '(' ExprCor ')'
761
 *      symbol
762
 *      CNUM
763
 *      FNUM
764
 *      CSTR
765
 *      CBLOB
766
 */
767
768
static void
769 5983975
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 5983975
        sign = "";
777 5983975
        *e = NULL;
778 5983975
        if (tl->t->tok == '(') {
779 68150
                SkipToken(tl, '(');
780 68150
                vcc_expr_cor(tl, &e2, fmt);
781 68150
                ERRCHK(tl);
782 68150
                SkipToken(tl, ')');
783 68150
                if (e2->fmt == STRINGS)
784 150
                        *e = e2;
785
                else
786 68000
                        *e = vcc_expr_edit(tl, e2->fmt, "(\v1)", e2, NULL);
787 68150
                return;
788
        }
789 5915825
        switch (tl->t->tok) {
790
        case ID:
791 3010175
                t = tl->t;
792 3010175
                t1 = vcc_PeekToken(tl);
793 3010175
                AN(t1);
794 3010175
                sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
795
                    SYMTAB_PARTIAL_NOERR, XREF_REF);
796 3010175
                if (sym == NULL && fmt->global_pfx != NULL && t1->tok != '.') {
797 225
                        sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
798
                            SYMTAB_CREATE, XREF_REF);
799 225
                        ERRCHK(tl);
800 175
                        AN(sym);
801 175
                        VCC_GlobalSymbol(sym, fmt);
802 175
                }
803 3010125
                ERRCHK(tl);
804 3010125
                if (sym == NULL)
805 300
                        AZ(VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
806
                            SYMTAB_PARTIAL, XREF_REF));
807 3010125
                ERRCHK(tl);
808 3009825
                AN(sym);
809 3009825
                if (sym->kind == SYM_INSTANCE) {
810 19350
                        AZ(*e);
811 19350
                        *e = vcc_new_expr(sym->type);
812 19350
                        (*e)->instance = sym;
813 19350
                        return;
814
                }
815 2990475
                if (sym->kind == SYM_FUNC && sym->type == VOID) {
816 25
                        VSB_cat(tl->sb, "Function returns VOID:\n");
817 25
                        vcc_ErrWhere(tl, tl->t);
818 25
                        return;
819
                }
820 2990450
                if (sym->eval != NULL) {
821 2990375
                        AN(sym->eval);
822 2990375
                        AZ(*e);
823 2990375
                        sym->eval(tl, e, t, sym, fmt);
824 2990375
                        if (tl->err) {
825 400
                                VSB_cat(tl->sb,
826
                                    "While compiling function call:\n\n");
827 400
                                vcc_ErrWhere2(tl, t, tl->t);
828 400
                        }
829 2990375
                        ERRCHK(tl);
830
                        /* Unless asked for a HEADER, fold to string here */
831 2989975
                        if (*e && fmt != HEADER && (*e)->fmt == HEADER) {
832 831100
                                vcc_expr_tostring(tl, e, STRINGS);
833 831100
                                ERRCHK(tl);
834 831100
                        }
835 2989975
                        return;
836
                }
837 150
                VSB_printf(tl->sb,
838
                    "Symbol '%.*s' type (%s) can not be used in expression.\n",
839 75
                    PF(t), sym->kind->name);
840 75
                vcc_ErrWhere(tl, t);
841 75
                if (sym->def_b != NULL) {
842 25
                        VSB_cat(tl->sb, "That symbol was defined here:\n");
843 25
                        vcc_ErrWhere(tl, sym->def_b);
844 25
                }
845 75
                return;
846
        case CSTR:
847 2473025
                assert(fmt != VOID);
848 2473025
                if (fmt == IP) {
849 750
                        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 25
                                VSB_cat(tl->sb,
857
                                    "Cannot convert to an IP address: ");
858 25
                                vcc_ErrToken(tl, tl->t);
859 25
                                vcc_ErrWhere(tl, tl->t);
860 25
                                return;
861
                        }
862 1450
                        Resolve_Sockaddr(tl, tl->t->dec, "80",
863
                            &ip, NULL, &ip, NULL, NULL, 1,
864 725
                            tl->t, "IP constant");
865 725
                        ERRCHK(tl);
866 650
                        e1 = vcc_mk_expr(IP, "%s", ip);
867 650
                        ERRCHK(tl);
868 2472925
                } else if (fmt == REGEX) {
869 204825
                        e1 = vcc_new_expr(REGEX);
870 204825
                        vcc_regexp(tl, e1->vsb);
871 204825
                        AZ(VSB_finish(e1->vsb));
872 204825
                } else {
873 2267450
                        e1 = vcc_new_expr(STRINGS);
874 2267450
                        EncToken(e1->vsb, tl->t);
875 2267450
                        AZ(VSB_finish(e1->vsb));
876 2267450
                        e1->constant |= EXPR_STR_CONST;
877 2267450
                        e1->nstr = 1;
878
                }
879 2472925
                e1->t1 = tl->t;
880 2472925
                e1->constant |= EXPR_CONST;
881 2472925
                vcc_NextToken(tl);
882 2472925
                *e = e1;
883 2472925
                return;
884
        case '-':
885 1500
                if (fmt != INT &&
886 350
                    fmt != REAL &&
887 50
                    fmt != DURATION &&
888 25
                    fmt != STRINGS)
889 0
                        break;
890 1475
                vcc_NextToken(tl);
891 1475
                if (tl->t->tok != FNUM && tl->t->tok != CNUM) {
892 225
                        vcc_expr_cor(tl, &e1, fmt);
893 225
                        ERRCHK(tl);
894 225
                        *e = vcc_expr_edit(tl, e1->fmt, "-(\v1)", e1, NULL);
895 225
                        return;
896
                }
897 1250
                sign = "-";
898
                /* FALLTHROUGH */
899
        case FNUM:
900
        case CNUM:
901 432250
                vcc_number(tl, e, fmt, sign);
902 432250
                return;
903
        case CBLOB:
904 50
                e1 = vcc_new_expr(BLOB);
905 50
                VSB_printf(e1->vsb, "%s", tl->t->dec);
906 50
                AZ(VSB_finish(e1->vsb));
907 50
                e1->constant |= EXPR_STR_CONST;
908 50
                e1->t1 = tl->t;
909 50
                vcc_NextToken(tl);
910 50
                *e = e1;
911 50
                return;
912
        default:
913 100
                break;
914
        }
915 100
        VSB_cat(tl->sb, "Unknown token ");
916 100
        vcc_ErrToken(tl, tl->t);
917 100
        VSB_printf(tl->sb, " when looking for %s\n\n", vcc_utype(fmt));
918 100
        vcc_ErrWhere(tl, tl->t);
919 5983975
}
920
921
/*--------------------------------------------------------------------
922
 * SYNTAX:
923
 *    Expr4:
924
 *      Expr5 [ '.' (type_attribute | type_method()) ]*
925
 */
926
927
void
928 67725
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 67725
        (void)t;
934 67725
        impl = VCC_Type_EvalMethod(tl, sym);
935 67725
        ERRCHK(tl);
936 67725
        AN(impl);
937 67725
        *e = vcc_expr_edit(tl, fmt, impl, *e, NULL);
938 67725
}
939
940
static void
941 5983975
vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt)
942
{
943
        struct symbol *sym;
944
945 5983975
        *e = NULL;
946 5983975
        vcc_expr5(tl, e, fmt);
947 5983975
        ERRCHK(tl);
948 5982775
        AN(*e);
949 6069800
        while (tl->t->tok == '.') {
950 87100
                vcc_NextToken(tl);
951 87100
                ExpectErr(tl, ID);
952
953 87075
                sym = VCC_TypeSymbol(tl, SYM_METHOD, (*e)->fmt);
954 87075
                if (sym == NULL) {
955 50
                        VSB_cat(tl->sb, "Unknown property ");
956 50
                        vcc_ErrToken(tl, tl->t);
957 50
                        VSB_printf(tl->sb, " for type %s\n", (*e)->fmt->name);
958 50
                        vcc_ErrWhere(tl, tl->t);
959 50
                        return;
960
                }
961
962 87025
                AN(sym->eval);
963 87025
                sym->eval(tl, e, tl->t, sym, sym->type);
964 87025
                ERRCHK(tl);
965 87025
                if ((*e)->fmt == STRING) {
966 67450
                        (*e)->fmt = STRINGS;
967 67450
                        (*e)->nstr = 1;
968 67450
                }
969
        }
970 5983975
}
971
972
/*--------------------------------------------------------------------
973
 * SYNTAX:
974
 *    ExprMul:
975
 *      Expr4 { {'*'|'/'|'%'} Expr4 } *
976
 */
977
978
static void
979 5769925
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 5769925
        *e = NULL;
987 5769925
        vcc_expr4(tl, e, fmt);
988 5769925
        ERRCHK(tl);
989 5768825
        AN(*e);
990
991 5769725
        while (tl->t->tok == '*' || tl->t->tok == '/' || tl->t->tok == '%') {
992 1000
                if (tl->t->tok == '%' && ((*e)->fmt != INT)) {
993 25
                        VSB_cat(tl->sb, "Operator % only possible on INT.\n");
994 25
                        vcc_ErrWhere(tl, tl->t);
995 25
                        return;
996
                }
997 975
                f2 = (*e)->fmt->multype;
998 975
                if (f2 == NULL) {
999 50
                        VSB_printf(tl->sb,
1000
                            "Operator %.*s not possible on type %s.\n",
1001 25
                            PF(tl->t), vcc_utype((*e)->fmt));
1002 25
                        vcc_ErrWhere(tl, tl->t);
1003 25
                        return;
1004
                }
1005 950
                tk = tl->t;
1006 950
                vcc_NextToken(tl);
1007 950
                vcc_expr4(tl, &e2, f2);
1008 950
                ERRCHK(tl);
1009 950
                if (e2->fmt != INT && e2->fmt != f2) {
1010 100
                        VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
1011 50
                            vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1012 50
                        vcc_ErrWhere(tl, tk);
1013 50
                        return;
1014
                }
1015 900
                bprintf(buf, "(\v1%c\v2)", tk->tok);
1016 900
                *e = vcc_expr_edit(tl, (*e)->fmt, buf, *e, e2);
1017
        }
1018 5769925
}
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 4143150
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 4143150
        *e = NULL;
1060 4143150
        vcc_expr_mul(tl, e, fmt);
1061 4143150
        ERRCHK(tl);
1062
1063 5768450
        while (tl->t->tok == '+' || tl->t->tok == '-') {
1064 1626775
                tk = tl->t;
1065 26010075
                for (ap = vcc_adds; ap->op != EOI; ap++)
1066 24385125
                        if (tk->tok == ap->op && (*e)->fmt == ap->a)
1067 1825
                                break;
1068 1626775
                vcc_NextToken(tl);
1069 1626775
                if (ap->op == EOI && fmt == STRINGS)
1070 12550
                        vcc_expr_mul(tl, &e2, STRINGS);
1071
                else
1072 1614225
                        vcc_expr_mul(tl, &e2, (*e)->fmt);
1073 1626775
                ERRCHK(tl);
1074
1075 26013125
                for (ap = vcc_adds; ap->op != EOI; ap++)
1076 24387925
                        if (tk->tok == ap->op && (*e)->fmt == ap->a &&
1077 24387925
                            e2->fmt == ap->b)
1078 1575
                                break;
1079
1080 1626775
                if (ap->op == '+') {
1081 1100
                        *e = vcc_expr_edit(tl, ap->fmt, "(\v1 + \v2)", *e, e2);
1082 1626775
                } else if (ap->op == '-') {
1083 475
                        *e = vcc_expr_edit(tl, ap->fmt, "(\v1 - \v2)", *e, e2);
1084 1626050
                } else if (tk->tok == '+' &&
1085 1625175
                    ((*e)->fmt == STRINGS || fmt == STRINGS)) {
1086 1624925
                        if ((*e)->fmt != STRINGS)
1087 125
                                vcc_expr_tostring(tl, e, STRINGS);
1088 1624925
                        if (e2->fmt != STRINGS)
1089 404450
                                vcc_expr_tostring(tl, &e2, STRINGS);
1090 1624925
                        if (vcc_islit(*e) && vcc_isconst(e2)) {
1091 1200
                                lit = vcc_islit(e2);
1092 2400
                                *e = vcc_expr_edit(tl, STRINGS,
1093 1200
                                    "\v1\n\v2", *e, e2);
1094 1200
                                (*e)->constant = EXPR_CONST;
1095 1200
                                (*e)->nstr = 1;
1096 1200
                                if (lit)
1097 1200
                                        (*e)->constant |= EXPR_STR_CONST;
1098 1200
                        } else {
1099 1623725
                                n = (*e)->nstr + e2->nstr;
1100 3247450
                                *e = vcc_expr_edit(tl, STRINGS,
1101 1623725
                                    "\v1,\n\v2", *e, e2);
1102 1623725
                                (*e)->constant = EXPR_VAR;
1103 1623725
                                (*e)->nstr = n;
1104
                        }
1105 1624925
                } else {
1106 550
                        VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
1107 275
                            vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1108 275
                        vcc_ErrWhere2(tl, tk, tl->t);
1109 275
                        return;
1110
                }
1111
        }
1112 4143150
}
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 137700
cmp_simple(struct vcc *tl, struct expr **e, const struct cmps *cp)
1140
{
1141
        struct expr *e2;
1142
        struct token *tk;
1143
1144 137700
        tk = tl->t;
1145 137700
        vcc_NextToken(tl);
1146 137700
        vcc_expr_add(tl, &e2, (*e)->fmt);
1147 137700
        ERRCHK(tl);
1148
1149 137625
        if (e2->fmt != (*e)->fmt) {
1150 100
                VSB_printf(tl->sb,
1151
                    "Comparison of different types: %s '%.*s' %s\n",
1152 50
                    vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1153 50
                vcc_ErrWhere(tl, tk);
1154 50
        } else
1155 137575
                *e = vcc_expr_edit(tl, BOOL, cp->emit, *e, e2);
1156 137700
}
1157
1158
static void v_matchproto_(cmp_f)
1159 203700
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 203700
        *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
1166 203700
        vcc_NextToken(tl);
1167 203700
        t1 = tl->t;
1168 203700
        vcc_expr4(tl, &e2, REGEX);
1169 203700
        ERRCHK(tl);
1170 203600
        vcc_expr_typecheck(tl, &e2, REGEX, t1);
1171 203600
        ERRCHK(tl);
1172 203575
        bprintf(buf, "%sVRT_re_match(ctx, \v1, \v2)", cp->emit);
1173 203575
        *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1174 203700
}
1175
1176
static void v_matchproto_(cmp_f)
1177 1075
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 1075
        vcc_NextToken(tl);
1184 1075
        t1 = tl->t;
1185 1075
        vcc_expr4(tl, &e2, ACL);
1186 1075
        ERRCHK(tl);
1187 1000
        vcc_expr_typecheck(tl, &e2, ACL, t1);
1188 1000
        ERRCHK(tl);
1189 925
        bprintf(buf, "%sVRT_acl_match(ctx, \v1, \v2)", cp->emit);
1190 925
        *e = vcc_expr_edit(tl, BOOL, buf, e2, *e);
1191 1075
}
1192
1193
static void v_matchproto_(cmp_f)
1194 951900
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 951900
        tk = tl->t;
1201 951900
        vcc_NextToken(tl);
1202 951900
        vcc_expr_add(tl, &e2, STRINGS);
1203 951900
        ERRCHK(tl);
1204 951900
        if (e2->fmt != STRINGS) {
1205 150
                VSB_printf(tl->sb,
1206
                    "Comparison of different types: %s '%.*s' %s\n",
1207 75
                    vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1208 75
                vcc_ErrWhere(tl, tk);
1209 951900
        } else if ((*e)->nstr == 1 && e2->nstr == 1) {
1210 951125
                bprintf(buf, "(%s VRT_strcmp(\v1, \v2))", cp->emit);
1211 951125
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1212 951125
        } else {
1213 700
                bprintf(buf, "(%s VRT_CompareStrands(\vT, \vt))", cp->emit);
1214 700
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1215
        }
1216 951900
}
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 3053550
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 3053550
        *e = NULL;
1273 3053550
        vcc_expr_add(tl, e, fmt);
1274 3053550
        ERRCHK(tl);
1275 3052150
        tk = tl->t;
1276
1277 159465125
        for (cp = vcc_cmps; cp->fmt != VOID; cp++) {
1278 157707350
                if ((*e)->fmt == cp->fmt && tl->t->tok == cp->token) {
1279 1294375
                        AN(cp->func);
1280 1294375
                        cp->func(tl, e, cp);
1281 1294375
                        return;
1282
                }
1283 156412975
        }
1284
1285 1757775
        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 100
                VSB_printf(tl->sb, "Operator %.*s not possible on %s\n",
1295 50
                    PF(tl->t), vcc_utype((*e)->fmt));
1296 50
                vcc_ErrWhere(tl, tl->t);
1297 50
                return;
1298
        default:
1299 1757725
                break;
1300
        }
1301 3053550
}
1302
1303
/*--------------------------------------------------------------------
1304
 * SYNTAX:
1305
 *    ExprNot:
1306
 *      '!' ExprCmp
1307
 */
1308
1309
static void
1310 3053550
vcc_expr_not(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1311
{
1312
        struct token *tk;
1313
1314 3053550
        *e = NULL;
1315 3053550
        tk = tl->t;
1316 3053550
        if (tl->t->tok == '!')
1317 136300
                vcc_NextToken(tl);
1318 3053550
        vcc_expr_cmp(tl, e, fmt);
1319 3053550
        ERRCHK(tl);
1320 3051625
        if (tk->tok != '!')
1321 2915350
                return;
1322 136275
        vcc_expr_tobool(tl, e);
1323 136275
        ERRCHK(tl);
1324 136275
        if ((*e)->fmt != BOOL) {
1325 25
                VSB_cat(tl->sb, "'!' must be followed by BOOL, found ");
1326 25
                VSB_printf(tl->sb, "%s.\n", vcc_utype((*e)->fmt));
1327 25
                vcc_ErrWhere2(tl, tk, tl->t);
1328 25
        } else {
1329 136250
                *e = vcc_expr_edit(tl, BOOL, "!(\v1)", *e, NULL);
1330
        }
1331 3053550
}
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 4561000
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 4561000
        *e = NULL;
1350 4561000
        tk = tl->t;
1351 4561000
        up(tl, e, fmt);
1352 4561000
        ERRCHK(tl);
1353 4557050
        if (tl->t->tok != ourtok)
1354 4220400
                return;
1355 336650
        vcc_expr_tobool(tl, e);
1356 336650
        ERRCHK(tl);
1357 336650
        if ((*e)->fmt != BOOL) {
1358 100
                VSB_printf(tl->sb,
1359
                    "'%s' must be preceeded by BOOL,"
1360 50
                    " found %s.\n", tokstr, vcc_utype((*e)->fmt));
1361 50
                vcc_ErrWhere2(tl, tk, tl->t);
1362 50
                return;
1363
        }
1364 336600
        *e = vcc_expr_edit(tl, BOOL, "(\v+\n\v1", *e, NULL);
1365 1143375
        while (tl->t->tok == ourtok) {
1366 806825
                vcc_NextToken(tl);
1367 806825
                tk = tl->t;
1368 806825
                up(tl, &e2, fmt);
1369 806825
                ERRCHK(tl);
1370 806825
                vcc_expr_tobool(tl, &e2);
1371 806825
                ERRCHK(tl);
1372 806825
                if (e2->fmt != BOOL) {
1373 100
                        VSB_printf(tl->sb,
1374
                            "'%s' must be followed by BOOL,"
1375 50
                            " found %s.\n", tokstr, vcc_utype(e2->fmt));
1376 50
                        vcc_ErrWhere2(tl, tk, tl->t);
1377 50
                        vcc_delete_expr(e2);
1378 50
                        return;
1379
                }
1380 806775
                bprintf(buf, "\v1\v-\n%s\v+\n\v2", tokstr);
1381 806775
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1382
        }
1383 336550
        *e = vcc_expr_edit(tl, BOOL, "\v1\v-\n)", *e, NULL);
1384 4561000
}
1385
1386
/*--------------------------------------------------------------------
1387
 * SYNTAX:
1388
 *    ExprCand:
1389
 *      ExprNot { '&&' ExprNot } *
1390
 */
1391
1392
static void
1393 2314275
vcc_expr_cand(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1394
{
1395
1396 2314275
        vcc_expr_bin_bool(tl, e, fmt, T_CAND, vcc_expr_not, "&&");
1397 2314275
}
1398
1399
/*--------------------------------------------------------------------
1400
 * SYNTAX:
1401
 *    ExprCOR:
1402
 *      ExprCand { '||' ExprCand } *
1403
 */
1404
1405
static void
1406 2246725
vcc_expr_cor(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1407
{
1408
1409 2246725
        vcc_expr_bin_bool(tl, e, fmt, T_COR, vcc_expr_cand, "||");
1410 2246725
}
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 2178350
vcc_expr0(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1419
{
1420
        struct token *t1;
1421
1422 2178350
        assert(fmt != VOID);
1423 2178350
        assert(fmt != STRINGS);
1424 2178350
        *e = NULL;
1425 2178350
        t1 = tl->t;
1426 2178350
        if (fmt->stringform)
1427 689450
                vcc_expr_cor(tl, e, STRINGS);
1428
        else
1429 1488900
                vcc_expr_cor(tl, e, fmt);
1430 2178350
        ERRCHK(tl);
1431
1432 2176300
        if ((*e)->fmt == fmt)
1433 1081950
                return;
1434
1435 1094350
        if ((*e)->fmt != STRINGS && fmt->stringform)
1436 82125
                vcc_expr_tostring(tl, e, STRINGS);
1437
1438 1094350
        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 1094350
        if (fmt == BODY && !(*e)->fmt->bodyform)
1447 25
                vcc_expr_tostring(tl, e, STRINGS);
1448
1449 1094350
        if (fmt == BODY && (*e)->fmt->bodyform) {
1450 134900
                if ((*e)->fmt == STRINGS)
1451 134800
                        *e = vcc_expr_edit(tl, BODY, "STRING, 0, \vT", *e, NULL);
1452 100
                else if ((*e)->fmt == BLOB)
1453 100
                        *e = vcc_expr_edit(tl, BODY, "BLOB, 0, \v1", *e, NULL);
1454
                else
1455 0
                        WRONG("Unhandled bodyform");
1456 134900
        }
1457
1458 1094350
        if ((*e)->fmt == STRINGS && fmt->stringform) {
1459 688700
                if (fmt == STRING)
1460 85775
                        *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
1461 602925
                else if (fmt == STRANDS)
1462 602925
                        *e = vcc_expr_edit(tl, STRANDS, "\vT", (*e), NULL);
1463
                else
1464 0
                        WRONG("Unhandled stringform");
1465 688700
        }
1466
1467 1094350
        if (fmt == BOOL) {
1468 270650
                vcc_expr_tobool(tl, e);
1469 270650
                ERRCHK(tl);
1470 270650
        }
1471
1472 1094350
        vcc_expr_typecheck(tl, e, fmt, t1);
1473 2178350
}
1474
1475
static void
1476 1298950
vcc_expr_typecheck(struct vcc *tl, struct expr **e, vcc_type_t fmt,
1477
    struct token *t1)
1478
{
1479
1480 1298950
        assert(fmt != VOID);
1481 1298950
        assert(fmt != STRINGS);
1482
1483 1298950
        if (fmt != (*e)->fmt)  {
1484 450
                VSB_printf(tl->sb, "Expression has type %s, expected %s\n",
1485 225
                    vcc_utype((*e)->fmt), vcc_utype(fmt));
1486 225
                vcc_ErrWhere2(tl, t1, tl->t);
1487 225
        }
1488 1298950
}
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 2110725
vcc_Expr(struct vcc *tl, vcc_type_t fmt)
1499
{
1500 2110725
        struct expr *e = NULL;
1501
1502 2110725
        assert(fmt != VOID);
1503 2110725
        assert(fmt != STRINGS);
1504 2110725
        vcc_expr0(tl, &e, fmt);
1505 2110725
        ERRCHK(tl);
1506 2108775
        assert(e->fmt == fmt);
1507
1508 2108775
        vcc_expr_fmt(tl->fb, tl->indent, e);
1509 2108775
        VSB_cat(tl->fb, "\n");
1510 2108775
        vcc_delete_expr(e);
1511 2110725
}
1512
1513
/*--------------------------------------------------------------------
1514
 */
1515
1516
void v_matchproto_(sym_act_f)
1517 11350
vcc_Act_Call(struct vcc *tl, struct token *t, struct symbol *sym)
1518
{
1519
1520
        struct expr *e;
1521
1522 11350
        e = NULL;
1523 11350
        vcc_func(tl, &e, sym->eval_priv, sym->extra, sym);
1524 11350
        if (!tl->err) {
1525 11225
                vcc_expr_fmt(tl->fb, tl->indent, e);
1526 11225
                SkipToken(tl, ';');
1527 11225
                VSB_cat(tl->fb, ";\n");
1528 11350
        } else if (t != tl->t) {
1529 125
                VSB_cat(tl->sb, "While compiling function call:\n\n");
1530 125
                vcc_ErrWhere2(tl, t, tl->t);
1531 125
        }
1532 11350
        vcc_delete_expr(e);
1533 11350
}
1534
1535
void v_matchproto_(sym_act_f)
1536 8350
vcc_Act_Obj(struct vcc *tl, struct token *t, struct symbol *sym)
1537
{
1538
1539 8350
        struct expr *e = NULL;
1540
1541 8350
        assert(sym->kind == SYM_INSTANCE);
1542 8350
        ExpectErr(tl, '.');
1543 8325
        tl->t = t;
1544 8325
        vcc_expr4(tl, &e, sym->type);
1545 8325
        ERRCHK(tl);
1546 8325
        vcc_expr_fmt(tl->fb, tl->indent, e);
1547 8325
        vcc_delete_expr(e);
1548 8325
        SkipToken(tl, ';');
1549 8325
        VSB_cat(tl->fb, ";\n");
1550 8350
}
1551
1552
/*--------------------------------------------------------------------
1553
 */
1554
1555
static void v_matchproto_(sym_expr_t)
1556 925
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 925
        int all = sym->eval_priv == NULL ? 0 : 1;
1561
        char buf[128];
1562
1563 925
        (void)t;
1564 925
        (void)fmt;
1565 925
        SkipToken(tl, '(');
1566 925
        vcc_expr0(tl, &e2, STRING);
1567 925
        ERRCHK(tl);
1568 925
        SkipToken(tl, ',');
1569 925
        vcc_expr0(tl, &e3, REGEX);
1570 925
        ERRCHK(tl);
1571
1572 900
        bprintf(buf, "VRT_regsub(ctx, %d,\v+\n\v1,\n\v2", all);
1573 900
        *e = vcc_expr_edit(tl, STRING, buf, e2, e3);
1574 900
        SkipToken(tl, ',');
1575 900
        vcc_expr0(tl, &e2, STRING);
1576 900
        ERRCHK(tl);
1577 900
        *e = vcc_expr_edit(tl, STRINGS, "\v1,\n\v2)\v-", *e, e2);
1578 900
        (*e)->nstr = 1;
1579 900
        SkipToken(tl, ')');
1580 925
}
1581
1582
/*--------------------------------------------------------------------
1583
 */
1584
1585
static void v_matchproto_(sym_expr_t)
1586 73325
vcc_Eval_BoolConst(struct vcc *tl, struct expr **e, struct token *t,
1587
    struct symbol *sym, vcc_type_t fmt)
1588
{
1589
1590 73325
        (void)t;
1591 73325
        (void)tl;
1592 73325
        (void)fmt;
1593 73325
        *e = vcc_mk_expr(BOOL, "(0==%d)", sym->eval_priv == NULL ? 1 : 0);
1594 73325
        (*e)->constant = EXPR_CONST;
1595 73325
}
1596
1597
/*--------------------------------------------------------------------
1598
 */
1599
1600
static void v_matchproto_(sym_expr_t)
1601 100
vcc_Eval_Default(struct vcc *tl, struct expr **e, struct token *t,
1602
    struct symbol *sym, vcc_type_t fmt)
1603
{
1604 100
        (void)e;
1605 100
        (void)fmt;
1606 100
        (void)sym;
1607 100
        (void)t;
1608
1609 100
        if (fmt == PROBE)
1610 0
                *e = vcc_mk_expr(PROBE, "%s", vcc_default_probe(tl));
1611 100
        else if (fmt == BACKEND)
1612 50
                *e = vcc_mk_expr(BACKEND, "*(VCL_conf.default_director)");
1613
        else {
1614 50
                VSB_cat(tl->sb, "Symbol 'default' is a reserved word.\n");
1615 50
                vcc_ErrWhere(tl, t);
1616
        }
1617 100
}
1618
1619
/*--------------------------------------------------------------------
1620
 */
1621
1622
void
1623 72975
vcc_Expr_Init(struct vcc *tl)
1624
{
1625
        struct symbol *sym;
1626
1627 72975
        sym = VCC_MkSym(tl, "regsub", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1628 72975
        AN(sym);
1629 72975
        sym->type = STRING;
1630 72975
        sym->eval = vcc_Eval_Regsub;
1631 72975
        sym->eval_priv = NULL;
1632
1633 72975
        sym = VCC_MkSym(tl, "regsuball", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1634 72975
        AN(sym);
1635 72975
        sym->type = STRING;
1636 72975
        sym->eval = vcc_Eval_Regsub;
1637 72975
        sym->eval_priv = sym;
1638
1639 72975
        sym = VCC_MkSym(tl, "true", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1640 72975
        AN(sym);
1641 72975
        sym->type = BOOL;
1642 72975
        sym->eval = vcc_Eval_BoolConst;
1643 72975
        sym->eval_priv = sym;
1644
1645 72975
        sym = VCC_MkSym(tl, "false", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1646 72975
        AN(sym);
1647 72975
        sym->type = BOOL;
1648 72975
        sym->eval = vcc_Eval_BoolConst;
1649 72975
        sym->eval_priv = NULL;
1650
1651 72975
        sym = VCC_MkSym(tl, "default", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1652 72975
        AN(sym);
1653 72975
        sym->type = BACKEND;    // ... can also (sometimes) deliver PROBE
1654 72975
        sym->eval = vcc_Eval_Default;
1655 72975
}