Initial commit.
[todo.git] / todo_utils.ml
1 (* Utility functions. *)
2
3 open CalendarLib
4
5 open Printf
6
7 let rec find s sub =
8   let len = String.length s in
9   let sublen = String.length sub in
10   let rec loop i =
11     if i <= len-sublen then (
12       let rec loop2 j =
13         if j < sublen then (
14           if s.[i+j] = sub.[j] then loop2 (j+1)
15           else -1
16         ) else
17           i (* found *)
18       in
19       let r = loop2 0 in
20       if r = -1 then loop (i+1) else r
21     ) else
22       -1 (* not found *)
23   in
24   loop 0
25
26 let rec nsplit sep str =
27   let len = String.length str in
28   let seplen = String.length sep in
29   let i = find str sep in
30   if i = -1 then [str]
31   else (
32     let s' = String.sub str 0 i in
33     let s'' = String.sub str (i+seplen) (len-i-seplen) in
34     s' :: nsplit sep s''
35   )
36
37 let error fs =
38   let display str =
39     prerr_string "todo: error: ";
40     prerr_endline str;
41     exit 1
42   in
43   ksprintf display fs
44
45 let string_of_estimate period =
46   (* We ignore the seconds, and assume every estimate is >= 1 day. *)
47   let (years, months, days, _) = Calendar.Period.ymds period in
48   let buf = Buffer.create 13 in
49   let append str =
50     if Buffer.length buf > 0 then
51       Buffer.add_string buf ", ";
52     Buffer.add_string buf str
53   in
54   if years >= 2 then append (sprintf "%d years" years)
55   else if years = 1 then append "1 year";
56   if months >= 2 then append (sprintf "%d months" months)
57   else if months = 1 then append "1 month";
58   if days >= 2 then append (sprintf "%d days" days)
59   else if days = 1 then append "1 day";
60   let str = Buffer.contents buf in
61   if str <> "" then str else "-"