From 18c6b0f85db6683f1d0789e800acfdd35da3ce07 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Mon, 13 Jun 2016 18:39:10 -0400 Subject: Fix usage of scalar type flag bits and fix some bugs in numeric conversions and lint checks. --- eval.c | 90 +++++++++++++++++++++--------------------------------------------- 1 file changed, 29 insertions(+), 61 deletions(-) (limited to 'eval.c') diff --git a/eval.c b/eval.c index 56c6007f..90947dc5 100644 --- a/eval.c +++ b/eval.c @@ -582,14 +582,8 @@ cmp_nodes(NODE *t1, NODE *t2) if (t1 == t2) return 0; - if ((t1->flags & MAYBE_NUM) != 0) - (void) force_number(t1); - if ((t2->flags & MAYBE_NUM) != 0) - (void) force_number(t2); - if ((t1->flags & INTIND) != 0) - t1 = force_string(t1); - if ((t2->flags & INTIND) != 0) - t2 = force_string(t2); + (void) fixtype(t1); + (void) fixtype(t2); if ((t1->flags & NUMBER) != 0 && (t2->flags & NUMBER) != 0) return cmp_numbers(t1, t2); @@ -698,7 +692,7 @@ void set_IGNORECASE() { static bool warned = false; - NODE *n = IGNORECASE_node->var_value; + NODE *n; if ((do_lint || do_traditional) && ! warned) { warned = true; @@ -707,19 +701,13 @@ set_IGNORECASE() load_casetable(); if (do_traditional) IGNORECASE = false; - else if ((n->flags & (NUMCUR|NUMBER)) != 0) - IGNORECASE = ! iszero(n); - else if ((n->flags & (STRING|STRCUR)) != 0) { - if ((n->flags & MAYBE_NUM) == 0) { - (void) force_string(n); - IGNORECASE = (n->stlen > 0); - } else { - (void) force_number(n); + else { + n = fixtype(IGNORECASE_node->var_value); + if ((n->flags & NUMBER) != 0) IGNORECASE = ! iszero(n); - } - } else - IGNORECASE = false; /* shouldn't happen */ - + else + IGNORECASE = (n->stlen > 0); + } set_RS(); /* set_RS() calls set_FS() if need be, for us */ } @@ -947,49 +935,32 @@ set_LINT() { #ifndef NO_LINT int old_lint = do_lint; - NODE *n = LINT_node->var_value; - - if ((n->flags & (STRING|STRCUR)) != 0) { - if ((n->flags & MAYBE_NUM) == 0) { - const char *lintval; - size_t lintlen; - - n = force_string(LINT_node->var_value); - lintval = n->stptr; - lintlen = n->stlen; - if (lintlen > 0) { - do_flags |= DO_LINT_ALL; - if (lintlen == 5 && strncmp(lintval, "fatal", 5) == 0) - lintfunc = r_fatal; - else if (lintlen == 7 && strncmp(lintval, "invalid", 7) == 0) { - do_flags &= ~ DO_LINT_ALL; - do_flags |= DO_LINT_INVALID; - } else - lintfunc = warning; - } else { - do_flags &= ~(DO_LINT_ALL|DO_LINT_INVALID); - lintfunc = warning; + NODE *n = fixtype(LINT_node->var_value); + + lintfunc = r_warning; /* reset to default */ + if ((n->flags & STRING) != 0) { + const char *lintval; + size_t lintlen; + + lintval = n->stptr; + lintlen = n->stlen; + if (lintlen > 0) { + do_flags |= DO_LINT_ALL; + if (lintlen == 5 && strncmp(lintval, "fatal", 5) == 0) + lintfunc = r_fatal; + else if (lintlen == 7 && strncmp(lintval, "invalid", 7) == 0) { + do_flags &= ~ DO_LINT_ALL; + do_flags |= DO_LINT_INVALID; } } else { - (void) force_number(n); - if (! iszero(n)) - do_flags |= DO_LINT_ALL; - else - do_flags &= ~(DO_LINT_ALL|DO_LINT_INVALID); - lintfunc = warning; + do_flags &= ~(DO_LINT_ALL|DO_LINT_INVALID); } - } else if ((n->flags & (NUMCUR|NUMBER)) != 0) { - (void) force_number(n); + } else { if (! iszero(n)) do_flags |= DO_LINT_ALL; else do_flags &= ~(DO_LINT_ALL|DO_LINT_INVALID); - lintfunc = warning; - } else - do_flags &= ~(DO_LINT_ALL|DO_LINT_INVALID); /* shouldn't happen */ - - if (! do_lint) - lintfunc = warning; + } /* explicitly use warning() here, in case lintfunc == r_fatal */ if (old_lint != do_lint && old_lint && ! do_lint) @@ -1546,10 +1517,7 @@ eval_condition(NODE *t) if (t == node_Boolean[true]) return true; - if ((t->flags & MAYBE_NUM) != 0) - force_number(t); - else if ((t->flags & INTIND) != 0) - force_string(t); + (void) fixtype(t); if ((t->flags & NUMBER) != 0) return ! iszero(t); -- cgit v1.2.3 From 5826beec258141776469c5fd9b703d52c81a35fb Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 14 Jun 2016 16:35:48 -0400 Subject: Add a new boolval function to awk.h to make sure we handle this consistently. --- eval.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'eval.c') diff --git a/eval.c b/eval.c index 90947dc5..ee674911 100644 --- a/eval.c +++ b/eval.c @@ -692,7 +692,6 @@ void set_IGNORECASE() { static bool warned = false; - NODE *n; if ((do_lint || do_traditional) && ! warned) { warned = true; @@ -701,13 +700,8 @@ set_IGNORECASE() load_casetable(); if (do_traditional) IGNORECASE = false; - else { - n = fixtype(IGNORECASE_node->var_value); - if ((n->flags & NUMBER) != 0) - IGNORECASE = ! iszero(n); - else - IGNORECASE = (n->stlen > 0); - } + else + IGNORECASE = boolval(IGNORECASE_node->var_value); set_RS(); /* set_RS() calls set_FS() if need be, for us */ } @@ -1517,12 +1511,7 @@ eval_condition(NODE *t) if (t == node_Boolean[true]) return true; - (void) fixtype(t); - - if ((t->flags & NUMBER) != 0) - return ! iszero(t); - - return (t->stlen != 0); + return boolval(t); } /* cmp_scalars -- compare two nodes on the stack */ -- cgit v1.2.3 From 2d2744ec74076d29e94a2a004e308f73a86b9fa5 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Mon, 20 Jun 2016 10:10:30 -0400 Subject: Call fixtype in a few more places to make sure we check types properly. --- eval.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'eval.c') diff --git a/eval.c b/eval.c index ee674911..d7735205 100644 --- a/eval.c +++ b/eval.c @@ -712,7 +712,7 @@ set_BINMODE() { static bool warned = false; char *p; - NODE *v = BINMODE_node->var_value; + NODE *v = fixtype(BINMODE_node->var_value); if ((do_lint || do_traditional) && ! warned) { warned = true; @@ -721,7 +721,6 @@ set_BINMODE() if (do_traditional) BINMODE = TEXT_TRANSLATE; else if ((v->flags & NUMBER) != 0) { - (void) force_number(v); BINMODE = get_number_si(v); /* Make sure the value is rational. */ if (BINMODE < TEXT_TRANSLATE) @@ -1157,7 +1156,7 @@ r_get_field(NODE *n, Func_ptr *assign, bool reference) if (assign) *assign = NULL; if (do_lint) { - if ((n->flags & NUMBER) == 0) { + if ((fixtype(n)->flags & NUMBER) == 0) { lintwarn(_("attempt to field reference from non-numeric value")); if (n->stlen == 0) lintwarn(_("attempt to field reference from null string")); -- cgit v1.2.3 From e18ebe10166e2c63f3385666978b678fe6ce67a2 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 26 Jun 2016 18:26:39 +0300 Subject: Minor improvements after Andy's reworking of stuff. --- eval.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'eval.c') diff --git a/eval.c b/eval.c index d7735205..5b4418b8 100644 --- a/eval.c +++ b/eval.c @@ -942,18 +942,16 @@ set_LINT() if (lintlen == 5 && strncmp(lintval, "fatal", 5) == 0) lintfunc = r_fatal; else if (lintlen == 7 && strncmp(lintval, "invalid", 7) == 0) { - do_flags &= ~ DO_LINT_ALL; + do_flags &= ~DO_LINT_ALL; do_flags |= DO_LINT_INVALID; } } else { do_flags &= ~(DO_LINT_ALL|DO_LINT_INVALID); } - } else { - if (! iszero(n)) - do_flags |= DO_LINT_ALL; - else - do_flags &= ~(DO_LINT_ALL|DO_LINT_INVALID); - } + } else if (! iszero(n)) + do_flags |= DO_LINT_ALL; + else + do_flags &= ~(DO_LINT_ALL|DO_LINT_INVALID); /* explicitly use warning() here, in case lintfunc == r_fatal */ if (old_lint != do_lint && old_lint && ! do_lint) -- cgit v1.2.3