🌐 AI搜索 & 代理 主页
blob: 57facbc21ec2545e5bdeb1e738445ad403f419b4 [file] [log] [blame]
Jonathan Nieder30955222011-02-22 23:41:221/*
2 * Copyright (c) 2010 Ævar Arnfjörð Bjarmason
3 */
4
Elijah Newren98750582023-03-21 06:26:045#include "git-compat-util.h"
Elijah Newren0b027f62023-03-21 06:25:586#include "abspath.h"
Elijah Newren32a8f512023-03-21 06:26:037#include "environment.h"
Junio C Hamano92034a92018-05-08 06:59:178#include "exec-cmd.h"
Jonathan Nieder30955222011-02-22 23:41:229#include "gettext.h"
Nguyễn Thái Ngọc Duy754395d2012-09-04 10:39:3510#include "utf8.h"
Jonathan Nieder30955222011-02-22 23:41:2211
Ævar Arnfjörð Bjarmason5e9637c2011-11-17 23:14:4212#ifndef NO_GETTEXT
Ævar Arnfjörð Bjarmason5e9637c2011-11-17 23:14:4213# include <libintl.h>
Karsten Blees090d1e82019-07-03 20:46:0414# ifdef GIT_WINDOWS_NATIVE
15
16static const char *locale_charset(void)
17{
18 const char *env = getenv("LC_ALL"), *dot;
19
20 if (!env || !*env)
21 env = getenv("LC_CTYPE");
22 if (!env || !*env)
23 env = getenv("LANG");
24
25 if (!env)
26 return "UTF-8";
27
28 dot = strchr(env, '.');
29 return !dot ? env : dot + 1;
30}
31
32# elif defined HAVE_LIBCHARSET_H
Ævar Arnfjörð Bjarmason5e9637c2011-11-17 23:14:4233# include <libcharset.h>
34# else
35# include <langinfo.h>
36# define locale_charset() nl_langinfo(CODESET)
37# endif
38#endif
39
Nguyễn Thái Ngọc Duye8c16722016-06-25 05:22:3440static const char *charset;
41
Jeff King93f7d912015-02-26 03:04:1642/*
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.
45 *
46 * The result can be a colon-separated list like "ko:ja:en".
47 */
48const char *get_preferred_languages(void)
49{
50 const char *retval;
51
52 retval = getenv("LANGUAGE");
53 if (retval && *retval)
54 return retval;
55
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
63
64 return NULL;
65}
66
Ævar Arnfjörð Bjarmason5e9637c2011-11-17 23:14:4267#ifndef NO_GETTEXT
Ævar Arnfjörð Bjarmason48ca53c2021-07-13 08:05:1868__attribute__((format (printf, 1, 2)))
Nguyễn Thái Ngọc Duy9c0495d2013-12-01 02:45:3869static 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
Ævar Arnfjörð Bjarmason5e9637c2011-11-17 23:14:4280static void init_gettext_charset(const char *domain)
81{
Ævar Arnfjörð Bjarmason5e9637c2011-11-17 23:14:4282 charset = locale_charset();
83 bind_textdomain_codeset(domain, charset);
Ævar Arnfjörð Bjarmason9371c0e2021-01-11 13:14:5184
85 /*
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.
90 *
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.
94 *
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.
98 */
Nguyễn Thái Ngọc Duy9c0495d2013-12-01 02:45:3899 if (test_vsnprintf("%.*s", 13, "David_K\345gedal") < 0)
100 setlocale(LC_CTYPE, "C");
Ævar Arnfjörð Bjarmason5e9637c2011-11-17 23:14:42101}
102
Johannes Schindelinc4137be2023-02-22 11:40:55103int git_gettext_enabled = 0;
104
Ævar Arnfjörð Bjarmason5e9637c2011-11-17 23:14:42105void git_setup_gettext(void)
106{
Dan Jacques226c0dd2018-04-10 15:05:44107 const char *podir = getenv(GIT_TEXT_DOMAIN_DIR_ENVIRONMENT);
Johannes Schindelin02102312018-04-21 11:14:28108 char *p = NULL;
Ævar Arnfjörð Bjarmason5e9637c2011-11-17 23:14:42109
110 if (!podir)
Johannes Schindelin02102312018-04-21 11:14:28111 podir = p = system_path(GIT_LOCALE_PATH);
Dan Jacques226c0dd2018-04-10 15:05:44112
Johannes Schindelin02102312018-04-21 11:14:28113 if (!is_directory(podir)) {
114 free(p);
Johannes Schindelincc5e1bf2018-04-21 11:14:08115 return;
Johannes Schindelin02102312018-04-21 11:14:28116 }
Ævar Arnfjörð Bjarmason5e9637c2011-11-17 23:14:42117
Ævar Arnfjörð Bjarmason5e9637c2011-11-17 23:14:42118 bindtextdomain("git", podir);
119 setlocale(LC_MESSAGES, "");
Jeff Kingaa1462c2015-06-25 16:55:45120 setlocale(LC_TIME, "");
Ævar Arnfjörð Bjarmason5e9637c2011-11-17 23:14:42121 init_gettext_charset("git");
122 textdomain("git");
Johannes Schindelin02102312018-04-21 11:14:28123
Johannes Schindelinc4137be2023-02-22 11:40:55124 git_gettext_enabled = 1;
125
Johannes Schindelin02102312018-04-21 11:14:28126 free(p);
Ævar Arnfjörð Bjarmason5e9637c2011-11-17 23:14:42127}
Nguyễn Thái Ngọc Duy754395d2012-09-04 10:39:35128
129/* return the number of columns of string 's' in current locale */
130int gettext_width(const char *s)
131{
132 static int is_utf8 = -1;
133 if (is_utf8 == -1)
Nguyễn Thái Ngọc Duye8c16722016-06-25 05:22:34134 is_utf8 = is_utf8_locale();
Nguyễn Thái Ngọc Duy754395d2012-09-04 10:39:35135
136 return is_utf8 ? utf8_strwidth(s) : strlen(s);
137}
Ævar Arnfjörð Bjarmason5e9637c2011-11-17 23:14:42138#endif
Nguyễn Thái Ngọc Duye8c16722016-06-25 05:22:34139
140int is_utf8_locale(void)
141{
142#ifdef NO_GETTEXT
143 if (!charset) {
144 const char *env = getenv("LC_ALL");
145 if (!env || !*env)
146 env = getenv("LC_CTYPE");
147 if (!env || !*env)
148 env = getenv("LANG");
149 if (!env)
150 env = "";
151 if (strchr(env, '.'))
152 env = strchr(env, '.') + 1;
153 charset = xstrdup(env);
154 }
155#endif
156 return is_encoding_utf8(charset);
157}