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