[cmake-commits] andy committed cmCommands.cxx 1.109 1.110 cmFindPackageCommand.cxx 1.20 1.21 cmMakefile.cxx 1.382 1.383 cmVariableWatch.cxx 1.4 1.5 cmVariableWatch.h 1.8 1.9 cmake.cxx 1.290 1.291 cmVariableWatchCommand.cxx NONE 1.1 cmVariableWatchCommand.h NONE 1.1

cmake-commits at cmake.org cmake-commits at cmake.org
Wed Apr 11 15:13:07 EDT 2007


Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv12459/Source

Modified Files:
	cmCommands.cxx cmFindPackageCommand.cxx cmMakefile.cxx 
	cmVariableWatch.cxx cmVariableWatch.h cmake.cxx 
Added Files:
	cmVariableWatchCommand.cxx cmVariableWatchCommand.h 
Log Message:
ENH: Add variable watch command


Index: cmCommands.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmCommands.cxx,v
retrieving revision 1.109
retrieving revision 1.110
diff -u -d -r1.109 -r1.110
--- cmCommands.cxx	3 Mar 2007 17:16:35 -0000	1.109
+++ cmCommands.cxx	11 Apr 2007 19:13:05 -0000	1.110
@@ -52,6 +52,8 @@
 #include "cmUseMangledMesaCommand.cxx"
 #include "cmUtilitySourceCommand.cxx"
 #include "cmVariableRequiresCommand.cxx"
+#include "cmVariableWatchCommand.cxx"
+
 #include "cmWhileCommand.cxx"
 #include "cmWriteFileCommand.cxx"
 
@@ -105,6 +107,7 @@
   commands.push_back(new cmUseMangledMesaCommand);
   commands.push_back(new cmUtilitySourceCommand);
   commands.push_back(new cmVariableRequiresCommand);
+  commands.push_back(new cmVariableWatchCommand);
   commands.push_back(new cmWhileCommand);
   commands.push_back(new cmWriteFileCommand);
 #endif

Index: cmVariableWatch.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmVariableWatch.cxx,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- cmVariableWatch.cxx	15 Mar 2006 16:02:07 -0000	1.4
+++ cmVariableWatch.cxx	11 Apr 2007 19:13:05 -0000	1.5
@@ -16,6 +16,25 @@
 =========================================================================*/
 #include "cmVariableWatch.h"
 
+static const char* const cmVariableWatchAccessStrings[] =
+{
+    "READ_ACCESS",
+    "UNKNOWN_READ_ACCESS",
+    "ALLOWED_UNKNOWN_READ_ACCESS",
+    "MODIFIED_ACCESS",
+    "REMOVED_ACCESS",
+    "NO_ACCESS"
+};
+
+const char* cmVariableWatch::GetAccessAsString(int access_type)
+{
+  if ( access_type < 0 || access_type >= cmVariableWatch::NO_ACCESS )
+    {
+    return "NO_ACCESS";
+    }
+  return cmVariableWatchAccessStrings[access_type];
+}
+
 cmVariableWatch::cmVariableWatch()
 {
 }
@@ -60,7 +79,9 @@
 }
 
 void  cmVariableWatch::VariableAccessed(const std::string& variable, 
-                                        int access_type) const
+                                        int access_type,
+                                        const char* newValue,
+                                        const cmMakefile* mf) const
 {
   cmVariableWatch::StringToVectorOfPairs::const_iterator mit = 
     this->WatchMap.find(variable);
@@ -70,7 +91,8 @@
     cmVariableWatch::VectorOfPairs::const_iterator it;
     for ( it = vp->begin(); it != vp->end(); it ++ )
       {
-      it->Method(variable, access_type, it->ClientData);
+      it->Method(variable, access_type, it->ClientData,
+        newValue, mf);
       }
     }
 }

