unpack_trees: start splitting internal fields from public API
[git/debian.git] / gettext.c
blobf139008d0a385140f354e6d2b36bd520c1b555b4
1 /*
2 * Copyright (c) 2010 Ævar Arnfjörð Bjarmason
3 */
5 #include "cache.h"
6 #include "exec-cmd.h"
7 #include "gettext.h"
8 #include "strbuf.h"
9 #include "utf8.h"
10 #include "config.h"
12 #ifndef NO_GETTEXT
13 # include <libintl.h>
14 # ifdef GIT_WINDOWS_NATIVE
16 static const char *locale_charset(void)
18 const char *env = getenv("LC_ALL"), *dot;
20 if (!env || !*env)
21 env = getenv("LC_CTYPE");
22 if (!env || !*env)
23 env = getenv("LANG");
25 if (!env)
26 return "UTF-8";
28 dot = strchr(env, '.');
29 return !dot ? env : dot + 1;
32 # elif defined HAVE_LIBCHARSET_H
33 # include <libcharset.h>
34 # else
35 # include <langinfo.h>
36 # define locale_charset() nl_langinfo(CODESET)
37 # endif
38 #endif
40 static const char *charset;
43 * Guess the user's preferred languages from the value in LANGUAGE environment
44 * variable and LC_MESSAGES locale category if NO_GETTEXT is not defined.
46 * The result can be a colon-separated list like "ko:ja:en".
48 const char *get_preferred_languages(void)
50 const char *retval;
52 retval = getenv("LANGUAGE");
53 if (retval && *retval)
54 return retval;
56 #ifndef NO_GETTEXT
57 retval = setlocale(LC_MESSAGES, NULL);
58 if (retval && *retval &&
59 strcmp(retval, "C") &&
60 strcmp(retval, "POSIX"))
61 return retval;
62 #endif
64 return NULL;
67 #ifndef NO_GETTEXT
68 __attribute__((format (printf, 1, 2)))
69 static int test_vsnprintf(const char *fmt, ...)
71 char buf[26];
72 int ret;
73 va_list ap;
74 va_start(ap, fmt);
75 ret = vsnprintf(buf, sizeof(buf), fmt, ap);
76 va_end(ap);
77 return ret;
80 static void init_gettext_charset(const char *domain)
82 charset = locale_charset();
83 bind_textdomain_codeset(domain, charset);
86 * Work around an old bug fixed in glibc 2.17 (released on
87 * 2012-12-24), at the cost of potentially making translated
88 * messages from external functions like perror() emitted in
89 * the wrong encoding.
91 * The bug affected e.g. git.git's own 7eb93c89651 ([PATCH]
92 * Simplify git script, 2005-09-07), which is the origin of
93 * the "David_K\345gedal" test string.
95 * See a much longer comment added to this file in 5e9637c6297
96 * (i18n: add infrastructure for translating Git with gettext,
97 * 2011-11-18) for more details.
99 if (test_vsnprintf("%.*s", 13, "David_K\345gedal") < 0)
100 setlocale(LC_CTYPE, "C");
103 void git_setup_gettext(void)
105 const char *podir = getenv(GIT_TEXT_DOMAIN_DIR_ENVIRONMENT);
106 char *p = NULL;
108 if (!podir)
109 podir = p = system_path(GIT_LOCALE_PATH);
111 if (!is_directory(podir)) {
112 free(p);
113 return;
116 bindtextdomain("git", podir);
117 setlocale(LC_MESSAGES, "");
118 setlocale(LC_TIME, "");
119 init_gettext_charset("git");
120 textdomain("git");
122 free(p);
125 /* return the number of columns of string 's' in current locale */
126 int gettext_width(const char *s)
128 static int is_utf8 = -1;
129 if (is_utf8 == -1)
130 is_utf8 = is_utf8_locale();
132 return is_utf8 ? utf8_strwidth(s) : strlen(s);
134 #endif
136 int is_utf8_locale(void)
138 #ifdef NO_GETTEXT
139 if (!charset) {
140 const char *env = getenv("LC_ALL");
141 if (!env || !*env)
142 env = getenv("LC_CTYPE");
143 if (!env || !*env)
144 env = getenv("LANG");
145 if (!env)
146 env = "";
147 if (strchr(env, '.'))
148 env = strchr(env, '.') + 1;
149 charset = xstrdup(env);
151 #endif
152 return is_encoding_utf8(charset);