From 5d49e2e3297c3af800eb68b74972d2b38c0eb8de Mon Sep 17 00:00:00 2001 From: Corey Farrell Date: Tue, 12 Dec 2017 13:36:39 -0500 Subject: aco: Create ways to minimize use of regex. ACO uses regex in many situations where it is completely unneeded. In some cases this doubles the total processing performed by aco_process_config. * Create ACO_IGNORE category type for use in place of skip_category regex source string. * Create additional aco_category_op values to allow specifying category filter using either a single plain string or a NULL terminated array of plain strings. * Create ACO_PREFIX to allow matching option names to case insensitive prefixes. Change-Id: I66a920dcd8e2b0301f73f968016440a985e72821 --- include/asterisk/config_options.h | 14 ++++++- main/config_options.c | 87 +++++++++++++++++++++++++++++++++++---- 2 files changed, 92 insertions(+), 9 deletions(-) diff --git a/include/asterisk/config_options.h b/include/asterisk/config_options.h index f4c3db188..3227f94eb 100644 --- a/include/asterisk/config_options.h +++ b/include/asterisk/config_options.h @@ -40,18 +40,30 @@ struct aco_type_internal; enum aco_type_t { ACO_GLOBAL, ACO_ITEM, + ACO_IGNORE, }; -/*! \brief Whether a category regex is a blackist or a whitelist */ +/*! Type of category matching to perform */ enum aco_category_op { + /*! Regex based blacklist. */ ACO_BLACKLIST = 0, + /*! Regex based whitelist. */ ACO_WHITELIST, + /*! Blacklist with a single string matched with strcasecmp. */ + ACO_BLACKLIST_EXACT, + /*! Whitelist with a single string matched with strcasecmp. */ + ACO_WHITELIST_EXACT, + /*! Blacklist with a NULL terminated array of strings matched with strcasecmp. */ + ACO_BLACKLIST_ARRAY, + /*! Whitelist with a NULL terminated array of strings matched with strcasecmp. */ + ACO_WHITELIST_ARRAY, }; /*! \brief What kind of matching should be done on an option name */ enum aco_matchtype { ACO_EXACT = 1, ACO_REGEX, + ACO_PREFIX, }; /*! Callback functions for option parsing via aco_process_config() */ diff --git a/main/config_options.c b/main/config_options.c index a9a145b96..1f4f99b72 100644 --- a/main/config_options.c +++ b/main/config_options.c @@ -131,7 +131,7 @@ static int noop_handler_fn(const struct aco_option *opt, struct ast_variable *va static int chararray_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj); #ifdef AST_XML_DOCS -static int xmldoc_update_config_type(const char *module, const char *name, const char *category, const char *matchfield, const char *matchvalue, unsigned int matches); +static int xmldoc_update_config_type(const char *module, const char *name, const char *category, const char *matchfield, const char *matchvalue, enum aco_category_op category_match); static int xmldoc_update_config_option(struct aco_type **types, const char *module, const char *name, const char *object_name, const char *default_value, unsigned int regex, enum aco_option_type type); #endif @@ -373,6 +373,8 @@ static int find_option_cb(void *obj, void *arg, int flags) switch (match->match_type) { case ACO_EXACT: return strcasecmp(name, match->name) ? 0 : CMP_MATCH | CMP_STOP; + case ACO_PREFIX: + return strncasecmp(name, match->name, strlen(match->name)) ? 0 : CMP_MATCH | CMP_STOP; case ACO_REGEX: return regexec(match->name_regex, name, 0, NULL, 0) ? 0 : CMP_MATCH | CMP_STOP; } @@ -402,6 +404,45 @@ struct ao2_container *aco_option_container_alloc(void) return ao2_container_alloc(CONFIG_OPT_BUCKETS, config_opt_hash, config_opt_cmp); } +static int internal_aco_type_category_check(struct aco_type *match, const char *category) +{ + const char **categories = (const char **)match->category; + + switch (match->category_match) { + case ACO_WHITELIST: + return regexec(match->internal->regex, category, 0, NULL, 0); + + case ACO_BLACKLIST: + return !regexec(match->internal->regex, category, 0, NULL, 0); + + case ACO_WHITELIST_EXACT: + return strcasecmp(match->category, category); + + case ACO_BLACKLIST_EXACT: + return !strcasecmp(match->category, category); + + case ACO_WHITELIST_ARRAY: + while (*categories) { + if (!strcasecmp(*categories, category)) { + return 0; + } + categories++; + } + return -1; + + case ACO_BLACKLIST_ARRAY: + while (*categories) { + if (!strcasecmp(*categories, category)) { + return -1; + } + categories++; + } + return 0; + } + + return -1; +} + static struct aco_type *internal_aco_type_find(struct aco_file *file, struct ast_config *cfg, const char *category) { size_t x; @@ -410,7 +451,7 @@ static struct aco_type *internal_aco_type_find(struct aco_file *file, struct ast for (x = 0, match = file->types[x]; match; match = file->types[++x]) { /* First make sure we are an object that can service this category */ - if (!regexec(match->internal->regex, category, 0, NULL, 0) == !match->category_match) { + if (internal_aco_type_category_check(match, category)) { continue; } @@ -483,6 +524,10 @@ static int process_category(struct ast_config *cfg, struct aco_info *info, struc return -1; } + if (type->type == ACO_IGNORE) { + return 0; + } + field = info->internal->pending + type->item_offset; if (!*field) { ast_log(LOG_ERROR, "In %s: %s - No object to update!\n", file->filename, cat); @@ -631,6 +676,10 @@ enum aco_process_status aco_process_config(struct aco_info *info, int reload) for (i = 0, match = file->types[i]; match; match = file->types[++i]) { void **field = info->internal->pending + match->item_offset; + if (match->type == ACO_IGNORE) { + continue; + } + if (match->type != ACO_GLOBAL || !*field) { continue; } @@ -797,9 +846,19 @@ static int internal_type_init(struct aco_type *type) return -1; } - if (!(type->internal->regex = build_regex(type->category))) { - internal_type_destroy(type); - return -1; + switch (type->category_match) { + case ACO_BLACKLIST: + case ACO_WHITELIST: + if (!(type->internal->regex = build_regex(type->category))) { + internal_type_destroy(type); + return -1; + } + break; + case ACO_BLACKLIST_EXACT: + case ACO_WHITELIST_EXACT: + case ACO_BLACKLIST_ARRAY: + case ACO_WHITELIST_ARRAY: + break; } if (!(type->internal->opts = aco_option_container_alloc())) { @@ -828,7 +887,8 @@ int aco_info_init(struct aco_info *info) #ifdef AST_XML_DOCS if (!info->hidden && !type->hidden && - xmldoc_update_config_type(info->module, type->name, type->category, type->matchfield, type->matchvalue, type->category_match == ACO_WHITELIST)) { + type->type != ACO_IGNORE && + xmldoc_update_config_type(info->module, type->name, type->category, type->matchfield, type->matchvalue, type->category_match)) { goto error; } #endif /* AST_XML_DOCS */ @@ -989,7 +1049,7 @@ static char *complete_config_option(const char *module, const char *option, cons /*! \internal * \brief Update the XML documentation for a config type based on its registration */ -static int xmldoc_update_config_type(const char *module, const char *name, const char *category, const char *matchfield, const char *matchvalue, unsigned int matches) +static int xmldoc_update_config_type(const char *module, const char *name, const char *category, const char *matchfield, const char *matchvalue, enum aco_category_op category_match) { RAII_VAR(struct ast_xml_xpath_results *, results, NULL, ast_xml_xpath_results_free); RAII_VAR(struct ast_xml_doc_item *, config_info, ao2_find(xmldocs, module, OBJ_KEY), ao2_cleanup); @@ -1028,7 +1088,18 @@ static int xmldoc_update_config_type(const char *module, const char *name, const } ast_xml_set_text(tmp, category); - ast_xml_set_attribute(tmp, "match", matches ? "true" : "false"); + switch (category_match) { + case ACO_WHITELIST: + case ACO_WHITELIST_EXACT: + case ACO_WHITELIST_ARRAY: + ast_xml_set_attribute(tmp, "match", "true"); + break; + case ACO_BLACKLIST: + case ACO_BLACKLIST_EXACT: + case ACO_BLACKLIST_ARRAY: + ast_xml_set_attribute(tmp, "match", "false"); + break; + } if (!ast_strlen_zero(matchfield) && !(tmp = ast_xml_new_child(matchinfo, "field"))) { ast_log(LOG_WARNING, "Could not add %s attribute for type '%s' in module '%s'\n", matchfield, name, module); -- cgit v1.2.3 From 957709e1e824e221254599e4ad8445e3839ce535 Mon Sep 17 00:00:00 2001 From: Corey Farrell Date: Tue, 12 Dec 2017 13:55:12 -0500 Subject: aco: Minimize use of regex. Remove nearly all use of regex from ACO users. Still remaining: * app_confbridge has a legitamate use of option name regex. * ast_sorcery_object_fields_register is implemented with regex, all callers use simple prefix based regex. I haven't decided the best way to fix this in both 13/15 and master. Change-Id: Ib5ed478218d8a661ace4d2eaaea98b59a897974b --- apps/app_agent_pool.c | 14 ++++++++++---- apps/app_skel.c | 18 ++++++++++++------ apps/confbridge/conf_config_parser.c | 20 ++++++++++---------- channels/chan_motif.c | 4 ++-- main/cdr.c | 28 ++++++++++++++++++++++++---- main/cel.c | 21 +++++++++++++++++---- main/features_config.c | 22 +++++++++++----------- main/named_acl.c | 4 ++-- main/stasis.c | 8 ++++---- main/udptl.c | 4 ++-- res/ari/config.c | 8 ++++---- res/res_hep.c | 4 ++-- res/res_parking.c | 8 ++++---- res/res_pjsip_notify.c | 8 ++++---- res/res_resolver_unbound.c | 4 ++-- res/res_statsd.c | 4 ++-- res/res_xmpp.c | 8 ++++---- tests/test_config.c | 14 ++++++++++---- 18 files changed, 126 insertions(+), 75 deletions(-) diff --git a/apps/app_agent_pool.c b/apps/app_agent_pool.c index 6a8c3955b..3c2ea3870 100644 --- a/apps/app_agent_pool.c +++ b/apps/app_agent_pool.c @@ -455,11 +455,17 @@ struct agents_cfg { struct ao2_container *agents; }; +static const char *agent_type_blacklist[] = { + "general", + "agents", + NULL, +}; + static struct aco_type agent_type = { .type = ACO_ITEM, .name = "agent-id", - .category_match = ACO_BLACKLIST, - .category = "^(general|agents)$", + .category_match = ACO_BLACKLIST_ARRAY, + .category = (const char *)agent_type_blacklist, .item_alloc = agent_cfg_alloc, .item_find = agent_cfg_find, .item_offset = offsetof(struct agents_cfg, agents), @@ -471,8 +477,8 @@ static struct aco_type *agent_types[] = ACO_TYPES(&agent_type); static struct aco_type general_type = { .type = ACO_GLOBAL, .name = "global", - .category_match = ACO_WHITELIST, - .category = "^general$", + .category_match = ACO_WHITELIST_EXACT, + .category = "general", }; static struct aco_file agents_conf = { diff --git a/apps/app_skel.c b/apps/app_skel.c index b3c887685..68f313fee 100644 --- a/apps/app_skel.c +++ b/apps/app_skel.c @@ -242,8 +242,8 @@ static struct aco_type global_option = { .type = ACO_GLOBAL, .name = "globals", .item_offset = offsetof(struct skel_config, global), - .category_match = ACO_WHITELIST, - .category = "^general$", + .category_match = ACO_WHITELIST_EXACT, + .category = "general", }; struct aco_type *global_options[] = ACO_TYPES(&global_option); @@ -253,18 +253,24 @@ static struct aco_type sound_option = { .type = ACO_GLOBAL, .name = "sounds", .item_offset = offsetof(struct skel_config, global), - .category_match = ACO_WHITELIST, - .category = "^sounds$", + .category_match = ACO_WHITELIST_EXACT, + .category = "sounds", }; struct aco_type *sound_options[] = ACO_TYPES(&sound_option); +static const char *level_categories[] = { + "general", + "sounds", + NULL, +}; + /*! \brief An aco_type structure to link the everything but the "general" and "sounds" categories to the skel_level type */ static struct aco_type level_option = { .type = ACO_ITEM, .name = "level", - .category_match = ACO_BLACKLIST, - .category = "^(general|sounds)$", + .category_match = ACO_BLACKLIST_ARRAY, + .category = (const char *)level_categories, .item_alloc = skel_level_alloc, .item_find = skel_level_find, .item_offset = offsetof(struct skel_config, levels), diff --git a/apps/confbridge/conf_config_parser.c b/apps/confbridge/conf_config_parser.c index 665930576..99eea0a27 100644 --- a/apps/confbridge/conf_config_parser.c +++ b/apps/confbridge/conf_config_parser.c @@ -409,7 +409,7 @@ regardless if this limit is reached or not. - + Override the various conference bridge sound files All sounds in the conference are customizable using the bridge profile options below. @@ -639,8 +639,8 @@ static void *bridge_profile_find(struct ao2_container *container, const char *ca static struct aco_type bridge_type = { .type = ACO_ITEM, .name = "bridge_profile", - .category_match = ACO_BLACKLIST, - .category = "^general$", + .category_match = ACO_BLACKLIST_EXACT, + .category = "general", .matchfield = "type", .matchvalue = "bridge", .item_alloc = bridge_profile_alloc, @@ -676,8 +676,8 @@ static void *user_profile_find(struct ao2_container *container, const char *cate static struct aco_type user_type = { .type = ACO_ITEM, .name = "user_profile", - .category_match = ACO_BLACKLIST, - .category = "^general$", + .category_match = ACO_BLACKLIST_EXACT, + .category = "general", .matchfield = "type", .matchvalue = "user", .item_alloc = user_profile_alloc, @@ -707,8 +707,8 @@ static void *menu_find(struct ao2_container *container, const char *category) static struct aco_type menu_type = { .type = ACO_ITEM, .name = "menu", - .category_match = ACO_BLACKLIST, - .category = "^general$", + .category_match = ACO_BLACKLIST_EXACT, + .category = "general", .matchfield = "type", .matchvalue = "menu", .item_alloc = menu_alloc, @@ -725,8 +725,8 @@ static struct aco_type *user_types[] = ACO_TYPES(&user_type); static struct aco_type general_type = { .type = ACO_GLOBAL, .name = "global", - .category_match = ACO_WHITELIST, - .category = "^general$", + .category_match = ACO_WHITELIST_EXACT, + .category = "general", }; static struct aco_file confbridge_conf = { @@ -2235,7 +2235,7 @@ int conf_load_config(void) aco_option_register(&cfg_info, "record_command", ACO_EXACT, bridge_types, NULL, OPT_CHAR_ARRAY_T, 0, CHARFLDSET(struct bridge_profile, rec_command)); aco_option_register(&cfg_info, "regcontext", ACO_EXACT, bridge_types, NULL, OPT_CHAR_ARRAY_T, 0, CHARFLDSET(struct bridge_profile, regcontext)); aco_option_register(&cfg_info, "language", ACO_EXACT, bridge_types, "en", OPT_CHAR_ARRAY_T, 0, CHARFLDSET(struct bridge_profile, language)); - aco_option_register_custom(&cfg_info, "^sound_", ACO_REGEX, bridge_types, NULL, sound_option_handler, 0); + aco_option_register_custom(&cfg_info, "sound_", ACO_PREFIX, bridge_types, NULL, sound_option_handler, 0); aco_option_register(&cfg_info, "video_update_discard", ACO_EXACT, bridge_types, "2000", OPT_UINT_T, 0, FLDSET(struct bridge_profile, video_update_discard)); /* This option should only be used with the CONFBRIDGE dialplan function */ aco_option_register_custom(&cfg_info, "template", ACO_EXACT, bridge_types, NULL, bridge_template_handler, 0); diff --git a/channels/chan_motif.c b/channels/chan_motif.c index 210cf36c6..6e8ce354a 100644 --- a/channels/chan_motif.c +++ b/channels/chan_motif.c @@ -541,8 +541,8 @@ static int jingle_endpoint_cmp(void *obj, void *arg, int flags) static struct aco_type endpoint_option = { .type = ACO_ITEM, .name = "endpoint", - .category_match = ACO_BLACKLIST, - .category = "^general$", + .category_match = ACO_BLACKLIST_EXACT, + .category = "general", .item_alloc = jingle_endpoint_alloc, .item_find = jingle_endpoint_find, .item_offset = offsetof(struct jingle_config, endpoints), diff --git a/main/cdr.c b/main/cdr.c index 3681cdc6b..d7384f259 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -238,8 +238,29 @@ static struct aco_type general_option = { .type = ACO_GLOBAL, .name = "general", .item_offset = offsetof(struct module_config, general), - .category = "^general$", - .category_match = ACO_WHITELIST, + .category = "general", + .category_match = ACO_WHITELIST_EXACT, +}; + +/*! Config sections used by existing modules. Do not add to this list. */ +static const char *ignore_categories[] = { + "csv", + "custom", + "manager", + "odbc", + "pgsql", + "radius", + "sqlite", + "tds", + "mysql", + NULL, +}; + +static struct aco_type ignore_option = { + .type = ACO_IGNORE, + .name = "modules", + .category = (const char*)ignore_categories, + .category_match = ACO_WHITELIST_ARRAY, }; static void *module_config_alloc(void); @@ -249,8 +270,7 @@ static void module_config_post_apply(void); /*! \brief The file definition */ static struct aco_file module_file_conf = { .filename = "cdr.conf", - .skip_category = "(^csv$|^custom$|^manager$|^odbc$|^pgsql$|^radius$|^sqlite$|^tds$|^mysql$)", - .types = ACO_TYPES(&general_option), + .types = ACO_TYPES(&general_option, &ignore_option), }; CONFIG_INFO_CORE("cdr", cfg_info, module_configs, module_config_alloc, diff --git a/main/cel.c b/main/cel.c index faf4fde71..cec0a85e4 100644 --- a/main/cel.c +++ b/main/cel.c @@ -242,15 +242,28 @@ static struct aco_type general_option = { .type = ACO_GLOBAL, .name = "general", .item_offset = offsetof(struct cel_config, general), - .category_match = ACO_WHITELIST, - .category = "^general$", + .category_match = ACO_WHITELIST_EXACT, + .category = "general", +}; + +/*! Config sections used by existing modules. Do not add to this list. */ +static const char *ignore_categories[] = { + "manager", + "radius", + NULL, +}; + +static struct aco_type ignore_option = { + .type = ACO_IGNORE, + .name = "modules", + .category = (const char*)ignore_categories, + .category_match = ACO_WHITELIST_ARRAY, }; /*! \brief The config file to be processed for the module. */ static struct aco_file cel_conf = { .filename = "cel.conf", /*!< The name of the config file */ - .types = ACO_TYPES(&general_option), /*!< The mapping object types to be processed */ - .skip_category = "(^manager$|^radius$)", /*!< Config sections used by existing modules. Do not add to this list. */ + .types = ACO_TYPES(&general_option, &ignore_option), /*!< The mapping object types to be processed */ }; static int cel_pre_apply_config(void); diff --git a/main/features_config.c b/main/features_config.c index 72cd0404f..a773f497f 100644 --- a/main/features_config.c +++ b/main/features_config.c @@ -219,7 +219,7 @@ The DYNAMIC_FEATURES is a # separated list of either applicationmap item names or featuregroup names. - + A custom feature to invoke during a bridged call Each item listed here is a comma-separated list of parameters that determine @@ -272,7 +272,7 @@ DTMF sequence used to invoke an applicationmap item to be overridden with a different sequence. - + Applicationmap item to place in the feature group Each item here must be a name of an item in the applicationmap. The @@ -578,24 +578,24 @@ struct features_config { static struct aco_type global_option = { .type = ACO_GLOBAL, .name = "globals", - .category_match = ACO_WHITELIST, - .category = "^general$", + .category_match = ACO_WHITELIST_EXACT, + .category = "general", .item_offset = offsetof(struct features_config, global), }; static struct aco_type featuremap_option = { .type = ACO_GLOBAL, .name = "featuremap", - .category_match = ACO_WHITELIST, - .category = "^featuremap$", + .category_match = ACO_WHITELIST_EXACT, + .category = "featuremap", .item_offset = offsetof(struct features_config, featuremap), }; static struct aco_type applicationmap_option = { .type = ACO_GLOBAL, .name = "applicationmap", - .category_match = ACO_WHITELIST, - .category = "^applicationmap$", + .category_match = ACO_WHITELIST_EXACT, + .category = "applicationmap", .item_offset = offsetof(struct features_config, applicationmap), }; @@ -1851,13 +1851,13 @@ static int load_config(void) aco_option_register_custom(&cfg_info, "automixmon", ACO_EXACT, featuremap_options, DEFAULT_FEATUREMAP_AUTOMIXMON, featuremap_handler, 0); - aco_option_register_custom(&cfg_info, "^.*$", ACO_REGEX, applicationmap_options, + aco_option_register_custom(&cfg_info, "", ACO_PREFIX, applicationmap_options, "", applicationmap_handler, 0); - aco_option_register_custom(&cfg_info, "^.*$", ACO_REGEX, featuregroup_options, + aco_option_register_custom(&cfg_info, "", ACO_PREFIX, featuregroup_options, "", featuregroup_handler, 0); - aco_option_register_custom_nodoc(&cfg_info, "^.*$", ACO_REGEX, parkinglot_options, + aco_option_register_custom_nodoc(&cfg_info, "", ACO_PREFIX, parkinglot_options, "", unsupported_handler, 0); if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) { diff --git a/main/named_acl.c b/main/named_acl.c index 8b5aedabb..393532a53 100644 --- a/main/named_acl.c +++ b/main/named_acl.c @@ -80,8 +80,8 @@ static void *named_acl_find(struct ao2_container *container, const char *cat); static struct aco_type named_acl_type = { .type = ACO_ITEM, /*!< named_acls are items stored in containers, not individual global objects */ .name = "named_acl", - .category_match = ACO_BLACKLIST, - .category = "^general$", /*!< Match everything but "general" */ + .category_match = ACO_BLACKLIST_EXACT, + .category = "general", /*!< Match everything but "general" */ .item_alloc = named_acl_alloc, /*!< A callback to allocate a new named_acl based on category */ .item_find = named_acl_find, /*!< A callback to find a named_acl in some container of named_acls */ .item_offset = offsetof(struct named_acl_config, named_acl_list), /*!< Could leave this out since 0 */ diff --git a/main/stasis.c b/main/stasis.c index 186d88fdd..77bf34082 100644 --- a/main/stasis.c +++ b/main/stasis.c @@ -1434,8 +1434,8 @@ static struct aco_type threadpool_option = { .type = ACO_GLOBAL, .name = "threadpool", .item_offset = offsetof(struct stasis_config, threadpool_options), - .category = "^threadpool$", - .category_match = ACO_WHITELIST, + .category = "threadpool", + .category_match = ACO_WHITELIST_EXACT, }; static struct aco_type *threadpool_options[] = ACO_TYPES(&threadpool_option); @@ -1445,8 +1445,8 @@ static struct aco_type declined_option = { .type = ACO_GLOBAL, .name = "declined_message_types", .item_offset = offsetof(struct stasis_config, declined_message_types), - .category_match = ACO_WHITELIST, - .category = "^declined_message_types$", + .category_match = ACO_WHITELIST_EXACT, + .category = "declined_message_types", }; struct aco_type *declined_options[] = ACO_TYPES(&declined_option); diff --git a/main/udptl.c b/main/udptl.c index d982f6bcb..5a491e65c 100644 --- a/main/udptl.c +++ b/main/udptl.c @@ -237,9 +237,9 @@ static int udptl_pre_apply_config(void); static struct aco_type general_option = { .type = ACO_GLOBAL, .name = "global", - .category_match = ACO_WHITELIST, + .category_match = ACO_WHITELIST_EXACT, .item_offset = offsetof(struct udptl_config, general), - .category = "^general$", + .category = "general", }; static struct aco_type *general_options[] = ACO_TYPES(&general_option); diff --git a/res/ari/config.c b/res/ari/config.c index a080bb713..46d23c61d 100644 --- a/res/ari/config.c +++ b/res/ari/config.c @@ -39,8 +39,8 @@ static struct aco_type general_option = { .type = ACO_GLOBAL, .name = "general", .item_offset = offsetof(struct ast_ari_conf, general), - .category = "^general$", - .category_match = ACO_WHITELIST, + .category = "general", + .category_match = ACO_WHITELIST_EXACT, }; static struct aco_type *general_options[] = ACO_TYPES(&general_option); @@ -156,8 +156,8 @@ static void *user_find(struct ao2_container *tmp_container, const char *cat) static struct aco_type user_option = { .type = ACO_ITEM, .name = "user", - .category_match = ACO_BLACKLIST, - .category = "^general$", + .category_match = ACO_BLACKLIST_EXACT, + .category = "general", .matchfield = "type", .matchvalue = "user", .item_alloc = user_alloc, diff --git a/res/res_hep.c b/res/res_hep.c index 25b4d13b1..48e7bbcbe 100644 --- a/res/res_hep.c +++ b/res/res_hep.c @@ -258,8 +258,8 @@ static struct aco_type global_option = { .type = ACO_GLOBAL, .name = "general", .item_offset = offsetof(struct module_config, general), - .category_match = ACO_WHITELIST, - .category = "^general$", + .category_match = ACO_WHITELIST_EXACT, + .category = "general", }; struct aco_type *global_options[] = ACO_TYPES(&global_option); diff --git a/res/res_parking.c b/res/res_parking.c index d511ab581..20827189d 100644 --- a/res/res_parking.c +++ b/res/res_parking.c @@ -289,8 +289,8 @@ static struct aco_type global_option = { .type = ACO_GLOBAL, .name = "globals", .item_offset = offsetof(struct parking_config, global), - .category_match = ACO_WHITELIST, - .category = "^general$", + .category_match = ACO_WHITELIST_EXACT, + .category = "general", }; struct aco_type *global_options[] = ACO_TYPES(&global_option); @@ -298,8 +298,8 @@ struct aco_type *global_options[] = ACO_TYPES(&global_option); static struct aco_type parking_lot_type = { .type = ACO_ITEM, .name = "parking_lot", - .category_match = ACO_BLACKLIST, - .category = "^(general)$", + .category_match = ACO_BLACKLIST_EXACT, + .category = "general", .item_alloc = parking_lot_cfg_alloc, .item_find = named_item_find, .item_offset = offsetof(struct parking_config, parking_lots), diff --git a/res/res_pjsip_notify.c b/res/res_pjsip_notify.c index 8de88c7e8..59b7c6ea4 100644 --- a/res/res_pjsip_notify.c +++ b/res/res_pjsip_notify.c @@ -82,7 +82,7 @@ order; any other header is treated as part of the SIP request. - + A key/value pair to add to a NOTIFY request. If the key is Content, @@ -234,8 +234,8 @@ static void *notify_cfg_alloc(void) static struct aco_type notify_option = { .type = ACO_ITEM, .name = "notify", - .category_match = ACO_BLACKLIST, - .category = "^general$", + .category_match = ACO_BLACKLIST_EXACT, + .category = "general", .item_offset = offsetof(struct notify_cfg, notify_options), .item_alloc = notify_option_alloc, .item_find = notify_option_find @@ -993,7 +993,7 @@ static int load_module(void) return AST_MODULE_LOAD_DECLINE; } - aco_option_register_custom(¬ify_cfg, "^.*$", ACO_REGEX, notify_options, + aco_option_register_custom(¬ify_cfg, "", ACO_PREFIX, notify_options, "", notify_option_handler, 0); if (aco_process_config(¬ify_cfg, 0)) { diff --git a/res/res_resolver_unbound.c b/res/res_resolver_unbound.c index 3c7805010..25f61509a 100644 --- a/res/res_resolver_unbound.c +++ b/res/res_resolver_unbound.c @@ -142,8 +142,8 @@ static struct aco_type global_option = { .type = ACO_GLOBAL, .name = "general", .item_offset = offsetof(struct unbound_config, global), - .category_match = ACO_WHITELIST, - .category = "^general$", + .category_match = ACO_WHITELIST_EXACT, + .category = "general", }; static struct aco_type *global_options[] = ACO_TYPES(&global_option); diff --git a/res/res_statsd.c b/res/res_statsd.c index aee0bcd5a..221b359c9 100644 --- a/res/res_statsd.c +++ b/res/res_statsd.c @@ -231,8 +231,8 @@ static struct aco_type global_option = { .type = ACO_GLOBAL, .name = "global", .item_offset = offsetof(struct conf, global), - .category = "^general$", - .category_match = ACO_WHITELIST + .category = "general", + .category_match = ACO_WHITELIST_EXACT, }; static struct aco_type *global_options[] = ACO_TYPES(&global_option); diff --git a/res/res_xmpp.c b/res/res_xmpp.c index f683557a5..b72581fa5 100644 --- a/res/res_xmpp.c +++ b/res/res_xmpp.c @@ -820,8 +820,8 @@ static struct aco_type global_option = { .type = ACO_GLOBAL, .name = "global", .item_offset = offsetof(struct xmpp_config, global), - .category_match = ACO_WHITELIST, - .category = "^general$", + .category_match = ACO_WHITELIST_EXACT, + .category = "general", }; struct aco_type *global_options[] = ACO_TYPES(&global_option); @@ -829,8 +829,8 @@ struct aco_type *global_options[] = ACO_TYPES(&global_option); static struct aco_type client_option = { .type = ACO_ITEM, .name = "client", - .category_match = ACO_BLACKLIST, - .category = "^(general)$", + .category_match = ACO_BLACKLIST_EXACT, + .category = "general", .item_alloc = ast_xmpp_client_config_alloc, .item_find = xmpp_config_find, .item_prelink = xmpp_config_prelink, diff --git a/tests/test_config.c b/tests/test_config.c index d74726a1a..de85f23b0 100644 --- a/tests/test_config.c +++ b/tests/test_config.c @@ -1456,13 +1456,19 @@ static struct aco_type global = { static struct aco_type global_defaults = { .type = ACO_GLOBAL, .item_offset = offsetof(struct test_config, global_defaults), - .category_match = ACO_WHITELIST, - .category = "^global_defaults$", + .category_match = ACO_WHITELIST_EXACT, + .category = "global_defaults", +}; +static const char *item_blacklist[] = { + "global", + "global_defaults", + NULL, }; + static struct aco_type item = { .type = ACO_ITEM, - .category_match = ACO_BLACKLIST, - .category = "^(global|global_defaults)$", + .category_match = ACO_BLACKLIST_ARRAY, + .category = (const char *)item_blacklist, .item_alloc = test_item_alloc, .item_find = test_item_find, .item_offset = offsetof(struct test_config, items), -- cgit v1.2.3