Merge "printf unification: floating point." am: a198c71752
am: 3ef0a47b71
Original change: https://android-review.googlesource.com/c/platform/bionic/+/2583717 Change-Id: I3f5b5da8734a5bd87f5c39490206bce24d74df5d Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
d2b4fab8d8
7 changed files with 42 additions and 29 deletions
|
@ -290,17 +290,21 @@ char* __ldtoa(long double*, int, int, int*, int*, char**);
|
|||
|
||||
#define WCIO_GET(fp) (_EXT(fp) ? &(_EXT(fp)->_wcio) : (struct wchar_io_data*)0)
|
||||
|
||||
#define ORIENT_BYTES (-1)
|
||||
#define ORIENT_UNKNOWN 0
|
||||
#define ORIENT_CHARS 1
|
||||
|
||||
#define _SET_ORIENTATION(fp, mode) \
|
||||
do { \
|
||||
struct wchar_io_data* _wcio = WCIO_GET(fp); \
|
||||
if (_wcio && _wcio->wcio_mode == 0) _wcio->wcio_mode = (mode); \
|
||||
if (_wcio && _wcio->wcio_mode == ORIENT_UNKNOWN) _wcio->wcio_mode = (mode); \
|
||||
} while (0)
|
||||
|
||||
#define WCIO_FREE(fp) \
|
||||
do { \
|
||||
struct wchar_io_data* _wcio = WCIO_GET(fp); \
|
||||
if (_wcio) { \
|
||||
_wcio->wcio_mode = 0; \
|
||||
_wcio->wcio_mode = ORIENT_UNKNOWN; \
|
||||
_wcio->wcio_ungetwc_inbuf = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
|
|
@ -773,7 +773,7 @@ char* fgets(char* buf, int n, FILE* fp) {
|
|||
char* fgets_unlocked(char* buf, int n, FILE* fp) {
|
||||
if (n <= 0) __fortify_fatal("fgets: buffer size %d <= 0", n);
|
||||
|
||||
_SET_ORIENTATION(fp, -1);
|
||||
_SET_ORIENTATION(fp, ORIENT_BYTES);
|
||||
|
||||
char* s = buf;
|
||||
n--; // Leave space for NUL.
|
||||
|
@ -903,7 +903,7 @@ int putc_unlocked(int c, FILE* fp) {
|
|||
errno = EBADF;
|
||||
return EOF;
|
||||
}
|
||||
_SET_ORIENTATION(fp, -1);
|
||||
_SET_ORIENTATION(fp, ORIENT_BYTES);
|
||||
if (--fp->_w >= 0 || (fp->_w >= fp->_lbfsize && c != '\n')) {
|
||||
return (*fp->_p++ = c);
|
||||
}
|
||||
|
@ -1098,7 +1098,7 @@ size_t fread_unlocked(void* buf, size_t size, size_t count, FILE* fp) {
|
|||
size_t total = desired_total;
|
||||
if (total == 0) return 0;
|
||||
|
||||
_SET_ORIENTATION(fp, -1);
|
||||
_SET_ORIENTATION(fp, ORIENT_BYTES);
|
||||
|
||||
// TODO: how can this ever happen?!
|
||||
if (fp->_r < 0) fp->_r = 0;
|
||||
|
@ -1165,7 +1165,7 @@ size_t fwrite_unlocked(const void* buf, size_t size, size_t count, FILE* fp) {
|
|||
__siov iov = { .iov_base = const_cast<void*>(buf), .iov_len = n };
|
||||
__suio uio = { .uio_iov = &iov, .uio_iovcnt = 1, .uio_resid = n };
|
||||
|
||||
_SET_ORIENTATION(fp, -1);
|
||||
_SET_ORIENTATION(fp, ORIENT_BYTES);
|
||||
|
||||
// The usual case is success (__sfvwrite returns 0); skip the divide if this happens,
|
||||
// since divides are generally slow.
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#define CHAR_TYPE_inf "inf"
|
||||
#define CHAR_TYPE_NAN "NAN"
|
||||
#define CHAR_TYPE_nan "nan"
|
||||
#define CHAR_TYPE_ORIENTATION -1
|
||||
#define CHAR_TYPE_ORIENTATION ORIENT_BYTES
|
||||
|
||||
#define PRINT(ptr, len) \
|
||||
do { \
|
||||
|
@ -361,14 +361,14 @@ int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
|
|||
if (dtoaresult) __freedtoa(dtoaresult);
|
||||
if (flags & LONGDBL) {
|
||||
fparg.ldbl = GETARG(long double);
|
||||
dtoaresult = cp = __hldtoa(fparg.ldbl, xdigs, prec, &expt, &signflag, &dtoaend);
|
||||
dtoaresult = __hldtoa(fparg.ldbl, xdigs, prec, &expt, &signflag, &dtoaend);
|
||||
if (dtoaresult == nullptr) {
|
||||
errno = ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
fparg.dbl = GETARG(double);
|
||||
dtoaresult = cp = __hdtoa(fparg.dbl, xdigs, prec, &expt, &signflag, &dtoaend);
|
||||
dtoaresult = __hdtoa(fparg.dbl, xdigs, prec, &expt, &signflag, &dtoaend);
|
||||
if (dtoaresult == nullptr) {
|
||||
errno = ENOMEM;
|
||||
goto error;
|
||||
|
@ -398,14 +398,14 @@ int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
|
|||
if (dtoaresult) __freedtoa(dtoaresult);
|
||||
if (flags & LONGDBL) {
|
||||
fparg.ldbl = GETARG(long double);
|
||||
dtoaresult = cp = __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend);
|
||||
dtoaresult = __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend);
|
||||
if (dtoaresult == nullptr) {
|
||||
errno = ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
fparg.dbl = GETARG(double);
|
||||
dtoaresult = cp = __dtoa(fparg.dbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend);
|
||||
dtoaresult = __dtoa(fparg.dbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend);
|
||||
if (dtoaresult == nullptr) {
|
||||
errno = ENOMEM;
|
||||
goto error;
|
||||
|
@ -413,6 +413,13 @@ int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
|
|||
if (expt == 9999) expt = INT_MAX;
|
||||
}
|
||||
fp_common:
|
||||
#if CHAR_TYPE_ORIENTATION == ORIENT_BYTES
|
||||
cp = dtoaresult;
|
||||
#else
|
||||
free(convbuf);
|
||||
cp = convbuf = helpers::mbsconv(dtoaresult, -1);
|
||||
if (cp == nullptr) goto error;
|
||||
#endif
|
||||
if (signflag) sign = '-';
|
||||
if (expt == INT_MAX) { /* inf or nan */
|
||||
if (*cp == 'N') {
|
||||
|
@ -425,7 +432,7 @@ int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
|
|||
break;
|
||||
}
|
||||
flags |= FPT;
|
||||
ndig = dtoaend - cp;
|
||||
ndig = dtoaend - dtoaresult;
|
||||
if (ch == 'g' || ch == 'G') {
|
||||
if (expt > -4 && expt <= prec) {
|
||||
/* Make %[gG] smell like %[fF] */
|
||||
|
@ -662,6 +669,7 @@ int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
|
|||
} else { /* glue together f_p fragments */
|
||||
if (decimal_point == nullptr) decimal_point = nl_langinfo(RADIXCHAR);
|
||||
if (!expchar) { /* %[fF] or sufficiently short %[gG] */
|
||||
CHAR_TYPE* end = cp + ndig;
|
||||
if (expt <= 0) {
|
||||
PRINT(zeroes, 1);
|
||||
if (prec || flags & ALT) PRINT(decimal_point, 1);
|
||||
|
@ -669,11 +677,11 @@ int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
|
|||
/* already handled initial 0's */
|
||||
prec += expt;
|
||||
} else {
|
||||
PRINTANDPAD(cp, dtoaend, lead, zeroes);
|
||||
PRINTANDPAD(cp, end, lead, zeroes);
|
||||
cp += lead;
|
||||
if (prec || flags & ALT) PRINT(decimal_point, 1);
|
||||
}
|
||||
PRINTANDPAD(cp, dtoaend, prec, zeroes);
|
||||
PRINTANDPAD(cp, end, prec, zeroes);
|
||||
} else { /* %[eE] or sufficiently long %[gG] */
|
||||
if (prec > 1 || flags & ALT) {
|
||||
buf[0] = *cp++;
|
||||
|
|
|
@ -102,7 +102,7 @@ int __svfscanf(FILE* fp, const char* fmt0, va_list ap) {
|
|||
void* allocation = nullptr; // Allocated but unassigned result for %mc/%ms/%m[.
|
||||
size_t capacity = 0; // Number of char/wchar_t units allocated in `allocation`.
|
||||
|
||||
_SET_ORIENTATION(fp, -1);
|
||||
_SET_ORIENTATION(fp, ORIENT_BYTES);
|
||||
|
||||
nassigned = 0;
|
||||
nread = 0;
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#define CHAR_TYPE_inf L"inf"
|
||||
#define CHAR_TYPE_NAN L"NAN"
|
||||
#define CHAR_TYPE_nan L"nan"
|
||||
#define CHAR_TYPE_ORIENTATION 1
|
||||
#define CHAR_TYPE_ORIENTATION ORIENT_CHARS
|
||||
|
||||
#define PRINT(ptr, len) \
|
||||
do { \
|
||||
|
@ -355,10 +355,6 @@ int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
|
|||
}
|
||||
if (prec < 0) prec = dtoaend - dtoaresult;
|
||||
if (expt == INT_MAX) ox[1] = '\0';
|
||||
free(convbuf);
|
||||
cp = convbuf = helpers::mbsconv(dtoaresult, -1);
|
||||
if (cp == nullptr) goto error;
|
||||
ndig = dtoaend - dtoaresult;
|
||||
goto fp_common;
|
||||
case 'e':
|
||||
case 'E':
|
||||
|
@ -395,11 +391,14 @@ int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
|
|||
}
|
||||
if (expt == 9999) expt = INT_MAX;
|
||||
}
|
||||
fp_common:
|
||||
#if CHAR_TYPE_ORIENTATION == ORIENT_BYTES
|
||||
cp = dtoaresult;
|
||||
#else
|
||||
free(convbuf);
|
||||
cp = convbuf = helpers::mbsconv(dtoaresult, -1);
|
||||
if (cp == nullptr) goto error;
|
||||
ndig = dtoaend - dtoaresult;
|
||||
fp_common:
|
||||
#endif
|
||||
if (signflag) sign = '-';
|
||||
if (expt == INT_MAX) { /* inf or nan */
|
||||
if (*cp == 'N') {
|
||||
|
@ -412,6 +411,7 @@ int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
|
|||
break;
|
||||
}
|
||||
flags |= FPT;
|
||||
ndig = dtoaend - dtoaresult;
|
||||
if (ch == 'g' || ch == 'G') {
|
||||
if (expt > -4 && expt <= prec) {
|
||||
/* Make %[gG] smell like %[fF] */
|
||||
|
@ -652,6 +652,7 @@ int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
|
|||
} else { /* glue together f_p fragments */
|
||||
if (decimal_point == nullptr) decimal_point = nl_langinfo(RADIXCHAR);
|
||||
if (!expchar) { /* %[fF] or sufficiently short %[gG] */
|
||||
CHAR_TYPE* end = cp + ndig;
|
||||
if (expt <= 0) {
|
||||
PRINT(zeroes, 1);
|
||||
if (prec || flags & ALT) PRINT(decimal_point, 1);
|
||||
|
@ -659,11 +660,11 @@ int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
|
|||
/* already handled initial 0's */
|
||||
prec += expt;
|
||||
} else {
|
||||
PRINTANDPAD(cp, convbuf + ndig, lead, zeroes);
|
||||
PRINTANDPAD(cp, end, lead, zeroes);
|
||||
cp += lead;
|
||||
if (prec || flags & ALT) PRINT(decimal_point, 1);
|
||||
}
|
||||
PRINTANDPAD(cp, convbuf + ndig, prec, zeroes);
|
||||
PRINTANDPAD(cp, end, prec, zeroes);
|
||||
} else { /* %[eE] or sufficiently long %[gG] */
|
||||
if (prec > 1 || flags & ALT) {
|
||||
buf[0] = *cp++;
|
||||
|
|
|
@ -150,7 +150,7 @@ int __vfwscanf(FILE* __restrict fp, const wchar_t* __restrict fmt, __va_list ap)
|
|||
char mbbuf[MB_LEN_MAX]; /* temporary mb. character buffer */
|
||||
mbstate_t mbs;
|
||||
|
||||
_SET_ORIENTATION(fp, 1);
|
||||
_SET_ORIENTATION(fp, ORIENT_CHARS);
|
||||
|
||||
nassigned = 0;
|
||||
nconversions = 0;
|
||||
|
|
|
@ -115,7 +115,7 @@ static void AssertFileIs(FILE* fp, const char* expected, bool is_fmemopen = fals
|
|||
wchar_t buf[BUFSIZ]; \
|
||||
int w = swprintf(buf, sizeof(buf), fmt __VA_OPT__(, ) __VA_ARGS__); \
|
||||
EXPECT_EQ(n, w); \
|
||||
EXPECT_EQ(std::wstring(expected), buf); \
|
||||
EXPECT_EQ(std::wstring(expected), std::wstring(buf, w)); \
|
||||
}
|
||||
#define EXPECT_SWPRINTF(expected, fmt, ...) \
|
||||
EXPECT_SWPRINTF_N(expected, static_cast<int>(wcslen(expected)), fmt __VA_OPT__(, ) __VA_ARGS__)
|
||||
|
|
Loading…
Reference in a new issue