ENH: Change to new CABLE command architecture. CABLE configuration code is now generated on the first pass, during the Invoke() calls.

This commit is contained in:
Brad King 2001-03-01 16:47:05 -05:00
parent af30fe6745
commit dc72655414
23 changed files with 1028 additions and 244 deletions

View File

@ -0,0 +1,55 @@
/*=========================================================================
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 "cmCableCloseNamespaceCommand.h"
#include "cmCacheManager.h"
// cmCableCloseNamespaceCommand
bool cmCableCloseNamespaceCommand::Invoke(std::vector<std::string>& args)
{
if(args.size() != 1)
{
this->SetError("called with incorrect number of arguments");
return false;
}
// This command needs to access the Cable data.
this->SetupCableData();
// The argument is the namespace name.
m_NamespaceName = args[0];
// Ask the cable data to close the namespace.
m_CableData->CloseNamespace(m_NamespaceName);
// Write the configuration for this command.
this->WriteNamespaceFooter();
return true;
}
/**
* Generate a CABLE Namespace close tag.
*/
void cmCableCloseNamespaceCommand::WriteNamespaceFooter() const
{
m_CableData->Unindent();
std::ostream& os = m_CableData->GetOutputStream();
cmCableData::Indentation indent = m_CableData->GetIndentation();
os << indent << "</Namespace> <!-- \"" << m_NamespaceName.c_str()
<< "\" -->" << std::endl;
}

View File

@ -0,0 +1,89 @@
/*=========================================================================
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 cmCableCloseNamespaceCommand_h
#define cmCableCloseNamespaceCommand_h
#include "cmStandardIncludes.h"
#include "cmCableCommand.h"
/** \class cmCableCloseNamespaceCommand
* \brief Define a command that closes a CABLE Namespace.
*
* cmCableCloseNamespaceCommand is used to generate CABLE Namespace
* close tags in the configuration file.
*/
class cmCableCloseNamespaceCommand : public cmCableCommand
{
public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
{
return new cmCableCloseNamespaceCommand;
}
/**
* 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 "CABLE_CLOSE_NAMESPACE";}
/**
* Succinct documentation.
*/
virtual const char* GetTerseDocumentation()
{
return "Close a CABLE Namespace";
}
/**
* More documentation.
*/
virtual const char* GetFullDocumentation()
{
return
"CABLE_CLOSE_NAMESPACE(namespace_name)\n"
"Close the given namespace in the generated configuration file.\n"
"There must be a matching CABLE_OPEN_NAMESPACE(namespace_name)\n"
"called with the same name.";
}
cmTypeMacro(cmCableCloseNamespaceCommand, cmCableCommand);
private:
void WriteNamespaceFooter() const;
private:
/**
* The name of the namespace to setup.
*/
std::string m_NamespaceName;
};
#endif

View File

@ -39,25 +39,6 @@ cmCableCommand::~cmCableCommand()
}
/**
* Write a CABLE configuration file header.
*/
void cmCableCommand::WriteConfigurationHeader(std::ostream& os) const
{
os << "<?xml version=\"1.0\"?>" << std::endl
<< "<CableConfiguration>" << std::endl;
}
/**
* Write a CABLE configuration file footer.
*/
void cmCableCommand::WriteConfigurationFooter(std::ostream& os) const
{
os << "</CableConfiguration>" << std::endl;
}
/**
* Ensure that this cmCableCommand has a valid m_CableData pointer.
*/

View File

@ -37,9 +37,6 @@ public:
cmCableCommand();
virtual ~cmCableCommand();
void WriteConfigurationHeader(std::ostream&) const;
void WriteConfigurationFooter(std::ostream&) const;
cmTypeMacro(cmCableCommand, cmCommand);
protected:
void SetupCableData();

View File

