Commit a2519bc9 authored by Martin Blix Grydeland's avatar Martin Blix Grydeland

Add a VSL_Glob2Tags function to the API.

VSL_Glob2Tags allows matching VSL tags against a glob expression.
parent 787a4e9d
......@@ -96,6 +96,15 @@ typedef int VSLQ_dispatch_f(struct VSL_data *vsl,
* !=0: Makes VSLQ_Dispatch return with this return value immediatly
*/
typedef void VSL_glob2tags_f(int tag, void *priv);
/*
* The callback function type for use with VSL_Glob2Tags.
*
* Arguments:
* tag: Tag number (= enum VSL_tag_e)
* priv: The priv argument from VSL_Glob2Tag
*/
extern const char *VSL_tags[SLT__MAX];
/*
* Tag to string array. Contains NULL for invalid tags.
......@@ -117,6 +126,25 @@ int VSL_Name2Tag(const char *name, int l);
* -2: Multiple tags match substring
*/
int VSL_Glob2Tags(const char *glob, int l, VSL_glob2tags_f *func, void *priv);
/*
* Convert a string to multiple tag matches. The string can have
* either a prefix or postfix wildcard (*) character. For each
* matching tag func is called. Matching is done case insensitive.
*
* Arguments:
* glob: The string to match
* l: The length of glob. -1 to use strlen.
* func: The function to call (can be NULL)
* priv: An argument that will be passed to func.
*
* Return values:
* >0: Number of times func was called for matching tags.
* -1: No tag matches
* -2: Multiple tags match non-glob input
* -3: Syntax error
*/
int VSLQ_Name2Grouping(const char *name, int l);
/*
* Convert string to grouping (= enum VSL_grouping_e)
......
......@@ -115,5 +115,6 @@ LIBVARNISHAPI_1.3 {
VSLQ_Dispatch;
VSLQ_Flush;
VSLQ_Name2Grouping;
VSL_Glob2Tags;
# Variables:
} LIBVARNISHAPI_1.0;
......@@ -83,6 +83,75 @@ VSL_Name2Tag(const char *name, int l)
return (n);
}
int
VSL_Glob2Tags(const char *glob, int l, VSL_glob2tags_f *func, void *priv)
{
int i, r, l2;
int pre = 0;
int post = 0;
char buf[64];
AN(glob);
if (l < 0)
l = strlen(glob);
if (l == 0 || l > sizeof buf - 1)
return (-1);
if (strchr(glob, '*') != NULL) {
if (glob[0] == '*') {
/* Prefix wildcard */
pre = 1;
glob++;
l--;
}
if (l > 0 && glob[l - 1] == '*') {
/* Postfix wildcard */
post = 1;
l--;
}
}
if (pre && post)
/* Support only post or prefix wildcards */
return (-3);
memcpy(buf, glob, l);
buf[l] = '\0';
if (strchr(buf, '*') != NULL)
/* No multiple wildcards */
return (-3);
if (pre == 0 && post == 0) {
/* No wildcards, use VSL_Name2Tag */
i = VSL_Name2Tag(buf, l);
if (i < 0)
return (i);
if (func != NULL)
(func)(i, priv);
return (1);
}
r = 0;
for (i = 0; i < SLT__MAX; i++) {
if (VSL_tags[i] == NULL)
continue;
l2 = strlen(VSL_tags[i]);
if (l2 < l)
continue;
if (pre) {
/* Prefix wildcard match */
if (strcasecmp(buf, VSL_tags[i] + l2 - l))
continue;
} else {
/* Postfix wildcard match */
if (strncasecmp(buf, VSL_tags[i], l))
continue;
}
if (func != NULL)
(func)(i, priv);
r++;
}
if (r == 0)
return (-1);
return (r);
}
static const char * const vsl_grouping[] = {
[VSL_g_raw] = "raw",
[VSL_g_vxid] = "vxid",
......
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