ENH: Added CABIL commands for configuration file generation.

This commit is contained in:
Brad King 2001-02-26 18:00:49 -05:00
parent 8859bd5ac8
commit b908149828
9 changed files with 695 additions and 0 deletions

91
Source/cmCableCommand.cxx Normal file
View File

@ -0,0 +1,91 @@
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2000 National Library of Medicine
All rights reserved.
See COPYRIGHT.txt for copyright details.
=========================================================================*/
#include "cmCabilCommand.h"
#include "cmCacheManager.h"
// cmCabilCommand
/**
* Constructor initializes to empty m_CabilData.
*/
cmCabilCommand::cmCabilCommand(): m_CabilData(0)
{
}
/**
* Destructor frees the cmCabilData only if this command is its owner.
*/
cmCabilCommand::~cmCabilCommand()
{
if(m_CabilData && m_CabilData->OwnerIs(this))
{
delete m_CabilData;
}
}
/**
* Write a CABIL configuration file header.
*/
void cmCabilCommand::WriteConfigurationHeader(std::ostream& os) const
{
os << "<?xml version=\"1.0\"?>" << std::endl
<< "<CabilConfiguration>" << std::endl;
}
/**
* Write a CABIL configuration file footer.
*/
void cmCabilCommand::WriteConfigurationFooter(std::ostream& os) const
{
os << "</CabilConfiguration>" << std::endl;
}
/**
* Ensure that this cmCabilCommand has a valid m_CabilData pointer.
*/
void cmCabilCommand::SetupCabilData()
{
// Only do something if the pointer is invalid.
if(m_CabilData)
{ return; }
// Look through the vector of commands from the makefile.
const std::vector<cmCommand*>& usedCommands =
m_Makefile->GetUsedCommands();
for(std::vector<cmCommand*>::const_iterator commandIter =
usedCommands.begin(); commandIter != usedCommands.end(); ++commandIter)
{
// If this command is a cmCabilCommand, see if it has a cmCabilData
// instance.
cmCabilCommand* command = cmCabilCommand::SafeDownCast(*commandIter);
if(command)
{ m_CabilData = command->m_CabilData; }
// If we found an instance of cmCabilData, then we are done.
if(m_CabilData)
{ return; }
}
// We didn't find another cmCabilCommand with a valid cmCabilData.
// We must allocate the new cmCabilData ourselves, and with this
// command as its owner.
m_CabilData = new cmCabilData(this);
}

48
Source/cmCableCommand.h Normal file
View File

@ -0,0 +1,48 @@
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2000 National Library of Medicine
All rights reserved.
See COPYRIGHT.txt for copyright details.
=========================================================================*/
#ifndef cmCabilCommand_h
#define cmCabilCommand_h
#include "cmStandardIncludes.h"
#include "cmCommand.h"
#include "cmCabilData.h"
/** \class cmCabilCommand
* \brief Superclass for all CABIL_ command classes.
*/
class cmCabilCommand : public cmCommand
{
public:
cmCabilCommand();
virtual ~cmCabilCommand();
void WriteConfigurationHeader(std::ostream&) const;
void WriteConfigurationFooter(std::ostream&) const;
cmTypeMacro(cmCabilCommand, cmCommand);
protected:
void SetupCabilData();
/**
* The cmCabilData holding common information for all cmCabilCommand
* instances.
*/
cmCabilData* m_CabilData;
};
#endif

119
Source/cmCableData.cxx Normal file
View File

