From: Pekka Riikonen Date: Wed, 30 Mar 2005 20:02:06 +0000 (+0000) Subject: Added silc_utf8_str[n]casecmp. X-Git-Tag: silc.server.0.9.19~23 X-Git-Url: http://git.silcnet.org/gitweb/?a=commitdiff_plain;h=d43836db244e823f157dfb795fb37221772783ac;p=silc.git Added silc_utf8_str[n]casecmp. --- diff --git a/lib/silcutil/silcutf8.c b/lib/silcutil/silcutf8.c index f53f7276..8fea7b39 100644 --- a/lib/silcutil/silcutf8.c +++ b/lib/silcutil/silcutf8.c @@ -540,3 +540,53 @@ bool silc_utf8_valid(const unsigned char *utf8, SilcUInt32 utf8_len) { return silc_utf8_decode(utf8, utf8_len, 0, NULL, 0) != 0; } + +/* Pretty close strcasecmp */ + +bool silc_utf8_strcasecmp(const char *s1, const char *s2) +{ + SilcUInt32 n; + + if (s1 == s2) + return TRUE; + + n = strlen(s2); + if (strlen(s1) > n) + n = strlen(s1); + + return silc_utf8_strncasecmp(s1, s2, n); +} + +/* Pretty close strcasecmp */ + +bool silc_utf8_strncasecmp(const char *s1, const char *s2, SilcUInt32 n) +{ + unsigned char *s1u, *s2u; + SilcUInt32 s1u_len, s2u_len; + SilcStringprepStatus status; + bool ret; + + if (s1 == s2) + return TRUE; + + /* Casefold and normalize */ + status = silc_stringprep(s1, strlen(s1), SILC_STRING_UTF8, + SILC_IDENTIFIERC_PREP, 0, &s1u, + &s1u_len, SILC_STRING_UTF8); + if (status != SILC_STRINGPREP_OK) + return FALSE; + + /* Casefold and normalize */ + status = silc_stringprep(s2, strlen(s2), SILC_STRING_UTF8, + SILC_IDENTIFIERC_PREP, 0, &s2u, + &s2u_len, SILC_STRING_UTF8); + if (status != SILC_STRINGPREP_OK) + return FALSE; + + ret = !memcmp(s1u, s2u, n); + + silc_free(s1u); + silc_free(s2u); + + return ret; +} diff --git a/lib/silcutil/silcutf8.h b/lib/silcutil/silcutf8.h index 8373cab2..ba09b4e9 100644 --- a/lib/silcutil/silcutf8.h +++ b/lib/silcutil/silcutf8.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2004, 2005 Pekka Riikonen + Copyright (C) 2004 - 2005 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -124,4 +124,43 @@ SilcUInt32 silc_utf8_decoded_len(const unsigned char *bin, SilcUInt32 bin_len, ***/ bool silc_utf8_valid(const unsigned char *utf8, SilcUInt32 utf8_len); +/****f* silcutil/SilcStrUtilAPI/silc_utf8_strcasecmp + * + * SYNOPSIS + * + * bool silc_utf8_strcasecmp(const char *s1, const char *s2); + * + * DESCRIPTION + * + * The silc_utf8_strcasecmp() function compares the two strings s1 and s2, + * ignoring the case of the characters. It returns TRUE if the strings + * match and FALSE if they differ. + * + * This functions expects NULL terminated UTF-8 strings. The strings + * will be casefolded and normalized before comparing. Certain special + * Unicode characters will be ignored when comparing. + * + ***/ +bool silc_utf8_strcasecmp(const char *s1, const char *s2); + +/****f* silcutil/SilcStrUtilAPI/silc_utf8_strncasecmp + * + * SYNOPSIS + * + * bool silc_utf8_strcasecmp(const char *s1, const char *s2, + * SilcUInt32 n); + * + * DESCRIPTION + * + * The silc_utf8_strcasecmp() function compares the two strings s1 and s2, + * ignoring the case of the characters. It returns TRUE if the strings + * match and FALSE if they differ. + * + * This functions expects NULL terminated UTF-8 strings. The strings + * will be casefolded and normalized before comparing. Certain special + * Unicode characters will be ignored when comparing. + * + ***/ +bool silc_utf8_strncasecmp(const char *s1, const char *s2, SilcUInt32 n); + #endif /* SILCUTF8_H */ diff --git a/lib/silcutil/tests/test_silcstrutil.c b/lib/silcutil/tests/test_silcstrutil.c index b647abec..f7b4faf8 100644 --- a/lib/silcutil/tests/test_silcstrutil.c +++ b/lib/silcutil/tests/test_silcstrutil.c @@ -51,7 +51,7 @@ utf8fail(30, "\xf0\x20\xf9\x20\xfa\x20\xfb\x20", 8); int main(int argc, char **argv) { bool success = FALSE; - unsigned char *s1, *s3, *s4; + unsigned char *s1, *s2, *s3, *s4; int l; if (argc > 1 && !strcmp(argv[1], "-d")) { @@ -101,6 +101,31 @@ int main(int argc, char **argv) SILC_LOG_DEBUG(("UTF-8 mismatch")); goto err; } + silc_free(s3); + silc_free(s4); + + /* UTF-8 strcasecmp test */ + SILC_LOG_DEBUG(("silc_utf8_strcasecmp test")); + s1 = "Päivää vuan Yrjö"; + s2 = "PÄIVÄÄ VUAN YRJÖ"; + l = silc_utf8_encoded_len(s1, strlen(s1), SILC_STRING_LOCALE); + if (!l) + goto err; + s3 = silc_calloc(l + 1, sizeof(*s3)); + silc_utf8_encode(s1, strlen(s1), SILC_STRING_LOCALE, s3, l); + + l = silc_utf8_encoded_len(s2, strlen(s2), SILC_STRING_LOCALE); + if (!l) + goto err; + s4 = silc_calloc(l + 1, sizeof(*s4)); + silc_utf8_encode(s2, strlen(s2), SILC_STRING_LOCALE, s4, l); + + SILC_LOG_DEBUG(("%s == %s", s3, s4)); + if (!silc_utf8_strcasecmp(s3, s4)) { + SILC_LOG_DEBUG(("mismatch")); + goto err; + } + SILC_LOG_DEBUG(("match")); silc_free(s3); silc_free(s4);