mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
Make port snprintf.c finally thread-safe.
This commit is contained in:
parent
87aafa1600
commit
9989e90490
@ -66,7 +66,7 @@
|
|||||||
* 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);
|
||||||
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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:
|
|||||||
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:
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
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
|
|||||||
{
|
{
|
||||||
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
|
|||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user