gawk-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] gawk branch, stable/printf-rework, updated. gawk-4.1.0-5518-ge7e22


From: Arnold Robbins
Subject: [SCM] gawk branch, stable/printf-rework, updated. gawk-4.1.0-5518-ge7e229d9
Date: Tue, 23 Jul 2024 15:31:08 -0400 (EDT)

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gawk".

The branch, stable/printf-rework has been updated
       via  e7e229d94e0b7f31f53faa8956888f82bb4dbb97 (commit)
      from  7731d9fd9fa4d0a27e15c8da5cbd1e4d3a515b0f (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.sv.gnu.org/cgit/gawk.git/commit/?id=e7e229d94e0b7f31f53faa8956888f82bb4dbb97

commit e7e229d94e0b7f31f53faa8956888f82bb4dbb97
Author: Arnold D. Robbins <arnold@skeeve.com>
Date:   Tue Jul 23 22:30:48 2024 +0300

    Printf refactoring finished!

diff --git a/ChangeLog b/ChangeLog
index 915fe065..7d915440 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2024-07-23         Arnold D. Robbins     <arnold@skeeve.com>
+
+       Finish cleaning up the printf refactoring. All tests run, both
+       regular and -M. Test suite is valgrind clean!
+
+       Summary of changes:
+       * printf.c: New file.
+       (format_args): Moved here and renamed from format_tree.  Considerably
+       simplified by moving code out into new routines.
+       (struct flags): New struct.
+       (add_thousands, do_printf, do_sprintf, format_nan_inf, mbc_byte_count,
+       mbc_char_count, out_of_range, printf_common, reverse): Moved to here.
+       (add_alt_format, add_plus_or_space_and_fill, adjust_flags, 
compute_zero_flag,
+       fill_to_field_width, format_float, format_integer_digits,
+       format_mpg_integer_digits, format_out_of_range, format_signed_integer,
+       format_unsigned_integer, zero_fill_to_precision): New routines.
+
 2024-07-21         Arnold D. Robbins     <arnold@skeeve.com>
 
        * printf.c: Simplify printing of signed integers; move several
diff --git a/printf.c b/printf.c
index 262edaab..648c9f38 100644
--- a/printf.c
+++ b/printf.c
@@ -64,6 +64,7 @@ static char *format_out_of_range(NODE *arg, struct flags 
*flags);
 static char *fill_to_field_width(char *startval, struct flags *flags, int 
fill);
 static char *add_plus_or_space_and_fill(char *number_value, struct flags 
*flags);
 static char *zero_fill_to_precision(char *number_value, struct flags *flags);
+static char *add_alt_format(char *number_value, struct flags *flags);
 
 #ifdef HAVE_MPFR
 
@@ -1082,203 +1083,6 @@ format_signed_integer(NODE *arg, struct flags *flags)
        return buf1;
 }
 
