vinyl-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 24240
vcc_isconst(const struct expr *e)
63
{
64 24240
        AN(e->constant);
65 24240
        return (e->constant & EXPR_CONST);
66
}
67
68
static inline int
69 286064
vcc_islit(const struct expr *e)
70
{
71 286064
        AN(e->constant);
72 286064
        return (e->constant & EXPR_STR_CONST);
73
}
74
75
static const char *
76 268
vcc_utype(vcc_type_t t)
77
{
78 268
        if (t == STRINGS || t->stringform)
79 68
                t = STRING;
80 268
        return (t->name);
81
}
82
83
static vcc_type_t
84 3388468
vcc_stringstype(vcc_type_t t)
85
{
86 3388468
        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 3113332
vcc_new_expr(vcc_type_t fmt)
97
{
98
        struct expr *e;
99
100 3113332
        ALLOC_OBJ(e, EXPR_MAGIC);
101 3113332
        AN(e);
102 3113332
        e->vsb = VSB_new_auto();
103 3113332
        e->fmt = fmt;
104 3113332
        e->constant = EXPR_VAR;
105 3113332
        return (e);
106
}
107
108
static struct expr * v_printflike_(2, 3)
109 831440
vcc_mk_expr(vcc_type_t fmt, const char *str, ...)
110
{
111
        va_list ap;
112
        struct expr *e;
113
114 831440
        e = vcc_new_expr(fmt);
115 831440
        va_start(ap, str);
116 831440
        VSB_vprintf(e->vsb, str, ap);
117 831440
        va_end(ap);
118 831440
        AZ(VSB_finish(e->vsb));
119 831440
        return (e);
120
}
121
122
static void
123 4016152
vcc_delete_expr(struct expr *e)
124
{
125 4016152
        if (e == NULL)
126 906236
                return;
127 3109916
        CHECK_OBJ(e, EXPR_MAGIC);
128 3109916
        VSB_destroy(&e->vsb);
129 3109916
        FREE_OBJ(e);
130 4016152
}
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 248756
vcc_strands_edit(const struct expr *e1, const struct expr *e2)
159
{
160
161 248756
        assert(e2->fmt == STRANDS || e2->fmt == STRINGS);
162
163 248756
        if (e2->fmt == STRANDS)
164 16
                VSB_cat(e1->vsb, VSB_data(e2->vsb));
165 248740
        else if (e2->nstr == 0) {
166 0
                VSB_cat(e1->vsb, "vrt_null_strands");
167 0
        }
168 248740
        else if (e2->nstr == 1)
169 224212
                VSB_printf(e1->vsb, "TOSTRAND(%s)", VSB_data(e2->vsb));
170
        else {
171 49056
                VSB_printf(e1->vsb, "TOSTRANDS(%d,\v+\n%s\v-)",
172 24528
                   e2->nstr, VSB_data(e2->vsb));
173
        }
174 248756
}
175
176
static struct expr *
177 1737568
vcc_expr_edit(struct vcc *tl, vcc_type_t fmt, const char *p, struct expr *e1,
178
    struct expr *e2)
179
{
180
        struct expr *e, *e3;
181 1737568
        int nl = 1;
182
183 1737568
        (void) tl;
184
185 1737568
        AN(e1);
186 1737568
        e = vcc_new_expr(fmt);
187 20095656
        while (*p != '\0') {
188 18358088
                if (*p != '\v') {
189 15160808
                        if (*p != '\n' || !nl)
190 15160604
                                VSB_putc(e->vsb, *p);
191 15160808
                        nl = (*p == '\n');
192 15160808
                        p++;
193 15160808
                        continue;
194
                }
195 3197280
                assert(*p == '\v');
196 3197280
                switch (*++p) {
197 307740
                case '+': VSB_cat(e->vsb, "\v+"); nl = 0; break;
198 320620
                case '-': VSB_cat(e->vsb, "\v-"); nl = 0; break;
199
                case 'S':
200
                case 's':
201 98156
                        e3 = (*p == 'S' ? e1 : e2);
202 98156
                        AN(e3);
203 98156
                        assert(e1->fmt == STRINGS);
204 98156
                        if (e3->nstr > 1) {
205 104
                                VSB_cat(e->vsb,
206
                                    "\nVRT_STRANDS_string(ctx,\v+\n");
207 104
                                vcc_strands_edit(e, e3);
208 104
                                VSB_cat(e->vsb,
209
                                    "\v-\n)\n");
210 104
                        } else {
211 98052
                                VSB_cat(e->vsb, VSB_data(e3->vsb));
212
                        }
213 98156
                        break;
214
                case 'T':
215
                case 't':
216 248652
                        e3 = (*p == 'T' ? e1 : e2);
217 248652
                        AN(e3);
218 248652
                        vcc_strands_edit(e, e3);
219 248652
                        break;
220
                case '1':
221 1390884
                        VSB_cat(e->vsb, VSB_data(e1->vsb));
222 1390884
                        break;
223
                case '2':
224 831228
                        AN(e2);
225 831228
                        VSB_cat(e->vsb, VSB_data(e2->vsb));
226 831228
                        break;
227
                default:
228 0
                        WRONG("Illegal edit in VCC expression");
229 0
                }
230 3197280
                p++;
231
        }
232 1737568
        AZ(VSB_finish(e->vsb));
233 1737568
        e->t1 = e1->t1;
234 1737568
        e->t2 = e1->t2;
235 1737568
        if (e2 != NULL)
236 831352
                e->t2 = e2->t2;
237 1737568
        vcc_delete_expr(e1);
238 1737568
        vcc_delete_expr(e2);
239 1737568
        return (e);
240
}
241
242
/*--------------------------------------------------------------------
243
 * Expand finished expression into C-source code
244
 */
245
246
static void
247 540988
vcc_expr_fmt(struct vsb *d, int ind, const struct expr *e1)
248
{
249
        char *p;
250
        int i;
251
252 540988
        if (!e1->fmt->noindent) {
253 5207792
                for (i = 0; i < ind; i++)
254 4690568
                        VSB_putc(d, ' ');
255 517224
        }
256 540988
        p = VSB_data(e1->vsb);
257 45940823
        while (*p != '\0') {
258 45399851
                if (*p == '\n') {
259 1302912
                        VSB_putc(d, '\n');
260 1302912
                        if (*++p == '\0')
261 16
                                break;
262 13843824
                        for (i = 0; i < ind; i++)
263 12540928
                                VSB_putc(d, ' ');
264 45399835
                } else if (*p != '\v') {
265 43406499
                        VSB_putc(d, *p++);
266 43406499
                } else {
267 690440
                        switch (*++p) {
268 345220
                        case '+': ind += INDENT; break;
269 345220
                        case '-': ind -= INDENT; break;
270 0
                        default:  WRONG("Illegal format in VCC expression");
271 0
                        }
272 690440
                        p++;
273
                }
274
        }
275 540988
}
276
277
/*--------------------------------------------------------------------
278
 */
279
280
static void
281 414764
vcc_expr_tobool(struct vcc *tl, struct expr **e)
282
{
283
284 414764
        if ((*e)->fmt == BOOL)
285 319608
                return;
286 95156
        if ((*e)->fmt == BACKEND || (*e)->fmt == INT)
287 40
                *e = vcc_expr_edit(tl, BOOL, "(\v1 != 0)", *e, NULL);
288 95116
        else if ((*e)->fmt == DURATION)
289 8
                *e = vcc_expr_edit(tl, BOOL, "(\v1 > 0)", *e, NULL);
290 95108
        else if ((*e)->fmt == STRINGS)
291 95084
                *e = vcc_expr_edit(tl, BOOL, "VRT_Strands2Bool(\vT)", *e, NULL);
292
        /*
293
         * We do not provide automatic folding from REAL to BOOL
294
         * because comparing to zero is seldom an exact science
295
         * and we want to force people to explicitly get it right.
296
         */
297 414764
}
298
299
/*--------------------------------------------------------------------
300
 */
301
302
static void
303 255672
vcc_expr_tostring(struct vcc *tl, struct expr **e)
304
{
305
        const char *p;
306 255672
        uint8_t constant = EXPR_VAR;
307
308 255672
        CHECK_OBJ_NOTNULL(*e, EXPR_MAGIC);
309 255672
        assert((*e)->fmt != STRINGS);
310
311 255672
        p = (*e)->fmt->tostring;
312 255672
        if (p != NULL) {
313 255668
                AN(*p);
314 255668
                *e = vcc_expr_edit(tl, STRINGS, p, *e, NULL);
315 255668
                (*e)->constant = constant;
316 255668
                (*e)->nstr = 1;
317 255668
        } else {
318 8
                VSB_printf(tl->sb,
319
                    "Cannot convert %s to STRING.\n",
320 4
                    vcc_utype((*e)->fmt));
321 4
                vcc_ErrWhere2(tl, (*e)->t1, tl->t);
322
        }
323 255672
}
324
325
/*--------------------------------------------------------------------
326
 */
327
328
void v_matchproto_(sym_expr_t)
329 1764
vcc_Eval_Handle(struct vcc *tl, struct expr **e, struct token *t,
330
    struct symbol *sym, vcc_type_t type)
331
{
332
333 1764
        (void)t;
334 1764
        (void)tl;
335 1764
        AN(sym->rname);
336 1764
        AZ(type->stringform);
337
338 1764
        if (sym->type->tostring == NULL &&
339 0
            sym->type != STRING && type == STRINGS) {
340 0
                *e = vcc_mk_expr(STRINGS, "\"%s\"", sym->name);
341 0
                (*e)->nstr = 1;
342 0
                (*e)->constant |= EXPR_CONST | EXPR_STR_CONST;
343 0
        } else {
344 1764
                *e = vcc_mk_expr(sym->type, "%s", sym->rname);
345 1764
                (*e)->constant = EXPR_VAR;
346 1764
                (*e)->nstr = 1;
347 1764
                if ((*e)->fmt == STRING)
348 0
                        (*e)->fmt = STRINGS;
349
        }
350 1764
}
351
352
void v_matchproto_(sym_expr_t)
353 100
vcc_Eval_Sub(struct vcc *tl, struct expr **e, struct token *t,
354
    struct symbol *sym, vcc_type_t type)
355
{
356
357 100
        (void)t;
358 100
        (void)tl;
359 100
        AN(sym->rname);
360 100
        AZ(type->stringform);
361
362 100
        assert (sym->type == SUB);
363
364 100
        if (type == SUB) {
365 88
                *e = vcc_mk_expr(sym->type, "%s", sym->rname);
366 88
                (*e)->constant = EXPR_CONST;
367 88
                return;
368
        }
369
370 24
        VSB_printf(tl->sb, "Symbol '%s' can only be used as a %s expression\n",
371 12
            sym->name, sym->type->name);
372 12
        vcc_ErrWhere(tl, tl->t);
373 100
}
374
375
/*--------------------------------------------------------------------
376
 */
377
378
void v_matchproto_(sym_expr_t)
379 647588
vcc_Eval_Var(struct vcc *tl, struct expr **e, struct token *t,
380
    struct symbol *sym, vcc_type_t type)
381
{
382
383 647588
        (void)type;
384 647588
        vcc_AddUses(tl, t, NULL, sym, XREF_READ);
385 647588
        ERRCHK(tl);
386 647588
        *e = vcc_mk_expr(sym->type, "%s", sym->rname);
387 647588
        (*e)->constant = EXPR_VAR;
388 647588
        (*e)->nstr = 1;
389 647588
        if ((*e)->fmt == STRING)
390 297844
                (*e)->fmt = STRINGS;
391 647588
}
392
393
void v_matchproto_(sym_expr_t)
394 44
vcc_Eval_ProtectedHeader(struct vcc *tl, struct expr **e, struct token *t,
395
    struct symbol *sym, vcc_type_t type)
396
{
397
398 44
        AN(sym);
399 44
        AZ(sym->lorev);
400
401 44
        vcc_Header_Fh(tl, sym);
402 44
        sym->eval = vcc_Eval_Var;
403 44
        vcc_Eval_Var(tl, e, t, sym, type);
404 44
}
405
406
/*--------------------------------------------------------------------
407
 */
408
409
static struct expr *
410 692
vcc_priv_arg(struct vcc *tl, const char *p, struct symbol *sym)
411
{
412
        char buf[64];
413
        struct inifin *ifp;
414 692
        const char *f = NULL;
415
416 692
        AN(sym);
417 692
        AN(sym->vmod_name);
418
419 692
        if (!vstrcmp(p, "PRIV_VCL"))
420 60
                return (vcc_mk_expr(VOID, "&vmod_priv_%s", sym->vmod_name));
421
422 632
        if (!vstrcmp(p, "PRIV_CALL")) {
423 92
                bprintf(buf, "vmod_priv_%u", tl->unique++);
424 92
                ifp = New_IniFin(tl);
425 92
                Fh(tl, 0, "static struct vmod_priv %s;\n", buf);
426 92
                VSB_printf(ifp->fin, "\tVRT_priv_fini(ctx, &%s);", buf);
427 92
                return (vcc_mk_expr(VOID, "&%s", buf));
428
        }
429
430 540
        if (!vstrcmp(p, "PRIV_TASK"))
431 508
                f = "task";
432 32
        else if (!vstrcmp(p, "PRIV_TOP")) {
433 32
                f = "top";
434 32
                sym->r_methods &= VCL_MET_TASK_C;
435 32
        } else {
436 0
                WRONG("Wrong PRIV_ type");
437
        }
438 540
        AN(f);
439
440 540
        return (vcc_mk_expr(VOID, "VRT_priv_%s(ctx, &VGC_vmod_%s)",
441 540
            f, sym->vmod_name));
442 692
}
443
444
struct func_arg {
445
        vcc_type_t              type;
446
        const struct vjsn_val   *enums;
447
        const char              *cname;
448
        const char              *name;
449
        const char              *val;
450
        struct expr             *result;
451
        int                     avail;
452
        int                     optional;
453
        VTAILQ_ENTRY(func_arg)  list;
454
};
455
456
static struct expr *
457 7380
vcc_do_enum(struct vcc *tl, const char *cfunc, int len, const char *ptr)
458
{
459
        const char *r;
460
461 7380
        (void)tl;
462 7380
        r = strchr(cfunc, '.');
463 7380
        AN(r);
464 7380
        return (vcc_mk_expr(VOID, "*%.*s.enum_%.*s",
465 7380
            (int)(r - cfunc), cfunc, len, ptr));
466
}
467
468
static void
469 16304
vcc_do_arg(struct vcc *tl, const char *cfunc, struct func_arg *fa)
470
{
471
        struct expr *e2;
472
        struct vjsn_val *vv;
473
474 16304
        if (fa->type == ENUM) {
475 5436
                ExpectErr(tl, ID);
476 5436
                ERRCHK(tl);
477 18848
                VTAILQ_FOREACH(vv, &fa->enums->children, list)
478 18840
                        if (vcc_IdIs(tl->t, vv->value))
479 5428
                                break;
480 5436
                if (vv == NULL) {
481 8
                        VSB_cat(tl->sb, "Wrong enum value.");
482 8
                        VSB_cat(tl->sb, "  Expected one of:\n");
483 40
                        VTAILQ_FOREACH(vv, &fa->enums->children, list)
484 32
                                VSB_printf(tl->sb, "\t%s\n", vv->value);
485 8
                        vcc_ErrWhere(tl, tl->t);
486 8
                        return;
487
                }
488 5428
                fa->result = vcc_do_enum(tl, cfunc, PF(tl->t));
489 5428
                SkipToken(tl, ID);
490 5428
        } else {
491 10868
                if (fa->type == SUB)
492 88
                        tl->subref++;
493 10868
                vcc_expr0(tl, &e2, fa->type);
494 10868
                ERRCHK(tl);
495 10836
                assert(e2->fmt == fa->type);
496 10836
                fa->result = e2;
497
        }
498 16264
        fa->avail = 1;
499 16304
}
500
501
static void
502 11296
vcc_func(struct vcc *tl, struct expr **e, const void *priv,
503
    const char *extra, struct symbol *sym)
504
{
505
        vcc_type_t rfmt;
506
        const char *cfunc;
507
        struct expr *e1;
508
        struct func_arg *fa, *fa2;
509
        VTAILQ_HEAD(,func_arg) head;
510
        struct token *tf, *t1;
511
        const struct vjsn_val *vv, *vvp;
512
        const char *sa, *extra_sep;
513
        char ssa[64];
514
        int n;
515
516 11296
        CAST_OBJ_NOTNULL(vv, priv, VJSN_VAL_MAGIC);
517 11296
        assert(vjsn_is_array(vv));
518 11296
        vv = VTAILQ_FIRST(&vv->children);
519 11296
        rfmt = VCC_Type(VTAILQ_FIRST(&vv->children)->value);
520 11296
        AN(rfmt);
521 11296
        vv = VTAILQ_NEXT(vv, list);
522 11296
        cfunc = vv->value;
523 11296
        vv = VTAILQ_NEXT(vv, list);
524 11296
        sa = vv->value;
525 11296
        if (*sa == '\0') {
526 9632
                sa = NULL;
527 9632
        }
528 11296
        vv = VTAILQ_NEXT(vv, list);
529 11296
        if (sym->kind == SYM_METHOD) {
530 3096
                if (*e == NULL) {
531 8
                        VSB_cat(tl->sb, "Syntax error.");
532 8
                        tl->err = 1;
533 8
                        return;
534
                }
535 3088
                vcc_NextToken(tl);
536 3088
                AZ(extra);
537 3088
                AN((*e)->instance);
538 3088
                extra = (*e)->instance->rname;
539 3088
        }
540 11288
        tf = VTAILQ_PREV(tl->t, tokenhead, list);
541 11288
        SkipToken(tl, '(');
542 11288
        if (extra == NULL) {
543 7396
                extra = "";
544 7396
                extra_sep = "";
545 7396
        } else {
546 3892
                AN(*extra);
547 3892
                extra_sep = ", ";
548
        }
549 11288
        VTAILQ_INIT(&head);
550 38608
        for (;vv != NULL; vv = VTAILQ_NEXT(vv, list)) {
551 27320
                assert(vjsn_is_array(vv));
552 27320
                fa = calloc(1, sizeof *fa);
553 27320
                AN(fa);
554 27320
                VTAILQ_INSERT_TAIL(&head, fa, list);
555
556 27320
                vvp = VTAILQ_FIRST(&vv->children);
557 27320
                if (!memcmp(vvp->value, "PRIV_", 5)) {
558 692
                        fa->result = vcc_priv_arg(tl, vvp->value, sym);
559 692
                        vvp = VTAILQ_NEXT(vvp, list);
560 692
                        if (vvp != NULL)
561 692
                                fa->cname = fa->name = vvp->value;
562 692
                        continue;
563
                }
564 26628
                fa->type = VCC_Type(vvp->value);
565 26628
                AN(fa->type);
566 26628
                vvp = VTAILQ_NEXT(vvp, list);
567 26628
                if (vvp != NULL) {
568 26628
                        fa->name = vvp->value;
569 26628
                        vvp = VTAILQ_NEXT(vvp, list);
570 26628
                        AN(vvp); /* vmod_syntax 2.0 */
571 26628
                        fa->cname = vvp->value;
572 26628
                        vvp = VTAILQ_NEXT(vvp, list);
573 26628
                        if (vvp != NULL) {
574 18532
                                fa->val = vvp->value;
575 18532
                                vvp = VTAILQ_NEXT(vvp, list);
576 18532
                                if (vvp != NULL) {
577 15180
                                        fa->enums = vvp;
578 15180
                                        vvp = VTAILQ_NEXT(vvp, list);
579 15180
                                }
580 18532
                        }
581 26628
                }
582 26628
                if (sa != NULL && vvp != NULL && vjsn_is_true(vvp)) {
583 8292
                        fa->optional = 1;
584 8292
                        vvp = VTAILQ_NEXT(vvp, list);
585 8292
                }
586 26628
                AZ(vvp);
587 26628
        }
588
589 18124
        VTAILQ_FOREACH(fa, &head, list) {
590 16280
                if (tl->t->tok == ')')
591 356
                        break;
592 15924
                if (fa->result != NULL)
593 496
                        continue;
594 15428
                if (tl->t->tok == ID) {
595 11292
                        t1 = VTAILQ_NEXT(tl->t, list);
596 11292
                        if (t1->tok == '=')
597 3068
                                break;
598 8224
                }
599 12360
                vcc_do_arg(tl, cfunc, fa);
600 12360
                if (tl->err)
601 80
                        VSB_printf(tl->sb, "Expected argument: %s %s\n\n",
602 40
                            fa->type->name,
603 40
                            fa->name ? fa->name : "(unnamed argument)");
604 12360
                ERRCHK(tl);
605 12320
                if (tl->t->tok == ')')
606 5980
                        break;
607 6340
                SkipToken(tl, ',');
608 6340
        }
609 12132
        while (tl->t->tok == ID) {
610 13008
                VTAILQ_FOREACH(fa, &head, list) {
611 13004
                        if (fa->name == NULL)
612 48
                                continue;
613 12956
                        if (vcc_IdIs(tl->t, fa->name))
614 3948
                                break;
615 9008
                }
616 3952
                if (fa == NULL) {
617 8
                        VSB_printf(tl->sb, "Unknown argument '%.*s'\n",
618 4
                            PF(tl->t));
619 4
                        vcc_ErrWhere(tl, tl->t);
620 4
                        return;
621
                }
622 3948
                if (fa->result != NULL) {
623 4
                        AN(fa->name);
624 8
                        VSB_printf(tl->sb, "Argument '%s' already used\n",
625 4
                            fa->name);
626 4
                        vcc_ErrWhere(tl, tl->t);
627 4
                        return;
628
                }
629 3944
                vcc_NextToken(tl);
630 3944
                SkipToken(tl, '=');
631 3944
                vcc_do_arg(tl, cfunc, fa);
632 3944
                ERRCHK(tl);
633 3944
                if (tl->t->tok == ')')
634 3060
                        break;
635 884
                SkipToken(tl, ',');
636
        }
637
638 11240
        if (sa != NULL)
639 3296
                e1 = vcc_mk_expr(rfmt, "%s(ctx%s%s,\v+\n&(%s)\v+ {\n",
640 1648
                    cfunc, extra_sep, extra, sa);
641
        else
642 19184
                e1 = vcc_mk_expr(rfmt, "%s(ctx%s%s\v+",
643 9592
                    cfunc, extra_sep, extra);
644 11240
        n = 0;
645 38276
        VTAILQ_FOREACH_SAFE(fa, &head, list, fa2) {
646 27036
                n++;
647 27036
                if (fa->optional) {
648 8116
                        AN(fa->cname);
649 8116
                        bprintf(ssa, "\v1.valid_%s = %d,\n",
650
                            fa->cname, fa->avail);
651 8116
                        e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, NULL);
652 8116
                }
653 27036
                if (fa->result == NULL && fa->type == ENUM && fa->val != NULL)
654 1952
                        fa->result = vcc_do_enum(tl, cfunc, vstrlen(fa->val), fa->val);
655 27036
                if (fa->result == NULL && fa->val != NULL) {
656 2500
                        if (fa->type == BOOL && fa->val[0] == 'f')
657 0
                                fa->result = vcc_mk_expr(fa->type, "0");
658 2500
                        else if (fa->type == BOOL && fa->val[0] == 't')
659 0
                                fa->result = vcc_mk_expr(fa->type, "1");
660
                        else
661 2500
                                fa->result = vcc_mk_expr(fa->type, "%s", fa->val);
662 2500
                }
663 27036
                if (fa->result != NULL && sa != NULL) {
664 3560
                        if (fa->cname)
665 3476
                                bprintf(ssa, "\v1.%s = \v2,\n", fa->cname);
666
                        else
667 84
                                bprintf(ssa, "\v1.arg%d = \v2,\n", n);
668 3560
                        e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, fa->result);
669 27036
                } else if (fa->result != NULL) {
670 35656
                        e1 = vcc_expr_edit(tl, e1->fmt, "\v1,\n\v2",
671 17828
                            e1, fa->result);
672 23476
                } else if (!fa->optional) {
673 4
                        if (fa->name)
674 8
                                VSB_printf(tl->sb, "Argument '%s' missing\n",
675 4
                                    fa->name);
676
                        else
677 0
                                VSB_printf(tl->sb, "Argument %d missing\n", n);
678 4
                        vcc_ErrWhere(tl, tl->t);
679 4
                }
680 27036
                free(fa);
681 27036
        }
