Actually run goal code.
[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 (* From OCaml 4.08 sources.  We can remove this when we can
25  * depend on min OCaml 4.08.
26  *)
27 let filter_map f =
28   let rec aux accu = function
29     | [] -> List.rev accu
30     | x :: l ->
31         match f x with
32         | None -> aux accu l
33         | Some v -> aux (v :: accu) l
34   in
35   aux []
36
37
38 (* From libguestfs sources. *)
39 let rec string_find s sub =
40   let len = String.length s in
41   let sublen = String.length sub in
42   let rec loop i =
43     if i <= len-sublen then (
44       let rec loop2 j =
45         if j < sublen then (
46           if s.[i+j] = sub.[j] then loop2 (j+1)
47           else -1
48         ) else
49           i (* found *)
50       in
51       let r = loop2 0 in
52       if r = -1 then loop (i+1) else r
53     ) else
54       -1 (* not found *)
55   in
56   loop 0
57
58 let isspace c =
59   c = ' '
60   (* || c = '\f' *) || c = '\n' || c = '\r' || c = '\t' (* || c = '\v' *)
61
62 let triml ?(test = isspace) str =
63   let i = ref 0 in
64   let n = ref (String.length str) in
65   while !n > 0 && test str.[!i]; do
66     decr n;
67     incr i
68   done;
69   if !i = 0 then str
70   else String.sub str !i !n
71
72 let trimr ?(test = isspace) str =
73   let n = ref (String.length str) in
74   while !n > 0 && test str.[!n-1]; do
75     decr n
76   done;
77   if !n = String.length str then str
78   else String.sub str 0 !n
79
80 let trim ?(test = isspace) str =
81   trimr ~test (triml ~test str)