Commit 4aaec2ff authored by Geoff Simmons's avatar Geoff Simmons

Add the .check_call() method.

parent d6d30486
......@@ -1072,6 +1072,21 @@ SUB xset.subroutine(INT n, STRING element, ENUM select)
XXX ...
.. _xset.check_call():
BOOL xset.check_call(INT n, STRING element, ENUM select)
--------------------------------------------------------
::
BOOL xset.check_call(
INT n=0,
STRING element=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST} select=UNIQUE
)
XXX ...
.. _selector.version():
STRING version()
......
......@@ -31,11 +31,11 @@
static unsigned
select(VRT_CTX, const struct match_data * const restrict match,
const char * const restrict obj, VCL_ENUM const restrict selects,
const char * const restrict method)
const char * const restrict method, int fail)
{
if (selects == VENUM(EXACT)) {
if (match->exact == UINT_MAX)
VFAIL(ctx, "%s.%s(select=EXACT): "
VFAIL_OR_NOTICE(ctx, fail, "%s.%s(select=EXACT): "
"no element matched exactly", obj, method);
return match->exact;
}
......@@ -45,8 +45,9 @@ select(VRT_CTX, const struct match_data * const restrict match,
switch (selects[0]) {
case 'U':
assert(selects == VENUM(UNIQUE));
VFAIL(ctx, "%s.%s(select=UNIQUE): %d elements were matched",
obj, method, match->n);
VFAIL_OR_NOTICE(ctx, fail,
"%s.%s(select=UNIQUE): %d elements were matched",
obj, method, match->n);
return (UINT_MAX);
case 'L':
if (selects == VENUM(LAST))
......@@ -81,7 +82,7 @@ vmod_set_which(VRT_CTX, struct vmod_selector_set *set, VCL_ENUM selects,
return (UINT_MAX);
}
match = get_existing_match_data(ctx, set, "which");
match = get_existing_match_data(ctx, set, "which", 1);
if (element != NULL) {
CHECK_OBJ_NOTNULL(match, MATCH_DATA_MAGIC);
assert(match->n == 1);
......@@ -89,35 +90,38 @@ vmod_set_which(VRT_CTX, struct vmod_selector_set *set, VCL_ENUM selects,
}
if (match == NULL || match->n == 0)
return (0);
return (select(ctx, match, set->vcl_name, selects, "which") + 1);
return (select(ctx, match, set->vcl_name, selects, "which", 1) + 1);
}
static unsigned
get_idx(VRT_CTX, VCL_INT n, const struct vmod_selector_set * const restrict set,
const char * const restrict method, VCL_STRING const restrict element,
VCL_ENUM const restrict selects)
VCL_ENUM const restrict selects, int fail)
{
struct match_data *match;
if (n > 0) {
if (n > set->nmembers) {
VFAIL(ctx, "%s.%s(%ld): set has %d elements",
set->vcl_name, method, n, set->nmembers);
VFAIL_OR_NOTICE(ctx, fail,
"%s.%s(%ld): set has %d elements",
set->vcl_name, method, n,
set->nmembers);
return (UINT_MAX);
}
return (n - 1);
}
if (element != NULL)
if (!vmod_set_match(ctx, TRUST_ME(set), element)) {
VFAIL(ctx, "%s.%s(element=\"%s\"): no such element",
set->vcl_name, method, element);
VFAIL_OR_NOTICE(ctx, fail,
"%s.%s(element=\"%s\"): no such element",
set->vcl_name, method, element);
return (UINT_MAX);
}
match = get_existing_match_data(ctx, set, method);
match = get_existing_match_data(ctx, set, method, fail);
if (match == NULL || match->n == 0)
return (UINT_MAX);
return (select(ctx, match, set->vcl_name, selects, method));
return (select(ctx, match, set->vcl_name, selects, method, fail));
}
VCL_STRING
......@@ -129,7 +133,7 @@ vmod_set_element(VRT_CTX, struct vmod_selector_set *set, VCL_INT n,
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
idx = get_idx(ctx, n, set, "element", NULL, selects);
idx = get_idx(ctx, n, set, "element", NULL, selects, 1);
if (idx == UINT_MAX)
return (NULL);
return (set->members[idx]);
......@@ -139,11 +143,12 @@ static inline int
check_added(VRT_CTX, const struct vmod_selector_set * const restrict set,
unsigned idx, enum bitmap_e bitmap,
const char * const restrict method,
const char * const restrict type)
const char * const restrict type, int fail)
{
if (!is_added(set, idx, bitmap)) {
VFAIL(ctx, "%s.%s(): %s not added for element %u",
set->vcl_name, method, type, idx + 1);
VFAIL_OR_NOTICE(ctx, fail,
"%s.%s(): %s not added for element %u",
set->vcl_name, method, type, idx + 1);
return (0);
}
return (1);
......@@ -159,10 +164,10 @@ vmod_set_backend(VRT_CTX, struct vmod_selector_set *set, VCL_INT n,
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
idx = get_idx(ctx, n, set, "backend", element, selects);
idx = get_idx(ctx, n, set, "backend", element, selects, 1);
if (idx == UINT_MAX)
return (NULL);
if (!check_added(ctx, set, idx, BACKEND, "backend", "backend"))
if (!check_added(ctx, set, idx, BACKEND, "backend", "backend", 1))
return (NULL);
b = set->table[idx]->backend;
......@@ -180,10 +185,10 @@ vmod_set_string(VRT_CTX, struct vmod_selector_set * set, VCL_INT n,
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
idx = get_idx(ctx, n, set, "string", element, selects);
idx = get_idx(ctx, n, set, "string", element, selects, 1);
if (idx == UINT_MAX)
return (NULL);
if (!check_added(ctx, set, idx, STRING, "string", "string"))
if (!check_added(ctx, set, idx, STRING, "string", "string", 1))
return (NULL);
s = set->table[idx]->string;
......@@ -200,10 +205,10 @@ vmod_set_integer(VRT_CTX, struct vmod_selector_set * set, VCL_INT n,
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
idx = get_idx(ctx, n, set, "integer", element, selects);
idx = get_idx(ctx, n, set, "integer", element, selects, 1);
if (idx == UINT_MAX)
return (0);
if (!check_added(ctx, set, idx, INTEGER, "integer", "integer"))
if (!check_added(ctx, set, idx, INTEGER, "integer", "integer", 1))
return (0);
return (set->table[idx]->integer);
......@@ -220,10 +225,10 @@ get_re(VRT_CTX, const struct vmod_selector_set * const restrict set,
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
idx = get_idx(ctx, n, set, method, element, selects);
idx = get_idx(ctx, n, set, method, element, selects, 1);
if (idx == UINT_MAX)
return (NULL);
if (!check_added(ctx, set, idx, REGEX, method, "regex"))
if (!check_added(ctx, set, idx, REGEX, method, "regex", 1))
return (NULL);
re = set->table[idx]->re;
......@@ -265,10 +270,10 @@ vmod_set_bool(VRT_CTX, struct VPFX(selector_set) *set, VCL_INT n,
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
idx = get_idx(ctx, n, set, "bool", element, selects);
idx = get_idx(ctx, n, set, "bool", element, selects, 1);
if (idx == UINT_MAX)
return (0);
if (!check_added(ctx, set, idx, BOOLEAN, "bool", "boolean"))
if (!check_added(ctx, set, idx, BOOLEAN, "bool", "boolean", 1))
return (0);
return (set->table[idx]->bool);
......@@ -283,11 +288,34 @@ vmod_set_subroutine(VRT_CTX, struct VPFX(selector_set) *set, VCL_INT n,
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
idx = get_idx(ctx, n, set, "subroutine", element, selects);
idx = get_idx(ctx, n, set, "subroutine", element, selects, 1);
if (idx == UINT_MAX)
return (NULL);
if (!check_added(ctx, set, idx, SUB, "subroutine", "subroutine"))
if (!check_added(ctx, set, idx, SUB, "subroutine", "subroutine", 1))
return (NULL);
return (set->table[idx]->sub);
}
VCL_BOOL
vmod_set_check_call(VRT_CTX, struct VPFX(selector_set) *set, VCL_INT n,
VCL_STRING element, VCL_ENUM selects)
{
unsigned idx;
VCL_STRING err;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
idx = get_idx(ctx, n, set, "check_call", element, selects, 0);
if (idx == UINT_MAX)
return (0);
if (!check_added(ctx, set, idx, SUB, "check_call", "subroutine", 0))
return (0);
if ((err = VRT_check_call(ctx, set->table[idx]->sub)) != NULL) {
VNOTICE(ctx, "%s", err);
return (0);
}
return (1);
}
......@@ -183,7 +183,7 @@ vmod_set_hasprefix(VRT_CTX, struct vmod_selector_set *set, VCL_STRING subject)
struct match_data *
get_existing_match_data(VRT_CTX,
const struct vmod_selector_set * const restrict set,
const char * const restrict method)
const char * const restrict method, int fail)
{
struct vmod_priv *task;
struct match_data *match;
......@@ -191,8 +191,8 @@ get_existing_match_data(VRT_CTX,
task = VRT_priv_task(ctx, set);
AN(task);
if (task->priv == NULL) {
VFAIL(ctx, "%s.%s() called without prior match", set->vcl_name,
method);
VFAIL_OR_NOTICE(ctx, fail, "%s.%s() called without prior match",
set->vcl_name, method);
return (NULL);
}
WS_Assert_Allocated(ctx->ws, task->priv, sizeof(*match));
......@@ -208,7 +208,7 @@ vmod_set_nmatches(VRT_CTX, struct vmod_selector_set *set)
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(set, VMOD_SELECTOR_SET_MAGIC);
match = get_existing_match_data(ctx, set, "nmatches");
match = get_existing_match_data(ctx, set, "nmatches", 1);
if (match == NULL)
return (0);
return (match->n);
......@@ -229,7 +229,7 @@ vmod_set_matched(VRT_CTX, struct VPFX(selector_set) *set, VCL_INT idx,
return (0);
}
match = get_existing_match_data(ctx, set, "matched");
match = get_existing_match_data(ctx, set, "matched", 1);
if (match == NULL || match->n == 0)
return (0);
......
This diff is collapsed.
......@@ -45,6 +45,13 @@
#define VNOTICE(ctx, fmt, ...) \
VSLb((ctx)->vsl, SLT_Notice, "vmod_selector: " fmt, __VA_ARGS__)
#define VFAIL_OR_NOTICE(ctx, fail, fmt, ...) do { \
if (fail) \
VFAIL((ctx), fmt, __VA_ARGS__); \
else \
VNOTICE((ctx), fmt, __VA_ARGS__); \
} while(0)
struct entry {
unsigned magic;
#define VMOD_SELECTOR_ENTRY_MAGIC 0x733dbe63
......@@ -101,4 +108,4 @@ is_added(const struct vmod_selector_set *set, unsigned idx,
struct match_data *
get_existing_match_data(const struct vrt_ctx *ctx,
const struct vmod_selector_set * const restrict set,
const char * const restrict method);
const char * const restrict method, int fail);
......@@ -937,6 +937,12 @@ $Method SUB .subroutine(INT n=0, STRING element=0,
XXX ...
$Method BOOL .check_call(INT n=0, STRING element=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST}
select=UNIQUE)
XXX ...
$Function STRING version()
Return the version string for this VMOD.
......
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