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 24156
vcc_isconst(const struct expr *e)
63
{
64 24156
        AN(e->constant);
65 24156
        return (e->constant & EXPR_CONST);
66
}
67
68
static inline int
69 285004
vcc_islit(const struct expr *e)
70
{
71 285004
        AN(e->constant);
72 285004
        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 3376808
vcc_stringstype(vcc_type_t t)
85
{
86 3376808
        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 3102248
vcc_new_expr(vcc_type_t fmt)
97
{
98
        struct expr *e;
99
100 3102248
        ALLOC_OBJ(e, EXPR_MAGIC);
101 3102248
        AN(e);
102 3102248
        e->vsb = VSB_new_auto();
103 3102248
        e->fmt = fmt;
104 3102248
        e->constant = EXPR_VAR;
105 3102248
        return (e);
106
}
107
108
static struct expr * v_printflike_(2, 3)
109 828356
vcc_mk_expr(vcc_type_t fmt, const char *str, ...)
110
{
111
        va_list ap;
112
        struct expr *e;
113
114 828356
        e = vcc_new_expr(fmt);
115 828356
        va_start(ap, str);
116 828356
        VSB_vprintf(e->vsb, str, ap);
117 828356
        va_end(ap);
118 828356
        AZ(VSB_finish(e->vsb));
119 828356
        return (e);
120
}
121
122
static void
123 4001936
vcc_delete_expr(struct expr *e)
124
{
125 4001936
        if (e == NULL)
126 903104
                return;
127 3098832
        CHECK_OBJ(e, EXPR_MAGIC);
128 3098832
        VSB_destroy(&e->vsb);
129 3098832
        FREE_OBJ(e);
130 4001936
}
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 247904
vcc_strands_edit(const struct expr *e1, const struct expr *e2)
159
{
160
161 247904
        assert(e2->fmt == STRANDS || e2->fmt == STRINGS);
162
163 247904
        if (e2->fmt == STRANDS)
164 16
                VSB_cat(e1->vsb, VSB_data(e2->vsb));
165 247888
        else if (e2->nstr == 0) {
166 0
                VSB_cat(e1->vsb, "vrt_null_strands");
167 0
        }
168 247888
        else if (e2->nstr == 1)
169 223444
                VSB_printf(e1->vsb, "TOSTRAND(%s)", VSB_data(e2->vsb));
170
        else {
171 48888
                VSB_printf(e1->vsb, "TOSTRANDS(%d,\v+\n%s\v-)",
172 24444
                   e2->nstr, VSB_data(e2->vsb));
173
        }
174 247904
}
175
176
static struct expr *
177 1731428
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 1731428
        int nl = 1;
182
183 1731428
        (void) tl;
184
185 1731428
        AN(e1);
186 1731428
        e = vcc_new_expr(fmt);
187 20025804
        while (*p != '\0') {
188 18294376
                if (*p != '\v') {
189 15108380
                        if (*p != '\n' || !nl)
190 15108180
                                VSB_putc(e->vsb, *p);
191 15108380
                        nl = (*p == '\n');
192 15108380
                        p++;
193 15108380
                        continue;
194
                }
195 3185996
                assert(*p == '\v');
196 3185996
                switch (*++p) {
197 306700
                case '+': VSB_cat(e->vsb, "\v+"); nl = 0; break;
198 319524
                case '-': VSB_cat(e->vsb, "\v-"); nl = 0; break;
199
                case 'S':
200
                case 's':
201 97828
                        e3 = (*p == 'S' ? e1 : e2);
202 97828
                        AN(e3);
203 97828
                        assert(e1->fmt == STRINGS);
204 97828
                        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 97724
                                VSB_cat(e->vsb, VSB_data(e3->vsb));
212
                        }
213 97828
                        break;
214
                case 'T':
215
                case 't':
216 247800
                        e3 = (*p == 'T' ? e1 : e2);
217 247800
                        AN(e3);
218 247800
                        vcc_strands_edit(e, e3);
219 247800
                        break;
220
                case '1':
221 1385924
                        VSB_cat(e->vsb, VSB_data(e1->vsb));
222 1385924
                        break;
223
                case '2':
224 828220
                        AN(e2);
225 828220
                        VSB_cat(e->vsb, VSB_data(e2->vsb));
226 828220
                        break;
227
                default:
228 0
                        WRONG("Illegal edit in VCC expression");
229 0
                }
230 3185996
                p++;
231
        }
232 1731428
        AZ(VSB_finish(e->vsb));
233 1731428
        e->t1 = e1->t1;
234 1731428
        e->t2 = e1->t2;
235 1731428
        if (e2 != NULL)
236 828344
                e->t2 = e2->t2;
237 1731428
        vcc_delete_expr(e1);
238 1731428
        vcc_delete_expr(e2);
239 1731428
        return (e);
240
}
241
242
/*--------------------------------------------------------------------
243
 * Expand finished expression into C-source code
244
 */
