[libc-commits] [libc] 128bf45 - [libc] Add tolower, toupper implementation.

via libc-commits libc-commits at lists.llvm.org
Thu Aug 6 12:22:17 PDT 2020


Author: cgyurgyik
Date: 2020-08-06T15:21:38-04:00
New Revision: 128bf458ab8c5bdbb02e5b13769a618b357d5ae2

URL: https://github.com/llvm/llvm-project/commit/128bf458ab8c5bdbb02e5b13769a618b357d5ae2
DIFF: https://github.com/llvm/llvm-project/commit/128bf458ab8c5bdbb02e5b13769a618b357d5ae2.diff

LOG: [libc] Add tolower, toupper implementation.

Reviewed By: sivachandra

Differential Revision: https://reviews.llvm.org/D85326

Added: 
    libc/src/ctype/tolower.cpp
    libc/src/ctype/tolower.h
    libc/src/ctype/toupper.cpp
    libc/src/ctype/toupper.h
    libc/test/src/ctype/tolower_test.cpp
    libc/test/src/ctype/toupper_test.cpp

Modified: 
    libc/config/linux/aarch64/entrypoints.txt
    libc/config/linux/api.td
    libc/config/linux/x86_64/entrypoints.txt
    libc/spec/stdc.td
    libc/src/ctype/CMakeLists.txt
    libc/src/ctype/ctype_utils.h
    libc/src/ctype/islower.cpp
    libc/src/ctype/isupper.cpp
    libc/test/src/ctype/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 468f2cc69ebe..e1f54bfaa4fd 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -12,6 +12,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.ctype.isspace
     libc.src.ctype.isupper
     libc.src.ctype.isxdigit
+    libc.src.ctype.tolower
+    libc.src.ctype.toupper
     
     # errno.h entrypoints
     libc.src.errno.__errno_location

diff  --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index 71b592d294a9..151924748dc1 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -100,6 +100,8 @@ def CTypeAPI : PublicAPI<"ctype.h"> {
     "isspace",
     "isupper",
     "isxdigit",
+    "tolower",
+    "toupper",
   ];
 }
 

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 031812ce32d7..db76c351db7f 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -15,6 +15,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.ctype.isspace
     libc.src.ctype.isupper
     libc.src.ctype.isxdigit
+    libc.src.ctype.tolower
+    libc.src.ctype.toupper
 
     # errno.h entrypoints
     libc.src.errno.__errno_location

diff  --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 892fbb2d3076..ac240ff9576e 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -106,6 +106,16 @@ def StdC : StandardSpec<"stdc"> {
               RetValSpec<IntType>,
               [ArgSpec<IntType>]
           >,
+          FunctionSpec<
+              "tolower",
+              RetValSpec<IntType>,
+              [ArgSpec<IntType>]
+          >,
+          FunctionSpec<
+              "toupper",
+              RetValSpec<IntType>,
+              [ArgSpec<IntType>]
+          >,
       ]
   >;
      