@ -16,104 +16,196 @@
#include "cmCableData.h"
#include "cmCacheManager.h"
#include "cmCablePackageCommand.h"
/**
* Free all data that was stored here.
* The cmCableData instance is owned by one cmCableCommand, which is given
* to this constructor.
*/
cmCableData::cmCableData(const cmCableCommand* owner):
m_Owner(owner),
m_Indentation(0),
m_Package(NULL),
m_PackageNamespaceDepth(0)
{
this->OpenOutputFile("cable_config.xml");
}
/**
* Free all data that was stored here. Also close the output file.
*/
cmCableData::~cmCableData()
{
for(OutputFiles::iterator i = m_OutputFiles.begin();
i != m_OutputFiles.end(); ++i)
// End last package, if any.
this->EndPackage();
// Finish up the output file.
this->CloseOutputFile();
}
/**
* Open the configuration output file with the given name. This
* writes the configuration header.
*/
void cmCableData::OpenOutputFile(const std::string& name)
{
m_OutputFile.open(name.c_str());
if(m_OutputFile)
{
delete i->second;
this->WriteConfigurationHeader();
}
}
/**
* The constructor attempts to open the file for writing.
* Close the configuration output file. This writes the configuration
* footer.
*/
cmCableData::OutputFile
::OutputFile(std::string file, const cmCableCommand* command):
m_FileStream(file.c_str()),
m_FirstReferencingCommand(command),
m_LastReferencingCommand(command)
void cmCableData::CloseOutputFile()
{
if(!m_FileStream)
if(m_OutputFile)
{
cmSystemTools::Error("Error can not open for write: ", file.c_str());
this->WriteConfigurationFooter();
m_OutputFile.close();
}
}
/**
* Destructor closes the file, if it was open.
* Write a CABLE configuration file header.
*/
cmCableData::OutputFile
::~OutputFile()
void cmCableData::WriteConfigurationHeader()
{
if(m_FileStream)
m_FileStream.close();
m_OutputFile << m_Indentation << "<?xml version=\"1.0\"?>" << std::endl
<< m_Indentation << "<CableConfiguration>" << std::endl;
this->Indent();
}
/**
* Get the output stream associated with this OutputFile.
* Write a CABLE configuration file footer.
*/
std::ostream&
cmCableData::OutputFile
::GetStream()
void cmCableData::WriteConfigurationFooter()
{
return m_FileStream;
this->Unindent();
m_OutputFile << m_Indentation << "</CableConfiguration>" << std::endl;
}
/**
* Print indentation spaces.
*/
void
cmCableData::OutputFile
::SetLastReferencingCommand(const cmCableCommand* command)
cmCableData::Indentation
::Print(std::ostream& os) const
{
m_LastReferencingCommand = command;
}
bool
cmCableData::OutputFile
::FirstReferencingCommandIs(const cmCableCommand* command) const
{
return (m_FirstReferencingCommand == command);
}
bool
cmCableData::OutputFile
::LastReferencingCommandIs(const cmCableCommand* command) const
{
return (m_LastReferencingCommand == command);
if(m_Indent <= 0)
{ return; }
// Use blocks of 8 spaces to speed up big indents.
unsigned int blockCount = m_Indent >> 3;
unsigned int singleCount = m_Indent & 7;
while(blockCount-- > 0)
{
os << " ";
}
while(singleCount-- > 0)
{
os << " ";
}
}
/**
* Get the OutputFile for the file with the given name. Automatically
* maintains first and last referencing commands.
* Open a namespace with the given name.
*/
cmCableData::OutputFile*
cmCableData::GetOutputFile(const std::string& name,
const cmCableCommand* command)
void cmCableData::OpenNamespace(const std::string& name)
{
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;
m_NamespaceStack.push_back(name);
}
/**
* Close the current namespace, checking whether it has the given name.
*/
void cmCableData::CloseNamespace(const std::string& name)
{
if(m_NamespaceStack.empty())
{
cmSystemTools::Error("Unbalanced close-namespace = ", name.c_str());
return;
}
if(m_NamespaceStack.back() != name)
{
cmSystemTools::Error("Wrong name on close-namespace = ", name.c_str());
}
// If this closes the namespace where the current package was opened,
// the package must end as well.
if(m_Package && (m_PackageNamespaceDepth == m_NamespaceStack.size()))
{
this->EndPackage();
}
m_NamespaceStack.pop_back();
}
/**
* Begin a new package definition. If there is a current one, it
* will be ended.
*/
void cmCableData::BeginPackage(cmCablePackageCommand* command)
{
// Close the current package, if any.
this->EndPackage();
// Open this package.
m_Package = command;
// Save the package's opening namespace depth for later verification
// on the end of the package.
m_PackageNamespaceDepth = m_NamespaceStack.size();
}
/**
* End a package definition.
*/
void cmCableData::EndPackage()
{
// Make sure we have an open package.
if(!m_Package)
{
return;
}
// Make sure the namespace nesting depth matches the opening depth
// of the package.
if(m_PackageNamespaceDepth != m_NamespaceStack.size())
{
cmSystemTools::Error("Package ended at different namespace depth than"
"it was created!", "");
}
// Write out the package's footer.
m_Package->WritePackageFooter();
// Done with the package.
m_Package = NULL;
}
/**
* Simplify indentation printing by allowing Indentation objects to be added
* to streams.
*/
std::ostream& operator<<(std::ostream& os,
const cmCableData::Indentation& indent)
{
indent.Print(os);
return os;
}

