static void vcc_expr_strfold(struct vcc *tl, struct expr **e, enum var_type fmt) { vcc_expr_add(tl, e, fmt); ERRCHK(tl); if (fmt != STRING_LIST && (*e)->fmt == STRING_LIST) *e = vcc_expr_edit(STRING, "\v+VRT_CollectString(ctx,\n\v1,\nvrt_magic_string_end)\v-", *e, NULL); if (fmt == STRING_LIST && (*e)->fmt == STRING) (*e)->fmt = STRING_LIST; }
static void vcc_expr_cmp(struct vcc *tl, struct expr **e, enum var_type fmt) { struct expr *e2; const struct cmps *cp; char buf[256]; char *re; const char *not; struct token *tk; *e = NULL; vcc_expr_add(tl, e, fmt); ERRCHK(tl); if ((*e)->fmt == BOOL) return; tk = tl->t; for (cp = vcc_cmps; cp->fmt != VOID; cp++) if ((*e)->fmt == cp->fmt && tl->t->tok == cp->token) break; if (cp->fmt != VOID) { vcc_NextToken(tl); vcc_expr_add(tl, &e2, (*e)->fmt); ERRCHK(tl); if (e2->fmt != (*e)->fmt) { /* XXX */ VSB_printf(tl->sb, "Comparison of different types: "); VSB_printf(tl->sb, "%s ", vcc_Type((*e)->fmt)); vcc_ErrToken(tl, tk); VSB_printf(tl->sb, " %s\n", vcc_Type(e2->fmt)); vcc_ErrWhere(tl, tk); return; } *e = vcc_expr_edit(BOOL, cp->emit, *e, e2); return; } if ((*e)->fmt == STRING && (tl->t->tok == '~' || tl->t->tok == T_NOMATCH)) { not = tl->t->tok == '~' ? "" : "!"; vcc_NextToken(tl); ExpectErr(tl, CSTR); re = vcc_regexp(tl); ERRCHK(tl); vcc_NextToken(tl); bprintf(buf, "%sVRT_re_match(\v1, %s)", not, re); *e = vcc_expr_edit(BOOL, buf, *e, NULL); return; } if ((*e)->fmt == IP && (tl->t->tok == '~' || tl->t->tok == T_NOMATCH)) { not = tl->t->tok == '~' ? "" : "!"; vcc_NextToken(tl); ExpectErr(tl, ID); vcc_AddRef(tl, tl->t, SYM_ACL); bprintf(buf, "%smatch_acl_named_%.*s(sp, \v1)", not, PF(tl->t)); vcc_NextToken(tl); *e = vcc_expr_edit(BOOL, buf, *e, NULL); return; } if ((*e)->fmt == IP && (tl->t->tok == T_EQ || tl->t->tok == T_NEQ)) { vcc_Acl_Hack(tl, buf); *e = vcc_expr_edit(BOOL, buf, *e, NULL); return; } if ((*e)->fmt == BACKEND && (tl->t->tok == T_EQ || tl->t->tok == T_NEQ)) { vcc_NextToken(tl); ExpectErr(tl, ID); vcc_AddRef(tl, tl->t, SYM_BACKEND); bprintf(buf, "(\v1 %.*s VGCDIR(_%.*s))", PF(tk), PF(tl->t)); vcc_NextToken(tl); *e = vcc_expr_edit(BOOL, buf, *e, NULL); return; } switch (tl->t->tok) { case T_EQ: case T_NEQ: case '<': case T_LEQ: case '>': case T_GEQ: case '~': case T_NOMATCH: VSB_printf(tl->sb, "Operator %.*s not possible on %s\n", PF(tl->t), vcc_Type((*e)->fmt)); vcc_ErrWhere(tl, tl->t); return; default: break; } if (fmt == BOOL && (*e)->fmt == STRING) { *e = vcc_expr_edit(BOOL, "(\v1 != 0)", *e, NULL); return; } }