#include "cache.h"
void
-VRT_re_init(void **rep, const char *re)
+VRT_re_init(void **rep, const char *re, int sub)
{
regex_t *t;
t = calloc(sizeof *t, 1);
XXXAN(t);
/* This was already check-compiled by the VCL compiler */
- AZ(regcomp(t, re, REG_EXTENDED | REG_NOSUB));
+ AZ(regcomp(t, re, REG_EXTENDED | (sub ? 0 : REG_NOSUB)));
*rep = t;
}
}
int
-VRT_re_test(struct vsb *sb, const char *re)
+VRT_re_test(struct vsb *sb, const char *re, int sub)
{
int i;
regex_t t;
char buf[BUFSIZ];
memset(&t, 0, sizeof t);
- i = regcomp(&t, re, REG_EXTENDED | REG_NOSUB);
+ i = regcomp(&t, re, REG_EXTENDED | (sub ? 0 : REG_NOSUB));
if (i == 0) {
regfree(&t);
return (0);
regfree(&t);
return (1);
}
+
+char *
+VRT_regsub(struct sess *sp, const char *str, void *re, const char *sub)
+{
+ static char foo[4] = "FOO";
+ (void)sp;
+ (void)str;
+ (void)re;
+ (void)sub;
+ return (foo);
+}
void VRT_acl_fini(struct vrt_acl *);
/* Regexp related */
-void VRT_re_init(void **, const char *);
+void VRT_re_init(void **, const char *, int sub);
void VRT_re_fini(void *);
int VRT_re_match(const char *, void *re);
-int VRT_re_test(struct vsb *, const char *);
+int VRT_re_test(struct vsb *, const char *, int sub);
+char *VRT_regsub(struct sess *sp, const char *, void *, const char *);
void VRT_count(struct sess *, unsigned);
int VRT_rewrite(const char *, const char *);
double vcc_DoubleVal(struct tokenlist *tl);
/* vcc_string.c */
+char *vcc_regexp(struct tokenlist *tl, int sub);
int vcc_StringVal(struct tokenlist *tl);
void vcc_ExpectedStringval(struct tokenlist *tl);
vsb_cat(sb, "void VRT_acl_fini(struct vrt_acl *);\n");
vsb_cat(sb, "\n");
vsb_cat(sb, "/* Regexp related */\n");
- vsb_cat(sb, "void VRT_re_init(void **, const char *);\n");
+ vsb_cat(sb, "void VRT_re_init(void **, const char *, int sub);\n");
vsb_cat(sb, "void VRT_re_fini(void *);\n");
vsb_cat(sb, "int VRT_re_match(const char *, void *re);\n");
- vsb_cat(sb, "int VRT_re_test(struct vsb *, const char *);\n");
+ vsb_cat(sb, "int VRT_re_test(struct vsb *, const char *, int sub);\n");
+ vsb_cat(sb, "char *VRT_regsub(struct sess *sp, const char *, void *, const char *);\n");
vsb_cat(sb, "\n");
vsb_cat(sb, "void VRT_count(struct sess *, unsigned);\n");
vsb_cat(sb, "int VRT_rewrite(const char *, const char *);\n");
Fb(tl, 0, "(%g * %g)", v, sc);
}
-/*--------------------------------------------------------------------*/
-
-static void
-vcc_re(struct tokenlist *tl, const char *str, const struct token *re)
-{
- char buf[32];
-
- assert(re->tok == CSTR);
- if (VRT_re_test(tl->sb, re->dec)) {
- vcc_ErrWhere(tl, re);
- return;
- }
- sprintf(buf, "VGC_re_%u", tl->recnt++);
-
- Fb(tl, 1, "VRT_re_match(%s, %s)\n", str, buf);
- Fh(tl, 0, "void *%s;\n", buf);
- Fi(tl, 0, "\tVRT_re_init(&%s, ",buf);
- EncToken(tl->fi, re);
- Fi(tl, 0, ");\n");
- Ff(tl, 0, "\tVRT_re_fini(%s);\n", buf);
-}
-
-
/*--------------------------------------------------------------------*/
static void
Cond_String(const struct var *vp, struct tokenlist *tl)
{
+ char *p;
switch (tl->t->tok) {
case '~':
vcc_NextToken(tl);
- ExpectErr(tl, CSTR);
- vcc_re(tl, vp->rname, tl->t);
+ p = vcc_regexp(tl, 0);
vcc_NextToken(tl);
+ Fb(tl, 1, "VRT_re_match(%s, %s)\n", vp->rname, p);
break;
case T_EQ:
case T_NEQ:
#include "vcc_compile.h"
#include "libvarnish.h"
+#include "vrt.h"
+
+/*--------------------------------------------------------------------*/
+
+char *
+vcc_regexp(struct tokenlist *tl, int sub)
+{
+ char buf[32], *p;
+
+ Expect(tl, CSTR);
+ if (VRT_re_test(tl->sb, tl->t->dec, sub)) {
+ vcc_ErrWhere(tl, tl->t);
+ return (NULL);
+ }
+ sprintf(buf, "VGC_re_%u", tl->recnt++);
+ p = TlAlloc(tl, strlen(buf) + 1);
+ strcpy(p, buf);
+
+ Fh(tl, 0, "void *%s;\n", buf);
+ Fi(tl, 0, "\tVRT_re_init(&%s, ",buf);
+ EncToken(tl->fi, tl->t);
+ Fi(tl, 0, ", %d);\n", sub);
+ Ff(tl, 0, "\tVRT_re_fini(%s);\n", buf);
+ return (p);
+}
+
+/*--------------------------------------------------------------------*/
+
+static int
+vcc_regsub(struct tokenlist *tl)
+{
+ char *p;
+
+ vcc_NextToken(tl);
+
+ Fb(tl, 0, "VRT_regsub(sp, ");
+
+ Expect(tl, '(');
+ vcc_NextToken(tl);
+
+ if (!vcc_StringVal(tl)) {
+ vcc_ExpectedStringval(tl);
+ return (0);
+ }
+
+ Expect(tl, ',');
+ vcc_NextToken(tl);
+
+ Expect(tl, CSTR);
+ p = vcc_regexp(tl, 1);
+ vcc_NextToken(tl);
+ Fb(tl, 0, ", %s, ", p);
+
+ Expect(tl, ',');
+ vcc_NextToken(tl);
+
+ Expect(tl, CSTR);
+ if (!vcc_StringVal(tl)) {
+ vcc_ExpectedStringval(tl);
+ return (0);
+ }
+
+ Expect(tl, ')');
+ vcc_NextToken(tl);
+ Fb(tl, 0, ")");
+
+ return (1);
+}
+
/*--------------------------------------------------------------------
* Parse a string value and emit something that results in a usable
* "const char *".
vcc_NextToken(tl);
return (1);
}
+ if (tl->t->tok == ID && vcc_IdIs(tl->t, "regsub"))
+ return (vcc_regsub(tl));
if (tl->t->tok == VAR) {
vp = vcc_FindVar(tl, tl->t, vcc_vars);
if (tl->err)