mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
Factor duplicate snprintf code into functions.
This commit is contained in:
parent
957f51ea6b
commit
7111a14fba
@ -65,7 +65,7 @@
|
|||||||
* causing nasty effects.
|
* 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);
|
static void dopr(char *buffer, const char *format, va_list args, char *end);
|
||||||
|
|
||||||
@ -149,16 +149,18 @@ pg_printf(const char *fmt,...)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static int adjust_sign(int is_negative, int forcesign, int *signvalue);
|
||||||
* dopr(): poor man's version of doprintf
|
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);
|
char *end, char **output);
|
||||||
static void fmtnum(int64 value, int base, int dosign, int forcesign,
|
static void fmtint(int64 value, int base, int dosign, int forcesign,
|
||||||
int ljust, int len, int zpad, char *end, char **output);
|
int leftjust, int minlen, int zpad, char *end, char **output);
|
||||||
static void fmtfloat(double value, char type, int forcesign,
|
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);
|
char **output);
|
||||||
static void dostr(char *str, int cut, 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);
|
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 FMTWIDTH 6
|
||||||
#define FMTLEN 7
|
#define FMTLEN 7
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dopr(): poor man's version of doprintf
|
||||||
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dopr(char *buffer, const char *format, va_list args, char *end)
|
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 longflag;
|
||||||
int pointflag;
|
int pointflag;
|
||||||
int maxwidth;
|
int maxwidth;
|
||||||
int ljust;
|
int leftjust;
|
||||||
int len;
|
int minlen;
|
||||||
int zpad;
|
int zpad;
|
||||||
int forcesign;
|
int forcesign;
|
||||||
int i;
|
int i;
|
||||||
@ -201,8 +207,8 @@ dopr(char *buffer, const char *format, va_list args, char *end)
|
|||||||
int64 numvalue;
|
int64 numvalue;
|
||||||
double fvalue;
|
double fvalue;
|
||||||
int charvalue;
|
int charvalue;
|
||||||
int ljust;
|
int leftjust;
|
||||||
int len;
|
int minlen;
|
||||||
int zpad;
|
int zpad;
|
||||||
int maxwidth;
|
int maxwidth;
|
||||||
int base;
|
int base;
|
||||||
@ -245,7 +251,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
|
|||||||
switch (ch)
|
switch (ch)
|
||||||
{
|
{
|
||||||
case '%':
|
case '%':
|
||||||
ljust = len = zpad = forcesign = maxwidth = 0;
|
leftjust = minlen = zpad = forcesign = maxwidth = 0;
|
||||||
longflag = longlongflag = pointflag = 0;
|
longflag = longlongflag = pointflag = 0;
|
||||||
fmtbegin = format - 1;
|
fmtbegin = format - 1;
|
||||||
realpos = 0;
|
realpos = 0;
|
||||||
@ -257,13 +263,13 @@ dopr(char *buffer, const char *format, va_list args, char *end)
|
|||||||
case '\0':
|
case '\0':
|
||||||
goto performpr;
|
goto performpr;
|
||||||
case '-':
|
case '-':
|
||||||
ljust = 1;
|
leftjust = 1;
|
||||||
goto nextch;
|
goto nextch;
|
||||||
case '+':
|
case '+':
|
||||||
forcesign = 1;
|
forcesign = 1;
|
||||||
goto nextch;
|
goto nextch;
|
||||||
case '0': /* set zero padding if len not set */
|
case '0': /* set zero padding if minlen not set */
|
||||||
if (len == 0 && !pointflag)
|
if (minlen == 0 && !pointflag)
|
||||||
zpad = '0';
|
zpad = '0';
|
||||||
case '1':
|
case '1':
|
||||||
case '2':
|
case '2':
|
||||||
@ -276,7 +282,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
|
|||||||
case '9':
|
case '9':
|
||||||
if (!pointflag)
|
if (!pointflag)
|
||||||
{
|
{
|
||||||
len = len * 10 + ch - '0';
|
minlen = minlen * 10 + ch - '0';
|
||||||
position = position * 10 + ch - '0';
|
position = position * 10 + ch - '0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -287,7 +293,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
|
|||||||
goto nextch;
|
goto nextch;
|
||||||
case '$':
|
case '$':
|
||||||
realpos = position;
|
realpos = position;
|
||||||
len = 0;
|
minlen = 0;
|
||||||
goto nextch;
|
goto nextch;
|
||||||
case '*':
|
case '*':
|
||||||
MemSet(&fmtpar[fmtpos], 0, sizeof(fmtpar[fmtpos]));
|
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].base = 10;
|
||||||
fmtpar[fmtpos].dosign = 0;
|
fmtpar[fmtpos].dosign = 0;
|
||||||
fmtpar[fmtpos].forcesign = forcesign;
|
fmtpar[fmtpos].forcesign = forcesign;
|
||||||
fmtpar[fmtpos].ljust = ljust;
|
fmtpar[fmtpos].leftjust = leftjust;
|
||||||
fmtpar[fmtpos].len = len;
|
fmtpar[fmtpos].minlen = minlen;
|
||||||
fmtpar[fmtpos].zpad = zpad;
|
fmtpar[fmtpos].zpad = zpad;
|
||||||
fmtpar[fmtpos].func = FMTNUM_U;
|
fmtpar[fmtpos].func = FMTNUM_U;
|
||||||
fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
|
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].base = 8;
|
||||||
fmtpar[fmtpos].dosign = 0;
|
fmtpar[fmtpos].dosign = 0;
|
||||||
fmtpar[fmtpos].forcesign = forcesign;
|
fmtpar[fmtpos].forcesign = forcesign;
|
||||||
fmtpar[fmtpos].ljust = ljust;
|
fmtpar[fmtpos].leftjust = leftjust;
|
||||||
fmtpar[fmtpos].len = len;
|
fmtpar[fmtpos].minlen = minlen;
|
||||||
fmtpar[fmtpos].zpad = zpad;
|
fmtpar[fmtpos].zpad = zpad;
|
||||||
fmtpar[fmtpos].func = FMTNUM_U;
|
fmtpar[fmtpos].func = FMTNUM_U;
|
||||||
fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
|
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].base = 10;
|
||||||
fmtpar[fmtpos].dosign = 1;
|
fmtpar[fmtpos].dosign = 1;
|
||||||
fmtpar[fmtpos].forcesign = forcesign;
|
fmtpar[fmtpos].forcesign = forcesign;
|
||||||
fmtpar[fmtpos].ljust = ljust;
|
fmtpar[fmtpos].leftjust = leftjust;
|
||||||
fmtpar[fmtpos].len = len;
|
fmtpar[fmtpos].minlen = minlen;
|
||||||
fmtpar[fmtpos].zpad = zpad;
|
fmtpar[fmtpos].zpad = zpad;
|
||||||
fmtpar[fmtpos].func = FMTNUM;
|
fmtpar[fmtpos].func = FMTNUM;
|
||||||
fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
|
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].base = 16;
|
||||||
fmtpar[fmtpos].dosign = 0;
|
fmtpar[fmtpos].dosign = 0;
|
||||||
fmtpar[fmtpos].forcesign = forcesign;
|
fmtpar[fmtpos].forcesign = forcesign;
|
||||||
fmtpar[fmtpos].ljust = ljust;
|
fmtpar[fmtpos].leftjust = leftjust;
|
||||||
fmtpar[fmtpos].len = len;
|
fmtpar[fmtpos].minlen = minlen;
|
||||||
fmtpar[fmtpos].zpad = zpad;
|
fmtpar[fmtpos].zpad = zpad;
|
||||||
fmtpar[fmtpos].func = FMTNUM_U;
|
fmtpar[fmtpos].func = FMTNUM_U;
|
||||||
fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
|
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].base = -16;
|
||||||
fmtpar[fmtpos].dosign = 1;
|
fmtpar[fmtpos].dosign = 1;
|
||||||
fmtpar[fmtpos].forcesign = forcesign;
|
fmtpar[fmtpos].forcesign = forcesign;
|
||||||
fmtpar[fmtpos].ljust = ljust;
|
fmtpar[fmtpos].leftjust = leftjust;
|
||||||
fmtpar[fmtpos].len = len;
|
fmtpar[fmtpos].minlen = minlen;
|
||||||
fmtpar[fmtpos].zpad = zpad;
|
fmtpar[fmtpos].zpad = zpad;
|
||||||
fmtpar[fmtpos].func = FMTNUM_U;
|
fmtpar[fmtpos].func = FMTNUM_U;
|
||||||
fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
|
fmtpar[fmtpos].realpos = realpos ? realpos : fmtpos;
|
||||||
@ -412,8 +418,8 @@ dopr(char *buffer, const char *format, va_list args, char *end)
|
|||||||
case 's':
|
case 's':
|
||||||
fmtpar[fmtpos].fmtbegin = fmtbegin;
|
fmtpar[fmtpos].fmtbegin = fmtbegin;
|
||||||
fmtpar[fmtpos].fmtend = format;
|
fmtpar[fmtpos].fmtend = format;
|
||||||
fmtpar[fmtpos].ljust = ljust;
|
fmtpar[fmtpos].leftjust = leftjust;
|
||||||
fmtpar[fmtpos].len = len;
|
fmtpar[fmtpos].minlen = minlen;
|
||||||
fmtpar[fmtpos].zpad = zpad;
|
fmtpar[fmtpos].zpad = zpad;
|
||||||
fmtpar[fmtpos].maxwidth = maxwidth;
|
fmtpar[fmtpos].maxwidth = maxwidth;
|
||||||
fmtpar[fmtpos].func = FMTSTR;
|
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].fmtend = format;
|
||||||
fmtpar[fmtpos].type = ch;
|
fmtpar[fmtpos].type = ch;
|
||||||
fmtpar[fmtpos].forcesign = forcesign;
|
fmtpar[fmtpos].forcesign = forcesign;
|
||||||
fmtpar[fmtpos].ljust = ljust;
|
fmtpar[fmtpos].leftjust = leftjust;
|
||||||
fmtpar[fmtpos].len = len;
|
fmtpar[fmtpos].minlen = minlen;
|
||||||
fmtpar[fmtpos].zpad = zpad;
|
fmtpar[fmtpos].zpad = zpad;
|
||||||
fmtpar[fmtpos].precision = precision;
|
fmtpar[fmtpos].precision = precision;
|
||||||
fmtpar[fmtpos].pointflag = pointflag;
|
fmtpar[fmtpos].pointflag = pointflag;
|
||||||
@ -499,11 +505,27 @@ performpr:
|
|||||||
fmtparptr[i]->charvalue = va_arg(args, int);
|
fmtparptr[i]->charvalue = va_arg(args, int);
|
||||||
break;
|
break;
|
||||||
case FMTLEN:
|
case FMTLEN:
|
||||||
if (i + 1 < fmtpos && fmtparptr[i + 1]->func != FMTWIDTH)
|
{
|
||||||
fmtparptr[i + 1]->len = va_arg(args, int);
|
int minlen = va_arg(args, int);
|
||||||
/* For "%*.*f", use the second arg */
|
int leftjust = 0;
|
||||||
if (i + 2 < fmtpos && fmtparptr[i + 1]->func == FMTWIDTH)
|
|
||||||
fmtparptr[i + 2]->len = va_arg(args, int);
|
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;
|
break;
|
||||||
case FMTWIDTH:
|
case FMTWIDTH:
|
||||||
if (i + 1 < fmtpos)
|
if (i + 1 < fmtpos)
|
||||||
@ -530,21 +552,21 @@ performpr:
|
|||||||
switch (fmtparptr[i]->func)
|
switch (fmtparptr[i]->func)
|
||||||
{
|
{
|
||||||
case FMTSTR:
|
case FMTSTR:
|
||||||
fmtstr(fmtparptr[i]->value, fmtparptr[i]->ljust,
|
fmtstr(fmtparptr[i]->value, fmtparptr[i]->leftjust,
|
||||||
fmtparptr[i]->len, fmtparptr[i]->maxwidth,
|
fmtparptr[i]->minlen, fmtparptr[i]->maxwidth,
|
||||||
end, &output);
|
end, &output);
|
||||||
break;
|
break;
|
||||||
case FMTNUM:
|
case FMTNUM:
|
||||||
case FMTNUM_U:
|
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]->dosign, fmtparptr[i]->forcesign,
|
||||||
fmtparptr[i]->ljust, fmtparptr[i]->len,
|
fmtparptr[i]->leftjust, fmtparptr[i]->minlen,
|
||||||
fmtparptr[i]->zpad, end, &output);
|
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]->forcesign, fmtparptr[i]->ljust,
|
fmtparptr[i]->forcesign, fmtparptr[i]->leftjust,
|
||||||
fmtparptr[i]->len, fmtparptr[i]->zpad,
|
fmtparptr[i]->minlen, fmtparptr[i]->zpad,
|
||||||
fmtparptr[i]->precision, fmtparptr[i]->pointflag,
|
fmtparptr[i]->precision, fmtparptr[i]->pointflag,
|
||||||
end, &output);
|
end, &output);
|
||||||
break;
|
break;
|
||||||
@ -574,7 +596,7 @@ nochar:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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)
|
char **output)
|
||||||
{
|
{
|
||||||
int padlen,
|
int padlen,
|
||||||
@ -582,185 +604,90 @@ fmtstr(char *value, int ljust, int len, int maxwidth, char *end,
|
|||||||
|
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
value = "<NULL>";
|
value = "<NULL>";
|
||||||
|
|
||||||
vallen = strlen(value);
|
vallen = strlen(value);
|
||||||
if (vallen > maxwidth && maxwidth)
|
if (maxwidth && vallen > maxwidth)
|
||||||
vallen = maxwidth;
|
vallen = maxwidth;
|
||||||
if (len < 0)
|
|
||||||
{
|
adjust_padlen(minlen, vallen, leftjust, &padlen);
|
||||||
/* this could happen with a "*" width spec */
|
|
||||||
ljust = 1;
|
|
||||||
len = -len;
|
|
||||||
}
|
|
||||||
padlen = len - vallen;
|
|
||||||
if (padlen < 0)
|
|
||||||
padlen = 0;
|
|
||||||
if (ljust)
|
|
||||||
padlen = -padlen;
|
|
||||||
while (padlen > 0)
|
while (padlen > 0)
|
||||||
{
|
{
|
||||||
dopr_outch(' ', end, output);
|
dopr_outch(' ', end, output);
|
||||||
--padlen;
|
--padlen;
|
||||||
}
|
}
|
||||||
dostr(value, maxwidth, end, output);
|
dostr(value, maxwidth, end, output);
|
||||||
while (padlen < 0)
|
|
||||||
{
|
trailing_pad(&padlen, end, output);
|
||||||
dopr_outch(' ', end, output);
|
|
||||||
++padlen;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fmtnum(int64 value, int base, int dosign, int forcesign, int ljust,
|
fmtint(int64 value, int base, int dosign, int forcesign, int leftjust,
|
||||||
int len, int zpad, char *end, char **output)
|
int minlen, int zpad, char *end, char **output)
|
||||||
{
|
{
|
||||||
int signvalue = 0;
|
int signvalue = 0;
|
||||||
uint64 uvalue;
|
|
||||||
char convert[64];
|
char convert[64];
|
||||||
int place = 0;
|
int vallen = 0;
|
||||||
int padlen = 0; /* amount to pad */
|
int padlen = 0; /* amount to pad */
|
||||||
int caps = 0;
|
int caps = 0;
|
||||||
|
|
||||||
/*
|
/* Handle +/- and %X (uppercase hex) */
|
||||||
* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
|
if (dosign && adjust_sign((value < 0), forcesign, &signvalue))
|
||||||
* value, base, dosign, ljust, len, zpad ));
|
value = -value;
|
||||||
*/
|
|
||||||
uvalue = value;
|
|
||||||
if (dosign)
|
|
||||||
{
|
|
||||||
if (value < 0)
|
|
||||||
{
|
|
||||||
signvalue = '-';
|
|
||||||
uvalue = -value;
|
|
||||||
}
|
|
||||||
else if (forcesign)
|
|
||||||
signvalue = '+';
|
|
||||||
}
|
|
||||||
if (base < 0)
|
if (base < 0)
|
||||||
{
|
{
|
||||||
caps = 1;
|
caps = 1;
|
||||||
base = -base;
|
base = -base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* make integer string */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
|
convert[vallen++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
|
||||||
[uvalue % (unsigned) base];
|
[value % (unsigned) base];
|
||||||
uvalue = (uvalue / (unsigned) base);
|
value = (value / (unsigned) base);
|
||||||
} while (uvalue);
|
} while (value);
|
||||||
convert[place] = 0;
|
convert[vallen] = 0;
|
||||||
|
|
||||||
if (len < 0)
|
adjust_padlen(minlen, vallen, leftjust, &padlen);
|
||||||
{
|
|
||||||
/* this could happen with a "*" width spec */
|
|
||||||
ljust = 1;
|
|
||||||
len = -len;
|
|
||||||
}
|
|
||||||
padlen = len - place;
|
|
||||||
if (padlen < 0)
|
|
||||||
padlen = 0;
|
|
||||||
if (ljust)
|
|
||||||
padlen = -padlen;
|
|
||||||
|
|
||||||
/*
|
leading_pad(zpad, &signvalue, &padlen, end, output);
|
||||||
* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n",
|
|
||||||
* convert,place,signvalue,padlen));
|
while (vallen > 0)
|
||||||
*/
|
dopr_outch(convert[--vallen], end, output);
|
||||||
if (zpad && padlen > 0)
|
|
||||||
{
|
trailing_pad(&padlen, end, output);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fmtfloat(double value, char type, int forcesign, int ljust,
|
fmtfloat(double value, char type, int forcesign, int leftjust,
|
||||||
int len, int zpad, int precision, int pointflag, char *end,
|
int minlen, int zpad, int precision, int pointflag, char *end,
|
||||||
char **output)
|
char **output)
|
||||||
{
|
{
|
||||||
int signvalue = 0;
|
int signvalue = 0;
|
||||||
double uvalue;
|
int vallen;
|
||||||
char fmt[32];
|
char fmt[32];
|
||||||
char convert[512];
|
char convert[512];
|
||||||
int padlen = 0; /* amount to pad */
|
int padlen = 0; /* amount to pad */
|
||||||
|
|
||||||
uvalue = value;
|
|
||||||
/* we rely on regular C library's sprintf to do the basic conversion */
|
/* we rely on regular C library's sprintf to do the basic conversion */
|
||||||
if (pointflag)
|
if (pointflag)
|
||||||
sprintf(fmt, "%%.%d%c", precision, type);
|
sprintf(fmt, "%%.%d%c", precision, type);
|
||||||
else
|
else
|
||||||
sprintf(fmt, "%%%c", type);
|
sprintf(fmt, "%%%c", type);
|
||||||
|
|
||||||
if (value < 0)
|
if (adjust_sign((value < 0), forcesign, &signvalue))
|
||||||
{
|
value = -value;
|
||||||
signvalue = '-';
|
|
||||||
uvalue = -value;
|
|
||||||
}
|
|
||||||
else if (forcesign)
|
|
||||||
signvalue = '+';
|
|
||||||
|
|
||||||
sprintf(convert, fmt, uvalue);
|
vallen = sprintf(convert, fmt, value);
|
||||||
|
|
||||||
if (len < 0)
|
adjust_padlen(minlen, vallen, leftjust, &padlen);
|
||||||
{
|
|
||||||
/* this could happen with a "*" width spec */
|
leading_pad(zpad, &signvalue, &padlen, end, output);
|
||||||
ljust = 1;
|
|
||||||
len = -len;
|
|
||||||
}
|
|
||||||
padlen = len - strlen(convert);
|
|
||||||
if (padlen < 0)
|
|
||||||
padlen = 0;
|
|
||||||
if (ljust)
|
|
||||||
padlen = -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);
|
|
||||||
dostr(convert, 0, end, output);
|
dostr(convert, 0, end, output);
|
||||||
while (padlen < 0)
|
|
||||||
{
|
trailing_pad(&padlen, end, output);
|
||||||
dopr_outch(' ', end, output);
|
|
||||||
++padlen;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -788,3 +715,73 @@ dopr_outch(int c, char *end, char **output)
|
|||||||
if (end == 0 || *output < end)
|
if (end == 0 || *output < end)
|
||||||
*(*output)++ = c;
|
*(*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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user