open StdLabels

module Ocaml_version : sig
  type t

  val v412 : t
  val v414 : 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 v412 = parse "4.12"
  let v414 = parse "4.14"
  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 oc =
    match Sys.argv with
    | [| _; "-o"; fn |] -> 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 "";
  pr "include Stdlib";
  pr "";
  if Ocaml_version.(compare current v412) < 0
  then (
    pr "module Atomic = struct end";
    pr "module Either = struct end");
  if Ocaml_version.(compare current v414) < 0
  then (
    pr "module In_channel = struct end";
    pr "module Out_channel = struct end")
;;
