Re: Numeric 508 datatype - Mailing list pgsql-patches

From Bruce Momjian
Subject Re: Numeric 508 datatype
Date
Msg-id 200512030425.jB34PNR04389@candle.pha.pa.us
Whole thread Raw
In response to Re: Numeric 508 datatype  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Numeric 508 datatype
port/snprintf.c (was Re: Numeric 508 datatype)
List pgsql-patches
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > Yep, I am digging through snprintf.c now to try find a solution.
>
> The cleanest solution is probably to fix things so that dopr_outch is
> aware of whether it's working for sprintf or fprintf, and can dump the
> buffer directly to the file when it gets full in the fprintf case.
> Its existing API would need to be changed a bit ... maybe pass it a
> struct containing what it needs, instead of having all the layers of
> code know what to pass.

OK, snprintf.c fixed.  I added a 'stream' and outlen parameter to all
the calls, and cleaned up the switch() statement that was outputing
twice.  When we were outputing just to a string, it didn't matter, but
now that we are also outputting to a stream, it does.

Passed regression and initdb tests, and factorial(4000) works!

(I could have done the struct but that seemed too invasive.)

--
  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: src/port/snprintf.c
===================================================================
RCS file: /cvsroot/pgsql/src/port/snprintf.c,v
retrieving revision 1.29
diff -c -c -r1.29 snprintf.c
*** src/port/snprintf.c    15 Oct 2005 02:49:51 -0000    1.29
--- src/port/snprintf.c    3 Dec 2005 04:23:00 -0000
***************
*** 64,70 ****

  /*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.29 2005/10/15 02:49:51 momjian Exp $";*/

! static void dopr(char *buffer, const char *format, va_list args, char *end);

  /* Prevent recursion */
  #undef    vsnprintf
--- 64,70 ----

  /*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.29 2005/10/15 02:49:51 momjian Exp $";*/

! static int dopr(FILE *stream, char *buffer, const char *format, va_list args, char *end);

  /* Prevent recursion */
  #undef    vsnprintf
***************
*** 73,89 ****
  #undef    fprintf
  #undef    printf

! int
! pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
  {
      char       *end;

!     str[0] = '\0';
!     end = str + count - 1;
!     dopr(str, fmt, args, end);
!     if (count > 0)
          end[0] = '\0';
!     return strlen(str);
  }

  int
--- 73,100 ----
  #undef    fprintf
  #undef    printf

!
! static int
! pg_fvsnprintf(FILE *stream, char *str, size_t count, const char *fmt, va_list args)
  {
      char       *end;
+     int            len;

!     if (str)
!     {
!         str[0] = '\0';
!         end = str + count - 1;
!     }
!     len = dopr(stream, str, fmt, args, end);
!     if (str && count > 0)
          end[0] = '\0';
!     return len;
! }
!
! int
! pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
! {
!     return pg_fvsnprintf(NULL, str, count, fmt, args);
  }

  int
***************
*** 93,99 ****
      va_list        args;

      va_start(args, fmt);
!     len = pg_vsnprintf(str, count, fmt, args);
      va_end(args);
      return len;
  }
--- 104,110 ----
      va_list        args;

      va_start(args, fmt);
!     len = pg_fvsnprintf(NULL, str, count, fmt, args);
      va_end(args);
      return len;
  }
***************
*** 103,115 ****
  {
      int            len;
      va_list        args;
!     char        buffer[4096];

      va_start(args, fmt);
!     len = pg_vsnprintf(buffer, (size_t) 4096, fmt, args);
      va_end(args);
      /* limit output to string */
!     StrNCpy(str, buffer, (len + 1 < 4096) ? len + 1 : 4096);
      return len;
  }

--- 114,126 ----
  {
      int            len;
      va_list        args;
!     char        buffer[8192];    /* arbitrary limit */

      va_start(args, fmt);
!     len = pg_fvsnprintf(NULL, buffer, (size_t) 4096, fmt, args);
      va_end(args);
      /* limit output to string */
!     StrNCpy(str, buffer, (len + 1 < 8192) ? len + 1 : 8192);
      return len;
  }

***************
*** 118,131 ****
  {
      int            len;
      va_list        args;
-     char        buffer[4096];
-     char       *p;

      va_start(args, fmt);
!     len = pg_vsnprintf(buffer, (size_t) 4096, fmt, args);
      va_end(args);
-     for (p = buffer; *p; p++)
-         putc(*p, stream);
      return len;
  }

