const char * vcc_regexp(struct vcc *tl) { char buf[BUFSIZ], *p; vre_t *t; const char *error; int erroroffset; struct inifin *ifp; Expect(tl, CSTR); if (tl->err) return (NULL); t = VRE_compile(tl->t->dec, 0, &error, &erroroffset); if (t == NULL) { VSB_printf(tl->sb, "Regexp compilation error:\n\n%s\n\n", error); vcc_ErrWhere(tl, tl->t); return (NULL); } VRE_free(&t); bprintf(buf, "VGC_re_%u", tl->unique++); p = TlAlloc(tl, strlen(buf) + 1); strcpy(p, buf); Fh(tl, 0, "static void *%s;\n", buf); ifp = New_IniFin(tl); VSB_printf(ifp->ini, "\tVRT_re_init(&%s, ",buf); EncToken(ifp->ini, tl->t); VSB_printf(ifp->ini, ");"); VSB_printf(ifp->fin, "\t\tVRT_re_fini(%s);", buf); vcc_NextToken(tl); return (p); }
static void vcc_suckaddr(struct vcc *tl, const char *host, const struct suckaddr *vsa, const char **ip, const char **ip_ascii, const char **p_ascii) { char a[VTCP_ADDRBUFSIZE]; char p[VTCP_PORTBUFSIZE]; const int sz = sizeof(unsigned long long); const unsigned n = (vsa_suckaddr_len + sz - 1) / sz; unsigned long long b[n]; int len; char *q; VTCP_name(vsa, a, sizeof a, p, sizeof p); Fh(tl, 0, "\n/* \"%s\" -> %s */\n", host, a); if (ip_ascii != NULL) *ip_ascii = TlDup(tl, a); if (p_ascii != NULL && *p_ascii == NULL) *p_ascii = TlDup(tl, p); Fh(tl, 0, "static const unsigned long long"); Fh(tl, 0, " suckaddr_%u[%d] = {\n", tl->unique, n); memcpy(b, vsa, vsa_suckaddr_len); for (len = 0; len < n; len++) Fh(tl, 0, "%s 0x%0*llxULL", len ? ",\n" : "", sz * 2, b[len]); Fh(tl, 0, "\n};\n"); q = TlAlloc(tl, 40); AN(q); assert(snprintf(q, 40, "(const void*)suckaddr_%u", tl->unique) < 40); *ip = q; tl->unique++; }
static void vcc_ParseSimpleDirector(struct vcc *tl) { struct host *h; char vgcname[BUFSIZ]; h = TlAlloc(tl, sizeof *h); h->name = tl->t_dir; vcc_DefBackend(tl, tl->t_dir); ERRCHK(tl); sprintf(vgcname, "_%.*s", PF(h->name)); h->vgcname = TlAlloc(tl, strlen(vgcname) + 1); strcpy(h->vgcname, vgcname); vcc_ParseHostDef(tl, -1, vgcname); ERRCHK(tl); VTAILQ_INSERT_TAIL(&tl->hosts, h, list); }
void vcc_AddToken(struct tokenlist *tl, unsigned tok, const char *b, const char *e) { struct token *t; t = TlAlloc(tl, sizeof *t); assert(t != NULL); t->tok = tok; t->b = b; t->e = e; t->src = tl->src; if (tl->t != NULL) VTAILQ_INSERT_AFTER(&tl->tokens, tl->t, t, list); else VTAILQ_INSERT_TAIL(&tl->tokens, t, list); tl->t = t; }
static struct var * vcc_Stv_mkvar(struct vcc *tl, const struct token *t, enum var_type fmt) { struct var *v; v = TlAlloc(tl, sizeof *v); AN(v); v->name = TlDupTok(tl, t); v->r_methods = 0; #define VCL_MET_MAC(l,u,t,b) v->r_methods |= VCL_MET_##u; #include "tbl/vcl_returns.h" #undef VCL_MET_MAC v->fmt = fmt; return (v); }
static int vcc_decstr(struct tokenlist *tl) { const char *p; char *q; unsigned char u; assert(tl->t->tok == CSTR); tl->t->dec = TlAlloc(tl, (tl->t->e - tl->t->b) - 1); assert(tl->t->dec != NULL); q = tl->t->dec; for (p = tl->t->b + 1; p < tl->t->e - 1; ) { if (*p != '%') { *q++ = *p++; continue; } if (p + 4 > tl->t->e) { vcc_AddToken(tl, CSTR, p, tl->t->e); vsb_printf(tl->sb, "Incomplete %%xx escape\n"); vcc_ErrWhere(tl, tl->t); return(1); } if (!isxdigit(p[1]) || !isxdigit(p[2])) { vcc_AddToken(tl, CSTR, p, p + 3); vsb_printf(tl->sb, "Invalid hex char in %%xx escape\n"); vcc_ErrWhere(tl, tl->t); return(1); } u = (vcc_xdig(p[1]) * 16 + vcc_xdig(p[2])) & 0xff; if (!isgraph(u)) { vcc_AddToken(tl, CSTR, p, p + 3); vsb_printf(tl->sb, "Control character in %%xx escape\n"); vcc_ErrWhere(tl, tl->t); return(1); } *q++ = u; p += 3; } *q++ = '\0'; return (0); }
struct symbol * vcc_Var_Wildcard(struct vcc *tl, const struct token *t, const struct symbol *wc) { struct symbol *sym; struct var *v; const struct var *vh; int l; char buf[258]; vh = wc->var; v = TlAlloc(tl, sizeof *v); AN(v); v->name = TlDupTok(tl, t); v->r_methods = vh->r_methods; v->w_methods = vh->w_methods; v->fmt = STRING; v->http = vh->http; l = strlen(v->name + vh->len) + 1; bprintf(buf, "\\%03o%s:", (unsigned)l, v->name + vh->len); v->hdr = TlDup(tl, buf); bprintf(buf, "VRT_GetHdr(sp, %s, \"%s\")", v->http, v->hdr); v->rname = TlDup(tl, buf); bprintf(buf, "VRT_SetHdr(sp, %s, \"%s\", ", v->http, v->hdr); v->lname = TlDup(tl, buf); sym = VCC_AddSymbolTok(tl, t, SYM_VAR); AN(sym); sym->var = v; sym->fmt = v->fmt; sym->eval = vcc_Eval_Var; sym->r_methods = v->r_methods; return (sym); }
void vcc_Lexer(struct tokenlist *tl, struct source *sp) { const char *p, *q; unsigned u; tl->src = sp; for (p = sp->b; p < sp->e; ) { /* Skip any whitespace */ if (isspace(*p)) { p++; continue; } /* Skip '#.*\n' comments */ if (*p == '#') { while (p < sp->e && *p != '\n') p++; continue; } /* Skip C-style comments */ if (*p == '/' && p[1] == '*') { for (q = p + 2; q < sp->e; q++) { if (*q == '/' && q[1] == '*') { vsb_printf(tl->sb, "/* ... */ comment contains /*\n"); vcc_AddToken(tl, EOI, p, p + 2); vcc_ErrWhere(tl, tl->t); vcc_AddToken(tl, EOI, q, q + 2); vcc_ErrWhere(tl, tl->t); return; } if (*q == '*' && q[1] == '/') { p = q + 2; break; } } if (q < sp->e) continue; vcc_AddToken(tl, EOI, p, p + 2); vsb_printf(tl->sb, "Unterminated /* ... */ comment, starting at\n"); vcc_ErrWhere(tl, tl->t); return; } /* Skip C++-style comments */ if (*p == '/' && p[1] == '/') { while (p < sp->e && *p != '\n') p++; continue; } /* Recognize inline C-code */ if (*p == 'C' && p[1] == '{') { for (q = p + 2; q < sp->e; q++) { if (*q == '}' && q[1] == 'C') { vcc_AddToken(tl, CSRC, p, q + 2); break; } } if (q < sp->e) { p = q + 2; continue; } vcc_AddToken(tl, EOI, p, p + 2); vsb_printf(tl->sb, "Unterminated inline C source, starting at\n"); vcc_ErrWhere(tl, tl->t); return; } /* Recognize long-strings */ if (*p == '{' && p[1] == '"') { for (q = p + 2; q < sp->e; q++) { if (*q == '"' && q[1] == '}') { vcc_AddToken(tl, CSTR, p, q + 2); break; } } if (q < sp->e) { p = q + 2; u = tl->t->e - tl->t->b; u -= 4; /* {" ... "} */ tl->t->dec = TlAlloc(tl, u + 1 ); AN(tl->t->dec); memcpy(tl->t->dec, tl->t->b + 2, u); tl->t->dec[u] = '\0'; continue; } vcc_AddToken(tl, EOI, p, p + 2); vsb_printf(tl->sb, "Unterminated long-string, starting at\n"); vcc_ErrWhere(tl, tl->t); return; } /* Match for the fixed tokens (see token.tcl) */ u = vcl_fixed_token(p, &q); if (u != 0) { vcc_AddToken(tl, u, p, q); p = q; continue; } /* Match strings, with \\ and \" escapes */ if (*p == '"') { for (q = p + 1; q < sp->e; q++) { if (*q == '"') { q++; break; } if (*q == '\r' || *q == '\n') { vcc_AddToken(tl, EOI, p, q); vsb_printf(tl->sb, "Unterminated string at\n"); vcc_ErrWhere(tl, tl->t); return; } } vcc_AddToken(tl, CSTR, p, q); if (vcc_decstr(tl)) return; p = q; continue; } /* Match Identifiers */ if (isident1(*p)) { for (q = p; q < sp->e; q++) if (!isident(*q)) break; if (isvar(*q)) { for (; q < sp->e; q++) if (!isvar(*q)) break; vcc_AddToken(tl, VAR, p, q); } else { vcc_AddToken(tl, ID, p, q); } p = q; continue; } /* Match numbers { [0-9]+ } */ if (isdigit(*p)) { for (q = p; q < sp->e; q++) if (!isdigit(*q)) break; vcc_AddToken(tl, CNUM, p, q); p = q; continue; } vcc_AddToken(tl, EOI, p, p + 1); vsb_printf(tl->sb, "Syntax error at\n"); vcc_ErrWhere(tl, tl->t); return; } }