mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 05:52:46 +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 { | ||||
| 
 | ||||
| using namespace Shell; | ||||
| 
 | ||||
| enum class AugmentedTokenKind : u32 { | ||||
|     __TokenTypeCount = (u32)AST::Node::Kind::__Count, | ||||
|     OpenParen, | ||||
|  |  | |||
|  | @ -37,7 +37,7 @@ | |||
| 
 | ||||
| //#define EXECUTE_DEBUG
 | ||||
| 
 | ||||
| namespace AST { | ||||
| namespace Shell::AST { | ||||
| 
 | ||||
| template<typename T, typename... Args> | ||||
| static inline NonnullRefPtr<T> create(Args... args) | ||||
|  |  | |||
|  | @ -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 }; | ||||
|  |  | |||
|  | @ -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; | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -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; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -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); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -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; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -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; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -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); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -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; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ | |||
| #include "NodeVisitor.h" | ||||
| #include "AST.h" | ||||
| 
 | ||||
| namespace AST { | ||||
| namespace Shell::AST { | ||||
| 
 | ||||
| void NodeVisitor::visit(const AST::PathRedirectionNode* node) | ||||
| { | ||||
|  |  | |||
|  | @ -28,7 +28,7 @@ | |||
| 
 | ||||
| #include "Forward.h" | ||||
| 
 | ||||
| namespace AST { | ||||
| namespace Shell::AST { | ||||
| 
 | ||||
| class NodeVisitor { | ||||
| public: | ||||
|  |  | |||
|  | @ -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); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -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() | |||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -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'); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -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(); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 AnotherTest
						AnotherTest