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