diff  --git a/libc/src/ctype/CMakeLists.txt b/libc/src/ctype/CMakeLists.txt
index 4356eabf23fe..da8c4403d959 100644
--- a/libc/src/ctype/CMakeLists.txt
+++ b/libc/src/ctype/CMakeLists.txt
@@ -66,6 +66,8 @@ add_entrypoint_object(
     islower.cpp
   HDRS
     islower.h
+  DEPENDS
+    .ctype_utils
 )
 
 add_entrypoint_object(
@@ -100,6 +102,8 @@ add_entrypoint_object(
     isupper.cpp
   HDRS
     isupper.h
+  DEPENDS
+    .ctype_utils
 )
 
 add_entrypoint_object(
@@ -111,3 +115,23 @@ add_entrypoint_object(
   DEPENDS
     .ctype_utils
 )
+
+add_entrypoint_object(
+  tolower
+  SRCS
+    tolower.cpp
+  HDRS
+    tolower.h
+  DEPENDS
+    .ctype_utils
+)
+
+add_entrypoint_object(
+  toupper
+  SRCS
+    toupper.cpp
+  HDRS
+    toupper.h
+  DEPENDS
+    .ctype_utils
+)

diff  --git a/libc/src/ctype/ctype_utils.h b/libc/src/ctype/ctype_utils.h
index 787a19ebf132..6238bd32d9f8 100644
--- a/libc/src/ctype/ctype_utils.h
+++ b/libc/src/ctype/ctype_utils.h
@@ -18,14 +18,18 @@ namespace internal {
 // of a function call by inlining them.
 // ------------------------------------------------------
 
-static inline int isdigit(unsigned ch) { return (ch - '0') < 10; }
-
 static inline int isalpha(unsigned ch) { return (ch | 32) - 'a' < 26; }
 
+static inline int isdigit(unsigned ch) { return (ch - '0') < 10; }
+
 static inline int isalnum(unsigned ch) { return isalpha(ch) || isdigit(ch); }
 
 static inline int isgraph(unsigned ch) { return 0x20 < ch && ch < 0x7f; }
 
+static inline int islower(unsigned ch) { return (ch - 'a') < 26; }
+
+static inline int isupper(unsigned ch) { return (ch - 'A') < 26; }
+
 } // namespace internal
 } // namespace __llvm_libc
 

diff  --git a/libc/src/ctype/islower.cpp b/libc/src/ctype/islower.cpp
index df21355f31ac..ae1291b5eda4 100644
--- a/libc/src/ctype/islower.cpp
+++ b/libc/src/ctype/islower.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/ctype/islower.h"
+#include "src/ctype/ctype_utils.h"
 
 #include "src/__support/common.h"
 
@@ -14,9 +15,6 @@ namespace __llvm_libc {
 
 // TODO: Currently restricted to default locale.
 // These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(islower)(int c) {
-  const unsigned ch = c;
-  return (ch - 'a') < 26;
-}
+int LLVM_LIBC_ENTRYPOINT(islower)(int c) { return internal::islower(c); }
 
 } // namespace __llvm_libc

diff  --git a/libc/src/ctype/isupper.cpp b/libc/src/ctype/isupper.cpp
index 57aed961d1e5..9b0e5232f1f9 100644
--- a/libc/src/ctype/isupper.cpp
+++ b/libc/src/ctype/isupper.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/ctype/isupper.h"
+#include "src/ctype/ctype_utils.h"
 
 #include "src/__support/common.h"
 
@@ -14,9 +15,6 @@ namespace __llvm_libc {
 
 // TODO: Currently restricted to default locale.
 // These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isupper)(int c) {
-  const unsigned ch = c;
-  return (ch - 'A') < 26;
-}
+int LLVM_LIBC_ENTRYPOINT(isupper)(int c) { return internal::isupper(c); }
 
 } // namespace __llvm_libc

diff  --git a/libc/src/ctype/tolower.cpp b/libc/src/ctype/tolower.cpp
new file mode 100644
index 000000000000..6fd300680179
--- /dev/null
+++ b/libc/src/ctype/tolower.cpp
@@ -0,0 +1,24 @@
+//===-- Implementation of tolower------------------------------------------===//
+//
+// 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/ctype/tolower.h"
+#include "src/ctype/ctype_utils.h"
+
+#include "src/__support/common.h"
+
+namespace __llvm_libc {
+
+// TODO: Currently restricted to default locale.
+// These should be extended using locale information.
+int LLVM_LIBC_ENTRYPOINT(tolower)(int c) {
+  if (internal::isupper(c))
+    return c + 'a' - 'A';
+  return c;
+}
+
+} // namespace __llvm_libc

diff  --git a/libc/src/ctype/tolower.h b/libc/src/ctype/tolower.h
new file mode 100644
index 000000000000..97e675c55825
--- /dev/null
+++ b/libc/src/ctype/tolower.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for tolower -------------------------*-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_CTYPE_TOLOWER_H
+#define LLVM_LIBC_SRC_CTYPE_TOLOWER_H
+
+namespace __llvm_libc {
+
+int tolower(int c);
+
+} // namespace __llvm_libc
+
+#endif //  LLVM_LIBC_SRC_CTYPE_TOLOWER_H

