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); }
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; } }
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; }
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; } }
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); }
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; }
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; }
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; } }