]> err.no Git - varnish/commitdiff
Add a new vcl function regsuball()
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Tue, 27 May 2008 07:10:22 +0000 (07:10 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Tue, 27 May 2008 07:10:22 +0000 (07:10 +0000)
It works just like regsub(), but replaces all occurrences of the regexp.

regsub("1foofoofoo2", "foo", "bar") -> "1barfoofoo2"

regsuball("1foofoofoo2", "foo", "bar") -> "1barbarbar2"

Fixes ticket 238

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2640 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/cache_vrt_re.c
varnish-cache/include/vrt.h
varnish-cache/lib/libvcl/vcc_fixed_token.c
varnish-cache/lib/libvcl/vcc_string.c
varnish-cache/man/vcl.7

index c3c84d462028de892f05e001fad7d83d63e7a1eb..538e1a4b99e2757b43e9ef448b419ea522dc76db 100644 (file)
@@ -104,12 +104,13 @@ VRT_re_test(struct vsb *sb, const char *re, int sub)
 }
 
 const char *
-VRT_regsub(const struct sess *sp, const char *str, void *re, const char *sub)
+VRT_regsub(const struct sess *sp, int all, const char *str, void *re, const char *sub)
 {
        regmatch_t pm[10];
        regex_t *t;
        int i, l;
        char *b, *p, *e;
+       const char *s;
        unsigned u, x;
 
        AN(re);
@@ -124,42 +125,48 @@ VRT_regsub(const struct sess *sp, const char *str, void *re, const char *sub)
        e = p = b = sp->http->ws->f;
        e += u;
 
-       /* Copy prefix to match */
-       if (pm[0].rm_so > 0) {
-               if (p + pm[0].rm_so < e)
-                       memcpy(p, str, pm[0].rm_so);
-               p += pm[0].rm_so;
-       }
+       do {
+               /* Copy prefix to match */
+               if (pm[0].rm_so > 0) {
+                       if (p + pm[0].rm_so < e)
+                               memcpy(p, str, pm[0].rm_so);
+                       p += pm[0].rm_so;
+               }
 
-       for ( ; *sub != '\0'; sub++ ) {
-               if (*sub == '&') {
-                       l = pm[0].rm_eo - pm[0].rm_so;
-                       if (l > 0) {
-                               if (p + l < e)
-                                       memcpy(p, str + pm[0].rm_so, l);
-                               p += l;
+               for (s = sub ; *s != '\0'; s++ ) {
+                       if (*s == '&') {
+                               l = pm[0].rm_eo - pm[0].rm_so;
+                               if (l > 0) {
+                                       if (p + l < e)
+                                               memcpy(p, str + pm[0].rm_so, l);
+                                       p += l;
+                               }
+                       } else if (*s == '$' && isdigit(s[1])) {
+                               x = sub[1] - '0';
+                               sub++;
+                               l = pm[x].rm_eo - pm[x].rm_so;
+                               if (l > 0) {
+                                       if (p + l < e)
+                                               memcpy(p, str + pm[x].rm_so, l);
+                                       p += l;
+                               }
+                       } else {
+                               if (p + 1 < e)
+                                       *p = *s;
+                               p++;
                        }
-               } else if (*sub == '$' && isdigit(sub[1])) {
-                       x = sub[1] - '0';
-                       sub++;
-                       l = pm[x].rm_eo - pm[x].rm_so;
-                       if (l > 0) {
-                               if (p + l < e)
-                                       memcpy(p, str + pm[x].rm_so, l);
-                               p += l;
-                       }
-               } else {
-                       if (p + 1 < e)
-                               *p = *sub;
-                       p++;
                }
-       }
+               str += pm[0].rm_eo;
+               if (!all)
+                       break;
+               i = regexec(t, str, 10, pm, 0);
+       } while (i != REG_NOMATCH);
 
        /* Copy suffix to match */
-       l = strlen(str + pm[0].rm_eo);
+       l = strlen(str);
        if (l > 0) {
                if (p + l < e)
-                       memcpy(p, str + pm[0].rm_eo, l);
+                       memcpy(p, str, l);
                p += l;
        }
        if (p + 1 < e)
index 7048f8dc7a7d039b9eba44be5e44a2d27a619a56..24c086e17cb4ee7a41eeab05a519d201626635dd 100644 (file)
@@ -108,7 +108,7 @@ 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 sub);
-const char *VRT_regsub(const struct sess *sp, const char *, void *, const char *);
+const char *VRT_regsub(const struct sess *sp, int all, const char *, void *, const char *);
 
 void VRT_purge(const char *, int hash);
 
index de54d69f896d8481eb595ff89de5e0249fdcad45..9232c3b0528a2fa30c4d9b83c4d7239b3d2e32c3 100644 (file)
@@ -462,7 +462,7 @@ vcl_output_lang_h(struct vsb *sb)
        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 *, int sub);\n");
-       vsb_cat(sb, "const char *VRT_regsub(const struct sess *sp, const char *, void *, const char *);\n");
+       vsb_cat(sb, "const char *VRT_regsub(const struct sess *sp, int all, const char *, void *, const char *);\n");
        vsb_cat(sb, "\n");
        vsb_cat(sb, "void VRT_purge(const char *, int hash);\n");
        vsb_cat(sb, "\n");
@@ -541,7 +541,7 @@ vcl_output_lang_h(struct vsb *sb)
        vsb_cat(sb, "double VRT_r_obj_prefetch(const struct sess *);\n");
        vsb_cat(sb, "void VRT_l_obj_prefetch(const struct sess *, double);\n");
        vsb_cat(sb, "double VRT_r_obj_lastuse(const struct sess *);\n");
-       vsb_cat(sb, "const char *VRT_r_obj_hash(struct sess *sp);\n");
+       vsb_cat(sb, "const char * VRT_r_obj_hash(const struct sess *);\n");
        vsb_cat(sb, "const char * VRT_r_resp_proto(const struct sess *);\n");
        vsb_cat(sb, "void VRT_l_resp_proto(const struct sess *, const char *, ...);\n");
        vsb_cat(sb, "int VRT_r_resp_status(const struct sess *);\n");
index 082bbd71ed944c4689f4bbb077349c616129c270..d7614977a36f2bb9a09e70a8d925bae1662f9894 100644 (file)
@@ -69,13 +69,13 @@ vcc_regexp(struct tokenlist *tl, int sub)
 /*--------------------------------------------------------------------*/
 
 static int
-vcc_regsub(struct tokenlist *tl)
+vcc_regsub(struct tokenlist *tl, int all)
 {
        char *p;
 
        vcc_NextToken(tl);
 
-       Fb(tl, 0, "VRT_regsub(sp, ");
+       Fb(tl, 0, "VRT_regsub(sp, %d, ", all);
 
        Expect(tl, '(');
        vcc_NextToken(tl);
@@ -96,7 +96,6 @@ vcc_regsub(struct tokenlist *tl)
        Expect(tl, ',');
        vcc_NextToken(tl);
        
-       Expect(tl, CSTR);
        if (!vcc_StringVal(tl)) {
                vcc_ExpectedStringval(tl);
                return (0);
@@ -129,7 +128,9 @@ vcc_StringVal(struct tokenlist *tl)
                return (1);
        }
        if (tl->t->tok == ID && vcc_IdIs(tl->t, "regsub"))
-               return (vcc_regsub(tl));
+               return (vcc_regsub(tl, 0));
+       if (tl->t->tok == ID && vcc_IdIs(tl->t, "regsuball"))
+               return (vcc_regsub(tl, 1));
        if (tl->t->tok == VAR) {
                vp = vcc_FindVar(tl, tl->t, vcc_vars);
                if (tl->err)
index 414c865ee741a5902661f0d2f70c79ced6a8616c..387b23a8d18277951d494ac8c73b79457c62c47a 100644 (file)
@@ -122,7 +122,7 @@ The following built-in functions are available:
 .It Fn regsub "str" "regex" "sub"
 Returns a copy of
 .Fa str
-with all occurrences of the regular expression
+with the first occurrence of the regular expression
 .Fa regex
 replaced with
 .Fa sub .
@@ -136,6 +136,10 @@ is replaced with the entire matched string, and
 is replaced with the contents of subgroup
 .Ar n
 in the matched string.
+.It Fn regsuball "str" "regex" "sub"
+As
+.Fn regsuball
+but this replaces all occurrences.
 .It Fn purge_hash "regex"
 Purge all objects in cache whose hash strings match
 .Fa regex .