From: Bruno Haible Date: Tue, 24 Jun 2025 10:28:21 +0000 (+0200) Subject: C++: Add another unit test. X-Git-Tag: v0.26~62 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=338edb5ccc9c15e43dbd07ae2e2cf5a87118006b;p=thirdparty%2Fgettext.git C++: Add another unit test. * gettext-tools/tests/lang-c++-boost: New file, based on gettext-tools/tests/lang-c++26. * gettext-tools/tests/Makefile.am (TESTS): Add it. * gettext-tools/doc/lang-c.texi: Mention how to use C++ with the Boost library. * HACKING: Mention the Boost library. --- diff --git a/HACKING b/HACKING index 4db0505db..3a39542a1 100644 --- a/HACKING +++ b/HACKING @@ -163,6 +163,12 @@ are skipped. To this effect, you need to install also: - On Debian and Debian-based systems: gobjc, - On Red Hat distributions: gcc-objc. - Other: https://repology.org/project/gcc/versions + * The Boost C++ library + + Homepage: https://www.boost.org/ + + Pre-built package name: + - On Debian and Debian-based systems: libboost1.83-dev, + - On Red Hat distributions: boost. + - Other: https://repology.org/project/boost/versions * Python + Homepage: https://www.python.org/ diff --git a/gettext-tools/doc/lang-c.texi b/gettext-tools/doc/lang-c.texi index 9e2d97ff4..8178fe09c 100644 --- a/gettext-tools/doc/lang-c.texi +++ b/gettext-tools/doc/lang-c.texi @@ -47,12 +47,14 @@ Use @item Extractor @code{xgettext -k_} +@*For C++ with the Boost library: @code{xgettext --boost -k_} @item Formatting with positions @code{fprintf "%2$d %1$d"} @*In C++: @code{autosprintf "%2$d %1$d"} (@pxref{Top, , Introduction, autosprintf, GNU autosprintf}) @*In C++ 20 or newer: @code{std::vformat "@{1@} @{0@}"} +@*In C++ with the Boost library: @code{boost::format "%2% %1%"} @item Portability autoconf (gettext.m4) and #if ENABLE_NLS diff --git a/gettext-tools/tests/Makefile.am b/gettext-tools/tests/Makefile.am index 046d3ea3b..a1846db34 100644 --- a/gettext-tools/tests/Makefile.am +++ b/gettext-tools/tests/Makefile.am @@ -233,7 +233,7 @@ TESTS = gettext-1 gettext-2 \ plural-1 plural-2 plural-3 plural-4 \ gettextpo-1 sentence-1 \ lang-po \ - lang-c lang-c++ lang-c++20 lang-c++26 lang-objc \ + lang-c lang-c++ lang-c++-boost lang-c++20 lang-c++26 lang-objc \ lang-python-1 lang-python-2 \ lang-java \ lang-csharp \ diff --git a/gettext-tools/tests/lang-c++-boost b/gettext-tools/tests/lang-c++-boost new file mode 100755 index 000000000..59b4312b1 --- /dev/null +++ b/gettext-tools/tests/lang-c++-boost @@ -0,0 +1,185 @@ +#! /bin/sh +. "${srcdir=.}/init.sh"; path_prepend_ . ../src + +# Test of gettext facilities in the C++ language, with the Boost library. +# Assumes an fr_FR locale is installed. +# Assumes the following packages are installed: gcc g++. + +# This test fails if the gettext package was configured with --disable-nls, +# because in this case the gettext-runtime/intl/ directory does not produce +# a header file. + +# Test whether a C++ compiler is found. +test "${CXX}" != "no" || { + echo "Skipping test: no C++ compiler found" + Exit 77 +} + +# Test whether Boost is installed. +cat <<\EOF > test.cc +#include +EOF +if ${CXX} ${CXXFLAGS} ${CPPFLAGS} -c test.cc 2>/dev/null; then + : +else + echo "Skipping test: Boost library not installed" + Exit 77 +fi + +cat <<\EOF > prog.cc +#include "config.h" + +#include +#include +using namespace std; + +#include +#include +#include +#include "xsetenv.h" +#define _(string) gettext (string) + +int main (int argc, char *argv[]) +{ + int n = atoi (argv[2]); + + xsetenv ("LC_ALL", argv[1], 1); + if (setlocale (LC_ALL, "") == NULL) + // Couldn't set locale. + exit (77); + + textdomain ("prog"); + bindtextdomain ("prog", "."); + + cout << _("'Your command, please?', asked the waiter.") << endl; + + cout << boost::format (ngettext ("a piece of cake", "%1% pieces of cake", n)) + % n + << endl; + + cout << boost::format (_("%1% is replaced by %2%.")) % "FF" % "EUR" + << endl; +} +EOF + +# Compile in two steps from .cc to .o and from .o to 'prog'. This way, +# relinking is faster because doesn't need to redo the first step. +# Put the -I flags before ${CXXFLAGS} ${CPPFLAGS}, to make sure that libintl.h +# is found in the build directory, regardless of -I options present in +# ${CXXFLAGS} or ${CPPFLAGS}. +${CXX} -I../.. -I"$abs_top_srcdir"/gnulib-lib -I../../../gettext-runtime/intl ${CXXFLAGS} ${CPPFLAGS} -c prog.cc \ + || Exit 1 +# Remove the -Wl,--disable-auto-import option here that is added by +# woe32-dll.m4. Cygwin 1.7.2 does not support it in C++ mode: It gives +# a link error about 'std::cout'. +: ${CONFIG_SHELL=${SHELL-/bin/sh}} +${CONFIG_SHELL} "$top_builddir"/libtool --quiet --tag=CXX --mode=link \ + ${CXX} ${CXXFLAGS} `echo "X ${LDFLAGS} " | sed -e 's/^X//' -e 's/ -Wl,--disable-auto-import / /'` -o prog prog.${OBJEXT} \ + ../../gnulib-lib/libgettextlib.la ${LTLIBINTL} \ + || Exit 1 + +: ${XGETTEXT=xgettext} +${XGETTEXT} -o prog.tmp --omit-header --no-location --boost -k_ prog.cc || Exit 1 +LC_ALL=C tr -d '\r' < prog.tmp > prog.pot || Exit 1 + +cat <<\EOF > prog.ok +msgid "'Your command, please?', asked the waiter." +msgstr "" + +#, boost-format +msgid "a piece of cake" +msgid_plural "%1% pieces of cake" +msgstr[0] "" +msgstr[1] "" + +#, boost-format +msgid "%1% is replaced by %2%." +msgstr "" +EOF + +: ${DIFF=diff} +${DIFF} prog.ok prog.pot || Exit 1 + +cat <<\EOF > fr.po +msgid "" +msgstr "" +"Content-Type: text/plain; charset=ISO-8859-1\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "'Your command, please?', asked the waiter." +msgstr "«Votre commande, s'il vous plait», dit le garçon." + +# Les gateaux allemands sont les meilleurs du monde. +#, boost-format +msgid "a piece of cake" +msgid_plural "%1% pieces of cake" +msgstr[0] "un morceau de gateau" +msgstr[1] "%1% morceaux de gateau" + +# Reverse the arguments. +#, boost-format +msgid "%1% is replaced by %2%." +msgstr "%2% remplace %1%." +EOF + +: ${MSGMERGE=msgmerge} +${MSGMERGE} -q -o fr.po.tmp fr.po prog.pot || Exit 1 +LC_ALL=C tr -d '\r' < fr.po.tmp > fr.po.new || Exit 1 + +: ${DIFF=diff} +${DIFF} fr.po fr.po.new || Exit 1 + +test -d fr || mkdir fr +test -d fr/LC_MESSAGES || mkdir fr/LC_MESSAGES + +: ${MSGFMT=msgfmt} +${MSGFMT} -o fr/LC_MESSAGES/prog.mo fr.po + +: ${DIFF=diff} +cat <<\EOF > prog.ok +«Votre commande, s'il vous plait», dit le garçon. +2 morceaux de gateau +EUR remplace FF. +EOF +cat <<\EOF > prog.oku +«Votre commande, s'il vous plait», dit le garçon. +2 morceaux de gateau +EUR remplace FF. +EOF + +: ${LOCALE_FR=fr_FR} +: ${LOCALE_FR_UTF8=fr_FR.UTF-8} +if test $LOCALE_FR != none; then + LANGUAGE= ./prog $LOCALE_FR 2 > prog.tmp + case $? in + 0) case "$host_os" in + mingw*) LC_ALL=C tr -d '\r' < prog.tmp > prog.out || Exit 1 ;; + *) cp prog.tmp prog.out || Exit 1 ;; + esac + ${DIFF} prog.ok prog.out || Exit 1;; + 77) LOCALE_FR=none;; + *) Exit 1;; + esac +fi +if test $LOCALE_FR_UTF8 != none; then + LANGUAGE= ./prog $LOCALE_FR_UTF8 2 > prog.tmp + case $? in + 0) case "$host_os" in + mingw*) LC_ALL=C tr -d '\r' < prog.tmp > prog.out || Exit 1 ;; + *) cp prog.tmp prog.out || Exit 1 ;; + esac + ${DIFF} prog.oku prog.out || Exit 1;; + 77) LOCALE_FR_UTF8=none;; + *) Exit 1;; + esac +fi +if test $LOCALE_FR = none && test $LOCALE_FR_UTF8 = none; then + if test -f /usr/bin/localedef; then + echo "Skipping test: no french locale is installed" + else + echo "Skipping test: no french locale is supported" + fi + Exit 77 +fi + +Exit 0