aboutsummaryrefslogtreecommitdiffstats
path: root/builtin.c
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2012-07-09 21:11:54 +0300
committerArnold D. Robbins <arnold@skeeve.com>2012-07-09 21:11:54 +0300
commite1749c3c853ace06796efd7dd3bd3e9bf025a549 (patch)
tree7e326a2d99075f6d7617692284f4d62cf06f4736 /builtin.c
parent518bcc6e640648717bc5512d3fd5c2bf16d6fec3 (diff)
downloadegawk-e1749c3c853ace06796efd7dd3bd3e9bf025a549.tar.gz
egawk-e1749c3c853ace06796efd7dd3bd3e9bf025a549.tar.bz2
egawk-e1749c3c853ace06796efd7dd3bd3e9bf025a549.zip
Extend or(), and(), xor() to N arguments, N >= 2.
Diffstat (limited to 'builtin.c')
-rw-r--r--builtin.c131
1 files changed, 62 insertions, 69 deletions
diff --git a/builtin.c b/builtin.c
index 87b596e6..3576372c 100644
--- a/builtin.c
+++ b/builtin.c
@@ -3021,33 +3021,30 @@ do_rshift(int nargs)
NODE *
do_and(int nargs)
{
- NODE *s1, *s2;
- uintmax_t uleft, uright, res;
- AWKNUM left, right;
+ NODE *s1;
+ uintmax_t res, uval;
+ AWKNUM val;
+ int i;
- POP_TWO_SCALARS(s1, s2);
- if (do_lint) {
- if ((s1->flags & (NUMCUR|NUMBER)) == 0)
- lintwarn(_("and: received non-numeric first argument"));
- if ((s2->flags & (NUMCUR|NUMBER)) == 0)
- lintwarn(_("and: received non-numeric second argument"));
- }
- left = force_number(s1)->numbr;
- right = force_number(s2)->numbr;
- if (do_lint) {
- if (left < 0 || right < 0)
- lintwarn(_("and(%f, %f): negative values will give strange results"), left, right);
- if (double_to_int(left) != left || double_to_int(right) != right)
- lintwarn(_("and(%f, %f): fractional values will be truncated"), left, right);
- }
+ res = ~0; /* start off with all ones */
+ if (nargs < 2)
+ fatal(_("and: called with less than two arguments"));
- DEREF(s1);
- DEREF(s2);
+ for (i = 1; nargs > 0; nargs--, i++) {
+ s1 = POP_SCALAR();
+ if (do_lint && (s1->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("and: argument %d is non-numeric"), i);
- uleft = (uintmax_t) left;
- uright = (uintmax_t) right;
+ val = force_number(s1)->numbr;
+ if (do_lint && val < 0)
+ lintwarn(_("and: argument %d negative value %g will give strange results"), i, val);
+
+ uval = (uintmax_t) val;
+ res &= uval;
+
+ DEREF(s1);
+ }
- res = uleft & uright;
return make_integer(res);
}
@@ -3056,33 +3053,30 @@ do_and(int nargs)
NODE *
do_or(int nargs)
{
- NODE *s1, *s2;
- uintmax_t uleft, uright, res;
- AWKNUM left, right;
+ NODE *s1;
+ uintmax_t res, uval;
+ AWKNUM val;
+ int i;
- POP_TWO_SCALARS(s1, s2);
- if (do_lint) {
- if ((s1->flags & (NUMCUR|NUMBER)) == 0)
- lintwarn(_("or: received non-numeric first argument"));
- if ((s2->flags & (NUMCUR|NUMBER)) == 0)
- lintwarn(_("or: received non-numeric second argument"));
- }
- left = force_number(s1)->numbr;
- right = force_number(s2)->numbr;
- if (do_lint) {
- if (left < 0 || right < 0)
- lintwarn(_("or(%f, %f): negative values will give strange results"), left, right);
- if (double_to_int(left) != left || double_to_int(right) != right)
- lintwarn(_("or(%f, %f): fractional values will be truncated"), left, right);
- }
+ res = 0;
+ if (nargs < 2)
+ fatal(_("or: called with less than two arguments"));
- DEREF(s1);
- DEREF(s2);
+ for (i = 1; nargs > 0; nargs--, i++) {
+ s1 = POP_SCALAR();
+ if (do_lint && (s1->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("or: argument %d is non-numeric"), i);
+
+ val = force_number(s1)->numbr;
+ if (do_lint && val < 0)
+ lintwarn(_("or: argument %d negative value %g will give strange results"), i, val);
- uleft = (uintmax_t) left;
- uright = (uintmax_t) right;
+ uval = (uintmax_t) val;
+ res |= uval;
+
+ DEREF(s1);
+ }
- res = uleft | uright;
return make_integer(res);
}
@@ -3091,34 +3085,33 @@ do_or(int nargs)
NODE *
do_xor(int nargs)
{
- NODE *s1, *s2;
- uintmax_t uleft, uright, res;
- AWKNUM left, right;
+ NODE *s1;
+ uintmax_t res, uval;
+ AWKNUM val;
+ int i;
- POP_TWO_SCALARS(s1, s2);
+ if (nargs < 2)
+ fatal(_("xor: called with less than two arguments"));
- if (do_lint) {
- if ((s1->flags & (NUMCUR|NUMBER)) == 0)
- lintwarn(_("xor: received non-numeric first argument"));
- if ((s2->flags & (NUMCUR|NUMBER)) == 0)
- lintwarn(_("xor: received non-numeric second argument"));
- }
- left = force_number(s1)->numbr;
- right = force_number(s2)->numbr;
- if (do_lint) {
- if (left < 0 || right < 0)
- lintwarn(_("xor(%f, %f): negative values will give strange results"), left, right);
- if (double_to_int(left) != left || double_to_int(right) != right)
- lintwarn(_("xor(%f, %f): fractional values will be truncated"), left, right);
- }
+ res = 0; /* silence compiler warning */
+ for (i = 1; nargs > 0; nargs--, i++) {
+ s1 = POP_SCALAR();
+ if (do_lint && (s1->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("xor: argument %d is non-numeric"), i);
- DEREF(s1);
- DEREF(s2);
+ val = force_number(s1)->numbr;
+ if (do_lint && val < 0)
+ lintwarn(_("xor: argument %d negative value %g will give strange results"), i, val);
- uleft = (uintmax_t) left;
- uright = (uintmax_t) right;
+ uval = (uintmax_t) val;
+ if (i == 1)
+ res = uval;
+ else
+ res ^= uval;
+
+ DEREF(s1);
+ }
- res = uleft ^ uright;
return make_integer(res);
}