On Thu, 10 Mar 2005 19:21:41 -0500 (EST), Bruce Momjian
<[email protected]> wrote:
> > The CVS-tip implementation is fundamentally broken and won't work even
> > for our internal uses. I've not wasted time complaining about it
> > because I thought we were going to replace it. If we can't find a
> > usable replacement then we're going to have to put a lot of effort
> > into fixing what's there. On the whole I think the effort would be
> > better spent importing someone else's solution.
>
> Oh, so our existing implementation doesn't even meet our needs. OK.
Which made me wander why did I not aggree with
Tom Lane's suggestion to make do three passes
instead of two. Tom was right, as usual. It happened to
be much easier than I expected. The patch is attached.
Please apply.
Tom, what do you think? Will it be fine with you?
Best regards,
Nicolai
*** ./src/port/snprintf.c.orig Sat Mar 12 01:28:49 2005
--- ./src/port/snprintf.c Sat Mar 12 01:08:30 2005
***************
*** 195,200 ****
--- 195,202 ----
int pointflag;
char func;
int realpos;
+ int longflag;
+ int longlongflag;
} *fmtpar, **fmtparptr;
/* Create enough structures to hold all arguments */
***************
*** 263,274 ****
--- 265,278 ----
realpos = position;
len = 0;
goto nextch;
+ /*
case '*':
if (pointflag)
maxwidth = va_arg(args, int);
else
len = va_arg(args, int);
goto nextch;
+ */
case '.':
pointflag = 1;
goto nextch;
***************
*** 300,315 ****
#endif
case 'u':
case 'U':
! /* fmtnum(value,base,dosign,ljust,len,zpad,&output) */
! if (longflag)
! {
! if (longlongflag)
! value = va_arg(args, uint64);
! else
! value = va_arg(args, unsigned long);
! }
! else
! value = va_arg(args, unsigned int);
fmtpar[fmtpos].fmtbegin = fmtbegin;
fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].numvalue = value;
--- 304,311 ----
#endif
case 'u':
case 'U':
! fmtpar[fmtpos].longflag = longflag;
! fmtpar[fmtpos].longlongflag = longlongflag;
fmtpar[fmtpos].fmtbegin = fmtbegin;
fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].numvalue = value;
***************
*** 324,339 ****
break;
case 'o':
case 'O':
! /* fmtnum(value,base,dosign,ljust,len,zpad,&output) */
! if (longflag)
! {
! if (longlongflag)
! value = va_arg(args, uint64);
! else
! value = va_arg(args, unsigned long);
! }
! else
! value = va_arg(args, unsigned int);
fmtpar[fmtpos].fmtbegin = fmtbegin;
fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].numvalue = value;
--- 320,327 ----
break;
case 'o':
case 'O':
! fmtpar[fmtpos].longflag = longflag;
! fmtpar[fmtpos].longlongflag = longlongflag;
fmtpar[fmtpos].fmtbegin = fmtbegin;
fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].numvalue = value;
***************
*** 348,364 ****
break;
case 'd':
case 'D':
! if (longflag)
! {
! if (longlongflag)
! {
! value = va_arg(args, int64);
! }
! else
! value = va_arg(args, long);
! }
! else
! value = va_arg(args, int);
fmtpar[fmtpos].fmtbegin = fmtbegin;
fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].numvalue = value;
--- 336,343 ----
break;
case 'd':
case 'D':
! fmtpar[fmtpos].longflag = longflag;
! fmtpar[fmtpos].longlongflag = longlongflag;
fmtpar[fmtpos].fmtbegin = fmtbegin;
fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].numvalue = value;
***************
*** 372,386 ****
fmtpos++;
break;
case 'x':
! if (longflag)
! {
! if (longlongflag)
! value = va_arg(args, uint64);
! else
! value = va_arg(args, unsigned long);
! }
! else
! value = va_arg(args, unsigned int);
fmtpar[fmtpos].fmtbegin = fmtbegin;
fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].numvalue = value;
--- 351,358 ----
fmtpos++;
break;
case 'x':
! fmtpar[fmtpos].longflag = longflag;
! fmtpar[fmtpos].longlongflag = longlongflag;
fmtpar[fmtpos].fmtbegin = fmtbegin;
fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].numvalue = value;
***************
*** 394,408 ****
fmtpos++;
break;
case 'X':
! if (longflag)
! {
! if (longlongflag)
! value = va_arg(args, uint64);
! else
! value = va_arg(args, unsigned long);
! }
! else
! value = va_arg(args, unsigned int);
fmtpar[fmtpos].fmtbegin = fmtbegin;
fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].numvalue = value;
--- 366,373 ----
fmtpos++;
break;
case 'X':
! fmtpar[fmtpos].longflag = longflag;
! fmtpar[fmtpos].longlongflag = longlongflag;
fmtpar[fmtpos].fmtbegin = fmtbegin;
fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].numvalue = value;
***************
*** 416,422 ****
fmtpos++;
break;
case 's':
- strvalue = va_arg(args, char *);
if (maxwidth > 0 || !pointflag)
{
if (pointflag && len > maxwidth)
--- 381,386 ----
***************
*** 434,440 ****
}
break;
case 'c':
- ch = va_arg(args, int);
fmtpar[fmtpos].fmtbegin = fmtbegin;
fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].charvalue = ch;
--- 398,403 ----
***************
*** 447,453 ****
case 'f':
case 'g':
case 'G':
- fvalue = va_arg(args, double);
fmtpar[fmtpos].fmtbegin = fmtbegin;
fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].fvalue = fvalue;
--- 410,415 ----
***************
*** 455,460 ****
--- 417,423 ----
fmtpar[fmtpos].ljust = ljust;
fmtpar[fmtpos].len = len;
fmtpar[fmtpos].maxwidth = maxwidth;
+ fmtpar[fmtpos].precision = maxwidth;
fmtpar[fmtpos].pointflag = pointflag;
fmtpar[fmtpos].func = FMTFLOAT;
fmtpar[fmtpos].realpos = realpos?realpos:fmtpos;
***************
*** 472,480 ****
}
}
performpr:
! /* shuffle pointers */
for(i = 1; i < fmtpos; i++)
fmtparptr[i] = &fmtpar[fmtpar[i].realpos];
output = buffer;
format = format_save;
while ((ch = *format++))
--- 435,471 ----
}
}
performpr:
! /* reorder pointers */
for(i = 1; i < fmtpos; i++)
fmtparptr[i] = &fmtpar[fmtpar[i].realpos];
+
+ /* assign values */
+ for(i = 1; i < fmtpos; i++){
+ switch(fmtparptr[i]->func){
+ case FMTSTR:
+ fmtparptr[i]->value = va_arg(args, char *);
+ break;
+ case FMTNUM:
+ if (fmtparptr[i]->longflag)
+ {
+ if (fmtparptr[i]->longlongflag)
+ fmtparptr[i]->numvalue = va_arg(args, uint64);
+ else
+ fmtparptr[i]->numvalue = va_arg(args, unsigned long);
+ }
+ else
+ fmtparptr[i]->numvalue = va_arg(args, unsigned int);
+ break;
+ case FMTFLOAT:
+ fmtparptr[i]->fvalue = va_arg(args, double);
+ break;
+ case FMTCHAR:
+ fmtparptr[i]->charvalue = va_arg(args, int);
+ break;
+ }
+ }
+
+ /* do the output */
output = buffer;
format = format_save;
while ((ch = *format++))
---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
joining column's datatypes do not match