Shell: Add the alias builtin and resolve aliases

This follows the other shells in alias resolution, and resolves the
alias only once.
This commit is contained in:
AnotherTest 2020-06-17 18:51:44 +04:30 committed by Andreas Kling
parent a4627f2439
commit 2915dcfcc3
Notes: sideshowbarker 2024-07-19 05:09:39 +09:00
4 changed files with 66 additions and 1 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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())

View File

@ -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)