diff  --git a/libc/src/ctype/toupper.cpp b/libc/src/ctype/toupper.cpp
new file mode 100644
index 000000000000..8d591c20be67
--- /dev/null
+++ b/libc/src/ctype/toupper.cpp
@@ -0,0 +1,24 @@
+//===-- Implementation of toupper------------------------------------------===//
+//
+// 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/ctype/toupper.h"
+#include "src/ctype/ctype_utils.h"
+
+#include "src/__support/common.h"
+
+namespace __llvm_libc {
+
+// TODO: Currently restricted to default locale.
+// These should be extended using locale information.
+int LLVM_LIBC_ENTRYPOINT(toupper)(int c) {
+  if (internal::islower(c))
+    return c + 'A' - 'a';
+  return c;
+}
+
+} // namespace __llvm_libc

diff  --git a/libc/src/ctype/toupper.h b/libc/src/ctype/toupper.h
new file mode 100644
index 000000000000..a21b0cf79d95
--- /dev/null
+++ b/libc/src/ctype/toupper.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for toupper -------------------------*-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_CTYPE_TOUPPER_H
+#define LLVM_LIBC_SRC_CTYPE_TOUPPER_H
+
+namespace __llvm_libc {
+
+int toupper(int c);
+
+} // namespace __llvm_libc
+
+#endif //  LLVM_LIBC_SRC_CTYPE_TOUPPER_H

diff  --git a/libc/test/src/ctype/CMakeLists.txt b/libc/test/src/ctype/CMakeLists.txt
index 0d77134b95eb..4141708fc2b4 100644
--- a/libc/test/src/ctype/CMakeLists.txt
+++ b/libc/test/src/ctype/CMakeLists.txt
@@ -119,3 +119,23 @@ add_libc_unittest(
   DEPENDS
     libc.src.ctype.isxdigit
 )
+
+add_libc_unittest(
+  tolower
+  SUITE
+    libc_ctype_unittests
+  SRCS
+    tolower_test.cpp
+  DEPENDS
+    libc.src.ctype.tolower
+)
+
+add_libc_unittest(
+  toupper
+  SUITE
+    libc_ctype_unittests
+  SRCS
+    toupper_test.cpp
+  DEPENDS
+    libc.src.ctype.toupper
+)

diff  --git a/libc/test/src/ctype/tolower_test.cpp b/libc/test/src/ctype/tolower_test.cpp
new file mode 100644
index 000000000000..096ef969bf63
--- /dev/null
+++ b/libc/test/src/ctype/tolower_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for tolower----------------------------------------------===//
+//
+// 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/ctype/tolower.h"
+#include "utils/UnitTest/Test.h"
+
+TEST(ToLower, DefaultLocale) {
+  for (int ch = 0; ch < 255; ++ch) {
+    // This follows pattern 'A' + 32 = 'a'.
+    if ('A' <= ch && ch <= 'Z')
+      EXPECT_EQ(__llvm_libc::tolower(ch), ch + 32);
+    else
+      EXPECT_EQ(__llvm_libc::tolower(ch), ch);
+  }
+}

diff  --git a/libc/test/src/ctype/toupper_test.cpp b/libc/test/src/ctype/toupper_test.cpp
new file mode 100644
index 000000000000..4d6a1b3d4f65
--- /dev/null
+++ b/libc/test/src/ctype/toupper_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for toupper----------------------------------------------===//
+//
+// 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/ctype/toupper.h"
+#include "utils/UnitTest/Test.h"
+
+TEST(ToUpper, DefaultLocale) {
+  for (int ch = 0; ch < 255; ++ch) {
+    // This follows pattern 'a' - 32 = 'A'.
+    if ('a' <= ch && ch <= 'z')
+      EXPECT_EQ(__llvm_libc::toupper(ch), ch - 32);
+    else
+      EXPECT_EQ(__llvm_libc::toupper(ch), ch);
+  }
+}


        


More information about the libc-commits mailing list