123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320(*****************************************************************************)(* libCUDF - CUDF (Common Upgrade Description Format) manipulation library *)(* Copyright (C) 2009-2012 Stefano Zacchiroli <zack@upsilon.cc> *)(* *)(* This library is free software: you can redistribute it and/or modify *)(* it under the terms of the GNU Lesser General Public License as *)(* published by the Free Software Foundation, either version 3 of the *)(* License, or (at your option) any later version. A special linking *)(* exception to the GNU Lesser General Public License applies to this *)(* library, see the COPYING file for more information. *)(*****************************************************************************)openExtLibopenPrintfopenCudf_typesopenCudf_types_ppexceptionConstraint_violationofstringtypepackage={package:pkgname;version:version;depends:vpkgformula;conflicts:vpkglist;provides:veqpkglist;installed:bool;was_installed:bool;keep:enum_keep;pkg_extra:typed_valuestanza;}typerequest={request_id:string;install:vpkglist;remove:vpkglist;upgrade:vpkglist;req_extra:typed_valuestanza;}typepreamble={preamble_id:string;property:typedecl;univ_checksum:string;status_checksum:string;req_checksum:string;}typecudf_doc=preambleoption*packagelist*requesttypecudf_item=[`Preambleofpreamble|`Packageofpackage|`Requestofrequest]typeuniverse={id2pkg:((string*int),package)Hashtbl.t;(** <name, ver> -> pkg *)name2pkgs:(string,packagelistref)Hashtbl.t;(** name -> pkg list ref *)uid2pkgs:(int,package)Hashtbl.t;(** int uid -> pkg *)id2uid:((pkgname*version),int)Hashtbl.t;(** <name, ver> -> int uid *)features:(string,(package*versionoption)listref)Hashtbl.t;(** feature -> avail feature versions
Each available feature is reported as a pair
<owner, provided version>, where owner is the package
providing it. Provided version "None" means "all possible
versions" *)mutableuniv_size:int;mutableinst_size:int;}typecudf=preamble*universe*requesttypesolution=preamble*universeletuniverse_sizeuniv=univ.univ_sizeletinstalled_sizeuniv=univ.inst_sizelet(=%)pkg1pkg2=pkg1.package=pkg2.package&&pkg1.version=pkg2.versionlet(<%)pkg1pkg2=Stdlib.compare(pkg1.package,pkg1.version)(pkg2.package,pkg2.version)let(>%)pkg1pkg2=Stdlib.compare(pkg2.package,pkg2.version)(pkg1.package,pkg1.version)letdefault_preamble={preamble_id="";property=[];univ_checksum="";status_checksum="";req_checksum="";}letdefault_package={package="";version=0;depends=[];conflicts=[];provides=[];installed=false;was_installed=false;keep=`Keep_none;pkg_extra=[];}letdefault_request={request_id="";install=[];remove=[];upgrade=[];req_extra=[];}letempty_universe?(size=1023)()={id2pkg=Hashtbl.createsize;uid2pkgs=Hashtbl.createsize;id2uid=Hashtbl.createsize;name2pkgs=Hashtbl.createsize;features=Hashtbl.createsize;univ_size=0;inst_size=0;}letadd_to_hash_listhnp=tryletl=Hashtbl.findhninl:=p::!lwithNot_found->Hashtbl.addhn(ref[p])letget_hash_listhn=try!(Hashtbl.findhn)withNot_found->[](** process all features (i.e., Provides) provided by a given package
and fill with them a given feature table *)letexpand_featurespkgfeatures=List.iter(function|name,None->add_to_hash_listfeaturesname(pkg,None)|name,Some(_,ver)->add_to_hash_listfeaturesname(pkg,(Somever)))pkg.providesletadd_package_auxunivpkguid=letid=pkg.package,pkg.versioninifHashtbl.memuniv.id2pkgidthenraise(Constraint_violation(sprintf"duplicate package: <%s, %d>"pkg.packagepkg.version))elsebeginHashtbl.adduniv.uid2pkgsuidpkg;Hashtbl.adduniv.id2uididuid;Hashtbl.adduniv.id2pkgidpkg;add_to_hash_listuniv.name2pkgspkg.packagepkg;expand_featurespkguniv.features;univ.univ_size<-univ.univ_size+1;ifpkg.installedthenuniv.inst_size<-univ.inst_size+1endletadd_packageunivpkg=letuid=(Hashtbl.lengthuniv.uid2pkgs)+1inadd_package_auxunivpkguidletremove_packageunivid=ifnot(Hashtbl.memuniv.id2pkgid)then()elsebeginletuid=Hashtbl.finduniv.id2uididinletp=Hashtbl.finduniv.uid2pkgsuidinletl=Hashtbl.finduniv.name2pkgsp.packageinl:=List.remove!lp;ifList.length!l=0thenHashtbl.removeuniv.name2pkgsp.package;List.iter(function|name,None->letl=Hashtbl.finduniv.featuresnameinl:=List.remove!l(p,None);ifList.length!l=0thenHashtbl.removeuniv.featuresname|name,Some(_,ver)->letl=Hashtbl.finduniv.featuresnameinl:=List.remove!l(p,(Somever));ifList.length!l=0thenHashtbl.removeuniv.featuresname)p.provides;Hashtbl.removeuniv.uid2pkgsuid;Hashtbl.removeuniv.id2uidid;Hashtbl.removeuniv.id2pkgid;univ.univ_size<-univ.univ_size-1;ifp.installedthenuniv.inst_size<-univ.inst_size-1;endletload_universepkgs=letsize=List.lengthpkgsinletuniv=empty_universe~size()inletuid=ref0inList.iter(funpkg->add_package_auxunivpkg!uid;incruid)pkgs;univletpackage_by_uiduniv=Hashtbl.finduniv.uid2pkgsletuid_by_packageunivpkg=Hashtbl.finduniv.id2uid(pkg.package,pkg.version)letlookup_packageuniv=Hashtbl.finduniv.id2pkgletmem_packageuniv=Hashtbl.memuniv.id2pkgletiter_packagesfuniv=Hashtbl.iter(fun_idpkg->fpkg)univ.id2pkgletiteri_packagesfuniv=Hashtbl.iter(fun_idpkg->f_idpkg)univ.uid2pkgsletfold_packagesfinituniv=Hashtbl.fold(fun_idpkgacc->faccpkg)univ.id2pkginitletiter_packages_by_namefuniv=Hashtbl.iter(funn{contents=l}->fnl)univ.name2pkgsletfold_packages_by_namefauniv=Hashtbl.fold(funn{contents=l}a->fanl)univ.name2pkgsaletpackage_namesuniv=List.of_enum(Hashtbl.keysuniv.name2pkgs)letget_packages?filteruniv=matchfilterwith|None->fold_packages(funaccpkg->pkg::acc)[]univ|Sometest->fold_packages(funaccpkg->iftestpkgthenpkg::accelseacc)[]univlet(|=)v=function|None->true|Some(`Eq,v')->v=v'|Some(`Neq,v')->v<>v'|Some(`Geq,v')->v>=v'|Some(`Gt,v')->v>v'|Some(`Leq,v')->v<=v'|Some(`Lt,v')->v<v'letversion_matches=(|=)letstatusuniv=letuniv'=empty_universe()inHashtbl.iter(funidpkg->matchpkgwith|{installed=true;_}->Hashtbl.adduniv'.id2pkgidpkg;add_to_hash_listuniv'.name2pkgspkg.packagepkg;expand_featurespkguniv'.features|_->())univ.id2pkg;univ'.inst_size<-univ.inst_size;univ'.univ_size<-univ.inst_size;(* as we filtered on installed pkgs *)univ'letlookup_packages?(filter=None)univpkgname=letpackages=get_hash_listuniv.name2pkgspkgnameinmatchfilterwithNone->packages|Some_aspred->List.filter(funp->p.version|=pred)packagesletget_installedunivpkgname=List.filter(fun{installed=i;_}->i)(lookup_packagesunivpkgname)letmem_installed?(include_features=true)?(ignore=fun_->false)univ(name,constr)=letpkg_filter=funpkg->not(ignorepkg)inletmem_featureconstr=letfeats=get_hash_listuniv.featuresnameinList.exists(function|owner_pkg,_whennotowner_pkg.installed->false|owner_pkg,None->pkg_filterowner_pkg|owner_pkg,Somev->pkg_filterowner_pkg&&v|=constr)featsinletpkgs=List.filterpkg_filter(get_installedunivname)inList.exists(funpkg->pkg.version|=constr)pkgs||(include_features&&mem_featureconstr)letwho_provides?(installed=true)univ(pkgname,constr)=List.filter(function|pkg,_whennotpkg.installed&&installed->false|_,None->true|_,Somev->v|=constr)(get_hash_listuniv.featurespkgname)letlookup_typed_package_propertypkg=function|"package"->`Pkgnamepkg.package|"version"->`Posintpkg.version|"depends"->`Vpkgformulapkg.depends|"conflicts"->`Vpkglistpkg.conflicts|"provides"->`Veqpkglistpkg.provides|"installed"->`Boolpkg.installed|"keep"->`Enum(keep_enums,string_of_keeppkg.keep)|prop_name->List.assocprop_namepkg.pkg_extraletlookup_typed_request_propertyreq=function|"request"->`Stringreq.request_id|"install"->`Vpkglistreq.install|"remove"->`Vpkglistreq.remove|"upgrade"->`Vpkglistreq.upgrade|prop_name->List.assocprop_namereq.req_extraletlookup_typed_preamble_propertypre=function|"preamble"->`Stringpre.preamble_id|"property"->`Typedeclpre.property|"univ-checksum"->`Stringpre.univ_checksum|"status-checksum"->`Stringpre.status_checksum|"req-checksum"->`Stringpre.req_checksum|_->raiseNot_foundletlookup_package_propertypkgprop=string_of_value(lookup_typed_package_propertypkgprop)letlookup_request_propertyreqprop=string_of_value(lookup_typed_request_propertyreqprop)letlookup_preamble_propertypreprop=string_of_value(lookup_typed_preamble_propertypreprop)letlookup_package_typedecl?(extra=[])prop=List.assocprop(Cudf_conf.package_typedecl@extra)