--- 129,138 ----
  {
      int            len;
      va_list        args;

      va_start(args, fmt);
!     len = pg_fvsnprintf(stream, NULL, 0, fmt, args);
      va_end(args);
      return len;
  }

***************
*** 134,166 ****
  {
      int            len;
      va_list        args;
-     char        buffer[4096];
-     char       *p;

      va_start(args, fmt);
!     len = pg_vsnprintf(buffer, (size_t) 4096, fmt, args);
      va_end(args);

-     for (p = buffer; *p; p++)
-         putchar(*p);
      return len;
  }

  static int    adjust_sign(int is_negative, int forcesign, int *signvalue);
  static void adjust_padlen(int minlen, int vallen, int leftjust, int *padlen);
  static void leading_pad(int zpad, int *signvalue, int *padlen, char *end,
!             char **output);
! static void trailing_pad(int *padlen, char *end, char **output);

  static void fmtstr(char *value, int leftjust, int minlen, int maxwidth,
!        char *end, char **output);
  static void fmtint(int64 value, int base, int dosign, int forcesign,
!        int leftjust, int minlen, int zpad, char *end, char **output);
  static void fmtfloat(double value, char type, int forcesign,
   int leftjust, int minlen, int zpad, int precision, int pointflag, char *end,
!          char **output);
! static void dostr(char *str, int cut, char *end, char **output);
! static void dopr_outch(int c, char *end, char **output);

  #define FMTSTR        1
  #define FMTNUM        2
--- 141,172 ----
  {
      int            len;
      va_list        args;

      va_start(args, fmt);
!     len = pg_fvsnprintf(stdout, NULL, 0, fmt, args);
      va_end(args);

      return len;
  }

  static int    adjust_sign(int is_negative, int forcesign, int *signvalue);
  static void adjust_padlen(int minlen, int vallen, int leftjust, int *padlen);
  static void leading_pad(int zpad, int *signvalue, int *padlen, char *end,
!             char **output, FILE *stream, int *outlen);
! static void trailing_pad(int *padlen, char *end, char **output,
!                          FILE *stream, int *outlen);

  static void fmtstr(char *value, int leftjust, int minlen, int maxwidth,
!        char *end, char **output, FILE *stream, int *outlen);
  static void fmtint(int64 value, int base, int dosign, int forcesign,
!        int leftjust, int minlen, int zpad, char *end, char **output,
!        FILE *stream, int *outlen);
  static void fmtfloat(double value, char type, int forcesign,
   int leftjust, int minlen, int zpad, int precision, int pointflag, char *end,
!          char **output, FILE *stream, int *outlen);
! static void dostr(char *str, int cut, char *end, char **output, FILE *stream,
!                   int *outlen);
! static void dopr_outch(int c, char *end, char **output, FILE *stream, int *outlen);

  #define FMTSTR        1
  #define FMTNUM        2
***************
*** 174,181 ****
   * dopr(): poor man's version of doprintf
   */

