mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-26 15:36:14 +01:00
Bug 531403 - g_utf8_collate broken on Mac.
2008-06-02 Yevgen Muntyan <muntyan@tamu.edu> Bug 531403 - g_utf8_collate broken on Mac. * glib/gunicollate.c: (g_utf8_collate): use UCCompareTextDefault; (collate_key_to_string), (carbon_collate_key_with_collator), (carbon_collate_key), (carbon_collate_key_for_filename): new functions using Carbon API to get collate key for g_utf8_collate_key() and g_utf8_collate_key_for_filename(); (g_utf8_collate_key), (g_utf8_collate_key_for_filename): use those. svn path=/trunk/; revision=6969
This commit is contained in:
parent
9d3834b708
commit
c5df5e88d9
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
|||||||
|
2008-06-02 Yevgen Muntyan <muntyan@tamu.edu>
|
||||||
|
|
||||||
|
Bug 531403 – g_utf8_collate broken on Mac.
|
||||||
|
|
||||||
|
* glib/gunicollate.c: (g_utf8_collate): use UCCompareTextDefault;
|
||||||
|
(collate_key_to_string), (carbon_collate_key_with_collator),
|
||||||
|
(carbon_collate_key), (carbon_collate_key_for_filename): new
|
||||||
|
functions using Carbon API to get collate key for g_utf8_collate_key()
|
||||||
|
and g_utf8_collate_key_for_filename();
|
||||||
|
(g_utf8_collate_key), (g_utf8_collate_key_for_filename): use those.
|
||||||
|
|
||||||
2008-05-30 Michael Natterer <mitch@imendio.com>
|
2008-05-30 Michael Natterer <mitch@imendio.com>
|
||||||
|
|
||||||
Bug 535628 - test/patterntest.c still includes gpattern.h
|
Bug 535628 - test/patterntest.c still includes gpattern.h
|
||||||
|
@ -26,6 +26,10 @@
|
|||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CARBON
|
||||||
|
#include <CoreServices/CoreServices.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
#include "gunicodeprivate.h"
|
#include "gunicodeprivate.h"
|
||||||
#include "galias.h"
|
#include "galias.h"
|
||||||
@ -68,8 +72,30 @@ g_utf8_collate (const gchar *str1,
|
|||||||
const gchar *str2)
|
const gchar *str2)
|
||||||
{
|
{
|
||||||
gint result;
|
gint result;
|
||||||
|
|
||||||
#ifdef __STDC_ISO_10646__
|
#ifdef HAVE_CARBON
|
||||||
|
|
||||||
|
UniChar *str1_utf16;
|
||||||
|
UniChar *str2_utf16;
|
||||||
|
glong len1;
|
||||||
|
glong len2;
|
||||||
|
SInt32 retval = 0;
|
||||||
|
|
||||||
|
g_return_val_if_fail (str1 != NULL, 0);
|
||||||
|
g_return_val_if_fail (str2 != NULL, 0);
|
||||||
|
|
||||||
|
str1_utf16 = g_utf8_to_utf16 (str1, -1, NULL, &len1, NULL);
|
||||||
|
str2_utf16 = g_utf8_to_utf16 (str2, -1, NULL, &len2, NULL);
|
||||||
|
|
||||||
|
UCCompareTextDefault (kUCCollateStandardOptions,
|
||||||
|
str1_utf16, len1, str2_utf16, len2,
|
||||||
|
NULL, &retval);
|
||||||
|
result = retval;
|
||||||
|
|
||||||
|
g_free (str2_utf16);
|
||||||
|
g_free (str1_utf16);
|
||||||
|
|
||||||
|
#elif defined(__STDC_ISO_10646__)
|
||||||
|
|
||||||
gunichar *str1_norm;
|
gunichar *str1_norm;
|
||||||
gunichar *str2_norm;
|
gunichar *str2_norm;
|
||||||
@ -127,7 +153,7 @@ g_utf8_collate (const gchar *str1,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __STDC_ISO_10646__
|
#if defined(__STDC_ISO_10646__) || defined(HAVE_CARBON)
|
||||||
/* We need UTF-8 encoding of numbers to encode the weights if
|
/* We need UTF-8 encoding of numbers to encode the weights if
|
||||||
* we are using wcsxfrm. However, we aren't encoding Unicode
|
* we are using wcsxfrm. However, we aren't encoding Unicode
|
||||||
* characters, so we can't simply use g_unichar_to_utf8.
|
* characters, so we can't simply use g_unichar_to_utf8.
|
||||||
@ -174,7 +200,149 @@ utf8_encode (char *buf, wchar_t val)
|
|||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
#endif /* __STDC_ISO_10646__ */
|
#endif /* __STDC_ISO_10646__ || HAVE_CARBON */
|
||||||
|
|
||||||
|
#ifdef HAVE_CARBON
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
collate_key_to_string (UCCollationValue *key,
|
||||||
|
gsize key_len)
|
||||||
|
{
|
||||||
|
gchar *result;
|
||||||
|
gsize result_len;
|
||||||
|
gsize i;
|
||||||
|
|
||||||
|
/* Pretty smart algorithm here: ignore first eight bytes of the
|
||||||
|
* collation key. It doesn't produce results equivalent to
|
||||||
|
* UCCompareCollationKeys's, but the difference seems to be only
|
||||||
|
* that UCCompareCollationKeys in some cases produces 0 where our
|
||||||
|
* comparison gets -1 or 1. */
|
||||||
|
|
||||||
|
if (key_len * sizeof (UCCollationValue) <= 8)
|
||||||
|
return g_strdup ("");
|
||||||
|
|
||||||
|
result_len = 0;
|
||||||
|
for (i = 8; i < key_len * sizeof (UCCollationValue); i++)
|
||||||
|
/* there may be nul bytes, encode byteval+1 */
|
||||||
|
result_len += utf8_encode (NULL, *((guchar*)key + i) + 1);
|
||||||
|
|
||||||
|
result = g_malloc (result_len + 1);
|
||||||
|
result_len = 0;
|
||||||
|
for (i = 8; i < key_len * sizeof (UCCollationValue); i++)
|
||||||
|
result_len += utf8_encode (result + result_len, *((guchar*)key + i) + 1);
|
||||||
|
|
||||||
|
result[result_len] = 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
carbon_collate_key_with_collator (const gchar *str,
|
||||||
|
gssize len,
|
||||||
|
CollatorRef collator)
|
||||||
|
{
|
||||||
|
UniChar *str_utf16 = NULL;
|
||||||
|
glong len_utf16;
|
||||||
|
OSStatus ret;
|
||||||
|
UCCollationValue staticbuf[512];
|
||||||
|
UCCollationValue *freeme = NULL;
|
||||||
|
UCCollationValue *buf;
|
||||||
|
ItemCount buf_len;
|
||||||
|
ItemCount key_len;
|
||||||
|
ItemCount try_len;
|
||||||
|
gchar *result = NULL;
|
||||||
|
|
||||||
|
str_utf16 = g_utf8_to_utf16 (str, len, NULL, &len_utf16, NULL);
|
||||||
|
try_len = len_utf16 * 5 + 2;
|
||||||
|
|
||||||
|
if (try_len <= sizeof staticbuf)
|
||||||
|
{
|
||||||
|
buf = staticbuf;
|
||||||
|
buf_len = sizeof staticbuf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
freeme = g_new (UCCollationValue, try_len);
|
||||||
|
buf = freeme;
|
||||||
|
buf_len = try_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = UCGetCollationKey (collator, str_utf16, len_utf16,
|
||||||
|
buf_len, &key_len, buf);
|
||||||
|
|
||||||
|
if (ret == kCollateBufferTooSmall)
|
||||||
|
{
|
||||||
|
freeme = g_renew (UCCollationValue, freeme, try_len * 2);
|
||||||
|
buf = freeme;
|
||||||
|
buf_len = try_len * 2;
|
||||||
|
ret = UCGetCollationKey (collator, str_utf16, len_utf16,
|
||||||
|
buf_len, &key_len, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
result = collate_key_to_string (buf, key_len);
|
||||||
|
else
|
||||||
|
result = g_strdup ("");
|
||||||
|
|
||||||
|
g_free (freeme);
|
||||||
|
g_free (str_utf16);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
carbon_collate_key (const gchar *str,
|
||||||
|
gssize len)
|
||||||
|
{
|
||||||
|
static CollatorRef collator;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (!collator))
|
||||||
|
{
|
||||||
|
UCCreateCollator (NULL, 0, kUCCollateStandardOptions, &collator);
|
||||||
|
|
||||||
|
if (!collator)
|
||||||
|
{
|
||||||
|
static gboolean been_here;
|
||||||
|
if (!been_here)
|
||||||
|
g_warning ("%s: UCCreateCollator failed", G_STRLOC);
|
||||||
|
been_here = TRUE;
|
||||||
|
return g_strdup ("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return carbon_collate_key_with_collator (str, len, collator);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
carbon_collate_key_for_filename (const gchar *str,
|
||||||
|
gssize len)
|
||||||
|
{
|
||||||
|
static CollatorRef collator;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (!collator))
|
||||||
|
{
|
||||||
|
/* http://developer.apple.com/qa/qa2004/qa1159.html */
|
||||||
|
UCCreateCollator (NULL, 0,
|
||||||
|
kUCCollateComposeInsensitiveMask
|
||||||
|
| kUCCollateWidthInsensitiveMask
|
||||||
|
| kUCCollateCaseInsensitiveMask
|
||||||
|
| kUCCollateDigitsOverrideMask
|
||||||
|
| kUCCollateDigitsAsNumberMask
|
||||||
|
| kUCCollatePunctuationSignificantMask,
|
||||||
|
&collator);
|
||||||
|
|
||||||
|
if (!collator)
|
||||||
|
{
|
||||||
|
static gboolean been_here;
|
||||||
|
if (!been_here)
|
||||||
|
g_warning ("%s: UCCreateCollator failed", G_STRLOC);
|
||||||
|
been_here = TRUE;
|
||||||
|
return g_strdup ("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return carbon_collate_key_with_collator (str, len, collator);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_CARBON */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_utf8_collate_key:
|
* g_utf8_collate_key:
|
||||||
@ -200,10 +368,15 @@ g_utf8_collate_key (const gchar *str,
|
|||||||
gssize len)
|
gssize len)
|
||||||
{
|
{
|
||||||
gchar *result;
|
gchar *result;
|
||||||
gsize xfrm_len;
|
|
||||||
|
|
||||||
#ifdef __STDC_ISO_10646__
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CARBON
|
||||||
|
|
||||||
|
g_return_val_if_fail (str != NULL, NULL);
|
||||||
|
result = carbon_collate_key (str, len);
|
||||||
|
|
||||||
|
#elif defined(__STDC_ISO_10646__)
|
||||||
|
|
||||||
|
gsize xfrm_len;
|
||||||
gunichar *str_norm;
|
gunichar *str_norm;
|
||||||
wchar_t *result_wc;
|
wchar_t *result_wc;
|
||||||
gsize i;
|
gsize i;
|
||||||
@ -233,6 +406,7 @@ g_utf8_collate_key (const gchar *str,
|
|||||||
return result;
|
return result;
|
||||||
#else /* !__STDC_ISO_10646__ */
|
#else /* !__STDC_ISO_10646__ */
|
||||||
|
|
||||||
|
gsize xfrm_len;
|
||||||
const gchar *charset;
|
const gchar *charset;
|
||||||
gchar *str_norm;
|
gchar *str_norm;
|
||||||
|
|
||||||
@ -317,6 +491,7 @@ gchar*
|
|||||||
g_utf8_collate_key_for_filename (const gchar *str,
|
g_utf8_collate_key_for_filename (const gchar *str,
|
||||||
gssize len)
|
gssize len)
|
||||||
{
|
{
|
||||||
|
#ifndef HAVE_CARBON
|
||||||
GString *result;
|
GString *result;
|
||||||
GString *append;
|
GString *append;
|
||||||
const gchar *p;
|
const gchar *p;
|
||||||
@ -488,6 +663,9 @@ g_utf8_collate_key_for_filename (const gchar *str,
|
|||||||
g_string_free (append, TRUE);
|
g_string_free (append, TRUE);
|
||||||
|
|
||||||
return g_string_free (result, FALSE);
|
return g_string_free (result, FALSE);
|
||||||
|
#else /* HAVE_CARBON */
|
||||||
|
return carbon_collate_key_for_filename (str, len);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user