Thread: Repleacement for src/port/snprintf.c

Repleacement for src/port/snprintf.c

From
Nicolai Tufar
Date:
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

Attachment

Repleacement for src/port/snprintf.c

From
Nicolai Tufar
Date:
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

Attachment

Re: [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

From
Bruce Momjian
Date:
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';
  }


Re: [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

From
Nicolai Tufar
Date:
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

Re: [PATCHES] [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

From
Bruce Momjian
Date:
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

Re: Repleacement for src/port/snprintf.c

From
Nicolai Tufar
Date:
> 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

Re: [PATCHES] [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

From
Kurt Roeckx
Date:
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

Re: [PATCHES] [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

From
Tom Lane
Date:
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

Re: [PATCHES] [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

From
Bruce Momjian
Date:
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

Re: [PATCHES] [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

From
Bruce Momjian
Date:
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

Re: [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

From
Bruce Momjian
Date:
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

Re: [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

From
Tom Lane
Date:
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

Re: [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

From
Bruce Momjian
Date:
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

Re: [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

From
Nicolai Tufar
Date:
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

Re: [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

From
Bruce Momjian
Date:
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

Re: [pgsql-hackers-win32] Repleacement for src/port/snprintf.c

From
Bruce Momjian
Date:
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