mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-03-01 00:50:53 +00:00
MEDIUM: pattern: Change the prototype of the function pattern_register().
Each pattern parser take only one string. This change is reported to the function prototype of the function "pattern_register()". Now, it is called with just one string and no need to browse the array of args.
This commit is contained in:
parent
580c32cb3a
commit
972028fa67
@ -40,7 +40,7 @@
|
|||||||
* The function returns 1 if the processing is ok, return 0
|
* The function returns 1 if the processing is ok, return 0
|
||||||
* if the parser fails, with <err> message filled.
|
* if the parser fails, with <err> message filled.
|
||||||
*/
|
*/
|
||||||
int pattern_register(struct pattern_expr *expr, const char **args, struct sample_storage *smp, struct pattern **pattern, int patflags, char **err);
|
int pattern_register(struct pattern_expr *expr, const char *arg, struct sample_storage *smp, struct pattern **pattern, int patflags, char **err);
|
||||||
|
|
||||||
/* return the PAT_MATCH_* index for match name "name", or < 0 if not found */
|
/* return the PAT_MATCH_* index for match name "name", or < 0 if not found */
|
||||||
static inline int pat_find_match_name(const char *name)
|
static inline int pat_find_match_name(const char *name)
|
||||||
|
@ -152,7 +152,6 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
|
|||||||
signed long long value, minor;
|
signed long long value, minor;
|
||||||
/* The following buffer contain two numbers, a ':' separator and the final \0. */
|
/* The following buffer contain two numbers, a ':' separator and the final \0. */
|
||||||
char buffer[NB_LLMAX_STR + 1 + NB_LLMAX_STR + 1];
|
char buffer[NB_LLMAX_STR + 1 + NB_LLMAX_STR + 1];
|
||||||
const char *text[2];
|
|
||||||
|
|
||||||
/* First, we look for an ACL keyword. And if we don't find one, then
|
/* First, we look for an ACL keyword. And if we don't find one, then
|
||||||
* we look for a sample fetch expression starting with a sample fetch
|
* we look for a sample fetch expression starting with a sample fetch
|
||||||
@ -570,9 +569,7 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
text[0] = arg;
|
if (!pattern_register(&expr->pat, arg, NULL, &pattern, patflags, err))
|
||||||
text[1] = "";
|
|
||||||
if (!pattern_register(&expr->pat, text, NULL, &pattern, patflags, err))
|
|
||||||
goto out_free_pattern;
|
goto out_free_pattern;
|
||||||
args++;
|
args++;
|
||||||
}
|
}
|
||||||
|
@ -1919,7 +1919,6 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
|
|||||||
}
|
}
|
||||||
else if (strcmp(args[0], "add") == 0) {
|
else if (strcmp(args[0], "add") == 0) {
|
||||||
if (strcmp(args[1], "map") == 0) {
|
if (strcmp(args[1], "map") == 0) {
|
||||||
const char *params[2];
|
|
||||||
struct pattern *pat;
|
struct pattern *pat;
|
||||||
struct map_entry *ent;
|
struct map_entry *ent;
|
||||||
struct sample_storage *smp;
|
struct sample_storage *smp;
|
||||||
@ -1931,9 +1930,6 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
params[0] = args[3];
|
|
||||||
params[1] = "";
|
|
||||||
|
|
||||||
/* Lookup the reference in the maps. */
|
/* Lookup the reference in the maps. */
|
||||||
appctx->ctx.map.ref = map_get_reference(args[2]);
|
appctx->ctx.map.ref = map_get_reference(args[2]);
|
||||||
if (!appctx->ctx.map.ref) {
|
if (!appctx->ctx.map.ref) {
|
||||||
@ -2012,7 +2008,7 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
|
|||||||
else
|
else
|
||||||
pat = NULL;
|
pat = NULL;
|
||||||
|
|
||||||
if (!pattern_register(appctx->ctx.map.desc->pat, params, smp, &pat, 0, NULL)) {
|
if (!pattern_register(appctx->ctx.map.desc->pat, args[3], smp, &pat, 0, NULL)) {
|
||||||
free(smp);
|
free(smp);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -307,7 +307,6 @@ static int map_parse_and_index(struct map_descriptor *desc,
|
|||||||
char **err)
|
char **err)
|
||||||
{
|
{
|
||||||
struct sample_storage *smp;
|
struct sample_storage *smp;
|
||||||
const char *args[2];
|
|
||||||
|
|
||||||
/* use new smp for storing value */
|
/* use new smp for storing value */
|
||||||
smp = calloc(1, sizeof(*smp));
|
smp = calloc(1, sizeof(*smp));
|
||||||
@ -322,9 +321,7 @@ static int map_parse_and_index(struct map_descriptor *desc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* register key */
|
/* register key */
|
||||||
args[0] = ent->key;
|
if (!pattern_register(desc->pat, ent->key, smp, pattern, patflags, err))
|
||||||
args[1] = "";
|
|
||||||
if (!pattern_register(desc->pat, args, smp, pattern, patflags, err))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
225
src/pattern.c
225
src/pattern.c
@ -790,152 +790,129 @@ void pattern_init_expr(struct pattern_expr *expr)
|
|||||||
* return -1 if the parser fail. The err message is filled.
|
* return -1 if the parser fail. The err message is filled.
|
||||||
* return -2 if out of memory
|
* return -2 if out of memory
|
||||||
*/
|
*/
|
||||||
int pattern_register(struct pattern_expr *expr, const char **args,
|
int pattern_register(struct pattern_expr *expr, const char *arg,
|
||||||
struct sample_storage *smp,
|
struct sample_storage *smp,
|
||||||
struct pattern **pattern,
|
struct pattern **pattern,
|
||||||
int patflags, char **err)
|
int patflags, char **err)
|
||||||
{
|
{
|
||||||
unsigned int mask = 0;
|
unsigned int mask = 0;
|
||||||
struct pat_idx_elt *node;
|
struct pat_idx_elt *node;
|
||||||
int len;
|
int len;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* eat args */
|
/* we keep the previous pattern along iterations as long as it's not used */
|
||||||
while (**args) {
|
if (!*pattern)
|
||||||
|
*pattern = (struct pattern *)malloc(sizeof(**pattern));
|
||||||
|
if (!*pattern) {
|
||||||
|
memprintf(err, "out of memory while loading pattern");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* we keep the previous pattern along iterations as long as it's not used */
|
memset(*pattern, 0, sizeof(**pattern));
|
||||||
if (!*pattern)
|
(*pattern)->flags = patflags;
|
||||||
*pattern = (struct pattern *)malloc(sizeof(**pattern));
|
|
||||||
if (!*pattern) {
|
ret = expr->parse(arg, *pattern, PAT_U_COMPILE, err);
|
||||||
|
if (!ret)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (expr->match == pat_match_str) {
|
||||||
|
/* SMP_T_CSTR tree indexation.
|
||||||
|
* The match "pat_match_str()" can use trees.
|
||||||
|
*/
|
||||||
|
if ((*pattern)->flags & PAT_F_IGNORE_CASE) {
|
||||||
|
/* If the flag PAT_F_IGNORE_CASE is set, we cannot use trees */
|
||||||
|
goto just_chain_the_pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process the key len */
|
||||||
|
len = strlen((*pattern)->ptr.str) + 1;
|
||||||
|
|
||||||
|
/* node memory allocation */
|
||||||
|
node = calloc(1, sizeof(*node) + len);
|
||||||
|
if (!node) {
|
||||||
memprintf(err, "out of memory while loading pattern");
|
memprintf(err, "out of memory while loading pattern");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(*pattern, 0, sizeof(**pattern));
|
/* copy the pointer to sample associated to this node */
|
||||||
(*pattern)->flags = patflags;
|
node->smp = smp;
|
||||||
|
|
||||||
ret = expr->parse(args[0], *pattern, PAT_U_COMPILE, err);
|
/* copy the string */
|
||||||
if (!ret)
|
memcpy(node->node.key, (*pattern)->ptr.str, len);
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* each parser return the number of args eated */
|
/* the "map_parser_str()" function always duplicate string information */
|
||||||
args += ret;
|
free((*pattern)->ptr.str);
|
||||||
|
(*pattern)->ptr.str = NULL;
|
||||||
|
|
||||||
/*
|
/* we pre-set the data pointer to the tree's head so that functions
|
||||||
*
|
* which are able to insert in a tree know where to do that.
|
||||||
* SMP_T_CSTR tree indexation
|
|
||||||
*
|
|
||||||
* The match "pat_match_str()" can use tree.
|
|
||||||
*
|
*
|
||||||
|
* because "val" is an "union", the previous data are crushed.
|
||||||
*/
|
*/
|
||||||
if (expr->match == pat_match_str) {
|
(*pattern)->flags |= PAT_F_TREE;
|
||||||
|
(*pattern)->val.tree = &expr->pattern_tree;
|
||||||
|
|
||||||
/* If the flag PAT_F_IGNORE_CASE is set, we cannot use trees */
|
/* index the new node */
|
||||||
if ((*pattern)->flags & PAT_F_IGNORE_CASE)
|
if (ebst_insert((*pattern)->val.tree, &node->node) != &node->node)
|
||||||
goto just_chain_the_pattern;
|
free(node); /* was a duplicate */
|
||||||
|
}
|
||||||
/* Process the key len */
|
else if (expr->match == pat_match_ip) {
|
||||||
len = strlen((*pattern)->ptr.str) + 1;
|
/* SMP_T_IPV4 tree indexation
|
||||||
|
|
||||||
/* node memory allocation */
|
|
||||||
node = calloc(1, sizeof(*node) + len);
|
|
||||||
if (!node) {
|
|
||||||
memprintf(err, "out of memory while loading pattern");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy the pointer to sample associated to this node */
|
|
||||||
node->smp = smp;
|
|
||||||
|
|
||||||
/* copy the string */
|
|
||||||
memcpy(node->node.key, (*pattern)->ptr.str, len);
|
|
||||||
|
|
||||||
/* the "map_parser_str()" function always duplicate string information */
|
|
||||||
free((*pattern)->ptr.str);
|
|
||||||
(*pattern)->ptr.str = NULL;
|
|
||||||
|
|
||||||
/* we pre-set the data pointer to the tree's head so that functions
|
|
||||||
* which are able to insert in a tree know where to do that.
|
|
||||||
*
|
|
||||||
* because "val" is an "union", the previous data are crushed.
|
|
||||||
*/
|
|
||||||
(*pattern)->flags |= PAT_F_TREE;
|
|
||||||
(*pattern)->val.tree = &expr->pattern_tree;
|
|
||||||
|
|
||||||
/* index the new node */
|
|
||||||
if (ebst_insert((*pattern)->val.tree, &node->node) != &node->node)
|
|
||||||
free(node); /* was a duplicate */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* SMP_T_IPV4 tree indexation
|
|
||||||
*
|
|
||||||
* The match "pat_match_ip()" can use tree.
|
* The match "pat_match_ip()" can use tree.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
else if (expr->match == pat_match_ip) {
|
if ((*pattern)->type != SMP_T_IPV4) {
|
||||||
|
|
||||||
/* Only IPv4 can be indexed */
|
/* Only IPv4 can be indexed */
|
||||||
if ((*pattern)->type != SMP_T_IPV4)
|
goto just_chain_the_pattern;
|
||||||
goto just_chain_the_pattern;
|
|
||||||
|
|
||||||
/* in IPv4 case, check if the mask is contiguous so that we can
|
|
||||||
* insert the network into the tree. A continuous mask has only
|
|
||||||
* ones on the left. This means that this mask + its lower bit
|
|
||||||
* added once again is null.
|
|
||||||
*/
|
|
||||||
mask = ntohl((*pattern)->val.ipv4.mask.s_addr);
|
|
||||||
if (mask + (mask & -mask) != 0)
|
|
||||||
goto just_chain_the_pattern;
|
|
||||||
mask = mask ? 33 - flsnz(mask & -mask) : 0; /* equals cidr value */
|
|
||||||
|
|
||||||
/* node memory allocation */
|
|
||||||
node = calloc(1, sizeof(*node) + 4);
|
|
||||||
if (!node) {
|
|
||||||
memprintf(err, "out of memory while loading pattern");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy the pointer to sample associated to this node */
|
|
||||||
node->smp = smp;
|
|
||||||
|
|
||||||
/* FIXME: insert <addr>/<mask> into the tree here */
|
|
||||||
memcpy(node->node.key, &(*pattern)->val.ipv4.addr, 4); /* network byte order */
|
|
||||||
|
|
||||||
/* we pre-set the data pointer to the tree's head so that functions
|
|
||||||
* which are able to insert in a tree know where to do that.
|
|
||||||
*
|
|
||||||
* because "val" is an "union", the previous data are crushed.
|
|
||||||
*/
|
|
||||||
(*pattern)->flags |= PAT_F_TREE;
|
|
||||||
(*pattern)->val.tree = &expr->pattern_tree;
|
|
||||||
|
|
||||||
/* Index the new node
|
|
||||||
* FIXME: insert <addr>/<mask> into the tree here
|
|
||||||
*/
|
|
||||||
node->node.node.pfx = mask;
|
|
||||||
if (ebmb_insert_prefix((*pattern)->val.tree, &node->node, 4) != &node->node)
|
|
||||||
free(node); /* was a duplicate */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* in IPv4 case, check if the mask is contiguous so that we can
|
||||||
*
|
* insert the network into the tree. A continuous mask has only
|
||||||
* if the parser did not feed the tree, let's chain the pattern to the list
|
* ones on the left. This means that this mask + its lower bit
|
||||||
*
|
* added once again is null.
|
||||||
*/
|
*/
|
||||||
else {
|
mask = ntohl((*pattern)->val.ipv4.mask.s_addr);
|
||||||
|
if (mask + (mask & -mask) != 0)
|
||||||
|
goto just_chain_the_pattern;
|
||||||
|
mask = mask ? 33 - flsnz(mask & -mask) : 0; /* equals cidr value */
|
||||||
|
|
||||||
just_chain_the_pattern:
|
/* node memory allocation */
|
||||||
|
node = calloc(1, sizeof(*node) + 4);
|
||||||
LIST_ADDQ(&expr->patterns, &(*pattern)->list);
|
if (!node) {
|
||||||
|
memprintf(err, "out of memory while loading pattern");
|
||||||
/* copy the pointer to sample associated to this node */
|
return 0;
|
||||||
(*pattern)->smp = smp;
|
|
||||||
|
|
||||||
/* get a new one */
|
|
||||||
*pattern = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* copy the pointer to sample associated to this node */
|
||||||
|
node->smp = smp;
|
||||||
|
|
||||||
|
/* FIXME: insert <addr>/<mask> into the tree here */
|
||||||
|
memcpy(node->node.key, &(*pattern)->val.ipv4.addr, 4); /* network byte order */
|
||||||
|
|
||||||
|
/* we pre-set the data pointer to the tree's head so that functions
|
||||||
|
* which are able to insert in a tree know where to do that.
|
||||||
|
*
|
||||||
|
* because "val" is an "union", the previous data are crushed.
|
||||||
|
*/
|
||||||
|
(*pattern)->flags |= PAT_F_TREE;
|
||||||
|
(*pattern)->val.tree = &expr->pattern_tree;
|
||||||
|
|
||||||
|
/* Index the new node
|
||||||
|
* FIXME: insert <addr>/<mask> into the tree here
|
||||||
|
*/
|
||||||
|
node->node.node.pfx = mask;
|
||||||
|
if (ebmb_insert_prefix((*pattern)->val.tree, &node->node, 4) != &node->node)
|
||||||
|
free(node); /* was a duplicate */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
just_chain_the_pattern:
|
||||||
|
/* if the parser did not feed the tree, let's chain the pattern to the list */
|
||||||
|
LIST_ADDQ(&expr->patterns, &(*pattern)->list);
|
||||||
|
|
||||||
|
/* copy the pointer to sample associated to this node */
|
||||||
|
(*pattern)->smp = smp;
|
||||||
|
|
||||||
|
/* get a new one */
|
||||||
|
*pattern = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -955,7 +932,6 @@ int pattern_read_from_file(struct pattern_expr *expr,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
int line = 0;
|
int line = 0;
|
||||||
int code;
|
int code;
|
||||||
const char *args[2];
|
|
||||||
|
|
||||||
file = fopen(filename, "r");
|
file = fopen(filename, "r");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
@ -990,10 +966,7 @@ int pattern_read_from_file(struct pattern_expr *expr,
|
|||||||
if (c == arg)
|
if (c == arg)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
args[0] = arg;
|
code = pattern_register(expr, arg, NULL, &pattern, patflags, err);
|
||||||
args[1] = "";
|
|
||||||
|
|
||||||
code = pattern_register(expr, args, NULL, &pattern, patflags, err);
|
|
||||||
if (code == -2) {
|
if (code == -2) {
|
||||||
memprintf(err, "out of memory when loading patterns from file <%s>", filename);
|
memprintf(err, "out of memory when loading patterns from file <%s>", filename);
|
||||||
goto out_close;
|
goto out_close;
|
||||||
|
Loading…
Reference in New Issue
Block a user