This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] printf: Enable grouping decimal values


On Feb  4 13:30, Jeff Johnston wrote:
> On 01/02/10 03:47 PM, Corinna Vinschen wrote:
> >Hi,
> >
> >the below patch is derived from NetBSD code.  It enables printf/wprintf
> >grouping using the thousands' grouping character from the locale
> >information when the ' (single quote) flag character has been specified
> >in decimal conversions (i, d, u, f, F, g, G), as specified by POSIX-1.2008.
> 
> This is a tough patch to review because of all the format changes
> and ifdefs in the patch itself.
> 
> I did notice one spot where the size is being calculated and the
> grouping ptr is moved to do this calculation.  I can't see anywhere
> where you are resetting grouping before the output is written.  This
> seems like a mistake, but perhaps I am missing something.

That's correct.  In case of float values there are two runs, one to
compute the size, the number of lead digits, the number of required
separators and and the number of repetitions for the leftmost grouping.
While doing that, the grouping pointer is moved to the end of the
grouping string:


> >+				if ((flags&  GROUPING)&&  expt>  0) {
> >+					/* space for thousands' grouping */
> >+					nseps = nrepeats = 0;
> >+					lead = expt;
> >+					while (*grouping != CHAR_MAX) {
> >+						if (lead<= *grouping)
> >+							break;
> >+						lead -= *grouping;
> >+						if (grouping[1]) {
> >+							nseps++;
> >+							grouping++;
> 
> ********** here you are altering "grouping", but only size is being
> calculated.  ************************
> >+						} else
> >+							nrepeats++;
> >+					}
> >+					size += (nseps + nrepeats) * thsnd_len;
> >+				} else
> >+# endif
> >+					lead = expt;
> >+			}

Later, when the float value is actually printed, the grouping pointer
moves backward again, depending on the number of repetitions and
actual number of explicit groupings:

> >+					if (flags & GROUPING) {
> >+					    while (nseps>  0 || nrepeats>  0) {
> >+						if (nrepeats>  0)
> >+						    nrepeats--;
> >+						else {
> >+						    grouping--;
> >+						    nseps--;
> >+						}
> >+						PRINT(thousands_sep, thsnd_len);
> >+						PRINTANDPAD (cp, convbuf + ndig,
> >+							     *grouping, zeroes);
> >+						cp += *grouping;
> >+					    }
> >+					    if (cp>  convbuf + ndig)
> >+						cp = convbuf + ndig;
> >+					}

This code, even though tweaked for newlib to accommodate multibyte
thousands_seps, is identical to the NetBSD implementation.


Corinna

-- 
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]