Skip to content

Commit e258bc4

Browse files
authored
Merge pull request swiftlang#32537 from 3405691582/StrtoSimplicity
[stdlib] Simplify the strto* platform stubs.
2 parents 7d5def9 + d3a9314 commit e258bc4

File tree

1 file changed

+64
-122
lines changed

1 file changed

+64
-122
lines changed

stdlib/public/stubs/Stubs.cpp

Lines changed: 64 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -36,63 +36,28 @@
3636
#endif
3737
#include <climits>
3838
#include <clocale>
39+
#include <cmath>
3940
#include <cstdarg>
4041
#include <cstdint>
4142
#include <cstdio>
4243
#include <cstdlib>
4344
#include <cstring>
44-
#if defined(__CYGWIN__) || defined(_WIN32) || defined(__HAIKU__)
4545
#include <sstream>
46-
#include <cmath>
47-
#elif defined(__OpenBSD__)
46+
#if defined(__OpenBSD__) || defined(__ANDROID__) || defined(__linux__) || defined(__wasi__) || defined(_WIN32)
4847
#include <locale.h>
49-
50-
static double swift_strtod_l(const char *nptr, char **endptr, locale_t loc) {
51-
return strtod(nptr, endptr);
52-
}
53-
54-
static float swift_strtof_l(const char *nptr, char **endptr, locale_t loc) {
55-
return strtof(nptr, endptr);
56-
}
57-
58-
static long double swift_strtold_l(const char *nptr, char **endptr,
59-
locale_t loc) {
60-
return strtold(nptr, endptr);
61-
}
62-
63-
#define strtod_l swift_strtod_l
64-
#define strtof_l swift_strtof_l
65-
#define strtold_l swift_strtold_l
66-
#elif defined(__ANDROID__)
67-
#include <locale.h>
68-
69-
#include <android/api-level.h>
70-
71-
#if __ANDROID_API__ < 21 // Introduced in Android API 21 - L
72-
static inline long double swift_strtold_l(const char *nptr, char **endptr,
73-
locale_t) {
74-
return strtod(nptr, endptr);
75-
}
76-
#define strtold_l swift_strtold_l
77-
#endif
78-
79-
#if __ANDROID_API__ < 26 // Introduced in Android API 26 - O
80-
static double swift_strtod_l(const char *nptr, char **endptr, locale_t loc) {
81-
return strtod(nptr, endptr);
82-
}
83-
static float swift_strtof_l(const char *nptr, char **endptr, locale_t loc) {
84-
return strtof(nptr, endptr);
85-
}
86-
#define strtod_l swift_strtod_l
87-
#define strtof_l swift_strtof_l
48+
#if defined(_WIN32)
49+
#define locale_t _locale_t
8850
#endif
89-
#elif defined(__linux__) || defined(__wasi__)
90-
#include <locale.h>
9151
#else
9252
#include <xlocale.h>
9353
#endif
9454
#include <limits>
9555
#include <thread>
56+
57+
#if defined(__ANDROID__)
58+
#include <android/api-level.h>
59+
#endif
60+
9661
#include "swift/Runtime/Debug.h"
9762
#include "swift/Runtime/SwiftDtoa.h"
9863
#include "swift/Basic/Lazy.h"
@@ -388,104 +353,82 @@ static bool swift_stringIsSignalingNaN(const char *nptr) {
388353
return strcasecmp(nptr, "snan") == 0;
389354
}
390355

