diff options
author | Damien Doligez <damien.doligez-inria.fr> | 2014-08-22 13:45:02 +0000 |
---|---|---|
committer | Damien Doligez <damien.doligez-inria.fr> | 2014-08-22 13:45:02 +0000 |
commit | cbfe627f925ab2bab93bae7a7bc9f6ee6afb8637 (patch) | |
tree | af5ec283ac3175b1ab95dd745dbd05f2298b9da6 /stdlib | |
parent | 09ad9c1abbe6bee443a55379223280dab3de4749 (diff) |
merge changes from branch 4.02 from branching (rev 14852) to 4.02.0+rc1 (rev 15121)
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@15125 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'stdlib')
-rw-r--r-- | stdlib/.depend | 8 | ||||
-rw-r--r-- | stdlib/StdlibModules | 2 | ||||
-rw-r--r-- | stdlib/array.mli | 2 | ||||
-rw-r--r-- | stdlib/arrayLabels.mli | 6 | ||||
-rw-r--r-- | stdlib/buffer.ml | 20 | ||||
-rw-r--r-- | stdlib/buffer.mli | 8 | ||||
-rw-r--r-- | stdlib/bytes.ml | 31 | ||||
-rw-r--r-- | stdlib/bytes.mli | 168 | ||||
-rw-r--r-- | stdlib/bytesLabels.mli | 4 | ||||
-rw-r--r-- | stdlib/camlinternalFormat.ml | 91 | ||||
-rw-r--r-- | stdlib/camlinternalFormat.mli | 6 | ||||
-rw-r--r-- | stdlib/camlinternalOO.ml | 6 | ||||
-rw-r--r-- | stdlib/filename.mli | 7 | ||||
-rw-r--r-- | stdlib/format.ml | 30 | ||||
-rw-r--r-- | stdlib/format.mli | 12 | ||||
-rw-r--r-- | stdlib/gc.mli | 3 | ||||
-rw-r--r-- | stdlib/lazy.mli | 6 | ||||
-rw-r--r-- | stdlib/marshal.ml | 11 | ||||
-rw-r--r-- | stdlib/marshal.mli | 3 | ||||
-rw-r--r-- | stdlib/nativeint.mli | 4 | ||||
-rw-r--r-- | stdlib/parsing.ml | 16 | ||||
-rw-r--r-- | stdlib/pervasives.ml | 8 | ||||
-rw-r--r-- | stdlib/pervasives.mli | 2 | ||||
-rw-r--r-- | stdlib/scanf.ml | 3 | ||||
-rw-r--r-- | stdlib/sort.mli | 3 | ||||
-rw-r--r-- | stdlib/string.ml | 4 | ||||
-rw-r--r-- | stdlib/string.mli | 25 | ||||
-rw-r--r-- | stdlib/sys.mli | 7 | ||||
-rw-r--r-- | stdlib/weak.ml | 4 |
29 files changed, 376 insertions, 124 deletions
diff --git a/stdlib/.depend b/stdlib/.depend index e3a0a671d..96f95082d 100644 --- a/stdlib/.depend +++ b/stdlib/.depend @@ -165,8 +165,8 @@ std_exit.cmo : std_exit.cmx : stream.cmo : string.cmi obj.cmi list.cmi lazy.cmi bytes.cmi stream.cmi stream.cmx : string.cmx obj.cmx list.cmx lazy.cmx bytes.cmx stream.cmi -string.cmo : pervasives.cmi obj.cmi bytes.cmi string.cmi -string.cmx : pervasives.cmx obj.cmx bytes.cmx string.cmi +string.cmo : pervasives.cmi list.cmi bytes.cmi string.cmi +string.cmx : pervasives.cmx list.cmx bytes.cmx string.cmi stringLabels.cmo : string.cmi stringLabels.cmi stringLabels.cmx : string.cmx stringLabels.cmi sys.cmo : sys.cmi @@ -291,8 +291,8 @@ std_exit.cmo : std_exit.p.cmx : stream.cmo : string.cmi obj.cmi list.cmi lazy.cmi bytes.cmi stream.cmi stream.p.cmx : string.p.cmx obj.p.cmx list.p.cmx lazy.p.cmx bytes.p.cmx stream.cmi -string.cmo : pervasives.cmi obj.cmi bytes.cmi string.cmi -string.p.cmx : pervasives.p.cmx obj.p.cmx bytes.p.cmx string.cmi +string.cmo : pervasives.cmi list.cmi bytes.cmi string.cmi +string.p.cmx : pervasives.p.cmx list.p.cmx bytes.p.cmx string.cmi stringLabels.cmo : string.cmi stringLabels.cmi stringLabels.p.cmx : string.p.cmx stringLabels.cmi sys.cmo : sys.cmi diff --git a/stdlib/StdlibModules b/stdlib/StdlibModules index a4552ad94..abdfcb362 100644 --- a/stdlib/StdlibModules +++ b/stdlib/StdlibModules @@ -24,6 +24,8 @@ STDLIB_MODULES=\ bytes \ bytesLabels \ callback \ + camlinternalFormat \ + camlinternalFormatBasics \ camlinternalLazy \ camlinternalMod \ camlinternalOO \ diff --git a/stdlib/array.mli b/stdlib/array.mli index 7c0049e28..e9a64528f 100644 --- a/stdlib/array.mli +++ b/stdlib/array.mli @@ -47,6 +47,7 @@ external make : int -> 'a -> 'a array = "caml_make_vect" size is only [Sys.max_array_length / 2].*) external create : int -> 'a -> 'a array = "caml_make_vect" + [@@ocaml.deprecated] (** @deprecated [Array.create] is an alias for {!Array.make}. *) val init : int -> (int -> 'a) -> 'a array @@ -73,6 +74,7 @@ val make_matrix : int -> int -> 'a -> 'a array array size is only [Sys.max_array_length / 2]. *) val create_matrix : int -> int -> 'a -> 'a array array + [@@ocaml.deprecated] (** @deprecated [Array.create_matrix] is an alias for {!Array.make_matrix}. *) val append : 'a array -> 'a array -> 'a array diff --git a/stdlib/arrayLabels.mli b/stdlib/arrayLabels.mli index 03b6224ae..cf8b650e5 100644 --- a/stdlib/arrayLabels.mli +++ b/stdlib/arrayLabels.mli @@ -47,7 +47,8 @@ external make : int -> 'a -> 'a array = "caml_make_vect" size is only [Sys.max_array_length / 2].*) external create : int -> 'a -> 'a array = "caml_make_vect" -(** @deprecated [Array.create] is an alias for {!ArrayLabels.make}. *) + [@@ocaml.deprecated] +(** @deprecated [ArrayLabels.create] is an alias for {!ArrayLabels.make}. *) val init : int -> f:(int -> 'a) -> 'a array (** [Array.init n f] returns a fresh array of length [n], @@ -73,7 +74,8 @@ val make_matrix : dimx:int -> dimy:int -> 'a -> 'a array array size is only [Sys.max_array_length / 2]. *) val create_matrix : dimx:int -> dimy:int -> 'a -> 'a array array -(** @deprecated [Array.create_matrix] is an alias for + [@@ocaml.deprecated] +(** @deprecated [ArrayLabels.create_matrix] is an alias for {!ArrayLabels.make_matrix}. *) val append : 'a array -> 'a array -> 'a array diff --git a/stdlib/buffer.ml b/stdlib/buffer.ml index 659729d3c..986fe6f33 100644 --- a/stdlib/buffer.ml +++ b/stdlib/buffer.ml @@ -78,25 +78,25 @@ let add_char b c = Bytes.unsafe_set b.buffer pos c; b.position <- pos + 1 -let add_subbytes b s offset len = - if offset < 0 || len < 0 || offset > Bytes.length s - len - then invalid_arg "Buffer.add_subbytes"; +let add_substring b s offset len = + if offset < 0 || len < 0 || offset + len > String.length s + then invalid_arg "Buffer.add_substring/add_subbytes"; let new_position = b.position + len in if new_position > b.length then resize b len; - Bytes.unsafe_blit s offset b.buffer b.position len; + Bytes.blit_string s offset b.buffer b.position len; b.position <- new_position -let add_substring b s offset len = - add_subbytes b (Bytes.unsafe_of_string s) offset len +let add_subbytes b s offset len = + add_substring b (Bytes.unsafe_to_string s) offset len -let add_bytes b s = - let len = Bytes.length s in +let add_string b s = + let len = String.length s in let new_position = b.position + len in if new_position > b.length then resize b len; - Bytes.unsafe_blit s 0 b.buffer b.position len; + Bytes.blit_string s 0 b.buffer b.position len; b.position <- new_position -let add_string b s = add_bytes b (Bytes.unsafe_of_string s) +let add_bytes b s = add_string b (Bytes.unsafe_to_string s) let add_buffer b bs = add_subbytes b bs.buffer 0 bs.position diff --git a/stdlib/buffer.mli b/stdlib/buffer.mli index 855a06166..e7ce8b999 100644 --- a/stdlib/buffer.mli +++ b/stdlib/buffer.mli @@ -46,9 +46,9 @@ val to_bytes : t -> bytes val sub : t -> int -> int -> string (** [Buffer.sub b off len] returns (a copy of) the bytes from the -current contents of the buffer [b] starting at offset [off] of length -[len] bytes. May raise [Invalid_argument] if out of bounds request. The -buffer itself is unaffected. *) + current contents of the buffer [b] starting at offset [off] of + length [len] bytes. May raise [Invalid_argument] if out of bounds + request. The buffer itself is unaffected. *) val blit : t -> int -> bytes -> int -> int -> unit (** [Buffer.blit src srcoff dst dstoff len] copies [len] characters from @@ -63,7 +63,7 @@ val blit : t -> int -> bytes -> int -> int -> unit val nth : t -> int -> char (** get the n-th character of the buffer. Raise [Invalid_argument] if -index out of bounds *) + index out of bounds *) val length : t -> int (** Return the number of characters currently contained in the buffer. *) diff --git a/stdlib/bytes.ml b/stdlib/bytes.ml index cfcd1ec05..ece7c1ea5 100644 --- a/stdlib/bytes.ml +++ b/stdlib/bytes.ml @@ -14,18 +14,22 @@ (* Byte sequence operations *) external length : bytes -> int = "%string_length" +external string_length : string -> int = "%string_length" external get : bytes -> int -> char = "%string_safe_get" external set : bytes -> int -> char -> unit = "%string_safe_set" external create : int -> bytes = "caml_create_string" external unsafe_get : bytes -> int -> char = "%string_unsafe_get" external unsafe_set : bytes -> int -> char -> unit = "%string_unsafe_set" -external unsafe_blit : bytes -> int -> bytes -> int -> int -> unit - = "caml_blit_string" "noalloc" external unsafe_fill : bytes -> int -> int -> char -> unit = "caml_fill_string" "noalloc" external unsafe_to_string : bytes -> string = "%identity" external unsafe_of_string : string -> bytes = "%identity" +external unsafe_blit : bytes -> int -> bytes -> int -> int -> unit + = "caml_blit_string" "noalloc" +external unsafe_blit_string : string -> int -> bytes -> int -> int -> unit + = "caml_blit_string" "noalloc" + let make n c = let s = create n in unsafe_fill s 0 n c; @@ -60,6 +64,14 @@ let sub s ofs len = let sub_string b ofs len = unsafe_to_string (sub b ofs len) +let extend s left right = + let len = length s + left + right in + let r = create len in + let (srcoff, dstoff) = if left < 0 then -left, 0 else 0, left in + let cpylen = min (length s - srcoff) (len - dstoff) in + if cpylen > 0 then unsafe_blit s srcoff r dstoff cpylen; + r + let fill s ofs len c = if ofs < 0 || len < 0 || ofs > length s - len then invalid_arg "Bytes.fill" @@ -71,6 +83,12 @@ let blit s1 ofs1 s2 ofs2 len = then invalid_arg "Bytes.blit" else unsafe_blit s1 ofs1 s2 ofs2 len +let blit_string s1 ofs1 s2 ofs2 len = + if len < 0 || ofs1 < 0 || ofs1 > string_length s1 - len + || ofs2 < 0 || ofs2 > length s2 - len + then invalid_arg "Bytes.blit_string" + else unsafe_blit_string s1 ofs1 s2 ofs2 len + let iter f a = for i = 0 to length a - 1 do f(unsafe_get a i) done @@ -95,6 +113,15 @@ let concat sep l = tl; r +let cat s1 s2 = + let l1 = length s1 in + let l2 = length s2 in + let r = create (l1 + l2) in + unsafe_blit s1 0 r 0 l1; + unsafe_blit s2 0 r l1 l2; + r +;; + external is_printable: char -> bool = "caml_is_printable" external char_code: char -> int = "%identity" external char_chr: int -> char = "%identity" diff --git a/stdlib/bytes.mli b/stdlib/bytes.mli index d9c104674..82b28a28c 100644 --- a/stdlib/bytes.mli +++ b/stdlib/bytes.mli @@ -99,6 +99,16 @@ val sub : bytes -> int -> int -> bytes val sub_string : bytes -> int -> int -> string (** Same as [sub] but return a string instead of a byte sequence. *) +val extend : bytes -> int -> int -> bytes +(** [extend s left right] returns a new byte sequence that contains + the bytes of [s], with [left] uninitialized bytes prepended and + [right] uninitialized bytes appended to it. If [left] or [right] + is negative, then bytes are removed (instead of appended) from + the corresponding side of [s]. + + Raise [Invalid_argument] if the result length is negative or + longer than {!Sys.max_string_length} bytes. *) + val fill : bytes -> int -> int -> char -> unit (** [fill s start len c] modifies [s] in place, replacing [len] characters with [c], starting at [start]. @@ -117,10 +127,29 @@ val blit : bytes -> int -> bytes -> int -> int -> unit designate a valid range of [src], or if [dstoff] and [len] do not designate a valid range of [dst]. *) +val blit_string : string -> int -> bytes -> int -> int -> unit +(** [blit src srcoff dst dstoff len] copies [len] bytes from string + [src], starting at index [srcoff], to byte sequence [dst], + starting at index [dstoff]. + + Raise [Invalid_argument] if [srcoff] and [len] do not + designate a valid range of [src], or if [dstoff] and [len] + do not designate a valid range of [dst]. *) + val concat : bytes -> bytes list -> bytes (** [concat sep sl] concatenates the list of byte sequences [sl], inserting the separator byte sequence [sep] between each, and - returns the result as a new byte sequence. *) + returns the result as a new byte sequence. + + Raise [Invalid_argument] if the result is longer than + {!Sys.max_string_length} bytes. *) + +val cat : bytes -> bytes -> bytes +(** [cat s1 s2] concatenates [s1] and [s2] and returns the result + as new byte sequence. + + Raise [Invalid_argument] if the result is longer than + {!Sys.max_string_length} bytes. *) val iter : (char -> unit) -> bytes -> unit (** [iter f s] applies function [f] in turn to all the bytes of [s]. @@ -149,7 +178,10 @@ val trim : bytes -> bytes val escaped : bytes -> bytes (** Return a copy of the argument, with special characters represented - by escape sequences, following the lexical conventions of OCaml. *) + by escape sequences, following the lexical conventions of OCaml. + + Raise [Invalid_argument] if the result is longer than + {!Sys.max_string_length} bytes. *) val index : bytes -> char -> int (** [index s c] returns the index of the first occurrence of byte [c] @@ -223,6 +255,136 @@ val compare: t -> t -> int this function [compare] allows the module [Bytes] to be passed as argument to the functors {!Set.Make} and {!Map.Make}. *) + +(** {4 Unsafe conversions (for advanced users)} + + This section describes unsafe, low-level conversion functions + between [bytes] and [string]. They do not copy the internal data; + used improperly, they can break the immutability invariant on + strings provided by the [-safe-string] option. They are available for + expert library authors, but for most purposes you should use the + always-correct {!Bytes.to_string} and {!Bytes.of_string} instead. +*) + +val unsafe_to_string : bytes -> string +(** Unsafely convert a byte sequence into a string. + + To reason about the use of [unsafe_to_string], it is convenient to + consider an "ownership" discipline. A piece of code that + manipulates some data "owns" it; there are several disjoint ownership + modes, including: + - Unique ownership: the data may be accessed and mutated + - Shared ownership: the data has several owners, that may only + access it, not mutate it. + + Unique ownership is linear: passing the data to another piece of + code means giving up ownership (we cannot write the + data again). A unique owner may decide to make the data shared + (giving up mutation rights on it), but shared data may not become + uniquely-owned again. + + [unsafe_to_string s] can only be used when the caller owns the byte + sequence [s] -- either uniquely or as shared immutable data. The + caller gives up ownership of [s], and gains ownership of the + returned string. + + There are two valid use-cases that respect this ownership + discipline: + + 1. Creating a string by initializing and mutating a byte sequence + that is never changed after initialization is performed. + + {[ +let string_init len f : string = + let s = Bytes.create len in + for i = 0 to len - 1 do Bytes.set s i (f i) done; + Bytes.unsafe_to_string s + ]} + + This function is safe because the byte sequence [s] will never be + accessed or mutated after [unsafe_to_string] is called. The + [string_init] code gives up ownership of [s], and returns the + ownership of the resulting string to its caller. + + Note that it would be unsafe if [s] was passed as an additional + parameter to the function [f] as it could escape this way and be + mutated in the future -- [string_init] would give up ownership of + [s] to pass it to [f], and could not call [unsafe_to_string] + safely. + + We have provided the {!String.init}, {!String.map} and + {!String.mapi} functions to cover most cases of building + new strings. You should prefer those over [to_string] or + [unsafe_to_string] whenever applicable. + + 2. Temporarily giving ownership of a byte sequence to a function + that expects a uniquely owned string and returns ownership back, so + that we can mutate the sequence again after the call ended. + + {[ +let bytes_length (s : bytes) = + String.length (Bytes.unsafe_to_string s) + ]} + + In this use-case, we do not promise that [s] will never be mutated + after the call to [bytes_length s]. The {!String.length} function + temporarily borrows unique ownership of the byte sequence + (and sees it as a [string]), but returns this ownership back to + the caller, which may assume that [s] is still a valid byte + sequence after the call. Note that this is only correct because we + know that {!String.length} does not capture its argument -- it could + escape by a side-channel such as a memoization combinator. + + The caller may not mutate [s] while the string is borrowed (it has + temporarily given up ownership). This affects concurrent programs, + but also higher-order functions: if [String.length] returned + a closure to be called later, [s] should not be mutated until this + closure is fully applied and returns ownership. +*) + +val unsafe_of_string : string -> bytes +(** Unsafely convert a shared string to a byte sequence that should + not be mutated. + + The same ownership discipline that makes [unsafe_to_string] + correct applies to [unsafe_of_string]: you may use it if you were + the owner of the [string] value, and you will own the return + [bytes] in the same mode. + + In practice, unique ownership of string values is extremely + difficult to reason about correctly. You should always assume + strings are shared, never uniquely owned. + + For example, string literals are implicitly shared by the + compiler, so you never uniquely own them. + + {[ +let incorrect = Bytes.unsafe_of_string "hello" +let s = Bytes.of_string "hello" + ]} + + The first declaration is incorrect, because the string literal + ["hello"] could be shared by the compiler with other parts of the + program, and mutating [incorrect] is a bug. You must always use + the second version, which performs a copy and is thus correct. + + Assuming unique ownership of strings that are not string + literals, but are (partly) built from string literals, is also + incorrect. For example, mutating [unsafe_of_string ("foo" ^ s)] + could mutate the shared string ["foo"] -- assuming a rope-like + representation of strings. More generally, functions operating on + strings will assume shared ownership, they do not preserve unique + ownership. It is thus incorrect to assume unique ownership of the + result of [unsafe_of_string]. + + The only case we have reasonable confidence is safe is if the + produced [bytes] is shared -- used as an immutable byte + sequence. This is possibly useful for incremental migration of + low-level programs that manipulate immutable sequences of bytes + (for example {!Marshal.from_bytes}) and previously used the + [string] type for this purpose. +*) + (**/**) (* The following is for system use only. Do not call directly. *) @@ -234,5 +396,3 @@ external unsafe_blit : = "caml_blit_string" "noalloc" external unsafe_fill : bytes -> int -> int -> char -> unit = "caml_fill_string" "noalloc" -external unsafe_to_string : bytes -> string = "%identity" -external unsafe_of_string : string -> bytes = "%identity" diff --git a/stdlib/bytesLabels.mli b/stdlib/bytesLabels.mli index b7ad82147..d48d95f5c 100644 --- a/stdlib/bytesLabels.mli +++ b/stdlib/bytesLabels.mli @@ -209,5 +209,5 @@ external unsafe_blit : unit = "caml_blit_string" "noalloc" external unsafe_fill : bytes -> pos:int -> len:int -> char -> unit = "caml_fill_string" "noalloc" -external unsafe_to_string : bytes -> string = "%identity" -external unsafe_of_string : string -> bytes = "%identity" +val unsafe_to_string : bytes -> string +val unsafe_of_string : string -> bytes diff --git a/stdlib/camlinternalFormat.ml b/stdlib/camlinternalFormat.ml index f28e05f18..983fc33a9 100644 --- a/stdlib/camlinternalFormat.ml +++ b/stdlib/camlinternalFormat.ml @@ -120,13 +120,15 @@ type ('b, 'c) acc_formatting_gen = (* Reversed list of printing atoms. *) (* Used to accumulate printf arguments. *) and ('b, 'c) acc = - | Acc_formatting_lit of ('b, 'c) acc * formatting_lit(* Special fmtting (box) *) + | Acc_formatting_lit of ('b, 'c) acc * formatting_lit (* Special fmtting (box) *) | Acc_formatting_gen of ('b, 'c) acc * ('b, 'c) acc_formatting_gen (* Special fmtting (box) *) - | Acc_string of ('b, 'c) acc * string (* Literal or generated string*) - | Acc_char of ('b, 'c) acc * char (* Literal or generated char *) - | Acc_delay of ('b, 'c) acc * ('b -> 'c) (* Delayed printing (%a, %t) *) - | Acc_flush of ('b, 'c) acc (* Flush *) - | Acc_invalid_arg of ('b, 'c) acc * string (* Raise Invalid_argument msg *) + | Acc_string_literal of ('b, 'c) acc * string (* Literal string *) + | Acc_char_literal of ('b, 'c) acc * char (* Literal char *) + | Acc_data_string of ('b, 'c) acc * string (* Generated string *) + | Acc_data_char of ('b, 'c) acc * char (* Generated char *) + | Acc_delay of ('b, 'c) acc * ('b -> 'c) (* Delayed printing (%a, %t) *) + | Acc_flush of ('b, 'c) acc (* Flush *) + | Acc_invalid_arg of ('b, 'c) acc * string (* Raise Invalid_argument msg *) | End_of_acc (* List of heterogeneous values. *) @@ -1363,11 +1365,11 @@ let rec make_printf : type a b c d e f . fun k o acc fmt -> match fmt with | Char rest -> fun c -> - let new_acc = Acc_char (acc, c) in + let new_acc = Acc_data_char (acc, c) in make_printf k o new_acc rest | Caml_char rest -> fun c -> - let new_acc = Acc_string (acc, format_caml_char c) in + let new_acc = Acc_data_string (acc, format_caml_char c) in make_printf k o new_acc rest | String (pad, rest) -> make_string_padding k o acc rest pad (fun str -> str) @@ -1384,7 +1386,7 @@ fun k o acc fmt -> match fmt with | Float (fconv, pad, prec, rest) -> make_float_padding_precision k o acc rest pad prec fconv | Bool rest -> - fun b -> make_printf k o (Acc_string (acc, string_of_bool b)) rest + fun b -> make_printf k o (Acc_data_string (acc, string_of_bool b)) rest | Alpha rest -> fun f x -> make_printf k o (Acc_delay (acc, fun o -> f o x)) rest | Theta rest -> @@ -1403,15 +1405,15 @@ fun k o acc fmt -> match fmt with make_printf k o (Acc_flush acc) rest | String_literal (str, rest) -> - make_printf k o (Acc_string (acc, str)) rest + make_printf k o (Acc_string_literal (acc, str)) rest | Char_literal (chr, rest) -> - make_printf k o (Acc_char (acc, chr)) rest + make_printf k o (Acc_char_literal (acc, chr)) rest | Format_arg (_, sub_fmtty, rest) -> let ty = string_of_fmtty sub_fmtty in (fun str -> ignore str; - make_printf k o (Acc_string (acc, ty)) rest) + make_printf k o (Acc_data_string (acc, ty)) rest) | Format_subst (_, fmtty, rest) -> fun (Format (fmt, _)) -> make_printf k o acc (concat_fmt (recast fmt fmtty) rest) @@ -1424,7 +1426,7 @@ fun k o acc fmt -> match fmt with (* Accepted for backward compatibility. *) (* Interpret %l, %n and %L as %u. *) fun n -> - let new_acc = Acc_string (acc, format_int "%u" n) in + let new_acc = Acc_data_string (acc, format_int "%u" n) in make_printf k o new_acc rest | Ignored_param (ign, rest) -> make_ignored_param k o acc ign rest @@ -1507,15 +1509,15 @@ and make_string_padding : type x z a b c d e f . fun k o acc fmt pad trans -> match pad with | No_padding -> fun x -> - let new_acc = Acc_string (acc, trans x) in + let new_acc = Acc_data_string (acc, trans x) in make_printf k o new_acc fmt | Lit_padding (padty, width) -> fun x -> - let new_acc = Acc_string (acc, fix_padding padty width (trans x)) in + let new_acc = Acc_data_string (acc, fix_padding padty width (trans x)) in make_printf k o new_acc fmt | Arg_padding padty -> fun w x -> - let new_acc = Acc_string (acc, fix_padding padty w (trans x)) in + let new_acc = Acc_data_string (acc, fix_padding padty w (trans x)) in make_printf k o new_acc fmt (* Fix padding and precision for int, int32, nativeint or int64. *) @@ -1529,39 +1531,39 @@ and make_int_padding_precision : type x y z a b c d e f . | No_padding, No_precision -> fun x -> let str = trans iconv x in - make_printf k o (Acc_string (acc, str)) fmt + make_printf k o (Acc_data_string (acc, str)) fmt | No_padding, Lit_precision p -> fun x -> let str = fix_int_precision p (trans iconv x) in - make_printf k o (Acc_string (acc, str)) fmt + make_printf k o (Acc_data_string (acc, str)) fmt | No_padding, Arg_precision -> fun p x -> let str = fix_int_precision p (trans iconv x) in - make_printf k o (Acc_string (acc, str)) fmt + make_printf k o (Acc_data_string (acc, str)) fmt | Lit_padding (padty, w), No_precision -> fun x -> let str = fix_padding padty w (trans iconv x) in - make_printf k o (Acc_string (acc, str)) fmt + make_printf k o (Acc_data_string (acc, str)) fmt | Lit_padding (padty, w), Lit_precision p -> fun x -> let str = fix_padding padty w (fix_int_precision p (trans iconv x)) in - make_printf k o (Acc_string (acc, str)) fmt + make_printf k o (Acc_data_string (acc, str)) fmt | Lit_padding (padty, w), Arg_precision -> fun p x -> let str = fix_padding padty w (fix_int_precision p (trans iconv x)) in - make_printf k o (Acc_string (acc, str)) fmt + make_printf k o (Acc_data_string (acc, str)) fmt | Arg_padding padty, No_precision -> fun w x -> let str = fix_padding padty w (trans iconv x) in - make_printf k o (Acc_string (acc, str)) fmt + make_printf k o (Acc_data_string (acc, str)) fmt | Arg_padding padty, Lit_precision p -> fun w x -> let str = fix_padding padty w (fix_int_precision p (trans iconv x)) in - make_printf k o (Acc_string (acc, str)) fmt + make_printf k o (Acc_data_string (acc, str)) fmt | Arg_padding padty, Arg_precision -> fun w p x -> let str = fix_padding padty w (fix_int_precision p (trans iconv x)) in - make_printf k o (Acc_string (acc, str)) fmt + make_printf k o (Acc_data_string (acc, str)) fmt (* Convert a float, fix padding and precision if needed. *) (* Take the float argument and one or two extra integer arguments if needed. *) @@ -1573,41 +1575,41 @@ and make_float_padding_precision : type x y a b c d e f . | No_padding, No_precision -> fun x -> let str = convert_float fconv default_float_precision x in - make_printf k o (Acc_string (acc, str)) fmt + make_printf k o (Acc_data_string (acc, str)) fmt | No_padding, Lit_precision p -> fun x -> let str = convert_float fconv p x in - make_printf k o (Acc_string (acc, str)) fmt + make_printf k o (Acc_data_string (acc, str)) fmt | No_padding, Arg_precision -> fun p x -> let str = convert_float fconv p x in - make_printf k o (Acc_string (acc, str)) fmt + make_printf k o (Acc_data_string (acc, str)) fmt | Lit_padding (padty, w), No_precision -> fun x -> let str = convert_float fconv default_float_precision x in let str' = fix_padding padty w str in - make_printf k o (Acc_string (acc, str')) fmt + make_printf k o (Acc_data_string (acc, str')) fmt | Lit_padding (padty, w), Lit_precision p -> fun x -> let str = fix_padding padty w (convert_float fconv p x) in - make_printf k o (Acc_string (acc, str)) fmt + make_printf k o (Acc_data_string (acc, str)) fmt | Lit_padding (padty, w), Arg_precision -> fun p x -> let str = fix_padding padty w (convert_float fconv p x) in - make_printf k o (Acc_string (acc, str)) fmt + make_printf k o (Acc_data_string (acc, str)) fmt | Arg_padding padty, No_precision -> fun w x -> let str = convert_float fconv default_float_precision x in let str' = fix_padding padty w str in - make_printf k o (Acc_string (acc, str')) fmt + make_printf k o (Acc_data_string (acc, str')) fmt | Arg_padding padty, Lit_precision p -> fun w x -> let str = fix_padding padty w (convert_float fconv p x) in - make_printf k o (Acc_string (acc, str)) fmt + make_printf k o (Acc_data_string (acc, str)) fmt | Arg_padding padty, Arg_precision -> fun w p x -> let str = fix_padding padty w (convert_float fconv p x) in - make_printf k o (Acc_string (acc, str)) fmt + make_printf k o (Acc_data_string (acc, str)) fmt (******************************************************************************) (* Continuations for make_printf *) @@ -1623,8 +1625,10 @@ let rec output_acc o acc = match acc with output_acc o p; output_string o "@{"; output_acc o acc'; | Acc_formatting_gen (p, Acc_open_box acc') -> output_acc o p; output_string o "@["; output_acc o acc'; - | Acc_string (p, s) -> output_acc o p; output_string o s - | Acc_char (p, c) -> output_acc o p; output_char o c + | Acc_string_literal (p, s) + | Acc_data_string (p, s) -> output_acc o p; output_string o s + | Acc_char_literal (p, c) + | Acc_data_char (p, c) -> output_acc o p; output_char o c | Acc_delay (p, f) -> output_acc o p; f o | Acc_flush p -> output_acc o p; flush o | Acc_invalid_arg (p, msg) -> output_acc o p; invalid_arg msg; @@ -1641,8 +1645,10 @@ let rec bufput_acc b acc = match acc with bufput_acc b p; Buffer.add_string b "@{"; bufput_acc b acc'; | Acc_formatting_gen (p, Acc_open_box acc') -> bufput_acc b p; Buffer.add_string b "@["; bufput_acc b acc'; - | Acc_string (p, s) -> bufput_acc b p; Buffer.add_string b s - | Acc_char (p, c) -> bufput_acc b p; Buffer.add_char b c + | Acc_string_literal (p, s) + | Acc_data_string (p, s) -> bufput_acc b p; Buffer.add_string b s + | Acc_char_literal (p, c) + | Acc_data_char (p, c) -> bufput_acc b p; Buffer.add_char b c | Acc_delay (p, f) -> bufput_acc b p; f b | Acc_flush p -> bufput_acc b p; | Acc_invalid_arg (p, msg) -> bufput_acc b p; invalid_arg msg; @@ -1660,8 +1666,10 @@ let rec strput_acc b acc = match acc with strput_acc b p; Buffer.add_string b "@{"; strput_acc b acc'; | Acc_formatting_gen (p, Acc_open_box acc') -> strput_acc b p; Buffer.add_string b "@["; strput_acc b acc'; - | Acc_string (p, s) -> strput_acc b p; Buffer.add_string b s - | Acc_char (p, c) -> strput_acc b p; Buffer.add_char b c + | Acc_string_literal (p, s) + | Acc_data_string (p, s) -> strput_acc b p; Buffer.add_string b s + | Acc_char_literal (p, c) + | Acc_data_char (p, c) -> strput_acc b p; Buffer.add_char b c | Acc_delay (p, f) -> strput_acc b p; Buffer.add_string b (f ()) | Acc_flush p -> strput_acc b p; | Acc_invalid_arg (p, msg) -> strput_acc b p; invalid_arg msg; @@ -1824,6 +1832,7 @@ let fmt_ebb_of_string str = and parse_ign : type e f . int -> int -> int -> (_, _, e, f) fmt_ebb = fun pct_ind str_ind end_ind -> + if str_ind = end_ind then unexpected_end_of_format end_ind; match str.[str_ind] with | '_' -> parse_flags pct_ind (str_ind+1) end_ind true | _ -> parse_flags pct_ind str_ind end_ind false @@ -1912,6 +1921,7 @@ let fmt_ebb_of_string str = if str_ind = end_ind then unexpected_end_of_format end_ind; let parse_literal str_ind = let new_ind, prec = parse_positive str_ind end_ind 0 in + if new_ind = end_ind then unexpected_end_of_format end_ind; parse_conversion pct_ind (new_ind + 1) end_ind plus sharp space ign pad (Lit_precision prec) str.[new_ind] in match str.[str_ind] with @@ -2409,6 +2419,7 @@ let fmt_ebb_of_string str = parse_char_set_content (str_ind + 1) end_ind in let str_ind, reverse = + if str_ind = end_ind then unexpected_end_of_format end_ind; match str.[str_ind] with | '^' -> str_ind + 1, true | _ -> str_ind, false in diff --git a/stdlib/camlinternalFormat.mli b/stdlib/camlinternalFormat.mli index 728dc865a..5c5b3e32a 100644 --- a/stdlib/camlinternalFormat.mli +++ b/stdlib/camlinternalFormat.mli @@ -25,8 +25,10 @@ type ('b, 'c) acc_formatting_gen = and ('b, 'c) acc = | Acc_formatting_lit of ('b, 'c) acc * formatting_lit | Acc_formatting_gen of ('b, 'c) acc * ('b, 'c) acc_formatting_gen - | Acc_string of ('b, 'c) acc * string - | Acc_char of ('b, 'c) acc * char + | Acc_string_literal of ('b, 'c) acc * string + | Acc_char_literal of ('b, 'c) acc * char + | Acc_data_string of ('b, 'c) acc * string + | Acc_data_char of ('b, 'c) acc * char | Acc_delay of ('b, 'c) acc * ('b -> 'c) | Acc_flush of ('b, 'c) acc | Acc_invalid_arg of ('b, 'c) acc * string diff --git a/stdlib/camlinternalOO.ml b/stdlib/camlinternalOO.ml index 872a56065..3c39c0b67 100644 --- a/stdlib/camlinternalOO.ml +++ b/stdlib/camlinternalOO.ml @@ -128,7 +128,7 @@ let rec fit_size n = let new_table pub_labels = incr table_count; let len = Array.length pub_labels in - let methods = Array.create (len*2+2) dummy_met in + let methods = Array.make (len*2+2) dummy_met in methods.(0) <- magic len; methods.(1) <- magic (fit_size len * Sys.word_size / 8 - 1); for i = 0 to len - 1 do methods.(i*2+3) <- magic pub_labels.(i) done; @@ -144,7 +144,7 @@ let new_table pub_labels = let resize array new_size = let old_size = Array.length array.methods in if new_size > old_size then begin - let new_buck = Array.create new_size dummy_met in + let new_buck = Array.make new_size dummy_met in Array.blit array.methods 0 new_buck 0 old_size; array.methods <- new_buck end @@ -267,7 +267,7 @@ let to_array arr = let new_methods_variables table meths vals = let meths = to_array meths in let nmeths = Array.length meths and nvals = Array.length vals in - let res = Array.create (nmeths + nvals) 0 in + let res = Array.make (nmeths + nvals) 0 in for i = 0 to nmeths - 1 do res.(i) <- get_method_label table meths.(i) done; diff --git a/stdlib/filename.mli b/stdlib/filename.mli index c44c6d954..a4ea3aaab 100644 --- a/stdlib/filename.mli +++ b/stdlib/filename.mli @@ -117,14 +117,13 @@ val set_temp_dir_name : string -> unit @since 4.00.0 *) -val temp_dir_name : string -(** @deprecated The name of the initial temporary directory: +val temp_dir_name : string [@@ocaml.deprecated] +(** The name of the initial temporary directory: Under Unix, the value of the [TMPDIR] environment variable, or "/tmp" if the variable is not set. Under Windows, the value of the [TEMP] environment variable, or "." if the variable is not set. - This function is deprecated; {!Filename.get_temp_dir_name} should be - used instead. + @deprecated You should use {!Filename.get_temp_dir_name} instead. @since 3.09.1 *) diff --git a/stdlib/format.ml b/stdlib/format.ml index 55674d179..5e206e11f 100644 --- a/stdlib/format.ml +++ b/stdlib/format.ml @@ -1070,10 +1070,10 @@ let compute_tag output tag_acc = else Buffer.sub buf 1 (len - 2) (************************************************************** - + Defining continuations to be passed as arguments of CamlinternalFormat.make_printf. - + **************************************************************) open CamlinternalFormatBasics @@ -1097,10 +1097,12 @@ let output_formatting_lit ppf fmting_lit = match fmting_lit with (* Differ from Printf.output_acc by the interpretation of formatting. *) (* Used as a continuation of CamlinternalFormat.make_printf. *) let rec output_acc ppf acc = match acc with - | Acc_string (Acc_formatting_lit (p, Magic_size (_, size)), s) -> + | Acc_string_literal (Acc_formatting_lit (p, Magic_size (_, size)), s) + | Acc_data_string (Acc_formatting_lit (p, Magic_size (_, size)), s) -> output_acc ppf p; pp_print_as_size ppf (size_of_int size) s; - | Acc_char (Acc_formatting_lit (p, Magic_size (_, size)), c) -> + | Acc_char_literal (Acc_formatting_lit (p, Magic_size (_, size)), c) + | Acc_data_char (Acc_formatting_lit (p, Magic_size (_, size)), c) -> output_acc ppf p; pp_print_as_size ppf (size_of_int size) (String.make 1 c); | Acc_formatting_lit (p, f) -> @@ -1113,8 +1115,10 @@ let rec output_acc ppf acc = match acc with let () = output_acc ppf p in let (indent, bty) = open_box_of_string (compute_tag output_acc acc') in pp_open_box_gen ppf indent bty - | Acc_string (p, s) -> output_acc ppf p; pp_print_string ppf s; - | Acc_char (p, c) -> output_acc ppf p; pp_print_char ppf c; + | Acc_string_literal (p, s) + | Acc_data_string (p, s) -> output_acc ppf p; pp_print_string ppf s; + | Acc_char_literal (p, c) + | Acc_data_char (p, c) -> output_acc ppf p; pp_print_char ppf c; | Acc_delay (p, f) -> output_acc ppf p; f ppf; | Acc_flush p -> output_acc ppf p; pp_print_flush ppf (); | Acc_invalid_arg (p, msg) -> output_acc ppf p; invalid_arg msg; @@ -1125,10 +1129,12 @@ let rec output_acc ppf acc = match acc with (* Differ from Printf.bufput_acc by the interpretation of formatting. *) (* Used as a continuation of CamlinternalFormat.make_printf. *) let rec strput_acc ppf acc = match acc with - | Acc_string (Acc_formatting_lit (p, Magic_size (_, size)), s) -> + | Acc_string_literal (Acc_formatting_lit (p, Magic_size (_, size)), s) + | Acc_data_string (Acc_formatting_lit (p, Magic_size (_, size)), s) -> strput_acc ppf p; pp_print_as_size ppf (size_of_int size) s; - | Acc_char (Acc_formatting_lit (p, Magic_size (_, size)), c) -> + | Acc_char_literal (Acc_formatting_lit (p, Magic_size (_, size)), c) + | Acc_data_char (Acc_formatting_lit (p, Magic_size (_, size)), c) -> strput_acc ppf p; pp_print_as_size ppf (size_of_int size) (String.make 1 c); | Acc_delay (Acc_formatting_lit (p, Magic_size (_, size)), f) -> @@ -1144,8 +1150,10 @@ let rec strput_acc ppf acc = match acc with let () = strput_acc ppf p in let (indent, bty) = open_box_of_string (compute_tag strput_acc acc') in pp_open_box_gen ppf indent bty - | Acc_string (p, s) -> strput_acc ppf p; pp_print_string ppf s; - | Acc_char (p, c) -> strput_acc ppf p; pp_print_char ppf c; + | Acc_string_literal (p, s) + | Acc_data_string (p, s) -> strput_acc ppf p; pp_print_string ppf s; + | Acc_char_literal (p, c) + | Acc_data_char (p, c) -> strput_acc ppf p; pp_print_char ppf c; | Acc_delay (p, f) -> strput_acc ppf p; pp_print_string ppf (f ()); | Acc_flush p -> strput_acc ppf p; pp_print_flush ppf (); | Acc_invalid_arg (p, msg) -> strput_acc ppf p; invalid_arg msg; @@ -1181,7 +1189,7 @@ let sprintf fmt = let asprintf (Format (fmt, _)) = let b = Buffer.create 512 in - let ppf = formatter_of_buffer b in + let ppf = formatter_of_buffer b in let k' : (formatter -> (formatter, unit) acc -> string) = fun ppf acc -> output_acc ppf acc; diff --git a/stdlib/format.mli b/stdlib/format.mli index e7cbe506e..b44fc0a94 100644 --- a/stdlib/format.mli +++ b/stdlib/format.mli @@ -714,14 +714,18 @@ val ksprintf : (string -> 'a) -> ('b, unit, string, 'a) format4 -> 'b;; (** {6 Deprecated} *) -val bprintf : Buffer.t -> ('a, formatter, unit) format -> 'a;; +val bprintf : Buffer.t -> ('a, formatter, unit) format -> 'a + [@@ocaml.deprecated] +;; (** @deprecated This function is error prone. Do not use it. If you need to print to some buffer [b], you must first define a formatter writing to [b], using [let to_b = formatter_of_buffer b]; then use regular calls to [Format.fprintf] on formatter [to_b]. *) -val kprintf : (string -> 'a) -> ('b, unit, string, 'a) format4 -> 'b;; +val kprintf : (string -> 'a) -> ('b, unit, string, 'a) format4 -> 'b + [@@ocaml.deprecated] +;; (** @deprecated An alias for [ksprintf]. *) val set_all_formatter_output_functions : @@ -730,6 +734,7 @@ val set_all_formatter_output_functions : newline:(unit -> unit) -> spaces:(int -> unit) -> unit +[@@ocaml.deprecated] ;; (** @deprecated Subsumed by [set_formatter_out_functions]. *) @@ -740,12 +745,14 @@ val get_all_formatter_output_functions : (unit -> unit) * (unit -> unit) * (int -> unit) +[@@ocaml.deprecated] ;; (** @deprecated Subsumed by [get_formatter_out_functions]. *) val pp_set_all_formatter_output_functions : formatter -> out:(string -> int -> int -> unit) -> flush:(unit -> unit) -> newline:(unit -> unit) -> spaces:(int -> unit) -> unit +[@@ocaml.deprecated] ;; (** @deprecated Subsumed by [pp_set_formatter_out_functions]. *) @@ -754,6 +761,7 @@ val pp_get_all_formatter_output_functions : formatter -> unit -> (string -> int -> int -> unit) * (unit -> unit) * (unit -> unit) * (int -> unit) +[@@ocaml.deprecated] ;; (** @deprecated Subsumed by [pp_get_formatter_out_functions]. *) diff --git a/stdlib/gc.mli b/stdlib/gc.mli index c4ed39930..8cd2a719a 100644 --- a/stdlib/gc.mli +++ b/stdlib/gc.mli @@ -215,6 +215,9 @@ val finalise : ('a -> unit) -> 'a -> unit before the values it depends upon. Of course, this becomes false if additional dependencies are introduced by assignments. + In the presence of multiple OCaml threads it should be assumed that + any particular finaliser may be executed in any of the threads. + Anything reachable from the closure of finalisation functions is considered reachable, so the following code will not work as expected: diff --git a/stdlib/lazy.mli b/stdlib/lazy.mli index 6108a715c..6ade2e3d4 100644 --- a/stdlib/lazy.mli +++ b/stdlib/lazy.mli @@ -75,11 +75,11 @@ val is_val : 'a t -> bool;; did not raise an exception. @since 4.00.0 *) -val lazy_from_fun : (unit -> 'a) -> 'a t;; +val lazy_from_fun : (unit -> 'a) -> 'a t [@@ocaml.deprecated];; (** @deprecated synonym for [from_fun]. *) -val lazy_from_val : 'a -> 'a t;; +val lazy_from_val : 'a -> 'a t [@@ocaml.deprecated];; (** @deprecated synonym for [from_val]. *) -val lazy_is_val : 'a t -> bool;; +val lazy_is_val : 'a t -> bool [@@ocaml.deprecated];; (** @deprecated synonym for [is_val]. *) diff --git a/stdlib/marshal.ml b/stdlib/marshal.ml index 4f59a3ef2..415559571 100644 --- a/stdlib/marshal.ml +++ b/stdlib/marshal.ml @@ -32,6 +32,12 @@ let to_buffer buff ofs len v flags = then invalid_arg "Marshal.to_buffer: substring out of bounds" else to_buffer_unsafe buff ofs len v flags +(* The functions below use byte sequences as input, never using any + mutation. It makes sense to use non-mutated [bytes] rather than + [string], because we really work with sequences of bytes, not + a text representation. +*) + external from_channel: in_channel -> 'a = "caml_input_value" external from_bytes_unsafe: bytes -> int -> 'a = "caml_input_value_from_string" @@ -54,4 +60,7 @@ let from_bytes buff ofs = else from_bytes_unsafe buff ofs end -let from_string buff ofs = from_bytes (Bytes.unsafe_of_string buff) ofs +let from_string buff ofs = + (* Bytes.unsafe_of_string is safe here, as the produced byte + sequence is never mutated *) + from_bytes (Bytes.unsafe_of_string buff) ofs diff --git a/stdlib/marshal.mli b/stdlib/marshal.mli index 37f0345b3..9dfdd1624 100644 --- a/stdlib/marshal.mli +++ b/stdlib/marshal.mli @@ -140,7 +140,8 @@ val from_bytes : bytes -> int -> 'a (** [Marshal.from_bytes buff ofs] unmarshals a structured value like {!Marshal.from_channel} does, except that the byte representation is not read from a channel, but taken from - the byte sequence [buff], starting at position [ofs]. *) + the byte sequence [buff], starting at position [ofs]. + The byte sequence is not mutated. *) val from_string : string -> int -> 'a (** Same as [from_bytes] but take a string as argument instead of a diff --git a/stdlib/nativeint.mli b/stdlib/nativeint.mli index eb2dde2cf..3dce1b6c4 100644 --- a/stdlib/nativeint.mli +++ b/stdlib/nativeint.mli @@ -16,8 +16,8 @@ This module provides operations on the type [nativeint] of signed 32-bit integers (on 32-bit platforms) or signed 64-bit integers (on 64-bit platforms). - This integer type has exactly the same width as that of a [long] - integer type in the C compiler. All arithmetic operations over + This integer type has exactly the same width as that of a + pointer type in the C compiler. All arithmetic operations over [nativeint] are taken modulo 2{^32} or 2{^64} depending on the word size of the architecture. diff --git a/stdlib/parsing.ml b/stdlib/parsing.ml index 762128244..47e151e1b 100644 --- a/stdlib/parsing.ml +++ b/stdlib/parsing.ml @@ -84,10 +84,10 @@ external set_trace: bool -> bool = "caml_set_parser_trace" let env = - { s_stack = Array.create 100 0; - v_stack = Array.create 100 (Obj.repr ()); - symb_start_stack = Array.create 100 dummy_pos; - symb_end_stack = Array.create 100 dummy_pos; + { s_stack = Array.make 100 0; + v_stack = Array.make 100 (Obj.repr ()); + symb_start_stack = Array.make 100 dummy_pos; + symb_end_stack = Array.make 100 dummy_pos; stacksize = 100; stackbase = 0; curr_char = 0; @@ -104,10 +104,10 @@ let env = let grow_stacks() = let oldsize = env.stacksize in let newsize = oldsize * 2 in - let new_s = Array.create newsize 0 - and new_v = Array.create newsize (Obj.repr ()) - and new_start = Array.create newsize dummy_pos - and new_end = Array.create newsize dummy_pos in + let new_s = Array.make newsize 0 + and new_v = Array.make newsize (Obj.repr ()) + and new_start = Array.make newsize dummy_pos + and new_end = Array.make newsize dummy_pos in Array.blit env.s_stack 0 new_s 0 oldsize; env.s_stack <- new_s; Array.blit env.v_stack 0 new_v 0 oldsize; diff --git a/stdlib/pervasives.ml b/stdlib/pervasives.ml index 8f9e423f9..6b7165206 100644 --- a/stdlib/pervasives.ml +++ b/stdlib/pervasives.ml @@ -290,6 +290,8 @@ let flush_all () = external unsafe_output : out_channel -> bytes -> int -> int -> unit = "caml_ml_output" +external unsafe_output_string : out_channel -> string -> int -> int -> unit + = "caml_ml_output" external output_char : out_channel -> char -> unit = "caml_ml_output_char" @@ -297,7 +299,7 @@ let output_bytes oc s = unsafe_output oc s 0 (bytes_length s) let output_string oc s = - unsafe_output oc (bytes_unsafe_of_string s) 0 (string_length s) + unsafe_output_string oc s 0 (string_length s) let output oc s ofs len = if ofs < 0 || len < 0 || ofs > bytes_length s - len @@ -305,7 +307,9 @@ let output oc s ofs len = else unsafe_output oc s ofs len let output_substring oc s ofs len = - output oc (bytes_unsafe_of_string s) ofs len + if ofs < 0 || len < 0 || ofs > string_length s - len + then invalid_arg "output_substring" + else unsafe_output_string oc s ofs len external output_byte : out_channel -> int -> unit = "caml_ml_output_char" external output_binary_int : out_channel -> int -> unit = "caml_ml_output_int" diff --git a/stdlib/pervasives.mli b/stdlib/pervasives.mli index 77cb1e92c..d471a4ebb 100644 --- a/stdlib/pervasives.mli +++ b/stdlib/pervasives.mli @@ -130,6 +130,7 @@ external ( && ) : bool -> bool -> bool = "%sequand" [e2] is not evaluated at all. *) external ( & ) : bool -> bool -> bool = "%sequand" + [@@ocaml.deprecated] (** @deprecated {!Pervasives.( && )} should be used instead. *) external ( || ) : bool -> bool -> bool = "%sequor" @@ -138,6 +139,7 @@ external ( || ) : bool -> bool -> bool = "%sequor" [e2] is not evaluated at all. *) external ( or ) : bool -> bool -> bool = "%sequor" + [@@ocaml.deprecated] (** @deprecated {!Pervasives.( || )} should be used instead.*) (** {6 Debugging} *) diff --git a/stdlib/scanf.ml b/stdlib/scanf.ml index c21de7248..2a63ced9a 100644 --- a/stdlib/scanf.ml +++ b/stdlib/scanf.ml @@ -1038,7 +1038,8 @@ fun k fmt -> match fmt with | Formatting_gen (Open_box (Format (fmt, _)), rest) -> take_format_readers k (concat_fmt fmt rest) | Format_arg (_, _, rest) -> take_format_readers k rest - | Format_subst (_, fmtty, rest) -> take_fmtty_format_readers k (erase_rel (symm fmtty)) rest + | Format_subst (_, fmtty, rest) -> + take_fmtty_format_readers k (erase_rel (symm fmtty)) rest | Ignored_param (ign, rest) -> take_ignored_format_readers k ign rest | End_of_format -> k Nil diff --git a/stdlib/sort.mli b/stdlib/sort.mli index d5abb79fa..a9be27e13 100644 --- a/stdlib/sort.mli +++ b/stdlib/sort.mli @@ -20,11 +20,13 @@ *) val list : ('a -> 'a -> bool) -> 'a list -> 'a list + [@@ocaml.deprecated] (** Sort a list in increasing order according to an ordering predicate. The predicate should return [true] if its first argument is less than or equal to its second argument. *) val array : ('a -> 'a -> bool) -> 'a array -> unit + [@@ocaml.deprecated] (** Sort an array in increasing order according to an ordering predicate. The predicate should return [true] if its first argument is @@ -32,6 +34,7 @@ val array : ('a -> 'a -> bool) -> 'a array -> unit The array is sorted in place. *) val merge : ('a -> 'a -> bool) -> 'a list -> 'a list -> 'a list + [@@ocaml.deprecated] (** Merge two lists according to the given predicate. Assuming the two argument lists are sorted according to the predicate, [merge] returns a sorted list containing the elements diff --git a/stdlib/string.ml b/stdlib/string.ml index 00ff8be9e..93880af26 100644 --- a/stdlib/string.ml +++ b/stdlib/string.ml @@ -39,8 +39,8 @@ let sub s ofs len = B.sub (bos s) ofs len |> bts let fill = B.fill -let blit s1 ofs1 s2 ofs2 len = - B.blit (bos s1) ofs1 s2 ofs2 len +let blit = + B.blit_string let concat sep l = match l with diff --git a/stdlib/string.mli b/stdlib/string.mli index da6d8351a..8f1e178b5 100644 --- a/stdlib/string.mli +++ b/stdlib/string.mli @@ -90,8 +90,11 @@ val init : int -> (int -> char) -> string @since 4.02.0 *) -val copy : string -> string -(** Return a copy of the given string. *) +val copy : string -> string [@@ocaml.deprecated] +(** Return a copy of the given string. + + @deprecated Because strings are immutable, it doesn't make much + sense to make identical copies of them. *) val sub : string -> int -> int -> string (** [String.sub s start len] returns a fresh string of length [len], @@ -111,17 +114,14 @@ val fill : bytes -> int -> int -> char -> unit [@@ocaml.deprecated] @deprecated This is a deprecated alias of {!Bytes.fill}.[ ] *) val blit : string -> int -> bytes -> int -> int -> unit -(** [String.blit src srcoff dst dstoff len] copies [len] characters - (bytes) from the string [src], starting at index [srcoff], to byte - sequence [dst], starting at index [dstoff]. - - Raise [Invalid_argument] if [srcoff] and [len] do not - designate a valid substring of [src], or if [dstoff] and [len] - do not designate a valid range of [dst]. *) +(** Same as {!Bytes.blit_string}. *) val concat : string -> string list -> string (** [String.concat sep sl] concatenates the list of strings [sl], - inserting the separator string [sep] between each. *) + inserting the separator string [sep] between each. + + Raise [Invalid_argument] if the result is longer than + {!Sys.max_string_length} bytes. *) val iter : (char -> unit) -> string -> unit (** [String.iter f s] applies function [f] in turn to all @@ -159,7 +159,10 @@ val escaped : string -> string represented by escape sequences, following the lexical conventions of OCaml. If there is no special character in the argument, return the original string itself, - not a copy. Its inverse function is Scanf.unescaped. *) + not a copy. Its inverse function is Scanf.unescaped. + + Raise [Invalid_argument] if the result is longer than + {!Sys.max_string_length} bytes. *) val index : string -> char -> int (** [String.index s c] returns the index of the first diff --git a/stdlib/sys.mli b/stdlib/sys.mli index 0f3b131ad..ae175c2e8 100644 --- a/stdlib/sys.mli +++ b/stdlib/sys.mli @@ -11,7 +11,12 @@ (* *) (***********************************************************************) -(** System interface. *) +(** System interface. + + Every function in this module raises [Sys_error] with an + informative message when the underlying system call signal + an error. +*) val argv : string array (** The command line arguments given to the process. diff --git a/stdlib/weak.ml b/stdlib/weak.ml index 536a42e04..8166142b6 100644 --- a/stdlib/weak.ml +++ b/stdlib/weak.ml @@ -80,8 +80,8 @@ module Make (H : Hashtbl.HashedType) : (S with type data = H.t) = struct let sz = if sz < 7 then 7 else sz in let sz = if sz > Sys.max_array_length then Sys.max_array_length else sz in { - table = Array.create sz emptybucket; - hashes = Array.create sz [| |]; + table = Array.make sz emptybucket; + hashes = Array.make sz [| |]; limit = limit; oversize = 0; rover = 0; |