From: Bruce Momjian Date: Thu, 17 Mar 2005 03:18:14 +0000 (+0000) Subject: Factor duplicate snprintf code into functions. X-Git-Tag: REL9_0_0~10587 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=7111a14fba5842aa0c02f47ec22d69535e59cf93;p=pg-rex%2Fsyncrep.git Factor duplicate snprintf code into functions. --- diff --git a/src/port/snprintf.c b/src/port/snprintf.c index e50555df62..544ab3d78c 100644 --- a/src/port/snprintf.c +++ b/src/port/snprintf.c @@ -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 = ""; + 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; + } +} +