1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
open StdLabels
module Ocaml_version : sig
type t
val v407 : t
val v408 : t
val current : t
val compare : t -> t -> int
end = struct
type t = int * int
let parse s =
try
let d1 = String.index_from s 0 '.' in
let d2 =
try String.index_from s (d1 + 1) '.' with
| Not_found -> String.length s
in
let p1 = int_of_string (String.sub s ~pos:0 ~len:d1) in
let p2 = int_of_string (String.sub s ~pos:(d1 + 1) ~len:(d2 - d1 - 1)) in
p1, p2
with
| _ -> failwith (Printf.sprintf "Invalid ocaml version %S" s)
;;
let v407 = parse "4.07"
let v408 = parse "4.08"
let current = parse Sys.ocaml_version
let compare ((a1, b1) : t) ((a2, b2) : t) =
match compare a1 a2 with
| 0 -> compare b1 b2
| c -> c
;;
end
let () =
let ocaml_where, oc =
match Sys.argv with
| [| _; "-ocaml-where"; ocaml_where; "-o"; fn |] -> ocaml_where, open_out fn
| _ -> failwith "bad command line arguments"
in
let pr fmt = Printf.fprintf oc (fmt ^^ "\n") in
pr "(* This file is automatically generated *)";
pr "";
if Ocaml_version.(compare current v407) >= 0
then pr "include Stdlib"
else (
(* The cma format is documented in typing/cmo_format.mli in the compiler sources *)
let ic =
let ( ^/ ) = Filename.concat in
try open_in_bin (ocaml_where ^/ "stdlib" ^/ "stdlib.cma") with
| Sys_error _ -> open_in_bin (ocaml_where ^/ "stdlib.cma")
in
let len_magic_number = String.length Config.cma_magic_number in
let magic_number = really_input_string ic len_magic_number in
assert (magic_number = Config.cma_magic_number);
let toc_pos = input_binary_int ic in
seek_in ic toc_pos;
let toc : Cmo_format.library = input_value ic in
close_in ic;
let units =
List.map toc.lib_units ~f:(fun cu -> cu.Cmo_format.cu_name)
|> List.sort ~cmp:String.compare
in
let max_len =
List.fold_left units ~init:0 ~f:(fun acc unit -> max acc (String.length unit))
in
List.iter units ~f:(fun u -> pr "module %-*s = %s" max_len u u);
pr "";
pr "include Pervasives");
pr "";
if Ocaml_version.(compare current v407) < 0 then pr "module Float = struct end";
if Ocaml_version.(compare current v408) < 0
then (
pr "module Bool = struct end";
pr "module Int = struct end";
pr "module Option = struct end";
pr "module Result = struct end";
pr "module Unit = struct end";
pr "module Fun = struct end");
pr "";
pr "exception Not_found = Not_found"
;;
|