source: trip-planner-front/node_modules/extsprintf/lib/extsprintf.js@ 6a3a178

Last change on this file since 6a3a178 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

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