-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfhtagn.awk
executable file
·83 lines (83 loc) · 2.98 KB
/
fhtagn.awk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/awk -f
BEGIN {
Prog = "fhtagn"
if (!(Diff = ENVIRON["DIFF"])) Diff = "diff"
if (!(Tmp = ENVIRON["TMPDIR"])) Tmp = "/tmp"
initRnd() # additional source of "random"
All = ENVIRON["ALL"]
srand()
Success = Failed = 0
fhtagn()
}
END { if (ToDel) system("rm -f" ToDel) }
function initRnd( c) {
(c = "echo $$") | getline Rnd # using PID serves a good approximation to random
close(c)
}
function fhtagn( i,file,err,l,code,nr,line,random,exitCode,stdOutF,stdErrF,testStarted,expected,hasMoreCode) {
for (i = 1; i < ARGC; i++) {
file = ARGV[i]
for (nr = 1; (err = getline l < file) > 0; nr++) {
if (l ~ /^\$/) {
if (testStarted) # finish previous
checkTestResult(file,code,line,expected,stdOutF,stdErrF,exitCode,random)
testStarted = 1
expected = ""
# execute line starting '$', producing out & err & exit_code
ToDel = ToDel " " (stdOutF = tmpFile(random = rndS(), "out")) " " (stdErrF = tmpFile(random, "err"))
code = substr(l,2)
line = nr
if (!(hasMoreCode = l ~ /\\$/))
exitCode = run(code,stdOutF,stdErrF)
} else if (hasMoreCode) {
code = code "\n" l
if (!(hasMoreCode = l ~ /\\$/))
exitCode = run(code,stdOutF,stdErrF)
} else if (l ~ /^[|@?]/) {
# parse result block (|@?)
expected = expected l "\n"
} else if (testStarted) {
testStarted = 0
checkTestResult(file,code,line,expected,stdOutF,stdErrF,exitCode,random)
}
}
if (err) die("error reading file: " file)
close(file)
if (testStarted) {
testStarted = 0
checkTestResult(file,code,line,expected,stdOutF,stdErrF,exitCode,random)
}
}
if (All) {
printf "result=%s, failure=%d, success=%d, total=%d, files=%d\n", Failed ? "FAIL" : "SUCCESS", Failed, Success, Failed + Success, i - 1
exit !!Failed
}
}
function die(err) { print err > "/dev/stderr"; exit 2 }
function checkTestResult(file, code, line, expected, stdOutF, stdErrF, exitCode, random, actual,expectF,d) {
actual = prefixFile("|",stdOutF) prefixFile("@",stdErrF)
if (exitCode != 0) actual = actual "? " exitCode "\n"
if (expected != actual) {
Failed++
# printf "FAIL:\nexpected:\n#%s#\nactual:\n#%s#\n", expected, actual
# use diff to show the difference
print expected > (expectF = tmpFile(random, "exp"))
close(expectF)
print file ":" line ": $" code
print actual | (d = Diff " -u --label expected --label actual " expectF " -; rm " expectF)
close(d)
if (!All) exit 1
} else Success++
}
function prefixFile(prefix, fname, l,res,err) {
while ((err = getline l < fname) > 0)
res = res prefix " " l "\n"
if (err) die("error reading file: " fname)
close(fname)
return res
}
function run(code,stdOutF,stdErrF) {
return system("{" code "\n} 1>" stdOutF " 2>" stdErrF)
}
function rndS() { return int(2147483647 * rand()) "." Rnd }
function tmpFile(random, ext) { return sprintf("%s/%s.%s.%s", Tmp, Prog, random, ext) }