diff --git a/Userland/Shell/AST.cpp b/Userland/Shell/AST.cpp index 8d87ec3104..aad68b4467 100644 --- a/Userland/Shell/AST.cpp +++ b/Userland/Shell/AST.cpp @@ -106,7 +106,7 @@ ErrorOr AK::Formatter::format(FormatBuilder& builder, namespace Shell::AST { -static inline void print_indented(const String& str, int indent) +static inline void print_indented(StringView str, int indent) { dbgln("{}{}", String::repeated(' ', indent * 2), str); } diff --git a/Userland/Shell/Builtin.cpp b/Userland/Shell/Builtin.cpp index baf863c88f..426b8c158a 100644 --- a/Userland/Shell/Builtin.cpp +++ b/Userland/Shell/Builtin.cpp @@ -124,7 +124,7 @@ int Shell::builtin_bg(int argc, const char** argv) .name = "job-id", .min_values = 0, .max_values = 1, - .accept_value = [&](const String& value) -> bool { + .accept_value = [&](StringView value) -> bool { // Check if it's a pid (i.e. literal integer) if (auto number = value.to_uint(); number.has_value()) { job_id = number.value(); @@ -497,7 +497,7 @@ int Shell::builtin_fg(int argc, const char** argv) .name = "job-id", .min_values = 0, .max_values = 1, - .accept_value = [&](const String& value) -> bool { + .accept_value = [&](StringView value) -> bool { // Check if it's a pid (i.e. literal integer) if (auto number = value.to_uint(); number.has_value()) { job_id = number.value(); @@ -568,7 +568,7 @@ int Shell::builtin_disown(int argc, const char** argv) .name = "job-id", .min_values = 0, .max_values = INT_MAX, - .accept_value = [&](const String& value) -> bool { + .accept_value = [&](StringView value) -> bool { // Check if it's a pid (i.e. literal integer) if (auto number = value.to_uint(); number.has_value()) { job_ids.append(number.value()); @@ -977,7 +977,7 @@ int Shell::builtin_wait(int argc, const char** argv) .name = "job-id", .min_values = 0, .max_values = INT_MAX, - .accept_value = [&](const String& value) -> bool { + .accept_value = [&](StringView value) -> bool { // Check if it's a pid (i.e. literal integer) if (auto number = value.to_uint(); number.has_value()) { job_ids.append(number.value()); diff --git a/Userland/Shell/Shell.cpp b/Userland/Shell/Shell.cpp index 28580ab6b6..4a8afde4fe 100644 --- a/Userland/Shell/Shell.cpp +++ b/Userland/Shell/Shell.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, the SerenityOS developers. + * Copyright (c) 2020-2022, the SerenityOS developers. * * SPDX-License-Identifier: BSD-2-Clause */ @@ -63,10 +63,10 @@ void Shell::setup_signals() } } -void Shell::print_path(const String& path) +void Shell::print_path(StringView path) { if (s_disable_hyperlinks || !m_is_interactive) { - printf("%s", path.characters()); + out("{}", path); return; } auto url = URL::create_with_file_scheme(path, {}, hostname); @@ -133,7 +133,7 @@ String Shell::prompt() const return build_prompt(); } -String Shell::expand_tilde(const String& expression) +String Shell::expand_tilde(StringView expression) { VERIFY(expression.starts_with('~')); @@ -337,7 +337,7 @@ String Shell::resolve_path(String path) const return Core::File::real_path_for(path); } -Shell::LocalFrame* Shell::find_frame_containing_local_variable(const String& name) +Shell::LocalFrame* Shell::find_frame_containing_local_variable(StringView name) { for (size_t i = m_local_frames.size(); i > 0; --i) { auto& frame = m_local_frames[i - 1]; @@ -347,7 +347,7 @@ Shell::LocalFrame* Shell::find_frame_containing_local_variable(const String& nam return nullptr; } -RefPtr Shell::lookup_local_variable(const String& name) const +RefPtr Shell::lookup_local_variable(StringView name) const { if (auto* frame = find_frame_containing_local_variable(name)) return frame->local_variables.get(name).value(); @@ -382,7 +382,7 @@ RefPtr Shell::get_argument(size_t index) const return nullptr; } -String Shell::local_variable_or(const String& name, const String& replacement) const +String Shell::local_variable_or(StringView name, const String& replacement) const { auto value = lookup_local_variable(name); if (value) { @@ -405,7 +405,7 @@ void Shell::set_local_variable(const String& name, RefPtr value, boo m_local_frames.last().local_variables.set(name, move(value)); } -void Shell::unset_local_variable(const String& name, bool only_in_current_frame) +void Shell::unset_local_variable(StringView name, bool only_in_current_frame) { if (!only_in_current_frame) { if (auto* frame = find_frame_containing_local_variable(name)) @@ -422,7 +422,7 @@ void Shell::define_function(String name, Vector argnames, RefPtr 1 && access(path.characters(), X_OK) == 0) return true; - return binary_search( - cached_path.span(), - path, - nullptr, - [](auto& name, auto& program) { return strcmp(name.characters(), program.characters()); }); + return binary_search(cached_path.span(), path, nullptr); } int Shell::run_command(StringView cmd, Optional source_position_override) @@ -1094,7 +1090,7 @@ String Shell::get_history_path() return String::formatted("{}/.history", home); } -String Shell::escape_token_for_single_quotes(const String& token) +String Shell::escape_token_for_single_quotes(StringView token) { // `foo bar \n '` -> `'foo bar \n '"'"` @@ -1124,7 +1120,7 @@ String Shell::escape_token_for_single_quotes(const String& token) return builder.build(); } -String Shell::escape_token_for_double_quotes(const String& token) +String Shell::escape_token_for_double_quotes(StringView token) { // `foo bar \n $x 'blah "hello` -> `"foo bar \\n $x 'blah \"hello"` @@ -1180,7 +1176,7 @@ Shell::SpecialCharacterEscapeMode Shell::special_character_escape_mode(u32 code_ } } -String Shell::escape_token(const String& token) +String Shell::escape_token(StringView token) { auto do_escape = [](auto& token) { StringBuilder builder; @@ -1230,7 +1226,7 @@ String Shell::escape_token(const String& token) return do_escape(token); } -String Shell::unescape_token(const String& token) +String Shell::unescape_token(StringView token) { StringBuilder builder; @@ -1332,11 +1328,7 @@ void Shell::cache_path() void Shell::add_entry_to_cache(const String& entry) { size_t index = 0; - auto match = binary_search( - cached_path.span(), - entry, - &index, - [](auto& name, auto& program) { return strcmp(name.characters(), program.characters()); }); + auto match = binary_search(cached_path.span(), entry, &index); if (match) return; @@ -1347,14 +1339,10 @@ void Shell::add_entry_to_cache(const String& entry) cached_path.insert(index, entry); } -void Shell::remove_entry_from_cache(const String& entry) +void Shell::remove_entry_from_cache(StringView entry) { size_t index { 0 }; - auto match = binary_search( - cached_path.span(), - entry, - &index, - [](const auto& a, const auto& b) { return strcmp(a.characters(), b.characters()); }); + auto match = binary_search(cached_path.span(), entry, &index); if (match) cached_path.remove(index); @@ -1384,8 +1372,8 @@ Vector Shell::complete() return ast->complete_for_editor(*this, line.length()); } -Vector Shell::complete_path(const String& base, - const String& part, size_t offset, ExecutableOnly executable_only) +Vector Shell::complete_path(StringView base, + StringView part, size_t offset, ExecutableOnly executable_only) { auto token = offset ? part.substring_view(0, offset) : ""; String path; @@ -1459,13 +1447,13 @@ Vector Shell::complete_path(const String& base, return suggestions; } -Vector Shell::complete_program_name(const String& name, size_t offset) +Vector Shell::complete_program_name(StringView name, size_t offset) { auto match = binary_search( cached_path.span(), name, nullptr, - [](auto& name, auto& program) { return strncmp(name.characters(), program.characters(), name.length()); }); + [](auto& name, auto& program) { return name.compare(program.view()); }); if (!match) return complete_path("", name, offset, ExecutableOnly::Yes); @@ -1496,7 +1484,7 @@ Vector Shell::complete_program_name(const String& na return suggestions; } -Vector Shell::complete_variable(const String& name, size_t offset) +Vector Shell::complete_variable(StringView name, size_t offset) { Vector suggestions; auto pattern = offset ? name.substring_view(0, offset) : ""; @@ -1530,7 +1518,7 @@ Vector Shell::complete_variable(const String& name, return suggestions; } -Vector Shell::complete_user(const String& name, size_t offset) +Vector Shell::complete_user(StringView name, size_t offset) { Vector suggestions; auto pattern = offset ? name.substring_view(0, offset) : ""; @@ -1554,7 +1542,7 @@ Vector Shell::complete_user(const String& name, size return suggestions; } -Vector Shell::complete_option(const String& program_name, const String& option, size_t offset) +Vector Shell::complete_option(StringView program_name, StringView option, size_t offset) { size_t start = 0; while (start < option.length() && option[start] == '-' && start < 2) @@ -1585,10 +1573,10 @@ Vector Shell::complete_option(const String& program_ builder.append(view); return builder.to_string(); }; -#define __ENUMERATE_SHELL_OPTION(name, d_, descr_) \ - if (StringView { #name }.starts_with(option_pattern)) { \ - suggestions.append(maybe_negate(#name)); \ - suggestions.last().input_offset = offset; \ +#define __ENUMERATE_SHELL_OPTION(name, d_, descr_) \ + if (#name##sv.starts_with(option_pattern)) { \ + suggestions.append(maybe_negate(#name)); \ + suggestions.last().input_offset = offset; \ } ENUMERATE_SHELL_OPTIONS(); @@ -1599,14 +1587,14 @@ Vector Shell::complete_option(const String& program_ return suggestions; } -Vector Shell::complete_immediate_function_name(const String& name, size_t offset) +Vector Shell::complete_immediate_function_name(StringView name, size_t offset) { Vector suggestions; -#define __ENUMERATE_SHELL_IMMEDIATE_FUNCTION(fn_name) \ - if (auto name_view = StringView { #fn_name }; name_view.starts_with(name)) { \ - suggestions.append({ name_view, " " }); \ - suggestions.last().input_offset = offset; \ +#define __ENUMERATE_SHELL_IMMEDIATE_FUNCTION(fn_name) \ + if (auto name_view = #fn_name##sv; name_view.starts_with(name)) { \ + suggestions.append({ name_view, " " }); \ + suggestions.last().input_offset = offset; \ } ENUMERATE_SHELL_IMMEDIATE_FUNCTIONS(); @@ -2080,7 +2068,7 @@ void Shell::possibly_print_error() const warnln(); } -Optional Shell::resolve_job_spec(const String& str) +Optional Shell::resolve_job_spec(StringView str) { if (!str.starts_with('%')) return {}; diff --git a/Userland/Shell/Shell.h b/Userland/Shell/Shell.h index 12e2f222a9..9a920cd42b 100644 --- a/Userland/Shell/Shell.h +++ b/Userland/Shell/Shell.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, the SerenityOS developers. + * Copyright (c) 2020-2022, the SerenityOS developers. * * SPDX-License-Identifier: BSD-2-Clause */ @@ -8,11 +8,13 @@ #include "Job.h" #include "Parser.h" +#include #include #include #include #include #include +#include #include #include #include @@ -99,25 +101,25 @@ public: void block_on_pipeline(RefPtr); String prompt() const; - static String expand_tilde(const String&); + static String expand_tilde(StringView expression); static Vector expand_globs(StringView path, StringView base); static Vector expand_globs(Vector path_segments, StringView base); Vector expand_aliases(Vector); String resolve_path(String) const; - String resolve_alias(const String&) const; + String resolve_alias(StringView) const; static String find_in_path(StringView program_name); static bool has_history_event(StringView); RefPtr get_argument(size_t) const; - RefPtr lookup_local_variable(const String&) const; - String local_variable_or(const String&, const String&) const; + RefPtr lookup_local_variable(StringView) const; + String local_variable_or(StringView, const String&) const; void set_local_variable(const String&, RefPtr, bool only_in_current_frame = false); - void unset_local_variable(const String&, bool only_in_current_frame = false); + void unset_local_variable(StringView, bool only_in_current_frame = false); void define_function(String name, Vector argnames, RefPtr body); - bool has_function(const String&); + bool has_function(StringView); bool invoke_function(const AST::Command&, int& retval); String format(StringView, ssize_t& cursor) const; @@ -154,10 +156,10 @@ public: [[nodiscard]] Frame push_frame(String name); void pop_frame(); - static String escape_token_for_double_quotes(const String& token); - static String escape_token_for_single_quotes(const String& token); - static String escape_token(const String& token); - static String unescape_token(const String& token); + static String escape_token_for_double_quotes(StringView token); + static String escape_token_for_single_quotes(StringView token); + static String escape_token(StringView token); + static String unescape_token(StringView token); enum class SpecialCharacterEscapeMode { Untouched, Escaped, @@ -176,12 +178,12 @@ public: void highlight(Line::Editor&) const; Vector complete(); - Vector complete_path(const String& base, const String&, size_t offset, ExecutableOnly executable_only); - Vector complete_program_name(const String&, size_t offset); - Vector complete_variable(const String&, size_t offset); - Vector complete_user(const String&, size_t offset); - Vector complete_option(const String&, const String&, size_t offset); - Vector complete_immediate_function_name(const String&, size_t offset); + Vector complete_path(StringView base, StringView, size_t offset, ExecutableOnly executable_only); + Vector complete_program_name(StringView, size_t offset); + Vector complete_variable(StringView, size_t offset); + Vector complete_user(StringView, size_t offset); + Vector complete_option(StringView, StringView, size_t offset); + Vector complete_immediate_function_name(StringView, size_t offset); void restore_ios(); @@ -191,7 +193,7 @@ public: void kill_job(const Job*, int sig); String get_history_path(); - void print_path(const String& path); + void print_path(StringView path); bool read_single_line(); @@ -293,14 +295,14 @@ private: void save_to(JsonObject&); void bring_cursor_to_beginning_of_a_line() const; - Optional resolve_job_spec(const String&); + Optional resolve_job_spec(StringView); void cache_path(); void add_entry_to_cache(const String&); - void remove_entry_from_cache(const String&); + void remove_entry_from_cache(StringView); void stop_all_jobs(); const Job* m_current_job { nullptr }; - LocalFrame* find_frame_containing_local_variable(const String& name); - const LocalFrame* find_frame_containing_local_variable(const String& name) const + LocalFrame* find_frame_containing_local_variable(StringView name); + const LocalFrame* find_frame_containing_local_variable(StringView name) const { return const_cast(this)->find_frame_containing_local_variable(name); } @@ -328,14 +330,14 @@ private: #undef __ENUMERATE_SHELL_BUILTIN - constexpr static const char* builtin_names[] = { -#define __ENUMERATE_SHELL_BUILTIN(builtin) #builtin, + static constexpr Array builtin_names = { +#define __ENUMERATE_SHELL_BUILTIN(builtin) #builtin##sv, ENUMERATE_SHELL_BUILTINS() #undef __ENUMERATE_SHELL_BUILTIN - ":", // POSIX-y name for "noop". + ":"sv, // POSIX-y name for "noop". }; bool m_should_ignore_jobs_on_next_exit { false }; @@ -376,7 +378,7 @@ private: return c == '_' || (c <= 'Z' && c >= 'A') || (c <= 'z' && c >= 'a') || (c <= '9' && c >= '0'); } -inline size_t find_offset_into_node(const String& unescaped_text, size_t escaped_offset) +inline size_t find_offset_into_node(StringView unescaped_text, size_t escaped_offset) { size_t unescaped_offset = 0; size_t offset = 0;