static void vcc_Eval_Regsub(struct vcc *tl, struct expr **e, const struct symbol *sym) { struct expr *e2; int all = sym->eval_priv == NULL ? 0 : 1; char *p; char buf[128]; vcc_delete_expr(*e); SkipToken(tl, ID); SkipToken(tl, '('); vcc_expr0(tl, &e2, STRING); if (e2->fmt != STRING) vcc_expr_tostring(&e2, STRING); SkipToken(tl, ','); ExpectErr(tl, CSTR); p = vcc_regexp(tl); vcc_NextToken(tl); bprintf(buf, "VRT_regsub(sp, %d,\n\v1,\n%s\n", all, p); *e = vcc_expr_edit(STRING, buf, e2, *e); SkipToken(tl, ','); vcc_expr0(tl, &e2, STRING); if (e2->fmt != STRING) vcc_expr_tostring(&e2, STRING); *e = vcc_expr_edit(STRING, "\v1, \v2)", *e, e2); SkipToken(tl, ')'); }
void vcc_Expr(struct vcc *tl, enum var_type fmt) { struct expr *e; struct token *t1; assert(fmt != VOID); t1 = tl->t; vcc_expr0(tl, &e, fmt); ERRCHK(tl); if (fmt == STRING || fmt == STRING_LIST) vcc_expr_tostring(&e, fmt); if (!tl->err && fmt != e->fmt) { VSB_printf(tl->sb, "Expression has type %s, expected %s\n", vcc_Type(e->fmt), vcc_Type(fmt)); tl->err = 1; } if (!tl->err) { if (e->fmt == STRING_LIST) { e = vcc_expr_edit(STRING_LIST, "\v+\n\v1,\nvrt_magic_string_end\v-", e, NULL); } vcc_expr_fmt(tl->fb, tl->indent, e); VSB_putc(tl->fb, '\n'); } else { if (t1 != tl->t) vcc_ErrWhere2(tl, t1, tl->t); } vcc_delete_expr(e); }
static void vcc_expr4(struct vcc *tl, struct expr **e, enum var_type fmt) { struct expr *e1, *e2; const struct symbol *sym; double d; *e = NULL; if (tl->t->tok == '(') { SkipToken(tl, '('); vcc_expr0(tl, &e2, fmt); ERRCHK(tl); SkipToken(tl, ')'); *e = vcc_expr_edit(e2->fmt, "(\v1)", e2, NULL); return; } switch(tl->t->tok) { case ID: /* * XXX: what if var and func/proc had same name ? * XXX: look for SYM_VAR first for consistency ? */ sym = VCC_FindSymbol(tl, tl->t, SYM_NONE); if (sym == NULL || sym->eval == NULL) { VSB_printf(tl->sb, "Symbol not found: "); vcc_ErrToken(tl, tl->t); VSB_printf(tl->sb, " (expected type %s):\n", vcc_Type(fmt)); vcc_ErrWhere(tl, tl->t); return; } AN(sym); switch(sym->kind) { case SYM_VAR: case SYM_FUNC: case SYM_BACKEND: AN(sym->eval); AZ(*e); sym->eval(tl, e, sym); return; default: break; } VSB_printf(tl->sb, "Symbol type (%s) can not be used in expression.\n", VCC_SymKind(tl, sym)); vcc_ErrWhere(tl, tl->t); return; case CSTR: assert(fmt != VOID); e1 = vcc_new_expr(); EncToken(e1->vsb, tl->t); e1->fmt = STRING; e1->t1 = tl->t; e1->constant = 1; vcc_NextToken(tl); AZ(VSB_finish(e1->vsb)); *e = e1; break; case CNUM: /* * XXX: %g may not have enough decimals by default * XXX: but %a is ugly, isn't it ? */ assert(fmt != VOID); if (fmt == DURATION) { vcc_RTimeVal(tl, &d); ERRCHK(tl); e1 = vcc_mk_expr(DURATION, "%g", d); } else if (fmt == BYTES) { vcc_ByteVal(tl, &d); ERRCHK(tl); e1 = vcc_mk_expr(BYTES, "%.1f", d); ERRCHK(tl); } else if (fmt == REAL) { e1 = vcc_mk_expr(REAL, "%g", vcc_DoubleVal(tl)); ERRCHK(tl); } else { e1 = vcc_mk_expr(INT, "%.*s", PF(tl->t)); vcc_NextToken(tl); } e1->constant = 1; *e = e1; break; default: VSB_printf(tl->sb, "Unknown token "); vcc_ErrToken(tl, tl->t); VSB_printf(tl->sb, " when looking for %s\n\n", vcc_Type(fmt)); vcc_ErrWhere(tl, tl->t); break; } }
void vcc_Eval_Func(struct vcc *tl, struct expr **e, const struct symbol *sym) { const char *p, *r; struct expr *e1, *e2; enum var_type fmt; char buf[32]; assert(sym->kind == SYM_FUNC || sym->kind == SYM_PROC); AN(sym->cfunc); AN(sym->args); SkipToken(tl, ID); SkipToken(tl, '('); p = sym->args; e2 = vcc_mk_expr(vcc_arg_type(&p), "%s(sp\v+", sym->cfunc); while (*p != '\0') { e1 = NULL; fmt = vcc_arg_type(&p); if (fmt == VOID && !strcmp(p, "PRIV_VCL")) { r = strchr(sym->name, '.'); AN(r); e1 = vcc_mk_expr(VOID, "&vmod_priv_%.*s", r - sym->name, sym->name); p += strlen(p) + 1; } else if (fmt == VOID && !strcmp(p, "PRIV_CALL")) { bprintf(buf, "vmod_priv_%u", tl->nvmodpriv++); Fh(tl, 0, "struct vmod_priv %s;\n", buf); e1 = vcc_mk_expr(VOID, "&%s", buf); p += strlen(p) + 1; } else if (fmt == ENUM) { ExpectErr(tl, ID); ERRCHK(tl); r = p; do { if (vcc_IdIs(tl->t, p)) break; p += strlen(p) + 1; } while (*p != '\0'); if (*p == '\0') { VSB_printf(tl->sb, "Wrong enum value."); VSB_printf(tl->sb, " Expected one of:\n"); do { VSB_printf(tl->sb, "\t%s\n", r); r += strlen(r) + 1; } while (*r != '\0'); vcc_ErrWhere(tl, tl->t); return; } e1 = vcc_mk_expr(VOID, "\"%.*s\"", PF(tl->t)); while (*p != '\0') p += strlen(p) + 1; p++; SkipToken(tl, ID); if (*p != '\0') SkipToken(tl, ','); } else if (fmt == HEADER) { const struct var *v; sym = VCC_FindSymbol(tl, tl->t, SYM_NONE); ERRCHK(tl); SkipToken(tl, ID); if (sym == NULL) { VSB_printf(tl->sb, "Symbol not found.\n"); vcc_ErrWhere(tl, tl->t); return; } vcc_AddUses(tl, tl->t, sym->r_methods, "Not available"); if (sym->kind != SYM_VAR) { VSB_printf(tl->sb, "Wrong kind of symbol.\n"); vcc_ErrWhere(tl, tl->t); return; } AN(sym->var); v = sym->var; if (v->http == NULL) { VSB_printf(tl->sb, "Variable not an HTTP header.\n"); vcc_ErrWhere(tl, tl->t); return; } e1 = vcc_mk_expr(VOID, "%s, \"%s\"", v->http, v->hdr); if (*p != '\0') SkipToken(tl, ','); } else { vcc_expr0(tl, &e1, fmt); ERRCHK(tl); if (e1->fmt != fmt) { VSB_printf(tl->sb, "Wrong argument type."); VSB_printf(tl->sb, " Expected %s.", vcc_Type(fmt)); VSB_printf(tl->sb, " Got %s.\n", vcc_Type(e1->fmt)); vcc_ErrWhere2(tl, e1->t1, tl->t); return; } assert(e1->fmt == fmt); if (e1->fmt == STRING_LIST) { e1 = vcc_expr_edit(STRING_LIST, "\v+\n\v1,\nvrt_magic_string_end\v-", e1, NULL); } if (*p != '\0') SkipToken(tl, ','); } e2 = vcc_expr_edit(e2->fmt, "\v1,\n\v2", e2, e1); } SkipToken(tl, ')'); e2 = vcc_expr_edit(e2->fmt, "\v1\n)\v-", e2, NULL); *e = e2; }
static void vcc_func(struct vcc *tl, struct expr **e, const char *cfunc, const char *extra, const char *name, const char *args) { const char *p, *r; struct expr *e1, *e2; struct inifin *ifp; enum var_type fmt; char buf[32]; AN(cfunc); AN(args); AN(name); SkipToken(tl, '('); p = args; if (extra == NULL) extra = ""; e1 = vcc_mk_expr(vcc_arg_type(&p), "%s(ctx%s\v+", cfunc, extra); while (*p != '\0') { e2 = NULL; fmt = vcc_arg_type(&p); if (fmt == VOID && !strcmp(p, "PRIV_VCL")) { r = strchr(name, '.'); AN(r); e2 = vcc_mk_expr(VOID, "&vmod_priv_%.*s", (int) (r - name), name); p += strlen(p) + 1; } else if (fmt == VOID && !strcmp(p, "PRIV_CALL")) { bprintf(buf, "vmod_priv_%u", tl->unique++); ifp = New_IniFin(tl); Fh(tl, 0, "static struct vmod_priv %s;\n", buf); VSB_printf(ifp->fin, "\tvmod_priv_fini(&%s);", buf); e2 = vcc_mk_expr(VOID, "&%s", buf); p += strlen(p) + 1; } else if (fmt == ENUM) { ExpectErr(tl, ID); ERRCHK(tl); r = p; do { if (vcc_IdIs(tl->t, p)) break; p += strlen(p) + 1; } while (*p != '\0'); if (*p == '\0') { VSB_printf(tl->sb, "Wrong enum value."); VSB_printf(tl->sb, " Expected one of:\n"); do { VSB_printf(tl->sb, "\t%s\n", r); r += strlen(r) + 1; } while (*r != '\0'); vcc_ErrWhere(tl, tl->t); return; } e2 = vcc_mk_expr(VOID, "\"%.*s\"", PF(tl->t)); while (*p != '\0') p += strlen(p) + 1; p++; SkipToken(tl, ID); if (*p != '\0') /*lint !e448 */ SkipToken(tl, ','); } else { vcc_expr0(tl, &e2, fmt); ERRCHK(tl); if (e2->fmt != fmt) { VSB_printf(tl->sb, "Wrong argument type."); VSB_printf(tl->sb, " Expected %s.", vcc_Type(fmt)); VSB_printf(tl->sb, " Got %s.\n", vcc_Type(e2->fmt)); vcc_ErrWhere2(tl, e2->t1, tl->t); return; } assert(e2->fmt == fmt); if (e2->fmt == STRING_LIST) { e2 = vcc_expr_edit(STRING_LIST, "\v+\n\v1,\nvrt_magic_string_end\v-", e2, NULL); } if (*p != '\0') SkipToken(tl, ','); } e1 = vcc_expr_edit(e1->fmt, "\v1,\n\v2", e1, e2); } SkipToken(tl, ')'); e1 = vcc_expr_edit(e1->fmt, "\v1\n)\v-", e1, NULL); *e = e1; }