36
36
#endif
37
37
#include < climits>
38
38
#include < clocale>
39
+ #include < cmath>
39
40
#include < cstdarg>
40
41
#include < cstdint>
41
42
#include < cstdio>
42
43
#include < cstdlib>
43
44
#include < cstring>
44
- #if defined(__CYGWIN__) || defined(_WIN32) || defined(__HAIKU__)
45
45
#include < sstream>
46
- #include < cmath>
47
- #elif defined(__OpenBSD__)
46
+ #if defined(__OpenBSD__) || defined(__ANDROID__) || defined(__linux__) || defined(__wasi__) || defined(_WIN32)
48
47
#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
88
50
#endif
89
- #elif defined(__linux__) || defined(__wasi__)
90
- #include < locale.h>
91
51
#else
92
52
#include < xlocale.h>
93
53
#endif
94
54
#include < limits>
95
55
#include < thread>
56
+
57
+ #if defined(__ANDROID__)
58
+ #include < android/api-level.h>
59
+ #endif
60
+
96
61
#include " swift/Runtime/Debug.h"
97
62
#include " swift/Runtime/SwiftDtoa.h"
98
63
#include " swift/Basic/Lazy.h"
@@ -388,104 +353,82 @@ static bool swift_stringIsSignalingNaN(const char *nptr) {
388
353
return strcasecmp (nptr, " snan" ) == 0 ;
389
354
}
390
355
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 .
394
359
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) {
402
361
std::istringstream ValueStream (nptr);
403
362
ValueStream.imbue (std::locale::classic ());
404
363
T ParsedValue;
405
364
ValueStream >> ParsedValue;
406
- *outResult = ParsedValue;
407
365
408
366
std::streamoff pos = ValueStream.tellg ();
409
367
if (ValueStream.eof ())
410
368
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
+ }
413
373
414
- return nptr + pos ;
374
+ return ParsedValue ;
415
375
}
416
376
377
+ static double swift_strtod_l (const char *nptr, char **endptr, locale_t loc) {
417
378
#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
434
385
}
435
386
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
452
395
}
453
396
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);
471
407
#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));
477
408
}
478
409
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
483
418
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 );
488
428
#else
429
+ errno = 0 ;
430
+ #endif
431
+ }
489
432
490
433
// We can't return Float80, but we can receive a pointer to one, so
491
434
// switch the return type and the out parameter on strtold.
@@ -502,7 +445,7 @@ static const char *_swift_stdlib_strtoX_clocale_impl(
502
445
}
503
446
504
447
char *EndPtr;
505
- errno = 0 ;
448
+ _swift_set_errno ( 0 ) ;
506
449
const auto result = posixImpl (nptr, &EndPtr, getCLocale ());
507
450
*outResult = result;
508
451
if (result == huge || result == -huge || result == 0.0 || result == -0.0 ) {
@@ -529,7 +472,6 @@ const char *swift::_swift_stdlib_strtof_clocale(
529
472
return _swift_stdlib_strtoX_clocale_impl (
530
473
nptr, outResult, HUGE_VALF, strtof_l);
531
474
}
532
- #endif
533
475
534
476
const char *swift::_swift_stdlib_strtof16_clocale (
535
477
const char * nptr, __fp16 *outResult) {
0 commit comments