245
246
static void
247 539052
vcc_expr_fmt(struct vsb *d, int ind, const struct expr *e1)
248
{
249
        char *p;
250
        int i;
251
252 539052
        if (!e1->fmt->noindent) {
253 5189000
                for (i = 0; i < ind; i++)
254 4673632
                        VSB_putc(d, ' ');
255 515368
        }
256 539052
        p = VSB_data(e1->vsb);
257 45748716
        while (*p != '\0') {
258 45209680
                if (*p == '\n') {
259 1298352
                        VSB_putc(d, '\n');
260 1298352
                        if (*++p == '\0')
261 16
                                break;
262 13794432
                        for (i = 0; i < ind; i++)
263 12496096
                                VSB_putc(d, ' ');
264 45209664
                } else if (*p != '\v') {
265 43223248
                        VSB_putc(d, *p++);
266 43223248
                } else {
267 688080
                        switch (*++p) {
268 344040
                        case '+': ind += INDENT; break;
269 344040
                        case '-': ind -= INDENT; break;
270 0
                        default:  WRONG("Illegal format in VCC expression");
271 0
                        }
272 688080
                        p++;
273
                }
274
        }
275 539052
}
276
277
/*--------------------------------------------------------------------
278
 */
279
280
static void
281 413364
vcc_expr_tobool(struct vcc *tl, struct expr **e)
282
{
283
284 413364
        if ((*e)->fmt == BOOL)
285 318528
                return;
286 94836
        if ((*e)->fmt == BACKEND || (*e)->fmt == INT)
287 40
                *e = vcc_expr_edit(tl, BOOL, "(\v1 != 0)", *e, NULL);
288 94796
        else if ((*e)->fmt == DURATION)
289 8
                *e = vcc_expr_edit(tl, BOOL, "(\v1 > 0)", *e, NULL);
290 94788
        else if ((*e)->fmt == STRINGS)
291 94764
                *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 413364
}
298
299
/*--------------------------------------------------------------------
300
 */
301
302
static void
303 254736
vcc_expr_tostring(struct vcc *tl, struct expr **e)
304
{
305
        const char *p;
306 254736
        uint8_t constant = EXPR_VAR;
307
308 254736
        CHECK_OBJ_NOTNULL(*e, EXPR_MAGIC);
309 254736
        assert((*e)->fmt != STRINGS);
310
311 254736
        p = (*e)->fmt->tostring;
312 254736
        if (p != NULL) {
313 254732
                AN(*p);
314 254732
                *e = vcc_expr_edit(tl, STRINGS, p, *e, NULL);
315 254732
                (*e)->constant = constant;
316 254732
                (*e)->nstr = 1;
317 254732
        } 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 254736
}
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 645312
vcc_Eval_Var(struct vcc *tl, struct expr **e, struct token *t,
380
    struct symbol *sym, vcc_type_t type)
381
{
382
383 645312
        (void)type;
384 645312
        vcc_AddUses(tl, t, NULL, sym, XREF_READ);
385 645312
        ERRCHK(tl);
386 645312
        *e = vcc_mk_expr(sym->type, "%s", sym->rname);
387 645312
        (*e)->constant = EXPR_VAR;
388 645312
        (*e)->nstr = 1;
389 645312
        if ((*e)->fmt == STRING)
390 296824
                (*e)->fmt = STRINGS;
391 645312
}
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 688
vcc_priv_arg(struct vcc *tl, const char *p, struct symbol *sym)
411
{
412
        char buf[64];
413
        struct inifin *ifp;
414 688
        const char *f = NULL;
415
416 688
        AN(sym);
417 688
        AN(sym->vmod_name);
418
419 688
        if (!vstrcmp(p, "PRIV_VCL"))
420 60
                return (vcc_mk_expr(VOID, "&vmod_priv_%s", sym->vmod_name));
421
422 628
        if (!vstrcmp(p, "PRIV_CALL")) {
423 88
                bprintf(buf, "vmod_priv_%u", tl->unique++);
424 88
                ifp = New_IniFin(tl);
425 88
                Fh(tl, 0, "static struct vmod_priv %s;\n", buf);
426 88
                VSB_printf(ifp->fin, "\tVRT_priv_fini(ctx, &%s);", buf);
427 88
                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 688
}
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 7304
vcc_do_enum(struct vcc *tl, const char *cfunc, int len, const char *ptr)
458
{
459
        const char *r;
460
461 7304
        (void)tl;
462 7304
        r = strchr(cfunc, '.');
463 7304
        AN(r);
464 7304
        return (vcc_mk_expr(VOID, "*%.*s.enum_%.*s",
465 7304
            (int)(r - cfunc), cfunc, len, ptr));
466
}
467
468
static void
469 16184
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 16184
        if (fa->type == ENUM) {
475 5376
                ExpectErr(tl, ID);
476 5376
                ERRCHK(tl);
477 18688
                VTAILQ_FOREACH(vv, &fa->enums->children, list)
478 18680
                        if (vcc_IdIs(tl->t, vv->value))
479 5368
                                break;
480 5376
                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 5368
                fa->result = vcc_do_enum(tl, cfunc, PF(tl->t));
489 5368
                SkipToken(tl, ID);
490 5368
        } else {
491 10808
                if (fa->type == SUB)
492 88
                        tl->subref++;
493 10808
                vcc_expr0(tl, &e2, fa->type);
494 10808
                ERRCHK(tl);
495 10776
                assert(e2->fmt == fa->type);
496 10776
                fa->result = e2;
497
        }
498 16144
        fa->avail = 1;
499 16184
}
500
501
static void
502 11240
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 11240
        CAST_OBJ_NOTNULL(vv, priv, VJSN_VAL_MAGIC);
