PageSourceSearch

https://embed.ly/static/scripts/vendor/sprintf-0.7-beta1.js?v=2ad4a4b3b4c5f19bb3b39595d865a679

js embed.ly collected 2026-09-24 08:28:55 UTC 6,919 bytes, 183 lines download raw bytes

1/**
2sprintf() for JavaScript 0.7-beta1
3http://www.diveintojavascript.com/projects/javascript-sprintf
4
5Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
6All rights reserved.
7
8Redistribution and use in source and binary forms, with or without
9modification, are permitted provided that the following conditions are met:
10    * Redistributions of source code must retain the above copyright
11      notice, this list of conditions and the following disclaimer.
12    * Redistributions in binary form must reproduce the above copyright
13      notice, this list of conditions and the following disclaimer in the
14      documentation and/or other materials provided with the distribution.
15    * Neither the name of sprintf() for JavaScript nor the
16      names of its contributors may be used to endorse or promote products
17      derived from this software without specific prior written permission.
18
19THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY
23DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30
31Changelog:
322010.09.06 - 0.7-beta1
33  - features: vsprintf, support for named placeholders
34  - enhancements: format cache, reduced global namespace pollution
35
362010.05.22 - 0.6:
37 - reverted to 0.4 and fixed the bug regarding the sign of the number 0
38 Note:
39 Thanks to Raphael Pigulla <raph (at] n3rd [dot) org> (http://www.n3rd.org/)
40 who warned me about a bug in 0.5, I discovered that the last update was
41 a regress. I appologize for that.
42
432010.05.09 - 0.5:
44 - bug fix: 0 is now preceeded with a + sign
45 - bug fix: the sign was not at the right position on padded results (Kamal Abdali)
46 - switched from GPL to BSD license
47
482007.10.21 - 0.4:
49 - unit test and patch (David Baird)
50
512007.09.17 - 0.3:
52 - bug fix: no longer throws exception on empty paramenters (Hans Pufal)
53
542007.09.11 - 0.2:
55 - feature: added argument swapping
56
572007.04.03 - 0.1:
58 - initial release
59**/
60
61var sprintf = (function() {
62	function get_type(variable) {
63		return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
64	}
65	function str_repeat(input, multiplier) {
66		for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
67		return output.join('');
68	}
69
70	var str_format = function() {
71		if (!str_format.cache.hasOwnProperty(arguments[0])) {
72			str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
73		}
74		return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
75	};
76
77	str_format.format = function(parse_tree, argv) {
78		var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
79		for (i = 0; i < tree_length; i++) {
80			node_type = get_type(parse_tree[i]);
81			if (node_type === 'string') {
82				output.push(parse_tree[i]);
83			}
84			else if (node_type === 'array') {
85				match = parse_tree[i]; // convenience purposes only
86				if (match[2]) { // keyword argument
87					arg = argv[cursor];
88					for (k = 0; k < match[2].length; k++) {
89						if (!arg.hasOwnProperty(match[2][k])) {
90							throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
91						}
92						arg = arg[match[2][k]];
93					}
94				}
95				else if (match[1]) { // positional argument (explicit)
96					arg = argv[match[1]];
97				}
98				else { // positional argument (implicit)
99					arg = argv[cursor++];
100				}
101
102				if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
103					throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
104				}
105				switch (match[8]) {
106					case 'b': arg = arg.toString(2); break;
107					case 'c': arg = String.fromCharCode(arg); break;
108					case 'd': arg = parseInt(arg, 10); break;
109					case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
110					case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
111					case 'o': arg = arg.toString(8); break;
112					case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
113					case 'u': arg = Math.abs(arg); break;
114					case 'x': arg = arg.toString(16); break;
115					case 'X': arg = arg.toString(16).toUpperCase(); break;
116				}
117				arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
118				pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
119				pad_length = match[6] - String(arg).length;
120				pad = match[6] ? str_repeat(pad_character, pad_length) : '';
121				output.push(match[5] ? arg + pad : pad + arg);
122			}
123		}
124		return output.join('');
125	};
126
127	str_format.cache = {};
128
129	str_format.parse = function(fmt) {
130		var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
131		while (_fmt) {
132			if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
133				parse_tree.push(match[0]);
134			}
135			else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
136				parse_tree.push('%');
137			}
138			else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
139				if (match[2]) {
140					arg_names |= 1;
141					var field_list = [], replacement_field = match[2], field_match = [];
142					if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
143						field_list.push(field_match[1]);
144						while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
145							if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
146								field_list.push(field_match[1]);
147							}
148							else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
149								field_list.push(field_match[1]);
150							}
151							else {
152								throw('[sprintf] huh?');
153							}
154						}
155					}
156					else {
157						throw('[sprintf] huh?');
158					}
159					match[2] = field_list;
160				}
161				else {
162					arg_names |= 2;
163				}
164				if (arg_names === 3) {
165					throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
166				}
167				parse_tree.push(match);
168			}
169			else {
170				throw('[sprintf] huh?');
171			}
172			_fmt = _fmt.substring(match[0].length);
173		}
174		return parse_tree;
175	};
176
177	return str_format;
178})();
179
180var vsprintf = function(fmt, argv) {
181	argv.unshift(fmt);
182	return sprintf.apply(null, argv);
183};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.