682 11240
        if (sa != NULL) {
683 1648
                *e = vcc_expr_edit(tl, e1->fmt, "\v1\v-\n}\v-\n)", e1, NULL);
684 1648
        } else {
685 9592
                *e = vcc_expr_edit(tl, e1->fmt, "\v1\v-\n)", e1, NULL);
686
        }
687 11240
        SkipToken(tl, ')');
688 11236
        vcc_AddUses(tl, tf, NULL, sym, XREF_READ);
689 11296
}
690
691
692
/*--------------------------------------------------------------------
693
 */
694
695
void
696 804
vcc_Eval_Func(struct vcc *tl, const struct vjsn_val *spec,
697
    const char *extra, struct symbol *sym)
698
{
699 804
        struct expr *e = NULL;
700
701 804
        vcc_func(tl, &e, spec, extra, sym);
702 804
        if (tl->err)
703 0
                VSB_cat(tl->sb, "While compiling function call:\n");
704 804
        ERRCHK(tl);
705 804
        vcc_expr_fmt(tl->fb, tl->indent, e);
706 804
        VSB_cat(tl->fb, ";\n");
707 804
        vcc_delete_expr(e);
708 804
}
709
710
/*--------------------------------------------------------------------
711
 */
712
713
void v_matchproto_(sym_expr_t)
714 8468
vcc_Eval_SymFunc(struct vcc *tl, struct expr **e, struct token *t,
715
    struct symbol *sym, vcc_type_t fmt)
