On Thu, Nov 30, 2017 at 01:33:48PM +0100, Jakub Jelinek wrote: > On Thu, Nov 30, 2017 at 01:01:58PM +0100, Jakub Jelinek wrote: > > I just followed: > > https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/Plural-forms.html > > > > "About larger integer types, such as ‘uintmax_t’ or ‘unsigned long long’: > > they can be > > handled by reducing the value to a range that fits in an ‘unsigned long’. > > Simply > > casting the value to ‘unsigned long’ would not do the right thing, since it > > would > > treat ULONG_MAX + 1 like zero, ULONG_MAX + 2 like singular, and the like. > > Here you > > can exploit the fact that all mentioned plural form formulas eventually > > become periodic, > > with a period that is a divisor of 100 (or 1000 or 1000000). So, when you > > reduce a large > > value to another one in the range [1000000, 1999999] that ends in the same > > 6 decimal > > digits, you can assume that it will lead to the same plural form selection. > > This code > > does this: > > > > #include <inttypes.h> > > uintmax_t nbytes = ...; > > printf (ngettext ("The file has %"PRIuMAX" byte.", > > "The file has %"PRIuMAX" bytes.", > > (nbytes > ULONG_MAX > > ? (nbytes % 1000000) + 1000000 > > : nbytes)), > > nbytes);" > > > > I can surely add a comment about that. > > > > Note the patch depends on the > > https://gcc.gnu.org/ml/gcc-patches/2017-11/msg02521.html > > patch. > > Though, looking at our *_n diagnostic routines, the n argument is actually > int there, not unsigned long for some reason. So, either we should fix > that (seems ngettext has unsigned long), or the above would need to be > (unsigned HOST_WIDE_INT) (int) eltscnt != eltscnt || (int) eltscnt < 0
Of course better eltscnt > INT_MAX Jakub