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