[libc-commits] [libc] [libc][ctype] delegate core ctype checks to ctype_utils (PR #198281)

Jeff Bailey via libc-commits libc-commits at lists.llvm.org
Mon May 18 05:27:43 PDT 2026


https://github.com/kaladron created https://github.com/llvm/llvm-project/pull/198281

Implemented internal helpers in ctype_utils.h and refactored isblank, isprint, iscntrl, and isascii to use them.

Assisted-by: Automated tooling, human reviewed.

>From 1654ad956e60d4090db1432c0abd7f030315621e Mon Sep 17 00:00:00 2001
From: Jeff Bailey <jbailey at raspberryginger.com>
Date: Mon, 18 May 2026 13:20:47 +0100
Subject: [PATCH] [libc][ctype] delegate core ctype checks to ctype_utils

Implemented internal helpers in ctype_utils.h and refactored
isblank, isprint, iscntrl, and isascii to use them.

Assisted-by: Automated tooling, human reviewed.
---
 libc/src/__support/ctype_utils.h | 12 ++++++++++++
 libc/src/ctype/CMakeLists.txt    | 23 +++++++++++++++++++++--
 libc/src/ctype/isascii.cpp       |  3 ++-
 libc/src/ctype/isblank.cpp       |  6 +++++-
 libc/src/ctype/iscntrl.cpp       |  7 +++++--
 libc/src/ctype/isprint.cpp       |  7 +++++--
 6 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/libc/src/__support/ctype_utils.h b/libc/src/__support/ctype_utils.h
index e52f6ec425e28..f99d1287be836 100644
--- a/libc/src/__support/ctype_utils.h
+++ b/libc/src/__support/ctype_utils.h
@@ -597,6 +597,18 @@ LIBC_INLINE constexpr bool is_char_or_wchar(char ch, char c_value,
   return (ch == c_value);
 }
 
+LIBC_INLINE constexpr bool isblank(char ch) { return ch == ' ' || ch == '\t'; }
+
+LIBC_INLINE constexpr bool iscntrl(char ch) {
+  return static_cast<unsigned char>(ch) < 0x20 || ch == 0x7f;
+}
+
+LIBC_INLINE constexpr bool isprint(char ch) {
+  return static_cast<unsigned char>(ch - 0x20) < 95;
+}
+
+LIBC_INLINE constexpr bool isascii(int c) { return (c & (~0x7f)) == 0; }
+
 } // namespace internal
 } // namespace LIBC_NAMESPACE_DECL
 
diff --git a/libc/src/ctype/CMakeLists.txt b/libc/src/ctype/CMakeLists.txt
index 68e982bd4529e..3e870144d4eb5 100644
--- a/libc/src/ctype/CMakeLists.txt
+++ b/libc/src/ctype/CMakeLists.txt
@@ -27,6 +27,10 @@ add_entrypoint_object(
     isascii.cpp
   HDRS
     isascii.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.macros.config
+    libc.src.__support.ctype_utils
 )
 
 add_entrypoint_object(
@@ -35,6 +39,11 @@ add_entrypoint_object(
     isblank.cpp
   HDRS
     isblank.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.macros.config
+    libc.src.__support.CPP.limits
+    libc.src.__support.ctype_utils
 )
 
 add_entrypoint_object(
@@ -43,6 +52,11 @@ add_entrypoint_object(
     iscntrl.cpp
   HDRS
     iscntrl.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.macros.config
+    libc.src.__support.CPP.limits
+    libc.src.__support.ctype_utils
 )
 
 add_entrypoint_object(
@@ -84,6 +98,11 @@ add_entrypoint_object(
     isprint.cpp
   HDRS
     isprint.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.macros.config
+    libc.src.__support.CPP.limits
+    libc.src.__support.ctype_utils
 )
 
 add_entrypoint_object(
@@ -115,7 +134,7 @@ add_entrypoint_object(
   HDRS
     isupper.h
   DEPENDS
-    libc.src.__support.CPP.limits  
+    libc.src.__support.CPP.limits
     libc.src.__support.ctype_utils
 )
 
@@ -285,7 +304,7 @@ add_entrypoint_object(
   HDRS
     isupper_l.h
   DEPENDS
-    libc.src.__support.CPP.limits  
+    libc.src.__support.CPP.limits
     libc.src.__support.ctype_utils
     libc.hdr.types.locale_t
 )
diff --git a/libc/src/ctype/isascii.cpp b/libc/src/ctype/isascii.cpp
index ef3788d136e9d..7cbfde57c7ebd 100644
--- a/libc/src/ctype/isascii.cpp
+++ b/libc/src/ctype/isascii.cpp
@@ -9,12 +9,13 @@
 #include "src/ctype/isascii.h"
 
 #include "src/__support/common.h"
+#include "src/__support/ctype_utils.h"
 #include "src/__support/macros/config.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, isascii, (int c)) {
-  return static_cast<int>((c & (~0x7f)) == 0);
+  return static_cast<int>(internal::isascii(c));
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/ctype/isblank.cpp b/libc/src/ctype/isblank.cpp
index e0a20829f86ce..071f4a8ce7c3a 100644
--- a/libc/src/ctype/isblank.cpp
+++ b/libc/src/ctype/isblank.cpp
@@ -8,13 +8,17 @@
 
 #include "src/ctype/isblank.h"
 
+#include "src/__support/CPP/limits.h"
 #include "src/__support/common.h"
+#include "src/__support/ctype_utils.h"
 #include "src/__support/macros/config.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, isblank, (int c)) {
-  return static_cast<int>(c == ' ' || c == '\t');
+  if (c < 0 || c > cpp::numeric_limits<unsigned char>::max())
+    return 0;
+  return static_cast<int>(internal::isblank(static_cast<char>(c)));
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/ctype/iscntrl.cpp b/libc/src/ctype/iscntrl.cpp
index 2218adfcc33f3..57941dad23d34 100644
--- a/libc/src/ctype/iscntrl.cpp
+++ b/libc/src/ctype/iscntrl.cpp
@@ -8,14 +8,17 @@
 
 #include "src/ctype/iscntrl.h"
 
+#include "src/__support/CPP/limits.h"
 #include "src/__support/common.h"
+#include "src/__support/ctype_utils.h"
 #include "src/__support/macros/config.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, iscntrl, (int c)) {
-  const unsigned ch = static_cast<unsigned>(c);
-  return static_cast<int>(ch < 0x20 || ch == 0x7f);
+  if (c < 0 || c > cpp::numeric_limits<unsigned char>::max())
+    return 0;
+  return static_cast<int>(internal::iscntrl(static_cast<char>(c)));
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/ctype/isprint.cpp b/libc/src/ctype/isprint.cpp
index 349aefe1c17bb..75b57370c593f 100644
--- a/libc/src/ctype/isprint.cpp
+++ b/libc/src/ctype/isprint.cpp
@@ -8,14 +8,17 @@
 
 #include "src/ctype/isprint.h"
 
+#include "src/__support/CPP/limits.h"
 #include "src/__support/common.h"
+#include "src/__support/ctype_utils.h"
 #include "src/__support/macros/config.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, isprint, (int c)) {
-  const unsigned ch = static_cast<unsigned>(c);
-  return static_cast<int>((ch - ' ') < 95);
+  if (c < 0 || c > cpp::numeric_limits<unsigned char>::max())
+    return 0;
+  return static_cast<int>(internal::isprint(static_cast<char>(c)));
 }
 
 } // namespace LIBC_NAMESPACE_DECL



More information about the libc-commits mailing list