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 7 Aug 2010 05:31:35 -0000 @@ -24,6 +24,7 @@ #include #include #include +#include #include "prereq.h" #include "dialog.h" @@ -150,47 +151,53 @@ 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) + + // packages that need to be checked for dependencies + queue todo; + + // 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 ((*p)->desired) + todo.push (*p); + } + + // churn through the worklist + while (!todo.empty ()) { - // if the package is installed or selected to be installed... - if ((*n)->desired) + packagemeta *pack = todo.front (); + todo.pop (); + + // go throught the package's dependencies + for (vector *>::iterator d = + pack->curr.depends ()->begin (); + d != pack->curr.depends ()->end (); ++d) { - // loop through each dependency - for (vector *>::iterator i = - (*n)->desired.depends ()->begin (); - i != (*n)->desired.depends ()->end (); ++i) + // 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 && !(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)) + // we've got an unmet dependency + if (unmet.find(dep) == unmet.end()) { - // dependency met - } - else - { - foundUnmet = true; - unmet[pack].push_back (*n); + // newly found dependency: add to worklist + todo.push(dep); } + unmet[dep].push_back (pack); } } } - - return !foundUnmet; + + return unmet.empty(); } /* Formats 'unmet' as a string for display to the user. */