Commit dc54c3fb authored by Geoff Simmons's avatar Geoff Simmons

add the sub() function

parent 4c4e7cc3
......@@ -39,6 +39,7 @@ CONTENTS
* VOID set.add(STRING)
* VOID set.compile()
* BOOL set.match(STRING)
* STRING sub(STRING, STRING, STRING, STRING, BOOL, BOOL, BOOL, INT, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL)
* STRING version()
.. _obj_regex:
......@@ -133,6 +134,14 @@ STRING namedref(PRIV_TASK, STRING, STRING)
Prototype
STRING namedref(PRIV_TASK, STRING name, STRING fallback)
.. _func_sub:
STRING sub(STRING, STRING, STRING, STRING, BOOL, BOOL, BOOL, INT, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL)
-----------------------------------------------------------------------------------------------------------------
Prototype
STRING sub(STRING pattern, STRING text, STRING rewrite, STRING fallback, BOOL utf8, BOOL posix_syntax, BOOL longest_match, INT max_mem, BOOL literal, BOOL never_nl, BOOL dot_nl, BOOL never_capture, BOOL case_sensitive, BOOL perl_classes, BOOL word_boundary, BOOL one_line)
.. _func_version:
STRING version()
......
# looks like -*- vcl -*-
varnishtest "sub() method"
varnishtest "sub() method and function"
# Tests from re2 testing/re2_test.cc
# regex object
varnish v1 -vcl {
import re2 from "${vmod_topbuild}/src/.libs/libvmod_re2.so";
backend be { .host = "${bad_ip}"; }
......@@ -38,6 +35,21 @@ varnish v1 -vcl {
set resp.http.bplus = bplus.sub("bbbbbb", "bb");
set resp.http.bstar1 = bstar.sub("bbbbbb", "bb");
set resp.http.bstar2 = bstar.sub("aaaaa", "bb");
set resp.http.pangramf
= re2.sub("(qu|[b-df-hj-np-tv-z]*)([a-z]+)",
"the quick brown fox jumps over the lazy dogs.",
"\2\1ay");
set resp.http.nospamf = re2.sub("\w+", "abcd.efghi@google.com",
"\0-NOSPAM");
set resp.http.startfoof = re2.sub("^", "foo", "(START)");
set resp.http.startf = re2.sub("^", "", "(START)");
set resp.http.endf = re2.sub("$", "", "(END)");
set resp.http.abf = re2.sub("b", "ababababab", "bb");
set resp.http.bbf = re2.sub("b", "bbbbbb", "bb");
set resp.http.bplusf = re2.sub("b+", "bbbbbb", "bb");
set resp.http.bstar1f = re2.sub("b*", "bbbbbb", "bb");
set resp.http.bstar2f = re2.sub("b*", "aaaaa", "bb");
}
} -start
......@@ -55,4 +67,15 @@ client c1 {
expect resp.http.bplus == "bb"
expect resp.http.bstar1 == "bb"
expect resp.http.bstar2 == "bbaaaaa"
expect resp.http.pangramf == "ethay quick brown fox jumps over the lazy dogs."
expect resp.http.nospamf == "abcd-NOSPAM.efghi@google.com"
expect resp.http.startfoof == "(START)foo"
expect resp.http.startf == "(START)"
expect resp.http.endf == "(END)"
expect resp.http.abf == "abbabababab"
expect resp.http.bbf == "bbbbbbb"
expect resp.http.bplusf == "bb"
expect resp.http.bstar1f == "bb"
expect resp.http.bstar2f == "bbaaaaa"
} -run
......@@ -232,6 +232,35 @@ namedref(VRT_CTX, vre2 * restrict vre2, VCL_STRING name, VCL_STRING fallback,
#undef ERR_PREFIX
#define ERR_PREFIX "sub(text=\"%s\", rewrite=\"%s\", fallback=\"%s\"): "
static VCL_STRING
sub(VRT_CTX, vre2 * restrict vre2, VCL_STRING text, VCL_STRING rewrite,
VCL_STRING fallback)
{
int match = 0;
size_t bytes, len;
char *ret;
const char *err;
ret = WS_Snapshot(ctx->ws);
bytes = WS_Reserve(ctx->ws, 0);
if ((err = vre2_replace(vre2, text, rewrite, ret, bytes, &match, &len))
!= NULL) {
VERR(ctx, ERR_PREFIX "%s", text, rewrite, fallback, err);
WS_Release(ctx->ws, 0);
return fallback;
}
if (!match) {
WS_Release(ctx->ws, 0);
return fallback;
}
WS_Release(ctx->ws, len);
return ret;
}
#undef ERR_PREFIX
/* Event function */
int
......@@ -387,11 +416,6 @@ VCL_STRING
vmod_regex_sub(VRT_CTX, struct vmod_re2_regex *re, VCL_STRING text,
VCL_STRING rewrite, VCL_STRING fallback)
{
int match = 0;
size_t bytes, len;
char *ret;
const char *err;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(re, VMOD_RE2_REGEX_MAGIC);
if (text == NULL)
......@@ -401,21 +425,7 @@ vmod_regex_sub(VRT_CTX, struct vmod_re2_regex *re, VCL_STRING text,
if (fallback == NULL)
fallback = "";
ret = WS_Snapshot(ctx->ws);
bytes = WS_Reserve(ctx->ws, 0);
if ((err = vre2_replace(re->vre2, text, rewrite, ret, bytes, &match,
&len)) != NULL) {
VERR(ctx, ERR_PREFIX "%s", re->vcl_name, text, rewrite,
fallback, err);
WS_Release(ctx->ws, 0);
return fallback;
}
if (!match) {
WS_Release(ctx->ws, 0);
return fallback;
}
WS_Release(ctx->ws, len);
return ret;
return sub(ctx, re->vre2, text, rewrite, fallback);
}
#undef ERR_PREFIX
......@@ -694,6 +704,46 @@ vmod_namedref(VRT_CTX, struct vmod_priv *priv, VCL_STRING name,
#undef ERR_PREFIX
#define ERR_PREFIX "re2.sub(pattern=\"%s\", text=\"%s\", rewrite=\"%s\", fallback=\"%s\"): "
VCL_STRING
vmod_sub(VRT_CTX, VCL_STRING pattern, VCL_STRING text, VCL_STRING rewrite,
VCL_STRING fallback, VCL_BOOL utf8, VCL_BOOL posix_syntax,
VCL_BOOL longest_match, VCL_INT max_mem, VCL_BOOL literal,
VCL_BOOL never_nl, VCL_BOOL dot_nl, VCL_BOOL never_capture,
VCL_BOOL case_sensitive, VCL_BOOL perl_classes, VCL_BOOL word_boundary,
VCL_BOOL one_line)
{
vre2 *vre2 = NULL;
const char *ret, *err;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
if (pattern == NULL)
pattern = "";
if (text == NULL)
text = "";
if (rewrite == NULL)
rewrite = "";
if (fallback == NULL)
fallback = "";
if ((err = vre2_init(&vre2, pattern, utf8, posix_syntax, longest_match,
max_mem, literal, never_nl, dot_nl, never_capture,
case_sensitive, perl_classes, word_boundary,
one_line))
!= NULL) {
VERR(ctx, "Cannot compile '%s': %s", pattern, text, rewrite,
fallback, pattern, err);
vre2_fini(&vre2);
return fallback;
}
ret = sub(ctx, vre2, text, rewrite, fallback);
vre2_fini(&vre2);
return ret;
}
#undef ERR_PREFIX
VCL_STRING
vmod_version(const struct vrt_ctx *ctx __attribute__((unused)))
{
......
......@@ -52,4 +52,11 @@ $Function STRING backref(PRIV_TASK, INT ref,
$Function STRING namedref(PRIV_TASK, STRING name,
STRING fallback = "**NAMEDREF FUNCTION FAILED**")
$Function STRING sub(STRING pattern, STRING text, STRING rewrite,
STRING fallback = "**SUB FUNCTION FAILED**",
BOOL utf8=0, BOOL posix_syntax=0, BOOL longest_match=0,
INT max_mem=8388608, BOOL literal=0, BOOL never_nl=0,
BOOL dot_nl=0, BOOL never_capture=0, BOOL case_sensitive=1,
BOOL perl_classes=0, BOOL word_boundary=0, BOOL one_line=0)
$Function STRING version()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment