[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [SCM] gawk branch, stable/printf-rework, updated. gawk-4.1.0-5518-ge7e229d9,
Arnold Robbins <=