123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121(* This file is part of Bisect_ppx, released under the MIT license. See
LICENSE.md for details, or visit
https://github.com/aantron/bisect_ppx/blob/master/LICENSE.md. *)moduleCommon=Bisect_commonletdefault_bisect_file=ref"bisect"letdefault_bisect_silent=ref"bisect.log"typemessage=|Unable_to_create_file|Unable_to_write_file|Stringofstringletstring_of_message=function|Unable_to_create_file->" *** Bisect runtime was unable to create file."|Unable_to_write_file->" *** Bisect runtime was unable to write file."|Strings->" *** "^sletfull_pathfname=ifFilename.is_implicitfnamethenFilename.concatFilename.current_dir_namefnameelsefnameletenv_to_fnameenvdefault=trySys.getenvenvwithNot_found->!defaultletverbose=lazybeginletfname=env_to_fname"BISECT_SILENT"default_bisect_silentinmatch(String.uppercase[@ocaml.warning"-3"])fnamewith|"YES"|"ON"->fun_->()|"ERR"->funmsg->prerr_endline(string_of_messagemsg)|_uc_fname->letoc_l=lazy((* A weird race condition is caused if we use this invocation instead
let oc = open_out_gen [Open_append] 0o244 (full_path fname) in
Note that verbose is called only during [at_exit]. *)letoc=open_out_bin(full_pathfname)inat_exit(fun()->close_out_noerroc);oc)infunmsg->Printf.fprintf(Lazy.forceoc_l)"%s\n"(string_of_messagemsg)endletverbosemessage=(Lazy.forceverbose)messageletget_coverage_data=Common.runtime_data_to_stringletwrite_coverage_data()=matchget_coverage_data()with|None->()|Somedata->letreccreate_fileattempts=letfilename=Common.random_filename"bisect"inletflags=[Open_wronly;Open_creat;Open_excl;Open_binary]inmatchopen_out_genflags0o644filenamewith|exceptionexn->ifattempts=0thenraiseexnelsecreate_file(attempts-1)|channel->output_stringchanneldata;close_out_noerrchannelincreate_file100letfile_channel()=letbase_name=full_path(env_to_fname"BISECT_FILE"default_bisect_file)inletreccreate_file()=letfilename=Common.random_filenamebase_nameintryletfd=Unix.(openfilefilename[O_WRONLY;O_CREAT;O_EXCL]0o644)inletchannel=Unix.out_channel_of_descrfdinSomechannelwith|Unix.Unix_error(Unix.EEXIST,_,_)->create_file()|Unix.Unix_error(code,_,_)->letdetail=Printf.sprintf"%s: %s"(Unix.error_messagecode)filenameinverboseUnable_to_create_file;verbose(Stringdetail);Noneincreate_file()letreset_counters=Common.reset_countersletdump_counters_exn=Common.write_runtime_dataletdump()=matchfile_channel()with|None->()|Somechannel->(trydump_counters_exnchannelwith_->verboseUnable_to_write_file);close_out_noerrchannelletregister_dump:unitLazy.t=lazy(at_exitdump)letregister_file~bisect_file~bisect_silentfile~point_count~point_definitions=(matchbisect_filewithNone->()|Somev->default_bisect_file:=v);(matchbisect_silentwithNone->()|Somev->default_bisect_silent:=v);let()=Lazy.forceregister_dumpinCommon.register_filefile~point_count~point_definitions