Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file external.ml
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364(** Provides a function for calling external checkers using a Unix command. *)openLplibopenBaseopenExtraopenCommonopenErroropenCore(** Logging function for external checkers. *)letlog_xtrn=Logger.make'z'"xtrn""external tools"letlog_xtrn=log_xtrn.pp(** [run prop pp cmd sign] runs the external checker given by the Unix command
[cmd] on the signature [sign]. The signature is processed and written to a
Unix pipe using the formatter [pp], and the produced output is fed to the
command on its standard output. The return value is [Some true] in case of
a successful check, [Some false] in the case of a failed check, and [None]
if the external tool cannot conclude. Note that the command [cmd] should
write either ["YES"], ["NO"] or ["MAYBE"] as its first line of (standard)
output. The exception [Fatal] may be raised if [cmd] exhibits a different
behavior. The name [prop] is used to refer to the checked property when an
error message is displayed. *)letrun:string->Sign.tpp->string->Sign.t->booloption=funpropppcmdsign->(* Run the command. *)ifLogger.log_enabled()thenlog_xtrn"Running %s command [%s]"propcmd;let(ic,oc,ec)=Unix.open_process_fullcmd(Unix.environment())in(* Feed it the printed signature. *)pp(Format.formatter_of_out_channeloc)sign;flushoc;close_outoc;ifLogger.log_enabled()thenlog_xtrn"Wrote the data and closed the pipe.";(* Read the answer (and possible error messages). *)letout=input_linesicinifLogger.log_enabled()&&out<>[]thenbeginlog_xtrn"==== Data written to [stdout] ====";List.iter(log_xtrn"%s")out;log_xtrn"==================================";end;leterr=input_linesecinifLogger.log_enabled()&&err<>[]thenbeginlog_xtrn"==== Data written to [stderr] ====";List.iter(log_xtrn"%s")err;log_xtrn"=================================="end;(* Terminate the process. *)match(Unix.close_process_full(ic,oc,ec),out)with|(Unix.WEXITED0,"YES"::_)->Sometrue|(Unix.WEXITED0,"NO"::_)->Somefalse|(Unix.WEXITED0,"MAYBE"::_)->None|(Unix.WEXITED0,[])->fatal_no_pos"The %s checker produced no output."prop|(Unix.WEXITED0,a::_)->fatal_no_pos"The %s checker gave an unexpected answer: %s"propa|(Unix.WEXITEDi,_)->fatal_no_pos"The %s checker returned with code [%i]."propi|(Unix.WSIGNALEDi,_)->fatal_no_pos"The %s checker was killed by signal [%i]."propi|(Unix.WSTOPPEDi,_)->fatal_no_pos"The %s checker was stopped by signal [%i]."propi(** {b NOTE} that for any given property being checked, the simplest possible
valid command is ["echo MAYBE"]. Moreover, ["cat > file; echo MAYBE"] can
conveniently be used to write generated data to the file ["file"]. This is
useful for debugging purposes. *)