tags 698867 + upstream
block 698867 by 208308
# basic i18n
severity 698867 important
quit
Hi Andrey,
Andrey Rahmatullin wrote:
> If git clone cannot connect to the server and maybe in other circumstances
> (and
> other tools) it fails to print a localized strerror() in the ru_RU.UTF-8
> locale:
>
> fatal: unable to connect to git.debian.org:
> wagner.debian.org[0: 217.196.43.134]: errno=? ?????????? ????????
> wagner.debian.org[1: 217.196.43.132]: errno=? ?????????? ????????
>
> It should read "В соединении отказано", as far as I know. It
> prints "errno=Connection refused" in the C locale.
Thanks for filing this. The bug is due to a workaround for glibc
PR6530 (bug#208308). That bug is fixed in experimental, so we can
drop the workaround in jessie (yay!).
Getting it right will take some upstream work to avoid assumptions
of C locale elsewhere in git. Here's a start for experimenting with
(untested).
Hope that helps,
Jonathan
diff --git i/gettext.c w/gettext.c
index 71e95456..f5dc9db9 100644
--- i/gettext.c
+++ w/gettext.c
@@ -32,90 +32,8 @@ int use_gettext_poison(void)
static const char *charset;
static void init_gettext_charset(const char *domain)
{
- /*
- This trick arranges for messages to be emitted in the user's
- requested encoding, but avoids setting LC_CTYPE from the
- environment for the whole program.
-
- This primarily done to avoid a bug in vsnprintf in the GNU C
- Library [1]. which triggered a "your vsnprintf is broken" error
- on Git's own repository when inspecting v0.99.6~1 under a UTF-8
- locale.
-
- That commit contains a ISO-8859-1 encoded author name, which
- the locale aware vsnprintf(3) won't interpolate in the format
- argument, due to mismatch between the data encoding and the
- locale.
-
- Even if it wasn't for that bug we wouldn't want to use LC_CTYPE at
- this point, because it'd require auditing all the code that uses C
- functions whose semantics are modified by LC_CTYPE.
-
- But only setting LC_MESSAGES as we do creates a problem, since
- we declare the encoding of our PO files[2] the gettext
- implementation will try to recode it to the user's locale, but
- without LC_CTYPE it'll emit something like this on 'git init'
- under the Icelandic locale:
-
- Bj? til t?ma Git lind ? /hlagh/.git/
-
- Gettext knows about the encoding of our PO file, but we haven't
- told it about the user's encoding, so all the non-US-ASCII
- characters get encoded to question marks.
-
- But we're in luck! We can set LC_CTYPE from the environment
- only while we call nl_langinfo and
- bind_textdomain_codeset. That suffices to tell gettext what
- encoding it should emit in, so it'll now say:
-
- Bjó til tóma Git lind í /hlagh/.git/
-
- And the equivalent ISO-8859-1 string will be emitted under a
- ISO-8859-1 locale.
-
- With this change way we get the advantages of setting LC_CTYPE
- (talk to the user in his language/encoding), without the major
- drawbacks (changed semantics for C functions we rely on).
-
- However foreign functions using other message catalogs that
- aren't using our neat trick will still have a problem, e.g. if
- we have to call perror(3):
-
- #include <stdio.h>
- #include <locale.h>
- #include <errno.h>
-
- int main(void)
- {
- setlocale(LC_MESSAGES, "");
- setlocale(LC_CTYPE, "C");
- errno = ENODEV;
- perror("test");
- return 0;
- }
-
- Running that will give you a message with question marks:
-
- $ LANGUAGE= LANG=de_DE.utf8 ./test
- test: Kein passendes Ger?t gefunden
-
- In the long term we should probably see about getting that
- vsnprintf bug in glibc fixed, and audit our code so it won't
- fall apart under a non-C locale.
-
- Then we could simply set LC_CTYPE from the environment, which would
- make things like the external perror(3) messages work.
-
- See t/t0203-gettext-setlocale-sanity.sh's "gettext.c" tests for
- regression tests.
-
- 1. http://sourceware.org/bugzilla/show_bug.cgi?id=6530
- 2. E.g. "Content-Type: text/plain; charset=UTF-8\n" in po/is.po
- */
- setlocale(LC_CTYPE, "");
charset = locale_charset();
bind_textdomain_codeset(domain, charset);
- setlocale(LC_CTYPE, "C");
}
void git_setup_gettext(void)
@@ -125,7 +43,7 @@ void git_setup_gettext(void)
if (!podir)
podir = GIT_LOCALE_PATH;
bindtextdomain("git", podir);
- setlocale(LC_MESSAGES, "");
+ setlocale(LC_ALL, "");
init_gettext_charset("git");
textdomain("git");
}
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]