<p>Corey Farrell has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/7772">View Change</a></p><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;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/72/7772/1</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..cf34fa4 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) \<br>+static int stype ## fn_suffix(void *obj, 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)<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)<br> <br> #endif /* _ASTERISK_ASTOBJ2_H */<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/7772">change 7772</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/7772"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I11af8c6a0c43380a42732553f519c667abb842cf </div>
<div style="display:none"> Gerrit-Change-Number: 7772 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Corey Farrell <git@cfware.com> </div>