# patch by Thomas E. Dickey <dickey@invisible-island.net>
# created  Thu Oct 11 20:26:15 UTC 2007
# ------------------------------------------------------------------------------
# display.c |   84 ++++++++++++++++++++++++++++++++++++------------------------
# 1 file changed, 51 insertions(+), 33 deletions(-)
# ------------------------------------------------------------------------------
Index: display.c
Prereq:  1.424 
--- vile-9.5r+/display.c	2007-05-28 14:03:37.000000000 +0000
+++ vile-9.5r-varargs/display.c	2007-10-11 20:23:24.000000000 +0000
@@ -194,34 +194,36 @@
  * appropriate width or limit.
  */
 static void
-decode_length(const char **fmt, va_list *app, int *result)
+decode_length(const char **fmt, int *result)
 {
     int c = **fmt;
     int value = 0;
     int found = FALSE;
 
-    if (c == '*') {
-	value = va_arg(*app, int);
+    while (isDigit(c)) {
+	value = (value * 10) + c - '0';
 	found = TRUE;
 	(*fmt)++;
-    } else {
-	while (isDigit(c)) {
-	    value = (value * 10) + c - '0';
-	    found = TRUE;
-	    (*fmt)++;
-	    c = **fmt;
-	}
+	c = **fmt;
     }
     if (found)
 	*result = value;
 }
 
+#define DecodeLength(fmt, app, result) \
+	if (*fmt == '*') { \
+	    result = va_arg(app, int); \
+	    ++fmt; \
+	} else { \
+	    decode_length(&fmt, &result); \
+	}
+
 /*
  * Generic string formatter.  Takes printf-like args, and calls
  * the global function (*dfoutfn)(c) for each c
  */
 static void
-dofmt(const char *fmt, va_list *app)
+dofmt(const char *fmt, va_list app2)
 {
     int c;			/* current char in format string */
     int the_width;
@@ -232,9 +234,11 @@
     ULONG ulong_value;
     int int_value;
     long long_value;
+    va_list app;
     OutFunc outfunc = dfoutfn;	/* local copy, for recursion */
 
     TRACE2(("dofmt fmt='%s'\n", visible_buff(fmt, strlen(fmt), FALSE)));
+    va_copy(app, app2);
     while ((c = *fmt++) != 0) {
 	if (c != '%') {
 	    (*outfunc) (c);
@@ -242,10 +246,10 @@
 	}
 	the_width = -1;
 	islong = FALSE;
-	decode_length(&fmt, app, &the_width);
+	DecodeLength(fmt, app, the_width);
 	if (*fmt == '.') {
 	    ++fmt;
-	    decode_length(&fmt, app, &the_limit);
+	    DecodeLength(fmt, app, the_limit);
 	    if (the_width < 0)
 		the_width = the_limit;
 	} else {
@@ -264,13 +268,13 @@
 	    n = 0;
 	    break;
 	case 'c':
-	    (*outfunc) (va_arg(*app, int));
+	    (*outfunc) (va_arg(app, int));
 	    n = 1;
 	    break;
 
 	case 'd':
 	    if (!islong) {
-		int_value = va_arg(*app, int);
+		int_value = va_arg(app, int);
 		if (int_value < 0) {
 		    if (int_value < vMAXNEG) {
 			n = dfputs(outfunc, "OVFL");
@@ -282,7 +286,7 @@
 		n = dfputi(outfunc, (UINT) int_value, 10);
 		break;
 	    }
-	    long_value = va_arg(*app, long);
+	    long_value = va_arg(app, long);
 	    if (long_value < 0) {
 		long_value = -long_value;
 		(*outfunc) ('-');
@@ -292,34 +296,34 @@
 
 	case 'u':
 	    if (!islong) {
-		uint_value = va_arg(*app, UINT);
+		uint_value = va_arg(app, UINT);
 		n = dfputi(outfunc, uint_value, 10);
 		break;
 	    }
-	    ulong_value = va_arg(*app, ULONG);
+	    ulong_value = va_arg(app, ULONG);
 	    n = dfputli(outfunc, ulong_value, 10);
 	    break;
 
 	case 'o':
-	    n = dfputi(outfunc, va_arg(*app, UINT), 8);
+	    n = dfputi(outfunc, va_arg(app, UINT), 8);
 	    break;
 
 	case 'x':
 	    if (!islong) {
-		n = dfputi(outfunc, va_arg(*app, UINT), 16);
+		n = dfputi(outfunc, va_arg(app, UINT), 16);
 		break;
 	    }
 	    /* FALLTHROUGH */
 	case 'X':
-	    n = dfputli(outfunc, va_arg(*app, ULONG), 16);
+	    n = dfputli(outfunc, va_arg(app, ULONG), 16);
 	    break;
 
 	case 's':
-	    n = dfputsn(outfunc, va_arg(*app, char *), the_width, the_limit);
+	    n = dfputsn(outfunc, va_arg(app, char *), the_width, the_limit);
 	    break;
 
 	case 'f':
-	    n = dfputf(outfunc, va_arg(*app, double));
+	    n = dfputf(outfunc, va_arg(app, double));
 	    break;
 
 	default:
@@ -332,6 +336,7 @@
 	    (*outfunc) (' ');
 	}
     }
+    va_end(app);
 }
 
 /******************************************************************************/
@@ -3624,9 +3629,11 @@
  * line" flag TRUE.
  */
 static void
-mlmsg(const char *fmt, va_list *app)
+mlmsg(const char *fmt, va_list app2)
 {
     static int recur;
+
+    va_list app;
     int end_at;
 #if DISP_NTWIN
     int cursor_state = 0;
@@ -3671,7 +3678,10 @@
 	} else
 #endif
 	    dfoutfn = mlsavec;
+
+	va_copy(app, app2);
 	dofmt(fmt, app);
+	va_end(app);
     } else {
 	beginDisplay();
 
@@ -3691,8 +3701,13 @@
 	    dfoutfn = kbd_putc;
 
 	if (*fmt != '\n') {
+
 	    kbd_erase_to_end(0);
+
+	    va_copy(app, app2);
 	    dofmt(fmt, app);
+	    va_end(app);
+
 	    kbd_expand = 0;
 
 	    /* if we can, erase to the end of screen */
@@ -3736,7 +3751,7 @@
 	    return;
 	}
 	va_start(ap, fmt);
-	mlmsg(fmt, &ap);
+	mlmsg(fmt, ap);
 	va_end(ap);
     }
 }
@@ -3751,7 +3766,7 @@
     if (fmt != 0) {
 	va_list ap;
 	va_start(ap, fmt);
-	mlmsg(fmt, &ap);
+	mlmsg(fmt, ap);
 	va_end(ap);
     }
 }
@@ -3769,7 +3784,7 @@
 	}
 	sgarbf = FALSE;
 	va_start(ap, fmt);
