[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