On Thu, 10 Mar 2005 19:21:41 -0500 (EST), Bruce Momjian
<pgman@candle.pha.pa.us> 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

Reply via email to