From 857c3501df3bb86754e47d5bd3c393434ca90d9d Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Mon, 6 Jun 2022 18:51:02 +0100 Subject: [PATCH] js: Add a loadINI() function for loading INI files :^) This works the same way as loadJSON, except it loads INI files and always returns an object. --- Userland/Utilities/js.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Userland/Utilities/js.cpp b/Userland/Utilities/js.cpp index 9c2ca1d275..4b00929374 100644 --- a/Userland/Utilities/js.cpp +++ b/Userland/Utilities/js.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -96,6 +97,7 @@ private: JS_DECLARE_NATIVE_FUNCTION(repl_help); JS_DECLARE_NATIVE_FUNCTION(load_file); JS_DECLARE_NATIVE_FUNCTION(save_to_file); + JS_DECLARE_NATIVE_FUNCTION(load_ini); JS_DECLARE_NATIVE_FUNCTION(load_json); JS_DECLARE_NATIVE_FUNCTION(last_value_getter); JS_DECLARE_NATIVE_FUNCTION(print); @@ -111,6 +113,7 @@ public: private: JS_DECLARE_NATIVE_FUNCTION(load_file); + JS_DECLARE_NATIVE_FUNCTION(load_ini); JS_DECLARE_NATIVE_FUNCTION(load_json); JS_DECLARE_NATIVE_FUNCTION(print); }; @@ -1196,6 +1199,26 @@ static JS::ThrowCompletionOr load_file_impl(JS::VM& vm, JS::GlobalObj return JS::js_undefined(); } +static JS::ThrowCompletionOr load_ini_impl(JS::VM& vm, JS::GlobalObject& global_object) +{ + auto filename = TRY(vm.argument(0).to_string(global_object)); + auto file = Core::File::construct(filename); + if (!file->open(Core::OpenMode::ReadOnly)) + return vm.throw_completion(global_object, String::formatted("Failed to open '{}': {}", filename, file->error_string())); + + auto config_file = MUST(Core::ConfigFile::open(filename, file->fd())); + auto* object = JS::Object::create(global_object, global_object.object_prototype()); + for (auto const& group : config_file->groups()) { + auto* group_object = JS::Object::create(global_object, global_object.object_prototype()); + for (auto const& key : config_file->keys(group)) { + auto entry = config_file->read_entry(group, key); + group_object->define_direct_property(key, js_string(vm, move(entry)), JS::Attribute::Enumerable | JS::Attribute::Configurable | JS::Attribute::Writable); + } + object->define_direct_property(group, group_object, JS::Attribute::Enumerable | JS::Attribute::Configurable | JS::Attribute::Writable); + } + return object; +} + static JS::ThrowCompletionOr load_json_impl(JS::VM& vm, JS::GlobalObject& global_object) { auto filename = TRY(vm.argument(0).to_string(global_object)); @@ -1218,6 +1241,7 @@ void ReplObject::initialize_global_object() define_native_function("help", repl_help, 0, attr); define_native_function("load", load_file, 1, attr); define_native_function("save", save_to_file, 1, attr); + define_native_function("loadINI", load_ini, 1, attr); define_native_function("loadJSON", load_json, 1, attr); define_native_function("print", print, 1, attr); @@ -1274,6 +1298,11 @@ JS_DEFINE_NATIVE_FUNCTION(ReplObject::load_file) return load_file_impl(vm, global_object); } +JS_DEFINE_NATIVE_FUNCTION(ReplObject::load_ini) +{ + return load_ini_impl(vm, global_object); +} + JS_DEFINE_NATIVE_FUNCTION(ReplObject::load_json) { return load_json_impl(vm, global_object); @@ -1291,6 +1320,7 @@ void ScriptObject::initialize_global_object() define_direct_property("global", this, JS::Attribute::Enumerable); u8 attr = JS::Attribute::Configurable | JS::Attribute::Writable | JS::Attribute::Enumerable; define_native_function("load", load_file, 1, attr); + define_native_function("loadINI", load_ini, 1, attr); define_native_function("loadJSON", load_json, 1, attr); define_native_function("print", print, 1, attr); } @@ -1300,6 +1330,11 @@ JS_DEFINE_NATIVE_FUNCTION(ScriptObject::load_file) return load_file_impl(vm, global_object); } +JS_DEFINE_NATIVE_FUNCTION(ScriptObject::load_ini) +{ + return load_ini_impl(vm, global_object); +} + JS_DEFINE_NATIVE_FUNCTION(ScriptObject::load_json) { return load_json_impl(vm, global_object);