View File

@ -20,6 +20,7 @@
#include "cmCommand.h"
class cmCableCommand;
class cmCablePackageCommand;
/** \class cmCableData
* \brief Hold data in one location for all cmCableCommand subclasses.
@ -27,12 +28,7 @@ class cmCableCommand;
class cmCableData
{
public:
/**
* The cmCableData instance is owned by one cmCableCommand, which is given
* to this constructor.
*/
cmCableData(const cmCableCommand* owner): m_Owner(owner) {}
cmCableData(const cmCableCommand*);
~cmCableData();
/**
@ -41,41 +37,73 @@ public:
*/
bool OwnerIs(const cmCableCommand* owner) const
{ return (owner == m_Owner); }
std::ostream& GetOutputStream()
{ return m_OutputFile; }
void OpenOutputFile(const std::string&);
void CloseOutputFile();
void WriteConfigurationHeader();
void WriteConfigurationFooter();
/**
* 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 to simplify indentation printing.
*/
class OutputFile
class Indentation
{
public:
OutputFile(std::string, const cmCableCommand*);
~OutputFile();
std::ostream& GetStream();
void SetLastReferencingCommand(const cmCableCommand*);
bool FirstReferencingCommandIs(const cmCableCommand*) const;
bool LastReferencingCommandIs(const cmCableCommand*) const;
Indentation(int indent): m_Indent(indent) {}
void Print(std::ostream& os) const;
Indentation Next() const { return Indentation(m_Indent+2); }
Indentation Previous() const { return Indentation(m_Indent-2); }
private:
std::ofstream m_FileStream;
const cmCableCommand* m_FirstReferencingCommand;
const cmCableCommand* m_LastReferencingCommand;
int m_Indent;
};
OutputFile* GetOutputFile(const std::string&, const cmCableCommand*);
void Indent() { m_Indentation = m_Indentation.Next(); }
void Unindent() { m_Indentation = m_Indentation.Previous(); }
const Indentation& GetIndentation() const { return m_Indentation; }
void OpenNamespace(const std::string&);
void CloseNamespace(const std::string&);
void BeginPackage(cmCablePackageCommand*);
void EndPackage();
private:
typedef std::map<std::string, OutputFile*> OutputFiles;
/**
* The cmCableCommand which created this instance of cmCableCommand.
*/
const cmCableCommand* m_Owner;
/**
* Hold all output streams by file name.
* Current indentation for output.
*/
OutputFiles m_OutputFiles;
Indentation m_Indentation;
/**
* The output file to which the configuration is written.
*/
std::ofstream m_OutputFile;
/**
* The stack of namespaces.
*/
std::list<std::string> m_NamespaceStack;
/**
* The command that created the package currently being defined.
*/
cmCablePackageCommand* m_Package;
/**
* The namespace level at which the current package was created.
* This must be the level when the package is ended.
*/
unsigned int m_PackageNamespaceDepth;
};
std::ostream& operator<<(std::ostream&, const cmCableData::Indentation&);
#endif

View File

