open Printf
let failwithf fs = ksprintf failwith fs
+
+let (//) = Filename.concat
+let is_directory d = try Sys.is_directory d with Sys_error _ -> false
+
+(* From OCaml 4.08 sources. We can remove this when we can
+ * depend on min OCaml 4.08.
+ *)
+let filter_map f =
+ let rec aux accu = function
+ | [] -> List.rev accu
+ | x :: l ->
+ match f x with
+ | None -> aux accu l
+ | Some v -> aux (v :: accu) l
+ in
+ aux []
+
+
+(* From libguestfs sources. *)
+let rec string_find s sub =
+ let len = String.length s in
+ let sublen = String.length sub in
+ let rec loop i =
+ if i <= len-sublen then (
+ let rec loop2 j =
+ if j < sublen then (
+ if s.[i+j] = sub.[j] then loop2 (j+1)
+ else -1
+ ) else
+ i (* found *)
+ in
+ let r = loop2 0 in
+ if r = -1 then loop (i+1) else r
+ ) else
+ -1 (* not found *)
+ in
+ loop 0
+
+let isspace c =
+ c = ' '
+ (* || c = '\f' *) || c = '\n' || c = '\r' || c = '\t' (* || c = '\v' *)
+
+let triml ?(test = isspace) str =
+ let i = ref 0 in
+ let n = ref (String.length str) in
+ while !n > 0 && test str.[!i]; do
+ decr n;
+ incr i
+ done;
+ if !i = 0 then str
+ else String.sub str !i !n
+
+let trimr ?(test = isspace) str =
+ let n = ref (String.length str) in
+ while !n > 0 && test str.[!n-1]; do
+ decr n
+ done;
+ if !n = String.length str then str
+ else String.sub str 0 !n
+
+let trim ?(test = isspace) str =
+ trimr ~test (triml ~test str)
+
+let absolute_path path =
+ if not (Filename.is_relative path) then path else Sys.getcwd () // path