716
{
717
718 8468
        (void)t;
719 8468
        (void)fmt;
720 8468
        assert(sym->kind == SYM_FUNC || sym->kind == SYM_METHOD);
721 8468
        AN(sym->eval_priv);
722
723 8468
        vcc_func(tl, e, sym->eval_priv, sym->extra, sym);
724 8468
        ERRCHK(tl);
725 8428
        if ((*e)->fmt == STRING) {
726 3068
                (*e)->fmt = STRINGS;
727 3068
                (*e)->nstr = 1;
728 3068
        }
729 8468
}
730
731
/*--------------------------------------------------------------------
732
 */
733
734
static void
735 147232
vcc_number(struct vcc *tl, struct expr **e, vcc_type_t fmt, const char *sign)
736
{
737
        VCL_INT vi;
738
        struct expr *e1;
739
        struct token *t;
740
741 147232
        assert(fmt != VOID);
742 147232
        if (fmt == BYTES) {
743 220
                vcc_ByteVal(tl, &vi);
744 220
                ERRCHK(tl);
745 212
                e1 = vcc_mk_expr(BYTES, "%ju", (intmax_t)vi);
746 212
        } else {
747 147012
                t = tl->t;
748 147012
                vcc_NextToken(tl);
749 147012
                if (tl->t->tok == ID) {
750 12932
                        e1 = vcc_mk_expr(DURATION, "%s%.3f * %g",
751 12932
                            sign, t->num, vcc_DurationUnit(tl));
752 12932
                        ERRCHK(tl);
753 147008
                } else if (fmt == REAL || t->tok == FNUM) {
754 728
                        e1 = vcc_mk_expr(REAL, "%s%.3f", sign, t->num);
755 728
                } else {
756 133352
                        e1 = vcc_mk_expr(INT, "%s%.0fLL", sign, t->num);
757
                }
758
        }
759 147220
        e1->constant = EXPR_CONST;
760 147220
        *e = e1;
761 147232
}
762
763
/*--------------------------------------------------------------------
764
 * SYNTAX:
765
 *    Expr5:
766
 *      '(' ExprCor ')'
767
 *      symbol
768
 *      CNUM
769
 *      FNUM
770
 *      CSTR
771
 *      CBLOB
772
 */
