| /* | 
 |  * 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 <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; | 
 | } | 
 |  | 
 | #ifndef NO_GETTEXT | 
 | __attribute__((format (printf, 1, 2))) | 
 | 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) | 
 | { | 
 | 	charset = locale_charset(); | 
 | 	bind_textdomain_codeset(domain, charset); | 
 |  | 
 | 	/* | 
 | 	 * Work around an old bug fixed in glibc 2.17 (released on | 
 | 	 * 2012-12-24), at the cost of potentially making translated | 
 | 	 * messages from external functions like perror() emitted in | 
 | 	 * the wrong encoding. | 
 | 	 * | 
 | 	 * The bug affected e.g. git.git's own 7eb93c89651 ([PATCH] | 
 | 	 * Simplify git script, 2005-09-07), which is the origin of | 
 | 	 * the "David_K\345gedal" test string. | 
 | 	 * | 
 | 	 * See a much longer comment added to this file in 5e9637c6297 | 
 | 	 * (i18n: add infrastructure for translating Git with gettext, | 
 | 	 * 2011-11-18) for more details. | 
 | 	 */ | 
 | 	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); | 
 |  | 
 | 	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); | 
 | } |