#load "unix.cma";; module Conf = struct open Format let o_fmt = ref std_formatter let o_chan = ref stdout let start () = ignore (Sys.command "cp myocamlbuild_config.ml.in myocamlbuild_config.ml"); o_chan := open_out_gen [ Open_append ] 0 "myocamlbuild_config.ml"; o_fmt := formatter_of_out_channel !o_chan ;; let finish () = pp_print_flush !o_fmt (); close_out !o_chan ;; let getc b c = try Buffer.add_channel b c 1; true with End_of_file -> false ;; let contents b = let last = Buffer.length b - 1 in if last < 0 || Buffer.nth b last <> '\n' then Buffer.contents b else Buffer.sub b 0 last ;; let explode ?(sep=[ ' '; '\t'; '\n']) s = let b = Buffer.create 512 in let seq = ref [] in for i = 0 to String.length s - 1 do let c = s.[i] in if List.mem c sep then let e = Buffer.contents b in Buffer.clear b; if String.length e > 0 then seq := e :: ! seq; else Buffer.add_char b c done; List.rev !seq ;; let version s = match explode ~sep:[ '.' ; '+' ] s with | [major; minor] -> int_of_string major, int_of_string minor, 0 | [major; minor; patch] | [major; minor; patch; _ ] -> int_of_string major, int_of_string minor, int_of_string patch | _ -> eprintf "Invalid version string \"%s\"\n%!" Sys.ocaml_version; exit 1 ;; let pr_str fmt s = fprintf fmt "%S" s ;; let pr_list fmt l = fprintf fmt "[ "; begin match l with [] -> () | [s] -> fprintf fmt "%S" s | s :: ll -> fprintf fmt "%S" s; List.iter (fun s -> fprintf fmt "; %S" s) ll end; fprintf fmt " ]" let exec cmd = let (sout, _, serr) as chans = Unix.open_process_full cmd (Unix.environment ()) in let bout = Buffer.create 512 and berr = Buffer.create 512 in while (getc bout sout) || (getc berr serr) do () done; match Unix.close_process_full chans with | Unix.WEXITED c -> (c, contents bout, contents berr) | _ -> eprintf "Interrupted\n%!"; exit 1 ;; let check_cond ?(required=true) ~display ~fmt_msg ~ok ~fail run cmd cond = printf fmt_msg display; let res = run cmd in if cond res then printf " %s\n%!" ok else begin printf " %s\n%!" fail; if required then (printf "%s is required to buid the project\n%!" display; exit 1); end; res ;; let run_prog ?(required=true) ~display ~fmt_msg ~ok ~fail cmd = check_cond ~required:required ~display:display ~fmt_msg:fmt_msg ~ok:ok ~fail:fail exec cmd (fun (c, _, _) -> c == 0) ;; let cfmt = format_of_string ("Checking for %- 25s ");; let cok = "ok";; let cfail = "failed" ;; let prog ?(required=true) display cmd = run_prog ~required:required ~display:display ~fmt_msg:cfmt ~ok:cok ~fail:cfail cmd ;; let check_prog ?(required=true) display cmd = ignore (prog ~required:required display cmd) ;; let check ?(required=true) display run cmd cond = check_cond ~required:required ~display:display ~fmt_msg:cfmt ~ok:cok ~fail:cfail run cmd cond ;; let def v p d = fprintf !o_fmt "let %s = %a;;\n%!" v p d ;; let def_str v d = def v pr_str d;; let def_list v l = def v pr_list l;; let exec_def v cmd = let c,o, _ = exec cmd in if c = 0 then def v pr_str o ;; let exec_def_list v cmd = let c,o, _ = exec cmd in if c = 0 then def v pr_list (explode o) ;; let absolute fmt = Printf.sprintf fmt (Sys.getcwd()) end ;;