[libc-commits] [libc] a871051 - [libc] Implement locale variants for 'stdlib.h' functions (#105718)
via libc-commits
libc-commits at lists.llvm.org
Thu Aug 29 12:18:40 PDT 2024
Author: Joseph Huber
Date: 2024-08-29T14:18:37-05:00
New Revision: a87105121dd300752c19024ebaf93319c2781a8b
URL: https://github.com/llvm/llvm-project/commit/a87105121dd300752c19024ebaf93319c2781a8b
DIFF: https://github.com/llvm/llvm-project/commit/a87105121dd300752c19024ebaf93319c2781a8b.diff
LOG: [libc] Implement locale variants for 'stdlib.h' functions (#105718)
Summary:
This provides the `_l` variants for the `stdlib.h` functions. These are
just copies of the same entrypoint and don't do anything with the locale
information.
Added:
libc/src/stdlib/strtod_l.cpp
libc/src/stdlib/strtod_l.h
libc/src/stdlib/strtof_l.cpp
libc/src/stdlib/strtof_l.h
libc/src/stdlib/strtol_l.cpp
libc/src/stdlib/strtol_l.h
libc/src/stdlib/strtold_l.cpp
libc/src/stdlib/strtold_l.h
libc/src/stdlib/strtoll_l.cpp
libc/src/stdlib/strtoll_l.h
libc/src/stdlib/strtoul_l.cpp
libc/src/stdlib/strtoul_l.h
libc/src/stdlib/strtoull_l.cpp
libc/src/stdlib/strtoull_l.h
Modified:
libc/config/gpu/entrypoints.txt
libc/config/linux/x86_64/entrypoints.txt
libc/include/llvm-libc-macros/stdlib-macros.h
libc/include/stdlib.h.def
libc/newhdrgen/yaml/stdlib.yaml
libc/spec/stdc.td
libc/src/stdlib/CMakeLists.txt
Removed:
################################################################################
diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index db7cd24dadb7fc..d8f78f0d174534 100644
--- a/libc/config/gpu/entrypoints.txt
+++ b/libc/config/gpu/entrypoints.txt
@@ -173,12 +173,19 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.stdlib.rand
libc.src.stdlib.srand
libc.src.stdlib.strtod
+ libc.src.stdlib.strtod_l
libc.src.stdlib.strtof
+ libc.src.stdlib.strtof_l
libc.src.stdlib.strtol
+ libc.src.stdlib.strtol_l
libc.src.stdlib.strtold
+ libc.src.stdlib.strtold_l
libc.src.stdlib.strtoll
+ libc.src.stdlib.strtoll_l
libc.src.stdlib.strtoul
+ libc.src.stdlib.strtoul_l
libc.src.stdlib.strtoull
+ libc.src.stdlib.strtoull_l
libc.src.stdlib.at_quick_exit
libc.src.stdlib.quick_exit
libc.src.stdlib.getenv
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 141dc70463d64a..0aa38c7afc76f4 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -800,6 +800,15 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.ctype.tolower_l
libc.src.ctype.toupper_l
+ # stdlib.h entrypoints
+ libc.src.stdlib.strtod_l
+ libc.src.stdlib.strtof_l
+ libc.src.stdlib.strtol_l
+ libc.src.stdlib.strtold_l
+ libc.src.stdlib.strtoll_l
+ libc.src.stdlib.strtoul_l
+ libc.src.stdlib.strtoull_l
+
# assert.h entrypoints
libc.src.assert.__assert_fail
diff --git a/libc/include/llvm-libc-macros/stdlib-macros.h b/libc/include/llvm-libc-macros/stdlib-macros.h
index 5fcbfef97b3285..2565c76be3c55c 100644
--- a/libc/include/llvm-libc-macros/stdlib-macros.h
+++ b/libc/include/llvm-libc-macros/stdlib-macros.h
@@ -17,6 +17,11 @@
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
+#ifndef MB_CUR_MAX
+// We only support the "C" locale right now, so this is a constant byte.
+#define MB_CUR_MAX 1
+#endif // MB_CUR_MAX
+
#define RAND_MAX 2147483647
#endif // LLVM_LIBC_MACROS_STDLIB_MACROS_H
diff --git a/libc/include/stdlib.h.def b/libc/include/stdlib.h.def
index d523f7a53024aa..01b0e1a2395a29 100644
--- a/libc/include/stdlib.h.def
+++ b/libc/include/stdlib.h.def
@@ -10,6 +10,7 @@
#define LLVM_LIBC_STDLIB_H
#include "__llvm-libc-common.h"
+#include "llvm-libc-types/locale_t.h"
#include "llvm-libc-macros/stdlib-macros.h"
%%public_api()
diff --git a/libc/newhdrgen/yaml/stdlib.yaml b/libc/newhdrgen/yaml/stdlib.yaml
index 081da5391c3a52..5da49b8a89101c 100644
--- a/libc/newhdrgen/yaml/stdlib.yaml
+++ b/libc/newhdrgen/yaml/stdlib.yaml
@@ -273,3 +273,63 @@ functions:
- type: const char *__restrict
- type: char **__restrict
- type: int
+ - name: strtod_l
+ standards:
+ - stdc
+ return_type: double
+ arguments:
+ - type: const char *__restrict
+ - type: char **__restrict
+ - type: locale_t
+ - name: strtof_l
+ standards:
+ - stdc
+ return_type: float
+ arguments:
+ - type: const char *__restrict
+ - type: char **__restrict
+ - type: locale_t
+ - name: strtol_l
+ standards:
+ - stdc
+ return_type: long
+ arguments:
+ - type: const char *__restrict
+ - type: char **__restrict
+ - type: int
+ - type: locale_t
+ - name: strtold_l
+ standards:
+ - stdc
+ return_type: long double
+ arguments:
+ - type: const char *__restrict
+ - type: char **__restrict
+ - type: locale_t
+ - name: strtoll_l
+ standards:
+ - stdc
+ return_type: long long
+ arguments:
+ - type: const char *__restrict
+ - type: char **__restrict
+ - type: int
+ - type: locale_t
+ - name: strtoul_l
+ standards:
+ - stdc
+ return_type: unsigned long
+ arguments:
+ - type: const char *__restrict
+ - type: char **__restrict
+ - type: int
+ - type: locale_t
+ - name: strtoull_l
+ standards:
+ - stdc
+ return_type: unsigned long long
+ arguments:
+ - type: const char *__restrict
+ - type: char **__restrict
+ - type: int
+ - type: locale_t
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 026cc72b458a77..2c61cb9d952951 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -1308,6 +1308,14 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"strtoul", RetValSpec<UnsignedLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
FunctionSpec<"strtoull", RetValSpec<UnsignedLongLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
+ FunctionSpec<"strtof", RetValSpec<FloatType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<LocaleT>]>,
+ FunctionSpec<"strtod", RetValSpec<DoubleType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<LocaleT>]>,
+ FunctionSpec<"strtold", RetValSpec<LongDoubleType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<LocaleT>]>,
+ FunctionSpec<"strtol", RetValSpec<LongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>, ArgSpec<LocaleT>]>,
+ FunctionSpec<"strtoll", RetValSpec<LongLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>, ArgSpec<LocaleT>]>,
+ FunctionSpec<"strtoul", RetValSpec<UnsignedLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>, ArgSpec<LocaleT>]>,
+ FunctionSpec<"strtoull", RetValSpec<UnsignedLongLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>, ArgSpec<LocaleT>]>,
+
FunctionSpec<"malloc", RetValSpec<VoidPtr>, [ArgSpec<SizeTType>]>,
FunctionSpec<"calloc", RetValSpec<VoidPtr>, [ArgSpec<SizeTType>, ArgSpec<SizeTType>]>,
FunctionSpec<"realloc", RetValSpec<VoidPtr>, [ArgSpec<VoidPtr>, ArgSpec<SizeTType>]>,
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index ce12e66cf3e57f..7fc68cb35e8489 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -428,6 +428,83 @@ if(NOT LLVM_LIBC_FULL_BUILD)
return()
endif()
+add_entrypoint_object(
+ strtof_l
+ SRCS
+ strtof_l.cpp
+ HDRS
+ strtof_l.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.src.__support.str_to_float
+)
+
+add_entrypoint_object(
+ strtod_l
+ SRCS
+ strtod_l.cpp
+ HDRS
+ strtod_l.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.src.__support.str_to_float
+)
+
+add_entrypoint_object(
+ strtold_l
+ SRCS
+ strtold_l.cpp
+ HDRS
+ strtold_l.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.src.__support.str_to_float
+)
+
+add_entrypoint_object(
+ strtol_l
+ SRCS
+ strtol_l.cpp
+ HDRS
+ strtol_l.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.src.__support.str_to_integer
+)
+
+add_entrypoint_object(
+ strtoll_l
+ SRCS
+ strtoll_l.cpp
+ HDRS
+ strtoll_l.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.src.__support.str_to_integer
+)
+
+add_entrypoint_object(
+ strtoul_l
+ SRCS
+ strtoul_l.cpp
+ HDRS
+ strtoul_l.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.src.__support.str_to_integer
+)
+
+add_entrypoint_object(
+ strtoull_l
+ SRCS
+ strtoull_l.cpp
+ HDRS
+ strtoull_l.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.src.__support.str_to_integer
+)
+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
endif()
diff --git a/libc/src/stdlib/strtod_l.cpp b/libc/src/stdlib/strtod_l.cpp
new file mode 100644
index 00000000000000..247314398315b0
--- /dev/null
+++ b/libc/src/stdlib/strtod_l.cpp
@@ -0,0 +1,30 @@
+//===-- Implementation of strtod_l ----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/strtod_l.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/str_to_float.h"
+#include "src/errno/libc_errno.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(double, strtod_l,
+ (const char *__restrict str, char **__restrict str_end,
+ locale_t)) {
+ auto result = internal::strtofloatingpoint<double>(str);
+ if (result.has_error())
+ libc_errno = result.error;
+
+ if (str_end != nullptr)
+ *str_end = const_cast<char *>(str + result.parsed_len);
+
+ return result.value;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/strtod_l.h b/libc/src/stdlib/strtod_l.h
new file mode 100644
index 00000000000000..06a8c893af2896
--- /dev/null
+++ b/libc/src/stdlib/strtod_l.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for strtod_l ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDLIB_STRTOD_L_H
+#define LLVM_LIBC_SRC_STDLIB_STRTOD_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+double strtod_l(const char *__restrict str, char **__restrict str_end,
+ locale_t locale);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRTOD_L_H
diff --git a/libc/src/stdlib/strtof_l.cpp b/libc/src/stdlib/strtof_l.cpp
new file mode 100644
index 00000000000000..d54efa66e0846c
--- /dev/null
+++ b/libc/src/stdlib/strtof_l.cpp
@@ -0,0 +1,30 @@
+//===-- Implementation of strtof_l ----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/strtof_l.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/str_to_float.h"
+#include "src/errno/libc_errno.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float, strtof_l,
+ (const char *__restrict str, char **__restrict str_end,
+ locale_t)) {
+ auto result = internal::strtofloatingpoint<float>(str);
+ if (result.has_error())
+ libc_errno = result.error;
+
+ if (str_end != nullptr)
+ *str_end = const_cast<char *>(str + result.parsed_len);
+
+ return result.value;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/strtof_l.h b/libc/src/stdlib/strtof_l.h
new file mode 100644
index 00000000000000..de629e3f36d458
--- /dev/null
+++ b/libc/src/stdlib/strtof_l.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for strtof_l ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDLIB_STRTOF_L_H
+#define LLVM_LIBC_SRC_STDLIB_STRTOF_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+float strtof_l(const char *__restrict str, char **__restrict str_end,
+ locale_t locale);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRTOF_L_H
diff --git a/libc/src/stdlib/strtol_l.cpp b/libc/src/stdlib/strtol_l.cpp
new file mode 100644
index 00000000000000..f94aff1a0d7b2a
--- /dev/null
+++ b/libc/src/stdlib/strtol_l.cpp
@@ -0,0 +1,30 @@
+//===-- Implementation of strtol_l ----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/strtol_l.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/str_to_integer.h"
+#include "src/errno/libc_errno.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(long, strtol_l,
+ (const char *__restrict str, char **__restrict str_end,
+ int base, locale_t)) {
+ auto result = internal::strtointeger<long>(str, base);
+ if (result.has_error())
+ libc_errno = result.error;
+
+ if (str_end != nullptr)
+ *str_end = const_cast<char *>(str + result.parsed_len);
+
+ return result;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/strtol_l.h b/libc/src/stdlib/strtol_l.h
new file mode 100644
index 00000000000000..9f8c8553654d78
--- /dev/null
+++ b/libc/src/stdlib/strtol_l.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for strtol_l ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDLIB_STRTOL_L_H
+#define LLVM_LIBC_SRC_STDLIB_STRTOL_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+long strtol_l(const char *__restrict str, char **__restrict str_end, int base,
+ locale_t locale);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRTOL_L_H
diff --git a/libc/src/stdlib/strtold_l.cpp b/libc/src/stdlib/strtold_l.cpp
new file mode 100644
index 00000000000000..d0c57f50246b5c
--- /dev/null
+++ b/libc/src/stdlib/strtold_l.cpp
@@ -0,0 +1,30 @@
+//===-- Implementation of strtold_l ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/strtold_l.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/str_to_float.h"
+#include "src/errno/libc_errno.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(long double, strtold_l,
+ (const char *__restrict str, char **__restrict str_end,
+ locale_t)) {
+ auto result = internal::strtofloatingpoint<long double>(str);
+ if (result.has_error())
+ libc_errno = result.error;
+
+ if (str_end != nullptr)
+ *str_end = const_cast<char *>(str + result.parsed_len);
+
+ return result.value;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/strtold_l.h b/libc/src/stdlib/strtold_l.h
new file mode 100644
index 00000000000000..d694ce279b6e39
--- /dev/null
+++ b/libc/src/stdlib/strtold_l.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for strtold_l ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDLIB_STRTOLD_L_H
+#define LLVM_LIBC_SRC_STDLIB_STRTOLD_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+long double strtold_l(const char *__restrict str, char **__restrict str_end,
+ locale_t locale);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRTOLD_L_H
diff --git a/libc/src/stdlib/strtoll_l.cpp b/libc/src/stdlib/strtoll_l.cpp
new file mode 100644
index 00000000000000..e82971d59c48d3
--- /dev/null
+++ b/libc/src/stdlib/strtoll_l.cpp
@@ -0,0 +1,30 @@
+//===-- Implementation of strtoll_l ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/strtoll_l.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/str_to_integer.h"
+#include "src/errno/libc_errno.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(long long, strtoll_l,
+ (const char *__restrict str, char **__restrict str_end,
+ int base, locale_t)) {
+ auto result = internal::strtointeger<long long>(str, base);
+ if (result.has_error())
+ libc_errno = result.error;
+
+ if (str_end != nullptr)
+ *str_end = const_cast<char *>(str + result.parsed_len);
+
+ return result;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/strtoll_l.h b/libc/src/stdlib/strtoll_l.h
new file mode 100644
index 00000000000000..461fedb3df485d
--- /dev/null
+++ b/libc/src/stdlib/strtoll_l.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for strtoll_l ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDLIB_STRTOLL_L_H
+#define LLVM_LIBC_SRC_STDLIB_STRTOLL_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+long long strtoll_l(const char *__restrict str, char **__restrict str_end,
+ int base, locale_t locale);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRTOLL_L_H
diff --git a/libc/src/stdlib/strtoul_l.cpp b/libc/src/stdlib/strtoul_l.cpp
new file mode 100644
index 00000000000000..74fce00a0ac3c4
--- /dev/null
+++ b/libc/src/stdlib/strtoul_l.cpp
@@ -0,0 +1,30 @@
+//===-- Implementation of strtoul_l ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/strtoul_l.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/str_to_integer.h"
+#include "src/errno/libc_errno.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(unsigned long, strtoul_l,
+ (const char *__restrict str, char **__restrict str_end,
+ int base, locale_t)) {
+ auto result = internal::strtointeger<unsigned long>(str, base);
+ if (result.has_error())
+ libc_errno = result.error;
+
+ if (str_end != nullptr)
+ *str_end = const_cast<char *>(str + result.parsed_len);
+
+ return result;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/strtoul_l.h b/libc/src/stdlib/strtoul_l.h
new file mode 100644
index 00000000000000..7c9f53a8acb31c
--- /dev/null
+++ b/libc/src/stdlib/strtoul_l.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for strtoul_l ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDLIB_STRTOUL_L_H
+#define LLVM_LIBC_SRC_STDLIB_STRTOUL_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned long strtoul_l(const char *__restrict str, char **__restrict str_end,
+ int base, locale_t locale);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRTOUL_L_H
diff --git a/libc/src/stdlib/strtoull_l.cpp b/libc/src/stdlib/strtoull_l.cpp
new file mode 100644
index 00000000000000..2ea8a43a40ef2a
--- /dev/null
+++ b/libc/src/stdlib/strtoull_l.cpp
@@ -0,0 +1,30 @@
+//===-- Implementation of strtoull_l --------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/strtoull_l.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/str_to_integer.h"
+#include "src/errno/libc_errno.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(unsigned long long, strtoull_l,
+ (const char *__restrict str, char **__restrict str_end,
+ int base, locale_t)) {
+ auto result = internal::strtointeger<unsigned long long>(str, base);
+ if (result.has_error())
+ libc_errno = result.error;
+
+ if (str_end != nullptr)
+ *str_end = const_cast<char *>(str + result.parsed_len);
+
+ return result;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/strtoull_l.h b/libc/src/stdlib/strtoull_l.h
new file mode 100644
index 00000000000000..c40f83ed1ffff2
--- /dev/null
+++ b/libc/src/stdlib/strtoull_l.h
@@ -0,0 +1,23 @@
+//===-- Implementation header for strtoull_l --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDLIB_STRTOULL_L_H
+#define LLVM_LIBC_SRC_STDLIB_STRTOULL_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned long long strtoull_l(const char *__restrict str,
+ char **__restrict str_end, int base,
+ locale_t locale);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRTOULL_L_H
More information about the libc-commits
mailing list