@ -0,0 +1,119 @@
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2000 National Library of Medicine
All rights reserved.
See COPYRIGHT.txt for copyright details.
=========================================================================*/
#include "cmCabilData.h"
#include "cmCacheManager.h"
/**
* Free all data that was stored here.
*/
cmCabilData::~cmCabilData()
{
for(OutputFiles::iterator i = m_OutputFiles.begin();
i != m_OutputFiles.end(); ++i)
{
delete i->second;
}
}
/**
* The constructor attempts to open the file for writing.
*/
cmCabilData::OutputFile
::OutputFile(std::string file, const cmCabilCommand* command):
m_FileStream(file.c_str()),
m_FirstReferencingCommand(command),
m_LastReferencingCommand(command)
{
if(!m_FileStream)
{
cmSystemTools::Error("Error can not open for write: ", file.c_str());
}
}
/**
* Destructor closes the file, if it was open.
*/
cmCabilData::OutputFile
::~OutputFile()
{
if(m_FileStream)
m_FileStream.close();
}
/**
* Get the output stream associated with this OutputFile.
*/
std::ostream&
cmCabilData::OutputFile
::GetStream()
{
return m_FileStream;
}
void
cmCabilData::OutputFile
::SetLastReferencingCommand(const cmCabilCommand* command)
{
m_LastReferencingCommand = command;
}
bool
cmCabilData::OutputFile
::FirstReferencingCommandIs(const cmCabilCommand* command) const
{
return (m_FirstReferencingCommand == command);
}
bool
cmCabilData::OutputFile
::LastReferencingCommandIs(const cmCabilCommand* command) const
{
return (m_LastReferencingCommand == command);
}
/**
* Get the OutputFile for the file with the given name. Automatically
* maintains first and last referencing commands.
*/
cmCabilData::OutputFile*
cmCabilData::GetOutputFile(const std::string& name,
const cmCabilCommand* command)
{
OutputFiles::iterator f = m_OutputFiles.find(name);
// If the file hasn't yet been opened, create an entry for it.
if(f == m_OutputFiles.end())
{
OutputFile* outputFile = new OutputFile(name, command);
m_OutputFiles[name] = outputFile;
return outputFile;
}
// The file has already been opened. Set the command as the last
// referencing command.
f->second->SetLastReferencingCommand(command);
return f->second;
}

81
Source/cmCableData.h Normal file
View File

@ -0,0 +1,81 @@
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2000 National Library of Medicine
All rights reserved.
See COPYRIGHT.txt for copyright details.
=========================================================================*/
#ifndef cmCabilData_h
#define cmCabilData_h
#include "cmStandardIncludes.h"
#include "cmCommand.h"
class cmCabilCommand;
/** \class cmCabilData
* \brief Hold data in one location for all cmCabilCommand subclasses.
*/
class cmCabilData
{
public:
/**
* The cmCabilData instance is owned by one cmCabilCommand, which is given
* to this constructor.
*/
cmCabilData(const cmCabilCommand* owner): m_Owner(owner) {}
~cmCabilData();
/**
* Returns true if the given cmCabilCommand is the owner of this
* cmCabilData.
*/
bool OwnerIs(const cmCabilCommand* owner) const
{ return (owner == m_Owner); }
/**
* Hold an output stream for all commands that use it. Maintain the
* first and last commands that reference it so that they can write the
* header/footer lines, if necessary.
*/
class OutputFile
{
public:
OutputFile(std::string, const cmCabilCommand*);
~OutputFile();
std::ostream& GetStream();
void SetLastReferencingCommand(const cmCabilCommand*);
bool FirstReferencingCommandIs(const cmCabilCommand*) const;
bool LastReferencingCommandIs(const cmCabilCommand*) const;
private:
std::ofstream m_FileStream;
const cmCabilCommand* m_FirstReferencingCommand;
const cmCabilCommand* m_LastReferencingCommand;
};
OutputFile* GetOutputFile(const std::string&, const cmCabilCommand*);
private:
typedef std::map<std::string, OutputFile*> OutputFiles;
/**
* The cmCabilCommand which created this instance of cmCabilCommand.
*/
const cmCabilCommand* m_Owner;
/**
* Hold all output streams by file name.
*/
OutputFiles m_OutputFiles;
};
#endif

View File

