Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

extsprintf.js 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * extsprintf.js: extended POSIX-style sprintf
  3. */
  4. var mod_assert = require('assert');
  5. var mod_util = require('util');
  6. /*
  7. * Public interface
  8. */
  9. exports.sprintf = jsSprintf;
  10. exports.printf = jsPrintf;
  11. /*
  12. * Stripped down version of s[n]printf(3c). We make a best effort to throw an
  13. * exception when given a format string we don't understand, rather than
  14. * ignoring it, so that we won't break existing programs if/when we go implement
  15. * the rest of this.
  16. *
  17. * This implementation currently supports specifying
  18. * - field alignment ('-' flag),
  19. * - zero-pad ('0' flag)
  20. * - always show numeric sign ('+' flag),
  21. * - field width
  22. * - conversions for strings, decimal integers, and floats (numbers).
  23. * - argument size specifiers. These are all accepted but ignored, since
  24. * Javascript has no notion of the physical size of an argument.
  25. *
  26. * Everything else is currently unsupported, most notably precision, unsigned
  27. * numbers, non-decimal numbers, and characters.
  28. */
  29. function jsSprintf(fmt)
  30. {
  31. var regex = [
  32. '([^%]*)', /* normal text */
  33. '%', /* start of format */
  34. '([\'\\-+ #0]*?)', /* flags (optional) */
  35. '([1-9]\\d*)?', /* width (optional) */
  36. '(\\.([1-9]\\d*))?', /* precision (optional) */
  37. '[lhjztL]*?', /* length mods (ignored) */
  38. '([diouxXfFeEgGaAcCsSp%jr])' /* conversion */
  39. ].join('');
  40. var re = new RegExp(regex);
  41. var args = Array.prototype.slice.call(arguments, 1);
  42. var flags, width, precision, conversion;
  43. var left, pad, sign, arg, match;
  44. var ret = '';
  45. var argn = 1;
  46. mod_assert.equal('string', typeof (fmt));
  47. while ((match = re.exec(fmt)) !== null) {
  48. ret += match[1];
  49. fmt = fmt.substring(match[0].length);
  50. flags = match[2] || '';
  51. width = match[3] || 0;
  52. precision = match[4] || '';
  53. conversion = match[6];
  54. left = false;
  55. sign = false;
  56. pad = ' ';
  57. if (conversion == '%') {
  58. ret += '%';
  59. continue;
  60. }
  61. if (args.length === 0)
  62. throw (new Error('too few args to sprintf'));
  63. arg = args.shift();
  64. argn++;
  65. if (flags.match(/[\' #]/))
  66. throw (new Error(
  67. 'unsupported flags: ' + flags));
  68. if (precision.length > 0)
  69. throw (new Error(
  70. 'non-zero precision not supported'));
  71. if (flags.match(/-/))
  72. left = true;
  73. if (flags.match(/0/))
  74. pad = '0';
  75. if (flags.match(/\+/))
  76. sign = true;
  77. switch (conversion) {
  78. case 's':
  79. if (arg === undefined || arg === null)
  80. throw (new Error('argument ' + argn +
  81. ': attempted to print undefined or null ' +
  82. 'as a string'));
  83. ret += doPad(pad, width, left, arg.toString());
  84. break;
  85. case 'd':
  86. arg = Math.floor(arg);
  87. /*jsl:fallthru*/
  88. case 'f':
  89. sign = sign && arg > 0 ? '+' : '';
  90. ret += sign + doPad(pad, width, left,
  91. arg.toString());
  92. break;
  93. case 'x':
  94. ret += doPad(pad, width, left, arg.toString(16));
  95. break;
  96. case 'j': /* non-standard */
  97. if (width === 0)
  98. width = 10;
  99. ret += mod_util.inspect(arg, false, width);
  100. break;
  101. case 'r': /* non-standard */
  102. ret += dumpException(arg);
  103. break;
  104. default:
  105. throw (new Error('unsupported conversion: ' +
  106. conversion));
  107. }
  108. }
  109. ret += fmt;
  110. return (ret);
  111. }
  112. function jsPrintf() {
  113. process.stdout.write(jsSprintf.apply(this, arguments));
  114. }
  115. function doPad(chr, width, left, str)
  116. {
  117. var ret = str;
  118. while (ret.length < width) {
  119. if (left)
  120. ret += chr;
  121. else
  122. ret = chr + ret;
  123. }
  124. return (ret);
  125. }
  126. /*
  127. * This function dumps long stack traces for exceptions having a cause() method.
  128. * See node-verror for an example.
  129. */
  130. function dumpException(ex)
  131. {
  132. var ret;
  133. if (!(ex instanceof Error))
  134. throw (new Error(jsSprintf('invalid type for %%r: %j', ex)));
  135. /* Note that V8 prepends "ex.stack" with ex.toString(). */
  136. ret = 'EXCEPTION: ' + ex.constructor.name + ': ' + ex.stack;
  137. if (ex.cause && typeof (ex.cause) === 'function') {
  138. var cex = ex.cause();
  139. if (cex) {
  140. ret += '\nCaused by: ' + dumpException(cex);
  141. }
  142. }
  143. return (ret);
  144. }