517 11240
        assert(vjsn_is_array(vv));
518 11240
        vv = VTAILQ_FIRST(&vv->children);
519 11240
        rfmt = VCC_Type(VTAILQ_FIRST(&vv->children)->value);
520 11240
        AN(rfmt);
521 11240
        vv = VTAILQ_NEXT(vv, list);
522 11240
        cfunc = vv->value;
523 11240
        vv = VTAILQ_NEXT(vv, list);
524 11240
        sa = vv->value;
525 11240
        if (*sa == '\0') {
526 9576
                sa = NULL;
527 9576
        }
528 11240
        vv = VTAILQ_NEXT(vv, list);
529 11240
        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 11232
        tf = VTAILQ_PREV(tl->t, tokenhead, list);
541 11232
        SkipToken(tl, '(');
542 11232
        if (extra == NULL) {
543 7340
                extra = "";
544 7340
                extra_sep = "";
545 7340
        } else {
546 3892
                AN(*extra);
547 3892
                extra_sep = ", ";
548
        }
549 11232
        VTAILQ_INIT(&head);
550 38384
        for (;vv != NULL; vv = VTAILQ_NEXT(vv, list)) {
551 27152
                assert(vjsn_is_array(vv));
552 27152
                fa = calloc(1, sizeof *fa);
553 27152
                AN(fa);
554 27152
                VTAILQ_INSERT_TAIL(&head, fa, list);
555
556 27152
                vvp = VTAILQ_FIRST(&vv->children);
557 27152
                if (!memcmp(vvp->value, "PRIV_", 5)) {
558 688
                        fa->result = vcc_priv_arg(tl, vvp->value, sym);
559 688
                        vvp = VTAILQ_NEXT(vvp, list);
560 688
                        if (vvp != NULL)
561 688
                                fa->cname = fa->name = vvp->value;
562 688
                        continue;
563
                }
564 26464
                fa->type = VCC_Type(vvp->value);
565 26464
                AN(fa->type);
566 26464
                vvp = VTAILQ_NEXT(vvp, list);
567 26464
                if (vvp != NULL) {
568 26464
                        fa->name = vvp->value;
569 26464
                        vvp = VTAILQ_NEXT(vvp, list);
570 26464
                        AN(vvp); /* vmod_syntax 2.0 */
571 26464
                        fa->cname = vvp->value;
572 26464
                        vvp = VTAILQ_NEXT(vvp, list);
573 26464
                        if (vvp != NULL) {
574 18428
                                fa->val = vvp->value;
575 18428
                                vvp = VTAILQ_NEXT(vvp, list);
576 18428
                                if (vvp != NULL) {
577 15104
                                        fa->enums = vvp;
578 15104
                                        vvp = VTAILQ_NEXT(vvp, list);
579 15104
                                }
580 18428
                        }
581 26464
                }
582 26464
                if (sa != NULL && vvp != NULL && vjsn_is_true(vvp)) {
583 8292
                        fa->optional = 1;
584 8292
                        vvp = VTAILQ_NEXT(vvp, list);
585 8292
                }
586 26464
                AZ(vvp);
587 26464
        }
588
589 17996
        VTAILQ_FOREACH(fa, &head, list) {
590 16156
                if (tl->t->tok == ')')
591 356
                        break;
592 15800
                if (fa->result != NULL)
593 492
                        continue;
594 15308
                if (tl->t->tok == ID) {
595 11200
                        t1 = VTAILQ_NEXT(tl->t, list);
596 11200
                        if (t1->tok == '=')
597 3044
                                break;
598 8156
                }
599 12264
                vcc_do_arg(tl, cfunc, fa);
600 12264
                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 12264
                ERRCHK(tl);
605 12224
                if (tl->t->tok == ')')
606 5952
                        break;
607 6272
                SkipToken(tl, ',');
608 6272
        }
