diff options
| author | ppedrot | 2012-11-13 22:38:00 +0000 |
|---|---|---|
| committer | ppedrot | 2012-11-13 22:38:00 +0000 |
| commit | 1d436a18f2f72b57ea09a6d27709a36b63be863a (patch) | |
| tree | 0082ab298988502105c7f71baa5a240051b82fdf /lib | |
| parent | 81ca535c9888bc578d8f9274568ace0d8e7b2d35 (diff) | |
Added a CString module.
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@15968 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/cString.ml | 152 | ||||
| -rw-r--r-- | lib/cString.mli | 63 | ||||
| -rw-r--r-- | lib/clib.mllib | 1 | ||||
| -rw-r--r-- | lib/envars.ml | 6 | ||||
| -rw-r--r-- | lib/util.ml | 96 | ||||
| -rw-r--r-- | lib/util.mli | 11 |
6 files changed, 224 insertions, 105 deletions
diff --git a/lib/cString.ml b/lib/cString.ml new file mode 100644 index 0000000000..6bc7c47295 --- /dev/null +++ b/lib/cString.ml @@ -0,0 +1,152 @@ +(************************************************************************) +(* v * The Coq Proof Assistant / The Coq Development Team *) +(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2012 *) +(* \VV/ **************************************************************) +(* // * This file is distributed under the terms of the *) +(* * GNU Lesser General Public License Version 2.1 *) +(************************************************************************) + +(** FIXME: use module type of *) +module type S = +sig + external length : string -> int = "%string_length" + external get : string -> int -> char = "%string_safe_get" + external set : string -> int -> char -> unit = "%string_safe_set" + external create : int -> string = "caml_create_string" + val make : int -> char -> string + val copy : string -> string + val sub : string -> int -> int -> string + val fill : string -> int -> int -> char -> unit + val blit : string -> int -> string -> int -> int -> unit + val concat : string -> string list -> string + val iter : (char -> unit) -> string -> unit + val escaped : string -> string + val index : string -> char -> int + val rindex : string -> char -> int + val index_from : string -> int -> char -> int + val rindex_from : string -> int -> char -> int + val contains : string -> char -> bool + val contains_from : string -> int -> char -> bool + val rcontains_from : string -> int -> char -> bool + val uppercase : string -> string + val lowercase : string -> string + val capitalize : string -> string + val uncapitalize : string -> string + type t = string + val compare: t -> t -> int + external unsafe_get : string -> int -> char = "%string_unsafe_get" + external unsafe_set : string -> int -> char -> unit = "%string_unsafe_set" + external unsafe_blit : + string -> int -> string -> int -> int -> unit = "caml_blit_string" "noalloc" + external unsafe_fill : + string -> int -> int -> char -> unit = "caml_fill_string" "noalloc" +end + +module type ExtS = +sig + include S + external equal : string -> string -> bool = "caml_string_equal" + val explode : string -> string list + val implode : string list -> string + val strip : string -> string + val map : (char -> char) -> string -> string + val drop_simple_quotes : string -> string + val string_index_from : string -> int -> string -> int + val string_contains : where:string -> what:string -> bool + val plural : int -> string -> string + val ordinal : int -> string + val split : char -> string -> string list +end + +include String + +external equal : string -> string -> bool = "caml_string_equal" + + +let explode s = + let rec explode_rec n = + if n >= String.length s then + [] + else + String.make 1 (String.get s n) :: explode_rec (succ n) + in + explode_rec 0 + +let implode sl = String.concat "" sl + +let is_blank = function + | ' ' | '\r' | '\t' | '\n' -> true + | _ -> false + +let strip s = + let n = String.length s in + let rec lstrip_rec i = + if i < n && is_blank s.[i] then + lstrip_rec (i+1) + else i + in + let rec rstrip_rec i = + if i >= 0 && is_blank s.[i] then + rstrip_rec (i-1) + else i + in + let a = lstrip_rec 0 and b = rstrip_rec (n-1) in + String.sub s a (b-a+1) + +let map f s = + let l = String.length s in + let r = String.create l in + for i = 0 to (l - 1) do r.[i] <- f (s.[i]) done; + r + +let drop_simple_quotes s = + let n = String.length s in + if n > 2 & s.[0] = '\'' & s.[n-1] = '\'' then String.sub s 1 (n-2) else s + +(* substring searching... *) + +(* gdzie = where, co = what *) +(* gdzie=gdzie(string) gl=gdzie(length) gi=gdzie(index) *) +let rec is_sub gdzie gl gi co cl ci = + (ci>=cl) || + ((String.unsafe_get gdzie gi = String.unsafe_get co ci) && + (is_sub gdzie gl (gi+1) co cl (ci+1))) + +let rec raw_str_index i gdzie l c co cl = + (* First adapt to ocaml 3.11 new semantics of index_from *) + if (i+cl > l) then raise Not_found; + (* Then proceed as in ocaml < 3.11 *) + let i' = String.index_from gdzie i c in + if (i'+cl <= l) && (is_sub gdzie l i' co cl 0) then i' else + raw_str_index (i'+1) gdzie l c co cl + +let string_index_from gdzie i co = + if co="" then i else + raw_str_index i gdzie (String.length gdzie) + (String.unsafe_get co 0) co (String.length co) + +let string_contains ~where ~what = + try + let _ = string_index_from where 0 what in true + with + Not_found -> false + +let plural n s = if n<>1 then s^"s" else s + +let ordinal n = + let s = match n mod 10 with 1 -> "st" | 2 -> "nd" | 3 -> "rd" | _ -> "th" in + string_of_int n ^ s + +(* string parsing *) + +let split c s = + let len = String.length s in + let rec split n = + try + let pos = String.index_from s n c in + let dir = String.sub s n (pos-n) in + dir :: split (succ pos) + with + | Not_found -> [String.sub s n (len-n)] + in + if Int.equal len 0 then [] else split 0 diff --git a/lib/cString.mli b/lib/cString.mli new file mode 100644 index 0000000000..d7ce35b009 --- /dev/null +++ b/lib/cString.mli @@ -0,0 +1,63 @@ +(************************************************************************) +(* v * The Coq Proof Assistant / The Coq Development Team *) +(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2012 *) +(* \VV/ **************************************************************) +(* // * This file is distributed under the terms of the *) +(* * GNU Lesser General Public License Version 2.1 *) +(************************************************************************) + +(** FIXME: From OCaml 3.12 onwards, that would only be a [module type of] *) + +(** Module type [S] is the one from OCaml Stdlib. *) +module type S = +sig + external length : string -> int = "%string_length" + external get : string -> int -> char = "%string_safe_get" + external set : string -> int -> char -> unit = "%string_safe_set" + external create : int -> string = "caml_create_string" + val make : int -> char -> string + val copy : string -> string + val sub : string -> int -> int -> string + val fill : string -> int -> int -> char -> unit + val blit : string -> int -> string -> int -> int -> unit + val concat : string -> string list -> string + val iter : (char -> unit) -> string -> unit + val escaped : string -> string + val index : string -> char -> int + val rindex : string -> char -> int + val index_from : string -> int -> char -> int + val rindex_from : string -> int -> char -> int + val contains : string -> char -> bool + val contains_from : string -> int -> char -> bool + val rcontains_from : string -> int -> char -> bool + val uppercase : string -> string + val lowercase : string -> string + val capitalize : string -> string + val uncapitalize : string -> string + type t = string + val compare: t -> t -> int + external unsafe_get : string -> int -> char = "%string_unsafe_get" + external unsafe_set : string -> int -> char -> unit = "%string_unsafe_set" + external unsafe_blit : + string -> int -> string -> int -> int -> unit = "caml_blit_string" "noalloc" + external unsafe_fill : + string -> int -> int -> char -> unit = "caml_fill_string" "noalloc" +end + +module type ExtS = +sig + include S + external equal : string -> string -> bool = "caml_string_equal" + val explode : string -> string list + val implode : string list -> string + val strip : string -> string + val map : (char -> char) -> string -> string + val drop_simple_quotes : string -> string + val string_index_from : string -> int -> string -> int + val string_contains : where:string -> what:string -> bool + val plural : int -> string -> string + val ordinal : int -> string + val split : char -> string -> string list +end + +include ExtS diff --git a/lib/clib.mllib b/lib/clib.mllib index f5fd721135..1f4707fda5 100644 --- a/lib/clib.mllib +++ b/lib/clib.mllib @@ -5,6 +5,7 @@ Coq_config Deque CObj CList +CString CArray Util Serialize diff --git a/lib/envars.ml b/lib/envars.ml index 846391d838..27579e4eaa 100644 --- a/lib/envars.ml +++ b/lib/envars.ml @@ -102,7 +102,7 @@ let docdir () = let path_to_list p = let sep = if Sys.os_type = "Win32" then ';' else ':' in - Util.split_string_at sep p + Util.String.split sep p let xdg_data_home warning = coqify @@ -170,7 +170,7 @@ let camllib () = let camlbin = camlbin () in let com = (Filename.concat camlbin "ocamlc") ^ " -where" in let _,res = CUnix.run_command (fun x -> x) (fun _ -> ()) com in - Util.strip res + Util.String.strip res let camlp4bin () = if !Flags.camlp4bin_spec then !Flags.camlp4bin else @@ -187,5 +187,5 @@ let camlp4lib () = let com = (Filename.concat camlp4bin Coq_config.camlp4) ^ " -where" in let ex,res = CUnix.run_command (fun x -> x) (fun _ -> ()) com in match ex with - |Unix.WEXITED 0 -> Util.strip res + |Unix.WEXITED 0 -> Util.String.strip res |_ -> "/dev/null" diff --git a/lib/util.ml b/lib/util.ml index 84249e6aec..fcbd969ab5 100644 --- a/lib/util.ml +++ b/lib/util.ml @@ -36,92 +36,10 @@ let is_blank = function (* Strings *) -let explode s = - let rec explode_rec n = - if n >= String.length s then - [] - else - String.make 1 (String.get s n) :: explode_rec (succ n) - in - explode_rec 0 - -let implode sl = String.concat "" sl - -let strip s = - let n = String.length s in - let rec lstrip_rec i = - if i < n && is_blank s.[i] then - lstrip_rec (i+1) - else i - in - let rec rstrip_rec i = - if i >= 0 && is_blank s.[i] then - rstrip_rec (i-1) - else i - in - let a = lstrip_rec 0 and b = rstrip_rec (n-1) in - String.sub s a (b-a+1) - -let string_map f s = - let l = String.length s in - let r = String.create l in - for i = 0 to (l - 1) do r.[i] <- f (s.[i]) done; - r - -let drop_simple_quotes s = - let n = String.length s in - if n > 2 & s.[0] = '\'' & s.[n-1] = '\'' then String.sub s 1 (n-2) else s - -(* substring searching... *) - -(* gdzie = where, co = what *) -(* gdzie=gdzie(string) gl=gdzie(length) gi=gdzie(index) *) -let rec is_sub gdzie gl gi co cl ci = - (ci>=cl) || - ((String.unsafe_get gdzie gi = String.unsafe_get co ci) && - (is_sub gdzie gl (gi+1) co cl (ci+1))) - -let rec raw_str_index i gdzie l c co cl = - (* First adapt to ocaml 3.11 new semantics of index_from *) - if (i+cl > l) then raise Not_found; - (* Then proceed as in ocaml < 3.11 *) - let i' = String.index_from gdzie i c in - if (i'+cl <= l) && (is_sub gdzie l i' co cl 0) then i' else - raw_str_index (i'+1) gdzie l c co cl - -let string_index_from gdzie i co = - if co="" then i else - raw_str_index i gdzie (String.length gdzie) - (String.unsafe_get co 0) co (String.length co) - -let string_string_contains ~where ~what = - try - let _ = string_index_from where 0 what in true - with - Not_found -> false - -let plural n s = if n<>1 then s^"s" else s - -let ordinal n = - let s = match n mod 10 with 1 -> "st" | 2 -> "nd" | 3 -> "rd" | _ -> "th" in - string_of_int n ^ s - -(* string parsing *) - -let split_string_at c s = - let len = String.length s in - let rec split n = - try - let pos = String.index_from s n c in - let dir = String.sub s n (pos-n) in - dir :: split (succ pos) - with - | Not_found -> [String.sub s n (len-n)] - in - if Int.equal len 0 then [] else split 0 +module String : CString.ExtS = CString let parse_loadpath s = - let l = split_string_at '/' s in + let l = String.split '/' s in if List.mem "" l then invalid_arg "parse_loadpath: find an empty dir in loadpath"; l @@ -137,14 +55,8 @@ let subst_command_placeholder s t = done; Buffer.contents buff -module StringOrd = -struct - type t = string - external compare : string -> string -> int = "caml_string_compare" -end - -module Stringset = Set.Make(StringOrd) -module Stringmap = Map.Make(StringOrd) +module Stringset = Set.Make(String) +module Stringmap = Map.Make(String) (* Lists *) diff --git a/lib/util.mli b/lib/util.mli index 694e79ce4a..6dc6c703dd 100644 --- a/lib/util.mli +++ b/lib/util.mli @@ -36,16 +36,7 @@ val is_blank : char -> bool (** {6 Strings. } *) -val explode : string -> string list -val implode : string list -> string -val strip : string -> string -val string_map : (char -> char) -> string -> string -val drop_simple_quotes : string -> string -val string_index_from : string -> int -> string -> int -val string_string_contains : where:string -> what:string -> bool -val plural : int -> string -> string -val ordinal : int -> string -val split_string_at : char -> string -> string list +module String : CString.ExtS (** Substitute %s in the first chain by the second chain *) val subst_command_placeholder : string -> string -> string |
