| /** | |
| * sprintf() for JavaScript v.0.4 | |
| * | |
| Copyright (c) 2007-present, Alexandru Mărășteanu <hello@alexei.ro> | |
| All rights reserved. | |
| Redistribution and use in source and binary forms, with or without | |
| modification, are permitted provided that the following conditions are met: | |
| * Redistributions of source code must retain the above copyright | |
| notice, this list of conditions and the following disclaimer. | |
| * Redistributions in binary form must reproduce the above copyright | |
| notice, this list of conditions and the following disclaimer in the | |
| documentation and/or other materials provided with the distribution. | |
| * Neither the name of this software nor the names of its contributors may be | |
| used to endorse or promote products derived from this software without | |
| specific prior written permission. | |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR | |
| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| */ | |
| //function str_repeat(i, m) { for (var o = []; m > 0; o[--m] = i); return(o.join('')); } | |
| var sprintf = function () { | |
| var i = 0, a, f = arguments[i++], o = [], m, p, c, x; | |
| while (f) { | |
| if (m = /^[^\x25]+/.exec(f)) o.push(m[0]); | |
| else if (m = /^\x25{2}/.exec(f)) o.push('%'); | |
| else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) { | |
| if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) throw ("Too few arguments."); | |
| if (/[^s]/.test(m[7]) && (typeof (a) != 'number')) | |
| throw ("Expecting number but found " + typeof (a)); | |
| switch (m[7]) { | |
| case 'b': a = a.toString(2); break; | |
| case 'c': a = String.fromCharCode(a); break; | |
| case 'd': a = parseInt(a); break; | |
| case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break; | |
| case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break; | |
| case 'o': a = a.toString(8); break; | |
| case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break; | |
| case 'u': a = Math.abs(a); break; | |
| case 'x': a = a.toString(16); break; | |
| case 'X': a = a.toString(16).toUpperCase(); break; | |
| } | |
| a = (/[def]/.test(m[7]) && m[2] && a > 0 ? '+' + a : a); | |
| c = m[3] ? m[3] == '0' ? '0' : m[3][1] : ' '; | |
| x = m[5] - String(a).length; | |
| p = m[5] ? str_repeat(c, x) : ''; | |
| o.push(m[4] ? a + p : p + a); | |
| } | |
| else throw ("Huh ?!"); | |
| f = f.substring(m[0].length); | |
| } | |
| return o.join(''); | |
| }; | |
| module.exports = sprintf; | |