609 12076
        while (tl->t->tok == ID) {
610 12904
                VTAILQ_FOREACH(fa, &head, list) {
611 12900
                        if (fa->name == NULL)
612 48
                                continue;
613 12852
                        if (vcc_IdIs(tl->t, fa->name))
614 3924
                                break;
615 8928
                }
616 3928
                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 3924
                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 3920
                vcc_NextToken(tl);
630 3920
                SkipToken(tl, '=');
631 3920
                vcc_do_arg(tl, cfunc, fa);
632 3920
                ERRCHK(tl);
633 3920
                if (tl->t->tok == ')')
634 3036
                        break;
635 884
                SkipToken(tl, ',');
636
        }
637
638 11184
        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 19072
                e1 = vcc_mk_expr(rfmt, "%s(ctx%s%s\v+",
643 9536
                    cfunc, extra_sep, extra);
644 11184
        n = 0;
645 38052
        VTAILQ_FOREACH_SAFE(fa, &head, list, fa2) {
646 26868
                n++;
647 26868
                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 26868
                if (fa->result == NULL && fa->type == ENUM && fa->val != NULL)
654 1936
                        fa->result = vcc_do_enum(tl, cfunc, vstrlen(fa->val), fa->val);
655 26868
                if (fa->result == NULL && fa->val != NULL) {
656 2472
                        if (fa->type == BOOL && fa->val[0] == 'f')
657 0
                                fa->result = vcc_mk_expr(fa->type, "0");
658 2472
                        else if (fa->type == BOOL && fa->val[0] == 't')
659 0
                                fa->result = vcc_mk_expr(fa->type, "1");
660
                        else
661 2472
                                fa->result = vcc_mk_expr(fa->type, "%s", fa->val);
662 2472
                }
663 26868
                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 26868
                } else if (fa->result != NULL) {
670 35320
                        e1 = vcc_expr_edit(tl, e1->fmt, "\v1,\n\v2",
671 17660
                            e1, fa->result);
672 23308
                } 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 26868
                free(fa);
681 26868
        }
682 11184
        if (sa != NULL) {
683 1648
                *e = vcc_expr_edit(tl, e1->fmt, "\v1\v-\n}\v-\n)", e1, NULL);
684 1648
        } else {
685 9536
                *e = vcc_expr_edit(tl, e1->fmt, "\v1\v-\n)", e1, NULL);
686
        }
687 11184
        SkipToken(tl, ')');
688 11180
        vcc_AddUses(tl, tf, NULL, sym, XREF_READ);
689 11240
}
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 8440
vcc_Eval_SymFunc(struct vcc *tl, struct expr **e, struct token *t,
715
    struct symbol *sym, vcc_type_t fmt)
716
{
717
718 8440
        (void)t;
719 8440
        (void)fmt;
720 8440
        assert(sym->kind == SYM_FUNC || sym->kind == SYM_METHOD);
721 8440
        AN(sym->eval_priv);
722
723 8440
        vcc_func(tl, e, sym->eval_priv, sym->extra, sym);
724 8440
        ERRCHK(tl);
725 8400
        if ((*e)->fmt == STRING) {
726 3048
                (*e)->fmt = STRINGS;
727 3048
                (*e)->nstr = 1;
728 3048
        }
729 8440
}
730
731
/*--------------------------------------------------------------------
732
 */
733
734
static void
735 146628
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 146628
        assert(fmt != VOID);
742 146628
        if (fmt == BYTES) {
743 212
                vcc_ByteVal(tl, &vi);
744 212
                ERRCHK(tl);
745 204
                e1 = vcc_mk_expr(BYTES, "%ju", (intmax_t)vi);
746 204
        } else {
747 146416
                t = tl->t;
748 146416
                vcc_NextToken(tl);
749 146416
                if (tl->t->tok == ID) {
750 12892
                        e1 = vcc_mk_expr(DURATION, "%s%.3f * %g",
751 12892
                            sign, t->num, vcc_DurationUnit(tl));
752 12892
                        ERRCHK(tl);
753 146412
                } else if (fmt == REAL || t->tok == FNUM) {
754 724
                        e1 = vcc_mk_expr(REAL, "%s%.3f", sign, t->num);
755 724
                } else {
756 132800
                        e1 = vcc_mk_expr(INT, "%s%.0fLL", sign, t->num);
757
                }
758
        }
759 146616
        e1->constant = EXPR_CONST;
760 146616
        *e = e1;
