/* Number of filters in this parser and parent parsers that have
filter.filter_name_array=TRUE. */
unsigned int named_list_filter_count;
+ /* Number of filters in this parser that have non-NULL
+ filter.filter_name and filter.filter_name_array=FALSE. */
+ unsigned int named_filter_count;
/* Filter parser tree. These are used only for doveconf's human output
to write the filters in nice nested hierarchies. */
if (parent_filter_parser != NULL) {
filter_parser->parent = parent_filter_parser;
filter_parser->named_list_filter_count =
- parent_filter_parser->named_list_filter_count +
- (filter->filter_name_array ? 1 : 0);
+ parent_filter_parser->named_list_filter_count;
+ filter_parser->named_filter_count =
+ parent_filter_parser->named_filter_count;
+ if (filter->filter_name_array)
+ filter_parser->named_list_filter_count++;
+ else if (filter->filter_name != NULL)
+ filter_parser->named_filter_count++;
DLLIST2_APPEND(&parent_filter_parser->children_head,
&parent_filter_parser->children_tail,
filter_parser);
if (ret != 0)
return ret;
+ /* After sorting by named list filter hierarchy count, sort by
+ named non-list filter hierarchy count. */
+ ret = (int)(*f1)->named_filter_count - (int)(*f2)->named_filter_count;
+ if (ret != 0)
+ return ret;
+
/* Finally, just order them in the order of creation. */
return (int)(*f1)->create_order - (int)(*f2)->create_order;
}
unsigned int path_element_count;
/* Number of named list filter elements in this override */
unsigned int filter_array_element_count;
+ /* Number of named (non-list) filter elements in this override */
+ unsigned int filter_element_count;
/* key += value is used, i.e. append this value to existing value */
bool append;
/* TRUE once all the filter elements have been processed in "key",
/* We want to sort the override similarly to filters in binary config,
i.e. primarily based on named list filter hierarchy length. This way
for example userdb namespace/inbox/mailbox/trash/auto is handled
- before -o mailbox/trash/auto CLI override. Only secondarily when the
- hierarchy lengths are equal, the override type determines the
- order. */
+ before -o mailbox/trash/auto CLI override. */
int ret = (int)set2->set->filter_array_element_count -
(int)set1->set->filter_array_element_count;
if (ret != 0)
return ret;
+ /* Sort by the number of named (non-list) filters. Do this only if
+ both overrides have named [list] filters, because we want e.g.
+ -o mail_path to override the default sdbox/mail_path. */
+ if (set1->set->filter_array_element_count > 0 ||
+ (set1->set->filter_element_count > 0 &&
+ set1->set->filter_element_count > 0)) {
+ ret = (int)set2->set->filter_element_count -
+ (int)set1->set->filter_element_count;
+ if (ret != 0)
+ return ret;
+ }
+
+ /* Next, the override type determines the order. */
ret = (int)set2->set->type - (int)set1->set->type;
if (ret != 0)
return ret;
event_strlist_append(set->filter_event,
SETTINGS_EVENT_FILTER_NAME,
last_filter_key);
+ set->filter_element_count++;
break;
case SET_FILTER_ARRAY: {
const char *value = p + 1;
set->path_element_count = path_element_count(set->orig_key);
set->filter_array_element_count =
array_set->filter_array_element_count;
+ set->filter_element_count =
+ array_set->filter_element_count;
set->value = p_strdup(set->pool, items[i]);
/* Get the final key we want to use in the event filter.