diff --git a/src/core_sys.ml b/src/core_sys.ml index 402af6d8..41b4eb8f 100644 --- a/src/core_sys.ml +++ b/src/core_sys.ml @@ -153,3 +153,18 @@ external opaque_identity : 'a -> 'a = "%opaque" module Private = struct let unix_quote = unix_quote end + +[%%if ocaml_version < (4, 09, 0)] +let override_argv args = + let len = Array.length args in + assert (len <= Array.length Sys.argv); + Array.blit ~src:args ~src_pos:0 ~dst:Sys.argv ~dst_pos:0 ~len; + (Caml.Obj.truncate [@ocaml.alert "-deprecated"]) (Obj.repr Sys.argv) len; + Arg.current := 0; +;; +[%%else] +external caml_sys_modify_argv : string array -> unit = "caml_sys_modify_argv";; +let override_argv new_argv = + caml_sys_modify_argv new_argv; + Arg.current := 0 +[%%endif] diff --git a/src/core_sys.mli b/src/core_sys.mli index 5c7fd792..35dea29f 100644 --- a/src/core_sys.mli +++ b/src/core_sys.mli @@ -182,6 +182,18 @@ val home_directory : unit -> string *) external opaque_identity : 'a -> 'a = "%opaque" +(** [override_argv new_argv] makes subsequent calls to {!get_argv} return [new_argv]. + + Prior to OCaml version 4.09, this function has two noteworthy behaviors: + + - it may raise if the length of [new_argv] is greater than the length of [argv] before + the call; + - it re-uses and mutates the previous [argv] value instead of using the new one; and + - it even mutates its length, which can be observed by inspecting the array returned + by an earlier call to {!get_argv}. +*) +val override_argv : string array -> unit + (**/**)