<p>Jenkins2 <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/7773">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Richard Mudgett: 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;">astobj2: Create case-insensitive variants of container function macros.<br><br>* AO2_STRING_FIELD_CASE_HASH_FN<br>* AO2_STRING_FIELD_CASE_CMP_FN<br>* AO2_STRING_FIELD_CASE_SORT_FN<br><br>Change-Id: I11af8c6a0c43380a42732553f519c667abb842cf<br>---<br>M include/asterisk/astobj2.h<br>1 file changed, 66 insertions(+), 38 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/include/asterisk/astobj2.h b/include/asterisk/astobj2.h<br>index 1b7f387..0e442db 100644<br>--- a/include/asterisk/astobj2.h<br>+++ b/include/asterisk/astobj2.h<br>@@ -1985,14 +1985,16 @@<br> int ao2_iterator_count(struct ao2_iterator *iter);<br> <br> /*!<br>- * \brief Creates a hash function for a structure string field.<br>+ * \brief Creates a hash function for a structure field.<br>  * \param stype The structure type<br>  * \param field The string field in the structure to hash<br>+ * \param hash_fn Function which hashes the field<br>  *<br>- * AO2_STRING_FIELD_HASH_CB(mystruct, myfield) will produce a function<br>- * named mystruct_hash_fn which hashes mystruct->myfield.<br>+ * AO2_FIELD_HASH_FN(mystruct, myfield, ast_str_hash) will<br>+ * produce a function named mystruct_hash_fn which hashes<br>+ * mystruct->myfield with ast_str_hash.<br>  */<br>-#define AO2_STRING_FIELD_HASH_FN(stype, field) \<br>+#define AO2_FIELD_HASH_FN(stype, field, hash_fn) \<br> static int stype ## _hash_fn(const void *obj, const int flags) \<br> { \<br>   const struct stype *object = obj; \<br>@@ -2008,19 +2010,33 @@<br>          ast_assert(0); \<br>              return 0; \<br>   } \<br>-  return ast_str_hash(key); \<br>+  return hash_fn(key); \<br> }<br> <br>+<br>+#define AO2_FIELD_TRANSFORM_CMP_FN(cmp) ((cmp) ? 0 : CMP_MATCH)<br>+#define AO2_FIELD_TRANSFORM_SORT_FN(cmp) (cmp)<br>+<br> /*!<br>+ * \internal<br>+ *<br>  * \brief Creates a compare function for a structure string field.<br>  * \param stype The structure type<br>+ * \param fn_suffix Function name suffix<br>  * \param field The string field in the structure to compare<br>+ * \param key_cmp Key comparison function like strcmp<br>+ * \param partial_key_cmp Partial key comparison function like strncmp<br>+ * \param transform A macro that takes the cmp result as an argument<br>+ *                  and transforms it to a return value.<br>  *<br>- * AO2_STRING_FIELD_CMP_FN(mystruct, myfield) will produce a function<br>- * named mystruct_cmp_fn which compares mystruct->myfield.<br>+ * Do not use this macro directly, instead use macro's starting with<br>+ * AST_STRING_FIELD.<br>+ *<br>+ * \warning The macro is an internal implementation detail, the API<br>+ *          may change at any time.<br>  */<br>-#define AO2_STRING_FIELD_CMP_FN(stype, field) \<br>-static int stype ## _cmp_fn(void *obj, void *arg, int flags) \<br>+#define AO2_FIELD_CMP_FN(stype, fn_suffix, field, key_cmp, partial_key_cmp, transform, argconst) \<br>+static int stype ## fn_suffix(argconst void *obj, argconst void *arg, int flags) \<br> { \<br>      const struct stype *object_left = obj, *object_right = arg; \<br>         const char *right_key = arg; \<br>@@ -2029,20 +2045,49 @@<br>       case OBJ_SEARCH_OBJECT: \<br>             right_key = object_right->field; \<br>         case OBJ_SEARCH_KEY: \<br>-               cmp = strcmp(object_left->field, right_key); \<br>+            cmp = key_cmp(object_left->field, right_key); \<br>            break; \<br>      case OBJ_SEARCH_PARTIAL_KEY: \<br>-               cmp = strncmp(object_left->field, right_key, strlen(right_key)); \<br>+                cmp = partial_key_cmp(object_left->field, right_key, strlen(right_key)); \<br>                 break; \<br>      default: \<br>            cmp = 0; \<br>            break; \<br>      } \<br>-  if (cmp) { \<br>-         return 0; \<br>-  } \<br>-  return CMP_MATCH; \<br>+  return transform(cmp); \<br> }<br>+<br>+/*!<br>+ * \brief Creates a hash function for a structure string field.<br>+ * \param stype The structure type<br>+ * \param field The string field in the structure to hash<br>+ *<br>+ * AO2_STRING_FIELD_HASH_FN(mystruct, myfield) will produce a function<br>+ * named mystruct_hash_fn which hashes mystruct->myfield.<br>+ *<br>+ * AO2_STRING_FIELD_HASH_FN(mystruct, myfield) would do the same except<br>+ * it uses the hash function which ignores case.<br>+ */<br>+#define AO2_STRING_FIELD_HASH_FN(stype, field) \<br>+     AO2_FIELD_HASH_FN(stype, field, ast_str_hash)<br>+#define AO2_STRING_FIELD_CASE_HASH_FN(stype, field) \<br>+        AO2_FIELD_HASH_FN(stype, field, ast_str_case_hash)<br>+<br>+/*!<br>+ * \brief Creates a compare function for a structure string field.<br>+ * \param stype The structure type<br>+ * \param field The string field in the structure to compare<br>+ *<br>+ * AO2_STRING_FIELD_CMP_FN(mystruct, myfield) will produce a function<br>+ * named mystruct_cmp_fn which compares mystruct->myfield.<br>+ *<br>+ * AO2_STRING_FIELD_CASE_CMP_FN(mystruct, myfield) would do the same<br>+ * except it performs case insensitive comparisons.<br>+ */<br>+#define AO2_STRING_FIELD_CMP_FN(stype, field) \<br>+  AO2_FIELD_CMP_FN(stype, _cmp_fn, field, strcmp, strncmp, AO2_FIELD_TRANSFORM_CMP_FN,)<br>+#define AO2_STRING_FIELD_CASE_CMP_FN(stype, field) \<br>+ AO2_FIELD_CMP_FN(stype, _cmp_fn, field, strcasecmp, strncasecmp, AO2_FIELD_TRANSFORM_CMP_FN,)<br> <br> /*!<br>  * \brief Creates a sort function for a structure string field.<br>@@ -2051,30 +2096,13 @@<br>  *<br>  * AO2_STRING_FIELD_SORT_FN(mystruct, myfield) will produce a function<br>  * named mystruct_sort_fn which compares mystruct->myfield.<br>+ *<br>+ * AO2_STRING_FIELD_CASE_SORT_FN(mystruct, myfield) would do the same<br>+ * except it performs case insensitive comparisons.<br>  */<br> #define AO2_STRING_FIELD_SORT_FN(stype, field) \<br>-static int stype ## _sort_fn(const void *obj, const void *arg, int flags) \<br>-{ \<br>-     const struct stype *object_left = obj; \<br>-     const struct stype *object_right = arg; \<br>-    const char *right_key = arg; \<br>-       int cmp; \<br>-\<br>-       switch (flags & OBJ_SEARCH_MASK) { \<br>-     case OBJ_SEARCH_OBJECT: \<br>-            right_key = object_right->field; \<br>-                /* Fall through */ \<br>- case OBJ_SEARCH_KEY: \<br>-               cmp = strcmp(object_left->field, right_key); \<br>-            break; \<br>-     case OBJ_SEARCH_PARTIAL_KEY: \<br>-               cmp = strncmp(object_left->field, right_key, strlen(right_key)); \<br>-                break; \<br>-     default: \<br>-           cmp = 0; \<br>-           break; \<br>-     } \<br>-  return cmp; \<br>-}<br>+    AO2_FIELD_CMP_FN(stype, _sort_fn, field, strcmp, strncmp, AO2_FIELD_TRANSFORM_SORT_FN, const)<br>+#define AO2_STRING_FIELD_CASE_SORT_FN(stype, field) \<br>+        AO2_FIELD_CMP_FN(stype, _sort_fn, field, strcasecmp, strncasecmp, AO2_FIELD_TRANSFORM_SORT_FN, const)<br> <br> #endif /* _ASTERISK_ASTOBJ2_H */<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/7773">change 7773</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/7773"/><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: I11af8c6a0c43380a42732553f519c667abb842cf </div>
<div style="display:none"> Gerrit-Change-Number: 7773 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Corey Farrell <git@cfware.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Richard Mudgett <rmudgett@digium.com> </div>