Skip to content

Commit 4b9b8ef

Browse files
committed
tinystdio: Clean up vfprintf. Avoid extra exponent width tests.
Share some code between skip_to_arg and vfprintf. Move float conversion selection code to dtoa.h. Use _NEED_IO_FLOAT64 and _NEED_IO_FLOAT_LARGE instead of _NEED_IO_DOUBLE and NEED_IO_LONG_DOUBLE when determining how many possible exponent digits there are as those will skip tests on targets with smaller float ranges. Signed-off-by: Keith Packard <[email protected]>
1 parent f976423 commit 4b9b8ef

File tree

2 files changed

+71
-112
lines changed

2 files changed

+71
-112
lines changed

newlib/libc/tinystdio/dtoa.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,24 +67,32 @@
6767
# if __SIZEOF_LONG_DOUBLE__ == 4
6868
# define _NEED_IO_FLOAT32
6969
# define LONG_FLOAT_MAX_DIG FTOA_MAX_DIG
70+
# define __lfloat_d_engine __ftoa_engine
71+
# define __lfloat_x_engine __ftox_engine
7072
# elif __SIZEOF_LONG_DOUBLE__ == 8
7173
# define _NEED_IO_FLOAT64
7274
# define LONG_FLOAT_MAX_DIG DTOA_MAX_DIG
75+
# define __lfloat_d_engine __dtoa_engine
76+
# define __lfloat_x_engine __dtox_engine
7377
# elif __SIZEOF_LONG_DOUBLE__ > 8
7478
# define _NEED_IO_FLOAT_LARGE
7579
# define LONG_FLOAT_MAX_DIG LDTOA_MAX_DIG
80+
# define __lfloat_d_engine __ldtoa_engine
81+
# define __lfloat_x_engine __ldtox_engine
7682
# endif
7783
#endif
7884

7985
#ifdef _NEED_IO_DOUBLE
8086
# if __SIZEOF_DOUBLE__ == 4
8187
# define _NEED_IO_FLOAT32
8288
# define FLOAT_MAX_DIG FTOA_MAX_DIG
83-
# define __float_engine __ftoa_engine
89+
# define __float_d_engine __ftoa_engine
90+
# define __float_x_engine __ftox_engine
8491
# elif __SIZEOF_DOUBLE__ == 8
8592
# define _NEED_IO_FLOAT64
8693
# define FLOAT_MAX_DIG DTOA_MAX_DIG
87-
# define __float_engine __dtoa_engine
94+
# define __float_d_engine __dtoa_engine
95+
# define __float_x_engine __dtox_engine
8896
# endif
8997
# define PRINTF_FLOAT_ARG(ap) (va_arg(ap, double))
9098
#endif
@@ -93,7 +101,8 @@
93101
# define _NEED_IO_FLOAT32
94102
# define PRINTF_FLOAT_ARG(ap) (asfloat(va_arg(ap, uint32_t)))
95103
# define FLOAT_MAX_DIG FTOA_MAX_DIG
96-
# define __float_engine __ftoa_engine
104+
# define __float_d_engine __ftoa_engine
105+
# define __float_x_engine __ftox_engine
97106
#endif
98107

99108
#ifdef _NEED_IO_FLOAT_LARGE

newlib/libc/tinystdio/vfprintf.c

Lines changed: 59 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,54 @@ typedef long ultoa_signed_t;
251251
#define FL_FLTEXP 0x1000
252252
#define FL_FLTFIX 0x2000
253253

254+
#ifdef _NEED_IO_C99_FORMATS
255+
256+
#define CHECK_INT_SIZE(c, flags, letter, type) \
257+
if (c == letter) { \
258+
if (sizeof(type) == sizeof(int)) \
259+
; \
260+
else if (sizeof(type) == sizeof(long)) \
261+
flags |= FL_LONG; \
262+
else if (sizeof(type) == sizeof(long long)) \
263+
flags |= FL_LONG|FL_REPD_TYPE; \
264+
else if (sizeof(type) == sizeof(short)) \
265+
flags |= FL_SHORT; \
266+
continue; \
267+
}
268+
269+
#define CHECK_C99_INT_SIZES(c, flags) \
270+
CHECK_INT_SIZE(c, flags, 'j', intmax_t); \
271+
CHECK_INT_SIZE(c, flags, 'z', size_t); \
272+
CHECK_INT_SIZE(c, flags, 't', ptrdiff_t);
273+
274+
#else
275+
#define CHECK_C99_INT_SIZES(c, flags)
276+
#endif
277+
278+
#define CHECK_INT_SIZES(c, flags) { \
279+
if (c == 'l') { \
280+
if (flags & FL_LONG) \
281+
flags |= FL_REPD_TYPE; \
282+
flags |= FL_LONG; \
283+
continue; \
284+
} \
285+
\
286+
if (c == 'h') { \
287+
if (flags & FL_SHORT) \
288+
flags |= FL_REPD_TYPE; \
289+
flags |= FL_SHORT; \
290+
continue; \
291+
} \
292+
\
293+
/* alias for 'll' */ \
294+
if (c == 'L') { \
295+
flags |= FL_REPD_TYPE; \
296+
flags |= FL_LONG; \
297+
continue; \
298+
} \
299+
CHECK_C99_INT_SIZES(c, flags); \
300+
}
301+
254302
#ifdef _NEED_IO_POS_ARGS
255303

