summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2015-03-17 22:46:11 +0200
committerArnold D. Robbins <arnold@skeeve.com>2015-03-17 22:46:11 +0200
commitcffd09247c1681fbf3d5cad5253b3199704f83e7 (patch)
tree5341be1b30a9efa371d1802a5bb73aba5e447294
parent1b047a42077ca58eeeaa93e0561c0b589350702b (diff)
downloadgawk-cffd09247c1681fbf3d5cad5253b3199704f83e7.tar.gz
Fix bad allocs -M and profiling.
-rw-r--r--ChangeLog6
-rw-r--r--profile.c26
-rw-r--r--test/ChangeLog5
-rw-r--r--test/Makefile.am11
-rw-r--r--test/Makefile.in11
-rw-r--r--test/mpfrmemok1.awk7
-rw-r--r--test/mpfrmemok1.ok7
7 files changed, 63 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 9dfad08a..cf18c51c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2015-03-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (pp_number): Allocate enough room to print the number
+ in all cases. Was a problem mixing -M with profiling with a really
+ big number. Thanks to Hermann Peifer for the bug report.
+
2015-03-08 Arnold D. Robbins <arnold@skeeve.com>
* re.c (regexflags2str): Removed. It was redundant.
diff --git a/profile.c b/profile.c
index 316ba393..fd37bc61 100644
--- a/profile.c
+++ b/profile.c
@@ -1304,16 +1304,30 @@ pp_number(NODE *n)
{
#define PP_PRECISION 6
char *str;
+ size_t count;
- emalloc(str, char *, PP_PRECISION + 10, "pp_number");
#ifdef HAVE_MPFR
- if (is_mpg_float(n))
- mpfr_sprintf(str, "%0.*R*g", PP_PRECISION, ROUND_MODE, n->mpg_numbr);
- else if (is_mpg_integer(n))
+ if (is_mpg_float(n)) {
+ count = mpfr_get_prec(n->mpg_numbr) / 3; /* ~ 3.22 binary digits per decimal digit */
+ emalloc(str, char *, count, "pp_number");
+ /*
+ * 3/2015: Format string used to be "%0.*R*g". That padded
+ * with leading zeros. But it doesn't do that for regular
+ * numbers in the non-MPFR case.
+ */
+ mpfr_sprintf(str, "%.*R*g", PP_PRECISION, ROUND_MODE, n->mpg_numbr);
+ } else if (is_mpg_integer(n)) {
+ count = mpz_sizeinbase(n->mpg_i, 10) + 2; /* +1 for sign, +1 for NUL at end */
+ emalloc(str, char *, count, "pp_number");
mpfr_sprintf(str, "%Zd", n->mpg_i);
- else
+ } else
#endif
- sprintf(str, "%0.*g", PP_PRECISION, n->numbr);
+ {
+ count = PP_PRECISION + 10;
+ emalloc(str, char *, count, "pp_number");
+ sprintf(str, "%0.*g", PP_PRECISION, n->numbr);
+ }
+
return str;
#undef PP_PRECISION
}
diff --git a/test/ChangeLog b/test/ChangeLog
index 8a264e3f..24d6bcd7 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,8 @@
+2015-03-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (mpfrmemok1): New test.
+ * mpfrmemok1.awk, mpfrmemok1.ok: New files.
+
2015-03-10 Arnold D. Robbins <arnold@skeeve.com>
* Makefile.am (fpat4): New test.
diff --git a/test/Makefile.am b/test/Makefile.am
index 34899943..f1a0a275 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -537,6 +537,8 @@ EXTRA_DIST = \
mpfrexprange.ok \
mpfrieee.awk \
mpfrieee.ok \
+ mpfrmemok1.awk \
+ mpfrmemok1.ok \
mpfrnegzero.awk \
mpfrnegzero.ok \
mpfrnr.awk \
@@ -1059,8 +1061,8 @@ INET_TESTS = inetdayu inetdayt inetechu inetecht
MACHINE_TESTS = double1 double2 fmtspcl intformat
-MPFR_TESTS = mpfrnr mpfrnegzero mpfrrem mpfrrnd mpfrieee mpfrexprange \
- mpfrsort mpfrsqrt mpfrbigint
+MPFR_TESTS = mpfrnr mpfrnegzero mpfrmemok1 mpfrrem mpfrrnd mpfrieee \
+ mpfrexprange mpfrsort mpfrsqrt mpfrbigint
LOCALE_CHARSET_TESTS = \
asort asorti backbigs1 backsmalls1 backsmalls2 \
@@ -1812,6 +1814,11 @@ mpfrrem:
@$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+mpfrmemok1:
+ @echo $@
+ @$(AWK) -p/dev/stdout -M -f "$(srcdir)"/$@.awk 2>&1 | sed 1d > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
jarebug::
@echo $@
@"$(srcdir)"/$@.sh "$(AWKPROG)" "$(srcdir)"/$@.awk "$(srcdir)"/$@.in "_$@"
diff --git a/test/Makefile.in b/test/Makefile.in
index 489b0d14..b794e04e 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -794,6 +794,8 @@ EXTRA_DIST = \
mpfrexprange.ok \
mpfrieee.awk \
mpfrieee.ok \
+ mpfrmemok1.awk \
+ mpfrmemok1.ok \
mpfrnegzero.awk \
mpfrnegzero.ok \
mpfrnr.awk \
@@ -1312,8 +1314,8 @@ GAWK_EXT_TESTS = \
EXTRA_TESTS = inftest regtest
INET_TESTS = inetdayu inetdayt inetechu inetecht
MACHINE_TESTS = double1 double2 fmtspcl intformat
-MPFR_TESTS = mpfrnr mpfrnegzero mpfrrem mpfrrnd mpfrieee mpfrexprange \
- mpfrsort mpfrsqrt mpfrbigint
+MPFR_TESTS = mpfrnr mpfrnegzero mpfrmemok1 mpfrrem mpfrrnd mpfrieee \
+ mpfrexprange mpfrsort mpfrsqrt mpfrbigint
LOCALE_CHARSET_TESTS = \
asort asorti backbigs1 backsmalls1 backsmalls2 \
@@ -2249,6 +2251,11 @@ mpfrrem:
@$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+mpfrmemok1:
+ @echo $@
+ @$(AWK) -p/dev/stdout -M -f "$(srcdir)"/$@.awk 2>&1 | sed 1d > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
jarebug::
@echo $@
@"$(srcdir)"/$@.sh "$(AWKPROG)" "$(srcdir)"/$@.awk "$(srcdir)"/$@.in "_$@"
diff --git a/test/mpfrmemok1.awk b/test/mpfrmemok1.awk
new file mode 100644
index 00000000..9331a34d
--- /dev/null
+++ b/test/mpfrmemok1.awk
@@ -0,0 +1,7 @@
+# This program tests that -M works with profiling.
+# It does not do anything real, but there should not be glibc memory
+# errors and it should be valgrind-clean too.
+
+BEGIN {
+ v = 0x0100000000000000000000000000000000
+}
diff --git a/test/mpfrmemok1.ok b/test/mpfrmemok1.ok
new file mode 100644
index 00000000..2389a2d5
--- /dev/null
+++ b/test/mpfrmemok1.ok
@@ -0,0 +1,7 @@
+
+ # BEGIN rule(s)
+
+ BEGIN {
+ 1 v = 340282366920938463463374607431768211456
+ }
+