static void vcc_ParseVcl(struct vcc *tl) { struct token *tok; assert(vcc_IdIs(tl->t, "vcl")); vcc_NextToken(tl); tok = tl->t; tok->src->syntax = vcc_DoubleVal(tl); ERRCHK(tl); if (tl->t->e - tok->b > 4) { VSB_printf(tl->sb, "Don't play silly buggers with VCL version numbers\n"); vcc_ErrWhere2(tl, tok, tl->t); ERRCHK(tl); } if (tl->syntax != 0.0 && tok->src->syntax > tl->syntax) { VSB_printf(tl->sb, "VCL version %.1f higher than" " the top level version %.1f\n", tok->src->syntax, tl->syntax); vcc_ErrWhere2(tl, tok, tl->t); ERRCHK(tl); } ExpectErr(tl, ';'); vcc_NextToken(tl); }
static void vcc_ByteVal(struct vcc *tl, double *d) { double v, sc; v = vcc_DoubleVal(tl); ERRCHK(tl); if (tl->t->tok != ID) { VSB_printf(tl->sb, "Expected BYTES unit (B, KB, MB...) got "); vcc_ErrToken(tl, tl->t); VSB_printf(tl->sb, "\n"); vcc_ErrWhere(tl, tl->t); return; } if (vcc_IdIs(tl->t, "B")) sc = 1.; else if (vcc_IdIs(tl->t, "KB")) sc = 1024.; else if (vcc_IdIs(tl->t, "MB")) sc = 1024. * 1024.; else if (vcc_IdIs(tl->t, "GB")) sc = 1024. * 1024. * 1024.; else if (vcc_IdIs(tl->t, "TB")) sc = 1024. * 1024. * 1024. * 1024.; else { VSB_printf(tl->sb, "Unknown BYTES unit "); vcc_ErrToken(tl, tl->t); VSB_printf(tl->sb, ". Legal are 'B', 'KB', 'MB', 'GB' and 'TB'\n"); vcc_ErrWhere(tl, tl->t); return; } vcc_NextToken(tl); *d = v * sc; }
void vcc_TimeVal(struct vcc *tl, double *d) { double v, sc; v = vcc_DoubleVal(tl); ERRCHK(tl); ExpectErr(tl, ID); sc = vcc_TimeUnit(tl); *d = v * sc; }
void vcc_RTimeVal(struct vcc *tl, double *d) { double v, sc; int sign = 1; if (tl->t->tok == '-') { sign *= -1; vcc_NextToken(tl); } v = vcc_DoubleVal(tl); ERRCHK(tl); ExpectErr(tl, ID); sc = vcc_TimeUnit(tl); *d = sign * v * sc; }
static void vcc_ParseVcl(struct vcc *tl) { double ver; struct token *tok; assert(vcc_IdIs(tl->t, "vcl")); vcc_NextToken(tl); tok = tl->t; ver = vcc_DoubleVal(tl); ERRCHK(tl); if (ver != 4.0) { VSB_printf(tl->sb, "VCL version %.1f not supported.\n", ver); vcc_ErrWhere(tl, tok); ERRCHK(tl); } ExpectErr(tl, ';'); vcc_NextToken(tl); }
static void vcc_ParseVcl(struct vcc *tl) { struct token *tok; assert(vcc_IdIs(tl->t, "vcl")); vcc_NextToken(tl); tok = tl->t; tl->syntax = vcc_DoubleVal(tl); ERRCHK(tl); if (tl->syntax != 4.0) { // see TODO above VSB_printf(tl->sb, "VCL version %.1f not supported.\n", tl->syntax); vcc_ErrWhere(tl, tok); ERRCHK(tl); } ExpectErr(tl, ';'); vcc_NextToken(tl); }
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; } }
static void parse_set(struct tokenlist *tl) { struct var *vp; struct token *at, *vt; vcc_NextToken(tl); ExpectErr(tl, VAR); vt = tl->t; vp = vcc_FindVar(tl, tl->t, vcc_vars); ERRCHK(tl); assert(vp != NULL); check_writebit(tl, vp); ERRCHK(tl); Fb(tl, 1, "%s", vp->lname); vcc_NextToken(tl); switch (vp->fmt) { case INT: case SIZE: case TIME: case RTIME: case FLOAT: if (tl->t->tok != '=') Fb(tl, 0, "%s %c ", vp->rname, *tl->t->b); at = tl->t; vcc_NextToken(tl); switch (at->tok) { case T_MUL: case T_DIV: Fb(tl, 0, "%g", vcc_DoubleVal(tl)); break; case T_INCR: case T_DECR: case '=': vcc_VarVal(tl, vp, vt); ERRCHK(tl); break; default: vsb_printf(tl->sb, "Invalid assignment operator.\n"); vcc_ErrWhere(tl, at); return; } Fb(tl, 0, ");\n"); break; #if 0 /* XXX: enable if we find a legit use */ case IP: if (tl->t->tok != '=') { illegal_assignment(tl, "IP numbers"); return; } vcc_NextToken(tl); u = vcc_vcc_IpVal(tl); Fb(tl, 0, "= %uU; /* %u.%u.%u.%u */\n", u, (u >> 24) & 0xff, (u >> 16) & 0xff, (u >> 8) & 0xff, u & 0xff); break; #endif case BACKEND: if (tl->t->tok != '=') { illegal_assignment(tl, "backend"); return; } vcc_NextToken(tl); vcc_ExpectCid(tl); ERRCHK(tl); vcc_AddRef(tl, tl->t, R_BACKEND); Fb(tl, 0, "VGCDIR(_%.*s)", PF(tl->t)); vcc_NextToken(tl); Fb(tl, 0, ");\n"); break; case HASH: SkipToken(tl, T_INCR); if (!vcc_StringVal(tl)) { ERRCHK(tl); vcc_ExpectedStringval(tl); return; } Fb(tl, 0, ");\n"); /* * We count the number of operations on the req.hash * variable, so that varnishd can preallocate the worst case * number of slots for composing the hash string. */ break; case STRING: if (tl->t->tok != '=') { illegal_assignment(tl, "strings"); return; } vcc_NextToken(tl); if (!vcc_StringVal(tl)) { ERRCHK(tl); vcc_ExpectedStringval(tl); return; } do Fb(tl, 0, ", "); while (vcc_StringVal(tl)); if (tl->t->tok != ';') { ERRCHK(tl); vsb_printf(tl->sb, "Expected variable, string or semicolon\n"); vcc_ErrWhere(tl, tl->t); return; } Fb(tl, 0, "vrt_magic_string_end);\n"); break; case BOOL: if (tl->t->tok != '=') { illegal_assignment(tl, "boolean"); return; } vcc_NextToken(tl); ExpectErr(tl, ID); if (vcc_IdIs(tl->t, "true")) { Fb(tl, 0, " 1);\n", vp->lname); } else if (vcc_IdIs(tl->t, "false")) { Fb(tl, 0, " 0);\n", vp->lname); } else { vsb_printf(tl->sb, "Expected true or false\n"); vcc_ErrWhere(tl, tl->t); return; } vcc_NextToken(tl); break; default: vsb_printf(tl->sb, "Assignments not possible for type of '%s'\n", vp->name); vcc_ErrWhere(tl, tl->t); return; } }