(** {2 Optional values} *)
let map_option f = function None -> None | Some v -> Some (f v)
+let iter_option f = function None -> () | Some v -> f v
let unopt = function None -> failwith "unopt: None" | Some v -> v
(** {2 String processing} *)
| None -> filter_map f tl
| Some v -> v :: filter_map f tl)
+let list_concat ?(sep = []) =
+ let rec aux acc =
+ function
+ | [] -> []
+ | [ last ] -> List.flatten (List.rev (last :: acc))
+ | hd :: tl -> aux ([sep; hd] @ acc) tl
+ in
+ aux []
+
(** {2 File predicates} *)
let is_dir fname =
let oc = open_out filename in
output_string oc text;
close_out oc
+
+let find ?(test = fun _ -> true) path =
+ let rec aux acc todo =
+ match todo with
+ | [] -> acc
+ | path :: tl ->
+ try
+ let handle = Unix.opendir path in
+ let dirs = ref [] in
+ let matching_files = ref [] in
+ (try
+ while true do
+ match Unix.readdir handle with
+ | "." | ".." -> ()
+ | entry ->
+ let qentry = path ^ "/" ^ entry in
+ (try
+ if is_dir qentry then
+ dirs := qentry :: !dirs
+ else if test qentry then
+ matching_files := qentry :: !matching_files;
+ with Unix.Unix_error _ -> ())
+ done
+ with End_of_file -> Unix.closedir handle);
+ aux (!matching_files @ acc) (!dirs @ tl)
+ with Unix.Unix_error _ -> aux acc tl
+ in
+ aux [] [path]
(** {2 Exception handling} *)