Implement -include (optional include) command.
[goals.git] / src / utils.ml
1 (* Goalfile utilities
2  * Copyright (C) 2019 Richard W.M. Jones
3  * Copyright (C) 2019 Red Hat Inc.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *)
19
20 open Printf
21
22 let failwithf fs = ksprintf failwith fs
23
24 let (//) = Filename.concat
25 let is_directory d = try Sys.is_directory d with Sys_error _ -> false
26
27 (* From OCaml 4.08 sources.  We can remove this when we can
28  * depend on min OCaml 4.08.
29  *)
30 let filter_map f =
31   let rec aux accu = function
32     | [] -> List.rev accu
33     | x :: l ->
34         match f x with
35         | None -> aux accu l
36         | Some v -> aux (v :: accu) l
37   in
38   aux []
39
40
41 (* From libguestfs sources. *)
42 let rec string_find s sub =
43   let len = String.length s in
44   let sublen = String.length sub in
45   let rec loop i =
46     if i <= len-sublen then (
47       let rec loop2 j =
48         if j < sublen then (
49           if s.[i+j] = sub.[j] then loop2 (j+1)
50           else -1
51         ) else
52           i (* found *)
53       in
54       let r = loop2 0 in
55       if r = -1 then loop (i+1) else r
56     ) else
57       -1 (* not found *)
58   in
59   loop 0
60
61 let isspace c =
62   c = ' '
63   (* || c = '\f' *) || c = '\n' || c = '\r' || c = '\t' (* || c = '\v' *)
64
65 let triml ?(test = isspace) str =
66   let i = ref 0 in
67   let n = ref (String.length str) in
68   while !n > 0 && test str.[!i]; do
69     decr n;
70     incr i
71   done;
72   if !i = 0 then str
73   else String.sub str !i !n
74
75 let trimr ?(test = isspace) str =
76   let n = ref (String.length str) in
77   while !n > 0 && test str.[!n-1]; do
78     decr n
79   done;
80   if !n = String.length str then str
81   else String.sub str 0 !n
82
83 let trim ?(test = isspace) str =
84   trimr ~test (triml ~test str)
85
86 let absolute_path path =
87   if not (Filename.is_relative path) then path else Sys.getcwd () // path