* actually print args for %g and %e
*
* Hrvoje Niksic <hniksic@xemacs.org> 2005-04-15
- * use the PARAMS macro to handle prototypes.
* 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.
#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-#endif
+#include <string.h>
#include <sys/types.h>
#include <stdio.h> /* for NULL */
-/* 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 <stdarg.h>
#ifdef HAVE_LONG_DOUBLE
#define LDOUBLE long double
# define vsnprintf test_vsnprintf
#endif
-#ifdef HAVE_STDARGS
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
-
-#ifndef PARAMS
-# define PARAMS(x) x
-#endif
-static int dopr PARAMS ((char *buffer, size_t maxlen, const char *format,
- va_list args));
-static int fmtstr PARAMS ((char *buffer, size_t *currlen, size_t maxlen,
- char *value, int flags, int min, int max));
-static int fmtint PARAMS ((char *buffer, size_t *currlen, size_t maxlen,
- LLONG value, int base, int min, int max, int flags));
-static int fmtfp PARAMS ((char *buffer, size_t *currlen, size_t maxlen,
- LDOUBLE fvalue, int min, int max, int flags));
-static int dopr_outch PARAMS ((char *buffer, size_t *currlen, size_t maxlen,
- char c));
+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,
+ 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);
+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);
/*
* dopr(): poor man's version of doprintf
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;
includes the digits in intpart. */
if (flags & DP_F_FP_G)
{
- LLONG temp = intpart;
- for (temp = intpart; temp != 0; temp /= 10)
- --max;
- if (max < 0)
- max = 0;
+ 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
#ifndef HAVE_SNPRINTF
int
-snprintf (char *str, size_t count,const char *fmt,...)
+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 */
char buf1[LONG_STRING];
char buf2[LONG_STRING];
char *fp_fmt[] = {
+ /* %f formats */
+ "%f",
"%-1.5f",
"%1.5f",
"%123.9f",
"%3.2f",
"%.0f",
"%.1f",
- "%-1.5g",
+ "%#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.00205, 0};
+ 0.9996, 1.996, 4.136, 0.00205, 0.0001, 321.000009,
+ 0};
char *int_fmt[] = {
"%-1.5d",
"%1.5d",