Name: cockpit/lib/printf.js 
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:
#  |   [email protected]                           [email protected]  |
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:
 
65:
(function($) {
66:
 
67:
  /*
68:
  **  Just an equivalent of the corresponding libc function
69:
  **
70:
  **  var str=jQuery.sprintf("%010d %-10s",intvalue,strvalue);
71:
  **
72:
  */
73:
 
74:
  $.sprintf=function(fmt)
75:
  {
76:
    return _sprintf_(fmt,arguments,1);
77:
  }
78:
 
79:
 
80:
  /*
81:
  **  vsprintf takes an argument list instead of a list of arguments (duh!)
82:
  **  (useful when forwarding parameters from one of your functions to a printf call)
83:
  **
84:
  **  str=jQuery.vsprintf(parameters[,offset]);
85:
  **
86:
  **    The 'offset' value, when present, instructs vprintf to start at the
87:
  **    corresponding index in the parameter list instead, of 0
88:
  **
89:
  **  Example 1:
90:
  **
91:
  **    function myprintf(<printf like arguments>)
92:
  **    {
93:
  **      var str=jQuery.vsprintf(arguments);
94:
  **      ..
95:
  **    }
96:
  **    myprintf("illegal value : %s",somevalue);
97:
  **
98:
  **
99:
  **  Example 2:
100:
  **
101:
  **    function logit(level,<the rest is printf like arguments>)
102:
  **    {
103:
  **      var str=jQuery.vsprintf(arguments,1);  // Skip prm #1
104:
  **      ..
105:
  **    }
106:
  **    logit("error","illegal value : %s",somevalue);
107:
  **
108:
  */
109:
 
110:
  $.vsprintf=function(args,offset)
111:
  {
112:
    if(offset === undefined)
113:
    {
114:
      offset=0;
115:
    }
116:
    return _sprintf_(args[offset],args,offset+1);
117:
  }
118:
 
119:
 
120:
  /*
121:
  **  logging using formatted messages
122:
  **  ================================
123:
  **
124:
  **  If you _hate_ debugging with alert() as much as I do, you might find the
125:
  **  following routines valuable.
126:
  **
127:
  **  jQuery.alertf("The variable 'str' contains: '%s'",str);
128:
  **    Show an alert message with a printf-like argument.
129:
  **
130:
  **  jQuery.logf("This is a log message, time is: %d",(new Date()).getTime());
131:
  **    Log the message on the console with the info level
132:
  **
133:
  **  jQuery.errorf("The given value (%d) is erroneous",avalue);
134:
  **    Log the message on the console with the error level
135:
  **
136:
  */
137:
 
138:
  $.alertf=function()
139:
  {
140:
    return alert($.vsprintf(arguments));
141:
  }
142:
 
143:
  $.vlogf=function(args)
144:
  {
145:
    if("console" in window)
146:
    {
147:
      console.info($.vsprintf(args));
148:
    }
149:
  }
150:
 
151:
  $.verrorf=function(args)
152:
  {
153:
    if("console" in window)
154:
    {
155:
      console.error($.vsprintf(args));
156:
    }
157:
  }
158:
 
159:
  $.errorf=function()
160:
  {
161:
    $.verrorf(arguments);
162:
  }
163:
 
164:
  $.logf=function()
165:
  {
166:
    $.vlogf(arguments);
167:
  }
168:
 
169:
 
170:
  /*-------------------------------------------------------------------------------------------
171:
  **
172:
  **  Following code is private; don't use it directly !
173:
  **
174:
  **-----------------------------------------------------------------------------------------*/
175:
 
176:
  FREGEXP  = /^([^%]*)%([-+])?(0)?(\d+)?(\.(\d+))?([doxXcsf])(.*)$/;
177:
  HDIGITS  = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
178:
 
179:
  function _empty(str)
180:
  {
181:
    if(str===undefined || str===null)
182:
    {
183:
      return true;
184:
    }
185:
    return (str == "") ? true : false;
186:
  }
187:
 
188:
  function _int_(val)
189:
  {
190:
    return Math.floor(val);
191:
  }
192:
 
193:
  function _printf_num_(val,base,pad,sign,width)
194:
  {
195:
    val=parseInt(val,10);
196:
    if(isNaN(val))
197:
    {
198:
      return "NaN";
199:
    }
200:
    aval=(val<0)?-val:val;
201:
    var ret="";
202:
 
203:
    if(aval==0)
204:
    {
205:
      ret="0";
206:
    }
207:
    else
208:
    {
209:
      while(aval>0)
210:
      {
211:
        ret=HDIGITS[aval%base]+ret;
212:
        aval=_int_(aval/base);
213:
      }
214:
    }
215:
    if(val<0)
216:
    {
217:
      ret="-"+ret;
218:
    }
219:
    if(sign=="-")
220:
    {
221:
      pad=" ";
222:
    }
223:
    return _printf_str_(ret,pad,sign,width,-1);
224:
  }
225:
 
226:
  function _printf_float_(val,base,pad,sign,prec)
227:
  {
228:
    if(prec==undefined)
229:
    {
230:
      if(parseInt(val) != val)
231:
      {
232:
        // No decimal part and no precision -> use int formatting
233:
        return ""+val;
234:
      }
235:
      prec=5;
236:
    }
237:
 
238:
    var p10=Math.pow(10,prec);
239:
    var ival=""+Math.round(val*p10);
240:
    var ilen=ival.length-prec;
241:
    if(ilen==0)
242:
    {
243:
      return "0."+ival.substr(ilen,prec);
244:
    }
245:
    return ival.substr(0,ilen)+"."+ival.substr(ilen,prec);
246:
  }
247:
 
248:
  function _printf_str_(val,pad,sign,width,prec)
249:
  {
250:
    var npad;
251:
 
252:
    if(val === undefined)
253:
    {
254:
      return "(undefined)";
255:
    }
256:
    if(val === null)
257:
    {
258:
      return "(null)";
259:
    }
260:
    if((npad=width-val.length)>0)
261:
    {
262:
      if(sign=="-")
263:
      {
264:
        while(npad>0)
265:
        {
266:
          val+=pad;
267:
          npad--;
268:
        }
269:
      }
270:
      else
271:
      {
272:
        while(npad>0)
273:
        {
274:
          val=pad+val;
275:
          npad--;
276:
        }
277:
      }
278:
    }
279:
    if(prec>0)
280:
    {
281:
      return val.substr(0,prec);
282:
    }
283:
    return val;
284:
  }
285:
 
286:
  function _sprintf_(fmt,av,index)
287:
  {
288:
    var output="";
289:
    var i,m,line,match;
290:
 
291:
    line=fmt.split("\n");
292:
    for(i=0;i<line.length;i++)
293:
    {
294:
      if(i>0)
295:
      {
296:
        output+="\n";
297:
      }
298:
      fmt=line[i];
299:
      while(match=FREGEXP.exec(fmt))
300:
      {
301:
        var sign="";
302:
        var pad=" ";
303:
 
304:
        if(!_empty(match[1])) // the left part
305:
        {
306:
          // You can't add this blindly because mozilla set the value to <undefined> when
307:
          // there is no match, and we don't want the "undefined" string be returned !
308:
          output+=match[1];
309:
        }
310:
        if(!_empty(match[2])) // the sign (like in %-15s)
311:
        {
312:
          sign=match[2];
313:
        }
314:
        if(!_empty(match[3])) // the "0" char for padding (like in %03d)
315:
        {
316:
          pad="0";
317:
        }
318:
 
319:
        var width=match[4];  // the with (32 in %032d)
320:
        var prec=match[6];  // the precision (10 in %.10s)
321:
        var type=match[7];  // the parameter type
322:
 
323:
        fmt=match[8];
324:
 
325:
        if(index>=av.length)
326:
        {
327:
          output += "[missing parameter for type '"+type+"']";
328:
          continue;
329:
        }
330:
 
331:
        var val=av[index++];
332:
 
333:
        switch(type)
334:
        {
335:
        case "d":
336:
          output += _printf_num_(val,10,pad,sign,width);
337:
          break;
338:
        case "o":
339:
          output += _printf_num_(val,8,pad,sign,width);
340:
          break;
341:
        case "x":
342:
          output += _printf_num_(val,16,pad,sign,width);
343:
          break;
344:
        case "X":
345:
          output += _printf_num_(val,16,pad,sign,width).toUpperCase();
346:
          break;
347:
        case "c":
348:
          output += String.fromCharCode(parseInt(val,10));
349:
          break;
350:
        case "s":
351:
          output += _printf_str_(val,pad,sign,width,prec);
352:
          break;
353:
        case "f":
354:
          output += _printf_float_(val,pad,sign,width,prec);
355:
          break;
356:
        default:
357:
          output += "[unknown format '"+type+"']";
358:
          break;
359:
        }
360:
      }
361:
      output+=fmt;
362:
    }
363:
    return output;
364:
  }
365:
 
366:
})(jQuery);