773
774
static void
775 1371704
vcc_expr5(struct vcc *tl, struct expr **e, vcc_type_t fmt)
776
{
777
        struct expr *e1, *e2;
778
        const char *ip, *sign;
779
        struct token *t, *t1;
780
        struct symbol *sym;
781
782 1371704
        sign = "";
783 1371704
        *e = NULL;
784 1371704
        if (tl->t->tok == '(') {
785 12052
                SkipToken(tl, '(');
786 12052
                vcc_expr_cor(tl, &e2, fmt);
787 12052
                ERRCHK(tl);
788 12052
                SkipToken(tl, ')');
789 12052
                if (e2->fmt == STRINGS)
790 24
                        *e = e2;
791
                else
792 12028
                        *e = vcc_expr_edit(tl, e2->fmt, "(\v1)", e2, NULL);
793 12052
                return;
794
        }
795 1359652
        switch (tl->t->tok) {
796
        case ID:
797 671020
                t = tl->t;
798 671020
                t1 = vcc_PeekToken(tl);
799 671020
                AN(t1);
800 671020
                sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
801
                    SYMTAB_PARTIAL_NOERR, XREF_REF);
802 671020
                if (sym == NULL && fmt->global_pfx != NULL && t1->tok != '.') {
803 36
                        sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
804
                            SYMTAB_CREATE, XREF_REF);
805 36
                        ERRCHK(tl);
806 28
                        AN(sym);
807 28
                        VCC_GlobalSymbol(sym, fmt);
808 28
                }
809 671012
                ERRCHK(tl);
810 671012
                if (sym == NULL)
811 48
                        AZ(VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
812
                            SYMTAB_PARTIAL, XREF_REF));
813 671012
                ERRCHK(tl);
814 670964
                AN(sym);
815 670964
                if (sym->kind == SYM_INSTANCE) {
816 3096
                        AZ(*e);
817 3096
                        *e = vcc_new_expr(sym->type);
818 3096
                        (*e)->instance = sym;
819 3096
                        return;
820
                }
821 667868
                if (sym->kind == SYM_FUNC && sym->type == VOID) {
822 4
                        VSB_cat(tl->sb, "Function returns VOID:\n");
823 4
                        vcc_ErrWhere(tl, tl->t);
824 4
                        return;
825
                }
826 667864
                if (sym->eval != NULL) {
827 667852
                        AN(sym->eval);
828 667852
                        AZ(*e);
829 667852
                        sym->eval(tl, e, t, sym, fmt);
830 667852
                        if (tl->err) {
831 64
                                VSB_cat(tl->sb,
832
                                    "While compiling function call:\n\n");
833 64
                                vcc_ErrWhere2(tl, t, tl->t);
834 64
                        }
835 667852
                        ERRCHK(tl);
836
                        /* Unless asked for a HEADER, fold to string here */
837 667788
                        if (*e && fmt != HEADER && (*e)->fmt == HEADER) {
838 169900
                                vcc_expr_tostring(tl, e);
839 169900
                                ERRCHK(tl);
840 169900
                        }
841 667788
                        return;
842
                }
843 24
                VSB_printf(tl->sb,
844
                    "Symbol '%.*s' type (%s) cannot be used in expression.\n",
845 12
                    PF(t), sym->kind->name);
846 12
                vcc_ErrWhere(tl, t);
847 12
                if (sym->def_b != NULL) {
848 4
                        VSB_cat(tl->sb, "That symbol was defined here:\n");
849 4
                        vcc_ErrWhere(tl, sym->def_b);
850 4
                }
851 12
                return;
852
        case CSTR:
853 541336
                assert(fmt != VOID);
854 541336
                if (fmt == IP) {
855 120
                        if (*tl->t->dec == '/') {
856
                                /*
857
                                 * On some platforms (e.g. FreeBSD),
858
                                 * getaddrinfo(3) may resolve a path to a
859
                                 * sockaddr_un if it happens to exist and
860
                                 * is a socket. So don't let that happen.
861
                                 */
862 4
                                VSB_cat(tl->sb,
863
                                    "Cannot convert to an IP address: ");
864 4
                                vcc_ErrToken(tl, tl->t);
865 4
                                vcc_ErrWhere(tl, tl->t);
866 4
                                return;
867
                        }
868 232
                        Resolve_Sockaddr(tl, tl->t->dec, "80",
869
                            &ip, NULL, &ip, NULL, NULL, 1,
870 116
                            tl->t, "IP constant");
871 116
                        ERRCHK(tl);
872 104
                        e1 = vcc_mk_expr(IP, "%s", ip);
873 104
                        ERRCHK(tl);
874 541320
                } else if (fmt == REGEX) {
875 47860
                        e1 = vcc_new_expr(REGEX);
876 47860
                        vcc_regexp(tl, e1->vsb);
877 47860
                        AZ(VSB_finish(e1->vsb));
878 47860
                } else {
879 493356
                        e1 = vcc_new_expr(STRINGS);
880 493356
                        EncToken(e1->vsb, tl->t);
881 493356
                        AZ(VSB_finish(e1->vsb));
882 493356
                        e1->constant |= EXPR_STR_CONST;
883 493356
                        e1->nstr = 1;
884
                }
885 541320
                e1->t1 = tl->t;
886 541320
                e1->constant |= EXPR_CONST;
887 541320
                vcc_NextToken(tl);
888 541320
                *e = e1;
889 541320
                return;
890
        case '-':
891 260
                if (fmt != INT &&
892 64
                    fmt != REAL &&
893 16
                    fmt != DURATION &&
894 4
                    fmt != STRINGS)
895 0
                        break;
