summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2017-12-18 14:41:55 -0600
committerGerrit Code Review <gerrit2@gerrit.digium.api>2017-12-18 14:41:55 -0600
commitbac31e55bb85ace72cf27155e84e569f6d7f6ada (patch)
tree08ce0b22b12fd558f535c1dd4ab604ba7b5563b7 /main
parenta853b3bcffb3eaa771cf6f52e6e2e8893a2c657e (diff)
parent957709e1e824e221254599e4ad8445e3839ce535 (diff)
Merge changes from topic 'faster-aco' into 15
* changes: aco: Minimize use of regex. aco: Create ways to minimize use of regex.
Diffstat (limited to 'main')
-rw-r--r--main/cdr.c28
-rw-r--r--main/cel.c21
-rw-r--r--main/config_options.c87
-rw-r--r--main/features_config.c22
-rw-r--r--main/named_acl.c4
-rw-r--r--main/stasis.c8
-rw-r--r--main/udptl.c4
7 files changed, 139 insertions, 35 deletions
diff --git a/main/cdr.c b/main/cdr.c
index 0e0366836..0f6a66517 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/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);
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 <replaceable>DYNAMIC_FEATURES</replaceable> is a <literal>#</literal> separated list of
either applicationmap item names or featuregroup names.</para>
</description>
- <configOption name="^.*$" regex="true">
+ <configOption name="">
<synopsis>A custom feature to invoke during a bridged call</synopsis>
<description>
<para>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.</para>
</description>
- <configOption name="^.*$" regex="true">
+ <configOption name="">
<synopsis>Applicationmap item to place in the feature group</synopsis>
<description>
<para>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);