123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
-
-
- var mod_assert = require('assert');
- var mod_util = require('util');
-
-
- exports.sprintf = jsSprintf;
- exports.printf = jsPrintf;
- exports.fprintf = jsFprintf;
-
-
- function jsSprintf(ofmt)
- {
- var regex = [
- '([^%]*)',
- '%',
- '([\'\\-+ #0]*?)',
- '([1-9]\\d*)?',
- '(\\.([1-9]\\d*))?',
- '[lhjztL]*?',
- '([diouxXfFeEgGaAcCsSp%jr])'
- ].join('');
-
- var re = new RegExp(regex);
-
-
- var args = Array.prototype.slice.call(arguments, 1);
-
- var fmt = ofmt;
-
-
- var flags, width, precision, conversion;
- var left, pad, sign, arg, match;
-
-
- var ret = '';
-
-
- var argn = 1;
-
- var posn = 0;
-
- var convposn;
-
- var curconv;
-
- mod_assert.equal('string', typeof (fmt),
- 'first argument must be a format string');
-
- while ((match = re.exec(fmt)) !== null) {
- ret += match[1];
- fmt = fmt.substring(match[0].length);
-
-
-
- curconv = match[0].substring(match[1].length);
- convposn = posn + match[1].length + 1;
- posn += 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 (jsError(ofmt, convposn, curconv,
- 'has no matching argument ' +
- '(too few arguments passed)'));
- }
-
- arg = args.shift();
- argn++;
-
- if (flags.match(/[\' #]/)) {
- throw (jsError(ofmt, convposn, curconv,
- 'uses unsupported flags'));
- }
-
- if (precision.length > 0) {
- throw (jsError(ofmt, convposn, curconv,
- 'uses 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 (jsError(ofmt, convposn, curconv,
- 'attempted to print undefined or null ' +
- 'as a string (argument ' + argn + ' to ' +
- 'sprintf)'));
- }
- ret += doPad(pad, width, left, arg.toString());
- break;
-
- case 'd':
- arg = Math.floor(arg);
-
- 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':
- if (width === 0)
- width = 10;
- ret += mod_util.inspect(arg, false, width);
- break;
-
- case 'r':
- ret += dumpException(arg);
- break;
-
- default:
- throw (jsError(ofmt, convposn, curconv,
- 'is not supported'));
- }
- }
-
- ret += fmt;
- return (ret);
- }
-
- function jsError(fmtstr, convposn, curconv, reason) {
- mod_assert.equal(typeof (fmtstr), 'string');
- mod_assert.equal(typeof (curconv), 'string');
- mod_assert.equal(typeof (convposn), 'number');
- mod_assert.equal(typeof (reason), 'string');
- return (new Error('format string "' + fmtstr +
- '": conversion specifier "' + curconv + '" at character ' +
- convposn + ' ' + reason));
- }
-
- 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);
- }
-
-
- function dumpException(ex)
- {
- var ret;
-
- if (!(ex instanceof Error))
- throw (new Error(jsSprintf('invalid type for %%r: %j', ex)));
-
-
- 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);
- }
|