diff options
Diffstat (limited to 'src/utility.js')
-rw-r--r-- | src/utility.js | 76 |
1 files changed, 58 insertions, 18 deletions
diff --git a/src/utility.js b/src/utility.js index b67e6c21..178c596b 100644 --- a/src/utility.js +++ b/src/utility.js @@ -68,7 +68,7 @@ function warn(a, msg) { a = false; } if (!a) { - printErr('Warning: ' + msg); + printErr('warning: ' + msg); } } @@ -81,7 +81,7 @@ function warnOnce(a, msg) { if (!warnOnce.msgs) warnOnce.msgs = {}; if (msg in warnOnce.msgs) return; warnOnce.msgs[msg] = true; - printErr('Warning: ' + msg); + printErr('warning: ' + msg); } } @@ -89,7 +89,7 @@ var abortExecution = false; function error(msg) { abortExecution = true; - printErr('Error: ' + msg); + printErr('error: ' + msg); } function dedup(items, ident) { @@ -222,7 +222,8 @@ function mergeInto(obj, other) { } function isNumber(x) { - return x == parseFloat(x) || (typeof x == 'string' && x.match(/^-?\d+$/)); + // XXX this does not handle 0xabc123 etc. We should likely also do x == parseInt(x) (which handles that), and remove hack |// handle 0x... as well| + return x == parseFloat(x) || (typeof x == 'string' && x.match(/^-?\d+$/)) || x === 'NaN'; } function isArray(x) { @@ -298,12 +299,26 @@ function setIntersect(x, y) { var ret = {}; for (xx in x) { if (xx in y) { - ret[xx] = true; + ret[xx] = 0; } } return ret; } +function setUnion(x, y) { + var ret = set(keys(x)); + for (yy in y) { + ret[yy] = 0; + } + return ret; +} + +function setSize(x) { + var ret = 0; + for (var xx in x) ret++; + return ret; +} + function invertArray(x) { var ret = {}; for (var i = 0; i < x.length; i++) { @@ -320,13 +335,30 @@ function jsonCompare(x, y) { return JSON.stringify(x) == JSON.stringify(y); } +function sortedJsonCompare(x, y) { + if (x === null || typeof x !== 'object') return x === y; + for (var i in x) { + if (!sortedJsonCompare(x[i], y[i])) return false; + } + for (var i in y) { + if (!sortedJsonCompare(x[i], y[i])) return false; + } + return true; +} + +function escapeJSONKey(x) { + if (/^[\d\w_]+$/.exec(x) || x[0] === '"' || x[0] === "'") return x; + assert(x.indexOf("'") < 0, 'cannot have internal single quotes in keys: ' + x); + return "'" + x + "'"; +} + function stringifyWithFunctions(obj) { if (typeof obj === 'function') return obj.toString(); if (obj === null || typeof obj !== 'object') return JSON.stringify(obj); if (isArray(obj)) { return '[' + obj.map(stringifyWithFunctions).join(',') + ']'; } else { - return '{' + keys(obj).map(function(key) { return key + ':' + stringifyWithFunctions(obj[key]) }).join(',') + '}'; + return '{' + keys(obj).map(function(key) { return escapeJSONKey(key) + ':' + stringifyWithFunctions(obj[key]) }).join(',') + '}'; } } @@ -350,22 +382,30 @@ function ceilPowerOfTwo(x) { } function Benchmarker() { - var starts = {}, times = {}, counts = {}; + var totals = {}; + var ids = [], lastTime = 0; this.start = function(id) { - //printErr(['+', id, starts[id]]); - starts[id] = (starts[id] || []).concat([Date.now()]); + var now = Date.now(); + if (ids.length > 0) { + totals[ids[ids.length-1]] += now - lastTime; + } + lastTime = now; + ids.push(id); + totals[id] = totals[id] || 0; }; this.stop = function(id) { - //printErr(['-', id, starts[id]]); - assert(starts[id], new Error().stack); - times[id] = (times[id] || 0) + Date.now() - starts[id].pop(); - counts[id] = (counts[id] || 0) + 1; - this.print(); + var now = Date.now(); + assert(id === ids[ids.length-1]); + totals[id] += now - lastTime; + lastTime = now; + ids.pop(); }; - this.print = function() { - var ids = keys(times); - ids.sort(function(a, b) { return times[b] - times[a] }); - printErr('times: \n' + ids.map(function(id) { return id + ' : ' + counts[id] + ' times, ' + times[id] + ' ms' }).join('\n')); + this.print = function(text) { + var ids = keys(totals); + if (ids.length > 0) { + ids.sort(function(a, b) { return totals[b] - totals[a] }); + printErr(text + ' times: \n' + ids.map(function(id) { return id + ' : ' + totals[id] + ' ms' }).join('\n')); + } }; }; |