Index: package_meta.cc =================================================================== RCS file: /cvs/cygwin-apps/setup/package_meta.cc,v retrieving revision 2.52 diff -u -w -p -r2.52 package_meta.cc --- package_meta.cc 17 Apr 2006 16:13:17 -0000 2.52 +++ package_meta.cc 26 Jun 2008 22:31:44 -0000 @@ -411,22 +411,22 @@ packagemeta::set_action (packageversion } int -packagemeta::set_requirements (trusts deftrust, size_t depth) +packagemeta::set_requirements (trusts deftrust, set& visitedpkgs) { if (visited()) return 0; /* Only prevent further checks once we have been required by something else */ - if (depth) + if (!visitedpkgs.empty()) visited(true); int changed = 0; /* handle build-depends */ - if (depth == 0 && desired.sourcePackage ().picked()) - changed += desired.sourcePackage ().set_requirements (deftrust, depth + 1); + if (visitedpkgs.empty() && desired.sourcePackage ().picked()) + changed += desired.sourcePackage ().set_requirements (deftrust, visitedpkgs); if (!desired || (desired != installed && !desired.picked ())) /* uninstall || source only */ return changed; - return changed + desired.set_requirements (deftrust, depth); + return changed + desired.set_requirements (deftrust, visitedpkgs); } Index: package_meta.h =================================================================== RCS file: /cvs/cygwin-apps/setup/package_meta.h,v retrieving revision 2.36 diff -u -w -p -r2.36 package_meta.h --- package_meta.h 17 Apr 2006 16:13:17 -0000 2.36 +++ package_meta.h 26 Jun 2008 22:31:44 -0000 @@ -80,10 +80,13 @@ public: void set_action (packageversion const &default_version); void set_action (_actions, packageversion const & default_version); void uninstall (); - int set_requirements (trusts deftrust, size_t depth); + int set_requirements (trusts deftrust, std::set& visitedpkgs); // explicit separation for generic programming. int set_requirements (trusts deftrust) - { return set_requirements (deftrust, 0); } + { + std::set visitedpkgs; + return set_requirements (deftrust, visitedpkgs); + } std::string action_caption () const; packageversion trustp (trusts const t) const Index: package_version.cc =================================================================== RCS file: /cvs/cygwin-apps/setup/package_version.cc,v retrieving revision 2.27 diff -u -w -p -r2.27 package_version.cc --- package_version.cc 6 Aug 2006 22:22:39 -0000 2.27 +++ package_version.cc 26 Jun 2008 22:31:45 -0000 @@ -385,7 +385,7 @@ checkForSatisfiable (PackageSpecificatio } static int -select (trusts deftrust, size_t depth, packagemeta *required, +select (trusts deftrust, set& visitedpkgs, packagemeta *required, const packageversion &aVersion) { /* preserve source */ @@ -395,11 +395,11 @@ select (trusts deftrust, size_t depth, p required->desired.pick (required->installed != required->desired); required->desired.sourcePackage ().pick (sourceticked); /* does this requirement have requirements? */ - return required->set_requirements (deftrust, depth + 1); + return required->set_requirements (deftrust, visitedpkgs); } static int -processOneDependency (trusts deftrust, size_t depth, +processOneDependency (trusts deftrust, set& visitedpkgs, PackageSpecification *spec) { /* TODO: add this to a set of packages to be offered to meet the @@ -411,7 +411,7 @@ processOneDependency (trusts deftrust, s packageversion trusted = required->trustp(deftrust); if (spec->satisfies (trusted)) { - return select (deftrust, depth, required, trusted); + return select (deftrust, visitedpkgs, required, trusted); } log (LOG_TIMESTAMP) << "Warning, the default trust level for package " @@ -426,17 +426,19 @@ processOneDependency (trusts deftrust, s /* assert ?! */ return 0; - return select (deftrust, depth, required, *v); + return select (deftrust, visitedpkgs, required, *v); } int -packageversion::set_requirements (trusts deftrust, size_t depth) +packageversion::set_requirements (trusts deftrust, set& visitedpkgs) { int changed = 0; vector *>::iterator dp = depends ()->begin(); - /* cheap test for too much recursion */ - if (depth > 5) - return changed; + packagedb db; + packagemeta * mypkg = db.findBinary(PackageSpecification(Name())); + if (visitedpkgs.find(mypkg) != visitedpkgs.end()) + return changed; /* already visited, so don't recurse into dependencies */ + visitedpkgs.insert(mypkg); /* mark as visited */ /* walk through each and clause */ while (dp != depends ()->end()) { @@ -464,7 +466,7 @@ packageversion::set_requirements (trusts requirement. (*i is the packagespec that can be satisfied.) */ ++dp; - changed += processOneDependency (deftrust, depth, *i) + 1; + changed += processOneDependency (deftrust, visitedpkgs, *i) + 1; continue; } /* check each or clause for an installable version */ @@ -473,7 +475,7 @@ packageversion::set_requirements (trusts { /* we found a package that can be installed to meet the requirement */ ++dp; - changed += processOneDependency (deftrust, depth, *i) + 1; + changed += processOneDependency (deftrust, visitedpkgs, *i) + 1; continue; } ++dp; Index: package_version.h =================================================================== RCS file: /cvs/cygwin-apps/setup/package_version.h,v retrieving revision 2.23 diff -u -w -p -r2.23 package_version.h --- package_version.h 17 Apr 2006 16:41:33 -0000 2.23 +++ package_version.h 26 Jun 2008 22:31:45 -0000 @@ -45,6 +45,7 @@ class CategoryList; #include "PackageTrust.h" #include "script.h" #include +#include typedef enum { @@ -69,6 +70,9 @@ typedef enum } package_type_t; +/* forward declarations */ +class packagemeta; + /* A wrapper class to be copied by value that references the same package. Nothing is virtual, because the wrapper cannot be inherited. @@ -139,7 +143,7 @@ public: void scan(); /* ensure that the depends clause is satisfied */ - int set_requirements (trusts deftrust, size_t depth = 0); + int set_requirements (trusts deftrust, std::set& visitedpkgs = std::set()); void addScript(Script const &); std::vector