doc: improvements to debugger.markdown copy
[platform/upstream/nodejs.git] / lib / util.js
1 'use strict';
2
3 const uv = process.binding('uv');
4 const Buffer = require('buffer').Buffer;
5 const internalUtil = require('internal/util');
6 const binding = process.binding('util');
7
8 var Debug;
9
10 const formatRegExp = /%[sdj%]/g;
11 exports.format = function(f) {
12   if (typeof f !== 'string') {
13     var objects = [];
14     for (var i = 0; i < arguments.length; i++) {
15       objects.push(inspect(arguments[i]));
16     }
17     return objects.join(' ');
18   }
19
20   if (arguments.length === 1) return f;
21
22   var i = 1;
23   var args = arguments;
24   var len = args.length;
25   var str = String(f).replace(formatRegExp, function(x) {
26     if (x === '%%') return '%';
27     if (i >= len) return x;
28     switch (x) {
29       case '%s': return String(args[i++]);
30       case '%d': return Number(args[i++]);
31       case '%j':
32         try {
33           return JSON.stringify(args[i++]);
34         } catch (_) {
35           return '[Circular]';
36         }
37         // falls through
38       default:
39         return x;
40     }
41   });
42   for (var x = args[i]; i < len; x = args[++i]) {
43     if (x === null || (typeof x !== 'object' && typeof x !== 'symbol')) {
44       str += ' ' + x;
45     } else {
46       str += ' ' + inspect(x);
47     }
48   }
49   return str;
50 };
51
52
53 exports.deprecate = internalUtil._deprecate;
54
55
56 var debugs = {};
57 var debugEnviron;
58 exports.debuglog = function(set) {
59   if (debugEnviron === undefined)
60     debugEnviron = process.env.NODE_DEBUG || '';
61   set = set.toUpperCase();
62   if (!debugs[set]) {
63     if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
64       var pid = process.pid;
65       debugs[set] = function() {
66         var msg = exports.format.apply(exports, arguments);
67         console.error('%s %d: %s', set, pid, msg);
68       };
69     } else {
70       debugs[set] = function() {};
71     }
72   }
73   return debugs[set];
74 };
75
76
77 /**
78  * Echos the value of a value. Trys to print the value out
79  * in the best way possible given the different types.
80  *
81  * @param {Object} obj The object to print out.
82  * @param {Object} opts Optional options object that alters the output.
83  */
84 /* legacy: obj, showHidden, depth, colors*/
85 function inspect(obj, opts) {
86   // default options
87   var ctx = {
88     seen: [],
89     stylize: stylizeNoColor
90   };
91   // legacy...
92   if (arguments.length >= 3) ctx.depth = arguments[2];
93   if (arguments.length >= 4) ctx.colors = arguments[3];
94   if (typeof opts === 'boolean') {
95     // legacy...
96     ctx.showHidden = opts;
97   } else if (opts) {
98     // got an "options" object
99     exports._extend(ctx, opts);
100   }
101   // set default options
102   if (ctx.showHidden === undefined) ctx.showHidden = false;
103   if (ctx.depth === undefined) ctx.depth = 2;
104   if (ctx.colors === undefined) ctx.colors = false;
105   if (ctx.customInspect === undefined) ctx.customInspect = true;
106   if (ctx.colors) ctx.stylize = stylizeWithColor;
107   return formatValue(ctx, obj, ctx.depth);
108 }
109 exports.inspect = inspect;
110
111
112 // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
113 inspect.colors = {
114   'bold' : [1, 22],
115   'italic' : [3, 23],
116   'underline' : [4, 24],
117   'inverse' : [7, 27],
118   'white' : [37, 39],
119   'grey' : [90, 39],
120   'black' : [30, 39],
121   'blue' : [34, 39],
122   'cyan' : [36, 39],
123   'green' : [32, 39],
124   'magenta' : [35, 39],
125   'red' : [31, 39],
126   'yellow' : [33, 39]
127 };
128
129 // Don't use 'blue' not visible on cmd.exe
130 inspect.styles = {
131   'special': 'cyan',
132   'number': 'yellow',
133   'boolean': 'yellow',
134   'undefined': 'grey',
135   'null': 'bold',
136   'string': 'green',
137   'symbol': 'green',
138   'date': 'magenta',
139   // "name": intentionally not styling
140   'regexp': 'red'
141 };
142
143
144 function stylizeWithColor(str, styleType) {
145   var style = inspect.styles[styleType];
146
147   if (style) {
148     return '\u001b[' + inspect.colors[style][0] + 'm' + str +
149            '\u001b[' + inspect.colors[style][1] + 'm';
150   } else {
151     return str;
152   }
153 }
154
155
156 function stylizeNoColor(str, styleType) {
157   return str;
158 }
159
160
161 function arrayToHash(array) {
162   var hash = {};
163
164   array.forEach(function(val, idx) {
165     hash[val] = true;
166   });
167
168   return hash;
169 }
170
171
172 function getConstructorOf(obj) {
173   while (obj) {
174     var descriptor = Object.getOwnPropertyDescriptor(obj, 'constructor');
175     if (descriptor !== undefined &&
176         typeof descriptor.value === 'function' &&
177         descriptor.value.name !== '') {
178       return descriptor.value;
179     }
180
181     obj = Object.getPrototypeOf(obj);
182   }
183
184   return null;
185 }
186
187
188 function ensureDebugIsInitialized() {
189   if (Debug === undefined) {
190     const runInDebugContext = require('vm').runInDebugContext;
191     Debug = runInDebugContext('Debug');
192   }
193 }
194
195
196 function inspectPromise(p) {
197   ensureDebugIsInitialized();
198   // Only create a mirror if the object is a Promise.
199   if (!binding.isPromise(p))
200     return null;
201   const mirror = Debug.MakeMirror(p, true);
202   return {status: mirror.status(), value: mirror.promiseValue().value_};
203 }
204
205
206 function formatValue(ctx, value, recurseTimes) {
207   // Provide a hook for user-specified inspect functions.
208   // Check that value is an object with an inspect function on it
209   if (ctx.customInspect &&
210       value &&
211       typeof value.inspect === 'function' &&
212       // Filter out the util module, it's inspect function is special
213       value.inspect !== exports.inspect &&
214       // Also filter out any prototype objects using the circular check.
215       !(value.constructor && value.constructor.prototype === value)) {
216     var ret = value.inspect(recurseTimes, ctx);
217     if (typeof ret !== 'string') {
218       ret = formatValue(ctx, ret, recurseTimes);
219     }
220     return ret;
221   }
222
223   // Primitive types cannot have properties
224   var primitive = formatPrimitive(ctx, value);
225   if (primitive) {
226     return primitive;
227   }
228
229   // Look up the keys of the object.
230   var keys = Object.keys(value);
231   var visibleKeys = arrayToHash(keys);
232
233   if (ctx.showHidden) {
234     keys = Object.getOwnPropertyNames(value);
235     keys = keys.concat(Object.getOwnPropertySymbols(value));
236   }
237
238   // This could be a boxed primitive (new String(), etc.), check valueOf()
239   // NOTE: Avoid calling `valueOf` on `Date` instance because it will return
240   // a number which, when object has some additional user-stored `keys`,
241   // will be printed out.
242   var formatted;
243   var raw = value;
244   try {
245     // the .valueOf() call can fail for a multitude of reasons
246     if (!isDate(value))
247       raw = value.valueOf();
248   } catch (e) {
249     // ignore...
250   }
251
252   if (typeof raw === 'string') {
253     // for boxed Strings, we have to remove the 0-n indexed entries,
254     // since they just noisey up the output and are redundant
255     keys = keys.filter(function(key) {
256       return !(key >= 0 && key < raw.length);
257     });
258   }
259
260   // Some type of object without properties can be shortcutted.
261   if (keys.length === 0) {
262     if (typeof value === 'function') {
263       var name = value.name ? ': ' + value.name : '';
264       return ctx.stylize('[Function' + name + ']', 'special');
265     }
266     if (isRegExp(value)) {
267       return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
268     }
269     if (isDate(value)) {
270       return ctx.stylize(Date.prototype.toString.call(value), 'date');
271     }
272     if (isError(value)) {
273       return formatError(value);
274     }
275     // now check the `raw` value to handle boxed primitives
276     if (typeof raw === 'string') {
277       formatted = formatPrimitiveNoColor(ctx, raw);
278       return ctx.stylize('[String: ' + formatted + ']', 'string');
279     }
280     if (typeof raw === 'number') {
281       formatted = formatPrimitiveNoColor(ctx, raw);
282       return ctx.stylize('[Number: ' + formatted + ']', 'number');
283     }
284     if (typeof raw === 'boolean') {
285       formatted = formatPrimitiveNoColor(ctx, raw);
286       return ctx.stylize('[Boolean: ' + formatted + ']', 'boolean');
287     }
288   }
289
290   var constructor = getConstructorOf(value);
291   var base = '', empty = false, braces, formatter;
292
293   // We can't compare constructors for various objects using a comparison like
294   // `constructor === Array` because the object could have come from a different
295   // context and thus the constructor won't match. Instead we check the
296   // constructor names (including those up the prototype chain where needed) to
297   // determine object types.
298   if (Array.isArray(value)) {
299     // Unset the constructor to prevent "Array [...]" for ordinary arrays.
300     if (constructor && constructor.name === 'Array')
301       constructor = null;
302     braces = ['[', ']'];
303     empty = value.length === 0;
304     formatter = formatArray;
305   } else if (objectToString(value) === '[object Set]') {
306     braces = ['{', '}'];
307     // With `showHidden`, `length` will display as a hidden property for
308     // arrays. For consistency's sake, do the same for `size`, even though this
309     // property isn't selected by Object.getOwnPropertyNames().
310     if (ctx.showHidden)
311       keys.unshift('size');
312     empty = value.size === 0;
313     formatter = formatSet;
314   } else if (objectToString(value) === '[object Map]') {
315     braces = ['{', '}'];
316     // Ditto.
317     if (ctx.showHidden)
318       keys.unshift('size');
319     empty = value.size === 0;
320     formatter = formatMap;
321   } else {
322     var promiseInternals = inspectPromise(value);
323     if (promiseInternals) {
324       braces = ['{', '}'];
325       formatter = formatPromise;
326     } else {
327       if (binding.isMapIterator(value)) {
328         constructor = { name: 'MapIterator' };
329         braces = ['{', '}'];
330         empty = false;
331         formatter = formatCollectionIterator;
332       } else if (binding.isSetIterator(value)) {
333         constructor = { name: 'SetIterator' };
334         braces = ['{', '}'];
335         empty = false;
336         formatter = formatCollectionIterator;
337       } else {
338         // Unset the constructor to prevent "Object {...}" for ordinary objects.
339         if (constructor && constructor.name === 'Object')
340           constructor = null;
341         braces = ['{', '}'];
342         empty = true;  // No other data than keys.
343         formatter = formatObject;
344       }
345     }
346   }
347
348   empty = empty === true && keys.length === 0;
349
350   // Make functions say that they are functions
351   if (typeof value === 'function') {
352     var n = value.name ? ': ' + value.name : '';
353     base = ' [Function' + n + ']';
354   }
355
356   // Make RegExps say that they are RegExps
357   if (isRegExp(value)) {
358     base = ' ' + RegExp.prototype.toString.call(value);
359   }
360
361   // Make dates with properties first say the date
362   if (isDate(value)) {
363     base = ' ' + Date.prototype.toUTCString.call(value);
364   }
365
366   // Make error with message first say the error
367   if (isError(value)) {
368     base = ' ' + formatError(value);
369   }
370
371   // Make boxed primitive Strings look like such
372   if (typeof raw === 'string') {
373     formatted = formatPrimitiveNoColor(ctx, raw);
374     base = ' ' + '[String: ' + formatted + ']';
375   }
376
377   // Make boxed primitive Numbers look like such
378   if (typeof raw === 'number') {
379     formatted = formatPrimitiveNoColor(ctx, raw);
380     base = ' ' + '[Number: ' + formatted + ']';
381   }
382
383   // Make boxed primitive Booleans look like such
384   if (typeof raw === 'boolean') {
385     formatted = formatPrimitiveNoColor(ctx, raw);
386     base = ' ' + '[Boolean: ' + formatted + ']';
387   }
388
389   // Add constructor name if available
390   if (base === '' && constructor)
391     braces[0] = constructor.name + ' ' + braces[0];
392
393   if (empty === true) {
394     return braces[0] + base + braces[1];
395   }
396
397   if (recurseTimes < 0) {
398     if (isRegExp(value)) {
399       return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
400     } else {
401       return ctx.stylize('[Object]', 'special');
402     }
403   }
404
405   ctx.seen.push(value);
406
407   var output = formatter(ctx, value, recurseTimes, visibleKeys, keys);
408
409   ctx.seen.pop();
410
411   return reduceToSingleString(output, base, braces);
412 }
413
414
415 function formatPrimitive(ctx, value) {
416   if (value === undefined)
417     return ctx.stylize('undefined', 'undefined');
418
419   // For some reason typeof null is "object", so special case here.
420   if (value === null)
421     return ctx.stylize('null', 'null');
422
423   var type = typeof value;
424
425   if (type === 'string') {
426     var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
427         .replace(/'/g, "\\'")
428         .replace(/\\"/g, '"') + '\'';
429     return ctx.stylize(simple, 'string');
430   }
431   if (type === 'number') {
432     // Format -0 as '-0'. Strict equality won't distinguish 0 from -0,
433     // so instead we use the fact that 1 / -0 < 0 whereas 1 / 0 > 0 .
434     if (value === 0 && 1 / value < 0)
435       return ctx.stylize('-0', 'number');
436     return ctx.stylize('' + value, 'number');
437   }
438   if (type === 'boolean')
439     return ctx.stylize('' + value, 'boolean');
440   // es6 symbol primitive
441   if (type === 'symbol')
442     return ctx.stylize(value.toString(), 'symbol');
443 }
444
445
446 function formatPrimitiveNoColor(ctx, value) {
447   var stylize = ctx.stylize;
448   ctx.stylize = stylizeNoColor;
449   var str = formatPrimitive(ctx, value);
450   ctx.stylize = stylize;
451   return str;
452 }
453
454
455 function formatError(value) {
456   return '[' + Error.prototype.toString.call(value) + ']';
457 }
458
459
460 function formatObject(ctx, value, recurseTimes, visibleKeys, keys) {
461   return keys.map(function(key) {
462     return formatProperty(ctx, value, recurseTimes, visibleKeys, key, false);
463   });
464 }
465
466
467 function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
468   var output = [];
469   for (var i = 0, l = value.length; i < l; ++i) {
470     if (hasOwnProperty(value, String(i))) {
471       output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
472           String(i), true));
473     } else {
474       output.push('');
475     }
476   }
477   keys.forEach(function(key) {
478     if (typeof key === 'symbol' || !key.match(/^\d+$/)) {
479       output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
480           key, true));
481     }
482   });
483   return output;
484 }
485
486
487 function formatSet(ctx, value, recurseTimes, visibleKeys, keys) {
488   var output = [];
489   value.forEach(function(v) {
490     var nextRecurseTimes = recurseTimes === null ? null : recurseTimes - 1;
491     var str = formatValue(ctx, v, nextRecurseTimes);
492     output.push(str);
493   });
494   keys.forEach(function(key) {
495     output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
496                                key, false));
497   });
498   return output;
499 }
500
501
502 function formatMap(ctx, value, recurseTimes, visibleKeys, keys) {
503   var output = [];
504   value.forEach(function(v, k) {
505     var nextRecurseTimes = recurseTimes === null ? null : recurseTimes - 1;
506     var str = formatValue(ctx, k, nextRecurseTimes);
507     str += ' => ';
508     str += formatValue(ctx, v, nextRecurseTimes);
509     output.push(str);
510   });
511   keys.forEach(function(key) {
512     output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
513                                key, false));
514   });
515   return output;
516 }
517
518 function formatCollectionIterator(ctx, value, recurseTimes, visibleKeys, keys) {
519   ensureDebugIsInitialized();
520   const mirror = Debug.MakeMirror(value, true);
521   var nextRecurseTimes = recurseTimes === null ? null : recurseTimes - 1;
522   var vals = mirror.preview();
523   var output = [];
524   for (const o of vals) {
525     output.push(formatValue(ctx, o, nextRecurseTimes));
526   }
527   return output;
528 }
529
530 function formatPromise(ctx, value, recurseTimes, visibleKeys, keys) {
531   var output = [];
532   var internals = inspectPromise(value);
533   if (internals.status === 'pending') {
534     output.push('<pending>');
535   } else {
536     var nextRecurseTimes = recurseTimes === null ? null : recurseTimes - 1;
537     var str = formatValue(ctx, internals.value, nextRecurseTimes);
538     if (internals.status === 'rejected') {
539       output.push('<rejected> ' + str);
540     } else {
541       output.push(str);
542     }
543   }
544   keys.forEach(function(key) {
545     output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
546                                key, false));
547   });
548   return output;
549 }
550
551
552 function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
553   var name, str, desc;
554   desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
555   if (desc.get) {
556     if (desc.set) {
557       str = ctx.stylize('[Getter/Setter]', 'special');
558     } else {
559       str = ctx.stylize('[Getter]', 'special');
560     }
561   } else {
562     if (desc.set) {
563       str = ctx.stylize('[Setter]', 'special');
564     }
565   }
566   if (!hasOwnProperty(visibleKeys, key)) {
567     if (typeof key === 'symbol') {
568       name = '[' + ctx.stylize(key.toString(), 'symbol') + ']';
569     } else {
570       name = '[' + key + ']';
571     }
572   }
573   if (!str) {
574     if (ctx.seen.indexOf(desc.value) < 0) {
575       if (recurseTimes === null) {
576         str = formatValue(ctx, desc.value, null);
577       } else {
578         str = formatValue(ctx, desc.value, recurseTimes - 1);
579       }
580       if (str.indexOf('\n') > -1) {
581         if (array) {
582           str = str.replace(/\n/g, '\n  ');
583         } else {
584           str = str.replace(/(^|\n)/g, '\n   ');
585         }
586       }
587     } else {
588       str = ctx.stylize('[Circular]', 'special');
589     }
590   }
591   if (name === undefined) {
592     if (array && key.match(/^\d+$/)) {
593       return str;
594     }
595     name = JSON.stringify('' + key);
596     if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
597       name = name.substr(1, name.length - 2);
598       name = ctx.stylize(name, 'name');
599     } else {
600       name = name.replace(/'/g, "\\'")
601                  .replace(/\\"/g, '"')
602                  .replace(/(^"|"$)/g, "'")
603                  .replace(/\\\\/g, '\\');
604       name = ctx.stylize(name, 'string');
605     }
606   }
607
608   return name + ': ' + str;
609 }
610
611
612 function reduceToSingleString(output, base, braces) {
613   var length = output.reduce(function(prev, cur) {
614     return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
615   }, 0);
616
617   if (length > 60) {
618     return braces[0] +
619            // If the opening "brace" is too large, like in the case of "Set {",
620            // we need to force the first item to be on the next line or the
621            // items will not line up correctly.
622            (base === '' && braces[0].length === 1 ? '' : base + '\n ') +
623            ' ' +
624            output.join(',\n  ') +
625            ' ' +
626            braces[1];
627   }
628
629   return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
630 }
631
632
633 // NOTE: These type checking functions intentionally don't use `instanceof`
634 // because it is fragile and can be easily faked with `Object.create()`.
635 exports.isArray = Array.isArray;
636
637 function isBoolean(arg) {
638   return typeof arg === 'boolean';
639 }
640 exports.isBoolean = isBoolean;
641
642 function isNull(arg) {
643   return arg === null;
644 }
645 exports.isNull = isNull;
646
647 function isNullOrUndefined(arg) {
648   return arg === null || arg === undefined;
649 }
650 exports.isNullOrUndefined = isNullOrUndefined;
651
652 function isNumber(arg) {
653   return typeof arg === 'number';
654 }
655 exports.isNumber = isNumber;
656
657 function isString(arg) {
658   return typeof arg === 'string';
659 }
660 exports.isString = isString;
661
662 function isSymbol(arg) {
663   return typeof arg === 'symbol';
664 }
665 exports.isSymbol = isSymbol;
666
667 function isUndefined(arg) {
668   return arg === undefined;
669 }
670 exports.isUndefined = isUndefined;
671
672 function isRegExp(re) {
673   return objectToString(re) === '[object RegExp]';
674 }
675 exports.isRegExp = isRegExp;
676
677 function isObject(arg) {
678   return arg !== null && typeof arg === 'object';
679 }
680 exports.isObject = isObject;
681
682 function isDate(d) {
683   return objectToString(d) === '[object Date]';
684 }
685 exports.isDate = isDate;
686
687 function isError(e) {
688   return objectToString(e) === '[object Error]' || e instanceof Error;
689 }
690 exports.isError = isError;
691
692 function isFunction(arg) {
693   return typeof arg === 'function';
694 }
695 exports.isFunction = isFunction;
696
697 function isPrimitive(arg) {
698   return arg === null ||
699          typeof arg !== 'object' && typeof arg !== 'function';
700 }
701 exports.isPrimitive = isPrimitive;
702
703 exports.isBuffer = Buffer.isBuffer;
704
705 function objectToString(o) {
706   return Object.prototype.toString.call(o);
707 }
708
709
710 function pad(n) {
711   return n < 10 ? '0' + n.toString(10) : n.toString(10);
712 }
713
714
715 const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
716                 'Oct', 'Nov', 'Dec'];
717
718 // 26 Feb 16:19:34
719 function timestamp() {
720   var d = new Date();
721   var time = [pad(d.getHours()),
722               pad(d.getMinutes()),
723               pad(d.getSeconds())].join(':');
724   return [d.getDate(), months[d.getMonth()], time].join(' ');
725 }
726
727
728 // log is just a thin wrapper to console.log that prepends a timestamp
729 exports.log = function() {
730   console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
731 };
732
733
734 /**
735  * Inherit the prototype methods from one constructor into another.
736  *
737  * The Function.prototype.inherits from lang.js rewritten as a standalone
738  * function (not on Function.prototype). NOTE: If this file is to be loaded
739  * during bootstrapping this function needs to be rewritten using some native
740  * functions as prototype setup using normal JavaScript does not work as
741  * expected during bootstrapping (see mirror.js in r114903).
742  *
743  * @param {function} ctor Constructor function which needs to inherit the
744  *     prototype.
745  * @param {function} superCtor Constructor function to inherit prototype from.
746  * @throws {TypeError} Will error if either constructor is null, or if
747  *     the super constructor lacks a prototype.
748  */
749 exports.inherits = function(ctor, superCtor) {
750
751   if (ctor === undefined || ctor === null)
752     throw new TypeError('The constructor to `inherits` must not be ' +
753                         'null or undefined.');
754
755   if (superCtor === undefined || superCtor === null)
756     throw new TypeError('The super constructor to `inherits` must not ' +
757                         'be null or undefined.');
758
759   if (superCtor.prototype === undefined)
760     throw new TypeError('The super constructor to `inherits` must ' +
761                         'have a prototype.');
762
763   ctor.super_ = superCtor;
764   ctor.prototype = Object.create(superCtor.prototype, {
765     constructor: {
766       value: ctor,
767       enumerable: false,
768       writable: true,
769       configurable: true
770     }
771   });
772 };
773
774 exports._extend = function(origin, add) {
775   // Don't do anything if add isn't an object
776   if (add === null || typeof add !== 'object') return origin;
777
778   var keys = Object.keys(add);
779   var i = keys.length;
780   while (i--) {
781     origin[keys[i]] = add[keys[i]];
782   }
783   return origin;
784 };
785
786 function hasOwnProperty(obj, prop) {
787   return Object.prototype.hasOwnProperty.call(obj, prop);
788 }
789
790
791 // Deprecated old stuff.
792
793 exports.p = internalUtil.deprecate(function() {
794   for (var i = 0, len = arguments.length; i < len; ++i) {
795     console.error(exports.inspect(arguments[i]));
796   }
797 }, 'util.p is deprecated. Use console.error instead.');
798
799
800 exports.exec = internalUtil.deprecate(function() {
801   return require('child_process').exec.apply(this, arguments);
802 }, 'util.exec is deprecated. Use child_process.exec instead.');
803
804
805 exports.print = internalUtil.deprecate(function() {
806   for (var i = 0, len = arguments.length; i < len; ++i) {
807     process.stdout.write(String(arguments[i]));
808   }
809 }, 'util.print is deprecated. Use console.log instead.');
810
811
812 exports.puts = internalUtil.deprecate(function() {
813   for (var i = 0, len = arguments.length; i < len; ++i) {
814     process.stdout.write(arguments[i] + '\n');
815   }
816 }, 'util.puts is deprecated. Use console.log instead.');
817
818
819 exports.debug = internalUtil.deprecate(function(x) {
820   process.stderr.write('DEBUG: ' + x + '\n');
821 }, 'util.debug is deprecated. Use console.error instead.');
822
823
824 exports.error = internalUtil.deprecate(function(x) {
825   for (var i = 0, len = arguments.length; i < len; ++i) {
826     process.stderr.write(arguments[i] + '\n');
827   }
828 }, 'util.error is deprecated. Use console.error instead.');
829
830
831 exports.pump = internalUtil.deprecate(function(readStream, writeStream, cb) {
832   var callbackCalled = false;
833
834   function call(a, b, c) {
835     if (cb && !callbackCalled) {
836       cb(a, b, c);
837       callbackCalled = true;
838     }
839   }
840
841   readStream.addListener('data', function(chunk) {
842     if (writeStream.write(chunk) === false) readStream.pause();
843   });
844
845   writeStream.addListener('drain', function() {
846     readStream.resume();
847   });
848
849   readStream.addListener('end', function() {
850     writeStream.end();
851   });
852
853   readStream.addListener('close', function() {
854     call();
855   });
856
857   readStream.addListener('error', function(err) {
858     writeStream.end();
859     call(err);
860   });
861
862   writeStream.addListener('error', function(err) {
863     readStream.destroy();
864     call(err);
865   });
866 }, 'util.pump is deprecated. Use readableStream.pipe instead.');
867
868
869 exports._errnoException = function(err, syscall, original) {
870   var errname = uv.errname(err);
871   var message = syscall + ' ' + errname;
872   if (original)
873     message += ' ' + original;
874   var e = new Error(message);
875   e.code = errname;
876   e.errno = errname;
877   e.syscall = syscall;
878   return e;
879 };
880
881
882 exports._exceptionWithHostPort = function(err,
883                                           syscall,
884                                           address,
885                                           port,
886                                           additional) {
887   var details;
888   if (port && port > 0) {
889     details = address + ':' + port;
890   } else {
891     details = address;
892   }
893
894   if (additional) {
895     details += ' - Local (' + additional + ')';
896   }
897   var ex = exports._errnoException(err, syscall, details);
898   ex.address = address;
899   if (port) {
900     ex.port = port;
901   }
902   return ex;
903 };