# tests for the tw utility
function DATA
{
typeset f i j k
for f
do test -d $f && continue
KEEP $f
case $f in
data) mkdir data
for i in aaa zzz
do i=data/$i
mkdir $i
for j in 111 222 333
do mkdir $i/$j
for k in 4 5 6 7
do mkdir $i/$j/$k
do print $i $j $k $l > $i/$j/$k/$l
chmod $k$k$k $i/$j/$k/$l
done
done
done
done
;;
link) mkdir -p link/x/y/z
ln -s x/y link/home
;;
match) mkdir -p match/.ghi match/jkl
: > match/.abc > match/def
: > match/.ghi/.mno > match/.ghi/pqr
: > match/jkl/.stu > match/jkl/vwx
;;
mode) mkdir mode
for i in 0 1 2 3 4 5 6 7
do : > mode/$i$i$i
chmod $i$i$i mode/$i$i$i
done
;;
one) mkdir one
> one/one
;;
esac
done
}
TEST 01 'basics'
DO DATA data
EXEC -d data -e sort:name
OUTPUT - $'data
data/aaa/111
data/aaa/111/4
data/aaa/111/5
data/aaa/111/6
data/aaa/111/7
data/aaa/222
data/aaa/222/4
data/aaa/222/5
data/aaa/222/6
data/aaa/222/7
data/aaa/333
data/aaa/333/4
data/aaa/333/5
data/aaa/333/6
data/aaa/333/7
data/zzz/111
data/zzz/111/4
data/zzz/111/5
data/zzz/111/6
data/zzz/111/7
data/zzz/222
data/zzz/222/4
data/zzz/222/5
data/zzz/222/6
data/zzz/222/7
data/zzz/333
data/zzz/333/4
data/zzz/333/5
data/zzz/333/6
data/zzz/333/7
TEST 02 'patterns'
DO DATA data
EXEC -d data -e sort:name -e 'name=="*.c"'
EXEC -d data -e sort:name -e 'name=="*.[cd]"'
EXEC -d data -e sort:name -e 'name=="*.c" || name=="*.d"'
TEST 03 'types'
DO DATA data
EXEC -d data -e sort:name -e type==DIR
OUTPUT - $'data
data/aaa/111
data/aaa/111/4
data/aaa/111/5
data/aaa/111/6
data/aaa/111/7
data/aaa/222
data/aaa/222/4
data/aaa/222/5
data/aaa/222/6
data/aaa/222/7
data/aaa/333
data/aaa/333/4
data/aaa/333/5
data/aaa/333/6
data/aaa/333/7
data/zzz/111
data/zzz/111/4
data/zzz/111/5
data/zzz/111/6
data/zzz/111/7
data/zzz/222
data/zzz/222/4
data/zzz/222/5
data/zzz/222/6
data/zzz/222/7
data/zzz/333
data/zzz/333/4
data/zzz/333/5
data/zzz/333/6
data/zzz/333/7'
EXEC -d data -e sort:name -e type==REG
TEST 04 'symlink hops'
DO DATA link
EXEC -d link -e sort:name -e "if(name=='home')status=FOLLOW;"
OUTPUT - $'link
link/x
link/x/y
link/x/y/z'
TEST 05 '-name pattern'
DO DATA match
EXEC -d match -e sort:name
OUTPUT - $'match
match/.abc
match/.ghi
match/.ghi/.mno
match/.ghi/pqr
match/jkl/.stu
EXEC -d match -e sort:name -e 'name=="*"'
EXEC -d match -e sort:name -e 'path=="*"'
EXEC -d match -e sort:name -e 'name==".*"'
OUTPUT - $'match/.abc
match/.ghi
match/.ghi/.mno
match/jkl/.stu'
EXEC -d match -e sort:name -e 'name=="*.*"'
TEST 06 'expressions and functions'
EXEC -n -e ' int i;
char* s = "abc pdq xyz";
char* a, p, x;
i = sscanf(s, "%s %s %s", &a, &p, &x);
printf("i=%d a=\"%s\" p=\"%s\" x=\"%s\"\n", i, a, p, x);'
OUTPUT - 'i=3 a="abc" p="pdq" x="xyz"'
EXEC -n -e ' int i;
char* s = "abc pdq xyz";
char* a, p, x;
i = sscanf(s, "%s %s %s", &a, &p, &x);
printf("i=%d x=\"%s\" p=\"%s\" a=\"%s\"\n", i, x, p, a);'
OUTPUT - 'i=3 x="xyz" p="pdq" a="abc"'
EXEC -n -e ' int i;
char* s = "abc pdq xyz";
char* a, p, x;
i = sscanf(s, "%s", &a);
printf("i=%d a=\"%s\"\n", i, a);
i = sscanf(s, "%s %s", &a, &p);
printf("i=%d a=\"%s\" p=\"%s\"\n", i, a, p);
i = sscanf(s, "%s %s %s", &a, &p, &x);
printf("i=%d a=\"%s\" p=\"%s\" x=\"%s\"\n", i, a, p, x);
i = sscanf(s, "%s %s %s", &a, &p, &x);
printf("i=%d x=\"%s\" p=\"%s\" a=\"%s\"\n", i, x, p, a);
printf("i=%d a=\"%s\" p=\"%s\" x=\"%s\"\n", i, a, p, x);'
OUTPUT - 'i=1 a="abc"
i=2 a="abc" p="pdq"
i=3 a="abc" p="pdq" x="xyz"
i=3 x="xyz" p="pdq" a="abc"
i=3 a="abc" p="pdq" x="xyz"'
EXEC -n -e ' int i,n;
float f;
char* s = "123 3.45e6";
i = sscanf(s,"%d %g", &n, &f);
printf("i=%d n=%d f=%g\n", i, n, f);'
OUTPUT - 'i=2 n=123 f=3.45e+06'
EXEC -n -e ' int i,n;
float f;
i = scanf("%d %g", &n, &f);
printf("i=%d n=%d f=%g\n", i, n, f);'
INPUT - '123 3.45e6'
EXEC -n -e ' int n,i,j,k;
char* s = "1";
n = sscanf(s,"%d %d %d", &i, &j, &k);
printf("n=%d i=%d j=%d k=%d\n", n, i, j, k);'
OUTPUT - $'n=1 i=1 j=0 k=0'
EXEC -n -e ' int i,n;
float f;
char* s = "123 3.45e6";
i = sscanf(s,"%d %g", n, &f);
printf("i=%d n=%d f=%g\n", i, n, f);'
EXIT 1
OUTPUT -
ERROR - 'tw: line 4: i = sscanf(s,"%d %g", n, &f)<<< sscanf: address argument expected'
EXEC -n -e ' int i,n;
float f;
char* s = "123 3.45e6";
i = sscanf(s,"%d %g", &n, f);
printf("i=%d n=%d f=%g\n", i, n, f);'
ERROR - 'tw: line 4: i = sscanf(s,"%d %g", &n, f)<<< sscanf: address argument expected'
EXEC -n -e ' int i,n;
float f;
char* s = "123 3.45e6";
i = sscanf(s);
printf("i=%d n=%d f=%g\n", i, n, f);'
ERROR - 'tw: line 4: i = sscanf(s)<<< sscanf: format argument expected'
EXEC -n -e ' int i,n;
float f;
char* s = "123 3.45e6";
i = sscanf(s,"%d %g");
printf("i=%d n=%d f=%g\n", i, n, f);'
ERROR - 'tw: scanf: not enough arguments'
EXEC -n -e ' int i,n;
float f;
char* s = "123 3.45e6";
i = sscanf(s,"%d %g", &n);
printf("i=%d n=%d f=%g\n", i, n, f);'
ERROR - 'tw: scanf: not enough arguments'
EXEC -n -e ' int i,n;
float f;
char* s = "123 3.45e6";
i = sscanf(s,"%d %g", &n, &f, &i);
printf("i=%d n=%d f=%g\n", i, n, f);'
ERROR - 'tw: scanf: i: too many arguments'
EXEC -n -e ' int i,n;
float f;
char* s = "123 3.45e6";
i = sscanf(s,"%d %g", &f, &f);
printf("i=%d n=%d f=%g\n", i, n, f);'
ERROR - 'tw: scanf: f: integer variable address argument expected'
EXEC -n -e ' int i,n;
float f;
char* s = "123 3.45e6";
i = sscanf(s,"%d %g", &n, &n);
printf("i=%d n=%d f=%g\n", i, n, f);'
ERROR - 'tw: scanf: n: floating variable address argument expected'
TEST 07 'function and variable scoping'
EXEC -n \
-e 'static int i = 1; int foo() { return i++; }' \
-e 'static int i = 11; int bar() { return i++; }' \
-e 'int end() { int i; for (i = 0; i < 8; i++) printf("%2d %2d\n", foo(), bar()); }'
OUTPUT - $' 1 11\n 2 12\n 3 13\n 4 14\n 5 15\n 6 16\n 7 17\n 8 18'
EXEC -n \
-e 'int i = 1; int foo() { return i++; }' \
-e 'int bar() { return i++; }' \
-e 'int end() { for (i = 0; i < 8; i++) printf("%2d %2d\n", foo(), bar()); }'
OUTPUT - $' 0 1\n 3 4\n 6 7'
EXEC -n \
-e 'int i = 1; int foo() { return i++; }' \
-e 'int bar() { return i++; }' \
-e 'int end() { int i; for (i = 0; i < 8; i++) printf("%2d %2d\n", foo(), bar()); }'
OUTPUT - $' 1 2\n 3 4\n 5 6\n 7 8\n 9 10\n11 12\n13 14\n15 16'
EXEC -n \
-e 'int i = 1; int foo() { return i++; }' \
-e 'int bar() { return i++; }' \
-e 'int end() { int j; for (j = 0; j < 8; j++) printf("%2d %2d\n", foo(), bar()); }'
TEST 08 'function declaration order'
EXEC -e '
action: return 0;
begin: printf("begin\n");
select: type == REG;
'
OUTPUT - begin
EXEC -e '
action: return;
select: type == REG;
begin: printf("begin\n");
'
EXEC -e '
begin: printf("begin\n");
action: return;
select: type == REG;
'
EXEC -e '
begin: printf("begin\n");
select: type == REG;
action: return;
'
EXEC -e '
select: type == REG;
action: return;
begin: printf("begin\n");
'
EXEC -e '
select: type == REG;
begin: printf("begin\n");
action: return;
'
TEST 09 'sum() functions'
DO DATA data
EXEC -d data -e '
sort: name;
select: type == REG;
action: printf("%s %s\n", md5sum, path);
'
EXEC -d data -e '
sort: name;
select: type == REG;
action: printf("%s %s\n", sum("md5"), path);
'
EXEC -d data -e '
sort: name;
select: type == REG;
action: printf("%s %s\n", sum("sha1"), path);
'
EXEC -d data -e '
sort: name;
select: type == REG;
action: printf("%s %s\n", sum("tw"), path);
'
TEST 10 'symbol table scope'
DO DATA one
EXEC -d one -e '
begin: printf("begin:\n");
select: if (type == REG) printf("select: %s\n", path); else return 0;
action: printf("action: %s\n", path);
end: printf("end:\n");
'