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:
Thierry FOURNIER 2014-01-23 17:53:31 +01:00 committed by Willy Tarreau
parent 580c32cb3a
commit 972028fa67
5 changed files with 103 additions and 140 deletions

View File

@ -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)

View File

@ -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++;
} }

View File

@ -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;
} }

View File

@ -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;

View File

@ -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;