aboutsummaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c107
1 files changed, 40 insertions, 67 deletions
diff --git a/eval.c b/eval.c
index 36dab2fb..491d0af2 100644
--- a/eval.c
+++ b/eval.c
@@ -25,7 +25,6 @@
#include "awk.h"
-extern void after_beginfile(IOBUF **curfile);
extern double pow(double x, double y);
extern double modf(double x, double *yp);
extern double fmod(double x, double y);
@@ -243,7 +242,6 @@ static const char *const nodetypes[] = {
"Node_param_list",
"Node_func",
"Node_ext_func",
- "Node_old_ext_func",
"Node_builtin_func",
"Node_array_ref",
"Node_array_tree",
@@ -289,6 +287,7 @@ static struct optypetab {
{ "Op_postincrement", "++" },
{ "Op_postdecrement", "--" },
{ "Op_unary_minus", "-" },
+ { "Op_unary_plus", "+" },
{ "Op_field_spec", "$" },
{ "Op_not", "! " },
{ "Op_assign", " = " },
@@ -334,12 +333,12 @@ static struct optypetab {
{ "Op_builtin", NULL },
{ "Op_sub_builtin", NULL },
{ "Op_ext_builtin", NULL },
- { "Op_old_ext_builtin", NULL }, /* temporary */
{ "Op_in_array", " in " },
{ "Op_func_call", NULL },
{ "Op_indirect_func_call", NULL },
{ "Op_push", NULL },
{ "Op_push_arg", NULL },
+ { "Op_push_arg_untyped", NULL },
{ "Op_push_i", NULL },
{ "Op_push_re", NULL },
{ "Op_push_array", NULL },
@@ -364,6 +363,7 @@ static struct optypetab {
{ "Op_after_beginfile", NULL },
{ "Op_after_endfile", NULL },
{ "Op_func", NULL },
+ { "Op_comment", NULL },
{ "Op_exec_count", NULL },
{ "Op_breakpoint", NULL },
{ "Op_lint", NULL },
@@ -575,7 +575,7 @@ posix_compare(NODE *s1, NODE *s2)
/* cmp_nodes --- compare two nodes, returning negative, 0, positive */
int
-cmp_nodes(NODE *t1, NODE *t2)
+cmp_nodes(NODE *t1, NODE *t2, bool use_strcmp)
{
int ret = 0;
size_t len1, len2;
@@ -584,14 +584,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);
@@ -604,7 +598,7 @@ cmp_nodes(NODE *t1, NODE *t2)
if (len1 == 0 || len2 == 0)
return ldiff;
- if (do_posix)
+ if (do_posix && ! use_strcmp)
return posix_compare(t1, t2);
l = (ldiff <= 0 ? len1 : len2);
@@ -700,7 +694,6 @@ void
set_IGNORECASE()
{
static bool warned = false;
- NODE *n = IGNORECASE_node->var_value;
if ((do_lint || do_traditional) && ! warned) {
warned = true;
@@ -709,19 +702,8 @@ 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);
- IGNORECASE = ! iszero(n);
- }
- } else
- IGNORECASE = false; /* shouldn't happen */
-
+ else
+ IGNORECASE = boolval(IGNORECASE_node->var_value);
set_RS(); /* set_RS() calls set_FS() if need be, for us */
}
@@ -732,7 +714,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;
@@ -741,7 +723,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)
@@ -829,9 +810,9 @@ set_OFS()
new_ofs_len = OFS_node->var_value->stlen;
if (OFS == NULL)
- emalloc(OFS, char *, new_ofs_len + 2, "set_OFS");
+ emalloc(OFS, char *, new_ofs_len + 1, "set_OFS");
else if (OFSlen < new_ofs_len)
- erealloc(OFS, char *, new_ofs_len + 2, "set_OFS");
+ erealloc(OFS, char *, new_ofs_len + 1, "set_OFS");
memcpy(OFS, OFS_node->var_value->stptr, OFS_node->var_value->stlen);
OFSlen = new_ofs_len;
@@ -904,7 +885,7 @@ fmt_index(NODE *n)
emalloc(fmt_list, NODE **, fmt_num*sizeof(*fmt_list), "fmt_index");
n = force_string(n);
while (ix < fmt_hiwater) {
- if (cmp_nodes(fmt_list[ix], n) == 0)
+ if (cmp_nodes(fmt_list[ix], n, true) == 0)
return ix;
ix++;
}
@@ -949,36 +930,28 @@ set_LINT()
{
#ifndef NO_LINT
int old_lint = do_lint;
- NODE *n = LINT_node->var_value;
+ NODE *n = fixtype(LINT_node->var_value);
/* start with clean defaults */
lintfunc = r_warning;
do_flags &= ~(DO_LINT_ALL|DO_LINT_INVALID);
- 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) {
- if (lintlen == 7 && strncmp(lintval, "invalid", 7) == 0)
- do_flags |= DO_LINT_INVALID;
- else {
- do_flags |= DO_LINT_ALL;
- if (lintlen == 5 && strncmp(lintval, "fatal", 5) == 0)
- lintfunc = r_fatal;
- }
- }
- } else {
- (void) force_number(n);
- if (! iszero(n))
+ if ((n->flags & STRING) != 0) {
+ const char *lintval;
+ size_t lintlen;
+
+ lintval = n->stptr;
+ lintlen = n->stlen;
+ if (lintlen > 0) {
+ if (lintlen == 7 && strncmp(lintval, "invalid", 7) == 0)
+ do_flags |= DO_LINT_INVALID;
+ else {
do_flags |= DO_LINT_ALL;
+ if (lintlen == 5 && strncmp(lintval, "fatal", 5) == 0)
+ lintfunc = r_fatal;
+ }
}
- } else if ((n->flags & (NUMCUR|NUMBER)) != 0) {
- (void) force_number(n);
+ } else {
if (! iszero(n))
do_flags |= DO_LINT_ALL;
}
@@ -1017,6 +990,7 @@ update_ERRNO_int(int errcode)
{
char *cp;
+ update_PROCINFO_num("errno", errcode);
if (errcode) {
cp = strerror(errcode);
cp = gettext(cp);
@@ -1031,6 +1005,7 @@ update_ERRNO_int(int errcode)
void
update_ERRNO_string(const char *string)
{
+ update_PROCINFO_num("errno", 0);
unref(ERRNO_node->var_value);
ERRNO_node->var_value = make_string(string, strlen(string));
}
@@ -1040,6 +1015,7 @@ update_ERRNO_string(const char *string)
void
unset_ERRNO(void)
{
+ update_PROCINFO_num("errno", 0);
unref(ERRNO_node->var_value);
ERRNO_node->var_value = dupnode(Nnull_string);
}
@@ -1181,7 +1157,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"));
@@ -1530,21 +1506,18 @@ 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);
-
- if ((t->flags & NUMBER) != 0)
- return ! iszero(t);
-
- return (t->stlen != 0);
+ return boolval(t);
}
+typedef enum {
+ SCALAR_EQ_NEQ,
+ SCALAR_RELATIONAL
+} scalar_cmp_t;
+
/* cmp_scalars -- compare two nodes on the stack */
static inline int
-cmp_scalars()
+cmp_scalars(scalar_cmp_t comparison_type)
{
NODE *t1, *t2;
int di;
@@ -1555,7 +1528,7 @@ cmp_scalars()
DEREF(t2);
fatal(_("attempt to use array `%s' in a scalar context"), array_vname(t1));
}
- di = cmp_nodes(t1, t2);
+ di = cmp_nodes(t1, t2, comparison_type == SCALAR_EQ_NEQ);
DEREF(t1);
DEREF(t2);
return di;