123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317openDune_site.Private_moduleData=Dune_site_plugins_dataletmeta_fn="META"letreaddir=let(/)=Filename.concatinletreaddir_noexndir=trySys.readdirdirwith|Sys_error_->[||]infundirs->List.concat(List.map(fundir->List.filter(funentry->Sys.file_exists(dir/entry/meta_fn))(Array.to_list(readdir_noexndir)))dirs);;letreclookupdirsfile=matchdirswith|[]->None|dir::dirs->letfile'=Filename.concatdirfileinifSys.file_existsfile'thenSomefile'elselookupdirsfile;;moduletypeS=sigvalpaths:stringlistvallist:unit->stringlistvalload_all:unit->unitvalload:string->unitendletreccheck_predicatespredicates=matchSys.backend_type,predicateswith|_,[]->true|Sys.Native,Meta_parser.Pos"byte"::_->false|Sys.Bytecode,Meta_parser.Pos"native"::_->false|Sys.Native,Meta_parser.Pos"native"::predicates->check_predicatespredicates|Sys.Bytecode,Meta_parser.Pos"byte"::predicates->check_predicatespredicates|Sys.Native,Meta_parser.Neg"native"::_->false|Sys.Bytecode,Meta_parser.Neg"byte"::_->false|Sys.Native,Meta_parser.Neg"byte"::predicates->check_predicatespredicates|Sys.Bytecode,Meta_parser.Neg"native"::predicates->check_predicatespredicates|_,Meta_parser.Pospred::predicates->Data.findlib_predicates_set_by_dunepred&&check_predicatespredicates|_,Meta_parser.Negpred::predicates->(not(Data.findlib_predicates_set_by_dunepred))&&check_predicatespredicates;;letcheck_predicates_with_pluginpredicates=letrecauxpredicateshas_pluginacc=matchpredicateswith|[]->has_plugin&&check_predicatesacc|Meta_parser.Pos"plugin"::predicates->auxpredicatestrueacc|predicate::predicates->auxpredicateshas_plugin(predicate::acc)inauxpredicatesfalse[];;letrecget_pluginpluginsrequiresentries=matchentrieswith|[]->List.revplugins,List.revrequires|Meta_parser.Comment_::entries->get_pluginpluginsrequiresentries|Package_::entries->get_pluginpluginsrequiresentries|Rule{var="plugin";predicates;action=Set;value}::entrieswhencheck_predicatespredicates->get_plugin[value]requiresentries|Rule{var="plugin";predicates;action=Add;value}::entrieswhencheck_predicatespredicates->get_plugin(value::plugins)requiresentries(* archive(native|byte,plugin) is the way used in the wild before findlib
supported plugins *)|Rule{var="archive";predicates;action=Set;value}::entrieswhencheck_predicates_with_pluginpredicates->get_plugin[value]requiresentries|Rule{var="archive";predicates;action=Add;value}::entrieswhencheck_predicates_with_pluginpredicates->get_plugin(value::plugins)requiresentries|Rule{var="requires";predicates;action=Set;value}::entrieswhencheck_predicatespredicates->get_pluginplugins[value]entries|Rule{var="requires";predicates;action=Add;value}::entrieswhencheck_predicatespredicates->get_pluginplugins(value::requires)entries|Rule_::entries->get_pluginpluginsrequiresentries;;exceptionThread_library_required_by_plugin_but_not_required_by_main_executableexceptionLibrary_not_foundof{search_paths:stringlist;prefix:stringlist;name:string}exceptionPlugin_not_foundof{search_paths:stringlist;name:string}let()=Printexc.register_printer(function|Thread_library_required_by_plugin_but_not_required_by_main_executable->Some(Format.asprintf"%a"Format.pp_print_text"It is not possible to dynamically link a plugin which uses the thread \
library with an executable not already linked with the thread library.")|Plugin_not_found{search_paths;name}->Some(Format.sprintf"The plugin %S can't be found in the search paths %S."name(String.concat":"search_paths))|Library_not_found{search_paths;prefix=[];name}->Some(Format.sprintf"The library %S can't be found in the search paths %S."name(String.concat":"search_paths))|Library_not_found{search_paths;prefix;name}->Some(Format.sprintf"The sub-library %S can't be found in the library %s in the search paths %S."name(String.concat"."prefix)(String.concat":"search_paths))|_->None);;letrecfind_library~dirs~prefix~suffixdirectorymeta=letrecfind_directorydirectory=function|[]->directory|Meta_parser.Rule{var="directory";predicates=[];action=Set;value}::_->(matchdirectorywith|None->Somevalue|Someold->Some(Filename.concatoldvalue))|_::entries->find_directorydirectoryentriesinmatchsuffixwith|[]->find_directorydirectorymeta,meta|pkg::suffix->letdirectory=find_directorydirectorymetainletrecauxpkg=function|[]->raise(Library_not_found{search_paths=dirs;prefix=List.revprefix;name=pkg})|Meta_parser.Package{name=Somename;entries}::_whenString.equalnamepkg->find_library~dirs~prefix:(pkg::prefix)~suffixdirectoryentries|_::entries->auxpkgentriesinauxpkgmeta;;letextract_wordss~is_word_char=letrecskip_blanksi=ifi=String.lengthsthen[]elseifis_word_chars.[i]thenparse_wordi(i+1)elseskip_blanks(i+1)andparse_wordij=ifj=String.lengthsthen[StringLabels.subs~pos:i~len:(j-i)]elseifis_word_chars.[j]thenparse_wordi(j+1)elseStringLabels.subs~pos:i~len:(j-i)::skip_blanks(j+1)inskip_blanks0;;letextract_comma_space_separated_wordss=extract_wordss~is_word_char:(function|','|' '|'\t'|'\n'->false|_->true);;letsplit_alll=List.concat(List.mapextract_comma_space_separated_wordsl)letfind_plugin~dirs~dir~suffix(meta:Meta_parser.t)=letdirectory,meta=find_library~dirs~prefix:(Option.to_listmeta.name)~suffixNonemeta.entriesinletplugins,requires=get_plugin[][]metainletdirectory=matchdirectorywith|None->dir|Somepkg_dir->ifpkg_dir.[0]='+'||pkg_dir.[0]='^'thenFilename.concat(Lazy.forceHelpers.stdlib)(String.subpkg_dir1(String.lengthpkg_dir-1))elseifFilename.is_relativepkg_dirthenFilename.concatdirpkg_direlsepkg_dirinletplugins=split_allpluginsinletrequires=split_allrequiresindirectory,plugins,requires;;letloadfile~pkg=letentries=letic=open_infileintryletlb=Lexing.from_channelicinlb.lex_curr_p<-{pos_fname=file;pos_lnum=1;pos_bol=0;pos_cnum=0};letr=Meta_parser.Parse.entrieslb0[]inclose_inic;rwith|exn->close_inic;raiseexnin{Meta_parser.name=Somepkg;entries};;letlookup_and_load_one_dir~dir~pkg=letmeta_file=Filename.concatdirmeta_fninifSys.file_existsmeta_filethenSome(loadmeta_file~pkg)else((* Alternative layout *)letdir=Filename.dirnamedirinletmeta_file=Filename.concatdir(meta_fn^"."^pkg)inifSys.file_existsmeta_filethenSome(loadmeta_file~pkg)elseNone);;letsplit~dirsname=matchString.split_on_char'.'namewith|[]->raise(Library_not_found{search_paths=dirs;prefix=[];name})|pkg::rest->pkg,rest;;letlookup_and_summarizealldirsname=letpkg,suffix=split~dirs:alldirsnameinletrecloopdirs=matchdirswith|[]->List.assoc_optpkgData.builtin_library|>(function|None->raise(Library_not_found{search_paths=alldirs;prefix=[];name})|Somemeta->find_plugin~dirs:alldirs~dir:(Lazy.forceHelpers.stdlib)~suffixmeta)|dir::dirs->letdir=Filename.concatdirpkgin(matchlookup_and_load_one_dir~dir~pkgwith|None->loopdirs|Somep->find_plugin~dirs:alldirs~dir~suffixp)inloopalldirs;;letloaded_libraries=lazy(leth=Hashtbl.create10inList.iter(funs->Hashtbl.addhs())Data.already_linked_libraries;h);;letload_gen~load_requiresdirsname=letloaded_libraries=Lazy.forceloaded_librariesinifnot(Hashtbl.memloaded_librariesname)then(ifname="threads"thenraiseThread_library_required_by_plugin_but_not_required_by_main_executable;Hashtbl.addloaded_librariesname();letdirectory,plugins,requires=lookup_and_summarizedirsnameinList.iterload_requiresrequires;List.iter(funp->letfile=Filename.concatdirectorypinDune_site_backend.Linker.loadfile)plugins);;letrecload_requiresname=load_gen~load_requires(Lazy.forceHelpers.ocamlpath)nameletload_pluginplugin_pathsname=matchlookupplugin_paths(Filename.concatnamemeta_fn)with|None->raise(Plugin_not_found{search_paths=plugin_paths;name})|Somemeta_file->letmeta=loadmeta_file~pkg:nameinletplugins,requires=get_plugin[][]meta.entriesinassert(plugins=[]);letrequires=split_allrequiresinList.iterload_requiresrequires;;moduleMake(X:sigvalpaths:stringlistend):S=structincludeXletlist()=List.sortString.compare(readdirpaths)letloadname=load_pluginpathsnameletload_all()=List.iterload(list())endletload=load_requiresletavailablename=Hashtbl.mem(Lazy.forceloaded_libraries)name||letocamlpath=Lazy.forceHelpers.ocamlpathintryignore(lookup_and_summarizeocamlpathname);truewith|_->(* CR - What exceptions are being swallowed here? *)false;;