6565 * causing nasty effects.
6666 **************************************************************/
6767
68- /*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.19 2005/03/12 04 :00:56 momjian Exp $";*/
68+ /*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.20 2005/03/16 06 :00:58 momjian Exp $";*/
6969
7070int pg_snprintf (char * str , size_t count , const char * fmt ,...);
7171int pg_vsnprintf (char * str , size_t count , const char * fmt , va_list args );
@@ -151,20 +151,20 @@ static void dopr_outch(int c, char *end, char **output);
151151
152152#define FMTSTR 1
153153#define FMTNUM 2
154- #define FMTFLOAT 3
155- #define FMTCHAR 4
154+ #define FMTNUM_U 3
155+ #define FMTFLOAT 4
156+ #define FMTCHAR 5
157+ #define FMTWIDTH 6
158+ #define FMTLEN 7
156159
157160static void
158161dopr (char * buffer , const char * format , va_list args , char * end )
159162{
160163 int ch ;
161- int64 value ;
162- double fvalue ;
163164 int longlongflag = 0 ;
164165 int longflag = 0 ;
165166 int pointflag = 0 ;
166167 int maxwidth = 0 ;
167- char * strvalue ;
168168 int ljust ;
169169 int len ;
170170 int zpad ;
@@ -173,6 +173,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
173173 const char * fmtbegin ;
174174 int fmtpos = 1 ;
175175 int realpos = 0 ;
176+ int precision ;
176177 int position ;
177178 char * output ;
178179 int percents = 1 ;
@@ -195,6 +196,8 @@ dopr(char *buffer, const char *format, va_list args, char *end)
195196 int pointflag ;
196197 char func ;
197198 int realpos ;
199+ int longflag ;
200+ int longlongflag ;
198201 } * fmtpar , * * fmtparptr ;
199202
200203 /* Create enough structures to hold all arguments */
@@ -229,12 +232,12 @@ dopr(char *buffer, const char *format, va_list args, char *end)
229232 longflag = longlongflag = pointflag = 0 ;
230233 fmtbegin = format - 1 ;
231234 realpos = 0 ;
232- position = 0 ;
235+ position = precision = 0 ;
233236 nextch :
234237 ch = * format ++ ;
235238 switch (ch )
236239 {
237- case 0 :
240+ case '\0' :
238241 goto performpr ;
239242 case '-' :
240243 ljust = 1 ;
@@ -251,24 +254,29 @@ dopr(char *buffer, const char *format, va_list args, char *end)
251254 case '7' :
252255 case '8' :
253256 case '9' :
254- if (pointflag )
255- /* could also be precision */
256- maxwidth = maxwidth * 10 + ch - '0' ;
257- else
257+ if (!pointflag )
258258 {
259259 len = len * 10 + ch - '0' ;
260260 position = position * 10 + ch - '0' ;
261261 }
262+ else
263+ {
264+ maxwidth = maxwidth * 10 + ch - '0' ;
265+ precision = precision * 10 + ch - '0' ;
266+ }
262267 goto nextch ;
263268 case '$' :
264269 realpos = position ;
265270 len = 0 ;
266271 goto nextch ;
267272 case '*' :
268- if (pointflag )
269- maxwidth = va_arg (args , int );
273+ MemSet (& fmtpar [fmtpos ], 0 , sizeof (fmtpar [fmtpos ]));
274+ if (!pointflag )
275+ fmtpar [fmtpos ].func = FMTLEN ;
270276 else
271- len = va_arg (args , int );
277+ fmtpar [fmtpos ].func = FMTWIDTH ;
278+ fmtpar [fmtpos ].realpos = realpos ?realpos :fmtpos ;
279+ fmtpos ++ ;
272280 goto nextch ;
273281 case '.' :
274282 pointflag = 1 ;
@@ -301,68 +309,40 @@ dopr(char *buffer, const char *format, va_list args, char *end)
301309#endif
302310 case 'u' :
303311 case 'U' :
304- /* fmtnum(value,base,dosign,ljust,len,zpad,&output) */
305- if (longflag )
306- {
307- if (longlongflag )
308- value = va_arg (args , uint64 );
309- else
310- value = va_arg (args , unsigned long );
311- }
312- else
313- value = va_arg (args , unsigned int );
312+ fmtpar [fmtpos ].longflag = longflag ;
313+ fmtpar [fmtpos ].longlongflag = longlongflag ;
314314 fmtpar [fmtpos ].fmtbegin = fmtbegin ;
315315 fmtpar [fmtpos ].fmtend = format ;
316- fmtpar [fmtpos ].numvalue = value ;
317316 fmtpar [fmtpos ].base = 10 ;
318317 fmtpar [fmtpos ].dosign = 0 ;
319318 fmtpar [fmtpos ].ljust = ljust ;
320319 fmtpar [fmtpos ].len = len ;
321320 fmtpar [fmtpos ].zpad = zpad ;
322- fmtpar [fmtpos ].func = FMTNUM ;
321+ fmtpar [fmtpos ].func = FMTNUM_U ;
323322 fmtpar [fmtpos ].realpos = realpos ?realpos :fmtpos ;
324323 fmtpos ++ ;
325324 break ;
326325 case 'o' :
327326 case 'O' :
328- /* fmtnum(value,base,dosign,ljust,len,zpad,&output) */
329- if (longflag )
330- {
331- if (longlongflag )
332- value = va_arg (args , uint64 );
333- else
334- value = va_arg (args , unsigned long );
335- }
336- else
337- value = va_arg (args , unsigned int );
327+ fmtpar [fmtpos ].longflag = longflag ;
328+ fmtpar [fmtpos ].longlongflag = longlongflag ;
338329 fmtpar [fmtpos ].fmtbegin = fmtbegin ;
339330 fmtpar [fmtpos ].fmtend = format ;
340- fmtpar [fmtpos ].numvalue = value ;
341331 fmtpar [fmtpos ].base = 8 ;
342332 fmtpar [fmtpos ].dosign = 0 ;
343333 fmtpar [fmtpos ].ljust = ljust ;
344334 fmtpar [fmtpos ].len = len ;
345335 fmtpar [fmtpos ].zpad = zpad ;
346- fmtpar [fmtpos ].func = FMTNUM ;
336+ fmtpar [fmtpos ].func = FMTNUM_U ;
347337 fmtpar [fmtpos ].realpos = realpos ?realpos :fmtpos ;
348338 fmtpos ++ ;
349339 break ;
350340 case 'd' :
351341 case 'D' :
352- if (longflag )
353- {
354- if (longlongflag )
355- {
356- value = va_arg (args , int64 );
357- }
358- else
359- value = va_arg (args , long );
360- }
361- else
362- value = va_arg (args , int );
342+ fmtpar [fmtpos ].longflag = longflag ;
343+ fmtpar [fmtpos ].longlongflag = longlongflag ;
363344 fmtpar [fmtpos ].fmtbegin = fmtbegin ;
364345 fmtpar [fmtpos ].fmtend = format ;
365- fmtpar [fmtpos ].numvalue = value ;
366346 fmtpar [fmtpos ].base = 10 ;
367347 fmtpar [fmtpos ].dosign = 1 ;
368348 fmtpar [fmtpos ].ljust = ljust ;
@@ -373,72 +353,47 @@ dopr(char *buffer, const char *format, va_list args, char *end)
373353 fmtpos ++ ;
374354 break ;
375355 case 'x' :
376- if (longflag )
377- {
378- if (longlongflag )
379- value = va_arg (args , uint64 );
380- else
381- value = va_arg (args , unsigned long );
382- }
383- else
384- value = va_arg (args , unsigned int );
356+ fmtpar [fmtpos ].longflag = longflag ;
357+ fmtpar [fmtpos ].longlongflag = longlongflag ;
385358 fmtpar [fmtpos ].fmtbegin = fmtbegin ;
386359 fmtpar [fmtpos ].fmtend = format ;
387- fmtpar [fmtpos ].numvalue = value ;
388360 fmtpar [fmtpos ].base = 16 ;
389361 fmtpar [fmtpos ].dosign = 0 ;
390362 fmtpar [fmtpos ].ljust = ljust ;
391363 fmtpar [fmtpos ].len = len ;
392364 fmtpar [fmtpos ].zpad = zpad ;
393- fmtpar [fmtpos ].func = FMTNUM ;
365+ fmtpar [fmtpos ].func = FMTNUM_U ;
394366 fmtpar [fmtpos ].realpos = realpos ?realpos :fmtpos ;
395367 fmtpos ++ ;
396368 break ;
397369 case 'X' :
398- if (longflag )
399- {
400- if (longlongflag )
401- value = va_arg (args , uint64 );
402- else
403- value = va_arg (args , unsigned long );
404- }
405- else
406- value = va_arg (args , unsigned int );
370+ fmtpar [fmtpos ].longflag = longflag ;
371+ fmtpar [fmtpos ].longlongflag = longlongflag ;
407372 fmtpar [fmtpos ].fmtbegin = fmtbegin ;
408373 fmtpar [fmtpos ].fmtend = format ;
409- fmtpar [fmtpos ].numvalue = value ;
410374 fmtpar [fmtpos ].base = -16 ;
411375 fmtpar [fmtpos ].dosign = 1 ;
412376 fmtpar [fmtpos ].ljust = ljust ;
413377 fmtpar [fmtpos ].len = len ;
414378 fmtpar [fmtpos ].zpad = zpad ;
415- fmtpar [fmtpos ].func = FMTNUM ;
379+ fmtpar [fmtpos ].func = FMTNUM_U ;
416380 fmtpar [fmtpos ].realpos = realpos ?realpos :fmtpos ;
417381 fmtpos ++ ;
418382 break ;
419383 case 's' :
420- strvalue = va_arg (args , char * );
421- if (maxwidth > 0 || !pointflag )
422- {
423- if (pointflag && len > maxwidth )
424- len = maxwidth ; /* Adjust padding */
425- fmtpar [fmtpos ].fmtbegin = fmtbegin ;
426- fmtpar [fmtpos ].fmtend = format ;
427- fmtpar [fmtpos ].value = strvalue ;
428- fmtpar [fmtpos ].ljust = ljust ;
429- fmtpar [fmtpos ].len = len ;
430- fmtpar [fmtpos ].zpad = zpad ;
431- fmtpar [fmtpos ].maxwidth = maxwidth ;
432- fmtpar [fmtpos ].func = FMTSTR ;
433- fmtpar [fmtpos ].realpos = realpos ?realpos :fmtpos ;
434- fmtpos ++ ;
435- }
384+ fmtpar [fmtpos ].fmtbegin = fmtbegin ;
385+ fmtpar [fmtpos ].fmtend = format ;
386+ fmtpar [fmtpos ].ljust = ljust ;
387+ fmtpar [fmtpos ].len = len ;
388+ fmtpar [fmtpos ].zpad = zpad ;
389+ fmtpar [fmtpos ].maxwidth = maxwidth ;
390+ fmtpar [fmtpos ].func = FMTSTR ;
391+ fmtpar [fmtpos ].realpos = realpos ?realpos :fmtpos ;
392+ fmtpos ++ ;
436393 break ;
437394 case 'c' :
438- ch = va_arg (args , int );
439395 fmtpar [fmtpos ].fmtbegin = fmtbegin ;
440396 fmtpar [fmtpos ].fmtend = format ;
441- fmtpar [fmtpos ].charvalue = ch ;
442397 fmtpar [fmtpos ].func = FMTCHAR ;
443398 fmtpar [fmtpos ].realpos = realpos ?realpos :fmtpos ;
444399 fmtpos ++ ;
@@ -448,15 +403,13 @@ dopr(char *buffer, const char *format, va_list args, char *end)
448403 case 'f' :
449404 case 'g' :
450405 case 'G' :
451- fvalue = va_arg (args , double );
452406 fmtpar [fmtpos ].fmtbegin = fmtbegin ;
453407 fmtpar [fmtpos ].fmtend = format ;
454- fmtpar [fmtpos ].fvalue = fvalue ;
455408 fmtpar [fmtpos ].type = ch ;
456409 fmtpar [fmtpos ].ljust = ljust ;
457410 fmtpar [fmtpos ].len = len ;
458411 fmtpar [fmtpos ].maxwidth = maxwidth ;
459- fmtpar [fmtpos ].precision = position ;
412+ fmtpar [fmtpos ].precision = precision ;
460413 fmtpar [fmtpos ].pointflag = pointflag ;
461414 fmtpar [fmtpos ].func = FMTFLOAT ;
462415 fmtpar [fmtpos ].realpos = realpos ?realpos :fmtpos ;
@@ -473,22 +426,74 @@ dopr(char *buffer, const char *format, va_list args, char *end)
473426 break ;
474427 }
475428 }
429+
476430performpr :
477- /* shuffle pointers */
431+ /* reorder pointers */
478432 for (i = 1 ; i < fmtpos ; i ++ )
479433 fmtparptr [i ] = & fmtpar [fmtpar [i ].realpos ];
434+
435+ /* assign values */
436+ for (i = 1 ; i < fmtpos ; i ++ ){
437+ switch (fmtparptr [i ]-> func ){
438+ case FMTSTR :
439+ fmtparptr [i ]-> value = va_arg (args , char * );
440+ break ;
441+ case FMTNUM :
442+ if (fmtparptr [i ]-> longflag )
443+ {
444+ if (fmtparptr [i ]-> longlongflag )
445+ fmtparptr [i ]-> numvalue = va_arg (args , int64 );
446+ else
447+ fmtparptr [i ]-> numvalue = va_arg (args , long );
448+ }
449+ else
450+ fmtparptr [i ]-> numvalue = va_arg (args , int );
451+ break ;
452+ case FMTNUM_U :
453+ if (fmtparptr [i ]-> longflag )
454+ {
455+ if (fmtparptr [i ]-> longlongflag )
456+ fmtparptr [i ]-> numvalue = va_arg (args , uint64 );
457+ else
458+ fmtparptr [i ]-> numvalue = va_arg (args , unsigned long );
459+ }
460+ else
461+ fmtparptr [i ]-> numvalue = va_arg (args , unsigned int );
462+ break ;
463+ case FMTFLOAT :
464+ fmtparptr [i ]-> fvalue = va_arg (args , double );
465+ break ;
466+ case FMTCHAR :
467+ fmtparptr [i ]-> charvalue = va_arg (args , int );
468+ break ;
469+ case FMTLEN :
470+ if (i + 1 < fmtpos && fmtpar [i + 1 ].func != FMTWIDTH )
471+ fmtpar [i + 1 ].len = va_arg (args , int );
472+ /* For "%*.*f", use the second arg */
473+ if (i + 2 < fmtpos && fmtpar [i + 1 ].func == FMTWIDTH )
474+ fmtpar [i + 2 ].len = va_arg (args , int );
475+ break ;
476+ case FMTWIDTH :
477+ if (i + 1 < fmtpos )
478+ fmtpar [i + 1 ].maxwidth = fmtpar [i + 1 ].precision =
479+ va_arg (args , int );
480+ break ;
481+ }
482+ }
483+
484+ /* do the output */
480485 output = buffer ;
481486 format = format_save ;
482487 while ((ch = * format ++ ))
483488 {
484489 for (i = 1 ; i < fmtpos ; i ++ )
485490 {
486- if (ch == '%' && * format == '%' )
491+ if (ch == '%' && * format == '%' )
487492 {
488493 format ++ ;
489494 continue ;
490495 }
491- if (fmtpar [i ].fmtbegin == format - 1 )
496+ if (fmtpar [i ].fmtbegin == format - 1 )
492497 {
493498 switch (fmtparptr [i ]-> func ){
494499 case FMTSTR :
@@ -497,6 +502,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
497502 fmtparptr [i ]-> maxwidth , end , & output );
498503 break ;
499504 case FMTNUM :
505+ case FMTNUM_U :
500506 fmtnum (fmtparptr [i ]-> numvalue , fmtparptr [i ]-> base ,
501507 fmtparptr [i ]-> dosign , fmtparptr [i ]-> ljust ,
502508 fmtparptr [i ]-> len , fmtparptr [i ]-> zpad , end , & output );
0 commit comments