diff options
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibGUI/EditingEngine.cpp | 75 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/TextDocument.cpp | 16 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/TextEditor.cpp | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/GlobalObject.cpp | 16 | ||||
-rw-r--r-- | Userland/Libraries/LibLine/Editor.cpp | 18 | ||||
-rw-r--r-- | Userland/Libraries/LibLine/InternalFunctions.cpp | 32 | ||||
-rw-r--r-- | Userland/Libraries/LibRegex/RegexByteCode.cpp | 43 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/Tokenizer.cpp | 49 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/Document.cpp | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/HTML/Parser/HTMLTokenizer.cpp | 70 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/TextNode.cpp | 14 | ||||
-rw-r--r-- | Userland/Services/WindowServer/Menu.cpp | 6 | ||||
-rw-r--r-- | Userland/Services/WindowServer/Window.cpp | 4 | ||||
-rw-r--r-- | Userland/Shell/Shell.cpp | 7 |
14 files changed, 149 insertions, 213 deletions
diff --git a/Userland/Libraries/LibGUI/EditingEngine.cpp b/Userland/Libraries/LibGUI/EditingEngine.cpp index 2d02293ba9..99f2f779be 100644 --- a/Userland/Libraries/LibGUI/EditingEngine.cpp +++ b/Userland/Libraries/LibGUI/EditingEngine.cpp @@ -4,12 +4,23 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <AK/CharacterTypes.h> #include <LibGUI/EditingEngine.h> #include <LibGUI/Event.h> #include <LibGUI/TextEditor.h> namespace GUI { +constexpr bool is_vim_alphanumeric(u32 code_point) +{ + return is_ascii_alphanumeric(code_point) || code_point == '_'; +} + +constexpr bool is_vim_punctuation(u32 code_point) +{ + return is_ascii_punctuation(code_point) && code_point != '_'; +} + EditingEngine::~EditingEngine() { } @@ -379,15 +390,7 @@ TextPosition EditingEngine::find_beginning_of_next_word() * If the end of the input is reached, jump there */ - auto vim_isalnum = [](int c) { - return c == '_' || isalnum(c); - }; - - auto vim_ispunct = [](int c) { - return c != '_' && ispunct(c); - }; - - bool started_on_punct = vim_ispunct(m_editor->current_line().to_utf8().characters()[m_editor->cursor().column()]); + bool started_on_punct = is_vim_punctuation(m_editor->current_line().to_utf8().characters()[m_editor->cursor().column()]); bool has_seen_whitespace = false; bool is_first_line = true; auto& lines = m_editor->lines(); @@ -409,18 +412,18 @@ TextPosition EditingEngine::find_beginning_of_next_word() const u32* line_chars = line.view().code_points(); const u32 current_char = line_chars[column_index]; - if (started_on_punct && vim_isalnum(current_char)) { + if (started_on_punct && is_vim_alphanumeric(current_char)) { return { line_index, column_index }; } - if (vim_ispunct(current_char) && !started_on_punct) { + if (is_vim_punctuation(current_char) && !started_on_punct) { return { line_index, column_index }; } - if (isspace(current_char)) + if (is_ascii_space(current_char)) has_seen_whitespace = true; - if (has_seen_whitespace && (vim_isalnum(current_char) || vim_ispunct(current_char))) { + if (has_seen_whitespace && (is_vim_alphanumeric(current_char) || is_vim_punctuation(current_char))) { return { line_index, column_index }; } @@ -449,14 +452,6 @@ TextPosition EditingEngine::find_end_of_next_word() * If the end of the input is reached, jump there */ - auto vim_isalnum = [](int c) { - return c == '_' || isalnum(c); - }; - - auto vim_ispunct = [](int c) { - return c != '_' && ispunct(c); - }; - bool is_first_line = true; bool is_first_iteration = true; auto& lines = m_editor->lines(); @@ -481,7 +476,7 @@ TextPosition EditingEngine::find_end_of_next_word() const u32* line_chars = line.view().code_points(); const u32 current_char = line_chars[column_index]; - if (column_index == lines.at(line_index).length() - 1 && !is_first_iteration && (vim_isalnum(current_char) || vim_ispunct(current_char))) + if (column_index == lines.at(line_index).length() - 1 && !is_first_iteration && (is_vim_alphanumeric(current_char) || is_vim_punctuation(current_char))) return { line_index, column_index }; else if (column_index == lines.at(line_index).length() - 1) { is_first_iteration = false; @@ -490,10 +485,10 @@ TextPosition EditingEngine::find_end_of_next_word() const u32 next_char = line_chars[column_index + 1]; - if (!is_first_iteration && vim_isalnum(current_char) && (isspace(next_char) || vim_ispunct(next_char))) + if (!is_first_iteration && is_vim_alphanumeric(current_char) && (is_ascii_space(next_char) || is_vim_punctuation(next_char))) return { line_index, column_index }; - if (!is_first_iteration && vim_ispunct(current_char) && (isspace(next_char) || vim_isalnum(next_char))) + if (!is_first_iteration && is_vim_punctuation(current_char) && (is_ascii_space(next_char) || is_vim_alphanumeric(next_char))) return { line_index, column_index }; if (line_index == lines.size() - 1 && column_index == line.length() - 1) { @@ -513,15 +508,7 @@ void EditingEngine::move_to_end_of_next_word() TextPosition EditingEngine::find_end_of_previous_word() { - auto vim_isalnum = [](int c) { - return c == '_' || isalnum(c); - }; - - auto vim_ispunct = [](int c) { - return c != '_' && ispunct(c); - }; - - bool started_on_punct = vim_ispunct(m_editor->current_line().to_utf8().characters()[m_editor->cursor().column()]); + bool started_on_punct = is_vim_punctuation(m_editor->current_line().to_utf8().characters()[m_editor->cursor().column()]); bool is_first_line = true; bool has_seen_whitespace = false; auto& lines = m_editor->lines(); @@ -545,19 +532,19 @@ TextPosition EditingEngine::find_end_of_previous_word() const u32* line_chars = line.view().code_points(); const u32 current_char = line_chars[column_index]; - if (started_on_punct && vim_isalnum(current_char)) { + if (started_on_punct && is_vim_alphanumeric(current_char)) { return { line_index, column_index }; } - if (vim_ispunct(current_char) && !started_on_punct) { + if (is_vim_punctuation(current_char) && !started_on_punct) { return { line_index, column_index }; } - if (isspace(current_char)) { + if (is_ascii_space(current_char)) { has_seen_whitespace = true; } - if (has_seen_whitespace && (vim_isalnum(current_char) || vim_ispunct(current_char))) { + if (has_seen_whitespace && (is_vim_alphanumeric(current_char) || is_vim_punctuation(current_char))) { return { line_index, column_index }; } @@ -580,14 +567,6 @@ void EditingEngine::move_to_end_of_previous_word() TextPosition EditingEngine::find_beginning_of_previous_word() { - auto vim_isalnum = [](int c) { - return c == '_' || isalnum(c); - }; - - auto vim_ispunct = [](int c) { - return c != '_' && ispunct(c); - }; - bool is_first_iterated_line = true; bool is_first_iteration = true; auto& lines = m_editor->lines(); @@ -618,7 +597,7 @@ TextPosition EditingEngine::find_beginning_of_previous_word() const u32* line_chars = line.view().code_points(); const u32 current_char = line_chars[column_index]; - if (column_index == 0 && !is_first_iteration && (vim_isalnum(current_char) || vim_ispunct(current_char))) { + if (column_index == 0 && !is_first_iteration && (is_vim_alphanumeric(current_char) || is_vim_punctuation(current_char))) { return { line_index, column_index }; } else if (line_index == 0 && column_index == 0) { return { line_index, column_index }; @@ -629,10 +608,10 @@ TextPosition EditingEngine::find_beginning_of_previous_word() const u32 next_char = line_chars[column_index - 1]; - if (!is_first_iteration && vim_isalnum(current_char) && (isspace(next_char) || vim_ispunct(next_char))) + if (!is_first_iteration && is_vim_alphanumeric(current_char) && (is_ascii_space(next_char) || is_vim_punctuation(next_char))) return { line_index, column_index }; - if (!is_first_iteration && vim_ispunct(current_char) && (isspace(next_char) || vim_isalnum(next_char))) + if (!is_first_iteration && is_vim_punctuation(current_char) && (is_ascii_space(next_char) || is_vim_alphanumeric(next_char))) return { line_index, column_index }; is_first_iteration = false; diff --git a/Userland/Libraries/LibGUI/TextDocument.cpp b/Userland/Libraries/LibGUI/TextDocument.cpp index faa647dda8..93ba964fc9 100644 --- a/Userland/Libraries/LibGUI/TextDocument.cpp +++ b/Userland/Libraries/LibGUI/TextDocument.cpp @@ -5,6 +5,7 @@ */ #include <AK/Badge.h> +#include <AK/CharacterTypes.h> #include <AK/ScopeGuard.h> #include <AK/StringBuilder.h> #include <AK/Utf8View.h> @@ -12,7 +13,6 @@ #include <LibGUI/TextDocument.h> #include <LibGUI/TextEditor.h> #include <LibRegex/Regex.h> -#include <ctype.h> namespace GUI { @@ -104,7 +104,7 @@ size_t TextDocumentLine::first_non_whitespace_column() const { for (size_t i = 0; i < length(); ++i) { auto code_point = code_points()[i]; - if (!isspace(code_point)) + if (!is_ascii_space(code_point)) return i; } return length(); @@ -114,7 +114,7 @@ Optional<size_t> TextDocumentLine::last_non_whitespace_column() const { for (ssize_t i = length() - 1; i >= 0; --i) { auto code_point = code_points()[i]; - if (!isspace(code_point)) + if (!is_ascii_space(code_point)) return i; } return {}; @@ -124,7 +124,7 @@ bool TextDocumentLine::ends_in_whitespace() const { if (!length()) return false; - return isspace(code_points()[length() - 1]); + return is_ascii_space(code_points()[length() - 1]); } bool TextDocumentLine::can_select() const @@ -638,11 +638,11 @@ TextPosition TextDocument::first_word_break_before(const TextPosition& position, if (target.column() == line.length()) modifier = 1; - auto is_start_alphanumeric = isalnum(line.code_points()[target.column() - modifier]); + auto is_start_alphanumeric = is_ascii_alphanumeric(line.code_points()[target.column() - modifier]); while (target.column() > 0) { auto prev_code_point = line.code_points()[target.column() - 1]; - if ((is_start_alphanumeric && !isalnum(prev_code_point)) || (!is_start_alphanumeric && isalnum(prev_code_point))) + if ((is_start_alphanumeric && !is_ascii_alphanumeric(prev_code_point)) || (!is_start_alphanumeric && is_ascii_alphanumeric(prev_code_point))) break; target.set_column(target.column() - 1); } @@ -662,11 +662,11 @@ TextPosition TextDocument::first_word_break_after(const TextPosition& position) return TextPosition(position.line() + 1, 0); } - auto is_start_alphanumeric = isalnum(line.code_points()[target.column()]); + auto is_start_alphanumeric = is_ascii_alphanumeric(line.code_points()[target.column()]); while (target.column() < line.length()) { auto next_code_point = line.code_points()[target.column()]; - if ((is_start_alphanumeric && !isalnum(next_code_point)) || (!is_start_alphanumeric && isalnum(next_code_point))) + if ((is_start_alphanumeric && !is_ascii_alphanumeric(next_code_point)) || (!is_start_alphanumeric && is_ascii_alphanumeric(next_code_point))) break; target.set_column(target.column() + 1); } diff --git a/Userland/Libraries/LibGUI/TextEditor.cpp b/Userland/Libraries/LibGUI/TextEditor.cpp index 13d98504fa..a1299aee92 100644 --- a/Userland/Libraries/LibGUI/TextEditor.cpp +++ b/Userland/Libraries/LibGUI/TextEditor.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <AK/CharacterTypes.h> #include <AK/Debug.h> #include <AK/ScopeGuard.h> #include <AK/StringBuilder.h> @@ -25,7 +26,6 @@ #include <LibGfx/FontDatabase.h> #include <LibGfx/Palette.h> #include <LibSyntax/Highlighter.h> -#include <ctype.h> #include <fcntl.h> #include <math.h> #include <stdio.h> @@ -1232,12 +1232,12 @@ size_t TextEditor::number_of_selected_words() const bool in_word = false; auto selected_text = this->selected_text(); for (char c : selected_text) { - if (in_word && isspace(c)) { + if (in_word && is_ascii_space(c)) { in_word = false; word_count++; continue; } - if (!in_word && !isspace(c)) + if (!in_word && !is_ascii_space(c)) in_word = true; } if (in_word) @@ -1561,7 +1561,7 @@ void TextEditor::recompute_visual_lines(size_t line_index) auto glyph_spacing = font().glyph_spacing(); for (size_t i = 0; i < line.length(); ++i) { auto code_point = line.code_points()[i]; - if (isspace(code_point)) { + if (is_ascii_space(code_point)) { last_whitespace_index = i; line_width_since_last_whitespace = 0; } diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp index 7d9d92b498..a38489aae5 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -5,6 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <AK/CharacterTypes.h> #include <AK/Hex.h> #include <AK/Platform.h> #include <AK/TemporaryChange.h> @@ -56,7 +57,6 @@ #include <LibJS/Runtime/TypedArrayConstructor.h> #include <LibJS/Runtime/TypedArrayPrototype.h> #include <LibJS/Runtime/Value.h> -#include <ctype.h> namespace JS { @@ -249,16 +249,10 @@ JS_DEFINE_NATIVE_FUNCTION(GlobalObject::parse_int) } auto parse_digit = [&](u32 code_point, i32 radix) -> Optional<i32> { - i32 digit = -1; - - if (isdigit(code_point)) - digit = code_point - '0'; - else if (islower(code_point)) - digit = 10 + (code_point - 'a'); - else if (isupper(code_point)) - digit = 10 + (code_point - 'A'); - - if (digit == -1 || digit >= radix) + if (!is_ascii_hex_digit(code_point) || radix <= 0) + return {}; + auto digit = parse_ascii_hex_digit(code_point); + if (digit >= (u32)radix) return {}; return digit; }; diff --git a/Userland/Libraries/LibLine/Editor.cpp b/Userland/Libraries/LibLine/Editor.cpp index 1bdcc4040b..d6d57ac911 100644 --- a/Userland/Libraries/LibLine/Editor.cpp +++ b/Userland/Libraries/LibLine/Editor.cpp @@ -6,6 +6,7 @@ */ #include "Editor.h" +#include <AK/CharacterTypes.h> #include <AK/Debug.h> #include <AK/GenericLexer.h> #include <AK/JsonObject.h> @@ -19,7 +20,6 @@ #include <LibCore/EventLoop.h> #include <LibCore/File.h> #include <LibCore/Notifier.h> -#include <ctype.h> #include <errno.h> #include <signal.h> #include <stdio.h> @@ -1338,7 +1338,7 @@ void Editor::refresh_display() auto print_character_at = [this](size_t i) { StringBuilder builder; auto c = m_buffer[i]; - bool should_print_masked = isascii(c) && iscntrl(c) && c != '\n'; + bool should_print_masked = is_ascii_control(c) && c != '\n'; bool should_print_caret = c < 64 && should_print_masked; if (should_print_caret) builder.appendff("^{:c}", c + 64); @@ -1722,7 +1722,7 @@ Editor::VTState Editor::actual_rendered_string_length_step(StringMetrics& metric current_line.length = 0; return state; } - if (isascii(c) && iscntrl(c) && c != '\n') + if (is_ascii_control(c) && c != '\n') current_line.masked_chars.append({ index, 1, c < 64 ? 2u : 4u }); // if the character cannot be represented as ^c, represent it as \xbb. // FIXME: This will not support anything sophisticated ++current_line.length; @@ -1740,7 +1740,7 @@ Editor::VTState Editor::actual_rendered_string_length_step(StringMetrics& metric // FIXME: This does not support non-VT (aside from set-title) escapes return state; case Bracket: - if (isdigit(c)) { + if (is_ascii_digit(c)) { return BracketArgsSemi; } return state; @@ -1748,7 +1748,7 @@ Editor::VTState Editor::actual_rendered_string_length_step(StringMetrics& metric if (c == ';') { return Bracket; } - if (!isdigit(c)) + if (!is_ascii_digit(c)) state = Free; return state; case Title: @@ -1848,7 +1848,7 @@ Vector<size_t, 2> Editor::vt_dsr() m_incomplete_data.append(c); continue; case SawBracket: - if (isdigit(c)) { + if (is_ascii_digit(c)) { state = InFirstCoordinate; coordinate_buffer.append(c); continue; @@ -1856,7 +1856,7 @@ Vector<size_t, 2> Editor::vt_dsr() m_incomplete_data.append(c); continue; case InFirstCoordinate: - if (isdigit(c)) { + if (is_ascii_digit(c)) { coordinate_buffer.append(c); continue; } @@ -1872,7 +1872,7 @@ Vector<size_t, 2> Editor::vt_dsr() m_incomplete_data.append(c); continue; case SawSemicolon: - if (isdigit(c)) { + if (is_ascii_digit(c)) { state = InSecondCoordinate; coordinate_buffer.append(c); continue; @@ -1880,7 +1880,7 @@ Vector<size_t, 2> Editor::vt_dsr() m_incomplete_data.append(c); continue; case InSecondCoordinate: - if (isdigit(c)) { + if (is_ascii_digit(c)) { coordinate_buffer.append(c); continue; } diff --git a/Userland/Libraries/LibLine/InternalFunctions.cpp b/Userland/Libraries/LibLine/InternalFunctions.cpp index a5a45f14dd..b94f8d4067 100644 --- a/Userland/Libraries/LibLine/InternalFunctions.cpp +++ b/Userland/Libraries/LibLine/InternalFunctions.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <AK/CharacterTypes.h> #include <AK/FileStream.h> #include <AK/ScopeGuard.h> #include <AK/ScopedValueRollback.h> @@ -11,7 +12,6 @@ #include <AK/TemporaryChange.h> #include <LibCore/File.h> #include <LibLine/Editor.h> -#include <ctype.h> #include <stdio.h> #include <sys/wait.h> #include <unistd.h> @@ -84,7 +84,7 @@ void Editor::cursor_left_word() for (;;) { if (m_cursor == 0) break; - if (skipped_at_least_one_character && !isalnum(m_buffer[m_cursor - 1])) // stop *after* a non-alnum, but only if it changes the position + if (skipped_at_least_one_character && !is_ascii_alphanumeric(m_buffer[m_cursor - 1])) // stop *after* a non-alnum, but only if it changes the position break; skipped_at_least_one_character = true; --m_cursor; @@ -109,7 +109,7 @@ void Editor::cursor_right_word() for (;;) { if (m_cursor >= m_buffer.size()) break; - if (!isalnum(m_buffer[++m_cursor])) + if (!is_ascii_alphanumeric(m_buffer[++m_cursor])) break; } m_buffer.take_last(); @@ -178,7 +178,7 @@ void Editor::erase_word_backwards() // A word here is space-separated. `foo=bar baz` is two words. bool has_seen_nonspace = false; while (m_cursor > 0) { - if (isspace(m_buffer[m_cursor - 1])) { + if (is_ascii_space(m_buffer[m_cursor - 1])) { if (has_seen_nonspace) break; } else { @@ -375,27 +375,27 @@ void Editor::transpose_words() // Move to end of word under (or after) caret. size_t cursor = m_cursor; - while (cursor < m_buffer.size() && !isalnum(m_buffer[cursor])) + while (cursor < m_buffer.size() && !is_ascii_alphanumeric(m_buffer[cursor])) ++cursor; - while (cursor < m_buffer.size() && isalnum(m_buffer[cursor])) + while (cursor < m_buffer.size() && is_ascii_alphanumeric(m_buffer[cursor])) ++cursor; // Move left over second word and the space to its right. size_t end = cursor; size_t start = cursor; - while (start > 0 && !isalnum(m_buffer[start - 1])) + while (start > 0 && !is_ascii_alphanumeric(m_buffer[start - 1])) --start; - while (start > 0 && isalnum(m_buffer[start - 1])) + while (start > 0 && is_ascii_alphanumeric(m_buffer[start - 1])) --start; size_t start_second_word = start; // Move left over space between the two words. - while (start > 0 && !isalnum(m_buffer[start - 1])) + while (start > 0 && !is_ascii_alphanumeric(m_buffer[start - 1])) --start; size_t start_gap = start; // Move left over first word. - while (start > 0 && isalnum(m_buffer[start - 1])) + while (start > 0 && is_ascii_alphanumeric(m_buffer[start - 1])) --start; if (start != start_gap) { @@ -452,7 +452,7 @@ void Editor::erase_alnum_word_backwards() // A word here is contiguous alnums. `foo=bar baz` is three words. bool has_seen_alnum = false; while (m_cursor > 0) { - if (!isalnum(m_buffer[m_cursor - 1])) { + if (!is_ascii_alphanumeric(m_buffer[m_cursor - 1])) { if (has_seen_alnum) break; } else { @@ -467,7 +467,7 @@ void Editor::erase_alnum_word_forwards() // A word here is contiguous alnums. `foo=bar baz` is three words. bool has_seen_alnum = false; while (m_cursor < m_buffer.size()) { - if (!isalnum(m_buffer[m_cursor])) { + if (!is_ascii_alphanumeric(m_buffer[m_cursor])) { if (has_seen_alnum) break; } else { @@ -480,15 +480,15 @@ void Editor::erase_alnum_word_forwards() void Editor::case_change_word(Editor::CaseChangeOp change_op) { // A word here is contiguous alnums. `foo=bar baz` is three words. - while (m_cursor < m_buffer.size() && !isalnum(m_buffer[m_cursor])) + while (m_cursor < m_buffer.size() && !is_ascii_alphanumeric(m_buffer[m_cursor])) ++m_cursor; size_t start = m_cursor; - while (m_cursor < m_buffer.size() && isalnum(m_buffer[m_cursor])) { + while (m_cursor < m_buffer.size() && is_ascii_alphanumeric(m_buffer[m_cursor])) { if (change_op == CaseChangeOp::Uppercase || (change_op == CaseChangeOp::Capital && m_cursor == start)) { - m_buffer[m_cursor] = toupper(m_buffer[m_cursor]); + m_buffer[m_cursor] = to_ascii_uppercase(m_buffer[m_cursor]); } else { VERIFY(change_op == CaseChangeOp::Lowercase || (change_op == CaseChangeOp::Capital && m_cursor > start)); - m_buffer[m_cursor] = tolower(m_buffer[m_cursor]); + m_buffer[m_cursor] = to_ascii_lowercase(m_buffer[m_cursor]); } ++m_cursor; m_refresh_needed = true; diff --git a/Userland/Libraries/LibRegex/RegexByteCode.cpp b/Userland/Libraries/LibRegex/RegexByteCode.cpp index 68009575e0..d508851ab0 100644 --- a/Userland/Libraries/LibRegex/RegexByteCode.cpp +++ b/Userland/Libraries/LibRegex/RegexByteCode.cpp @@ -7,10 +7,9 @@ #include "RegexByteCode.h" #include "AK/StringBuilder.h" #include "RegexDebug.h" +#include <AK/CharacterTypes.h> #include <AK/Debug.h> -#include <ctype.h> - namespace regex { const char* OpCode::name(OpCodeId opcode_id) @@ -241,7 +240,7 @@ ALWAYS_INLINE ExecutionResult OpCode_CheckBegin::execute(const MatchInput& input ALWAYS_INLINE ExecutionResult OpCode_CheckBoundary::execute(const MatchInput& input, MatchState& state, MatchOutput&) const { - auto isword = [](auto ch) { return isalnum(ch) || ch == '_'; }; + auto isword = [](auto ch) { return is_ascii_alphanumeric(ch) || ch == '_'; }; auto is_word_boundary = [&] { if (state.string_position == input.view.length()) { if (state.string_position > 0 && isword(input.view[state.string_position - 1])) @@ -510,8 +509,8 @@ ALWAYS_INLINE void OpCode_Compare::compare_char(const MatchInput& input, MatchSt u32 ch2 = input.view[state.string_position]; if (input.regex_options & AllFlags::Insensitive) { - ch1 = tolower(ch1); - ch2 = tolower(ch2); + ch1 = to_ascii_lowercase(ch1); + ch2 = to_ascii_uppercase(ch2); } if (ch1 == ch2) { @@ -551,7 +550,7 @@ ALWAYS_INLINE void OpCode_Compare::compare_character_class(const MatchInput& inp { switch (character_class) { case CharClass::Alnum: - if (isalnum(ch)) { + if (is_ascii_alphanumeric(ch)) { if (inverse) inverse_matched = true; else @@ -559,11 +558,11 @@ ALWAYS_INLINE void OpCode_Compare::compare_character_class(const MatchInput& inp } break; case CharClass::Alpha: - if (isalpha(ch)) + if (is_ascii_alpha(ch)) ++state.string_position; break; case CharClass::Blank: - if (ch == ' ' || ch == '\t') { + if (is_ascii_blank(ch)) { if (inverse) inverse_matched = true; else @@ -571,7 +570,7 @@ ALWAYS_INLINE void OpCode_Compare::compare_character_class(const MatchInput& inp } break; case CharClass::Cntrl: - if (iscntrl(ch)) { + if (is_ascii_control(ch)) { if (inverse) inverse_matched = true; else @@ -579,7 +578,7 @@ ALWAYS_INLINE void OpCode_Compare::compare_character_class(const MatchInput& inp } break; case CharClass::Digit: - if (isdigit(ch)) { + if (is_ascii_digit(ch)) { if (inverse) inverse_matched = true; else @@ -587,7 +586,7 @@ ALWAYS_INLINE void OpCode_Compare::compare_character_class(const MatchInput& inp } break; case CharClass::Graph: - if (isgraph(ch)) { + if (is_ascii_graphical(ch)) { if (inverse) inverse_matched = true; else @@ -595,7 +594,7 @@ ALWAYS_INLINE void OpCode_Compare::compare_character_class(const MatchInput& inp } break; case CharClass::Lower: - if (islower(ch) || ((input.regex_options & AllFlags::Insensitive) && isupper(ch))) { + if (is_ascii_lower_alpha(ch) || ((input.regex_options & AllFlags::Insensitive) && is_ascii_upper_alpha(ch))) { if (inverse) inverse_matched = true; else @@ -603,7 +602,7 @@ ALWAYS_INLINE void OpCode_Compare::compare_character_class(const MatchInput& inp } break; case CharClass::Print: - if (isprint(ch)) { + if (is_ascii_printable(ch)) { if (inverse) inverse_matched = true; else @@ -611,7 +610,7 @@ ALWAYS_INLINE void OpCode_Compare::compare_character_class(const MatchInput& inp } break; case CharClass::Punct: - if (ispunct(ch)) { + if (is_ascii_punctuation(ch)) { if (inverse) inverse_matched = true; else @@ -619,7 +618,7 @@ ALWAYS_INLINE void OpCode_Compare::compare_character_class(const MatchInput& inp } break; case CharClass::Space: - if (isspace(ch)) { + if (is_ascii_space(ch)) { if (inverse) inverse_matched = true; else @@ -627,7 +626,7 @@ ALWAYS_INLINE void OpCode_Compare::compare_character_class(const MatchInput& inp } break; case CharClass::Upper: - if (isupper(ch) || ((input.regex_options & AllFlags::Insensitive) && islower(ch))) { + if (is_ascii_upper_alpha(ch) || ((input.regex_options & AllFlags::Insensitive) && is_ascii_lower_alpha(ch))) { if (inverse) inverse_matched = true; else @@ -635,7 +634,7 @@ ALWAYS_INLINE void OpCode_Compare::compare_character_class(const MatchInput& inp } break; case CharClass::Word: - if (isalnum(ch) || ch == '_') { + if (is_ascii_alphanumeric(ch) || ch == '_') { if (inverse) inverse_matched = true; else @@ -643,7 +642,7 @@ ALWAYS_INLINE void OpCode_Compare::compare_character_class(const MatchInput& inp } break; case CharClass::Xdigit: - if (isxdigit(ch)) { + if (is_ascii_hex_digit(ch)) { if (inverse) inverse_matched = true; else @@ -656,9 +655,9 @@ ALWAYS_INLINE void OpCode_Compare::compare_character_class(const MatchInput& inp ALWAYS_INLINE void OpCode_Compare::compare_character_range(const MatchInput& input, MatchState& state, u32 from, u32 to, u32 ch, bool inverse, bool& inverse_matched) { if (input.regex_options & AllFlags::Insensitive) { - from = tolower(from); - to = tolower(to); - ch = tolower(ch); + from = to_ascii_lowercase(from); + to = to_ascii_lowercase(to); + ch = to_ascii_lowercase(ch); } if (ch >= from && ch <= to) { @@ -689,7 +688,7 @@ const Vector<String> OpCode_Compare::variable_arguments_to_string(Optional<Match if (compare_type == CharacterCompareType::Char) { auto ch = m_bytecode->at(offset++); - auto is_ascii = isascii(ch) && isprint(ch); + auto is_ascii = is_ascii_printable(ch); if (is_ascii) result.empend(String::formatted("value='{:c}'", static_cast<char>(ch))); else diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Tokenizer.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Tokenizer.cpp index d15e1664ef..113b240cde 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Tokenizer.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Tokenizer.cpp @@ -4,11 +4,11 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <AK/CharacterTypes.h> #include <AK/SourceLocation.h> #include <AK/Vector.h> #include <LibTextCodec/Decoder.h> #include <LibWeb/CSS/Parser/Tokenizer.h> -#include <ctype.h> #define CSS_TOKENIZER_TRACE 0 @@ -20,11 +20,6 @@ static inline void log_parse_error(const SourceLocation& location = SourceLocati dbgln_if(CSS_TOKENIZER_TRACE, "Parse error (css tokenization) {} ", location); } -static inline bool is_surrogate(u32 code_point) -{ - return (code_point & 0xfffff800) == 0xd800; -} - static inline bool is_quotation_mark(u32 code_point) { return code_point == 0x22; @@ -35,24 +30,14 @@ static inline bool is_greater_than_maximum_allowed_code_point(u32 code_point) return code_point > 0x10FFFF; } -static inline bool is_hex_digit(u32 code_point) -{ - return isxdigit(code_point); -} - static inline bool is_low_line(u32 code_point) { return code_point == 0x5F; } -static inline bool is_non_ascii(u32 code_point) -{ - return code_point >= 0x80; -} - static inline bool is_name_start_code_point(u32 code_point) { - return isalpha(code_point) || is_non_ascii(code_point) || is_low_line(code_point); + return is_ascii_alpha(code_point) || !is_ascii(code_point) || is_low_line(code_point); } static inline bool is_hyphen_minus(u32 code_point) @@ -62,7 +47,7 @@ static inline bool is_hyphen_minus(u32 code_point) static inline bool is_name_code_point(u32 code_point) { - return is_name_start_code_point(code_point) || isdigit(code_point) || is_hyphen_minus(code_point); + return is_name_start_code_point(code_point) || is_ascii_digit(code_point) || is_hyphen_minus(code_point); } static inline bool is_non_printable(u32 code_point) @@ -303,12 +288,12 @@ u32 Tokenizer::consume_escaped_code_point() auto input = code_point.value(); - if (is_hex_digit(input)) { + if (is_ascii_hex_digit(input)) { StringBuilder builder; builder.append_code_point(input); size_t counter = 0; - while (is_hex_digit(peek_code_point().value()) && counter++ < 5) { + while (is_ascii_hex_digit(peek_code_point().value()) && counter++ < 5) { builder.append_code_point(next_code_point().value()); } @@ -317,7 +302,7 @@ u32 Tokenizer::consume_escaped_code_point() } auto unhexed = strtoul(builder.to_string().characters(), nullptr, 16); - if (unhexed == 0 || is_surrogate(unhexed) || is_greater_than_maximum_allowed_code_point(unhexed)) { + if (unhexed == 0 || is_unicode_surrogate(unhexed) || is_greater_than_maximum_allowed_code_point(unhexed)) { return REPLACEMENT_CHARACTER; } @@ -378,14 +363,14 @@ CSSNumber Tokenizer::consume_a_number() for (;;) { auto digits = peek_code_point().value(); - if (!isdigit(digits)) + if (!is_ascii_digit(digits)) break; repr.append_code_point(next_code_point().value()); } auto maybe_number = peek_twin().value(); - if (is_full_stop(maybe_number.first) && isdigit(maybe_number.second)) { + if (is_full_stop(maybe_number.first) && is_ascii_digit(maybe_number.second)) { repr.append_code_point(next_code_point().value()); repr.append_code_point(next_code_point().value()); @@ -393,7 +378,7 @@ CSSNumber Tokenizer::consume_a_number() for (;;) { auto digits = peek_code_point(); - if (digits.has_value() && !isdigit(digits.value())) + if (digits.has_value() && !is_ascii_digit(digits.value())) break; repr.append_code_point(next_code_point().value()); @@ -403,12 +388,12 @@ CSSNumber Tokenizer::consume_a_number() auto maybe_exp = peek_triplet().value(); if (is_E(maybe_exp.first) || is_e(maybe_exp.first)) { if (is_plus_sign(maybe_exp.second) || is_hyphen_minus(maybe_exp.second)) { - if (isdigit(maybe_exp.third)) { + if (is_ascii_digit(maybe_exp.third)) { repr.append_code_point(next_code_point().value()); repr.append_code_point(next_code_point().value()); repr.append_code_point(next_code_point().value()); } - } else if (isdigit(maybe_exp.second)) { + } else if (is_ascii_digit(maybe_exp.second)) { repr.append_code_point(next_code_point().value()); repr.append_code_point(next_code_point().value()); } @@ -417,7 +402,7 @@ CSSNumber Tokenizer::consume_a_number() for (;;) { auto digits = peek_code_point().value(); - if (!isdigit(digits)) + if (!is_ascii_digit(digits)) break; repr.append_code_point(next_code_point().value()); @@ -588,19 +573,19 @@ bool Tokenizer::starts_with_a_number() const bool Tokenizer::starts_with_a_number(U32Triplet values) { if (is_plus_sign(values.first) || is_hyphen_minus(values.first)) { - if (isdigit(values.second)) + if (is_ascii_digit(values.second)) return true; - if (is_full_stop(values.second) && isdigit(values.third)) + if (is_full_stop(values.second) && is_ascii_digit(values.third)) return true; return false; } if (is_full_stop(values.first)) - return isdigit(values.second); + return is_ascii_digit(values.second); - if (isdigit(values.first)) + if (is_ascii_digit(values.first)) return true; return false; @@ -902,7 +887,7 @@ Token Tokenizer::consume_a_token() return create_new_token(Token::TokenType::CloseCurly); } - if (isdigit(input)) { + if (is_ascii_digit(input)) { dbgln_if(CSS_TOKENIZER_TRACE, "is digit"); reconsume_current_input_code_point(); return consume_a_numeric_token(); diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index b9887a8553..27c8ba5bb0 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -6,6 +6,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <AK/CharacterTypes.h> #include <AK/StringBuilder.h> #include <AK/Utf8View.h> #include <LibCore/Timer.h> @@ -53,7 +54,6 @@ #include <LibWeb/Page/BrowsingContext.h> #include <LibWeb/SVG/TagNames.h> #include <LibWeb/UIEvents/MouseEvent.h> -#include <ctype.h> namespace Web::DOM { @@ -253,7 +253,7 @@ String Document::title() const StringBuilder builder; bool last_was_space = false; for (auto code_point : Utf8View(raw_title)) { - if (isspace(code_point)) { + if (is_ascii_space(code_point)) { last_was_space = true; } else { if (last_was_space && !builder.is_empty()) diff --git a/Userland/Libraries/LibWeb/HTML/Parser/HTMLTokenizer.cpp b/Userland/Libraries/LibWeb/HTML/Parser/HTMLTokenizer.cpp index 7d716a8532..638ba37bea 100644 --- a/Userland/Libraries/LibWeb/HTML/Parser/HTMLTokenizer.cpp +++ b/Userland/Libraries/LibWeb/HTML/Parser/HTMLTokenizer.cpp @@ -4,13 +4,13 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <AK/CharacterTypes.h> #include <AK/Debug.h> #include <AK/SourceLocation.h> #include <LibTextCodec/Decoder.h> #include <LibWeb/HTML/Parser/Entities.h> #include <LibWeb/HTML/Parser/HTMLToken.h> #include <LibWeb/HTML/Parser/HTMLTokenizer.h> -#include <ctype.h> #include <string.h> namespace Web::HTML { @@ -93,25 +93,25 @@ namespace Web::HTML { if (!current_input_character.has_value()) #define ON_ASCII_ALPHA \ - if (current_input_character.has_value() && isalpha(current_input_character.value())) + if (current_input_character.has_value() && is_ascii_alpha(current_input_character.value())) #define ON_ASCII_ALPHANUMERIC \ - if (current_input_character.has_value() && isalnum(current_input_character.value())) + if (current_input_character.has_value() && is_ascii_alphanumeric(current_input_character.value())) #define ON_ASCII_UPPER_ALPHA \ - if (current_input_character.has_value() && current_input_character.value() >= 'A' && current_input_character.value() <= 'Z') + if (current_input_character.has_value() && is_ascii_upper_alpha(current_input_character.value())) #define ON_ASCII_LOWER_ALPHA \ - if (current_input_character.has_value() && current_input_character.value() >= 'a' && current_input_character.value() <= 'z') + if (current_input_character.has_value() && is_ascii_lower_alpha(current_input_character.value())) #define ON_ASCII_DIGIT \ - if (current_input_character.has_value() && isdigit(current_input_character.value())) + if (current_input_character.has_value() && is_ascii_digit(current_input_character.value())) #define ON_ASCII_HEX_DIGIT \ - if (current_input_character.has_value() && isxdigit(current_input_character.value())) + if (current_input_character.has_value() && is_ascii_hex_digit(current_input_character.value())) #define ON_WHITESPACE \ - if (current_input_character.has_value() && strchr("\t\n\f ", current_input_character.value())) + if (current_input_character.has_value() && is_ascii(current_input_character.value()) && "\t\n\f "sv.contains(current_input_character.value())) #define ANYTHING_ELSE if (1) @@ -172,26 +172,6 @@ static inline void log_parse_error(const SourceLocation& location = SourceLocati dbgln_if(TOKENIZER_TRACE_DEBUG, "Parse error (tokenization) {}", location); } -static inline bool is_surrogate(u32 code_point) -{ - return (code_point & 0xfffff800) == 0xd800; -} - -static inline bool is_noncharacter(u32 code_point) -{ - return code_point >= 0xfdd0 && (code_point <= 0xfdef || (code_point & 0xfffe) == 0xfffe) && code_point <= 0x10ffff; -} - -static inline bool is_c0_control(u32 code_point) -{ - return code_point <= 0x1f; -} - -static inline bool is_control(u32 code_point) -{ - return is_c0_control(code_point) || (code_point >= 0x7f && code_point <= 0x9f); -} - Optional<u32> HTMLTokenizer::next_code_point() { if (m_utf8_iterator == m_utf8_view.end()) @@ -322,7 +302,7 @@ _StartOfFunction: } ON_ASCII_UPPER_ALPHA { - m_current_token.m_tag.tag_name.append(tolower(current_input_character.value())); + m_current_token.m_tag.tag_name.append(to_ascii_lowercase(current_input_character.value())); m_current_token.m_end_position = nth_last_position(0); continue; } @@ -458,7 +438,7 @@ _StartOfFunction: ON_ASCII_UPPER_ALPHA { create_new_token(HTMLToken::Type::DOCTYPE); - m_current_token.m_doctype.name.append(tolower(current_input_character.value())); + m_current_token.m_doctype.name.append(to_ascii_lowercase(current_input_character.value())); m_current_token.m_doctype.missing_name = false; SWITCH_TO(DOCTYPEName); } @@ -507,7 +487,7 @@ _StartOfFunction: } ON_ASCII_UPPER_ALPHA { - m_current_token.m_doctype.name.append(tolower(current_input_character.value())); + m_current_token.m_doctype.name.append(to_ascii_lowercase(current_input_character.value())); continue; } ON(0) @@ -550,10 +530,10 @@ _StartOfFunction: } ANYTHING_ELSE { - if (toupper(current_input_character.value()) == 'P' && consume_next_if_match("UBLIC", CaseSensitivity::CaseInsensitive)) { + if (to_ascii_uppercase(current_input_character.value()) == 'P' && consume_next_if_match("UBLIC", CaseSensitivity::CaseInsensitive)) { SWITCH_TO(AfterDOCTYPEPublicKeyword); } - if (toupper(current_input_character.value()) == 'S' && consume_next_if_match("YSTEM", CaseSensitivity::CaseInsensitive)) { + if (to_ascii_uppercase(current_input_character.value()) == 'S' && consume_next_if_match("YSTEM", CaseSensitivity::CaseInsensitive)) { SWITCH_TO(AfterDOCTYPESystemKeyword); } log_parse_error(); @@ -1068,7 +1048,7 @@ _StartOfFunction: } ON_ASCII_UPPER_ALPHA { - m_current_token.m_tag.attributes.last().local_name_builder.append_code_point(tolower(current_input_character.value())); + m_current_token.m_tag.attributes.last().local_name_builder.append_code_point(to_ascii_lowercase(current_input_character.value())); continue; } ON(0) @@ -1558,7 +1538,7 @@ _StartOfFunction: if (consumed_as_part_of_an_attribute() && !match.value().entity.ends_with(';')) { auto next_code_point = peek_code_point(0); - if (next_code_point.has_value() && (next_code_point.value() == '=' || isalnum(next_code_point.value()))) { + if (next_code_point.has_value() && (next_code_point.value() == '=' || is_ascii_alphanumeric(next_code_point.value()))) { FLUSH_CODEPOINTS_CONSUMED_AS_A_CHARACTER_REFERENCE; SWITCH_TO_RETURN_STATE; } @@ -1720,14 +1700,14 @@ _StartOfFunction: log_parse_error(); m_character_reference_code = 0xFFFD; } - if (is_surrogate(m_character_reference_code)) { + if (is_unicode_surrogate(m_character_reference_code)) { log_parse_error(); m_character_reference_code = 0xFFFD; } - if (is_noncharacter(m_character_reference_code)) { + if (is_unicode_noncharacter(m_character_reference_code)) { log_parse_error(); } - if (m_character_reference_code == 0xd || (is_control(m_character_reference_code) && !isspace(m_character_reference_code))) { + if (m_character_reference_code == 0xd || (is_unicode_control(m_character_reference_code) && !is_ascii_space(m_character_reference_code))) { log_parse_error(); constexpr struct { u32 number; @@ -1870,7 +1850,7 @@ _StartOfFunction: } ON_ASCII_UPPER_ALPHA { - m_current_token.m_tag.tag_name.append(tolower(current_input_character.value())); + m_current_token.m_tag.tag_name.append(to_ascii_lowercase(current_input_character.value())); m_temporary_buffer.append(current_input_character.value()); continue; } @@ -1980,7 +1960,7 @@ _StartOfFunction: } ON_ASCII_UPPER_ALPHA { - m_current_token.m_tag.tag_name.append(tolower(current_input_character.value())); + m_current_token.m_tag.tag_name.append(to_ascii_lowercase(current_input_character.value())); m_temporary_buffer.append(current_input_character.value()); continue; } @@ -2193,7 +2173,7 @@ _StartOfFunction: } ON_ASCII_UPPER_ALPHA { - m_current_token.m_tag.tag_name.append(tolower(current_input_character.value())); + m_current_token.m_tag.tag_name.append(to_ascii_lowercase(current_input_character.value())); m_temporary_buffer.append(current_input_character.value()); continue; } @@ -2247,7 +2227,7 @@ _StartOfFunction: } ON_ASCII_UPPER_ALPHA { - m_temporary_buffer.append(tolower(current_input_character.value())); + m_temporary_buffer.append(to_ascii_lowercase(current_input_character.value())); EMIT_CURRENT_CHARACTER; } ON_ASCII_LOWER_ALPHA @@ -2393,7 +2373,7 @@ _StartOfFunction: } ON_ASCII_UPPER_ALPHA { - m_temporary_buffer.append(tolower(current_input_character.value())); + m_temporary_buffer.append(to_ascii_lowercase(current_input_character.value())); EMIT_CURRENT_CHARACTER; } ON_ASCII_LOWER_ALPHA @@ -2512,7 +2492,7 @@ _StartOfFunction: } ON_ASCII_UPPER_ALPHA { - m_current_token.m_tag.tag_name.append(tolower(current_input_character.value())); + m_current_token.m_tag.tag_name.append(to_ascii_lowercase(current_input_character.value())); m_temporary_buffer.append(current_input_character.value()); continue; } @@ -2598,7 +2578,7 @@ bool HTMLTokenizer::consume_next_if_match(const StringView& string, CaseSensitiv // FIXME: This should be more Unicode-aware. if (case_sensitivity == CaseSensitivity::CaseInsensitive) { if (code_point.value() < 0x80) { - if (tolower(code_point.value()) != tolower(string[i])) + if (to_ascii_lowercase(code_point.value()) != to_ascii_lowercase(string[i])) return false; continue; } diff --git a/Userland/Libraries/LibWeb/Layout/TextNode.cpp b/Userland/Libraries/LibWeb/Layout/TextNode.cpp index c5aaeb47d8..6f7818c55f 100644 --- a/Userland/Libraries/LibWeb/Layout/TextNode.cpp +++ b/Userland/Libraries/LibWeb/Layout/TextNode.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <AK/CharacterTypes.h> #include <AK/ScopeGuard.h> #include <AK/StringBuilder.h> #include <LibGfx/Painter.h> @@ -13,7 +14,6 @@ #include <LibWeb/Layout/Label.h> #include <LibWeb/Layout/TextNode.h> #include <LibWeb/Page/BrowsingContext.h> -#include <ctype.h> namespace Web::Layout { @@ -30,7 +30,7 @@ TextNode::~TextNode() static bool is_all_whitespace(const StringView& string) { for (size_t i = 0; i < string.length(); ++i) { - if (!isspace(string[i])) + if (!is_ascii_space(string[i])) return false; } return true; @@ -116,7 +116,7 @@ void TextNode::compute_text_for_rendering(bool collapse, bool previous_is_empty_ auto it = utf8_view.begin(); auto skip_over_whitespace = [&] { auto prev = it; - while (it != utf8_view.end() && isspace(*it)) { + while (it != utf8_view.end() && is_ascii_space(*it)) { prev = it; ++it; } @@ -125,7 +125,7 @@ void TextNode::compute_text_for_rendering(bool collapse, bool previous_is_empty_ if (previous_is_empty_or_ends_in_whitespace) skip_over_whitespace(); for (; it != utf8_view.end(); ++it) { - if (!isspace(*it)) { + if (!is_ascii_space(*it)) { builder.append(utf8_view.as_string().characters_without_null_termination() + utf8_view.byte_offset_of(it), it.code_point_length_in_bytes()); } else { builder.append(' '); @@ -160,7 +160,7 @@ void TextNode::split_into_lines_by_rules(InlineFormattingContext& context, Layou float chunk_width; if (do_wrap_lines) { - if (do_collapse && isspace(*chunk.view.begin()) && line_boxes.last().is_empty_or_ends_in_whitespace()) { + if (do_collapse && is_ascii_space(*chunk.view.begin()) && line_boxes.last().is_empty_or_ends_in_whitespace()) { // This is a non-empty chunk that starts with collapsible whitespace. // We are at either at the start of a new line, or after something that ended in whitespace, // so we don't need to contribute our own whitespace to the line. Skip over it instead! @@ -264,7 +264,7 @@ TextNode::ChunkIterator::ChunkIterator(StringView const& text, LayoutMode layout , m_start_of_chunk(m_utf8_view.begin()) , m_iterator(m_utf8_view.begin()) { - m_last_was_space = !text.is_empty() && isspace(*m_utf8_view.begin()); + m_last_was_space = !text.is_empty() && is_ascii_space(*m_utf8_view.begin()); } Optional<TextNode::Chunk> TextNode::ChunkIterator::next() @@ -286,7 +286,7 @@ Optional<TextNode::Chunk> TextNode::ChunkIterator::next() return result.release_value(); } if (m_wrap_lines) { - bool is_space = isspace(*m_iterator); + bool is_space = is_ascii_space(*m_iterator); if (is_space != m_last_was_space) { m_last_was_space = is_space; if (auto result = try_commit_chunk(m_iterator, false); result.has_value()) diff --git a/Userland/Services/WindowServer/Menu.cpp b/Userland/Services/WindowServer/Menu.cpp index 2af35fb794..f878ab1035 100644 --- a/Userland/Services/WindowServer/Menu.cpp +++ b/Userland/Services/WindowServer/Menu.cpp @@ -12,6 +12,7 @@ #include "Screen.h" #include "Window.h" #include "WindowManager.h" +#include <AK/CharacterTypes.h> #include <LibGfx/Bitmap.h> #include <LibGfx/CharacterBitmap.h> #include <LibGfx/Font.h> @@ -20,7 +21,6 @@ #include <LibGfx/Triangle.h> #include <WindowServer/ClientConnection.h> #include <WindowServer/WindowClientEndpoint.h> -#include <ctype.h> namespace WindowServer { @@ -631,14 +631,14 @@ void Menu::set_visible(bool visible) void Menu::add_item(NonnullOwnPtr<MenuItem> item) { if (auto alt_shortcut = find_ampersand_shortcut_character(item->text())) { - m_alt_shortcut_character_to_item_indices.ensure(tolower(alt_shortcut)).append(m_items.size()); + m_alt_shortcut_character_to_item_indices.ensure(to_ascii_lowercase(alt_shortcut)).append(m_items.size()); } m_items.append(move(item)); } const Vector<size_t>* Menu::items_with_alt_shortcut(u32 alt_shortcut) const { - auto it = m_alt_shortcut_character_to_item_indices.find(tolower(alt_shortcut)); + auto it = m_alt_shortcut_character_to_item_indices.find(to_ascii_lowercase(alt_shortcut)); if (it == m_alt_shortcut_character_to_item_indices.end()) return nullptr; return &it->value; diff --git a/Userland/Services/WindowServer/Window.cpp b/Userland/Services/WindowServer/Window.cpp index 8eba0a07e2..3f0bb32f26 100644 --- a/Userland/Services/WindowServer/Window.cpp +++ b/Userland/Services/WindowServer/Window.cpp @@ -13,8 +13,8 @@ #include "Screen.h" #include "WindowManager.h" #include <AK/Badge.h> +#include <AK/CharacterTypes.h> #include <WindowServer/WindowClientEndpoint.h> -#include <ctype.h> namespace WindowServer { @@ -461,7 +461,7 @@ void Window::handle_keydown_event(const KeyEvent& event) if (event.modifiers() == Mod_Alt && event.code_point() && menubar()) { Menu* menu_to_open = nullptr; menubar()->for_each_menu([&](Menu& menu) { - if (tolower(menu.alt_shortcut_character()) == tolower(event.code_point())) { + if (to_ascii_lowercase(menu.alt_shortcut_character()) == to_ascii_lowercase(event.code_point())) { menu_to_open = &menu; return IterationDecision::Break; } diff --git a/Userland/Shell/Shell.cpp b/Userland/Shell/Shell.cpp index aa985d8e7d..d7069dd654 100644 --- a/Userland/Shell/Shell.cpp +++ b/Userland/Shell/Shell.cpp @@ -7,6 +7,7 @@ #include "Shell.h" #include "Execution.h" #include "Formatter.h" +#include <AK/CharacterTypes.h> #include <AK/Debug.h> #include <AK/Function.h> #include <AK/LexicalPath.h> @@ -1188,10 +1189,8 @@ Shell::SpecialCharacterEscapeMode Shell::special_character_escape_mode(u32 code_ return SpecialCharacterEscapeMode::QuotedAsEscape; default: // FIXME: Should instead use unicode's "graphic" property (categories L, M, N, P, S, Zs) - if (code_point < NumericLimits<i32>::max()) { - if (isascii(static_cast<i32>(code_point))) - return isprint(static_cast<i32>(code_point)) ? SpecialCharacterEscapeMode::Untouched : SpecialCharacterEscapeMode::QuotedAsHex; - } + if (is_ascii(code_point)) + return is_ascii_printable(code_point) ? SpecialCharacterEscapeMode::Untouched : SpecialCharacterEscapeMode::QuotedAsHex; return SpecialCharacterEscapeMode::Untouched; } } |