summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/extsprintf/lib/extsprintf.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/node_modules/extsprintf/lib/extsprintf.js')
-rw-r--r--deps/npm/node_modules/extsprintf/lib/extsprintf.js183
1 files changed, 183 insertions, 0 deletions
diff --git a/deps/npm/node_modules/extsprintf/lib/extsprintf.js b/deps/npm/node_modules/extsprintf/lib/extsprintf.js
new file mode 100644
index 0000000000..ed883d32b9
--- /dev/null
+++ b/deps/npm/node_modules/extsprintf/lib/extsprintf.js
@@ -0,0 +1,183 @@
+/*
+ * extsprintf.js: extended POSIX-style sprintf
+ */
+
+var mod_assert = require('assert');
+var mod_util = require('util');
+
+/*
+ * Public interface
+ */
+exports.sprintf = jsSprintf;
+exports.printf = jsPrintf;
+exports.fprintf = jsFprintf;
+
+/*
+ * Stripped down version of s[n]printf(3c). We make a best effort to throw an
+ * exception when given a format string we don't understand, rather than
+ * ignoring it, so that we won't break existing programs if/when we go implement
+ * the rest of this.
+ *
+ * This implementation currently supports specifying
+ * - field alignment ('-' flag),
+ * - zero-pad ('0' flag)
+ * - always show numeric sign ('+' flag),
+ * - field width
+ * - conversions for strings, decimal integers, and floats (numbers).
+ * - argument size specifiers. These are all accepted but ignored, since
+ * Javascript has no notion of the physical size of an argument.
+ *
+ * Everything else is currently unsupported, most notably precision, unsigned
+ * numbers, non-decimal numbers, and characters.
+ */
+function jsSprintf(fmt)
+{
+ var regex = [
+ '([^%]*)', /* normal text */
+ '%', /* start of format */
+ '([\'\\-+ #0]*?)', /* flags (optional) */
+ '([1-9]\\d*)?', /* width (optional) */
+ '(\\.([1-9]\\d*))?', /* precision (optional) */
+ '[lhjztL]*?', /* length mods (ignored) */
+ '([diouxXfFeEgGaAcCsSp%jr])' /* conversion */
+ ].join('');
+
+ var re = new RegExp(regex);
+ var args = Array.prototype.slice.call(arguments, 1);
+ var flags, width, precision, conversion;
+ var left, pad, sign, arg, match;
+ var ret = '';
+ var argn = 1;
+
+ mod_assert.equal('string', typeof (fmt));
+
+ while ((match = re.exec(fmt)) !== null) {
+ ret += match[1];
+ fmt = fmt.substring(match[0].length);
+
+ flags = match[2] || '';
+ width = match[3] || 0;
+ precision = match[4] || '';
+ conversion = match[6];
+ left = false;
+ sign = false;
+ pad = ' ';
+
+ if (conversion == '%') {
+ ret += '%';
+ continue;
+ }
+
+ if (args.length === 0)
+ throw (new Error('too few args to sprintf'));
+
+ arg = args.shift();
+ argn++;
+
+ if (flags.match(/[\' #]/))
+ throw (new Error(
+ 'unsupported flags: ' + flags));
+
+ if (precision.length > 0)
+ throw (new Error(
+ 'non-zero precision not supported'));
+
+ if (flags.match(/-/))
+ left = true;
+
+ if (flags.match(/0/))
+ pad = '0';
+
+ if (flags.match(/\+/))
+ sign = true;
+
+ switch (conversion) {
+ case 's':
+ if (arg === undefined || arg === null)
+ throw (new Error('argument ' + argn +
+ ': attempted to print undefined or null ' +
+ 'as a string'));
+ ret += doPad(pad, width, left, arg.toString());
+ break;
+
+ case 'd':
+ arg = Math.floor(arg);
+ /*jsl:fallthru*/
+ case 'f':
+ sign = sign && arg > 0 ? '+' : '';
+ ret += sign + doPad(pad, width, left,
+ arg.toString());
+ break;
+
+ case 'x':
+ ret += doPad(pad, width, left, arg.toString(16));
+ break;
+
+ case 'j': /* non-standard */
+ if (width === 0)
+ width = 10;
+ ret += mod_util.inspect(arg, false, width);
+ break;
+
+ case 'r': /* non-standard */
+ ret += dumpException(arg);
+ break;
+
+ default:
+ throw (new Error('unsupported conversion: ' +
+ conversion));
+ }
+ }
+
+ ret += fmt;
+ return (ret);
+}
+
+function jsPrintf() {
+ var args = Array.prototype.slice.call(arguments);
+ args.unshift(process.stdout);
+ jsFprintf.apply(null, args);
+}
+
+function jsFprintf(stream) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ return (stream.write(jsSprintf.apply(this, args)));
+}
+
+function doPad(chr, width, left, str)
+{
+ var ret = str;
+
+ while (ret.length < width) {
+ if (left)
+ ret += chr;
+ else
+ ret = chr + ret;
+ }
+
+ return (ret);
+}
+
+/*
+ * This function dumps long stack traces for exceptions having a cause() method.
+ * See node-verror for an example.
+ */
+function dumpException(ex)
+{
+ var ret;
+
+ if (!(ex instanceof Error))
+ throw (new Error(jsSprintf('invalid type for %%r: %j', ex)));
+
+ /* Note that V8 prepends "ex.stack" with ex.toString(). */
+ ret = 'EXCEPTION: ' + ex.constructor.name + ': ' + ex.stack;
+
+ if (ex.cause && typeof (ex.cause) === 'function') {
+ var cex = ex.cause();
+ if (cex) {
+ ret += '\nCaused by: ' + dumpException(cex);
+ }
+ }
+
+ return (ret);
+}