mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-27 13:11:46 +03:00
AK: Remove the ctype adapters and use the actual ctype functions instead
This finally takes care of the kind-of excessive boilerplate code that were the ctype adapters. On the other hand, I had to link `LibC/ctype.cpp` to the Kernel (for `AK/JsonParser.cpp` and `AK/Format.cpp`). The previous commit actually makes sense now: the `string.h` includes in `ctype.{h,cpp}` would require to link more LibC stuff to the Kernel when it only needs the `_ctype_` array of `ctype.cpp`, and there wasn't any string stuff used in ctype. Instead of all this I could have put static derivatives of `is_any_of()` in the concerned AK files, however that would have meant more boilerplate and workarounds; so I went for the Kernel approach.
This commit is contained in:
parent
f158cb27ea
commit
f0f6b09acb
Notes:
sideshowbarker
2024-07-19 02:09:17 +09:00
Author: https://github.com/benit8 Commit: https://github.com/SerenityOS/serenity/commit/f0f6b09acb2 Pull-request: https://github.com/SerenityOS/serenity/pull/3623
@ -29,6 +29,7 @@
|
||||
#include <AK/PrintfImplementation.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <ctype.h>
|
||||
|
||||
namespace {
|
||||
|
||||
@ -79,7 +80,7 @@ static bool parse_number(GenericLexer& lexer, size_t& value)
|
||||
|
||||
bool consumed_at_least_one = false;
|
||||
while (!lexer.is_eof()) {
|
||||
if (lexer.next_is(is_digit)) {
|
||||
if (lexer.next_is(isdigit)) {
|
||||
value *= 10;
|
||||
value += lexer.consume() - '0';
|
||||
consumed_at_least_one = true;
|
||||
|
@ -188,7 +188,7 @@ StringView GenericLexer::consume_until(const char* stop)
|
||||
*/
|
||||
StringView GenericLexer::consume_quoted_string(char escape_char)
|
||||
{
|
||||
if (!is_quote(peek()))
|
||||
if (!next_is(is_quote))
|
||||
return {};
|
||||
|
||||
char quote_char = consume();
|
||||
@ -264,75 +264,4 @@ void GenericLexer::ignore_until(const char* stop)
|
||||
ignore(__builtin_strlen(stop));
|
||||
}
|
||||
|
||||
// CType adapters
|
||||
bool is_alpha(char c)
|
||||
{
|
||||
return is_lowercase(c) || is_uppercase(c);
|
||||
}
|
||||
|
||||
bool is_alphanum(char c)
|
||||
{
|
||||
return is_alpha(c) || is_digit(c);
|
||||
}
|
||||
|
||||
bool is_control(char c)
|
||||
{
|
||||
return (c >= 0 && c <= 31) || c == 127;
|
||||
}
|
||||
|
||||
bool is_digit(char c)
|
||||
{
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
bool is_graphic(char c)
|
||||
{
|
||||
return c > ' ' && c <= '~';
|
||||
}
|
||||
|
||||
bool is_hex_digit(char c)
|
||||
{
|
||||
return is_digit(c)
|
||||
|| (c >= 'A' && c <= 'F')
|
||||
|| (c >= 'a' && c <= 'f');
|
||||
}
|
||||
|
||||
bool is_lowercase(char c)
|
||||
{
|
||||
return c >= 'a' && c <= 'z';
|
||||
}
|
||||
|
||||
bool is_path_separator(char c)
|
||||
{
|
||||
return c == '/' || c == '\\';
|
||||
}
|
||||
|
||||
bool is_printable(char c)
|
||||
{
|
||||
return c >= ' ' && c <= '~';
|
||||
}
|
||||
|
||||
bool is_punctuation(char c)
|
||||
{
|
||||
return (c >= '!' && c <= '/')
|
||||
|| (c >= ':' && c <= '@')
|
||||
|| (c >= '[' && c <= '`')
|
||||
|| (c >= '{' && c <= '~');
|
||||
}
|
||||
|
||||
bool is_quote(char c)
|
||||
{
|
||||
return c == '\'' || c == '"';
|
||||
}
|
||||
|
||||
bool is_uppercase(char c)
|
||||
{
|
||||
return c >= 'A' && c <= 'Z';
|
||||
}
|
||||
|
||||
bool is_whitespace(char c)
|
||||
{
|
||||
return (c >= '\t' && c <= '\r') || c == ' ';
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -136,42 +136,12 @@ constexpr auto is_any_of(const StringView& values)
|
||||
return [values](auto c) { return values.contains(c); };
|
||||
}
|
||||
|
||||
/*
|
||||
* CType adapters: pass them as Conditions to a GenericLexer's methods
|
||||
* Examples:
|
||||
* - `if (lexer.next_is(is_digit))`
|
||||
* - `auto name = lexer.consume_while(is_alphanum);
|
||||
* - `lexer.ignore_until(is_any_of("<^>"))`
|
||||
*/
|
||||
bool is_alpha(char);
|
||||
bool is_alphanum(char);
|
||||
bool is_control(char);
|
||||
bool is_digit(char);
|
||||
bool is_graphic(char);
|
||||
bool is_hex_digit(char);
|
||||
bool is_lowercase(char);
|
||||
bool is_path_separator(char);
|
||||
bool is_printable(char);
|
||||
bool is_punctuation(char);
|
||||
bool is_quote(char);
|
||||
bool is_uppercase(char);
|
||||
bool is_whitespace(char);
|
||||
constexpr auto is_path_separator = is_any_of("/\\");
|
||||
constexpr auto is_quote = is_any_of("'\"");
|
||||
|
||||
}
|
||||
|
||||
using AK::GenericLexer;
|
||||
|
||||
using AK::is_alpha;
|
||||
using AK::is_alphanum;
|
||||
using AK::is_any_of;
|
||||
using AK::is_control;
|
||||
using AK::is_digit;
|
||||
using AK::is_graphic;
|
||||
using AK::is_hex_digit;
|
||||
using AK::is_lowercase;
|
||||
using AK::is_path_separator;
|
||||
using AK::is_printable;
|
||||
using AK::is_punctuation;
|
||||
using AK::is_quote;
|
||||
using AK::is_uppercase;
|
||||
using AK::is_whitespace;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <AK/JsonObject.h>
|
||||
#include <AK/JsonParser.h>
|
||||
#include <AK/Memory.h>
|
||||
#include <ctype.h>
|
||||
|
||||
namespace AK {
|
||||
|
||||
@ -104,27 +105,27 @@ Optional<JsonValue> JsonParser::parse_object()
|
||||
if (!consume_specific('{'))
|
||||
return {};
|
||||
for (;;) {
|
||||
ignore_while(is_whitespace);
|
||||
ignore_while(isspace);
|
||||
if (peek() == '}')
|
||||
break;
|
||||
ignore_while(is_whitespace);
|
||||
ignore_while(isspace);
|
||||
auto name = consume_and_unescape_string();
|
||||
if (name.is_null())
|
||||
return {};
|
||||
ignore_while(is_whitespace);
|
||||
ignore_while(isspace);
|
||||
if (!consume_specific(':'))
|
||||
return {};
|
||||
ignore_while(is_whitespace);
|
||||
ignore_while(isspace);
|
||||
auto value = parse_helper();
|
||||
if (!value.has_value())
|
||||
return {};
|
||||
object.set(name, move(value.value()));
|
||||
ignore_while(is_whitespace);
|
||||
ignore_while(isspace);
|
||||
if (peek() == '}')
|
||||
break;
|
||||
if (!consume_specific(','))
|
||||
return {};
|
||||
ignore_while(is_whitespace);
|
||||
ignore_while(isspace);
|
||||
if (peek() == '}')
|
||||
return {};
|
||||
}
|
||||
@ -139,23 +140,23 @@ Optional<JsonValue> JsonParser::parse_array()
|
||||
if (!consume_specific('['))
|
||||
return {};
|
||||
for (;;) {
|
||||
ignore_while(is_whitespace);
|
||||
ignore_while(isspace);
|
||||
if (peek() == ']')
|
||||
break;
|
||||
auto element = parse_helper();
|
||||
if (!element.has_value())
|
||||
return {};
|
||||
array.append(element.value());
|
||||
ignore_while(is_whitespace);
|
||||
ignore_while(isspace);
|
||||
if (peek() == ']')
|
||||
break;
|
||||
if (!consume_specific(','))
|
||||
return {};
|
||||
ignore_while(is_whitespace);
|
||||
ignore_while(isspace);
|
||||
if (peek() == ']')
|
||||
return {};
|
||||
}
|
||||
ignore_while(is_whitespace);
|
||||
ignore_while(isspace);
|
||||
if (!consume_specific(']'))
|
||||
return {};
|
||||
return array;
|
||||
@ -260,7 +261,7 @@ Optional<JsonValue> JsonParser::parse_null()
|
||||
|
||||
Optional<JsonValue> JsonParser::parse_helper()
|
||||
{
|
||||
ignore_while(is_whitespace);
|
||||
ignore_while(isspace);
|
||||
auto type_hint = peek();
|
||||
switch (type_hint) {
|
||||
case '{':
|
||||
@ -297,7 +298,7 @@ Optional<JsonValue> JsonParser::parse()
|
||||
auto result = parse_helper();
|
||||
if (!result.has_value())
|
||||
return {};
|
||||
ignore_while(is_whitespace);
|
||||
ignore_while(isspace);
|
||||
if (!is_eof())
|
||||
return {};
|
||||
return result;
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <LibCore/File.h>
|
||||
#include <LibJS/Parser.h>
|
||||
#include <LibJS/Runtime/Function.h>
|
||||
#include <ctype.h>
|
||||
|
||||
namespace Spreadsheet {
|
||||
|
||||
@ -192,8 +193,8 @@ Cell* Sheet::at(const Position& position)
|
||||
Optional<Position> Sheet::parse_cell_name(const StringView& name)
|
||||
{
|
||||
GenericLexer lexer(name);
|
||||
auto col = lexer.consume_while([](auto c) { return is_alpha(c); });
|
||||
auto row = lexer.consume_while([](auto c) { return is_alphanum(c) && !is_alpha(c); });
|
||||
auto col = lexer.consume_while(isalpha);
|
||||
auto row = lexer.consume_while(isdigit);
|
||||
|
||||
if (!lexer.is_eof() || row.is_empty() || col.is_empty())
|
||||
return {};
|
||||
|
@ -223,7 +223,6 @@ set(VT_SOURCES
|
||||
../Libraries/LibVT/Line.cpp
|
||||
)
|
||||
|
||||
|
||||
set(KEYBOARD_SOURCES
|
||||
../Libraries/LibKeyboard/CharacterMap.cpp
|
||||
)
|
||||
@ -233,6 +232,10 @@ set(CRYPTO_SOURCES
|
||||
../Libraries/LibCrypto/Hash/SHA2.cpp
|
||||
)
|
||||
|
||||
set(C_SOURCES
|
||||
../Libraries/LibC/ctype.cpp
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
${KERNEL_SOURCES}
|
||||
${AK_SOURCES}
|
||||
@ -240,6 +243,7 @@ set(SOURCES
|
||||
${VT_SOURCES}
|
||||
${KEYBOARD_SOURCES}
|
||||
${CRYPTO_SOURCES}
|
||||
${C_SOURCES}
|
||||
)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option -DKERNEL")
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <LibCore/ArgsParser.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <LibCore/ProcessStatisticsReader.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct OpenFile {
|
||||
@ -56,8 +57,8 @@ static bool parse_name(StringView name, OpenFile& file)
|
||||
return true;
|
||||
} else {
|
||||
file.type = component1;
|
||||
auto component2 = lexer.consume_while([](char c) { return is_printable(c) && !is_whitespace(c) && c != '('; });
|
||||
lexer.ignore_while(is_whitespace);
|
||||
auto component2 = lexer.consume_while([](char c) { return isprint(c) && !isspace(c) && c != '('; });
|
||||
lexer.ignore_while(isspace);
|
||||
file.name = component2;
|
||||
|
||||
if (lexer.tell_remaining() == 0) {
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <LibCore/File.h>
|
||||
#include <LibProtocol/Client.h>
|
||||
#include <LibProtocol/Download.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// FIXME: Move this somewhere else when it's needed (e.g. in the Browser)
|
||||
@ -43,7 +44,7 @@ public:
|
||||
{
|
||||
GenericLexer lexer(value);
|
||||
|
||||
lexer.ignore_while(is_whitespace);
|
||||
lexer.ignore_while(isspace);
|
||||
|
||||
if (lexer.consume_specific("inline")) {
|
||||
m_kind = Kind::Inline;
|
||||
@ -55,7 +56,7 @@ public:
|
||||
if (lexer.consume_specific("attachment")) {
|
||||
m_kind = Kind::Attachment;
|
||||
if (lexer.consume_specific(";")) {
|
||||
lexer.ignore_while(is_whitespace);
|
||||
lexer.ignore_while(isspace);
|
||||
if (lexer.consume_specific("filename=")) {
|
||||
// RFC 2183: "A short (length <= 78 characters)
|
||||
// parameter value containing only non-`tspecials' characters SHOULD be
|
||||
@ -77,7 +78,7 @@ public:
|
||||
if (lexer.consume_specific("form-data")) {
|
||||
m_kind = Kind::FormData;
|
||||
while (lexer.consume_specific(";")) {
|
||||
lexer.ignore_while(is_whitespace);
|
||||
lexer.ignore_while(isspace);
|
||||
if (lexer.consume_specific("name=")) {
|
||||
m_name = lexer.consume_quoted_string();
|
||||
} else if (lexer.consume_specific("filename=")) {
|
||||
|
Loading…
Reference in New Issue
Block a user