aboutsummaryrefslogtreecommitdiff
path: root/portable/snprintf.c
diff options
context:
space:
mode:
authorRuss Allbery <eagle@eyrie.org>2018-05-27 20:59:59 -0700
committerRuss Allbery <eagle@eyrie.org>2018-05-27 20:59:59 -0700
commitbdcb3741db27d6b773ce7cdf05aab063a70ea100 (patch)
tree11e11bb646e0b58db6e23b59e3c856ea59ef3545 /portable/snprintf.c
parent62a9101895a2d596bf91231f119d338d2025ff08 (diff)
Update to rra-c-util 7.2 and C TAP Harness 4.3
Update to rra-c-util 7.2: * Improve configure output for krb5-config testing. * Define UINT32_MAX for systems that don't have it. * Add SPDX-License-Identifier headers to all substantial source files. * Fix new warnings from GCC 7 and Clang warnings. * Require Test::Strict 0.25 or later to run those tests. * Fix off-by-one error in return-value checks for snprintf. * Use Autoconf to probe for supported warning flags. * Fix running module-version-t -u with current versions of Perl. * Use C_TAP_SOURCE and C_TAP_BUILD instead of SOURCE and BUILD. Update to C TAP Harness 4.3: * Add support for valgrind and libtool in test lists. * Report test failures as left and right, not wanted and expected. * Fix string comparisons with NULL pointers and the string "(null)". * Add SPDX-License-Identifier headers to all substantial source files. * Avoid zero-length realloc allocations in breallocarray. * Fix new warnings from GCC 7 and Clang warnings. * Use C_TAP_SOURCE and C_TAP_BUILD instead of SOURCE and BUILD.
Diffstat (limited to 'portable/snprintf.c')
-rw-r--r--portable/snprintf.c117
1 files changed, 68 insertions, 49 deletions
diff --git a/portable/snprintf.c b/portable/snprintf.c
index 9818acd..a42ef3b 100644
--- a/portable/snprintf.c
+++ b/portable/snprintf.c
@@ -11,7 +11,7 @@
* improvements should be sent back to the original author.
*
* The canonical version of this file is maintained in the rra-c-util package,
- * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*/
/*
@@ -25,11 +25,18 @@
# define vsnprintf test_vsnprintf
#endif
+/* Specific to rra-c-util, but only when debugging is enabled. */
+#ifdef DEBUG_SNPRINTF
+# include <util/messages.h>
+#endif
+
/*
* 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
+ *
+ * There is no SPDX-License-Identifier registered for this license.
*/
/**************************************************************
@@ -79,11 +86,24 @@
* Russ Allbery <eagle@eyrie.org> 2000-08-26
* fixed return value to comply with C99
* fixed handling of snprintf(NULL, ...)
+ * added explicit casts for double to long long int conversion
+ * fixed various warnings with GCC 7
+ * fixed various warnings with Clang
*
- * Hrvoje Niksic <hniksic@arsdigita.com> 2000-11-04
+ * Hrvoje Niksic <hniksic@xemacs.org> 2000-11-04
+ * include <config.h> instead of "config.h".
+ * moved TEST_SNPRINTF stuff out of HAVE_SNPRINTF ifdef.
* include <stdio.h> for NULL.
- * added support for long long.
+ * added support and test cases for long long.
* 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
* use the PARAMS macro to handle prototypes.
@@ -109,11 +129,6 @@
/* varargs declarations: */
#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)
/* Assume all compilers support long double, per Autoconf documentation. */
#define LDOUBLE long double
@@ -180,7 +195,7 @@ static int dopr (char *buffer, size_t maxlen, const char *format, va_list args)
char *strvalue;
int min;
int max;
- int state;
+ unsigned int state;
int flags;
int cflags;
int total;
@@ -351,6 +366,7 @@ static int dopr (char *buffer, size_t maxlen, const char *format, va_list args)
break;
case 'X':
flags |= DP_F_UP;
+ /* fallthrough */
case 'x':
flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT)
@@ -367,33 +383,36 @@ static int dopr (char *buffer, size_t maxlen, const char *format, va_list args)
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, LDOUBLE);
else
- fvalue = va_arg (args, double);
+ fvalue = (LDOUBLE) va_arg (args, double);
total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
break;
case 'E':
flags |= DP_F_UP;
+ /* fallthrough */
case 'e':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, LDOUBLE);
else
- fvalue = va_arg (args, double);
+ fvalue = (LDOUBLE) va_arg (args, double);
total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
break;
case 'G':
flags |= DP_F_UP;
+ /* fallthrough */
case 'g':
flags |= DP_F_FP_G;
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, LDOUBLE);
else
- fvalue = va_arg (args, double);
+ fvalue = (LDOUBLE) 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));
+ total += dopr_outch (buffer, &currlen, maxlen,
+ (char) va_arg (args, int));
break;
case 's':
strvalue = va_arg (args, char *);
@@ -409,7 +428,7 @@ static int dopr (char *buffer, size_t maxlen, const char *format, va_list args)
{
short int *num;
num = va_arg (args, short int *);
- *num = currlen;
+ *num = (short) currlen;
}
else if (cflags == DP_C_LONG)
{
@@ -427,7 +446,7 @@ static int dopr (char *buffer, size_t maxlen, const char *format, va_list args)
{
int *num;
num = va_arg (args, int *);
- *num = currlen;
+ *num = (int) currlen;
}
break;
case '%':
@@ -476,7 +495,7 @@ static int fmtstr (char *buffer, size_t *currlen, size_t maxlen,
}
if (max < 0)
- strln = strlen (value);
+ strln = (int) strlen (value);
else
/* When precision is specified, don't read VALUE past precision. */
/*strln = strnlen (value, max);*/
@@ -510,7 +529,7 @@ static int 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)
{
- int signvalue = 0;
+ char signvalue = 0;
unsigned LLONG uvalue;
char convert[24];
unsigned int place = 0;
@@ -564,8 +583,8 @@ static int fmtint (char *buffer, size_t *currlen, size_t maxlen,
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));
+ debug ("zpad: %d, spad: %d, min: %d, max: %d, place: %u\n",
+ zpadlen, spadlen, min, max, place);
#endif
/* Spaces */
@@ -612,7 +631,7 @@ static LDOUBLE abs_val (LDOUBLE value)
return result;
}
-static LDOUBLE pow10_int (int exp)
+static LLONG pow10_int (unsigned int exp)
{
LDOUBLE result = 1;
@@ -622,32 +641,40 @@ static LDOUBLE pow10_int (int exp)
exp--;
}
- return result;
+ return (LLONG) result;
}
static LLONG round_int (LDOUBLE value)
{
LLONG intpart;
- intpart = value;
+ intpart = (LLONG) value;
value = value - intpart;
- if (value >= 0.5)
+ if (value >= (LDOUBLE) 0.5)
intpart++;
return intpart;
}
+/*
+ * GCC 7.1 issues this warning at the point of the function definition header
+ * (not in any actual code), and I can't figure out what's triggering it since
+ * the comparison form doesn't appear anywhere in this code. Since this is
+ * rarely-used portability code, suppress the warning.
+ */
+#pragma GCC diagnostic ignored "-Wstrict-overflow"
+
static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
LDOUBLE fvalue, int min, int max, int flags)
{
- int signvalue = 0;
+ char signvalue = 0;
LDOUBLE ufvalue;
char iconvert[24];
char fconvert[24];
size_t iplace = 0;
size_t fplace = 0;
- int padlen = 0; /* amount to pad */
- int zpadlen = 0;
+ long padlen = 0; /* amount to pad */
+ long zpadlen = 0;
int total = 0;
LLONG intpart;
LLONG fracpart;
@@ -678,7 +705,7 @@ static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
#endif
- intpart = ufvalue;
+ intpart = (LLONG) ufvalue;
/* With %g precision is the number of significant digits, which
includes the digits in intpart. */
@@ -699,7 +726,7 @@ static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
fractional digit. */
LDOUBLE temp;
if (ufvalue > 0)
- for (temp = ufvalue; temp < 0.1; temp *= 10)
+ for (temp = ufvalue; temp < (LDOUBLE) 0.1; temp *= 10)
++max;
}
}
@@ -746,12 +773,16 @@ static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
}
#ifdef DEBUG_SNPRINTF
- dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart));
+# ifdef HAVE_LONG_LONG_INT
+ debug ("fmtfp: %Lf =? %lld.%lld\n", fvalue, intpart, fracpart);
+# else
+ debug ("fmtfp: %Lf =? %ld.%ld\n", fvalue, intpart, fracpart);
+# endif
#endif
/* Convert integer part */
do {
- iconvert[iplace++] = '0' + intpart % 10;
+ iconvert[iplace++] = (char) ('0' + (intpart % 10));
intpart = (intpart / 10);
} while(intpart && (iplace < sizeof(iconvert)));
if (iplace == sizeof(iconvert)) iplace--;
@@ -759,7 +790,7 @@ static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
/* Convert fractional part */
do {
- fconvert[fplace++] = '0' + fracpart % 10;
+ fconvert[fplace++] = (char) ('0' + (fracpart % 10));
fracpart = (fracpart / 10);
} while(fracpart && (fplace < sizeof(fconvert)));
while (leadingfrac0s-- > 0 && fplace < sizeof(fconvert))
@@ -847,27 +878,14 @@ int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
return dopr(str, count, fmt, args);
}
-/* 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 *);
+ va_start(ap, fmt);
total = vsnprintf(str, count, fmt, ap);
- VA_END;
+ va_end(ap);
return total;
}
@@ -944,5 +962,6 @@ int main (void)
num++;
}
printf ("%d tests failed out of %d.\n", fail, num);
+ return 0;
}
-#endif /* SNPRINTF_TEST */
+#endif /* TEST_SNPRINTF */