implement printf("%a")

Jeff Johnston
Fri May 11 13:09:00 GMT 2007

Yes, the code with modification is fine and can be checked in.

However, after testing this and thinking about it, we need to 
enable/disable the C99 format specifiers at will.  The majority of 
embedded platforms do not need/use the C99 specifiers and it adds bulk 
to the executable size.

Thus, I am proposing a _WANT_IO_C99 flag (optionally 
_WANT_IO_C99_FORMATS).  The default is no for all platforms except for 
*-linux and Cygwin where it will default to yes.  The flag will remove 
the 'a', 'A', 'z', etc... specifiers that do not appear in C90.

This would be implemented the same as long_long and long_double are 
today and have a configure option.

-- Jeff J.

Eric Blake wrote:
> Eric Blake <ebb9 <at>> writes:
>> Here it goes; tested on cygwin using the gnulib printf-posix testsuite [1]; 
>> this passes all tests that used to require a gnulib replacement function.
> It passed the gnulib testsuite on cygwin by sheer dumb luck, because the single-
> threaded testsuite never used more than eight hex digits and snprintf didn't 
> trigger an intermediate malloc.  I was able to get asnprintf to corrupt the 
> heap; and multithreaded malloc'ing could do likewise.
>>  <at>  <at>  -892,10 +885,33  <at>  <at>  reswitch:	switch (ch) {
>>  			}
>>  #endif /* !_NO_LONGDBL */
>> +			if (ch == 'a' || ch == 'A') {
>> +				ox[0] = '0';
>> +				ox[1] = ch == 'a' ? 'x' : 'X';
>> +				flags |= HEXPREFIX;
>> +				if (prec >= sizeof buf)
> prec is -1 for %a, but sizeof is unsigned.  The unsigned comparison led to 
> mallocing 0 bytes (and the consequent heap corruption when writing beyond the 8-
> byte bounds of the malloc granularity).  The conditional should instead 
> be "prec >= (int) (sizeof buf)", or simply "prec >= BUF", to force signed 
> comparison.
> With that correction, is this patch okay to commit?

More information about the Newlib mailing list