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
|
(***********************************************************************)
(* *)
(* Objective Caml *)
(* *)
(* Jun Furuse, projet Cristal, INRIA Rocquencourt *)
(* *)
(* Copyright 1999,2000,2001,2002,2001,2002 *)
(* Institut National de Recherche en Informatique et en Automatique. *)
(* Distributed only by permission. *)
(* *)
(***********************************************************************)
open Unix
let ignore_dirs = ref [".xvpics"]
let scan_dir f fn =
let scanned = ref [] in
let rec sub fn =
let st = stat fn in
match st.st_kind with
| S_DIR ->
if List.mem st.st_ino !scanned then ()
else begin
scanned := st.st_ino :: !scanned;
let dh = opendir fn in
let files = ref [] in
begin try while true do
files := (readdir dh) :: !files
done with End_of_file -> ()
| e -> prerr_endline ("readdir: " ^Printexc.to_string e) end;
closedir dh;
let files = Sort.list (>) !files in
let subdirs = ref [] in
List.iter (fun fn' ->
if not (fn' = ".." || fn' = ".") then begin
let fn'' = Filename.concat (if fn = "." then "" else fn) fn' in
try
let st = Unix.stat fn'' in
match st.st_kind with
| S_DIR -> (* sub-dir check is delayed *)
if not (List.mem fn' !ignore_dirs) then
subdirs := fn'' :: !subdirs
| _ ->
f fn'' (* or sub fn', but it's more efficient *)
with
Unix.Unix_error(_,"stat",_) ->
prerr_endline (fn''^": stat failed")
| e -> prerr_endline (fn''^": "^Printexc.to_string e)
end) files;
List.iter sub (List.rev !subdirs);
end
| _ -> f fn
in
sub fn
;;
|