2013-11-26 05:03:52 +08:00
|
|
|
# This shell library is Git's interface to gettext.sh. See po/README
|
|
|
|
# for usage instructions.
|
2011-05-14 21:47:43 +08:00
|
|
|
#
|
|
|
|
# Copyright (c) 2010 Ævar Arnfjörð Bjarmason
|
|
|
|
#
|
i18n: add infrastructure for translating Git with gettext
Change the skeleton implementation of i18n in Git to one that can show
localized strings to users for our C, Shell and Perl programs using
either GNU libintl or the Solaris gettext implementation.
This new internationalization support is enabled by default. If
gettext isn't available, or if Git is compiled with
NO_GETTEXT=YesPlease, Git falls back on its current behavior of
showing interface messages in English. When using the autoconf script
we'll auto-detect if the gettext libraries are installed and act
appropriately.
This change is somewhat large because as well as adding a C, Shell and
Perl i18n interface we're adding a lot of tests for them, and for
those tests to work we need a skeleton PO file to actually test
translations. A minimal Icelandic translation is included for this
purpose. Icelandic includes multi-byte characters which makes it easy
to test various edge cases, and it's a language I happen to
understand.
The rest of the commit message goes into detail about various
sub-parts of this commit.
= Installation
Gettext .mo files will be installed and looked for in the standard
$(prefix)/share/locale path. GIT_TEXTDOMAINDIR can also be set to
override that, but that's only intended to be used to test Git itself.
= Perl
Perl code that's to be localized should use the new Git::I18n
module. It imports a __ function into the caller's package by default.
Instead of using the high level Locale::TextDomain interface I've
opted to use the low-level (equivalent to the C interface)
Locale::Messages module, which Locale::TextDomain itself uses.
Locale::TextDomain does a lot of redundant work we don't need, and
some of it would potentially introduce bugs. It tries to set the
$TEXTDOMAIN based on package of the caller, and has its own
hardcoded paths where it'll search for messages.
I found it easier just to completely avoid it rather than try to
circumvent its behavior. In any case, this is an issue wholly
internal Git::I18N. Its guts can be changed later if that's deemed
necessary.
See <AANLkTilYD_NyIZMyj9dHtVk-ylVBfvyxpCC7982LWnVd@mail.gmail.com> for
a further elaboration on this topic.
= Shell
Shell code that's to be localized should use the git-sh-i18n
library. It's basically just a wrapper for the system's gettext.sh.
If gettext.sh isn't available we'll fall back on gettext(1) if it's
available. The latter is available without the former on Solaris,
which has its own non-GNU gettext implementation. We also need to
emulate eval_gettext() there.
If neither are present we'll use a dumb printf(1) fall-through
wrapper.
= About libcharset.h and langinfo.h
We use libcharset to query the character set of the current locale if
it's available. I.e. we'll use it instead of nl_langinfo if
HAVE_LIBCHARSET_H is set.
The GNU gettext manual recommends using langinfo.h's
nl_langinfo(CODESET) to acquire the current character set, but on
systems that have libcharset.h's locale_charset() using the latter is
either saner, or the only option on those systems.
GNU and Solaris have a nl_langinfo(CODESET), FreeBSD can use either,
but MinGW and some others need to use libcharset.h's locale_charset()
instead.
=Credits
This patch is based on work by Jeff Epler <jepler@unpythonic.net> who
did the initial Makefile / C work, and a lot of comments from the Git
mailing list, including Jonathan Nieder, Jakub Narebski, Johannes
Sixt, Erik Faye-Lund, Peter Krefting, Junio C Hamano, Thomas Rast and
others.
[jc: squashed a small Makefile fix from Ramsay]
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-11-18 07:14:42 +08:00
|
|
|
|
|
|
|
# Export the TEXTDOMAIN* data that we need for Git
|
|
|
|
TEXTDOMAIN=git
|
|
|
|
export TEXTDOMAIN
|
|
|
|
if test -z "$GIT_TEXTDOMAINDIR"
|
|
|
|
then
|
|
|
|
TEXTDOMAINDIR="@@LOCALEDIR@@"
|
|
|
|
else
|
|
|
|
TEXTDOMAINDIR="$GIT_TEXTDOMAINDIR"
|
|
|
|
fi
|
|
|
|
export TEXTDOMAINDIR
|
2011-05-14 21:47:43 +08:00
|
|
|
|
2012-01-24 06:02:55 +08:00
|
|
|
# First decide what scheme to use...
|
|
|
|
GIT_INTERNAL_GETTEXT_SH_SCHEME=fallthrough
|
i18n: make GETTEXT_POISON a runtime option
Change the GETTEXT_POISON compile-time + runtime GIT_GETTEXT_POISON
test parameter to only be a GIT_TEST_GETTEXT_POISON=<non-empty?>
runtime parameter, to be consistent with other parameters documented
in "Running tests with special setups" in t/README.
When I added GETTEXT_POISON in bb946bba76 ("i18n: add GETTEXT_POISON
to simulate unfriendly translator", 2011-02-22) I was concerned with
ensuring that the _() function would get constant folded if NO_GETTEXT
was defined, and likewise that GETTEXT_POISON would be compiled out
unless it was defined.
But as the benchmark in my [1] shows doing a one-off runtime
getenv("GIT_TEST_[...]") is trivial, and since GETTEXT_POISON was
originally added the GIT_TEST_* env variables have become the common
idiom for turning on special test setups.
So change GETTEXT_POISON to work the same way. Now the
GETTEXT_POISON=YesPlease compile-time option is gone, and running the
tests with GIT_TEST_GETTEXT_POISON=[YesPlease|] can be toggled on/off
without recompiling.
This allows for conditionally amending tests to test with/without
poison, similar to what 859fdc0c3c ("commit-graph: define
GIT_TEST_COMMIT_GRAPH", 2018-08-29) did for GIT_TEST_COMMIT_GRAPH. Do
some of that, now we e.g. always run the t0205-gettext-poison.sh test.
I did enough there to remove the GETTEXT_POISON prerequisite, but its
inverse C_LOCALE_OUTPUT is still around, and surely some tests using
it can be converted to e.g. always set GIT_TEST_GETTEXT_POISON=.
Notes on the implementation:
* We still compile a dedicated GETTEXT_POISON build in Travis
CI. Perhaps this should be revisited and integrated into the
"linux-gcc" build, see ae59a4e44f ("travis: run tests with
GIT_TEST_SPLIT_INDEX", 2018-01-07) for prior art in that area. Then
again maybe not, see [2].
* We now skip a test in t0000-basic.sh under
GIT_TEST_GETTEXT_POISON=YesPlease that wasn't skipped before. This
test relies on C locale output, but due to an edge case in how the
previous implementation of GETTEXT_POISON worked (reading it from
GIT-BUILD-OPTIONS) wasn't enabling poison correctly. Now it does,
and needs to be skipped.
* The getenv() function is not reentrant, so out of paranoia about
code of the form:
printf(_("%s"), getenv("some-env"));
call use_gettext_poison() in our early setup in git_setup_gettext()
so we populate the "poison_requested" variable in a codepath that's
won't suffer from that race condition.
* We error out in the Makefile if you're still saying
GETTEXT_POISON=YesPlease to prompt users to change their
invocation.
* We should not print out poisoned messages during the test
initialization itself to keep it more readable, so the test library
hides the variable if set in $GIT_TEST_GETTEXT_POISON_ORIG during
setup. See [3].
See also [4] for more on the motivation behind this patch, and the
history of the GETTEXT_POISON facility.
1. https://public-inbox.org/git/871s8gd32p.fsf@evledraar.gmail.com/
2. https://public-inbox.org/git/20181102163725.GY30222@szeder.dev/
3. https://public-inbox.org/git/20181022202241.18629-2-szeder.dev@gmail.com/
4. https://public-inbox.org/git/878t2pd6yu.fsf@evledraar.gmail.com/
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-11-09 05:15:29 +08:00
|
|
|
if test -n "$GIT_TEST_GETTEXT_POISON"
|
2018-02-06 16:44:56 +08:00
|
|
|
then
|
|
|
|
GIT_INTERNAL_GETTEXT_SH_SCHEME=poison
|
|
|
|
elif test -n "@@USE_GETTEXT_SCHEME@@"
|
2012-01-24 06:04:29 +08:00
|
|
|
then
|
|
|
|
GIT_INTERNAL_GETTEXT_SH_SCHEME="@@USE_GETTEXT_SCHEME@@"
|
2012-03-13 05:41:15 +08:00
|
|
|
elif test -n "$GIT_INTERNAL_GETTEXT_TEST_FALLBACKS"
|
2012-01-24 06:02:55 +08:00
|
|
|
then
|
|
|
|
: no probing necessary
|
|
|
|
elif type gettext.sh >/dev/null 2>&1
|
|
|
|
then
|
|
|
|
# GNU libintl's gettext.sh
|
|
|
|
GIT_INTERNAL_GETTEXT_SH_SCHEME=gnu
|
|
|
|
elif test "$(gettext -h 2>&1)" = "-h"
|
|
|
|
then
|
|
|
|
# gettext binary exists but no gettext.sh. likely to be a gettext
|
|
|
|
# binary on a Solaris or something that is not GNU libintl and
|
|
|
|
# lack eval_gettext.
|
|
|
|
GIT_INTERNAL_GETTEXT_SH_SCHEME=gettext_without_eval_gettext
|
|
|
|
fi
|
|
|
|
export GIT_INTERNAL_GETTEXT_SH_SCHEME
|
i18n: add infrastructure for translating Git with gettext
Change the skeleton implementation of i18n in Git to one that can show
localized strings to users for our C, Shell and Perl programs using
either GNU libintl or the Solaris gettext implementation.
This new internationalization support is enabled by default. If
gettext isn't available, or if Git is compiled with
NO_GETTEXT=YesPlease, Git falls back on its current behavior of
showing interface messages in English. When using the autoconf script
we'll auto-detect if the gettext libraries are installed and act
appropriately.
This change is somewhat large because as well as adding a C, Shell and
Perl i18n interface we're adding a lot of tests for them, and for
those tests to work we need a skeleton PO file to actually test
translations. A minimal Icelandic translation is included for this
purpose. Icelandic includes multi-byte characters which makes it easy
to test various edge cases, and it's a language I happen to
understand.
The rest of the commit message goes into detail about various
sub-parts of this commit.
= Installation
Gettext .mo files will be installed and looked for in the standard
$(prefix)/share/locale path. GIT_TEXTDOMAINDIR can also be set to
override that, but that's only intended to be used to test Git itself.
= Perl
Perl code that's to be localized should use the new Git::I18n
module. It imports a __ function into the caller's package by default.
Instead of using the high level Locale::TextDomain interface I've
opted to use the low-level (equivalent to the C interface)
Locale::Messages module, which Locale::TextDomain itself uses.
Locale::TextDomain does a lot of redundant work we don't need, and
some of it would potentially introduce bugs. It tries to set the
$TEXTDOMAIN based on package of the caller, and has its own
hardcoded paths where it'll search for messages.
I found it easier just to completely avoid it rather than try to
circumvent its behavior. In any case, this is an issue wholly
internal Git::I18N. Its guts can be changed later if that's deemed
necessary.
See <AANLkTilYD_NyIZMyj9dHtVk-ylVBfvyxpCC7982LWnVd@mail.gmail.com> for
a further elaboration on this topic.
= Shell
Shell code that's to be localized should use the git-sh-i18n
library. It's basically just a wrapper for the system's gettext.sh.
If gettext.sh isn't available we'll fall back on gettext(1) if it's
available. The latter is available without the former on Solaris,
which has its own non-GNU gettext implementation. We also need to
emulate eval_gettext() there.
If neither are present we'll use a dumb printf(1) fall-through
wrapper.
= About libcharset.h and langinfo.h
We use libcharset to query the character set of the current locale if
it's available. I.e. we'll use it instead of nl_langinfo if
HAVE_LIBCHARSET_H is set.
The GNU gettext manual recommends using langinfo.h's
nl_langinfo(CODESET) to acquire the current character set, but on
systems that have libcharset.h's locale_charset() using the latter is
either saner, or the only option on those systems.
GNU and Solaris have a nl_langinfo(CODESET), FreeBSD can use either,
but MinGW and some others need to use libcharset.h's locale_charset()
instead.
=Credits
This patch is based on work by Jeff Epler <jepler@unpythonic.net> who
did the initial Makefile / C work, and a lot of comments from the Git
mailing list, including Jonathan Nieder, Jakub Narebski, Johannes
Sixt, Erik Faye-Lund, Peter Krefting, Junio C Hamano, Thomas Rast and
others.
[jc: squashed a small Makefile fix from Ramsay]
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-11-18 07:14:42 +08:00
|
|
|
|
2012-01-24 06:02:55 +08:00
|
|
|
# ... and then follow that decision.
|
|
|
|
case "$GIT_INTERNAL_GETTEXT_SH_SCHEME" in
|
|
|
|
gnu)
|
|
|
|
# Use libintl's gettext.sh, or fall back to English if we can't.
|
|
|
|
. gettext.sh
|
|
|
|
;;
|
|
|
|
gettext_without_eval_gettext)
|
|
|
|
# Solaris has a gettext(1) but no eval_gettext(1)
|
|
|
|
eval_gettext () {
|
|
|
|
gettext "$1" | (
|
|
|
|
export PATH $(git sh-i18n--envsubst --variables "$1");
|
|
|
|
git sh-i18n--envsubst "$1"
|
|
|
|
)
|
|
|
|
}
|
2016-06-18 04:21:04 +08:00
|
|
|
|
|
|
|
eval_ngettext () {
|
|
|
|
ngettext "$1" "$2" "$3" | (
|
|
|
|
export PATH $(git sh-i18n--envsubst --variables "$2");
|
|
|
|
git sh-i18n--envsubst "$2"
|
|
|
|
)
|
|
|
|
}
|
2012-01-24 06:02:55 +08:00
|
|
|
;;
|
|
|
|
poison)
|
|
|
|
# Emit garbage so that tests that incorrectly rely on translatable
|
|
|
|
# strings will fail.
|
2011-05-14 21:47:44 +08:00
|
|
|
gettext () {
|
|
|
|
printf "%s" "# GETTEXT POISON #"
|
|
|
|
}
|
|
|
|
|
|
|
|
eval_gettext () {
|
|
|
|
printf "%s" "# GETTEXT POISON #"
|
|
|
|
}
|
2016-06-18 04:21:04 +08:00
|
|
|
|
|
|
|
eval_ngettext () {
|
|
|
|
printf "%s" "# GETTEXT POISON #"
|
|
|
|
}
|
2012-01-24 06:02:55 +08:00
|
|
|
;;
|
|
|
|
*)
|
|
|
|
gettext () {
|
|
|
|
printf "%s" "$1"
|
|
|
|
}
|
|
|
|
|
|
|
|
eval_gettext () {
|
|
|
|
printf "%s" "$1" | (
|
|
|
|
export PATH $(git sh-i18n--envsubst --variables "$1");
|
|
|
|
git sh-i18n--envsubst "$1"
|
|
|
|
)
|
|
|
|
}
|
2016-06-18 04:21:04 +08:00
|
|
|
|
|
|
|
eval_ngettext () {
|
|
|
|
(test "$3" = 1 && printf "%s" "$1" || printf "%s" "$2") | (
|
|
|
|
export PATH $(git sh-i18n--envsubst --variables "$2");
|
|
|
|
git sh-i18n--envsubst "$2"
|
|
|
|
)
|
|
|
|
}
|
2012-01-24 06:02:55 +08:00
|
|
|
;;
|
|
|
|
esac
|
2011-05-14 21:47:43 +08:00
|
|
|
|
i18n: add infrastructure for translating Git with gettext
Change the skeleton implementation of i18n in Git to one that can show
localized strings to users for our C, Shell and Perl programs using
either GNU libintl or the Solaris gettext implementation.
This new internationalization support is enabled by default. If
gettext isn't available, or if Git is compiled with
NO_GETTEXT=YesPlease, Git falls back on its current behavior of
showing interface messages in English. When using the autoconf script
we'll auto-detect if the gettext libraries are installed and act
appropriately.
This change is somewhat large because as well as adding a C, Shell and
Perl i18n interface we're adding a lot of tests for them, and for
those tests to work we need a skeleton PO file to actually test
translations. A minimal Icelandic translation is included for this
purpose. Icelandic includes multi-byte characters which makes it easy
to test various edge cases, and it's a language I happen to
understand.
The rest of the commit message goes into detail about various
sub-parts of this commit.
= Installation
Gettext .mo files will be installed and looked for in the standard
$(prefix)/share/locale path. GIT_TEXTDOMAINDIR can also be set to
override that, but that's only intended to be used to test Git itself.
= Perl
Perl code that's to be localized should use the new Git::I18n
module. It imports a __ function into the caller's package by default.
Instead of using the high level Locale::TextDomain interface I've
opted to use the low-level (equivalent to the C interface)
Locale::Messages module, which Locale::TextDomain itself uses.
Locale::TextDomain does a lot of redundant work we don't need, and
some of it would potentially introduce bugs. It tries to set the
$TEXTDOMAIN based on package of the caller, and has its own
hardcoded paths where it'll search for messages.
I found it easier just to completely avoid it rather than try to
circumvent its behavior. In any case, this is an issue wholly
internal Git::I18N. Its guts can be changed later if that's deemed
necessary.
See <AANLkTilYD_NyIZMyj9dHtVk-ylVBfvyxpCC7982LWnVd@mail.gmail.com> for
a further elaboration on this topic.
= Shell
Shell code that's to be localized should use the git-sh-i18n
library. It's basically just a wrapper for the system's gettext.sh.
If gettext.sh isn't available we'll fall back on gettext(1) if it's
available. The latter is available without the former on Solaris,
which has its own non-GNU gettext implementation. We also need to
emulate eval_gettext() there.
If neither are present we'll use a dumb printf(1) fall-through
wrapper.
= About libcharset.h and langinfo.h
We use libcharset to query the character set of the current locale if
it's available. I.e. we'll use it instead of nl_langinfo if
HAVE_LIBCHARSET_H is set.
The GNU gettext manual recommends using langinfo.h's
nl_langinfo(CODESET) to acquire the current character set, but on
systems that have libcharset.h's locale_charset() using the latter is
either saner, or the only option on those systems.
GNU and Solaris have a nl_langinfo(CODESET), FreeBSD can use either,
but MinGW and some others need to use libcharset.h's locale_charset()
instead.
=Credits
This patch is based on work by Jeff Epler <jepler@unpythonic.net> who
did the initial Makefile / C work, and a lot of comments from the Git
mailing list, including Jonathan Nieder, Jakub Narebski, Johannes
Sixt, Erik Faye-Lund, Peter Krefting, Junio C Hamano, Thomas Rast and
others.
[jc: squashed a small Makefile fix from Ramsay]
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-11-18 07:14:42 +08:00
|
|
|
# Git-specific wrapper functions
|
|
|
|
gettextln () {
|
|
|
|
gettext "$1"
|
|
|
|
echo
|
|
|
|
}
|
|
|
|
|
|
|
|
eval_gettextln () {
|
|
|
|
eval_gettext "$1"
|
|
|
|
echo
|
|
|
|
}
|