-#if 0
-/* format_signed_integer --- format a signed integer (decimal) value. caller 
frees return value */
-
-static const char *
-format_signed_integer0(NODE *arg, struct flags *flags)
-{
-       const char *number_value;
-       size_t val_len;
-       char *buf1 = NULL;
-       char fill = ' ';
-       bool used_float = false;
-
-       if (out_of_range(arg))
-               return format_out_of_range(arg, flags);
-
-       if (is_mpg_integer(arg) || is_mpg_float(arg))
-               number_value = format_mpg_integer_digits(arg, flags, & 
used_float);
-       else
-               number_value = format_integer_digits(arg, flags, & used_float); 
// just digits, possible leading '-'
-
-       if (used_float)
-               return number_value;
-
-       val_len = strlen(number_value);
-
-       // We now have the initial *integer* decimalvalue in hand.
-       // If it's decimal, we've added commas if appropriate. If it's negative
-       // and decimal, it has a minus sign.
-       
-       // The next step is deal with the rest of the printf flags.
-
-       // add more output digits to match the precision
-       if (flags->have_prec && flags->precision == 0 && is_zero(arg)) {
-               int fw = flags->field_width;
-               char *cp;
-
-               /*
-                * No actual value. But if there is plus or space or wide
-                * field width or left just, we have to handle those. Bleah.
-                */
-               free((void *) number_value);
-
-               emalloc(buf1, char *, flags->field_width + (flags->plus || 
flags->space) + 1,
-                               "format_signed_integer");
-               cp = buf1;
-               if (flags->left_just) {
-                       if (flags->plus) {
-                               *cp++ = '+';
-                               fw--;
-                       } else if (flags->space) {
-                               *cp++ = ' ';
-                               fw--;
-                       }
-                       for (; fw > 0; fw--)
-                               *cp++ = ' ';
-                       *cp = '\0';
-               } else if (fw > 0 || flags->plus || flags->space) {
-                       char final = ' ';
-                       if (flags->plus)
-                               final = '+';
-
-                       for (fw--; fw > 0; fw--)
-                               *cp++ = ' ';
-                       *cp++ = final;
-                       *cp = '\0';
-               } else
-                       buf1[0] = '\0';
-
-               return buf1;
-       } else if (flags->have_prec && val_len < flags->precision) {
-               char *cp;
-               char *buf2;
-               const char *src;
-               int prec = flags->precision;
-               int count = flags->precision + flags->field_width + 1 + 
(flags->plus || flags->space);
-               int fw = flags->field_width;
-
-               emalloc(buf1, char *, count, "format_signed_integer");
-               cp = buf1;
-               src = number_value;
-               if (number_value[0] == '-') {
-                       *cp++ = '-';
-                       src++;
-                       val_len--;
-               } else if (flags->plus) {
-                       *cp++ = '+';
-               } else if (flags->space) {
-                       *cp++ = ' ';
-               }
-
-               for (; prec > val_len; prec--)
-                       *cp++ = '0';
-
-               strcpy(cp, src);
-               free((void *) number_value);
-               val_len = strlen(buf1);
-
-               if (fw > val_len) {
-                       emalloc(buf2, char *, count, "format_signed_integer");
-                       cp = buf2;
-                       for (; fw > val_len; fw--)
-                               *cp++ = fill;
-                       strcpy(cp, buf1);
-                       free((void *) buf1);
-
-                       buf1 = buf2;
-               }
-
-               return buf1;
-       } else if (flags->field_width > val_len) {
-               char *cp;
-               const char *src;
-               int fw = flags->field_width;
-
-               emalloc(buf1, char *, flags->field_width + 1 + (flags->plus || 
flags->space),
-                               "format_signed_integer");
-
-               if (compute_zero_flag(flags))
-                       fill = '0';
-
-               cp = buf1;
-               src = number_value;
-
-               if (flags->left_just) {
-                       if (number_value[0] == '-') {
-                               *cp++ = '-';
-                               src++;
-                               fw--;
-                               val_len--;
-                       } else if (flags->plus) {
-                               *cp++ = '+';
-                               fw--;
-                       } else if (flags->space) {
-                               *cp++ = ' ';
-                               fw--;
-                       }
-                       strcpy(cp, src);
-                       cp += val_len;
-                       for (; fw > val_len; fw--)
-                               *cp++ = fill;
-                       *cp = '\0';
-               } else {
-                       strcpy(buf1, number_value);
-                       reverse(buf1);
-                       bool negative = (buf1[val_len - 1] == '-');
-                       cp = buf1 + val_len;
-
-                       if (negative) {
-                               *cp = '\0';     // remove minus temporarily
-                               val_len--;
-                       }
-
-                       if (fill == '0') {
-                               // leave room for the extra character
-                               int stop = val_len + (negative || flags->plus 
|| flags->space);
-
-                               for (; fw > stop; fw--)
-                                       *cp++ = fill;
-                       }
-
-                       if (negative) {
-                               *cp++ = '-';
-                               fw--;
-                       } else if (flags->plus) {
-                               *cp++ = '+';
-                               fw--;
-                       } else if (flags->space) {
-                               *cp++ = ' ';
-                               fw--;
-                       }
-
-                       if (fill == ' ') {
-                               for (; fw > val_len; fw--)
-                                       *cp++ = fill;
-                       }
-                       *cp = '\0';
-
-                       reverse(buf1);
-               }
-
-               free((void *) number_value);
-       } else if (flags->plus || flags->space) {
-               emalloc(buf1, char *, val_len + 2, "format_signed_integer");
-               if (flags->plus) {
-                       sprintf(buf1, "+%s", number_value);
-               } else {
-                       sprintf(buf1, " %s", number_value);
-               }
-
-               free((void *) number_value);
-       } else
-               buf1 = number_value;
-
-       return buf1;
-}
-#endif
-
 /* format_unsigned_integer --- format an unsigned integer value. caller frees 
return value */
 
 static char *
