This is an automated email from the git hooks/post-receive script. glondu pushed a commit to branch master in repository extlib.
commit 117dffb4fb183c3f7ba3cc058d5ed464fd1d4ea3 Author: Stephane Glondu <st...@glondu.net> Date: Sun Jan 26 15:16:20 2014 +0100 Imported Upstream version 1.6.1 --- IO.ml | 43 ++++++++++++++++++++++ IO.mli | 21 +++++++++-- Makefile | 58 +++++++++++++++++++++--------- README.txt | 22 ++++++++++-- configure.ml | 1 + enum.ml | 2 ++ enum.mli | 4 +++ extArray.ml | 14 ++++---- extHashtbl.ml => extHashtbl.mlpp | 34 +++++++++++++++--- extList.mli | 2 +- extString.ml | 27 +++++++------- extString.mli | 10 ++++-- install.ml | 78 +++++++++++++++++++++++++--------------- optParse.mli | 2 +- uTF8.ml | 5 +++ uTF8.mli | 4 +++ 16 files changed, 248 insertions(+), 79 deletions(-) diff --git a/IO.ml b/IO.ml index 533a0ca..dee9387 100644 --- a/IO.ml +++ b/IO.ml @@ -145,6 +145,10 @@ let output o s p l = if p + l > sl || p < 0 || l < 0 then invalid_arg "IO.output"; o.out_output s p l +let scanf i fmt = + let ib = Scanf.Scanning.from_function (fun () -> try read i with No_more_input -> raise End_of_file) in + Scanf.kscanf ib (fun _ exn -> raise exn) fmt + let printf o fmt = Printf.kprintf (fun s -> nwrite o s) fmt @@ -248,6 +252,33 @@ let output_string() = out_flush = (fun () -> ()); } +let output_strings() = + let sl = ref [] in + let size = ref 0 in + let b = Buffer.create 0 in + { + out_write = (fun c -> + if !size = Sys.max_string_length then begin + sl := Buffer.contents b :: !sl; + Buffer.clear b; + size := 0; + end else incr size; + Buffer.add_char b c + ); + out_output = (fun s p l -> + if !size + l > Sys.max_string_length then begin + sl := Buffer.contents b :: !sl; + Buffer.clear b; + size := 0; + end else size := !size + l; + Buffer.add_substring b s p l; + l + ); + out_close = (fun () -> sl := Buffer.contents b :: !sl; List.rev (!sl)); + out_flush = (fun () -> ()); + } + + let input_channel ch = { in_read = (fun () -> @@ -464,6 +495,9 @@ let read_i64 ch = let big = Int64.of_int32 (read_real_i32 ch) in Int64.logor (Int64.shift_left big 32) small +let read_float32 ch = + Int32.float_of_bits (read_real_i32 ch) + let read_double ch = Int64.float_of_bits (read_i64 ch) @@ -509,6 +543,9 @@ let write_i64 ch n = write_real_i32 ch (Int64.to_int32 n); write_real_i32 ch (Int64.to_int32 (Int64.shift_right_logical n 32)) +let write_float32 ch f = + write_real_i32 ch (Int32.bits_of_float f) + let write_double ch f = write_i64 ch (Int64.bits_of_float f) @@ -562,6 +599,9 @@ let read_i64 ch = let small = Int64.logor base (Int64.shift_left (Int64.of_int ch4) 24) in Int64.logor (Int64.shift_left big 32) small +let read_float32 ch = + Int32.float_of_bits (read_real_i32 ch) + let read_double ch = Int64.float_of_bits (read_i64 ch) @@ -595,6 +635,9 @@ let write_i64 ch n = write_real_i32 ch (Int64.to_int32 (Int64.shift_right_logical n 32)); write_real_i32 ch (Int64.to_int32 n) +let write_float32 ch f = + write_real_i32 ch (Int32.bits_of_float f) + let write_double ch f = write_i64 ch (Int64.bits_of_float f) diff --git a/IO.mli b/IO.mli index 2d8bd77..880bffc 100644 --- a/IO.mli +++ b/IO.mli @@ -109,6 +109,12 @@ val output_string : unit -> string output (** Create an output that will write into a string in an efficient way. When closed, the output returns all the data written into it. *) +val output_strings : unit -> string list output +(** Create an output that will write into a string in an efficient way. + When closed, the output returns all the data written into it. + Several strings are used in case the output size excess max_string_length +*) + val input_channel : in_channel -> input (** Create an input that will read from a channel. *) @@ -135,6 +141,9 @@ val create_out : (** {6 Utilities} *) +val scanf : input -> ('a, 'b, 'c, 'd) Scanf.scanner +(** The scanf function works for any input. *) + val printf : 'a output -> ('b, unit, string, unit) format4 -> 'b (** The printf function works for any output. *) @@ -190,8 +199,11 @@ val read_real_i32 : input -> int32 val read_i64 : input -> int64 (** Read a signed 64-bit integer as an OCaml int64. *) +val read_float32 : input -> float +(** Read an IEEE single precision floating point value (32 bits). *) + val read_double : input -> float -(** Read an IEEE double precision floating point value. *) +(** Read an IEEE double precision floating point value (64 bits). *) val read_string : input -> string (** Read a null-terminated string. *) @@ -217,8 +229,11 @@ val write_real_i32 : 'a output -> int32 -> unit val write_i64 : 'a output -> int64 -> unit (** Write an OCaml int64. *) +val write_float32 : 'a output -> float -> unit +(** Write an IEEE single precision floating point value (32 bits). *) + val write_double : 'a output -> float -> unit -(** Write an IEEE double precision floating point value. *) +(** Write an IEEE double precision floating point value (64 bits). *) val write_string : 'a output -> string -> unit (** Write a string and append an null character. *) @@ -236,6 +251,7 @@ sig val read_i32 : input -> int val read_real_i32 : input -> int32 val read_i64 : input -> int64 + val read_float32 : input -> float val read_double : input -> float val write_ui16 : 'a output -> int -> unit @@ -243,6 +259,7 @@ sig val write_i32 : 'a output -> int -> unit val write_real_i32 : 'a output -> int32 -> unit val write_i64 : 'a output -> int64 -> unit + val write_float32 : 'a output -> float -> unit val write_double : 'a output -> float -> unit end diff --git a/Makefile b/Makefile index 3690ac6..f088b27 100644 --- a/Makefile +++ b/Makefile @@ -1,38 +1,62 @@ # Makefile contributed by Alain Frisch -VERSION = 1.5.4 +VERSION = 1.6.1 -MODULES = \ +# the list is topologically sorted +MODULES := \ enum bitSet dynArray extArray extHashtbl extList extString global IO option \ - pMap std uChar uTF8 base64 unzip refList optParse dllist + pMap std uChar uTF8 base64 unzip refList optParse dllist extLib -# the list is topologically sorted +ifdef minimal +MODULES := $(filter-out unzip uChar uTF8, $(MODULES)) +endif + +OCAMLC = ocamlc -g +OCAMLOPT = ocamlopt -g -MLI = $(MODULES:=.mli) +MLI = $(filter-out extLib.mli, $(MODULES:=.mli)) CMI = $(MODULES:=.cmi) +CMO = $(MODULES:=.cmo) CMX = $(MODULES:=.cmx) -SRC = $(MLI) $(MODULES:=.ml) extLib.ml -.PHONY: all opt cmxs doc install uninstall clean release +.SUFFIXES: +.PHONY: build all opt cmxs doc install uninstall clean release + +build: all opt cmxs + +all: extLib.cma +opt: extLib.cmxa +cmxs: extLib.cmxs -all: - ocamlc -a -o extLib.cma $(SRC) -opt: - ocamlopt -a -o extLib.cmxa $(SRC) -cmxs: opt - ocamlopt -shared -linkall extLib.cmxa -o extLib.cmxs doc: - ocamlc -c $(MLI) - ocamldoc -sort -html -d doc/ $(MLI) + $(OCAMLC) -c $(MLI) + ocamldoc -sort -html -d doc/ $(MLI) extLib.ml + +extLib.cma: $(CMO) + $(OCAMLC) -a -o $@ $^ +extLib.cmxa: $(CMX) + $(OCAMLOPT) -a -o $@ $^ +%.cmxs: %.cmxa + $(OCAMLOPT) -shared -linkall $< -o $@ +%.cmo: %.mli %.ml + $(OCAMLC) -c $^ +%.cmx: %.mli %.ml + $(OCAMLOPT) -c $^ +extLib.cmo: extLib.ml + $(OCAMLC) -c $< +extLib.cmx: extLib.ml + $(OCAMLOPT) -c $< +extHashtbl.ml: extHashtbl.mlpp + camlp4of pr_o.cmo $(shell ocaml configure.ml) -impl $< -o $@ install: - ocamlfind install -patch-version $(VERSION) extlib META extLib.cma extLib.cmi $(MLI) $(CMI) -optional extLib.cmxa $(CMX) extLib.cmxs extLib.a extLib.lib + ocamlfind install -patch-version $(VERSION) extlib META extLib.cma $(MLI) $(CMI) -optional extLib.cmxa $(CMX) extLib.cmxs extLib.a extLib.lib uninstall: ocamlfind remove extlib clean: - rm -f *.cmo *.cmx *.o *.obj *.cmi *.cma *.cmxa *.cmxs *.a *.lib doc/*.html + rm -f *.cmo *.cmx *.o *.obj *.cmi *.cma *.cmxa *.cmxs *.a *.lib doc/*.html extHashtbl.ml release: svn export . extlib-$(VERSION) diff --git a/README.txt b/README.txt index 435916f..92d93c4 100644 --- a/README.txt +++ b/README.txt @@ -30,16 +30,29 @@ they might have with ExtLib by using the mailing list. Installation : -------------- -Unzip or untar in any directory, then simply run +Unzip or untar in any directory and run -> ocaml install.ml + make minimal=1 build install + +This will build and install bytecode and native libraries. +On bytecode-only architecture run + + make minimal=1 all install + +`minimal=1` will exclude from build several modules (namely Unzip UChar UTF8) potentially +conflicting with other well established OCaml libraries. If your code is expecting to find +these modules in extlib - omit this parameter during build to produce the full library. + +Alternatively, run + + ocaml install.ml and follow the instructions. Usage : ------- -Generate and watch the documentation. +Generate and read the documentation. Contributors : -------------- @@ -47,6 +60,9 @@ Contributors : Nicolas Cannasse (ncanna...@motion-twin.com) Brian Hurt (brian.h...@qlogic.com) Yamagata Yoriyuki (y...@users.sourceforge.net) +Janne Hellsten <jjhellst AT gmail DOT com> +Richard W.M. Jones <rjones AT redhat DOT com> +ygrek <ygrek AT autistici DOT org> License : --------- diff --git a/configure.ml b/configure.ml new file mode 100644 index 0000000..4ba705c --- /dev/null +++ b/configure.ml @@ -0,0 +1 @@ +let () = print_endline (if Sys.ocaml_version >= "4.00.0" then "-D OCAML4" else ""); exit 0 diff --git a/enum.ml b/enum.ml index 3b7708d..cd64abb 100644 --- a/enum.ml +++ b/enum.ml @@ -124,6 +124,8 @@ let from2 next clone = e.count <- (fun () -> force e; e.count()); e +let next t = t.next () + let get t = try Some (t.next()) diff --git a/enum.mli b/enum.mli index 5ab6fbf..95d4583 100644 --- a/enum.mli +++ b/enum.mli @@ -88,6 +88,10 @@ val get : 'a t -> 'a option (** [get e] returns [None] if [e] is empty or [Some x] where [x] is the next element of [e], in which case the element is removed from the enumeration. *) +val next : 'a t -> 'a +(** [next e] returns the next element of [e] (and removes it from enumeration). + @raise No_more_elements if enumeration is empty *) + val push : 'a t -> 'a -> unit (** [push e x] will add [x] at the beginning of [e]. *) diff --git a/extArray.ml b/extArray.ml index 0ce9c8e..1e5bd60 100644 --- a/extArray.ml +++ b/extArray.ml @@ -46,14 +46,14 @@ let for_all p xs = in loop 0 +exception Exists + let exists p xs = - let n = length xs in - let rec loop i = - if i = n then false - else if p xs.(i) then true - else loop (succ i) - in - loop 0 + try + for i = 0 to Array.length xs - 1 do + if p xs.(i) then raise Exists + done; false + with Exists -> true let mem a xs = let n = length xs in diff --git a/extHashtbl.ml b/extHashtbl.mlpp similarity index 80% rename from extHashtbl.ml rename to extHashtbl.mlpp index 72c818a..fec9abe 100644 --- a/extHashtbl.ml +++ b/extHashtbl.mlpp @@ -22,14 +22,28 @@ module Hashtbl = struct +IFDEF OCAML4 THEN + external old_hash_param : + int -> int -> 'a -> int = "caml_hash_univ_param" "noalloc" +END + type ('a, 'b) h_bucketlist = | Empty | Cons of 'a * 'b * ('a, 'b) h_bucketlist +IFDEF OCAML4 THEN + type ('a, 'b) h_t = { + mutable size: int; + mutable data: ('a, 'b) h_bucketlist array; + mutable seed: int; + initial_size: int; + } +ELSE type ('a, 'b) h_t = { mutable size: int; mutable data: ('a, 'b) h_bucketlist array } +END include Hashtbl let create n = Hashtbl.create (* no seed *) n @@ -87,11 +101,21 @@ module Hashtbl = | Empty -> Empty | Cons (k,v,next) -> Cons (k,f v,loop next) in - h_make { - size = (h_conv h).size; + h_make { (h_conv h) with data = Array.map loop (h_conv h).data; } +IFDEF OCAML4 THEN + (* copied from stdlib :( *) + let key_index h key = + (* compatibility with old hash tables *) + if Obj.size (Obj.repr h) >= 3 + then (seeded_hash_param 10 100 (h_conv h).seed key) land (Array.length (h_conv h).data - 1) + else (old_hash_param 10 100 key) mod (Array.length (h_conv h).data) +ELSE + let key_index h key = (hash key) mod (Array.length (h_conv h).data) +END + let remove_all h key = let hc = h_conv h in let rec loop = function @@ -103,7 +127,7 @@ module Hashtbl = end else Cons(k,v,loop next) in - let pos = (hash key) mod (Array.length hc.data) in + let pos = key_index h key in Array.unsafe_set hc.data pos (loop (Array.unsafe_get hc.data pos)) let find_default h key defval = @@ -112,7 +136,7 @@ module Hashtbl = | Cons (k,v,next) -> if k = key then v else loop next in - let pos = (hash key) mod (Array.length (h_conv h).data) in + let pos = key_index h key in loop (Array.unsafe_get (h_conv h).data pos) let find_option h key = @@ -121,7 +145,7 @@ module Hashtbl = | Cons (k,v,next) -> if k = key then Some v else loop next in - let pos = (hash key) mod (Array.length (h_conv h).data) in + let pos = key_index h key in loop (Array.unsafe_get (h_conv h).data pos) let of_enum e = diff --git a/extList.mli b/extList.mli index 58cc72e..c4eaed7 100644 --- a/extList.mli +++ b/extList.mli @@ -51,7 +51,7 @@ module List : (** Returns the last element of the list, or raise [Empty_list] if the list is empty. This function takes linear time. *) - val iteri : (int -> 'a -> 'b) -> 'a list -> unit + val iteri : (int -> 'a -> unit) -> 'a list -> unit (** [iteri f l] will call [(f 0 a0);(f 1 a1) ... (f n an)] where [a0..an] are the elements of the list [l]. *) diff --git a/extString.ml b/extString.ml index 7cbd1c2..71dcaad 100644 --- a/extString.ml +++ b/extString.ml @@ -53,7 +53,7 @@ let ends_with s e = in loop s e 0 -let find str sub = +let find_from str pos sub = let sublen = length sub in if sublen = 0 then 0 @@ -61,7 +61,7 @@ let find str sub = let found = ref 0 in let len = length str in try - for i = 0 to len - sublen do + for i = pos to len - sublen do let j = ref 0 in while unsafe_get str (i + !j) = unsafe_get sub !j do incr j; @@ -72,6 +72,8 @@ let find str sub = with Exit -> !found +let find str sub = find_from str 0 sub + let exists str sub = try ignore(find str sub); @@ -99,18 +101,17 @@ let split str sep = sub str 0 p, sub str (p + len) (slen - p - len) let nsplit str sep = - if str = "" then [] - else if sep = "" then raise Invalid_string - else ( - let rec nsplit str sep = - try - let s1 , s2 = split str sep in - s1 :: nsplit s2 sep - with - Invalid_string -> [str] + if str = "" then [] + else if sep = "" then raise Invalid_string + else + let rec loop acc pos = + if pos > String.length str then + List.rev acc + else + let i = try find_from str pos sep with Invalid_string -> String.length str in + loop (String.sub str pos (i - pos) :: acc) (i + String.length sep) in - nsplit str sep - ) + loop [] 0 let join = concat diff --git a/extString.mli b/extString.mli index cc88f9b..88fb4cd 100644 --- a/extString.mli +++ b/extString.mli @@ -29,16 +29,22 @@ module String : val init : int -> (int -> char) -> string (** [init l f] returns the string of length [l] with the chars - f 0 , f 1 , f 2 ... f (l-1). *) + f 0 , f 1 , f 2 ... f (l-1). *) val find : string -> string -> int (** [find s x] returns the starting index of the string [x] within the string [s] or raises [Invalid_string] if [x] is not a substring of [s]. *) + val find_from : string -> int -> string -> int + (** [find s i x] returns the starting index of the string [x] + within the string [s] (starting search from position [i]) or + raises [Invalid_string] if no such substring exists. + [find s x] is equivalent to [find_from s 0 x]. *) + val split : string -> string -> string * string (** [split s sep] splits the string [s] between the first - occurrence of [sep]. + occurrence of [sep]. raises [Invalid_string] if the separator is not found. *) val nsplit : string -> string -> string list diff --git a/install.ml b/install.ml index 5c2f0dc..1541930 100644 --- a/install.ml +++ b/install.ml @@ -24,7 +24,7 @@ type path = | PathUnix | PathDos -let modules = [ +let modules_min = [ "enum"; "bitSet"; "dynArray"; @@ -37,17 +37,17 @@ let modules = [ "option"; "pMap"; "std"; - "uChar"; - "uTF8"; "base64"; - "unzip"; "refList"; "optParse"; - "dllist"; + "dllist"; ] -let m_list suffix = - String.concat " " (List.map (fun m -> m ^ suffix) modules) +let modules_compat = [ + "uChar"; + "uTF8"; + "unzip"; +] let obj_ext , lib_ext , cp_cmd , path_type = match Sys.os_type with | "Unix" | "Cygwin" | "MacOS" -> ".o" , ".a" , "cp", PathUnix @@ -110,35 +110,37 @@ type install_dir = Findlib | Dir of string let install() = let autodir = ref None in - let docflag = ref None in - let autodoc = ref false in + let autodoc = ref None in let autobyte = ref false in let autonative = ref false in + let autofull = ref None in let version = get_version () in let usage = sprintf "ExtLib installation program v%s\n(C) 2003 Nicolas Cannasse" version in Arg.parse [ ("-d", Arg.String (fun s -> autodir := Some s) , "<dir> : install in target directory"); ("-b", Arg.Unit (fun () -> autobyte := true) , ": byte code installation"); ("-n", Arg.Unit (fun () -> autonative := true) , ": native code installation"); - ("-doc", Arg.Unit (fun () -> docflag := Some true) , ": documentation installation"); - ("-nodoc", Arg.Unit (fun () -> docflag := Some false) , ": documentation installation"); + ("-min", Arg.Unit (fun () -> autofull := Some false) , ": exclude potentially conflicting modules (recommended)"); + ("-full", Arg.Unit (fun () -> autofull := Some true) , ": include all modules (compatibility)"); + ("-doc", Arg.Unit (fun () -> autodoc := Some true) , ": documentation installation"); + ("-nodoc", Arg.Unit (fun () -> autodoc := Some false) , ": disable documentation installation"); ] (fun s -> raise (Arg.Bad s)) usage; let findlib = is_findlib () in let install_dir = ( match !autodir with | Some dir -> - if not !autobyte && not !autonative && not !autodoc then failwith "Nothing to do."; + if not !autobyte && not !autonative && !autodoc = None then failwith "Nothing to do."; Dir (complete_path dir) | None -> let byte, native = if !autobyte || !autonative then (!autobyte, !autonative) else begin - printf "Choose one of the following :\n1- Bytecode installation only\n2- Native installation only\n3- Both Native and Bytecode installation\n> "; + printf "Choose one of the following :\n1- Bytecode installation only\n2- Native installation only\n[3]- Both Native and Bytecode installation\n> "; (match read_line() with | "1" -> true, false | "2" -> false, true - | "3" -> true, true + | "" | "3" -> true, true | _ -> failwith "Invalid choice, exit.") end in @@ -157,37 +159,57 @@ let install() = autonative := native; dest ) in + let modules = + let full = + match !autofull with + | Some f -> f + | None -> + printf "Do you want to exclude potentially conflicting modules (Unzip UChar UTF8) from build ([Y]/N) ?\n> "; + (match read_line() with + | "" | "y" | "Y" -> false + | "n" | "N" -> true + | _ -> failwith "Invalid choice, exit.") + in + match full with + | true -> modules_min @ modules_compat + | false -> modules_min + in + let m_list suffix = String.concat " " (List.map (fun m -> m ^ suffix) modules) in let doc = - match !docflag with - Some doc -> doc + match !autodoc with + | Some doc -> doc | None -> - printf "Do you want to generate ocamldoc documentation (Y/N) ?\n> "; + printf "Do you want to generate ocamldoc documentation ([Y]/N) ?\n> "; (match read_line() with - | "y" | "Y" -> true + | "" | "y" | "Y" -> true | "n" | "N" -> false | _ -> failwith "Invalid choice, exit.") in - autodoc := doc; let doc_dir = match install_dir with - Findlib -> "extlib-doc" - | Dir install_dir -> - sprintf "%sextlib-doc" install_dir in - if !autodoc && not (Sys.file_exists doc_dir) then run (sprintf "mkdir %s" doc_dir); + | Findlib -> "doc" + | Dir install_dir -> Filename.concat install_dir "extlib-doc" + in + if doc && not (Sys.file_exists doc_dir) then run (sprintf "mkdir %s" doc_dir); + (* generate extHashtbl.ml *) + let camlp4_flags = if Sys.ocaml_version >= "4.00.0" then "-D OCAML4" else "" in + run (sprintf "camlp4of pr_o.cmo %s -impl extHashtbl.mlpp -o extHashtbl.ml" camlp4_flags); + (* compile mli *) run (sprintf "ocamlc -c %s" (m_list ".mli")); + (* compile ml *) if !autobyte then begin - List.iter (fun m -> run (sprintf "ocamlc -c %s.ml" m)) modules; - run (sprintf "ocamlc -a -o extLib.cma %s extLib.ml" (m_list ".cmo")); + List.iter (fun m -> run (sprintf "ocamlc -g -c %s.ml" m)) modules; + run (sprintf "ocamlc -g -a -o extLib.cma %s extLib.ml" (m_list ".cmo")); List.iter (fun m -> remove (m ^ ".cmo")) modules; remove "extLib.cmo"; end; if !autonative then begin - List.iter (fun m -> run (sprintf "ocamlopt -c %s.ml" m)) modules; - run (sprintf "ocamlopt -a -o extLib.cmxa %s extLib.ml" (m_list ".cmx")); + List.iter (fun m -> run (sprintf "ocamlopt -g -c %s.ml" m)) modules; + run (sprintf "ocamlopt -g -a -o extLib.cmxa %s extLib.ml" (m_list ".cmx")); List.iter (fun m -> remove (m ^ obj_ext)) modules; remove ("extLib" ^ obj_ext); end; - if !autodoc then begin + if doc then begin run (sprintf "ocamldoc -sort -html -d %s %s" doc_dir (m_list ".mli")); if doc_dir <> "doc" then (* style.css is already there *) run ((match path_type with diff --git a/optParse.mli b/optParse.mli index 92b9f9c..da096aa 100644 --- a/optParse.mli +++ b/optParse.mli @@ -441,7 +441,7 @@ module OptParser : (** {6 Output and error handling} *) - val error : t -> ?chn: out_channel -> ?status: int -> string -> unit + val error : t -> ?chn: out_channel -> ?status: int -> string -> 'a (** Display an error message and exit the program. The error message is printed to the channel [chn] (default is [Pervasives.stderr]) and the program exits with exit status diff --git a/uTF8.ml b/uTF8.ml index b7da7b9..06c58f9 100644 --- a/uTF8.ml +++ b/uTF8.ml @@ -108,6 +108,11 @@ let rec nth_aux s i n = let nth s n = nth_aux s 0 n +let substring s i n = + let j = nth s i in + let j' = (nth_aux s j n) - 1 in + String.sub s j (j' - j + 1) + let last s = search_head_backward s (String.length s - 1) let out_of_range s i = i < 0 || i >= String.length s diff --git a/uTF8.mli b/uTF8.mli index 72d9a13..a864ab6 100644 --- a/uTF8.mli +++ b/uTF8.mli @@ -66,6 +66,10 @@ val last : t -> index returns the Unicode character of the location [i] in the string [s]. *) val look : t -> index -> uchar +(** [substring s i len] returns the substring made of the Unicode locations [i] to [i + len - 1] inclusive. + The string is always copied *) +val substring : t -> int -> int -> t + (** [out_of_range s i] tests whether [i] is a position inside of [s]. *) val out_of_range : t -> index -> bool -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ocaml-maint/packages/extlib.git _______________________________________________ Pkg-ocaml-maint-commits mailing list Pkg-ocaml-maint-commits@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-ocaml-maint-commits