diff options
author | AnotherTest <ali.mpfard@gmail.com> | 2020-06-17 18:51:44 +0430 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-07-05 15:43:14 +0200 |
commit | 2915dcfcc314deb4b41efdf14768e527614dc3fc (patch) | |
tree | 2209513d6907cd93bd47231e740d98075b6f7bd2 | |
parent | a4627f24390035a8a8402e019be42b03f525f034 (diff) | |
download | serenity-2915dcfcc314deb4b41efdf14768e527614dc3fc.zip |
Shell: Add the alias builtin and resolve aliases
This follows the other shells in alias resolution, and resolves the
alias only once.
-rw-r--r-- | Shell/AST.cpp | 25 | ||||
-rw-r--r-- | Shell/Builtin.cpp | 34 | ||||
-rw-r--r-- | Shell/Shell.cpp | 5 | ||||
-rw-r--r-- | Shell/Shell.h | 3 |
4 files changed, 66 insertions, 1 deletions
diff --git a/Shell/AST.cpp b/Shell/AST.cpp index 9f6340e913..6674dd5185 100644 --- a/Shell/AST.cpp +++ b/Shell/AST.cpp @@ -617,7 +617,30 @@ RefPtr<Value> Execute::run(TheExecutionInputType input_value) RefPtr<Job> job; auto shell = input_value; - auto commands = m_command->run(input_value)->resolve_as_commands(input_value); + auto initial_commands = m_command->run(input_value)->resolve_as_commands(input_value); + decltype(initial_commands) commands; + + for (auto& command : initial_commands) { + if (!command.argv.is_empty()) { + auto alias = shell->resolve_alias(command.argv[0]); + if (!alias.is_null()) { + auto argv0 = command.argv.take_first(); + auto subcommand_ast = Parser { alias }.parse(); + if (subcommand_ast) { + while (subcommand_ast->is_execute()) { + auto* ast = static_cast<Execute*>(subcommand_ast.ptr()); + subcommand_ast = ast->command(); + } + RefPtr<Node> substitute = adopt(*new Join(position(), move(subcommand_ast), adopt(*new CommandLiteral(position(), command)))); + commands.append(substitute->run(input_value)->resolve_as_commands(input_value)); + } else { + commands.append(command); + } + } else { + commands.append(command); + } + } + } Vector<RefPtr<Job>> jobs_to_wait_for; auto run_commands = [&](auto& commands) { diff --git a/Shell/Builtin.cpp b/Shell/Builtin.cpp index 14d7aece5c..4be6e4ff4f 100644 --- a/Shell/Builtin.cpp +++ b/Shell/Builtin.cpp @@ -33,6 +33,40 @@ extern RefPtr<Line::Editor> editor; +int Shell::builtin_alias(int argc, const char** argv) +{ + Vector<const char*> arguments; + + Core::ArgsParser parser; + parser.add_positional_argument(arguments, "List of name[=values]'s", "name[=value]", Core::ArgsParser::Required::No); + + if (!parser.parse(argc, const_cast<char**>(argv), false)) + return 1; + + if (arguments.is_empty()) { + for (auto& alias : m_aliases) + printf("%s=%s\n", escape_token(alias.key).characters(), escape_token(alias.value).characters()); + return 0; + } + + bool fail = false; + for (auto& argument : arguments) { + auto parts = String { argument }.split_limit('=', 2, true); + if (parts.size() == 1) { + auto alias = m_aliases.get(parts[0]); + if (alias.has_value()) { + printf("%s=%s\n", escape_token(parts[0]).characters(), escape_token(alias.value()).characters()); + } else { + fail = true; + } + } else { + m_aliases.set(parts[0], parts[1]); + } + } + + return fail ? 1 : 0; +} + int Shell::builtin_bg(int argc, const char** argv) { int job_id = -1; diff --git a/Shell/Shell.cpp b/Shell/Shell.cpp index 9ae3b6bc80..b6ce3d8437 100644 --- a/Shell/Shell.cpp +++ b/Shell/Shell.cpp @@ -306,6 +306,11 @@ void Shell::unset_local_variable(const String& name) m_local_variables.remove(name); } +String Shell::resolve_alias(const String& name) const +{ + return m_aliases.get(name).value_or({}); +} + int Shell::run_command(const StringView& cmd) { if (cmd.is_empty()) diff --git a/Shell/Shell.h b/Shell/Shell.h index cfdf06a860..e052428c15 100644 --- a/Shell/Shell.h +++ b/Shell/Shell.h @@ -40,6 +40,7 @@ #include <termios.h> #define ENUMERATE_SHELL_BUILTINS() \ + __ENUMERATE_SHELL_BUILTIN(alias) \ __ENUMERATE_SHELL_BUILTIN(cd) \ __ENUMERATE_SHELL_BUILTIN(cdh) \ __ENUMERATE_SHELL_BUILTIN(pwd) \ @@ -73,6 +74,7 @@ public: static Vector<String> expand_globs(const StringView& path, StringView base); static Vector<String> expand_globs(Vector<StringView> path_segments, const StringView& base); String resolve_path(String) const; + String resolve_alias(const String&) const; RefPtr<AST::Value> lookup_local_variable(const String&); String local_variable_or(const String&, const String&); @@ -161,6 +163,7 @@ private: pid_t m_pid { 0 }; HashMap<String, RefPtr<AST::Value>> m_local_variables; + HashMap<String, String> m_aliases; }; static constexpr bool is_word_character(char c) |