! static void
! dopr(char *buffer, const char *format, va_list args, char *end)
  {
      int            ch;
      int            longlongflag;
--- 180,187 ----
   * dopr(): poor man's version of doprintf
   */

! static int
! dopr(FILE *stream, char *buffer, const char *format, va_list args, char *end)
  {
      int            ch;
      int            longlongflag;
***************
*** 195,200 ****
--- 201,207 ----
      int            position;
      char       *output;
      int            nargs = 1;
+     int            outlen = 0;
      const char *p;
      struct fmtpar
      {
***************
*** 246,463 ****
      output = buffer;
      while ((ch = *format++))
      {
!         switch (ch)
          {
!             case '%':
!                 leftjust = minlen = zpad = forcesign = maxwidth = 0;
!                 longflag = longlongflag = pointflag = 0;
!                 fmtbegin = format - 1;
!                 realpos = 0;
!                 position = precision = 0;
!         nextch:
!                 ch = *format++;
!                 switch (ch)
!                 {
!                     case '\0':
!                         goto performpr;
!                     case '-':
!                         leftjust = 1;
!                         goto nextch;
!                     case '+':
!                         forcesign = 1;
!                         goto nextch;
!                     case '0':    /* set zero padding if minlen not set */
!                         if (minlen == 0 && !pointflag)
!                             zpad = '0';
!                     case '1':
!                     case '2':
!                     case '3':
!                     case '4':
!                     case '5':
!                     case '6':
!                     case '7':
!                     case '8':
!                     case '9':
!                         if (!pointflag)
!                         {
!                             minlen = minlen * 10 + ch - '0';
!                             position = position * 10 + ch - '0';
!                         }
!                         else
!                         {
!                             maxwidth = maxwidth * 10 + ch - '0';
!                             precision = precision * 10 + ch - '0';
!                         }
!                         goto nextch;
!                     case '$':
!                         realpos = position;
!                         minlen = 0;
!                         goto nextch;
!                     case '*':
!                         MemSet(&fmtpar[fmtpos], 0, sizeof(fmtpar[fmtpos]));
!                         if (!pointflag)
!                             fmtpar[fmtpos].func = FMTLEN;
!                         else
!                             fmtpar[fmtpos].func = FMTWIDTH;
!                         fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                         fmtpos++;
!                         goto nextch;
!                     case '.':
!                         pointflag = 1;
!                         goto nextch;
!                     case 'l':
!                         if (longflag)
!                             longlongflag = 1;
!                         else
!                             longflag = 1;
!                         goto nextch;
!                     case 'h':
!                         /* ignore */
!                         goto nextch;
  #ifdef NOT_USED

!                         /*
!                          * We might export this to client apps so we should
!                          * support 'qd' and 'I64d'(MinGW) also in case the
!                          * native version does.
!                          */
!                     case 'q':
                          longlongflag = 1;
                          longflag = 1;
                          goto nextch;
!                     case 'I':
!                         if (*format == '6' && *(format + 1) == '4')
!                         {
!                             format += 2;
!                             longlongflag = 1;
!                             longflag = 1;
!                             goto nextch;
!                         }
!                         break;
  #endif
!                     case 'u':
!                     case 'U':
!                         fmtpar[fmtpos].longflag = longflag;
!                         fmtpar[fmtpos].longlongflag = longlongflag;
!                         fmtpar[fmtpos].fmtbegin = fmtbegin;
!                         fmtpar[fmtpos].fmtend = format;
!                         fmtpar[fmtpos].base = 10;
!                         fmtpar[fmtpos].dosign = 0;
!                         fmtpar[fmtpos].forcesign = forcesign;
!                         fmtpar[fmtpos].leftjust = leftjust;
!                         fmtpar[fmtpos].minlen = minlen;
!                         fmtpar[fmtpos].zpad = zpad;
!                         fmtpar[fmtpos].func = FMTNUM_U;
!                         fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                         fmtpos++;
!                         break;
!                     case 'o':
!                     case 'O':
!                         fmtpar[fmtpos].longflag = longflag;
!                         fmtpar[fmtpos].longlongflag = longlongflag;
!                         fmtpar[fmtpos].fmtbegin = fmtbegin;
!                         fmtpar[fmtpos].fmtend = format;
!                         fmtpar[fmtpos].base = 8;
!                         fmtpar[fmtpos].dosign = 0;
!                         fmtpar[fmtpos].forcesign = forcesign;
!                         fmtpar[fmtpos].leftjust = leftjust;
!                         fmtpar[fmtpos].minlen = minlen;
!                         fmtpar[fmtpos].zpad = zpad;
!                         fmtpar[fmtpos].func = FMTNUM_U;
!                         fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                         fmtpos++;
!                         break;
!                     case 'd':
!                     case 'D':
!                         fmtpar[fmtpos].longflag = longflag;
!                         fmtpar[fmtpos].longlongflag = longlongflag;
!                         fmtpar[fmtpos].fmtbegin = fmtbegin;
!                         fmtpar[fmtpos].fmtend = format;
!                         fmtpar[fmtpos].base = 10;
!                         fmtpar[fmtpos].dosign = 1;
!                         fmtpar[fmtpos].forcesign = forcesign;
!                         fmtpar[fmtpos].leftjust = leftjust;
!                         fmtpar[fmtpos].minlen = minlen;
!                         fmtpar[fmtpos].zpad = zpad;
!                         fmtpar[fmtpos].func = FMTNUM;
!                         fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                         fmtpos++;
!                         break;
!                     case 'x':
!                         fmtpar[fmtpos].longflag = longflag;
!                         fmtpar[fmtpos].longlongflag = longlongflag;
!                         fmtpar[fmtpos].fmtbegin = fmtbegin;
!                         fmtpar[fmtpos].fmtend = format;
!                         fmtpar[fmtpos].base = 16;
!                         fmtpar[fmtpos].dosign = 0;
!                         fmtpar[fmtpos].forcesign = forcesign;
!                         fmtpar[fmtpos].leftjust = leftjust;
!                         fmtpar[fmtpos].minlen = minlen;
!                         fmtpar[fmtpos].zpad = zpad;
!                         fmtpar[fmtpos].func = FMTNUM_U;
!                         fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                         fmtpos++;
!                         break;
!                     case 'X':
!                         fmtpar[fmtpos].longflag = longflag;
!                         fmtpar[fmtpos].longlongflag = longlongflag;
!                         fmtpar[fmtpos].fmtbegin = fmtbegin;
!                         fmtpar[fmtpos].fmtend = format;
!                         fmtpar[fmtpos].base = -16;
!                         fmtpar[fmtpos].dosign = 1;
!                         fmtpar[fmtpos].forcesign = forcesign;
!                         fmtpar[fmtpos].leftjust = leftjust;
!                         fmtpar[fmtpos].minlen = minlen;
!                         fmtpar[fmtpos].zpad = zpad;
!                         fmtpar[fmtpos].func = FMTNUM_U;
!                         fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                         fmtpos++;
!                         break;
!                     case 's':
!                         fmtpar[fmtpos].fmtbegin = fmtbegin;
!                         fmtpar[fmtpos].fmtend = format;
!                         fmtpar[fmtpos].leftjust = leftjust;
!                         fmtpar[fmtpos].minlen = minlen;
!                         fmtpar[fmtpos].zpad = zpad;
!                         fmtpar[fmtpos].maxwidth = maxwidth;
!                         fmtpar[fmtpos].func = FMTSTR;
!                         fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                         fmtpos++;
!                         break;
!                     case 'c':
!                         fmtpar[fmtpos].fmtbegin = fmtbegin;
!                         fmtpar[fmtpos].fmtend = format;
!                         fmtpar[fmtpos].func = FMTCHAR;
!                         fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                         fmtpos++;
!                         break;
!                     case 'e':
!                     case 'E':
!                     case 'f':
!                     case 'g':
!                     case 'G':
!                         fmtpar[fmtpos].fmtbegin = fmtbegin;
!                         fmtpar[fmtpos].fmtend = format;
!                         fmtpar[fmtpos].type = ch;
!                         fmtpar[fmtpos].forcesign = forcesign;
!                         fmtpar[fmtpos].leftjust = leftjust;
!                         fmtpar[fmtpos].minlen = minlen;
!                         fmtpar[fmtpos].zpad = zpad;
!                         fmtpar[fmtpos].precision = precision;
!                         fmtpar[fmtpos].pointflag = pointflag;
!                         fmtpar[fmtpos].func = FMTFLOAT;
!                         fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                         fmtpos++;
!                         break;
!                     case '%':
!                         break;
!                     default:
!                         dostr("???????", 0, end, &output);
!                 }
!                 break;
!             default:
!                 dopr_outch(ch, end, &output);
!                 break;
          }
      }

--- 253,463 ----
      output = buffer;
      while ((ch = *format++))
      {
!         if (ch == '%')
          {
!             leftjust = minlen = zpad = forcesign = maxwidth = 0;
!             longflag = longlongflag = pointflag = 0;
!             fmtbegin = format - 1;
!             realpos = 0;
!             position = precision = 0;
!     nextch:
!             ch = *format++;
!             switch (ch)
!             {
!                 case '\0':
!                     goto performpr;
!                 case '-':
!                     leftjust = 1;
!                     goto nextch;
!                 case '+':
!                     forcesign = 1;
!                     goto nextch;
!                 case '0':    /* set zero padding if minlen not set */
!                     if (minlen == 0 && !pointflag)
!                         zpad = '0';
!                 case '1':
!                 case '2':
!                 case '3':
!                 case '4':
!                 case '5':
!                 case '6':
!                 case '7':
!                 case '8':
!                 case '9':
!                     if (!pointflag)
!                     {
!                         minlen = minlen * 10 + ch - '0';
!                         position = position * 10 + ch - '0';
!                     }
!                     else
!                     {
!                         maxwidth = maxwidth * 10 + ch - '0';
!                         precision = precision * 10 + ch - '0';
!                     }
!                     goto nextch;
!                 case '$':
!                     realpos = position;
!                     minlen = 0;
!                     goto nextch;
!                 case '*':
!                     MemSet(&fmtpar[fmtpos], 0, sizeof(fmtpar[fmtpos]));
!                     if (!pointflag)
!                         fmtpar[fmtpos].func = FMTLEN;
!                     else
!                         fmtpar[fmtpos].func = FMTWIDTH;
!                     fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                     fmtpos++;
!                     goto nextch;
!                 case '.':
!                     pointflag = 1;
!                     goto nextch;
!                 case 'l':
!                     if (longflag)
!                         longlongflag = 1;
!                     else
!                         longflag = 1;
!                     goto nextch;
!                 case 'h':
!                     /* ignore */
!                     goto nextch;
  #ifdef NOT_USED

!                     /*
!                      * We might export this to client apps so we should
!                      * support 'qd' and 'I64d'(MinGW) also in case the
!                      * native version does.
!                      */
!                 case 'q':
!                     longlongflag = 1;
!                     longflag = 1;
!                     goto nextch;
!                 case 'I':
!                     if (*format == '6' && *(format + 1) == '4')
!                     {
!                         format += 2;
                          longlongflag = 1;
                          longflag = 1;
                          goto nextch;
!                     }
!                     break;
  #endif
!                 case 'u':
!                 case 'U':
!                     fmtpar[fmtpos].longflag = longflag;
!                     fmtpar[fmtpos].longlongflag = longlongflag;
!                     fmtpar[fmtpos].fmtbegin = fmtbegin;
!                     fmtpar[fmtpos].fmtend = format;
!                     fmtpar[fmtpos].base = 10;
!                     fmtpar[fmtpos].dosign = 0;
!                     fmtpar[fmtpos].forcesign = forcesign;
!                     fmtpar[fmtpos].leftjust = leftjust;
!                     fmtpar[fmtpos].minlen = minlen;
!                     fmtpar[fmtpos].zpad = zpad;
!                     fmtpar[fmtpos].func = FMTNUM_U;
!                     fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                     fmtpos++;
!                     break;
!                 case 'o':
!                 case 'O':
!                     fmtpar[fmtpos].longflag = longflag;
!                     fmtpar[fmtpos].longlongflag = longlongflag;
!                     fmtpar[fmtpos].fmtbegin = fmtbegin;
!                     fmtpar[fmtpos].fmtend = format;
!                     fmtpar[fmtpos].base = 8;
!                     fmtpar[fmtpos].dosign = 0;
!                     fmtpar[fmtpos].forcesign = forcesign;
!                     fmtpar[fmtpos].leftjust = leftjust;
!                     fmtpar[fmtpos].minlen = minlen;
!                     fmtpar[fmtpos].zpad = zpad;
!                     fmtpar[fmtpos].func = FMTNUM_U;
!                     fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                     fmtpos++;
!                     break;
!                 case 'd':
!                 case 'D':
!                     fmtpar[fmtpos].longflag = longflag;
!                     fmtpar[fmtpos].longlongflag = longlongflag;
!                     fmtpar[fmtpos].fmtbegin = fmtbegin;
!                     fmtpar[fmtpos].fmtend = format;
!                     fmtpar[fmtpos].base = 10;
!                     fmtpar[fmtpos].dosign = 1;
!                     fmtpar[fmtpos].forcesign = forcesign;
!                     fmtpar[fmtpos].leftjust = leftjust;
!                     fmtpar[fmtpos].minlen = minlen;
!                     fmtpar[fmtpos].zpad = zpad;
!                     fmtpar[fmtpos].func = FMTNUM;
!                     fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                     fmtpos++;
!                     break;
!                 case 'x':
!                     fmtpar[fmtpos].longflag = longflag;
!                     fmtpar[fmtpos].longlongflag = longlongflag;
!                     fmtpar[fmtpos].fmtbegin = fmtbegin;
!                     fmtpar[fmtpos].fmtend = format;
!                     fmtpar[fmtpos].base = 16;
!                     fmtpar[fmtpos].dosign = 0;
!                     fmtpar[fmtpos].forcesign = forcesign;
!                     fmtpar[fmtpos].leftjust = leftjust;
!                     fmtpar[fmtpos].minlen = minlen;
!                     fmtpar[fmtpos].zpad = zpad;
!                     fmtpar[fmtpos].func = FMTNUM_U;
!                     fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                     fmtpos++;
!                     break;
!                 case 'X':
!                     fmtpar[fmtpos].longflag = longflag;
!                     fmtpar[fmtpos].longlongflag = longlongflag;
!                     fmtpar[fmtpos].fmtbegin = fmtbegin;
!                     fmtpar[fmtpos].fmtend = format;
!                     fmtpar[fmtpos].base = -16;
!                     fmtpar[fmtpos].dosign = 1;
!                     fmtpar[fmtpos].forcesign = forcesign;
!                     fmtpar[fmtpos].leftjust = leftjust;
!                     fmtpar[fmtpos].minlen = minlen;
!                     fmtpar[fmtpos].zpad = zpad;
!                     fmtpar[fmtpos].func = FMTNUM_U;
!                     fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                     fmtpos++;
!                     break;
!                 case 's':
!                     fmtpar[fmtpos].fmtbegin = fmtbegin;
!                     fmtpar[fmtpos].fmtend = format;
!                     fmtpar[fmtpos].leftjust = leftjust;
!                     fmtpar[fmtpos].minlen = minlen;
!                     fmtpar[fmtpos].zpad = zpad;
!                     fmtpar[fmtpos].maxwidth = maxwidth;
!                     fmtpar[fmtpos].func = FMTSTR;
!                     fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                     fmtpos++;
!                     break;
!                 case 'c':
!                     fmtpar[fmtpos].fmtbegin = fmtbegin;
!                     fmtpar[fmtpos].fmtend = format;
!                     fmtpar[fmtpos].func = FMTCHAR;
!                     fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                     fmtpos++;
!                     break;
!                 case 'e':
!                 case 'E':
!                 case 'f':
!                 case 'g':
!                 case 'G':
!                     fmtpar[fmtpos].fmtbegin = fmtbegin;
!                     fmtpar[fmtpos].fmtend = format;
!                     fmtpar[fmtpos].type = ch;
!                     fmtpar[fmtpos].forcesign = forcesign;
!                     fmtpar[fmtpos].leftjust = leftjust;
!                     fmtpar[fmtpos].minlen = minlen;
!                     fmtpar[fmtpos].zpad = zpad;
!                     fmtpar[fmtpos].precision = precision;
!                     fmtpar[fmtpos].pointflag = pointflag;
!                     fmtpar[fmtpos].func = FMTFLOAT;
!                     fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
!                     fmtpos++;
!                     break;
!                 case '%':
!                     break;
!             }
          }
      }

***************
*** 538,543 ****
--- 538,545 ----
      format = format_save;
      while ((ch = *format++))
      {
+         bool skip_output = false;
+
          for (i = 1; i < fmtpos; i++)
          {
              if (ch == '%' && *format == '%')
***************
*** 552,596 ****
                      case FMTSTR:
                          fmtstr(fmtparptr[i]->value, fmtparptr[i]->leftjust,
                                 fmtparptr[i]->minlen, fmtparptr[i]->maxwidth,
!                                end, &output);
                          break;
                      case FMTNUM:
                      case FMTNUM_U:
                          fmtint(fmtparptr[i]->numvalue, fmtparptr[i]->base,
                                 fmtparptr[i]->dosign, fmtparptr[i]->forcesign,
                                 fmtparptr[i]->leftjust, fmtparptr[i]->minlen,
!                                fmtparptr[i]->zpad, end, &output);
                          break;
                      case FMTFLOAT:
                          fmtfloat(fmtparptr[i]->fvalue, fmtparptr[i]->type,
                               fmtparptr[i]->forcesign, fmtparptr[i]->leftjust,
                                   fmtparptr[i]->minlen, fmtparptr[i]->zpad,
                              fmtparptr[i]->precision, fmtparptr[i]->pointflag,
!                                  end, &output);
                          break;
                      case FMTCHAR:
!                         dopr_outch(fmtparptr[i]->charvalue, end, &output);
                          break;
                  }
                  format = fmtpar[i].fmtend;
!                 goto nochar;
              }
          }
!         dopr_outch(ch, end, &output);
! nochar:
!         /* nothing */
!         ;                        /* semicolon required because a goto has to be
!                                  * attached to a statement */
      }
!     *output = '\0';

      free(fmtpar);
      free(fmtparptr);
  }

  static void
  fmtstr(char *value, int leftjust, int minlen, int maxwidth, char *end,
!        char **output)
  {
      int            padlen,
                  vallen;            /* amount to pad */
--- 554,601 ----
                      case FMTSTR:
                          fmtstr(fmtparptr[i]->value, fmtparptr[i]->leftjust,
                                 fmtparptr[i]->minlen, fmtparptr[i]->maxwidth,
!                                end, (output) ? &output : NULL, stream, &outlen);
                          break;
                      case FMTNUM:
                      case FMTNUM_U:
                          fmtint(fmtparptr[i]->numvalue, fmtparptr[i]->base,
                                 fmtparptr[i]->dosign, fmtparptr[i]->forcesign,
                                 fmtparptr[i]->leftjust, fmtparptr[i]->minlen,
!                                fmtparptr[i]->zpad, end,
!                                (output) ? &output : NULL, stream, &outlen);
                          break;
                      case FMTFLOAT:
                          fmtfloat(fmtparptr[i]->fvalue, fmtparptr[i]->type,
                               fmtparptr[i]->forcesign, fmtparptr[i]->leftjust,
                                   fmtparptr[i]->minlen, fmtparptr[i]->zpad,
                              fmtparptr[i]->precision, fmtparptr[i]->pointflag,
!                                  end, (output) ? &output : NULL, stream, &outlen);
                          break;
                      case FMTCHAR:
!                         dopr_outch(fmtparptr[i]->charvalue, end,
!                                    (output) ? &output : NULL, stream, &outlen);
                          break;
                  }
                  format = fmtpar[i].fmtend;