Index: cmake.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmake.cxx,v
retrieving revision 1.290
retrieving revision 1.291
diff -u -d -r1.290 -r1.291
--- cmake.cxx	12 Mar 2007 20:10:00 -0000	1.290
+++ cmake.cxx	11 Apr 2007 19:13:05 -0000	1.291
@@ -88,7 +88,7 @@
 #include <memory> // auto_ptr
 
 void cmNeedBackwardsCompatibility(const std::string& variable,
-                                  int access_type, void* )
+  int access_type, void*, const char*, const cmMakefile*)
 {
 #ifdef CMAKE_BUILD_WITH_CMAKE
   if (access_type == cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS)

--- NEW FILE: cmVariableWatchCommand.h ---
/*=========================================================================

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmVariableWatchCommand.h,v $
  Language:  C++
  Date:      $Date: 2007/04/11 19:13:05 $
  Version:   $Revision: 1.1 $

  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.

=========================================================================*/
#ifndef cmVariableWatchCommand_h
#define cmVariableWatchCommand_h

#include "cmCommand.h"

class cmVariableWatchCommandHandler
{
public:
  typedef std::vector<std::string> VectorOfCommands;
  VectorOfCommands Commands;
};

/** \class cmVariableWatchCommand
 * \brief Watch when the variable changes and invoke command
 *
 */
class cmVariableWatchCommand : public cmCommand
{
public:
  /**
   * This is a virtual constructor for the command.
   */
  virtual cmCommand* Clone() 
    {
    return new cmVariableWatchCommand;
    }

  //! Default constructor
  cmVariableWatchCommand();

  /**
   * This is called when the command is first encountered in
   * the CMakeLists.txt file.
   */
  virtual bool InitialPass(std::vector<std::string> const& args);

  /**
   * This determines if the command is invoked when in script mode.
   */
  virtual bool IsScriptable() { return true; }

  /**
   * The name of the command as specified in CMakeList.txt.
   */
  virtual const char* GetName() { return "VARIABLE_WATCH";}

  /**
   * Succinct documentation.
   */
  virtual const char* GetTerseDocumentation() 
    {
    return "Watch the CMake variable for change.";
    }
  
  /**
   * More documentation.
   */
  virtual const char* GetFullDocumentation()
    {
    return
      "  VARIABLE_WATCH(<variable name> [<command to execute>])\n"
      "If the specified variable changes, the message will be printed about "
      "the variable being changed. If the command is spceified, the command "
      "will be executed. The command will receive the following arguments:"
      " COMMAND(<variable> <access> <value> <current list file> <stack>)";
    }
  
  cmTypeMacro(cmVariableWatchCommand, cmCommand);

  void VariableAccessed(const std::string& variable, int access_type,
    const char* newValue, const cmMakefile* mf);

protected:
  std::map<std::string, cmVariableWatchCommandHandler> Handlers;

  bool InCallback;
};


#endif



--- NEW FILE: cmVariableWatchCommand.cxx ---
/*=========================================================================

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmVariableWatchCommand.cxx,v $
  Language:  C++
  Date:      $Date: 2007/04/11 19:13:05 $
  Version:   $Revision: 1.1 $

  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;
}

Index: cmVariableWatch.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmVariableWatch.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- cmVariableWatch.h	15 Mar 2006 16:02:07 -0000	1.8
+++ cmVariableWatch.h	11 Apr 2007 19:13:05 -0000	1.9
@@ -19,6 +19,8 @@
 
 #include "cmStandardIncludes.h"
 
+class cmMakefile;
+
 /** \class cmVariableWatch
  * \brief Helper class for watching of variable accesses.
  *
@@ -28,7 +30,7 @@
 {
 public:
   typedef void (*WatchMethod)(const std::string& variable, int access_type,
-                              void* client_data);
+    void* client_data, const char* newValue, const cmMakefile* mf);
 
   cmVariableWatch();
   ~cmVariableWatch();
@@ -43,20 +45,26 @@
   /**
    * This method is called when variable is accessed
    */
-  void VariableAccessed(const std::string& variable, int access_type) const;
+  void VariableAccessed(const std::string& variable, int access_type,
+    const char* newValue, const cmMakefile* mf) const;
 
   /**
    * Different access types.
    */
   enum
     {
-      VARIABLE_READ_ACCESS,
-      UNKNOWN_VARIABLE_READ_ACCESS,
-      ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS,
-      VARIABLE_MODIFIED_ACCESS,
-      VARIABLE_REMOVED_ACCESS,
-      NO_ACCESS
+    VARIABLE_READ_ACCESS = 0,
+    UNKNOWN_VARIABLE_READ_ACCESS,
+    ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS,
+    VARIABLE_MODIFIED_ACCESS,
+    VARIABLE_REMOVED_ACCESS,
+    NO_ACCESS
     };
+
+  /**
+   * Return the access as string
+   */
+  static const char* GetAccessAsString(int access_type);
   
 protected:
   struct Pair

Index: cmFindPackageCommand.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmFindPackageCommand.cxx,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- cmFindPackageCommand.cxx	26 Oct 2006 15:39:53 -0000	1.20
+++ cmFindPackageCommand.cxx	11 Apr 2007 19:13:05 -0000	1.21
@@ -22,8 +22,10 @@
 #endif
 
 void cmFindPackageNeedBackwardsCompatibility(const std::string& variable,
-                                             int access_type, void* )
+  int access_type, void*, const char* newValue,
+  const cmMakefile*)
 {
+  (void)newValue;
 #ifdef CMAKE_BUILD_WITH_CMAKE
   if(access_type == cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS)
     {

Index: cmMakefile.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmMakefile.cxx,v
retrieving revision 1.382
retrieving revision 1.383
diff -u -d -r1.382 -r1.383
--- cmMakefile.cxx	5 Apr 2007 13:19:29 -0000	1.382
+++ cmMakefile.cxx	11 Apr 2007 19:13:05 -0000	1.383
@@ -1215,7 +1215,9 @@
   if ( vv )
     {
     vv->VariableAccessed(this->TemporaryDefinitionKey, 
-                         cmVariableWatch::VARIABLE_MODIFIED_ACCESS);
+                         cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
+                         value,
+                         this);
     }
 #endif
 }
