2010-01-15 21:46:08 +01:00
|
|
|
var events = require('events');
|
|
|
|
|
2010-02-10 02:27:23 +01:00
|
|
|
exports.print = function () {
|
|
|
|
for (var i = 0, len = arguments.length; i < len; ++i) {
|
|
|
|
process.stdio.write(arguments[i]);
|
|
|
|
}
|
2009-10-13 13:26:00 +02:00
|
|
|
};
|
|
|
|
|
2010-02-10 02:27:23 +01:00
|
|
|
exports.puts = function () {
|
|
|
|
for (var i = 0, len = arguments.length; i < len; ++i) {
|
|
|
|
process.stdio.write(arguments[i] + '\n');
|
|
|
|
}
|
2009-10-13 13:26:00 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
exports.debug = function (x) {
|
2009-11-28 12:15:37 +01:00
|
|
|
process.stdio.writeError("DEBUG: " + x + "\n");
|
2009-10-13 13:26:00 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
exports.error = function (x) {
|
2010-02-10 02:27:23 +01:00
|
|
|
for (var i = 0, len = arguments.length; i < len; ++i) {
|
|
|
|
process.stdio.writeError(arguments[i] + '\n');
|
|
|
|
}
|
2009-10-13 13:26:00 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Echos the value of a value. Trys to print the value out
|
|
|
|
* in the best way possible given the different types.
|
2009-12-01 11:20:14 +01:00
|
|
|
*
|
2009-10-13 13:26:00 +02:00
|
|
|
* @param {Object} value The object to print out
|
2010-02-09 17:50:05 +01:00
|
|
|
* @param {Boolean} showHidden Flag that shows hidden (not enumerable) properties of objects.
|
2009-10-13 13:26:00 +02:00
|
|
|
*/
|
2010-02-25 22:12:39 +01:00
|
|
|
exports.inspect = function (obj, showHidden, depth) {
|
2010-02-09 17:50:05 +01:00
|
|
|
var seen = [];
|
2010-02-25 22:12:39 +01:00
|
|
|
function format(value, recurseTimes) {
|
2010-02-09 17:50:05 +01:00
|
|
|
// Primitive types cannot have properties
|
|
|
|
switch (typeof value) {
|
|
|
|
case 'undefined': return 'undefined';
|
2010-02-26 02:41:02 +01:00
|
|
|
case 'string': return JSON.stringify(value).replace(/'/g, "\\'").replace(/\\"/g, '"').replace(/(^"|"$)/g, "'");
|
2010-02-09 17:50:05 +01:00
|
|
|
case 'number': return '' + value;
|
|
|
|
case 'boolean': return '' + value;
|
|
|
|
}
|
|
|
|
// For some reason typeof null is "object", so special case here.
|
|
|
|
if (value === null) {
|
|
|
|
return 'null';
|
|
|
|
}
|
|
|
|
|
|
|
|
// Look up the keys of the object.
|
2010-02-25 22:12:39 +01:00
|
|
|
if (showHidden) {
|
|
|
|
var keys = Object.getOwnPropertyNames(value).map(function (key) { return '' + key; });
|
|
|
|
} else {
|
|
|
|
var keys = Object.keys(value);
|
|
|
|
}
|
|
|
|
|
2010-02-09 18:15:02 +01:00
|
|
|
var visible_keys = Object.keys(value);
|
2010-02-09 17:50:05 +01:00
|
|
|
|
|
|
|
// Functions without properties can be shortcutted.
|
|
|
|
if (typeof value === 'function' && keys.length === 0) {
|
|
|
|
if (value instanceof RegExp) {
|
|
|
|
return '' + value;
|
|
|
|
} else {
|
|
|
|
return '[Function]';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-14 13:11:59 +01:00
|
|
|
// Dates without properties can be shortcutted
|
|
|
|
if (value instanceof Date && keys.length === 0) {
|
|
|
|
return value.toUTCString();
|
|
|
|
}
|
|
|
|
|
2010-02-09 18:15:02 +01:00
|
|
|
var base, type, braces;
|
2010-02-09 17:50:05 +01:00
|
|
|
// Determine the object type
|
|
|
|
if (value instanceof Array) {
|
|
|
|
type = 'Array';
|
|
|
|
braces = ["[", "]"];
|
|
|
|
} else {
|
|
|
|
type = 'Object';
|
|
|
|
braces = ["{", "}"];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make functions say that they are functions
|
|
|
|
if (typeof value === 'function') {
|
|
|
|
base = (value instanceof RegExp) ? ' ' + value : ' [Function]';
|
|
|
|
} else {
|
|
|
|
base = "";
|
|
|
|
}
|
2010-02-14 13:11:59 +01:00
|
|
|
|
|
|
|
// Make dates with properties first say the date
|
|
|
|
if (value instanceof Date) {
|
|
|
|
base = ' ' + value.toUTCString();
|
|
|
|
}
|
2010-02-09 17:50:05 +01:00
|
|
|
|
|
|
|
seen.push(value);
|
|
|
|
|
|
|
|
if (keys.length === 0) {
|
|
|
|
return braces[0] + base + braces[1];
|
|
|
|
}
|
|
|
|
|
2010-02-27 09:32:55 +01:00
|
|
|
if (recurseTimes < 0) {
|
2010-02-26 02:41:02 +01:00
|
|
|
if (value instanceof RegExp) {
|
|
|
|
return '' + value;
|
|
|
|
} else {
|
2010-02-27 09:32:55 +01:00
|
|
|
return "[Object]";
|
2010-02-26 02:41:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
output = keys.map(function (key) {
|
2010-02-09 17:50:05 +01:00
|
|
|
var name, str;
|
|
|
|
if (value.__lookupGetter__) {
|
|
|
|
if (value.__lookupGetter__(key)) {
|
|
|
|
if (value.__lookupSetter__(key)) {
|
|
|
|
str = "[Getter/Setter]";
|
|
|
|
} else {
|
|
|
|
str = "[Getter]";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (value.__lookupSetter__(key)) {
|
|
|
|
str = "[Setter]";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (visible_keys.indexOf(key) < 0) {
|
|
|
|
name = "[" + key + "]";
|
|
|
|
}
|
|
|
|
if (!str) {
|
|
|
|
if (seen.indexOf(value[key]) < 0) {
|
2010-02-26 02:41:02 +01:00
|
|
|
if ( recurseTimes === null) {
|
2010-02-25 22:12:39 +01:00
|
|
|
str = format(value[key]);
|
|
|
|
}
|
2010-02-26 02:41:02 +01:00
|
|
|
else {
|
2010-02-25 22:12:39 +01:00
|
|
|
str = format(value[key], recurseTimes - 1);
|
|
|
|
}
|
2010-02-27 09:32:55 +01:00
|
|
|
if (str.indexOf('\n') > -1) {
|
|
|
|
if (value instanceof Array) {
|
|
|
|
str = str.split('\n').map(function(line) {
|
|
|
|
return ' ' + line;
|
|
|
|
}).join('\n').substr(2);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
str = '\n' + str.split('\n').map(function(line) {
|
2010-02-26 02:41:02 +01:00
|
|
|
return ' ' + line;
|
|
|
|
}).join('\n');
|
2010-02-27 09:32:55 +01:00
|
|
|
}
|
2010-02-25 22:12:39 +01:00
|
|
|
}
|
2010-02-09 17:50:05 +01:00
|
|
|
} else {
|
|
|
|
str = '[Circular]';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (typeof name === 'undefined') {
|
|
|
|
if (type === 'Array' && key.match(/^\d+$/)) {
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
name = JSON.stringify('' + key);
|
2010-02-27 09:32:55 +01:00
|
|
|
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
|
2010-02-26 02:41:02 +01:00
|
|
|
name = name.substr(1, name.length-2);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
name = name.replace(/'/g, "\\'").replace(/\\"/g, '"').replace(/(^"|"$)/g, "'");
|
|
|
|
}
|
2010-02-09 17:50:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return name + ": " + str;
|
2010-02-26 02:41:02 +01:00
|
|
|
});
|
|
|
|
|
2010-02-27 09:32:55 +01:00
|
|
|
var numLinesEst = 0;
|
2010-02-26 02:41:02 +01:00
|
|
|
var length = output.reduce(function(prev, cur) {
|
2010-02-27 09:32:55 +01:00
|
|
|
numLinesEst++;
|
|
|
|
if( cur.indexOf('\n') >= 0 ) {
|
|
|
|
numLinesEst++;
|
|
|
|
}
|
2010-02-26 02:41:02 +01:00
|
|
|
return prev + cur.length + 1;
|
|
|
|
},0);
|
|
|
|
|
2010-02-27 09:32:55 +01:00
|
|
|
if (length > 50) {
|
|
|
|
output = braces[0] + (base === '' ? '' : base + '\n,') + ' ' + output.join('\n, ') + (numLinesEst > 1 ? '\n' : ' ') + braces[1];
|
2010-02-26 02:41:02 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
return output;
|
2010-02-09 17:50:05 +01:00
|
|
|
}
|
2010-02-26 02:41:02 +01:00
|
|
|
return format(obj, (typeof depth === 'undefined' ? 2 : depth));
|
2009-10-13 13:26:00 +02:00
|
|
|
};
|
|
|
|
|
2010-02-10 02:27:23 +01:00
|
|
|
exports.p = function () {
|
|
|
|
for (var i = 0, len = arguments.length; i < len; ++i) {
|
|
|
|
exports.error(exports.inspect(arguments[i]));
|
|
|
|
}
|
2009-10-13 13:26:00 +02:00
|
|
|
};
|
|
|
|
|
2010-02-20 01:55:46 +01:00
|
|
|
exports.exec = function (command, callback) {
|
2009-10-29 23:34:10 +01:00
|
|
|
var child = process.createChildProcess("/bin/sh", ["-c", command]);
|
2009-10-13 13:26:00 +02:00
|
|
|
var stdout = "";
|
|
|
|
var stderr = "";
|
|
|
|
|
|
|
|
child.addListener("output", function (chunk) {
|
2009-12-01 11:20:14 +01:00
|
|
|
if (chunk) stdout += chunk;
|
2009-10-13 13:26:00 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
child.addListener("error", function (chunk) {
|
2009-12-01 11:20:14 +01:00
|
|
|
if (chunk) stderr += chunk;
|
2009-10-13 13:26:00 +02:00
|
|
|
});
|
2009-12-01 11:20:14 +01:00
|
|
|
|
2009-10-13 13:26:00 +02:00
|
|
|
child.addListener("exit", function (code) {
|
|
|
|
if (code == 0) {
|
2010-02-20 01:55:46 +01:00
|
|
|
if (callback) callback(null, stdout, stderr);
|
2009-10-13 13:26:00 +02:00
|
|
|
} else {
|
2010-02-20 01:55:46 +01:00
|
|
|
var e = new Error("Command failed: " + stderr);
|
|
|
|
e.code = code;
|
|
|
|
if (callback) callback(e, stdout, stderr);
|
2009-10-13 13:26:00 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
2009-11-07 14:45:39 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Inherit the prototype methods from one constructor into another.
|
|
|
|
*
|
|
|
|
* The Function.prototype.inherits from lang.js rewritten as a standalone
|
|
|
|
* function (not on Function.prototype). NOTE: If this file is to be loaded
|
|
|
|
* during bootstrapping this function needs to be revritten using some native
|
|
|
|
* functions as prototype setup using normal JavaScript does not work as
|
|
|
|
* expected during bootstrapping (see mirror.js in r114903).
|
|
|
|
*
|
|
|
|
* @param {function} ctor Constructor function which needs to inherit the
|
|
|
|
* prototype
|
|
|
|
* @param {function} superCtor Constructor function to inherit prototype from
|
|
|
|
*/
|
2010-03-01 20:39:35 +01:00
|
|
|
exports.inherits = function (ctor, superCtor) {
|
|
|
|
var tempCtor = function(){};
|
|
|
|
tempCtor.prototype = superCtor.prototype;
|
|
|
|
ctor.super_ = superCtor;
|
|
|
|
ctor.prototype = new tempCtor();
|
|
|
|
ctor.prototype.constructor = ctor;
|
|
|
|
};
|
|
|
|
|
2009-12-01 11:20:14 +01:00
|
|
|
|