Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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);
}
Пример #6
0
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);
}
Пример #7
0
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;
	}
}
Пример #8
0
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;
	}
}