Example #1
0
void
vcc_Eval_Backend(struct vcc *tl, struct expr **e, const struct symbol *sym)
{

	assert(sym->kind == SYM_BACKEND);

	vcc_ExpectCid(tl);
	vcc_AddRef(tl, tl->t, SYM_BACKEND);
	*e = vcc_mk_expr(BACKEND, "VGCDIR(_%.*s)", PF(tl->t));
	vcc_NextToken(tl);
}
Example #2
0
void
vcc_ParseBackend(struct vcc *tl)
{
	struct token *t_first, *t_be;
	struct symbol *sym;
	char vgcname[MAX_BACKEND_NAME + 20];

	t_first = tl->t;
	vcc_NextToken(tl);		/* ID: backend */

	vcc_ExpectCid(tl);		/* ID: name */
	ERRCHK(tl);

	if (tl->t->e - tl->t->b > MAX_BACKEND_NAME) {
		VSB_printf(tl->sb,
		    "Name of %.*s too long (max %d, is %zu):\n",
		    PF(t_first), MAX_BACKEND_NAME,
		    (size_t)(tl->t->e - tl->t->b));
		vcc_ErrWhere(tl, tl->t);
		return;
	}

	t_be = tl->t;
	vcc_NextToken(tl);

	sprintf(vgcname, "vgc_backend_%.*s", PF(t_be));
	Fh(tl, 0, "\nstatic struct director *%s;\n", vgcname);

	sym = VCC_HandleSymbol(tl, t_be, BACKEND, "%s", vgcname);
	ERRCHK(tl);

	vcc_ParseHostDef(tl, t_be, vgcname);
	ERRCHK(tl);

	if (tl->err) {
		VSB_printf(tl->sb,
		    "\nIn %.*s specification starting at:\n", PF(t_first));
		vcc_ErrWhere(tl, t_first);
		return;
	}

	if (tl->default_director == NULL || vcc_IdIs(t_be, "default")) {
		tl->default_director = sym->rname;
		tl->t_default_director = t_be;
	}
}
Example #3
0
void
vcc_ParseDirector(struct vcc *tl)
{
	struct token *t_first;
	int isfirst;

	t_first = tl->t;
	vcc_NextToken(tl);		/* ID: director | backend */

	vcc_ExpectCid(tl);		/* ID: name */
	ERRCHK(tl);
	if (tl->t->e - tl->t->b > 64) {
		VSB_printf(tl->sb,
		    "Name of %.*s too long (max 64, is %zu):\n",
		    PF(t_first), (size_t)(tl->t->e - tl->t->b));
		vcc_ErrWhere(tl, tl->t);
		return;
	}
	tl->t_dir = tl->t;
	vcc_NextToken(tl);


	isfirst = tl->ndirector;
	if (vcc_IdIs(t_first, "backend")) {
		vcc_ParseSimpleDirector(tl);
	} else {
		VSB_printf(tl->sb,
		    "\ndirectors are now in VMOD.directors\n");
		vcc_ErrWhere(tl, t_first);
		return;
	}
	if (tl->err) {
		VSB_printf(tl->sb,
		    "\nIn %.*s specification starting at:\n", PF(t_first));
		vcc_ErrWhere(tl, t_first);
		return;
	}

	if (isfirst == 1 || vcc_IdIs(tl->t_dir, "default")) {
		tl->defaultdir = tl->ndirector - 1;
		tl->t_defaultdir = tl->t_dir;
	}

	tl->t_dir = NULL;
}
Example #4
0
void
vcc_ParseProbe(struct vcc *tl)
{
	struct token *t_probe;
	char *p;

	vcc_NextToken(tl);		/* ID: probe */

	vcc_ExpectCid(tl);		/* ID: name */
	ERRCHK(tl);
	t_probe = tl->t;
	vcc_NextToken(tl);

	(void)VCC_HandleSymbol(tl, t_probe, PROBE, "%.s", PF(t_probe));
	ERRCHK(tl);

	vcc_ParseProbeSpec(tl, t_probe, &p);
	if (vcc_IdIs(t_probe, "default")) {
		vcc_AddRef(tl, t_probe, SYM_PROBE);
		tl->default_probe = p;
	}
}
Example #5
0
void
vcc_ParseProbe(struct vcc *tl)
{
	struct token *t_probe;
	int i;

	vcc_NextToken(tl);		/* ID: probe */

	vcc_ExpectCid(tl);		/* ID: name */
	ERRCHK(tl);
	t_probe = tl->t;
	vcc_NextToken(tl);
	i = vcc_AddDef(tl, t_probe, SYM_PROBE);
	if (i > 1) {
		VSB_printf(tl->sb, "Probe %.*s redefined\n", PF(t_probe));
		vcc_ErrWhere(tl, t_probe);
	}

	Fh(tl, 0, "\n#define vgc_probe_%.*s\tvgc_probe__%d\n",
	    PF(t_probe), tl->nprobe);
	vcc_ParseProbeSpec(tl);
}
Example #6
0
static void
vcc_ParseFunction(struct vcc *tl)
{
	int m, i;

	vcc_NextToken(tl);
	vcc_ExpectCid(tl, "function");
	ERRCHK(tl);

	m = IsMethod(tl->t);
	if (m == -2) {
		VSB_printf(tl->sb,
		    "VCL sub's named 'vcl*' are reserved names.\n");
		vcc_ErrWhere(tl, tl->t);
		VSB_printf(tl->sb, "Valid vcl_* methods are:\n");
		for (i = 1; method_tab[i].name != NULL; i++)
			VSB_printf(tl->sb, "\t%s\n", method_tab[i].name);
		return;
	} else if (m != -1) {
		assert(m < VCL_MET_MAX);
		tl->fb = tl->fm[m];
		if (tl->mprocs[m] == NULL) {
			(void)vcc_AddDef(tl, tl->t, SYM_SUB);
			vcc_AddRef(tl, tl->t, SYM_SUB);
			tl->mprocs[m] = vcc_AddProc(tl, tl->t);
		}
		tl->curproc = tl->mprocs[m];
		Fb(tl, 1, "  /* ... from ");
		vcc_Coord(tl, tl->fb, NULL);
		Fb(tl, 0, " */\n");
	} else {
		tl->fb = tl->fc;
		i = vcc_AddDef(tl, tl->t, SYM_SUB);
		if (i > 1) {
			VSB_printf(tl->sb,
			    "Function '%.*s' redefined\n", PF(tl->t));
			vcc_ErrWhere(tl, tl->t);
			return;
		}
		tl->curproc = vcc_AddProc(tl, tl->t);
		Fh(tl, 0, "int VGC_function_%.*s "
		    "(VRT_CTX);\n", PF(tl->t));
		Fc(tl, 1, "\nint __match_proto__(vcl_func_t)\n");
		Fc(tl, 1, "VGC_function_%.*s(VRT_CTX)\n",
		    PF(tl->t));
	}
	vcc_NextToken(tl);
	tl->indent += INDENT;
	Fb(tl, 1, "{\n");
	L(tl, vcc_Compound(tl));
	if (m == -1) {
		/*
		 * non-method subroutines must have an explicit non-action
		 * return in case they just fall through the bottom.
		 */
		Fb(tl, 1, "  return(0);\n");
	}
	Fb(tl, 1, "}\n");
	tl->indent -= INDENT;
	tl->fb = NULL;
	tl->curproc = NULL;
}
Example #7
0
void
vcc_ParseNew(struct vcc *tl)
{
	struct symbol *sy1, *sy2, *sy3;
	struct inifin *ifp;
	const char *p, *s_obj;
	char buf1[128];
	char buf2[128];

	vcc_NextToken(tl);
	ExpectErr(tl, ID);
	vcc_ExpectCid(tl, "VCL object");
	ERRCHK(tl);
	sy1 = VCC_HandleSymbol(tl, tl->t, INSTANCE, "XXX");
	ERRCHK(tl);

	/* We allow implicit use of VMOD objects:  Pretend it's ref'ed */
	sy1->nref++;

	vcc_NextToken(tl);

	ExpectErr(tl, '=');
	vcc_NextToken(tl);

	ExpectErr(tl, ID);
	sy2 = VCC_SymbolTok(tl, NULL, tl->t, SYM_OBJECT, 0);
	if (sy2 == NULL) {
		VSB_printf(tl->sb, "Symbol not found: ");
		vcc_ErrToken(tl, tl->t);
		VSB_printf(tl->sb, " at ");
		vcc_ErrWhere(tl, tl->t);
		return;
	}
	vcc_NextToken(tl);

	p = sy2->extra;

	s_obj = p;
	p += strlen(p) + 1;

	Fh(tl, 0, "static %s *vo_%s;\n\n", p, sy1->name);
	p += strlen(p) + 1;

	bprintf(buf1, ", &vo_%s, \"%s\"", sy1->name, sy1->name);
	vcc_Eval_Func(tl, p, buf1, sy2);
	ExpectErr(tl, ';');

	while (p[0] != '\0' || p[1] != '\0' || p[2] != '\0')
		p++;
	p += 3;

	ifp = New_IniFin(tl);
	p += strlen(p) + 1;
	VSB_printf(ifp->fin, "\t\t%s(&vo_%s);", p, sy1->name);

	while (p[0] != '\0' || p[1] != '\0' || p[2] != '\0')
		p++;
	p += 3;

	/* Instantiate symbols for the methods */
	bprintf(buf1, ", vo_%s", sy1->name);
	while (*p != '\0') {
		p += strlen(s_obj);
		bprintf(buf2, "%s%s", sy1->name, p);
		sy3 = VCC_Symbol(tl, NULL, buf2, NULL, SYM_FUNC, 1);
		AN(sy3);
		sy3->eval = vcc_Eval_SymFunc;
		p += strlen(p) + 1;
		sy3->eval_priv = p;
		sy3->fmt = VCC_Type(p);
		sy3->extra = TlDup(tl, buf1);
		while (p[0] != '\0' || p[1] != '\0' || p[2] != '\0')
			p++;
		p += 3;
	}
	sy1->def_e = tl->t;
}
Example #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;
	}
}