@ -28,6 +28,9 @@ bool cmCableDefineSetCommand::Invoke(std::vector<std::string>& args)
return false;
}
// This command needs access to the Cable data.
this->SetupCableData();
std::vector<std::string>::const_iterator arg = args.begin();
// The first argument is the name of the set.
@ -39,6 +42,9 @@ bool cmCableDefineSetCommand::Invoke(std::vector<std::string>& args)
m_Elements.push_back(Element(this->GenerateTag(*arg), *arg));
}
// Write this command's configuration output.
this->WriteConfiguration();
return true;
}
@ -46,15 +52,20 @@ bool cmCableDefineSetCommand::Invoke(std::vector<std::string>& args)
/**
* Write the CABLE configuration code to define this Set.
*/
void cmCableDefineSetCommand::WriteConfiguration(std::ostream& os) const
void cmCableDefineSetCommand::WriteConfiguration() const
{
cmRegularExpression needCdataBlock("[&<>]");
os << " <Set name=\"" << m_SetName.c_str() << "\">" << std::endl;
// Get the ouptut information from the cmCableData.
std::ostream& os = m_CableData->GetOutputStream();
cmCableData::Indentation indent = m_CableData->GetIndentation();
// Output the code.
os << indent << "<Set name=\"" << m_SetName.c_str() << "\">" << std::endl;
for(Elements::const_iterator e = m_Elements.begin();
e != m_Elements.end(); ++e)
{
os << " <Element";
os << indent << " <Element";
// Only output the tag if it is not the empty string.
if(e->first.length() > 0)
{
@ -71,7 +82,7 @@ void cmCableDefineSetCommand::WriteConfiguration(std::ostream& os) const
}
os << "</Element>" << std::endl;
}
os << " </Set>" << std::endl;
os << indent << "</Set>" << std::endl;
}

View File

@ -48,7 +48,7 @@ public:
* to makefiles located in subdirectories.
*/
virtual bool IsInherited()
{return true;}
{ return true; }
/**
* The name of the command as specified in CMakeList.txt.
@ -75,13 +75,11 @@ public:
"commands by a '$' immediately followed by the set name (ex. $SetName).";
}
virtual void WriteConfiguration(std::ostream&) const;
cmTypeMacro(cmCableDefineSetCommand, cmCableCommand);
private:
void WriteConfiguration() const;
std::string GenerateTag(const std::string&) const;
private:
typedef std::pair<std::string, std::string> Element;
typedef std::vector<Element> Elements;

View File

@ -23,16 +23,18 @@
* Write the CABLE configuration code to define this InstantiationSet.
* This includes the "class" keyword to do class template instantiations.
*/
void cmCableInstantiateClassCommand::WriteConfiguration(std::ostream& os) const
void cmCableInstantiateClassCommand::WriteConfiguration() const
{
std::ostream& os = m_CableData->GetOutputStream();
cmCableData::Indentation indent = m_CableData->GetIndentation();
cmRegularExpression needCdataBlock("[&<>]");
os << std::endl
<< " <InstantiationSet>" << std::endl;
for(Elements::const_iterator e = m_Elements.begin();
e != m_Elements.end(); ++e)
os << indent << "<InstantiationSet>" << std::endl;
for(Entries::const_iterator e = m_Entries.begin();
e != m_Entries.end(); ++e)
{
os << " <Element>class ";
os << indent << " <Element>class ";
if(needCdataBlock.find(e->c_str()))
{
os << "<![CDATA[" << e->c_str() << "]]>";
@ -43,5 +45,5 @@ void cmCableInstantiateClassCommand::WriteConfiguration(std::ostream& os) const
}
os << "</Element>" << std::endl;
}
os << " </InstantiationSet>" << std::endl;
os << indent << "</InstantiationSet>" << std::endl;
}

View File

