[gjs] jsapi-util: Make gjs_strip_unix_shebang public and clarify some variable names



commit e00f673a4caf32e594d0aba792d36be1232488cd
Author: Sam Spilsbury <smspillaz gmail com>
Date:   Wed Jan 8 14:39:44 2014 -0200

    jsapi-util: Make gjs_strip_unix_shebang public and clarify some variable names
    
    line_number in this instance is really the starting line number.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=721246

 gjs/jsapi-util.cpp |   50 ++++++++++++++++++++++++++++++++++-------------
 gjs/jsapi-util.h   |   20 +++++++++++++++++++
 test/gjs-tests.cpp |   54 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 110 insertions(+), 14 deletions(-)
---
diff --git a/gjs/jsapi-util.cpp b/gjs/jsapi-util.cpp
index 59b3dc1..7e1dbda 100644
--- a/gjs/jsapi-util.cpp
+++ b/gjs/jsapi-util.cpp
@@ -1167,23 +1167,42 @@ gjs_unblock_gc(void)
     g_mutex_unlock(&gc_lock);
 }
 
-static void
-strip_unix_shebang(const char  **script,
-                   gssize       *script_len,
-                   int          *line_number)
+const char *
+gjs_strip_unix_shebang(const char  *script,
+                       gssize      *script_len,
+                       int         *start_line_number_out)
 {
-    /* handle scripts with UNIX shebangs */
-    if (strncmp(*script, "#!", *script_len) == 0) {
-        const char *s;
+    g_assert(script_len);
 
-        s = (const char *) strstr (*script, "\n");
+    /* handle scripts with UNIX shebangs */
+    if (strncmp(script, "#!", 2) == 0) {
+        /* If we found a newline, advance the script by one line */
+        const char *s = (const char *) strstr (script, "\n");
         if (s != NULL) {
             if (*script_len > 0)
-                *script_len -= (s + 1 - *script);
-            *script = s + 1;
-            *line_number++;
+                *script_len -= (s + 1 - script);
+            script = s + 1;
+
+            if (start_line_number_out)
+                *start_line_number_out = 2;
+
+            return script;
+        } else {
+            /* Just a shebang */
+            if (start_line_number_out)
+                *start_line_number_out = -1;
+
+            *script_len = 0;
+
+            return NULL;
         }
     }
+
+    /* No shebang, return the original script */
+    if (start_line_number_out)
+        *start_line_number_out = 1;
+
+    return script;
 }
 
 JSBool
@@ -1196,12 +1215,15 @@ gjs_eval_with_scope(JSContext    *context,
                     GError      **error)
 {
     JSBool ret = JS_FALSE;
-    int line_number = 1;
+    int start_line_number;
     jsval retval = JSVAL_VOID;
 
     if (script_len < 0)
         script_len = strlen(script);
-    strip_unix_shebang(&script, &script_len, &line_number);
+
+    script = gjs_strip_unix_shebang(script,
+                                    &script_len,
+                                    &start_line_number);
 
     /* log and clear exception if it's set (should not be, normally...) */
     if (gjs_log_exception(context)) {
@@ -1221,7 +1243,7 @@ gjs_eval_with_scope(JSContext    *context,
 
     JS::CompileOptions options(context);
     options.setUTF8(true)
-           .setFileAndLine(filename, line_number)
+           .setFileAndLine(filename, start_line_number)
            .setSourcePolicy(JS::CompileOptions::LAZY_SOURCE);
 
     js::RootedObject rootedObj(context, object);
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 0b69ac5..bb37da5 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -391,6 +391,26 @@ JSBool            gjs_eval_with_scope        (JSContext    *context,
                                               jsval        *retval_p,
                                               GError      **error);
 
+/**
+ * gjs_strip_unix_shebang:
+ *
+ * @script: (in): A pointer to a JS script
+ * @script_len: (inout): A pointer to the script length. The
+ * pointer will be modified if a shebang is stripped.
+ * @new_start_line_number: (out) (allow-none): A pointer to
+ * write the start-line number to account for the offset
+ * as a result of stripping the shebang.
+ *
+ * Returns a pointer to the beginning of a script with unix
+ * shebangs removed. The outparams are useful to know the
+ * new length of the script and on what line of the
+ * original script we're executing from, so that any relevant
+ * offsets can be applied to the results of an execution pass.
+ */
+const char * gjs_strip_unix_shebang(const char *script,
+                                    gssize     *script_len,
+                                    int        *new_start_line_number);
+
 G_END_DECLS
 
 #endif  /* __GJS_JSAPI_UTIL_H__ */
diff --git a/test/gjs-tests.cpp b/test/gjs-tests.cpp
index 1fda57a..2dba2b2 100644
--- a/test/gjs-tests.cpp
+++ b/test/gjs-tests.cpp
@@ -299,6 +299,57 @@ gjstest_test_func_util_glib_strv_concat_pointers(void)
     g_strfreev(ret);
 }
 
+static void
+gjstest_test_strip_shebang_no_advance_for_no_shebang(void)
+{
+    const char *script = "foo\nbar";
+    gssize     script_len_original = strlen(script);
+    gssize     script_len = script_len_original;
+    int        line_number = 1;
+
+    const char *stripped = gjs_strip_unix_shebang(script,
+                                                  &script_len,
+                                                  &line_number);
+
+    g_assert_cmpstr(script, ==, stripped);
+    g_assert(script_len == script_len_original);
+    g_assert(line_number == 1);
+}
+
+static void
+gjstest_test_strip_shebang_advance_for_shebang(void)
+{
+    const char *script = "#!foo\nbar";
+    gssize     script_len_original = strlen(script);
+    gssize     script_len = script_len_original;
+    int        line_number = 1;
+
+    const char *stripped = gjs_strip_unix_shebang(script,
+                                                  &script_len,
+                                                  &line_number);
+
+    g_assert_cmpstr(stripped, ==, "bar");
+    g_assert(script_len == 3);
+    g_assert(line_number == 2);
+}
+
+static void
+gjstest_test_strip_shebang_return_null_for_just_shebang(void)
+{
+    const char *script = "#!foo";
+    gssize     script_len_original = strlen(script);
+    gssize     script_len = script_len_original;
+    int        line_number = 1;
+
+    const char *stripped = gjs_strip_unix_shebang(script,
+                                                  &script_len,
+                                                  &line_number);
+
+    g_assert(stripped == NULL);
+    g_assert(script_len == 0);
+    g_assert(line_number == -1);
+}
+
 int
 main(int    argc,
      char **argv)
@@ -313,6 +364,9 @@ main(int    argc,
     g_test_add_func("/gjs/jsapi/util/array", gjstest_test_func_gjs_jsapi_util_array);
     g_test_add_func("/gjs/jsapi/util/error/throw", gjstest_test_func_gjs_jsapi_util_error_throw);
     g_test_add_func("/gjs/jsapi/util/string/js/string/utf8", 
gjstest_test_func_gjs_jsapi_util_string_js_string_utf8);
+    g_test_add_func("/gjs/jsutil/strip_shebang/no_shebang", 
gjstest_test_strip_shebang_no_advance_for_no_shebang);
+    g_test_add_func("/gjs/jsutil/strip_shebang/have_shebang", 
gjstest_test_strip_shebang_advance_for_shebang);
+    g_test_add_func("/gjs/jsutil/strip_shebang/only_shebang", 
gjstest_test_strip_shebang_return_null_for_just_shebang);
     g_test_add_func("/gjs/stack/dump", gjstest_test_func_gjs_stack_dump);
     g_test_add_func("/util/glib/strv/concat/null", gjstest_test_func_util_glib_strv_concat_null);
     g_test_add_func("/util/glib/strv/concat/pointers", gjstest_test_func_util_glib_strv_concat_pointers);


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