let find ?(follow = Skip) tst fln exec accu =
let ctest = compile_filter (And(tst,Not(Or(Is_parent_dir,Is_current_dir))))
in
let cdir = compile_filter (And(Is_dir,Not(Or(Is_parent_dir,Is_current_dir))))
in
let clink = fun fln ->
if test Is_link fln then
match follow with
Follow -> true
| Skip -> false
| SkipInform f -> f fln; false
| AskFollow f -> f fln
else
true
in
let rec find_dir (already_read,accu) fln =
let _ = dbug_print ("Entering dir : "^(fln))
in
let newly_read = prevent_recursion already_read (make_absolute (pwd ()) (readlink fln))
in
let _ = dbug_print "Recursion test passed"
in
let dir_content = ls fln
in
let _ = dbug_print_list "Directory listing" dir_content
in
let new_accu = List.fold_left exec accu (List.filter ctest dir_content)
in
let directories = List.filter clink (List.filter cdir dir_content)
in
if directories = [] then
(newly_read,new_accu)
else
List.fold_left find_dir (newly_read,new_accu) directories
in
let find_simple (already_read,accu) fln =
let new_accu =
if ctest fln then
exec accu fln
else
accu
in
if test Is_dir fln then
find_dir (already_read,new_accu) fln
else
(already_read,new_accu)
in
snd(find_simple (SetFilename.empty,accu) fln)