Loading crypto/bio/b_print.c +575 −566 Original line number Diff line number Diff line Loading @@ -62,11 +62,20 @@ #include <stdio.h> #include <stdarg.h> #include <string.h> #include <ctype.h> #include <sys/types.h> #include "cryptlib.h" #include <openssl/bio.h> static void dopr (char *buffer, size_t maxlen, const char *format, va_list args); #ifdef BN_LLONG # ifndef HAVE_LONG_LONG # define HAVE_LONG_LONG # endif #endif static void dopr (char *buffer, size_t maxlen, size_t *retlen, const char *format, va_list args); int BIO_printf (BIO *bio, ...) { Loading @@ -79,10 +88,8 @@ int BIO_printf (BIO *bio, ...) format=va_arg(args, char *); hugebuf[0]='\0'; dopr(hugebuf, sizeof(hugebuf), format, args); ret=BIO_write(bio,hugebuf,strlen(hugebuf)); dopr(hugebuf, sizeof(hugebuf), &ret, format, args); ret=BIO_write(bio, hugebuf, ret); va_end(args); return(ret); Loading @@ -90,28 +97,42 @@ int BIO_printf (BIO *bio, ...) /* * Copyright Patrick Powell 1995 * This code is based on code written by Patrick Powell (papowell@astart.com) * This code is based on code written by Patrick Powell <papowell@astart.com> * It may be used for any purpose as long as this notice remains intact * on all source code distributions * on all source code distributions. */ #include <string.h> #include <ctype.h> #include <sys/types.h> #include <stdarg.h> static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max); static void fmtint (char *buffer, size_t *currlen, size_t maxlen, long value, int base, int min, int max, int flags); static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, long double fvalue, int min, int max, int flags); static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c ); /* * dopr(): poor man's version of doprintf * This code contains numerious changes and enhancements which were * made by lots of contributors over the last years to Patrick Powell's * original code: * * o Patrick Powell <papowell@astart.com> (1995) * o Brandon Long <blong@fiction.net> (1996, for Mutt) * o Thomas Roessler <roessler@guug.de> (1998, for Mutt) * o Michael Elkins <me@cs.hmc.edu> (1998, for Mutt) * o Andrew Tridgell <tridge@samba.org> (1998, for Samba) * o Luke Mewburn <lukem@netbsd.org> (1999, for LukemFTP) * o Ralf S. Engelschall <rse@engelschall.com> (1999, for Pth) */ #if HAVE_LONG_DOUBLE #define LDOUBLE long double #else #define LDOUBLE double #endif #if HAVE_LONG_LONG #define LLONG long long #else #define LLONG long #endif static void fmtstr (char *, size_t *, size_t, char *, int, int, int); static void fmtint (char *, size_t *, size_t, LLONG, int, int, int, int); static void fmtfp (char *, size_t *, size_t, LDOUBLE, int, int, int); static void dopr_outch (char *, size_t *, size_t, int); /* format read states */ #define DP_S_DEFAULT 0 #define DP_S_FLAGS 1 Loading @@ -131,19 +152,27 @@ static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c ); #define DP_F_UP (1 << 5) #define DP_F_UNSIGNED (1 << 6) /* Conversion Flags */ /* conversion flags */ #define DP_C_SHORT 1 #define DP_C_LONG 2 #define DP_C_LDOUBLE 3 #define DP_C_LLONG 4 /* some handy macros */ #define char_to_int(p) (p - '0') #define MAX(p,q) ((p >= q) ? p : q) static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) static void dopr( char *buffer, size_t maxlen, size_t *retlen, const char *format, va_list args) { char ch; long value; long double fvalue; LLONG value; LDOUBLE fvalue; char *strvalue; int min; int max; Loading @@ -153,17 +182,15 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) size_t currlen; state = DP_S_DEFAULT; currlen = flags = cflags = min = 0; flags = currlen = cflags = min = 0; max = -1; ch = *format++; while (state != DP_S_DONE) { while (state != DP_S_DONE) { if ((ch == '\0') || (currlen >= maxlen)) state = DP_S_DONE; switch(state) { switch (state) { case DP_S_DEFAULT: if (ch == '%') state = DP_S_FLAGS; Loading @@ -172,8 +199,7 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) ch = *format++; break; case DP_S_FLAGS: switch (ch) { switch (ch) { case '-': flags |= DP_F_MINUS; ch = *format++; Loading @@ -200,58 +226,54 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) } break; case DP_S_MIN: if (isdigit((unsigned char)ch)) { if (isdigit((unsigned char)ch)) { min = 10 * min + char_to_int(ch); ch = *format++; } else if (ch == '*') { } else if (ch == '*') { min = va_arg(args, int); ch = *format++; state = DP_S_DOT; } else } else state = DP_S_DOT; break; case DP_S_DOT: if (ch == '.') { if (ch == '.') { state = DP_S_MAX; ch = *format++; } else } else state = DP_S_MOD; break; case DP_S_MAX: if (isdigit((unsigned char)ch)) { if (isdigit((unsigned char)ch)) { if (max < 0) max = 0; max = 10 * max + char_to_int(ch); ch = *format++; } else if (ch == '*') { } else if (ch == '*') { max = va_arg(args, int); ch = *format++; state = DP_S_MOD; } else } else state = DP_S_MOD; break; case DP_S_MOD: /* Currently, we don't support Long Long, bummer */ switch (ch) { switch (ch) { case 'h': cflags = DP_C_SHORT; ch = *format++; break; case 'l': if (*format == 'l') { cflags = DP_C_LLONG; format++; } else cflags = DP_C_LONG; ch = *format++; break; case 'q': cflags = DP_C_LLONG; ch = *format++; break; case 'L': cflags = DP_C_LDOUBLE; ch = *format++; Loading @@ -262,63 +284,65 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) state = DP_S_CONV; break; case DP_S_CONV: switch (ch) { switch (ch) { case 'd': case 'i': if (cflags == DP_C_SHORT) switch (cflags) { case DP_C_SHORT: value = va_arg(args, short int); else if (cflags == DP_C_LONG) break; case DP_C_LONG: value = va_arg(args, long int); else value = va_arg (args, int); fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); break; case 'o': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg (args, unsigned short int); else if (cflags == DP_C_LONG) value = va_arg (args, unsigned long int); else value = va_arg (args, unsigned int); fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); case DP_C_LLONG: value = va_arg(args, LLONG); break; case 'u': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg (args, unsigned short int); else if (cflags == DP_C_LONG) value = va_arg (args, unsigned long int); else value = va_arg (args, unsigned int); default: value = va_arg(args, int); break; } fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags); break; case 'X': flags |= DP_F_UP; /* FALLTHROUGH */ case 'x': case 'o': case 'u': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg (args, unsigned short int); else if (cflags == DP_C_LONG) value = va_arg (args, unsigned long int); else value = va_arg (args, unsigned int); fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); switch (cflags) { case DP_C_SHORT: value = va_arg(args, unsigned short int); break; case DP_C_LONG: value = (LLONG) va_arg(args, unsigned long int); break; case DP_C_LLONG: value = va_arg(args, unsigned LLONG); break; default: value = (LLONG) va_arg(args, unsigned int); break; } fmtint(buffer, &currlen, maxlen, value, ch == 'o' ? 8 : (ch == 'u' ? 10 : 16), min, max, flags); break; case 'f': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, long double); fvalue = va_arg(args, LDOUBLE); else fvalue = va_arg(args, double); /* um, floating point? */ fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags); break; case 'E': flags |= DP_F_UP; case 'e': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, long double); fvalue = va_arg(args, LDOUBLE); else fvalue = va_arg(args, double); break; Loading @@ -326,38 +350,40 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) flags |= DP_F_UP; case 'g': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, long double); fvalue = va_arg(args, LDOUBLE); else fvalue = va_arg(args, double); break; case 'c': dopr_outch (buffer, &currlen, maxlen, va_arg (args, int)); dopr_outch(buffer, &currlen, maxlen, va_arg(args, int)); break; case 's': strvalue = va_arg(args, char *); if (max < 0) max = maxlen; /* ie, no max */ fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); max = maxlen; fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max); break; case 'p': strvalue = va_arg (args, void *); fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); value = (long)va_arg(args, void *); fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags); break; case 'n': if (cflags == DP_C_SHORT) { case 'n': /* XXX */ if (cflags == DP_C_SHORT) { short int *num; num = va_arg(args, short int *); *num = currlen; } else if (cflags == DP_C_LONG) { } else if (cflags == DP_C_LONG) { /* XXX */ long int *num; num = va_arg(args, long int *); *num = currlen; } else { *num = (long int) currlen; } else if (cflags == DP_C_LLONG) { /* XXX */ LLONG *num; num = va_arg(args, LLONG *); *num = (LLONG) currlen; } else { int *num; num = va_arg(args, int *); *num = currlen; Loading @@ -371,7 +397,7 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) ch = *format++; break; default: /* Unknown, skip */ /* unknown, skip */ break; } ch = *format++; Loading @@ -382,257 +408,239 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) case DP_S_DONE: break; default: /* hmm? */ break; /* some picky compilers need this */ break; } } if (currlen < maxlen - 1) if (currlen >= maxlen - 1) currlen = maxlen - 1; buffer[currlen] = '\0'; else buffer[maxlen - 1] = '\0'; *retlen = currlen; return; } static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max) static void fmtstr( char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max) { int padlen, strln; /* amount to pad */ int padlen, strln; int cnt = 0; if (value == 0) { value = "<NULL>"; } for (strln = 0; value[strln]; ++strln); /* strlen */ for (strln = 0; value[strln]; ++strln) ; padlen = min - strln; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justify */ padlen = -padlen; while ((padlen > 0) && (cnt < max)) { while ((padlen > 0) && (cnt < max)) { dopr_outch(buffer, currlen, maxlen, ' '); --padlen; ++cnt; } while (*value && (cnt < max)) { while (*value && (cnt < max)) { dopr_outch(buffer, currlen, maxlen, *value++); ++cnt; } while ((padlen < 0) && (cnt < max)) { while ((padlen < 0) && (cnt < max)) { dopr_outch(buffer, currlen, maxlen, ' '); ++padlen; ++cnt; } } /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ static void fmtint (char *buffer, size_t *currlen, size_t maxlen, long value, int base, int min, int max, int flags) static void fmtint( char *buffer, size_t *currlen, size_t maxlen, LLONG value, int base, int min, int max, int flags) { int signvalue = 0; unsigned long uvalue; unsigned LLONG uvalue; char convert[20]; int place = 0; int spadlen = 0; /* amount to space pad */ int zpadlen = 0; /* amount to zero pad */ int spadlen = 0; int zpadlen = 0; int caps = 0; if (max < 0) max = 0; uvalue = value; if(!(flags & DP_F_UNSIGNED)) { if (!(flags & DP_F_UNSIGNED)) { if (value < 0) { signvalue = '-'; uvalue = -value; } else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ } else if (flags & DP_F_PLUS) signvalue = '+'; else if (flags & DP_F_SPACE) else if (flags & DP_F_SPACE) signvalue = ' '; } if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ if (flags & DP_F_UP) caps = 1; do { convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef") [uvalue % (unsigned) base]; uvalue = (uvalue / (unsigned) base); } while (uvalue && (place < 20)); if (place == 20) place--; if (place == 20) place--; convert[place] = 0; zpadlen = max - place; spadlen = min - MAX(max, place) - (signvalue ? 1 : 0); if (zpadlen < 0) zpadlen = 0; if (spadlen < 0) spadlen = 0; if (flags & DP_F_ZERO) { if (zpadlen < 0) zpadlen = 0; if (spadlen < 0) spadlen = 0; if (flags & DP_F_ZERO) { zpadlen = MAX(zpadlen, spadlen); spadlen = 0; } if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */ spadlen = -spadlen; #ifdef DEBUG_SNPRINTF dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", zpadlen, spadlen, min, max, place)); #endif /* Spaces */ while (spadlen > 0) { /* spaces */ while (spadlen > 0) { dopr_outch(buffer, currlen, maxlen, ' '); --spadlen; } /* Sign */ /* sign */ if (signvalue) dopr_outch(buffer, currlen, maxlen, signvalue); /* Zeros */ if (zpadlen > 0) { while (zpadlen > 0) { /* zeros */ if (zpadlen > 0) { while (zpadlen > 0) { dopr_outch(buffer, currlen, maxlen, '0'); --zpadlen; } } /* Digits */ /* digits */ while (place > 0) dopr_outch(buffer, currlen, maxlen, convert[--place]); /* Left Justified spaces */ /* left justified spaces */ while (spadlen < 0) { dopr_outch(buffer, currlen, maxlen, ' '); ++spadlen; } return; } static long double abs_val (long double value) static LDOUBLE abs_val(LDOUBLE value) { long double result = value; LDOUBLE result = value; if (value < 0) result = -value; return result; } static long double pow10 (int exp) { long double result = 1; while (exp) static LDOUBLE pow10(int exp) { LDOUBLE result = 1; while (exp) { result *= 10; exp--; } return result; } static long round (long double value) static long round(LDOUBLE value) { long intpart; intpart = value; intpart = (long) value; value = value - intpart; if (value >= 0.5) intpart++; return intpart; } static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, long double fvalue, int min, int max, int flags) static void fmtfp( char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags) { int signvalue = 0; long double ufvalue; LDOUBLE ufvalue; char iconvert[20]; char fconvert[20]; int iplace = 0; int fplace = 0; int padlen = 0; /* amount to pad */ int padlen = 0; int zpadlen = 0; int caps = 0; long intpart; long fracpart; /* * AIX manpage says the default is 0, but Solaris says the default * is 6, and sprintf on AIX defaults to 6 */ if (max < 0) max = 6; ufvalue = abs_val(fvalue); if (fvalue < 0) signvalue = '-'; else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ else if (flags & DP_F_PLUS) signvalue = '+'; else if (flags & DP_F_SPACE) else if (flags & DP_F_SPACE) signvalue = ' '; #if 0 if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ #endif intpart = ufvalue; intpart = (long)ufvalue; /* * Sorry, we only support 9 digits past the decimal because of our * conversion method */ /* sorry, we only support 9 digits past the decimal because of our conversion method */ if (max > 9) max = 9; /* We "cheat" by converting the fractional part to integer by * multiplying by a factor of 10 */ /* we "cheat" by converting the fractional part to integer by multiplying by a factor of 10 */ fracpart = round((pow10(max)) * (ufvalue - intpart)); if (fracpart >= pow10 (max)) { if (fracpart >= pow10(max)) { intpart++; fracpart -= pow10(max); } #ifdef DEBUG_SNPRINTF dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart)); #endif /* Convert integer part */ /* convert integer part */ do { iconvert[iplace++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; (caps ? "0123456789ABCDEF" : "0123456789abcdef")[intpart % 10]; intpart = (intpart / 10); } while (intpart && (iplace < 20)); if (iplace == 20) iplace--; if (iplace == 20) iplace--; iconvert[iplace] = 0; /* Convert fractional part */ /* convert fractional part */ do { fconvert[fplace++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; (caps ? "0123456789ABCDEF" : "0123456789abcdef")[fracpart % 10]; fracpart = (fracpart / 10); } while (fracpart && (fplace < 20)); if (fplace == 20) fplace--; if (fplace == 20) fplace--; fconvert[fplace] = 0; /* -1 for decimal point, another -1 if we are printing a sign */ Loading @@ -643,24 +651,20 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justifty */ padlen = -padlen; if ((flags & DP_F_ZERO) && (padlen > 0)) { if (signvalue) { if ((flags & DP_F_ZERO) && (padlen > 0)) { if (signvalue) { dopr_outch(buffer, currlen, maxlen, signvalue); --padlen; signvalue = 0; } while (padlen > 0) { while (padlen > 0) { dopr_outch(buffer, currlen, maxlen, '0'); --padlen; } } while (padlen > 0) { while (padlen > 0) { dopr_outch(buffer, currlen, maxlen, ' '); --padlen; } Loading @@ -674,26 +678,31 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, * Decimal point. This should probably use locale to find the correct * char to print out. */ if (max > 0) { dopr_outch(buffer, currlen, maxlen, '.'); while (fplace > 0) dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]); while (zpadlen > 0) { } while (zpadlen > 0) { dopr_outch(buffer, currlen, maxlen, '0'); --zpadlen; } while (padlen < 0) { while (padlen < 0) { dopr_outch(buffer, currlen, maxlen, ' '); ++padlen; } } static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c) static void dopr_outch( char *buffer, size_t *currlen, size_t maxlen, int c) { if (*currlen < maxlen) buffer[(*currlen)++] = c; buffer[(*currlen)++] = (char)c; return; } Loading
crypto/bio/b_print.c +575 −566 Original line number Diff line number Diff line Loading @@ -62,11 +62,20 @@ #include <stdio.h> #include <stdarg.h> #include <string.h> #include <ctype.h> #include <sys/types.h> #include "cryptlib.h" #include <openssl/bio.h> static void dopr (char *buffer, size_t maxlen, const char *format, va_list args); #ifdef BN_LLONG # ifndef HAVE_LONG_LONG # define HAVE_LONG_LONG # endif #endif static void dopr (char *buffer, size_t maxlen, size_t *retlen, const char *format, va_list args); int BIO_printf (BIO *bio, ...) { Loading @@ -79,10 +88,8 @@ int BIO_printf (BIO *bio, ...) format=va_arg(args, char *); hugebuf[0]='\0'; dopr(hugebuf, sizeof(hugebuf), format, args); ret=BIO_write(bio,hugebuf,strlen(hugebuf)); dopr(hugebuf, sizeof(hugebuf), &ret, format, args); ret=BIO_write(bio, hugebuf, ret); va_end(args); return(ret); Loading @@ -90,28 +97,42 @@ int BIO_printf (BIO *bio, ...) /* * Copyright Patrick Powell 1995 * This code is based on code written by Patrick Powell (papowell@astart.com) * This code is based on code written by Patrick Powell <papowell@astart.com> * It may be used for any purpose as long as this notice remains intact * on all source code distributions * on all source code distributions. */ #include <string.h> #include <ctype.h> #include <sys/types.h> #include <stdarg.h> static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max); static void fmtint (char *buffer, size_t *currlen, size_t maxlen, long value, int base, int min, int max, int flags); static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, long double fvalue, int min, int max, int flags); static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c ); /* * dopr(): poor man's version of doprintf * This code contains numerious changes and enhancements which were * made by lots of contributors over the last years to Patrick Powell's * original code: * * o Patrick Powell <papowell@astart.com> (1995) * o Brandon Long <blong@fiction.net> (1996, for Mutt) * o Thomas Roessler <roessler@guug.de> (1998, for Mutt) * o Michael Elkins <me@cs.hmc.edu> (1998, for Mutt) * o Andrew Tridgell <tridge@samba.org> (1998, for Samba) * o Luke Mewburn <lukem@netbsd.org> (1999, for LukemFTP) * o Ralf S. Engelschall <rse@engelschall.com> (1999, for Pth) */ #if HAVE_LONG_DOUBLE #define LDOUBLE long double #else #define LDOUBLE double #endif #if HAVE_LONG_LONG #define LLONG long long #else #define LLONG long #endif static void fmtstr (char *, size_t *, size_t, char *, int, int, int); static void fmtint (char *, size_t *, size_t, LLONG, int, int, int, int); static void fmtfp (char *, size_t *, size_t, LDOUBLE, int, int, int); static void dopr_outch (char *, size_t *, size_t, int); /* format read states */ #define DP_S_DEFAULT 0 #define DP_S_FLAGS 1 Loading @@ -131,19 +152,27 @@ static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c ); #define DP_F_UP (1 << 5) #define DP_F_UNSIGNED (1 << 6) /* Conversion Flags */ /* conversion flags */ #define DP_C_SHORT 1 #define DP_C_LONG 2 #define DP_C_LDOUBLE 3 #define DP_C_LLONG 4 /* some handy macros */ #define char_to_int(p) (p - '0') #define MAX(p,q) ((p >= q) ? p : q) static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) static void dopr( char *buffer, size_t maxlen, size_t *retlen, const char *format, va_list args) { char ch; long value; long double fvalue; LLONG value; LDOUBLE fvalue; char *strvalue; int min; int max; Loading @@ -153,17 +182,15 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) size_t currlen; state = DP_S_DEFAULT; currlen = flags = cflags = min = 0; flags = currlen = cflags = min = 0; max = -1; ch = *format++; while (state != DP_S_DONE) { while (state != DP_S_DONE) { if ((ch == '\0') || (currlen >= maxlen)) state = DP_S_DONE; switch(state) { switch (state) { case DP_S_DEFAULT: if (ch == '%') state = DP_S_FLAGS; Loading @@ -172,8 +199,7 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) ch = *format++; break; case DP_S_FLAGS: switch (ch) { switch (ch) { case '-': flags |= DP_F_MINUS; ch = *format++; Loading @@ -200,58 +226,54 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) } break; case DP_S_MIN: if (isdigit((unsigned char)ch)) { if (isdigit((unsigned char)ch)) { min = 10 * min + char_to_int(ch); ch = *format++; } else if (ch == '*') { } else if (ch == '*') { min = va_arg(args, int); ch = *format++; state = DP_S_DOT; } else } else state = DP_S_DOT; break; case DP_S_DOT: if (ch == '.') { if (ch == '.') { state = DP_S_MAX; ch = *format++; } else } else state = DP_S_MOD; break; case DP_S_MAX: if (isdigit((unsigned char)ch)) { if (isdigit((unsigned char)ch)) { if (max < 0) max = 0; max = 10 * max + char_to_int(ch); ch = *format++; } else if (ch == '*') { } else if (ch == '*') { max = va_arg(args, int); ch = *format++; state = DP_S_MOD; } else } else state = DP_S_MOD; break; case DP_S_MOD: /* Currently, we don't support Long Long, bummer */ switch (ch) { switch (ch) { case 'h': cflags = DP_C_SHORT; ch = *format++; break; case 'l': if (*format == 'l') { cflags = DP_C_LLONG; format++; } else cflags = DP_C_LONG; ch = *format++; break; case 'q': cflags = DP_C_LLONG; ch = *format++; break; case 'L': cflags = DP_C_LDOUBLE; ch = *format++; Loading @@ -262,63 +284,65 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) state = DP_S_CONV; break; case DP_S_CONV: switch (ch) { switch (ch) { case 'd': case 'i': if (cflags == DP_C_SHORT) switch (cflags) { case DP_C_SHORT: value = va_arg(args, short int); else if (cflags == DP_C_LONG) break; case DP_C_LONG: value = va_arg(args, long int); else value = va_arg (args, int); fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); break; case 'o': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg (args, unsigned short int); else if (cflags == DP_C_LONG) value = va_arg (args, unsigned long int); else value = va_arg (args, unsigned int); fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); case DP_C_LLONG: value = va_arg(args, LLONG); break; case 'u': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg (args, unsigned short int); else if (cflags == DP_C_LONG) value = va_arg (args, unsigned long int); else value = va_arg (args, unsigned int); default: value = va_arg(args, int); break; } fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags); break; case 'X': flags |= DP_F_UP; /* FALLTHROUGH */ case 'x': case 'o': case 'u': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg (args, unsigned short int); else if (cflags == DP_C_LONG) value = va_arg (args, unsigned long int); else value = va_arg (args, unsigned int); fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); switch (cflags) { case DP_C_SHORT: value = va_arg(args, unsigned short int); break; case DP_C_LONG: value = (LLONG) va_arg(args, unsigned long int); break; case DP_C_LLONG: value = va_arg(args, unsigned LLONG); break; default: value = (LLONG) va_arg(args, unsigned int); break; } fmtint(buffer, &currlen, maxlen, value, ch == 'o' ? 8 : (ch == 'u' ? 10 : 16), min, max, flags); break; case 'f': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, long double); fvalue = va_arg(args, LDOUBLE); else fvalue = va_arg(args, double); /* um, floating point? */ fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags); break; case 'E': flags |= DP_F_UP; case 'e': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, long double); fvalue = va_arg(args, LDOUBLE); else fvalue = va_arg(args, double); break; Loading @@ -326,38 +350,40 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) flags |= DP_F_UP; case 'g': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, long double); fvalue = va_arg(args, LDOUBLE); else fvalue = va_arg(args, double); break; case 'c': dopr_outch (buffer, &currlen, maxlen, va_arg (args, int)); dopr_outch(buffer, &currlen, maxlen, va_arg(args, int)); break; case 's': strvalue = va_arg(args, char *); if (max < 0) max = maxlen; /* ie, no max */ fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); max = maxlen; fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max); break; case 'p': strvalue = va_arg (args, void *); fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); value = (long)va_arg(args, void *); fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags); break; case 'n': if (cflags == DP_C_SHORT) { case 'n': /* XXX */ if (cflags == DP_C_SHORT) { short int *num; num = va_arg(args, short int *); *num = currlen; } else if (cflags == DP_C_LONG) { } else if (cflags == DP_C_LONG) { /* XXX */ long int *num; num = va_arg(args, long int *); *num = currlen; } else { *num = (long int) currlen; } else if (cflags == DP_C_LLONG) { /* XXX */ LLONG *num; num = va_arg(args, LLONG *); *num = (LLONG) currlen; } else { int *num; num = va_arg(args, int *); *num = currlen; Loading @@ -371,7 +397,7 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) ch = *format++; break; default: /* Unknown, skip */ /* unknown, skip */ break; } ch = *format++; Loading @@ -382,257 +408,239 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) case DP_S_DONE: break; default: /* hmm? */ break; /* some picky compilers need this */ break; } } if (currlen < maxlen - 1) if (currlen >= maxlen - 1) currlen = maxlen - 1; buffer[currlen] = '\0'; else buffer[maxlen - 1] = '\0'; *retlen = currlen; return; } static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max) static void fmtstr( char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max) { int padlen, strln; /* amount to pad */ int padlen, strln; int cnt = 0; if (value == 0) { value = "<NULL>"; } for (strln = 0; value[strln]; ++strln); /* strlen */ for (strln = 0; value[strln]; ++strln) ; padlen = min - strln; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justify */ padlen = -padlen; while ((padlen > 0) && (cnt < max)) { while ((padlen > 0) && (cnt < max)) { dopr_outch(buffer, currlen, maxlen, ' '); --padlen; ++cnt; } while (*value && (cnt < max)) { while (*value && (cnt < max)) { dopr_outch(buffer, currlen, maxlen, *value++); ++cnt; } while ((padlen < 0) && (cnt < max)) { while ((padlen < 0) && (cnt < max)) { dopr_outch(buffer, currlen, maxlen, ' '); ++padlen; ++cnt; } } /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ static void fmtint (char *buffer, size_t *currlen, size_t maxlen, long value, int base, int min, int max, int flags) static void fmtint( char *buffer, size_t *currlen, size_t maxlen, LLONG value, int base, int min, int max, int flags) { int signvalue = 0; unsigned long uvalue; unsigned LLONG uvalue; char convert[20]; int place = 0; int spadlen = 0; /* amount to space pad */ int zpadlen = 0; /* amount to zero pad */ int spadlen = 0; int zpadlen = 0; int caps = 0; if (max < 0) max = 0; uvalue = value; if(!(flags & DP_F_UNSIGNED)) { if (!(flags & DP_F_UNSIGNED)) { if (value < 0) { signvalue = '-'; uvalue = -value; } else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ } else if (flags & DP_F_PLUS) signvalue = '+'; else if (flags & DP_F_SPACE) else if (flags & DP_F_SPACE) signvalue = ' '; } if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ if (flags & DP_F_UP) caps = 1; do { convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef") [uvalue % (unsigned) base]; uvalue = (uvalue / (unsigned) base); } while (uvalue && (place < 20)); if (place == 20) place--; if (place == 20) place--; convert[place] = 0; zpadlen = max - place; spadlen = min - MAX(max, place) - (signvalue ? 1 : 0); if (zpadlen < 0) zpadlen = 0; if (spadlen < 0) spadlen = 0; if (flags & DP_F_ZERO) { if (zpadlen < 0) zpadlen = 0; if (spadlen < 0) spadlen = 0; if (flags & DP_F_ZERO) { zpadlen = MAX(zpadlen, spadlen); spadlen = 0; } if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */ spadlen = -spadlen; #ifdef DEBUG_SNPRINTF dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", zpadlen, spadlen, min, max, place)); #endif /* Spaces */ while (spadlen > 0) { /* spaces */ while (spadlen > 0) { dopr_outch(buffer, currlen, maxlen, ' '); --spadlen; } /* Sign */ /* sign */ if (signvalue) dopr_outch(buffer, currlen, maxlen, signvalue); /* Zeros */ if (zpadlen > 0) { while (zpadlen > 0) { /* zeros */ if (zpadlen > 0) { while (zpadlen > 0) { dopr_outch(buffer, currlen, maxlen, '0'); --zpadlen; } } /* Digits */ /* digits */ while (place > 0) dopr_outch(buffer, currlen, maxlen, convert[--place]); /* Left Justified spaces */ /* left justified spaces */ while (spadlen < 0) { dopr_outch(buffer, currlen, maxlen, ' '); ++spadlen; } return; } static long double abs_val (long double value) static LDOUBLE abs_val(LDOUBLE value) { long double result = value; LDOUBLE result = value; if (value < 0) result = -value; return result; } static long double pow10 (int exp) { long double result = 1; while (exp) static LDOUBLE pow10(int exp) { LDOUBLE result = 1; while (exp) { result *= 10; exp--; } return result; } static long round (long double value) static long round(LDOUBLE value) { long intpart; intpart = value; intpart = (long) value; value = value - intpart; if (value >= 0.5) intpart++; return intpart; } static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, long double fvalue, int min, int max, int flags) static void fmtfp( char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags) { int signvalue = 0; long double ufvalue; LDOUBLE ufvalue; char iconvert[20]; char fconvert[20]; int iplace = 0; int fplace = 0; int padlen = 0; /* amount to pad */ int padlen = 0; int zpadlen = 0; int caps = 0; long intpart; long fracpart; /* * AIX manpage says the default is 0, but Solaris says the default * is 6, and sprintf on AIX defaults to 6 */ if (max < 0) max = 6; ufvalue = abs_val(fvalue); if (fvalue < 0) signvalue = '-'; else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ else if (flags & DP_F_PLUS) signvalue = '+'; else if (flags & DP_F_SPACE) else if (flags & DP_F_SPACE) signvalue = ' '; #if 0 if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ #endif intpart = ufvalue; intpart = (long)ufvalue; /* * Sorry, we only support 9 digits past the decimal because of our * conversion method */ /* sorry, we only support 9 digits past the decimal because of our conversion method */ if (max > 9) max = 9; /* We "cheat" by converting the fractional part to integer by * multiplying by a factor of 10 */ /* we "cheat" by converting the fractional part to integer by multiplying by a factor of 10 */ fracpart = round((pow10(max)) * (ufvalue - intpart)); if (fracpart >= pow10 (max)) { if (fracpart >= pow10(max)) { intpart++; fracpart -= pow10(max); } #ifdef DEBUG_SNPRINTF dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart)); #endif /* Convert integer part */ /* convert integer part */ do { iconvert[iplace++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; (caps ? "0123456789ABCDEF" : "0123456789abcdef")[intpart % 10]; intpart = (intpart / 10); } while (intpart && (iplace < 20)); if (iplace == 20) iplace--; if (iplace == 20) iplace--; iconvert[iplace] = 0; /* Convert fractional part */ /* convert fractional part */ do { fconvert[fplace++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; (caps ? "0123456789ABCDEF" : "0123456789abcdef")[fracpart % 10]; fracpart = (fracpart / 10); } while (fracpart && (fplace < 20)); if (fplace == 20) fplace--; if (fplace == 20) fplace--; fconvert[fplace] = 0; /* -1 for decimal point, another -1 if we are printing a sign */ Loading @@ -643,24 +651,20 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justifty */ padlen = -padlen; if ((flags & DP_F_ZERO) && (padlen > 0)) { if (signvalue) { if ((flags & DP_F_ZERO) && (padlen > 0)) { if (signvalue) { dopr_outch(buffer, currlen, maxlen, signvalue); --padlen; signvalue = 0; } while (padlen > 0) { while (padlen > 0) { dopr_outch(buffer, currlen, maxlen, '0'); --padlen; } } while (padlen > 0) { while (padlen > 0) { dopr_outch(buffer, currlen, maxlen, ' '); --padlen; } Loading @@ -674,26 +678,31 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, * Decimal point. This should probably use locale to find the correct * char to print out. */ if (max > 0) { dopr_outch(buffer, currlen, maxlen, '.'); while (fplace > 0) dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]); while (zpadlen > 0) { } while (zpadlen > 0) { dopr_outch(buffer, currlen, maxlen, '0'); --zpadlen; } while (padlen < 0) { while (padlen < 0) { dopr_outch(buffer, currlen, maxlen, ' '); ++padlen; } } static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c) static void dopr_outch( char *buffer, size_t *currlen, size_t maxlen, int c) { if (*currlen < maxlen) buffer[(*currlen)++] = c; buffer[(*currlen)++] = (char)c; return; }