-	mlmsg(fmt, &ap);
+	mlmsg(fmt, ap);
 	va_end(ap);
 	sgarbf = osgarbf;
     }
@@ -3785,7 +3800,7 @@
 	va_list ap;		/* ptr to current data field */
 	va_start(ap, fmt);
 	lsprintf(temp, "[press ^G to continue] %s", fmt);
-	mlmsg(temp, &ap);
+	mlmsg(temp, ap);
 	va_end(ap);
 	beginDisplay();
 	while (term.getch() != '\007') {
@@ -3838,7 +3853,7 @@
 {
     va_list ap;
     va_start(ap, fmt);
-    mlmsg(fmt, &ap);
+    mlmsg(fmt, ap);
     va_end(ap);
     kbd_alarm();
 }
@@ -3870,7 +3885,7 @@
 
 	dfoutfn = lspputc;
 
-	dofmt(fmt, &ap);
+	dofmt(fmt, ap);
 	va_end(ap);
 
 	*lsp = EOS;
@@ -3922,7 +3937,7 @@
     dfoutfn = bputc;
 
     va_start(ap, fmt);
-    dofmt(fmt, &ap);
+    dofmt(fmt, ap);
     va_end(ap);
 }
 
@@ -3931,8 +3946,9 @@
  * written.
  */
 LINE *
-b2vprintf(BUFFER *bp, const char *fmt, va_list ap)
+b2vprintf(BUFFER *bp, const char *fmt, va_list app2)
 {
+    va_list app;
     LINE *result = 0;
     WINDOW *save_wp;
     BUFFER *save_bp = curbp;
@@ -3950,7 +3966,9 @@
 	(void) gotoeob(FALSE, 1);
 	(void) gotoeol(FALSE, 1);
 
-	dofmt(fmt, &ap);
+	va_copy(app, app2);
+	dofmt(fmt, app);
+	va_end(app);
 
 	result = lback(DOT.l);
 
