i_unreached();
}
-static void
-event_filter_add_categories(pool_t pool,
- struct event_filter_node **root,
- const char *const *categories)
-{
- unsigned int categories_count = str_array_length(categories);
- unsigned int i;
-
- if (categories_count == 0)
- return;
-
- for (i = 0; i < categories_count; i++) {
- struct event_filter_node *node;
-
- node = p_new(pool, struct event_filter_node, 1);
- node->type = EVENT_FILTER_NODE_TYPE_EVENT_CATEGORY;
- node->op = EVENT_FILTER_OP_CMP_EQ;
- if (!event_filter_category_to_log_type(categories[i], &node->category.log_type)) {
- node->category.name = p_strdup(pool, categories[i]);
- node->category.ptr = event_category_find_registered(categories[i]);
- }
-
- add_node(pool, root, node, EVENT_FILTER_OP_AND);
- }
-}
-
-static void
-event_filter_add_fields(pool_t pool,
- struct event_filter_node **root,
- const struct event_filter_field *fields)
-{
- unsigned int i;
-
- if (fields == NULL)
- return;
-
- for (i = 0; fields[i].key != NULL; i++) {
- struct event_filter_node *node;
-
- node = p_new(pool, struct event_filter_node, 1);
- node->type = EVENT_FILTER_NODE_TYPE_EVENT_FIELD_WILDCARD;
- node->op = EVENT_FILTER_OP_CMP_EQ;
- node->field.key = p_strdup(pool, fields[i].key);
- node->field.value.str = p_strdup(pool, fields[i].value);
-
- /* Filter currently supports only comparing strings
- and numbers. */
- if (str_to_intmax(fields[i].value, &node->field.value.intmax) < 0) {
- /* not a number - no problem
- Either we have a string, or a number with wildcards */
- node->field.value.intmax = INT_MIN;
- }
-
- add_node(pool, root, node, EVENT_FILTER_OP_AND);
- }
-}
-
-void event_filter_add(struct event_filter *filter,
- const struct event_filter_query *query)
-{
- struct event_filter_query_internal *int_query;
- struct event_filter_node *expr = NULL;
-
- if (query->name != NULL) {
- struct event_filter_node *node;
-
- node = p_new(filter->pool, struct event_filter_node, 1);
- node->type = EVENT_FILTER_NODE_TYPE_EVENT_NAME_WILDCARD;
- node->op = EVENT_FILTER_OP_CMP_EQ;
- node->str = p_strdup(filter->pool, query->name);
- if (wildcard_is_literal(query->name))
- node->type = EVENT_FILTER_NODE_TYPE_EVENT_NAME_EXACT;
-
- add_node(filter->pool, &expr, node, EVENT_FILTER_OP_AND);
- }
-
- if ((query->source_filename != NULL) && (query->source_filename[0] != '\0')) {
- struct event_filter_node *node;
-
- node = p_new(filter->pool, struct event_filter_node, 1);
- node->type = EVENT_FILTER_NODE_TYPE_EVENT_SOURCE_LOCATION;
- node->op = EVENT_FILTER_OP_CMP_EQ;
- node->str = p_strdup(filter->pool, query->source_filename);
- node->intmax = query->source_linenum;
-
- add_node(filter->pool, &expr, node, EVENT_FILTER_OP_AND);
- }
-
- event_filter_add_categories(filter->pool, &expr, query->categories);
- event_filter_add_fields(filter->pool, &expr, query->fields);
-
- if (expr == NULL)
- return; /* completely empty query - ignore it */
-
- int_query = event_filter_get_or_alloc_internal_query(filter, query->context);
-
- if (query->name == NULL)
- filter->named_queries_only = FALSE;
-
- /* OR the new expression with existing query */
- add_node(filter->pool, &int_query->expr, expr, EVENT_FILTER_OP_OR);
-}
-
static struct event_filter_node *
clone_expr(pool_t pool, struct event_filter_node *old)
{
const char *value;
};
-struct event_filter_query {
- /* NULL-terminated list of categories */
- const char *const *categories;
- /* key=NULL-terminated list of key=value fields */
- const struct event_filter_field *fields;
-
- /* event name. Supports '*' and '?' wildcards. */
- const char *name;
- /* source filename:line */
- const char *source_filename;
- unsigned int source_linenum;
-
- /* context associated with this query. This is returned when iterating
- through matched queries. If NULL, the iteration won't return this
- query. */
- void *context;
-};
-
struct event_filter *event_filter_create(void);
struct event_filter *event_filter_create_fragment(pool_t pool);
void event_filter_ref(struct event_filter *filter);
void event_filter_unref(struct event_filter **filter);
-/* Add a new query to the filter. All of the categories and fields in the query
- need to match, so they're ANDed together. Separate queries are ORed
- together. */
-void event_filter_add(struct event_filter *filter,
- const struct event_filter_query *query);
/* Add queries from source filter to destination filter. */
void event_filter_merge(struct event_filter *dest,
const struct event_filter *src);