[glibc] stdio-common: avoid repeated regexp matches in tst-printf-format.awk

Sam James via Glibc-cvs <[email protected]>
Newsgroups gmane.comp.lib.glibc.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=0cc3f9b3f3f2950844bd41cc8923215cd5d97269

commit 0cc3f9b3f3f2950844bd41cc8923215cd5d97269
Author: Matt Turner <[email protected]>
Date:   Mon Aug 3 21:59:44 2026 -0400

    stdio-common: avoid repeated regexp matches in tst-printf-format.awk
    
    Whether the value is an infinity, a NaN or zero does not change between
    the conversions applied to it, but was determined again for each one.
    Determine it where the value is read.
    
    Also look for the '#' flag with index() before matching the expressions
    that need it, and test the value first where both have to hold.
    
    For the %f conversion for double, in the C locale, as the median of five
    runs:
    
      x86_64, gawk 5.4.1    1.248s -> 1.184s
      x86_64, gawk 5.3.2    0.703s -> 0.708s
      alpha,  gawk 5.4.60    26.6s ->  25.8s
    
    So this only helps with the regular expression engine that gawk 5.4
    brought in; under 5.3.2 it is lost in the noise.  Output and exit status
    are unchanged for the e, f and g conversions for double under both
    gawk versions and both locales.
    
    Reviewed-by: Adhemerval Zanella <[email protected]>

Diff:
---
 stdio-common/tst-printf-format.awk | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/stdio-common/tst-printf-format.awk b/stdio-common/tst-printf-format.awk
index 5d0324c551..57bea12621 100644
--- a/stdio-common/tst-printf-format.awk
+++ b/stdio-common/tst-printf-format.awk
@@ -32,6 +32,9 @@ BEGIN {
   # non-bignum mode unless a sign has been explicitly given.  Keep
   # original 'val' for reporting.
   value = gensub(/^(INF|NAN|inf|nan)/, "+\\1", 1, val)
+  # Neither changes between the conversions applied to this value.
+  value_infnan = value ~ /(INF|NAN|inf|nan)/
+  value_zero = value == 0
   next
 }
 
@@ -52,7 +55,7 @@ BEGIN {
   # Discard the '#' flag with the octal conversion if output starts with
   # 0 in the absence of this flag.  In that case no extra 0 is supposed
   # to be produced, but gawk prepends it anyway.
-  if (format ~ /#.*o/)
+  if (index(format, "#") && format ~ /#.*o/)
     {
       tmpfmt = gensub(/#/, "", "g", format)
       tmpout = sprintf(tmpfmt, value)
@@ -62,7 +65,7 @@ BEGIN {
   # Likewise with the hexadecimal conversion where zero value with the
   # precision of zero is supposed to produce no characters, but gawk
   # outputs 0 instead.
-  else if (format ~ /#.*[Xx]/)
+  else if (index(format, "#") && format ~ /#.*[Xx]/)
     {
       tmpfmt = gensub(/#/, "", "g", format)
       tmpout = sprintf(tmpfmt, value)
@@ -78,7 +81,7 @@ BEGIN {
   # values and reprint the output produced using the string conversion,
   # with the field width carried over and the relevant flags handled by
   # hand.
-  if (format ~ /[EFGefg]/ && value ~ /(INF|NAN|inf|nan)/)
+  if (value_infnan && format ~ /[EFGefg]/)
     {
       minus = format ~ /-/ ? "-" : ""
       sign = value ~ /-/ ? "-" : format ~ /\+/ ? "+" : format ~ / / ? " " : ""
@@ -94,7 +97,7 @@ BEGIN {
   # In that case "+" is always supposed to be produced, but with the
   # precision of zero gawk in the non-bignum mode produces any padding
   # requested only.
-  else if (format ~ /\+.*[di]/ && value == 0)
+  else if (value_zero && format ~ /\+.*[di]/)
     {
       output = gensub(/^( *) $/, format ~ /-/ ? "+\\1" : "\\1+", 1, output)
       output = gensub(/^$/, "+", 1, output)
@@ -103,7 +106,7 @@ BEGIN {
   # conversion for zero value.  In that case at least one " " is
   # supposed to be produced, but with the precision of zero gawk in the
   # non-bignum mode produces nothing.
-  else if (format ~ / .*[di]/ && value == 0)
+  else if (value_zero && format ~ / .*[di]/)
     {
       output = gensub(/^$/, " ", 1, output)
     }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.