* don't declare argument types to (v)snprintf if stdarg is not used.
* use int instead of short int as 2nd arg to va_arg.
*
+ * alexk (INN) 2002-08-21
+ * use LLONG in fmtfp to handle more characters during floating
+ * point conversion.
+ *
+ * herb (Samba) 2002-12-19
+ * actually print args for %g and %e
+ *
+ * Hrvoje Niksic <hniksic@xemacs.org> 2005-04-15
+ * write function definitions in the ansi2knr-friendly way.
+ * if string precision is specified, don't read VALUE past it.
+ * fix bug in fmtfp that caused 0.01 to be printed as 0.1.
+ * don't include <ctype.h> because none of it is used.
+ * interpret precision as number of significant digits with %g
+ * omit trailing decimal zeros with %g
+ *
**************************************************************/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
+#include "wget.h"
+
+/* For testing purposes, always compile in the code. */
+#ifdef TEST_SNPRINTF
+# undef HAVE_SNPRINTF
+# undef HAVE_VSNPRINTF
+# ifndef SIZEOF_LONG_LONG
+# ifdef __GNUC__
+# define SIZEOF_LONG_LONG 8
+# endif
+# endif
#endif
#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
#include <string.h>
#include <sys/types.h>
-#include <stdio.h> /* for NULL */
-#include <safe-ctype.h>
-
-/* varargs declarations: */
-
-#if defined(HAVE_STDARG_H)
-# include <stdarg.h>
-# 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
-# include <varargs.h>
-# 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)
-#endif
+#include <stdio.h> /* for NULL */
+
+#include <stdarg.h>
#ifdef HAVE_LONG_DOUBLE
#define LDOUBLE long double
# define LLONG long
#endif
-#ifdef HAVE_STDARGS
+/* If we're running the test suite, rename snprintf and vsnprintf to
+ avoid conflicts with the system version. */
+#ifdef TEST_SNPRINTF
+# define snprintf test_snprintf
+# define vsnprintf test_vsnprintf
+#endif
+
int snprintf (char *str, size_t count, const char *fmt, ...);
int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
-#else
-int snprintf ();
-int vsnprintf ();
-#endif
-static int dopr (char *buffer, size_t maxlen, const char *format,
+static int dopr (char *buffer, size_t maxlen, const char *format,
va_list args);
static int fmtstr (char *buffer, size_t *currlen, size_t maxlen,
- char *value, int flags, int min, int max);
+ const 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);
+ 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_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
+ LDOUBLE fvalue, int min, int max, int flags);
+static int dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c);
/*
* dopr(): poor man's version of doprintf
#define DP_S_DONE 8
/* 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)
+#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)
+#define DP_F_FP_G (1 << 7)
/* Conversion Flags */
#define DP_C_SHORT 1
{
case DP_S_DEFAULT:
if (ch == '%')
- state = DP_S_FLAGS;
+ state = DP_S_FLAGS;
else
- total += dopr_outch (buffer, &currlen, maxlen, ch);
+ total += dopr_outch (buffer, &currlen, maxlen, ch);
ch = *format++;
break;
case DP_S_FLAGS:
switch (ch)
{
case '-':
- flags |= DP_F_MINUS;
+ flags |= DP_F_MINUS;
ch = *format++;
- break;
+ break;
case '+':
- flags |= DP_F_PLUS;
+ flags |= DP_F_PLUS;
ch = *format++;
- break;
+ break;
case ' ':
- flags |= DP_F_SPACE;
+ flags |= DP_F_SPACE;
ch = *format++;
- break;
+ break;
case '#':
- flags |= DP_F_NUM;
+ flags |= DP_F_NUM;
ch = *format++;
- break;
+ break;
case '0':
- flags |= DP_F_ZERO;
+ flags |= DP_F_ZERO;
ch = *format++;
- break;
+ break;
default:
- state = DP_S_MIN;
- break;
+ state = DP_S_MIN;
+ break;
}
break;
case DP_S_MIN:
if ('0' <= ch && ch <= '9')
{
- min = 10*min + char_to_int (ch);
- ch = *format++;
+ min = 10*min + char_to_int (ch);
+ ch = *format++;
}
else if (ch == '*')
{
- min = va_arg (args, int);
- ch = *format++;
- state = DP_S_DOT;
+ min = va_arg (args, int);
+ ch = *format++;
+ state = DP_S_DOT;
}
else
- state = DP_S_DOT;
+ state = DP_S_DOT;
break;
case DP_S_DOT:
if (ch == '.')
{
- state = DP_S_MAX;
- ch = *format++;
+ state = DP_S_MAX;
+ ch = *format++;
}
else
- state = DP_S_MOD;
+ state = DP_S_MOD;
break;
case DP_S_MAX:
if ('0' <= ch && ch <= '9')
{
- if (max < 0)
- max = 0;
- max = 10*max + char_to_int (ch);
- ch = *format++;
+ 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;
+ max = va_arg (args, int);
+ ch = *format++;
+ state = DP_S_MOD;
}
else
- state = DP_S_MOD;
+ state = DP_S_MOD;
break;
case DP_S_MOD:
switch (ch)
{
case 'h':
- cflags = DP_C_SHORT;
- ch = *format++;
- break;
+ cflags = DP_C_SHORT;
+ ch = *format++;
+ break;
case 'l':
- cflags = DP_C_LONG;
- ch = *format++;
- break;
+ cflags = DP_C_LONG;
+ ch = *format++;
+ break;
case 'L':
- cflags = DP_C_LDOUBLE;
- ch = *format++;
- break;
+ cflags = DP_C_LDOUBLE;
+ ch = *format++;
+ break;
default:
- break;
+ break;
}
if (cflags != DP_C_LONG)
- state = DP_S_CONV;
+ state = DP_S_CONV;
else
- state = DP_S_MOD_L;
+ state = DP_S_MOD_L;
break;
case DP_S_MOD_L:
switch (ch)
- {
- case 'l':
- cflags = DP_C_LLONG;
- ch = *format++;
- break;
- default:
- break;
- }
+ {
+ case 'l':
+ cflags = DP_C_LLONG;
+ ch = *format++;
+ break;
+ default:
+ break;
+ }
state = DP_S_CONV;
break;
case DP_S_CONV:
{
case 'd':
case 'i':
- if (cflags == DP_C_SHORT)
- value = (short int)va_arg (args, int);
- else if (cflags == DP_C_LONG)
- value = va_arg (args, long int);
- else if (cflags == DP_C_LLONG)
- value = va_arg (args, LLONG);
- else
- value = va_arg (args, int);
- total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
- break;
+ if (cflags == DP_C_SHORT)
+ value = (short int) va_arg (args, int);
+ else if (cflags == DP_C_LONG)
+ value = va_arg (args, long int);
+ else if (cflags == DP_C_LLONG)
+ value = va_arg (args, LLONG);
+ else
+ value = va_arg (args, int);
+ total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
+ break;
case 'o':
- flags |= DP_F_UNSIGNED;
- if (cflags == DP_C_SHORT)
- value = (unsigned short int)va_arg (args, unsigned int);
- else if (cflags == DP_C_LONG)
- value = va_arg (args, unsigned long int);
- else if (cflags == DP_C_LLONG)
- value = va_arg (args, unsigned LLONG);
- else
- value = va_arg (args, unsigned int);
- total += fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
- break;
+ flags |= DP_F_UNSIGNED;
+ if (cflags == DP_C_SHORT)
+ value = (unsigned short int) va_arg (args, unsigned int);
+ else if (cflags == DP_C_LONG)
+ value = va_arg (args, unsigned long int);
+ else if (cflags == DP_C_LLONG)
+ value = va_arg (args, unsigned LLONG);
+ else
+ value = va_arg (args, unsigned int);
+ total += fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
+ break;
case 'u':
- flags |= DP_F_UNSIGNED;
- if (cflags == DP_C_SHORT)
- value = (unsigned short int)va_arg (args, unsigned int);
- else if (cflags == DP_C_LONG)
- value = va_arg (args, unsigned long int);
- else if (cflags == DP_C_LLONG)
- value = va_arg (args, unsigned LLONG);
- else
- value = va_arg (args, unsigned int);
- total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
- break;
+ flags |= DP_F_UNSIGNED;
+ if (cflags == DP_C_SHORT)
+ value = (unsigned short int) va_arg (args, unsigned int);
+ else if (cflags == DP_C_LONG)
+ value = va_arg (args, unsigned long int);
+ else if (cflags == DP_C_LLONG)
+ value = va_arg (args, unsigned LLONG);
+ else
+ value = va_arg (args, unsigned int);
+ total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
+ break;
case 'X':
- flags |= DP_F_UP;
+ flags |= DP_F_UP;
case 'x':
- flags |= DP_F_UNSIGNED;
- if (cflags == DP_C_SHORT)
- value = (unsigned short int)va_arg (args, unsigned int);
- else if (cflags == DP_C_LONG)
- value = va_arg (args, unsigned long int);
- else if (cflags == DP_C_LLONG)
- value = va_arg (args, unsigned LLONG);
- else
- value = va_arg (args, unsigned int);
- total += fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
- break;
+ flags |= DP_F_UNSIGNED;
+ if (cflags == DP_C_SHORT)
+ value = (unsigned short int) va_arg (args, unsigned int);
+ else if (cflags == DP_C_LONG)
+ value = va_arg (args, unsigned long int);
+ else if (cflags == DP_C_LLONG)
+ value = va_arg (args, unsigned LLONG);
+ else
+ value = va_arg (args, unsigned int);
+ total += fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
+ break;
case 'f':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg (args, LDOUBLE);
- else
- fvalue = va_arg (args, double);
- /* um, floating point? */
- total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
- break;
+ if (cflags == DP_C_LDOUBLE)
+ fvalue = va_arg (args, LDOUBLE);
+ else
+ fvalue = va_arg (args, double);
+ total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
+ break;
case 'E':
- flags |= DP_F_UP;
+ flags |= DP_F_UP;
case 'e':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg (args, LDOUBLE);
- else
- fvalue = va_arg (args, double);
- break;
+ if (cflags == DP_C_LDOUBLE)
+ fvalue = va_arg (args, LDOUBLE);
+ else
+ fvalue = va_arg (args, double);
+ total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
+ break;
case 'G':
- flags |= DP_F_UP;
+ flags |= DP_F_UP;
case 'g':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg (args, LDOUBLE);
- else
- fvalue = va_arg (args, double);
- break;
+ flags |= DP_F_FP_G;
+ if (cflags == DP_C_LDOUBLE)
+ fvalue = va_arg (args, LDOUBLE);
+ else
+ fvalue = va_arg (args, double);
+ if (max == 0)
+ /* C99 says: if precision [for %g] is zero, it is taken as one */
+ max = 1;
+ total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
+ break;
case 'c':
- total += dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
- break;
+ total += dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
+ break;
case 's':
- strvalue = va_arg (args, char *);
- total += fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
- break;
+ strvalue = va_arg (args, char *);
+ total += fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
+ break;
case 'p':
- strvalue = va_arg (args, void *);
- total += fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min,
+ strvalue = va_arg (args, void *);
+ total += fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min,
max, flags);
- break;
+ break;
case 'n':
- if (cflags == DP_C_SHORT)
- {
- short int *num;
- num = va_arg (args, short int *);
- *num = currlen;
+ 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 int *num;
+ num = va_arg (args, long int *);
+ *num = currlen;
}
- else if (cflags == DP_C_LLONG)
- {
- LLONG *num;
- num = va_arg (args, LLONG *);
- *num = currlen;
+ else if (cflags == DP_C_LLONG)
+ {
+ LLONG *num;
+ num = va_arg (args, LLONG *);
+ *num = currlen;
}
- else
- {
- int *num;
- num = va_arg (args, int *);
- *num = currlen;
+ else
+ {
+ int *num;
+ num = va_arg (args, int *);
+ *num = currlen;
}
- break;
+ break;
case '%':
- total += dopr_outch (buffer, &currlen, maxlen, ch);
- break;
+ total += dopr_outch (buffer, &currlen, maxlen, ch);
+ break;
case 'w':
- /* not supported yet, treat as next char */
- ch = *format++;
- break;
+ /* not supported yet, treat as next char */
+ ch = *format++;
+ break;
default:
- /* Unknown, skip */
- break;
+ /* Unknown, skip */
+ break;
}
ch = *format++;
state = DP_S_DEFAULT;
}
static int fmtstr (char *buffer, size_t *currlen, size_t maxlen,
- char *value, int flags, int min, int max)
+ const char *value, int flags, int min, int max)
{
int padlen, strln; /* amount to pad */
int cnt = 0;
if (value == 0)
{
- value = "<NULL>";
+ value = "(null)";
}
- for (strln = 0; value[strln]; ++strln); /* strlen */
- if (max >= 0 && max < strln)
- strln = max;
+ if (max < 0)
+ strln = strlen (value);
+ else
+ /* When precision is specified, don't read VALUE past precision. */
+ /*strln = strnlen (value, max);*/
+ for (strln = 0; strln < max && value[strln]; ++strln)
+ ;
padlen = min - strln;
if (padlen < 0)
padlen = 0;
/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
static int fmtint (char *buffer, size_t *currlen, size_t maxlen,
- LLONG value, int base, int min, int max, int flags)
+ LLONG value, int base, int min, int max, int flags)
{
int signvalue = 0;
unsigned LLONG uvalue;
}
else
if (flags & DP_F_PLUS) /* Do a sign (+/i) */
- signvalue = '+';
+ signvalue = '+';
else
if (flags & DP_F_SPACE)
- signvalue = ' ';
+ signvalue = ' ';
}
if (flags & DP_F_UP)
return result;
}
-static LDOUBLE pow10 (int exp)
+static LDOUBLE pow10_int (int exp)
{
LDOUBLE result = 1;
return result;
}
-static long round (LDOUBLE value)
+static LLONG round_int (LDOUBLE value)
{
- long intpart;
+ LLONG intpart;
intpart = value;
value = value - intpart;
}
static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
- LDOUBLE fvalue, int min, int max, int flags)
+ LDOUBLE fvalue, int min, int max, int flags)
{
int signvalue = 0;
LDOUBLE ufvalue;
- char iconvert[20];
- char fconvert[20];
+ char iconvert[24];
+ char fconvert[24];
int iplace = 0;
int fplace = 0;
int padlen = 0; /* amount to pad */
int zpadlen = 0;
- int caps = 0;
int total = 0;
- long intpart;
- long fracpart;
+ LLONG intpart;
+ LLONG fracpart;
+ LLONG mask10;
+ int leadingfrac0s = 0; /* zeros at the start of fractional part */
+ int omitzeros = 0;
+ int omitcount = 0;
/*
* AIX manpage says the default is 0, but Solaris says the default
signvalue = '+';
else
if (flags & DP_F_SPACE)
- signvalue = ' ';
+ signvalue = ' ';
#if 0
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
intpart = ufvalue;
+ /* With %g precision is the number of significant digits, which
+ includes the digits in intpart. */
+ if (flags & DP_F_FP_G)
+ {
+ if (intpart != 0)
+ {
+ /* For each digit of INTPART, print one less fractional digit. */
+ LLONG temp = intpart;
+ for (temp = intpart; temp != 0; temp /= 10)
+ --max;
+ if (max < 0)
+ max = 0;
+ }
+ else
+ {
+ /* For each leading 0 in fractional part, print one more
+ fractional digit. */
+ LDOUBLE temp;
+ if (ufvalue != 0)
+ for (temp = ufvalue; temp < 0.1; temp *= 10)
+ ++max;
+ }
+ }
+
+ /* C99: trailing zeros are removed from the fractional portion of the
+ result unless the # flag is specified */
+ if ((flags & DP_F_FP_G) && !(flags & DP_F_NUM))
+ omitzeros = 1;
+
+#if SIZEOF_LONG_LONG > 0
+# define MAX_DIGITS 18 /* grok more digits with long long */
+#else
+# define MAX_DIGITS 9 /* just long */
+#endif
+
/*
- * Sorry, we only support 9 digits past the decimal because of our
- * conversion method
+ * Sorry, we only support several digits past the decimal because of
+ * our conversion method
*/
- if (max > 9)
- max = 9;
+ if (max > MAX_DIGITS)
+ max = MAX_DIGITS;
+
+ /* Factor of 10 with the needed number of digits, e.g. 1000 for max==3 */
+ mask10 = pow10_int (max);
/* We "cheat" by converting the fractional part to integer by
* multiplying by a factor of 10
*/
- fracpart = round ((pow10 (max)) * (ufvalue - intpart));
+ fracpart = round_int (mask10 * (ufvalue - intpart));
- if (fracpart >= pow10 (max))
+ if (fracpart >= mask10)
{
intpart++;
- fracpart -= pow10 (max);
+ fracpart -= mask10;
}
+ else if (fracpart != 0)
+ /* If fracpart has less digits than the 10* mask, we need to
+ manually insert leading 0s. For example 2.01's fractional part
+ requires one leading zero to distinguish it from 2.1. */
+ while (fracpart < mask10 / 10)
+ {
+ ++leadingfrac0s;
+ mask10 /= 10;
+ }
#ifdef DEBUG_SNPRINTF
dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart));
/* Convert integer part */
do {
- iconvert[iplace++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10];
+ iconvert[iplace++] = '0' + intpart % 10;
intpart = (intpart / 10);
- } while(intpart && (iplace < 20));
- if (iplace == 20) iplace--;
+ } while(intpart && (iplace < sizeof(iconvert)));
+ if (iplace == sizeof(iconvert)) iplace--;
iconvert[iplace] = 0;
/* Convert fractional part */
do {
- fconvert[fplace++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10];
+ fconvert[fplace++] = '0' + fracpart % 10;
fracpart = (fracpart / 10);
- } while(fracpart && (fplace < 20));
- if (fplace == 20) fplace--;
+ } while(fracpart && (fplace < sizeof(fconvert)));
+ while (leadingfrac0s-- > 0 && fplace < sizeof(fconvert))
+ fconvert[fplace++] = '0';
+ if (fplace == sizeof(fconvert)) fplace--;
fconvert[fplace] = 0;
+ if (omitzeros)
+ while (omitcount < fplace && fconvert[omitcount] == '0')
+ ++omitcount;
/* -1 for decimal point, another -1 if we are printing a sign */
- padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
- zpadlen = max - fplace;
+ padlen = min - iplace - (max - omitcount) - 1 - ((signvalue) ? 1 : 0);
+ if (!omitzeros)
+ zpadlen = max - fplace;
if (zpadlen < 0)
zpadlen = 0;
if (padlen < 0)
* Decimal point. This should probably use locale to find the correct
* char to print out.
*/
- if (max > 0)
+ if (max > 0 && (fplace > omitcount || zpadlen > 0))
{
total += dopr_outch (buffer, currlen, maxlen, '.');
- while (fplace > 0)
+ while (fplace > omitcount)
total += dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
}
#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_list ap;
int total;
-
- VA_START (fmt);
- VA_SHIFT (str, char *);
- VA_SHIFT (count, size_t );
- VA_SHIFT (fmt, char *);
- total = vsnprintf(str, count, fmt, ap);
- VA_END;
+
+ va_start (ap, fmt);
+ total = vsnprintf (str, count, fmt, ap);
+ va_end (ap);
return total;
}
#endif /* !HAVE_SNPRINTF */
#ifdef TEST_SNPRINTF
-#include <stdio.h>
+# ifndef LONG_STRING
+# define LONG_STRING 1024
+# endif
-#ifndef LONG_STRING
-#define LONG_STRING 1024
-#endif
int main (void)
{
char buf1[LONG_STRING];
char buf2[LONG_STRING];
char *fp_fmt[] = {
+ /* %f formats */
+ "%f",
"%-1.5f",
"%1.5f",
"%123.9f",
"%3.2f",
"%.0f",
"%.1f",
+ "%#10.1f",
+#if SIZEOF_LONG_LONG != 0
+ "%.16f",
+ "%18.16f",
+ "%-16.16f",
+#endif
+ /* %g formats */
+ "%g",
+ "%1.5g",
+ "%-1.5g",
+ "%.9g",
+ "%123.9g",
+ "%#123.9g",
+#if SIZEOF_LONG_LONG != 0
+ "%.16g",
+ "%20.16g",
+#endif
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};
+ 0.9996, 1.996, 4.136, 0.00205, 0.0001, 321.000009,
+ 0};
char *int_fmt[] = {
"%-1.5d",
"%1.5d",
long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
#if SIZEOF_LONG_LONG != 0
char *llong_fmt[] = {
- "%lld", "%llu",
- "%-1.5lld", "%-1.5llu",
- "%1.5lld", "%1.5llu",
- "%123.9lld", "%123.9llu",
- "%5.5lld", "%5.5llu",
- "%10.5lld", "%10.5llu",
- "% 10.5lld", "% 10.5llu",
- "%+22.33lld", "%+22.33llu",
- "%01.3lld", "%01.3llu",
- "%4lld", "%4llu",
+ "%lld", "%llu",
+ "%-1.5lld", "%-1.5llu",
+ "%1.5lld", "%1.5llu",
+ "%123.9lld", "%123.9llu",
+ "%5.5lld", "%5.5llu",
+ "%10.5lld", "%10.5llu",
+ "% 10.5lld", "% 10.5llu",
+ "%+22.33lld", "%+22.33llu",
+ "%01.3lld", "%01.3llu",
+ "%4lld", "%4llu",
NULL
};
long long llong_nums[] = {
- ~(long long)0, /* all-1 bit pattern */
+ ~(long long)0, /* all-1 bit pattern */
(~(unsigned long long)0) >> 1, /* largest signed long long */
/* random... */
-150, 134, 91340, 341,
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++;
+ printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
+ fp_fmt[x], buf1, buf2);
+ fail++;
}
num++;
}
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++;
+ printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
+ int_fmt[x], buf1, buf2);
+ fail++;
}
num++;
}
sprintf (buf2, llong_fmt[x], llong_nums[y]);
if (strcmp (buf1, buf2))
{
- printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
- llong_fmt[x], buf1, buf2);
- fail++;
+ printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
+ llong_fmt[x], buf1, buf2);
+ fail++;
}
num++;
}
#endif
printf ("%d tests failed out of %d.\n", fail, num);
+ return 0;
}
-#endif /* SNPRINTF_TEST */
+#endif /* TEST_SNPRINTF */