/*========================================================================= Program: CMake - Cross-Platform Makefile Generator Module: $RCSfile: cmCommandArgumentsHelper.cxx,v $ Language: C++ Date: $Date: 2007-08-23 20:13:15 $ Version: $Revision: 1.4 $ Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "cmCommandArgumentsHelper.h" cmCommandArgument::cmCommandArgument(cmCommandArgumentsHelper* args, const char* key, cmCommandArgumentGroup* group) :Key(key) ,Group(group) ,WasActive(false) ,ArgumentsBeforeEmpty(true) ,CurrentIndex(0) { if (args!=0) { args->AddArgument(this); } if (this->Group!=0) { this->Group->ContainedArguments.push_back(this); } } void cmCommandArgument::Reset() { this->WasActive =false; this->CurrentIndex = 0; this->DoReset(); } void cmCommandArgument::Follows(const cmCommandArgument* arg) { this->ArgumentsBeforeEmpty = false; this->ArgumentsBefore.insert(arg); } void cmCommandArgument::FollowsGroup(const cmCommandArgumentGroup* group) { if (group!=0) { this->ArgumentsBeforeEmpty = false; for(std::vector::const_iterator argIt= group->ContainedArguments.begin(); argIt != group->ContainedArguments.end(); ++argIt) { this->ArgumentsBefore.insert(*argIt); } } } bool cmCommandArgument::MayFollow(const cmCommandArgument* current) const { if (this->ArgumentsBeforeEmpty) { return true; } std::set::const_iterator argIt = this->ArgumentsBefore.find(current); if (argIt != this->ArgumentsBefore.end()) { return true; } return false; } bool cmCommandArgument::KeyMatches(const std::string& key) const { if ((this->Key==0) || (this->Key[0]=='\0')) { return true; } return (key==this->Key); } void cmCommandArgument::ApplyOwnGroup() { if (this->Group!=0) { for (std::vector::const_iterator it = this->Group->ContainedArguments.begin(); it != this->Group->ContainedArguments.end(); ++it) { if(*it != this) { this->ArgumentsBefore.insert(*it); } } } } void cmCommandArgument::Activate() { this->WasActive = true; this->CurrentIndex = 0; } bool cmCommandArgument::Consume(const std::string& arg) { bool res=this->DoConsume(arg, this->CurrentIndex); this->CurrentIndex++; return res; } cmCAStringVector::cmCAStringVector(cmCommandArgumentsHelper* args, const char* key, cmCommandArgumentGroup* group) :cmCommandArgument(args, key, group) ,Ignore(0) { if ((key==0) || (*key==0)) { this->DataStart = 0; } else { this->DataStart = 1; } } bool cmCAStringVector::DoConsume(const std::string& arg,unsigned int index) { if (index >= this->DataStart) { if ((this->Ignore==0) || (arg != this->Ignore)) { this->Vector.push_back(arg); } } return false; } void cmCAStringVector::DoReset() { this->Vector.clear(); } cmCAString::cmCAString(cmCommandArgumentsHelper* args, const char* key, cmCommandArgumentGroup* group) :cmCommandArgument(args, key, group) { if ((key==0) || (*key==0)) { this->DataStart = 0; } else { this->DataStart = 1; } } bool cmCAString::DoConsume(const std::string& arg, unsigned int index) { if (index == this->DataStart) { this->String = arg; } return index >= this->DataStart; } void cmCAString::DoReset() { this->String = this->DefaultString; } cmCAEnabler::cmCAEnabler(cmCommandArgumentsHelper* args, const char* key, cmCommandArgumentGroup* group) :cmCommandArgument(args, key, group) ,Enabled(false) {} bool cmCAEnabler::DoConsume(const std::string&, unsigned int index) { if (index==0) { this->Enabled = true; } return true; } void cmCAEnabler::DoReset() { this->Enabled = false; } cmCADisabler::cmCADisabler(cmCommandArgumentsHelper* args, const char* key, cmCommandArgumentGroup* group) :cmCommandArgument(args, key, group) ,Enabled(true) {} bool cmCADisabler::DoConsume(const std::string&, unsigned int index) { if (index==0) { this->Enabled = false; } return true; } void cmCADisabler::DoReset() { this->Enabled = true; } void cmCommandArgumentGroup::Follows(const cmCommandArgument* arg) { for(std::vector::iterator it = this->ContainedArguments.begin(); it != this->ContainedArguments.end(); ++it) { (*it)->Follows(arg); } } void cmCommandArgumentGroup::FollowsGroup(const cmCommandArgumentGroup* group) { for(std::vector::iterator it = this->ContainedArguments.begin(); it != this->ContainedArguments.end(); ++it) { (*it)->FollowsGroup(group); } } void cmCommandArgumentsHelper::Parse(const std::vector* args, std::vector* unconsumedArgs) { if(args==0) { return; } for(std::vector::iterator argIt = this->Arguments.begin(); argIt != this->Arguments.end(); ++argIt) { (*argIt)->ApplyOwnGroup(); (*argIt)->Reset(); } cmCommandArgument* activeArgument = 0; const cmCommandArgument* previousArgument = 0; for(std::vector::const_iterator it = args->begin(); it != args->end(); ++it) { for(std::vector::iterator argIt = this->Arguments.begin(); argIt != this->Arguments.end(); ++argIt) { if ((*argIt)->KeyMatches(*it) && ((*argIt)->MayFollow(previousArgument))) { activeArgument = *argIt; activeArgument->Activate(); break; } } if (activeArgument) { bool argDone = activeArgument->Consume(*it); previousArgument = activeArgument; if (argDone) { activeArgument = 0; } } else { if (unconsumedArgs!=0) { unconsumedArgs->push_back(*it); } } } } void cmCommandArgumentsHelper::AddArgument(cmCommandArgument* arg) { this->Arguments.push_back(arg); }