1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:08:11 +00:00

Shell: Move everything to the Shell namespace

Also provide a basic default-constructor.
This commit is contained in:
AnotherTest 2020-10-01 18:13:01 +03:30 committed by Andreas Kling
parent 34039d6639
commit f164b808b5
17 changed files with 115 additions and 17 deletions

View file

@ -33,6 +33,8 @@
namespace GUI { namespace GUI {
using namespace Shell;
enum class AugmentedTokenKind : u32 { enum class AugmentedTokenKind : u32 {
__TokenTypeCount = (u32)AST::Node::Kind::__Count, __TokenTypeCount = (u32)AST::Node::Kind::__Count,
OpenParen, OpenParen,

View file

@ -37,7 +37,7 @@
//#define EXECUTE_DEBUG //#define EXECUTE_DEBUG
namespace AST { namespace Shell::AST {
template<typename T, typename... Args> template<typename T, typename... Args>
static inline NonnullRefPtr<T> create(Args... args) static inline NonnullRefPtr<T> create(Args... args)

View file

@ -38,7 +38,7 @@
#include <AK/Vector.h> #include <AK/Vector.h>
#include <LibLine/Editor.h> #include <LibLine/Editor.h>
namespace AST { namespace Shell::AST {
struct HighlightMetadata { struct HighlightMetadata {
bool is_first_in_list { true }; bool is_first_in_list { true };

View file

@ -35,6 +35,8 @@
extern char** environ; extern char** environ;
namespace Shell {
int Shell::builtin_alias(int argc, const char** argv) int Shell::builtin_alias(int argc, const char** argv)
{ {
Vector<const char*> arguments; Vector<const char*> arguments;
@ -806,3 +808,5 @@ bool Shell::has_builtin(const StringView& name) const
#undef __ENUMERATE_SHELL_BUILTIN #undef __ENUMERATE_SHELL_BUILTIN
return false; return false;
} }
}

View file

@ -33,6 +33,8 @@
#include <AK/Vector.h> #include <AK/Vector.h>
#include <LibCore/ElapsedTimer.h> #include <LibCore/ElapsedTimer.h>
namespace Shell {
class FileDescriptionCollector { class FileDescriptionCollector {
public: public:
FileDescriptionCollector() { } FileDescriptionCollector() { }
@ -59,3 +61,5 @@ private:
Vector<SavedFileDescriptor> m_saves; Vector<SavedFileDescriptor> m_saves;
FileDescriptionCollector m_collector; FileDescriptionCollector m_collector;
}; };
}

View file

@ -29,6 +29,8 @@
#include "Parser.h" #include "Parser.h"
#include <AK/TemporaryChange.h> #include <AK/TemporaryChange.h>
namespace Shell {
String Formatter::format() String Formatter::format()
{ {
auto node = Parser(m_source).parse(); auto node = Parser(m_source).parse();
@ -595,3 +597,5 @@ void Formatter::visit(const AST::WriteRedirection* node)
current_builder().append(" >"); current_builder().append(" >");
NodeVisitor::visit(node); NodeVisitor::visit(node);
} }
}

View file

@ -34,6 +34,8 @@
#include <AK/Vector.h> #include <AK/Vector.h>
#include <ctype.h> #include <ctype.h>
namespace Shell {
class Formatter final : public AST::NodeVisitor { class Formatter final : public AST::NodeVisitor {
public: public:
Formatter(const StringView& source, ssize_t cursor = -1) Formatter(const StringView& source, ssize_t cursor = -1)
@ -119,3 +121,5 @@ private:
StringView m_trivia; StringView m_trivia;
}; };
}

View file

@ -26,8 +26,7 @@
#pragma once #pragma once
class Shell; namespace Shell::AST {
namespace AST {
struct Command; struct Command;
class Node; class Node;
@ -75,3 +74,9 @@ class WriteAppendRedirection;
class WriteRedirection; class WriteRedirection;
} }
namespace Shell {
class Shell;
}

View file

@ -31,6 +31,8 @@
#include <stdio.h> #include <stdio.h>
#include <sys/wait.h> #include <sys/wait.h>
namespace Shell {
bool Job::print_status(PrintStatusMode mode) bool Job::print_status(PrintStatusMode mode)
{ {
int wstatus; int wstatus;
@ -110,3 +112,5 @@ void Job::unblock() const
if (!m_exited && on_exit) if (!m_exited && on_exit)
on_exit(*this); on_exit(*this);
} }
}

View file

@ -41,6 +41,8 @@
# undef JOB_TIME_INFO # undef JOB_TIME_INFO
#endif #endif
namespace Shell {
struct LocalFrame; struct LocalFrame;
class Job : public RefCounted<Job> { class Job : public RefCounted<Job> {
@ -127,3 +129,5 @@ private:
bool m_should_be_disowned { false }; bool m_should_be_disowned { false };
OwnPtr<AST::Command> m_command; OwnPtr<AST::Command> m_command;
}; };
}

View file

@ -27,7 +27,7 @@
#include "NodeVisitor.h" #include "NodeVisitor.h"
#include "AST.h" #include "AST.h"
namespace AST { namespace Shell::AST {
void NodeVisitor::visit(const AST::PathRedirectionNode* node) void NodeVisitor::visit(const AST::PathRedirectionNode* node)
{ {

View file

@ -28,7 +28,7 @@
#include "Forward.h" #include "Forward.h"
namespace AST { namespace Shell::AST {
class NodeVisitor { class NodeVisitor {
public: public:

View file

@ -29,6 +29,8 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
namespace Shell {
Parser::SavedOffset Parser::save_offset() const Parser::SavedOffset Parser::save_offset() const
{ {
return { m_offset, m_line }; return { m_offset, m_line };
@ -1350,3 +1352,5 @@ StringView Parser::consume_while(Function<bool(char)> condition)
return m_input.substring_view(start_offset, m_offset - start_offset); return m_input.substring_view(start_offset, m_offset - start_offset);
} }
}

View file

@ -33,6 +33,8 @@
#include <AK/StringBuilder.h> #include <AK/StringBuilder.h>
#include <AK/Vector.h> #include <AK/Vector.h>
namespace Shell {
class Parser { class Parser {
public: public:
Parser(StringView input) Parser(StringView input)
@ -232,3 +234,5 @@ glob :: [*?] bareword?
| bareword [*?] | bareword [*?]
)"; )";
#endif #endif
}

View file

@ -57,6 +57,8 @@ extern char** environ;
//#define SH_DEBUG //#define SH_DEBUG
namespace Shell {
// FIXME: This should eventually be removed once we've established that // FIXME: This should eventually be removed once we've established that
// waitpid() is not passed the same job twice. // waitpid() is not passed the same job twice.
#ifdef __serenity__ #ifdef __serenity__
@ -523,6 +525,10 @@ bool Shell::is_runnable(const StringView& name)
int Shell::run_command(const StringView& cmd) int Shell::run_command(const StringView& cmd)
{ {
// The default-constructed mode of the shell
// should not be used for execution!
ASSERT(!m_default_constructed);
if (cmd.is_empty()) if (cmd.is_empty())
return 0; return 0;
@ -1158,7 +1164,8 @@ Vector<Line::CompletionSuggestion> Shell::complete_path(const String& base, cons
// since we are not suggesting anything starting with // since we are not suggesting anything starting with
// `/foo/', but rather just `bar...' // `/foo/', but rather just `bar...'
auto token_length = escape_token(token).length(); auto token_length = escape_token(token).length();
m_editor->suggest(token_length, original_token.length() - token_length); if (m_editor)
m_editor->suggest(token_length, original_token.length() - token_length);
// only suggest dot-files if path starts with a dot // only suggest dot-files if path starts with a dot
Core::DirIterator files(path, Core::DirIterator files(path,
@ -1195,7 +1202,8 @@ Vector<Line::CompletionSuggestion> Shell::complete_program_name(const String& na
return complete_path("", name, offset); return complete_path("", name, offset);
String completion = *match; String completion = *match;
m_editor->suggest(escape_token(name).length(), 0); if (m_editor)
m_editor->suggest(escape_token(name).length(), 0);
// Now that we have a program name starting with our token, we look at // Now that we have a program name starting with our token, we look at
// other program names starting with our token and cut off any mismatching // other program names starting with our token and cut off any mismatching
@ -1220,7 +1228,8 @@ Vector<Line::CompletionSuggestion> Shell::complete_variable(const String& name,
Vector<Line::CompletionSuggestion> suggestions; Vector<Line::CompletionSuggestion> suggestions;
auto pattern = offset ? name.substring_view(0, offset) : ""; auto pattern = offset ? name.substring_view(0, offset) : "";
m_editor->suggest(offset); if (m_editor)
m_editor->suggest(offset);
// Look at local variables. // Look at local variables.
for (auto& frame : m_local_frames) { for (auto& frame : m_local_frames) {
@ -1252,7 +1261,8 @@ Vector<Line::CompletionSuggestion> Shell::complete_user(const String& name, size
Vector<Line::CompletionSuggestion> suggestions; Vector<Line::CompletionSuggestion> suggestions;
auto pattern = offset ? name.substring_view(0, offset) : ""; auto pattern = offset ? name.substring_view(0, offset) : "";
m_editor->suggest(offset); if (m_editor)
m_editor->suggest(offset);
Core::DirIterator di("/home", Core::DirIterator::SkipParentAndBaseDir); Core::DirIterator di("/home", Core::DirIterator::SkipParentAndBaseDir);
@ -1274,7 +1284,8 @@ Vector<Line::CompletionSuggestion> Shell::complete_option(const String& program_
while (start < option.length() && option[start] == '-' && start < 2) while (start < option.length() && option[start] == '-' && start < 2)
++start; ++start;
auto option_pattern = offset > start ? option.substring_view(start, offset - start) : ""; auto option_pattern = offset > start ? option.substring_view(start, offset - start) : "";
m_editor->suggest(offset); if (m_editor)
m_editor->suggest(offset);
Vector<Line::CompletionSuggestion> suggestions; Vector<Line::CompletionSuggestion> suggestions;
@ -1459,6 +1470,42 @@ void Shell::notify_child_event()
} while (!found_child); } while (!found_child);
} }
Shell::Shell()
: m_default_constructed(true)
{
push_frame().leak_frame();
int rc = gethostname(hostname, Shell::HostNameSize);
if (rc < 0)
perror("gethostname");
{
auto* pw = getpwuid(getuid());
if (pw) {
username = pw->pw_name;
home = pw->pw_dir;
setenv("HOME", pw->pw_dir, 1);
}
endpwent();
}
// For simplicity, start at the user's home directory.
this->cwd = home;
setenv("PWD", home.characters(), 1);
// Add the default PATH vars.
{
StringBuilder path;
path.append(getenv("PATH"));
if (path.length())
path.append(":");
path.append("/bin:/usr/bin:/usr/local/bin");
setenv("PATH", path.to_string().characters(), true);
}
cache_path();
}
Shell::Shell(Line::Editor& editor) Shell::Shell(Line::Editor& editor)
: m_editor(editor) : m_editor(editor)
{ {
@ -1507,6 +1554,9 @@ Shell::Shell(Line::Editor& editor)
Shell::~Shell() Shell::~Shell()
{ {
if (m_default_constructed)
return;
stop_all_jobs(); stop_all_jobs();
save_history(); save_history();
} }
@ -1641,3 +1691,5 @@ SavedFileDescriptors::~SavedFileDescriptors()
} }
} }
} }
}

View file

@ -64,6 +64,8 @@
__ENUMERATE_SHELL_OPTION(inline_exec_keep_empty_segments, false, "Keep empty segments in inline execute $(...)") \ __ENUMERATE_SHELL_OPTION(inline_exec_keep_empty_segments, false, "Keep empty segments in inline execute $(...)") \
__ENUMERATE_SHELL_OPTION(verbose, false, "Announce every command that is about to be executed") __ENUMERATE_SHELL_OPTION(verbose, false, "Announce every command that is about to be executed")
namespace Shell {
class Shell; class Shell;
class Shell : public Core::Object { class Shell : public Core::Object {
@ -199,6 +201,7 @@ public:
private: private:
Shell(Line::Editor&); Shell(Line::Editor&);
Shell();
virtual ~Shell() override; virtual ~Shell() override;
// FIXME: Port to Core::Property // FIXME: Port to Core::Property
@ -252,9 +255,13 @@ private:
bool m_should_format_live { false }; bool m_should_format_live { false };
RefPtr<Line::Editor> m_editor; RefPtr<Line::Editor> m_editor;
bool m_default_constructed { false };
}; };
static constexpr bool is_word_character(char c) static constexpr bool is_word_character(char c)
{ {
return c == '_' || (c <= 'Z' && c >= 'A') || (c <= 'z' && c >= 'a'); return c == '_' || (c <= 'Z' && c >= 'A') || (c <= 'z' && c >= 'a');
} }
}

View file

@ -36,7 +36,7 @@
#include <string.h> #include <string.h>
RefPtr<Line::Editor> editor; RefPtr<Line::Editor> editor;
Shell* s_shell; Shell::Shell* s_shell;
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
@ -62,7 +62,7 @@ int main(int argc, char** argv)
editor = Line::Editor::construct(); editor = Line::Editor::construct();
auto shell = Shell::construct(*editor); auto shell = Shell::Shell::construct(*editor);
s_shell = shell.ptr(); s_shell = shell.ptr();
s_shell->setup_signals(); s_shell->setup_signals();
@ -163,15 +163,15 @@ int main(int argc, char** argv)
shell->run_file(file_path, false); shell->run_file(file_path, false);
} }
}; };
run_rc_file(Shell::global_init_file_path); run_rc_file(Shell::Shell::global_init_file_path);
run_rc_file(Shell::local_init_file_path); run_rc_file(Shell::Shell::local_init_file_path);
} }
{ {
Vector<String> args; Vector<String> args;
for (auto* arg : script_args) for (auto* arg : script_args)
args.empend(arg); args.empend(arg);
shell->set_local_variable("ARGV", adopt(*new AST::ListValue(move(args)))); shell->set_local_variable("ARGV", adopt(*new Shell::AST::ListValue(move(args))));
} }
if (command_to_run) { if (command_to_run) {
@ -188,7 +188,7 @@ int main(int argc, char** argv)
shell->add_child(*editor); shell->add_child(*editor);
Core::EventLoop::current().post_event(*shell, make<Core::CustomEvent>(Shell::ShellEventType::ReadLine)); Core::EventLoop::current().post_event(*shell, make<Core::CustomEvent>(Shell::Shell::ShellEventType::ReadLine));
return loop.exec(); return loop.exec();
} }