1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
open Fugue
(** [index_pred p s] returns the index of the first character in [s] satisfying predicate [p].
@raise Not_found if no character satisfies the predicate *)
let index_pred p s =
let len = String.length s in
let i = ref 0 in
while !i < len && not (p s.[!i]) do
i := !i + 1
done;
if !i == len then
raise Not_found
else
!i
(** [strip_predicate p s] removes leading and trailing characters satisfying predicate [p] from [s]
*)
let rec split ?(limit = -1) c s =
let i = try String.index s c with Not_found -> -1 in
let nlimit = if limit = -1 || limit = 0 then limit else limit - 1 in
if i = -1 || nlimit = 0 then
[ s ]
else
let a = String.sub s 0 i and b = String.sub s (i + 1) (String.length s - i - 1) in
a :: split ~limit:nlimit c b
let rec split_pred ?(limit = -1) p s =
let i = try index_pred p s with Not_found -> -1 in
let nlimit = if limit = -1 || limit = 0 then limit else limit - 1 in
if i = -1 || nlimit = 0 then
[ s ]
else
let a = String.sub s 0 i and b = String.sub s (i + 1) (String.length s - i - 1) in
a :: split_pred ~limit:nlimit p b
let startswith prefix x =
let x_l = String.length x and prefix_l = String.length prefix in
prefix_l <= x_l && String.sub x 0 prefix_l = prefix
let endswith suffix x = Filename.check_suffix x suffix
let strip_predicate p str =
let len = String.length str in
let s = ref 0 in
let e = ref (String.length str) in
while !s < len && p str.[!s] do
s := !s + 1
done;
let start = !s in
while !e > start && p str.[!e - 1] do
e := !e - 1
done;
String.sub str start (!e - start)
let strip_spaces = strip_predicate (fun c -> c = ' ' || c = '\t' || c = '\n')
let split_at pos s =
let len = String.length s in
if pos > len then
invalid_arg "splitAt"
else
(String.sub s 0 pos, String.sub s pos (len - pos))
let drop n s =
let len = String.length s in
if n > len then
invalid_arg "String.drop"
else
String.sub s n (len - n)
let init n s =
let len = String.length s in
if n > len then
invalid_arg "String.init"
else
String.sub s 0 (len - n)
let all p s =
let len = String.length s in
let rec loop i = if i = len then true else if not (p s.[i]) then false else loop (i + 1) in
loop 0
let escape_ocaml_string s =
let buf = Buffer.create (String.length s) in
for i = 0 to String.length s - 1 do
match s.[i] with
| '\\' -> Buffer.add_string buf "\\\\"
| '"' -> Buffer.add_string buf "\\\""
| '\n' -> Buffer.add_string buf "\\n"
| '\r' -> Buffer.add_string buf "\\r"
| '\t' -> Buffer.add_string buf "\\t"
| c -> Buffer.add_char buf c
done;
Buffer.contents buf
let escape_c_string s =
let buf = Buffer.create (String.length s) in
for i = 0 to String.length s - 1 do
match s.[i] with
| '\\' -> Buffer.add_string buf "\\\\"
| '"' -> Buffer.add_string buf "\\\""
| '\n' -> Buffer.add_string buf "\\n"
| '\r' -> Buffer.add_string buf "\\r"
| '\t' -> Buffer.add_string buf "\\t"
| '%' -> Buffer.add_string buf "%%"
| c -> Buffer.add_char buf c
done;
Buffer.contents buf
let strip_cr s =
let len = String.length s in
if len > 0 && s.[len - 1] = '\r' then String.sub s 0 (len - 1) else s
let lines s = List.map strip_cr (split '\n' s)
let words s = split_pred (fun c -> c = ' ' || c = '\n' || c = '\t') s
let words_noempty s = no_empty "" (words s)
let lines_noempty s = no_empty "" (lines s)
|