cmVariableWatchCommand.cxx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmVariableWatchCommand.h"
  11. #include "cmVariableWatch.h"
  12. //----------------------------------------------------------------------------
  13. static void cmVariableWatchCommandVariableAccessed(
  14. const std::string& variable, int access_type, void* client_data,
  15. const char* newValue, const cmMakefile* mf)
  16. {
  17. cmVariableWatchCommand* command
  18. = static_cast<cmVariableWatchCommand*>(client_data);
  19. command->VariableAccessed(variable, access_type, newValue, mf);
  20. }
  21. //----------------------------------------------------------------------------
  22. cmVariableWatchCommand::cmVariableWatchCommand()
  23. {
  24. this->InCallback = false;
  25. }
  26. //----------------------------------------------------------------------------
  27. bool cmVariableWatchCommand
  28. ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
  29. {
  30. if ( args.size() < 1 )
  31. {
  32. this->SetError("must be called with at least one argument.");
  33. return false;
  34. }
  35. std::string variable = args[0];
  36. if ( args.size() > 1 )
  37. {
  38. std::string command = args[1];
  39. this->Handlers[variable].Commands.push_back(args[1]);
  40. }
  41. if ( variable == "CMAKE_CURRENT_LIST_FILE" )
  42. {
  43. cmOStringStream ostr;
  44. ostr << "cannot be set on the variable: " << variable.c_str();
  45. this->SetError(ostr.str().c_str());
  46. return false;
  47. }
  48. this->Makefile->GetCMakeInstance()->GetVariableWatch()->AddWatch(
  49. variable, cmVariableWatchCommandVariableAccessed, this);
  50. return true;
  51. }
  52. //----------------------------------------------------------------------------
  53. void cmVariableWatchCommand::VariableAccessed(const std::string& variable,
  54. int access_type, const char* newValue, const cmMakefile* mf)
  55. {
  56. if ( this->InCallback )
  57. {
  58. return;
  59. }
  60. this->InCallback = true;
  61. cmListFileFunction newLFF;
  62. cmVariableWatchCommandHandler *handler = &this->Handlers[variable];
  63. cmVariableWatchCommandHandler::VectorOfCommands::iterator it;
  64. cmListFileArgument arg;
  65. bool processed = false;
  66. const char* accessString = cmVariableWatch::GetAccessAsString(access_type);
  67. const char* currentListFile = mf->GetDefinition("CMAKE_CURRENT_LIST_FILE");
  68. /// Ultra bad!!
  69. cmMakefile* makefile = const_cast<cmMakefile*>(mf);
  70. std::string stack = makefile->GetProperty("LISTFILE_STACK");
  71. for ( it = handler->Commands.begin(); it != handler->Commands.end();
  72. ++ it )
  73. {
  74. std::string command = *it;
  75. newLFF.Arguments.clear();
  76. newLFF.Arguments.push_back(
  77. cmListFileArgument(variable, cmListFileArgument::Quoted,
  78. "unknown", 9999));
  79. newLFF.Arguments.push_back(
  80. cmListFileArgument(accessString, cmListFileArgument::Quoted,
  81. "unknown", 9999));
  82. newLFF.Arguments.push_back(
  83. cmListFileArgument(newValue?newValue:"", cmListFileArgument::Quoted,
  84. "unknown", 9999));
  85. newLFF.Arguments.push_back(
  86. cmListFileArgument(currentListFile, cmListFileArgument::Quoted,
  87. "unknown", 9999));
  88. newLFF.Arguments.push_back(
  89. cmListFileArgument(stack, cmListFileArgument::Quoted,
  90. "unknown", 9999));
  91. newLFF.Name = command;
  92. newLFF.FilePath = "Some weird path";
  93. newLFF.Line = 9999;
  94. cmExecutionStatus status;
  95. if(!makefile->ExecuteCommand(newLFF,status))
  96. {
  97. arg.FilePath = "Unknown";
  98. arg.Line = 0;
  99. cmOStringStream error;
  100. error << "Error in cmake code at\n"
  101. << arg.FilePath << ":" << arg.Line << ":\n"
  102. << "A command failed during the invocation of callback\""
  103. << command << "\".";
  104. cmSystemTools::Error(error.str().c_str());
  105. this->InCallback = false;
  106. return;
  107. }
  108. processed = true;
  109. }
  110. if ( !processed )
  111. {
  112. cmOStringStream msg;
  113. msg << "Variable \"" << variable.c_str() << "\" was accessed using "
  114. << accessString << " with value \"" << newValue << "\".";
  115. makefile->IssueMessage(cmake::LOG, msg.str());
  116. }
  117. this->InCallback = false;
  118. }