--- portage.orig/pym/portage.py 2004-09-11 11:21:38.000000000 +0100 +++ portage/pym/portage.py 2004-09-15 23:38:58.312967072 +0100 @@ -4072,6 +4072,9 @@ def cpv_exists(self,mycpv): return self.cpvdict.has_key(mycpv) + + def cpv_all(self): + return self.cpvdict.keys() def cp_list(self,mycp,use_cache=1): if not self.cpdict.has_key(mycp): @@ -4418,8 +4421,93 @@ myd = "" results.append(myd) return results + + def revdeps(self, mycpv, buildtimedeps=0): + "Returns a list of first-level reverse dependencies on cpv." + + myfdb = fakedbapi() + for i in self.cpv_all(): + myfdb.cpv_inject(i) + myfdb.cpv_remove(mycpv) + myvdb=self + + if buildtimedeps: + self.depvars = ["RDEPEND","DEPEND","PDEPEND"] + else: + self.depvars = ["RDEPEND","PDEPEND"] + # Start with some local helper functions. Defined here since they really aren't useful + # elsewhere. + def potential_revdeps(cpv): + mycp=pkgsplit(cpv)[0] + #print "'"+cpv+"'" + #print myvdb.aux_get(cpv, ["PROVIDE"]) + myprovide=myvdb.aux_get(cpv, ["PROVIDE"])[0].split() + #print cpv,"provides", myprovide + + myret=[] + for x in myvdb.cpv_all(): + myrawdep=string.join(myvdb.aux_get(x, myvdb.depvars), " ") + if string.find(myrawdep, mycp) != -1: + myret.append( (x,myrawdep) ) + for p in myprovide: + if string.find(myrawdep, p) != -1: + myret.append( (x,myrawdep) ) + #print "potentials for %s: " % cpv, [ x[0] for x in myret] + return myret + + def parse_dep(cpv, dep): + """ Returns 1 if cpv and nothing else installed satisfies a requirement of depstring. + Takes a paren_ and use_reduced list or single atom for dep. """ + if type(dep) is list: + if len(dep) == 0: + return 0 + elif dep[0] == "||": + # Any one of the items is enough to satisfy + mylist = dep[1:] + cpv_satisfies=0 + for myatom in mylist: + if parse_dep(cpv, myatom): + cpv_satisfies=1 + if not cpv_satisfies: + return 0 + #else: + # print cpv,"matches",dep + for myother in myfdb.cpv_all(): + for myatom in mylist: + if parse_dep(cpv, myatom): + return 0 + return 1 + else: + # Not a || list; we handle each atom individually. + for myatom in dep: + if parse_dep(cpv, myatom): + return 1 + return 0 + else: + # A simple atom. First, check it isn't a !depend... + if dep[0] == "!": + return 0 + # If cpv and nothing else matches the dep, return 1 + if cpv not in myvdb.match(dep): + #print cpv,"doesn't match",dep + return 0 + if len(myfdb.match(dep)) == 0: + return 1 + #else: + # print "another matches", dep + return 0 + myrevdeps = [] + for myp,mydep in potential_revdeps(mycpv): + myuse = self.aux_get(myp, ["USE"])[0].split() + mydep = portage_dep.paren_reduce(mydep) + mydep = portage_dep.dep_opconvert(mydep) + mydep = portage_dep.use_reduce(mydep,myuse) + if parse_dep(mycpv, mydep): + myrevdeps.append(myp) + return myrevdeps + class vartree(packagetree): "this tree will scan a var/db/pkg database located at root (passed to init)" def __init__(self,root="/",virtual=None,clone=None,categories=None):