]> git.ipfire.org Git - thirdparty/git.git/blame - gettext.c
Merge branch 'ab/pager-exit-log'
[thirdparty/git.git] / gettext.c
CommitLineData
30955229
JN
1/*
2 * Copyright (c) 2010 Ævar Arnfjörð Bjarmason
3 */
4
226c0ddd 5#include "cache.h"
92034a9c 6#include "exec-cmd.h"
30955229 7#include "gettext.h"
754395d3
NTND
8#include "strbuf.h"
9#include "utf8.h"
6cdccfce 10#include "config.h"
30955229 11
5e9637c6
ÆAB
12#ifndef NO_GETTEXT
13# include <locale.h>
14# include <libintl.h>
090d1e84
KB
15# ifdef GIT_WINDOWS_NATIVE
16
17static const char *locale_charset(void)
18{
19 const char *env = getenv("LC_ALL"), *dot;
20
21 if (!env || !*env)
22 env = getenv("LC_CTYPE");
23 if (!env || !*env)
24 env = getenv("LANG");
25
26 if (!env)
27 return "UTF-8";
28
29 dot = strchr(env, '.');
30 return !dot ? env : dot + 1;
31}
32
33# elif defined HAVE_LIBCHARSET_H
5e9637c6
ÆAB
34# include <libcharset.h>
35# else
36# include <langinfo.h>
37# define locale_charset() nl_langinfo(CODESET)
38# endif
39#endif
40
e8c16726
NTND
41static const char *charset;
42
93f7d910
JK
43/*
44 * Guess the user's preferred languages from the value in LANGUAGE environment
45 * variable and LC_MESSAGES locale category if NO_GETTEXT is not defined.
46 *
47 * The result can be a colon-separated list like "ko:ja:en".
48 */
49const char *get_preferred_languages(void)
50{
51 const char *retval;
52
53 retval = getenv("LANGUAGE");
54 if (retval && *retval)
55 return retval;
56
57#ifndef NO_GETTEXT
58 retval = setlocale(LC_MESSAGES, NULL);
59 if (retval && *retval &&
60 strcmp(retval, "C") &&
61 strcmp(retval, "POSIX"))
62 return retval;
63#endif
64
65 return NULL;
66}
67
5e9637c6 68#ifndef NO_GETTEXT
9c0495d2
NTND
69static int test_vsnprintf(const char *fmt, ...)
70{
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;
78}
79
5e9637c6
ÆAB
80static void init_gettext_charset(const char *domain)
81{
5e9637c6
ÆAB
82 setlocale(LC_CTYPE, "");
83 charset = locale_charset();
84 bind_textdomain_codeset(domain, charset);
9371c0e9
ÆAB
85
86 /*
87 * Work around an old bug fixed in glibc 2.17 (released on
88 * 2012-12-24), at the cost of potentially making translated
89 * messages from external functions like perror() emitted in
90 * the wrong encoding.
91 *
92 * The bug affected e.g. git.git's own 7eb93c89651 ([PATCH]
93 * Simplify git script, 2005-09-07), which is the origin of
94 * the "David_K\345gedal" test string.
95 *
96 * See a much longer comment added to this file in 5e9637c6297
97 * (i18n: add infrastructure for translating Git with gettext,
98 * 2011-11-18) for more details.
99 */
9c0495d2
NTND
100 if (test_vsnprintf("%.*s", 13, "David_K\345gedal") < 0)
101 setlocale(LC_CTYPE, "C");
5e9637c6
ÆAB
102}
103
104void git_setup_gettext(void)
105{
226c0ddd 106 const char *podir = getenv(GIT_TEXT_DOMAIN_DIR_ENVIRONMENT);
0210231b 107 char *p = NULL;
5e9637c6
ÆAB
108
109 if (!podir)
0210231b 110 podir = p = system_path(GIT_LOCALE_PATH);
226c0ddd 111
0210231b
JS
112 if (!is_directory(podir)) {
113 free(p);
cc5e1bf9 114 return;
0210231b 115 }
226c0ddd 116
5e9637c6
ÆAB
117 bindtextdomain("git", podir);
118 setlocale(LC_MESSAGES, "");
aa1462cc 119 setlocale(LC_TIME, "");
5e9637c6
ÆAB
120 init_gettext_charset("git");
121 textdomain("git");
0210231b
JS
122
123 free(p);
5e9637c6 124}
754395d3
NTND
125
126/* return the number of columns of string 's' in current locale */
127int gettext_width(const char *s)
128{
129 static int is_utf8 = -1;
130 if (is_utf8 == -1)
e8c16726 131 is_utf8 = is_utf8_locale();
754395d3
NTND
132
133 return is_utf8 ? utf8_strwidth(s) : strlen(s);
134}
5e9637c6 135#endif
e8c16726
NTND
136
137int is_utf8_locale(void)
138{
139#ifdef NO_GETTEXT
140 if (!charset) {
141 const char *env = getenv("LC_ALL");
142 if (!env || !*env)
143 env = getenv("LC_CTYPE");
144 if (!env || !*env)
145 env = getenv("LANG");
146 if (!env)
147 env = "";
148 if (strchr(env, '.'))
149 env = strchr(env, '.') + 1;
150 charset = xstrdup(env);
151 }
152#endif
153 return is_encoding_utf8(charset);
154}