Fix bugs when printing plurals of numbers that are not
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 16 Aug 2006 19:36:46 +0000 (19:36 +0000)
committerPaul Eggert <eggert@cs.ucla.edu>
Wed, 16 Aug 2006 19:36:46 +0000 (19:36 +0000)
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.

ChangeLog
src/dd.c
src/md5sum.c
src/system.h
src/uptime.c

index ceb5e21..5a31ecb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2006-08-16  Paul Eggert  <eggert@cs.ucla.edu>
+
+       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.
+
 2006-08-16  Bruno Haible  <bruno@clisp.org>
 
        Old versions of gzip would write --help output to stderr, and it
index 577e9a0..211c731 100644 (file)
--- a/src/dd.c
+++ b/src/dd.c
@@ -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
index 1ecd672..a8ce1cf 100644 (file)
@@ -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 423f0fa..3f6aed6 100644 (file)
@@ -383,6 +383,14 @@ static inline unsigned char to_uchar (char ch) { return 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 da8618e..bd2b0ec 100644 (file)
@@ -125,7 +125,8 @@ print_uptime (size_t n, const STRUCT_UTMP *this)
   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),