896 256
                vcc_NextToken(tl);
897 256
                if (tl->t->tok != FNUM && tl->t->tok != CNUM) {
898 36
                        vcc_expr_cor(tl, &e1, fmt);
899 36
                        ERRCHK(tl);
900 36
                        *e = vcc_expr_edit(tl, e1->fmt, "-(\v1)", e1, NULL);
901 36
                        return;
902
                }
903 220
                sign = "-";
904
                /* FALLTHROUGH */
905
        case FNUM:
906
        case CNUM:
907 147232
                vcc_number(tl, e, fmt, sign);
908 147232
                return;
909
        case CBLOB:
910 12
                e1 = vcc_new_expr(BLOB);
911 12
                VSB_printf(e1->vsb, "%s", tl->t->dec);
912 12
                AZ(VSB_finish(e1->vsb));
913 12
                e1->constant |= EXPR_STR_CONST;
914 12
                e1->t1 = tl->t;
915 12
                vcc_NextToken(tl);
916 12
                *e = e1;
917 12
                return;
918
        default:
919 16
                break;
920
        }
921 16
        VSB_cat(tl->sb, "Unknown token ");
922 16
        vcc_ErrToken(tl, tl->t);
923 16
        VSB_printf(tl->sb, " when looking for %s\n\n", vcc_utype(fmt));
924 16
        vcc_ErrWhere(tl, tl->t);
925 1371704
}
926
927
/*--------------------------------------------------------------------
928
 * SYNTAX:
929
 *    Expr4:
930
 *      Expr5 [ '.' (type_attribute | type_method()) ]*
931
 */
932
933
void
934 11908
vcc_Eval_TypeMethod(struct vcc *tl, struct expr **e, struct token *t,
935
    struct symbol *sym, vcc_type_t fmt)
936
{
937
        const char *impl;
938
939 11908
        (void)t;
940 11908
        impl = VCC_Type_EvalMethod(tl, sym);
941 11908
        ERRCHK(tl);
942 11908
        AN(impl);
943 11908
        *e = vcc_expr_edit(tl, fmt, impl, *e, NULL);
944 11908
}
945
946
static void
947 1371704
vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt)
948
{
949
        struct symbol *sym;
950
951 1371704
        *e = NULL;
952 1371704
        vcc_expr5(tl, e, fmt);
953 1371704
        ERRCHK(tl);
954 1371512
        AN(*e);
955 1386508
        while (tl->t->tok == '.') {
956 15008
                vcc_NextToken(tl);
957 15008
                ExpectErr(tl, ID);
958
959 15004
                sym = VCC_TypeSymbol(tl, SYM_METHOD, (*e)->fmt);
960 15004
                if (sym == NULL) {
961 8
                        VSB_cat(tl->sb, "Unknown property ");
962 8
                        vcc_ErrToken(tl, tl->t);
963 8
                        VSB_printf(tl->sb, " for type %s\n", (*e)->fmt->name);
964 8
                        vcc_ErrWhere(tl, tl->t);
965 8
                        return;
966
                }
967
968 14996
                AN(sym->eval);
969 14996
                sym->eval(tl, e, tl->t, sym, sym->type);
970 14996
                ERRCHK(tl);
971 14996
                if ((*e)->fmt == STRING) {
972 11864
                        (*e)->fmt = STRINGS;
973 11864
                        (*e)->nstr = 1;
974 11864
                }
975
        }
976 1371704
}
977
978
/*--------------------------------------------------------------------
979
 * SYNTAX:
980
 *    ExprMul:
981
 *      Expr4 { {'*'|'/'|'%'} Expr4 } *
982
 */
983
984
static void
985 1322320
vcc_expr_mul(struct vcc *tl, struct expr **e, vcc_type_t fmt)
986
{
987
        struct expr *e2;
988
        vcc_type_t f2;
989
        struct token *tk;
990
        char buf[24];
991
992 1322320
        *e = NULL;
993 1322320
        vcc_expr4(tl, e, fmt);
994 1322320
        ERRCHK(tl);
995 1322144
        AN(*e);
996
997 1322308
        while (tl->t->tok == '*' || tl->t->tok == '/' || tl->t->tok == '%') {
998 180
                if (tl->t->tok == '%' && ((*e)->fmt != INT)) {
999 4
                        VSB_cat(tl->sb, "Operator % only possible on INT.\n");
1000 4
                        vcc_ErrWhere(tl, tl->t);
1001 4
                        return;
1002
                }
1003 176
                f2 = (*e)->fmt->multype;
1004 176
                if (f2 == NULL) {
1005 8
                        VSB_printf(tl->sb,
1006
                            "Operator %.*s not possible on type %s.\n",
1007 4
                            PF(tl->t), vcc_utype((*e)->fmt));
1008 4
                        vcc_ErrWhere(tl, tl->t);
1009 4
                        return;
1010
                }
1011 172
                tk = tl->t;
1012 172
                vcc_NextToken(tl);
1013 172
                vcc_expr4(tl, &e2, f2);
1014 172
                ERRCHK(tl);
1015 172
                if (e2->fmt != INT && e2->fmt != f2) {
1016 16
                        VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
1017 8
                            vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1018 8
                        vcc_ErrWhere(tl, tk);
1019 8
                        return;
1020
                }
1021 164
                bprintf(buf, "(\v1%c\v2)", tk->tok);
1022 164
                *e = vcc_expr_edit(tl, (*e)->fmt, buf, *e, e2);
1023
        }
1024 1322320
}
1025
1026
/*--------------------------------------------------------------------
1027
 * SYNTAX:
1028
 *    ExprAdd:
1029
 *      ExprMul { {'+'|'-'} ExprMul } *
1030
 */
