123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296(************************************************************************)(* * 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) *)(************************************************************************)openUtil(* Dump of globalization (to be used by coqdoc) *)letglob_file=refstdoutletopen_glob_filef=glob_file:=open_outfletclose_glob_file()=close_out!glob_filetypeglob_output=|NoGlob|Feedback|MultFiles|Fileofstringletglob_output=ref[]letget_output()=match!glob_outputwith|[]->NoGlob|g::_->gletpush_outputg=glob_output:=g::!glob_outputletpop_output()=glob_output:=match!glob_outputwith|[]->CErrors.anomaly(Pp.str"No output left to pop")|_::ds->dsletpause()=push_outputNoGlobletcontinue=pop_outputletwith_glob_outputgf()=push_outputg;tryletres=f()inpop_output();reswithreraise->letreraise=Exninfo.capturereraiseinpop_output();Exninfo.iraisereraiseletdump()=get_output()<>NoGlobletdump_strings=ifdump()&&get_output()!=Feedbackthenoutput_string!glob_filesletstart_dump_glob~vfile~vofile=matchget_output()with|MultFiles->open_glob_file(Filename.chop_extensionvofile^".glob");output_string!glob_file"DIGEST ";output_string!glob_file(Digest.to_hex(Digest.filevfile));output_char!glob_file'\n'|Filef->open_glob_filef;output_string!glob_file"DIGEST NO\n"|NoGlob|Feedback->()letend_dump_glob()=matchget_output()with|MultFiles|File_->close_glob_file()|NoGlob|Feedback->()openDeclsopenDeclarationslettype_of_logical_kind=function|IsDefinitiondef->(matchdefwith|Definition|Let|LetContext->"def"|Coercion->"coe"|SubClass->"subclass"|CanonicalStructure->"canonstruc"|Example->"ex"|Fixpoint->"def"|CoFixpoint->"def"|Scheme->"scheme"|StructureComponent->"proj"|IdentityCoercion->"coe"|Instance->"inst"|Method->"meth")|IsAssumptiona->(matchawith|Definitional->"defax"|Logical->"prfax"|Conjectural->"prfax"|Context->"prfax")|IsProofth->(matchthwith|Theorem|Lemma|Fact|Remark|Property|Proposition|Corollary->"thm")|IsPrimitive->"prim"|IsSymbol->"symb"(** Data associated to global parameters and constants *)letcsttab=Summary.ref(Names.Cmap.empty:logical_kindNames.Cmap.t)~name:"CONSTANT"letadd_constant_kindknk=csttab:=Names.Cmap.addknk!csttabletconstant_kindkn=Names.Cmap.findkn!csttablettype_of_global_refgr=ifTypeclasses.is_classgrthen"class"elseletopenNames.GlobRefinmatchgrwith|ConstRefcst->type_of_logical_kind(constant_kindcst)|VarRefv->"var"^type_of_logical_kind(Decls.variable_kindv)|IndRefind->let(mib,oib)=Inductive.lookup_mind_specif(Global.env())indinifmib.Declarations.mind_record<>Declarations.NotRecordthenbeginmatchmib.Declarations.mind_finitewith|Finite->"indrec"|BiFinite->"rec"|CoFinite->"corec"endelsebeginmatchmib.Declarations.mind_finitewith|Finite->"ind"|BiFinite->"variant"|CoFinite->"coind"end|ConstructRef_->"constr"letremove_sectionsdir=letcwd=Lib.cwd_except_section()inifLibnames.is_dirpath_prefix_ofcwddirthen(* Not yet (fully) discharged *)cwdelse(* Theorem/Lemma outside its outer section of definition *)dirletintervalloc=letloc1,loc2=Loc.unloclocinloc1,loc2-1letdump_ref?locfilepathmodpathidentty=matchget_output()with|Feedback->Option.iter(funloc->Feedback.feedback(Feedback.GlobRef(loc,filepath,modpath,ident,ty)))loc|NoGlob->()|_->Option.iter(funloc->letbl,el=intervallocindump_string(Printf.sprintf"R%d:%d %s %s %s %s\n"blelfilepathmodpathidentty))locletdump_reference?locmodpathidentty=letfilepath=Names.DirPath.to_string(Lib.library_dp())indump_ref?locfilepathmodpathidenttyletdump_secvar?locid=dump_reference?loc"<>"(Libnames.string_of_qualid(Decls.variable_secpathid))"var"letdump_modref?locmpty=let(dp,l)=Lib.split_modpathmpinletfilepath=Names.DirPath.to_stringdpinletmodpath=Names.DirPath.to_string(Names.DirPath.makel)inletident="<>"indump_ref?locfilepathmodpathidenttyletdump_libref?locdpty=dump_ref?loc(Names.DirPath.to_stringdp)"<>""<>"tyletcook_notation(from,df)sc=(* We encode notations so that they are space-free and still human-readable *)(* - all spaces are replaced by _ *)(* - all _ denoting a non-terminal symbol are replaced by x *)(* - all terminal tokens are surrounded by single quotes, including '_' *)(* which already denotes terminal _ *)(* - all single quotes in terminal tokens are doubled *)(* - characters < 32 are represented by '^A, '^B, '^C, etc *)(* The output is decoded in function Index.prepare_entry of coqdoc *)letntn=Bytes.make(String.lengthdf*5)'_'inletj=ref0inletl=String.lengthdf-1inleti=ref0inletopenBytesin(* Bytes.set *)while!i<=ldoassert(df.[!i]!=' ');ifdf.[!i]=='_'&&(Int.equal!il||df.[!i+1]==' ')then(* Next token is a non-terminal *)(setntn!j'x';incrj;incri)elsebegin(* Next token is a terminal *)setntn!j'\'';incrj;while!i<=l&&df.[!i]!=' 'doifdf.[!i]<' 'thenletc=char_of_int(int_of_char'A'+int_of_chardf.[!i]-1)in(String.blit("'^"^String.make1c)0ntn!j3;j:=!j+3;incri)elsebeginifdf.[!i]=='\''then(setntn!j'\'';incrj);setntn!jdf.[!i];incrj;incrienddone;setntn!j'\'';incrjend;if!i<=lthen(setntn!j'_';incrj;incri)done;letdf=Bytes.sub_stringntn0!jinletdf_sc=matchscwithSomesc->":"^sc^":"^df|_->"::"^dfinletfrom_df_sc=matchfromwithConstrexpr.InCustomEntryfrom->":"^from^df_sc|Constrexpr.InConstrEntry->":"^df_scinfrom_df_scletdump_notation_locationposldf(((path,secpath),_),sc)=ifdump()thenletpath=Names.DirPath.to_stringpathinletsecpath=Names.DirPath.to_stringsecpathinletdf=cook_notationdfscinList.iter(funl->dump_ref~loc:(Loc.make_locl)pathsecpathdf"not")poslletadd_glob_gen?locsplib_dpty=ifdump()thenletmod_dp,id=Libnames.repr_pathspinletmod_dp=remove_sectionsmod_dpinletmod_dp_trunc=Libnames.drop_dirpath_prefixlib_dpmod_dpinletfilepath=Names.DirPath.to_stringlib_dpinletmodpath=Names.DirPath.to_stringmod_dp_truncinletident=Names.Id.to_stringidindump_ref?locfilepathmodpathidenttyletadd_glob?locref=ifdump()thenletsp=Nametab.path_of_globalrefinletlib_dp=Lib.library_partrefinletty=type_of_global_refrefinadd_glob_gen?locsplib_dptyletmp_of_knkn=letmp,l=Names.KerName.reprkninNames.MPdot(mp,l)letadd_glob_kn?lockn=ifdump()thenletsp=Nametab.path_of_abbreviationkninletlib_dp=Names.ModPath.dp(mp_of_knkn)inadd_glob_gen?locsplib_dp"abbrev"letdump_def?loctysecpathid=Option.iter(funloc->ifget_output()=FeedbackthenFeedback.feedback(Feedback.GlobDef(loc,id,secpath,ty))elseletbl,el=intervallocindump_string(Printf.sprintf"%s %d:%d %s %s\n"tyblelsecpathid))locletdump_definition{CAst.loc;v=id}secs=dump_def?locs(Names.DirPath.to_string(Lib.current_dirpathsec))(Names.Id.to_stringid)letdump_constraint{CAst.loc;v=n}secty=matchnwith|Names.Nameid->dump_definitionCAst.(make?locid)secty|Names.Anonymous->()letdump_moddef?locmpty=let(dp,l)=Lib.split_modpathmpinletmp=Names.DirPath.to_string(Names.DirPath.makel)indump_def?locty"<>"mpletdump_notation{CAst.loc;v=df}scsec=Option.iter(funloc->(* We dump the location of the opening '"' *)leti=fst(Loc.unlocloc)inletlocation=(Loc.make_loc(i,i+1))indump_def~loc:location"not"(Names.DirPath.to_string(Lib.current_dirpathsec))(cook_notationdfsc))locletdump_binding?locuid=dump_def?loc"binder""<>"uid