File: string_utils.ml

package info (click to toggle)
ocaml-obuild 0.2.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,456 kB
  • sloc: ml: 14,491; sh: 211; ansic: 34; makefile: 11
file content (117 lines) | stat: -rw-r--r-- 3,469 bytes parent folder | download
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)