[PATCH 1/3] string: add match_string_nocase() for case-insensitive match

From: Soha Jin
Date: Sun Oct 09 2022 - 12:22:45 EST


Sometimes we want to make a case-insensitive comparison with strings, like
checking compatible devices in fwnode properties, so this commit abstracts
match_string to __match_string with a compare function. The original
match_string will call __match_string with strcmp, and the new
match_string_nocase will call it with strcasecmp.

Signed-off-by: Soha Jin <soha@xxxxxxxxx>
---
include/linux/string.h | 31 ++++++++++++++++++++++++++++++-
lib/string_helpers.c | 10 ++++++----
2 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/include/linux/string.h b/include/linux/string.h
index cf7607b32102..fcfa67f598f5 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -183,9 +183,38 @@ extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
extern void argv_free(char **argv);

extern bool sysfs_streq(const char *s1, const char *s2);
-int match_string(const char * const *array, size_t n, const char *string);
+int __match_string(const char * const *array, size_t n, const char *string,
+ int (*cmp)(const char *, const char *));
int __sysfs_match_string(const char * const *array, size_t n, const char *s);

+/**
+ * match_string - matches given string in an array
+ * @_a: array of strings
+ * @_n: number of strings in the array
+ * @_s: string to match with
+ *
+ * Helper for __match_string(). Look for a string in an array of strings up to
+ * the n-th element in the array with a case-sensitive compare.
+ *
+ * Return:
+ * index of a @string in the @array if matches, or %-EINVAL otherwise.
+ */
+#define match_string(_a, _n, _s) __match_string(_a, _n, _s, strcmp)
+
+/**
+ * match_string_nocase - matches given string in an array
+ * @_a: array of strings
+ * @_n: number of strings in the array
+ * @_s: string to match with
+ *
+ * Helper for __match_string(). Look for a string in an array of strings up to
+ * the n-th element in the array with a case-insensitive compare.
+ *
+ * Return:
+ * index of a @string in the @array if matches, or %-EINVAL otherwise.
+ */
+#define match_string_nocase(_a, _n, _s) __match_string(_a, _n, _s, strcasecmp)
+
/**
* sysfs_match_string - matches given string in an array
* @_a: array of strings
diff --git a/lib/string_helpers.c b/lib/string_helpers.c
index 230020a2e076..52949adfdfe4 100644
--- a/lib/string_helpers.c
+++ b/lib/string_helpers.c
@@ -910,10 +910,11 @@ bool sysfs_streq(const char *s1, const char *s2)
EXPORT_SYMBOL(sysfs_streq);

/**
- * match_string - matches given string in an array
+ * __match_string - matches given string in an array
* @array: array of strings
* @n: number of strings in the array or -1 for NULL terminated arrays
* @string: string to match with
+ * @cmp: compare function
*
* This routine will look for a string in an array of strings up to the
* n-th element in the array or until the first NULL element.
@@ -926,7 +927,8 @@ EXPORT_SYMBOL(sysfs_streq);
* Return:
* index of a @string in the @array if matches, or %-EINVAL otherwise.
*/
-int match_string(const char * const *array, size_t n, const char *string)
+int __match_string(const char * const *array, size_t n, const char *string,
+ int (*cmp)(const char *, const char *))
{
int index;
const char *item;
@@ -935,13 +937,13 @@ int match_string(const char * const *array, size_t n, const char *string)
item = array[index];
if (!item)
break;
- if (!strcmp(item, string))
+ if (!cmp(item, string))
return index;
}

return -EINVAL;
}
-EXPORT_SYMBOL(match_string);
+EXPORT_SYMBOL(__match_string);

/**
* __sysfs_match_string - matches given string in an array
--
2.30.2