summaryrefslogtreecommitdiff
path: root/Shell/Builtin.cpp
diff options
context:
space:
mode:
authorAnotherTest <ali.mpfard@gmail.com>2021-01-03 12:39:27 +0330
committerAndreas Kling <kling@serenityos.org>2021-01-03 17:13:00 +0100
commitaaa83e95c95619398610cde68ee2654abf45ccc8 (patch)
tree00d6f2e4ccc78956a87ea6e91c32618e73e68cc4 /Shell/Builtin.cpp
parenta698af88fcede7ba4db04fe4f9a98991c545ea7d (diff)
downloadserenity-aaa83e95c95619398610cde68ee2654abf45ccc8.zip
Shell: Implement a 'source' builtin
Diffstat (limited to 'Shell/Builtin.cpp')
-rw-r--r--Shell/Builtin.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/Shell/Builtin.cpp b/Shell/Builtin.cpp
index 99727f524a..fb3791695e 100644
--- a/Shell/Builtin.cpp
+++ b/Shell/Builtin.cpp
@@ -24,8 +24,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "AST.h"
#include "Shell.h"
#include <AK/LexicalPath.h>
+#include <AK/ScopeGuard.h>
#include <LibCore/ArgsParser.h>
#include <LibCore/EventLoop.h>
#include <LibCore/File.h>
@@ -723,6 +725,37 @@ int Shell::builtin_shift(int argc, const char** argv)
return 0;
}
+int Shell::builtin_source(int argc, const char** argv)
+{
+ const char* file_to_source = nullptr;
+ Vector<const char*> args;
+
+ Core::ArgsParser parser;
+ parser.add_positional_argument(file_to_source, "File to read commands from", "path");
+ parser.add_positional_argument(args, "ARGV for the sourced file", "args", Core::ArgsParser::Required::No);
+
+ if (!parser.parse(argc, const_cast<char**>(argv)))
+ return 1;
+
+ Vector<String> string_argv;
+ for (auto& arg : args)
+ string_argv.append(arg);
+
+ auto previous_argv = lookup_local_variable("ARGV");
+ ScopeGuard guard { [&] {
+ if (!args.is_empty())
+ set_local_variable("ARGV", move(previous_argv));
+ } };
+
+ if (!args.is_empty())
+ set_local_variable("ARGV", AST::create<AST::ListValue>(move(string_argv)));
+
+ if (!run_file(file_to_source, true))
+ return 126;
+
+ return 0;
+}
+
int Shell::builtin_time(int argc, const char** argv)
{
Vector<const char*> args;