!                 skip_output = true;
!                 break;
              }
          }
!         if (!skip_output)
!             dopr_outch(ch, end, (output) ? &output : NULL, stream, &outlen);
      }
!     if (output)
!         *output = '\0';

      free(fmtpar);
      free(fmtparptr);
+
+     return outlen;
  }

  static void
  fmtstr(char *value, int leftjust, int minlen, int maxwidth, char *end,
!        char **output, FILE *stream, int *outlen)
  {
      int            padlen,
                  vallen;            /* amount to pad */
***************
*** 606,622 ****

      while (padlen > 0)
      {
!         dopr_outch(' ', end, output);
          --padlen;
      }
!     dostr(value, maxwidth, end, output);

!     trailing_pad(&padlen, end, output);
  }

  static void
  fmtint(int64 value, int base, int dosign, int forcesign, int leftjust,
!        int minlen, int zpad, char *end, char **output)
  {
      int            signvalue = 0;
      char        convert[64];
--- 611,628 ----

      while (padlen > 0)
      {
!         dopr_outch(' ', end, output, stream, outlen);
          --padlen;
      }
!     dostr(value, maxwidth, end, output, stream, outlen);

!     trailing_pad(&padlen, end, output, stream, outlen);
  }

  static void
  fmtint(int64 value, int base, int dosign, int forcesign, int leftjust,
!        int minlen, int zpad, char *end, char **output, FILE *stream,
!        int *outlen)
  {
      int            signvalue = 0;
      char        convert[64];
***************
*** 644,661 ****

      adjust_padlen(minlen, vallen, leftjust, &padlen);

!     leading_pad(zpad, &signvalue, &padlen, end, output);

      while (vallen > 0)
!         dopr_outch(convert[--vallen], end, output);

!     trailing_pad(&padlen, end, output);
  }

  static void
  fmtfloat(double value, char type, int forcesign, int leftjust,
           int minlen, int zpad, int precision, int pointflag, char *end,
!          char **output)
  {
      int            signvalue = 0;
      int            vallen;
--- 650,667 ----

      adjust_padlen(minlen, vallen, leftjust, &padlen);

!     leading_pad(zpad, &signvalue, &padlen, end, output, stream, outlen);

      while (vallen > 0)
!         dopr_outch(convert[--vallen], end, output, stream, outlen);

!     trailing_pad(&padlen, end, output, stream, outlen);
  }

  static void
  fmtfloat(double value, char type, int forcesign, int leftjust,
           int minlen, int zpad, int precision, int pointflag, char *end,
!          char **output, FILE *stream, int *outlen)
  {
      int            signvalue = 0;
      int            vallen;
***************
*** 676,712 ****

      adjust_padlen(minlen, vallen, leftjust, &padlen);

!     leading_pad(zpad, &signvalue, &padlen, end, output);

!     dostr(convert, 0, end, output);

!     trailing_pad(&padlen, end, output);
  }

  static void