256304
typedef struct {
@@ -344,47 +392,8 @@ skip_to_arg(const CHAR *fmt_orig, my_va_list *ap, int target_argno)
344392
}
345393
}
346394

347-
if (c == 'l') {
348-
if (flags & FL_LONG)
349-
flags |= FL_REPD_TYPE;
350-
flags |= FL_LONG;
351-
continue;
352-
}
395+
CHECK_INT_SIZES(c, flags);
353396

354-
if (c == 'h') {
355-
if (flags & FL_SHORT)
356-
flags |= FL_REPD_TYPE;
357-
flags |= FL_SHORT;
358-
continue;
359-
}
360-
361-
/* alias for 'll' */
362-
if (c == 'L') {
363-
flags |= FL_REPD_TYPE;
364-
flags |= FL_LONG;
365-
continue;
366-
}
367-
368-
#ifdef _NEED_IO_C99_FORMATS
369-
370-
#define CHECK_LONGLONG(type) else if (sizeof(type) == sizeof(long long)) flags |= FL_LONG|FL_REPD_TYPE;
371-
372-
#define CHECK_INT_SIZE(letter, type) \
373-
if (c == letter) { \
374-
if (sizeof(type) == sizeof(int)) \
375-
; \
376-
else if (sizeof(type) == sizeof(long)) \
377-
flags |= FL_LONG; \
378-
CHECK_LONGLONG(type) \
379-
else if (sizeof(type) == sizeof(short)) \
380-
flags |= FL_SHORT; \
381-
continue; \
382-
}
383-
384-
CHECK_INT_SIZE('j', intmax_t);
385-
CHECK_INT_SIZE('z', size_t);
386-
CHECK_INT_SIZE('t', ptrdiff_t);
387-
#endif
388397
break;
389398
} while ( (c = *fmt++) != 0);
390399
if (argno == 0)
@@ -575,47 +584,7 @@ int vfprintf (FILE * stream, const CHAR *fmt, va_list ap_orig)
575584
#endif
576585
}
577586

578-
if (c == 'l') {
579-
if (flags & FL_LONG)
580-
flags |= FL_REPD_TYPE;
581-
flags |= FL_LONG;
582-
continue;
583-
}
584-
585-
if (c == 'h') {
586-
if (flags & FL_SHORT)
587-
flags |= FL_REPD_TYPE;
588-
flags |= FL_SHORT;
589-
continue;
590-
}
591-
592-
/* alias for 'll' */
593-
if (c == 'L') {
594-
flags |= FL_REPD_TYPE;
595-
flags |= FL_LONG;
596-
continue;
597-
}
598-
599-
#define CHECK_LONGLONG(type) else if (sizeof(type) == sizeof(long long)) flags |= FL_LONG|FL_REPD_TYPE;
600-
601-
#ifdef _NEED_IO_C99_FORMATS
602-
603-
#define CHECK_INT_SIZE(letter, type) \
604-
if (c == letter) { \
605-
if (sizeof(type) == sizeof(int)) \
606-
; \
607-
else if (sizeof(type) == sizeof(long)) \
608-
flags |= FL_LONG; \
609-
CHECK_LONGLONG(type) \
610-
else if (sizeof(type) == sizeof(short)) \
611-
flags |= FL_SHORT; \
612-
continue; \
613-
}
614-
615-
CHECK_INT_SIZE('j', intmax_t);
616-
CHECK_INT_SIZE('z', size_t);
617-
CHECK_INT_SIZE('t', ptrdiff_t);
618-
#endif
587+
CHECK_INT_SIZES(c, flags);
619588

620589
break;
621590
} while ( (c = *fmt++) != 0);
@@ -643,10 +612,6 @@ int vfprintf (FILE * stream, const CHAR *fmt, va_list ap_orig)
643612

644613
/* Only a format character is valid. */
645614

646-
#if 'F' != 'E'+1 || 'G' != 'F'+1 || 'f' != 'e'+1 || 'g' != 'f'+1
647-
# error
648-
#endif
649-
650615
#define TOCASE(c) ((c) - case_convert)
651616

