Repleacement for src/port/snprintf.c

Started by Nicolai Tufarabout 21 years ago16 messageshackers
Jump to latest
#1Nicolai Tufar
ntufar@gmail.com

Greetings,
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.

Best regards,
Nicolai Tufar

Attachments:

snprintf.difftext/plain; name=snprintf.diffDownload+209-97
configure.in.difftext/plain; name=configure.in.diffDownload+1-0
#2Nicolai Tufar
ntufar@gmail.com
In reply to: Nicolai Tufar (#1)

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

Attachments:

snprintf.difftext/plain; charset=us-ascii; name=snprintf.diffDownload+209-97
configure.in.difftext/plain; charset=us-ascii; name=configure.in.diffDownload+1-0
#3Bruce Momjian
bruce@momjian.us
In reply to: Nicolai Tufar (#2)
Re: [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

Nicolai Tufar wrote:

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:

It took me a while to understand this but I get it now. This is the
best explanation I have seen, from Linux 2.6:

One can also specify explicitly which argument is taken, at each place
where an argument is required, by writing '%m$' instead of '%' and '*m$'
instead of '*', where the decimal integer m denotes the position in the
argument list of the desired argument, indexed starting from 1. Thus,

printf("%*d", width, num);

and

printf("%2$*1$d", width, num);

are equivalent. The second style allows repeated references to the
same argument. The C99 standard does not include the style using '$',
which comes from the Single Unix Specification. If the style using '$'
is used, it must be used throughout for all conversions taking an
argument and all width and precision arguments, but it may be mixed with
'%%' formats which do not consume an argument. There may be no gaps in
the numbers of arguments specified using '$'; for example, if
arguments 1 and 3 are specified, argument 2 must also be specified
somewhere in the format string.

I can see why this would be useful for translations because it uncouples
the order of the printf arguments from the printf string. However, I
have learned that Win32, HP-UX, NetBSD 2.0, and BSD/OS do not support
this. This is probably because it is not in C99 but in SUS (see above).

Anyway, this is too large to put into 8.0, but I am attaching a patch
for 8.1 that has the proper configure tests to check if the C library
supports this behavior. If it does not, the build will use our
port/snprintf.c.

One problem with that is that our snprintf.c is not thread-safe. Seems
the increases use of it will require us to fix this soon. I have added
to TODO:

* Make src/port/snprintf.c thread-safe

One change to the original port is that there was a define of a union
with no name:

+               union{
+                       void*   value;
+                       long_long       numvalue;
+                       double          fvalue;
+                       int             charvalue;
+               };

As far as I know a union with no name is illegal. I just removed the
"union {" and the closing brace.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

Attachments:

/pgpatches/snprintftext/plainDownload+304-97
#4Nicolai Tufar
ntufar@gmail.com
In reply to: Bruce Momjian (#3)
Re: [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

On Sun, 13 Feb 2005 19:06:34 -0500 (EST), Bruce Momjian
<pgman@candle.pha.pa.us> wrote:

Anyway, this is too large to put into 8.0, but I am attaching a patch
for 8.1 that has the proper configure tests to check if the C library
supports this behavior. If it does not, the build will use our
port/snprintf.c.
One problem with that is that our snprintf.c is not thread-safe. Seems
the increases use of it will require us to fix this soon. I have added
to TODO:

* Make src/port/snprintf.c thread-safe

Okay, I am applying your patch to CVS HEAD and
getting hands on making snprintf.c thread-safe. I will
submit a roll up pathch in a day or two.

Regards,
Nicolai

#5Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#3)
Re: [PATCHES] [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

Applied.

---------------------------------------------------------------------------

Bruce Momjian wrote:

Nicolai Tufar wrote:

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:

It took me a while to understand this but I get it now. This is the
best explanation I have seen, from Linux 2.6:

One can also specify explicitly which argument is taken, at each place
where an argument is required, by writing '%m$' instead of '%' and '*m$'
instead of '*', where the decimal integer m denotes the position in the
argument list of the desired argument, indexed starting from 1. Thus,

printf("%*d", width, num);

and

printf("%2$*1$d", width, num);

are equivalent. The second style allows repeated references to the
same argument. The C99 standard does not include the style using '$',
which comes from the Single Unix Specification. If the style using '$'
is used, it must be used throughout for all conversions taking an
argument and all width and precision arguments, but it may be mixed with
'%%' formats which do not consume an argument. There may be no gaps in
the numbers of arguments specified using '$'; for example, if
arguments 1 and 3 are specified, argument 2 must also be specified
somewhere in the format string.

I can see why this would be useful for translations because it uncouples
the order of the printf arguments from the printf string. However, I
have learned that Win32, HP-UX, NetBSD 2.0, and BSD/OS do not support
this. This is probably because it is not in C99 but in SUS (see above).

Anyway, this is too large to put into 8.0, but I am attaching a patch
for 8.1 that has the proper configure tests to check if the C library
supports this behavior. If it does not, the build will use our
port/snprintf.c.

One problem with that is that our snprintf.c is not thread-safe. Seems
the increases use of it will require us to fix this soon. I have added
to TODO:

* Make src/port/snprintf.c thread-safe

One change to the original port is that there was a define of a union
with no name:

+               union{
+                       void*   value;
+                       long_long       numvalue;
+                       double          fvalue;
+                       int             charvalue;
+               };

As far as I know a union with no name is illegal. I just removed the
"union {" and the closing brace.

-- 
Bruce Momjian                        |  http://candle.pha.pa.us
pgman@candle.pha.pa.us               |  (610) 359-1001
+  If your life is a hard drive,     |  13 Roberts Road
+  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
Index: configure
===================================================================
RCS file: /cvsroot/pgsql/configure,v
retrieving revision 1.425
diff -c -c -r1.425 configure
*** configure	18 Jan 2005 05:23:35 -0000	1.425
--- configure	13 Feb 2005 23:50:46 -0000
***************
*** 12162,12167 ****
--- 12162,12224 ----
done
+ echo "$as_me:$LINENO: checking printf supports argument control" >&5
+ echo $ECHO_N "checking printf supports argument control... $ECHO_C" >&6
+ if test "${pgac_cv_printf_arg_control+set}" = set; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   if test "$cross_compiling" = yes; then
+   pgac_cv_printf_arg_control=cross
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+ #include <stdio.h>
+ 
+ int does_printf_have_arg_control()
+ {
+   char buf[100];
+ 
+   /* can it swap arguments? */
+   snprintf(buf, 100, "%2$d|%1$d", 3, 4);
+   if (strcmp(buf, "4|3") != 0)
+     return 0;
+   return 1;
+ }
+ main() {
+   exit(! does_printf_have_arg_control());
+ }
+ _ACEOF
+ rm -f conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+   (eval $ac_link) 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }; }; then
+   pgac_cv_printf_arg_control=yes
+ else
+   echo "$as_me: program exited with status $ac_status" >&5
+ echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ( exit $ac_status )
+ pgac_cv_printf_arg_control=no
+ fi
+ rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ fi
+ 
+ fi
+ echo "$as_me:$LINENO: result: $pgac_cv_printf_arg_control" >&5
+ echo "${ECHO_T}$pgac_cv_printf_arg_control" >&6
+ 
+ # cross compiler should use our snprintf too
+ if test $pgac_cv_printf_arg_control != yes ; then
+   pgac_need_repl_snprintf=yes
+ fi
# Check whether <stdio.h> declares snprintf() and vsnprintf(); if not,
# include/c.h will provide declarations.  Note this is a separate test
Index: configure.in
===================================================================
RCS file: /cvsroot/pgsql/configure.in,v
retrieving revision 1.399
diff -c -c -r1.399 configure.in
*** configure.in	18 Jan 2005 05:23:36 -0000	1.399
--- configure.in	13 Feb 2005 23:50:47 -0000
***************
*** 881,886 ****
--- 881,891 ----
AC_CHECK_FUNCS(snprintf, [], pgac_need_repl_snprintf=yes)
AC_CHECK_FUNCS(vsnprintf, [], pgac_need_repl_snprintf=yes)
+ PGAC_FUNC_PRINTF_ARG_CONTROL
+ # cross compiler should use our snprintf too
+ if test $pgac_cv_printf_arg_control != yes ; then
+   pgac_need_repl_snprintf=yes
+ fi
# Check whether <stdio.h> declares snprintf() and vsnprintf(); if not,
# include/c.h will provide declarations.  Note this is a separate test
***************
*** 1069,1074 ****
--- 1074,1081 ----
[AC_MSG_RESULT([cross-compiling])])
+ dnl  64-bit section
+ dnl
dnl Check to see if we have a working 64-bit integer type.
dnl This breaks down into two steps:
dnl (1) figure out if the compiler has a 64-bit int type with working
Index: config/c-library.m4
===================================================================
RCS file: /cvsroot/pgsql/config/c-library.m4,v
retrieving revision 1.29
diff -c -c -r1.29 c-library.m4
*** config/c-library.m4	16 Dec 2004 17:48:26 -0000	1.29
--- config/c-library.m4	13 Feb 2005 23:50:48 -0000
***************
*** 266,268 ****
--- 266,301 ----
LONG_LONG_INT_FORMAT=$pgac_cv_snprintf_long_long_int_format;;
*)     AC_MSG_RESULT(none);;
esac])# PGAC_FUNC_SNPRINTF_LONG_LONG_INT_FORMAT
+ 
+ 
+ # PGAC_FUNC_PRINTF_ARG_CONTROL
+ # ---------------------------------------
+ # Determine if printf supports %1$ argument selection, e.g. %5$ selects
+ # the fifth argument after the printf print string.
+ # This is not in the C99 standard, but in the Single Unix Specification (SUS).
+ # It is used in our langauge translation strings.
+ #
+ AC_DEFUN([PGAC_FUNC_PRINTF_ARG_CONTROL],
+ [AC_MSG_CHECKING([printf supports argument control])
+ AC_CACHE_VAL(pgac_cv_printf_arg_control,
+ [AC_TRY_RUN([#include <stdio.h>
+ 
+ int does_printf_have_arg_control()
+ {
+   char buf[100];
+ 
+   /* can it swap arguments? */
+   snprintf(buf, 100, "%2$d|%1$d", 3, 4);
+   if (strcmp(buf, "4|3") != 0)
+     return 0;
+   return 1;
+ }
+ main() {
+   exit(! does_printf_have_arg_control());
+ }],
+ [pgac_cv_printf_arg_control=yes],
+ [pgac_cv_printf_arg_control=no],
+ [pgac_cv_printf_arg_control=cross])
+ ])dnl AC_CACHE_VAL
+ AC_MSG_RESULT([$pgac_cv_printf_arg_control])
+ ])# PGAC_FUNC_PRINTF_ARG_CONTROL
Index: src/port/snprintf.c
===================================================================
RCS file: /cvsroot/pgsql/src/port/snprintf.c,v
retrieving revision 1.4
diff -c -c -r1.4 snprintf.c
*** src/port/snprintf.c	29 Aug 2004 05:07:02 -0000	1.4
--- src/port/snprintf.c	13 Feb 2005 23:50:56 -0000
***************
*** 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,198 ----
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;
+ 		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;
--- 201,215 ----
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 ****
--- 228,241 ----
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':
--- 264,280 ----
}
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':
--- 288,304 ----
}
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)
--- 311,327 ----
}
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)
--- 333,349 ----
}
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 *);
--- 355,371 ----
}
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':
--- 373,398 ----
{
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);
}
--- 400,419 ----
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 ****
--- 423,475 ----
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';
}

