aboutsummaryrefslogtreecommitdiffstats
path: root/builtin.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin.c')
-rw-r--r--builtin.c93
1 files changed, 61 insertions, 32 deletions
diff --git a/builtin.c b/builtin.c
index b3e2962b..54f52350 100644
--- a/builtin.c
+++ b/builtin.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2013 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-2014 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -719,7 +719,7 @@ format_tree(
mpz_ptr zi;
mpfr_ptr mf;
#endif
- enum { MP_INT_WITH_PREC = 1, MP_INT_WITHOUT_PREC, MP_FLOAT } fmt_type;
+ enum { MP_NONE = 0, MP_INT_WITH_PREC = 1, MP_INT_WITHOUT_PREC, MP_FLOAT } fmt_type;
static const char sp[] = " ";
static const char zero_string[] = "0";
@@ -817,7 +817,7 @@ format_tree(
mf = NULL;
zi = NULL;
#endif
- fmt_type = 0;
+ fmt_type = MP_NONE;
lj = alt = big_flag = bigbig_flag = small_flag = false;
fill = sp;
@@ -994,9 +994,7 @@ check_pos:
goto check_pos;
case '\'':
#if defined(HAVE_LOCALE_H)
- /* allow quote_flag if there is a thousands separator. */
- if (loc.thousands_sep[0] != '\0')
- quote_flag = true;
+ quote_flag = true;
goto check_pos;
#else
goto retry;
@@ -1196,6 +1194,9 @@ out0:
}
if (i < 1)
goto out_of_range;
+#if defined(HAVE_LOCALE_H)
+ quote_flag = (quote_flag && loc.thousands_sep[0] != 0);
+#endif
chp = &cpbufs[1].buf[i-1];
ii = jj = 0;
do {
@@ -1203,8 +1204,14 @@ out0:
chp--; i--;
#if defined(HAVE_LOCALE_H)
if (quote_flag && loc.grouping[ii] && ++jj == loc.grouping[ii]) {
- if (i) /* only add if more digits coming */
- PREPEND(loc.thousands_sep[0]); /* XXX - assumption it's one char */
+ if (i) { /* only add if more digits coming */
+ int k;
+ const char *ts = loc.thousands_sep;
+
+ for (k = strlen(ts) - 1; k >= 0; k--) {
+ PREPEND(ts[k]);
+ }
+ }
if (loc.grouping[ii+1] == 0)
jj = 0; /* keep using current val in loc.grouping[ii] */
else if (loc.grouping[ii+1] == CHAR_MAX)
@@ -1360,6 +1367,9 @@ mpf1:
#ifdef HAVE_MPFR
int0:
#endif
+#if defined(HAVE_LOCALE_H)
+ quote_flag = (quote_flag && loc.thousands_sep[0] != 0);
+#endif
/*
* When to fill with zeroes is of course not simple.
* First: No zero fill if left-justifying.
@@ -1378,8 +1388,14 @@ mpf1:
uval /= base;
#if defined(HAVE_LOCALE_H)
if (base == 10 && quote_flag && loc.grouping[ii] && ++jj == loc.grouping[ii]) {
- if (uval) /* only add if more digits coming */
- PREPEND(loc.thousands_sep[0]); /* XXX --- assumption it's one char */
+ if (uval) { /* only add if more digits coming */
+ int k;
+ const char *ts = loc.thousands_sep;
+
+ for (k = strlen(ts) - 1; k >= 0; k--) {
+ PREPEND(ts[k]);
+ }
+ }
if (loc.grouping[ii+1] == 0)
jj = 0; /* keep using current val in loc.grouping[ii] */
else if (loc.grouping[ii+1] == CHAR_MAX)
@@ -1999,10 +2015,10 @@ do_mktime(int nargs)
& hour, & minute, & second,
& dst);
- if (do_lint /* Ready? Set! Go: */
- && ( (second < 0 || second > 60)
- || (minute < 0 || minute > 60)
- || (hour < 0 || hour > 23)
+ if ( do_lint /* Ready? Set! Go: */
+ && ( (second < 0 || second > 60)
+ || (minute < 0 || minute > 59)
+ || (hour < 0 || hour > 23) /* FIXME ISO 8601 allows 24 ? */
|| (day < 1 || day > 31)
|| (month < 1 || month > 12) ))
lintwarn(_("mktime: at least one of the values is out of the default range"));
@@ -2438,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);
@@ -2686,23 +2708,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.
*/
/*
@@ -2813,9 +2840,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;
/*