X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Funistr%2Fu-strcoll.h;h=2a1b553556bc486a3c347c7f091177c6d22cae9d;hb=4fe68d4176b4f0da64660bb9ce0f5412a6bb24de;hp=03a99a64003aaadb73e78fea2b0ee965144def03;hpb=441aa3044f43e5572f58c354f01e6bc070acd5c7;p=gnulib.git diff --git a/lib/unistr/u-strcoll.h b/lib/unistr/u-strcoll.h index 03a99a640..2a1b55355 100644 --- a/lib/unistr/u-strcoll.h +++ b/lib/unistr/u-strcoll.h @@ -1,6 +1,6 @@ /* Compare UTF-8/UTF-16/UTF-32 strings using the collation rules of the current locale. - Copyright (C) 2009 Free Software Foundation, Inc. + Copyright (C) 2009-2011 Free Software Foundation, Inc. Written by Bruno Haible , 2009. This program is free software: you can redistribute it and/or modify it @@ -23,14 +23,19 @@ FUNC (const UNIT *s1, const UNIT *s2) When it fails, it sets errno, but also returns a meaningful return value, for the sake of callers which ignore errno. */ int final_errno = errno; + const char *encoding = locale_charset (); char *sl1; char *sl2; int result; - sl1 = U_STRCONV_TO_LOCALE (s1); + /* Pass iconveh_error here, not iconveh_question_mark. Otherwise the + conversion to locale encoding can do transliteration or map some + characters to question marks, leading to results that depend on the + iconv() implementation and are not obvious. */ + sl1 = U_STRCONV_TO_ENCODING (s1, encoding, iconveh_error); if (sl1 != NULL) { - sl2 = U_STRCONV_TO_LOCALE (s2); + sl2 = U_STRCONV_TO_ENCODING (s2, encoding, iconveh_error); if (sl2 != NULL) { /* Compare sl1 and sl2. */ @@ -41,6 +46,12 @@ FUNC (const UNIT *s1, const UNIT *s2) /* strcoll succeeded. */ free (sl1); free (sl2); + /* The conversion to locale encoding can drop Unicode TAG + characters. Therefore sl1 and sl2 may be equal when s1 + and s2 were in fact different. Return a nonzero result + in this case. */ + if (result == 0) + result = U_STRCMP (s1, s2); } else { @@ -62,7 +73,7 @@ FUNC (const UNIT *s1, const UNIT *s2) else { final_errno = errno; - sl2 = U_STRCONV_TO_LOCALE (s2); + sl2 = U_STRCONV_TO_ENCODING (s2, encoding, iconveh_error); if (sl2 != NULL) { /* s2 could be converted to locale encoding, s1 not. */