]> code.delx.au - gnu-emacs/blobdiff - src/doprnt.c
Merge from emacs-23
[gnu-emacs] / src / doprnt.c
index 205eeea2eb3f9f3ad4139d033d90d0979dcb3515..2e46df2d90811536db3f95460fb1dd4a9448645c 100644 (file)
@@ -33,22 +33,16 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #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.
@@ -60,17 +54,11 @@ static int doprnt1 ();
    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.  */
@@ -108,7 +96,7 @@ doprnt (buffer, bufsize, format, format_end, nargs, args)
       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.  */
@@ -169,8 +157,6 @@ doprnt (buffer, bufsize, format, format_end, nargs, args)
            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))
@@ -181,7 +167,7 @@ doprnt (buffer, bufsize, format, format_end, nargs, args)
                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;
@@ -190,12 +176,8 @@ doprnt (buffer, bufsize, format, format_end, nargs, args)
            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;
@@ -204,11 +186,9 @@ doprnt (buffer, bufsize, format, format_end, nargs, args)
            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;
@@ -237,12 +217,12 @@ doprnt (buffer, bufsize, format, format_end, nargs, args)
                  /* 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)
@@ -258,16 +238,21 @@ doprnt (buffer, bufsize, format, format_end, nargs, args)
              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 */