123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566moduleP=Extend_protocol(** Helper for the driver (Merlin) *)typet={name:string;capabilities:P.capabilities;stdin:out_channel;stdout:in_channel;mutablepid:int;notify:string->unit;debug:string->unit;}exceptionExtensionofstring*string*stringletrun?(notify=ignore)?(debug=ignore)name=letpstdin,stdin=Unix.pipe()inletstdout,pstdout=Unix.pipe()inUnix.set_close_on_execpstdin;Unix.set_close_on_execstdin;Unix.set_close_on_execpstdout;Unix.set_close_on_execstdout;letpid=Unix.create_process("ocamlmerlin-"^name)[||]pstdinpstdoutUnix.stderrinUnix.closepstdout;Unix.closepstdin;letstdin=Unix.out_channel_of_descrstdininletstdout=Unix.in_channel_of_descrstdoutinmatchExtend_main.Handshake.negotiate_drivernamestdoutstdinwith|capabilities->{name;capabilities;stdin;stdout;pid;notify;debug}|exceptionexn->close_out_noerrstdin;close_in_noerrstdout;raiseexnletstopt=close_out_noerrt.stdin;close_in_noerrt.stdout;ift.pid<>-1then(let_,_=Unix.waitpid[]t.pidint.pid<--1;)letcapabilitiest=t.capabilitiesletreadertrequest=ift.pid=-1theninvalid_arg"Extend_main.Driver.reader: extension is closed";output_valuet.stdin(P.Reader_requestrequest);flusht.stdin;letrecaux()=matchinput_valuet.stdoutwith|P.Notifystr->t.notifystr;aux()|P.Debugstr->t.debugstr;aux()|P.Exception(kind,msg)->stopt;raise(Extension(t.name,kind,msg))|P.Reader_responseresponse->responseinaux()