@@ -231,40 +231,46 @@ static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen
231
231
static size_t _ntoa_format (out_fct_type out , char * buffer , size_t idx , size_t maxlen , char * buf , size_t len , bool negative , unsigned int base , unsigned int prec , unsigned int width , unsigned int flags )
232
232
{
233
233
// pad leading zeros
234
- if (!(flags & FLAGS_LEFT )) {
235
- if (width && (flags & FLAGS_ZEROPAD ) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE )))) {
236
- width -- ;
237
- }
238
- while ((len < prec ) && (len < PRINTF_NTOA_BUFFER_SIZE )) {
239
- buf [len ++ ] = '0' ;
240
- }
241
- while ((flags & FLAGS_ZEROPAD ) && (len < width ) && (len < PRINTF_NTOA_BUFFER_SIZE )) {
242
- buf [len ++ ] = '0' ;
234
+ int zeropad = 0 ;
235
+ if (flags & FLAGS_PRECISION ) {
236
+ // no other source of zero-padding if prec is specified
237
+ zeropad = (int )(prec - len );
243
238
}
239
+ else if (flags & FLAGS_ZEROPAD ) {
240
+ zeropad = (int )(width - len );
241
+ if (negative || flags & (FLAGS_PLUS | FLAGS_SPACE )) {
242
+ // keep one position for sign
243
+ zeropad -- ;
244
244
}
245
-
246
- // handle hash
247
245
if (flags & FLAGS_HASH ) {
248
- if (!( flags & FLAGS_PRECISION ) && len && (( len == prec ) || ( len == width ))) {
249
- len -- ;
250
- if (len && ( base == 16U ) ) {
251
- len -- ;
246
+ // keep space for 0x / 0b
247
+ // octal is handled separately
248
+ if (base == 16U || base == 2U ) {
249
+ zeropad -= 2 ;
252
250
}
253
251
}
254
- if ((base == 16U ) && !(flags & FLAGS_UPPERCASE ) && (len < PRINTF_NTOA_BUFFER_SIZE )) {
255
- buf [len ++ ] = 'x' ;
256
252
}
257
- else if ((base == 16U ) && (flags & FLAGS_UPPERCASE ) && (len < PRINTF_NTOA_BUFFER_SIZE )) {
258
- buf [len ++ ] = 'X' ;
253
+
254
+ while ((zeropad -- > 0 ) && (len < PRINTF_NTOA_BUFFER_SIZE )) {
255
+ buf [len ++ ] = '0' ;
259
256
}
260
- else if ((base == 2U ) && (len < PRINTF_NTOA_BUFFER_SIZE )) {
257
+
258
+ // handle hash
259
+ if (flags & FLAGS_HASH ) {
260
+ if (base == 2 && len < PRINTF_NTOA_BUFFER_SIZE - 1 ) {
261
261
buf [len ++ ] = 'b' ;
262
+ buf [len ++ ] = '0' ;
262
263
}
263
- if (len < PRINTF_NTOA_BUFFER_SIZE ) {
264
+ // pesky octal case. Add 0 prefix only if following digit is not zero (both from value and zero-padding)
265
+ if (base == 8 && len < PRINTF_NTOA_BUFFER_SIZE && (!len || buf [len - 1 ] != '0' )) {
264
266
buf [len ++ ] = '0' ;
265
267
}
268
+ if (base == 16 && len < PRINTF_NTOA_BUFFER_SIZE - 1 ) {
269
+ buf [len ++ ] = (flags & FLAGS_UPPERCASE ) ? 'X' : 'x' ;
270
+ buf [len ++ ] = '0' ;
266
271
}
267
-
272
+ }
273
+ // handle '+', '-', ' '
268
274
if (len < PRINTF_NTOA_BUFFER_SIZE ) {
269
275
if (negative ) {
270
276
buf [len ++ ] = '-' ;
@@ -287,12 +293,13 @@ static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxl
287
293
char buf [PRINTF_NTOA_BUFFER_SIZE ];
288
294
size_t len = 0U ;
289
295
290
- // no hash for 0 values
291
- if (!value ) {
296
+ // no hash for 0 values, except octal 0 */
297
+ if (!value && ( base != 8 ) ) {
292
298
flags &= ~FLAGS_HASH ;
293
299
}
294
300
295
- // write if precision != 0 and value is != 0
301
+ // if precision is specified and zero, don't print zero value
302
+ // if precision > 0, zero padding code will supply at least one zero
296
303
if (!(flags & FLAGS_PRECISION ) || value ) {
297
304
do {
298
305
const char digit = (char )(value % base );
@@ -313,11 +320,12 @@ static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t
313
320
size_t len = 0U ;
314
321
315
322
// no hash for 0 values
316
- if (!value ) {
323
+ if (!value && ( base != 8 ) ) {
317
324
flags &= ~FLAGS_HASH ;
318
325
}
319
326
320
- // write if precision != 0 and value is != 0
327
+ // if precision is specified and zero, don't print zero value
328
+ // if precision > 0, zero padding code will supply at least one zero
321
329
if (!(flags & FLAGS_PRECISION ) || value ) {
322
330
do {
323
331
const char digit = (char )(value % base );
@@ -761,6 +769,9 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
761
769
#if defined(PRINTF_SUPPORT_FLOAT )
762
770
case 'f' :
763
771
case 'F' :
772
+ if (flags & FLAGS_LEFT ) {
773
+ flags &= ~FLAGS_ZEROPAD ;
774
+ }
764
775
if (* format == 'F' ) flags |= FLAGS_UPPERCASE ;
765
776
idx = _ftoa (out , buffer , idx , maxlen , va_arg (va , double ), precision , width , flags );
766
777
format ++ ;
@@ -770,6 +781,9 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
770
781
case 'E' :
771
782
case 'g' :
772
783
case 'G' :
784
+ if (flags & FLAGS_LEFT ) {
785
+ flags &= ~FLAGS_ZEROPAD ;
786
+ }
773
787
if ((* format == 'g' )|| (* format == 'G' )) flags |= FLAGS_ADAPT_EXP ;
774
788
if ((* format == 'E' )|| (* format == 'G' )) flags |= FLAGS_UPPERCASE ;
775
789
idx = _etoa (out , buffer , idx , maxlen , va_arg (va , double ), precision , width , flags );
0 commit comments