761 146628
}
762
763
/*--------------------------------------------------------------------
764
 * SYNTAX:
765
 *    Expr5:
766
 *      '(' ExprCor ')'
767
 *      symbol
768
 *      CNUM
769
 *      FNUM
770
 *      CSTR
771
 *      CBLOB
772
 */
773
774
static void
775 1366856
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 1366856
        sign = "";
783 1366856
        *e = NULL;
784 1366856
        if (tl->t->tok == '(') {
785 12012
                SkipToken(tl, '(');
786 12012
                vcc_expr_cor(tl, &e2, fmt);
787 12012
                ERRCHK(tl);
788 12012
                SkipToken(tl, ')');
789 12012
                if (e2->fmt == STRINGS)
790 24
                        *e = e2;
791
                else
792 11988
                        *e = vcc_expr_edit(tl, e2->fmt, "(\v1)", e2, NULL);
793 12012
                return;
794
        }
795 1354844
        switch (tl->t->tok) {
796
        case ID:
797 668676
                t = tl->t;
798 668676
                t1 = vcc_PeekToken(tl);
799 668676
                AN(t1);
800 668676
                sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
801
                    SYMTAB_PARTIAL_NOERR, XREF_REF);
802 668676
                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 668668
                ERRCHK(tl);
810 668668
                if (sym == NULL)
811 48
                        AZ(VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
812
                            SYMTAB_PARTIAL, XREF_REF));
813 668668
                ERRCHK(tl);
814 668620
                AN(sym);
815 668620
                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 665524
                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 665520
                if (sym->eval != NULL) {
827 665508
                        AN(sym->eval);
828 665508
                        AZ(*e);
829 665508
                        sym->eval(tl, e, t, sym, fmt);
830 665508
                        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 665508
                        ERRCHK(tl);
836
                        /* Unless asked for a HEADER, fold to string here */
837 665444
                        if (*e && fmt != HEADER && (*e)->fmt == HEADER) {
838 169244
                                vcc_expr_tostring(tl, e);
839 169244
                                ERRCHK(tl);
840 169244
                        }
841 665444
                        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 539476
                assert(fmt != VOID);
854 539476
                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 539460
                } else if (fmt == REGEX) {
875 47700
                        e1 = vcc_new_expr(REGEX);
876 47700
                        vcc_regexp(tl, e1->vsb);
877 47700
                        AZ(VSB_finish(e1->vsb));
878 47700
                } else {
879 491656
                        e1 = vcc_new_expr(STRINGS);
880 491656
                        EncToken(e1->vsb, tl->t);
881 491656
                        AZ(VSB_finish(e1->vsb));
882 491656
                        e1->constant |= EXPR_STR_CONST;
883 491656
                        e1->nstr = 1;
884
                }
885 539460
                e1->t1 = tl->t;
886 539460
                e1->constant |= EXPR_CONST;
887 539460
                vcc_NextToken(tl);
888 539460
                *e = e1;
889 539460
                return;
890
        case '-':
891 248
                if (fmt != INT &&
892 64
                    fmt != REAL &&
893 16
                    fmt != DURATION &&
894 4
                    fmt != STRINGS)
895 0
                        break;
896 244
                vcc_NextToken(tl);
897 244
                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 208
                sign = "-";
904
                /* FALLTHROUGH */
905
        case FNUM:
906
        case CNUM:
907 146628
                vcc_number(tl, e, fmt, sign);
908 146628
                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 1366856
}
926
927
/*--------------------------------------------------------------------
928
 * SYNTAX:
929
 *    Expr4:
930
 *      Expr5 [ '.' (type_attribute | type_method()) ]*
931
 */
932
933
void
934 11868
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 11868
        (void)t;
940 11868
        impl = VCC_Type_EvalMethod(tl, sym);
941 11868
        ERRCHK(tl);
942 11868
        AN(impl);
943 11868
        *e = vcc_expr_edit(tl, fmt, impl, *e, NULL);
944 11868
}
945
946
static void
947 1366856
vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt)
948
{
949
        struct symbol *sym;
950
951 1366856
        *e = NULL;
952 1366856
        vcc_expr5(tl, e, fmt);
953 1366856
        ERRCHK(tl);
954 1366664
        AN(*e);
955 1381620
        while (tl->t->tok == '.') {
956 14968
                vcc_NextToken(tl);
957 14968
                ExpectErr(tl, ID);
958
959 14964
                sym = VCC_TypeSymbol(tl, SYM_METHOD, (*e)->fmt);
960 14964
                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 14956
                AN(sym->eval);
969 14956
                sym->eval(tl, e, tl->t, sym, sym->type);
970 14956
                ERRCHK(tl);
971 14956
                if ((*e)->fmt == STRING) {
972 11824
                        (*e)->fmt = STRINGS;
973 11824
                        (*e)->nstr = 1;
974 11824
                }
975
        }
976 1366856
}
977
978
/*--------------------------------------------------------------------
979
 * SYNTAX:
980
 *    ExprMul:
981
 *      Expr4 { {'*'|'/'|'%'} Expr4 } *
982
 */
