diff options
author | Andy Cedilnik <andy.cedilnik@kitware.com> | 2007-04-11 19:13:05 (GMT) |
---|---|---|
committer | Andy Cedilnik <andy.cedilnik@kitware.com> | 2007-04-11 19:13:05 (GMT) |
commit | f9f1ccadb370b7b3466d491b1824104d81a15308 (patch) | |
tree | 8428b8e66ce907c5befa5b86fa3fb6773722e8c4 /Source/cmVariableWatchCommand.cxx | |
parent | 76e5344590f6259fcfc73d35e286509f9e260678 (diff) | |
download | CMake-f9f1ccadb370b7b3466d491b1824104d81a15308.zip CMake-f9f1ccadb370b7b3466d491b1824104d81a15308.tar.gz CMake-f9f1ccadb370b7b3466d491b1824104d81a15308.tar.bz2 |
ENH: Add variable watch command
Diffstat (limited to 'Source/cmVariableWatchCommand.cxx')
-rw-r--r-- | Source/cmVariableWatchCommand.cxx | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx new file mode 100644 index 0000000..8e83756 --- /dev/null +++ b/Source/cmVariableWatchCommand.cxx @@ -0,0 +1,136 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + 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 "cmVariableWatchCommand.h" + +#include "cmVariableWatch.h" + +//---------------------------------------------------------------------------- +static void cmVariableWatchCommandVariableAccessed( + const std::string& variable, int access_type, void* client_data, + const char* newValue, const cmMakefile* mf) +{ + cmVariableWatchCommand* command = static_cast<cmVariableWatchCommand*>(client_data); + command->VariableAccessed(variable, access_type, newValue, mf); +} + +//---------------------------------------------------------------------------- +cmVariableWatchCommand::cmVariableWatchCommand() +{ + this->InCallback = false; +} + +//---------------------------------------------------------------------------- +bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args) +{ + if ( args.size() < 1 ) + { + this->SetError("must be called with at least one argument."); + return false; + } + std::string variable = args[0]; + if ( args.size() > 1 ) + { + std::string command = args[1]; + this->Handlers[variable].Commands.push_back(args[1]); + } + if ( variable == "CMAKE_CURRENT_LIST_FILE" ) + { + cmOStringStream ostr; + ostr << "cannot be set on the variable: " << variable.c_str(); + this->SetError(ostr.str().c_str()); + return false; + } + + this->Makefile->GetCMakeInstance()->GetVariableWatch()->AddWatch( + variable, cmVariableWatchCommandVariableAccessed, this); + + return true; +} + +//---------------------------------------------------------------------------- +void cmVariableWatchCommand::VariableAccessed(const std::string& variable, + int access_type, const char* newValue, const cmMakefile* mf) +{ + if ( this->InCallback ) + { + return; + } + this->InCallback = true; + + cmListFileFunction newLFF; + cmVariableWatchCommandHandler *handler = &this->Handlers[variable]; + cmVariableWatchCommandHandler::VectorOfCommands::iterator it; + cmListFileArgument arg; + bool processed = false; + const char* accessString = cmVariableWatch::GetAccessAsString(access_type); + const char* currentListFile = mf->GetDefinition("CMAKE_CURRENT_LIST_FILE"); + + /// Ultra bad!! + cmMakefile* makefile = const_cast<cmMakefile*>(mf); + + std::string stack = makefile->GetProperty("LISTFILE_STACK"); + for ( it = handler->Commands.begin(); it != handler->Commands.end(); + ++ it ) + { + std::string command = *it; + newLFF.Arguments.clear(); + newLFF.Arguments.push_back(cmListFileArgument(variable, true, "unknown", 9999)); + newLFF.Arguments.push_back(cmListFileArgument(accessString, true, "unknown", 9999)); + newLFF.Arguments.push_back(cmListFileArgument(newValue?newValue:"", true, "unknown", 9999)); + newLFF.Arguments.push_back(cmListFileArgument(currentListFile, true, "unknown", 9999)); + newLFF.Arguments.push_back(cmListFileArgument(stack, true, "unknown", 9999)); + newLFF.Name = command; + newLFF.FilePath = "Some weird path"; + newLFF.Line = 9999; + if(!makefile->ExecuteCommand(newLFF)) + { + arg.FilePath = "Unknown"; + arg.Line = 0; + cmOStringStream error; + error << "Error in cmake code at\n" + << arg.FilePath << ":" << arg.Line << ":\n" + << "A command failed during the invocation of callback\"" + << command << "\"."; + cmSystemTools::Error(error.str().c_str()); + this->InCallback = false; + return; + } + processed = true; + } + if ( !processed ) + { + cmOStringStream msg; + msg << "* Variable \"" << variable.c_str() << "\" was accessed using " + << accessString << " in: " << currentListFile << std::endl; + msg << " The value of the variable: \"" << newValue << "\"" << std::endl; + msg << " The list file stack: " << stack.c_str(); + cmSystemTools::Message(msg.str().c_str()); + std::vector<std::string> vars = makefile->GetDefinitions(); + cmOStringStream msg2; + size_t cc; + for ( cc = 0; cc < vars.size(); cc ++ ) + { + if ( vars[cc] == variable ) + { + continue; + } + msg2 << vars[cc] << " = \"" << makefile->GetDefinition(vars[cc].c_str()) << "\"" << std::endl; + } + //cmSystemTools::Message(msg2.str().c_str()); + } + this->InCallback = false; +} |