r16547 - gnucash/trunk/lib/libqof/qof - #438360: Replace str{, n}casestr and strcasecmp by qof_utf8_{substr_nocase, strcasecmp}.

Andreas Köhler andi5 at cvs.gnucash.org
Tue Oct 2 21:18:14 EDT 2007


Author: andi5
Date: 2007-10-02 21:18:13 -0400 (Tue, 02 Oct 2007)
New Revision: 16547
Trac: http://svn.gnucash.org/trac/changeset/16547

Modified:
   gnucash/trunk/lib/libqof/qof/qofquerycore.c
   gnucash/trunk/lib/libqof/qof/qofutil.c
   gnucash/trunk/lib/libqof/qof/qofutil.h
Log:
#438360: Replace str{,n}casestr and strcasecmp by qof_utf8_{substr_nocase,strcasecmp}.

The functions used did not work for non-ascii characters.  The new
implementations use g_utf8_casefold and g_utf8_normalize to improve case
insensitive searches and comparisons.


Modified: gnucash/trunk/lib/libqof/qof/qofquerycore.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofquerycore.c	2007-09-30 19:00:49 UTC (rev 16546)
+++ gnucash/trunk/lib/libqof/qof/qofquerycore.c	2007-10-03 01:18:13 UTC (rev 16547)
@@ -148,7 +148,7 @@
       ret = 1;
 
   } else if (pdata->options == QOF_STRING_MATCH_CASEINSENSITIVE) {
-    if (strcasestr (s, pdata->matchstring))
+    if (qof_utf8_substr_nocase (s, pdata->matchstring))
       ret = 1;
 
   } else {

Modified: gnucash/trunk/lib/libqof/qof/qofutil.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofutil.c	2007-09-30 19:00:49 UTC (rev 16546)
+++ gnucash/trunk/lib/libqof/qof/qofutil.c	2007-10-03 01:18:13 UTC (rev 16547)
@@ -36,33 +36,48 @@
 
 static QofLogModule log_module = QOF_MOD_UTIL;
 
-/* Search for str2 in first nchar chars of str1, ignore case..  Return
- * pointer to first match, or null.  */
-gchar *
-strncasestr(const guchar *str1, const guchar *str2, size_t len) 
+gboolean
+qof_utf8_substr_nocase (const gchar *haystack, const gchar *needle)
 {
-  while (*str1 && len--) 
-  {
-    if (toupper(*str1) == toupper(*str2)) 
-    {
-      if (strncasecmp(str1,str2,strlen(str2)) == 0) 
-      {
-        return (gchar *) str1;
-      }
-    }
-    str1++;
-  }
-  return NULL;
+    gchar *haystack_casefold, *haystack_normalized;
+    gchar *needle_casefold, *needle_normalized;
+    gchar *p;
+    gint offset;
+
+    g_return_val_if_fail (haystack && needle, FALSE);
+
+    haystack_casefold = g_utf8_casefold (haystack, -1);
+    haystack_normalized = g_utf8_normalize (haystack_casefold, -1,
+                                            G_NORMALIZE_ALL);
+    g_free (haystack_casefold);
+
+    needle_casefold = g_utf8_casefold (needle, -1);
+    needle_normalized = g_utf8_normalize (needle_casefold, -1, G_NORMALIZE_ALL);
+    g_free (needle_casefold);
+
+    p = strstr (haystack_normalized, needle_normalized);
+    g_free (haystack_normalized);
+    g_free (needle_normalized);
+
+    return p != NULL;
 }
 
-/* Search for str2 in str1, ignore case.  Return pointer to first
- * match, or null.  */
-gchar *
-strcasestr(const gchar *str1, const gchar *str2) 
+gint
+qof_utf8_strcasecmp (const gchar *da, const gchar *db)
 {
-   size_t len = strlen (str1);
-   gchar * retval = strncasestr (str1, str2, len);
-   return retval;
+    gchar *da_casefold, *db_casefold;
+    gint retval;
+
+    g_return_val_if_fail (da != NULL, 0);
+    g_return_val_if_fail (db != NULL, 0);
+
+    da_casefold = g_utf8_casefold (da, -1);
+    db_casefold = g_utf8_casefold (db, -1);
+    retval = g_utf8_collate (da_casefold, db_casefold);
+    g_free (da_casefold);
+    g_free (db_casefold);
+
+    return retval;
 }
 
 gint 
@@ -89,7 +104,7 @@
 {
 	if ((da) && (db)) {
 		if ((da) != (db)) {
-			gint retval = strcasecmp ((da), (db));
+			gint retval = qof_utf8_strcasecmp ((da), (db));
 			/* if strings differ, return */
 			if (retval) return retval;
 		}     

Modified: gnucash/trunk/lib/libqof/qof/qofutil.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofutil.h	2007-09-30 19:00:49 UTC (rev 16546)
+++ gnucash/trunk/lib/libqof/qof/qofutil.h	2007-10-03 01:18:13 UTC (rev 16547)
@@ -166,6 +166,16 @@
 
 /* **** Prototypes *********************************************/
 
+/** Search for an occurence of the substring needle in the string
+ * haystack, ignoring case. Return TRUE if one is found or FALSE
+ * otherwise. */
+gboolean qof_utf8_substr_nocase (const gchar *haystack, const gchar *needle);
+
+/** Use g_utf8_casefold and g_utf8_collate to compare two utf8 strings,
+ * ignore case. Return < 0 if da compares before db, 0 if they compare
+ * equal, > 0 if da compares after db. */
+gint qof_utf8_strcasecmp (const gchar *da, const gchar *db);
+
 /** The safe_strcmp compares strings da and db the same way that strcmp()
  does, except that either may be null.  This routine assumes that
  a non-null string is always greater than a null string.
@@ -201,13 +211,6 @@
  */
 gint null_strcmp (const gchar * da, const gchar * db);
 
-/** Search for str2 in first nchar chars of str1, ignore case. Return
- * pointer to first match, or null. These are just like that strnstr
- * and the strstr functions, except that they ignore the case. */
-extern gchar *strncasestr(const guchar *str1, const guchar *str2, 
-	size_t len);
-extern gchar *strcasestr(const gchar *str1, const gchar *str2);
-
 /** The ultostr() subroutine is the inverse of strtoul(). It accepts a
  * number and prints it in the indicated base.  The returned string
  * should be g_freed when done.  */



More information about the gnucash-changes mailing list