From 975fbde5ddb54b76212f25e5f114758ebf91f572 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 20 Apr 2014 11:37:26 +0300 Subject: Fix do_rand order-of-evaluation dependency. --- builtin.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 875b3e5c..3464dc21 100644 --- a/builtin.c +++ b/builtin.c @@ -2454,8 +2454,14 @@ do_rand(int nargs ATTRIBUTE_UNUSED) */ do { - tmprand = 0.5 + ( (random()/RAND_DIVISOR + random()) - / RAND_DIVISOR); + long d1, d2; + /* + * Do the calls in predictable order to avoid + * compiler differences in order of evaluation. + */ + d1 = random(); + d2 = random(); + tmprand = 0.5 + ( (d1/RAND_DIVISOR + d2) / RAND_DIVISOR ); tmprand -= 0.5; } while (tmprand == 1.0); -- cgit v1.2.3 From 5cb84303090ceeaae218692e849d76bb5f0dce69 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Thu, 19 Jun 2014 20:24:04 +0300 Subject: Add more comments and whitespace for do_sub(). --- builtin.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index b5d38d8d..fa03222b 100644 --- a/builtin.c +++ b/builtin.c @@ -2647,23 +2647,28 @@ do_match(int nargs) * 2001 standard: * * sub(ere, repl[, in ]) - * Substitute the string repl in place of the first instance of the extended regular - * expression ERE in string in and return the number of substitutions. An ampersand - * ('&') appearing in the string repl shall be replaced by the string from in that - * matches the ERE. An ampersand preceded with a backslash ('\') shall be - * interpreted as the literal ampersand character. An occurrence of two consecutive - * backslashes shall be interpreted as just a single literal backslash character. Any - * other occurrence of a backslash (for example, preceding any other character) shall - * be treated as a literal backslash character. Note that if repl is a string literal (the - * lexical token STRING; see Grammar (on page 170)), the handling of the - * ampersand character occurs after any lexical processing, including any lexical - * backslash escape sequence processing. If in is specified and it is not an lvalue (see - * Expressions in awk (on page 156)), the behavior is undefined. If in is omitted, awk - * shall use the current record ($0) in its place. + * Substitute the string repl in place of the first instance of the + * extended regular expression ERE in string in and return the number of + * substitutions. An ampersand ('&') appearing in the string repl shall + * be replaced by the string from in that matches the ERE. An ampersand + * preceded with a backslash ('\') shall be interpreted as the literal + * ampersand character. An occurrence of two consecutive backslashes shall + * be interpreted as just a single literal backslash character. Any other + * occurrence of a backslash (for example, preceding any other character) + * shall be treated as a literal backslash character. Note that if repl is a + * string literal (the lexical token STRING; see Grammar (on page 170)), the + * handling of the ampersand character occurs after any lexical processing, + * including any lexical backslash escape sequence processing. If in is + * specified and it is not an lvalue (see Expressions in awk (on page 156)), + * the behavior is undefined. If in is omitted, awk shall use the current + * record ($0) in its place. * - * 11/2010: The text in the 2008 standard is the same as just quoted. However, POSIX behavior - * is now the default. This can change the behavior of awk programs. The old behavior - * is not available. + * 11/2010: The text in the 2008 standard is the same as just quoted. + * However, POSIX behavior is now the default. This can change the behavior + * of awk programs. The old behavior is not available. + * + * 7/2011: Reverted backslash handling to what it used to be. It was in + * gawk for too long. Should have known better. */ /* @@ -2774,9 +2779,11 @@ set_how_many: repl = s->stptr; replend = repl + s->stlen; repllen = replend - repl; + emalloc(buf, char *, buflen + 2, "do_sub"); buf[buflen] = '\0'; buf[buflen + 1] = '\0'; + ampersands = 0; /* -- cgit v1.2.3 From 9a5b89ce4cf173a7e23d9b196a2d7dee9ec2d2f0 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Thu, 10 Jul 2014 15:40:23 -0700 Subject: Bug fix when sprintf %c on huge values in multibyte locales. --- builtin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index fa03222b..7523d6c9 100644 --- a/builtin.c +++ b/builtin.c @@ -1112,7 +1112,7 @@ out0: memset(& state, 0, sizeof(state)); count = mbrlen(cp, arg->stlen, & state); - if (count > 0) { + if (count != (size_t) -1 && count != (size_t) -2 && count > 0) { prec = count; /* may need to increase fw so that padding happens, see pr_tail code */ if (fw > 0) -- cgit v1.2.3 From df2eaea6a92c7d89d604d0a4e885d064678ce3ed Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Thu, 10 Jul 2014 16:32:44 -0700 Subject: Add div() function for integer division & remainder. --- builtin.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 470f7bbe..6f8aeb36 100644 --- a/builtin.c +++ b/builtin.c @@ -3612,6 +3612,72 @@ do_bindtextdomain(int nargs) return make_string(the_result, strlen(the_result)); } +/* do_div --- do integer division, return quotient and remainder in dest array */ + +/* + * We define the semantics as: + * numerator = int(numerator) + * denominator = int(denonmator) + * quotient = int(numerator / denomator) + * remainder = int(numerator % denomator) + */ + +NODE * +do_div(int nargs) +{ + NODE *numerator, *denominator, *result; + double num, denom, quotient, remainder; + NODE *sub, **lhs; + + result = POP_PARAM(); + if (result->type != Node_var_array) + fatal(_("div: third argument is not an array")); + assoc_clear(result); + + denominator = POP_SCALAR(); + numerator = POP_SCALAR(); + + if (do_lint) { + if ((numerator->flags & (NUMCUR|NUMBER)) == 0) + lintwarn(_("div: received non-numeric first argument")); + if ((denominator->flags & (NUMCUR|NUMBER)) == 0) + lintwarn(_("div: received non-numeric second argument")); + } + + (void) force_number(numerator); + (void) force_number(denominator); + num = double_to_int(get_number_d(numerator)); + denom = double_to_int(get_number_d(denominator)); + + if (denom == 0.0) + fatal(_("div: division by zero attempted")); + + quotient = double_to_int(num / denom); + /* + * FIXME: This code is duplicated, factor it out to a + * separate function. + */ +#ifdef HAVE_FMOD + remainder = fmod(num, denom); +#else /* ! HAVE_FMOD */ + (void) modf(num / denom, & remainder); + remainder = num - remainder * denom; +#endif /* ! HAVE_FMOD */ + remainder = double_to_int(remainder); + + sub = make_string("quotient", 8); + lhs = assoc_lookup(result, sub); + unref(*lhs); + *lhs = make_number((AWKNUM) quotient); + + sub = make_string("remainder", 9); + lhs = assoc_lookup(result, sub); + unref(*lhs); + *lhs = make_number((AWKNUM) remainder); + + return make_number((AWKNUM) 0.0); +} + /* mbc_byte_count --- return number of bytes for corresponding numchars multibyte characters */ -- cgit v1.2.3 From e02ffe43c534493a40e9b9403cd91a6357514c85 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Thu, 31 Jul 2014 23:07:09 +0300 Subject: Make sprintf %c work better on Windows (printhuge test) --- builtin.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 7523d6c9..7d314dc5 100644 --- a/builtin.c +++ b/builtin.c @@ -1066,13 +1066,30 @@ check_pos: size_t count; memset(& mbs, 0, sizeof(mbs)); + + /* handle systems with too small wchar_t */ + if (sizeof(wchar_t) < 4 && uval > 0xffff) { + if (do_lint) + lintwarn( + _("[s]printf: value %g is too big for %%c format"), + arg->numbr); + + goto out0; + } + wc = uval; count = wcrtomb(buf, wc, & mbs); if (count == 0 || count == (size_t)-1 - || count == (size_t)-2) + || count == (size_t)-2) { + if (do_lint) + lintwarn( + _("[s]printf: value %g is not a valid wide character"), + arg->numbr); + goto out0; + } memcpy(cpbuf, buf, count); prec = count; @@ -1084,10 +1101,6 @@ out0: /* else, fall through */ #endif - if (do_lint && uval > 255) { - lintwarn("[s]printf: value %g is too big for %%c format", - arg->numbr); - } cpbuf[0] = uval; prec = 1; cp = cpbuf; -- cgit v1.2.3 From 9a1a8c22e42af12f5859ef5d159b070f959912e6 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 3 Aug 2014 22:03:03 +0300 Subject: Minor code improvement for sprintf %c. --- builtin.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 7d314dc5..077575fa 100644 --- a/builtin.c +++ b/builtin.c @@ -1081,8 +1081,7 @@ check_pos: count = wcrtomb(buf, wc, & mbs); if (count == 0 - || count == (size_t)-1 - || count == (size_t)-2) { + || count == (size_t) -1) { if (do_lint) lintwarn( _("[s]printf: value %g is not a valid wide character"), -- cgit v1.2.3 From aec76b2b6e79e36dafced60fd91a877f5db98c4e Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 13 Aug 2014 06:06:02 +0300 Subject: Minor improvement in gsub() memory management. --- builtin.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 077575fa..0995fdf7 100644 --- a/builtin.c +++ b/builtin.c @@ -2786,16 +2786,11 @@ set_how_many: text = t->stptr; textlen = t->stlen; - buflen = textlen + 2; repl = s->stptr; replend = repl + s->stlen; repllen = replend - repl; - emalloc(buf, char *, buflen + 2, "do_sub"); - buf[buflen] = '\0'; - buf[buflen + 1] = '\0'; - ampersands = 0; /* @@ -2854,6 +2849,13 @@ set_how_many: } lastmatchnonzero = false; + + /* guesstimate how much room to allocate; +2 forces > 0 */ + buflen = textlen + (ampersands + 1) * repllen + 2; + emalloc(buf, char *, buflen + 2, "do_sub"); + buf[buflen] = '\0'; + buf[buflen + 1] = '\0'; + bp = buf; for (current = 1;; current++) { matches++; -- cgit v1.2.3 From bfc794de222760871c6c6de6bb923a0bf57ee166 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Mon, 1 Sep 2014 22:42:07 +0300 Subject: Minor improvement to substr(). --- builtin.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 0995fdf7..6e4a1b72 100644 --- a/builtin.c +++ b/builtin.c @@ -1759,7 +1759,14 @@ do_substr(int nargs) else if (do_lint == DO_LINT_INVALID && ! (d_length >= 0)) lintwarn(_("substr: length %g is not >= 0"), d_length); DEREF(t1); - return dupnode(Nnull_string); + /* + * Return explicit null string instead of doing + * dupnode(Nnull_string) so that if the result + * is checked with the combination of length() + * and lint, no error is reported about using + * an uninitialized value. Same thing later, too. + */ + return make_string("", 0); } if (do_lint) { if (double_to_int(d_length) != d_length) @@ -1813,7 +1820,7 @@ do_substr(int nargs) if (do_lint && (do_lint == DO_LINT_ALL || ((indx | length) != 0))) lintwarn(_("substr: source string is zero length")); DEREF(t1); - return dupnode(Nnull_string); + return make_string("", 0); } /* get total len of input string, for following checks */ @@ -1830,7 +1837,7 @@ do_substr(int nargs) lintwarn(_("substr: start index %g is past end of string"), d_index); DEREF(t1); - return dupnode(Nnull_string); + return make_string("", 0); } if (length > src_len - indx) { if (do_lint) -- cgit v1.2.3 From 3fcce8a32e825dd10384d5276c420c2514442fe2 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Mon, 15 Sep 2014 19:47:03 +0300 Subject: Finish excising isalpha and isalnum. Document. --- builtin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 6e4a1b72..3eb09b48 100644 --- a/builtin.c +++ b/builtin.c @@ -1569,7 +1569,7 @@ mpf1: s0 = s1; break; default: - if (do_lint && isalpha(cs1)) + if (do_lint && is_alpha(cs1)) lintwarn(_("ignoring unknown format specifier character `%c': no argument converted"), cs1); break; } -- cgit v1.2.3