123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128(************************************************************************)(* * The Coq Proof Assistant / The Coq Development Team *)(* v * Copyright INRIA, CNRS and contributors *)(* <O___,, * (see version control and CREDITS file for authors & dates) *)(* \VV/ **************************************************************)(* // * This file is distributed under the terms of the *)(* * GNU Lesser General Public License Version 2.1 *)(* * (see LICENSE file for the text of the license) *)(************************************************************************)openXml_datatypetypelevel=|Debug|Info|Notice|Warning|Errorletpp_lvlfmtlvl=letopenFormatinmatchlvlwith|Error->fprintffmt"Error: "|Info->fprintffmt"Info: "|Debug->fprintffmt"Debug: "|Warning->fprintffmt"Warning: "|Notice->fprintffmt""typedoc_id=inttyperoute_id=inttypefeedback_content=|Processed|Incomplete|Complete|ProcessingInofstring|InProgressofint|WorkerStatusofstring*string|AddedAxiom|GlobRefofLoc.t*string*string*string*string|GlobDefofLoc.t*string*string*string|FileDependencyofstringoption*string|FileLoadedofstring*string(* Extra metadata *)|CustomofLoc.toption*string*xml(* Generic messages *)|Messageoflevel*Loc.toption*Pp.ttypefeedback={doc_id:doc_id;(* The document being concerned *)span_id:Stateid.t;route:route_id;contents:feedback_content;}(** Feeders *)letfeeders:(int,feedback->unit)Hashtbl.t=Hashtbl.create7letadd_feeder=letf_id=ref0infunf->incrf_id;Hashtbl.addfeeders!f_idf;!f_idletdel_feederfid=Hashtbl.removefeedersfidletdefault_route=0letspan_id=refStateid.dummyletdoc_id=ref0letfeedback_route=refdefault_routeletset_id_for_feedback?(route=default_route)di=doc_id:=d;span_id:=i;feedback_route:=routeletwarn_no_listeners=reftrueletfeedback?did?id?routewhat=letm={contents=what;route=Option.default!feedback_routeroute;doc_id=Option.default!doc_iddid;span_id=Option.default!span_idid;}inif!warn_no_listeners&&Hashtbl.lengthfeeders=0thenbeginFormat.eprintf"Warning, feedback message received but no listener to handle it!@\n%!";matchm.contentswith|Message(lvl,_,msg)->Format.eprintf"%a%a"pp_lvllvlPp.pp_withmsg|_->()end;Hashtbl.iter(fun_f->fm)feeders(* Logging messages *)letfeedback_logger?loclvlmsg=feedback~route:!feedback_route~id:!span_id(Message(lvl,loc,msg))letmsg_info?locx=feedback_logger?locInfoxletmsg_notice?locx=feedback_logger?locNoticexletmsg_warning?locx=feedback_logger?locWarningx(* let msg_error ?loc x = feedback_logger ?loc Error x *)letmsg_debug?locx=feedback_logger?locDebugx(* Helper for tools willing to understand only the messages *)letconsole_feedback_listenerfmt=letopenFormatinletpp_locfmtloc=letopenLocinmatchlocwith|None->fprintffmt""|Someloc->letwhere=matchloc.fnamewithInFile{file}->file|ToplevelInput->"Toplevel input"infprintffmt"\"%s\", line %d, characters %d-%d:@\n"whereloc.line_nb(loc.bp-loc.bol_pos)(loc.ep-loc.bol_pos)inletchecker_feed(fb:feedback)=matchfb.contentswith|Processed->()|Incomplete->()|Complete->()|ProcessingIn_->()|InProgress_->()|WorkerStatus(_,_)->()|AddedAxiom->()|GlobRef(_,_,_,_,_)->()|GlobDef(_,_,_,_)->()|FileDependency(_,_)->()|FileLoaded(_,_)->()|Custom(_,_,_)->()|Message(lvl,loc,msg)->fprintffmt"@[%a@]%a@[%a@]\n%!"pp_loclocpp_lvllvlPp.pp_withmsginchecker_feed