@ -17,7 +17,7 @@
#define cmCableInstantiateClassCommand_h
#include "cmStandardIncludes.h"
#include "cmCableInstantiateCommand.h"
#include "cmCablePackageEntryCommand.h"
/** \class cmCableInstantiateClassCommand
* \brief Define a command that generates a rule for explicit template
@ -27,7 +27,7 @@
* configuration file to create explicit template instantiations of
* classes.
*/
class cmCableInstantiateClassCommand : public cmCableInstantiateCommand
class cmCableInstantiateClassCommand : public cmCablePackageEntryCommand
{
public:
/**
@ -48,7 +48,7 @@ public:
*/
virtual const char* GetTerseDocumentation()
{
return "Define CABLE InstantiationSet of classes.";
return "Define CABLE InstantiationSet of classes in a package.";
}
/**
@ -57,17 +57,17 @@ public:
virtual const char* GetFullDocumentation()
{
return
"CABLE_INSTANTIATE_CLASS(cable_config_file member1 member2 ...)\n"
"CABLE_INSTANTIATE_CLASS(package_name member1 member2 ...)\n"
"Generates an InstantiationSet in the CABLE configuration. It is\n"
"assumed that all members of the set are explicit instantiations of\n"
"template classes (not functions, operators, etc).";
}
virtual void WriteConfiguration(std::ostream&) const;
virtual void WriteConfiguration() const;
cmTypeMacro(cmCableInstantiateClassCommand, cmCableInstantiateCommand);
protected:
typedef cmCableInstantiateCommand::Elements Elements;
typedef cmCablePackageEntryCommand::Entries Entries;
};

View File

@ -16,96 +16,24 @@
#include "cmCableInstantiateCommand.h"
#include "cmCacheManager.h"
#include "cmCableDefineSetCommand.h"
#include "cmRegularExpression.h"
// cmCableInstantiateCommand
bool cmCableInstantiateCommand::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 cmCableData instance.
this->SetupCableData();
// The output file must be opened in the output directory.
std::string file = m_Makefile->GetStartOutputDirectory();
// The first argument is the file into which the configuration code is to be
// written.
std::vector<std::string>::const_iterator arg = args.begin();
// Concatenate the file name onto the path.
file += "/" + *arg++;
// Get the OutputFile corresponding to this file name.
m_OutputFile = m_CableData->GetOutputFile(file, 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 cmCableInstantiateCommand::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 cmCableDefineSetCommand, ask it to write its
// configuration code to the output file.
cmCableDefineSetCommand* command =
cmCableDefineSetCommand::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 CABLE configuration code to define this InstantiationSet.
*/
void cmCableInstantiateCommand::WriteConfiguration(std::ostream& os) const
void cmCableInstantiateCommand::WriteConfiguration() const
{
std::ostream& os = m_CableData->GetOutputStream();
cmCableData::Indentation indent = m_CableData->GetIndentation();
cmRegularExpression needCdataBlock("[&<>]");
os << std::endl
<< " <InstantiationSet>" << std::endl;
for(Elements::const_iterator e = m_Elements.begin();
e != m_Elements.end(); ++e)
os << indent << "<InstantiationSet>" << std::endl;
for(Entries::const_iterator e = m_Entries.begin();
e != m_Entries.end(); ++e)
{
os << " <Element>";
os << indent << " <Element>";
if(needCdataBlock.find(e->c_str()))
{
os << "<![CDATA[" << e->c_str() << "]]>";
@ -116,5 +44,5 @@ void cmCableInstantiateCommand::WriteConfiguration(std::ostream& os) const
}
os << "</Element>" << std::endl;
}
os << " </InstantiationSet>" << std::endl;
os << indent << "</InstantiationSet>" << std::endl;
}

View File

@ -17,7 +17,7 @@
#define cmCableInstantiateCommand_h
#include "cmStandardIncludes.h"
#include "cmCableCommand.h"
#include "cmCablePackageEntryCommand.h"
/** \class cmCableInstantiateCommand
* \brief Define a command that generates a rule for explicit template
@ -26,7 +26,7 @@
* cmCableInstantiateCommand is used to generate a rule in a CABLE
* configuration file to create explicit template instantiations.
*/
class cmCableInstantiateCommand : public cmCableCommand
class cmCableInstantiateCommand : public cmCablePackageEntryCommand
{
public:
/**
@ -37,24 +37,6 @@ public:
return new cmCableInstantiateCommand;
}
/**
* 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.
*/
@ -65,7 +47,7 @@ public:
*/
virtual const char* GetTerseDocumentation()
{
return "Define CABLE InstantiationSet.";
return "Define CABLE InstantiationSet in a package.";
}
/**
@ -74,27 +56,17 @@ public:
virtual const char* GetFullDocumentation()
{
return
"CABLE_INSTANTIATE(cable_config_file member1 member2 ...)\n"
"CABLE_INSTANTIATE(member1 member2 ...)\n"
"Generates an InstantiationSet in the CABLE configuration. It is\n"
"assumed that all members of the set are explicit instantiations of\n"
"template non-classes (functions, operators, etc).";
}
virtual void WriteConfiguration(std::ostream&) const;
virtual void WriteConfiguration() const;
cmTypeMacro(cmCableInstantiateCommand, cmCableCommand);
cmTypeMacro(cmCableInstantiateCommand, cmCablePackageCommand);
protected:
typedef std::vector<std::string> Elements;
/**
* The output file to which to write the configuration.
*/
cmCableData::OutputFile* m_OutputFile;
/**
* The elements describing the set of instantiations.
*/
Elements m_Elements;
typedef cmCablePackageEntryCommand::Entries Entries;
};

View File

@ -0,0 +1,55 @@
/*=========================================================================
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 "cmCableOpenNamespaceCommand.h"
#include "cmCacheManager.h"
// cmCableOpenNamespaceCommand
bool cmCableOpenNamespaceCommand::Invoke(std::vector<std::string>& args)
{
if(args.size() != 1)
{
this->SetError("called with incorrect number of arguments");
return false;
}
// This command needs to access the Cable data.
this->SetupCableData();
// The argument is the namespace name.
m_NamespaceName = args[0];
// Write the configuration for this command.
this->WriteNamespaceHeader();
// Ask the cable data to open the namespace.
m_CableData->OpenNamespace(m_NamespaceName);
return true;
}
/**
* Generate a CABLE Namespace open tag.
*/
void cmCableOpenNamespaceCommand::WriteNamespaceHeader() const
{
std::ostream& os = m_CableData->GetOutputStream();
cmCableData::Indentation indent = m_CableData->GetIndentation();
os << indent << "<Namespace name=\"" << m_NamespaceName.c_str()
<< "\">" << std::endl;
m_CableData->Indent();
}

View File

@ -0,0 +1,89 @@
/*=========================================================================
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 cmCableOpenNamespaceCommand_h
#define cmCableOpenNamespaceCommand_h
#include "cmStandardIncludes.h"
#include "cmCableCommand.h"
/** \class cmCableOpenNamespaceCommand
* \brief Define a command that opens a CABLE Namespace.
*
* cmCableOpenNamespaceCommand is used to generate CABLE Namespace
* open tags in the configuration file.
*/
class cmCableOpenNamespaceCommand : public cmCableCommand
{
public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
{
return new cmCableOpenNamespaceCommand;
}
/**
* 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 "CABLE_OPEN_NAMESPACE";}
/**
* Succinct documentation.
*/
virtual const char* GetTerseDocumentation()
{
return "Open a CABLE Namespace";
}
/**
* More documentation.
*/
virtual const char* GetFullDocumentation()
{
return
"CABLE_OPEN_NAMESPACE(namespace_name)\n"
"Open the given namespace in the generated configuration file.\n"
"There must be a matching CABLE_CLOSE_NAMESPACE(namespace_name)\n"
"called with the same name.";
}
cmTypeMacro(cmCableOpenNamespaceCommand, cmCableCommand);
private:
void WriteNamespaceHeader() const;
private:
/**
* The name of the namespace to setup.
*/
std::string m_NamespaceName;
};
#endif

View File

@ -0,0 +1,70 @@
/*=========================================================================
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 "cmCablePackageCommand.h"
#include "cmCacheManager.h"
// cmCablePackageCommand
bool cmCablePackageCommand::Invoke(std::vector<std::string>& args)
{
if(args.size() != 1)
{
this->SetError("called with incorrect number of arguments");
return false;
}
// This command needs to access the Cable data.
this->SetupCableData();
// The argument is the package name.
m_PackageName = args[0];
// Ask the cable data to begin the package. This may call another
// cmCablePackageCommand's WritePackageFooter().
m_CableData->BeginPackage(this);
// Write the configuration for this command.
// The cmCableData::EndPackage() later on will call WritePackageFooter().
this->WritePackageHeader();
return true;
}
/**
* Write a CABLE package header.
*/
void cmCablePackageCommand::WritePackageHeader() const
{
std::ostream& os = m_CableData->GetOutputStream();
cmCableData::Indentation indent = m_CableData->GetIndentation();
os << indent << "<Package name=\"" << m_PackageName.c_str() << "\">"
<< std::endl;
m_CableData->Indent();
}
/**
* Write a CABLE package footer.
*/
void cmCablePackageCommand::WritePackageFooter() const
{
m_CableData->Unindent();
std::ostream& os = m_CableData->GetOutputStream();
cmCableData::Indentation indent = m_CableData->GetIndentation();
os << indent << "</Package> <!-- \"" << m_PackageName.c_str() << "\" -->"
<< std::endl;
}

View File

@ -0,0 +1,85 @@
/*=========================================================================
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 cmCablePackageCommand_h
#define cmCablePackageCommand_h
#include "cmStandardIncludes.h"
#include "cmCableCommand.h"
/** \class cmCablePackageCommand
* \brief Define a command that begins a CABLE Package definition.
*
* cmCablePackageCommand is used to generate a new CABLE Package.
* All subsequent commands that require a package will refer to that
* setup by this command, until another package is started.
*/
class cmCablePackageCommand : public cmCableCommand
{
public:
cmCablePackageCommand() {}
virtual ~cmCablePackageCommand() {}
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
{
return new cmCablePackageCommand;
}
/**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
virtual bool Invoke(std::vector<std::string>& args);
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual const char* GetName() { return "CABLE_PACKAGE";}
/**
* Succinct documentation.
*/
virtual const char* GetTerseDocumentation()
{
return "Begin a package definition.";
}
/**
* More documentation.
*/
virtual const char* GetFullDocumentation()
{
return
"CABLE_PACKAGE(package_name)\n"
"Close current package (if any), and open a new package definition.";
}
void WritePackageHeader() const;
void WritePackageFooter() const;
cmTypeMacro(cmCablePackageCommand, cmCableCommand);
private:
/**
* The name of the package.
*/
std::string m_PackageName;
};
#endif

View File

@ -0,0 +1,42 @@
/*=========================================================================
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 "cmCablePackageEntryCommand.h"
#include "cmCacheManager.h"
// cmCablePackageEntryCommand
bool cmCablePackageEntryCommand::Invoke(std::vector<std::string>& args)
{
if(args.size() < 1)
{
this->SetError("called with incorrect number of arguments");
return false;
}
// This command instance needs to use the cmCableData instance.
this->SetupCableData();
// The arguments are the entries to the Pacakge.
for(std::vector<std::string>::const_iterator arg = args.begin();
arg != args.end(); ++arg)
{
m_Entries.push_back(*arg);
}
// Write this command's configuration.
this->WriteConfiguration();
return true;
}

View File

@ -0,0 +1,57 @@
/*=========================================================================
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 cmCablePackageEntryCommand_h
#define cmCablePackageEntryCommand_h
#include "cmStandardIncludes.h"
#include "cmCableCommand.h"
/** \class cmCablePackageEntryCommand
* \brief Superclass to all CABLE Package entry generation commands.
*
* cmCablePackageEntryCommand implements the Invoke method of a cmCommand
* to save the arguments as a vector of entries to a CABLE Package. The
* Invoke then calls the virtual WriteConfiguration() so that the subclass
* can generate the configuration code for its particular type of Package
* entry.
*/
class cmCablePackageEntryCommand : public cmCableCommand
{
public:
cmCablePackageEntryCommand() {}
virtual ~cmCablePackageEntryCommand() {}
/**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
virtual bool Invoke(std::vector<std::string>& args);
cmTypeMacro(cmCablePackageEntryCommand, cmCableCommand);
virtual void WriteConfiguration() const =0;
protected:
typedef std::vector<std::string> Entries;
/**
* The package entries.
*/
Entries m_Entries;
};
#endif

View File

@ -0,0 +1,37 @@
/*=========================================================================
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 "cmCableSourceFilesCommand.h"
#include "cmCacheManager.h"
/**
* Write the CABLE configuration code to indicate header dependencies for
* a package.
*/
void cmCableSourceFilesCommand::WriteConfiguration() const
{
std::ostream& os = m_CableData->GetOutputStream();
cmCableData::Indentation indent = m_CableData->GetIndentation();
cmRegularExpression needCdataBlock("[&<>]");
os << indent << "<Headers>" << std::endl;
for(Entries::const_iterator f = m_Entries.begin();
f != m_Entries.end(); ++f)
{
os << indent << " <File name=\"" << f->c_str() << ".h\"/>" << std::endl;
}
os << indent << "</Headers>" << std::endl;
}

View File

@ -0,0 +1,71 @@
/*=========================================================================
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 cmCableSourceFilesCommand_h
#define cmCableSourceFilesCommand_h
#include "cmStandardIncludes.h"
#include "cmCablePackageEntryCommand.h"
/** \class cmCableSourceFilesCommand
* \brief Define a command that generates a rule for a CABLE Headers block.
*
* cmCableSourceFilesCommand is used to generate a rule in a CABLE
* configuration file to setup a Package's include files.
*/
class cmCableSourceFilesCommand : public cmCablePackageEntryCommand
{
public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
{
return new cmCableSourceFilesCommand;
}
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual const char* GetName() { return "CABLE_SOURCE_FILES";}
/**
* Succinct documentation.
*/
virtual const char* GetTerseDocumentation()
{
return "Define CABLE header file dependencies in a package.";
}
/**
* More documentation.
*/
virtual const char* GetFullDocumentation()
{
return
"CABLE_SOURCE_FILES(file1 file2 ...)"
"Generates a Package's Headers block in the CABLE configuration.";
}
virtual void WriteConfiguration() const;
cmTypeMacro(cmCableSourceFilesCommand, cmCableCommand);
protected:
typedef cmCablePackageEntryCommand::Entries Entries;
};
#endif

View File

@ -0,0 +1,45 @@
/*=========================================================================
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 "cmCableWrapCommand.h"
#include "cmCacheManager.h"
/**
* Write the CABLE configuration code to define this WrapperSet.
*/
void cmCableWrapCommand::WriteConfiguration() const
{
std::ostream& os = m_CableData->GetOutputStream();
cmCableData::Indentation indent = m_CableData->GetIndentation();
cmRegularExpression needCdataBlock("[&<>]");
os << indent << "<WrapperSet>" << std::endl;
for(Entries::const_iterator e = m_Entries.begin();
e != m_Entries.end(); ++e)
{
os << indent << " <Element>";
if(needCdataBlock.find(e->c_str()))
{
os << "<![CDATA[" << e->c_str() << "]]>";
}
else
{
os << e->c_str();
}
os << "</Element>" << std::endl;
}
os << indent << "</WrapperSet>" << std::endl;
}

View File

@ -0,0 +1,69 @@
/*=========================================================================
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 cmCableWrapCommand_h
#define cmCableWrapCommand_h
#include "cmStandardIncludes.h"
#include "cmCablePackageEntryCommand.h"
/** \class cmCableWrapCommand
* \brief Define a command that generates a rule for CABLE-generated wrappers.
*
* cmCableWrapCommand is used to generate a rule in a CABLE
* configuration file to create type wrappers.
*/
class cmCableWrapCommand : public cmCablePackageEntryCommand
{
public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
{
return new cmCableWrapCommand;
}
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual const char* GetName() { return "CABLE_WRAP";}
/**
* Succinct documentation.
*/
virtual const char* GetTerseDocumentation()
{
return "Define CABLE WrapSet in a package.";
}
/**
* More documentation.
*/
virtual const char* GetFullDocumentation()
{
return
"CABLE_WRAP(member1 member2 ...)\n"
"Generates a WrapSet in the CABLE configuration.";
}
virtual void WriteConfiguration() const;
cmTypeMacro(cmCableWrapCommand, cmCablePackageCommand);
};
#endif

View File

@ -27,6 +27,12 @@
#include "cmCableCommand.cxx"
#include "cmCableData.cxx"
#include "cmCableDefineSetCommand.cxx"
#include "cmCableOpenNamespaceCommand.cxx"
#include "cmCableCloseNamespaceCommand.cxx"
#include "cmCablePackageCommand.cxx"
#include "cmCablePackageEntryCommand.cxx"
#include "cmCableSourceFilesCommand.cxx"
#include "cmCableWrapCommand.cxx"
#include "cmCableInstantiateCommand.cxx"
#include "cmCableInstantiateClassCommand.cxx"
#include "cmFindFileCommand.cxx"
@ -58,6 +64,11 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands)
commands.push_back(new cmWin32LibrariesCommand);
commands.push_back(new cmConfigureFileNoAutoconf);
commands.push_back(new cmCableDefineSetCommand);
commands.push_back(new cmCableOpenNamespaceCommand);
commands.push_back(new cmCableCloseNamespaceCommand);
commands.push_back(new cmCablePackageCommand);
commands.push_back(new cmCableSourceFilesCommand);
commands.push_back(new cmCableWrapCommand);
commands.push_back(new cmCableInstantiateCommand);
commands.push_back(new cmCableInstantiateClassCommand);
commands.push_back(new cmFindFileCommand);