[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