From 27e6b3a92e3dddb61ca8b15dfa61c6a41388a9c4 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 23 Feb 2021 09:19:48 +0100 Subject: [PATCH] lib/strutils: add ul_stralnumcmp() Signed-off-by: Karel Zak --- include/strutils.h | 1 + lib/strutils.c | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/include/strutils.h b/include/strutils.h index 09cc35e25..cb267e227 100644 --- a/include/strutils.h +++ b/include/strutils.h @@ -363,5 +363,6 @@ extern char *strfappend(const char *s, const char *format, ...) extern const char *split(const char **state, size_t *l, const char *separator, int quoted); extern int skip_fline(FILE *fp); +extern int ul_stralnumcmp(const char *p1, const char *p2); #endif diff --git a/lib/strutils.c b/lib/strutils.c index eec4cd5fa..bf60aed51 100644 --- a/lib/strutils.c +++ b/lib/strutils.c @@ -1045,6 +1045,36 @@ int skip_fline(FILE *fp) } while (1); } + +/* compare two strings, but ignoring non-alnum and case of the characters, for example + * "Hello (123)!" is the same as "hello123". + */ +int ul_stralnumcmp(const char *p1, const char *p2) +{ + const unsigned char *s1 = (const unsigned char *) p1; + const unsigned char *s2 = (const unsigned char *) p2; + unsigned char c1, c2; + + do { + do { + c1 = (unsigned char) *s1++; + } while (c1 != '\0' && !isalnum((unsigned int) c1)); + + do { + c2 = (unsigned char) *s2++; + } while (c2 != '\0' && !isalnum((unsigned int) c2)); + + if (c1 != '\0') + c1 = tolower(c1); + if (c2 != '\0') + c2 = tolower(c2); + if (c1 == '\0') + return c1 - c2; + } while (c1 == c2); + + return c1 - c2; +} + #ifdef TEST_PROGRAM_STRUTILS struct testS { char *name; @@ -1142,13 +1172,19 @@ int main(int argc, char *argv[]) if (argc == 4 && strcmp(argv[1], "--strdup-member") == 0) return test_strdup_to_member(argc - 1, argv + 1); - else if (argc == 3 && strcmp(argv[1], "--normalize") == 0) + if (argc == 4 && strcmp(argv[1], "--stralnumcmp") == 0) { + printf("%s\n", ul_stralnumcmp(argv[2], argv[3]) == 0 ? + "match" : "dismatch"); + return EXIT_SUCCESS; + + } else if (argc == 3 && strcmp(argv[1], "--normalize") == 0) return test_strutils_normalize(argc - 1, argv + 1); else { fprintf(stderr, "usage: %1$s --size [suffix]\n" " %1$s --cmp-paths \n" " %1$s --strdup-member \n" + " %1$s --stralnumcmp \n" " %1$s --normalize \n", argv[0]); exit(EXIT_FAILURE);