[cmake-commits] king committed cmBootstrapCommands.cxx 1.20 1.21 cmSetPropertiesCommand.cxx 1.9 NONE cmSetPropertiesCommand.h 1.6 NONE cmSetPropertyCommand.cxx NONE 1.1 cmSetPropertyCommand.h NONE 1.1

cmake-commits at cmake.org cmake-commits at cmake.org
Thu Jan 17 15:54:52 EST 2008


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

Modified Files:
	cmBootstrapCommands.cxx 
Added Files:
	cmSetPropertyCommand.cxx cmSetPropertyCommand.h 
Removed Files:
	cmSetPropertiesCommand.cxx cmSetPropertiesCommand.h 
Log Message:
ENH: Rename SET_PROPERITES command to SET_PROPERTY and give it a more powerful signature.


--- cmSetPropertiesCommand.h DELETED ---

--- cmSetPropertiesCommand.cxx DELETED ---

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

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmSetPropertyCommand.h,v $
  Language:  C++
  Date:      $Date: 2008/01/17 20:54:49 $
  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 cmSetsPropertiesCommand_h
#define cmSetsPropertiesCommand_h

#include "cmCommand.h"

class cmSetPropertyCommand : public cmCommand
{
public:
  cmSetPropertyCommand();

  virtual cmCommand* Clone()
    {
      return new cmSetPropertyCommand;
    }

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

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

  /**
   * Succinct documentation.
   */
  virtual const char* GetTerseDocumentation()
    {
    return "Set a named property in a given scope.";
    }

  /**
   * Longer documentation.
   */
  virtual const char* GetFullDocumentation()
    {
      return
        "  set_property(<GLOBAL                            |\n"
        "                DIRECTORY [dir]                   |\n"
        "                TARGET    [target1 [target2 ...]] |\n"
        "                SOURCE    [src1 [src2 ...]]       |\n"
        "                TEST      [test1 [test2 ...]]>\n"
        "               [APPEND]\n"
        "               PROPERTY <name> [value1 [value2 ...]])\n"
        "Set one property on zero or more objects of a scope.  "
        "The first argument determines the scope in which the property "
        "is set.  It must be one of the following:\n"
        "GLOBAL scope is unique and does not accept a name.\n"
        "DIRECTORY scope defaults to the current directory but another "
        "directory (already processed by CMake) may be named by full or "
        "relative path.\n"
        "TARGET scope may name zero or more existing targets.\n"
        "SOURCE scope may name zero or more source files.\n"
        "TEST scope may name zero or more existing tests.\n"
        "The required PROPERTY option is immediately followed by the name "
        "of the property to set.  Remaining arguments are used to "
        "compose the property value in the form of a semicolon-separated "
        "list.  "
        "If the APPEND option is given the list is appended to any "
        "existing property value."
        ;
    }

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

  cmTypeMacro(cmSetPropertyCommand, cmCommand);

private:
  std::set<cmStdString> Names;
  std::string PropertyName;
  std::string PropertyValue;
  bool AppendMode;

  // Implementation of value construction.
  bool ConstructValue(std::string& value, const char* old);

  // Implementation of each property type.
  bool HandleGlobalMode();
  bool HandleDirectoryMode();
  bool HandleTargetMode();
  bool HandleTarget(cmTarget* target);
  bool HandleSourceMode();
  bool HandleSource(cmSourceFile* sf);
  bool HandleTestMode();
  bool HandleTest(cmTest* test);
};



#endif

Index: cmBootstrapCommands.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmBootstrapCommands.cxx,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- cmBootstrapCommands.cxx	17 Jan 2008 14:02:31 -0000	1.20
+++ cmBootstrapCommands.cxx	17 Jan 2008 20:54:49 -0000	1.21
@@ -72,7 +72,7 @@
 #include "cmProjectCommand.cxx"
 #include "cmRaiseScopeCommand.cxx"
 #include "cmSetCommand.cxx"
-#include "cmSetPropertiesCommand.cxx"
+#include "cmSetPropertyCommand.cxx"
 #include "cmSetSourceFilesPropertiesCommand.cxx"
 #include "cmSetTargetPropertiesCommand.cxx"
 #include "cmSetTestsPropertiesCommand.cxx"
@@ -132,7 +132,7 @@
   commands.push_back(new cmProjectCommand);
   commands.push_back(new cmRaiseScopeCommand);
   commands.push_back(new cmSetCommand);
