summaryrefslogtreecommitdiff
path: root/gettext.c
diff options
context:
space:
mode:
Diffstat (limited to 'gettext.c')
-rw-r--r--gettext.c60
1 files changed, 54 insertions, 6 deletions
diff --git a/gettext.c b/gettext.c
index f75bca7f56..a268a2c52c 100644
--- a/gettext.c
+++ b/gettext.c
@@ -4,6 +4,8 @@
#include "git-compat-util.h"
#include "gettext.h"
+#include "strbuf.h"
+#include "utf8.h"
#ifndef NO_GETTEXT
# include <locale.h>
@@ -16,6 +18,31 @@
# endif
#endif
+/*
+ * 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;
+}
+
#ifdef GETTEXT_POISON
int use_gettext_poison(void)
{
@@ -27,10 +54,20 @@ int use_gettext_poison(void)
#endif
#ifndef NO_GETTEXT
-static void init_gettext_charset(const char *domain)
+static int test_vsnprintf(const char *fmt, ...)
{
- const char *charset;
+ 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 const char *charset;
+static void init_gettext_charset(const char *domain)
+{
/*
This trick arranges for messages to be emitted in the user's
requested encoding, but avoids setting LC_CTYPE from the
@@ -98,9 +135,7 @@ static void init_gettext_charset(const char *domain)
$ LANGUAGE= LANG=de_DE.utf8 ./test
test: Kein passendes Ger?t gefunden
- In the long term we should probably see about getting that
- vsnprintf bug in glibc fixed, and audit our code so it won't
- fall apart under a non-C locale.
+ The vsnprintf bug has been fixed since glibc 2.17.
Then we could simply set LC_CTYPE from the environment, which would
make things like the external perror(3) messages work.
@@ -114,7 +149,9 @@ static void init_gettext_charset(const char *domain)
setlocale(LC_CTYPE, "");
charset = locale_charset();
bind_textdomain_codeset(domain, charset);
- setlocale(LC_CTYPE, "C");
+ /* the string is taken from v0.99.6~1 */
+ if (test_vsnprintf("%.*s", 13, "David_K\345gedal") < 0)
+ setlocale(LC_CTYPE, "C");
}
void git_setup_gettext(void)
@@ -125,7 +162,18 @@ void git_setup_gettext(void)
podir = GIT_LOCALE_PATH;
bindtextdomain("git", podir);
setlocale(LC_MESSAGES, "");
+ setlocale(LC_TIME, "");
init_gettext_charset("git");
textdomain("git");
}
+
+/* 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 = !strcmp(charset, "UTF-8");
+
+ return is_utf8 ? utf8_strwidth(s) : strlen(s);
+}
#endif