From 70ebef4c2013676b450c6744ac506fe8082d5e2a Mon Sep 17 00:00:00 2001 From: Denis Zubarev Date: Thu, 6 Nov 2025 15:28:11 +0300 Subject: [PATCH 1/8] ctype functions -> runtime-common --- .../kphp-light/stdlib/system-functions.txt | 11 ++++++++--- runtime-common/stdlib/stdlib.cmake | 4 ++-- .../stdlib/string/ctype-functions.cpp | 4 ++-- .../stdlib/string/ctype-functions.h | 2 +- runtime/runtime.cmake | 1 - 5 files changed, 13 insertions(+), 9 deletions(-) rename runtime/ctype.cpp => runtime-common/stdlib/string/ctype-functions.cpp (96%) rename runtime/ctype.h => runtime-common/stdlib/string/ctype-functions.h (94%) diff --git a/builtin-functions/kphp-light/stdlib/system-functions.txt b/builtin-functions/kphp-light/stdlib/system-functions.txt index 3ec1bcec1e..8b6b55ba11 100644 --- a/builtin-functions/kphp-light/stdlib/system-functions.txt +++ b/builtin-functions/kphp-light/stdlib/system-functions.txt @@ -50,9 +50,14 @@ function raise_sigsegv () ::: void; /** @kphp-extern-func-info stub */ function system($command ::: string, int &$result_code = 0): int; -/** @kphp-extern-func-info stub generation-required */ function ctype_alnum(mixed $text): bool; -/** @kphp-extern-func-info stub generation-required */ +function ctype_alpha(mixed $text): bool; +function ctype_cntrl(mixed $text): bool; function ctype_digit(mixed $text): bool; -/** @kphp-extern-func-info stub generation-required */ +function ctype_graph(mixed $text): bool; +function ctype_lower(mixed $text): bool; +function ctype_print(mixed $text): bool; +function ctype_punct(mixed $text): bool; +function ctype_space(mixed $text): bool; +function ctype_upper(mixed $text): bool; function ctype_xdigit(mixed $text): bool; diff --git a/runtime-common/stdlib/stdlib.cmake b/runtime-common/stdlib/stdlib.cmake index 46b4f14cfd..ad0ebe9898 100644 --- a/runtime-common/stdlib/stdlib.cmake +++ b/runtime-common/stdlib/stdlib.cmake @@ -6,8 +6,8 @@ prepend(STDLIB_MSGPACK stdlib/msgpack/ object_visitor.cpp packer.cpp parser.cpp unpacker.cpp zone.cpp) prepend(STDLIB_SERIALIZATION stdlib/serialization/ json-functions.cpp json-writer.cpp serialize-functions.cpp) -prepend(STDLIB_STRING stdlib/string/ mbstring-functions.cpp - regex-functions.cpp string-functions.cpp) +prepend(STDLIB_STRING stdlib/string/ ctype-functions.cpp + mbstring-functions.cpp regex-functions.cpp string-functions.cpp) prepend(STDLIB_SYSTEM stdlib/system/ system-functions.cpp) prepend(STDLIB_SERVER stdlib/server/ url-functions.cpp net-functions.cpp) diff --git a/runtime/ctype.cpp b/runtime-common/stdlib/string/ctype-functions.cpp similarity index 96% rename from runtime/ctype.cpp rename to runtime-common/stdlib/string/ctype-functions.cpp index 6932d35c9b..18da331e72 100644 --- a/runtime/ctype.cpp +++ b/runtime-common/stdlib/string/ctype-functions.cpp @@ -1,8 +1,8 @@ // Compiler for PHP (aka KPHP) -// Copyright (c) 2020 LLC «V Kontakte» +// Copyright (c) 2025 LLC «V Kontakte» // Distributed under the GPL v3 License, see LICENSE.notice.txt -#include "runtime/ctype.h" +#include "ctype-functions.h" #include #include diff --git a/runtime/ctype.h b/runtime-common/stdlib/string/ctype-functions.h similarity index 94% rename from runtime/ctype.h rename to runtime-common/stdlib/string/ctype-functions.h index a62dd67061..c52e1d3d05 100644 --- a/runtime/ctype.h +++ b/runtime-common/stdlib/string/ctype-functions.h @@ -1,5 +1,5 @@ // Compiler for PHP (aka KPHP) -// Copyright (c) 2022 LLC «V Kontakte» +// Copyright (c) 2025 LLC «V Kontakte» // Distributed under the GPL v3 License, see LICENSE.notice.txt #pragma once diff --git a/runtime/runtime.cmake b/runtime/runtime.cmake index 9c161d5864..29a08819de 100644 --- a/runtime/runtime.cmake +++ b/runtime/runtime.cmake @@ -70,7 +70,6 @@ prepend(KPHP_RUNTIME_SOURCES ${BASE_DIR}/runtime/ confdata-global-manager.cpp confdata-keys.cpp critical_section.cpp - ctype.cpp curl.cpp curl-async.cpp env.cpp From 839feaf7ae93cf7850b857cac81e9384331c2905 Mon Sep 17 00:00:00 2001 From: Denis Zubarev Date: Thu, 6 Nov 2025 16:02:23 +0300 Subject: [PATCH 2/8] add tests --- tests/phpt/string_functions/012_ctype.php | 79 +++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 tests/phpt/string_functions/012_ctype.php diff --git a/tests/phpt/string_functions/012_ctype.php b/tests/phpt/string_functions/012_ctype.php new file mode 100644 index 0000000000..502f178707 --- /dev/null +++ b/tests/phpt/string_functions/012_ctype.php @@ -0,0 +1,79 @@ +@ok + Date: Thu, 6 Nov 2025 16:03:31 +0300 Subject: [PATCH 3/8] add new line in test file --- tests/phpt/string_functions/012_ctype.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpt/string_functions/012_ctype.php b/tests/phpt/string_functions/012_ctype.php index 502f178707..2263126897 100644 --- a/tests/phpt/string_functions/012_ctype.php +++ b/tests/phpt/string_functions/012_ctype.php @@ -76,4 +76,4 @@ var_dump(ctype_punct("abc!")); var_dump(ctype_punct(" ")); var_dump(ctype_punct("")); -var_dump(ctype_punct("!@#abc")); \ No newline at end of file +var_dump(ctype_punct("!@#abc")); From d50866f29b0ffd9a757af45732156b65fa13c93e Mon Sep 17 00:00:00 2001 From: Denis Zubarev Date: Thu, 6 Nov 2025 16:54:24 +0300 Subject: [PATCH 4/8] minifix --- .../kphp-light/stdlib/system-functions.txt | 34 ++++++++++++------- .../stdlib/string/ctype-functions.cpp | 9 +++-- .../stdlib/string/ctype-functions.h | 12 +++++-- 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/builtin-functions/kphp-light/stdlib/system-functions.txt b/builtin-functions/kphp-light/stdlib/system-functions.txt index 8b6b55ba11..4c7e9c5fa6 100644 --- a/builtin-functions/kphp-light/stdlib/system-functions.txt +++ b/builtin-functions/kphp-light/stdlib/system-functions.txt @@ -1,5 +1,27 @@ #include -static bool ctype_impl(const mixed& text, int (*iswhat)(int), bool allow_digits, bool allow_minus) noexcept { +namespace { +bool ctype_impl(const mixed& text, int (*iswhat)(int), bool allow_digits, bool allow_minus) noexcept { if (text.is_string()) { const string& str = text.as_string(); if (str.empty()) { return false; } - return std::all_of(str.c_str(), str.c_str() + str.size(), [iswhat](std::uint8_t c) { return iswhat(c); }); + return std::all_of(str.c_str(), str.c_str() + str.size(), [iswhat](uint8_t c) noexcept { return iswhat(c); }); } if (text.is_int()) { @@ -31,6 +33,7 @@ static bool ctype_impl(const mixed& text, int (*iswhat)(int), bool allow_digits, return false; } +} // namespace bool f$ctype_alnum(const mixed& text) noexcept { return ctype_impl(text, std::isalnum, true, false); diff --git a/runtime-common/stdlib/string/ctype-functions.h b/runtime-common/stdlib/string/ctype-functions.h index c52e1d3d05..9c166fce77 100644 --- a/runtime-common/stdlib/string/ctype-functions.h +++ b/runtime-common/stdlib/string/ctype-functions.h @@ -4,16 +4,24 @@ #pragma once -#include "runtime-common/core/runtime-core.h" - bool f$ctype_alnum(const mixed& text) noexcept; + bool f$ctype_alpha(const mixed& text) noexcept; + bool f$ctype_cntrl(const mixed& text) noexcept; + bool f$ctype_digit(const mixed& text) noexcept; + bool f$ctype_graph(const mixed& text) noexcept; + bool f$ctype_lower(const mixed& text) noexcept; + bool f$ctype_print(const mixed& text) noexcept; + bool f$ctype_punct(const mixed& text) noexcept; + bool f$ctype_space(const mixed& text) noexcept; + bool f$ctype_upper(const mixed& text) noexcept; + bool f$ctype_xdigit(const mixed& text) noexcept; From f1a6d21328e8c3d8c7a4b0952e531e115af8b4f9 Mon Sep 17 00:00:00 2001 From: Denis Zubarev Date: Fri, 7 Nov 2025 10:29:42 +0300 Subject: [PATCH 5/8] fix --- runtime-common/stdlib/string/ctype-functions.cpp | 1 - runtime-common/stdlib/string/ctype-functions.h | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/runtime-common/stdlib/string/ctype-functions.cpp b/runtime-common/stdlib/string/ctype-functions.cpp index dd64d5624d..589e24ac08 100644 --- a/runtime-common/stdlib/string/ctype-functions.cpp +++ b/runtime-common/stdlib/string/ctype-functions.cpp @@ -2,7 +2,6 @@ // Copyright (c) 2025 LLC «V Kontakte» // Distributed under the GPL v3 License, see LICENSE.notice.txt -#include "runtime-common/core/runtime-core.h" #include "runtime-common/stdlib/string/ctype-functions.h" #include diff --git a/runtime-common/stdlib/string/ctype-functions.h b/runtime-common/stdlib/string/ctype-functions.h index 9c166fce77..1414218981 100644 --- a/runtime-common/stdlib/string/ctype-functions.h +++ b/runtime-common/stdlib/string/ctype-functions.h @@ -4,6 +4,8 @@ #pragma once +#include "runtime-common/core/runtime-core.h" + bool f$ctype_alnum(const mixed& text) noexcept; bool f$ctype_alpha(const mixed& text) noexcept; From 136a87b52cc7213928b3afd401c37dce76caeb7d Mon Sep 17 00:00:00 2001 From: Denis Zubarev Date: Fri, 7 Nov 2025 13:12:21 +0300 Subject: [PATCH 6/8] ctype.cpp -> ctype.h --- runtime-common/stdlib/stdlib.cmake | 4 +- .../stdlib/string/ctype-functions.cpp | 79 ------------------- .../stdlib/string/ctype-functions.h | 74 ++++++++++++++--- 3 files changed, 65 insertions(+), 92 deletions(-) delete mode 100644 runtime-common/stdlib/string/ctype-functions.cpp diff --git a/runtime-common/stdlib/stdlib.cmake b/runtime-common/stdlib/stdlib.cmake index ad0ebe9898..46b4f14cfd 100644 --- a/runtime-common/stdlib/stdlib.cmake +++ b/runtime-common/stdlib/stdlib.cmake @@ -6,8 +6,8 @@ prepend(STDLIB_MSGPACK stdlib/msgpack/ object_visitor.cpp packer.cpp parser.cpp unpacker.cpp zone.cpp) prepend(STDLIB_SERIALIZATION stdlib/serialization/ json-functions.cpp json-writer.cpp serialize-functions.cpp) -prepend(STDLIB_STRING stdlib/string/ ctype-functions.cpp - mbstring-functions.cpp regex-functions.cpp string-functions.cpp) +prepend(STDLIB_STRING stdlib/string/ mbstring-functions.cpp + regex-functions.cpp string-functions.cpp) prepend(STDLIB_SYSTEM stdlib/system/ system-functions.cpp) prepend(STDLIB_SERVER stdlib/server/ url-functions.cpp net-functions.cpp) diff --git a/runtime-common/stdlib/string/ctype-functions.cpp b/runtime-common/stdlib/string/ctype-functions.cpp deleted file mode 100644 index 589e24ac08..0000000000 --- a/runtime-common/stdlib/string/ctype-functions.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// Compiler for PHP (aka KPHP) -// Copyright (c) 2025 LLC «V Kontakte» -// Distributed under the GPL v3 License, see LICENSE.notice.txt - -#include "runtime-common/stdlib/string/ctype-functions.h" - -#include -#include - -namespace { -bool ctype_impl(const mixed& text, int (*iswhat)(int), bool allow_digits, bool allow_minus) noexcept { - if (text.is_string()) { - const string& str = text.as_string(); - if (str.empty()) { - return false; - } - return std::all_of(str.c_str(), str.c_str() + str.size(), [iswhat](uint8_t c) noexcept { return iswhat(c); }); - } - - if (text.is_int()) { - const int64_t i = text.as_int(); - if (i <= 255 && i >= 0) { - return iswhat(i); - } else if (i >= -128 && i < 0) { - return iswhat(i + 256); - } else if (i >= 0) { - return allow_digits; - } else { - return allow_minus; - } - } - - return false; -} -} // namespace - -bool f$ctype_alnum(const mixed& text) noexcept { - return ctype_impl(text, std::isalnum, true, false); -} - -bool f$ctype_alpha(const mixed& text) noexcept { - return ctype_impl(text, std::isalpha, false, false); -} - -bool f$ctype_cntrl(const mixed& text) noexcept { - return ctype_impl(text, std::iscntrl, false, false); -} - -bool f$ctype_digit(const mixed& text) noexcept { - return ctype_impl(text, std::isdigit, true, false); -} - -bool f$ctype_graph(const mixed& text) noexcept { - return ctype_impl(text, std::isgraph, true, true); -} - -bool f$ctype_lower(const mixed& text) noexcept { - return ctype_impl(text, std::islower, false, false); -} - -bool f$ctype_print(const mixed& text) noexcept { - return ctype_impl(text, std::isprint, true, true); -} - -bool f$ctype_punct(const mixed& text) noexcept { - return ctype_impl(text, std::ispunct, false, false); -} - -bool f$ctype_space(const mixed& text) noexcept { - return ctype_impl(text, std::isspace, false, false); -} - -bool f$ctype_upper(const mixed& text) noexcept { - return ctype_impl(text, std::isupper, false, false); -} - -bool f$ctype_xdigit(const mixed& text) noexcept { - return ctype_impl(text, std::isxdigit, true, false); -} diff --git a/runtime-common/stdlib/string/ctype-functions.h b/runtime-common/stdlib/string/ctype-functions.h index 1414218981..164877c9b6 100644 --- a/runtime-common/stdlib/string/ctype-functions.h +++ b/runtime-common/stdlib/string/ctype-functions.h @@ -6,24 +6,76 @@ #include "runtime-common/core/runtime-core.h" -bool f$ctype_alnum(const mixed& text) noexcept; +#include +#include -bool f$ctype_alpha(const mixed& text) noexcept; +namespace ctype_impl_{ +inline bool ctype_impl(const mixed& text, int (*iswhat)(int), bool allow_digits, bool allow_minus) noexcept { + if (text.is_string()) { + const string& str = text.as_string(); + if (str.empty()) { + return false; + } + return std::all_of(str.c_str(), str.c_str() + str.size(), [iswhat](uint8_t c) noexcept { return iswhat(c); }); + } -bool f$ctype_cntrl(const mixed& text) noexcept; + if (text.is_int()) { + const int64_t i = text.as_int(); + if (i <= 255 && i >= 0) { + return iswhat(i); + } else if (i >= -128 && i < 0) { + return iswhat(i + 256); + } else if (i >= 0) { + return allow_digits; + } else { + return allow_minus; + } + } -bool f$ctype_digit(const mixed& text) noexcept; + return false; +} +} // namespace ctype_impl_ -bool f$ctype_graph(const mixed& text) noexcept; +inline bool f$ctype_alnum(const mixed& text) noexcept { + return ctype_impl_::ctype_impl(text, std::isalnum, true, false); +} -bool f$ctype_lower(const mixed& text) noexcept; +inline bool f$ctype_alpha(const mixed& text) noexcept { + return ctype_impl_::ctype_impl(text, std::isalpha, false, false); +} -bool f$ctype_print(const mixed& text) noexcept; +inline bool f$ctype_cntrl(const mixed& text) noexcept { + return ctype_impl_::ctype_impl(text, std::iscntrl, false, false); +} -bool f$ctype_punct(const mixed& text) noexcept; +inline bool f$ctype_digit(const mixed& text) noexcept { + return ctype_impl_::ctype_impl(text, std::isdigit, true, false); +} -bool f$ctype_space(const mixed& text) noexcept; +inline bool f$ctype_graph(const mixed& text) noexcept { + return ctype_impl_::ctype_impl(text, std::isgraph, true, true); +} -bool f$ctype_upper(const mixed& text) noexcept; +inline bool f$ctype_lower(const mixed& text) noexcept { + return ctype_impl_::ctype_impl(text, std::islower, false, false); +} -bool f$ctype_xdigit(const mixed& text) noexcept; +inline bool f$ctype_print(const mixed& text) noexcept { + return ctype_impl_::ctype_impl(text, std::isprint, true, true); +} + +inline bool f$ctype_punct(const mixed& text) noexcept { + return ctype_impl_::ctype_impl(text, std::ispunct, false, false); +} + +inline bool f$ctype_space(const mixed& text) noexcept { + return ctype_impl_::ctype_impl(text, std::isspace, false, false); +} + +inline bool f$ctype_upper(const mixed& text) noexcept { + return ctype_impl_::ctype_impl(text, std::isupper, false, false); +} + +inline bool f$ctype_xdigit(const mixed& text) noexcept { + return ctype_impl_::ctype_impl(text, std::isxdigit, true, false); +} From 4dfaaa156b84ea9ab681d80cd73fc57110b763af Mon Sep 17 00:00:00 2001 From: Denis Zubarev Date: Fri, 7 Nov 2025 13:14:40 +0300 Subject: [PATCH 7/8] add space --- runtime-common/stdlib/string/ctype-functions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime-common/stdlib/string/ctype-functions.h b/runtime-common/stdlib/string/ctype-functions.h index 164877c9b6..80365e5058 100644 --- a/runtime-common/stdlib/string/ctype-functions.h +++ b/runtime-common/stdlib/string/ctype-functions.h @@ -9,7 +9,7 @@ #include #include -namespace ctype_impl_{ +namespace ctype_impl_ { inline bool ctype_impl(const mixed& text, int (*iswhat)(int), bool allow_digits, bool allow_minus) noexcept { if (text.is_string()) { const string& str = text.as_string(); From c1f6b68dfe3ee37a00a380c0a42b74d22ab386d2 Mon Sep 17 00:00:00 2001 From: Denis Zubarev Date: Sat, 8 Nov 2025 01:05:55 +0300 Subject: [PATCH 8/8] include cstdint --- runtime-common/stdlib/string/ctype-functions.h | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime-common/stdlib/string/ctype-functions.h b/runtime-common/stdlib/string/ctype-functions.h index 80365e5058..731883e07f 100644 --- a/runtime-common/stdlib/string/ctype-functions.h +++ b/runtime-common/stdlib/string/ctype-functions.h @@ -8,6 +8,7 @@ #include #include +#include namespace ctype_impl_ { inline bool ctype_impl(const mixed& text, int (*iswhat)(int), bool allow_digits, bool allow_minus) noexcept {