1031
1032
static const struct adds {
1033
        unsigned        op;
1034
        vcc_type_t      a;
1035
        vcc_type_t      b;
1036
        vcc_type_t      fmt;
1037
} vcc_adds[] = {
1038
        { '+', BYTES,           BYTES,          BYTES },
1039
        { '-', BYTES,           BYTES,          BYTES },
1040
        { '+', DURATION,        DURATION,       DURATION },
1041
        { '-', DURATION,        DURATION,       DURATION },
1042
        { '+', INT,             INT,            INT },
1043
        { '-', INT,             INT,            INT },
1044
        { '+', INT,             REAL,           REAL },
1045
        { '-', INT,             REAL,           REAL },
1046
        { '+', REAL,            INT,            REAL },
1047
        { '-', REAL,            INT,            REAL },
1048
        { '+', REAL,            REAL,           REAL },
1049
        { '-', REAL,            REAL,           REAL },
1050
        { '-', TIME,            TIME,           DURATION },
1051
        { '+', TIME,            DURATION,       TIME },
1052
        { '-', TIME,            DURATION,       TIME },
1053
1054
        { EOI, VOID,            VOID,           VOID }
1055
};
1056
1057
static void
1058 1036120
vcc_expr_add(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1059
{
1060
        const struct adds *ap;
1061
        struct expr  *e2;
1062
        struct token *tk;
1063
        int lit, n;
1064
1065 1036120
        *e = NULL;
1066 1036120
        vcc_expr_mul(tl, e, fmt);
1067 1036120
        ERRCHK(tl);
1068
1069 1322084
        while (tl->t->tok == '+' || tl->t->tok == '-') {
1070 286200
                tk = tl->t;
1071 4575856
                for (ap = vcc_adds; ap->op != EOI; ap++)
1072 4289992
                        if (tk->tok == ap->op && (*e)->fmt == ap->a)
1073 336
                                break;
1074 286200
                vcc_NextToken(tl);
1075 286200
                if (ap->op == EOI && fmt == STRINGS)
1076 2136
                        vcc_expr_mul(tl, &e2, STRINGS);
1077
                else
1078 284064
                        vcc_expr_mul(tl, &e2, (*e)->fmt);
1079 286200
                ERRCHK(tl);
1080
1081 4576408
                for (ap = vcc_adds; ap->op != EOI; ap++)
1082 4290504
                        if (tk->tok == ap->op && (*e)->fmt == ap->a &&
1083 4290504
                            e2->fmt == ap->b)
1084 296
                                break;
1085
1086 286200
                if (ap->op == '+') {
1087 212
                        *e = vcc_expr_edit(tl, ap->fmt, "(\v1 + \v2)", *e, e2);
1088 286200
                } else if (ap->op == '-') {
1089 84
                        *e = vcc_expr_edit(tl, ap->fmt, "(\v1 - \v2)", *e, e2);
1090 286060
                } else if (tk->tok == '+' &&
1091 285900
                    ((*e)->fmt == STRINGS || fmt == STRINGS)) {
1092 285860
                        if ((*e)->fmt != STRINGS)
1093 32
                                vcc_expr_tostring(tl, e);
1094 285860
                        if (e2->fmt != STRINGS)
1095 71160
                                vcc_expr_tostring(tl, &e2);
1096 285860
                        if (vcc_islit(*e) && vcc_isconst(e2)) {
1097 204
                                lit = vcc_islit(e2);
1098 408
                                *e = vcc_expr_edit(tl, STRINGS,
1099 204
                                    "\v1\n\v2", *e, e2);
1100 204
                                (*e)->constant = EXPR_CONST;
1101 204
                                (*e)->nstr = 1;
1102 204
                                if (lit)
1103 204
                                        (*e)->constant |= EXPR_STR_CONST;
1104 204
                        } else {
1105 285656
                                n = (*e)->nstr + e2->nstr;
1106 571312
                                *e = vcc_expr_edit(tl, STRINGS,
1107 285656
                                    "\v1,\n\v2", *e, e2);
1108 285656
                                (*e)->constant = EXPR_VAR;
1109 285656
                                (*e)->nstr = n;
1110
                        }
1111 285860
                } else {
1112 88
                        VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
1113 44
                            vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1114 44
                        vcc_ErrWhere2(tl, tk, tl->t);
1115 44
                        return;
1116
                }
1117
        }
1118 1036120
}
1119
1120
/*--------------------------------------------------------------------
1121
 * SYNTAX:
1122
 *    ExprCmp:
1123
 *      ExprAdd
1124
 *      ExprAdd Relation ExprAdd
1125
 *      ExprAdd(STRING) '~' CString
1126
 *      ExprAdd(STRING) '!~' CString
1127
 *      ExprAdd(IP) '==' ExprAdd(IP)
1128
 *      ExprAdd(IP) '!=' ExprAdd(IP)
1129
 *      ExprAdd(IP) '~' ACL
1130
 *      ExprAdd(IP) '!~' ACL
1131
 */
1132
1133
struct cmps;
1134
1135
typedef void cmp_f(struct vcc *, struct expr **, const struct cmps *);
1136
1137
struct cmps {
1138
        vcc_type_t              fmt;
1139
        unsigned                token;
1140
        cmp_f                   *func;
1141
        const char              *emit;
1142
};
1143
1144
static void v_matchproto_(cmp_f)
1145 59744
cmp_simple(struct vcc *tl, struct expr **e, const struct cmps *cp)
1146
{
1147
        struct expr *e2;
1148
        struct token *tk;
1149
1150 59744
        tk = tl->t;
1151 59744
        vcc_NextToken(tl);
1152 59744
        vcc_expr_add(tl, &e2, (*e)->fmt);
1153 59744
        ERRCHK(tl);
1154
1155 59732
        if (e2->fmt != (*e)->fmt) {
1156 16
                VSB_printf(tl->sb,
1157
                    "Comparison of different types: %s '%.*s' %s\n",
1158 8
                    vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1159 8
                vcc_ErrWhere(tl, tk);
1160 8
        } else
1161 59724
                *e = vcc_expr_edit(tl, BOOL, cp->emit, *e, e2);
1162 59744
}
1163
1164
static void v_matchproto_(cmp_f)
1165 47676
cmp_regexp(struct vcc *tl, struct expr **e, const struct cmps *cp)
1166
{
1167
        struct token *t1;
1168
        struct expr *e2;
1169
        char buf[128];
1170
1171 47676
        *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
1172 47676
        vcc_NextToken(tl);
1173 47676
        t1 = tl->t;
1174 47676
        vcc_expr4(tl, &e2, REGEX);
1175 47676
        ERRCHK(tl);
1176 47660
        vcc_expr_typecheck(tl, &e2, REGEX, t1);
1177 47660
        ERRCHK(tl);
1178 47656
        bprintf(buf, "%sVRT_re_match(ctx, \v1, \v2)", cp->emit);
1179 47656
        *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1180 47676
}
1181
1182
static void v_matchproto_(cmp_f)
1183 204
cmp_acl(struct vcc *tl, struct expr **e, const struct cmps *cp)
1184
{
1185
        struct token *t1;
1186
        struct expr *e2;
1187
        char buf[256];
1188
1189 204
        vcc_NextToken(tl);
1190 204
        t1 = tl->t;
1191 204
        vcc_expr4(tl, &e2, ACL);
1192 204
        ERRCHK(tl);
1193 192
        vcc_expr_typecheck(tl, &e2, ACL, t1);
1194 192
        ERRCHK(tl);
1195 180
        bprintf(buf, "%sVRT_acl_match(ctx, \v1, \v2)", cp->emit);
1196 180
        *e = vcc_expr_edit(tl, BOOL, buf, e2, *e);
1197 204
}
1198
1199
static void v_matchproto_(cmp_f)
1200 214728
cmp_string(struct vcc *tl, struct expr **e, const struct cmps *cp)
1201
{
1202
        struct expr *e2;
1203
        struct token *tk;
1204
        char buf[128];
1205
1206 214728
        tk = tl->t;
1207 214728
        vcc_NextToken(tl);
1208 214728
        vcc_expr_add(tl, &e2, STRINGS);
1209 214728
        ERRCHK(tl);
1210 214728
        if (vcc_stringstype(e2->fmt) != STRINGS) {
1211 24
                VSB_printf(tl->sb,
1212
                    "Comparison of different types: %s '%.*s' %s\n",
1213 12
                    vcc_utype((*e)->fmt), PF(tk), vcc_utype(e2->fmt));
1214 12
                vcc_ErrWhere(tl, tk);
1215 214728
        } else if ((*e)->nstr == 1 && e2->nstr == 1) {
1216 214592
                bprintf(buf, "(%s VRT_strcmp(\v1, \v2))", cp->emit);
1217 214592
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1218 214592
        } else {
1219 124
                bprintf(buf, "(%s VRT_CompareStrands(\vT, \vt))", cp->emit);
1220 124
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1221
        }
1222 214728
}
1223
1224
#define PTR_REL(typ)                                                            \
1225
        {typ,           T_EQ,           cmp_simple, "!VPI_PtrCmp(\v1, \v2)" },  \
1226
        {typ,           T_NEQ,          cmp_simple, "VPI_PtrCmp(\v1, \v2)" }
1227
1228
#define IDENT_REL(typ)                                                  \
1229
        {typ,           T_EQ,           cmp_simple, "(\v1 == \v2)" },   \
1230
        {typ,           T_NEQ,          cmp_simple, "(\v1 != \v2)" }
1231
1232
#define NUM_REL(typ)                                                    \
1233
        IDENT_REL(typ),                                                 \
1234
        {typ,           T_LEQ,          cmp_simple, "(\v1 <= \v2)" },   \
1235
        {typ,           T_GEQ,          cmp_simple, "(\v1 >= \v2)" },   \
1236
        {typ,           '<',            cmp_simple, "(\v1 < \v2)" },    \
1237
        {typ,           '>',            cmp_simple, "(\v1 > \v2)" }
1238
1239
static const struct cmps vcc_cmps[] = {
1240
        NUM_REL(INT),
1241
        NUM_REL(DURATION),
1242
        NUM_REL(BYTES),
1243
        NUM_REL(REAL),
1244
        NUM_REL(TIME),
1245
        PTR_REL(BACKEND),
1246
        PTR_REL(ACL),
1247
        PTR_REL(PROBE),
1248
        IDENT_REL(STEVEDORE),
1249
        IDENT_REL(SUB),
1250
        IDENT_REL(INSTANCE),
1251
1252
        {BOOL,          T_EQ,           cmp_simple, "((!(\v1)) == (!(\v2)))" },
1253
        {BOOL,          T_NEQ,          cmp_simple, "((!(\v1)) != (!(\v2)))" },
1254
        {IP,            T_EQ,           cmp_simple, "!VRT_ipcmp(ctx, \v1, \v2)" },
1255
        {IP,            T_NEQ,          cmp_simple, "VRT_ipcmp(ctx, \v1, \v2)" },
1256
1257
        {IP,            '~',            cmp_acl, "" },
1258
        {IP,            T_NOMATCH,      cmp_acl, "!" },
1259
1260
        {STRINGS,       T_EQ,           cmp_string, "0 =="},
1261
        {STRINGS,       T_NEQ,          cmp_string, "0 !="},
1262
        {STRINGS,       '<',            cmp_string, "0 > "},
1263
        {STRINGS,       '>',            cmp_string, "0 < "},
1264
        {STRINGS,       T_LEQ,          cmp_string, "0 >="},
1265
        {STRINGS,       T_GEQ,          cmp_string, "0 <="},
1266
1267
        {STRINGS,       '~',            cmp_regexp, "" },
1268
        {STRINGS,       T_NOMATCH,      cmp_regexp, "!" },
1269
1270
        {VOID,          0,              NULL, NULL}
1271
};
1272
1273
#undef IDENT_REL
1274
#undef NUM_REL
1275
1276
static void
1277 761648
vcc_expr_cmp(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1278
{
1279
        const struct cmps *cp;
1280
        struct token *tk;
1281
1282 761648
        *e = NULL;
1283 761648
        vcc_expr_add(tl, e, fmt);
1284 761648
        ERRCHK(tl);
1285 761424
        tk = tl->t;
1286
1287 38541280
        for (cp = vcc_cmps; cp->fmt != VOID; cp++) {
1288 38102208
                if (tl->t->tok != cp->token)
1289 34928468
                        continue;
1290 3173740
                if (vcc_stringstype((*e)->fmt) != cp->fmt)
1291 2851388
                        continue;
1292 322352
                AN(cp->func);
1293 322352
                cp->func(tl, e, cp);
1294 322352
                return;
1295
        }
1296
1297 439072
        switch (tk->tok) {
1298
        case T_EQ:
1299
        case T_NEQ:
1300
        case '<':
1301
        case T_LEQ:
1302
        case '>':
1303
        case T_GEQ:
1304
        case '~':
1305
        case T_NOMATCH:
1306 16
                VSB_printf(tl->sb, "Operator %.*s not possible on %s\n",
1307 8
                    PF(tl->t), vcc_utype((*e)->fmt));
1308 8
                vcc_ErrWhere(tl, tl->t);
1309 8
                return;
1310
        default:
1311 439064
                break;
1312
        }
1313 761648
}
1314
1315
/*--------------------------------------------------------------------
1316
 * SYNTAX:
1317
 *    ExprNot:
1318
 *      '!' ExprCmp
1319
 */
1320
1321
static void
1322 761648
vcc_expr_not(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1323
{
1324
        struct token *tk;
1325
1326 761648
        *e = NULL;
1327 761648
        tk = tl->t;
1328 761648
        if (tl->t->tok == '!')
1329 59436
                vcc_NextToken(tl);
1330 761648
        vcc_expr_cmp(tl, e, fmt);
1331 761648
        ERRCHK(tl);
1332 761340
        if (tk->tok != '!')
1333 701908
                return;
1334 59432
        vcc_expr_tobool(tl, e);
1335 59432
        ERRCHK(tl);
1336 59432
        if ((*e)->fmt != BOOL) {
1337 4
                VSB_cat(tl->sb, "'!' must be followed by BOOL, found ");
1338 4
                VSB_printf(tl->sb, "%s.\n", vcc_utype((*e)->fmt));
1339 4
                vcc_ErrWhere2(tl, tk, tl->t);
1340 4
        } else {
1341 59428
                *e = vcc_expr_edit(tl, BOOL, "!(\v1)", *e, NULL);
1342
        }
1343 761648
}
1344
1345
/*--------------------------------------------------------------------
1346
 * CAND and COR are identical save for a few details, but they are
1347
 * stacked so handling them in the same function is not simpler.
1348
 * Instead have them both call this helper function to do everything.
1349
 */
1350
1351
typedef void upfunc(struct vcc *tl, struct expr **e, vcc_type_t fmt);
1352
1353
static void
1354 1133016
vcc_expr_bin_bool(struct vcc *tl, struct expr **e, vcc_type_t fmt,
1355
    unsigned ourtok, upfunc *up, const char *tokstr)
1356
{
1357
        struct expr *e2;
1358
        struct token *tk;
1359
        char buf[32];
1360
1361 1133016
        *e = NULL;
1362 1133016
        tk = tl->t;
1363 1133016
        up(tl, e, fmt);
1364 1133016
        ERRCHK(tl);
1365 1132384
        if (tl->t->tok != ourtok)
1366 1025856
                return;
1367 106528
        vcc_expr_tobool(tl, e);
1368 106528
        ERRCHK(tl);
1369 106528
        if ((*e)->fmt != BOOL) {
1370 16
                VSB_printf(tl->sb,
1371
                    "'%s' must be preceded by BOOL,"
1372 8
                    " found %s.\n", tokstr, vcc_utype((*e)->fmt));
1373 8
                vcc_ErrWhere2(tl, tk, tl->t);
1374 8
                return;
1375
        }
1376 106520
        *e = vcc_expr_edit(tl, BOOL, "(\v+\n\v1", *e, NULL);
1377 307592
        while (tl->t->tok == ourtok) {
1378 201080
                vcc_NextToken(tl);
1379 201080
                tk = tl->t;
1380 201080
                up(tl, &e2, fmt);
1381 201080
                ERRCHK(tl);
1382 201080
                vcc_expr_tobool(tl, &e2);
1383 201080
                ERRCHK(tl);
1384 201080
                if (e2->fmt != BOOL) {
1385 16
                        VSB_printf(tl->sb,
1386
                            "'%s' must be followed by BOOL,"
1387 8
                            " found %s.\n", tokstr, vcc_utype(e2->fmt));
1388 8
                        vcc_ErrWhere2(tl, tk, tl->t);
1389 8
                        vcc_delete_expr(e2);
1390 8
                        return;
1391
                }
1392 201072
                bprintf(buf, "\v1\v-\n%s\v+\n\v2", tokstr);
1393 201072
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1394
        }
1395 106512
        *e = vcc_expr_edit(tl, BOOL, "\v1\v-\n)", *e, NULL);
1396 1133016
}
1397
1398
/*--------------------------------------------------------------------
1399
 * SYNTAX:
1400
 *    ExprCand:
1401
 *      ExprNot { '&&' ExprNot } *
1402
 */
1403
1404
static void
1405 572448
vcc_expr_cand(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1406
{
1407
1408 572448
        vcc_expr_bin_bool(tl, e, fmt, T_CAND, vcc_expr_not, "&&");
1409 572448
}
1410
1411
/*--------------------------------------------------------------------
1412
 * SYNTAX:
1413
 *    ExprCOR:
1414
 *      ExprCand { '||' ExprCand } *
1415
 */
1416
1417
static void
1418 560568
vcc_expr_cor(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1419
{
1420
1421 560568
        vcc_expr_bin_bool(tl, e, fmt, T_COR, vcc_expr_cand, "||");
1422 560568
}
1423
1424
/*--------------------------------------------------------------------
1425
 * This function is the entry-point for getting an expression with
1426
 * a particular type, ready for inclusion in the VGC.
1427
 */
1428
1429
static void
1430 548480
vcc_expr0(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1431
{
1432
        struct token *t1;
1433
1434 548480
        assert(fmt != VOID);
1435 548480
        assert(fmt != STRINGS);
1436 548480
        *e = NULL;
1437 548480
        t1 = tl->t;
1438 548480
        if (fmt->stringform)
1439 168316
                vcc_expr_cor(tl, e, STRINGS);
1440
        else
1441 380164
                vcc_expr_cor(tl, e, fmt);
1442 548480
        ERRCHK(tl);
1443
1444 548152
        if ((*e)->fmt == fmt)
1445 308460
                return;
1446
1447 239692
        if ((*e)->fmt != STRINGS && fmt->stringform)
1448 14576
                vcc_expr_tostring(tl, e);
1449
1450 239692
        if ((*e)->fmt->stringform) {
1451 0
                VSB_printf(tl->sb, "Cannot convert type %s(%s) to %s(%s)\n",
1452 0
                    vcc_utype((*e)->fmt), (*e)->fmt->name,
1453 0
                    vcc_utype(fmt), fmt->name);
1454 0
                vcc_ErrWhere2(tl, t1, tl->t);
1455 0
                return;
1456
        }
1457
1458 239692
        if (fmt == BODY && !(*e)->fmt->bodyform)
1459 4
                vcc_expr_tostring(tl, e);
1460
1461 239692
        if (fmt == BODY && (*e)->fmt->bodyform) {
1462 23764
                if ((*e)->fmt == STRINGS)
1463 23748
                        *e = vcc_expr_edit(tl, BODY, "STRING, 0, \vT", *e, NULL);
1464 16
                else if ((*e)->fmt == BLOB)
1465 16
                        *e = vcc_expr_edit(tl, BODY, "BLOB, 0, \v1", *e, NULL);
1466
                else
1467 0
                        WRONG("Unhandled bodyform");
1468 23764
        }
1469
1470 239692
        if ((*e)->fmt == STRINGS && fmt->stringform) {
1471 168188
                if (fmt == STRING)
1472 50480
                        *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
1473 117708
                else if (fmt == STRANDS)
1474 117708
                        *e = vcc_expr_edit(tl, STRANDS, "\vT", (*e), NULL);
1475
                else
1476 0
                        WRONG("Unhandled stringform");
1477 168188
        }
1478
1479 239692
        if (fmt == BOOL) {
1480 47724
                vcc_expr_tobool(tl, e);
1481 47724
                ERRCHK(tl);
1482 47724
        }
1483
1484 239692
        vcc_expr_typecheck(tl, e, fmt, t1);
1485 548480
}
1486
1487
static void
1488 287544
vcc_expr_typecheck(struct vcc *tl, struct expr **e, vcc_type_t fmt,
1489
    struct token *t1)
1490
{
1491
1492 287544
        assert(fmt != VOID);
1493 287544
        assert(fmt != STRINGS);
1494
1495 287544
        if (fmt != (*e)->fmt)  {
1496 72
                VSB_printf(tl->sb, "Expression has type %s, expected %s\n",
1497 36
                    vcc_utype((*e)->fmt), vcc_utype(fmt));
1498 36
                vcc_ErrWhere2(tl, t1, tl->t);
1499 36
        }
1500 287544
}
1501
1502
/*--------------------------------------------------------------------
1503
 * This function parses and emits the C-code to evaluate an expression
1504
 *
1505
 * We know up front what kind of type we want the expression to be,
1506
 * and this function is the backstop if that doesn't succeed.
1507
 */
1508
1509
void
1510 537160
vcc_Expr(struct vcc *tl, vcc_type_t fmt)
1511
{
1512 537160
        struct expr *e = NULL;
1513
1514 537160
        assert(fmt != VOID);
1515 537160
        assert(fmt != STRINGS);
1516 537160
        vcc_expr0(tl, &e, fmt);
1517 537160
        ERRCHK(tl);
1518 536848
        assert(e->fmt == fmt);
1519
1520 536848
        vcc_expr_fmt(tl->fb, tl->indent, e);
1521 536848
        VSB_cat(tl->fb, "\n");
1522 536848
        vcc_delete_expr(e);
1523 537160
}
1524
1525
/*--------------------------------------------------------------------
1526
 */
1527
1528
void v_matchproto_(sym_act_f)
1529 2024
vcc_Act_Call(struct vcc *tl, struct token *t, struct symbol *sym)
1530
{
1531
1532
        struct expr *e;
1533
1534 2024
        e = NULL;
1535 2024
        vcc_func(tl, &e, sym->eval_priv, sym->extra, sym);
1536 2024
        if (!tl->err) {
1537 2004
                vcc_expr_fmt(tl->fb, tl->indent, e);
1538 2004
                SkipToken(tl, ';');
1539 2004
                VSB_cat(tl->fb, ";\n");
1540 2024
        } else if (t != tl->t) {
1541 20
                VSB_cat(tl->sb, "While compiling function call:\n\n");
1542 20
                vcc_ErrWhere2(tl, t, tl->t);
1543 20
        }
1544 2024
        vcc_delete_expr(e);
1545 2024
}
1546
1547
void v_matchproto_(sym_act_f)
1548 1336
vcc_Act_Obj(struct vcc *tl, struct token *t, struct symbol *sym)
1549
{
1550
1551 1336
        struct expr *e = NULL;
1552
1553 1336
        assert(sym->kind == SYM_INSTANCE);
1554 1336
        ExpectErr(tl, '.');
1555 1332
        tl->t = t;
1556 1332
        vcc_expr4(tl, &e, sym->type);
1557 1332
        ERRCHK(tl);
1558 1332
        vcc_expr_fmt(tl->fb, tl->indent, e);
1559 1332
        vcc_delete_expr(e);
1560 1332
        SkipToken(tl, ';');
1561 1332
        VSB_cat(tl->fb, ";\n");
1562 1336
}
1563
1564
/*--------------------------------------------------------------------
1565
 */
1566
1567
static void v_matchproto_(sym_expr_t)
1568 152
vcc_Eval_Regsub(struct vcc *tl, struct expr **e, struct token *t,
1569
    struct symbol *sym, vcc_type_t fmt)
1570
{
1571
        struct expr *e2, *e3;
1572 152
        int all = sym->eval_priv == NULL ? 0 : 1;
1573
        char buf[128];
1574
1575 152
        (void)t;
1576 152
        (void)fmt;
1577 152
        SkipToken(tl, '(');
1578 152
        vcc_expr0(tl, &e2, STRING);
1579 152
        ERRCHK(tl);
1580 152
        SkipToken(tl, ',');
1581 152
        vcc_expr0(tl, &e3, REGEX);
1582 152
        ERRCHK(tl);
1583
1584 148
        bprintf(buf, "VRT_regsub(ctx, %d,\v+\n\v1,\n\v2", all);
1585 148
        *e = vcc_expr_edit(tl, STRING, buf, e2, e3);
1586 148
        SkipToken(tl, ',');
1587 148
        vcc_expr0(tl, &e2, STRING);
1588 148
        ERRCHK(tl);
1589 148
        *e = vcc_expr_edit(tl, STRINGS, "\v1,\n\v2)\v-", *e, e2);
1590 148
        (*e)->nstr = 1;
1591 148
        SkipToken(tl, ')');
1592 152
}
1593
1594
/*--------------------------------------------------------------------
1595
 */
1596
1597
static void v_matchproto_(sym_expr_t)
1598 12852
vcc_Eval_BoolConst(struct vcc *tl, struct expr **e, struct token *t,
1599
    struct symbol *sym, vcc_type_t fmt)
1600
{
1601
1602 12852
        (void)t;
1603 12852
        (void)tl;
1604 12852
        (void)fmt;
1605 12852
        *e = vcc_mk_expr(BOOL, "(0==%d)", sym->eval_priv == NULL ? 1 : 0);
1606 12852
        (*e)->constant = EXPR_CONST;
1607 12852
}
1608
1609
/*--------------------------------------------------------------------
1610
 */
1611
1612
static void v_matchproto_(sym_expr_t)
1613 16
vcc_Eval_Default(struct vcc *tl, struct expr **e, struct token *t,
1614
    struct symbol *sym, vcc_type_t fmt)
1615
{
1616 16
        (void)e;
1617 16
        (void)fmt;
1618 16
        (void)sym;
1619 16
        (void)t;
1620
1621 16
        if (fmt->default_sym == NULL) {
1622 8
                VSB_cat(tl->sb, "Symbol 'default' is a reserved word.\n");
1623 8
                vcc_ErrWhere(tl, t);
1624 8
                return;
1625
        }
1626
1627 8
        *e = vcc_mk_expr(fmt, "%s", fmt->default_sym->rname);
1628 16
}
1629
1630
/*--------------------------------------------------------------------
1631
 */
1632
1633
void
1634 12788
vcc_Expr_Init(struct vcc *tl)
1635
{
1636
        struct symbol *sym;
1637
1638 12788
        sym = VCC_MkSym(tl, "regsub", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1639 12788
        AN(sym);
1640 12788
        sym->type = STRING;
1641 12788
        sym->eval = vcc_Eval_Regsub;
1642 12788
        sym->eval_priv = NULL;
1643
1644 12788
        sym = VCC_MkSym(tl, "regsuball", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1645 12788
        AN(sym);
1646 12788
        sym->type = STRING;
1647 12788
        sym->eval = vcc_Eval_Regsub;
1648 12788
        sym->eval_priv = sym;
1649
1650 12788
        sym = VCC_MkSym(tl, "true", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1651 12788
        AN(sym);
1652 12788
        sym->type = BOOL;
1653 12788
        sym->eval = vcc_Eval_BoolConst;
1654 12788
        sym->eval_priv = sym;
1655
1656 12788
        sym = VCC_MkSym(tl, "false", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1657 12788
        AN(sym);
1658 12788
        sym->type = BOOL;
1659 12788
        sym->eval = vcc_Eval_BoolConst;
1660 12788
        sym->eval_priv = NULL;
1661
1662 12788
        sym = VCC_MkSym(tl, "default", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1663 12788
        AN(sym);
1664 12788
        sym->type = DEFAULT;
1665 12788
        sym->eval = vcc_Eval_Default;
1666 12788
}