Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file primus_print_main.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192openCore_kernelopenBap.StdopenBap_primus.StdopenBap_future.StdopenMonads.StdopenFormatincludeSelf()moduleParam=structopenConfig;;manpage[`S"DESCRIPTION";`P"Monitors a Lisp Machine execution."]letmonitors=param(liststring)"observations"~doc:"A list of observations to print. A keyword `all` can be use to
select all events. To ignore a particular event, add `-' before
the name. An optional + is allowed for the consistency."letoutput=param(somestring)"output"~doc:"A name of a file in which to store the monitor output. If
not specified, then outputs result into stdout"letrules=param(liststring)"rules"lettraceback=param(someint)~as_flag:(Some16)"traceback"~doc:"Stores and outputs a trace of execution. Takes an
optional argument that limits the traceback length to the
specified number of terms."endletstarts_withnamex=String.lengthname>1&&Char.equalname.[0]xletstripname=ifstarts_withname'+'||starts_withname'-'thenString.subo~pos:1nameelsenamelethas_namenamep=String.equal(Primus.Observation.Provider.namep)nameletremove_providername=List.filter~f:(Fn.non(has_namename))letmonitor_providernameps=Primus.Observation.list_providers()|>List.find~f:(has_namename)|>function|None->invalid_argf"An unknown observation provider `%s'"name()|Somep->p::psletparse_monitors=List.fold~init:[]~f:(funps->function|"all"->ps@Primus.Observation.list_providers()|namewhenstarts_withname'-'->remove_provider(stripname)ps|name->monitor_provider(stripname)ps)letprint_eventoutpev=fprintfout"@[(%s %a)@]@\n%!"(Primus.Observation.Provider.namep)Sexp.pp_humevletidppfpos=fprintfppf"%a"Tid.pp(Primus.Pos.tidpos)letprint_posppfpos=letopenPrimus.Posinmatchposwith|Top_->()|Sub{me}->fprintfppf"%a: <%s>@\n"idpos(Sub.nameme)|Blk_->fprintfppf"%a:@\n"idpos|Arg{me}->fprintfppf"%a"Arg.ppme|Phi{me}->fprintfppf"%a"Phi.ppme|Def{me}->fprintfppf"%a"Def.ppme|Jmp{me}->fprintfppf"%a"Jmp.ppmeletrule_providersrule=Bare.Rule.lhsrule|>List.concat_map~f:(function|Sexp.Atomx|Sexp.List(Sexp.Atomx::_)->ifString.lengthx>0&&Char.(x.[0]='?')thenPrimus.Observation.list_providers()|>List.map~f:Primus.Observation.Provider.nameelse[x]|_->warning"Rule %a won't match with any observation"Bare.Rule.pprule;[])letprint_traceppf=List.iter~f:(print_posppf)typestate={trace:Primus.poslist;}letconcatstreams=letstream,main=Stream.create()inList.iterstreams~f:(funstream->Stream.observestream(funx->Signal.sendmainx));stream,main(* returns a stream of derived facts, each element of the stream is
a non-empty list of facts provided from some fact in the list of
facts or another derived fact. *)letprocess_rulerule=letmoduleProv=Primus.Observation.Providerinletobserving=String.Set.of_list(rule_providersrule)inletfacts,to_facts=Primus.Observation.list_providers()|>List.filter~f:(funp->Set.memobserving(Prov.namep))|>List.map~f:(funp->Prov.datap|>Stream.map~f:(funev->Sexp.List[Sexp.Atom(Prov.namep);ev]))|>concatinStream.parsefacts~init:rule~f:(funruleev->letrule,facts=Bare.Rule.applyruleevinList.iterfacts~f:(Signal.sendto_facts);matchfactswith|[]->None,rule|facts->Somefacts,rule)letread_rulesfilename=matchBare.Rule.from_filefilenamewith|Okrules->rules|Errorerr->leterr=asprintf"%a"(Bare.Rule.report_error~filename)errininvalid_argerrletsetup_rules_processoroutrules=rules|>List.concat_map~f:read_rules|>List.map~f:process_rule|>List.iter~f:(funfacts->Stream.observefacts(List.iter~f:(fprintfout"%a@\n%!"Sexp.pp_hum)))letstate=Primus.Machine.State.declare~name:"primus-debug"~uuid:"2fdb0758-3233-4d69-b2e6-704b303ac03a"(fun_->{trace=[]})letstart_monitoring{Config.get=(!)}=letout=match!Param.outputwith|None->std_formatter|Somename->formatter_of_out_channel(Out_channel.createname)insetup_rules_processorout!Param.rules;letmoduleMonitor(Machine:Primus.Machine.S)=structopenMachine.Syntaxletrecord_tracep=Machine.Local.updatestate~f:(funs->{trace=p::s.trace})letprint_trace_=Machine.Local.getstate>>|fun{trace}->print_traceouttraceletsetup_tracing()=ifOption.is_some!Param.tracebackthenMachine.List.sequence[Primus.Interpreter.enter_pos>>>record_trace;Primus.System.stop>>>print_trace;]elseMachine.return()letinit()=setup_tracing()endinPrimus.Machine.add_component(moduleMonitor)[@warning"-D"];Primus.Components.register_generic"observation-printer"(moduleMonitor)~package:"bap"~desc:"Prints the specified set of observations. Controlled via \
the primus-print plugin.";parse_monitors!Param.monitors|>List.iter~f:(funm->info"monitoring %s"(Primus.Observation.Provider.namem);Stream.observe(Primus.Observation.Provider.datam)(print_eventoutm))let()=Config.when_readystart_monitoring