MEDIUM: pattern: The function pattern_exec_match() returns "struct pattern" if the patten match.
Before this commit, the pattern_exec_match() function returns the
associate sample, the associate struct pattern or the associate struct
pattern_tree. This is complex to use, because we can check the type of
information returned.
Now the function return always a "struct pattern". If <fill> is not set,
only the value of the pointer can be used as boolean (NULL or other). If
<fill> is set, you can use the <smp> pointer and the pattern
information.
If information must be duplicated, it is stored in trash buffer.
Otherwise, the pattern can point on existing strings.
diff --git a/src/pattern.c b/src/pattern.c
index d41e086..aa6a3d4 100644
--- a/src/pattern.c
+++ b/src/pattern.c
@@ -105,6 +105,9 @@
[PAT_MATCH_REG] = SMP_T_STR,
};
+/* this struct is used to return information */
+static struct pattern static_pattern;
+
/*
*
* The following functions are not exported and are used by internals process
@@ -1059,19 +1062,18 @@
return ret;
}
-/* This function matches a sample <smp> against a set of patterns presented in
- * pattern expression <expr>. Upon success, if <sample> is not NULL, it is fed
- * with the pointer associated with the matching pattern. This function returns
- * PAT_NOMATCH or PAT_MATCH.
+/* This function executes a pattern match on a sample. It applies pattern <expr>
+ * to sample <smp>. The function returns NULL if the sample dont match. It returns
+ * non-null if the sample match. If <fill> is true and the sample match, the
+ * function returns the matched pattern. In many cases, this pattern can be a
+ * static buffer.
*/
-enum pat_match_res pattern_exec_match(struct pattern_expr *expr, struct sample *smp,
- struct sample_storage **sample,
- struct pattern **pat, struct pattern_tree **idx_elt)
+struct pattern *pattern_exec_match(struct pattern_expr *expr, struct sample *smp, int fill)
{
enum pat_match_res pat_res = PAT_NOMATCH;
- struct pattern_list *pattern;
+ struct pattern_list *pattern = NULL;
struct ebmb_node *node = NULL;
- struct pattern_tree *elt;
+ struct pattern_tree *elt = NULL;
if (expr->match == pat_match_nothing) {
if (smp->data.uint)
@@ -1097,27 +1099,62 @@
if (node) {
pat_res |= PAT_MATCH;
elt = ebmb_entry(node, struct pattern_tree, node);
- if (sample)
- *sample = elt->smp;
- if (idx_elt)
- *idx_elt = elt;
}
}
/* call the match() function for all tests on this value */
- list_for_each_entry(pattern, &expr->patterns, list) {
- if (pat_res == PAT_MATCH)
- break;
- if (sample_convert(smp, pattern->pat.expect_type))
- pat_res |= expr->match(smp, &pattern->pat);
- if (sample)
- *sample = pattern->pat.smp;
- if (pat)
- *pat = &pattern->pat;
+ if (pat_res != PAT_MATCH) {
+ list_for_each_entry(pattern, &expr->patterns, list) {
+ if (sample_convert(smp, pattern->pat.expect_type))
+ pat_res |= expr->match(smp, &pattern->pat);
+ if (pat_res == PAT_MATCH)
+ break;
+ }
}
}
+ if (pat_res == PAT_MATCH) {
+ static_pattern.flags = 0;
+ if (fill) {
+ /* fill with boolean */
+ if (expr->match == NULL ||
+ expr->match == pat_match_nothing) {
+ static_pattern.smp = NULL;
+ static_pattern.type = SMP_T_BOOL;
+ static_pattern.val.i = 1;
+ return &static_pattern;
+ }
+
+ /* fill with ipv4 */
+ if (expr->match == pat_match_ip && elt) {
+ static_pattern.smp = elt->smp;;
+ static_pattern.flags |= PAT_F_TREE;
+ static_pattern.type = SMP_T_IPV4;
+ memcpy(&static_pattern.val.ipv4.addr, &elt->node.key, 4);
+ if (!cidr2dotted(elt->node.node.pfx, &static_pattern.val.ipv4.mask))
+ return NULL;
+ return &static_pattern;
+ }
+
+ /* fill with string */
+ if (expr->match == pat_match_str && elt) {
+ static_pattern.smp = elt->smp;;
+ static_pattern.flags |= PAT_F_TREE;
+ static_pattern.type = SMP_T_STR;
+ static_pattern.ptr.str = (char *)elt->node.key;
+ return &static_pattern;
+ }
+
+ /* return the pattern */
+ return &pattern->pat;
+ }
+
+ /* Return uninitialized pattern. The content must not be used by the caller */
+ return &static_pattern;
+ }
+
- return pat_res;
+ /* No match */
+ return NULL;
}
/* This function browse the pattern expr <expr> to lookup the key <key>. On