summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Bolte <sbolte@lavabit.com>2013-05-17 00:46:50 +0200
committerStefan Bolte <sbolte@lavabit.com>2013-05-17 00:46:50 +0200
commite93251b85f935d1b9b1ebe25383f0183c0c50c07 (patch)
tree845368d4eed62dd02ec6d6f5c48adc45bb87507c
parenta4862d0ab27539ab8a141f4a6a2bc4b8a3e6098c (diff)
downloaddwb-e93251b85f935d1b9b1ebe25383f0183c0c50c07.zip
Implementing xinclude
-rw-r--r--exar/Makefile6
-rw-r--r--exar/exar.c14
-rw-r--r--src/scripts.c110
3 files changed, 88 insertions, 42 deletions
diff --git a/exar/Makefile b/exar/Makefile
index 554f8c06..93f34733 100644
--- a/exar/Makefile
+++ b/exar/Makefile
@@ -2,12 +2,8 @@ CFLAGS += -Wall -pedantic -Werror -std=c99 -g
TARGET=exar
OBJ=$(patsubst %.c, %.o, $(wildcard *.c))
-LIBEXAR=libexar.a
-all: $(TARGET) $(LIBEXAR)
-
-$(LIBEXAR): exar.o
- @$(AR) rcs $@ $<
+all: $(TARGET)
$(TARGET): $(OBJ)
@echo $(CC) $@
diff --git a/exar/exar.c b/exar/exar.c
index 2b600658..074e6b6d 100644
--- a/exar/exar.c
+++ b/exar/exar.c
@@ -26,8 +26,8 @@
#include <assert.h>
#include "exar.h"
-#define VERSION_BASE "exar-"
-#define VERSION VERSION_BASE "1"
+#define EXAR_VERSION_BASE "exar-"
+#define EXAR_VERSION EXAR_VERSION_BASE "1"
#define EXTENSION "exar"
#define SZ_VERSION 8
@@ -56,7 +56,7 @@ static unsigned char s_version[SZ_VERSION];
static void *
xmalloc(size_t size)
{
- void *ret = malloc(size);
+ void *ret = calloc(1, size);
if (ret == NULL)
{
fprintf(stderr, "Cannot malloc %lu bytes\n", size);
@@ -99,9 +99,9 @@ check_version(FILE *f, int verbose)
fprintf(stderr, "Not an exar file?\n");
return -1;
}
- memcpy(orig_version, VERSION, sizeof(orig_version));
+ memcpy(orig_version, EXAR_VERSION, sizeof(orig_version));
LOG(2, "Checking filetype\n");
- if (strncmp((char*)s_version, VERSION_BASE, 5))
+ if (strncmp((char*)s_version, EXAR_VERSION_BASE, 5))
{
if (verbose)
fprintf(stderr, "Not an exar file?\n");
@@ -242,8 +242,8 @@ exar_pack(const char *path)
}
// set version header
- LOG(2, "Writing version header (%s)\n", VERSION);
- memcpy(version, VERSION, sizeof(version));
+ LOG(2, "Writing version header (%s)\n", EXAR_VERSION);
+ memcpy(version, EXAR_VERSION, sizeof(version));
fwrite(version, 1, sizeof(version), s_out);
ret = ftw(path, pack, MAX_FILE_HANDLES);
diff --git a/src/scripts.c b/src/scripts.c
index 85828389..a9660033 100644
--- a/src/scripts.c
+++ b/src/scripts.c
@@ -29,6 +29,7 @@
#include <JavaScriptCore/JavaScript.h>
#include <glib.h>
#include <cairo.h>
+#include <exar.h>
#include "dwb.h"
#include "scripts.h"
#include "session.h"
@@ -46,12 +47,14 @@
#define kJSDefaultProperty (kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly )
#define kJSDefaultAttributes (kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly )
-#define SCRIPT_TEMPLATE_START "try{_initNewContext(this, arguments, '%s');const script=this;/*<dwb*/"
+#define SCRIPT_TEMPLATE_START "try{_initNewContext(this,arguments,'%s');const script=this;/*<dwb*/"
+#define SCRIPT_TEMPLATE_XSTART "try{_initNewContext(this,arguments,'%s');const xinclude=_xinclude.bind(this,this.path);const script=this;/*<dwb*/"
#define SCRIPT_TEMPLATE_END "%s/*dwb>*/}catch(e){script.debug(e);};"
#define SCRIPT_TEMPLATE SCRIPT_TEMPLATE_START"//!javascript\n"SCRIPT_TEMPLATE_END
#define SCRIPT_TEMPLATE_INCLUDE SCRIPT_TEMPLATE_START SCRIPT_TEMPLATE_END
+#define SCRIPT_TEMPLATE_XINCLUDE SCRIPT_TEMPLATE_XSTART SCRIPT_TEMPLATE_END
#define SCRIPT_WEBVIEW(o) (WEBVIEW(((GList*)JSObjectGetPrivate(o))))
#define EXCEPTION(X) "DWB EXCEPTION : "X
@@ -1726,6 +1729,31 @@ settings_get(JSContextRef ctx, JSObjectRef jsobj, JSStringRef js_name, JSValueRe
}
/*}}}*/
+static JSValueRef
+do_include(JSContextRef ctx, const char *path, const char *script, gboolean global, gboolean is_archive, JSValueRef *exc)
+{
+ JSStringRef js_script;
+ JSValueRef ret = NIL;
+
+ if (global)
+ {
+ js_script = JSStringCreateWithUTF8CString(script);
+ ret = JSEvaluateScript(ctx, js_script, NULL, NULL, 0, exc);
+ }
+ else
+ {
+ char *debug = g_strdup_printf(is_archive ? SCRIPT_TEMPLATE_XINCLUDE : SCRIPT_TEMPLATE_INCLUDE, path, script);
+ js_script = JSStringCreateWithUTF8CString(debug);
+ JSObjectRef function = JSObjectMakeFunction(ctx, NULL, 0, NULL, js_script, NULL, 1, exc);
+ if (function != NULL)
+ {
+ ret = JSObjectCallAsFunction(ctx, function, function, 0, NULL, exc);
+ }
+ g_free(debug);
+ }
+ JSStringRelease(js_script);
+ return ret;
+}
/* global_include {{{*/
/**
* Includes a file.
@@ -1776,10 +1804,9 @@ settings_get(JSContextRef ctx, JSObjectRef jsobj, JSStringRef js_name, JSValueRe
* */
static JSValueRef
-global_include(JSContextRef ctx, JSObjectRef f, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exc)
+global_include(JSContextRef ctx, JSObjectRef f, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc)
{
- JSValueRef ret = NULL;
- JSStringRef script;
+ JSValueRef ret = NIL;
gboolean global = false;
char *path = NULL, *content = NULL;
@@ -1805,36 +1832,58 @@ global_include(JSContextRef ctx, JSObjectRef f, JSObjectRef thisObject, size_t a
} while(*tmp && *tmp != '\n');
tmp++;
}
-
- if (global)
- {
- script = JSStringCreateWithUTF8CString(tmp);
- ret = JSEvaluateScript(ctx, script, NULL, NULL, 0, exc);
- }
- else
- {
- char *debug = g_strdup_printf(SCRIPT_TEMPLATE_INCLUDE, path, tmp);
- script = JSStringCreateWithUTF8CString(debug);
- JSObjectRef function = JSObjectMakeFunction(ctx, NULL, 0, NULL, script, NULL, 1, exc);
- if (function != NULL)
- {
- JSObjectRef this = JSObjectMake(ctx, NULL, NULL);
- JSValueProtect(ctx, this);
- js_set_object_property(ctx, this, "path", path, exc);
- ret = JSObjectCallAsFunction(ctx, function, this, 0, NULL, exc);
- }
- g_free(debug);
- }
- JSStringRelease(script);
+ ret = do_include(ctx, path, tmp, global, false, exc);
error_out:
g_free(content);
g_free(path);
- if (ret == NULL)
- return NIL;
return ret;
}/*}}}*/
+/**
+ * Include scripts from an archive.
+ *
+ * Same as {@link include} but this function can only be called from scripts
+ * inside an archive, so this is only useful in extensions. However it is
+ * possible to include scripts from an archive calling the internal function
+ * _xinclude which takes two parameters, the path of the archive and the path of
+ * the included file in the archive.
+ * Unlike {@link inlucde} included archive-scripts cannot be included into the
+ * global scope.
+ *
+ * @name xinclude
+ * @param path {String}
+ * Path of the file in the archive
+ *
+ * @returns {Object}
+ * The object returned from the included file.
+ * */
+
+static JSValueRef
+global_xinclude(JSContextRef ctx, JSObjectRef f, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exc)
+{
+ char *archive = NULL, *path = NULL, *content = NULL;
+ JSValueRef ret = NIL;
+ size_t fs;
+
+ if (argc < 2)
+ return NIL;
+ if ((archive = js_value_to_char(ctx, argv[0], -1, exc)) == NULL)
+ goto error_out;
+ if ((path = js_value_to_char(ctx, argv[1], -1, exc)) == NULL)
+ goto error_out;
+
+ content = (char*)exar_extract(archive, path, &fs);
+ if (content != NULL)
+ do_include(ctx, archive, content, false, true, exc);
+
+error_out:
+ g_free(archive);
+ g_free(path);
+ g_free(content);
+ return ret;
+}
+
/* global_send_request {{{*/
static JSValueRef
@@ -4772,10 +4821,11 @@ create_global_object()
JSStaticFunction global_functions[] = {
{ "execute", global_execute, kJSDefaultAttributes },
- { "exit", global_exit, kJSDefaultAttributes },
- { "bind", global_bind, kJSDefaultAttributes },
- { "unbind", global_unbind, kJSDefaultAttributes },
+ { "exit", global_exit, kJSDefaultAttributes },
+ { "bind", global_bind, kJSDefaultAttributes },
+ { "unbind", global_unbind, kJSDefaultAttributes },
{ "include", global_include, kJSDefaultAttributes },
+ { "_xinclude", global_xinclude, kJSDefaultAttributes },
{ 0, 0, 0 },
};