<p>Joshua Colp <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/7565">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  George Joseph: Looks good to me, but someone else must approve
  Joshua Colp: Looks good to me, approved
  Jenkins2: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">aco: Minimize use of regex.<br><br>Remove nearly all use of regex from ACO users.  Still remaining:<br>* app_confbridge has a legitamate use of option name regex.<br>* ast_sorcery_object_fields_register is implemented with regex, all<br>  callers use simple prefix based regex.  I haven't decided the best<br>  way to fix this in both 13/15 and master.<br><br>Change-Id: Ib5ed478218d8a661ace4d2eaaea98b59a897974b<br>---<br>M apps/app_agent_pool.c<br>M apps/app_skel.c<br>M apps/confbridge/conf_config_parser.c<br>M channels/chan_motif.c<br>M main/cdr.c<br>M main/cel.c<br>M main/features_config.c<br>M main/named_acl.c<br>M main/stasis.c<br>M main/udptl.c<br>M res/ari/config.c<br>M res/res_hep.c<br>M res/res_parking.c<br>M res/res_pjsip_notify.c<br>M res/res_resolver_unbound.c<br>M res/res_statsd.c<br>M res/res_xmpp.c<br>M tests/test_config.c<br>18 files changed, 126 insertions(+), 75 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/apps/app_agent_pool.c b/apps/app_agent_pool.c<br>index 6a8c395..3c2ea38 100644<br>--- a/apps/app_agent_pool.c<br>+++ b/apps/app_agent_pool.c<br>@@ -455,11 +455,17 @@<br>  struct ao2_container *agents;<br> };<br> <br>+static const char *agent_type_blacklist[] = {<br>+        "general",<br>+ "agents",<br>+  NULL,<br>+};<br>+<br> static struct aco_type agent_type = {<br>         .type = ACO_ITEM,<br>     .name = "agent-id",<br>-        .category_match = ACO_BLACKLIST,<br>-     .category = "^(general|agents)$",<br>+  .category_match = ACO_BLACKLIST_ARRAY,<br>+       .category = (const char *)agent_type_blacklist,<br>       .item_alloc = agent_cfg_alloc,<br>        .item_find = agent_cfg_find,<br>  .item_offset = offsetof(struct agents_cfg, agents),<br>@@ -471,8 +477,8 @@<br> static struct aco_type general_type = {<br>    .type = ACO_GLOBAL,<br>   .name = "global",<br>-  .category_match = ACO_WHITELIST,<br>-     .category = "^general$",<br>+   .category_match = ACO_WHITELIST_EXACT,<br>+       .category = "general",<br> };<br> <br> static struct aco_file agents_conf = {<br>diff --git a/apps/app_skel.c b/apps/app_skel.c<br>index b3c8876..68f313f 100644<br>--- a/apps/app_skel.c<br>+++ b/apps/app_skel.c<br>@@ -242,8 +242,8 @@<br>   .type = ACO_GLOBAL,<br>   .name = "globals",<br>  .item_offset = offsetof(struct skel_config, global),<br>- .category_match = ACO_WHITELIST,<br>-     .category = "^general$",<br>+   .category_match = ACO_WHITELIST_EXACT,<br>+       .category = "general",<br> };<br> <br> struct aco_type *global_options[] = ACO_TYPES(&global_option);<br>@@ -253,18 +253,24 @@<br>  .type = ACO_GLOBAL,<br>   .name = "sounds",<br>   .item_offset = offsetof(struct skel_config, global),<br>- .category_match = ACO_WHITELIST,<br>-     .category = "^sounds$",<br>+    .category_match = ACO_WHITELIST_EXACT,<br>+       .category = "sounds",<br> };<br> <br> struct aco_type *sound_options[] = ACO_TYPES(&sound_option);<br>+<br>+static const char *level_categories[] = {<br>+    "general",<br>+ "sounds",<br>+  NULL,<br>+};<br> <br> /*! \brief An aco_type structure to link the everything but the "general" and "sounds" categories to the skel_level type */<br> static struct aco_type level_option = {<br>     .type = ACO_ITEM,<br>     .name = "level",<br>-   .category_match = ACO_BLACKLIST,<br>-     .category = "^(general|sounds)$",<br>+  .category_match = ACO_BLACKLIST_ARRAY,<br>+       .category = (const char *)level_categories,<br>   .item_alloc = skel_level_alloc,<br>       .item_find = skel_level_find,<br>         .item_offset = offsetof(struct skel_config, levels),<br>diff --git a/apps/confbridge/conf_config_parser.c b/apps/confbridge/conf_config_parser.c<br>index 6659305..99eea0a 100644<br>--- a/apps/confbridge/conf_config_parser.c<br>+++ b/apps/confbridge/conf_config_parser.c<br>@@ -409,7 +409,7 @@<br>                                            regardless if this limit is reached or not.<br>                                   </para></description><br>                             </configOption><br>-                                <configOption name="^sound_"><br>+                                <configOption name="sound_"><br>                                  <synopsis>Override the various conference bridge sound files</synopsis><br>                                   <description><para><br>                                               All sounds in the conference are customizable using the bridge profile options below.<br>@@ -639,8 +639,8 @@<br> static struct aco_type bridge_type = {<br>   .type = ACO_ITEM,<br>     .name = "bridge_profile",<br>-  .category_match = ACO_BLACKLIST,<br>-     .category = "^general$",<br>+   .category_match = ACO_BLACKLIST_EXACT,<br>+       .category = "general",<br>      .matchfield = "type",<br>       .matchvalue = "bridge",<br>     .item_alloc = bridge_profile_alloc,<br>@@ -676,8 +676,8 @@<br> static struct aco_type user_type = {<br>       .type = ACO_ITEM,<br>     .name  = "user_profile",<br>-   .category_match = ACO_BLACKLIST,<br>-     .category = "^general$",<br>+   .category_match = ACO_BLACKLIST_EXACT,<br>+       .category = "general",<br>      .matchfield = "type",<br>       .matchvalue = "user",<br>       .item_alloc = user_profile_alloc,<br>@@ -707,8 +707,8 @@<br> static struct aco_type menu_type = {<br>         .type = ACO_ITEM,<br>     .name = "menu",<br>-    .category_match = ACO_BLACKLIST,<br>-     .category = "^general$",<br>+   .category_match = ACO_BLACKLIST_EXACT,<br>+       .category = "general",<br>      .matchfield = "type",<br>       .matchvalue = "menu",<br>       .item_alloc = menu_alloc,<br>@@ -725,8 +725,8 @@<br> static struct aco_type general_type = {<br>      .type = ACO_GLOBAL,<br>   .name = "global",<br>-  .category_match = ACO_WHITELIST,<br>-     .category = "^general$",<br>+   .category_match = ACO_WHITELIST_EXACT,<br>+       .category = "general",<br> };<br> <br> static struct aco_file confbridge_conf = {<br>@@ -2235,7 +2235,7 @@<br>  aco_option_register(&cfg_info, "record_command", ACO_EXACT, bridge_types, NULL, OPT_CHAR_ARRAY_T, 0, CHARFLDSET(struct bridge_profile, rec_command));<br>   aco_option_register(&cfg_info, "regcontext", ACO_EXACT, bridge_types, NULL, OPT_CHAR_ARRAY_T, 0, CHARFLDSET(struct bridge_profile, regcontext));<br>        aco_option_register(&cfg_info, "language", ACO_EXACT, bridge_types, "en", OPT_CHAR_ARRAY_T, 0, CHARFLDSET(struct bridge_profile, language));<br>- aco_option_register_custom(&cfg_info, "^sound_", ACO_REGEX, bridge_types, NULL, sound_option_handler, 0);<br>+      aco_option_register_custom(&cfg_info, "sound_", ACO_PREFIX, bridge_types, NULL, sound_option_handler, 0);<br>       aco_option_register(&cfg_info, "video_update_discard", ACO_EXACT, bridge_types, "2000", OPT_UINT_T, 0, FLDSET(struct bridge_profile, video_update_discard));<br>  /* This option should only be used with the CONFBRIDGE dialplan function */<br>   aco_option_register_custom(&cfg_info, "template", ACO_EXACT, bridge_types, NULL, bridge_template_handler, 0);<br>diff --git a/channels/chan_motif.c b/channels/chan_motif.c<br>index 210cf36..6e8ce35 100644<br>--- a/channels/chan_motif.c<br>+++ b/channels/chan_motif.c<br>@@ -541,8 +541,8 @@<br> static struct aco_type endpoint_option = {<br>    .type = ACO_ITEM,<br>     .name = "endpoint",<br>-        .category_match = ACO_BLACKLIST,<br>-     .category = "^general$",<br>+   .category_match = ACO_BLACKLIST_EXACT,<br>+       .category = "general",<br>      .item_alloc = jingle_endpoint_alloc,<br>  .item_find = jingle_endpoint_find,<br>    .item_offset = offsetof(struct jingle_config, endpoints),<br>diff --git a/main/cdr.c b/main/cdr.c<br>index 3681cdc..d7384f2 100644<br>--- a/main/cdr.c<br>+++ b/main/cdr.c<br>@@ -238,8 +238,29 @@<br>      .type = ACO_GLOBAL,<br>   .name = "general",<br>  .item_offset = offsetof(struct module_config, general),<br>-      .category = "^general$",<br>-   .category_match = ACO_WHITELIST,<br>+     .category = "general",<br>+     .category_match = ACO_WHITELIST_EXACT,<br>+};<br>+<br>+/*! Config sections used by existing modules. Do not add to this list. */<br>+static const char *ignore_categories[] = {<br>+      "csv",<br>+     "custom",<br>+  "manager",<br>+ "odbc",<br>+    "pgsql",<br>+   "radius",<br>+  "sqlite",<br>+  "tds",<br>+     "mysql",<br>+   NULL,<br>+};<br>+<br>+static struct aco_type ignore_option = {<br>+     .type = ACO_IGNORE,<br>+  .name = "modules",<br>+ .category = (const char*)ignore_categories,<br>+  .category_match = ACO_WHITELIST_ARRAY,<br> };<br> <br> static void *module_config_alloc(void);<br>@@ -249,8 +270,7 @@<br> /*! \brief The file definition */<br> static struct aco_file module_file_conf = {<br>       .filename = "cdr.conf",<br>-    .skip_category = "(^csv$|^custom$|^manager$|^odbc$|^pgsql$|^radius$|^sqlite$|^tds$|^mysql$)",<br>-      .types = ACO_TYPES(&general_option),<br>+     .types = ACO_TYPES(&general_option, &ignore_option),<br> };<br> <br> CONFIG_INFO_CORE("cdr", cfg_info, module_configs, module_config_alloc,<br>diff --git a/main/cel.c b/main/cel.c<br>index faf4fde..cec0a85 100644<br>--- a/main/cel.c<br>+++ b/main/cel.c<br>@@ -242,15 +242,28 @@<br>       .type = ACO_GLOBAL,<br>   .name = "general",<br>  .item_offset = offsetof(struct cel_config, general),<br>- .category_match = ACO_WHITELIST,<br>-     .category = "^general$",<br>+   .category_match = ACO_WHITELIST_EXACT,<br>+       .category = "general",<br>+};<br>+<br>+/*! Config sections used by existing modules. Do not add to this list. */<br>+static const char *ignore_categories[] = {<br>+    "manager",<br>+ "radius",<br>+  NULL,<br>+};<br>+<br>+static struct aco_type ignore_option = {<br>+     .type = ACO_IGNORE,<br>+  .name = "modules",<br>+ .category = (const char*)ignore_categories,<br>+  .category_match = ACO_WHITELIST_ARRAY,<br> };<br> <br> /*! \brief The config file to be processed for the module. */<br> static struct aco_file cel_conf = {<br>  .filename = "cel.conf",                  /*!< The name of the config file */<br>-    .types = ACO_TYPES(&general_option),     /*!< The mapping object types to be processed */<br>-     .skip_category = "(^manager$|^radius$)", /*!< Config sections used by existing modules. Do not add to this list. */<br>+     .types = ACO_TYPES(&general_option, &ignore_option),     /*!< The mapping object types to be processed */<br> };<br> <br> static int cel_pre_apply_config(void);<br>diff --git a/main/features_config.c b/main/features_config.c<br>index 72cd040..a773f49 100644<br>--- a/main/features_config.c<br>+++ b/main/features_config.c<br>@@ -219,7 +219,7 @@<br>                                   The <replaceable>DYNAMIC_FEATURES</replaceable> is a <literal>#</literal> separated list of<br>                                   either applicationmap item names or featuregroup names.</para><br>                          </description><br>-                         <configOption name="^.*$" regex="true"><br>+                            <configOption name=""><br>                                        <synopsis>A custom feature to invoke during a bridged call</synopsis><br>                                     <description><br>                                           <para>Each item listed here is a comma-separated list of parameters that determine<br>@@ -272,7 +272,7 @@<br>                                         DTMF sequence used to invoke an applicationmap item to be overridden with<br>                                     a different sequence.</para><br>                            </description><br>-                         <configOption name="^.*$" regex="true"><br>+                            <configOption name=""><br>                                        <synopsis>Applicationmap item to place in the feature group</synopsis><br>                                    <description><br>                                           <para>Each item here must be a name of an item in the applicationmap. The<br>@@ -578,24 +578,24 @@<br> static struct aco_type global_option = {<br>     .type = ACO_GLOBAL,<br>   .name = "globals",<br>- .category_match = ACO_WHITELIST,<br>-     .category = "^general$",<br>+   .category_match = ACO_WHITELIST_EXACT,<br>+       .category = "general",<br>      .item_offset = offsetof(struct features_config, global),<br> };<br> <br> static struct aco_type featuremap_option = {<br>       .type = ACO_GLOBAL,<br>   .name = "featuremap",<br>-      .category_match = ACO_WHITELIST,<br>-     .category = "^featuremap$",<br>+        .category_match = ACO_WHITELIST_EXACT,<br>+       .category = "featuremap",<br>   .item_offset = offsetof(struct features_config, featuremap),<br> };<br> <br> static struct aco_type applicationmap_option = {<br>       .type = ACO_GLOBAL,<br>   .name = "applicationmap",<br>-  .category_match = ACO_WHITELIST,<br>-     .category = "^applicationmap$",<br>+    .category_match = ACO_WHITELIST_EXACT,<br>+       .category = "applicationmap",<br>       .item_offset = offsetof(struct features_config, applicationmap),<br> };<br> <br>@@ -1851,13 +1851,13 @@<br>     aco_option_register_custom(&cfg_info, "automixmon", ACO_EXACT, featuremap_options,<br>                      DEFAULT_FEATUREMAP_AUTOMIXMON, featuremap_handler, 0);<br> <br>-    aco_option_register_custom(&cfg_info, "^.*$", ACO_REGEX, applicationmap_options,<br>+       aco_option_register_custom(&cfg_info, "", ACO_PREFIX, applicationmap_options,<br>                   "", applicationmap_handler, 0);<br> <br>- aco_option_register_custom(&cfg_info, "^.*$", ACO_REGEX, featuregroup_options,<br>+ aco_option_register_custom(&cfg_info, "", ACO_PREFIX, featuregroup_options,<br>                     "", featuregroup_handler, 0);<br> <br>-   aco_option_register_custom_nodoc(&cfg_info, "^.*$", ACO_REGEX, parkinglot_options,<br>+     aco_option_register_custom_nodoc(&cfg_info, "", ACO_PREFIX, parkinglot_options,<br>                         "", unsupported_handler, 0);<br> <br>     if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {<br>diff --git a/main/named_acl.c b/main/named_acl.c<br>index 8b5aeda..393532a 100644<br>--- a/main/named_acl.c<br>+++ b/main/named_acl.c<br>@@ -80,8 +80,8 @@<br> static struct aco_type named_acl_type = {<br>      .type = ACO_ITEM,                  /*!< named_acls are items stored in containers, not individual global objects */<br>        .name = "named_acl",<br>-       .category_match = ACO_BLACKLIST,<br>-     .category = "^general$",           /*!< Match everything but "general" */<br>+     .category_match = ACO_BLACKLIST_EXACT,<br>+       .category = "general",           /*!< Match everything but "general" */<br>        .item_alloc = named_acl_alloc,     /*!< A callback to allocate a new named_acl based on category */<br>        .item_find = named_acl_find,       /*!< A callback to find a named_acl in some container of named_acls */<br>  .item_offset = offsetof(struct named_acl_config, named_acl_list), /*!< Could leave this out since 0 */<br>diff --git a/main/stasis.c b/main/stasis.c<br>index 186d88f..77bf340 100644<br>--- a/main/stasis.c<br>+++ b/main/stasis.c<br>@@ -1434,8 +1434,8 @@<br>         .type = ACO_GLOBAL,<br>   .name = "threadpool",<br>       .item_offset = offsetof(struct stasis_config, threadpool_options),<br>-   .category = "^threadpool$",<br>-        .category_match = ACO_WHITELIST,<br>+     .category = "threadpool",<br>+  .category_match = ACO_WHITELIST_EXACT,<br> };<br> <br> static struct aco_type *threadpool_options[] = ACO_TYPES(&threadpool_option);<br>@@ -1445,8 +1445,8 @@<br>     .type = ACO_GLOBAL,<br>   .name = "declined_message_types",<br>   .item_offset = offsetof(struct stasis_config, declined_message_types),<br>-       .category_match = ACO_WHITELIST,<br>-     .category = "^declined_message_types$",<br>+    .category_match = ACO_WHITELIST_EXACT,<br>+       .category = "declined_message_types",<br> };<br> <br> struct aco_type *declined_options[] = ACO_TYPES(&declined_option);<br>diff --git a/main/udptl.c b/main/udptl.c<br>index d982f6b..5a491e6 100644<br>--- a/main/udptl.c<br>+++ b/main/udptl.c<br>@@ -237,9 +237,9 @@<br> static struct aco_type general_option = {<br>    .type = ACO_GLOBAL,<br>   .name = "global",<br>-  .category_match = ACO_WHITELIST,<br>+     .category_match = ACO_WHITELIST_EXACT,<br>        .item_offset = offsetof(struct udptl_config, general),<br>-       .category = "^general$",<br>+   .category = "general",<br> };<br> <br> static struct aco_type *general_options[] = ACO_TYPES(&general_option);<br>diff --git a/res/ari/config.c b/res/ari/config.c<br>index a080bb7..46d23c6 100644<br>--- a/res/ari/config.c<br>+++ b/res/ari/config.c<br>@@ -39,8 +39,8 @@<br>    .type = ACO_GLOBAL,<br>   .name = "general",<br>  .item_offset = offsetof(struct ast_ari_conf, general),<br>-       .category = "^general$",<br>-   .category_match = ACO_WHITELIST,<br>+     .category = "general",<br>+     .category_match = ACO_WHITELIST_EXACT,<br> };<br> <br> static struct aco_type *general_options[] = ACO_TYPES(&general_option);<br>@@ -156,8 +156,8 @@<br> static struct aco_type user_option = {<br>    .type = ACO_ITEM,<br>     .name = "user",<br>-    .category_match = ACO_BLACKLIST,<br>-     .category = "^general$",<br>+   .category_match = ACO_BLACKLIST_EXACT,<br>+       .category = "general",<br>      .matchfield = "type",<br>       .matchvalue = "user",<br>       .item_alloc = user_alloc,<br>diff --git a/res/res_hep.c b/res/res_hep.c<br>index 25b4d13..48e7bbc 100644<br>--- a/res/res_hep.c<br>+++ b/res/res_hep.c<br>@@ -258,8 +258,8 @@<br>   .type = ACO_GLOBAL,<br>   .name = "general",<br>  .item_offset = offsetof(struct module_config, general),<br>-      .category_match = ACO_WHITELIST,<br>-     .category = "^general$",<br>+   .category_match = ACO_WHITELIST_EXACT,<br>+       .category = "general",<br> };<br> <br> struct aco_type *global_options[] = ACO_TYPES(&global_option);<br>diff --git a/res/res_parking.c b/res/res_parking.c<br>index d511ab5..2082718 100644<br>--- a/res/res_parking.c<br>+++ b/res/res_parking.c<br>@@ -289,8 +289,8 @@<br>       .type = ACO_GLOBAL,<br>   .name = "globals",<br>  .item_offset = offsetof(struct parking_config, global),<br>-      .category_match = ACO_WHITELIST,<br>-     .category = "^general$",<br>+   .category_match = ACO_WHITELIST_EXACT,<br>+       .category = "general",<br> };<br> <br> struct aco_type *global_options[] = ACO_TYPES(&global_option);<br>@@ -298,8 +298,8 @@<br> static struct aco_type parking_lot_type = {<br>      .type = ACO_ITEM,<br>     .name = "parking_lot",<br>-     .category_match = ACO_BLACKLIST,<br>-     .category = "^(general)$",<br>+ .category_match = ACO_BLACKLIST_EXACT,<br>+       .category = "general",<br>      .item_alloc = parking_lot_cfg_alloc,<br>  .item_find = named_item_find,<br>         .item_offset = offsetof(struct parking_config, parking_lots),<br>diff --git a/res/res_pjsip_notify.c b/res/res_pjsip_notify.c<br>index 8de88c7..59b7c6e 100644<br>--- a/res/res_pjsip_notify.c<br>+++ b/res/res_pjsip_notify.c<br>@@ -82,7 +82,7 @@<br>                                     order; any other header is treated as part of the SIP<br>                                         request.</para><br>                                 </description><br>-                         <configOption name="^.*$"><br>+                           <configOption name=""><br>                                        <synopsis>A key/value pair to add to a NOTIFY request.</synopsis><br>                                         <description><br>                                           <para>If the key is <literal>Content</literal>,<br>@@ -234,8 +234,8 @@<br> static struct aco_type notify_option = {<br>     .type = ACO_ITEM,<br>     .name = "notify",<br>-  .category_match = ACO_BLACKLIST,<br>-     .category = "^general$",<br>+   .category_match = ACO_BLACKLIST_EXACT,<br>+       .category = "general",<br>      .item_offset = offsetof(struct notify_cfg, notify_options),<br>   .item_alloc = notify_option_alloc,<br>    .item_find = notify_option_find<br>@@ -993,7 +993,7 @@<br>          return AST_MODULE_LOAD_DECLINE;<br>       }<br> <br>- aco_option_register_custom(&notify_cfg, "^.*$", ACO_REGEX, notify_options,<br>+     aco_option_register_custom(&notify_cfg, "", ACO_PREFIX, notify_options,<br>                                    "", notify_option_handler, 0);<br> <br>        if (aco_process_config(&notify_cfg, 0)) {<br>diff --git a/res/res_resolver_unbound.c b/res/res_resolver_unbound.c<br>index 3c78050..25f6150 100644<br>--- a/res/res_resolver_unbound.c<br>+++ b/res/res_resolver_unbound.c<br>@@ -142,8 +142,8 @@<br>   .type = ACO_GLOBAL,<br>   .name = "general",<br>  .item_offset = offsetof(struct unbound_config, global),<br>-      .category_match = ACO_WHITELIST,<br>-     .category = "^general$",<br>+   .category_match = ACO_WHITELIST_EXACT,<br>+       .category = "general",<br> };<br> <br> static struct aco_type *global_options[] = ACO_TYPES(&global_option);<br>diff --git a/res/res_statsd.c b/res/res_statsd.c<br>index aee0bcd..221b359 100644<br>--- a/res/res_statsd.c<br>+++ b/res/res_statsd.c<br>@@ -231,8 +231,8 @@<br>    .type = ACO_GLOBAL,<br>   .name = "global",<br>   .item_offset = offsetof(struct conf, global),<br>-        .category = "^general$",<br>-   .category_match = ACO_WHITELIST<br>+      .category = "general",<br>+     .category_match = ACO_WHITELIST_EXACT,<br> };<br> <br> static struct aco_type *global_options[] = ACO_TYPES(&global_option);<br>diff --git a/res/res_xmpp.c b/res/res_xmpp.c<br>index f683557..b72581f 100644<br>--- a/res/res_xmpp.c<br>+++ b/res/res_xmpp.c<br>@@ -820,8 +820,8 @@<br>      .type = ACO_GLOBAL,<br>   .name = "global",<br>   .item_offset = offsetof(struct xmpp_config, global),<br>- .category_match = ACO_WHITELIST,<br>-     .category = "^general$",<br>+   .category_match = ACO_WHITELIST_EXACT,<br>+       .category = "general",<br> };<br> <br> struct aco_type *global_options[] = ACO_TYPES(&global_option);<br>@@ -829,8 +829,8 @@<br> static struct aco_type client_option = {<br>         .type = ACO_ITEM,<br>     .name = "client",<br>-  .category_match = ACO_BLACKLIST,<br>-     .category = "^(general)$",<br>+ .category_match = ACO_BLACKLIST_EXACT,<br>+       .category = "general",<br>      .item_alloc = ast_xmpp_client_config_alloc,<br>   .item_find = xmpp_config_find,<br>        .item_prelink = xmpp_config_prelink,<br>diff --git a/tests/test_config.c b/tests/test_config.c<br>index d74726a..de85f23 100644<br>--- a/tests/test_config.c<br>+++ b/tests/test_config.c<br>@@ -1456,13 +1456,19 @@<br> static struct aco_type global_defaults = {<br>       .type = ACO_GLOBAL,<br>   .item_offset = offsetof(struct test_config, global_defaults),<br>-        .category_match = ACO_WHITELIST,<br>-     .category = "^global_defaults$",<br>+   .category_match = ACO_WHITELIST_EXACT,<br>+       .category = "global_defaults",<br> };<br>+static const char *item_blacklist[] = {<br>+      "global",<br>+  "global_defaults",<br>+ NULL,<br>+};<br>+<br> static struct aco_type item = {<br>       .type = ACO_ITEM,<br>-    .category_match = ACO_BLACKLIST,<br>-     .category = "^(global|global_defaults)$",<br>+  .category_match = ACO_BLACKLIST_ARRAY,<br>+       .category = (const char *)item_blacklist,<br>     .item_alloc = test_item_alloc,<br>        .item_find = test_item_find,<br>  .item_offset = offsetof(struct test_config, items),<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/7565">change 7565</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/7565"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 15 </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Ib5ed478218d8a661ace4d2eaaea98b59a897974b </div>
<div style="display:none"> Gerrit-Change-Number: 7565 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: Corey Farrell <git@cfware.com> </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>