Commit 9989e904 authored by Bruce Momjian's avatar Bruce Momjian

Make port snprintf.c finally thread-safe.

parent 87aafa16
...@@ -66,12 +66,12 @@ ...@@ -66,12 +66,12 @@
* causing nasty effects. * causing nasty effects.
**************************************************************/ **************************************************************/
/*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.9 2005/03/01 05:47:28 momjian Exp $";*/ /*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.10 2005/03/02 00:02:13 momjian Exp $";*/
int snprintf(char *str, size_t count, const char *fmt,...); int snprintf(char *str, size_t count, const char *fmt,...);
int vsnprintf(char *str, size_t count, const char *fmt, va_list args); int vsnprintf(char *str, size_t count, const char *fmt, va_list args);
int printf(const char *format, ...); int printf(const char *format, ...);
static void dopr(char *buffer, const char *format, va_list args, char *end); static void dopr(char *buffer, const char *format, va_list args, char *end);
int int
printf(const char *fmt,...) printf(const char *fmt,...)
...@@ -119,13 +119,14 @@ vsnprintf(char *str, size_t count, const char *fmt, va_list args) ...@@ -119,13 +119,14 @@ vsnprintf(char *str, size_t count, const char *fmt, va_list args)
* dopr(): poor man's version of doprintf * dopr(): poor man's version of doprintf
*/ */
static void fmtstr(char *value, int ljust, int len, int zpad, int maxwidth, char *end); static void fmtstr(char *value, int ljust, int len, int zpad, int maxwidth,
static void fmtnum(int64 value, int base, int dosign, int ljust, int len, int zpad, char *end); char *end, char **output);
static void fmtfloat(double value, char type, int ljust, int len, int precision, int pointflag, char *end); static void fmtnum(int64 value, int base, int dosign, int ljust, int len,
static void dostr(char *str, int cut, char *end); int zpad, char *end, char **output);
static void dopr_outch(int c, char *end); static void fmtfloat(double value, char type, int ljust, int len,
int precision, int pointflag, char *end, char **output);
static 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 FMTSTR 1
#define FMTNUM 2 #define FMTNUM 2
...@@ -152,7 +153,12 @@ dopr(char *buffer, const char *format, va_list args, char *end) ...@@ -152,7 +153,12 @@ dopr(char *buffer, const char *format, va_list args, char *end)
int fmtpos = 1; int fmtpos = 1;
int realpos = 0; int realpos = 0;
int position; int position;
static struct{ char *output;
/* In thread mode this structure is too large. */
#ifndef ENABLE_THREAD_SAFETY
static
#endif
struct{
const char* fmtbegin; const char* fmtbegin;
const char* fmtend; const char* fmtend;
void* value; void* value;
...@@ -235,7 +241,7 @@ dopr(char *buffer, const char *format, va_list args, char *end) ...@@ -235,7 +241,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
goto nextch; goto nextch;
case 'u': case 'u':
case 'U': case 'U':
/* fmtnum(value,base,dosign,ljust,len,zpad) */ /* fmtnum(value,base,dosign,ljust,len,zpad,&output) */
if (longflag) if (longflag)
{ {
if (longlongflag) if (longlongflag)
...@@ -259,7 +265,7 @@ dopr(char *buffer, const char *format, va_list args, char *end) ...@@ -259,7 +265,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
break; break;
case 'o': case 'o':
case 'O': case 'O':
/* fmtnum(value,base,dosign,ljust,len,zpad) */ /* fmtnum(value,base,dosign,ljust,len,zpad,&output) */
if (longflag) if (longflag)
{ {
if (longlongflag) if (longlongflag)
...@@ -286,7 +292,9 @@ dopr(char *buffer, const char *format, va_list args, char *end) ...@@ -286,7 +292,9 @@ dopr(char *buffer, const char *format, va_list args, char *end)
if (longflag) if (longflag)
{ {
if (longlongflag) if (longlongflag)
{
value = va_arg(args, int64); value = va_arg(args, int64);
}
else else
value = va_arg(args, long); value = va_arg(args, long);
} }
...@@ -396,11 +404,11 @@ dopr(char *buffer, const char *format, va_list args, char *end) ...@@ -396,11 +404,11 @@ dopr(char *buffer, const char *format, va_list args, char *end)
case '%': case '%':
break; break;
default: default:
dostr("???????", 0, end); dostr("???????", 0, end, &output);
} }
break; break;
default: default:
dopr_outch(ch, end); dopr_outch(ch, end, &output);
break; break;
} }
} }
...@@ -427,28 +435,28 @@ performpr: ...@@ -427,28 +435,28 @@ performpr:
case FMTSTR: case FMTSTR:
fmtstr(fmtparptr[i]->value, fmtparptr[i]->ljust, fmtstr(fmtparptr[i]->value, fmtparptr[i]->ljust,
fmtparptr[i]->len, fmtparptr[i]->zpad, fmtparptr[i]->len, fmtparptr[i]->zpad,
fmtparptr[i]->maxwidth, end); fmtparptr[i]->maxwidth, end, &output);
break; break;
case FMTNUM: case FMTNUM:
fmtnum(fmtparptr[i]->numvalue, fmtparptr[i]->base, fmtnum(fmtparptr[i]->numvalue, fmtparptr[i]->base,
fmtparptr[i]->dosign, fmtparptr[i]->ljust, fmtparptr[i]->dosign, fmtparptr[i]->ljust,
fmtparptr[i]->len, fmtparptr[i]->zpad, end); fmtparptr[i]->len, fmtparptr[i]->zpad, end, &output);
break; break;
case FMTFLOAT: case FMTFLOAT:
fmtfloat(fmtparptr[i]->fvalue, fmtparptr[i]->type, fmtfloat(fmtparptr[i]->fvalue, fmtparptr[i]->type,
fmtparptr[i]->ljust, fmtparptr[i]->len, fmtparptr[i]->ljust, fmtparptr[i]->len,
fmtparptr[i]->precision, fmtparptr[i]->pointflag, fmtparptr[i]->precision, fmtparptr[i]->pointflag,
end); end, &output);
break; break;
case FMTCHAR: case FMTCHAR:
dopr_outch(fmtparptr[i]->charvalue, end); dopr_outch(fmtparptr[i]->charvalue, end, &output);
break; break;
} }
format = fmtpar[i].fmtend; format = fmtpar[i].fmtend;
goto nochar; goto nochar;
} }
} }
dopr_outch(ch, end); dopr_outch(ch, end, &output);
nochar: nochar:
/* nothing */ /* nothing */
; /* semicolon required because a goto has to be attached to a statement */ ; /* semicolon required because a goto has to be attached to a statement */
...@@ -457,7 +465,8 @@ nochar: ...@@ -457,7 +465,8 @@ nochar:
} }
static void static void
fmtstr(char *value, int ljust, int len, int zpad, int maxwidth, char *end) fmtstr(char *value, int ljust, int len, int zpad, int maxwidth, char *end,
char **output)
{ {
int padlen, int padlen,
strlen; /* amount to pad */ strlen; /* amount to pad */
...@@ -474,19 +483,20 @@ fmtstr(char *value, int ljust, int len, int zpad, int maxwidth, char *end) ...@@ -474,19 +483,20 @@ fmtstr(char *value, int ljust, int len, int zpad, int maxwidth, char *end)
padlen = -padlen; padlen = -padlen;
while (padlen > 0) while (padlen > 0)
{ {
dopr_outch(' ', end); dopr_outch(' ', end, output);
--padlen; --padlen;
} }
dostr(value, maxwidth, end); dostr(value, maxwidth, end, output);
while (padlen < 0) while (padlen < 0)
{ {
dopr_outch(' ', end); dopr_outch(' ', end, output);
++padlen; ++padlen;
} }
} }
static void static void
fmtnum(int64 value, int base, int dosign, int ljust, int len, int zpad, char *end) fmtnum(int64 value, int base, int dosign, int ljust, int len, int zpad,
char *end, char **output)
{ {
int signvalue = 0; int signvalue = 0;
uint64 uvalue; uint64 uvalue;
...@@ -541,34 +551,35 @@ fmtnum(int64 value, int base, int dosign, int ljust, int len, int zpad, char *en ...@@ -541,34 +551,35 @@ fmtnum(int64 value, int base, int dosign, int ljust, int len, int zpad, char *en
{ {
if (signvalue) if (signvalue)
{ {
dopr_outch(signvalue, end); dopr_outch(signvalue, end, output);
--padlen; --padlen;
signvalue = 0; signvalue = 0;
} }
while (padlen > 0) while (padlen > 0)
{ {
dopr_outch(zpad, end); dopr_outch(zpad, end, output);
--padlen; --padlen;
} }
} }
while (padlen > 0) while (padlen > 0)
{ {
dopr_outch(' ', end); dopr_outch(' ', end, output);
--padlen; --padlen;
} }
if (signvalue) if (signvalue)
dopr_outch(signvalue, end); dopr_outch(signvalue, end, output);
while (place > 0) while (place > 0)
dopr_outch(convert[--place], end); dopr_outch(convert[--place], end, output);
while (padlen < 0) while (padlen < 0)
{ {
dopr_outch(' ', end); dopr_outch(' ', end, output);
++padlen; ++padlen;
} }
} }
static void static void
fmtfloat(double value, char type, int ljust, int len, int precision, int pointflag, char *end) fmtfloat(double value, char type, int ljust, int len, int precision,
int pointflag, char *end, char **output)
{ {
char fmt[32]; char fmt[32];
char convert[512]; char convert[512];
...@@ -595,43 +606,43 @@ fmtfloat(double value, char type, int ljust, int len, int precision, int pointfl ...@@ -595,43 +606,43 @@ fmtfloat(double value, char type, int ljust, int len, int precision, int pointfl
while (padlen > 0) while (padlen > 0)
{ {
dopr_outch(' ', end); dopr_outch(' ', end, output);
--padlen; --padlen;
} }
dostr(convert, 0, end); dostr(convert, 0, end, output);
while (padlen < 0) while (padlen < 0)
{ {
dopr_outch(' ', end); dopr_outch(' ', end, output);
++padlen; ++padlen;
} }
} }
static void static void
dostr(char *str, int cut, char *end) dostr(char *str, int cut, char *end, char **output)
{ {
if (cut) if (cut)
{ {
while (*str && cut-- > 0) while (*str && cut-- > 0)
dopr_outch(*str++, end); dopr_outch(*str++, end, output);
} }
else else
{ {
while (*str) while (*str)
dopr_outch(*str++, end); dopr_outch(*str++, end, output);
} }
} }
static void static void
dopr_outch(int c, char *end) dopr_outch(int c, char *end, char **output)
{ {
#ifdef NOT_USED #ifdef NOT_USED
if (iscntrl((unsigned char) c) && c != '\n' && c != '\t') if (iscntrl((unsigned char) c) && c != '\n' && c != '\t')
{ {
c = '@' + (c & 0x1F); c = '@' + (c & 0x1F);
if (end == 0 || output < end) if (end == 0 || *output < end)
*output++ = '^'; *(*output)++ = '^';
} }
#endif #endif
if (end == 0 || output < end) if (end == 0 || *output < end)
*output++ = c; *(*output)++ = c;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment