Commit 7ea83d5c authored by Geoff Simmons's avatar Geoff Simmons

Consolidate common code for the sub() method and function.

parent cd2b0621
Pipeline #259 skipped
......@@ -703,6 +703,68 @@ refer(VRT_CTX, VCL_INT ref, VCL_STRING restrict const name,
return fallback;
}
static inline VCL_STRING
sub(VRT_CTX, VCL_STRING restrict subject, VCL_STRING const restrict replacement,
VCL_INT len, struct vmod_priv * const restrict priv_task,
pcre2_code * restrict code,
const struct match_call * const restrict match_opts,
const char * const restrict context)
{
pcre2_match_data *mdata;
struct task *match_task = NULL;
int ret;
PCRE2_SIZE bytes;
PCRE2_UCHAR *buf;
char *msg;
uintptr_t snap;
if ((match_task = get_task(ctx, priv_task, context, ".sub()"))
== NULL)
return NULL;
mdata = pcre2_match_data_create_from_pattern(code, match_task->gctx);
if (mdata == NULL) {
VERRNOMEM(ctx, "initializing match data in %s.sub()", context);
return NULL;
}
/*
* Don't need to ensure that the subject is in workspace, as we do
* with matches, because we won't be retrieving backrefs, and we
* give pcre2 the rest of the workspace to write the substitution.
*/
if (subject == NULL)
subject = "";
if (len == 0)
len = PCRE2_ZERO_TERMINATED;
buf = (PCRE2_UCHAR *) WS_Front(ctx->ws);
bytes = (PCRE2_SIZE) WS_Reserve(ctx->ws, 0);
/* XXX param for start_offset */
ret = pcre2_substitute(code, (PCRE2_SPTR)subject, len, 0,
match_opts->match_options, mdata,
match_opts->mctx, (PCRE2_SPTR)replacement,
PCRE2_ZERO_TERMINATED, buf, &bytes);
if (ret > 0) {
WS_Release(ctx->ws, bytes + 1);
return (VCL_STRING)buf;
}
WS_Release(ctx->ws, 0);
if (ret == 0)
return subject;
if (ret == PCRE2_ERROR_NOMEMORY) {
VERRNOMEM(ctx, "allocating substitution result in %s.sub()",
context);
return NULL;
}
snap = WS_Snapshot(ctx->ws);
if ((msg = WS_Printf(ctx->ws, "in %s.sub()", context)) == NULL)
msg = "";
report_pcre2_err(ctx, ret, msg, "");
WS_Reset(ctx->ws, snap);
return NULL;
}
VCL_VOID
vmod_regex__init(VRT_CTX, struct vmod_pcre2_regex **regexp,
const char *vcl_name, VCL_STRING pattern, COMPILE_OPTS)
......@@ -844,14 +906,7 @@ vmod_regex_sub(VRT_CTX, struct vmod_pcre2_regex *regex,
VCL_STRING subject, VCL_STRING replacement, MATCH_OPTS,
SUB_OPTS)
{
pcre2_match_data *mdata;
struct task *match_task = NULL;
struct match_call *match_opts;
int ret;
PCRE2_SIZE bytes;
PCRE2_UCHAR *buf;
char *msg;
uintptr_t snap;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(regex, VMOD_PCRE2_REGEX_MAGIC);
......@@ -869,54 +924,8 @@ vmod_regex_sub(VRT_CTX, struct vmod_pcre2_regex *regex,
if (match_opts == NULL)
return 0;
/* XXX mdata in PRIV_CALL? */
if ((match_task = get_task(ctx, priv_task, regex->vcl_name, ".sub()"))
== NULL)
return NULL;
mdata = pcre2_match_data_create_from_pattern(regex->code,
match_task->gctx);
if (mdata == NULL) {
VERRNOMEM(ctx, "initializing match data in %s.sub()",
regex->vcl_name);
return NULL;
}
/*
* Don't need to ensure that the subject is in workspace, as we do
* with matches, because we won't be retrieving backrefs, and we
* give pcre2 the rest of the workspace to write the substitution.
*/
if (subject == NULL)
subject = "";
if (len == 0)
len = PCRE2_ZERO_TERMINATED;
buf = (PCRE2_UCHAR *) WS_Front(ctx->ws);
bytes = (PCRE2_SIZE) WS_Reserve(ctx->ws, 0);
/* XXX param for start_offset */
ret = pcre2_substitute(regex->code, (PCRE2_SPTR)subject, len, 0,
match_opts->match_options, mdata,
match_opts->mctx, (PCRE2_SPTR)replacement,
PCRE2_ZERO_TERMINATED, buf, &bytes);
if (ret > 0) {
WS_Release(ctx->ws, bytes + 1);
return (VCL_STRING)buf;
}
WS_Release(ctx->ws, 0);
if (ret == 0)
return subject;
if (ret == PCRE2_ERROR_NOMEMORY) {
VERRNOMEM(ctx, "allocating substitution result in %s.sub()",
regex->vcl_name);
return NULL;
}
snap = WS_Snapshot(ctx->ws);
if ((msg = WS_Printf(ctx->ws, "in %s.sub()", regex->vcl_name)) == NULL)
msg = "";
report_pcre2_err(ctx, ret, msg, "");
WS_Reset(ctx->ws, snap);
return NULL;
return sub(ctx, subject, replacement, len, priv_task, regex->code,
match_opts, regex->vcl_name);
}
/* Functional interface */
......@@ -1028,15 +1037,9 @@ vmod_sub(VRT_CTX, struct vmod_priv *priv_call, struct vmod_priv *priv_task,
VCL_STRING pattern, VCL_STRING subject, VCL_STRING replacement,
COMPILE_OPTS, MATCHF_OPTS, SUB_OPTS)
{
pcre2_match_data *mdata;
struct task *match_task = NULL;
struct match_call *match_opts;
pcre2_code *code;
int ret;
PCRE2_SIZE bytes;
PCRE2_UCHAR *buf;
char *msg;
uintptr_t snap;
VCL_STRING ret;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(priv_task);
......@@ -1068,52 +1071,10 @@ vmod_sub(VRT_CTX, struct vmod_priv *priv_call, struct vmod_priv *priv_task,
"pcre2", ".match()")) == NULL)
return NULL;
/* XXX mdata in PRIV_CALL? */
if ((match_task = get_task(ctx, priv_task, "pcre2", ".sub()"))
== NULL)
return NULL;
mdata = pcre2_match_data_create_from_pattern(code, match_task->gctx);
if (mdata == NULL) {
ERRNOMEM(ctx, "initializing match data in pcre2.sub()");
return NULL;
}
/*
* Don't need to ensure that the subject is in workspace, as we do
* with matches, because we won't be retrieving backrefs, and we
* give pcre2 the rest of the workspace to write the substitution.
*/
if (subject == NULL)
subject = "";
if (len == 0)
len = PCRE2_ZERO_TERMINATED;
buf = (PCRE2_UCHAR *) WS_Front(ctx->ws);
bytes = (PCRE2_SIZE) WS_Reserve(ctx->ws, 0);
/* XXX param for start_offset */
ret = pcre2_substitute(code, (PCRE2_SPTR)subject, len, 0,
match_opts->match_options, mdata,
match_opts->mctx, (PCRE2_SPTR)replacement,
PCRE2_ZERO_TERMINATED, buf, &bytes);
ret = sub(ctx, subject, replacement, len, priv_task, code, match_opts,
"pcre2");
pcre2_code_free(code);
if (ret > 0) {
WS_Release(ctx->ws, bytes + 1);
return (VCL_STRING)buf;
}
WS_Release(ctx->ws, 0);
if (ret == 0)
return subject;
if (ret == PCRE2_ERROR_NOMEMORY) {
ERRNOMEM(ctx, "allocating substitution result in pcre2.sub()");
return NULL;
}
snap = WS_Snapshot(ctx->ws);
if ((msg = WS_Printf(ctx->ws, "in pcre2.sub()")) == NULL)
msg = "";
report_pcre2_err(ctx, ret, msg, "");
WS_Reset(ctx->ws, snap);
return NULL;
return ret;
}
/* Functions */
......
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