! dostr(char *str, int cut, char *end, char **output)
  {
      if (cut)
          while (*str && cut-- > 0)
!             dopr_outch(*str++, end, output);
      else
          while (*str)
!             dopr_outch(*str++, end, output);
  }

  static void
! dopr_outch(int c, char *end, char **output)
  {
  #ifdef NOT_USED
      if (iscntrl((unsigned char) c) && c != '\n' && c != '\t')
      {
          c = '@' + (c & 0x1F);
!         if (end == 0 || *output < end)
!             *(*output)++ = '^';
      }
  #endif
!     if (end == 0 || *output < end)
!         *(*output)++ = c;
  }


--- 682,730 ----

      adjust_padlen(minlen, vallen, leftjust, &padlen);

!     leading_pad(zpad, &signvalue, &padlen, end, output, stream, outlen);

!     dostr(convert, 0, end, output, stream, outlen);

!     trailing_pad(&padlen, end, output, stream, outlen);
  }

  static void
! dostr(char *str, int cut, char *end, char **output, FILE *stream, int *outlen)
  {
      if (cut)
          while (*str && cut-- > 0)
!             dopr_outch(*str++, end, output, stream, outlen);
      else
          while (*str)
!             dopr_outch(*str++, end, output, stream, outlen);
  }

  static void
