Просмотр исходного кода

stdio: fix radix point output for %a

`%a` conversion format must output the radix point when the alternative
format is chosen, or the precision is specified and is greater than 0,
or when it's not specified and there are non-zero digits after it.

This fixes the following output for the format %.1a and the value 1.0:

	0x10p0

which should look like this:

	0x1.0p0

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Max Filippov 1 месяц назад
Родитель
Сommit
75aae164de
1 измененных файлов с 10 добавлено и 4 удалено
  1. 10 4
      libc/stdio/_fpmaxtostr.c

+ 10 - 4
libc/stdio/_fpmaxtostr.c

@@ -193,6 +193,7 @@ ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
 	int ndb = NUM_DIGIT_BLOCKS;
 	int nd = DECIMAL_DIG;
 	int sufficient_precision = 0;
+	int non_zero_digits = 0;
 #endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */
 #ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__
 	int num_groups = 0;
@@ -373,7 +374,12 @@ ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
 			s += dpb;
 			j = 0;
 			do {
-				s[- ++j] = '0' + (digit_block % base);
+				uint_fast32_t digit = (digit_block % base);
+
+				s[- ++j] = '0' + digit;
+#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
+				non_zero_digits += digit > 0;
+#endif
 				digit_block /= base;
 			} while (j < dpb);
 		} while (++i < ndb);
@@ -532,11 +538,11 @@ ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
 
 		if (PRINT_INFO_FLAG_VAL(info,alt)
 			|| (i)
-			|| ((o_mode != 'g')
+			|| ((o_mode == 'e' || o_mode == 'f') && (preci > 0))
 #ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
-				&& (o_mode != 'a')
+			|| ((o_mode == 'a')
+			    && ((info->prec < 0 && non_zero_digits > 1) || info->prec > 0))
 #endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */
-				&& (preci > 0))
 			) {
 			ppc[0] = FPO_STR_PREC;
 #ifdef __LOCALE_C_ONLY