391-
#if defined(__CYGWIN__) || defined(_WIN32) || defined(__HAIKU__)
392-
// Cygwin does not support uselocale(), but we can use the locale feature
393-
// in stringstream object.
356+
// This implementation should only be used on platforms without the
357+
// relevant strto* functions, such as Cygwin or Haiku.
358+
// Note that using this currently causes test failures.
394359
template <typename T>
395-
static const char *_swift_stdlib_strtoX_clocale_impl(
396-
const char *nptr, T *outResult) {
397-
if (swift_stringIsSignalingNaN(nptr)) {
398-
*outResult = std::numeric_limits<T>::signaling_NaN();
399-
return nptr + std::strlen(nptr);
400-
}
401-
360+
T _swift_strto(const char *nptr, char **endptr) {
402361
std::istringstream ValueStream(nptr);
403362
ValueStream.imbue(std::locale::classic());
404363
T ParsedValue;
405364
ValueStream >> ParsedValue;
406-
*outResult = ParsedValue;
407365

408366
std::streamoff pos = ValueStream.tellg();
409367
if (ValueStream.eof())
410368
pos = static_cast<std::streamoff>(strlen(nptr));
411-
if (pos <= 0)
412-
return nullptr;
369+
if (pos <= 0) {
370+
errno = ERANGE;
371+
return 0.0;
372+
}
413373

414-
return nptr + pos;
374+
return ParsedValue;
415375
}
416376

377+
static double swift_strtod_l(const char *nptr, char **endptr, locale_t loc) {
417378
#if defined(_WIN32)
418-
template <>
419-
const char *
420-
_swift_stdlib_strtoX_clocale_impl<float>(const char *str, float *result) {
421-
if (swift_stringIsSignalingNaN(str)) {
422-
*result = std::numeric_limits<float>::signaling_NaN();
423-
return str + std::strlen(str);
424-
}
425-
426-
char *end;
427-
_set_errno(0);
428-
*result = _strtof_l(str, &end, getCLocale());
429-
if (*result == HUGE_VALF || *result == -HUGE_VALF || *result == 0.0 || *result == -0.0) {
430-
if (errno == ERANGE)
431-
end = nullptr;
432-
}
433-
return end;
379+
return _strtod_l(nptr, endptr, getCLocale());
380+
#elif defined(__CYGWIN__) || defined(__HAIKU__)
381+
return _swift_strto<double>(nptr, endptr);
382+
#else
383+
return strtod(nptr, endptr);
384+
#endif
434385
}
435386

436-
template <>
437-
const char *
438-
_swift_stdlib_strtoX_clocale_impl<double>(const char *str, double *result) {
439-
if (swift_stringIsSignalingNaN(str)) {
440-
*result = std::numeric_limits<double>::signaling_NaN();
441-
return str + std::strlen(str);
442-
}
443-
444-
char *end;
445-
_set_errno(0);
446-
*result = _strtod_l(str, &end, getCLocale());
447-
if (*result == HUGE_VAL || *result == -HUGE_VAL || *result == 0.0 || *result == -0.0) {
448-
if (errno == ERANGE)
449-
end = nullptr;
450-
}
451-
return end;
387+
static float swift_strtof_l(const char *nptr, char **endptr, locale_t loc) {
388+
#if defined(_WIN32)
389+
return _strtof_l(nptr, endptr, getCLocale());
390+
#elif defined(__CYGWIN__) || defined(__HAIKU__)
391+
return _swift_strto<float>(nptr, endptr);
392+
#else
393+
return strtof(nptr, endptr);
394+
#endif
452395
}
453396

454-
template <>
455-
const char *
456-
_swift_stdlib_strtoX_clocale_impl<long double>(const char *str, long double *result) {
457-
if (swift_stringIsSignalingNaN(str)) {
458-
*result = std::numeric_limits<long double>::signaling_NaN();
459-
return str + std::strlen(str);
460-
}
461-
462-
char *end;
463-
_set_errno(0);
464-
*result = _strtod_l(str, &end, getCLocale());
465-
if (*result == HUGE_VALL || *result == -HUGE_VALL || *result == 0.0 || *result == -0.0) {
466-
if (errno == ERANGE)
467-
end = nullptr;
468-
}
469-
return end;
470-
}
397+
static long double swift_strtold_l(const char *nptr, char **endptr,
398+
locale_t loc) {
399+
#if defined(_WIN32)
400+
return _strtod_l(nptr, endptr, getCLocale());
401+
#elif defined(__ANDROID__)
402+
return strtod(nptr, endptr);
403+
#elif defined(__CYGWIN__) || defined(__HAIKU__)
404+
return _swift_strto<long double>(nptr, endptr);
405+
#else
406+
return strtold(nptr, endptr);
471407
#endif
472-
473-
const char *swift::_swift_stdlib_strtold_clocale(
474-
const char *nptr, void *outResult) {
475-
return _swift_stdlib_strtoX_clocale_impl(
476-
nptr, static_cast<long double*>(outResult));
477408
}
478409

479-
const char *swift::_swift_stdlib_strtod_clocale(
480-
const char * nptr, double *outResult) {
481-
return _swift_stdlib_strtoX_clocale_impl(nptr, outResult);
482-
}
410+
#if defined(__OpenBSD__) || defined(_WIN32) || defined(__CYGWIN__) || defined(__HAIKU__)
411+
#define strtod_l swift_strtod_l
412+
#define strtof_l swift_strtof_l
413+
#define strtold_l swift_strtold_l
414+
#elif defined(__ANDROID__)
415+
#if __ANDROID_API__ < 21 // Introduced in Android API 21 - L
416+
#define strtold_l swift_strtold_l
417+
#endif
483418

484-
const char *swift::_swift_stdlib_strtof_clocale(
485-
const char * nptr, float *outResult) {
486-
return _swift_stdlib_strtoX_clocale_impl(nptr, outResult);
487-
}
419+
#if __ANDROID_API__ < 26 // Introduced in Android API 26 - O
420+
#define strtod_l swift_strtod_l
421+
#define strtof_l swift_strtof_l
422+
#endif
423+
#endif
424+
425+
static inline void _swift_set_errno(int to) {
426+
#if defined(_WIN32)
427+
_set_errno(0);
488428
#else
429+
errno = 0;
430+
#endif
431+
}
489432

490433
// We can't return Float80, but we can receive a pointer to one, so
491434
// switch the return type and the out parameter on strtold.
@@ -502,7 +445,7 @@ static const char *_swift_stdlib_strtoX_clocale_impl(
502445
}
503446

504447
char *EndPtr;
505-
errno = 0;
448+
_swift_set_errno(0);
506449
const auto result = posixImpl(nptr, &EndPtr, getCLocale());
507450
*outResult = result;
508451
if (result == huge || result == -huge || result == 0.0 || result == -0.0) {
@@ -529,7 +472,6 @@ const char *swift::_swift_stdlib_strtof_clocale(
529472
return _swift_stdlib_strtoX_clocale_impl(
530473
nptr, outResult, HUGE_VALF, strtof_l);
531474
}
532-
#endif
533475

534476
const char *swift::_swift_stdlib_strtof16_clocale(
535477
const char * nptr, __fp16 *outResult) {

0 commit comments

Comments
 (0)