*
* You should have received a copy of the GNU Lesser General Public
* License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <CoreServices/CoreServices.h>
#endif
-#include "glib.h"
+#include "gmem.h"
+#include "gunicode.h"
#include "gunicodeprivate.h"
-#include "galias.h"
+#include "gstring.h"
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+#include "gcharset.h"
+#ifndef __STDC_ISO_10646__
+#include "gconvert.h"
+#endif
+
#ifdef _MSC_VER
/* Workaround for bug in MSVCR80.DLL */
* @str2: a UTF-8 encoded string
*
* Compares two strings for ordering using the linguistically
- * correct rules for the <link linkend="setlocale">current locale</link>.
+ * correct rules for the [current locale][setlocale].
* When sorting a large number of strings, it will be significantly
* faster to obtain collation keys with g_utf8_collate_key() and
* compare the keys with strcmp() when sorting instead of sorting
* the original strings.
*
- * Return value: < 0 if @str1 compares before @str2,
- * 0 if they compare equal, > 0 if @str1 compares after @str2.
+ * Returns: < 0 if @str1 compares before @str2,
+ * 0 if they compare equal, > 0 if @str1 compares after @str2.
**/
gint
g_utf8_collate (const gchar *str1,
gsize key_len)
{
gchar *result;
- gsize result_len;
+ gsize result_len = 0;
+ const gsize start = 2 * sizeof (void *) / sizeof (UCCollationValue);
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)
+ /* The first codes should be skipped: the same string on the same
+ * system can get different values at runtime in those positions,
+ * and they do not sort correctly. The exact size of the prefix
+ * depends on whether we are building 64 or 32 bit.
+ */
+ if (key_len <= start)
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);
+ for (i = start; i < key_len; i++)
+ result_len += utf8_encode (NULL, g_htonl (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);
+ for (i = start; i < key_len; i++)
+ result_len += utf8_encode (result + result_len, g_htonl (key[i] + 1));
+
+ result[result_len] = '\0';
- result[result_len] = 0;
return result;
}
* with strcmp() will always be the same as comparing the two
* original keys with g_utf8_collate().
*
- * Note that this function depends on the
- * <link linkend="setlocale">current locale</link>.
+ * Note that this function depends on the [current locale][setlocale].
*
- * Return value: a newly allocated string. This string should
+ * Returns: a newly allocated string. This string should
* be freed with g_free() when you are done with it.
**/
gchar *
result_wc = g_new (wchar_t, xfrm_len + 1);
wcsxfrm (result_wc, (wchar_t *)str_norm, xfrm_len + 1);
- for (i=0; i < xfrm_len; i++)
+ for (i = 0; i < xfrm_len; i++)
result_len += utf8_encode (NULL, result_wc[i]);
result = g_malloc (result_len + 1);
result_len = 0;
- for (i=0; i < xfrm_len; i++)
+ for (i = 0; i < xfrm_len; i++)
result_len += utf8_encode (result + result_len, result_wc[i]);
result[result_len] = '\0';
str_norm = g_utf8_normalize (str, len, G_NORMALIZE_ALL_COMPOSE);
+ result = NULL;
+
if (g_get_charset (&charset))
{
xfrm_len = strxfrm (NULL, str_norm, 0);
- result = g_malloc (xfrm_len + 1);
- strxfrm (result, str_norm, xfrm_len + 1);
+ if (xfrm_len >= 0 && xfrm_len < G_MAXINT - 2)
+ {
+ result = g_malloc (xfrm_len + 1);
+ strxfrm (result, str_norm, xfrm_len + 1);
+ }
}
else
{
g_free (str_locale);
}
- else
- {
- xfrm_len = strlen (str_norm);
- result = g_malloc (xfrm_len + 2);
- result[0] = 'B';
- memcpy (result + 1, str_norm, xfrm_len);
- result[xfrm_len+1] = '\0';
- }
+ }
+
+ if (!result)
+ {
+ xfrm_len = strlen (str_norm);
+ result = g_malloc (xfrm_len + 2);
+ result[0] = 'B';
+ memcpy (result + 1, str_norm, xfrm_len);
+ result[xfrm_len+1] = '\0';
}
g_free (str_norm);
}
/* This is a collation key that is very very likely to sort before any
- collation key that libc strxfrm generates. We use this before any
- special case (dot or number) to make sure that its sorted before
- anything else.
+ * collation key that libc strxfrm generates. We use this before any
+ * special case (dot or number) to make sure that its sorted before
+ * anything else.
*/
#define COLLATION_SENTINEL "\1\1\1"
* would like to treat numbers intelligently so that "file1" "file10" "file5"
* is sorted as "file1" "file5" "file10".
*
- * Note that this function depends on the
- * <link linkend="setlocale">current locale</link>.
+ * Note that this function depends on the [current locale][setlocale].
*
- * Return value: a newly allocated string. This string should
+ * Returns: a newly allocated string. This string should
* be freed with g_free() when you are done with it.
*
* Since: 2.8
*/
-gchar*
+gchar *
g_utf8_collate_key_for_filename (const gchar *str,
gssize len)
{
return carbon_collate_key_for_filename (str, len);
#endif
}
-
-
-#define __G_UNICOLLATE_C__
-#include "galiasdef.c"