Merge branch 'master' into stable for 0.21

This commit is contained in:
Simon Cruanes 2016-11-03 16:06:48 +01:00
commit d84b1e1369
17 changed files with 372 additions and 49 deletions

View file

@ -1,5 +1,20 @@
= Changelog
== 0.21
- (breaking) make default `start`/`stop` arguments empty in printers (#82)
- add `CCFormat.{with_color_sf,fprintf_dyn_color,sprintf_dyn_color}`
- add `CCFormat.Dump` for easy debugging (see #82)
- add `CCArray.Sub.to_list`
- add `CCArray.{sorted,sort_indices,sort_ranking}` (closes #81)
- handle '\r` in CCSexpM (fixes #83)
- add alias `Containers.IO`
- bugfixes in `CCArray.Sub`
- bugfix + tests for `CCArray.Sub.sub`
- disable parallel build to support cygwin
== 0.20
- bugfix in `CCArray.equal`

5
_oasis
View file

@ -1,6 +1,6 @@
OASISFormat: 0.4
Name: containers
Version: 0.20
Version: 0.21
Homepage: https://github.com/c-cube/ocaml-containers
Authors: Simon Cruanes
License: BSD-2-clause
@ -10,7 +10,8 @@ OCamlVersion: >= 4.00.1
BuildTools: ocamlbuild
AlphaFeatures: ocamlbuild_more_args
XOCamlbuildExtraArgs: "-j 0"
# cygwin fails with anything else
XOCamlbuildExtraArgs: "-j 1"
Synopsis: A modular standard library focused on data structures.
Description:

2
opam
View file

@ -1,6 +1,6 @@
opam-version: "1.2"
name: "containers"
version: "0.20"
version: "0.21"
author: "Simon Cruanes"
maintainer: "simon.cruanes@inria.fr"
build: [

View file

@ -1,7 +1,7 @@
(* setup.ml generated for the first time by OASIS v0.4.4 *)
(* OASIS_START *)
(* DO NOT EDIT (digest: 1ed8a841a820b1830b239987cd022aa8) *)
(* DO NOT EDIT (digest: 5a4456e803f365ce3410624a599bc76f) *)
(*
Regenerated by OASIS v0.4.7
Visit http://oasis.forge.ocamlcore.org for more information and
@ -6980,7 +6980,7 @@ open OASISTypes;;
let setup_t =
{
BaseSetup.configure = InternalConfigurePlugin.configure;
build = OCamlbuildPlugin.build ["-use-ocamlfind"; "-j 0"];
build = OCamlbuildPlugin.build ["-use-ocamlfind"; "-j 1"];
test =
[
("all",
@ -7049,7 +7049,7 @@ let setup_t =
{
oasis_version = "0.4";
ocaml_version = Some (OASISVersion.VGreaterEqual "4.00.1");
version = "0.20";
version = "0.21";
license =
OASISLicense.DEP5License
(OASISLicense.DEP5Unit
@ -9689,7 +9689,7 @@ let setup_t =
};
oasis_fn = Some "_oasis";
oasis_version = "0.4.7";
oasis_digest = Some "\223\133\236\175X\030c\221\172i#\201\\\181\1865";
oasis_digest = Some "v\210\236\240,\180C\195X\143\011\\\217Y\180\206";
oasis_exec = None;
oasis_setup_args = [];
setup_update = false

View file

@ -51,6 +51,29 @@ module type S = sig
val reverse_in_place : 'a t -> unit
(** Reverse the array in place *)
val sorted : ('a -> 'a -> int) -> 'a t -> 'a array
(** [sorted cmp a] makes a copy of [a] and sorts it with [cmp].
@since 0.21 *)
val sort_indices : ('a -> 'a -> int) -> 'a t -> int array
(** [sort_indices cmp a] returns a new array [b], with the same length as [a],
such that [b.(i)] is the index of the [i]-th element of [a] in [sort cmp a].
In other words, [map (fun i -> a.(i)) (sort_indices a) = sorted cmp a].
[a] is not modified.
@since 0.21 *)
val sort_ranking : ('a -> 'a -> int) -> 'a t -> int array
(** [sort_ranking cmp a] returns a new array [b], with the same length as [a],
such that [b.(i)] is the position in [sorted cmp a] of the [i]-th
element of [a].
[a] is not modified.
In other words, [map (fun i -> (sorted cmp a).(i)) (sort_ranking cmp a) = a].
Without duplicates, we also have
[lookup_exn a.(i) (sorted a) = (sorted_ranking a).(i)]
@since 0.21 *)
val find : ('a -> 'b option) -> 'a t -> 'b option
(** [find f a] returns [Some y] if there is an element [x] such
that [f x = Some y], else it returns [None] *)
@ -260,6 +283,18 @@ let _shuffle _rand_int a i j =
let b = Array.copy a in shuffle_with st a; a <> b
*)
let _sort_indices cmp a i j =
let len = j-i in
let b = Array.init len (fun k->k) in
Array.sort (fun k1 k2 -> cmp a.(k1+i) a.(k2+i)) b;
b
let _sorted cmp a i j =
let len = j-i in
let b = Array.sub a i len in
Array.sort cmp b;
b
let _choose a i j st =
if i>=j then raise Not_found;
a.(i+Random.State.int st (j-i))
@ -366,6 +401,48 @@ let reverse_in_place a =
a = [| 6;5;4;3;2;1 |]
*)
let sorted cmp a = _sorted cmp a 0 (Array.length a)
(*$= & ~cmp:(=) ~printer:Q.Print.(array int)
[||] (sorted Pervasives.compare [||])
[|0;1;2;3;4|] (sorted Pervasives.compare [|3;2;1;4;0|])
*)
(*$Q
Q.(array int) (fun a -> \
let b = Array.copy a in \
Array.sort Pervasives.compare b; b = sorted Pervasives.compare a)
*)
let sort_indices cmp a = _sort_indices cmp a 0 (Array.length a)
(*$= & ~cmp:(=) ~printer:Q.Print.(array int)
[||] (sort_indices Pervasives.compare [||])
[|4;2;1;0;3|] (sort_indices Pervasives.compare [|"d";"c";"b";"e";"a"|])
*)
(*$Q
Q.(array printable_string) (fun a -> \
let b = sort_indices String.compare a in \
sorted String.compare a = Array.map (Array.get a) b)
*)
let sort_ranking cmp a =
let cmp_int : int -> int -> int = Pervasives.compare in
sort_indices cmp_int (sort_indices cmp a)
(*$= & ~cmp:(=) ~printer:Q.Print.(array int)
[||] (sort_ranking Pervasives.compare [||])
[|3;2;1;4;0|] (sort_ranking Pervasives.compare [|"d";"c";"b";"e";"a"|])
*)
(*$Q
Q.(array printable_string) (fun a -> \
let b = sort_ranking String.compare a in \
let a_sorted = sorted String.compare a in \
a = Array.map (Array.get a_sorted) b)
*)
let rev a =
let b = Array.copy a in
reverse_in_place b;
@ -618,7 +695,15 @@ module Sub = struct
let copy a = Array.sub a.arr a.i (length a)
let sub a i len = make a.arr ~len:(a.i + i) len
let sub a i len = make a.arr (a.i + i) ~len
(*$=
[ 3;4 ] \
(let a = Sub.make (0--10) 2 5 in Sub.sub a 1 2 |> Sub.to_list)
[ ] \
(let a = Sub.make (0--10) 2 5 in Sub.sub a 1 0 |> Sub.to_list)
[ 5 ] \
(let a = Sub.make (0--10) 1 9 in Sub.sub a 4 1 |> Sub.to_list)
*)
let equal eq a b =
length a = length b && _equal eq a.arr a.i a.j b.arr b.i b.j
@ -632,6 +717,10 @@ module Sub = struct
else _fold (f acc a.arr.(i)) (i+1) j
in _fold acc a.i a.j
let to_list a =
let l = fold (fun l x -> x::l) [] a in
List.rev l
let foldi f acc a = _foldi f acc a.arr a.i a.j
let fold_while f acc a =
@ -689,22 +778,95 @@ module Sub = struct
Sub.reverse_in_place s; a = [| 1; 2; 5; 4; 3; 6 |]
*)
let sorted cmp a = _sorted cmp a.arr a.i a.j
(*$= & ~cmp:(=) ~printer:Q.Print.(array int)
[||] \
(let a = 1--6 in let s = Sub.make a 2 ~len:0 in \
Sub.sorted Pervasives.compare s)
[|2;3;4|] \
(let a = [|6;5;4;3;2;1|] in let s = Sub.make a 2 ~len:3 in \
Sub.sorted Pervasives.compare s)
*)
(*$Q
Q.(array int) (fun a -> \
Array.length a > 10 ==> ( Array.length a > 10 && \
let s = Sub.make a 5 ~len:5 in \
let b = Array.sub a 5 5 in \
Array.sort Pervasives.compare b; b = Sub.sorted Pervasives.compare s))
*)
let sort_ranking cmp a =
let idx = _sort_indices cmp a.arr a.i a.j in
let cmp_int : int -> int -> int = Pervasives.compare in
sort_indices cmp_int idx
(*$= & ~cmp:(=) ~printer:Q.Print.(array int)
[||] \
(let a = 1--6 in let s = Sub.make a 2 ~len:0 in \
Sub.sort_ranking Pervasives.compare s)
[|2;1;3;0|] \
(let a = [|"d";"c";"b";"e";"a"|] in let s = Sub.make a 1 ~len:4 in \
Sub.sort_ranking Pervasives.compare s)
*)
(*$Q
Q.(array printable_string) (fun a -> \
Array.length a > 10 ==> ( Array.length a > 10 && \
let s = Sub.make a 5 ~len:5 in \
let b = Sub.sort_indices String.compare s in \
Sub.sorted String.compare s = Array.map (Sub.get s) b))
*)
let sort_indices cmp a = _sort_indices cmp a.arr a.i a.j
(*$= & ~cmp:(=) ~printer:Q.Print.(array int)
[||] \
(let a = 1--6 in let s = Sub.make a 2 ~len:0 in \
Sub.sort_indices Pervasives.compare s)
[|3;1;0;2|] \
(let a = [|"d";"c";"b";"e";"a"|] in let s = Sub.make a 1 ~len:4 in \
Sub.sort_indices Pervasives.compare s)
*)
(*$Q
Q.(array printable_string) (fun a -> \
Array.length a > 10 ==> ( Array.length a > 10 && \
let s = Sub.make a 5 ~len:5 in \
let b = Sub.sort_ranking String.compare s in \
let a_sorted = Sub.sorted String.compare s in \
Sub.copy s = Array.map (Array.get a_sorted) b))
*)
let find f a = _find (fun _ -> f) a.arr a.i a.j
let findi f a = _find (fun i -> f (i-a.i)) a.arr a.i a.j
let find_idx p a =
_find (fun i x -> if p x then Some (i,x) else None) a.arr a.i a.j
_find (fun i x -> if p x then Some (i-a.i,x) else None) a.arr a.i a.j
(*$=
(Some (1,"c")) (Sub.find_idx ((=) "c") (Sub.make [| "a"; "b"; "c" |] 1 2))
*)
let lookup_exn ?(cmp=Pervasives.compare) k a =
_lookup_exn ~cmp k a.arr a.i (a.j-1)
_lookup_exn ~cmp k a.arr a.i (a.j-1) - a.i
let lookup ?(cmp=Pervasives.compare) k a =
try Some (_lookup_exn ~cmp k a.arr a.i (a.j-1))
try Some (_lookup_exn ~cmp k a.arr a.i (a.j-1) - a.i)
with Not_found -> None
(*$=
(Some 1) (Sub.lookup "c" (Sub.make [| "a"; "b"; "c" |] 1 2))
*)
let bsearch ?(cmp=Pervasives.compare) k a =
bsearch_ ~cmp k a.arr a.i (a.j - 1)
match bsearch_ ~cmp k a.arr a.i (a.j - 1) with
| `At m -> `At (m - a.i)
| `Just_after m -> `Just_after (m - a.i)
| res -> res
let for_all p a = _for_all p a.arr a.i a.j
@ -738,7 +900,8 @@ module Sub = struct
let pp ?(sep=", ") pp_item buf a = _pp ~sep pp_item buf a.arr a.i a.j
let pp_i ?(sep=", ") pp_item buf a = _pp_i ~sep pp_item buf a.arr a.i a.j
let pp_i ?(sep=", ") pp_item buf a =
_pp_i ~sep (fun out k x -> pp_item out (k-a.i) x) buf a.arr a.i a.j
let print ?(sep=", ") pp_item fmt a = _print ~sep pp_item fmt a.arr a.i a.j

View file

@ -53,6 +53,29 @@ module type S = sig
val reverse_in_place : 'a t -> unit
(** Reverse the array in place *)
val sorted : ('a -> 'a -> int) -> 'a t -> 'a array
(** [sorted cmp a] makes a copy of [a] and sorts it with [cmp].
@since 0.21 *)
val sort_indices : ('a -> 'a -> int) -> 'a t -> int array
(** [sort_indices cmp a] returns a new array [b], with the same length as [a],
such that [b.(i)] is the index of the [i]-th element of [a] in [sort cmp a].
In other words, [map (fun i -> a.(i)) (sort_indices a) = sorted cmp a].
[a] is not modified.
@since 0.21 *)
val sort_ranking : ('a -> 'a -> int) -> 'a t -> int array
(** [sort_ranking cmp a] returns a new array [b], with the same length as [a],
such that [b.(i)] is the position in [sorted cmp a] of the [i]-th
element of [a].
[a] is not modified.
In other words, [map (fun i -> (sorted cmp a).(i)) (sort_ranking cmp a) = a].
Without duplicates, we also have
[lookup_exn a.(i) (sorted a) = (sorted_ranking a).(i)]
@since 0.21 *)
val find : ('a -> 'b option) -> 'a t -> 'b option
(** [find f a] returns [Some y] if there is an element [x] such
that [f x = Some y], else it returns [None] *)
@ -224,6 +247,10 @@ module Sub : sig
(** Convert into a triple [(arr, i, len)] where [len] is the length of
the subarray of [arr] starting at offset [i] *)
val to_list : 'a t -> 'a list
(** Convert directly to a list
@since 0.21 *)
val full : 'a array -> 'a t
(** Slice that covers the full array *)

View file

@ -25,7 +25,7 @@ let int64 fmt n = Format.fprintf fmt "%Ld" n
let nativeint fmt n = Format.fprintf fmt "%nd" n
let string_quoted fmt s = Format.fprintf fmt "\"%s\"" s
let list ?(start="[") ?(stop="]") ?(sep=", ") pp fmt l =
let list ?(start="") ?(stop="") ?(sep=", ") pp fmt l =
let rec pp_list l = match l with
| x::((_::_) as l) ->
pp fmt x;
@ -39,7 +39,7 @@ let list ?(start="[") ?(stop="]") ?(sep=", ") pp fmt l =
pp_list l;
Format.pp_print_string fmt stop
let array ?(start="[") ?(stop="]") ?(sep=", ") pp fmt a =
let array ?(start="") ?(stop="") ?(sep=", ") pp fmt a =
Format.pp_print_string fmt start;
for i = 0 to Array.length a - 1 do
if i > 0 then (
@ -50,7 +50,7 @@ let array ?(start="[") ?(stop="]") ?(sep=", ") pp fmt a =
done;
Format.pp_print_string fmt stop
let arrayi ?(start="[") ?(stop="]") ?(sep=", ") pp fmt a =
let arrayi ?(start="") ?(stop="") ?(sep=", ") pp fmt a =
Format.pp_print_string fmt start;
for i = 0 to Array.length a - 1 do
if i > 0 then (
@ -61,7 +61,7 @@ let arrayi ?(start="[") ?(stop="]") ?(sep=", ") pp fmt a =
done;
Format.pp_print_string fmt stop
let seq ?(start="[") ?(stop="]") ?(sep=", ") pp fmt seq =
let seq ?(start="") ?(stop="") ?(sep=", ") pp fmt seq =
Format.pp_print_string fmt start;
let first = ref true in
seq (fun x ->
@ -279,8 +279,28 @@ let sprintf_ c format =
fmt
format
let with_color_sf s fmt =
let buf = Buffer.create 64 in
let out = Format.formatter_of_buffer buf in
if !color_enabled then set_color_tag_handling out;
Format.pp_open_tag out s;
Format.kfprintf
(fun out ->
Format.pp_close_tag out ();
Format.pp_print_flush out ();
Buffer.contents buf)
out fmt
let sprintf fmt = sprintf_ true fmt
let sprintf_no_color fmt = sprintf_ false fmt
let sprintf_dyn_color ~colors fmt = sprintf_ colors fmt
let fprintf_dyn_color ~colors out fmt =
let old_tags = Format.pp_get_mark_tags out () in
Format.pp_set_mark_tags out colors; (* enable/disable tags *)
Format.kfprintf
(fun out -> Format.pp_set_mark_tags out old_tags)
out fmt
(*$T
sprintf "yolo %s %d" "a b" 42 = "yolo a b 42"
@ -301,3 +321,31 @@ let ksprintf ~f fmt =
Format.kfprintf
(fun _ -> Format.pp_print_flush out (); f (Buffer.contents buf))
out fmt
module Dump = struct
type 'a t = 'a printer
let unit = unit
let int = int
let string = string_quoted
let bool = bool
let float = float
let char = char
let int32 = int32
let int64 = int64
let nativeint = nativeint
let list pp = within "[" "]" (hovbox (list ~sep:";" pp))
let array pp = within "[|" "|]" (hovbox (array ~sep:";" pp))
let option pp out x = match x with
| None -> Format.pp_print_string out "None"
| Some x -> Format.fprintf out "Some %a" pp x
let pair p1 p2 = pair p1 p2
let triple p1 p2 p3 = triple p1 p2 p3
let quad p1 p2 p3 p4 = quad p1 p2 p3 p4
end
(*$= & ~printer:(fun s->s)
"[1;2;3]" (to_string Dump.(list int) [1;2;3])
"Some 1" (to_string Dump.(option int) (Some 1))
"[None;Some \"a b\"]" (to_string Dump.(list (option string)) [None; Some "a b"])
*)

View file

@ -137,6 +137,16 @@ val with_colorf : string -> t -> ('a, t, unit, unit) format4 -> 'a
{b status: experimental}
@since 0.16 *)
val with_color_sf : string -> ('a, t, unit, string) format4 -> 'a
(** [with_color_sf "Blue" out "%s %d" "yolo" 42] will behave like
{!sprintf}, but wrapping the content with the given style
Example:
{[
CCFormat.with_color_sf "red" "%a" CCFormat.Dump.(list int) [1;2;3] |> print_endline;;
]}
{b status: experimental}
@since 0.21 *)
(** {2 IO} *)
val output : t -> 'a printer -> 'a -> unit
@ -153,10 +163,28 @@ val sprintf_no_color : ('a, t, unit, string) format4 -> 'a
(** Similar to {!sprintf} but never prints colors
@since 0.16 *)
val sprintf_dyn_color : colors:bool -> ('a, t, unit, string) format4 -> 'a
(** Similar to {!sprintf} but enable/disable colors depending on [colors].
Example:
{[
(* with colors *)
CCFormat.sprintf_dyn_color ~colors:true "@{<Red>%a@}"
CCFormat.Dump.(list int) [1;2;3] |> print_endline;;
(* without colors *)
CCFormat.sprintf_dyn_color ~colors:false "@{<Red>%a@}"
CCFormat.Dump.(list int) [1;2;3] |> print_endline;;
]}
@since 0.21 *)
val fprintf : t -> ('a, t, unit ) format -> 'a
(** Alias to {!Format.fprintf}
@since 0.14 *)
val fprintf_dyn_color : colors:bool -> t -> ('a, t, unit ) format -> 'a
(** Similar to {!fprintf} but enable/disable colors depending on [colors]
@since 0.21 *)
val ksprintf :
f:(string -> 'b) ->
('a, Format.formatter, unit, 'b) format4 ->
@ -172,3 +200,39 @@ val ksprintf :
val to_file : string -> ('a, t, unit, unit) format4 -> 'a
(** Print to the given file *)
(** {2 Dump}
Print structures as OCaml values, so that they can be parsed back
by OCaml (typically, in the toplevel, for debugging).
Example:
{[
Format.printf "%a@." CCFormat.Dump.(list int) CCList.(1 -- 200);;
Format.printf "%a@." CCFormat.Dump.(array (list (pair int bool)))
[| [1, true; 2, false]; []; [42, false] |];;
]}
@since 0.21 *)
module Dump : sig
type 'a t = 'a printer
val unit : unit t
val int : int t
val string : string t
val bool : bool t
val float : float t
val char : char t
val int32 : int32 t
val int64 : int64 t
val nativeint : nativeint t
val list : 'a t -> 'a list t
val array : 'a t -> 'a array t
val option : 'a t -> 'a option t
val pair : 'a t -> 'b t -> ('a * 'b) t
val triple : 'a t -> 'b t -> 'c t -> ('a * 'b * 'c) t
val quad :
'a t -> 'b t -> 'c t -> 'd t ->
('a * 'b * 'c * 'd) t
end

View file

@ -1221,7 +1221,7 @@ end
(** {2 IO} *)
let pp ?(start="[") ?(stop="]") ?(sep=", ") pp_item buf l =
let pp ?(start="") ?(stop="") ?(sep=", ") pp_item buf l =
let rec print l = match l with
| x::((_::_) as l) ->
pp_item buf x;
@ -1232,10 +1232,10 @@ let pp ?(start="[") ?(stop="]") ?(sep=", ") pp_item buf l =
in Buffer.add_string buf start; print l; Buffer.add_string buf stop
(*$T
CCPrint.to_string (pp CCPrint.int) [1;2;3] = "[1, 2, 3]"
CCPrint.to_string (pp ~start:"[" ~stop:"]" CCPrint.int) [1;2;3] = "[1, 2, 3]"
*)
let print ?(start="[") ?(stop="]") ?(sep=", ") pp_item fmt l =
let print ?(start="") ?(stop="") ?(sep=", ") pp_item fmt l =
let rec print fmt l = match l with
| x::((_::_) as l) ->
pp_item fmt x;

View file

@ -113,7 +113,7 @@ module Make(O : Map.OrderedType) = struct
let to_list m =
fold (fun k v acc -> (k,v)::acc) m []
let pp ?(start="{") ?(stop="}") ?(arrow="->") ?(sep=", ") pp_k pp_v buf m =
let pp ?(start="") ?(stop="") ?(arrow="->") ?(sep=", ") pp_k pp_v buf m =
let first = ref true in
Buffer.add_string buf start;
iter
@ -125,7 +125,7 @@ module Make(O : Map.OrderedType) = struct
m;
Buffer.add_string buf stop
let print ?(start="[") ?(stop="]") ?(arrow="->") ?(sep=", ") pp_k pp_v fmt m =
let print ?(start="") ?(stop="") ?(arrow="->") ?(sep=", ") pp_k pp_v fmt m =
Format.pp_print_string fmt start;
let first = ref true in
iter

View file

@ -25,7 +25,7 @@ let float3 buf f = Printf.bprintf buf "%.3f" f
let float buf f = Buffer.add_string buf (string_of_float f)
let char buf c = Buffer.add_char buf c
let list ?(start="[") ?(stop="]") ?(sep=", ") pp buf l =
let list ?(start="") ?(stop="") ?(sep=", ") pp buf l =
let rec pp_list l = match l with
| x::((_::_) as l) ->
pp buf x;
@ -38,7 +38,7 @@ let list ?(start="[") ?(stop="]") ?(sep=", ") pp buf l =
pp_list l;
Buffer.add_string buf stop
let array ?(start="[") ?(stop="]") ?(sep=", ") pp buf a =
let array ?(start="") ?(stop="") ?(sep=", ") pp buf a =
Buffer.add_string buf start;
for i = 0 to Array.length a - 1 do
(if i > 0 then Buffer.add_string buf sep);
@ -46,7 +46,7 @@ let array ?(start="[") ?(stop="]") ?(sep=", ") pp buf a =
done;
Buffer.add_string buf stop
let arrayi ?(start="[") ?(stop="]") ?(sep=", ") pp buf a =
let arrayi ?(start="") ?(stop="") ?(sep=", ") pp buf a =
Buffer.add_string buf start;
for i = 0 to Array.length a - 1 do
(if i > 0 then Buffer.add_string buf sep);
@ -54,7 +54,7 @@ let arrayi ?(start="[") ?(stop="]") ?(sep=", ") pp buf a =
done;
Buffer.add_string buf stop
let seq ?(start="[") ?(stop="]") ?(sep=", ") pp buf seq =
let seq ?(start="") ?(stop="") ?(sep=", ") pp buf seq =
Buffer.add_string buf start;
let first = ref true in
seq (fun x ->

View file

@ -51,7 +51,7 @@ module Make(O : Map.OrderedType) = struct
let to_list = elements
let pp ?(start="{") ?(stop="}") ?(sep=", ") pp_x buf m =
let pp ?(start="") ?(stop="") ?(sep=", ") pp_x buf m =
let first = ref true in
Buffer.add_string buf start;
iter
@ -61,7 +61,7 @@ module Make(O : Map.OrderedType) = struct
m;
Buffer.add_string buf stop
let print ?(start="[") ?(stop="]") ?(sep=", ") pp_x fmt m =
let print ?(start="") ?(stop="") ?(sep=", ") pp_x fmt m =
Format.pp_print_string fmt start;
let first = ref true in
iter

View file

@ -737,7 +737,7 @@ let to_klist v =
else `Cons (v.vec.(i), aux (i+1))
in aux 0
let pp ?(start="[") ?(stop="]") ?(sep=", ") pp_item buf v =
let pp ?(start="") ?(stop="") ?(sep=", ") pp_item buf v =
Buffer.add_string buf start;
iteri
(fun i x ->
@ -746,7 +746,7 @@ let pp ?(start="[") ?(stop="]") ?(sep=", ") pp_item buf v =
) v;
Buffer.add_string buf stop
let print ?(start="[") ?(stop="]") ?(sep=", ") pp_item fmt v =
let print ?(start="") ?(stop="") ?(sep=", ") pp_item fmt v =
Format.pp_print_string fmt start;
iteri
(fun i x ->

View file

@ -1,6 +1,6 @@
# OASIS_START
# DO NOT EDIT (digest: 5fef39d6aa86c783d2d134baf25c1157)
version = "0.20"
# DO NOT EDIT (digest: 2366633cbce20e67d6074e01f20927dc)
version = "0.21"
description = "A modular standard library focused on data structures."
requires = "bytes result"
archive(byte) = "containers.cma"
@ -9,7 +9,7 @@ archive(native) = "containers.cmxa"
archive(native, plugin) = "containers.cmxs"
exists_if = "containers.cma"
package "unix" (
version = "0.20"
version = "0.21"
description = "A modular standard library focused on data structures."
requires = "bytes unix"
archive(byte) = "containers_unix.cma"
@ -20,7 +20,7 @@ package "unix" (
)
package "top" (
version = "0.20"
version = "0.21"
description = "A modular standard library focused on data structures."
requires =
"compiler-libs.common containers containers.data containers.bigarray containers.string containers.unix containers.sexp containers.iter"
@ -32,7 +32,7 @@ package "top" (
)
package "thread" (
version = "0.20"
version = "0.21"
description = "A modular standard library focused on data structures."
requires = "containers threads"
archive(byte) = "containers_thread.cma"
@ -43,7 +43,7 @@ package "thread" (
)
package "string" (
version = "0.20"
version = "0.21"
description = "A modular standard library focused on data structures."
requires = "bytes"
archive(byte) = "containers_string.cma"
@ -54,7 +54,7 @@ package "string" (
)
package "sexp" (
version = "0.20"
version = "0.21"
description = "A modular standard library focused on data structures."
requires = "bytes"
archive(byte) = "containers_sexp.cma"
@ -65,7 +65,7 @@ package "sexp" (
)
package "iter" (
version = "0.20"
version = "0.21"
description = "A modular standard library focused on data structures."
archive(byte) = "containers_iter.cma"
archive(byte, plugin) = "containers_iter.cma"
@ -75,7 +75,7 @@ package "iter" (
)
package "io" (
version = "0.20"
version = "0.21"
description = "A modular standard library focused on data structures."
requires = "bytes"
archive(byte) = "containers_io.cma"
@ -86,7 +86,7 @@ package "io" (
)
package "data" (
version = "0.20"
version = "0.21"
description = "A modular standard library focused on data structures."
requires = "bytes"
archive(byte) = "containers_data.cma"
@ -97,7 +97,7 @@ package "data" (
)
package "bigarray" (
version = "0.20"
version = "0.21"
description = "A modular standard library focused on data structures."
requires = "containers bigarray bytes"
archive(byte) = "containers_bigarray.cma"
@ -108,7 +108,7 @@ package "bigarray" (
)
package "advanced" (
version = "0.20"
version = "0.21"
description = "A modular standard library focused on data structures."
requires = "containers sequence"
archive(byte) = "containers_advanced.cma"

View file

@ -81,6 +81,9 @@ module Vector = CCVector
module Int64 = CCInt64
(** @since 0.13 *)
module IO = CCIO
(** @since 0.21 *)
module Char = struct
include Char
include (CCChar : module type of CCChar with type t := t)

View file

@ -116,7 +116,7 @@ let to_gen a =
type 'a printer = Format.formatter -> 'a -> unit
let print ?(start="[|") ?(stop="|]") ?(sep=";") pp_item out a =
let print ?(start="") ?(stop="") ?(sep=", ") pp_item out a =
Format.pp_print_string out start;
for k = 0 to Array.length a - 1 do
if k > 0 then (

View file

@ -41,7 +41,7 @@ let _must_escape s =
for i = 0 to String.length s - 1 do
let c = String.unsafe_get s i in
match c with
| ' ' | ';' | ')' | '(' | '"' | '\\' | '\n' | '\t' -> raise Exit
| ' ' | ';' | ')' | '(' | '"' | '\\' | '\n' | '\t' | '\r' -> raise Exit
| _ when Char.code c > 127 -> raise Exit (* non-ascii *)
| _ -> ()
done;
@ -176,11 +176,11 @@ module MakeDecode(M : MONAD) = struct
let rec expr k t =
if t.i = t.len then _refill t (expr k) _error_eof
else match _get t with
| ' ' | '\t' | '\n' -> expr k t
| ' ' | '\t' | '\r' | '\n' -> expr k t
| c -> expr_starting_with c k t
and expr_starting_with c k t = match c with
| ' ' | '\t' | '\n' -> assert false
| ' ' | '\t' | '\r' | '\n' -> assert false
| ';' -> skip_comment (fun _ () -> expr k t) t
| '(' -> expr_list [] k t
| ')' -> _error t "unexpected ')'"
@ -194,7 +194,7 @@ module MakeDecode(M : MONAD) = struct
and expr_list acc k t =
if t.i = t.len then _refill t (expr_list acc k) _error_eof
else match _get t with
| ' ' | '\t' | '\n' -> expr_list acc k t
| ' ' | '\t' | '\r' | '\n' -> expr_list acc k t
| ')' -> k None (`List (List.rev acc))
| c ->
expr_starting_with c
@ -216,7 +216,7 @@ module MakeDecode(M : MONAD) = struct
else match _get t with
| '\\' -> _error t "unexpected '\\' in non-quoted string"
| '"' -> _error t "unexpected '\"' in the middle of an atom"
| (' ' | '\n' | '\t' | '(' | ')') as c ->
| (' ' | '\r' | '\n' | '\t' | '(' | ')') as c ->
_return_atom (Some c) k t
| c ->
Buffer.add_char t.atom c;
@ -277,7 +277,7 @@ module MakeDecode(M : MONAD) = struct
if t.i = t.len
then _refill t (expr_or_end k) (fun _ -> M.return `End)
else match _get t with
| ' ' | '\t' | '\n' -> expr_or_end k t
| ' ' | '\t' | '\r' | '\n' -> expr_or_end k t
| c -> expr_starting_with c k t
(* entry point *)
@ -308,6 +308,8 @@ let parse_string s : t or_error =
(*$T
CCError.to_opt (parse_string "(abc d/e/f \"hello \\\" () world\" )") <> None
CCError.to_opt (parse_string "(abc ( d e ffff ) \"hello/world\")") <> None
(parse_string "(abc\r\n ( d e \r\tffff ))") \
= `Ok (`List [`Atom "abc"; `List [`Atom "d"; `Atom "e"; `Atom "ffff"]])
*)
(*$inject