1echo T.func: test user-defined functions
2
3awk=${awk-../a.out}
4
5echo '10 2
62 10
710 10
810 1e1
91e1 9' | $awk '
10# tests whether function returns sensible type bits
11
12function assert(cond) { # assertion
13    if (cond) print 1; else print 0
14}
15
16function i(x) { return x }
17
18{ m=$1; n=i($2); assert(m>n) }
19' >foo1
20echo '1
210
220
230
241' >foo2
25diff foo1 foo2 || echo 'BAD: T.func (function return type)'
26
27echo 'data: data' >foo1
28$awk '
29function test1(array) { array["test"] = "data" }
30function test2(array) { return(array["test"]) }
31BEGIN { test1(foo); print "data: " test2(foo) }
32' >foo2
33diff foo1 foo2 || echo 'BAD: T.func (array type)'
34
35$awk '
36BEGIN	{ code() }
37END	{ codeout("x") }
38function code() { ; }
39function codeout(ex) { print ex }
40' /dev/null >foo1
41echo x >foo2
42diff foo1 foo2 || echo 'BAD: T.func (argument passing)'
43
44$awk '
45BEGIN { unireghf() }
46
47function unireghf(hfeed) {
48	hfeed[1]=0
49	rcell("foo",hfeed)
50	hfeed[1]=0
51	rcell("bar",hfeed)
52}
53
54function rcell(cellname,hfeed) {
55	print cellname
56}
57' >foo1
58echo "foo
59bar" >foo2
60diff foo1 foo2 || echo 'BAD: T.func (convert arg to array)'
61
62$awk '
63function f(n) {
64	if (n <= 1)
65		return 1
66	else
67		return n * f(n-1)
68}
69{ print f($1) }
70' <<! >foo2
710
721
732
743
754
765
776
787
798
809
81!
82cat <<! >foo1
831
841
852
866
8724
88120
89720
905040
9140320
92362880
93!
94diff foo1 foo2 || echo 'BAD: T.func (factorial)'
95
96$awk '
97function ack(m,n) {
98	k = k+1
99	if (m == 0) return n+1
100	if (n == 0) return ack(m-1, 1)
101	return ack(m-1, ack(m, n-1))
102}
103{ k = 0; print ack($1,$2), "(" k " calls)" }
104' <<! >foo2
1050 0
1061 1
1072 2
1083 3
1093 4
1103 5
111!
112cat <<! >foo1
1131 (1 calls)
1143 (4 calls)
1157 (27 calls)
11661 (2432 calls)
117125 (10307 calls)
118253 (42438 calls)
119!
120diff foo1 foo2 || echo 'BAD: T.func (ackermann)'
121
122$awk '
123END { print "end" }
124{ print fib($1) }
125function fib(n) {
126	if (n <= 1) return 1
127	else return add(fib(n-1), fib(n-2))
128}
129function add(m,n) { return m+n }
130BEGIN { print "begin" }
131' <<! >foo2
1321
1333
1345
13510
136!
137cat <<! >foo1
138begin
1391
1403
1418
14289
143end
144!
145diff foo1 foo2 || echo 'BAD: T.func (fib)'
146
147$awk '
148function foo() {
149	for (i = 1; i <= 2; i++)
150		return 3
151	print "should not see this"
152}
153BEGIN { foo(); exit }
154' >foo1
155grep 'should not' foo1 && echo 'BAD: T.func (return)'
156
157# this exercises multiple free of temp cells
158echo 'eqn
159eqn2' >foo1
160$awk 'BEGIN 	{ eprocess("eqn", "x", contig) 
161	  process("tbl" )
162	  eprocess("eqn" "2", "x", contig) 
163	}
164function eprocess(file, first, contig) {
165	print file
166}
167function process(file) {
168	close(file)
169}' >foo2
170diff foo1 foo2 || echo 'BAD: T.func (eqn)'
171
172echo 1 >foo1
173$awk 'function f() { n = 1; exit }
174	BEGIN { n = 0; f(); n = 2 }; END { print n}' >foo2
175diff foo1 foo2 || echo 'BAD: T.func (exit in function)'
176
177echo 1 >foo1
178$awk '
179BEGIN {	n = 10
180	for (i = 1; i <= n; i++)
181	for (j = 1; j <= n; j++)
182		x[i,j] = n * i + j
183	for (i = 1; i <= n; i++)
184	for (j = 1; j <= n; j++)
185		if ((i,j) in x)
186			k++
187	print (k == n^2)
188      }
189' >foo2
190diff foo1 foo2 || echo 'BAD: T.func (multi-dim subscript)'
191
192echo '<> 0' >foo1
193$awk '
194function foo() { i = 0 }
195        BEGIN { x = foo(); printf "<%s> %d\n", x, x }' >foo2
196diff foo1 foo2 || echo 'BAD: T.func (fall off end)'
197