---------------------------(end of broadcast)---------------------------
TIP 2: you can get off all lists at once with the unregister command
(send "unregister YourEmailAddressHere" to majordomo@postgresql.org)

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
#6Kurt Roeckx
kurt@roeckx.be
In reply to: Bruce Momjian (#5)
Re: [PATCHES] [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

On Mon, Feb 21, 2005 at 10:53:08PM -0500, Bruce Momjian wrote:

Applied.

The configure test is a little broken. It needs to quote the
$'s.

I've rewritten the test a little.

Kurt

Attachments:

print.difftext/plain; charset=us-asciiDownload+6-8
#7Nicolai Tufar
ntufar@gmail.com
In reply to: Kurt Roeckx (#6)
Re: Repleacement for src/port/snprintf.c

On Mon, Feb 21, 2005 at 10:53:08PM -0500, Bruce Momjian wrote:

Applied.

Thanks a lot. The patch attached solves the tread
safety problem. Please review it before applying,
I am not sure I am doing the right thing

On Tue, 22 Feb 2005 19:57:15 +0100, Kurt Roeckx <kurt@roeckx.be> wrote:

The configure test is a little broken. It needs to quote the
$'s.

I've rewritten the test a little.

This one needs applying too. $'s do get scrambled.

Best regards,
Nicolai.

Attachments:

snprintf.difftext/x-patch; name=snprintf.diffDownload+75-78
#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Kurt Roeckx (#6)
Re: [PATCHES] [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

Kurt Roeckx <kurt@roeckx.be> writes:

The configure test is a little broken. It needs to quote the
$'s.

I've rewritten the test a little.

Applied, thanks.

regards, tom lane

#9Bruce Momjian
bruce@momjian.us
In reply to: Kurt Roeckx (#6)
Re: [PATCHES] [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

Oh, thanks. That is a great fix. Applied. Glad you could test it on a
machine that supports positional parameters.

---------------------------------------------------------------------------

Kurt Roeckx wrote:

On Mon, Feb 21, 2005 at 10:53:08PM -0500, Bruce Momjian wrote:

Applied.

The configure test is a little broken. It needs to quote the
$'s.

I've rewritten the test a little.

Kurt

[ Attachment, skipping... ]

---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
#10Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#8)
Re: [PATCHES] [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

Tom Lane wrote:

Kurt Roeckx <kurt@roeckx.be> writes:

The configure test is a little broken. It needs to quote the
$'s.

I've rewritten the test a little.

Applied, thanks.

Oops, Tom got to it first. (Darn!) :-)

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
#11Bruce Momjian
bruce@momjian.us
In reply to: Nicolai Tufar (#7)
Re: [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

Your patch has been added to the PostgreSQL unapplied patches list at:

http://momjian.postgresql.org/cgi-bin/pgpatches

It will be applied as soon as one of the PostgreSQL committers reviews
and approves it.

---------------------------------------------------------------------------

Nicolai Tufar wrote:

On Mon, Feb 21, 2005 at 10:53:08PM -0500, Bruce Momjian wrote:

Applied.

Thanks a lot. The patch attached solves the tread
safety problem. Please review it before applying,
I am not sure I am doing the right thing

On Tue, 22 Feb 2005 19:57:15 +0100, Kurt Roeckx <kurt@roeckx.be> wrote:

The configure test is a little broken. It needs to quote the
$'s.

I've rewritten the test a little.

This one needs applying too. $'s do get scrambled.

Best regards,
Nicolai.

[ Attachment, skipping... ]

---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
#12Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#11)
Re: [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

Bruce Momjian <pgman@candle.pha.pa.us> writes:

Your patch has been added to the PostgreSQL unapplied patches list at:

Didn't we do that already?

regards, tom lane

#13Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#12)
Re: [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

Your patch has been added to the PostgreSQL unapplied patches list at:

Didn't we do that already?

This patch is for thread safety:

Thanks a lot. The patch attached solves the tread
safety problem. Please review it before applying,
I am not sure I am doing the right thing

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
#14Nicolai Tufar
ntufar@gmail.com
In reply to: Tom Lane (#12)
Re: [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

On Thu, 24 Feb 2005 22:18:11 -0500, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Didn't we do that already?

No :( I promised to do it a couple of weeks ago but could not get to do it.
Now with Magnus's help I finaly did it. The last patch should be fine.

regards, tom lane

Nicolai

#15Bruce Momjian
bruce@momjian.us
In reply to: Nicolai Tufar (#7)
Re: [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

Would you please check current CVS? I think I addressed most of these
issues already.

---------------------------------------------------------------------------

Nicolai Tufar wrote:

On Mon, Feb 21, 2005 at 10:53:08PM -0500, Bruce Momjian wrote:

Applied.

Thanks a lot. The patch attached solves the tread
safety problem. Please review it before applying,
I am not sure I am doing the right thing

On Tue, 22 Feb 2005 19:57:15 +0100, Kurt Roeckx <kurt@roeckx.be> wrote:

The configure test is a little broken. It needs to quote the
$'s.

I've rewritten the test a little.

This one needs applying too. $'s do get scrambled.

Best regards,
Nicolai.

[ Attachment, skipping... ]

---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
#16Bruce Momjian
bruce@momjian.us
In reply to: Nicolai Tufar (#7)
Re: [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

I have reviewed this patch, and I already added these changes myself in
CVS.

Thanks.

---------------------------------------------------------------------------

Nicolai Tufar wrote:

On Mon, Feb 21, 2005 at 10:53:08PM -0500, Bruce Momjian wrote:

Applied.

Thanks a lot. The patch attached solves the tread
safety problem. Please review it before applying,
I am not sure I am doing the right thing

On Tue, 22 Feb 2005 19:57:15 +0100, Kurt Roeckx <kurt@roeckx.be> wrote:

The configure test is a little broken. It needs to quote the
$'s.

I've rewritten the test a little.

This one needs applying too. $'s do get scrambled.

Best regards,
Nicolai.

[ Attachment, skipping... ]

---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073