983
984
static void
985 1317632
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 1317632
        *e = NULL;
993 1317632
        vcc_expr4(tl, e, fmt);
994 1317632
        ERRCHK(tl);
995 1317456
        AN(*e);
996
997 1317620
        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 1317632
}
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 1032492
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 1032492
        *e = NULL;
1066 1032492
        vcc_expr_mul(tl, e, fmt);
1067 1032492
        ERRCHK(tl);
1068
1069 1317396
        while (tl->t->tok == '+' || tl->t->tok == '-') {
1070 285140
                tk = tl->t;
1071 4558952
                for (ap = vcc_adds; ap->op != EOI; ap++)
1072 4274144
                        if (tk->tok == ap->op && (*e)->fmt == ap->a)
1073 332
                                break;
1074 285140
                vcc_NextToken(tl);
1075 285140
                if (ap->op == EOI && fmt == STRINGS)
1076 2040
                        vcc_expr_mul(tl, &e2, STRINGS);
1077
                else
1078 283100
                        vcc_expr_mul(tl, &e2, (*e)->fmt);
1079 285140
                ERRCHK(tl);
1080
1081 4559504
                for (ap = vcc_adds; ap->op != EOI; ap++)
1082 4274656
                        if (tk->tok == ap->op && (*e)->fmt == ap->a &&
1083 4274656
                            e2->fmt == ap->b)
1084 292
                                break;
1085
1086 285140
                if (ap->op == '+') {
1087 212
                        *e = vcc_expr_edit(tl, ap->fmt, "(\v1 + \v2)", *e, e2);
1088 285140
                } else if (ap->op == '-') {
1089 80
                        *e = vcc_expr_edit(tl, ap->fmt, "(\v1 - \v2)", *e, e2);
1090 285000
                } else if (tk->tok == '+' &&
1091 284844
                    ((*e)->fmt == STRINGS || fmt == STRINGS)) {
1092 284804
                        if ((*e)->fmt != STRINGS)
1093 32
                                vcc_expr_tostring(tl, e);
1094 284804
                        if (e2->fmt != STRINGS)
1095 70920
                                vcc_expr_tostring(tl, &e2);
1096 284804
                        if (vcc_islit(*e) && vcc_isconst(e2)) {
1097 200
                                lit = vcc_islit(e2);
1098 400
                                *e = vcc_expr_edit(tl, STRINGS,
1099 200
                                    "\v1\n\v2", *e, e2);
1100 200
                                (*e)->constant = EXPR_CONST;
1101 200
                                (*e)->nstr = 1;
1102 200
                                if (lit)
1103 200
                                        (*e)->constant |= EXPR_STR_CONST;
1104 200
                        } else {
1105 284604
                                n = (*e)->nstr + e2->nstr;
1106 569208
                                *e = vcc_expr_edit(tl, STRINGS,
1107 284604
                                    "\v1,\n\v2", *e, e2);
1108 284604
                                (*e)->constant = EXPR_VAR;
1109 284604
                                (*e)->nstr = n;
1110
                        }
1111 284804
                } 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 1032492
}
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 59544
cmp_simple(struct vcc *tl, struct expr **e, const struct cmps *cp)
1146
{
1147
        struct expr *e2;
1148
        struct token *tk;
1149
1150 59544
        tk = tl->t;
1151 59544
        vcc_NextToken(tl);
1152 59544
        vcc_expr_add(tl, &e2, (*e)->fmt);
1153 59544
        ERRCHK(tl);
1154
1155 59532
        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 59524
                *e = vcc_expr_edit(tl, BOOL, cp->emit, *e, e2);
1162 59544
}
1163
1164
static void v_matchproto_(cmp_f)
1165 47516
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 47516
        *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
1172 47516
        vcc_NextToken(tl);
1173 47516
        t1 = tl->t;
1174 47516
        vcc_expr4(tl, &e2, REGEX);
1175 47516
        ERRCHK(tl);
1176 47500
        vcc_expr_typecheck(tl, &e2, REGEX, t1);
1177 47500
        ERRCHK(tl);
1178 47496
        bprintf(buf, "%sVRT_re_match(ctx, \v1, \v2)", cp->emit);
1179 47496
        *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1180 47516
}
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 213988
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 213988
        tk = tl->t;
1207 213988
        vcc_NextToken(tl);
1208 213988
        vcc_expr_add(tl, &e2, STRINGS);
1209 213988
        ERRCHK(tl);
