let opt_of_string = function
"" -> None
| s -> Some s
let string_of_opt = function
None -> ""
| Some s -> s
let no_blanks s =
let len = String.length s in
let buf = Buffer.create len in
for i = 0 to len - 1 do
match s.[i] with
' ' | '\n' | '\t' | '\r' -> ()
| c -> Buffer.add_char buf c
done;
Buffer.contents buf
let keep_alpha_nums s =
let len = String.length s in
let b = Buffer.create len in
for i = 0 to len - 1 do
match s.[i] with
'a'..'z'
| 'A'..'Z'
| '0'..'9' -> Buffer.add_char b s.[i]
| _ -> ()
done;
Buffer.contents b
let chop_n_char n s =
let len = String.length s in
if len <= n +1 or n < 0 then
s
else
Printf.sprintf "%s..." (String.sub s 0 (n+1))
let string_of_date =
let raw_string_of_date ~f_mon ~f_wday ~wday ~hours ~secs d =
let tm = Unix.localtime d in
let mon = f_mon tm.Unix.tm_mon in
let day = f_wday tm.Unix.tm_wday in
Printf.sprintf
"%s%02d-%s-%4d%s"
(if wday then day^", " else "")
tm.Unix.tm_mday mon (tm.Unix.tm_year + 1900)
(
if hours then
Printf.sprintf " %02d:%02d%s"
tm.Unix.tm_hour tm.Unix.tm_min
(if secs then Printf.sprintf ":%02d" tm.Unix.tm_sec else "")
else
""
)
in
let mon_of_int_fr = function
0 -> "Jan"
| 1 -> "Fev"
| 2 -> "Mar"
| 3 -> "Avr"
| 4 -> "Mai"
| 5 -> "Jui"
| 6 -> "Jul"
| 7 -> "Aou"
| 8 -> "Sep"
| 9 -> "Oct"
| 10 -> "Nov"
| _ -> "Dec"
in
let wday_of_int_fr = function
0 -> "Dimanche"
| 1 -> "Lundi"
| 2 -> "Mardi"
| 3 -> "Mercredi"
| 4 -> "Jeudi"
| 5 -> "Vendredi"
| _ -> "Samedi"
in
let mon_of_int_en = function
0 -> "Jan"
| 1 -> "Feb"
| 2 -> "Mar"
| 3 -> "Apr"
| 4 -> "May"
| 5 -> "Jun"
| 6 -> "Jul"
| 7 -> "Aug"
| 8 -> "Sep"
| 9 -> "Oct"
| 10 -> "Nov"
| _ -> "Dec"
in
let wday_of_int_en = function
0 -> "Sunday"
| 1 -> "Monday"
| 2 -> "Tuesday"
| 3 -> "Wednesday"
| 4 -> "Thursday"
| 5 -> "Friday"
| _ -> "Saturday"
in
fun ?(fr=false)
?(wday=false) ?(hours=true) ?(secs=false) d ->
let (f_mon, f_wday) =
if fr then
(mon_of_int_fr, wday_of_int_fr)
else
(mon_of_int_en, wday_of_int_en)
in
raw_string_of_date ~f_mon ~f_wday
~wday ~hours ~secs d
let string_of_in_channel ic =
let len = 1024 in
let s = String.create len in
let buf = Buffer.create len in
let rec iter () =
try
let n = input ic s 0 len in
if n = 0 then
()
else
(
Buffer.add_substring buf s 0 n;
iter ()
)
with
End_of_file -> ()
in
iter ();
Buffer.contents buf
let first_sentence ?(limit=40) s =
let rec get_before_dot s =
try
let len = String.length s in
let n = String.index s '.' in
if n + 1 >= len then
(true, s)
else
(
match s.[n+1] with
' ' | '\n' | '\r' | '\t' ->
(true, String.sub s 0 (n+1))
| _ ->
let (b, s2) = get_before_dot (String.sub s (n + 1) (len - n - 1)) in
(b, (String.sub s 0 (n+1))^s2)
)
with
Not_found -> (false, s)
in
let len = String.length s in
let s_limited =
if len > limit then
String.sub s 0 limit
else
s
in
let (found, res) = get_before_dot s_limited in
if found then
res
else
if len > limit then
if limit > 3 then
(String.sub s_limited 0 (limit - 3) ^ "...")
else
s_limited
else
s
let lowercase s =
let len = String.length s in
let b = Buffer.create len in
for i = 0 to len - 1 do
let c =
match s.[i] with
| 'à' | 'â' | 'ä' -> 'a'
| 'é' | 'è' | 'ê' | 'ë' -> 'e'
| 'î' | 'ï' -> 'i'
| 'ô' | 'ö' -> 'o'
| 'ù' | 'û' | 'ü' -> 'u'
| 'ç' -> 'c'
| c -> Char.lowercase c
in
Buffer.add_char b c
done;
Buffer.contents b
let capitalize_name s =
let len = String.length s in
let b = Buffer.create len in
let last_was_blank = ref true in
for i = 0 to len - 1 do
match s.[i] with
'-' | '_' | ' ' | '\t' | '\r' | '\n' | '\'' ->
last_was_blank := true ;
Buffer.add_char b s.[i]
| c ->
let c2 =
(if !last_was_blank then
if i + 1 < len then
match s.[i+1] with
'\'' -> Char.lowercase
| c2 ->
match c with
'd' | 'D' ->
if i + 2 < len then
match s.[i+2] with
' ' | '\t' | '\n' | '\r' ->
(match c2 with
'e' | 'u' | 'i' -> Char.lowercase
| _ -> Char.uppercase
)
| _ ->
Char.uppercase
else
Char.uppercase
| _ ->
Char.uppercase
else
Char.uppercase
else
Char.lowercase
)
c
in
Buffer.add_char b c2;
last_was_blank := false;
done;
Buffer.contents b
let split_string ?(keep_empty=false) s chars =
let len = String.length s in
let rec iter acc pos =
if pos >= len then
match acc with
"" -> []
| _ -> [acc]
else
if List.mem s.[pos] chars then
match acc with
"" ->
if keep_empty then
"" :: iter "" (pos + 1)
else
iter "" (pos + 1)
| _ -> acc :: (iter "" (pos + 1))
else
iter (Printf.sprintf "%s%c" acc s.[pos]) (pos + 1)
in
iter "" 0
let count_char s c =
let cpt = ref 0 in
for i = 0 to String.length s - 1 do
if s.[i] = c then incr cpt
done;
!cpt
let is_prefix s1 s2 =
let len1 = String.length s1 in
let len2 = String.length s2 in
(len1 <= len2) &&
(String.sub s2 0 len1) = s1
let replace_in_string ~pat ~subs ~s =
let len_pat = String.length pat in
let len = String.length s in
let b = Buffer.create len in
let rec iter pos =
if pos >= len then
()
else
if pos + len_pat > len then
Buffer.add_string b (String.sub s pos (len - pos))
else
if String.sub s pos len_pat = pat then
(
Buffer.add_string b subs;
iter (pos+len_pat)
)
else
(
Buffer.add_char b s.[pos];
iter (pos+1);
)
in
iter 0;
Buffer.contents b
let strip_string s =
let len = String.length s in
let rec iter_first n =
if n >= len then
None
else
match s.[n] with
' ' | '\t' | '\n' | '\r' -> iter_first (n+1)
| _ -> Some n
in
match iter_first 0 with
None -> ""
| Some first ->
let rec iter_last n =
if n <= first then
None
else
match s.[n] with
' ' | '\t' | '\n' | '\r' -> iter_last (n-1)
| _ -> Some n
in
match iter_last (len-1) with
None -> String.sub s first 1
| Some last -> String.sub s first ((last-first)+1)