From bb0989fdef65d8e716e67df7379d13ecace416e2 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Tue, 3 Oct 2023 10:24:10 +0300 Subject: [PATCH] Shell: Implement sourcing scripts --- userspace/Shell/main.cpp | 62 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/userspace/Shell/main.cpp b/userspace/Shell/main.cpp index 279c14c22..6ca698685 100644 --- a/userspace/Shell/main.cpp +++ b/userspace/Shell/main.cpp @@ -265,6 +265,8 @@ BAN::Vector> parse_command(BAN::StringView command_view int execute_command(BAN::Vector& args, int fd_in, int fd_out); +int source_script(const BAN::String& path); + BAN::Optional execute_builtin(BAN::Vector& args, int fd_in, int fd_out) { if (args.empty()) @@ -312,6 +314,15 @@ BAN::Optional execute_builtin(BAN::Vector& args, int fd_in, in ERROR_RETURN("setenv", 1); } } + else if (args.front() == "source"sv) + { + if (args.size() != 2) + { + fprintf(fout, "usage: source FILE\n"); + return 1; + } + return source_script(args[1]); + } else if (args.front() == "env"sv) { char** current = environ; @@ -634,6 +645,52 @@ int execute_piped_commands(BAN::Vector>& commands) return exit_codes.back(); } +int parse_and_execute_command(BAN::StringView command) +{ + if (command.empty()) + return 0; + auto parsed_commands = parse_command(command); + if (parsed_commands.empty()) + return 0; + tcsetattr(0, TCSANOW, &old_termios); + int ret = execute_piped_commands(parsed_commands); + tcsetattr(0, TCSANOW, &new_termios); + return ret; +} + +int source_script(const BAN::String& path) +{ + FILE* fp = fopen(path.data(), "r"); + if (fp == nullptr) + ERROR_RETURN("fopen", 1); + + int ret = 0; + + BAN::String command; + char temp_buffer[128]; + while (fgets(temp_buffer, sizeof(temp_buffer), fp)) + { + MUST(command.append(temp_buffer)); + if (command.back() != '\n') + continue; + + command.pop_back(); + + if (!command.empty()) + if (int temp = parse_and_execute_command(command)) + ret = temp; + command.clear(); + } + + if (!command.empty()) + if (int temp = parse_and_execute_command(command)) + ret = temp; + + fclose(fp); + + return ret; +} + int character_length(BAN::StringView prompt) { int length { 0 }; @@ -901,10 +958,7 @@ int main(int argc, char** argv) fputc('\n', stdout); if (!buffers[index].empty()) { - tcsetattr(0, TCSANOW, &old_termios); - auto commands = parse_command(buffers[index]); - last_return = execute_piped_commands(commands); - tcsetattr(0, TCSANOW, &new_termios); + last_return = parse_and_execute_command(buffers[index]); MUST(history.push_back(buffers[index])); buffers = history; MUST(buffers.emplace_back(""sv));