1210 213988
        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 213988
        } else if ((*e)->nstr == 1 && e2->nstr == 1) {
1216 213852
                bprintf(buf, "(%s VRT_strcmp(\v1, \v2))", cp->emit);
1217 213852
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1218 213852
        } 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 213988
}
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 758960
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 758960
        *e = NULL;
1283 758960
        vcc_expr_add(tl, e, fmt);
1284 758960
        ERRCHK(tl);
1285 758736
        tk = tl->t;
1286
1287 38404504
        for (cp = vcc_cmps; cp->fmt != VOID; cp++) {
1288 37967020
                if (tl->t->tok != cp->token)
1289 34804200
                        continue;
1290 3162820
                if (vcc_stringstype((*e)->fmt) != cp->fmt)
1291 2841568
                        continue;
1292 321252
                AN(cp->func);
1293 321252
                cp->func(tl, e, cp);
1294 321252
                return;
1295
        }
1296
1297 437484
        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 437476
                break;
1312
        }
1313 758960
}
1314
1315
/*--------------------------------------------------------------------
1316
 * SYNTAX:
1317
 *    ExprNot:
1318
 *      '!' ExprCmp
1319
 */
1320
1321
static void
1322 758960
vcc_expr_not(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1323
{
1324
        struct token *tk;
1325
1326 758960
        *e = NULL;
1327 758960
        tk = tl->t;
1328 758960
        if (tl->t->tok == '!')
1329 59236
                vcc_NextToken(tl);
1330 758960
        vcc_expr_cmp(tl, e, fmt);
1331 758960
        ERRCHK(tl);
1332 758652
        if (tk->tok != '!')
1333 699420
                return;
1334 59232
        vcc_expr_tobool(tl, e);
1335 59232
        ERRCHK(tl);
1336 59232
        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 59228
                *e = vcc_expr_edit(tl, BOOL, "!(\v1)", *e, NULL);
1342
        }
1343 758960
}
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 1128960
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 1128960
        *e = NULL;
1362 1128960
        tk = tl->t;
1363 1128960
        up(tl, e, fmt);
1364 1128960
        ERRCHK(tl);
1365 1128328
        if (tl->t->tok != ourtok)
1366 1022160
                return;
1367 106168
        vcc_expr_tobool(tl, e);
1368 106168
        ERRCHK(tl);
1369 106168
        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 106160
        *e = vcc_expr_edit(tl, BOOL, "(\v+\n\v1", *e, NULL);
1377 306552
        while (tl->t->tok == ourtok) {
1378 200400
                vcc_NextToken(tl);
1379 200400
                tk = tl->t;
1380 200400
                up(tl, &e2, fmt);
1381 200400
                ERRCHK(tl);
1382 200400
                vcc_expr_tobool(tl, &e2);
1383 200400
                ERRCHK(tl);
1384 200400
                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 200392
                bprintf(buf, "\v1\v-\n%s\v+\n\v2", tokstr);
1393 200392
                *e = vcc_expr_edit(tl, BOOL, buf, *e, e2);
1394
        }
1395 106152
        *e = vcc_expr_edit(tl, BOOL, "\v1\v-\n)", *e, NULL);
1396 1128960
}
1397
1398
/*--------------------------------------------------------------------
1399
 * SYNTAX:
1400
 *    ExprCand:
1401
 *      ExprNot { '&&' ExprNot } *
1402
 */
