123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166(* 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"letsigterm_enable=reffalseletbisect_file_written=reffalsetypemessage=|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->!defaultletenv_to_booleanenvdefault=trymatchString.uppercase_ascii(Sys.getenvenv)with|"YES"->true|"NO"->false|_->defaultwithNot_found->defaultletverbose=lazybeginletfname=env_to_fname"BISECT_SILENT"default_bisect_silentinmatchString.uppercase_asciifnamewith|"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~prefix:"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()=letprefix=full_path(env_to_fname"BISECT_FILE"default_bisect_file)inletreccreate_file()=letfilename=Common.random_filename~prefixintryletfd=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_exnchannel=Common.coverage|>Lazy.force|>Common.write_coverage|>output_stringchannel;flushchannelletdump()=matchSys.backend_typewith|Sys.Other"js_of_ocaml"->(* The dump function is a no-op when running a js_of_ocaml-compiled binary,
as the Unix file-manipulating functions will not be present; instead, the
user must explicitly call write_coverage_data or get_coverage_data as
appropriate. *)()|_->matchfile_channel()with|None->()|Somechannel->(trydump_counters_exnchannelwith_->verboseUnable_to_write_file);close_out_noerrchannelletsigterm_handler(_:int)=bisect_file_written:=true;dump();exit0letdump_at_exit()=ifnot!bisect_file_writtenthenbeginif!sigterm_enablethenbeginignore@@Sys.(signalsigtermSignal_ignore);bisect_file_written:=true;dump();ignore@@Sys.(signalsigtermSignal_default)endelsedump()endletregister_dump:unitLazy.t=lazy(at_exitdump_at_exit)letregister_sigterm_hander:unitLazy.t=lazy(ignore@@Sys.(signalsigterm(Signal_handlesigterm_handler)))letregister_file~bisect_file~bisect_silent~bisect_sigterm~filename~points=(matchbisect_filewithNone->()|Somev->default_bisect_file:=v);(matchbisect_silentwithNone->()|Somev->default_bisect_silent:=v);sigterm_enable:=env_to_boolean"BISECT_SIGTERM"bisect_sigterm;(if!sigterm_enablethenLazy.forceregister_sigterm_hander);let()=Lazy.forceregister_dumpinCommon.register_file~filename~points