From ee080ba2cb6cdb3aa586bd2015fd5c57f4610916 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Thu, 15 Jun 2023 23:33:50 +0200 Subject: [PATCH] Fix a bug in the last commit. * gettext-tools/src/write-mo.c (write_table): Include the number of system dependent string pairs in the computation of the hash table's size. * gettext-tools/tests/msgfmt-20: New file. * gettext-tools/tests/Makefile.am (TESTS): Add it. --- gettext-tools/src/write-mo.c | 5 +- gettext-tools/tests/Makefile.am | 2 +- gettext-tools/tests/msgfmt-20 | 100 ++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 2 deletions(-) create mode 100755 gettext-tools/tests/msgfmt-20 diff --git a/gettext-tools/src/write-mo.c b/gettext-tools/src/write-mo.c index 1809549a8..06c7cff0a 100644 --- a/gettext-tools/src/write-mo.c +++ b/gettext-tools/src/write-mo.c @@ -765,7 +765,10 @@ write_table (FILE *output_file, message_list_ty *mlp) Sorting and Searching, 1973, Addison Wesley] */ if (!omit_hash_table) { - hash_tab_size = next_prime ((nstrings * 4) / 3); + /* N is the number of static string pairs (filled in here, below) + plus the number of system dependent string pairs (filled at runtime, + in loadmsgcat.c). */ + hash_tab_size = next_prime (((nstrings + n_sysdep_strings) * 4) / 3); /* Ensure M > 2. */ if (hash_tab_size <= 2) hash_tab_size = 3; diff --git a/gettext-tools/tests/Makefile.am b/gettext-tools/tests/Makefile.am index 04a61264a..f39459e79 100644 --- a/gettext-tools/tests/Makefile.am +++ b/gettext-tools/tests/Makefile.am @@ -51,7 +51,7 @@ TESTS = gettext-1 gettext-2 \ msgfilter-sr-latin-1 msgfilter-quote-1 \ msgfmt-1 msgfmt-2 msgfmt-3 msgfmt-4 msgfmt-5 msgfmt-6 msgfmt-7 \ msgfmt-8 msgfmt-9 msgfmt-10 msgfmt-11 msgfmt-12 msgfmt-13 msgfmt-14 \ - msgfmt-15 msgfmt-16 msgfmt-17 msgfmt-18 msgfmt-19 \ + msgfmt-15 msgfmt-16 msgfmt-17 msgfmt-18 msgfmt-19 msgfmt-20 \ msgfmt-properties-1 \ msgfmt-qt-1 msgfmt-qt-2 \ msgfmt-desktop-1 msgfmt-desktop-2 msgfmt-desktop-3 \ diff --git a/gettext-tools/tests/msgfmt-20 b/gettext-tools/tests/msgfmt-20 new file mode 100755 index 000000000..4751ce9a8 --- /dev/null +++ b/gettext-tools/tests/msgfmt-20 @@ -0,0 +1,100 @@ +#! /bin/sh +. "${srcdir=.}/init.sh"; path_prepend_ . ../src + +# Test .mo file with many system dependent string pairs. +# Cf. format string directives support as in msgfmt-12, format-c-3, +# and the 'I' format directive flag as in format-c-5. + +# This test used to trigger an endless loop in loadmsgcat.c, because +# hash_tab_size was too small and the "open addressing" collision resolution +# leads to an endless loop when the hash table is full. + +cat <<\EOF > mf-20.po +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8\n" + +msgid "The trees are green." +msgstr "Les arbres sont verts." + +#, c-format +msgid "A meter has %d millimeters." +msgstr "Un mètre a %Id millimètres." + +#, c-format +msgid "A pig has %d legs." +msgstr "Un cochon a %Id pattes." + +#, c-format +msgid "The French revolution took place in %d." +msgstr "La révolution française eut lieu en %Id." + +#, c-format +msgid "Abraham died at the age of %d." +msgstr "Abraham mourut à l’âge de %Id ans." + +#, c-format +msgid "Everyone has %d fingers at each hand." +msgstr "Chacun a %Id doigts à chaque main." + +msgid "Sunshine heats." +msgstr "Le soleil tape." + +#, c-format +msgid "Most cars have %d wheels." +msgstr "La plupart des voitures a %Id roues." + +#, c-format +msgid "The oldest person is %d years old." +msgstr "La personne la plus vieille a %Id ans." + +#, c-format +msgid "Cesar tool %d years to conquer Gaul." +msgstr "César mit %Id ans à conquérir la Gaule." + +#, c-format +msgid "There are %d pyramids in Egypt." +msgstr "Il y a %Id pyramides en Égypte." + +#, c-format +msgid "The number %d causes bad luck." +msgstr "Le nombre %Id porte malheur." +EOF + +test -d fr || mkdir fr +test -d fr/LC_MESSAGES || mkdir fr/LC_MESSAGES + +: ${MSGFMT=msgfmt} +${MSGFMT} -o fr/LC_MESSAGES/mf-20.mo mf-20.po || Exit 1 + +cat < mf-20.ok +Le soleil tape. +EOF + +: ${LOCALE_FR=fr_FR} +: ${LOCALE_FR_UTF8=fr_FR.UTF-8} +: ${GETTEXT=gettext} +: ${DIFF=diff} +if test $LOCALE_FR != none; then + prepare_locale_ fr $LOCALE_FR + LC_ALL=$LOCALE_FR LANGUAGE= TEXTDOMAINDIR=. TEXTDOMAIN=mf-20 \ + ${GETTEXT} -s 'Sunshine heats.' > mf-20.tmp + LC_ALL=C tr -d '\r' < mf-20.tmp > mf-20.out + ${DIFF} mf-20.ok mf-20.out || Exit 1 +fi +if test $LOCALE_FR_UTF8 != none; then + prepare_locale_ fr $LOCALE_FR_UTF8 + LC_ALL=$LOCALE_FR_UTF8 LANGUAGE= TEXTDOMAINDIR=. TEXTDOMAIN=mf-20 \ + ${GETTEXT} -s 'Sunshine heats.' > mf-20.tmp + LC_ALL=C tr -d '\r' < mf-20.tmp > mf-20.out + ${DIFF} mf-20.ok mf-20.out || Exit 1 +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 -- 2.47.2