#include "regex/cdefs.h"
+#include
#include
#include
#include
-/* IRIX doesn't do 'long long' in va_arg(), so use a typedef */
+/*
+ * We do all internal arithmetic in the widest available integer type,
+ * here called long_long (or ulong_long for unsigned).
+ */
#ifdef HAVE_LONG_LONG_INT_64
-typedef long long long_long;
-typedef unsigned long long ulong_long;
+typedef long long long_long;
+typedef unsigned long long ulong_long;
+#else
+typedef long long_long;
+typedef unsigned long ulong_long;
#endif
/*
* 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...
+ * the version here does not include floating point. (now it does ... tgl)
*
* snprintf() is used instead of sprintf() as it does limit checks
* for string length. This covers a nasty loophole.
* causing nast effects.
**************************************************************/
-/*static char _id[] = "$Id: snprintf.c,v 1.19 1999/02/03 21:17:00 momjian Exp $";*/
+/*static char _id[] = "$Id: snprintf.c,v 1.20 1999/02/06 21:51:03 tgl Exp $";*/
static char *end;
static int SnprfOverflow;
* dopr(): poor man's version of doprintf
*/
-static void fmtstr __P((char *value, int ljust, int len, int zpad, int maxwidth));
-
-#ifndef HAVE_LONG_LONG_INT_64
-static void fmtnum __P((long value, int base, int dosign, int ljust, int len, int zpad));
-#else
-static void fmtnum __P((long_long value, int base, int dosign, int ljust, int len, int zpad));
-#endif
+static void fmtstr (char *value, int ljust, int len, int zpad, int maxwidth);
+static void fmtnum (long_long value, int base, int dosign, int ljust, int len, int zpad);
+static void fmtfloat (double value, char type, int ljust, int len, int precision, int pointflag);
+static void dostr (char *str, int cut);
+static void dopr_outch (int c);
-static void dostr __P((char *, int));
static char *output;
-static void dopr_outch __P((int c));
+
static void
dopr(char *buffer, const char *format, va_list args)
{
int ch;
-#ifdef HAVE_LONG_LONG_INT_64
long_long value;
+ double fvalue;
int longlongflag = 0;
-#else
- long value;
-#endif
int longflag = 0;
int pointflag = 0;
int maxwidth = 0;
{
case '%':
ljust = len = zpad = maxwidth = 0;
- longflag = pointflag = 0;
-#ifdef HAVE_LONG_LONG_INT_64
- longlongflag = 0;
-#endif
+ longflag = longlongflag = pointflag = 0;
nextch:
ch = *format++;
switch (ch)
pointflag = 1;
goto nextch;
case 'l':
-#ifdef HAVE_LONG_LONG_INT_64
if (longflag)
longlongflag = 1;
else
-#endif
longflag = 1;
goto nextch;
case 'u':
/* fmtnum(value,base,dosign,ljust,len,zpad) */
if (longflag)
{
-#ifdef HAVE_LONG_LONG_INT_64
if (longlongflag)
value = va_arg(args, long_long);
else
-#endif
value = va_arg(args, long);
}
else
/* fmtnum(value,base,dosign,ljust,len,zpad) */
if (longflag)
{
-#ifdef HAVE_LONG_LONG_INT_64
if (longlongflag)
value = va_arg(args, long_long);
else
-#endif
- value = va_arg(args, long);
+ value = va_arg(args, long);
}
else
value = va_arg(args, int);
case 'D':
if (longflag)
{
-#ifdef HAVE_LONG_LONG_INT_64
if (longlongflag)
value = va_arg(args, long_long);
else
-#endif
value = va_arg(args, long);
}
else
case 'x':
if (longflag)
{
-#ifdef HAVE_LONG_LONG_INT_64
if (longlongflag)
value = va_arg(args, long_long);
else
-#endif
- value = va_arg(args, long);
+ value = va_arg(args, long);
}
else
value = va_arg(args, int);
case 'X':
if (longflag)
{
-#ifdef HAVE_LONG_LONG_INT_64
if (longlongflag)
value = va_arg(args, long_long);
else
-#endif
value = va_arg(args, long);
}
else
ch = va_arg(args, int);
dopr_outch(ch);
break;
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'g':
+ case 'G':
+ fvalue = va_arg(args, double);
+ fmtfloat(fvalue, ch, ljust, len, maxwidth, pointflag);
+ break;
case '%':
dopr_outch(ch);
continue;
}
static void
-fmtstr(value, ljust, len, zpad, maxwidth)
-char *value;
-int ljust,
- len,
- zpad,
- maxwidth;
+fmtstr(char *value, int ljust, int len, int zpad, int maxwidth)
{
int padlen,
strlen; /* amount to pad */
}
static void
-fmtnum(value, base, dosign, ljust, len, zpad)
-#ifdef HAVE_LONG_LONG_INT_64
- long_long value;
-#else
- long value;
-#endif
-int base,
- dosign,
- ljust,
- len,
- zpad;
+fmtnum(long_long value, int base, int dosign, int ljust, int len, int zpad)
{
int signvalue = 0;
-#ifdef HAVE_LONG_LONG_INT_64
- ulong_long uvalue;
-#else
- unsigned long uvalue;
-#endif
- char convert[20];
+ ulong_long uvalue;
+ char convert[64];
int place = 0;
int padlen = 0; /* amount to pad */
int caps = 0;
uvalue = (uvalue / (unsigned) base);
} while (uvalue);
convert[place] = 0;
+
+ if (len < 0)
+ {
+ /* this could happen with a "*" width spec */
+ ljust = 1;
+ len = -len;
+ }
padlen = len - place;
if (padlen < 0)
padlen = 0;
}
static void
-dostr(str, cut)
-char *str;
-int cut;
+fmtfloat (double value, char type, int ljust, int len, int precision, int pointflag)
+{
+ char fmt[32];
+ char convert[512];
+ int padlen = 0; /* amount to pad */
+
+ /* we rely on regular C library's sprintf to do the basic conversion */
+ if (pointflag)
+ sprintf(fmt, "%%.%d%c", precision, type);
+ else
+ sprintf(fmt, "%%%c", type);
+ sprintf(convert, fmt, value);
+
+ if (len < 0)
+ {
+ /* this could happen with a "*" width spec */
+ ljust = 1;
+ len = -len;
+ }
+ padlen = len - strlen(convert);
+ if (padlen < 0)
+ padlen = 0;
+ if (ljust)
+ padlen = -padlen;
+
+ while (padlen > 0)
+ {
+ dopr_outch(' ');
+ --padlen;
+ }
+ dostr(convert, 0);
+ while (padlen < 0)
+ {
+ dopr_outch(' ');
+ ++padlen;
+ }
+}
+
+static void
+dostr(char *str, int cut)
{
if (cut)
{
}
static void
-dopr_outch(c)
-int c;
+dopr_outch(int c)
{
#if 0
if (iscntrl(c) && c != '\n' && c != '\t')