diff --git a/app.js b/app.js index e8c9c01..57f88eb 100644 --- a/app.js +++ b/app.js @@ -120,6 +120,14 @@ var console = { debug: function() { this._echo(arguments, "debug"); }, + trace: function() { + try { + var callee = arguments.callee.caller.caller; + throw new TraceError("DEBUG", "", callee); + } catch (e) { + this.debug(e.message); + } + }, time: function(label) { label = label || "default"; if (!(label in this._timers)) { @@ -154,6 +162,118 @@ var console = { } }; +function TraceError(severity, message, callee) { + var MAX_DEPTH = 20; + + var SEVERITY_MAP = { + "": "ERROR", + "LOG": "INFO", + "INFO": "INFO", + "WARN": "WARN", + "WARNING": "WARN", + "ERROR": "ERROR", + "ERR": "ERROR", + "CRITICAL": "ERROR", + "FATAL": "ERROR", + "DEBUG": "DEBUG" + }; + + var CONSOLE_METHOD_MAP = { + "ERROR": "error", + "WARN": "warn", + "INFO": "info", + "DEBUG": "debug" + }; + + function fnName(fn) { + return fn ? (fn.__name__ || fn.name || "(anonymous)") : "(null)"; + } + + function normSeverity(s) { + s = (s == null) ? "" : String(s); + s = s.toUpperCase(); + return SEVERITY_MAP[s] || (s || "ERROR"); + } + + function callersOf(startFn) { + var out = []; + var f = startFn; + var i = 0; + + while (f && i < MAX_DEPTH) { + out[out.length] = fnName(f); + try { + f = f.caller; + } catch (e) { + break; + } + i++; + } + return out; + } + + function pickConsoleFn(sev) { + if (typeof console === "undefined" || !console) + return null; + + var methodName = CONSOLE_METHOD_MAP[sev] || "log"; + var fn = console[methodName] || console.log; + + if (!fn) + return null; + + return (function (fns) { + var i; + + return function (s) { + for (i = 0; i < fns.length; i++) { + try { + fns[i](s); + return; + } catch (e) { + // try next + } + } + }; + })([ + function (s) { fn.call(console, s); }, // 1) severity-specific console + function (s) { console.log(s); }, // 2) generic console.log + function (s) { WScript.Echo(s); } // 3) WSH fallback + ]); + } + + function buildMessage(name, sev, msg, chain) { + var s = name + " [" + sev + "]"; + if (msg) s += ": " + msg; + if (chain) s += "\r\n" + chain; + return s; + } + + this.name = "TraceException"; + this.severity = normSeverity(severity); + this.message = message || ""; + this.description = this.message; // IE friendly + this.callee = callee || null; + + this.callers = callersOf(this.callee); + this.callChain = this.callers.length ? this.callers.join("\r\n <- ") : ""; + + this.fullMessage = buildMessage(this.name, this.severity, this.message, this.callChain); + this.toString = function () { + return this.fullMessage; + }; + + this._logFn = pickConsoleFn(this.severity); + + this.log = function () { + if (this._logFn) + this._logFn(this.fullMessage); + }; + + this.log(); +} +TraceError.prototype = new Error; + if (typeof CreateObject === "undefined") { var CreateObject = function(progId, serverName, callback) { var progIds = (progId instanceof Array ? progId : [progId]); @@ -225,6 +345,47 @@ function __evalFile__(FN) { } } +/** + * @f {Function} a function object + * @name {string} a name of the exported function + */ +function __export__(f, name) { + if (typeof f !== "function") + return f; + + name = (name == null) ? "" : String(name); + + if (!name) + name = "(exported)"; + + try { + f.__name__ = name; + } catch (e) {} + + try { + f.name = name; + } catch (e) {} + + var wrapped = function () { + try { + return f.apply(this, arguments); + } catch (e) { + if (typeof TraceError === "function") { + throw new TraceError( + "ERROR", + (e && (e.message || e.description)) ? (e.message || e.description) : "error", + arguments.callee + ); + } + } + }; + + wrapped.__name__ = name; + wrapped.__target__ = f; + + return wrapped; +} + /** * @FN {string} The name of the file. */ diff --git a/bootstrap.js b/bootstrap.js index 2df570e..0e7d919 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -12,7 +12,9 @@ var SHELL = require("lib/shell"); var appName = "welsonjs"; var isDisabledRegisterURIScheme = false; -exports.main = function(args) { +function main(args) { + //console.trace(); + // unlock file console.log("Starting unlock files..."); PS.execCommand("dir | Unblock-File"); @@ -67,3 +69,6 @@ exports.main = function(args) { // print welcome console.log("welcome"); }; + +//exports.main = __export__(main, "main"); +exports.main = main;