printf.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. /*##############################################################################
  2. # ____________________________________________________________________
  3. # / \
  4. # | ____ __ ___ _____ / ___ ___ |
  5. # | ____ / \/ \ ' / \ / / /__ / \ / \ |
  6. # | / _ \ / / / / / / ___/ \__ / /____/ / / |
  7. # | / |_ / / / / / / / / / \ / / /____/ |
  8. # | \____/ / / \/_/ / \__/ _____/ \__/ \___/ / |
  9. # | / |
  10. # | |
  11. # | Copyright (c) 2007 MindStep SCOP SARL |
  12. # | Herve Masson |
  13. # | |
  14. # | www.mindstep.com www.mjslib.com |
  15. # | info-oss@mindstep.com mjslib@mjslib.com |
  16. # \____________________________________________________________________/
  17. #
  18. # Version: 1.0.0
  19. #
  20. # (Svn version: $Id: jquery.printf.js 3434 2007-08-27 09:31:20Z herve $)
  21. #
  22. #----------[This product is distributed under a BSD license]-----------------
  23. #
  24. # Redistribution and use in source and binary forms, with or without
  25. # modification, are permitted provided that the following conditions
  26. # are met:
  27. #
  28. # 1. Redistributions of source code must retain the above copyright
  29. # notice, this list of conditions and the following disclaimer.
  30. #
  31. # 2. Redistributions in binary form must reproduce the above copyright
  32. # notice, this list of conditions and the following disclaimer in
  33. # the documentation and/or other materials provided with the
  34. # distribution.
  35. #
  36. # THIS SOFTWARE IS PROVIDED BY THE MINDSTEP CORP PROJECT ``AS IS'' AND
  37. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  38. # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  39. # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MINDSTEP CORP OR CONTRIBUTORS
  40. # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  41. # OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  42. # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  43. # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  44. # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  45. # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  46. # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47. #
  48. # The views and conclusions contained in the software and documentation
  49. # are those of the authors and should not be interpreted as representing
  50. # official policies, either expressed or implied, of MindStep Corp.
  51. #
  52. ################################################################################
  53. #
  54. # This is a jQuery [jquery.com] plugin that implements printf' like functions
  55. # (Examples and documentation at: http://mjslib.com)
  56. #
  57. # @author: Herve Masson
  58. # @version: 1.0.0 (8/27/2007)
  59. # @requires jQuery v1.1.2 or later
  60. #
  61. # (Based on the legacy mjslib.org framework)
  62. #
  63. ##############################################################################*/
  64. (function($) {
  65. /*
  66. ** Just an equivalent of the corresponding libc function
  67. **
  68. ** var str=jQuery.sprintf("%010d %-10s",intvalue,strvalue);
  69. **
  70. */
  71. $.sprintf=function(fmt)
  72. {
  73. return _sprintf_(fmt,arguments,1);
  74. }
  75. /*
  76. ** vsprintf takes an argument list instead of a list of arguments (duh!)
  77. ** (useful when forwarding parameters from one of your functions to a printf call)
  78. **
  79. ** str=jQuery.vsprintf(parameters[,offset]);
  80. **
  81. ** The 'offset' value, when present, instructs vprintf to start at the
  82. ** corresponding index in the parameter list instead, of 0
  83. **
  84. ** Example 1:
  85. **
  86. ** function myprintf(<printf like arguments>)
  87. ** {
  88. ** var str=jQuery.vsprintf(arguments);
  89. ** ..
  90. ** }
  91. ** myprintf("illegal value : %s",somevalue);
  92. **
  93. **
  94. ** Example 2:
  95. **
  96. ** function logit(level,<the rest is printf like arguments>)
  97. ** {
  98. ** var str=jQuery.vsprintf(arguments,1); // Skip prm #1
  99. ** ..
  100. ** }
  101. ** logit("error","illegal value : %s",somevalue);
  102. **
  103. */
  104. $.vsprintf=function(args,offset)
  105. {
  106. if(offset === undefined)
  107. {
  108. offset=0;
  109. }
  110. return _sprintf_(args[offset],args,offset+1);
  111. }
  112. /*
  113. ** logging using formatted messages
  114. ** ================================
  115. **
  116. ** If you _hate_ debugging with alert() as much as I do, you might find the
  117. ** following routines valuable.
  118. **
  119. ** jQuery.alertf("The variable 'str' contains: '%s'",str);
  120. ** Show an alert message with a printf-like argument.
  121. **
  122. ** jQuery.logf("This is a log message, time is: %d",(new Date()).getTime());
  123. ** Log the message on the console with the info level
  124. **
  125. ** jQuery.errorf("The given value (%d) is erroneous",avalue);
  126. ** Log the message on the console with the error level
  127. **
  128. */
  129. $.alertf=function()
  130. {
  131. return alert($.vsprintf(arguments));
  132. }
  133. $.vlogf=function(args)
  134. {
  135. if("console" in window)
  136. {
  137. console.info($.vsprintf(args));
  138. }
  139. }
  140. $.verrorf=function(args)
  141. {
  142. if("console" in window)
  143. {
  144. console.error($.vsprintf(args));
  145. }
  146. }
  147. $.errorf=function()
  148. {
  149. $.verrorf(arguments);
  150. }
  151. $.logf=function()
  152. {
  153. $.vlogf(arguments);
  154. }
  155. /*-------------------------------------------------------------------------------------------
  156. **
  157. ** Following code is private; don't use it directly !
  158. **
  159. **-----------------------------------------------------------------------------------------*/
  160. FREGEXP = /^([^%]*)%([-+])?(0)?(\d+)?(\.(\d+))?([doxXcsf])(.*)$/;
  161. HDIGITS = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
  162. function _empty(str)
  163. {
  164. if(str===undefined || str===null)
  165. {
  166. return true;
  167. }
  168. return (str == "") ? true : false;
  169. }
  170. function _int_(val)
  171. {
  172. return Math.floor(val);
  173. }
  174. function _printf_num_(val,base,pad,sign,width)
  175. {
  176. val=parseInt(val,10);
  177. if(isNaN(val))
  178. {
  179. return "NaN";
  180. }
  181. aval=(val<0)?-val:val;
  182. var ret="";
  183. if(aval==0)
  184. {
  185. ret="0";
  186. }
  187. else
  188. {
  189. while(aval>0)
  190. {
  191. ret=HDIGITS[aval%base]+ret;
  192. aval=_int_(aval/base);
  193. }
  194. }
  195. if(val<0)
  196. {
  197. ret="-"+ret;
  198. }
  199. if(sign=="-")
  200. {
  201. pad=" ";
  202. }
  203. return _printf_str_(ret,pad,sign,width,-1);
  204. }
  205. function _printf_float_(val,base,pad,sign,prec)
  206. {
  207. if(prec==undefined)
  208. {
  209. if(parseInt(val) != val)
  210. {
  211. // No decimal part and no precision -> use int formatting
  212. return ""+val;
  213. }
  214. prec=5;
  215. }
  216. var p10=Math.pow(10,prec);
  217. var ival=""+Math.round(val*p10);
  218. var ilen=ival.length-prec;
  219. if(ilen==0)
  220. {
  221. return "0."+ival.substr(ilen,prec);
  222. }
  223. return ival.substr(0,ilen)+"."+ival.substr(ilen,prec);
  224. }
  225. function _printf_str_(val,pad,sign,width,prec)
  226. {
  227. var npad;
  228. if(val === undefined)
  229. {
  230. return "(undefined)";
  231. }
  232. if(val === null)
  233. {
  234. return "(null)";
  235. }
  236. if((npad=width-val.length)>0)
  237. {
  238. if(sign=="-")
  239. {
  240. while(npad>0)
  241. {
  242. val+=pad;
  243. npad--;
  244. }
  245. }
  246. else
  247. {
  248. while(npad>0)
  249. {
  250. val=pad+val;
  251. npad--;
  252. }
  253. }
  254. }
  255. if(prec>0)
  256. {
  257. return val.substr(0,prec);
  258. }
  259. return val;
  260. }
  261. function _sprintf_(fmt,av,index)
  262. {
  263. var output="";
  264. var i,m,line,match;
  265. line=fmt.split("\n");
  266. for(i=0;i<line.length;i++)
  267. {
  268. if(i>0)
  269. {
  270. output+="\n";
  271. }
  272. fmt=line[i];
  273. while(match=FREGEXP.exec(fmt))
  274. {
  275. var sign="";
  276. var pad=" ";
  277. if(!_empty(match[1])) // the left part
  278. {
  279. // You can't add this blindly because mozilla set the value to <undefined> when
  280. // there is no match, and we don't want the "undefined" string be returned !
  281. output+=match[1];
  282. }
  283. if(!_empty(match[2])) // the sign (like in %-15s)
  284. {
  285. sign=match[2];
  286. }
  287. if(!_empty(match[3])) // the "0" char for padding (like in %03d)
  288. {
  289. pad="0";
  290. }
  291. var width=match[4]; // the with (32 in %032d)
  292. var prec=match[6]; // the precision (10 in %.10s)
  293. var type=match[7]; // the parameter type
  294. fmt=match[8];
  295. if(index>=av.length)
  296. {
  297. output += "[missing parameter for type '"+type+"']";
  298. continue;
  299. }
  300. var val=av[index++];
  301. switch(type)
  302. {
  303. case "d":
  304. output += _printf_num_(val,10,pad,sign,width);
  305. break;
  306. case "o":
  307. output += _printf_num_(val,8,pad,sign,width);
  308. break;
  309. case "x":
  310. output += _printf_num_(val,16,pad,sign,width);
  311. break;
  312. case "X":
  313. output += _printf_num_(val,16,pad,sign,width).toUpperCase();
  314. break;
  315. case "c":
  316. output += String.fromCharCode(parseInt(val,10));
  317. break;
  318. case "s":
  319. output += _printf_str_(val,pad,sign,width,prec);
  320. break;
  321. case "f":
  322. output += _printf_float_(val,pad,sign,width,prec);
  323. break;
  324. default:
  325. output += "[unknown format '"+type+"']";
  326. break;
  327. }
  328. }
  329. output+=fmt;
  330. }
  331. return output;
  332. }
  333. })(jQuery);