[gjs/ewlsh/refactor-argv] Refactor ARGV handling.



commit 92fcef20365b080005242677ff419d8a187bc2f7
Author: Evan Welsh <noreply evanwelsh com>
Date:   Mon Jun 22 19:43:47 2020 -0500

    Refactor ARGV handling.

 gjs/console.cpp       |  8 +-------
 gjs/context-private.h |  8 ++++++++
 gjs/context.cpp       | 21 +++++++++++++++++++++
 gjs/context.h         |  4 ++++
 gjs/global.cpp        | 20 ++++++++++++++++++++
 gjs/global.h          |  2 ++
 6 files changed, 56 insertions(+), 7 deletions(-)
---
diff --git a/gjs/console.cpp b/gjs/console.cpp
index 9e335594..460068e7 100644
--- a/gjs/console.cpp
+++ b/gjs/console.cpp
@@ -191,13 +191,7 @@ int define_argv_and_eval_script(GjsContext* js_context, int argc,
                                 size_t len, const char* filename) {
     GError* error = nullptr;
 
-    /* prepare command line arguments */
-    if (!gjs_context_define_string_array(
-            js_context, "ARGV", argc, const_cast<const char**>(argv), &error)) {
-        g_critical("Failed to define ARGV: %s", error->message);
-        g_clear_error(&error);
-        return 1;
-    }
+    gjs_context_set_argv(js_context, argc, const_cast<const char**>(argv));
 
     /* evaluate the script */
     int code;
diff --git a/gjs/context-private.h b/gjs/context-private.h
index 1b1e5562..1237523c 100644
--- a/gjs/context-private.h
+++ b/gjs/context-private.h
@@ -29,8 +29,10 @@
 #include <stdint.h>
 #include <sys/types.h>  // for ssize_t
 
+#include <string>
 #include <type_traits>  // for is_same
 #include <unordered_map>
+#include <vector>
 
 #include <glib-object.h>
 #include <glib.h>
@@ -103,6 +105,8 @@ class GjsContextPrivate : public JS::JobQueue {
 
     GjsAtoms* m_atoms;
 
+    std::vector<std::string> m_args;
+
     JobQueueStorage m_job_queue;
     unsigned m_idle_drain_handler;
 
@@ -193,6 +197,10 @@ class GjsContextPrivate : public JS::JobQueue {
     void set_should_listen_sigusr2(bool value) {
         m_should_listen_sigusr2 = value;
     }
+
+    void set_args(std::vector<std::string> args);
+    std::vector<std::string> get_args();
+
     GJS_USE bool is_owner_thread(void) const {
         return m_owner_thread == g_thread_self();
     }
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 04f28f73..2a1fe033 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -532,6 +532,12 @@ GjsContextPrivate::GjsContextPrivate(JSContext* cx, GjsContext* public_context)
     }
 }
 
+void GjsContextPrivate::set_args(std::vector<std::string> args) {
+    m_args = args;
+}
+
+std::vector<std::string> GjsContextPrivate::get_args() { return m_args; }
+
 static void
 gjs_context_get_property (GObject     *object,
                           guint        prop_id,
@@ -1132,6 +1138,13 @@ gjs_context_define_string_array(GjsContext  *js_context,
         strings = {array_values, array_values + array_length};
     }
 
+    // ARGV is a special case to preserve backwards compatibility.
+    if (strcmp(array_name, "ARGV") == 0) {
+        gjs->set_args(strings);
+
+        return true;
+    }
+
     JS::RootedObject global_root(gjs->context(), gjs->global());
     if (!gjs_define_string_array(gjs->context(), global_root, array_name,
                                  strings, JSPROP_READONLY | JSPROP_PERMANENT)) {
@@ -1146,6 +1159,14 @@ gjs_context_define_string_array(GjsContext  *js_context,
     return true;
 }
 
+void gjs_context_set_argv(GjsContext* js_context, gssize array_length,
+                          const char** array_values) {
+    g_return_if_fail(GJS_IS_CONTEXT(js_context));
+    GjsContextPrivate* gjs = GjsContextPrivate::from_object(js_context);
+    std::vector<std::string> args(array_values, array_values + array_length);
+    gjs->set_args(args);
+}
+
 static GjsContext *current_context;
 
 GjsContext *
diff --git a/gjs/context.h b/gjs/context.h
index 13be25b9..9f9a86fc 100644
--- a/gjs/context.h
+++ b/gjs/context.h
@@ -69,6 +69,10 @@ GJS_EXPORT GJS_USE bool gjs_context_define_string_array(
     GjsContext* js_context, const char* array_name, gssize array_length,
     const char** array_values, GError** error);
 
+GJS_EXPORT void gjs_context_set_argv(GjsContext* js_context,
+                                     gssize array_length,
+                                     const char** array_values);
+
 GJS_EXPORT GJS_USE GList* gjs_context_get_all(void);
 
 GJS_EXPORT GJS_USE GjsContext* gjs_context_get_current(void);
diff --git a/gjs/global.cpp b/gjs/global.cpp
index dd2ad2a9..041596fe 100644
--- a/gjs/global.cpp
+++ b/gjs/global.cpp
@@ -227,6 +227,20 @@ gjs_printerr(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
+static bool gjs_argv(JSContext* cx, unsigned argc, JS::Value* vp) {
+    JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
+    GjsContextPrivate* gjs = GjsContextPrivate::from_cx(cx);
+    auto array = gjs_build_string_array(cx, gjs->get_args());
+
+    if (!array) {
+        return false;
+    }
+
+    argv.rval().setObjectOrNull(array);
+    return true;
+}
+
 const JSClassOps defaultclassops = JS::DefaultGlobalClassOps;
 
 class GjsGlobal {
@@ -298,6 +312,12 @@ class GjsGlobal {
                                    GJS_MODULE_PROP_FLAGS))
             return false;
 
+        if (!JS_DefineProperty(cx, global, "ARGV", gjs_argv, nullptr,
+                               GJS_MODULE_PROP_FLAGS | JSPROP_READONLY)) {
+            gjs_log_exception(cx);
+            return false;
+        }
+
         if (bootstrap_script) {
             if (!run_bootstrap(cx, bootstrap_script, global))
                 return false;
diff --git a/gjs/global.h b/gjs/global.h
index 649ee3dc..8c4a74d1 100644
--- a/gjs/global.h
+++ b/gjs/global.h
@@ -26,6 +26,8 @@
 
 #include <config.h>
 
+#include <stdint.h>
+
 #include <js/TypeDecls.h>
 #include <js/Value.h>
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]