@@ -1286,7 +1090,6 @@ format_unsigned_integer(NODE *arg, struct flags *flags)
 {
        char *number_value;
        char *buf1 = NULL;
-       char *buf2 = NULL;
        char fill = ' ';
        size_t val_len;
        bool used_float = false;
@@ -1309,273 +1112,50 @@ format_unsigned_integer(NODE *arg, struct flags *flags)
        
        // The next step is deal with the rest of the printf flags.
 
-       // Add more output digits to match the precision
-       if (flags->have_prec) {
-               if (flags->precision == 0 && is_zero(arg) && flags->field_width 
== 0 && ! flags->alt) {
-                       free((void *) number_value);
-                       return estrdup("", 1);
-               }
-
-               if (val_len < flags->precision) {
-                       char *cp;
-                       const char *src;
-                       int prec = flags->precision;
-
-                       // plus and space flags are only for signed conversions
-                       emalloc(buf1, char *, flags->precision + 1,
-                                       "format_unsigned_integer");
-                       cp = buf1;
-                       src = number_value;
-
-                       for (; prec > val_len; prec--)
-                               *cp++ = '0';
-
-                       strcpy(cp, src);
-                       free((void *) number_value);
-               } else if (flags->have_prec) {
-                       if (flags->base == 8) {
-                               if (number_value[0] != '0') {
-                                       emalloc(buf1, char *, val_len + 2, 
"format_unsigned_integer");
-                                       sprintf(buf1, "0%s", number_value);
-                                       free((void *) number_value);
-                               } else
-                                       buf1 = number_value;
-                       } else {
-                               free((void *) number_value);
-                               if (flags->plus)
-                                       buf1 = estrdup("+", 1);
-                               else if (flags->space)
-                                       buf1 = estrdup(" ", 1);
-                               else
-                                       buf1 = estrdup("", 1);
-                       }
-               } else
-                       buf1 = number_value;
-
-               val_len = strlen(buf1);
-       } else if (flags->field_width > val_len) { // pad the field if necessary
-               // when there's a precision, field width padding with zeros is 
not done.
-               char *cp;
-               const char *src;
-               int fw = flags->field_width;
-
-               emalloc(buf1, char *, flags->field_width + 3, 
"format_unsigned_integer");
-
-               cp = buf1;
-               src = number_value;
-
-               if (compute_zero_flag(flags))
-                       fill = '0';
-
-               if (flags->alt) {
-                       if (flags->base == 16 && ! is_zero(arg)) {
-                               if (fill == '0') {
-                                       *cp++ = '0';
-                                       *cp++ = flags->format;
-                                       fw -= 2;
-                                       for (; fw > val_len; fw--)
-                                               *cp++ = fill;
-                               } else {
-                                       fw -= 2;
-                                       *cp++ = '0';
-                                       *cp++ = flags->format;
-                               }
-                       } else if (flags->base == 8 && src[0] != '0') {
-                               *cp++ = '0';
-                       }
-
-                       strcpy(cp, src);
-                       free((void *) number_value);
-                       flags->alt = false;
-               } else
-                       buf1 = number_value;
+       if (flags->have_prec && flags->precision == 0 && is_zero(arg)
+               && (! flags->alt || flags->base != 8)) {
+                       number_value[0] = '\0';
 
-               val_len = strlen(buf1);
+                       if (flags->field_width > 0)
+                               number_value = 
fill_to_field_width(number_value, flags, ' ');
 
-               if (val_len < flags->field_width) {
-                       buf1 = fill_to_field_width(buf1, flags, fill);
-                       val_len = strlen(buf1);
-               }
-       } else
-               buf1 = number_value;
-
-       if (flags->alt && ! is_zero(arg)) {
-               // handle the alt flag
-               emalloc(buf2, char *, val_len + 3, "format_unsigned_integer");
-
-               if (flags->base == 16) {
-                       sprintf(buf2, "0%c%s", flags->format, buf1);
-               } else if (flags->base == 8) {
-                       if (buf1[0] != '0')
-                               sprintf(buf2, "0%s", buf1);
-                       else
-                               strcpy(buf2, buf1);
-               }
-               free((void *) buf1);
-               buf1 = buf2;
-               val_len = strlen(buf1);
+                       return number_value;
        }
 
-       if (is_zero(arg) && (flags->plus || flags->space)) {
-               emalloc(buf2, char *, val_len + 3, "format_unsigned_integer");
-               strcpy(buf2, " ");
-               free((void *) buf1);
-               buf1 = buf2;
+       // Add more output digits to match the precision
+       if (flags->have_prec && val_len < flags->precision) {
+               // we ignore flags->alt when there's a precision
+               buf1 = zero_fill_to_precision(number_value, flags);     // 
frees number_value
                val_len = strlen(buf1);
+               number_value = buf1;
        }
 
-       return buf1;
-}
-
-#if 0
-/* format_unsigned_integer --- format an unsigned integer value. caller frees 
return value */
-
-static char *
-format_unsigned_integer0(NODE *arg, struct flags *flags)
-{
-       char *number_value;
-       char *buf1 = NULL;
-       char *buf2 = NULL;
-       char fill = ' ';
-       size_t val_len;
-       bool used_float = false;
-
-       if (out_of_range(arg))
-               return format_out_of_range(arg, flags);
-
-       if (is_mpg_integer(arg) || is_mpg_float(arg))
-               number_value = format_mpg_integer_digits(arg, flags, & 
used_float);
-       else
-               number_value = format_integer_digits(arg, flags, & used_float); 
// just digits
-
-       if (used_float)
-               return number_value;
-
-       val_len = strlen(number_value);
-
-       // We now have the initial *integer* decimal, octal, or hex value in 
hand.
-       // If it's decimal, we've added commas if appropriate.
-       
-       // The next step is deal with the rest of the printf flags.
-
-       // Add more output digits to match the precision
-       if (flags->have_prec) {
-               if (flags->precision == 0 && is_zero(arg) && flags->field_width 
== 0 && ! flags->alt) {
-                       free((void *) number_value);
-                       return estrdup("", 1);
-               }
-
-               if (val_len < flags->precision) {
-                       char *cp;
-                       const char *src;
-                       int prec = flags->precision;
-
-                       // plus and space flags are only for signed conversions
-                       emalloc(buf1, char *, flags->precision + 1,
-                                       "format_unsigned_integer");
-                       cp = buf1;
-                       src = number_value;
-
-                       for (; prec > val_len; prec--)
-                               *cp++ = '0';
-
-                       strcpy(cp, src);
-                       free((void *) number_value);
-               } else if (flags->have_prec) {
-                       if (flags->base == 8) {
-                               if (number_value[0] != '0') {
-                                       emalloc(buf1, char *, val_len + 2, 
"format_unsigned_integer");
-                                       sprintf(buf1, "0%s", number_value);
-                                       free((void *) number_value);
-                               } else
-                                       buf1 = (char *) number_value;
-                       } else {
-                               free((void *) number_value);
-                               if (flags->plus)
-                                       buf1 = estrdup("+", 1);
-                               else if (flags->space)
-                                       buf1 = estrdup(" ", 1);
-                               else
-                                       buf1 = estrdup("", 1);
-                       }
-               } else
-                       buf1 = (char *) number_value;
+       if (flags->alt && flags->base != 10 && ! is_zero(arg)) {
+               buf1 = add_alt_format(number_value, flags);
+               flags->alt = false;
+       } else {
+               buf1 = number_value;
+       }
+       val_len = strlen(buf1);
 
-               val_len = strlen(buf1);
-       } else if (flags->field_width > val_len) { // pad the field if necessary
+       // continue with buf1
+       if (flags->field_width > val_len) {
+               // pad the field if necessary
                // when there's a precision, field width padding with zeros is 
not done.
-               char *cp;
-               const char *src;
-               int fw = flags->field_width;
-
-               emalloc(buf1, char *, flags->field_width + 3, 
"format_unsigned_integer");
-
-               cp = buf1;
-               src = number_value;
-
                if (compute_zero_flag(flags))
                        fill = '0';
 
-               if (flags->alt) {
-                       if (flags->base == 16 && ! is_zero(arg)) {
-                               if (fill == '0') {
-                                       *cp++ = '0';
-                                       *cp++ = flags->format;
-                                       fw -= 2;
-                                       for (; fw > val_len; fw--)
-                                               *cp++ = fill;
-                               } else {
-                                       fw -= 2;
-                                       *cp++ = '0';
-                                       *cp++ = flags->format;
-                               }
-                       } else if (flags->base == 8 && src[0] != '0') {
-                               *cp++ = '0';
-                       }
-
-                       strcpy(cp, src);
-                       free((void *) number_value);
-                       flags->alt = false;
-               } else
-                       buf1 = number_value;
-
-               val_len = strlen(buf1);
-
-               if (val_len < flags->field_width) {
-                       buf1 = fill_to_field_width(buf1, flags, fill);
-                       val_len = strlen(buf1);
-               }
-       } else
-               buf1 = number_value;
-
-       if (flags->alt && ! is_zero(arg)) {
-               // handle the alt flag
-               emalloc(buf2, char *, val_len + 3, "format_unsigned_integer");
-
-               if (flags->base == 16) {
-                       sprintf(buf2, "0%c%s", flags->format, buf1);
-               } else if (flags->base == 8) {
-                       if (buf1[0] != '0')
-                               sprintf(buf2, "0%s", buf1);
-                       else
-                               strcpy(buf2, buf1);
-               }
-               free((void *) buf1);
-               buf1 = buf2;
+               buf1 = fill_to_field_width(buf1, flags, fill);
                val_len = strlen(buf1);
        }
 
-       if (is_zero(arg) && (flags->plus || flags->space)) {
-               emalloc(buf2, char *, val_len + 3, "format_unsigned_integer");
-               strcpy(buf2, " ");
-               free((void *) buf1);
-               buf1 = buf2;
+       if (flags->alt && ! is_zero(arg)) {
+               buf1 = add_alt_format(buf1, flags);
                val_len = strlen(buf1);
        }
 
        return buf1;
 }
-#endif
 
 /* format_out_of_range --- format an out of range value as %g. caller frees 
return value */
 
@@ -2084,6 +1664,9 @@ add_thousands(const char *original)
 
 #if defined(HAVE_LOCALE_H)
        new_len = orig_len + (orig_len * strlen(loc.thousands_sep)) + 1;        
// worst case
+       erealloc(newbuf, char *, new_len, "add_thousands");
+       memset(newbuf, '\0', new_len);
+
        src = original + strlen(original) - 1;
        dest = newbuf;
 
@@ -2145,7 +1728,7 @@ fill_to_field_width(char *startval, struct flags *flags, 
int fill)
        if (l >= fw)    // nothing to do
                return startval;
 
-       emalloc(buf, char *, l + 1, "fill_to_field_width");
+       emalloc(buf, char *, fw + 1, "fill_to_field_width");
        cp = buf;
 
        if (flags->left_just) {
@@ -2154,6 +1737,7 @@ fill_to_field_width(char *startval, struct flags *flags, 
int fill)
                fw -= l;
                for (; fw > 0; fw--)
                        *cp++ = fill;
+               *cp = '\0';
        } else {
                for (; fw > l; fw--)
                        *cp++ = fill;
@@ -2252,3 +1836,52 @@ zero_fill_to_precision(char *number_value, struct flags 
*flags)
 
        return buf1;
 }
+
+/* add_alt_format --- deal with zero padding and the alt flag */
+
+static char *
+add_alt_format(char *number_value, struct flags *flags)
+{
+       int fw;
+       bool zero_flag;
+       char *buf, *cp;
+       size_t buflen;
+       size_t val_len = strlen(number_value);
+
+       assert(flags->alt);
+       assert(flags->base != 10);
+
+       zero_flag = compute_zero_flag(flags);
+
+       buflen = flags->field_width;
+       if (buflen < val_len)
+               buflen = val_len;
+       buflen += 3;
+
+       emalloc(buf, char *, buflen, "add_alt_format");
+       cp = buf;
+
+       fw = flags->field_width;
+       if (flags->base == 16) {
+               *cp++ = '0';
+               *cp++ = flags->format;
+               fw -= 2;
+
+               if (zero_flag) {
+                       fw -= val_len;
+                       for (; fw > 0; fw--)
+                               *cp++ = '0';
+                       // fall through
+               }
+
+               strcpy(cp, number_value);
+       } else if (number_value[0] != '0') {
+               sprintf(buf, "0%s", number_value);
+       } else {
+               strcpy(buf, number_value);
+       }
+
+       free((void *) number_value);
+
+       return buf;
+}
diff --git a/test/ChangeLog b/test/ChangeLog
index 2daec81a..478199af 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,8 @@
+2024-07-23         Arnold D. Robbins     <arnold@skeeve.com>
+
+       * printf-corners.awk, printf-corners.ok, printf-corners-mpfr: Add
+       an additional test case.
+
 2024-07-05         Maciej W. Rozycki     <macro@redhat.com>
 
        * printf-corners.awk, printf-corners.ok, printf-corners-mpfr: Remove
diff --git a/test/printf-corners-mpfr.ok b/test/printf-corners-mpfr.ok
index 7ea6b4c6..d9fa07bc 100644
--- a/test/printf-corners-mpfr.ok
+++ b/test/printf-corners-mpfr.ok
@@ -76,3 +76,4 @@
 <                -INF>
 <                -inf>
 <                -INF>
+<   00045>
diff --git a/test/printf-corners.awk b/test/printf-corners.awk
index ca949c68..b1f991ed 100644
--- a/test/printf-corners.awk
+++ b/test/printf-corners.awk
@@ -77,4 +77,5 @@ BEGIN {
        printf "<%20.20G>\n", "-inf"    # "                -INF"
        printf "<%20.20a>\n", "-inf"    # "                -inf"
        printf "<%20.20A>\n", "-inf"    # "                -INF"
+       printf "<%3$*2$.*1$d>\n", 5, 8, 45      # "   00045"
 }
diff --git a/test/printf-corners.ok b/test/printf-corners.ok
index 7ea6b4c6..d9fa07bc 100644
--- a/test/printf-corners.ok
+++ b/test/printf-corners.ok
@@ -76,3 +76,4 @@
 <                -INF>
 <                -inf>
 <                -INF>
+<   00045>

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                   |  17 ++
 printf.c                    | 525 +++++++-------------------------------------
 test/ChangeLog              |   5 +
 test/printf-corners-mpfr.ok |   1 +
 test/printf-corners.awk     |   1 +
 test/printf-corners.ok      |   1 +
 6 files changed, 104 insertions(+), 446 deletions(-)


hooks/post-receive
-- 
gawk



reply via email to

[Prev in Thread] Current Thread [Next in Thread]