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;
        }
  }
---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?

               http://www.postgresql.org/docs/faq

Reply via email to