123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142(**************************************************************************)(* *)(* OCaml *)(* *)(* Hugo Heuzard *)(* *)(* Copyright 2020 Institut National de Recherche en Informatique et *)(* en Automatique. *)(* *)(* All rights reserved. This file is distributed under the terms of *)(* the GNU Lesser General Public License version 2.1, with the *)(* special exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)moduleStyle=Misc.Styletypecompunit=stringtypefilename=stringtypecompunit_and_source={compunit:compunit;filename:filename;}moduleCompunit_and_source=structtypet=compunit_and_sourcemoduleSet=Set.Make(structtypenonrect=tletcompare=compareend)endtyperefs=Compunit_and_source.Set.ttypet={complete:bool;missing_compunits:(compunit,refs)Hashtbl.t;provided_compunits:(compunit,filenamelist)Hashtbl.t;badly_ordered_deps:(Compunit_and_source.t,refs)Hashtbl.t;}typeerror=|Missing_implementationsof(compunit*compunit_and_sourcelist)list|Wrong_link_orderof(compunit_and_source*compunit_and_sourcelist)list|Multiple_definitionsof(compunit*filenamelist)listletcreate~complete={complete;missing_compunits=Hashtbl.create17;provided_compunits=Hashtbl.create17;badly_ordered_deps=Hashtbl.create17;}letrequiredtcompunit=Hashtbl.memt.missing_compunitscompunitletupdatetkf=letv=Hashtbl.find_opttkinHashtbl.replacetk(fv)letadd_requiredtby(name:string)=letadds=Compunit_and_source.Set.addby(Option.values~default:Compunit_and_source.Set.empty)in(tryletfilename=List.hd(Hashtbl.findt.provided_compunitsname)inupdatet.badly_ordered_deps{compunit=name;filename}addwithNot_found->());updatet.missing_compunitsnameaddletaddt~filename~compunit~provides~requires=List.iter(add_requiredt{compunit;filename})requires;List.iter(funp->Hashtbl.removet.missing_compunitsp;letl=Option.value~default:[](Hashtbl.find_optt.provided_compunitsp)inHashtbl.replacet.provided_compunitsp(filename::l))providesletcheckt=letof_seqs=Seq.map(fun(k,v)->k,Compunit_and_source.Set.elementsv)s|>List.of_seqinletmissing=of_seq(Hashtbl.to_seqt.missing_compunits)inletbadly_ordered_deps=of_seq(Hashtbl.to_seqt.badly_ordered_deps)inletduplicated=Hashtbl.to_seqt.provided_compunits|>Seq.filter(fun(_,files)->List.compare_length_withfiles1>0)|>List.of_seqinmatchduplicated,badly_ordered_deps,missingwith|[],[],[]->None|[],[],l->ift.completethenSome(Missing_implementationsl)elseNone|[],l,_->Some(Wrong_link_orderl)|l,_,_->Some(Multiple_definitionsl)(* Error report *)openFormat_docletprint_referenceprint_fnameppf{compunit;filename}=fprintfppf"%a (%a)"Style.inline_codecompunitprint_fnamefilenameletpp_list_commaf=pp_print_list~pp_sep:(funppf()->fprintfppf",@ ")fletreport_error_doc~print_filenameppf=function|Missing_implementationsl->letprint_modulesppf=List.iter(fun(md,rq)->fprintfppf"@ @[<hov 2>%a referenced from %a@]"Style.inline_codemd(pp_list_comma(print_referenceprint_filename))rq)infprintfppf"@[<v 2>No implementation provided for the following modules:%a@]"print_modulesl|Wrong_link_orderl->letdepends_onppf(dep,depending)=fprintfppf"@ @[<hov 2>%a depends on %a@]"(pp_list_comma(print_referenceprint_filename))depending(print_referenceprint_filename)depinfprintfppf"@[<hov 2>Wrong link order:%a@]"(pp_list_commadepends_on)l|Multiple_definitionsl->letprintppf(compunit,files)=fprintfppf"@ @[<hov>Multiple definitions of module %a in files %a@]"Style.inline_codecompunit(pp_list_comma(Style.as_inline_codeprint_filename))filesinfprintfppf"@[<hov 2> Duplicated implementations:%a@]"(pp_list_commaprint)lletreport_error~print_filename=Format_doc.compat(report_error_doc~print_filename)