@@ -1275,7 +1277,8 @@
   cmVariableWatch* vv = this->GetVariableWatch();
   if ( vv )
     {
-    vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS);
+    vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
+      value?"ON":"OFF", this);
     }
 #endif
 }
@@ -1304,7 +1307,8 @@
   cmVariableWatch* vv = this->GetVariableWatch();
   if ( vv )
     {
-    vv->VariableAccessed(name, cmVariableWatch::VARIABLE_REMOVED_ACCESS);
+    vv->VariableAccessed(name, cmVariableWatch::VARIABLE_REMOVED_ACCESS,
+      0, this);
     }
 #endif
 }
@@ -1649,7 +1653,8 @@
     {
     if ( def )
       {
-      vv->VariableAccessed(name, cmVariableWatch::VARIABLE_READ_ACCESS);
+      vv->VariableAccessed(name, cmVariableWatch::VARIABLE_READ_ACCESS,
+        def, this);
       }
     else 
       {
@@ -1659,13 +1664,13 @@
       if (pos2 != this->Definitions.end() && 
           cmSystemTools::IsOn((*pos2).second.c_str())) 
         {
-        vv->VariableAccessed
-          (name, cmVariableWatch::ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS);
+        vv->VariableAccessed(name,
+          cmVariableWatch::ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS, def, this);
         }
       else
         {
-        vv->VariableAccessed(name, cmVariableWatch::
-                             UNKNOWN_VARIABLE_READ_ACCESS);
+        vv->VariableAccessed(name,
+          cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS, def, this);
         }
       }
     }



More information about the Cmake-commits mailing list