[gjs/wip/imports-cleanup: 10/13] Add a simple API to import a GFile as a JS module



commit 37c045f72243f35cd2bd598ce7fddff0ed569085
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Fri Sep 27 17:49:15 2013 -0400

    Add a simple API to import a GFile as a JS module
    
    Without going through the crazy importer lookup system.

 gjs/importer.c   |   73 +----------------------------------------------------
 gjs/jsapi-util.c |   69 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gjs/jsapi-util.h |    6 ++++
 modules/system.c |   34 +++++++++++++++++++++++++
 4 files changed, 111 insertions(+), 71 deletions(-)
---
diff --git a/gjs/importer.c b/gjs/importer.c
index 13a1a68..5a0bc7b 100644
--- a/gjs/importer.c
+++ b/gjs/importer.c
@@ -264,75 +264,6 @@ import_native_file(JSContext  *context,
     return retval;
 }
 
-static JSBool
-import_file(JSContext  *context,
-            const char *name,
-            GFile      *file,
-            JSObject  **module_out)
-{
-    JSBool ret = JS_FALSE;
-    JSObject *module_obj;
-    char *script = NULL;
-    char *full_path = NULL;
-    gsize script_len = 0;
-    jsval script_retval;
-    GError *error = NULL;
-
-    module_obj = JS_NewObject(context, NULL, NULL, NULL);
-    if (module_obj == NULL)
-        goto out;
-
-    if (!(g_file_load_contents(file, NULL, &script, &script_len, NULL, &error))) {
-        if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY) &&
-            !g_error_matches(error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY) &&
-            !g_error_matches(error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
-            gjs_throw_g_error(context, error);
-        else
-            g_error_free(error);
-
-        goto out;
-    }
-
-    g_assert(script != NULL);
-
-    gjs_debug(GJS_DEBUG_IMPORTER, "Importing %s", full_path);
-
-    full_path = g_file_get_parse_name (file);
-
-    if (!JS_EvaluateScript(context,
-                           module_obj,
-                           script,
-                           script_len,
-                           full_path,
-                           1, /* line number */
-                           &script_retval)) {
-
-        /* If JSOPTION_DONT_REPORT_UNCAUGHT is set then the exception
-         * would be left set after the evaluate and not go to the error
-         * reporter function.
-         */
-        if (JS_IsExceptionPending(context)) {
-            gjs_debug(GJS_DEBUG_IMPORTER,
-                      "Module '%s' left an exception set",
-                      name);
-            gjs_log_and_keep_exception(context);
-        } else {
-            gjs_throw(context,
-                         "JS_EvaluateScript() returned FALSE but did not set exception");
-        }
-
-        goto out;
-    }
-
-    ret = JS_TRUE;
-
- out:
-    g_free(script);
-    g_free(full_path);
-    *module_out = module_obj;
-    return ret;
-}
-
 static JSObject *
 load_module_init(JSContext  *context,
                  JSObject   *in_object,
@@ -358,7 +289,7 @@ load_module_init(JSContext  *context,
     }
 
     file = g_file_new_for_commandline_arg(full_path);
-    if (!import_file (context, "__init__", file, &module_obj))
+    if (!gjs_import_file (context, "__init__", file, &module_obj))
         goto out;
 
     if (!JS_DefinePropertyById(context, in_object,
@@ -427,7 +358,7 @@ import_file_on_module(JSContext  *context,
     gjs_debug(GJS_DEBUG_IMPORTER,
               "Importing '%s'", full_path);
 
-    if (!import_file (context, name, file, &module_obj))
+    if (!gjs_import_file (context, name, file, &module_obj))
         goto out;
 
     if (!define_import(context, obj, module_obj, name))
diff --git a/gjs/jsapi-util.c b/gjs/jsapi-util.c
index 15b42ac..f0ff7db 100644
--- a/gjs/jsapi-util.c
+++ b/gjs/jsapi-util.c
@@ -1158,3 +1158,72 @@ gjs_unblock_gc(void)
 {
     g_mutex_unlock(&gc_lock);
 }
+
+JSBool
+gjs_import_file (JSContext  *context,
+                 const char *name,
+                 GFile      *file,
+                 JSObject  **module_out)
+{
+    JSBool ret = JS_FALSE;
+    JSObject *module_obj;
+    char *script = NULL;
+    char *full_path = NULL;
+    gsize script_len = 0;
+    jsval script_retval;
+    GError *error = NULL;
+
+    module_obj = JS_NewObject(context, NULL, NULL, NULL);
+    if (module_obj == NULL)
+        goto out;
+
+    if (!(g_file_load_contents(file, NULL, &script, &script_len, NULL, &error))) {
+        if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY) &&
+            !g_error_matches(error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY) &&
+            !g_error_matches(error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+            gjs_throw_g_error(context, error);
+        else
+            g_error_free(error);
+
+        goto out;
+    }
+
+    g_assert(script != NULL);
+
+    gjs_debug(GJS_DEBUG_IMPORTER, "Importing %s", full_path);
+
+    full_path = g_file_get_parse_name (file);
+
+    if (!JS_EvaluateScript(context,
+                           module_obj,
+                           script,
+                           script_len,
+                           full_path,
+                           1, /* line number */
+                           &script_retval)) {
+
+        /* If JSOPTION_DONT_REPORT_UNCAUGHT is set then the exception
+         * would be left set after the evaluate and not go to the error
+         * reporter function.
+         */
+        if (JS_IsExceptionPending(context)) {
+            gjs_debug(GJS_DEBUG_IMPORTER,
+                      "Module '%s' left an exception set",
+                      name);
+            gjs_log_and_keep_exception(context);
+        } else {
+            gjs_throw(context,
+                         "JS_EvaluateScript() returned FALSE but did not set exception");
+        }
+
+        goto out;
+    }
+
+    ret = JS_TRUE;
+
+ out:
+    g_free(script);
+    g_free(full_path);
+    *module_out = module_obj;
+    return ret;
+}
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 62cffed..a9e5410 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -31,6 +31,7 @@
 #include <gjs/compat.h>
 #include <gjs/runtime.h>
 #include <glib-object.h>
+#include <gio/gio.h>
 
 G_BEGIN_DECLS
 
@@ -382,6 +383,11 @@ JSBool            gjs_context_get_frame_info (JSContext  *context,
                                               jsval      *fileName,
                                               jsval      *lineNumber);
 
+JSBool gjs_import_file (JSContext *context,
+                        const char *name,
+                        GFile      *file,
+                        JSObject  **module_out);
+
 G_END_DECLS
 
 #endif  /* __GJS_JSAPI_UTIL_H__ */
diff --git a/modules/system.c b/modules/system.c
index 6fc1e21..004beb4 100644
--- a/modules/system.c
+++ b/modules/system.c
@@ -119,12 +119,46 @@ gjs_exit(JSContext *context,
     return JS_TRUE;
 }
 
+static JSBool
+import_file (JSContext *context,
+             unsigned   argc,
+             jsval     *vp)
+{
+    JSBool ret = JS_FALSE;
+    jsval *argv = JS_ARGV(cx, vp);
+    gchar *name = NULL;
+    GFile *file = NULL;
+    JSObject *file_object;
+    JSObject *module_obj;
+
+    if (!gjs_parse_args(context, "importFile", "so", argc, argv,
+                        "name", &name,
+                        "object", &file_object))
+        goto out;
+
+    file = G_FILE (gjs_g_object_from_object (context, file_object));
+    if (file == NULL)
+        goto out;
+
+    if (!gjs_import_file (context, name, file, &module_obj))
+        goto out;
+
+    JS_SET_RVAL (cx, argv, OBJECT_TO_JSVAL (module_obj));
+
+    ret = JS_TRUE;
+ out:
+    g_free (name);
+    g_object_unref (file);
+    return ret;
+}
+
 static JSFunctionSpec module_funcs[] = {
     { "addressOf", JSOP_WRAPPER (gjs_address_of), 1, GJS_MODULE_PROP_FLAGS },
     { "refcount", JSOP_WRAPPER (gjs_refcount), 1, GJS_MODULE_PROP_FLAGS },
     { "breakpoint", JSOP_WRAPPER (gjs_breakpoint), 0, GJS_MODULE_PROP_FLAGS },
     { "gc", JSOP_WRAPPER (gjs_gc), 0, GJS_MODULE_PROP_FLAGS },
     { "exit", JSOP_WRAPPER (gjs_exit), 0, GJS_MODULE_PROP_FLAGS },
+    { "importFile", JSOP_WRAPPER (import_file), 0, GJS_MODULE_PROP_FLAGS },
     { NULL },
 };
 


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