mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 15:12:45 +00:00 
			
		
		
		
	Shell: Move everything to the Shell namespace
Also provide a basic default-constructor.
This commit is contained in:
		
							parent
							
								
									34039d6639
								
							
						
					
					
						commit
						f164b808b5
					
				
					 17 changed files with 115 additions and 17 deletions
				
			
		|  | @ -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, | ||||||
|  |  | ||||||
|  | @ -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) | ||||||
|  |  | ||||||
|  | @ -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 }; | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -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) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "Forward.h" | #include "Forward.h" | ||||||
| 
 | 
 | ||||||
| namespace AST { | namespace Shell::AST { | ||||||
| 
 | 
 | ||||||
| class NodeVisitor { | class NodeVisitor { | ||||||
| public: | public: | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -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() | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -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'); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 AnotherTest
						AnotherTest