| None -> filter_map f tl
| Some v -> v :: filter_map f tl)
+let list_rev_map_filter f l =
+ let rec aux a = function
+ | [] -> a
+ | hd :: tl ->
+ begin match f hd with
+ | None -> aux a tl
+ | Some b -> aux (b :: a) tl
+ end
+ in
+ aux [] l
+
+let list_rev_map_filter_fold f v l =
+ let rec aux v a = function
+ | [] -> v, a
+ | hd :: tl ->
+ begin match f v hd with
+ | v, None -> aux v a tl
+ | v, Some b -> aux v (b :: a) tl
+ end
+ in
+ aux v [] l
+
let list_concat ?(sep = []) =
let rec aux acc =
function
in
aux l
+let split_nth n l =
+ let rec aux acc n l =
+ match n, l with
+ | 0, _ -> List.rev acc, l
+ | n, [] -> raise (Failure "HExtlib.split_nth")
+ | n, hd :: tl -> aux (hd :: acc) (n - 1) tl in
+ aux [] n l
+
+let list_last l =
+ let l = List.rev l in
+ try List.hd l with exn -> raise (Failure "HExtlib.list_last")
+;;
+
(** {2 File predicates} *)
let is_dir fname =
(Unix.stat fname).Unix.st_kind = Unix.S_DIR
with Unix.Unix_error _ -> false
+let writable_dir path =
+ try
+ let file = path ^ "/prova_matita" in
+ let oc = open_out file in
+ close_out oc;
+ Sys.remove file;
+ true
+ with Sys_error _ -> false
+
+
let is_regular fname =
try
(Unix.stat fname).Unix.st_kind = Unix.S_REG
with Unix.Unix_error _ -> false
+let is_executable fname =
+ try
+ let stat = (Unix.stat fname) in
+ stat.Unix.st_kind = Unix.S_REG &&
+ (stat.Unix.st_perm land 0o001 > 0)
+ with Unix.Unix_error _ -> false
+
let mkdir path =
let components = split ~sep:'/' path in
let rec aux where = function