Added silc_utf8_str[n]casecmp.
authorPekka Riikonen <priikone@silcnet.org>
Wed, 30 Mar 2005 20:02:06 +0000 (20:02 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Wed, 30 Mar 2005 20:02:06 +0000 (20:02 +0000)
lib/silcutil/silcutf8.c
lib/silcutil/silcutf8.h
lib/silcutil/tests/test_silcstrutil.c

index f53f7276062b75653cd6f51e2272bcdfc450d6ea..8fea7b394e75c4ca45b87ede74099c5fe23d1ca1 100644 (file)
@@ -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;
+}
index 8373cab2136fdc16315516f708e914d942b4a4b0..ba09b4e91f4f48dd2c8bf14001db6da6784f937e 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  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 */
index b647abec4111eeb86a6e4c46f97185393e895eb0..f7b4faf81078facbe9bf9244cad13d352080ffe5 100644 (file)
@@ -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);