echo T.func: test user-defined functions awk=${awk-../a.out} echo '10 2 2 10 10 10 10 1e1 1e1 9' | $awk ' # tests whether function returns sensible type bits function assert(cond) { # assertion if (cond) print 1; else print 0 } function i(x) { return x } { m=$1; n=i($2); assert(m>n) } ' >foo1 echo '1 0 0 0 1' >foo2 diff foo1 foo2 || echo 'BAD: T.func (function return type)' echo 'data: data' >foo1 $awk ' function test1(array) { array["test"] = "data" } function test2(array) { return(array["test"]) } BEGIN { test1(foo); print "data: " test2(foo) } ' >foo2 diff foo1 foo2 || echo 'BAD: T.func (array type)' $awk ' BEGIN { code() } END { codeout("x") } function code() { ; } function codeout(ex) { print ex } ' /dev/null >foo1 echo x >foo2 diff foo1 foo2 || echo 'BAD: T.func (argument passing)' $awk ' BEGIN { unireghf() } function unireghf(hfeed) { hfeed[1]=0 rcell("foo",hfeed) hfeed[1]=0 rcell("bar",hfeed) } function rcell(cellname,hfeed) { print cellname } ' >foo1 echo "foo bar" >foo2 diff foo1 foo2 || echo 'BAD: T.func (convert arg to array)' $awk ' function f(n) { if (n <= 1) return 1 else return n * f(n-1) } { print f($1) } ' <foo2 0 1 2 3 4 5 6 7 8 9 ! cat <foo1 1 1 2 6 24 120 720 5040 40320 362880 ! diff foo1 foo2 || echo 'BAD: T.func (factorial)' $awk ' function ack(m,n) { k = k+1 if (m == 0) return n+1 if (n == 0) return ack(m-1, 1) return ack(m-1, ack(m, n-1)) } { k = 0; print ack($1,$2), "(" k " calls)" } ' <foo2 0 0 1 1 2 2 3 3 3 4 3 5 ! cat <foo1 1 (1 calls) 3 (4 calls) 7 (27 calls) 61 (2432 calls) 125 (10307 calls) 253 (42438 calls) ! diff foo1 foo2 || echo 'BAD: T.func (ackermann)' $awk ' END { print "end" } { print fib($1) } function fib(n) { if (n <= 1) return 1 else return add(fib(n-1), fib(n-2)) } function add(m,n) { return m+n } BEGIN { print "begin" } ' <foo2 1 3 5 10 ! cat <foo1 begin 1 3 8 89 end ! diff foo1 foo2 || echo 'BAD: T.func (fib)' $awk ' function foo() { for (i = 1; i <= 2; i++) return 3 print "should not see this" } BEGIN { foo(); exit } ' >foo1 grep 'should not' foo1 && echo 'BAD: T.func (return)' # this exercises multiple free of temp cells echo 'eqn eqn2' >foo1 $awk 'BEGIN { eprocess("eqn", "x", contig) process("tbl" ) eprocess("eqn" "2", "x", contig) } function eprocess(file, first, contig) { print file } function process(file) { close(file) }' >foo2 diff foo1 foo2 || echo 'BAD: T.func (eqn)' echo 1 >foo1 $awk 'function f() { n = 1; exit } BEGIN { n = 0; f(); n = 2 }; END { print n}' >foo2 diff foo1 foo2 || echo 'BAD: T.func (exit in function)' echo 1 >foo1 $awk ' BEGIN { n = 10 for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) x[i,j] = n * i + j for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) if ((i,j) in x) k++ print (k == n^2) } ' >foo2 diff foo1 foo2 || echo 'BAD: T.func (multi-dim subscript)' echo '<> 0' >foo1 $awk ' function foo() { i = 0 } BEGIN { x = foo(); printf "<%s> %d\n", x, x }' >foo2 diff foo1 foo2 || echo 'BAD: T.func (fall off end)'