123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- var mod_assert = require('assert');
- var mod_util = require('util');
- exports.sprintf = jsSprintf;
- exports.printf = jsPrintf;
- exports.fprintf = jsFprintf;
- function jsSprintf(fmt)
- {
- 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 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);
-
- 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 (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);
- }
- 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);
- }
|