@ -0,0 +1,56 @@
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2000 National Library of Medicine
All rights reserved.
See COPYRIGHT.txt for copyright details.
=========================================================================*/
#include "cmCabilDefineSetCommand.h"
#include "cmCacheManager.h"
// cmCabilDefineSetCommand
bool cmCabilDefineSetCommand::Invoke(std::vector<std::string>& args)
{
if(args.size() < 2)
{
this->SetError("called with incorrect number of arguments");
return false;
}
std::vector<std::string>::const_iterator arg = args.begin();
// The first argument is the name of the set.
m_SetName = *arg++;
// The rest of the arguments are the elements to be placed in the set.
for(; arg != args.end(); ++arg)
{
m_Elements.push_back(*arg);
}
return true;
}
/**
* Write the CABIL configuration code to define this Set.
*/
void cmCabilDefineSetCommand::WriteConfiguration(std::ostream& os) const
{
os << " <Set name=\"" << m_SetName.c_str() << "\">" << std::endl;
for(Elements::const_iterator e = m_Elements.begin();
e != m_Elements.end(); ++e)
{
os << " <Element>" << e->c_str() << "</Element>" << std::endl;
}
os << " </Set>" << std::endl;
}

View File

@ -0,0 +1,94 @@
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2000 National Library of Medicine
All rights reserved.
See COPYRIGHT.txt for copyright details.
=========================================================================*/
#ifndef cmCabilDefineSetCommand_h
#define cmCabilDefineSetCommand_h
#include "cmStandardIncludes.h"
#include "cmCabilCommand.h"
/** \class cmCabilDefineSetCommand
* \brief Define a command that adds a CABIL Set definition.
*
* cmCabilDefineSetCommand is used to define a named CABIL Set.
* The set can be referenced in other CABIL command arguments
* with a '$' followed by the set name.
*/
class cmCabilDefineSetCommand : public cmCabilCommand
{
public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
{
return new cmCabilDefineSetCommand;
}
/**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
virtual bool Invoke(std::vector<std::string>& args);
/**
* This determines if the command gets propagated down
* to makefiles located in subdirectories.
*/
virtual bool IsInherited()
{return true;}
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual const char* GetName() { return "CABIL_DEFINE_SET";}
/**
* Succinct documentation.
*/
virtual const char* GetTerseDocumentation()
{
return "Define a CABIL Set.";
}
/**
* More documentation.
*/
virtual const char* GetFullDocumentation()
{
return
"CABIL_DEFINE_SET(name_of_set member1 member2 ...)";
}
virtual void WriteConfiguration(std::ostream&) const;
cmTypeMacro(cmCabilDefineSetCommand, cmCabilCommand);
private:
typedef std::vector<std::string> Elements;
/**
* The name of the set.
*/
std::string m_SetName;
/**
* The elements to be defined in the set (before $ expansion).
*/
Elements m_Elements;
};
#endif

View File

@ -0,0 +1,101 @@
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2000 National Library of Medicine
All rights reserved.
See COPYRIGHT.txt for copyright details.
=========================================================================*/
#include "cmCabilInstantiateCommand.h"
#include "cmCacheManager.h"
#include "cmCabilDefineSetCommand.h"
// cmCabilInstantiateCommand
bool cmCabilInstantiateCommand::Invoke(std::vector<std::string>& args)
{
if(args.size() < 2)
{
this->SetError("called with incorrect number of arguments");
return false;
}
// This command instance needs to use the cmCabilData instance.
this->SetupCabilData();
std::vector<std::string>::const_iterator arg = args.begin();
// Get the output file into which the configuration code is to be
// written. The name of the file is the first argument.
m_OutputFile = m_CabilData->GetOutputFile(*arg++, this);
// The rest of the arguments are the elements to be placed in the set.
for(; arg != args.end(); ++arg)
{
m_Elements.push_back(*arg);
}
return true;
}
void cmCabilInstantiateCommand::FinalPass()
{
// If this command is the first to reference its output file, write the
// header information.
if(m_OutputFile->FirstReferencingCommandIs(this))
{
this->WriteConfigurationHeader(m_OutputFile->GetStream());
// Need to write out the Set definitions.
// Look through the vector of commands from the makefile.
const std::vector<cmCommand*>& usedCommands =
m_Makefile->GetUsedCommands();
for(std::vector<cmCommand*>::const_iterator commandIter =
usedCommands.begin();
commandIter != usedCommands.end(); ++commandIter)
{
// If this command is a cmCabilDefineSetCommand, ask it to write its
// configuration code to the output file.
cmCabilDefineSetCommand* command =
cmCabilDefineSetCommand::SafeDownCast(*commandIter);
if(command)
{
command->WriteConfiguration(m_OutputFile->GetStream());
}
}
}
// Write the instantiation block's code.
this->WriteConfiguration(m_OutputFile->GetStream());
// If this command is the last to reference its output file, write the
// footer information.
if(m_OutputFile->LastReferencingCommandIs(this))
{
this->WriteConfigurationFooter(m_OutputFile->GetStream());
}
}
/**
* Write the CABIL configuration code to define this InstantiationSet.
*/
void cmCabilInstantiateCommand::WriteConfiguration(std::ostream& os) const
{
os << std::endl
<< " <InstantiationSet>" << std::endl;
for(Elements::const_iterator e = m_Elements.begin();
e != m_Elements.end(); ++e)
{
os << " <Element>" << e->c_str() << "</Element>" << std::endl;
}
os << " </InstantiationSet>" << std::endl;
}

