summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnotherTest <ali.mpfard@gmail.com>2020-06-17 18:51:44 +0430
committerAndreas Kling <kling@serenityos.org>2020-07-05 15:43:14 +0200
commit2915dcfcc314deb4b41efdf14768e527614dc3fc (patch)
tree2209513d6907cd93bd47231e740d98075b6f7bd2
parenta4627f24390035a8a8402e019be42b03f525f034 (diff)
downloadserenity-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.cpp25
-rw-r--r--Shell/Builtin.cpp34
-rw-r--r--Shell/Shell.cpp5
-rw-r--r--Shell/Shell.h3
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)