var events = require('events'); exports.print = function () { for (var i = 0, len = arguments.length; i < len; ++i) { process.stdout.write(String(arguments[i])); } }; exports.puts = function () { for (var i = 0, len = arguments.length; i < len; ++i) { process.stdout.write(arguments[i] + '\n'); } }; exports.debug = function (x) { process.binding('stdio').writeError("DEBUG: " + x + "\n"); }; var error = exports.error = function (x) { for (var i = 0, len = arguments.length; i < len; ++i) { process.binding('stdio').writeError(arguments[i] + '\n'); } }; /** * Echos the value of a value. Trys to print the value out * in the best way possible given the different types. * * @param {Object} value The object to print out * @param {Boolean} showHidden Flag that shows hidden (not enumerable) * properties of objects. * @param {Number} depth Depth in which to descend in object. Default is 2. * @param {Boolean} colors Flag to turn on ANSI escape codes to color the * output. Default is false (no coloring). */ exports.inspect = function (obj, showHidden, depth, colors) { var seen = []; var stylize = function (str, styleType) { // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics var styles = { 'bold' : [1, 22] , 'italic' : [3, 23] , 'underline' : [4, 24] , 'inverse' : [7, 27] , 'white' : [37, 39] , 'grey' : [90, 39] , 'black' : [30, 39] , 'blue' : [34, 39] , 'cyan' : [36, 39] , 'green' : [32, 39] , 'magenta' : [35, 39] , 'red' : [31, 39] , 'yellow' : [33, 39] }; var style = { "special": "grey" , "number": "blue" , "boolean": "blue" , "undefined": "red" , "null": "red" , "string": "green" , "date": "magenta" //, "name": intentionally not styling , "regexp": "cyan" }[styleType]; if (style) { return '\033[' + styles[style][0] + 'm' + str + '\033[' + styles[style][1] + 'm'; } else { return str; } }; if (! colors) { stylize = function(str, styleType) { return str; }; } function format(value, recurseTimes) { // Provide a hook for user-specified inspect functions. // Check that value is an object with an inspect function on it if (value && typeof value.inspect === 'function' && // Filter out the sys module, it's inspect function is special value !== exports && // Also filter out any prototype objects using the circular check. !(value.constructor && value.constructor.prototype === value)) { return value.inspect(recurseTimes); } // Primitive types cannot have properties switch (typeof value) { case 'undefined': return stylize('undefined', 'undefined'); case 'string': return stylize( JSON.stringify(value).replace(/'/g, "\\'") .replace(/\\"/g, '"') .replace(/(^"|"$)/g, "'"), 'string'); case 'number': return stylize('' + value, 'number'); case 'boolean': return stylize('' + value, 'boolean'); } // For some reason typeof null is "object", so special case here. if (value === null) { return stylize('null', 'null'); } // Look up the keys of the object. var visible_keys = Object.keys(value); var keys = showHidden ? Object.getOwnPropertyNames(value) : visible_keys; // Functions without properties can be shortcutted. if (typeof value === 'function' && keys.length === 0) { if (isRegExp(value)) { return stylize('' + value, 'regexp'); } else { return stylize('[Function'+ (value.name ? ': '+ value.name : '')+ ']', 'special'); } } // Dates without properties can be shortcutted if (isDate(value) && keys.length === 0) { return stylize(value.toUTCString(), 'date'); } var base, type, braces; // Determine the object type if (isArray(value)) { type = 'Array'; braces = ["[", "]"]; } else { type = 'Object'; braces = ["{", "}"]; } // Make functions say that they are functions if (typeof value === 'function') { base = (isRegExp(value)) ? ' ' + value : ' [Function'+ (value.name ? ': '+ value.name : '')+ ']'; } else { base = ""; } // Make dates with properties first say the date if (isDate(value)) { base = ' ' + value.toUTCString(); } seen.push(value); if (keys.length === 0) { return braces[0] + base + braces[1]; } if (recurseTimes < 0) { if (isRegExp(value)) { return stylize('' + value, "regexp"); } else { return stylize("[Object]", "special"); } } var output = keys.map(function (key) { var name, str; if (value.__lookupGetter__) { if (value.__lookupGetter__(key)) { if (value.__lookupSetter__(key)) { str = stylize("[Getter/Setter]", "special"); } else { str = stylize("[Getter]", "special"); } } else { if (value.__lookupSetter__(key)) { str = stylize("[Setter]", "special"); } } } if (visible_keys.indexOf(key) < 0) { name = "[" + key + "]"; } if (!str) { if (seen.indexOf(value[key]) < 0) { if ( recurseTimes === null) { str = format(value[key]); } else { str = format(value[key], recurseTimes - 1); } if (str.indexOf('\n') > -1) { if (isArray(value)) { str = str.split('\n').map(function(line) { return ' ' + line; }).join('\n').substr(2); } else { str = '\n' + str.split('\n').map(function(line) { return ' ' + line; }).join('\n'); } } } else { str = stylize('[Circular]', 'special'); } } if (typeof name === 'undefined') { if (type === 'Array' && key.match(/^\d+$/)) { return str; } name = JSON.stringify('' + key); if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { name = name.substr(1, name.length-2); name = stylize(name, "name"); } else { name = name.replace(/'/g, "\\'") .replace(/\\"/g, '"') .replace(/(^"|"$)/g, "'"); name = stylize(name, "string"); } } return name + ": " + str; }); var numLinesEst = 0; var length = output.reduce(function(prev, cur) { numLinesEst++; if( cur.indexOf('\n') >= 0 ) { numLinesEst++; } return prev + cur.length + 1; },0); if (length > (require('readline').columns || 50)) { output = braces[0] + (base === '' ? '' : base + '\n ') + ' ' + output.join(',\n ') + ' ' + braces[1] ; } else { output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; } return output; } return format(obj, (typeof depth === 'undefined' ? 2 : depth)); }; function isArray (ar) { return ar instanceof Array || Array.isArray(ar) || (ar && ar !== Object.prototype && isArray(ar.__proto__)); } function isRegExp (re) { var s = ""+re; return re instanceof RegExp // easy case || typeof(re) === "function" // duck-type for context-switching evalcx case && re.constructor.name === "RegExp" && re.compile && re.test && re.exec && s.match(/^\/.*\/[gim]{0,3}$/); } function isDate (d) { if (d instanceof Date) return true; if (typeof d !== "object") return false; var properties = Date.prototype && Object.getOwnPropertyNames(Date.prototype); var proto = d.__proto__ && Object.getOwnPropertyNames(d.__proto__); return JSON.stringify(proto) === JSON.stringify(properties); } var pWarning; exports.p = function () { if (!pWarning) { pWarning = "sys.p will be removed in future versions of Node. Use sys.puts(sys.inspect()) instead.\n"; exports.error(pWarning); } for (var i = 0, len = arguments.length; i < len; ++i) { error(exports.inspect(arguments[i])); } }; function pad (n) { return n < 10 ? '0' + n.toString(10) : n.toString(10); } var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; // 26 Feb 16:19:34 function timestamp () { var d = new Date(); return [ d.getDate() , months[d.getMonth()] , [pad(d.getHours()), pad(d.getMinutes()), pad(d.getSeconds())].join(':') ].join(' '); } exports.log = function (msg) { exports.puts(timestamp() + ' - ' + msg.toString()); }; var execWarning; exports.exec = function () { if (!execWarning) { execWarning = 'sys.exec has moved to the "child_process" module. Please update your source code.'; error(execWarning); } return require('child_process').exec.apply(this, arguments); }; exports.pump = function (readStream, writeStream, callback) { var callbackCalled = false; function call (a, b, c) { if (callback && !callbackCalled) { callback(a, b, c); callbackCalled = true; } } if (!readStream.pause) readStream.pause = function () {readStream.emit("pause");}; if (!readStream.resume) readStream.resume = function () {readStream.emit("resume");}; readStream.addListener("data", function (chunk) { if (writeStream.write(chunk) === false) readStream.pause(); }); writeStream.addListener("pause", function () { readStream.pause(); }); writeStream.addListener("drain", function () { readStream.resume(); }); writeStream.addListener("resume", function () { readStream.resume(); }); readStream.addListener("end", function () { writeStream.end(); }); readStream.addListener("close", function () { call(); }); readStream.addListener("error", function (err) { writeStream.end(); call(err); }); writeStream.addListener("error", function (err) { readStream.destroy(); call(err); }); }; /** * 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 */ exports.inherits = function (ctor, superCtor) { ctor.super_ = superCtor; ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false } }); };