1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 18:14:59 +00:00

Shell: Use StringView instead of String const& where feasible

This commit is contained in:
Daniel Bertalan 2022-01-29 16:24:01 +01:00 committed by Andreas Kling
parent 1a4aad9b7e
commit 5b64abe76e
4 changed files with 68 additions and 78 deletions

View file

@ -106,7 +106,7 @@ ErrorOr<void> AK::Formatter<Shell::AST::Command>::format(FormatBuilder& builder,
namespace Shell::AST { 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); dbgln("{}{}", String::repeated(' ', indent * 2), str);
} }

View file

@ -124,7 +124,7 @@ int Shell::builtin_bg(int argc, const char** argv)
.name = "job-id", .name = "job-id",
.min_values = 0, .min_values = 0,
.max_values = 1, .max_values = 1,
.accept_value = [&](const String& value) -> bool { .accept_value = [&](StringView value) -> bool {
// Check if it's a pid (i.e. literal integer) // Check if it's a pid (i.e. literal integer)
if (auto number = value.to_uint(); number.has_value()) { if (auto number = value.to_uint(); number.has_value()) {
job_id = number.value(); job_id = number.value();
@ -497,7 +497,7 @@ int Shell::builtin_fg(int argc, const char** argv)
.name = "job-id", .name = "job-id",
.min_values = 0, .min_values = 0,
.max_values = 1, .max_values = 1,
.accept_value = [&](const String& value) -> bool { .accept_value = [&](StringView value) -> bool {
// Check if it's a pid (i.e. literal integer) // Check if it's a pid (i.e. literal integer)
if (auto number = value.to_uint(); number.has_value()) { if (auto number = value.to_uint(); number.has_value()) {
job_id = number.value(); job_id = number.value();
@ -568,7 +568,7 @@ int Shell::builtin_disown(int argc, const char** argv)
.name = "job-id", .name = "job-id",
.min_values = 0, .min_values = 0,
.max_values = INT_MAX, .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) // Check if it's a pid (i.e. literal integer)
if (auto number = value.to_uint(); number.has_value()) { if (auto number = value.to_uint(); number.has_value()) {
job_ids.append(number.value()); job_ids.append(number.value());
@ -977,7 +977,7 @@ int Shell::builtin_wait(int argc, const char** argv)
.name = "job-id", .name = "job-id",
.min_values = 0, .min_values = 0,
.max_values = INT_MAX, .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) // Check if it's a pid (i.e. literal integer)
if (auto number = value.to_uint(); number.has_value()) { if (auto number = value.to_uint(); number.has_value()) {
job_ids.append(number.value()); job_ids.append(number.value());

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2021, the SerenityOS developers. * Copyright (c) 2020-2022, the SerenityOS developers.
* *
* SPDX-License-Identifier: BSD-2-Clause * 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) { if (s_disable_hyperlinks || !m_is_interactive) {
printf("%s", path.characters()); out("{}", path);
return; return;
} }
auto url = URL::create_with_file_scheme(path, {}, hostname); auto url = URL::create_with_file_scheme(path, {}, hostname);
@ -133,7 +133,7 @@ String Shell::prompt() const
return build_prompt(); return build_prompt();
} }
String Shell::expand_tilde(const String& expression) String Shell::expand_tilde(StringView expression)
{ {
VERIFY(expression.starts_with('~')); VERIFY(expression.starts_with('~'));
@ -337,7 +337,7 @@ String Shell::resolve_path(String path) const
return Core::File::real_path_for(path); 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) { for (size_t i = m_local_frames.size(); i > 0; --i) {
auto& frame = m_local_frames[i - 1]; auto& frame = m_local_frames[i - 1];
@ -347,7 +347,7 @@ Shell::LocalFrame* Shell::find_frame_containing_local_variable(const String& nam
return nullptr; return nullptr;
} }
RefPtr<AST::Value> Shell::lookup_local_variable(const String& name) const RefPtr<AST::Value> Shell::lookup_local_variable(StringView name) const
{ {
if (auto* frame = find_frame_containing_local_variable(name)) if (auto* frame = find_frame_containing_local_variable(name))
return frame->local_variables.get(name).value(); return frame->local_variables.get(name).value();
@ -382,7 +382,7 @@ RefPtr<AST::Value> Shell::get_argument(size_t index) const
return nullptr; 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); auto value = lookup_local_variable(name);
if (value) { if (value) {
@ -405,7 +405,7 @@ void Shell::set_local_variable(const String& name, RefPtr<AST::Value> value, boo
m_local_frames.last().local_variables.set(name, move(value)); 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 (!only_in_current_frame) {
if (auto* frame = find_frame_containing_local_variable(name)) if (auto* frame = find_frame_containing_local_variable(name))
@ -422,7 +422,7 @@ void Shell::define_function(String name, Vector<String> argnames, RefPtr<AST::No
m_functions.set(name, { name, move(argnames), move(body) }); m_functions.set(name, { name, move(argnames), move(body) });
} }
bool Shell::has_function(const String& name) bool Shell::has_function(StringView name)
{ {
return m_functions.contains(name); return m_functions.contains(name);
} }
@ -509,7 +509,7 @@ Shell::Frame::~Frame()
(void)frames.take_last(); (void)frames.take_last();
} }
String Shell::resolve_alias(const String& name) const String Shell::resolve_alias(StringView name) const
{ {
return m_aliases.get(name).value_or({}); return m_aliases.get(name).value_or({});
} }
@ -521,11 +521,7 @@ bool Shell::is_runnable(StringView name)
if (parts.size() > 1 && access(path.characters(), X_OK) == 0) if (parts.size() > 1 && access(path.characters(), X_OK) == 0)
return true; return true;
return binary_search( return binary_search(cached_path.span(), path, nullptr);
cached_path.span(),
path,
nullptr,
[](auto& name, auto& program) { return strcmp(name.characters(), program.characters()); });
} }
int Shell::run_command(StringView cmd, Optional<SourcePosition> source_position_override) int Shell::run_command(StringView cmd, Optional<SourcePosition> source_position_override)
@ -1094,7 +1090,7 @@ String Shell::get_history_path()
return String::formatted("{}/.history", home); 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 '"'"` // `foo bar \n '` -> `'foo bar \n '"'"`
@ -1124,7 +1120,7 @@ String Shell::escape_token_for_single_quotes(const String& token)
return builder.build(); 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"` // `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) { auto do_escape = [](auto& token) {
StringBuilder builder; StringBuilder builder;
@ -1230,7 +1226,7 @@ String Shell::escape_token(const String& token)
return do_escape(token); return do_escape(token);
} }
String Shell::unescape_token(const String& token) String Shell::unescape_token(StringView token)
{ {
StringBuilder builder; StringBuilder builder;
@ -1332,11 +1328,7 @@ void Shell::cache_path()
void Shell::add_entry_to_cache(const String& entry) void Shell::add_entry_to_cache(const String& entry)
{ {
size_t index = 0; size_t index = 0;
auto match = binary_search( auto match = binary_search(cached_path.span(), entry, &index);
cached_path.span(),
entry,
&index,
[](auto& name, auto& program) { return strcmp(name.characters(), program.characters()); });
if (match) if (match)
return; return;
@ -1347,14 +1339,10 @@ void Shell::add_entry_to_cache(const String& entry)
cached_path.insert(index, 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 }; size_t index { 0 };
auto match = binary_search( auto match = binary_search(cached_path.span(), entry, &index);
cached_path.span(),
entry,
&index,
[](const auto& a, const auto& b) { return strcmp(a.characters(), b.characters()); });
if (match) if (match)
cached_path.remove(index); cached_path.remove(index);
@ -1384,8 +1372,8 @@ Vector<Line::CompletionSuggestion> Shell::complete()
return ast->complete_for_editor(*this, line.length()); return ast->complete_for_editor(*this, line.length());
} }
Vector<Line::CompletionSuggestion> Shell::complete_path(const String& base, Vector<Line::CompletionSuggestion> Shell::complete_path(StringView base,
const String& part, size_t offset, ExecutableOnly executable_only) StringView part, size_t offset, ExecutableOnly executable_only)
{ {
auto token = offset ? part.substring_view(0, offset) : ""; auto token = offset ? part.substring_view(0, offset) : "";
String path; String path;
@ -1459,13 +1447,13 @@ Vector<Line::CompletionSuggestion> Shell::complete_path(const String& base,
return suggestions; return suggestions;
} }
Vector<Line::CompletionSuggestion> Shell::complete_program_name(const String& name, size_t offset) Vector<Line::CompletionSuggestion> Shell::complete_program_name(StringView name, size_t offset)
{ {
auto match = binary_search( auto match = binary_search(
cached_path.span(), cached_path.span(),
name, name,
nullptr, nullptr,
[](auto& name, auto& program) { return strncmp(name.characters(), program.characters(), name.length()); }); [](auto& name, auto& program) { return name.compare(program.view()); });
if (!match) if (!match)
return complete_path("", name, offset, ExecutableOnly::Yes); return complete_path("", name, offset, ExecutableOnly::Yes);
@ -1496,7 +1484,7 @@ Vector<Line::CompletionSuggestion> Shell::complete_program_name(const String& na
return suggestions; return suggestions;
} }
Vector<Line::CompletionSuggestion> Shell::complete_variable(const String& name, size_t offset) Vector<Line::CompletionSuggestion> Shell::complete_variable(StringView name, size_t offset)
{ {
Vector<Line::CompletionSuggestion> suggestions; Vector<Line::CompletionSuggestion> suggestions;
auto pattern = offset ? name.substring_view(0, offset) : ""; auto pattern = offset ? name.substring_view(0, offset) : "";
@ -1530,7 +1518,7 @@ Vector<Line::CompletionSuggestion> Shell::complete_variable(const String& name,
return suggestions; return suggestions;
} }
Vector<Line::CompletionSuggestion> Shell::complete_user(const String& name, size_t offset) Vector<Line::CompletionSuggestion> Shell::complete_user(StringView name, size_t offset)
{ {
Vector<Line::CompletionSuggestion> suggestions; Vector<Line::CompletionSuggestion> suggestions;
auto pattern = offset ? name.substring_view(0, offset) : ""; auto pattern = offset ? name.substring_view(0, offset) : "";
@ -1554,7 +1542,7 @@ Vector<Line::CompletionSuggestion> Shell::complete_user(const String& name, size
return suggestions; return suggestions;
} }
Vector<Line::CompletionSuggestion> Shell::complete_option(const String& program_name, const String& option, size_t offset) Vector<Line::CompletionSuggestion> Shell::complete_option(StringView program_name, StringView option, size_t offset)
{ {
size_t start = 0; size_t start = 0;
while (start < option.length() && option[start] == '-' && start < 2) while (start < option.length() && option[start] == '-' && start < 2)
@ -1585,10 +1573,10 @@ Vector<Line::CompletionSuggestion> Shell::complete_option(const String& program_
builder.append(view); builder.append(view);
return builder.to_string(); return builder.to_string();
}; };
#define __ENUMERATE_SHELL_OPTION(name, d_, descr_) \ #define __ENUMERATE_SHELL_OPTION(name, d_, descr_) \
if (StringView { #name }.starts_with(option_pattern)) { \ if (#name##sv.starts_with(option_pattern)) { \
suggestions.append(maybe_negate(#name)); \ suggestions.append(maybe_negate(#name)); \
suggestions.last().input_offset = offset; \ suggestions.last().input_offset = offset; \
} }
ENUMERATE_SHELL_OPTIONS(); ENUMERATE_SHELL_OPTIONS();
@ -1599,14 +1587,14 @@ Vector<Line::CompletionSuggestion> Shell::complete_option(const String& program_
return suggestions; return suggestions;
} }
Vector<Line::CompletionSuggestion> Shell::complete_immediate_function_name(const String& name, size_t offset) Vector<Line::CompletionSuggestion> Shell::complete_immediate_function_name(StringView name, size_t offset)
{ {
Vector<Line::CompletionSuggestion> suggestions; Vector<Line::CompletionSuggestion> suggestions;
#define __ENUMERATE_SHELL_IMMEDIATE_FUNCTION(fn_name) \ #define __ENUMERATE_SHELL_IMMEDIATE_FUNCTION(fn_name) \
if (auto name_view = StringView { #fn_name }; name_view.starts_with(name)) { \ if (auto name_view = #fn_name##sv; name_view.starts_with(name)) { \
suggestions.append({ name_view, " " }); \ suggestions.append({ name_view, " " }); \
suggestions.last().input_offset = offset; \ suggestions.last().input_offset = offset; \
} }
ENUMERATE_SHELL_IMMEDIATE_FUNCTIONS(); ENUMERATE_SHELL_IMMEDIATE_FUNCTIONS();
@ -2080,7 +2068,7 @@ void Shell::possibly_print_error() const
warnln(); warnln();
} }
Optional<int> Shell::resolve_job_spec(const String& str) Optional<int> Shell::resolve_job_spec(StringView str)
{ {
if (!str.starts_with('%')) if (!str.starts_with('%'))
return {}; return {};

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2021, the SerenityOS developers. * Copyright (c) 2020-2022, the SerenityOS developers.
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -8,11 +8,13 @@
#include "Job.h" #include "Job.h"
#include "Parser.h" #include "Parser.h"
#include <AK/Array.h>
#include <AK/CircularQueue.h> #include <AK/CircularQueue.h>
#include <AK/HashMap.h> #include <AK/HashMap.h>
#include <AK/NonnullOwnPtrVector.h> #include <AK/NonnullOwnPtrVector.h>
#include <AK/String.h> #include <AK/String.h>
#include <AK/StringBuilder.h> #include <AK/StringBuilder.h>
#include <AK/StringView.h>
#include <AK/Types.h> #include <AK/Types.h>
#include <AK/Vector.h> #include <AK/Vector.h>
#include <LibCore/Notifier.h> #include <LibCore/Notifier.h>
@ -99,25 +101,25 @@ public:
void block_on_pipeline(RefPtr<AST::Pipeline>); void block_on_pipeline(RefPtr<AST::Pipeline>);
String prompt() const; String prompt() const;
static String expand_tilde(const String&); static String expand_tilde(StringView expression);
static Vector<String> expand_globs(StringView path, StringView base); static Vector<String> expand_globs(StringView path, StringView base);
static Vector<String> expand_globs(Vector<StringView> path_segments, StringView base); static Vector<String> expand_globs(Vector<StringView> path_segments, StringView base);
Vector<AST::Command> expand_aliases(Vector<AST::Command>); Vector<AST::Command> expand_aliases(Vector<AST::Command>);
String resolve_path(String) const; 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 String find_in_path(StringView program_name);
static bool has_history_event(StringView); static bool has_history_event(StringView);
RefPtr<AST::Value> get_argument(size_t) const; RefPtr<AST::Value> get_argument(size_t) const;
RefPtr<AST::Value> lookup_local_variable(const String&) const; RefPtr<AST::Value> lookup_local_variable(StringView) const;
String local_variable_or(const String&, const String&) const; String local_variable_or(StringView, const String&) const;
void set_local_variable(const String&, RefPtr<AST::Value>, bool only_in_current_frame = false); void set_local_variable(const String&, RefPtr<AST::Value>, 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<String> argnames, RefPtr<AST::Node> body); void define_function(String name, Vector<String> argnames, RefPtr<AST::Node> body);
bool has_function(const String&); bool has_function(StringView);
bool invoke_function(const AST::Command&, int& retval); bool invoke_function(const AST::Command&, int& retval);
String format(StringView, ssize_t& cursor) const; String format(StringView, ssize_t& cursor) const;
@ -154,10 +156,10 @@ public:
[[nodiscard]] Frame push_frame(String name); [[nodiscard]] Frame push_frame(String name);
void pop_frame(); void pop_frame();
static String escape_token_for_double_quotes(const String& token); static String escape_token_for_double_quotes(StringView token);
static String escape_token_for_single_quotes(const String& token); static String escape_token_for_single_quotes(StringView token);
static String escape_token(const String& token); static String escape_token(StringView token);
static String unescape_token(const String& token); static String unescape_token(StringView token);
enum class SpecialCharacterEscapeMode { enum class SpecialCharacterEscapeMode {
Untouched, Untouched,
Escaped, Escaped,
@ -176,12 +178,12 @@ public:
void highlight(Line::Editor&) const; void highlight(Line::Editor&) const;
Vector<Line::CompletionSuggestion> complete(); Vector<Line::CompletionSuggestion> complete();
Vector<Line::CompletionSuggestion> complete_path(const String& base, const String&, size_t offset, ExecutableOnly executable_only); Vector<Line::CompletionSuggestion> complete_path(StringView base, StringView, size_t offset, ExecutableOnly executable_only);
Vector<Line::CompletionSuggestion> complete_program_name(const String&, size_t offset); Vector<Line::CompletionSuggestion> complete_program_name(StringView, size_t offset);
Vector<Line::CompletionSuggestion> complete_variable(const String&, size_t offset); Vector<Line::CompletionSuggestion> complete_variable(StringView, size_t offset);
Vector<Line::CompletionSuggestion> complete_user(const String&, size_t offset); Vector<Line::CompletionSuggestion> complete_user(StringView, size_t offset);
Vector<Line::CompletionSuggestion> complete_option(const String&, const String&, size_t offset); Vector<Line::CompletionSuggestion> complete_option(StringView, StringView, size_t offset);
Vector<Line::CompletionSuggestion> complete_immediate_function_name(const String&, size_t offset); Vector<Line::CompletionSuggestion> complete_immediate_function_name(StringView, size_t offset);
void restore_ios(); void restore_ios();
@ -191,7 +193,7 @@ public:
void kill_job(const Job*, int sig); void kill_job(const Job*, int sig);
String get_history_path(); String get_history_path();
void print_path(const String& path); void print_path(StringView path);
bool read_single_line(); bool read_single_line();
@ -293,14 +295,14 @@ private:
void save_to(JsonObject&); void save_to(JsonObject&);
void bring_cursor_to_beginning_of_a_line() const; void bring_cursor_to_beginning_of_a_line() const;
Optional<int> resolve_job_spec(const String&); Optional<int> resolve_job_spec(StringView);
void cache_path(); void cache_path();
void add_entry_to_cache(const String&); void add_entry_to_cache(const String&);
void remove_entry_from_cache(const String&); void remove_entry_from_cache(StringView);
void stop_all_jobs(); void stop_all_jobs();
const Job* m_current_job { nullptr }; const Job* m_current_job { nullptr };
LocalFrame* find_frame_containing_local_variable(const String& name); LocalFrame* find_frame_containing_local_variable(StringView name);
const LocalFrame* find_frame_containing_local_variable(const String& name) const const LocalFrame* find_frame_containing_local_variable(StringView name) const
{ {
return const_cast<Shell*>(this)->find_frame_containing_local_variable(name); return const_cast<Shell*>(this)->find_frame_containing_local_variable(name);
} }
@ -328,14 +330,14 @@ private:
#undef __ENUMERATE_SHELL_BUILTIN #undef __ENUMERATE_SHELL_BUILTIN
constexpr static const char* builtin_names[] = { static constexpr Array builtin_names = {
#define __ENUMERATE_SHELL_BUILTIN(builtin) #builtin, #define __ENUMERATE_SHELL_BUILTIN(builtin) #builtin##sv,
ENUMERATE_SHELL_BUILTINS() ENUMERATE_SHELL_BUILTINS()
#undef __ENUMERATE_SHELL_BUILTIN #undef __ENUMERATE_SHELL_BUILTIN
":", // POSIX-y name for "noop". ":"sv, // POSIX-y name for "noop".
}; };
bool m_should_ignore_jobs_on_next_exit { false }; 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'); 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 unescaped_offset = 0;
size_t offset = 0; size_t offset = 0;