#include <unistd.h>
#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
#include "lisp.h"
-#ifndef DBL_MAX_10_EXP
-#define DBL_MAX_10_EXP 308 /* IEEE double */
-#endif
-
/* Since we use the macro CHAR_HEAD_P, we have to include this, but
don't have to include others because CHAR_HEAD_P does not contains
another macro. */
#include "character.h"
-static int doprnt1 ();
+#ifndef DBL_MAX_10_EXP
+#define DBL_MAX_10_EXP 308 /* IEEE double */
+#endif
/* Generate output from a format-spec FORMAT,
terminated at position FORMAT_END.
String arguments are passed as C strings.
Integers are passed as C integers. */
-int
-doprnt (buffer, bufsize, format, format_end, nargs, args)
- char *buffer;
- register int bufsize;
- char *format;
- char *format_end;
- int nargs;
- char **args;
+EMACS_INT
+doprnt (char *buffer, register int bufsize, const char *format,
+ const char *format_end, va_list ap)
{
- int cnt = 0; /* Number of arg to gobble next */
- register char *fmt = format; /* Pointer into format string */
+ const char *fmt = format; /* Pointer into format string */
register char *bufptr = buffer; /* Pointer into output buffer.. */
/* Use this for sprintf unless we need something really big. */
if (*fmt == '%') /* Check for a '%' character */
{
unsigned size_bound = 0;
- int width; /* Columns occupied by STRING. */
+ EMACS_INT width; /* Columns occupied by STRING. */
fmt++;
/* Copy this one %-spec into fmtcpy. */
case 'd':
case 'o':
case 'x':
- if (cnt == nargs)
- error ("Not enough arguments for format string");
if (sizeof (int) == sizeof (EMACS_INT))
;
else if (sizeof (long) == sizeof (EMACS_INT))
string++;
else
abort ();
- sprintf (sprintf_buffer, fmtcpy, args[cnt++]);
+ sprintf (sprintf_buffer, fmtcpy, va_arg(ap, char *));
/* Now copy into final output, truncating as nec. */
string = (unsigned char *) sprintf_buffer;
goto doit;
case 'e':
case 'g':
{
- union { double d; char *half[2]; } u;
- if (cnt + 1 == nargs)
- error ("Not enough arguments for format string");
- u.half[0] = args[cnt++];
- u.half[1] = args[cnt++];
- sprintf (sprintf_buffer, fmtcpy, u.d);
+ double d = va_arg(ap, double);
+ sprintf (sprintf_buffer, fmtcpy, d);
/* Now copy into final output, truncating as nec. */
string = (unsigned char *) sprintf_buffer;
goto doit;
case 'S':
string[-1] = 's';
case 's':
- if (cnt == nargs)
- error ("Not enough arguments for format string");
if (fmtcpy[1] != 's')
minlen = atoi (&fmtcpy[1]);
- string = (unsigned char *) args[cnt++];
+ string = va_arg(ap, unsigned char *);
tem = strlen (string);
width = strwidth (string, tem);
goto doit1;
/* Truncate the string at character boundary. */
tem = bufsize;
while (!CHAR_HEAD_P (string[tem - 1])) tem--;
- bcopy (string, bufptr, tem);
+ memcpy (bufptr, string, tem);
/* We must calculate WIDTH again. */
width = strwidth (bufptr, tem);
}
else
- bcopy (string, bufptr, tem);
+ memcpy (bufptr, string, tem);
bufptr += tem;
bufsize -= tem;
if (minlen < 0)
continue;
case 'c':
- if (cnt == nargs)
- error ("Not enough arguments for format string");
- tem = CHAR_STRING ((int) (EMACS_INT) args[cnt], charbuf);
- string = charbuf;
- cnt++;
- string[tem] = 0;
- width = strwidth (string, tem);
- if (fmtcpy[1] != 'c')
- minlen = atoi (&fmtcpy[1]);
- goto doit1;
+ {
+ /* Sometimes for %c we pass a char, which would widen
+ to int. Sometimes we pass XFASTINT() or XINT()
+ values, which would be EMACS_INT. Let's hope that
+ both are passed the same way, otherwise we'll need
+ to rewrite callers. */
+ EMACS_INT chr = va_arg(ap, EMACS_INT);
+ tem = CHAR_STRING ((int) chr, charbuf);
+ string = charbuf;
+ string[tem] = 0;
+ width = strwidth (string, tem);
+ if (fmtcpy[1] != 'c')
+ minlen = atoi (&fmtcpy[1]);
+ goto doit1;
+ }
case '%':
fmt--; /* Drop thru and this % will be treated as normal */