Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libvmod-re2
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nils Goroll
libvmod-re2
Commits
669080ed
Commit
669080ed
authored
Mar 17, 2016
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add .backref_named()
parent
025f5654
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
191 additions
and
38 deletions
+191
-38
README.rst
README.rst
+9
-0
backref_named.vtc
src/tests/backref_named.vtc
+66
-0
vmod_re2.c
src/vmod_re2.c
+86
-38
vmod_re2.vcc
src/vmod_re2.vcc
+3
-0
vre2.cpp
src/vre2/vre2.cpp
+23
-0
vre2.h
src/vre2/vre2.h
+4
-0
No files found.
README.rst
View file @
669080ed
...
@@ -29,6 +29,7 @@ CONTENTS
...
@@ -29,6 +29,7 @@ CONTENTS
* Object regex
* Object regex
* STRING regex.backref(INT, STRING)
* STRING regex.backref(INT, STRING)
* STRING regex.backref_named(STRING, STRING)
* BOOL regex.match(STRING)
* BOOL regex.match(STRING)
* STRING version()
* STRING version()
...
@@ -54,6 +55,14 @@ STRING regex.backref(INT, STRING)
...
@@ -54,6 +55,14 @@ STRING regex.backref(INT, STRING)
Prototype
Prototype
STRING regex.backref(INT ref, STRING fallback)
STRING regex.backref(INT ref, STRING fallback)
.. _func_regex.backref_named:
STRING regex.backref_named(STRING, STRING)
------------------------------------------
Prototype
STRING regex.backref_named(STRING name, STRING fallback)
.. _func_version:
.. _func_version:
STRING version()
STRING version()
...
...
src/tests/backref_named.vtc
0 → 100644
View file @
669080ed
# looks like -*- vcl -*-
varnishtest "backref_named()"
varnish v1 -vcl {
import re2 from "${vmod_topbuild}/src/.libs/libvmod_re2.so";
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new barbaz = re2.regex("(?P<bar>bar)(?P<baz>baz)");
new never = re2.regex("(?P<bar>bar)(?P<baz>baz)",
never_capture=true);
}
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
if (barbaz.match("barbaz")) {
set resp.http.num0 = barbaz.backref(0, "error0");
set resp.http.num1 = barbaz.backref(1, "error1");
set resp.http.num2 = barbaz.backref(2, "error2");
set resp.http.bar
= barbaz.backref_named("bar", "error_bar");
set resp.http.baz
= barbaz.backref_named("baz", "error_baz");
set resp.http.quux
= barbaz.backref_named("quux", "error_quux");
}
if (never.match("barbaz")) {
set resp.http.never = "match";
set resp.http.neverbar
= never.backref_named("bar", "error_bar");
set resp.http.neverbaz
= never.backref_named("baz", "error_baz");
set resp.http.neverquux
= never.backref_named("quux", "error_quux");
}
}
} -start
client c1 {
txreq
rxresp
expect resp.http.num0 == "barbaz"
expect resp.http.num1 == "bar"
expect resp.http.num2 == "baz"
expect resp.http.bar == "bar"
expect resp.http.baz == "baz"
expect resp.http.quux == "error_quux"
expect resp.http.never == "match"
expect resp.http.neverbar == "error_bar"
expect resp.http.neverbaz == "error_baz"
expect resp.http.neverquux == "error_quux"
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "^vmod re2 error: barbaz\.backref_named\(\"quux\", \"error_quux\"\): no such named group$"
expect * = VCL_Error "^vmod re2 error: never\.backref_named\(\"bar\", \"error_bar\"\): never_capture is true for object never$"
expect * = VCL_Error "^vmod re2 error: never\.backref_named\(\"baz\", \"error_baz\"\): never_capture is true for object never$"
expect * = VCL_Error "^vmod re2 error: never\.backref_named\(\"quux\", \"error_quux\"\): never_capture is true for object never$"
expect * = End
} -run
src/vmod_re2.c
View file @
669080ed
...
@@ -89,6 +89,51 @@ init_matchsz(void)
...
@@ -89,6 +89,51 @@ init_matchsz(void)
match_sz
=
vre2_matchsz
();
match_sz
=
vre2_matchsz
();
}
}
#define ERR_PREFIX "%s backref %ld, fallback \"%s\": "
static
VCL_STRING
backref
(
VRT_CTX
,
struct
vmod_re2_regex
*
re
,
VCL_INT
refnum
,
VCL_STRING
fallback
)
{
void
*
group
;
const
char
*
err
,
*
capture
;
char
*
backref
;
int
len
;
group
=
pthread_getspecific
(
re
->
matchk
);
if
(
group
==
NULL
)
{
VERR
(
ctx
,
ERR_PREFIX
"backref called without prior match"
,
re
->
vcl_name
,
refnum
,
fallback
);
return
fallback
;
}
if
(
group
==
match_failed
)
return
fallback
;
assert
((
char
*
)
group
>=
ctx
->
ws
->
s
&&
(
char
*
)(
group
+
((
re
->
ngroups
+
1
)
*
match_sz
))
<=
ctx
->
ws
->
e
);
if
((
err
=
vre2_capture
(
group
,
(
int
)
refnum
,
&
capture
,
&
len
))
!=
NULL
)
{
VERR
(
ctx
,
ERR_PREFIX
"error retrieving capture: %s"
,
re
->
vcl_name
,
refnum
,
fallback
,
err
);
return
fallback
;
}
assert
(
len
>=
0
);
if
(
capture
==
NULL
)
return
fallback
;
if
(
len
==
0
)
return
""
;
if
((
backref
=
WS_Copy
(
ctx
->
ws
,
capture
,
len
+
1
))
==
NULL
)
{
VERR
(
ctx
,
ERR_PREFIX
"insufficient workspace for backref"
,
re
->
vcl_name
,
refnum
,
fallback
);
return
fallback
;
}
backref
[
len
]
=
'\0'
;
return
backref
;
}
#undef ERR_PREFIX
VCL_VOID
VCL_VOID
vmod_regex__init
(
const
struct
vrt_ctx
*
ctx
,
struct
vmod_re2_regex
**
rep
,
vmod_regex__init
(
const
struct
vrt_ctx
*
ctx
,
struct
vmod_re2_regex
**
rep
,
const
char
*
vcl_name
,
VCL_STRING
pattern
,
VCL_BOOL
utf8
,
const
char
*
vcl_name
,
VCL_STRING
pattern
,
VCL_BOOL
utf8
,
...
@@ -147,6 +192,8 @@ vmod_regex__fini(struct vmod_re2_regex **rep)
...
@@ -147,6 +192,8 @@ vmod_regex__fini(struct vmod_re2_regex **rep)
FREE_OBJ
(
re
);
FREE_OBJ
(
re
);
}
}
#define ERR_PREFIX "%s.match(\"%s\"): "
VCL_BOOL
VCL_BOOL
vmod_regex_match
(
const
struct
vrt_ctx
*
ctx
,
struct
vmod_re2_regex
*
re
,
vmod_regex_match
(
const
struct
vrt_ctx
*
ctx
,
struct
vmod_re2_regex
*
re
,
VCL_STRING
subject
)
VCL_STRING
subject
)
...
@@ -161,8 +208,6 @@ vmod_regex_match(const struct vrt_ctx *ctx, struct vmod_re2_regex *re,
...
@@ -161,8 +208,6 @@ vmod_regex_match(const struct vrt_ctx *ctx, struct vmod_re2_regex *re,
if
(
subject
==
NULL
)
if
(
subject
==
NULL
)
subject
=
""
;
subject
=
""
;
#define ERR_PREFIX "%s.match(\"%s\"): "
AZ
(
pthread_setspecific
(
re
->
matchk
,
match_failed
));
AZ
(
pthread_setspecific
(
re
->
matchk
,
match_failed
));
len
=
strlen
(
subject
);
len
=
strlen
(
subject
);
...
@@ -197,24 +242,21 @@ vmod_regex_match(const struct vrt_ctx *ctx, struct vmod_re2_regex *re,
...
@@ -197,24 +242,21 @@ vmod_regex_match(const struct vrt_ctx *ctx, struct vmod_re2_regex *re,
}
}
return
match
;
return
match
;
#undef ERR_PREFIX
}
}
#undef ERR_PREFIX
#define ERR_PREFIX "%s.backref(%ld, \"%s\"): "
VCL_STRING
VCL_STRING
vmod_regex_backref
(
VRT_CTX
,
struct
vmod_re2_regex
*
re
,
VCL_INT
refnum
,
vmod_regex_backref
(
VRT_CTX
,
struct
vmod_re2_regex
*
re
,
VCL_INT
refnum
,
VCL_STRING
fallback
)
VCL_STRING
fallback
)
{
{
void
*
group
;
const
char
*
err
,
*
capture
;
char
*
backref
;
int
len
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
re
,
VMOD_RE2_REGEX_MAGIC
);
CHECK_OBJ_NOTNULL
(
re
,
VMOD_RE2_REGEX_MAGIC
);
AN
(
fallback
);
assert
(
refnum
>=
0
);
assert
(
refnum
>=
0
);
if
(
fallback
==
NULL
)
#define ERR_PREFIX "%s.backref(%ld, \"%s\"): "
fallback
=
""
;
if
(
re
->
never_capture
)
{
if
(
re
->
never_capture
)
{
VERR
(
ctx
,
ERR_PREFIX
"never_capture is true for object %s"
,
VERR
(
ctx
,
ERR_PREFIX
"never_capture is true for object %s"
,
...
@@ -226,41 +268,47 @@ vmod_regex_backref(VRT_CTX, struct vmod_re2_regex *re, VCL_INT refnum,
...
@@ -226,41 +268,47 @@ vmod_regex_backref(VRT_CTX, struct vmod_re2_regex *re, VCL_INT refnum,
re
->
vcl_name
,
refnum
,
fallback
,
re
->
ngroups
);
re
->
vcl_name
,
refnum
,
fallback
,
re
->
ngroups
);
return
fallback
;
return
fallback
;
}
}
return
backref
(
ctx
,
re
,
refnum
,
fallback
);
}
group
=
pthread_getspecific
(
re
->
matchk
);
#undef ERR_PREFIX
if
(
group
==
NULL
)
{
VERR
(
ctx
,
ERR_PREFIX
"backref called without prior match"
,
re
->
vcl_name
,
refnum
,
fallback
);
return
fallback
;
}
if
(
group
==
match_failed
)
return
fallback
;
assert
((
char
*
)
group
>=
ctx
->
ws
->
s
#define ERR_PREFIX "%s.backref_named(\"%s\", \"%s\"): "
&&
(
char
*
)(
group
+
((
re
->
ngroups
+
1
)
*
match_sz
))
<=
ctx
->
ws
->
e
);
if
((
err
=
vre2_capture
(
group
,
(
int
)
refnum
,
&
capture
,
&
len
))
VCL_STRING
!=
NULL
)
{
vmod_regex_backref_named
(
VRT_CTX
,
struct
vmod_re2_regex
*
re
,
VCL_STRING
name
,
VERR
(
ctx
,
ERR_PREFIX
"error retrieving capture: %s"
,
VCL_STRING
fallback
)
re
->
vcl_name
,
refnum
,
fallback
,
err
);
{
int
refnum
;
const
char
*
err
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
re
,
VMOD_RE2_REGEX_MAGIC
);
if
(
name
==
NULL
)
name
=
""
;
if
(
fallback
==
NULL
)
fallback
=
""
;
if
(
re
->
never_capture
)
{
VERR
(
ctx
,
ERR_PREFIX
"never_capture is true for object %s"
,
re
->
vcl_name
,
name
,
fallback
,
re
->
vcl_name
);
return
fallback
;
return
fallback
;
}
}
if
((
err
=
vre2_get_group
(
re
->
vre2
,
name
,
&
refnum
))
!=
NULL
)
{
assert
(
len
>=
0
);
VERR
(
ctx
,
ERR_PREFIX
"%s"
,
re
->
vcl_name
,
name
,
fallback
,
err
);
if
(
capture
==
NULL
)
return
fallback
;
return
fallback
;
if
(
len
==
0
)
}
return
""
;
if
(
refnum
==
-
1
)
{
if
((
backref
=
WS_Copy
(
ctx
->
ws
,
capture
,
len
+
1
))
==
NULL
)
{
VERR
(
ctx
,
ERR_PREFIX
"no such named group"
,
re
->
vcl_name
,
name
,
VERR
(
ctx
,
ERR_PREFIX
"insufficient workspace for backref"
,
fallback
);
re
->
vcl_name
,
refnum
,
fallback
);
return
fallback
;
return
fallback
;
}
}
backref
[
len
]
=
'\0'
;
assert
(
refnum
>
0
&&
refnum
<=
re
->
ngroups
);
return
backref
;
return
backref
(
ctx
,
re
,
refnum
,
fallback
);
#undef ERR_PREFIX
}
}
#undef ERR_PREFIX
VCL_STRING
VCL_STRING
vmod_version
(
const
struct
vrt_ctx
*
ctx
__attribute__
((
unused
)))
vmod_version
(
const
struct
vrt_ctx
*
ctx
__attribute__
((
unused
)))
{
{
...
...
src/vmod_re2.vcc
View file @
669080ed
...
@@ -19,4 +19,7 @@ $Method BOOL .match(STRING)
...
@@ -19,4 +19,7 @@ $Method BOOL .match(STRING)
$Method STRING .backref(INT ref, STRING fallback = "**BACKREF FAILED**")
$Method STRING .backref(INT ref, STRING fallback = "**BACKREF FAILED**")
$Method STRING .backref_named(STRING name,
STRING fallback = "**BACKREF FAILED**")
$Function STRING version()
$Function STRING version()
src/vre2/vre2.cpp
View file @
669080ed
...
@@ -46,6 +46,7 @@ vre2::vre2(const char *pattern, RE2::Options * const opt) {
...
@@ -46,6 +46,7 @@ vre2::vre2(const char *pattern, RE2::Options * const opt) {
re_
=
new
RE2
(
pattern
,
*
opt
);
re_
=
new
RE2
(
pattern
,
*
opt
);
if
(
!
re_
->
ok
())
if
(
!
re_
->
ok
())
throw
runtime_error
(
re_
->
error
());
throw
runtime_error
(
re_
->
error
());
named_group
=
re_
->
NamedCapturingGroups
();
}
}
vre2
::~
vre2
()
{
vre2
::~
vre2
()
{
...
@@ -53,6 +54,7 @@ vre2::~vre2() {
...
@@ -53,6 +54,7 @@ vre2::~vre2() {
delete
re_
;
delete
re_
;
re_
=
NULL
;
re_
=
NULL
;
}
}
delete
&
named_group
;
}
}
inline
bool
inline
bool
...
@@ -68,6 +70,17 @@ vre2::ngroups() const
...
@@ -68,6 +70,17 @@ vre2::ngroups() const
return
re_
->
NumberOfCapturingGroups
();
return
re_
->
NumberOfCapturingGroups
();
}
}
inline
int
vre2
::
get_group
(
const
char
*
const
name
)
const
{
try
{
return
named_group
.
at
(
name
);
}
catch
(
const
out_of_range
&
ex
)
{
return
-
1
;
}
}
const
char
*
const
char
*
vre2_init
(
vre2
**
vre2p
,
const
char
*
pattern
,
unsigned
utf8
,
vre2_init
(
vre2
**
vre2p
,
const
char
*
pattern
,
unsigned
utf8
,
unsigned
posix_syntax
,
unsigned
longest_match
,
long
max_mem
,
unsigned
posix_syntax
,
unsigned
longest_match
,
long
max_mem
,
...
@@ -141,6 +154,16 @@ vre2_ngroups(vre2 *vre2, int * const ngroups)
...
@@ -141,6 +154,16 @@ vre2_ngroups(vre2 *vre2, int * const ngroups)
CATCHALL
CATCHALL
}
}
const
char
*
vre2_get_group
(
vre2
*
vre2
,
const
char
*
const
name
,
int
*
const
refnum
)
{
try
{
*
refnum
=
vre2
->
get_group
(
name
);
return
NULL
;
}
CATCHALL
}
const
char
*
const
char
*
vre2_fini
(
vre2
**
vre2
)
vre2_fini
(
vre2
**
vre2
)
{
{
...
...
src/vre2/vre2.h
View file @
669080ed
...
@@ -39,6 +39,7 @@ using namespace re2;
...
@@ -39,6 +39,7 @@ using namespace re2;
class
vre2
{
class
vre2
{
private
:
private
:
RE2
*
re_
;
RE2
*
re_
;
map
<
string
,
int
>
named_group
;
public
:
public
:
vre2
(
const
char
*
pattern
,
RE2
::
Options
*
const
opt
);
vre2
(
const
char
*
pattern
,
RE2
::
Options
*
const
opt
);
...
@@ -46,6 +47,7 @@ public:
...
@@ -46,6 +47,7 @@ public:
bool
match
(
const
char
*
subject
,
size_t
len
,
int
ngroups
,
bool
match
(
const
char
*
subject
,
size_t
len
,
int
ngroups
,
StringPiece
*
groups
)
const
;
StringPiece
*
groups
)
const
;
const
int
ngroups
()
const
;
const
int
ngroups
()
const
;
int
get_group
(
const
char
*
const
name
)
const
;
};
};
#else
#else
typedef
struct
vre2
vre2
;
typedef
struct
vre2
vre2
;
...
@@ -70,6 +72,8 @@ extern "C" {
...
@@ -70,6 +72,8 @@ extern "C" {
void
*
const
group
);
void
*
const
group
);
const
char
*
vre2_capture
(
void
*
group
,
int
refnum
,
const
char
*
vre2_capture
(
void
*
group
,
int
refnum
,
const
char
**
const
capture
,
int
*
const
len
);
const
char
**
const
capture
,
int
*
const
len
);
const
char
*
vre2_get_group
(
vre2
*
vre2
,
const
char
*
const
name
,
int
*
const
refnum
);
#ifdef __cplusplus
#ifdef __cplusplus
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment