From 3c06f6a0b234822c7b2d6c63ef1aaf554af7167b Mon Sep 17 00:00:00 2001 From: Ben Lindstrom Date: Wed, 31 Jan 2001 21:52:01 +0000 Subject: - (bal) Reorder. Move all bsd-*, fake-*, next-*, and cygwin* stuff to openbsd-compat/. And resolve all ./configure and Makefile.in issues assocated. Logic: * All OpenBSD functions should have the same filename as in the OpenBSD tree * All 'home brew' functions have bsd-* infront of them. * All 'not really implemented' functions have fake-* infront of them. --- openbsd-compat/bsd-snprintf.c | 818 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 818 insertions(+) create mode 100644 openbsd-compat/bsd-snprintf.c (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c new file mode 100644 index 00000000..59fefbf2 --- /dev/null +++ b/openbsd-compat/bsd-snprintf.c @@ -0,0 +1,818 @@ +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point... + * + * snprintf() is used instead of sprintf() as it does limit checks + * for string length. This covers a nasty loophole. + * + * The other functions are there to prevent NULL pointers from + * causing nast effects. + * + * More Recently: + * Brandon Long 9/15/96 for mutt 0.43 + * This was ugly. It is still ugly. I opted out of floating point + * numbers, but the formatter understands just about everything + * from the normal C string format, at least as far as I can tell from + * the Solaris 2.5 printf(3S) man page. + * + * Brandon Long 10/22/97 for mutt 0.87.1 + * Ok, added some minimal floating point support, which means this + * probably requires libm on most operating systems. Don't yet + * support the exponent (e,E) and sigfig (g,G). Also, fmtint() + * was pretty badly broken, it just wasn't being exercised in ways + * which showed it, so that's been fixed. Also, formated the code + * to mutt conventions, and removed dead code left over from the + * original. Also, there is now a builtin-test, just compile with: + * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm + * and run snprintf for results. + * + * Thomas Roessler 01/27/98 for mutt 0.89i + * The PGP code was using unsigned hexadecimal formats. + * Unfortunately, unsigned formats simply didn't work. + * + * Michael Elkins 03/05/98 for mutt 0.90.8 + * The original code assumed that both snprintf() and vsnprintf() were + * missing. Some systems only have snprintf() but not vsnprintf(), so + * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. + * + * Ben Lindstrom 09/27/00 for OpenSSH + * Welcome to the world of %lld and %qd support. With other + * long long support. This is needed for sftp-server to work + * right. + **************************************************************/ + +#include "config.h" + +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) + +#include +# include +#include + +/* Define this as a fall through, HAVE_STDARG_H is probably already set */ + +#define HAVE_VARARGS_H + +/* varargs declarations: */ + +#if defined(HAVE_STDARG_H) +# include +# define HAVE_STDARGS /* let's hope that works everywhere (mj) */ +# define VA_LOCAL_DECL va_list ap +# define VA_START(f) va_start(ap, f) +# define VA_SHIFT(v,t) ; /* no-op for ANSI */ +# define VA_END va_end(ap) +#else +# if defined(HAVE_VARARGS_H) +# include +# undef HAVE_STDARGS +# define VA_LOCAL_DECL va_list ap +# define VA_START(f) va_start(ap) /* f is ignored! */ +# define VA_SHIFT(v,t) v = va_arg(ap,t) +# define VA_END va_end(ap) +# else +/*XX ** NO VARARGS ** XX*/ +# endif +#endif + +/*int snprintf (char *str, size_t count, const char *fmt, ...);*/ +/*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/ + +static void dopr (char *buffer, size_t maxlen, const char *format, + va_list args); +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 + */ + +/* format read states */ +#define DP_S_DEFAULT 0 +#define DP_S_FLAGS 1 +#define DP_S_MIN 2 +#define DP_S_DOT 3 +#define DP_S_MAX 4 +#define DP_S_MOD 5 +#define DP_S_CONV 6 +#define DP_S_DONE 7 + +/* format flags - Bits */ +#define DP_F_MINUS (1 << 0) +#define DP_F_PLUS (1 << 1) +#define DP_F_SPACE (1 << 2) +#define DP_F_NUM (1 << 3) +#define DP_F_ZERO (1 << 4) +#define DP_F_UP (1 << 5) +#define DP_F_UNSIGNED (1 << 6) + +/* Conversion Flags */ +#define DP_C_SHORT 1 +#define DP_C_LONG 2 +#define DP_C_LDOUBLE 3 +#define DP_C_LONG_LONG 4 + +#define char_to_int(p) (p - '0') +#ifndef MAX +# define MAX(p,q) ((p >= q) ? p : q) +#endif + +static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) +{ + char ch; + long value; + long double fvalue; + char *strvalue; + int min; + int max; + int state; + int flags; + int cflags; + size_t currlen; + + state = DP_S_DEFAULT; + currlen = flags = cflags = min = 0; + max = -1; + ch = *format++; + + while (state != DP_S_DONE) + { + if ((ch == '\0') || (currlen >= maxlen)) + state = DP_S_DONE; + + switch(state) + { + case DP_S_DEFAULT: + if (ch == '%') + state = DP_S_FLAGS; + else + dopr_outch (buffer, &currlen, maxlen, ch); + ch = *format++; + break; + case DP_S_FLAGS: + switch (ch) + { + case '-': + flags |= DP_F_MINUS; + ch = *format++; + break; + case '+': + flags |= DP_F_PLUS; + ch = *format++; + break; + case ' ': + flags |= DP_F_SPACE; + ch = *format++; + break; + case '#': + flags |= DP_F_NUM; + ch = *format++; + break; + case '0': + flags |= DP_F_ZERO; + ch = *format++; + break; + default: + state = DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if (isdigit((unsigned char)ch)) + { + min = 10*min + char_to_int (ch); + ch = *format++; + } + else if (ch == '*') + { + min = va_arg (args, int); + ch = *format++; + state = DP_S_DOT; + } + else + state = DP_S_DOT; + break; + case DP_S_DOT: + if (ch == '.') + { + state = DP_S_MAX; + ch = *format++; + } + else + state = DP_S_MOD; + break; + case DP_S_MAX: + if (isdigit((unsigned char)ch)) + { + if (max < 0) + max = 0; + max = 10*max + char_to_int (ch); + ch = *format++; + } + else if (ch == '*') + { + max = va_arg (args, int); + ch = *format++; + state = DP_S_MOD; + } + else + state = DP_S_MOD; + break; + case DP_S_MOD: + switch (ch) + { + case 'h': + cflags = DP_C_SHORT; + ch = *format++; + break; + case 'l': + cflags = DP_C_LONG; + ch = *format++; + if (ch == 'l') { + cflags = DP_C_LONG_LONG; + ch = *format++; + } + break; + case 'q': + cflags = DP_C_LONG_LONG; + ch = *format++; + break; + case 'L': + cflags = DP_C_LDOUBLE; + ch = *format++; + break; + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + switch (ch) + { + case 'd': + case 'i': + if (cflags == DP_C_SHORT) + value = va_arg (args, int); + else if (cflags == DP_C_LONG) + value = va_arg (args, long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg (args, long long); + 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 int); + else if (cflags == DP_C_LONG) + value = va_arg (args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg (args, unsigned long long); + else + value = va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); + break; + case 'u': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned int); + else if (cflags == DP_C_LONG) + value = va_arg (args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg (args, unsigned long long); + else + value = va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'X': + flags |= DP_F_UP; + case 'x': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned int); + else if (cflags == DP_C_LONG) + value = va_arg (args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg (args, unsigned long long); + else + value = va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); + break; + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, long double); + 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); + else + fvalue = va_arg (args, double); + break; + case 'G': + flags |= DP_F_UP; + case 'g': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, long double); + else + fvalue = va_arg (args, double); + break; + case 'c': + 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); + break; + case 'p': + strvalue = va_arg (args, void *); + fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); + break; + case 'n': + if (cflags == DP_C_SHORT) + { + short int *num; + num = va_arg (args, short int *); + *num = currlen; + } + else if (cflags == DP_C_LONG) + { + long int *num; + num = va_arg (args, long int *); + *num = currlen; + } + else if (cflags == DP_C_LONG_LONG) + { + long long *num; + num = va_arg (args, long long *); + *num = currlen; + } + else + { + int *num; + num = va_arg (args, int *); + *num = currlen; + } + break; + case '%': + dopr_outch (buffer, &currlen, maxlen, ch); + break; + case 'w': + /* not supported yet, treat as next char */ + ch = *format++; + break; + default: + /* Unknown, skip */ + break; + } + ch = *format++; + state = DP_S_DEFAULT; + flags = cflags = min = 0; + max = -1; + break; + case DP_S_DONE: + break; + default: + /* hmm? */ + break; /* some picky compilers need this */ + } + } + if (currlen < maxlen - 1) + buffer[currlen] = '\0'; + else + buffer[maxlen - 1] = '\0'; +} + +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 cnt = 0; + + if (value == 0) + { + value = ""; + } + + for (strln = 0; value[strln]; ++strln); /* strlen */ + padlen = min - strln; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justify */ + + while ((padlen > 0) && (cnt < max)) + { + dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + ++cnt; + } + while (*value && (cnt < max)) + { + dopr_outch (buffer, currlen, maxlen, *value++); + ++cnt; + } + 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) +{ + int signvalue = 0; + unsigned long uvalue; + char convert[20]; + int place = 0; + int spadlen = 0; /* amount to space pad */ + int zpadlen = 0; /* amount to zero pad */ + int caps = 0; + + if (max < 0) + max = 0; + + uvalue = value; + + if(!(flags & DP_F_UNSIGNED)) + { + if( value < 0 ) { + signvalue = '-'; + uvalue = -value; + } + else + if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else + if (flags & DP_F_SPACE) + signvalue = ' '; + } + + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ + + do { + convert[place++] = + (caps? "0123456789ABCDEF":"0123456789abcdef") + [uvalue % (unsigned)base ]; + uvalue = (uvalue / (unsigned)base ); + } while(uvalue && (place < 20)); + 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) + { + zpadlen = MAX(zpadlen, spadlen); + spadlen = 0; + } + if (flags & DP_F_MINUS) + spadlen = -spadlen; /* Left Justifty */ + +#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) + { + dopr_outch (buffer, currlen, maxlen, ' '); + --spadlen; + } + + /* Sign */ + if (signvalue) + dopr_outch (buffer, currlen, maxlen, signvalue); + + /* Zeros */ + if (zpadlen > 0) + { + while (zpadlen > 0) + { + dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + } + + /* Digits */ + while (place > 0) + dopr_outch (buffer, currlen, maxlen, convert[--place]); + + /* Left Justified spaces */ + while (spadlen < 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++spadlen; + } +} + +static long double abs_val (long double value) +{ + long double result = value; + + if (value < 0) + result = -value; + + return result; +} + +static long double pow10 (int exp) +{ + long double result = 1; + + while (exp) + { + result *= 10; + exp--; + } + + return result; +} + +static long round (long double value) +{ + long intpart; + + intpart = 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) +{ + int signvalue = 0; + long double ufvalue; + char iconvert[20]; + char fconvert[20]; + int iplace = 0; + int fplace = 0; + int padlen = 0; /* amount to pad */ + 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) */ + signvalue = '+'; + else + if (flags & DP_F_SPACE) + signvalue = ' '; + +#if 0 + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ +#endif + + intpart = ufvalue; + + /* + * 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 + */ + fracpart = round ((pow10 (max)) * (ufvalue - intpart)); + + 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 */ + do { + iconvert[iplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; + intpart = (intpart / 10); + } while(intpart && (iplace < 20)); + if (iplace == 20) iplace--; + iconvert[iplace] = 0; + + /* Convert fractional part */ + do { + fconvert[fplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; + fracpart = (fracpart / 10); + } while(fracpart && (fplace < 20)); + if (fplace == 20) fplace--; + fconvert[fplace] = 0; + + /* -1 for decimal point, another -1 if we are printing a sign */ + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + zpadlen = max - fplace; + if (zpadlen < 0) + zpadlen = 0; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justifty */ + + if ((flags & DP_F_ZERO) && (padlen > 0)) + { + if (signvalue) + { + dopr_outch (buffer, currlen, maxlen, signvalue); + --padlen; + signvalue = 0; + } + while (padlen > 0) + { + dopr_outch (buffer, currlen, maxlen, '0'); + --padlen; + } + } + while (padlen > 0) + { + dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + } + if (signvalue) + dopr_outch (buffer, currlen, maxlen, signvalue); + + while (iplace > 0) + dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); + + /* + * Decimal point. This should probably use locale to find the correct + * char to print out. + */ + dopr_outch (buffer, currlen, maxlen, '.'); + + while (fplace > 0) + dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); + + while (zpadlen > 0) + { + dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + + while (padlen < 0) + { + dopr_outch (buffer, currlen, maxlen, ' '); + ++padlen; + } +} + +static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c) +{ + if (*currlen < maxlen) + buffer[(*currlen)++] = c; +} +#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ + +#ifndef HAVE_VSNPRINTF +int vsnprintf (char *str, size_t count, const char *fmt, va_list args) +{ + str[0] = 0; + dopr(str, count, fmt, args); + return(strlen(str)); +} +#endif /* !HAVE_VSNPRINTF */ + +#ifndef HAVE_SNPRINTF +/* VARARGS3 */ +#ifdef HAVE_STDARGS +int snprintf (char *str,size_t count,const char *fmt,...) +#else +int snprintf (va_alist) va_dcl +#endif +{ +#ifndef HAVE_STDARGS + char *str; + size_t count; + char *fmt; +#endif + VA_LOCAL_DECL; + + VA_START (fmt); + VA_SHIFT (str, char *); + VA_SHIFT (count, size_t ); + VA_SHIFT (fmt, char *); + (void) vsnprintf(str, count, fmt, ap); + VA_END; + return(strlen(str)); +} + +#ifdef TEST_SNPRINTF +#ifndef LONG_STRING +#define LONG_STRING 1024 +#endif +int main (void) +{ + char buf1[LONG_STRING]; + char buf2[LONG_STRING]; + char *fp_fmt[] = { + "%-1.5f", + "%1.5f", + "%123.9f", + "%10.5f", + "% 10.5f", + "%+22.9f", + "%+4.9f", + "%01.3f", + "%4f", + "%3.1f", + "%3.2f", + NULL + }; + double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, + 0.9996, 1.996, 4.136, 0}; + char *int_fmt[] = { + "%-1.5d", + "%1.5d", + "%123.9d", + "%5.5d", + "%10.5d", + "% 10.5d", + "%+22.33d", + "%01.3d", + "%4d", + "%lld", + "%qd", + NULL + }; + long long int_nums[] = { -1, 134, 91340, 341, 0203, 0, 9999999 }; + int x, y; + int fail = 0; + int num = 0; + + printf ("Testing snprintf format codes against system sprintf...\n"); + + for (x = 0; fp_fmt[x] != NULL ; x++) + for (y = 0; fp_nums[y] != 0 ; y++) + { + snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]); + sprintf (buf2, fp_fmt[x], fp_nums[y]); + if (strcmp (buf1, buf2)) + { + printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", + fp_fmt[x], buf1, buf2); + fail++; + } + num++; + } + + for (x = 0; int_fmt[x] != NULL ; x++) + for (y = 0; int_nums[y] != 0 ; y++) + { + snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]); + sprintf (buf2, int_fmt[x], int_nums[y]); + if (strcmp (buf1, buf2)) + { + printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", + int_fmt[x], buf1, buf2); + fail++; + } + num++; + } + printf ("%d tests failed out of %d.\n", fail, num); +} +#endif /* SNPRINTF_TEST */ + +#endif /* !HAVE_SNPRINTF */ -- cgit v1.2.3 From e9cf357a99dcd2db14635974289e04f5f0808123 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 9 Feb 2001 12:55:35 +1100 Subject: - (djm) Add CVS Id's to files that we have missed --- openbsd-compat/bsd-snprintf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index 59fefbf2..c75359c5 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -44,7 +44,9 @@ * right. **************************************************************/ -#include "config.h" +#include "includes.h" + +RCSID("$Id: bsd-snprintf.c,v 1.2 2001/02/09 01:55:36 djm Exp $"); #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) -- cgit v1.2.3 From 6c92dab9a1ab05426b42d7cc5dca2a9c5af52f1d Mon Sep 17 00:00:00 2001 From: Ben Lindstrom Date: Tue, 13 Feb 2001 02:18:50 +0000 Subject: - (bal) Cleaned out bsd-snprintf.c. VARARGS have been banished and I did a base KNF over the whe whole file to make it more acceptable. (backed out of original patch and removed it from ChangeLog) This has been a long time coming. If we decide that we need VARARGS support we should do it at a higher level, since no where else do we support VARARGS in the code base. --- openbsd-compat/bsd-snprintf.c | 1290 +++++++++++++++++++---------------------- 1 file changed, 603 insertions(+), 687 deletions(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index c75359c5..55d14284 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -38,60 +38,37 @@ * missing. Some systems only have snprintf() but not vsnprintf(), so * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. * - * Ben Lindstrom 09/27/00 for OpenSSH + * Ben Lindstrom 09/27/00 for OpenSSH * Welcome to the world of %lld and %qd support. With other * long long support. This is needed for sftp-server to work * right. + * + * Ben Lindstrom 02/12/01 for OpenSSH + * Removed all hint of VARARGS stuff and banished it to the void, + * and did a bit of KNF style work to make things a bit more + * acceptable. Consider stealing from mutt or enlightenment. **************************************************************/ #include "includes.h" -RCSID("$Id: bsd-snprintf.c,v 1.2 2001/02/09 01:55:36 djm Exp $"); +RCSID("$Id: bsd-snprintf.c,v 1.3 2001/02/13 02:18:50 mouring Exp $"); #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) -#include -# include -#include - -/* Define this as a fall through, HAVE_STDARG_H is probably already set */ - -#define HAVE_VARARGS_H - -/* varargs declarations: */ - -#if defined(HAVE_STDARG_H) -# include -# define HAVE_STDARGS /* let's hope that works everywhere (mj) */ -# define VA_LOCAL_DECL va_list ap -# define VA_START(f) va_start(ap, f) -# define VA_SHIFT(v,t) ; /* no-op for ANSI */ -# define VA_END va_end(ap) -#else -# if defined(HAVE_VARARGS_H) -# include -# undef HAVE_STDARGS -# define VA_LOCAL_DECL va_list ap -# define VA_START(f) va_start(ap) /* f is ignored! */ -# define VA_SHIFT(v,t) v = va_arg(ap,t) -# define VA_END va_end(ap) -# else -/*XX ** NO VARARGS ** XX*/ -# endif -#endif - -/*int snprintf (char *str, size_t count, const char *fmt, ...);*/ -/*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/ - -static void dopr (char *buffer, size_t maxlen, const char *format, - va_list args); -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 ); +static void +dopr(char *buffer, size_t maxlen, const char *format, va_list args); + +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); /* * dopr(): poor man's version of doprintf @@ -123,697 +100,636 @@ static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c ); #define DP_C_LONG_LONG 4 #define char_to_int(p) (p - '0') -#ifndef MAX -# define MAX(p,q) ((p >= q) ? p : q) -#endif +#define abs_val(p) (p < 0 ? -p : p) -static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) + +static void +dopr(char *buffer, size_t maxlen, const char *format, va_list args) { - char ch; - long value; - long double fvalue; - char *strvalue; - int min; - int max; - int state; - int flags; - int cflags; - size_t currlen; + char *strvalue; + char ch; + long value; + long double fvalue; + int min = 0; + int max = -1; + int state = DP_S_DEFAULT; + int flags = 0; + int cflags = 0; + size_t currlen = 0; - state = DP_S_DEFAULT; - currlen = flags = cflags = min = 0; - max = -1; - ch = *format++; - - while (state != DP_S_DONE) - { - if ((ch == '\0') || (currlen >= maxlen)) - state = DP_S_DONE; - - switch(state) - { - case DP_S_DEFAULT: - if (ch == '%') - state = DP_S_FLAGS; - else - dopr_outch (buffer, &currlen, maxlen, ch); - ch = *format++; - break; - case DP_S_FLAGS: - switch (ch) - { - case '-': - flags |= DP_F_MINUS; - ch = *format++; - break; - case '+': - flags |= DP_F_PLUS; - ch = *format++; - break; - case ' ': - flags |= DP_F_SPACE; - ch = *format++; - break; - case '#': - flags |= DP_F_NUM; - ch = *format++; - break; - case '0': - flags |= DP_F_ZERO; - ch = *format++; - break; - default: - state = DP_S_MIN; - break; - } - break; - case DP_S_MIN: - if (isdigit((unsigned char)ch)) - { - min = 10*min + char_to_int (ch); - ch = *format++; - } - else if (ch == '*') - { - min = va_arg (args, int); - ch = *format++; - state = DP_S_DOT; - } - else - state = DP_S_DOT; - break; - case DP_S_DOT: - if (ch == '.') - { - state = DP_S_MAX; ch = *format++; - } - else - state = DP_S_MOD; - break; - case DP_S_MAX: - if (isdigit((unsigned char)ch)) - { - if (max < 0) - max = 0; - max = 10*max + char_to_int (ch); - ch = *format++; - } - else if (ch == '*') - { - max = va_arg (args, int); - ch = *format++; - state = DP_S_MOD; - } - else - state = DP_S_MOD; - break; - case DP_S_MOD: - switch (ch) - { - case 'h': - cflags = DP_C_SHORT; - ch = *format++; - break; - case 'l': - cflags = DP_C_LONG; - ch = *format++; - if (ch == 'l') { - cflags = DP_C_LONG_LONG; - ch = *format++; - } - break; - case 'q': - cflags = DP_C_LONG_LONG; - ch = *format++; - break; - case 'L': - cflags = DP_C_LDOUBLE; - ch = *format++; - break; - default: - break; - } - state = DP_S_CONV; - break; - case DP_S_CONV: - switch (ch) - { - case 'd': - case 'i': - if (cflags == DP_C_SHORT) - value = va_arg (args, int); - else if (cflags == DP_C_LONG) - value = va_arg (args, long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg (args, long long); - 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 int); - else if (cflags == DP_C_LONG) - value = va_arg (args, unsigned long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg (args, unsigned long long); - else - value = va_arg (args, unsigned int); - fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); - break; - case 'u': - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_SHORT) - value = va_arg (args, unsigned int); - else if (cflags == DP_C_LONG) - value = va_arg (args, unsigned long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg (args, unsigned long long); - else - value = va_arg (args, unsigned int); - fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); - break; - case 'X': - flags |= DP_F_UP; - case 'x': - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_SHORT) - value = va_arg (args, unsigned int); - else if (cflags == DP_C_LONG) - value = va_arg (args, unsigned long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg (args, unsigned long long); - else - value = va_arg (args, unsigned int); - fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); - break; - case 'f': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg (args, long double); - 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); - else - fvalue = va_arg (args, double); - break; - case 'G': - flags |= DP_F_UP; - case 'g': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg (args, long double); - else - fvalue = va_arg (args, double); - break; - case 'c': - 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); - break; - case 'p': - strvalue = va_arg (args, void *); - fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); - break; - case 'n': - if (cflags == DP_C_SHORT) - { - short int *num; - num = va_arg (args, short int *); - *num = currlen; - } - else if (cflags == DP_C_LONG) - { - long int *num; - num = va_arg (args, long int *); - *num = currlen; - } - else if (cflags == DP_C_LONG_LONG) - { - long long *num; - num = va_arg (args, long long *); - *num = currlen; - } + + while (state != DP_S_DONE) { + if ((ch == '\0') || (currlen >= maxlen)) + state = DP_S_DONE; + + switch(state) { + case DP_S_DEFAULT: + if (ch == '%') + state = DP_S_FLAGS; + else + dopr_outch(buffer, &currlen, maxlen, ch); + ch = *format++; + break; + case DP_S_FLAGS: + switch (ch) { + case '-': + flags |= DP_F_MINUS; + ch = *format++; + break; + case '+': + flags |= DP_F_PLUS; + ch = *format++; + break; + case ' ': + flags |= DP_F_SPACE; + ch = *format++; + break; + case '#': + flags |= DP_F_NUM; + ch = *format++; + break; + case '0': + flags |= DP_F_ZERO; + ch = *format++; + break; + default: + state = DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if (isdigit((unsigned char)ch)) { + min = 10*min + char_to_int (ch); + ch = *format++; + } else if (ch == '*') { + min = va_arg (args, int); + ch = *format++; + state = DP_S_DOT; + } else + state = DP_S_DOT; + break; + case DP_S_DOT: + if (ch == '.') { + state = DP_S_MAX; + ch = *format++; + } else + state = DP_S_MOD; + break; + case DP_S_MAX: + if (isdigit((unsigned char)ch)) { + if (max < 0) + max = 0; + max = 10*max + char_to_int(ch); + ch = *format++; + } else if (ch == '*') { + max = va_arg (args, int); + ch = *format++; + state = DP_S_MOD; + } else + state = DP_S_MOD; + break; + case DP_S_MOD: + switch (ch) { + case 'h': + cflags = DP_C_SHORT; + ch = *format++; + break; + case 'l': + cflags = DP_C_LONG; + ch = *format++; + if (ch == 'l') { + cflags = DP_C_LONG_LONG; + ch = *format++; + } + break; + case 'q': + cflags = DP_C_LONG_LONG; + ch = *format++; + break; + case 'L': + cflags = DP_C_LDOUBLE; + ch = *format++; + break; + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + switch (ch) { + case 'd': + case 'i': + if (cflags == DP_C_SHORT) + value = va_arg(args, int); + else if (cflags == DP_C_LONG) + value = va_arg(args, long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg (args, long long); + 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 int); + else if (cflags == DP_C_LONG) + value = va_arg(args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg(args, unsigned long long); + else + value = va_arg(args, unsigned int); + fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags); + break; + case 'u': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg(args, unsigned int); + else if (cflags == DP_C_LONG) + value = va_arg(args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg(args, unsigned long long); + else + value = va_arg(args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'X': + flags |= DP_F_UP; + case 'x': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg(args, unsigned int); + else if (cflags == DP_C_LONG) + value = va_arg(args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg(args, unsigned long long); + else + value = va_arg(args, unsigned int); + fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags); + break; + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, long double); + 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); + else + fvalue = va_arg(args, double); + break; + case 'G': + flags |= DP_F_UP; + case 'g': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, long double); + else + fvalue = va_arg(args, double); + break; + case 'c': + 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); + break; + case 'p': + strvalue = va_arg(args, void *); + fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); + break; + case 'n': + if (cflags == DP_C_SHORT) { + short int *num; + num = va_arg(args, short int *); + *num = currlen; + } else if (cflags == DP_C_LONG) { + long int *num; + num = va_arg(args, long int *); + *num = currlen; + } else if (cflags == DP_C_LONG_LONG) { + long long *num; + num = va_arg(args, long long *); + *num = currlen; + } else { + int *num; + num = va_arg(args, int *); + *num = currlen; + } + break; + case '%': + dopr_outch(buffer, &currlen, maxlen, ch); + break; + case 'w': /* not supported yet, treat as next char */ + ch = *format++; + break; + default: /* Unknown, skip */ + break; + } + ch = *format++; + state = DP_S_DEFAULT; + flags = cflags = min = 0; + max = -1; + break; + case DP_S_DONE: + break; + default: /* hmm? */ + break; /* some picky compilers need this */ + } + } + if (currlen < maxlen - 1) + buffer[currlen] = '\0'; else - { - int *num; - num = va_arg (args, int *); - *num = currlen; - } - break; - case '%': - dopr_outch (buffer, &currlen, maxlen, ch); - break; - case 'w': - /* not supported yet, treat as next char */ - ch = *format++; - break; - default: - /* Unknown, skip */ - break; - } - ch = *format++; - state = DP_S_DEFAULT; - flags = cflags = min = 0; - max = -1; - break; - case DP_S_DONE: - break; - default: - /* hmm? */ - break; /* some picky compilers need this */ - } - } - if (currlen < maxlen - 1) - buffer[currlen] = '\0'; - else - buffer[maxlen - 1] = '\0'; + buffer[maxlen - 1] = '\0'; } -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 cnt = 0; + int padlen, strln; /* amount to pad */ + int cnt = 0; - if (value == 0) - { - value = ""; - } - - for (strln = 0; value[strln]; ++strln); /* strlen */ - padlen = min - strln; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; /* Left Justify */ - - while ((padlen > 0) && (cnt < max)) - { - dopr_outch (buffer, currlen, maxlen, ' '); - --padlen; - ++cnt; - } - while (*value && (cnt < max)) - { - dopr_outch (buffer, currlen, maxlen, *value++); - ++cnt; - } - while ((padlen < 0) && (cnt < max)) - { - dopr_outch (buffer, currlen, maxlen, ' '); - ++padlen; - ++cnt; - } + if (value == 0) + value = ""; + + for (strln = 0; value[strln]; ++strln); /* strlen */ + padlen = min - strln; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justify */ + + while ((padlen > 0) && (cnt < max)) { + dopr_outch(buffer, currlen, maxlen, ' '); + --padlen; + ++cnt; + } + while (*value && (cnt < max)) { + dopr_outch(buffer, currlen, maxlen, *value++); + ++cnt; + } + 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, + long value, int base, int min, int max, int flags) { - int signvalue = 0; - unsigned long uvalue; - char convert[20]; - int place = 0; - int spadlen = 0; /* amount to space pad */ - int zpadlen = 0; /* amount to zero pad */ - int caps = 0; + unsigned long uvalue; + char convert[20]; + int signvalue = 0; + int place = 0; + int spadlen = 0; /* amount to space pad */ + int zpadlen = 0; /* amount to zero pad */ + int caps = 0; - if (max < 0) - max = 0; - - uvalue = value; - - if(!(flags & DP_F_UNSIGNED)) - { - if( value < 0 ) { - signvalue = '-'; - uvalue = -value; - } - else - if (flags & DP_F_PLUS) /* Do a sign (+/i) */ - signvalue = '+'; - else - if (flags & DP_F_SPACE) - signvalue = ' '; - } + if (max < 0) + max = 0; + + uvalue = value; + + if (!(flags & DP_F_UNSIGNED)) { + if (value < 0) { + signvalue = '-'; + uvalue = -value; + } else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else if (flags & DP_F_SPACE) + signvalue = ' '; + } - if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ - - do { - convert[place++] = - (caps? "0123456789ABCDEF":"0123456789abcdef") - [uvalue % (unsigned)base ]; - uvalue = (uvalue / (unsigned)base ); - } while(uvalue && (place < 20)); - 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) - { - zpadlen = MAX(zpadlen, spadlen); - spadlen = 0; - } - if (flags & DP_F_MINUS) - spadlen = -spadlen; /* Left Justifty */ - -#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) - { - dopr_outch (buffer, currlen, maxlen, ' '); - --spadlen; - } - - /* Sign */ - if (signvalue) - dopr_outch (buffer, currlen, maxlen, signvalue); - - /* Zeros */ - if (zpadlen > 0) - { - while (zpadlen > 0) - { - dopr_outch (buffer, currlen, maxlen, '0'); - --zpadlen; - } - } - - /* Digits */ - while (place > 0) - dopr_outch (buffer, currlen, maxlen, convert[--place]); + if (flags & DP_F_UP) + caps = 1; /* Should characters be upper case? */ + + do { + convert[place++] = + (caps? "0123456789ABCDEF":"0123456789abcdef") + [uvalue % (unsigned)base]; + uvalue = (uvalue / (unsigned)base ); + } while (uvalue && (place < 20)); + 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) { + zpadlen = MAX(zpadlen, spadlen); + spadlen = 0; + } + if (flags & DP_F_MINUS) + spadlen = -spadlen; /* Left Justifty */ + + + /* Spaces */ + while (spadlen > 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + --spadlen; + } + + /* Sign */ + if (signvalue) + dopr_outch(buffer, currlen, maxlen, signvalue); + + /* Zeros */ + if (zpadlen > 0) { + while (zpadlen > 0) { + dopr_outch(buffer, currlen, maxlen, '0'); + --zpadlen; + } + } + + /* Digits */ + while (place > 0) + dopr_outch(buffer, currlen, maxlen, convert[--place]); - /* Left Justified spaces */ - while (spadlen < 0) { - dopr_outch (buffer, currlen, maxlen, ' '); - ++spadlen; - } -} - -static long double abs_val (long double value) -{ - long double result = value; - - if (value < 0) - result = -value; - - return result; + /* Left Justified spaces */ + while (spadlen < 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++spadlen; + } } -static long double pow10 (int exp) +static long double +pow10(int exp) { - long double result = 1; + long double result = 1; - while (exp) - { - result *= 10; - exp--; - } + while (exp) { + result *= 10; + exp--; + } - return result; + return result; } -static long round (long double value) +static long +round(long double value) { - long intpart; + long intpart = value; - intpart = value; - value = value - intpart; - if (value >= 0.5) - intpart++; + value -= intpart; + if (value >= 0.5) + intpart++; - return 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, long double fvalue, + int min, int max, int flags) { - int signvalue = 0; - long double ufvalue; - char iconvert[20]; - char fconvert[20]; - int iplace = 0; - int fplace = 0; - int padlen = 0; /* amount to pad */ - int zpadlen = 0; - int caps = 0; - long intpart; - long fracpart; + char iconvert[20]; + char fconvert[20]; + int signvalue = 0; + int iplace = 0; + int fplace = 0; + int padlen = 0; /* amount to pad */ + int zpadlen = 0; + int caps = 0; + long intpart; + long fracpart; + long double ufvalue; - /* - * 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) */ - signvalue = '+'; - else - if (flags & DP_F_SPACE) - signvalue = ' '; - -#if 0 - if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ -#endif - - intpart = ufvalue; - - /* - * 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 - */ - fracpart = round ((pow10 (max)) * (ufvalue - intpart)); - - 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 */ - do { - iconvert[iplace++] = - (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; - intpart = (intpart / 10); - } while(intpart && (iplace < 20)); - if (iplace == 20) iplace--; - iconvert[iplace] = 0; - - /* Convert fractional part */ - do { - fconvert[fplace++] = - (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; - fracpart = (fracpart / 10); - } while(fracpart && (fplace < 20)); - if (fplace == 20) fplace--; - fconvert[fplace] = 0; - - /* -1 for decimal point, another -1 if we are printing a sign */ - padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); - zpadlen = max - fplace; - if (zpadlen < 0) - zpadlen = 0; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; /* Left Justifty */ - - if ((flags & DP_F_ZERO) && (padlen > 0)) - { - if (signvalue) - { - dopr_outch (buffer, currlen, maxlen, signvalue); - --padlen; - signvalue = 0; - } - while (padlen > 0) - { - dopr_outch (buffer, currlen, maxlen, '0'); - --padlen; - } - } - while (padlen > 0) - { - dopr_outch (buffer, currlen, maxlen, ' '); - --padlen; - } - if (signvalue) - dopr_outch (buffer, currlen, maxlen, signvalue); - - while (iplace > 0) - dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); - - /* - * Decimal point. This should probably use locale to find the correct - * char to print out. - */ - dopr_outch (buffer, currlen, maxlen, '.'); - - while (fplace > 0) - dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); - - while (zpadlen > 0) - { - dopr_outch (buffer, currlen, maxlen, '0'); - --zpadlen; - } - - while (padlen < 0) - { - dopr_outch (buffer, currlen, maxlen, ' '); - ++padlen; - } + /* + * 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) */ + signvalue = '+'; + else if (flags & DP_F_SPACE) + signvalue = ' '; + + intpart = ufvalue; + + /* + * 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 + */ + fracpart = round((pow10 (max)) * (ufvalue - intpart)); + + if (fracpart >= pow10 (max)) { + intpart++; + fracpart -= pow10 (max); + } + + /* Convert integer part */ + do { + iconvert[iplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; + intpart = (intpart / 10); + } while(intpart && (iplace < 20)); + if (iplace == 20) + iplace--; + iconvert[iplace] = 0; + + /* Convert fractional part */ + do { + fconvert[fplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; + fracpart = (fracpart / 10); + } while(fracpart && (fplace < 20)); + if (fplace == 20) + fplace--; + fconvert[fplace] = 0; + + /* -1 for decimal point, another -1 if we are printing a sign */ + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + zpadlen = max - fplace; + if (zpadlen < 0) + zpadlen = 0; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justifty */ + + if ((flags & DP_F_ZERO) && (padlen > 0)) { + if (signvalue) { + dopr_outch(buffer, currlen, maxlen, signvalue); + --padlen; + signvalue = 0; + } + while (padlen > 0) { + dopr_outch(buffer, currlen, maxlen, '0'); + --padlen; + } + } + while (padlen > 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + --padlen; + } + if (signvalue) + dopr_outch(buffer, currlen, maxlen, signvalue); + + while (iplace > 0) + dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]); + + /* + * Decimal point. This should probably use locale to find the correct + * char to print out. + */ + dopr_outch(buffer, currlen, maxlen, '.'); + + while (fplace > 0) + dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]); + + while (zpadlen > 0) { + dopr_outch(buffer, currlen, maxlen, '0'); + --zpadlen; + } + + 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, char c) { - if (*currlen < maxlen) - buffer[(*currlen)++] = c; + if (*currlen < maxlen) + buffer[(*currlen)++] = c; } #endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ #ifndef HAVE_VSNPRINTF -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) { - str[0] = 0; - dopr(str, count, fmt, args); - return(strlen(str)); + str[0] = 0; + dopr(str, count, fmt, args); + + return(strlen(str)); } #endif /* !HAVE_VSNPRINTF */ #ifndef HAVE_SNPRINTF -/* VARARGS3 */ -#ifdef HAVE_STDARGS -int snprintf (char *str,size_t count,const char *fmt,...) -#else -int snprintf (va_alist) va_dcl -#endif +int +snprintf(char *str,size_t count,const char *fmt,...) { -#ifndef HAVE_STDARGS - char *str; - size_t count; - char *fmt; -#endif - VA_LOCAL_DECL; - - VA_START (fmt); - VA_SHIFT (str, char *); - VA_SHIFT (count, size_t ); - VA_SHIFT (fmt, char *); - (void) vsnprintf(str, count, fmt, ap); - VA_END; - return(strlen(str)); + va_list ap; + + va_start(ap, fmt); + (void) vsnprintf(str, count, fmt, ap); + va_end(ap); + + return(strlen(str)); } #ifdef TEST_SNPRINTF -#ifndef LONG_STRING -#define LONG_STRING 1024 -#endif -int main (void) +int +main(void) { - char buf1[LONG_STRING]; - char buf2[LONG_STRING]; - char *fp_fmt[] = { - "%-1.5f", - "%1.5f", - "%123.9f", - "%10.5f", - "% 10.5f", - "%+22.9f", - "%+4.9f", - "%01.3f", - "%4f", - "%3.1f", - "%3.2f", - NULL - }; - double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, - 0.9996, 1.996, 4.136, 0}; - char *int_fmt[] = { - "%-1.5d", - "%1.5d", - "%123.9d", - "%5.5d", - "%10.5d", - "% 10.5d", - "%+22.33d", - "%01.3d", - "%4d", - "%lld", - "%qd", - NULL - }; - long long int_nums[] = { -1, 134, 91340, 341, 0203, 0, 9999999 }; - int x, y; - int fail = 0; - int num = 0; - - printf ("Testing snprintf format codes against system sprintf...\n"); - - for (x = 0; fp_fmt[x] != NULL ; x++) - for (y = 0; fp_nums[y] != 0 ; y++) - { - snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]); - sprintf (buf2, fp_fmt[x], fp_nums[y]); - if (strcmp (buf1, buf2)) - { - printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", - fp_fmt[x], buf1, buf2); - fail++; - } - num++; - } - - for (x = 0; int_fmt[x] != NULL ; x++) - for (y = 0; int_nums[y] != 0 ; y++) - { - snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]); - sprintf (buf2, int_fmt[x], int_nums[y]); - if (strcmp (buf1, buf2)) - { - printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", - int_fmt[x], buf1, buf2); - fail++; - } - num++; - } - printf ("%d tests failed out of %d.\n", fail, num); +#define LONG_STRING 1024 + char buf1[LONG_STRING]; + char buf2[LONG_STRING]; + char *fp_fmt[] = { + "%-1.5f", + "%1.5f", + "%123.9f", + "%10.5f", + "% 10.5f", + "%+22.9f", + "%+4.9f", + "%01.3f", + "%4f", + "%3.1f", + "%3.2f", + NULL + }; + double fp_nums[] = { + -1.5, + 134.21, + 91340.2, + 341.1234, + 0203.9, + 0.96, + 0.996, + 0.9996, + 1.996, + 4.136, + 0 + }; + char *int_fmt[] = { + "%-1.5d", + "%1.5d", + "%123.9d", + "%5.5d", + "%10.5d", + "% 10.5d", + "%+22.33d", + "%01.3d", + "%4d", + "%lld", + "%qd", + NULL + }; + long long int_nums[] = { -1, 134, 91340, 341, 0203, 0, 9999999 }; + int x, y; + int fail = 0; + int num = 0; + + printf("Testing snprintf format codes against system sprintf...\n"); + + for (x = 0; fp_fmt[x] != NULL ; x++) { + for (y = 0; fp_nums[y] != 0 ; y++) { + snprintf(buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]); + sprintf (buf2, fp_fmt[x], fp_nums[y]); + if (strcmp (buf1, buf2)) { + printf("snprintf doesn't match Format: %s\n\t" + "snprintf = %s\n\tsprintf = %s\n", + fp_fmt[x], buf1, buf2); + fail++; + } + num++; + } + } + for (x = 0; int_fmt[x] != NULL ; x++) { + for (y = 0; int_nums[y] != 0 ; y++) { + snprintf(buf1, sizeof (buf1), int_fmt[x], int_nums[y]); + sprintf(buf2, int_fmt[x], int_nums[y]); + if (strcmp (buf1, buf2)) { + printf("snprintf doesn't match Format: %s\n\t" + "snprintf = %s\n\tsprintf = %s\n", + int_fmt[x], buf1, buf2); + fail++; + } + num++; + } + } + printf("%d tests failed out of %d.\n", fail, num); + return(0); } #endif /* SNPRINTF_TEST */ -- cgit v1.2.3 From 116b6bdda81d6647cc2742280c15b3f42ab3dd24 Mon Sep 17 00:00:00 2001 From: Ben Lindstrom Date: Tue, 13 Feb 2001 14:05:59 +0000 Subject: - (bal) Missing function prototype in bsd-snprintf.c patch by Mark Miller --- openbsd-compat/bsd-snprintf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index 55d14284..d02e5ae5 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -51,7 +51,7 @@ #include "includes.h" -RCSID("$Id: bsd-snprintf.c,v 1.3 2001/02/13 02:18:50 mouring Exp $"); +RCSID("$Id: bsd-snprintf.c,v 1.4 2001/02/13 14:05:59 mouring Exp $"); #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) @@ -70,6 +70,9 @@ 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 */ -- cgit v1.2.3 From 63941f9631b8316d57d54e0ef7484c66bb1c1b7d Mon Sep 17 00:00:00 2001 From: Ben Lindstrom Date: Sun, 25 Feb 2001 23:20:40 +0000 Subject: - (bal) Fixed bsd-snprinf.c so it now honors 'BROKEN_SNPRINTF' again. --- openbsd-compat/bsd-snprintf.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index d02e5ae5..1c72ea61 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -51,7 +51,12 @@ #include "includes.h" -RCSID("$Id: bsd-snprintf.c,v 1.4 2001/02/13 14:05:59 mouring Exp $"); +RCSID("$Id: bsd-snprintf.c,v 1.5 2001/02/25 23:20:41 mouring Exp $"); + +#if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ +# undef HAVE_SNPRINTF +# undef HAVE_VSNPRINTF +#endif #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) -- cgit v1.2.3 From f18462f5bff7265d151f9367d4dd2632a0b0fb25 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 1 Apr 2003 21:31:56 +1000 Subject: license from samba --- openbsd-compat/bsd-snprintf.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index 1c72ea61..2f82180d 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -1,3 +1,10 @@ +/* + * Copyright Patrick Powell 1995 + * 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 + */ + /************************************************************** * Original: * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 @@ -51,7 +58,7 @@ #include "includes.h" -RCSID("$Id: bsd-snprintf.c,v 1.5 2001/02/25 23:20:41 mouring Exp $"); +RCSID("$Id: bsd-snprintf.c,v 1.6 2003/04/01 11:31:56 djm Exp $"); #if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ # undef HAVE_SNPRINTF -- cgit v1.2.3 From 317412502b900ddecdafdfa171da99271846478b Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 19 May 2003 00:13:38 +1000 Subject: - (djm) Big KNF on openbsd-compat/ --- openbsd-compat/bsd-snprintf.c | 557 +++++++++++++++++------------------------- 1 file changed, 229 insertions(+), 328 deletions(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index 2f82180d..e4d8a439 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -58,7 +58,7 @@ #include "includes.h" -RCSID("$Id: bsd-snprintf.c,v 1.6 2003/04/01 11:31:56 djm Exp $"); +RCSID("$Id: bsd-snprintf.c,v 1.7 2003/05/18 14:13:39 djm Exp $"); #if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ # undef HAVE_SNPRINTF @@ -72,15 +72,15 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args); static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, - int min, int max); + 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); + 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); + int min, int max, int flags); static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); @@ -121,15 +121,10 @@ dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); static void dopr(char *buffer, size_t maxlen, const char *format, va_list args) { - char *strvalue; - char ch; + char *strvalue, ch; long value; long double fvalue; - int min = 0; - int max = -1; - int state = DP_S_DEFAULT; - int flags = 0; - int cflags = 0; + int min = 0, max = -1, state = DP_S_DEFAULT, flags = 0, cflags = 0; size_t currlen = 0; ch = *format++; @@ -139,224 +134,224 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args) state = DP_S_DONE; switch(state) { - case DP_S_DEFAULT: - if (ch == '%') - state = DP_S_FLAGS; - else - dopr_outch(buffer, &currlen, maxlen, ch); + case DP_S_DEFAULT: + if (ch == '%') + state = DP_S_FLAGS; + else + dopr_outch(buffer, &currlen, maxlen, ch); + ch = *format++; + break; + case DP_S_FLAGS: + switch (ch) { + case '-': + flags |= DP_F_MINUS; ch = *format++; break; - case DP_S_FLAGS: - switch (ch) { - case '-': - flags |= DP_F_MINUS; - ch = *format++; - break; - case '+': - flags |= DP_F_PLUS; - ch = *format++; - break; - case ' ': - flags |= DP_F_SPACE; - ch = *format++; - break; - case '#': - flags |= DP_F_NUM; - ch = *format++; - break; - case '0': - flags |= DP_F_ZERO; - ch = *format++; - break; - default: - state = DP_S_MIN; - break; - } + case '+': + flags |= DP_F_PLUS; + ch = *format++; break; - case DP_S_MIN: - if (isdigit((unsigned char)ch)) { - min = 10*min + char_to_int (ch); - ch = *format++; - } else if (ch == '*') { - min = va_arg (args, int); - ch = *format++; - state = DP_S_DOT; - } else - state = DP_S_DOT; + case ' ': + flags |= DP_F_SPACE; + ch = *format++; break; - case DP_S_DOT: - if (ch == '.') { - state = DP_S_MAX; - ch = *format++; - } else - state = DP_S_MOD; + case '#': + flags |= DP_F_NUM; + ch = *format++; break; - case DP_S_MAX: - if (isdigit((unsigned char)ch)) { - if (max < 0) - max = 0; - max = 10*max + char_to_int(ch); - ch = *format++; - } else if (ch == '*') { - max = va_arg (args, int); - ch = *format++; - state = DP_S_MOD; - } else - state = DP_S_MOD; + case '0': + flags |= DP_F_ZERO; + ch = *format++; break; - case DP_S_MOD: - switch (ch) { - case 'h': - cflags = DP_C_SHORT; - ch = *format++; - break; - case 'l': - cflags = DP_C_LONG; - ch = *format++; - if (ch == 'l') { - cflags = DP_C_LONG_LONG; - ch = *format++; - } - break; - case 'q': - cflags = DP_C_LONG_LONG; - ch = *format++; - break; - case 'L': - cflags = DP_C_LDOUBLE; - ch = *format++; - break; - default: - break; - } - state = DP_S_CONV; + default: + state = DP_S_MIN; break; - case DP_S_CONV: - switch (ch) { - case 'd': - case 'i': - if (cflags == DP_C_SHORT) - value = va_arg(args, int); - else if (cflags == DP_C_LONG) - value = va_arg(args, long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg (args, long long); - 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 int); - else if (cflags == DP_C_LONG) - value = va_arg(args, unsigned long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg(args, unsigned long long); - else - value = va_arg(args, unsigned int); - fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags); - break; - case 'u': - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_SHORT) - value = va_arg(args, unsigned int); - else if (cflags == DP_C_LONG) - value = va_arg(args, unsigned long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg(args, unsigned long long); - else - value = va_arg(args, unsigned int); - fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); - break; - case 'X': - flags |= DP_F_UP; - case 'x': - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_SHORT) - value = va_arg(args, unsigned int); - else if (cflags == DP_C_LONG) - value = va_arg(args, unsigned long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg(args, unsigned long long); - else - value = va_arg(args, unsigned int); - fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags); - break; - case 'f': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg(args, long double); - 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); - else - fvalue = va_arg(args, double); - break; - case 'G': - flags |= DP_F_UP; - case 'g': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg(args, long double); - else - fvalue = va_arg(args, double); - break; - case 'c': - 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); - break; - case 'p': - strvalue = va_arg(args, void *); - fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); - break; - case 'n': - if (cflags == DP_C_SHORT) { - short int *num; - num = va_arg(args, short int *); - *num = currlen; - } else if (cflags == DP_C_LONG) { - long int *num; - num = va_arg(args, long int *); - *num = currlen; - } else if (cflags == DP_C_LONG_LONG) { - long long *num; - num = va_arg(args, long long *); - *num = currlen; - } else { - int *num; - num = va_arg(args, int *); - *num = currlen; - } - break; - case '%': - dopr_outch(buffer, &currlen, maxlen, ch); - break; - case 'w': /* not supported yet, treat as next char */ - ch = *format++; - break; - default: /* Unknown, skip */ - break; + } + break; + case DP_S_MIN: + if (isdigit((unsigned char)ch)) { + min = 10 * min + char_to_int (ch); + ch = *format++; + } else if (ch == '*') { + min = va_arg (args, int); + ch = *format++; + state = DP_S_DOT; + } else + state = DP_S_DOT; + break; + case DP_S_DOT: + if (ch == '.') { + state = DP_S_MAX; + ch = *format++; + } else + state = DP_S_MOD; + break; + case DP_S_MAX: + if (isdigit((unsigned char)ch)) { + if (max < 0) + max = 0; + max = 10 * max + char_to_int(ch); + ch = *format++; + } else if (ch == '*') { + max = va_arg (args, int); + ch = *format++; + state = DP_S_MOD; + } else + state = DP_S_MOD; + break; + case DP_S_MOD: + switch (ch) { + case 'h': + cflags = DP_C_SHORT; + ch = *format++; + break; + case 'l': + cflags = DP_C_LONG; + ch = *format++; + if (ch == 'l') { + cflags = DP_C_LONG_LONG; + ch = *format++; } + break; + case 'q': + cflags = DP_C_LONG_LONG; + ch = *format++; + break; + case 'L': + cflags = DP_C_LDOUBLE; ch = *format++; - state = DP_S_DEFAULT; - flags = cflags = min = 0; - max = -1; break; - case DP_S_DONE: + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + switch (ch) { + case 'd': + case 'i': + if (cflags == DP_C_SHORT) + value = va_arg(args, int); + else if (cflags == DP_C_LONG) + value = va_arg(args, long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg (args, long long); + 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 int); + else if (cflags == DP_C_LONG) + value = va_arg(args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg(args, unsigned long long); + else + value = va_arg(args, unsigned int); + fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags); break; - default: /* hmm? */ - break; /* some picky compilers need this */ + case 'u': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg(args, unsigned int); + else if (cflags == DP_C_LONG) + value = va_arg(args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg(args, unsigned long long); + else + value = va_arg(args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'X': + flags |= DP_F_UP; + case 'x': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg(args, unsigned int); + else if (cflags == DP_C_LONG) + value = va_arg(args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg(args, unsigned long long); + else + value = va_arg(args, unsigned int); + fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags); + break; + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, long double); + 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); + else + fvalue = va_arg(args, double); + break; + case 'G': + flags |= DP_F_UP; + case 'g': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, long double); + else + fvalue = va_arg(args, double); + break; + case 'c': + 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); + break; + case 'p': + strvalue = va_arg(args, void *); + fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); + break; + case 'n': + if (cflags == DP_C_SHORT) { + short int *num; + num = va_arg(args, short int *); + *num = currlen; + } else if (cflags == DP_C_LONG) { + long int *num; + num = va_arg(args, long int *); + *num = currlen; + } else if (cflags == DP_C_LONG_LONG) { + long long *num; + num = va_arg(args, long long *); + *num = currlen; + } else { + int *num; + num = va_arg(args, int *); + *num = currlen; + } + break; + case '%': + dopr_outch(buffer, &currlen, maxlen, ch); + break; + case 'w': /* not supported yet, treat as next char */ + ch = *format++; + break; + default: /* Unknown, skip */ + break; + } + ch = *format++; + state = DP_S_DEFAULT; + flags = cflags = min = 0; + max = -1; + break; + case DP_S_DONE: + break; + default: /* hmm? */ + break; /* some picky compilers need this */ } } if (currlen < maxlen - 1) @@ -367,10 +362,9 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args) static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, - char *value, int flags, int min, int max) + char *value, int flags, int min, int max) { - int padlen, strln; /* amount to pad */ - int cnt = 0; + int cnt = 0, padlen, strln; /* amount to pad */ if (value == 0) value = ""; @@ -402,15 +396,13 @@ fmtstr(char *buffer, size_t *currlen, size_t maxlen, static void fmtint(char *buffer, size_t *currlen, size_t maxlen, - long value, int base, int min, int max, int flags) + long value, int base, int min, int max, int flags) { unsigned long uvalue; char convert[20]; - int signvalue = 0; - int place = 0; + int signvalue = 0, place = 0, caps = 0; int spadlen = 0; /* amount to space pad */ int zpadlen = 0; /* amount to zero pad */ - int caps = 0; if (max < 0) max = 0; @@ -429,11 +421,10 @@ fmtint(char *buffer, size_t *currlen, size_t maxlen, if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ - do { convert[place++] = - (caps? "0123456789ABCDEF":"0123456789abcdef") - [uvalue % (unsigned)base]; + (caps ? "0123456789ABCDEF" : "0123456789abcdef") + [uvalue % (unsigned)base]; uvalue = (uvalue / (unsigned)base ); } while (uvalue && (place < 20)); if (place == 20) @@ -453,7 +444,6 @@ fmtint(char *buffer, size_t *currlen, size_t maxlen, if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */ - /* Spaces */ while (spadlen > 0) { dopr_outch(buffer, currlen, maxlen, ' '); @@ -512,16 +502,11 @@ static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, int min, int max, int flags) { - char iconvert[20]; - char fconvert[20]; - int signvalue = 0; - int iplace = 0; - int fplace = 0; + char iconvert[20], fconvert[20]; + int signvalue = 0, iplace = 0, fplace = 0; int padlen = 0; /* amount to pad */ - int zpadlen = 0; - int caps = 0; - long intpart; - long fracpart; + int zpadlen = 0, caps = 0; + long intpart, fracpart; long double ufvalue; /* @@ -562,7 +547,8 @@ fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, /* 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) @@ -572,7 +558,8 @@ fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, /* 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) @@ -611,8 +598,8 @@ fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]); /* - * Decimal point. This should probably use locale to find the correct - * char to print out. + * Decimal point. This should probably use locale to find the + * correct char to print out. */ dopr_outch(buffer, currlen, maxlen, '.'); @@ -662,90 +649,4 @@ snprintf(char *str,size_t count,const char *fmt,...) return(strlen(str)); } -#ifdef TEST_SNPRINTF -int -main(void) -{ -#define LONG_STRING 1024 - char buf1[LONG_STRING]; - char buf2[LONG_STRING]; - char *fp_fmt[] = { - "%-1.5f", - "%1.5f", - "%123.9f", - "%10.5f", - "% 10.5f", - "%+22.9f", - "%+4.9f", - "%01.3f", - "%4f", - "%3.1f", - "%3.2f", - NULL - }; - double fp_nums[] = { - -1.5, - 134.21, - 91340.2, - 341.1234, - 0203.9, - 0.96, - 0.996, - 0.9996, - 1.996, - 4.136, - 0 - }; - char *int_fmt[] = { - "%-1.5d", - "%1.5d", - "%123.9d", - "%5.5d", - "%10.5d", - "% 10.5d", - "%+22.33d", - "%01.3d", - "%4d", - "%lld", - "%qd", - NULL - }; - long long int_nums[] = { -1, 134, 91340, 341, 0203, 0, 9999999 }; - int x, y; - int fail = 0; - int num = 0; - - printf("Testing snprintf format codes against system sprintf...\n"); - - for (x = 0; fp_fmt[x] != NULL ; x++) { - for (y = 0; fp_nums[y] != 0 ; y++) { - snprintf(buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]); - sprintf (buf2, fp_fmt[x], fp_nums[y]); - if (strcmp (buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\t" - "snprintf = %s\n\tsprintf = %s\n", - fp_fmt[x], buf1, buf2); - fail++; - } - num++; - } - } - for (x = 0; int_fmt[x] != NULL ; x++) { - for (y = 0; int_nums[y] != 0 ; y++) { - snprintf(buf1, sizeof (buf1), int_fmt[x], int_nums[y]); - sprintf(buf2, int_fmt[x], int_nums[y]); - if (strcmp (buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\t" - "snprintf = %s\n\tsprintf = %s\n", - int_fmt[x], buf1, buf2); - fail++; - } - num++; - } - } - printf("%d tests failed out of %d.\n", fail, num); - return(0); -} -#endif /* SNPRINTF_TEST */ - #endif /* !HAVE_SNPRINTF */ -- cgit v1.2.3 From 50fbb45dbd2f95f95c959dc03663b213b4aac2aa Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 21 Sep 2004 21:32:12 +1000 Subject: - (dtucker) [openbsd-compat/bsd-snprintf.c] Check for max length too. ok djm@ --- openbsd-compat/bsd-snprintf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index e4d8a439..aea501c6 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -58,7 +58,7 @@ #include "includes.h" -RCSID("$Id: bsd-snprintf.c,v 1.7 2003/05/18 14:13:39 djm Exp $"); +RCSID("$Id: bsd-snprintf.c,v 1.8 2004/09/21 11:32:13 dtucker Exp $"); #if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ # undef HAVE_SNPRINTF @@ -369,7 +369,7 @@ fmtstr(char *buffer, size_t *currlen, size_t maxlen, if (value == 0) value = ""; - for (strln = 0; value[strln]; ++strln); /* strlen */ + for (strln = 0; strln <= max && value[strln]; ++strln); /* strlen */ padlen = min - strln; if (padlen < 0) padlen = 0; -- cgit v1.2.3 From 4127f559ada4573e66c0e55dc920147d73e48974 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Thu, 23 Sep 2004 21:35:09 +1000 Subject: - (dtucker) [openbsd-compat/bsd-snprintf.c] Previous change was off by one, which could have caused the justification to be wrong. ok djm@ --- openbsd-compat/bsd-snprintf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index aea501c6..b5a7ef7a 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -58,7 +58,7 @@ #include "includes.h" -RCSID("$Id: bsd-snprintf.c,v 1.8 2004/09/21 11:32:13 dtucker Exp $"); +RCSID("$Id: bsd-snprintf.c,v 1.9 2004/09/23 11:35:09 dtucker Exp $"); #if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ # undef HAVE_SNPRINTF @@ -369,7 +369,7 @@ fmtstr(char *buffer, size_t *currlen, size_t maxlen, if (value == 0) value = ""; - for (strln = 0; strln <= max && value[strln]; ++strln); /* strlen */ + for (strln = 0; strln < max && value[strln]; ++strln); /* strlen */ padlen = min - strln; if (padlen < 0) padlen = 0; -- cgit v1.2.3 From 57f3915b5513495b11e7052df0260c7896b7b612 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 24 Nov 2005 19:58:19 +1100 Subject: - (djm) [configure.ac openbsd-compat/Makefile.in openbsd-compat/bsd-asprintf.c openbsd-compat/bsd-snprintf.c openbsd-compat/openbsd-compat.h] Add an asprintf() implementation, after syncing our {v,}snprintf() implementation with some extra fixes from Samba's version. With help and debugging from dtucker and tim; ok dtucker@ --- openbsd-compat/bsd-snprintf.c | 610 ++++++++++++++++++++++++++---------------- 1 file changed, 380 insertions(+), 230 deletions(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index b5a7ef7a..ca275abd 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -45,45 +45,82 @@ * missing. Some systems only have snprintf() but not vsnprintf(), so * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. * - * Ben Lindstrom 09/27/00 for OpenSSH - * Welcome to the world of %lld and %qd support. With other - * long long support. This is needed for sftp-server to work - * right. + * Andrew Tridgell (tridge@samba.org) Oct 1998 + * fixed handling of %.0f + * added test for HAVE_LONG_DOUBLE * - * Ben Lindstrom 02/12/01 for OpenSSH - * Removed all hint of VARARGS stuff and banished it to the void, - * and did a bit of KNF style work to make things a bit more - * acceptable. Consider stealing from mutt or enlightenment. + * tridge@samba.org, idra@samba.org, April 2001 + * got rid of fcvt code (twas buggy and made testing harder) + * added C99 semantics + * + * date: 2002/12/19 19:56:31; author: herb; state: Exp; lines: +2 -0 + * actually print args for %g and %e + * + * date: 2002/06/03 13:37:52; author: jmcd; state: Exp; lines: +8 -0 + * Since includes.h isn't included here, VA_COPY has to be defined here. I don't + * see any include file that is guaranteed to be here, so I'm defining it + * locally. Fixes AIX and Solaris builds. + * + * date: 2002/06/03 03:07:24; author: tridge; state: Exp; lines: +5 -13 + * put the ifdef for HAVE_VA_COPY in one place rather than in lots of + * functions + * + * date: 2002/05/17 14:51:22; author: jmcd; state: Exp; lines: +21 -4 + * Fix usage of va_list passed as an arg. Use __va_copy before using it + * when it exists. + * + * date: 2002/04/16 22:38:04; author: idra; state: Exp; lines: +20 -14 + * Fix incorrect zpadlen handling in fmtfp. + * Thanks to Ollie Oldham for spotting it. + * few mods to make it easier to compile the tests. + * addedd the "Ollie" test to the floating point ones. + * + * Martin Pool (mbp@samba.org) April 2003 + * Remove NO_CONFIG_H so that the test case can be built within a source + * tree with less trouble. + * Remove unnecessary SAFE_FREE() definition. + * + * Martin Pool (mbp@samba.org) May 2003 + * Put in a prototype for dummy_snprintf() to quiet compiler warnings. + * + * Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even + * if the C library has some snprintf functions already. **************************************************************/ #include "includes.h" -RCSID("$Id: bsd-snprintf.c,v 1.9 2004/09/23 11:35:09 dtucker Exp $"); +RCSID("$Id: bsd-snprintf.c,v 1.10 2005/11/24 08:58:21 djm Exp $"); #if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ # undef HAVE_SNPRINTF # undef HAVE_VSNPRINTF #endif -#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) - -static void -dopr(char *buffer, size_t maxlen, const char *format, va_list args); - -static void -fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, - int min, int max); +#ifndef VA_COPY +# ifdef HAVE_VA_COPY +# define VA_COPY(dest, src) va_copy(dest, src) +# else +# ifdef HAVE___VA_COPY +# define VA_COPY(dest, src) __va_copy(dest, src) +# else +# define VA_COPY(dest, src) (dest) = (src) +# endif +# endif +#endif -static void -fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, - int min, int max, int flags); +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) -static void -fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, - int min, int max, int flags); +#ifdef HAVE_LONG_DOUBLE +# define LDOUBLE long double +#else +# define LDOUBLE double +#endif -static void -dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); +#ifdef HAVE_LONG_LONG +# define LLONG long long +#else +# define LLONG long +#endif /* * dopr(): poor man's version of doprintf @@ -109,28 +146,49 @@ dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); #define DP_F_UNSIGNED (1 << 6) /* Conversion Flags */ -#define DP_C_SHORT 1 -#define DP_C_LONG 2 -#define DP_C_LDOUBLE 3 -#define DP_C_LONG_LONG 4 - -#define char_to_int(p) (p - '0') -#define abs_val(p) (p < 0 ? -p : p) - +#define DP_C_SHORT 1 +#define DP_C_LONG 2 +#define DP_C_LDOUBLE 3 +#define DP_C_LLONG 4 + +#define char_to_int(p) ((p)- '0') +#ifndef MAX +# define MAX(p,q) (((p) >= (q)) ? (p) : (q)) +#endif -static void -dopr(char *buffer, size_t maxlen, const char *format, va_list args) +static size_t dopr(char *buffer, size_t maxlen, const char *format, + va_list args_in); +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, + LDOUBLE fvalue, int min, int max, int flags); +static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); + +static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) { - char *strvalue, ch; - long value; - long double fvalue; - int min = 0, max = -1, state = DP_S_DEFAULT, flags = 0, cflags = 0; - size_t currlen = 0; - + char ch; + LLONG value; + LDOUBLE fvalue; + char *strvalue; + int min; + int max; + int state; + int flags; + int cflags; + size_t currlen; + va_list args; + + VA_COPY(args, args_in); + + state = DP_S_DEFAULT; + currlen = flags = cflags = min = 0; + max = -1; ch = *format++; - + while (state != DP_S_DONE) { - if ((ch == '\0') || (currlen >= maxlen)) + if (ch == '\0') state = DP_S_DONE; switch(state) { @@ -138,7 +196,7 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args) if (ch == '%') state = DP_S_FLAGS; else - dopr_outch(buffer, &currlen, maxlen, ch); + dopr_outch (buffer, &currlen, maxlen, ch); ch = *format++; break; case DP_S_FLAGS: @@ -170,34 +228,37 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args) break; case DP_S_MIN: if (isdigit((unsigned char)ch)) { - min = 10 * min + char_to_int (ch); + min = 10*min + char_to_int (ch); ch = *format++; } 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 == '.') { state = DP_S_MAX; ch = *format++; - } else + } else { state = DP_S_MOD; + } break; case DP_S_MAX: if (isdigit((unsigned char)ch)) { if (max < 0) max = 0; - max = 10 * max + char_to_int(ch); + max = 10*max + char_to_int (ch); ch = *format++; } 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: switch (ch) { @@ -208,15 +269,11 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args) case 'l': cflags = DP_C_LONG; ch = *format++; - if (ch == 'l') { - cflags = DP_C_LONG_LONG; + if (ch == 'l') { /* It's a long long */ + cflags = DP_C_LLONG; ch = *format++; } break; - case 'q': - cflags = DP_C_LONG_LONG; - ch = *format++; - break; case 'L': cflags = DP_C_LDOUBLE; ch = *format++; @@ -231,37 +288,37 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args) case 'd': case 'i': if (cflags == DP_C_SHORT) - value = va_arg(args, int); + value = va_arg (args, int); else if (cflags == DP_C_LONG) - value = va_arg(args, long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg (args, long long); + value = va_arg (args, long int); + else if (cflags == DP_C_LLONG) + value = va_arg (args, LLONG); else value = va_arg (args, int); - fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags); + 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 int); + value = va_arg (args, unsigned int); else if (cflags == DP_C_LONG) - value = va_arg(args, unsigned long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg(args, unsigned long long); + value = (long)va_arg (args, unsigned long int); + else if (cflags == DP_C_LLONG) + value = (long)va_arg (args, unsigned LLONG); else - value = va_arg(args, unsigned int); - fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags); + value = (long)va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); break; case 'u': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) - value = va_arg(args, unsigned int); + value = va_arg (args, unsigned int); else if (cflags == DP_C_LONG) - value = va_arg(args, unsigned long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg(args, unsigned long long); + value = (long)va_arg (args, unsigned long int); + else if (cflags == DP_C_LLONG) + value = (LLONG)va_arg (args, unsigned LLONG); else - value = va_arg(args, unsigned int); + value = (long)va_arg (args, unsigned int); fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); break; case 'X': @@ -269,79 +326,86 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args) case 'x': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) - value = va_arg(args, unsigned int); + value = va_arg (args, unsigned int); else if (cflags == DP_C_LONG) - value = va_arg(args, unsigned long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg(args, unsigned long long); + value = (long)va_arg (args, unsigned long int); + else if (cflags == DP_C_LLONG) + value = (LLONG)va_arg (args, unsigned LLONG); else - value = va_arg(args, unsigned int); - fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags); + value = (long)va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 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); + fvalue = va_arg (args, double); /* um, floating point? */ - fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags); + 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); + fvalue = va_arg (args, double); + fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); break; case 'G': 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); + fvalue = va_arg (args, double); + fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); 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); + strvalue = va_arg (args, char *); + if (!strvalue) strvalue = "(NULL)"; + if (max == -1) { + max = strlen(strvalue); + } + if (min > 0 && max >= 0 && min > max) max = min; + 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); + strvalue = va_arg (args, void *); + fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); break; case 'n': if (cflags == DP_C_SHORT) { short int *num; - num = va_arg(args, short int *); + num = va_arg (args, short int *); *num = currlen; } else if (cflags == DP_C_LONG) { long int *num; - num = va_arg(args, long int *); - *num = currlen; - } else if (cflags == DP_C_LONG_LONG) { - long long *num; - num = va_arg(args, long long *); - *num = currlen; + num = va_arg (args, long int *); + *num = (long int)currlen; + } else if (cflags == DP_C_LLONG) { + LLONG *num; + num = va_arg (args, LLONG *); + *num = (LLONG)currlen; } else { int *num; - num = va_arg(args, int *); + num = va_arg (args, int *); *num = currlen; } break; case '%': - dopr_outch(buffer, &currlen, maxlen, ch); + dopr_outch (buffer, &currlen, maxlen, ch); break; - case 'w': /* not supported yet, treat as next char */ + case 'w': + /* not supported yet, treat as next char */ ch = *format++; break; - default: /* Unknown, skip */ - break; + default: + /* Unknown, skip */ + break; } ch = *format++; state = DP_S_DEFAULT; @@ -350,24 +414,33 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args) break; case DP_S_DONE: break; - default: /* hmm? */ + default: + /* hmm? */ break; /* some picky compilers need this */ } } - if (currlen < maxlen - 1) - buffer[currlen] = '\0'; - else - buffer[maxlen - 1] = '\0'; + if (maxlen != 0) { + if (currlen < maxlen - 1) + buffer[currlen] = '\0'; + else if (maxlen > 0) + buffer[maxlen - 1] = '\0'; + } + + return currlen; } -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 cnt = 0, padlen, strln; /* amount to pad */ - - if (value == 0) + int padlen, strln; /* amount to pad */ + int cnt = 0; + +#ifdef DEBUG_SNPRINTF + printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value); +#endif + if (value == 0) { value = ""; + } for (strln = 0; strln < max && value[strln]; ++strln); /* strlen */ padlen = min - strln; @@ -375,18 +448,18 @@ fmtstr(char *buffer, size_t *currlen, size_t maxlen, padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justify */ - + while ((padlen > 0) && (cnt < max)) { - dopr_outch(buffer, currlen, maxlen, ' '); + dopr_outch (buffer, currlen, maxlen, ' '); --padlen; ++cnt; } while (*value && (cnt < max)) { - dopr_outch(buffer, currlen, maxlen, *value++); + dopr_outch (buffer, currlen, maxlen, *value++); ++cnt; } while ((padlen < 0) && (cnt < max)) { - dopr_outch(buffer, currlen, maxlen, ' '); + dopr_outch (buffer, currlen, maxlen, ' '); ++padlen; ++cnt; } @@ -394,49 +467,49 @@ fmtstr(char *buffer, size_t *currlen, size_t maxlen, /* 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, + long value, int base, int min, int max, int flags) { + int signvalue = 0; unsigned long uvalue; char convert[20]; - int signvalue = 0, place = 0, caps = 0; + int place = 0; int spadlen = 0; /* amount to space pad */ int zpadlen = 0; /* amount to zero pad */ - + int caps = 0; + if (max < 0) max = 0; - + uvalue = value; - - if (!(flags & DP_F_UNSIGNED)) { - if (value < 0) { + + if(!(flags & DP_F_UNSIGNED)) { + if( value < 0 ) { signvalue = '-'; uvalue = -value; - } else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ - signvalue = '+'; - else if (flags & DP_F_SPACE) - signvalue = ' '; + } else { + if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + 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; /* Should characters be upper case? */ + do { convert[place++] = - (caps ? "0123456789ABCDEF" : "0123456789abcdef") - [uvalue % (unsigned)base]; + (caps? "0123456789ABCDEF":"0123456789abcdef") + [uvalue % (unsigned)base ]; uvalue = (uvalue / (unsigned)base ); - } while (uvalue && (place < 20)); - if (place == 20) - place--; + } while(uvalue && (place < 20)); + 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 (zpadlen < 0) zpadlen = 0; + if (spadlen < 0) spadlen = 0; if (flags & DP_F_ZERO) { zpadlen = MAX(zpadlen, spadlen); spadlen = 0; @@ -444,27 +517,32 @@ fmtint(char *buffer, size_t *currlen, size_t maxlen, if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */ +#ifdef DEBUG_SNPRINTF + printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", + zpadlen, spadlen, min, max, place); +#endif + /* Spaces */ while (spadlen > 0) { - dopr_outch(buffer, currlen, maxlen, ' '); + dopr_outch (buffer, currlen, maxlen, ' '); --spadlen; } /* Sign */ if (signvalue) - dopr_outch(buffer, currlen, maxlen, signvalue); + dopr_outch (buffer, currlen, maxlen, signvalue); /* Zeros */ if (zpadlen > 0) { while (zpadlen > 0) { - dopr_outch(buffer, currlen, maxlen, '0'); + dopr_outch (buffer, currlen, maxlen, '0'); --zpadlen; } } /* Digits */ while (place > 0) - dopr_outch(buffer, currlen, maxlen, convert[--place]); + dopr_outch (buffer, currlen, maxlen, convert[--place]); /* Left Justified spaces */ while (spadlen < 0) { @@ -473,11 +551,20 @@ fmtint(char *buffer, size_t *currlen, size_t maxlen, } } -static long double -pow10(int exp) +static LDOUBLE abs_val(LDOUBLE value) { - long double result = 1; + LDOUBLE result = value; + + if (value < 0) + result = -value; + + return result; +} +static LDOUBLE POW10(int exp) +{ + LDOUBLE result = 1; + while (exp) { result *= 10; exp--; @@ -486,28 +573,69 @@ pow10(int exp) return result; } -static long -round(long double value) +static LLONG ROUND(LDOUBLE value) { - long intpart = value; - - value -= intpart; - if (value >= 0.5) - intpart++; + LLONG intpart; + intpart = (LLONG)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) +/* a replacement for modf that doesn't need the math library. Should + be portable, but slow */ +static double my_modf(double x0, double *iptr) { - char iconvert[20], fconvert[20]; - int signvalue = 0, iplace = 0, fplace = 0; + int i; + long l; + double x = x0; + double f = 1.0; + + for (i=0;i<100;i++) { + l = (long)x; + if (l <= (x+1) && l >= (x-1)) break; + x *= 0.1; + f *= 10.0; + } + + if (i == 100) { + /* yikes! the number is beyond what we can handle. What do we do? */ + (*iptr) = 0; + return 0; + } + + if (i != 0) { + double i2; + double ret; + + ret = my_modf(x0-l*f, &i2); + (*iptr) = l*f + i2; + return ret; + } + + (*iptr) = l; + return x - (*iptr); +} + + +static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags) +{ + int signvalue = 0; + double ufvalue; + char iconvert[311]; + char fconvert[311]; + int iplace = 0; + int fplace = 0; int padlen = 0; /* amount to pad */ - int zpadlen = 0, caps = 0; - long intpart, fracpart; - long double ufvalue; + int zpadlen = 0; + int caps = 0; + int idx; + double intpart; + double fracpart; + double temp; /* * AIX manpage says the default is 0, but Solaris says the default @@ -516,137 +644,159 @@ fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, if (max < 0) max = 6; - ufvalue = abs_val(fvalue); + ufvalue = abs_val (fvalue); - if (fvalue < 0) + if (fvalue < 0) { signvalue = '-'; - else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ - signvalue = '+'; - else if (flags & DP_F_SPACE) - signvalue = ' '; + } else { + if (flags & DP_F_PLUS) { /* Do a sign (+/i) */ + signvalue = '+'; + } else { + if (flags & DP_F_SPACE) + signvalue = ' '; + } + } - intpart = ufvalue; +#if 0 + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ +#endif + +#if 0 + if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */ +#endif /* - * Sorry, we only support 9 digits past the decimal because of our + * Sorry, we only support 16 digits past the decimal because of our * conversion method */ - if (max > 9) - max = 9; + if (max > 16) + max = 16; /* 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)) { + temp = ufvalue; + my_modf(temp, &intpart); + + fracpart = ROUND((POW10(max)) * (ufvalue - intpart)); + + if (fracpart >= POW10(max)) { intpart++; - fracpart -= pow10 (max); + fracpart -= POW10(max); } /* Convert integer part */ do { + temp = intpart*0.1; + my_modf(temp, &intpart); + idx = (int) ((temp -intpart +0.05)* 10.0); + /* idx = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */ + /* printf ("%llf, %f, %x\n", temp, intpart, idx); */ iconvert[iplace++] = - (caps ? "0123456789ABCDEF" : "0123456789abcdef") - [intpart % 10]; - intpart = (intpart / 10); - } while(intpart && (iplace < 20)); - if (iplace == 20) - iplace--; + (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; + } while (intpart && (iplace < 311)); + if (iplace == 311) iplace--; iconvert[iplace] = 0; /* Convert fractional part */ - do { - fconvert[fplace++] = - (caps ? "0123456789ABCDEF" : "0123456789abcdef") - [fracpart % 10]; - fracpart = (fracpart / 10); - } while(fracpart && (fplace < 20)); - if (fplace == 20) - fplace--; + if (fracpart) + { + do { + temp = fracpart*0.1; + my_modf(temp, &fracpart); + idx = (int) ((temp -fracpart +0.05)* 10.0); + /* idx = (int) ((((temp/10) -fracpart) +0.05) *10); */ + /* printf ("%lf, %lf, %ld\n", temp, fracpart, idx ); */ + fconvert[fplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; + } while(fracpart && (fplace < 311)); + if (fplace == 311) fplace--; + } fconvert[fplace] = 0; - + /* -1 for decimal point, another -1 if we are printing a sign */ padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); zpadlen = max - fplace; - if (zpadlen < 0) - zpadlen = 0; + if (zpadlen < 0) zpadlen = 0; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justifty */ - + if ((flags & DP_F_ZERO) && (padlen > 0)) { if (signvalue) { - dopr_outch(buffer, currlen, maxlen, signvalue); + dopr_outch (buffer, currlen, maxlen, signvalue); --padlen; signvalue = 0; } while (padlen > 0) { - dopr_outch(buffer, currlen, maxlen, '0'); + dopr_outch (buffer, currlen, maxlen, '0'); --padlen; } } while (padlen > 0) { - dopr_outch(buffer, currlen, maxlen, ' '); + dopr_outch (buffer, currlen, maxlen, ' '); --padlen; } if (signvalue) - dopr_outch(buffer, currlen, maxlen, signvalue); - + dopr_outch (buffer, currlen, maxlen, signvalue); + while (iplace > 0) - dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]); + dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); + +#ifdef DEBUG_SNPRINTF + printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); +#endif /* - * Decimal point. This should probably use locale to find the - * correct char to print out. + * Decimal point. This should probably use locale to find the correct + * char to print out. */ - dopr_outch(buffer, currlen, maxlen, '.'); - - while (fplace > 0) - dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]); + if (max > 0) { + dopr_outch (buffer, currlen, maxlen, '.'); + + while (zpadlen > 0) { + dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } - while (zpadlen > 0) { - dopr_outch(buffer, currlen, maxlen, '0'); - --zpadlen; + while (fplace > 0) + dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); } while (padlen < 0) { - dopr_outch(buffer, currlen, maxlen, ' '); + 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, char c) { - if (*currlen < maxlen) - buffer[(*currlen)++] = c; + if (*currlen < maxlen) { + buffer[(*currlen)] = c; + } + (*currlen)++; } #endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ -#ifndef HAVE_VSNPRINTF -int -vsnprintf(char *str, size_t count, const char *fmt, va_list args) +#if !defined(HAVE_VSNPRINTF) +int vsnprintf (char *str, size_t count, const char *fmt, va_list args) { - str[0] = 0; - dopr(str, count, fmt, args); - - return(strlen(str)); + return dopr(str, count, fmt, args); } -#endif /* !HAVE_VSNPRINTF */ +#endif -#ifndef HAVE_SNPRINTF -int -snprintf(char *str,size_t count,const char *fmt,...) +#if !defined(HAVE_SNPRINTF) +int snprintf(char *str,size_t count,const char *fmt,...) { + size_t ret; va_list ap; va_start(ap, fmt); - (void) vsnprintf(str, count, fmt, ap); + ret = vsnprintf(str, count, fmt, ap); va_end(ap); - - return(strlen(str)); + return ret; } +#endif -#endif /* !HAVE_SNPRINTF */ -- cgit v1.2.3 From d40c66cf3f5d7713ea9489778dc450a48984a81d Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 17 Dec 2005 22:32:03 +1100 Subject: - (dtucker) [configure.ac openbsd-compat/bsd-snprintf.c] Bug #1133: Our snprintf replacement can have a conflicting declaration in HP-UX's system headers (const vs. no const) so we now check for and work around it. Patch from the dynamic duo of David Leonard and Ted Percival. --- openbsd-compat/bsd-snprintf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index ca275abd..e4ba154f 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -89,7 +89,7 @@ #include "includes.h" -RCSID("$Id: bsd-snprintf.c,v 1.10 2005/11/24 08:58:21 djm Exp $"); +RCSID("$Id: bsd-snprintf.c,v 1.11 2005/12/17 11:32:04 dtucker Exp $"); #if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ # undef HAVE_SNPRINTF @@ -788,7 +788,7 @@ int vsnprintf (char *str, size_t count, const char *fmt, va_list args) #endif #if !defined(HAVE_SNPRINTF) -int snprintf(char *str,size_t count,const char *fmt,...) +int snprintf(char *str, size_t count, SNPRINTF_CONST char *fmt, ...) { size_t ret; va_list ap; -- cgit v1.2.3 From 9834cab32ef1abd8f0e4e74852ac52c35cfce0ef Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 19 Mar 2006 00:07:07 +1100 Subject: - (dtucker) [openbsd-compat/bsd-snprintf.c] Bug #1173: make fmtint() take a LLONG rather than a long. Fixes scp'ing of large files on platforms with missing/broken snprintfs. Patch from e.borovac at bom.gov.au. --- openbsd-compat/bsd-snprintf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index e4ba154f..571c61fc 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -89,7 +89,7 @@ #include "includes.h" -RCSID("$Id: bsd-snprintf.c,v 1.11 2005/12/17 11:32:04 dtucker Exp $"); +RCSID("$Id: bsd-snprintf.c,v 1.12 2006/03/18 13:07:07 dtucker Exp $"); #if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ # undef HAVE_SNPRINTF @@ -161,7 +161,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, 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); + LLONG value, int base, 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); static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); @@ -468,10 +468,10 @@ static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, /* 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) + 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 */ -- cgit v1.2.3 From b0fb6872ed2efe3a116083e43dd4f5f47cd4882b Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 26 Mar 2006 00:03:21 +1100 Subject: - deraadt@cvs.openbsd.org 2006/03/19 18:51:18 [atomicio.c auth-bsdauth.c auth-chall.c auth-krb5.c auth-options.c] [auth-pam.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c auth-rsa.c] [auth-shadow.c auth-skey.c auth.c auth1.c auth2-chall.c] [auth2-hostbased.c auth2-kbdint.c auth2-none.c auth2-passwd.c] [auth2-pubkey.c auth2.c authfd.c authfile.c bufaux.c buffer.c] [canohost.c channels.c cipher-3des1.c cipher-acss.c cipher-aes.c] [cipher-bf1.c cipher-ctr.c cipher.c cleanup.c clientloop.c compat.c] [compress.c deattack.c dh.c dispatch.c dns.c entropy.c fatal.c] [groupaccess.c hostfile.c includes.h kex.c kexdh.c kexdhc.c] [kexdhs.c kexgex.c kexgexc.c kexgexs.c key.c log.c loginrec.c] [loginrec.h logintest.c mac.c match.c md-sha256.c md5crypt.c misc.c] [monitor.c monitor_fdpass.c monitor_mm.c monitor_wrap.c msg.c] [nchan.c packet.c progressmeter.c readconf.c readpass.c rsa.c] [scard.c scp.c servconf.c serverloop.c session.c sftp-client.c] [sftp-common.c sftp-glob.c sftp-server.c sftp.c ssh-add.c] [ssh-agent.c ssh-dss.c ssh-keygen.c ssh-keyscan.c ssh-keysign.c] [ssh-rand-helper.c ssh-rsa.c ssh.c sshconnect.c sshconnect1.c] [sshconnect2.c sshd.c sshlogin.c sshpty.c sshtty.c ttymodes.c] [uidswap.c uuencode.c xmalloc.c openbsd-compat/bsd-arc4random.c] [openbsd-compat/bsd-closefrom.c openbsd-compat/bsd-cygwin_util.c] [openbsd-compat/bsd-getpeereid.c openbsd-compat/bsd-misc.c] [openbsd-compat/bsd-nextstep.c openbsd-compat/bsd-snprintf.c] [openbsd-compat/bsd-waitpid.c openbsd-compat/fake-rfc2553.c] RCSID() can die --- openbsd-compat/bsd-snprintf.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index 571c61fc..c30cd122 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -89,8 +89,6 @@ #include "includes.h" -RCSID("$Id: bsd-snprintf.c,v 1.12 2006/03/18 13:07:07 dtucker Exp $"); - #if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ # undef HAVE_SNPRINTF # undef HAVE_VSNPRINTF -- cgit v1.2.3 From 62da44f0644f5d1cc7fa3b6b967482b5d2f15aa2 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 24 Jul 2006 15:08:35 +1000 Subject: - (djm) [openbsd-compat/basename.c openbsd-compat/bsd-closefrom.c] [openbsd-compat/bsd-cray.c openbsd-compat/bsd-openpty.c] [openbsd-compat/bsd-snprintf.c openbsd-compat/fake-rfc2553.c] [openbsd-compat/port-aix.c openbsd-compat/port-irix.c] [openbsd-compat/rresvport.c] These look to need string.h and/or unistd.h (based on a grep for function names) --- openbsd-compat/bsd-snprintf.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index c30cd122..9fdf4d3f 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -108,6 +108,8 @@ #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) +#include + #ifdef HAVE_LONG_DOUBLE # define LDOUBLE long double #else -- cgit v1.2.3 From f78fb54412e34c2647c1bc9f895af00620f42730 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 6 Aug 2006 21:25:24 +1000 Subject: - (dtucker) [openbsd-compat/{bsd-asprintf.c,bsd-openpty.c,bsd-snprintf.c, glob.c}] Include stdlib.h for malloc and friends in compat code. --- openbsd-compat/bsd-snprintf.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index 9fdf4d3f..47cbcff6 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -108,6 +108,8 @@ #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) +#include +#include #include #ifdef HAVE_LONG_DOUBLE -- cgit v1.2.3 From 08432d54faf63a2f5f9c264ac8ff6aa343ebeabc Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Sep 2006 15:59:43 +1000 Subject: - (dtucker) [openbsd-compat/bsd-snprintf.c] Add stdarg.h. --- openbsd-compat/bsd-snprintf.c | 1 + 1 file changed, 1 insertion(+) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index 47cbcff6..04651e1d 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -109,6 +109,7 @@ #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) #include +#include #include #include -- cgit v1.2.3 From 742cc1c19420db71275d3e8ef9fb86d96a463a4b Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 14 Jan 2007 21:20:30 +1100 Subject: - (djm) [openbsd-compat/bsd-snprintf.c] Fix integer overflow in return value of snprintf replacement, similar to bugs in various libc implementations. This overflow is not exploitable in OpenSSH. While I'm fiddling with it, make it a fair bit faster by inlining the append-char routine; ok dtucker@ --- openbsd-compat/bsd-snprintf.c | 164 ++++++++++++++++++++++++++---------------- 1 file changed, 101 insertions(+), 63 deletions(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index 04651e1d..cefb1d1a 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -85,6 +85,11 @@ * * Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even * if the C library has some snprintf functions already. + * + * Damien Miller (djm@mindrot.org) Jan 2007 + * Fix integer overflows in return value. + * Make formatting quite a bit faster by inlining dopr_outch() + * **************************************************************/ #include "includes.h" @@ -112,6 +117,8 @@ #include #include #include +#include +#include #ifdef HAVE_LONG_DOUBLE # define LDOUBLE long double @@ -159,17 +166,27 @@ # define MAX(p,q) (((p) >= (q)) ? (p) : (q)) #endif -static size_t dopr(char *buffer, size_t maxlen, const char *format, - va_list args_in); -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, - LLONG value, int base, 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); -static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); - -static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) +#define DOPR_OUTCH(buf, pos, buflen, thechar) \ + do { \ + if (++pos >= INT_MAX) { \ + errno = ERANGE; \ + return -1; \ + if (pos < buflen) \ + buf[pos] = thechar; \ + } \ + } while (0) + +static int dopr(char *buffer, size_t maxlen, const char *format, + va_list args_in); +static int fmtstr(char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max); +static int fmtint(char *buffer, size_t *currlen, size_t maxlen, + LLONG value, int base, int min, int max, int flags); +static int fmtfp(char *buffer, size_t *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags); + +static int +dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) { char ch; LLONG value; @@ -198,8 +215,8 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args case DP_S_DEFAULT: if (ch == '%') state = DP_S_FLAGS; - else - dopr_outch (buffer, &currlen, maxlen, ch); + else + DOPR_OUTCH(buffer, currlen, maxlen, ch); ch = *format++; break; case DP_S_FLAGS: @@ -298,7 +315,9 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args value = va_arg (args, LLONG); else value = va_arg (args, int); - fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + if (fmtint(buffer, &currlen, maxlen, + value, 10, min, max, flags) == -1) + return -1; break; case 'o': flags |= DP_F_UNSIGNED; @@ -310,7 +329,9 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args value = (long)va_arg (args, unsigned LLONG); else value = (long)va_arg (args, unsigned int); - fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); + if (fmtint(buffer, &currlen, maxlen, value, + 8, min, max, flags) == -1) + return -1; break; case 'u': flags |= DP_F_UNSIGNED; @@ -322,7 +343,9 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args value = (LLONG)va_arg (args, unsigned LLONG); else value = (long)va_arg (args, unsigned int); - fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + if (fmtint(buffer, &currlen, maxlen, value, + 10, min, max, flags) == -1) + return -1; break; case 'X': flags |= DP_F_UP; @@ -336,15 +359,18 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args value = (LLONG)va_arg (args, unsigned LLONG); else value = (long)va_arg (args, unsigned int); - fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); + if (fmtint(buffer, &currlen, maxlen, value, + 16, min, max, flags) == -1) + return -1; break; case 'f': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); - /* um, floating point? */ - fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); + if (fmtfp(buffer, &currlen, maxlen, fvalue, + min, max, flags) == -1) + return -1; break; case 'E': flags |= DP_F_UP; @@ -353,7 +379,9 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); - fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); + if (fmtfp(buffer, &currlen, maxlen, fvalue, + min, max, flags) == -1) + return -1; break; case 'G': flags |= DP_F_UP; @@ -362,10 +390,13 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); - fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); + if (fmtfp(buffer, &currlen, maxlen, fvalue, + min, max, flags) == -1) + return -1; 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 *); @@ -374,11 +405,15 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args max = strlen(strvalue); } if (min > 0 && max >= 0 && min > max) max = min; - fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); + if (fmtstr(buffer, &currlen, maxlen, + strvalue, flags, min, max) == -1) + return -1; break; case 'p': strvalue = va_arg (args, void *); - fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); + if (fmtint(buffer, &currlen, maxlen, + (long) strvalue, 16, min, max, flags) == -1) + return -1; break; case 'n': if (cflags == DP_C_SHORT) { @@ -400,7 +435,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args } break; case '%': - dopr_outch (buffer, &currlen, maxlen, ch); + DOPR_OUTCH(buffer, currlen, maxlen, ch); break; case 'w': /* not supported yet, treat as next char */ @@ -429,11 +464,12 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args buffer[maxlen - 1] = '\0'; } - return currlen; + return currlen < INT_MAX ? (int)currlen : -1; } -static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, - char *value, int flags, int min, int max) +static int +fmtstr(char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max) { int padlen, strln; /* amount to pad */ int cnt = 0; @@ -453,24 +489,26 @@ static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, padlen = -padlen; /* Left Justify */ while ((padlen > 0) && (cnt < max)) { - dopr_outch (buffer, currlen, maxlen, ' '); + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); --padlen; ++cnt; } while (*value && (cnt < max)) { - dopr_outch (buffer, currlen, maxlen, *value++); + DOPR_OUTCH(buffer, *currlen, maxlen, *value++); ++cnt; } while ((padlen < 0) && (cnt < max)) { - dopr_outch (buffer, currlen, maxlen, ' '); + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); ++padlen; ++cnt; } + return 0; } /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ -static void fmtint(char *buffer, size_t *currlen, size_t maxlen, +static int +fmtint(char *buffer, size_t *currlen, size_t maxlen, LLONG value, int base, int min, int max, int flags) { int signvalue = 0; @@ -527,31 +565,32 @@ static void fmtint(char *buffer, size_t *currlen, size_t maxlen, /* Spaces */ while (spadlen > 0) { - dopr_outch (buffer, currlen, maxlen, ' '); + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); --spadlen; } /* Sign */ if (signvalue) - dopr_outch (buffer, currlen, maxlen, signvalue); + DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); /* Zeros */ if (zpadlen > 0) { while (zpadlen > 0) { - dopr_outch (buffer, currlen, maxlen, '0'); + DOPR_OUTCH(buffer, *currlen, maxlen, '0'); --zpadlen; } } /* Digits */ while (place > 0) - dopr_outch (buffer, currlen, maxlen, convert[--place]); + DOPR_OUTCH(buffer, *currlen, maxlen, convert[--place]); /* Left Justified spaces */ while (spadlen < 0) { - dopr_outch (buffer, currlen, maxlen, ' '); + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); ++spadlen; } + return 0; } static LDOUBLE abs_val(LDOUBLE value) @@ -564,13 +603,13 @@ static LDOUBLE abs_val(LDOUBLE value) return result; } -static LDOUBLE POW10(int exp) +static LDOUBLE POW10(int val) { LDOUBLE result = 1; - while (exp) { + while (val) { result *= 10; - exp--; + val--; } return result; @@ -604,7 +643,10 @@ static double my_modf(double x0, double *iptr) } if (i == 100) { - /* yikes! the number is beyond what we can handle. What do we do? */ + /* + * yikes! the number is beyond what we can handle. + * What do we do? + */ (*iptr) = 0; return 0; } @@ -623,8 +665,9 @@ static double my_modf(double x0, double *iptr) } -static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, - LDOUBLE fvalue, int min, int max, int flags) +static int +fmtfp (char *buffer, size_t *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags) { int signvalue = 0; double ufvalue; @@ -729,24 +772,24 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, if ((flags & DP_F_ZERO) && (padlen > 0)) { if (signvalue) { - dopr_outch (buffer, currlen, maxlen, signvalue); + DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); --padlen; signvalue = 0; } while (padlen > 0) { - dopr_outch (buffer, currlen, maxlen, '0'); + DOPR_OUTCH(buffer, *currlen, maxlen, '0'); --padlen; } } while (padlen > 0) { - dopr_outch (buffer, currlen, maxlen, ' '); + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); --padlen; } if (signvalue) - dopr_outch (buffer, currlen, maxlen, signvalue); + DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); while (iplace > 0) - dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); + DOPR_OUTCH(buffer, *currlen, maxlen, iconvert[--iplace]); #ifdef DEBUG_SNPRINTF printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); @@ -757,41 +800,37 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, * char to print out. */ if (max > 0) { - dopr_outch (buffer, currlen, maxlen, '.'); + DOPR_OUTCH(buffer, *currlen, maxlen, '.'); while (zpadlen > 0) { - dopr_outch (buffer, currlen, maxlen, '0'); + DOPR_OUTCH(buffer, *currlen, maxlen, '0'); --zpadlen; } while (fplace > 0) - dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); + DOPR_OUTCH(buffer, *currlen, maxlen, + fconvert[--fplace]); } while (padlen < 0) { - dopr_outch (buffer, currlen, maxlen, ' '); + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); ++padlen; } -} - -static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) -{ - if (*currlen < maxlen) { - buffer[(*currlen)] = c; - } - (*currlen)++; + return 0; } #endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ #if !defined(HAVE_VSNPRINTF) -int vsnprintf (char *str, size_t count, const char *fmt, va_list args) +static int +vsnprintf (char *str, size_t count, const char *fmt, va_list args) { return dopr(str, count, fmt, args); } #endif #if !defined(HAVE_SNPRINTF) -int snprintf(char *str, size_t count, SNPRINTF_CONST char *fmt, ...) +static int +snprintf(char *str, size_t count, const char *fmt, ...) { size_t ret; va_list ap; @@ -802,4 +841,3 @@ int snprintf(char *str, size_t count, SNPRINTF_CONST char *fmt, ...) return ret; } #endif - -- cgit v1.2.3 From 07877ca68066593473fbe29dd309dcdc61b6d629 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 24 Jan 2007 00:07:29 +1100 Subject: - (dtucker) [openbsd-compat/bsd-snprintf.c] Static declarations for public library interfaces aren't very helpful. Fix up the DOPR_OUTCH macro so it works properly and modify its callers so that they don't pre or post decrement arguments that are conditionally evaluated. While there, put SNPRINTF_CONST back as it prevents build failures in some configurations. ok djm@ (for most of it) --- openbsd-compat/bsd-snprintf.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index cefb1d1a..41d2be23 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -168,12 +168,13 @@ #define DOPR_OUTCH(buf, pos, buflen, thechar) \ do { \ - if (++pos >= INT_MAX) { \ + if (pos + 1 >= INT_MAX) { \ errno = ERANGE; \ return -1; \ + } \ if (pos < buflen) \ buf[pos] = thechar; \ - } \ + (pos)++; \ } while (0) static int dopr(char *buffer, size_t maxlen, const char *format, @@ -494,7 +495,8 @@ fmtstr(char *buffer, size_t *currlen, size_t maxlen, ++cnt; } while (*value && (cnt < max)) { - DOPR_OUTCH(buffer, *currlen, maxlen, *value++); + DOPR_OUTCH(buffer, *currlen, maxlen, *value); + *value++; ++cnt; } while ((padlen < 0) && (cnt < max)) { @@ -582,8 +584,10 @@ fmtint(char *buffer, size_t *currlen, size_t maxlen, } /* Digits */ - while (place > 0) - DOPR_OUTCH(buffer, *currlen, maxlen, convert[--place]); + while (place > 0) { + --place; + DOPR_OUTCH(buffer, *currlen, maxlen, convert[place]); + } /* Left Justified spaces */ while (spadlen < 0) { @@ -788,8 +792,10 @@ fmtfp (char *buffer, size_t *currlen, size_t maxlen, if (signvalue) DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); - while (iplace > 0) - DOPR_OUTCH(buffer, *currlen, maxlen, iconvert[--iplace]); + while (iplace > 0) { + --iplace; + DOPR_OUTCH(buffer, *currlen, maxlen, iconvert[iplace]); + } #ifdef DEBUG_SNPRINTF printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); @@ -807,9 +813,10 @@ fmtfp (char *buffer, size_t *currlen, size_t maxlen, --zpadlen; } - while (fplace > 0) - DOPR_OUTCH(buffer, *currlen, maxlen, - fconvert[--fplace]); + while (fplace > 0) { + --fplace; + DOPR_OUTCH(buffer, *currlen, maxlen, fconvert[fplace]); + } } while (padlen < 0) { @@ -821,7 +828,7 @@ fmtfp (char *buffer, size_t *currlen, size_t maxlen, #endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ #if !defined(HAVE_VSNPRINTF) -static int +int vsnprintf (char *str, size_t count, const char *fmt, va_list args) { return dopr(str, count, fmt, args); @@ -829,8 +836,8 @@ vsnprintf (char *str, size_t count, const char *fmt, va_list args) #endif #if !defined(HAVE_SNPRINTF) -static int -snprintf(char *str, size_t count, const char *fmt, ...) +int +snprintf(char *str, size_t count, SNPRINTF_CONST char *fmt, ...) { size_t ret; va_list ap; -- cgit v1.2.3 From 04be8b9e53f8388c94b531ebc5d1bd6e10e930d1 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 28 Aug 2013 12:49:43 +1000 Subject: - (djm) [openbsd-compat/bsd-snprintf.c] teach our local snprintf code the 'j' (intmax_t/uintmax_t) and 'z' (size_t/ssize_t) conversions in case we start to use them in the future. --- openbsd-compat/bsd-snprintf.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index 41d2be23..308078e0 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -160,6 +160,8 @@ #define DP_C_LONG 2 #define DP_C_LDOUBLE 3 #define DP_C_LLONG 4 +#define DP_C_SIZE 5 +#define DP_C_INTMAX 6 #define char_to_int(p) ((p)- '0') #ifndef MAX @@ -182,7 +184,7 @@ static int dopr(char *buffer, size_t maxlen, const char *format, static int fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max); static int fmtint(char *buffer, size_t *currlen, size_t maxlen, - LLONG value, int base, int min, int max, int flags); + intmax_t value, int base, int min, int max, int flags); static int fmtfp(char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags); @@ -190,7 +192,7 @@ static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) { char ch; - LLONG value; + intmax_t value; LDOUBLE fvalue; char *strvalue; int min; @@ -287,6 +289,10 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) cflags = DP_C_SHORT; ch = *format++; break; + case 'j': + cflags = DP_C_INTMAX; + ch = *format++; + break; case 'l': cflags = DP_C_LONG; ch = *format++; @@ -299,6 +305,10 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) cflags = DP_C_LDOUBLE; ch = *format++; break; + case 'z': + cflags = DP_C_SIZE; + ch = *format++; + break; default: break; } @@ -314,6 +324,10 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) value = va_arg (args, long int); else if (cflags == DP_C_LLONG) value = va_arg (args, LLONG); + else if (cflags == DP_C_SIZE) + value = va_arg (args, ssize_t); + else if (cflags == DP_C_INTMAX) + value = va_arg (args, intmax_t); else value = va_arg (args, int); if (fmtint(buffer, &currlen, maxlen, @@ -328,6 +342,10 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) value = (long)va_arg (args, unsigned long int); else if (cflags == DP_C_LLONG) value = (long)va_arg (args, unsigned LLONG); + else if (cflags == DP_C_SIZE) + value = va_arg (args, size_t); + else if (cflags == DP_C_INTMAX) + value = va_arg (args, uintmax_t); else value = (long)va_arg (args, unsigned int); if (fmtint(buffer, &currlen, maxlen, value, @@ -342,6 +360,10 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) value = (long)va_arg (args, unsigned long int); else if (cflags == DP_C_LLONG) value = (LLONG)va_arg (args, unsigned LLONG); + else if (cflags == DP_C_SIZE) + value = va_arg (args, size_t); + else if (cflags == DP_C_INTMAX) + value = va_arg (args, uintmax_t); else value = (long)va_arg (args, unsigned int); if (fmtint(buffer, &currlen, maxlen, value, @@ -358,6 +380,10 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) value = (long)va_arg (args, unsigned long int); else if (cflags == DP_C_LLONG) value = (LLONG)va_arg (args, unsigned LLONG); + else if (cflags == DP_C_SIZE) + value = va_arg (args, size_t); + else if (cflags == DP_C_INTMAX) + value = va_arg (args, uintmax_t); else value = (long)va_arg (args, unsigned int); if (fmtint(buffer, &currlen, maxlen, value, @@ -416,6 +442,7 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) (long) strvalue, 16, min, max, flags) == -1) return -1; break; +#if we_dont_want_this_in_openssh case 'n': if (cflags == DP_C_SHORT) { short int *num; @@ -429,12 +456,21 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) LLONG *num; num = va_arg (args, LLONG *); *num = (LLONG)currlen; + } else if (cflags == DP_C_SIZE) { + ssize_t *num; + num = va_arg (args, ssize_t *); + *num = (ssize_t)currlen; + } else if (cflags == DP_C_INTMAX) { + intmax_t *num; + num = va_arg (args, intmax_t *); + *num = (intmax_t)currlen; } else { int *num; num = va_arg (args, int *); *num = currlen; } break; +#endif case '%': DOPR_OUTCH(buffer, currlen, maxlen, ch); break; -- cgit v1.2.3 From 43968a8e66a0aa1afefb11665bf96f86b113f5d9 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 28 Aug 2013 14:00:54 +1000 Subject: - (djm) [openbsd-compat/bsd-snprintf.c] #ifdef noytet for intmax_t bits until we have configure support. --- openbsd-compat/bsd-snprintf.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index 308078e0..975991e7 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -344,8 +344,10 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) value = (long)va_arg (args, unsigned LLONG); else if (cflags == DP_C_SIZE) value = va_arg (args, size_t); +#ifdef notyet else if (cflags == DP_C_INTMAX) value = va_arg (args, uintmax_t); +#endif else value = (long)va_arg (args, unsigned int); if (fmtint(buffer, &currlen, maxlen, value, @@ -362,8 +364,10 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) value = (LLONG)va_arg (args, unsigned LLONG); else if (cflags == DP_C_SIZE) value = va_arg (args, size_t); +#ifdef notyet else if (cflags == DP_C_INTMAX) value = va_arg (args, uintmax_t); +#endif else value = (long)va_arg (args, unsigned int); if (fmtint(buffer, &currlen, maxlen, value, @@ -382,8 +386,10 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) value = (LLONG)va_arg (args, unsigned LLONG); else if (cflags == DP_C_SIZE) value = va_arg (args, size_t); +#ifdef notyet else if (cflags == DP_C_INTMAX) value = va_arg (args, uintmax_t); +#endif else value = (long)va_arg (args, unsigned int); if (fmtint(buffer, &currlen, maxlen, value, -- cgit v1.2.3 From 4d69aeabd6e60afcdc7cca177ca751708ab79a9d Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 22 Aug 2014 17:48:27 +1000 Subject: - (djm) [openbsd-compat/bsd-snprintf.c] Fix compilation failure (prototype/ definition mismatch) and warning for broken/missing snprintf case. --- openbsd-compat/bsd-snprintf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index 975991e7..23a63598 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -538,7 +538,7 @@ fmtstr(char *buffer, size_t *currlen, size_t maxlen, } while (*value && (cnt < max)) { DOPR_OUTCH(buffer, *currlen, maxlen, *value); - *value++; + value++; ++cnt; } while ((padlen < 0) && (cnt < max)) { @@ -553,7 +553,7 @@ fmtstr(char *buffer, size_t *currlen, size_t maxlen, static int fmtint(char *buffer, size_t *currlen, size_t maxlen, - LLONG value, int base, int min, int max, int flags) + intmax_t value, int base, int min, int max, int flags) { int signvalue = 0; unsigned LLONG uvalue; -- cgit v1.2.3 From 5abfb15ced985c340359ae7fb65a625ed3692b3e Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 15 Jul 2016 14:48:30 +1000 Subject: Move VA_COPY macro into compat header. Some AIX compilers unconditionally undefine va_copy but don't set it back to an internal function, causing link errors. In some compat code we already use VA_COPY instead so move the two existing instances into the shared header and use for sshbuf-getput-basic.c too. Should fix building with at lease some versions of AIX's compiler. bz#2589, ok djm@ --- openbsd-compat/bsd-snprintf.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index 23a63598..d95b6a40 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -99,18 +99,6 @@ # undef HAVE_VSNPRINTF #endif -#ifndef VA_COPY -# ifdef HAVE_VA_COPY -# define VA_COPY(dest, src) va_copy(dest, src) -# else -# ifdef HAVE___VA_COPY -# define VA_COPY(dest, src) __va_copy(dest, src) -# else -# define VA_COPY(dest, src) (dest) = (src) -# endif -# endif -#endif - #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) #include -- cgit v1.2.3 From 10479cc2a4acd6faaf643eb305233b49d70c31c1 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 10 Apr 2018 10:19:02 +1000 Subject: Many typo fixes from Karsten Weiss Spotted using https://github.com/lucasdemarchi/codespell --- openbsd-compat/bsd-snprintf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index d95b6a40..f27b9d80 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -30,7 +30,7 @@ * probably requires libm on most operating systems. Don't yet * support the exponent (e,E) and sigfig (g,G). Also, fmtint() * was pretty badly broken, it just wasn't being exercised in ways - * which showed it, so that's been fixed. Also, formated the code + * which showed it, so that's been fixed. Also, formatted the code * to mutt conventions, and removed dead code left over from the * original. Also, there is now a builtin-test, just compile with: * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm -- cgit v1.2.3 From 397f217e8640e75bb719a8e87111b4bd848fb3df Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 13 Mar 2020 14:24:23 +1100 Subject: another spelling error in comment --- openbsd-compat/bsd-snprintf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'openbsd-compat/bsd-snprintf.c') diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index f27b9d80..f041121f 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -73,7 +73,7 @@ * Fix incorrect zpadlen handling in fmtfp. * Thanks to Ollie Oldham for spotting it. * few mods to make it easier to compile the tests. - * addedd the "Ollie" test to the floating point ones. + * added the "Ollie" test to the floating point ones. * * Martin Pool (mbp@samba.org) April 2003 * Remove NO_CONFIG_H so that the test case can be built within a source -- cgit v1.2.3