static struct expr * vcc_expr_edit(enum var_type fmt, const char *p, struct expr *e1, struct expr *e2) { struct expr *e; int nl = 1; e = vcc_new_expr(); while (*p != '\0') { if (*p == '\n') { if (!nl) VSB_putc(e->vsb, *p); nl = 1; p++; continue; } nl = 0; if (*p != '\v') { VSB_putc(e->vsb, *p); p++; continue; } assert(*p == '\v'); p++; switch(*p) { case '+': VSB_cat(e->vsb, "\v+"); break; case '-': VSB_cat(e->vsb, "\v-"); break; case '1': case '2': if (*p == '1') VSB_cat(e->vsb, VSB_data(e1->vsb)); else { AN(e2); VSB_cat(e->vsb, VSB_data(e2->vsb)); } break; default: assert(__LINE__ == 0); } p++; } AZ(VSB_finish(e->vsb)); if (e1 != NULL) e->t1 = e1->t1; else if (e2 != NULL) e->t1 = e2->t1; if (e2 != NULL) e->t2 = e2->t1; else if (e1 != NULL) e->t1 = e1->t1; if ((e1 == NULL || e1->constant) && (e2 == NULL || e2->constant)) e->constant = 1; vcc_delete_expr(e1); vcc_delete_expr(e2); e->fmt = fmt; return (e); }
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 struct expr * vcc_expr_edit(enum var_type fmt, const char *p, struct expr *e1, struct expr *e2) { struct expr *e; int nl = 1; AN(e1); e = vcc_new_expr(); while (*p != '\0') { if (*p != '\v') { if (*p != '\n' || !nl) VSB_putc(e->vsb, *p); nl = (*p == '\n'); p++; continue; } assert(*p == '\v'); switch(*++p) { case '+': VSB_cat(e->vsb, "\v+"); break; case '-': VSB_cat(e->vsb, "\v-"); break; case '1': VSB_cat(e->vsb, VSB_data(e1->vsb)); break; case '2': AN(e2); VSB_cat(e->vsb, VSB_data(e2->vsb)); break; default: WRONG("Illegal edit in VCC expression"); } p++; } AZ(VSB_finish(e->vsb)); e->t1 = e1->t1; e->t2 = e1->t2; if (e2 != NULL) e->t2 = e2->t2; vcc_delete_expr(e1); vcc_delete_expr(e2); e->fmt = fmt; return (e); }
void vcc_Eval_Func(struct vcc *tl, const char *cfunc, const char *extra, const char *name, const char *args) { struct expr *e = NULL; struct token *t1; t1 = tl->t; vcc_func(tl, &e, cfunc, extra, name, args); if (!tl->err) { vcc_expr_fmt(tl->fb, tl->indent, e); VSB_cat(tl->fb, ";\n"); } else if (t1 != tl->t) { vcc_ErrWhere2(tl, t1, tl->t); } vcc_delete_expr(e); }
void vcc_Expr_Call(struct vcc *tl, const struct symbol *sym) { struct expr *e; struct token *t1; t1 = tl->t; e = NULL; vcc_Eval_Func(tl, &e, sym); if (!tl->err) { vcc_expr_fmt(tl->fb, tl->indent, e); VSB_cat(tl->fb, ";\n"); } else if (t1 != tl->t) { vcc_ErrWhere2(tl, t1, tl->t); } vcc_delete_expr(e); }