shithub: trueawk

Download patch

ref: a96aebbbd601a619318312e835b76c3cd7816518
parent: af86dacfad85857b2ea9fa95150ddd8c671695ed
author: zoulasc <zoulasc@users.noreply.github.com>
date: Tue Dec 10 21:17:34 EST 2019

Fix printf format conversions. (#59)

Further simplify printf % parsing by eating the length specifiers
during the copy phase, and substitute 'j' when finalizing the format.
Add some more tests for this.

--- a/run.c
+++ b/run.c
@@ -855,7 +855,12 @@
 		for (t = fmt; (*t++ = *s) != '\0'; s++) {
 			if (!adjbuf(&fmt, &fmtsz, MAXNUMSIZE+1+t-fmt, recsize, &t, "format3"))
 				FATAL("format item %.30s... ran format() out of memory", os);
-			if (isalpha((uschar)*s) && *s != 'l' && *s != 'h' && *s != 'L')
+			/* Ignore size specifiers */
+			if (strchr("hjLlqtz", *s)) {
+				t--;
+				continue;
+			}
+			if (isalpha((uschar)*s))
 				break;	/* the ansi panoply */
 			if (*s == '$') {
 				FATAL("'$' not permitted in awk formats");
@@ -889,15 +894,8 @@
 		case 'f': case 'e': case 'g': case 'E': case 'G':
 			flag = 'f';
 			break;
-		case 'd': case 'i':
-			flag = 'd';
-			if(*(s-1) == 'l') break;
-			*(t-1) = 'j';
-			*t = 'd';
-			*++t = '\0';
-			break;
-		case 'o': case 'x': case 'X': case 'u':
-			flag = *(s-1) == 'l' ? 'd' : 'u';
+		case 'd': case 'i': case 'o': case 'x': case 'X': case 'u':
+			flag = *s == 'd' || *s == 'i' ? 'd' : 'u';
 			*(t-1) = 'j';
 			*t = *s;
 			*++t = '\0';
--- a/testdir/T.expr
+++ b/testdir/T.expr
@@ -167,15 +167,15 @@
 2	1	ah b
 3	1	ah  b
 
-try { printf("%d %ld\n", $1, $1) }
-1	1 1
-10	10 10
-10000	10000 10000
+try { printf("%d %ld %lld %zd %jd %hd %hhd\n", $1, $1, $1, $1, $1, $1, $1) }
+1	1 1 1 1 1 1 1
+10	10 10 10 10 10 10 10
+10000	10000 10000 10000 10000 10000 10000 10000
 
-try { printf("%x %lx\n", $1, $1) }
-1	1 1
-10	a a
-10000	2710 2710
+try { printf("%x %lx %llx %zx %jx %hx %hhx\n", $1, $1, $1, $1, $1, $1, $1) }
+1	1 1 1 1 1 1 1
+10	a a a a a a a
+10000	2710 2710 2710 2710 2710 2710 2710
 
 try { if ($1 ~ $2) print 1; else print 0 }
 a	\141	1
--