-  commands.push_back(new cmSetPropertiesCommand);
+  commands.push_back(new cmSetPropertyCommand);
   commands.push_back(new cmSetSourceFilesPropertiesCommand);
   commands.push_back(new cmSetTargetPropertiesCommand);
   commands.push_back(new cmSetTestsPropertiesCommand);

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

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmSetPropertyCommand.cxx,v $
  Language:  C++
  Date:      $Date: 2008/01/17 20:54:49 $
  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 "cmSetPropertyCommand.h"
#include "cmSetTargetPropertiesCommand.h"
#include "cmSetTestsPropertiesCommand.h"
#include "cmSetSourceFilesPropertiesCommand.h"

//----------------------------------------------------------------------------
cmSetPropertyCommand::cmSetPropertyCommand()
{
  this->AppendMode = false;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::InitialPass(std::vector<std::string> const& args)
{
  if(args.size() < 2 )
    {
    this->SetError("called with incorrect number of arguments");
    return false;
    }

  // Get the scope on which to set the property.
  std::vector<std::string>::const_iterator arg = args.begin();
  cmProperty::ScopeType scope;
  if(*arg == "GLOBAL")
    {
    scope = cmProperty::GLOBAL;
    }
  else if(*arg == "DIRECTORY")
    {
    scope = cmProperty::DIRECTORY;
    }
  else if(*arg == "TARGET")
    {
    scope = cmProperty::TARGET;
    }
  else if(*arg == "SOURCE")
    {
    scope = cmProperty::SOURCE_FILE;
    }
  else if(*arg == "TEST")
    {
    scope = cmProperty::TEST;
    }
  else
    {
    cmOStringStream e;
    e << "given invalid scope " << *arg << ".  "
      << "Valid scopes are GLOBAL, DIRECTORY, TARGET, SOURCE, TEST.";
    this->SetError(e.str().c_str());
    return false;
    }

  // Parse the rest of the arguments up to the values.
  enum Doing { DoingNone, DoingNames, DoingProperty, DoingValues };
  Doing doing = DoingNames;
  const char* sep = "";
  for(++arg; arg != args.end(); ++arg)
    {
    if(*arg == "PROPERTY")
      {
      doing = DoingProperty;
      }
    else if(*arg == "APPEND")
      {
      doing = DoingNone;
      this->AppendMode = true;
      }
    else if(doing == DoingNames)
      {
      this->Names.insert(*arg);
      }
    else if(doing == DoingProperty)
      {
      this->PropertyName = *arg;
      doing = DoingValues;
      }
    else if(doing == DoingValues)
      {
      this->PropertyValue += sep;
      sep = ";";
      this->PropertyValue += *arg;
      }
    else
      {
      cmOStringStream e;
      e << "given invalid argument \"" << *arg << "\".";
      this->SetError(e.str().c_str());
      return false;
      }
    }

  // Make sure a property name was found.
  if(this->PropertyName.empty())
    {
    this->SetError("not given a PROPERTY <name> argument.");
    return false;
    }

  // Dispatch property setting.
  switch(scope)
    {
    case cmProperty::GLOBAL:      return this->HandleGlobalMode();
    case cmProperty::DIRECTORY:   return this->HandleDirectoryMode();
    case cmProperty::TARGET:      return this->HandleTargetMode();
    case cmProperty::SOURCE_FILE: return this->HandleSourceMode();
    case cmProperty::TEST:        return this->HandleTestMode();

    case cmProperty::VARIABLE:
    case cmProperty::CACHED_VARIABLE:
      break; // should never happen
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::ConstructValue(std::string& value,
                                          const char* old)
{
  if(this->AppendMode)
    {
    // This is an append.  Start with the original value.
    if(old)
      {
      value = old;
      }
    }
  else if(this->PropertyValue.empty())
    {
    // This is a set to no values.  Remove the property.
    return false;
    }

  // Add the new value.
  if(!this->PropertyValue.empty())
    {
    if(!value.empty())
      {
      value += ";";
      }
    value += this->PropertyValue;
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleGlobalMode()
{
  if(!this->Names.empty())
    {
    this->SetError("given names for GLOBAL scope.");
    return false;
    }

  // Set or append the property.
  cmake* cm = this->Makefile->GetCMakeInstance();
  const char* name = this->PropertyName.c_str();
  std::string value;
  if(this->ConstructValue(value, cm->GetProperty(name)))
    {
    // Set the new property.
    cm->SetProperty(name, value.c_str());
    }
  else
    {
    // Remove the property.
    cm->SetProperty(name, 0);
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleDirectoryMode()
{
  if(this->Names.size() > 1)
    {
    this->SetError("allows at most one name for DIRECTORY scope.");
    return false;
    }

  // Default to the current directory.
  cmMakefile* mf = this->Makefile;

  // Lookup the directory if given.
  if(!this->Names.empty())
    {
    // Construct the directory name.  Interpret relative paths with
    // respect to the current directory.
    std::string dir = *this->Names.begin();
    if(!cmSystemTools::FileIsFullPath(dir.c_str()))
      {
      dir = this->Makefile->GetCurrentDirectory();
      dir += "/";
      dir += *this->Names.begin();
      }

    // The local generators are associated with collapsed paths.
    dir = cmSystemTools::CollapseFullPath(dir.c_str());

    // Lookup the generator.
    if(cmLocalGenerator* lg =
       (this->Makefile->GetLocalGenerator()
        ->GetGlobalGenerator()->FindLocalGenerator(dir.c_str())))
      {
      // Use the makefile for the directory found.
      mf = lg->GetMakefile();
      }
    else
      {
      // Could not find the directory.
      this->SetError
        ("DIRECTORY scope provided but requested directory was not found. "
         "This could be because the directory argument was invalid or, "
         "it is valid but has not been processed yet.");
      return false;
      }
    }

  // Set or append the property.
  const char* name = this->PropertyName.c_str();
  std::string value;
  if(this->ConstructValue(value, mf->GetProperty(name)))
    {
    // Set the new property.
    mf->SetProperty(name, value.c_str());
    }
  else
    {
    // Remove the property.
    mf->SetProperty(name, 0);
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleTargetMode()
{
  for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
      ni != this->Names.end(); ++ni)
    {
    if(cmTarget* target =
       this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
       ->FindTarget(0, ni->c_str(), true))
      {
      // Handle the current target.
      if(!this->HandleTarget(target))
        {
        return false;
        }
      }
    else
      {
      cmOStringStream e;
      e << "could not find TARGET " << *ni
        << ".  Perhaps it has not yet been created.";
      this->SetError(e.str().c_str());
      return false;
      }
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleTarget(cmTarget* target)
{
  // Set or append the property.
  const char* name = this->PropertyName.c_str();
  std::string value;
  if(this->ConstructValue(value, target->GetProperty(name)))
    {
    // Set the new property.
    target->SetProperty(name, value.c_str());
    }
  else
    {
    // Remove the property.
    target->SetProperty(name, 0);
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleSourceMode()
{
  for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
      ni != this->Names.end(); ++ni)
    {
    // Get the source file.
    if(cmSourceFile* sf = this->Makefile->GetOrCreateSource(ni->c_str()))
      {
      if(!this->HandleSource(sf))
        {
        return false;
        }
      }
    else
      {
      cmOStringStream e;
      e << "given SOURCE name that could not be found or created: " << *ni;
      this->SetError(e.str().c_str());
      return false;
      }
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleSource(cmSourceFile* sf)
{
  // Set or append the property.
  const char* name = this->PropertyName.c_str();
  std::string value;
  if(this->ConstructValue(value, sf->GetProperty(name)))
    {
    // Set the new property.
    sf->SetProperty(name, value.c_str());
    }
  else
    {
    // Remove the property.
    sf->SetProperty(name, 0);
    }

  // TODO: MACOSX_PACKAGE_LOCATION special case in
  // cmSetSourceFilesPropertiesCommand
  // The logic should be moved to cmSourceFile.

  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleTestMode()
{
  // Loop over all tests looking for matching names.
  std::vector<cmTest*> const& tests = *this->Makefile->GetTests();
  for(std::vector<cmTest*>::const_iterator ti = tests.begin();
      ti != tests.end(); ++ti)
    {
    cmTest* test = *ti;
    std::set<cmStdString>::const_iterator ni =
      this->Names.find(test->GetName());
    if(ni != this->Names.end())
      {
      if(this->HandleTest(test))
        {
        this->Names.erase(ni);
        }
      else
        {
        return false;
        }
      }
    }

  // Names that are still left were not found.
  if(!this->Names.empty())
    {
    cmOStringStream e;
    e << "given TEST names that do not exist:\n";
    for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
        ni != this->Names.end(); ++ni)
      {
      e << "  " << *ni << "\n";
      }
    this->SetError(e.str().c_str());
    return false;
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleTest(cmTest* test)
{
  // Set or append the property.
  const char* name = this->PropertyName.c_str();
  std::string value;
  if(this->ConstructValue(value, test->GetProperty(name)))
    {
    // Set the new property.
    test->SetProperty(name, value.c_str());
    }
  else
    {
    // Remove the property.
    test->SetProperty(name, 0);
    }

  return true;
}



More information about the Cmake-commits mailing list