652617
#ifndef _NEED_IO_SHRINK
@@ -684,13 +649,7 @@ int vfprintf (FILE * stream, const CHAR *fmt, va_list ap_orig)
684649

685650
if (!(flags & FL_PREC))
686651
prec = -1;
687-
#ifdef _NEED_IO_FLOAT_LARGE
688-
prec = __ldtox_engine(fval, &dtoa, prec, case_convert);
689-
#elif __SIZEOF_LONG_DOUBLE__ == 8
690-
prec = __dtox_engine(fval, &dtoa, prec, case_convert);
691-
#elif __SIZEOF_LONG_DOUBLE__ == 4
692-
prec = __ftox_engine(fval, &dtoa, prec, case_convert);
693-
#endif
652+
prec = __lfloat_x_engine(fval, &dtoa, prec, case_convert);
694653
ndigs = prec + 1;
695654
exp = dtoa.exp;
696655
ndigs_exp = 1;
@@ -719,13 +678,8 @@ int vfprintf (FILE * stream, const CHAR *fmt, va_list ap_orig)
719678
if (ndigs > LONG_FLOAT_MAX_DIG)
720679
ndigs = LONG_FLOAT_MAX_DIG;
721680

722-
#ifdef _NEED_IO_FLOAT_LARGE
723-
ndigs = __ldtoa_engine(fval, &dtoa, ndigs, fmode, ndecimal);
724-
#elif __SIZEOF_LONG_DOUBLE__ == 8
725-
ndigs = __dtoa_engine((FLOAT64) fval, &dtoa, ndigs, fmode, ndecimal);
726-
#elif __SIZEOF_LONG_DOUBLE__ == 4
727-
ndigs = __ftoa_engine ((float) fval, &dtoa, ndigs, fmode, ndecimal);
728-
#endif
681+
ndigs = __lfloat_d_engine(fval, &dtoa, ndigs, fmode, ndecimal);
682+
729683
exp = dtoa.exp;
730684
ndigs_exp = 2;
731685
}
@@ -747,11 +701,7 @@ int vfprintf (FILE * stream, const CHAR *fmt, va_list ap_orig)
747701
if (!(flags & FL_PREC))
748702
prec = -1;
749703

750-
#if defined(_NEED_IO_DOUBLE) && __SIZEOF_DOUBLE__ == 8
751-
prec = __dtox_engine(fval, &dtoa, prec, case_convert);
752-
#else
753-
prec = __ftox_engine(fval, &dtoa, prec, case_convert);
754-
#endif
704+
prec = __float_x_engine(fval, &dtoa, prec, case_convert);
755705
ndigs = prec + 1;
756706
exp = dtoa.exp;
757707
ndigs_exp = 1;
@@ -780,7 +730,7 @@ int vfprintf (FILE * stream, const CHAR *fmt, va_list ap_orig)
780730
if (ndigs > FLOAT_MAX_DIG)
781731
ndigs = FLOAT_MAX_DIG;
782732

783-
ndigs = __float_engine (fval, &dtoa, ndigs, fmode, ndecimal);
733+
ndigs = __float_d_engine (fval, &dtoa, ndigs, fmode, ndecimal);
784734
exp = dtoa.exp;
785735
ndigs_exp = 2;
786736
}
@@ -789,10 +739,10 @@ int vfprintf (FILE * stream, const CHAR *fmt, va_list ap_orig)
789739
ndigs_exp = 2;
790740
if (exp < -99 || 99 < exp)
791741
ndigs_exp = 3;
792-
#ifdef _NEED_IO_DOUBLE
742+
#ifdef _NEED_IO_FLOAT64
793743
if (exp < -999 || 999 < exp)
794744
ndigs_exp = 4;
795-
#ifdef _NEED_IO_LONG_DOUBLE
745+
#ifdef _NEED_IO_FLOAT_LARGE
796746
if (exp < -9999 || 9999 < exp)
797747
ndigs_exp = 5;
798748
#endif
@@ -1001,13 +951,13 @@ int vfprintf (FILE * stream, const CHAR *fmt, va_list ap_orig)
1001951
sign = '-';
1002952
}
1003953
my_putc (sign, stream);
1004-
#ifdef _NEED_IO_LONG_DOUBLE
954+
#ifdef _NEED_IO_FLOAT_LARGE
1005955
if (ndigs_exp > 4) {
1006956
my_putc(exp / 10000 + '0', stream);
1007957
exp %= 10000;
1008958
}
1009959
#endif
1010-
#ifdef _NEED_IO_DOUBLE
960+
#ifdef _NEED_IO_FLOAT64
1011961
if (ndigs_exp > 3) {
1012962
my_putc(exp / 1000 + '0', stream);
1013963
exp %= 1000;

0 commit comments

Comments
 (0)