Commit 7111a14f authored by Bruce Momjian's avatar Bruce Momjian

Factor duplicate snprintf code into functions.

parent 957f51ea
......@@ -65,7 +65,7 @@
* causing nasty effects.
**************************************************************/
/*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.23 2005/03/16 21:27:23 momjian Exp $";*/
/*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.24 2005/03/17 03:18:14 momjian Exp $";*/
static void dopr(char *buffer, const char *format, va_list args, char *end);
......@@ -149,16 +149,18 @@ pg_printf(const char *fmt,...)
return len;
}
/*
* dopr(): poor man's version of doprintf
*/
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 ljust, int len, int maxwidth,
static void fmtstr(char *value, int leftjust, int minlen, int maxwidth,
char *end, char **output);
static void fmtnum(int64 value, int base, int dosign, int forcesign,
int ljust, int len, int zpad, 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 ljust, int len, int zpad, int precision, int pointflag, char *end,
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);
......@@ -171,6 +173,10 @@ static void dopr_outch(int c, char *end, char **output);
#define FMTWIDTH 6
#define FMTLEN 7
/*
* dopr(): poor man's version of doprintf
*/
static void
dopr(char *buffer, const char *format, va_list args, char *end)
{
......@@ -179,8 +185,8 @@ dopr(char *buffer, const char *format, va_list args, char *end)
int longflag;
int pointflag;
int maxwidth;
int ljust;
int len;
int leftjust;
int minlen;
int zpad;
int forcesign;
int i;
......@@ -201,8 +207,8 @@ dopr(char *buffer, const char *format, va_list args, char *end)
int64 numvalue;
double fvalue;
int charvalue;
int ljust;
int len;
int leftjust;
int minlen;
int zpad;
int maxwidth;
int base;
......@@ -245,7 +251,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
switch (ch)
{
case '%':
ljust = len = zpad = forcesign = maxwidth = 0;
leftjust = minlen = zpad = forcesign = maxwidth = 0;
longflag = longlongflag = pointflag = 0;
fmtbegin = format - 1;
realpos = 0;
......@@ -257,13 +263,13 @@ dopr(char *buffer, const char *format, va_list args, char *end)
case '\0':
goto performpr;
case '-':
ljust = 1;
leftjust = 1;
goto nextch;
case '+':
forcesign = 1;
goto nextch;
case '0': /* set zero padding if len not set */
if (len == 0 && !pointflag)
case '0': /* set zero padding if minlen not set */
if (minlen == 0 && !pointflag)
zpad = '0';
case '1':
case '2':
......@@ -276,7 +282,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
case '9':
if (!pointflag)
{
len = len * 10 + ch - '0';
minlen = minlen * 10 + ch - '0';
position = position * 10 + ch - '0';
}
else
......@@ -287,7 +293,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
goto nextch;
case '$':
realpos = position;
len = 0;
minlen = 0;
goto nextch;
case '*':
MemSet(&fmtpar[fmtpos], 0, sizeof(fmtpar[fmtpos]));
......@@ -340,8 +346,8 @@ dopr(char *buffer, const char *format, va_list args, char *end)
fmtpar[fmtpos].base = 10;
fmtpar[fmtpos].dosign = 0;
fmtpar[fmtpos].forcesign = forcesign;
fmtpar[fmtpos].ljust = ljust;
fmtpar[fmtpos].len = len;
fmtpar[fmtpos].leftjust = leftjust;
fmtpar[fmtpos].minlen = minlen;
fmtpar[fmtpos].zpad = zpad;
fmtpar[fmtpos].func = FMTNUM_U;
fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
......@@ -356,8 +362,8 @@ dopr(char *buffer, const char *format, va_list args, char *end)
fmtpar[fmtpos].base = 8;
fmtpar[fmtpos].dosign = 0;
fmtpar[fmtpos].forcesign = forcesign;
fmtpar[fmtpos].ljust = ljust;
fmtpar[fmtpos].len = len;
fmtpar[fmtpos].leftjust = leftjust;
fmtpar[fmtpos].minlen = minlen;
fmtpar[fmtpos].zpad = zpad;
fmtpar[fmtpos].func = FMTNUM_U;
fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
......@@ -372,8 +378,8 @@ dopr(char *buffer, const char *format, va_list args, char *end)
fmtpar[fmtpos].base = 10;
fmtpar[fmtpos].dosign = 1;
fmtpar[fmtpos].forcesign = forcesign;
fmtpar[fmtpos].ljust = ljust;
fmtpar[fmtpos].len = len;
fmtpar[fmtpos].leftjust = leftjust;
fmtpar[fmtpos].minlen = minlen;
fmtpar[fmtpos].zpad = zpad;
fmtpar[fmtpos].func = FMTNUM;
fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
......@@ -387,8 +393,8 @@ dopr(char *buffer, const char *format, va_list args, char *end)
fmtpar[fmtpos].base = 16;
fmtpar[fmtpos].dosign = 0;
fmtpar[fmtpos].forcesign = forcesign;
fmtpar[fmtpos].ljust = ljust;
fmtpar[fmtpos].len = len;
fmtpar[fmtpos].leftjust = leftjust;
fmtpar[fmtpos].minlen = minlen;
fmtpar[fmtpos].zpad = zpad;
fmtpar[fmtpos].func = FMTNUM_U;
fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
......@@ -402,8 +408,8 @@ dopr(char *buffer, const char *format, va_list args, char *end)
fmtpar[fmtpos].base = -16;
fmtpar[fmtpos].dosign = 1;
fmtpar[fmtpos].forcesign = forcesign;
fmtpar[fmtpos].ljust = ljust;
fmtpar[fmtpos].len = len;
fmtpar[fmtpos].leftjust = leftjust;
fmtpar[fmtpos].minlen = minlen;
fmtpar[fmtpos].zpad = zpad;
fmtpar[fmtpos].func = FMTNUM_U;
fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
......@@ -412,8 +418,8 @@ dopr(char *buffer, const char *format, va_list args, char *end)
case 's':
fmtpar[fmtpos].fmtbegin = fmtbegin;
fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].ljust = ljust;
fmtpar[fmtpos].len = len;
fmtpar[fmtpos].leftjust = leftjust;
fmtpar[fmtpos].minlen = minlen;
fmtpar[fmtpos].zpad = zpad;
fmtpar[fmtpos].maxwidth = maxwidth;
fmtpar[fmtpos].func = FMTSTR;
......@@ -436,8 +442,8 @@ dopr(char *buffer, const char *format, va_list args, char *end)
fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].type = ch;
fmtpar[fmtpos].forcesign = forcesign;
fmtpar[fmtpos].ljust = ljust;
fmtpar[fmtpos].len = len;
fmtpar[fmtpos].leftjust = leftjust;
fmtpar[fmtpos].minlen = minlen;
fmtpar[fmtpos].zpad = zpad;
fmtpar[fmtpos].precision = precision;
fmtpar[fmtpos].pointflag = pointflag;
......@@ -499,11 +505,27 @@ performpr:
fmtparptr[i]->charvalue = va_arg(args, int);
break;
case FMTLEN:
if (i + 1 < fmtpos && fmtparptr[i + 1]->func != FMTWIDTH)
fmtparptr[i + 1]->len = va_arg(args, int);
/* For "%*.*f", use the second arg */
if (i + 2 < fmtpos && fmtparptr[i + 1]->func == FMTWIDTH)
fmtparptr[i + 2]->len = va_arg(args, int);
{
int minlen = va_arg(args, int);
int leftjust = 0;
if (minlen < 0)
{
minlen = -minlen;
leftjust = 1;
}
if (i + 1 < fmtpos && fmtparptr[i + 1]->func != FMTWIDTH)
{
fmtparptr[i + 1]->minlen = minlen;
fmtparptr[i + 1]->leftjust |= leftjust;
}
/* For "%*.*f", use the second arg */
if (i + 2 < fmtpos && fmtparptr[i + 1]->func == FMTWIDTH)
{
fmtparptr[i + 2]->minlen = minlen;
fmtparptr[i + 2]->leftjust |= leftjust;
}
}
break;
case FMTWIDTH:
if (i + 1 < fmtpos)
......@@ -530,21 +552,21 @@ performpr:
switch (fmtparptr[i]->func)
{
case FMTSTR:
fmtstr(fmtparptr[i]->value, fmtparptr[i]->ljust,
fmtparptr[i]->len, fmtparptr[i]->maxwidth,
fmtstr(fmtparptr[i]->value, fmtparptr[i]->leftjust,
fmtparptr[i]->minlen, fmtparptr[i]->maxwidth,
end, &output);
break;
case FMTNUM:
case FMTNUM_U:
fmtnum(fmtparptr[i]->numvalue, fmtparptr[i]->base,
fmtint(fmtparptr[i]->numvalue, fmtparptr[i]->base,
fmtparptr[i]->dosign, fmtparptr[i]->forcesign,
fmtparptr[i]->ljust, fmtparptr[i]->len,
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]->ljust,
fmtparptr[i]->len, fmtparptr[i]->zpad,
fmtparptr[i]->forcesign, fmtparptr[i]->leftjust,
fmtparptr[i]->minlen, fmtparptr[i]->zpad,
fmtparptr[i]->precision, fmtparptr[i]->pointflag,
end, &output);
break;
......@@ -574,7 +596,7 @@ nochar:
}
static void
fmtstr(char *value, int ljust, int len, int maxwidth, char *end,
fmtstr(char *value, int leftjust, int minlen, int maxwidth, char *end,
char **output)
{
int padlen,
......@@ -582,185 +604,90 @@ fmtstr(char *value, int ljust, int len, int maxwidth, char *end,
if (value == NULL)
value = "<NULL>";
vallen = strlen(value);
if (vallen > maxwidth && maxwidth)
if (maxwidth && vallen > maxwidth)
vallen = maxwidth;
if (len < 0)
{
/* this could happen with a "*" width spec */
ljust = 1;
len = -len;
}
padlen = len - vallen;
if (padlen < 0)
padlen = 0;
if (ljust)
padlen = -padlen;
adjust_padlen(minlen, vallen, leftjust, &padlen);
while (padlen > 0)
{
dopr_outch(' ', end, output);
--padlen;
}
dostr(value, maxwidth, end, output);
while (padlen < 0)
{
dopr_outch(' ', end, output);
++padlen;
}
trailing_pad(&padlen, end, output);
}
static void
fmtnum(int64 value, int base, int dosign, int forcesign, int ljust,
int len, int zpad, char *end, char **output)
fmtint(int64 value, int base, int dosign, int forcesign, int leftjust,
int minlen, int zpad, char *end, char **output)
{
int signvalue = 0;
uint64 uvalue;
char convert[64];
int place = 0;
int vallen = 0;
int padlen = 0; /* amount to pad */
int caps = 0;
/*
* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
* value, base, dosign, ljust, len, zpad ));
*/
uvalue = value;
if (dosign)
{
if (value < 0)
{
signvalue = '-';
uvalue = -value;
}
else if (forcesign)
signvalue = '+';
}
/* Handle +/- and %X (uppercase hex) */
if (dosign && adjust_sign((value < 0), forcesign, &signvalue))
value = -value;
if (base < 0)
{
caps = 1;
base = -base;
}
/* make integer string */
do
{
convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
[uvalue % (unsigned) base];
uvalue = (uvalue / (unsigned) base);
} while (uvalue);
convert[place] = 0;
convert[vallen++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
[value % (unsigned) base];
value = (value / (unsigned) base);
} while (value);
convert[vallen] = 0;
if (len < 0)
{
/* this could happen with a "*" width spec */
ljust = 1;
len = -len;
}
padlen = len - place;
if (padlen < 0)
padlen = 0;
if (ljust)
padlen = -padlen;
/*
* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n",
* convert,place,signvalue,padlen));
*/
if (zpad && padlen > 0)
{
if (signvalue)
{
dopr_outch(signvalue, end, output);
--padlen;
signvalue = 0;
}
while (padlen > 0)
{
dopr_outch(zpad, end, output);
--padlen;
}
}
while (padlen > 0)
{
dopr_outch(' ', end, output);
--padlen;
}
if (signvalue)
dopr_outch(signvalue, end, output);
while (place > 0)
dopr_outch(convert[--place], end, output);
while (padlen < 0)
{
dopr_outch(' ', end, output);
++padlen;
}
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 ljust,
int len, int zpad, int precision, int pointflag, char *end,
fmtfloat(double value, char type, int forcesign, int leftjust,
int minlen, int zpad, int precision, int pointflag, char *end,
char **output)
{
int signvalue = 0;
double uvalue;
int vallen;
char fmt[32];
char convert[512];
int padlen = 0; /* amount to pad */
uvalue = value;
/* we rely on regular C library's sprintf to do the basic conversion */
if (pointflag)
sprintf(fmt, "%%.%d%c", precision, type);
else
sprintf(fmt, "%%%c", type);
if (value < 0)
{
signvalue = '-';
uvalue = -value;
}
else if (forcesign)
signvalue = '+';
if (adjust_sign((value < 0), forcesign, &signvalue))
value = -value;
sprintf(convert, fmt, uvalue);
vallen = sprintf(convert, fmt, value);
if (len < 0)
{
/* this could happen with a "*" width spec */
ljust = 1;
len = -len;
}
padlen = len - strlen(convert);
if (padlen < 0)
padlen = 0;
if (ljust)
padlen = -padlen;
adjust_padlen(minlen, vallen, leftjust, &padlen);
leading_pad(zpad, &signvalue, &padlen, end, output);
if (zpad && padlen > 0)
{
if (signvalue)
{
dopr_outch(signvalue, end, output);
--padlen;
signvalue = 0;
}
while (padlen > 0)
{
dopr_outch(zpad, end, output);
--padlen;
}
}
while (padlen > 0)
{
dopr_outch(' ', end, output);
--padlen;
}
if (signvalue)
dopr_outch(signvalue, end, output);
dostr(convert, 0, end, output);
while (padlen < 0)
{
dopr_outch(' ', end, output);
++padlen;
}
trailing_pad(&padlen, end, output);
}
static void
......@@ -788,3 +715,73 @@ dopr_outch(int c, char *end, char **output)
if (end == 0 || *output < end)
*(*output)++ = c;
}
static int
adjust_sign(int is_negative, int forcesign, int *signvalue)
{
if (is_negative)
{
*signvalue = '-';
return true;
}
else if (forcesign)
*signvalue = '+';
return false;
}
static void
adjust_padlen(int minlen, int vallen, int leftjust, int *padlen)
{
*padlen = minlen - vallen;
if (*padlen < 0)
*padlen = 0;
if (leftjust)
*padlen = -*padlen;
}
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)
++padlen;
}
}
static void
trailing_pad(int *padlen, char *end, char **output)
{
while (*padlen < 0)
{
dopr_outch(' ', end, output);
++*padlen;
}
}
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