Index: prereq.cc =================================================================== RCS file: /cvs/cygwin-apps/setup/prereq.cc,v retrieving revision 2.3 diff -u -r2.3 prereq.cc --- prereq.cc 13 Dec 2009 19:23:43 -0000 2.3 +++ prereq.cc 6 Aug 2010 21:29:19 -0000 @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include "prereq.h" #include "dialog.h" @@ -150,47 +152,56 @@ PrereqChecker::isMet () { packagedb db; - bool foundUnmet = false; // unmet is static - clear it each time this is called unmet.clear (); - - // loop through each package - for (vector ::iterator n = db.packages.begin (); - n != db.packages.end (); ++n) + + queue todo; + set known; + + // go through all packages, adding desired ones to the initial work list + for (vector ::iterator p = db.packages.begin (); + p != db.packages.end (); ++p) { - // if the package is installed or selected to be installed... - if ((*n)->desired) + if ((*p)->desired) { - // loop through each dependency - for (vector *>::iterator i = - (*n)->desired.depends ()->begin (); - i != (*n)->desired.depends ()->end (); ++i) + todo.push (*p); + known.insert (*p); + } + } + + while (!todo.empty ()) + { + packagemeta *pack = todo.front (); + todo.pop (); + for (vector *>::iterator d = + pack->curr.depends ()->begin (); + d != pack->curr.depends ()->end (); ++d) + { + // XXX: the following assumes that there is only a single + // node in each OR clause, which is currently the case. + // if setup is ever pushed to use AND/OR in "depends:" + // lines this will have to be updated + PackageSpecification *dep_spec = (*d)->at(0); + packagemeta *dep = db.findBinary (*dep_spec); + if (!dep) + continue; // asking for a package that doesn't exist - ignore + + if (dep->desired && dep_spec->satisfies (dep->desired)) { - // XXX: the following assumes that there is only a single - // node in each OR clause, which is currently the case. - // if setup is ever pushed to use AND/OR in "depends:" - // lines this will have to be updated - PackageSpecification *spec = (*i)->at(0); - - packagemeta *pack = db.findBinary (*spec); - if (!pack) - continue; // asking for a package that doesn't exist - error? - - if (pack->desired && spec->satisfies (pack->desired)) - { - // dependency met - } - else - { - foundUnmet = true; - unmet[pack].push_back (*n); - } + // dependency met + } + else + { + unmet[dep].push_back (pack); + bool unknown = known.insert (dep).second; + if (unknown) + todo.push (dep); } } } - - return !foundUnmet; + + return unmet.empty(); } /* Formats 'unmet' as a string for display to the user. */