! dopr_outch(int c, char *end, char **output, FILE *stream, int *outlen)
  {
  #ifdef NOT_USED
      if (iscntrl((unsigned char) c) && c != '\n' && c != '\t')
      {
          c = '@' + (c & 0x1F);
!         if (output)
!         {
!             if (end == 0 || *output < end)
!                 *(*output)++ = '^';
!         }
!         else
!             putc(c, stream);
!         (*outlen)++;
      }
  #endif
!     if (output)
!     {
!         if (end == 0 || *output < end)
!             *(*output)++ = c;
!     }
!     else
!         putc(c, stream);
!     (*outlen)++;
  }


***************
*** 736,765 ****


  static void
! leading_pad(int zpad, int *signvalue, int *padlen, char *end, char **output)
  {
      if (*padlen > 0 && zpad)
      {
          if (*signvalue)
          {
!             dopr_outch(*signvalue, end, output);
              --*padlen;
              *signvalue = 0;
          }
          while (*padlen > 0)
          {
!             dopr_outch(zpad, end, output);
              --*padlen;
          }
      }
      while (*padlen > 0 + (*signvalue != 0))
      {
!         dopr_outch(' ', end, output);
          --*padlen;
      }
      if (*signvalue)
      {
!         dopr_outch(*signvalue, end, output);
          if (*padlen > 0)
              --* padlen;
          if (padlen < 0)
--- 754,784 ----


  static void
! leading_pad(int zpad, int *signvalue, int *padlen, char *end, char **output,
!             FILE *stream, int *outlen)
  {
      if (*padlen > 0 && zpad)
      {
          if (*signvalue)
          {
!             dopr_outch(*signvalue, end, output, stream, outlen);
              --*padlen;
              *signvalue = 0;
          }
          while (*padlen > 0)
          {
!             dopr_outch(zpad, end, output, stream, outlen);
              --*padlen;
          }
      }
      while (*padlen > 0 + (*signvalue != 0))
      {
!         dopr_outch(' ', end, output, stream, outlen);
          --*padlen;
      }
      if (*signvalue)
      {
!         dopr_outch(*signvalue, end, output, stream, outlen);
          if (*padlen > 0)
              --* padlen;
          if (padlen < 0)
***************
*** 769,779 ****


  static void
! trailing_pad(int *padlen, char *end, char **output)
  {
      while (*padlen < 0)
      {
!         dopr_outch(' ', end, output);
          ++*padlen;
      }
  }
--- 788,798 ----


  static void
! trailing_pad(int *padlen, char *end, char **output, FILE *stream, int *outlen)
  {
      while (*padlen < 0)
      {
!         dopr_outch(' ', end, output, stream, outlen);
          ++*padlen;
      }
  }

pgsql-patches by date:

Previous
From: Atsushi Ogawa
Date:
Subject: Re: Allow an alias for the target table in UPDATE/DELETE
Next
From: Qingqing Zhou
Date:
Subject: Add function to return the thread safety status of libpq