160 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			160 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
| /*
 | |
|  * Copyright (c) 2010 Ævar Arnfjörð Bjarmason
 | |
|  */
 | |
| 
 | |
| #define DISABLE_SIGN_COMPARE_WARNINGS
 | |
| 
 | |
| #include "git-compat-util.h"
 | |
| #include "abspath.h"
 | |
| #include "environment.h"
 | |
| #include "exec-cmd.h"
 | |
| #include "gettext.h"
 | |
| #include "utf8.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");
 | |
| }
 | |
| 
 | |
| int git_gettext_enabled = 0;
 | |
| 
 | |
| 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");
 | |
| 
 | |
| 	git_gettext_enabled = 1;
 | |
| 
 | |
| 	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);
 | |
| }
 |