From b2f041f6a899b2592477c98da0d060cc7c983a91 Mon Sep 17 00:00:00 2001 From: David Cole Date: Wed, 30 Jul 2008 13:28:17 -0400 Subject: [PATCH] BUG: Fix issue #7414 - do not crash when given components with circular dependencies. Thanks to Doug Gregor for the patch. --- Source/CPack/cmCPackPackageMakerGenerator.cxx | 27 +++++++++++++++---- Source/CPack/cmCPackPackageMakerGenerator.h | 7 +++-- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx index d35e76467..049a6e450 100644 --- a/Source/CPack/cmCPackPackageMakerGenerator.cxx +++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx @@ -829,8 +829,10 @@ cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponent& component, // on (B and A), while selecting something that depends on C--either D // or E--will automatically cause C to get selected. out << "selected=\"my.choice.selected"; - AddDependencyAttributes(component, out); - AddReverseDependencyAttributes(component, out); + std::set visited; + AddDependencyAttributes(component, visited, out); + visited.clear(); + AddReverseDependencyAttributes(component, visited, out); out << "\""; } out << ">" << std::endl; @@ -868,15 +870,23 @@ cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponent& component, //---------------------------------------------------------------------- void cmCPackPackageMakerGenerator:: -AddDependencyAttributes(const cmCPackComponent& component, cmOStringStream& out) +AddDependencyAttributes(const cmCPackComponent& component, + std::set& visited, + cmOStringStream& out) { + if (visited.find(&component) != visited.end()) + { + return; + } + visited.insert(&component); + std::vector::const_iterator dependIt; for (dependIt = component.Dependencies.begin(); dependIt != component.Dependencies.end(); ++dependIt) { out << " && choices['" << (*dependIt)->Name << "Choice'].selected"; - AddDependencyAttributes(**dependIt, out); + AddDependencyAttributes(**dependIt, visited, out); } } @@ -884,15 +894,22 @@ AddDependencyAttributes(const cmCPackComponent& component, cmOStringStream& out) void cmCPackPackageMakerGenerator:: AddReverseDependencyAttributes(const cmCPackComponent& component, + std::set& visited, cmOStringStream& out) { + if (visited.find(&component) != visited.end()) + { + return; + } + visited.insert(&component); + std::vector::const_iterator dependIt; for (dependIt = component.ReverseDependencies.begin(); dependIt != component.ReverseDependencies.end(); ++dependIt) { out << " || choices['" << (*dependIt)->Name << "Choice'].selected"; - AddReverseDependencyAttributes(**dependIt, out); + AddReverseDependencyAttributes(**dependIt, visited, out); } } diff --git a/Source/CPack/cmCPackPackageMakerGenerator.h b/Source/CPack/cmCPackPackageMakerGenerator.h index 228e099ce..ea835b759 100644 --- a/Source/CPack/cmCPackPackageMakerGenerator.h +++ b/Source/CPack/cmCPackPackageMakerGenerator.h @@ -88,12 +88,15 @@ protected: // Subroutine of WriteDistributionFile that writes out the // dependency attributes for inter-component dependencies. void AddDependencyAttributes(const cmCPackComponent& component, + std::set& visited, cmOStringStream& out); // Subroutine of WriteDistributionFile that writes out the // reverse dependency attributes for inter-component dependencies. - void AddReverseDependencyAttributes(const cmCPackComponent& component, - cmOStringStream& out); + void + AddReverseDependencyAttributes(const cmCPackComponent& component, + std::set& visited, + cmOStringStream& out); // Generates XML that encodes the hierarchy of component groups and // their components in a form that can be used by distribution