diff options
author | Pierre-Yves Ritschard <pyr@cvs.openbsd.org> | 2008-06-04 14:04:43 +0000 |
---|---|---|
committer | Pierre-Yves Ritschard <pyr@cvs.openbsd.org> | 2008-06-04 14:04:43 +0000 |
commit | 18645061397746019dfe96d4a76ffdf5fc144b4b (patch) | |
tree | 3c1e892c0720b0a22cc5c53b9febf16a547c45e6 /usr.bin | |
parent | 0f13c3aa8fe5b0a22b7726f3ace0fd12dc6976aa (diff) |
Extend awk with bitwise operations. This is an extension to the awk
spec and documented as such, but comes in handy from time to time.
The prototypes make it compatible with a similar GNU awk extension.
ok millert@, enthusiasm from deraadt@
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/awk/awk.1 | 21 | ||||
-rw-r--r-- | usr.bin/awk/awk.h | 8 | ||||
-rw-r--r-- | usr.bin/awk/lex.c | 8 | ||||
-rw-r--r-- | usr.bin/awk/run.c | 60 |
4 files changed, 91 insertions, 6 deletions
diff --git a/usr.bin/awk/awk.1 b/usr.bin/awk/awk.1 index e34d339174c..1d6da9ab0fb 100644 --- a/usr.bin/awk/awk.1 +++ b/usr.bin/awk/awk.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: awk.1,v 1.28 2007/06/27 21:10:39 jmc Exp $ +.\" $OpenBSD: awk.1,v 1.29 2008/06/04 14:04:42 pyr Exp $ .\" EX/EE is a Bd .\" .\" Copyright (C) Lucent Technologies 1997 @@ -23,7 +23,7 @@ .\" ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF .\" THIS SOFTWARE. .\" -.Dd $Mdocdate: June 27 2007 $ +.Dd $Mdocdate: June 4 2008 $ .Dt AWK 1 .Os .Sh NAME @@ -678,6 +678,21 @@ Executes .Fa cmd and returns its exit status. .El +.Ss Bit-Operation functions +.Bl -tag -width "lshift(a, b)" +.It Fn compl x +Returns the bitwise complement of integer argument x. +.It Fn and x y +Performs a bitwise AND on integer arguments x and y +.It Fn or x y +Performs a bitwise OR on integer arguments x and y +.It Fn xor x y +Performs a bitwise Exclusive-OR on integer arguments x and y +.It Fn lshift x n +Returns x shifted by n bits to the left. +.It Fn rshift x n +Returns y shifted by n bits to the right. +.El .Pp Functions may be defined (at the position of a pattern-action statement) thusly: @@ -756,7 +771,7 @@ The flags and .Op Fl safe , as well as the command -.Cm fflush , +.Cm fflush , compl , and , or , xor , lshift , rshift are extensions to that specification. .Sh HISTORY An diff --git a/usr.bin/awk/awk.h b/usr.bin/awk/awk.h index 2159f662d9f..8cbfda041a8 100644 --- a/usr.bin/awk/awk.h +++ b/usr.bin/awk/awk.h @@ -1,4 +1,4 @@ -/* $OpenBSD: awk.h,v 1.11 2004/12/30 01:52:48 millert Exp $ */ +/* $OpenBSD: awk.h,v 1.12 2008/06/04 14:04:42 pyr Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved @@ -127,6 +127,12 @@ extern Cell *rlengthloc; /* RLENGTH */ #define FTOUPPER 12 #define FTOLOWER 13 #define FFLUSH 14 +#define FAND 15 +#define FFOR 16 +#define FXOR 17 +#define FCOMPL 18 +#define FLSHIFT 19 +#define FRSHIFT 20 /* Node: parse tree is made of nodes, with Cell's at bottom */ diff --git a/usr.bin/awk/lex.c b/usr.bin/awk/lex.c index eaf09d1cd45..46252f1f335 100644 --- a/usr.bin/awk/lex.c +++ b/usr.bin/awk/lex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lex.c,v 1.9 2006/04/16 02:10:18 hugh Exp $ */ +/* $OpenBSD: lex.c,v 1.10 2008/06/04 14:04:42 pyr Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved @@ -48,9 +48,11 @@ Keyword keywords[] ={ /* keep sorted: binary searched */ { "BEGIN", XBEGIN, XBEGIN }, { "END", XEND, XEND }, { "NF", VARNF, VARNF }, + { "and", FAND, BLTIN }, { "atan2", FATAN, BLTIN }, { "break", BREAK, BREAK }, { "close", CLOSE, CLOSE }, + { "compl", FCOMPL, BLTIN }, { "continue", CONTINUE, CONTINUE }, { "cos", FCOS, BLTIN }, { "delete", DELETE, DELETE }, @@ -70,13 +72,16 @@ Keyword keywords[] ={ /* keep sorted: binary searched */ { "int", FINT, BLTIN }, { "length", FLENGTH, BLTIN }, { "log", FLOG, BLTIN }, + { "lshift", FLSHIFT, BLTIN }, { "match", MATCHFCN, MATCHFCN }, { "next", NEXT, NEXT }, { "nextfile", NEXTFILE, NEXTFILE }, + { "or", FFOR, BLTIN }, { "print", PRINT, PRINT }, { "printf", PRINTF, PRINTF }, { "rand", FRAND, BLTIN }, { "return", RETURN, RETURN }, + { "rshift", FRSHIFT, BLTIN }, { "sin", FSIN, BLTIN }, { "split", SPLIT, SPLIT }, { "sprintf", SPRINTF, SPRINTF }, @@ -88,6 +93,7 @@ Keyword keywords[] ={ /* keep sorted: binary searched */ { "tolower", FTOLOWER, BLTIN }, { "toupper", FTOUPPER, BLTIN }, { "while", WHILE, WHILE }, + { "xor", FXOR, BLTIN }, }; #define DEBUG diff --git a/usr.bin/awk/run.c b/usr.bin/awk/run.c index 3dccfff73a1..9aa255c3516 100644 --- a/usr.bin/awk/run.c +++ b/usr.bin/awk/run.c @@ -1,4 +1,4 @@ -/* $OpenBSD: run.c,v 1.28 2008/04/13 00:22:17 djm Exp $ */ +/* $OpenBSD: run.c,v 1.29 2008/06/04 14:04:42 pyr Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved @@ -1509,6 +1509,64 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis nextarg = nextarg->nnext; } break; + case FCOMPL: + u = ~((int)getfval(x)); + break; + case FAND: + if (nextarg == 0) { + WARNING("and requires two arguments; returning 0"); + u = 0; + break; + } + y = execute(a[1]->nnext); + u = ((int)getfval(x)) & ((int)getfval(y)); + tempfree(y); + nextarg = nextarg->nnext; + break; + case FFOR: + if (nextarg == 0) { + WARNING("or requires two arguments; returning 0"); + u = 0; + break; + } + y = execute(a[1]->nnext); + u = ((int)getfval(x)) | ((int)getfval(y)); + tempfree(y); + nextarg = nextarg->nnext; + break; + case FXOR: + if (nextarg == 0) { + WARNING("or requires two arguments; returning 0"); + u = 0; + break; + } + y = execute(a[1]->nnext); + u = ((int)getfval(x)) ^ ((int)getfval(y)); + tempfree(y); + nextarg = nextarg->nnext; + break; + case FLSHIFT: + if (nextarg == 0) { + WARNING("or requires two arguments; returning 0"); + u = 0; + break; + } + y = execute(a[1]->nnext); + u = ((int)getfval(x)) << ((int)getfval(y)); + tempfree(y); + nextarg = nextarg->nnext; + break; + case FRSHIFT: + if (nextarg == 0) { + WARNING("or requires two arguments; returning 0"); + u = 0; + break; + } + y = execute(a[1]->nnext); + u = ((int)getfval(x)) >> ((int)getfval(y)); + tempfree(y); + nextarg = nextarg->nnext; + break; case FSYSTEM: fflush(stdout); /* in case something is buffered already */ u = (Awkfloat) system(getsval(x)) / 256; /* 256 is unix-dep */ |