diff options
-rw-r--r-- | api/dwb-js.7 | 39 | ||||
-rw-r--r-- | api/jsapi.7.txt | 23 | ||||
-rw-r--r-- | api/jsapi.txt | 54 | ||||
-rw-r--r-- | scripts/lib/dwb.js | 24 | ||||
-rw-r--r-- | scripts/lib/io.js | 8 | ||||
-rw-r--r-- | src/js.c | 15 | ||||
-rw-r--r-- | src/js.h | 1 | ||||
-rw-r--r-- | src/scripts.c | 29 |
8 files changed, 146 insertions, 47 deletions
diff --git a/api/dwb-js.7 b/api/dwb-js.7 index 1f5e1889..bebd106f 100644 --- a/api/dwb-js.7 +++ b/api/dwb-js.7 @@ -1078,6 +1078,30 @@ The object to search for The index in the array or \-1 if the Object wasn\(cqt found\&. .RE .RE +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.ps +1 +\fBvoid Function.debug([Object scope])\fR +.RS 4 +.sp +A wrapper method for debugging callbacks, espacially useful if it is combined with script\&. +.PP +\fIscope\fR +.RS 4 + +\fBscript\fR +or +\fBthis\fR, optional +.RE +.PP +\fIreturns\fR +.RS 4 +A new function that calls script\&.debug on errors\&. +.RE +.RE .SS "clipboard" .sp .it 1 an-trap @@ -3509,16 +3533,11 @@ foo(); // fails .\} .sp For sharing data between scripts either signals or modules can be created\&. -.SS "self and this" +.SS "script and this" .sp -In every script the variable \fBself\fR refers to \fBthis\fR, the encapsulating function\&. The encapsulating function itself has the following properties and methods: -.PP -\fIthis\&.path (Object, read)\fR -.RS 4 -The path of the script\&. -.RE +In every script the variable \fBscript\fR refers to \fBthis\fR, the encapsulating function, it has the following properties and methods: .PP -\fIself\&.path (Object, read)\fR +\fIscript\&.path (Object, read)\fR .RS 4 The path of the script\&. .RE @@ -3528,10 +3547,10 @@ The path of the script\&. .nr an-break-flag 1 .br .ps +1 -\fBvoid this.debug(Object params)\fR +\fBvoid script.debug(Object params)\fR .RS 4 .sp -Same as io\&.debug but also prints additional information, e\&.g\&. if the object is an Error, this function will also print the corresponding source of the error\&. +Same as io\&.debug but also prints additional information, e\&.g\&. if the object is an Error, this method will also print the corresponding source of the error\&. .RE .SH "MODULES" .sp diff --git a/api/jsapi.7.txt b/api/jsapi.7.txt index fa4076cb..bc18c7aa 100644 --- a/api/jsapi.7.txt +++ b/api/jsapi.7.txt @@ -496,6 +496,16 @@ _object_;; The object to search for _returns_;; The index in the array or -1 if the Object wasn't found. **** +==== void Function.debug([Object scope]) +**** + +A wrapper method for debugging callbacks, espacially useful if it is combined +with script. + +_scope_;; *script* or *this*, optional +_returns_;; A new function that calls script.debug on errors. +**** + === clipboard === ==== void clipboard.get(Selection selection, [Function callback]) @@ -1776,19 +1786,18 @@ foo(); // fails For sharing data between scripts either signals or modules can be created. -=== self and this -In every script the variable *self* refers to *this*, the encapsulating -function. The encapsulating function itself has the following properties and methods: +=== script and this +In every script the variable *script* refers to *this*, the encapsulating +function, it has the following properties and methods: -_this.path (Object, read)_;; The path of the script. -_self.path (Object, read)_;; The path of the script. +_script.path (Object, read)_;; The path of the script. -==== void this.debug(Object params) +==== void script.debug(Object params) **** Same as io.debug but also prints additional information, e.g. if the object is -an Error, this function will also print the corresponding source of the error. +an Error, this method will also print the corresponding source of the error. **** == Modules == diff --git a/api/jsapi.txt b/api/jsapi.txt index 76f461b1..a59a9583 100644 --- a/api/jsapi.txt +++ b/api/jsapi.txt @@ -928,6 +928,43 @@ _object_;; The object to search for _returns_;; The index in the array or +-1+ if the Object wasn't found. **** +**** +[[fastLastIndexOf]] +[float] +==== *Function.debug()* ==== +[source,javascript] +---- +void Function.debug([Object scope]) +---- + +A wrapper method for debugging callbacks, espacially useful if it is combined +with <<scriptandthis,script>>. + + :: + +_scope_;; *script* or *this*, optional +_returns_;; A new function that calls script.debug on errors. +**** + +**** +.Example +[source,javascript] +---- +bind("x", function() { ... }.debug(script)); + +// is a shorthand for + +bind("x", function () { + try { + ... + } + catch (e) { + script.debug(e); + } +}); +---- +**** + [[clipboard]] === clipboard === @@ -3117,9 +3154,10 @@ foo(); // fails For sharing data between scripts either signals or modules can be created. -=== self and this === -In every script the variable *self* refers to *this*, the encapsulating -function. The encapsulating function itself has the following properties and methods: +[[scriptandthis]] +=== script and this === +In every script the variable *script* refers to *this*, the encapsulating +function, it has the following properties and methods: **** @@ -3128,8 +3166,7 @@ function. The encapsulating function itself has the following properties and met [source,javascript] ---- -this.path string read -self.path string read +script.path string read ---- The path of the script. @@ -3142,12 +3179,11 @@ The path of the script. [source,javascript] ---- -void this.debug(Object params) -void self.debug(Object params) +void script.debug(Object params) ---- Same as io.debug but also prints additional information, e.g. if the object is -an Error, this function will also print the corresponding source of the error. +an Error, this method will also print the corresponding source of the error. **** .Example @@ -3164,7 +3200,7 @@ try } catch(e) { - self.debug(e); + script.debug(e); } ------- diff --git a/scripts/lib/dwb.js b/scripts/lib/dwb.js index 584b04dd..ba5f2754 100644 --- a/scripts/lib/dwb.js +++ b/scripts/lib/dwb.js @@ -213,5 +213,29 @@ return callback(value); } }); + if (!Function.prototype.debug) + { + Object.defineProperty(Function.prototype, "debug", { + value : function(scope) + { + var callee; + var self = this; + if (scope && scope.arguments && scope.arguments.callee) + callee = String(scope.arguments.callee); + return function() { + try + { + self.apply(self, arguments); + } + catch (e) + { + if (callee) + e.callee = callee; + io.debug(e); + } + }; + } + }); + } })(); Object.preventExtensions(this); diff --git a/scripts/lib/io.js b/scripts/lib/io.js index e6f1c4de..77878198 100644 --- a/scripts/lib/io.js +++ b/scripts/lib/io.js @@ -10,7 +10,7 @@ var regHasDwb = new RegExp("[^]*/\\*<dwb\\*/([^]*)/\\*dwb>\\*/[^]*"); var formatLine = function(line, max) { - var size = max - Math.max(1, Math.ceil(Math.log(line+1)/Math.log(10))) + 1; + var size = max - Math.ceil(Math.log(line+1)/Math.log(10)) + 1; return Array(size).join(" ") + line + " > "; }; @@ -82,9 +82,9 @@ outMessage += prefixStack + stack; } - if (this.arguments && line >= 0) + if ((params.callee || this.arguments) && line >= 0) { - caller = String(this.arguments.callee).replace(regHasDwb, "$1", ""); + caller = (params.callee || String(this.arguments.callee)).replace(regHasDwb, "$1", ""); source = caller.split("\n"); var length = source.length; var max = Math.ceil(Math.log(source.length+1)/Math.log(10)); @@ -105,6 +105,8 @@ outMessage += formatLine(line+1, max) + source[line-1]; if (length > line + 1) outMessage += "\n..."; + else + outMessage += "\nEOF"; } else outMessage += "EOF"; @@ -341,3 +341,18 @@ js_value_to_function(JSContextRef ctx, JSValueRef val, JSValueRef *exc) return NULL; } +gboolean +js_check_syntax(JSContextRef ctx, const char *script, const char *filename, int lineOffset) +{ + JSValueRef exc = NULL; + JSStringRef jsscript = JSStringCreateWithUTF8CString(script); + gboolean correct = JSCheckScriptSyntax(ctx, jsscript, NULL, lineOffset, &exc); + if (!correct) + { + fprintf(stderr, "DWB SCRIPT EXCEPTION: in file %s\n", filename); + js_print_exception(ctx, exc); + } + JSStringRelease(jsscript); + return correct; +} + @@ -39,6 +39,7 @@ JSObjectRef js_make_function(JSContextRef ctx, const char *script); JSValueRef js_json_to_value(JSContextRef ctx, const char *text); JSValueRef js_context_change(JSContextRef, JSContextRef, JSValueRef, JSValueRef *); JSObjectRef js_value_to_function(JSContextRef, JSValueRef, JSValueRef *); +gboolean js_check_syntax(JSContextRef ctx, const char *script, const char *filename, int lineOffset); typedef struct js_array_iterator_s { JSContextRef ctx; diff --git a/src/scripts.c b/src/scripts.c index 6797f6c1..2cb547d1 100644 --- a/src/scripts.c +++ b/src/scripts.c @@ -3406,14 +3406,17 @@ scripts_init_script(const char *path, const char *script) if (s_global_context == NULL) create_global_object(); - debug = g_strdup_printf("\n" - "try{const self=this;" - "Object.defineProperties(this,{'path':{value:'%s'},'debug':{value:io.debug.bind(this)}});Object.freeze(this);" - "/*<dwb*/%s/*dwb>*/}catch(e){this.debug({error:e});};", path, script); - JSObjectRef function = js_make_function(s_global_context, debug); + if (js_check_syntax(s_global_context, script, path, 1)) + { + debug = g_strdup_printf("\n" + "try{const script=this;" + "Object.defineProperties(this,{'path':{value:'%s'},'debug':{value:io.debug.bind(this)}});Object.freeze(this);" + "/*<dwb*/%s/*dwb>*/}catch(e){this.debug({error:e});};", path, script); + JSObjectRef function = js_make_function(s_global_context, debug); - if (function != NULL) - s_script_list = g_slist_prepend(s_script_list, function); + if (function != NULL) + s_script_list = g_slist_prepend(s_script_list, function); + } g_free(debug); }/*}}}*/ @@ -3534,20 +3537,10 @@ scripts_check_syntax(char **scripts) const char *tmp = content; if (g_str_has_prefix(tmp, "#!javascript")) tmp += 12; - - JSValueRef exc = NULL; - JSStringRef script = JSStringCreateWithUTF8CString(tmp); - - if (!JSCheckScriptSyntax(s_global_context, script, NULL, 0, &exc)) - { - fprintf(stderr, "DWB SCRIPT EXCEPTION: in file %s\n", scripts[i]); - js_print_exception(s_global_context, exc); - } - else + if (js_check_syntax(s_global_context, tmp, scripts[i], 0)) { fprintf(stderr, "Syntax of %s is correct.\n", scripts[i]); } - JSStringRelease(script); g_free(content); } } |