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
Notes: sideshowbarker 2024-07-19 02:03:08 +09:00
17 changed files with 115 additions and 17 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -29,6 +29,8 @@
#include <stdio.h>
#include <unistd.h>
namespace Shell {
Parser::SavedOffset Parser::save_offset() const
{
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);
}
}

View file

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

View file

@ -57,6 +57,8 @@ extern char** environ;
//#define SH_DEBUG
namespace Shell {
// FIXME: This should eventually be removed once we've established that
// waitpid() is not passed the same job twice.
#ifdef __serenity__
@ -523,6 +525,10 @@ bool Shell::is_runnable(const StringView& name)
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())
return 0;
@ -1158,7 +1164,8 @@ Vector<Line::CompletionSuggestion> Shell::complete_path(const String& base, cons
// since we are not suggesting anything starting with
// `/foo/', but rather just `bar...'
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
Core::DirIterator files(path,
@ -1195,7 +1202,8 @@ Vector<Line::CompletionSuggestion> Shell::complete_program_name(const String& na
return complete_path("", name, offset);
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
// 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;
auto pattern = offset ? name.substring_view(0, offset) : "";
m_editor->suggest(offset);
if (m_editor)
m_editor->suggest(offset);
// Look at local variables.
for (auto& frame : m_local_frames) {
@ -1252,7 +1261,8 @@ Vector<Line::CompletionSuggestion> Shell::complete_user(const String& name, size
Vector<Line::CompletionSuggestion> suggestions;
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);
@ -1274,7 +1284,8 @@ Vector<Line::CompletionSuggestion> Shell::complete_option(const String& program_
while (start < option.length() && option[start] == '-' && start < 2)
++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;
@ -1459,6 +1470,42 @@ void Shell::notify_child_event()
} 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)
: m_editor(editor)
{
@ -1507,6 +1554,9 @@ Shell::Shell(Line::Editor& editor)
Shell::~Shell()
{
if (m_default_constructed)
return;
stop_all_jobs();
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(verbose, false, "Announce every command that is about to be executed")
namespace Shell {
class Shell;
class Shell : public Core::Object {
@ -199,6 +201,7 @@ public:
private:
Shell(Line::Editor&);
Shell();
virtual ~Shell() override;
// FIXME: Port to Core::Property
@ -252,9 +255,13 @@ private:
bool m_should_format_live { false };
RefPtr<Line::Editor> m_editor;
bool m_default_constructed { false };
};
static constexpr bool is_word_character(char c)
{
return c == '_' || (c <= 'Z' && c >= 'A') || (c <= 'z' && c >= 'a');
}
}

View file

@ -36,7 +36,7 @@
#include <string.h>
RefPtr<Line::Editor> editor;
Shell* s_shell;
Shell::Shell* s_shell;
int main(int argc, char** argv)
{
@ -62,7 +62,7 @@ int main(int argc, char** argv)
editor = Line::Editor::construct();
auto shell = Shell::construct(*editor);
auto shell = Shell::Shell::construct(*editor);
s_shell = shell.ptr();
s_shell->setup_signals();
@ -163,15 +163,15 @@ int main(int argc, char** argv)
shell->run_file(file_path, false);
}
};
run_rc_file(Shell::global_init_file_path);
run_rc_file(Shell::local_init_file_path);
run_rc_file(Shell::Shell::global_init_file_path);
run_rc_file(Shell::Shell::local_init_file_path);
}
{
Vector<String> args;
for (auto* arg : script_args)
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) {
@ -188,7 +188,7 @@ int main(int argc, char** argv)
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();
}