View File

@ -0,0 +1,99 @@
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2000 National Library of Medicine
All rights reserved.
See COPYRIGHT.txt for copyright details.
=========================================================================*/
#ifndef cmCabilInstantiateCommand_h
#define cmCabilInstantiateCommand_h
#include "cmStandardIncludes.h"
#include "cmCabilCommand.h"
/** \class cmCabilInstantiateCommand
* \brief Define a command that generates a rule for explicit template
* instantiations.
*
* cmCabilInstantiateCommand is used to generate a rule in a CABIL
* configuration file to create explicit template instantiations.
*/
class cmCabilInstantiateCommand : public cmCabilCommand
{
public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
{
return new cmCabilInstantiateCommand;
}
/**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
virtual bool Invoke(std::vector<std::string>& args);
/**
* This is called after all input commands have been processed.
*/
virtual void FinalPass();
/**
* This determines if the command gets propagated down
* to makefiles located in subdirectories.
*/
virtual bool IsInherited()
{return true;}
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual const char* GetName() { return "CABIL_INSTANTIATE";}
/**
* Succinct documentation.
*/
virtual const char* GetTerseDocumentation()
{
return "Define a rule for creating explicit template instantiations.";
}
/**
* More documentation.
*/
virtual const char* GetFullDocumentation()
{
return
"CABIL_INSTANTIATE(cabil_config_file member1 member2 ...)";
}
virtual void WriteConfiguration(std::ostream&) const;
cmTypeMacro(cmCabilInstantiateCommand, cmCabilCommand);
private:
typedef std::vector<std::string> Elements;
/**
* The output file to which to write the configuration.
*/
cmCabilData::OutputFile* m_OutputFile;
/**
* The elements describing the set of instantiations.
*/
Elements m_Elements;
};
#endif

View File

@ -24,6 +24,10 @@
#include "cmWin32DefinesCommand.cxx"
#include "cmWin32LibrariesCommand.cxx"
#include "cmConfigureFileNoAutoconf.cxx"
#include "cmCabilCommand.cxx"
#include "cmCabilData.cxx"
#include "cmCabilDefineSetCommand.cxx"
#include "cmCabilInstantiateCommand.cxx"
#include "cmFindFileCommand.cxx"
#include "cmWrapTclCommand.cxx"
@ -50,6 +54,8 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands)
commands.push_back(new cmWin32DefinesCommand);
commands.push_back(new cmWin32LibrariesCommand);
commands.push_back(new cmConfigureFileNoAutoconf);
commands.push_back(new cmCabilDefineSetCommand);
commands.push_back(new cmCabilInstantiateCommand);
commands.push_back(new cmFindFileCommand);
commands.push_back(new cmWrapTclCommand);
}