Hello all, I would like to submit my changes to src/port/snprintf.c to enable %n$ format placeholder replacement in snprintf() and vsnprintf(). Additionally I implemented a trivial printf().
I also attach a diff for configure.in to include snprintf.o in pgport but I am sure it is not the right thing to do. Could someone give a hint on where I need to place such a definition. Please review my patch. as Tom Lane pointed out there are 150 messages in the following files that do not print properly: src/backend/po/pt_BR.po src/backend/po/de.po src/backend/po/es.po src/backend/po/zh_CN.po src/backend/po/tr.po src/bin/pg_dump/po/zh_CN.po src/bin/pg_dump/po/tr.po src/bin/psql/po/zh_CN.po src/bin/psql/po/zh_TW.po src/bin/psql/po/tr.po src/bin/scripts/po/zh_CN.po we need to fix snprintf.c before next release Best regards, Nicolai Tufar
*** ./src/port/snprintf.c.orig 2005-01-20 01:27:22.000000000 +0200
--- ./src/port/snprintf.c 2005-01-24 03:09:31.000000000 +0200
***************
*** 57,62 ****
--- 57,66 ----
typedef unsigned long ulong_long;
#endif
+ #ifndef NL_ARGMAX
+ #define NL_ARGMAX 4096
+ #endif
+
/*
** SNPRINTF, VSNPRINT -- counted versions of printf
**
***************
*** 85,93 ****
--- 89,115 ----
int snprintf(char *str, size_t count, const char *fmt,...);
int vsnprintf(char *str, size_t count, const char *fmt,
va_list args);
+ int printf(const char *format, ...);
static void dopr(char *buffer, const char *format, va_list args);
int
+ printf(const char *fmt,...)
+ {
+ int len;
+ va_list args;
+ static char* buffer[4096];
+ char* p;
+
+ va_start(args, fmt);
+ len = vsnprintf((char*)buffer, (size_t)4096, fmt, args);
+ va_end(args);
+ p = (char*)buffer;
+ for(;*p;p++)
+ putchar(*p);
+ return len;
+ }
+
+ int
snprintf(char *str, size_t count, const char *fmt,...)
{
int len;
***************
*** 124,129 ****
--- 146,155 ----
static char *output;
+ #define FMTSTR 1
+ #define FMTNUM 2
+ #define FMTFLOAT 3
+ #define FMTCHAR 4
static void
dopr(char *buffer, const char *format, va_list args)
***************
*** 139,145 ****
--- 165,200 ----
int ljust;
int len;
int zpad;
+ int i;
+ const char* format_save;
+ const char* fmtbegin;
+ int fmtpos = 1;
+ int realpos = 0;
+ int position;
+ static struct{
+ const char* fmtbegin;
+ const char* fmtend;
+ union{
+ void* value;
+ long_long numvalue;
+ double fvalue;
+ int charvalue;
+ };
+ int ljust;
+ int len;
+ int zpad;
+ int maxwidth;
+ int base;
+ int dosign;
+ char type;
+ int precision;
+ int pointflag;
+ char func;
+ int realpos;
+ }fmtpar[NL_ARGMAX+1], *fmtparptr[NL_ARGMAX+1];
+
+ format_save = format;
output = buffer;
while ((ch = *format++))
{
***************
*** 148,161 ****
case '%':
ljust = len = zpad = maxwidth = 0;
longflag = longlongflag = pointflag = 0;
nextch:
ch = *format++;
switch (ch)
{
case 0:
! dostr("**end of format**", 0);
! *output = '\0';
! return;
case '-':
ljust = 1;
goto nextch;
--- 203,217 ----
case '%':
ljust = len = zpad = maxwidth = 0;
longflag = longlongflag = pointflag = 0;
+ fmtbegin = format - 1;
+ realpos = 0;
+ position = 0;
nextch:
ch = *format++;
switch (ch)
{
case 0:
! goto performpr;
case '-':
ljust = 1;
goto nextch;
***************
*** 174,180 ****
--- 230,243 ----
if (pointflag)
maxwidth = maxwidth *
10 + ch - '0';
else
+ {
len = len * 10 + ch -
'0';
+ position = position *
10 + ch - '0';
+ }
+ goto nextch;
+ case '$':
+ realpos = position;
+ len = 0;
goto nextch;
case '*':
if (pointflag)
***************
*** 203,209 ****
}
else
value = va_arg(args,
unsigned int);
! fmtnum(value, 10, 0, ljust,
len, zpad);
break;
case 'o':
case 'O':
--- 266,282 ----
}
else
value = va_arg(args,
unsigned int);
! fmtpar[fmtpos].fmtbegin =
fmtbegin;
! fmtpar[fmtpos].fmtend = format;
! fmtpar[fmtpos].numvalue = value;
! fmtpar[fmtpos].base = 10;
! fmtpar[fmtpos].dosign = 0;
! fmtpar[fmtpos].ljust = ljust;
! fmtpar[fmtpos].len = len;
! fmtpar[fmtpos].zpad = zpad;
! fmtpar[fmtpos].func = FMTNUM;
! fmtpar[fmtpos].realpos =
realpos?realpos:fmtpos;
! fmtpos++;
break;
case 'o':
case 'O':
***************
*** 217,223 ****
}
else
value = va_arg(args,
unsigned int);
! fmtnum(value, 8, 0, ljust, len,
zpad);
break;
case 'd':
case 'D':
--- 290,306 ----
}
else
value = va_arg(args,
unsigned int);
! fmtpar[fmtpos].fmtbegin =
fmtbegin;
! fmtpar[fmtpos].fmtend = format;
! fmtpar[fmtpos].numvalue = value;
! fmtpar[fmtpos].base = 8;
! fmtpar[fmtpos].dosign = 0;
! fmtpar[fmtpos].ljust = ljust;
! fmtpar[fmtpos].len = len;
! fmtpar[fmtpos].zpad = zpad;
! fmtpar[fmtpos].func = FMTNUM;
! fmtpar[fmtpos].realpos =
realpos?realpos:fmtpos;
! fmtpos++;
break;
case 'd':
case 'D':
***************
*** 230,236 ****
}
else
value = va_arg(args,
int);
! fmtnum(value, 10, 1, ljust,
len, zpad);
break;
case 'x':
if (longflag)
--- 313,329 ----
}
else
value = va_arg(args,
int);
! fmtpar[fmtpos].fmtbegin =
fmtbegin;
! fmtpar[fmtpos].fmtend = format;
! fmtpar[fmtpos].numvalue = value;
! fmtpar[fmtpos].base = 10;
! fmtpar[fmtpos].dosign = 1;
! fmtpar[fmtpos].ljust = ljust;
! fmtpar[fmtpos].len = len;
! fmtpar[fmtpos].zpad = zpad;
! fmtpar[fmtpos].func = FMTNUM;
! fmtpar[fmtpos].realpos =
realpos?realpos:fmtpos;
! fmtpos++;
break;
case 'x':
if (longflag)
***************
*** 242,248 ****
}
else
value = va_arg(args,
unsigned int);
! fmtnum(value, 16, 0, ljust,
len, zpad);
break;
case 'X':
if (longflag)
--- 335,351 ----
}
else
value = va_arg(args,
unsigned int);
! fmtpar[fmtpos].fmtbegin =
fmtbegin;
! fmtpar[fmtpos].fmtend = format;
! fmtpar[fmtpos].numvalue = value;
! fmtpar[fmtpos].base = 16;
! fmtpar[fmtpos].dosign = 0;
! fmtpar[fmtpos].ljust = ljust;
! fmtpar[fmtpos].len = len;
! fmtpar[fmtpos].zpad = zpad;
! fmtpar[fmtpos].func = FMTNUM;
! fmtpar[fmtpos].realpos =
realpos?realpos:fmtpos;
! fmtpos++;
break;
case 'X':
if (longflag)
***************
*** 254,260 ****
}
else
value = va_arg(args,
unsigned int);
! fmtnum(value, -16, 0, ljust,
len, zpad);
break;
case 's':
strvalue = va_arg(args, char *);
--- 357,373 ----
}
else
value = va_arg(args,
unsigned int);
! fmtpar[fmtpos].fmtbegin =
fmtbegin;
! fmtpar[fmtpos].fmtend = format;
! fmtpar[fmtpos].numvalue = value;
! fmtpar[fmtpos].base = -16;
! fmtpar[fmtpos].dosign = 1;
! fmtpar[fmtpos].ljust = ljust;
! fmtpar[fmtpos].len = len;
! fmtpar[fmtpos].zpad = zpad;
! fmtpar[fmtpos].func = FMTNUM;
! fmtpar[fmtpos].realpos =
realpos?realpos:fmtpos;
! fmtpos++;
break;
case 's':
strvalue = va_arg(args, char *);
***************
*** 262,273 ****
{
if (pointflag && len >
maxwidth)
len = maxwidth;
/* Adjust padding */
! fmtstr(strvalue, ljust,
len, zpad, maxwidth);
}
break;
case 'c':
ch = va_arg(args, int);
! dopr_outch(ch);
break;
case 'e':
case 'E':
--- 375,400 ----
{
if (pointflag && len >
maxwidth)
len = maxwidth;
/* Adjust padding */
! fmtpar[fmtpos].fmtbegin
= fmtbegin;
! fmtpar[fmtpos].fmtend =
format;
! fmtpar[fmtpos].value =
strvalue;
! fmtpar[fmtpos].ljust =
ljust;
! fmtpar[fmtpos].len =
len;
! fmtpar[fmtpos].zpad =
zpad;
! fmtpar[fmtpos].maxwidth
= maxwidth;
! fmtpar[fmtpos].func =
FMTSTR;
! fmtpar[fmtpos].realpos
= realpos?realpos:fmtpos;
! fmtpos++;
}
break;
case 'c':
ch = va_arg(args, int);
! fmtpar[fmtpos].fmtbegin =
fmtbegin;
! fmtpar[fmtpos].fmtend = format;
! fmtpar[fmtpos].charvalue = ch;
! fmtpar[fmtpos].func = FMTCHAR;
! fmtpar[fmtpos].realpos =
realpos?realpos:fmtpos;
! fmtpos++;
break;
case 'e':
case 'E':
***************
*** 275,285 ****
case 'g':
case 'G':
fvalue = va_arg(args, double);
! fmtfloat(fvalue, ch, ljust,
len, maxwidth, pointflag);
break;
case '%':
! dopr_outch(ch);
! continue;
default:
dostr("???????", 0);
}
--- 402,421 ----
case 'g':
case 'G':
fvalue = va_arg(args, double);
! fmtpar[fmtpos].fmtbegin =
fmtbegin;
! fmtpar[fmtpos].fmtend = format;
! fmtpar[fmtpos].fvalue = fvalue;
! fmtpar[fmtpos].type = ch;
! fmtpar[fmtpos].ljust = ljust;
! fmtpar[fmtpos].len = len;
! fmtpar[fmtpos].maxwidth =
maxwidth;
! fmtpar[fmtpos].pointflag =
pointflag;
! fmtpar[fmtpos].func = FMTFLOAT;
! fmtpar[fmtpos].realpos =
realpos?realpos:fmtpos;
! fmtpos++;
break;
case '%':
! break;
default:
dostr("???????", 0);
}
***************
*** 289,294 ****
--- 425,477 ----
break;
}
}
+ performpr:
+ /* shuffle pointers */
+ for(i = 1; i < fmtpos; i++)
+ {
+ fmtparptr[i] = &fmtpar[fmtpar[i].realpos];
+ }
+ output = buffer;
+ format = format_save;
+ while ((ch = *format++))
+ {
+ for(i = 1; i < fmtpos; i++)
+ {
+ if(ch == '%' && *format == '%')
+ {
+ format++;
+ continue;
+ }
+ if(fmtpar[i].fmtbegin == format - 1)
+ {
+ switch(fmtparptr[i]->func){
+ case FMTSTR:
+ fmtstr(fmtparptr[i]->value,
fmtparptr[i]->ljust,
+ fmtparptr[i]->len,
fmtparptr[i]->zpad,
+ fmtparptr[i]->maxwidth);
+ break;
+ case FMTNUM:
+ fmtnum(fmtparptr[i]->numvalue,
fmtparptr[i]->base,
+ fmtparptr[i]->dosign,
fmtparptr[i]->ljust,
+ fmtparptr[i]->len,
fmtparptr[i]->zpad);
+ break;
+ case FMTFLOAT:
+ fmtfloat(fmtparptr[i]->fvalue,
fmtparptr[i]->type,
+ fmtparptr[i]->ljust,
fmtparptr[i]->len,
+ fmtparptr[i]->precision,
fmtparptr[i]->pointflag);
+ break;
+ case FMTCHAR:
+ dopr_outch(fmtparptr[i]->charvalue);
+ break;
+ }
+ format = fmtpar[i].fmtend;
+ goto nochar;
+ }
+ }
+ dopr_outch(ch);
+ nochar:
+ /* nothing */
+ }
*output = '\0';
}
*** ./configure.in.orig 2005-01-30 11:46:36.000000000 +0200
--- ./configure.in 2005-01-30 11:46:49.000000000 +0200
***************
*** 639,644 ****
--- 639,645 ----
if test "$PORTNAME" = "win32"
then
AC_CHECK_LIB(wsock32, main)
+ AC_LIBOBJ(snprintf)
fi
if test "$with_readline" = yes; then
---------------------------(end of broadcast)--------------------------- TIP 8: explain analyze is your friend
