[git commit] awk: optimize 'print "no format specs here\n"' case

Denys Vlasenko vda.linux at googlemail.com
Thu Jul 2 03:57:28 UTC 2026


commit: https://git.busybox.net/busybox/commit/?id=133202305105ce57a5a2bde9f57a951152e08f92
branch: https://git.busybox.net/busybox/log/?h=master

function                                             old     new   delta
awk_printf                                          1349    1381     +32

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 editors/awk.c | 46 ++++++++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 20 deletions(-)

diff --git a/editors/awk.c b/editors/awk.c
index 2db19c35e..9a9e79bf8 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -2456,18 +2456,15 @@ static char *awk_printf(node *n, size_t *len)
 		char *use_fmt;
 		const char *diouxX;
 
-		/* Find end of the next format spec, or end of line */
+		/* find end of the next format spec, or end of string */
 		s = fmt_cur;
 //bb_error_msg("s:'%s'", s);
-		while (1) {
-			c = *fmt_cur;
-			if (!c) { /* no percent chars found at all */
-				goto nul;
-			}
-			fmt_cur++;
-			if (c == '%')
-				break;
+		fmt_cur = strchrnul(fmt_cur, '%');
+		c = *fmt_cur;
+		if (!c) { /* no more percent chars */
+			goto nul;
 		}
+		fmt_cur++;
 		/* we are past % in "....%..." */
 		c = *fmt_cur;
 		if (c == '%') { /* "....%%...." */
@@ -2476,19 +2473,29 @@ static char *awk_printf(node *n, size_t *len)
 			goto append_slen; /* append "....%" part verbatim */
 		}
 
-		/* find trailing %FMT letter */
+		/* find trailing letter of the %FMT */
 		starred = 0;
 		after_fmt = fmt_cur;
-		while (!isalpha(c) && c != '\0') {
+		while (1) {
+			if (!c) { /* unterminated "....%FMT" */
+				fmt_cur = after_fmt;
+ nul:
+				slen = fmt_cur - s;
+//bb_error_msg("fmt:'%s', res_buf:'%s'", fmt, res_buf);
+				if (!res_buf) { /* the entire fmt had no (valid) %FMTs? */
+					/* optimize this case (avoid xrealloc+free) */
+					res_buf = fmt;
+					res_len = slen;
+					goto ret;
+				}
+				goto tail; /* append remaining string, exit loop */
+			}
+			if (isalpha(c))
+				break;
 			starred |= (c == '*');
 			c = *++after_fmt;
 		}
-		if (!c) { /* unterminated "....%FMT" */
-			fmt_cur = after_fmt;
- nul:
-			slen = fmt_cur - s;
-			goto tail; /* append remaining string, exit loop */
-		}
+
 		diouxX = strchr("diouxX", c);
 		if (!(diouxX || strchr("cs""eEfFgGaA", c))
 		 || (after_fmt - fmt_cur) >= MAX_FMT_LEN
@@ -2504,7 +2511,6 @@ static char *awk_printf(node *n, size_t *len)
 			slen = fmt_cur - s;
 			goto append_slen;
 		}
-
 		if (*s != '%') {
 			/* the %FMT does not start immediately at the beginning of s */
 			if (starred || diouxX) {
@@ -2534,7 +2540,7 @@ static char *awk_printf(node *n, size_t *len)
 			// printf "Number:%d\n" (one extra char between %FMT and EOL)
 			// printf "String:'%s'\n" (two extra chars)
 			// - we can handle a small tail of literals after %FMT in one pass!
-			// (careful: do not overflow baked_format[] array!)
+			// (careful: they are added to baked_format[] array, do not overflow it!)
 			after_fmt++;
 			if (*after_fmt && *after_fmt != '%')
 				after_fmt++;
@@ -2670,7 +2676,7 @@ static char *awk_printf(node *n, size_t *len)
 	free(fmt);
 	//nvfree(tmpvar, 1);
 #undef TMPVAR
-
+ ret:
 #if ENABLE_FEATURE_AWK_GNU_EXTENSIONS
 	if (len)
 		*len = res_len;


More information about the busybox-cvs mailing list