1403
1404
static void
1405 570400
vcc_expr_cand(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1406
{
1407
1408 570400
        vcc_expr_bin_bool(tl, e, fmt, T_CAND, vcc_expr_not, "&&");
1409 570400
}
1410
1411
/*--------------------------------------------------------------------
1412
 * SYNTAX:
1413
 *    ExprCOR:
1414
 *      ExprCand { '||' ExprCand } *
1415
 */
1416
1417
static void
1418 558560
vcc_expr_cor(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1419
{
1420
1421 558560
        vcc_expr_bin_bool(tl, e, fmt, T_COR, vcc_expr_cand, "||");
1422 558560
}
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 546512
vcc_expr0(struct vcc *tl, struct expr **e, vcc_type_t fmt)
1431
{
1432
        struct token *t1;
1433
1434 546512
        assert(fmt != VOID);
1435 546512
        assert(fmt != STRINGS);
1436 546512
        *e = NULL;
1437 546512
        t1 = tl->t;
1438 546512
        if (fmt->stringform)
1439 167736
                vcc_expr_cor(tl, e, STRINGS);
1440
        else
1441 378776
                vcc_expr_cor(tl, e, fmt);
1442 546512
        ERRCHK(tl);
1443
1444 546184
        if ((*e)->fmt == fmt)
1445 307312
                return;
1446
1447 238872
        if ((*e)->fmt != STRINGS && fmt->stringform)
1448 14536
                vcc_expr_tostring(tl, e);
1449
1450 238872
        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 238872
        if (fmt == BODY && !(*e)->fmt->bodyform)
1459 4
                vcc_expr_tostring(tl, e);
1460
1461 238872
        if (fmt == BODY && (*e)->fmt->bodyform) {
1462 23684
                if ((*e)->fmt == STRINGS)
1463 23668
                        *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 23684
        }
1469
1470 238872
        if ((*e)->fmt == STRINGS && fmt->stringform) {
1471 167608
                if (fmt == STRING)
1472 50312
                        *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
1473 117296
                else if (fmt == STRANDS)
1474 117296
                        *e = vcc_expr_edit(tl, STRANDS, "\vT", (*e), NULL);
1475
                else
1476 0
                        WRONG("Unhandled stringform");
1477 167608
        }
1478
1479 238872
        if (fmt == BOOL) {
1480 47564
                vcc_expr_tobool(tl, e);
1481 47564
                ERRCHK(tl);
1482 47564
        }
1483
1484 238872
        vcc_expr_typecheck(tl, e, fmt, t1);
1485 546512
}
1486
1487
static void
1488 286564
vcc_expr_typecheck(struct vcc *tl, struct expr **e, vcc_type_t fmt,
1489
    struct token *t1)
1490
{
1491
1492 286564
        assert(fmt != VOID);
1493 286564
        assert(fmt != STRINGS);
1494
1495 286564
        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 286564
}
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 535252
vcc_Expr(struct vcc *tl, vcc_type_t fmt)
1511
{
1512 535252
        struct expr *e = NULL;
1513
1514 535252
        assert(fmt != VOID);
1515 535252
        assert(fmt != STRINGS);
1516 535252
        vcc_expr0(tl, &e, fmt);
1517 535252
        ERRCHK(tl);
1518 534940
        assert(e->fmt == fmt);
1519
1520 534940
        vcc_expr_fmt(tl->fb, tl->indent, e);
1521 534940
        VSB_cat(tl->fb, "\n");
1522 534940
        vcc_delete_expr(e);
1523 535252
}
1524
1525
/*--------------------------------------------------------------------
1526
 */
1527
1528
void v_matchproto_(sym_act_f)
1529 1996
vcc_Act_Call(struct vcc *tl, struct token *t, struct symbol *sym)
1530
{
1531
1532
        struct expr *e;
1533
1534 1996
        e = NULL;
1535 1996
        vcc_func(tl, &e, sym->eval_priv, sym->extra, sym);
1536 1996
        if (!tl->err) {
1537 1976
                vcc_expr_fmt(tl->fb, tl->indent, e);
1538 1976
                SkipToken(tl, ';');
1539 1976
                VSB_cat(tl->fb, ";\n");
1540 1996
        } 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 1996
        vcc_delete_expr(e);
1545 1996
}
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 12812
vcc_Eval_BoolConst(struct vcc *tl, struct expr **e, struct token *t,
1599
    struct symbol *sym, vcc_type_t fmt)
1600
{
1601
1602 12812
        (void)t;
1603 12812
        (void)tl;
1604 12812
        (void)fmt;
1605 12812
        *e = vcc_mk_expr(BOOL, "(0==%d)", sym->eval_priv == NULL ? 1 : 0);
1606 12812
        (*e)->constant = EXPR_CONST;
1607 12812
}
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 12748
vcc_Expr_Init(struct vcc *tl)
1635
{
1636
        struct symbol *sym;
1637
1638 12748
        sym = VCC_MkSym(tl, "regsub", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1639 12748
        AN(sym);
1640 12748
        sym->type = STRING;
1641 12748
        sym->eval = vcc_Eval_Regsub;
1642 12748
        sym->eval_priv = NULL;
1643
1644 12748
        sym = VCC_MkSym(tl, "regsuball", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1645 12748
        AN(sym);
1646 12748
        sym->type = STRING;
1647 12748
        sym->eval = vcc_Eval_Regsub;
1648 12748
        sym->eval_priv = sym;
1649
1650 12748
        sym = VCC_MkSym(tl, "true", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1651 12748
        AN(sym);
1652 12748
        sym->type = BOOL;
1653 12748
        sym->eval = vcc_Eval_BoolConst;
1654 12748
        sym->eval_priv = sym;
1655
1656 12748
        sym = VCC_MkSym(tl, "false", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1657 12748
        AN(sym);
1658 12748
        sym->type = BOOL;
1659 12748
        sym->eval = vcc_Eval_BoolConst;
1660 12748
        sym->eval_priv = NULL;
1661
1662 12748
        sym = VCC_MkSym(tl, "default", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
1663 12748
        AN(sym);
1664 12748
        sym->type = DEFAULT;
1665 12748
        sym->eval = vcc_Eval_Default;
1666 12748
}