xlocale.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // -*- C++ -*-
  2. //===-----------------------------------------------------------------------===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef _LIBCPP_SUPPORT_IBM_XLOCALE_H
  10. #define _LIBCPP_SUPPORT_IBM_XLOCALE_H
  11. #include <__support/ibm/locale_mgmt_zos.h>
  12. #include <stdarg.h>
  13. #include "cstdlib"
  14. #ifdef __cplusplus
  15. extern "C" {
  16. #endif
  17. #if defined(__MVS__)
  18. #include <wctype.h>
  19. // POSIX routines
  20. #include <__support/xlocale/__posix_l_fallback.h>
  21. #endif // defined(__MVS__)
  22. namespace {
  23. struct __setAndRestore {
  24. explicit __setAndRestore(locale_t locale) {
  25. if (locale == (locale_t)0) {
  26. __cloc = newlocale(LC_ALL_MASK, "C", /* base */ (locale_t)0);
  27. __stored = uselocale(__cloc);
  28. } else {
  29. __stored = uselocale(locale);
  30. }
  31. }
  32. ~__setAndRestore() {
  33. uselocale(__stored);
  34. if (__cloc)
  35. freelocale(__cloc);
  36. }
  37. private:
  38. locale_t __stored = (locale_t)0;
  39. locale_t __cloc = (locale_t)0;
  40. };
  41. } // namespace
  42. // The following are not POSIX routines. These are quick-and-dirty hacks
  43. // to make things pretend to work
  44. static inline
  45. long long strtoll_l(const char *__nptr, char **__endptr,
  46. int __base, locale_t locale) {
  47. __setAndRestore __newloc(locale);
  48. return strtoll(__nptr, __endptr, __base);
  49. }
  50. static inline
  51. long strtol_l(const char *__nptr, char **__endptr,
  52. int __base, locale_t locale) {
  53. __setAndRestore __newloc(locale);
  54. return strtol(__nptr, __endptr, __base);
  55. }
  56. static inline
  57. double strtod_l(const char *__nptr, char **__endptr,
  58. locale_t locale) {
  59. __setAndRestore __newloc(locale);
  60. return strtod(__nptr, __endptr);
  61. }
  62. static inline
  63. float strtof_l(const char *__nptr, char **__endptr,
  64. locale_t locale) {
  65. __setAndRestore __newloc(locale);
  66. return strtof(__nptr, __endptr);
  67. }
  68. static inline
  69. long double strtold_l(const char *__nptr, char **__endptr,
  70. locale_t locale) {
  71. __setAndRestore __newloc(locale);
  72. return strtold(__nptr, __endptr);
  73. }
  74. static inline
  75. unsigned long long strtoull_l(const char *__nptr, char **__endptr,
  76. int __base, locale_t locale) {
  77. __setAndRestore __newloc(locale);
  78. return strtoull(__nptr, __endptr, __base);
  79. }
  80. static inline
  81. unsigned long strtoul_l(const char *__nptr, char **__endptr,
  82. int __base, locale_t locale) {
  83. __setAndRestore __newloc(locale);
  84. return strtoul(__nptr, __endptr, __base);
  85. }
  86. static inline
  87. int vasprintf(char **strp, const char *fmt, va_list ap) {
  88. const size_t buff_size = 256;
  89. if ((*strp = (char *)malloc(buff_size)) == NULL) {
  90. return -1;
  91. }
  92. va_list ap_copy;
  93. // va_copy may not be provided by the C library in C++ 03 mode.
  94. #if defined(_LIBCPP_CXX03_LANG) && __has_builtin(__builtin_va_copy)
  95. __builtin_va_copy(ap_copy, ap);
  96. #else
  97. va_copy(ap_copy, ap);
  98. #endif
  99. int str_size = vsnprintf(*strp, buff_size, fmt, ap_copy);
  100. va_end(ap_copy);
  101. if ((size_t) str_size >= buff_size) {
  102. if ((*strp = (char *)realloc(*strp, str_size + 1)) == NULL) {
  103. return -1;
  104. }
  105. str_size = vsnprintf(*strp, str_size + 1, fmt, ap);
  106. }
  107. return str_size;
  108. }
  109. #ifdef __cplusplus
  110. }
  111. #endif
  112. #endif // _LIBCPP_SUPPORT_IBM_XLOCALE_H