mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
#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. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@16547 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
@@ -148,7 +148,7 @@ string_match_predicate (gpointer object,
|
||||
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 {
|
||||
|
||||
@@ -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 @@ safe_strcasecmp (const gchar * da, const gchar * db)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -166,6 +166,16 @@ void qof_close (void);
|
||||
|
||||
/* **** 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 safe_strcasecmp (const gchar * da, const gchar * db);
|
||||
*/
|
||||
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. */
|
||||
|
||||
Reference in New Issue
Block a user