In the thread rooted at <http://lists.gnu.org/archive/html/bug-coreutils/2006-08/msg00082.html> Koblinger Egmont <[EMAIL PROTECTED]> writes:
> What is the correct approach if the number isn't presented in the string, as > in his "This item" vs. "These items" case? Should ngettext be used in this > case? Or this piece of code a good programming approach: > if (n == 1) printf(_("This item...")); else printf(_("These items...")); ? That's a tricky question, so I'll forward this email to the gettext maintainer. I just now reviewed the gettext manual and led me to some other translation glitches in coreutils. I installed the following patch to coreutils. This sort of thing should be documented in the gettext manual, and I'll follow up with another message about that. 2006-08-16 Paul Eggert <[EMAIL PROTECTED]> Fix bugs when printing plurals of numbers that are not unsigned long int values. * src/system.h (select_plural): New function. * src/md5sum.c (digest_check): Use select_plural to avoid bug. * src/uptime.c (print_uptime): Likewise. * src/dd.c (print_stats): Likewise. Also, don't use ngettext to print a floating point number, as reducing to 0 or 1 doesn't work for some languages. Instead, just use "s" for seconds since it doesn't need a plural form. Index: src/system.h =================================================================== RCS file: /fetish/cu/src/system.h,v retrieving revision 1.150 diff -p -u -r1.150 system.h --- src/system.h 11 Jul 2006 17:22:15 -0000 1.150 +++ src/system.h 16 Aug 2006 19:34:55 -0000 @@ -383,6 +383,14 @@ static inline unsigned char to_uchar (ch #define _(msgid) gettext (msgid) #define N_(msgid) msgid +/* Return a value that pluralizes the same way that N does, in all + languages we know of. */ +static inline unsigned long int +select_plural (uintmax_t n) +{ + return (n <= ULONG_MAX ? n : n % 1000 + 1000); +} + #define STREQ(a, b) (strcmp ((a), (b)) == 0) #if !HAVE_DECL_FREE Index: src/md5sum.c =================================================================== RCS file: /fetish/cu/src/md5sum.c,v retrieving revision 1.146 diff -p -u -r1.146 md5sum.c --- src/md5sum.c 9 Jul 2006 17:08:55 -0000 1.146 +++ src/md5sum.c 16 Aug 2006 19:34:55 -0000 @@ -563,7 +563,7 @@ digest_check (const char *checkfile_name " listed file could not be read", "WARNING: %" PRIuMAX " of %" PRIuMAX " listed files could not be read", - n_properly_formatted_lines), + select_plural (n_properly_formatted_lines)), n_open_or_read_failures, n_properly_formatted_lines); if (n_mismatched_checksums != 0) @@ -575,7 +575,7 @@ digest_check (const char *checkfile_name " computed checksum did NOT match", "WARNING: %" PRIuMAX " of %" PRIuMAX " computed checksums did NOT match", - n_computed_checksums), + select_plural (n_computed_checksums)), n_mismatched_checksums, n_computed_checksums); } } Index: src/uptime.c =================================================================== RCS file: /fetish/cu/src/uptime.c,v retrieving revision 1.54 diff -p -u -r1.54 uptime.c --- src/uptime.c 3 Dec 2005 23:24:46 -0000 1.54 +++ src/uptime.c 16 Aug 2006 19:34:55 -0000 @@ -125,7 +125,8 @@ print_uptime (size_t n, const STRUCT_UTM else { if (0 < updays) - printf (ngettext ("%ld day", "%ld days", updays), updays); + printf (ngettext ("%ld day", "%ld days", select_plural (updays)), + updays); printf (" %2d:%02d, ", uphours, upmins); } printf (ngettext ("%lu user", "%lu users", entries), Index: src/dd.c =================================================================== RCS file: /fetish/cu/src/dd.c,v retrieving revision 1.197 diff -p -u -r1.197 dd.c --- src/dd.c 15 Aug 2006 20:50:22 -0000 1.197 +++ src/dd.c 16 Aug 2006 19:34:55 -0000 @@ -550,7 +550,7 @@ print_stats (void) fprintf (stderr, ngettext ("%"PRIuMAX" truncated record\n", "%"PRIuMAX" truncated records\n", - MIN (r_truncate, ULONG_MAX)), + select_plural (r_truncate)), r_truncate); if (status_flags & STATUS_NOXFER) @@ -562,7 +562,7 @@ print_stats (void) fprintf (stderr, ngettext ("%"PRIuMAX" byte (%s) copied", "%"PRIuMAX" bytes (%s) copied", - MIN (w_bytes, ULONG_MAX)), + select_plural (w_bytes)), w_bytes, human_readable (w_bytes, hbuf, human_opts, 1, 1)); @@ -581,10 +581,17 @@ print_stats (void) bytes_per_second = _("Infinity B"); } - fprintf (stderr, - ngettext (", %g second, %s/s\n", - ", %g seconds, %s/s\n", delta_s == 1), - delta_s, bytes_per_second); + /* TRANSLATORS: The two instances of "s" in this string are the SI + symbol "s" (meaning second), and should not be translated. + + This format used to be: + + ngettext (", %g second, %s/s\n", ", %g seconds, %s/s\n", delta_s == 1) + + but that was incorrect for languages like Polish. To fix this + bug we now use SI symbols even though they're a bit more + confusing in English. */ + fprintf (stderr, _(", %g s, %s/s\n"), delta_s, bytes_per_second); } static void _______________________________________________ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils