diff options
Diffstat (limited to 'third_party/git/gettext.c')
-rw-r--r-- | third_party/git/gettext.c | 228 |
1 files changed, 0 insertions, 228 deletions
diff --git a/third_party/git/gettext.c b/third_party/git/gettext.c deleted file mode 100644 index 35d2c1218d..0000000000 --- a/third_party/git/gettext.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2010 Ævar Arnfjörð Bjarmason - */ - -#include "cache.h" -#include "exec-cmd.h" -#include "gettext.h" -#include "strbuf.h" -#include "utf8.h" -#include "config.h" - -#ifndef NO_GETTEXT -# include <locale.h> -# include <libintl.h> -# ifdef GIT_WINDOWS_NATIVE - -static const char *locale_charset(void) -{ - const char *env = getenv("LC_ALL"), *dot; - - if (!env || !*env) - env = getenv("LC_CTYPE"); - if (!env || !*env) - env = getenv("LANG"); - - if (!env) - return "UTF-8"; - - dot = strchr(env, '.'); - return !dot ? env : dot + 1; -} - -# elif defined HAVE_LIBCHARSET_H -# include <libcharset.h> -# else -# include <langinfo.h> -# define locale_charset() nl_langinfo(CODESET) -# endif -#endif - -static const char *charset; - -/* - * Guess the user's preferred languages from the value in LANGUAGE environment - * variable and LC_MESSAGES locale category if NO_GETTEXT is not defined. - * - * The result can be a colon-separated list like "ko:ja:en". - */ -const char *get_preferred_languages(void) -{ - const char *retval; - - retval = getenv("LANGUAGE"); - if (retval && *retval) - return retval; - -#ifndef NO_GETTEXT - retval = setlocale(LC_MESSAGES, NULL); - if (retval && *retval && - strcmp(retval, "C") && - strcmp(retval, "POSIX")) - return retval; -#endif - - return NULL; -} - -int use_gettext_poison(void) -{ - static int poison_requested = -1; - if (poison_requested == -1) - poison_requested = git_env_bool("GIT_TEST_GETTEXT_POISON", 0); - return poison_requested; -} - -#ifndef NO_GETTEXT -static int test_vsnprintf(const char *fmt, ...) -{ - char buf[26]; - int ret; - va_list ap; - va_start(ap, fmt); - ret = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return ret; -} - -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 - - The vsnprintf bug has been fixed since glibc 2.17. - - 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); - /* the string is taken from v0.99.6~1 */ - if (test_vsnprintf("%.*s", 13, "David_K\345gedal") < 0) - setlocale(LC_CTYPE, "C"); -} - -void git_setup_gettext(void) -{ - const char *podir = getenv(GIT_TEXT_DOMAIN_DIR_ENVIRONMENT); - char *p = NULL; - - if (!podir) - podir = p = system_path(GIT_LOCALE_PATH); - - use_gettext_poison(); /* getenv() reentrancy paranoia */ - - if (!is_directory(podir)) { - free(p); - return; - } - - bindtextdomain("git", podir); - setlocale(LC_MESSAGES, ""); - setlocale(LC_TIME, ""); - init_gettext_charset("git"); - textdomain("git"); - - free(p); -} - -/* return the number of columns of string 's' in current locale */ -int gettext_width(const char *s) -{ - static int is_utf8 = -1; - if (is_utf8 == -1) - is_utf8 = is_utf8_locale(); - - return is_utf8 ? utf8_strwidth(s) : strlen(s); -} -#endif - -int is_utf8_locale(void) -{ -#ifdef NO_GETTEXT - if (!charset) { - const char *env = getenv("LC_ALL"); - if (!env || !*env) - env = getenv("LC_CTYPE"); - if (!env || !*env) - env = getenv("LANG"); - if (!env) - env = ""; - if (strchr(env, '.')) - env = strchr(env, '.') + 1; - charset = xstrdup(env); - } -#endif - return is_encoding_utf8(charset); -} |