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. * Ensure that this cmCableCommand has a valid m_CableData pointer.
*/ */

View File

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

View File

@ -16,104 +16,196 @@
#include "cmCableData.h" #include "cmCableData.h"
#include "cmCacheManager.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() cmCableData::~cmCableData()
{ {
for(OutputFiles::iterator i = m_OutputFiles.begin(); // End last package, if any.
i != m_OutputFiles.end(); ++i) 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 void cmCableData::CloseOutputFile()
::OutputFile(std::string file, const cmCableCommand* command):
m_FileStream(file.c_str()),
m_FirstReferencingCommand(command),
m_LastReferencingCommand(command)
{ {
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 void cmCableData::WriteConfigurationHeader()
::~OutputFile()
{ {
if(m_FileStream) m_OutputFile << m_Indentation << "<?xml version=\"1.0\"?>" << std::endl
m_FileStream.close(); << m_Indentation << "<CableConfiguration>" << std::endl;
this->Indent();
} }
/** /**
* Get the output stream associated with this OutputFile. * Write a CABLE configuration file footer.
*/ */
std::ostream& void cmCableData::WriteConfigurationFooter()
cmCableData::OutputFile
::GetStream()
{ {
return m_FileStream; this->Unindent();
m_OutputFile << m_Indentation << "</CableConfiguration>" << std::endl;
} }
/**
* Print indentation spaces.
*/
void void
cmCableData::OutputFile cmCableData::Indentation
::SetLastReferencingCommand(const cmCableCommand* command) ::Print(std::ostream& os) const
{ {
m_LastReferencingCommand = command; if(m_Indent <= 0)
} { return; }
// Use blocks of 8 spaces to speed up big indents.
bool unsigned int blockCount = m_Indent >> 3;
cmCableData::OutputFile unsigned int singleCount = m_Indent & 7;
::FirstReferencingCommandIs(const cmCableCommand* command) const while(blockCount-- > 0)
{ {
return (m_FirstReferencingCommand == command); os << " ";
} }
while(singleCount-- > 0)
{
bool os << " ";
cmCableData::OutputFile }
::LastReferencingCommandIs(const cmCableCommand* command) const
{
return (m_LastReferencingCommand == command);
} }
/** /**
* Get the OutputFile for the file with the given name. Automatically * Open a namespace with the given name.
* maintains first and last referencing commands.
*/ */
cmCableData::OutputFile* void cmCableData::OpenNamespace(const std::string& name)
cmCableData::GetOutputFile(const std::string& name,
const cmCableCommand* command)
{ {
OutputFiles::iterator f = m_OutputFiles.find(name); m_NamespaceStack.push_back(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; * Close the current namespace, checking whether it has the given name.
*/
return outputFile; void cmCableData::CloseNamespace(const std::string& name)
} {
if(m_NamespaceStack.empty())
// The file has already been opened. Set the command as the last {
// referencing command. cmSystemTools::Error("Unbalanced close-namespace = ", name.c_str());
f->second->SetLastReferencingCommand(command); return;
}
return f->second; 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" #include "cmCommand.h"
class cmCableCommand; class cmCableCommand;
class cmCablePackageCommand;
/** \class cmCableData /** \class cmCableData
* \brief Hold data in one location for all cmCableCommand subclasses. * \brief Hold data in one location for all cmCableCommand subclasses.
@ -27,12 +28,7 @@ class cmCableCommand;
class cmCableData class cmCableData
{ {
public: public:
/** cmCableData(const cmCableCommand*);
* The cmCableData instance is owned by one cmCableCommand, which is given
* to this constructor.
*/
cmCableData(const cmCableCommand* owner): m_Owner(owner) {}
~cmCableData(); ~cmCableData();
/** /**
@ -41,41 +37,73 @@ public:
*/ */
bool OwnerIs(const cmCableCommand* owner) const bool OwnerIs(const cmCableCommand* owner) const
{ return (owner == m_Owner); } { 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 * Class to simplify indentation printing.
* first and last commands that reference it so that they can write the
* header/footer lines, if necessary.
*/ */
class OutputFile class Indentation
{ {
public: public:
OutputFile(std::string, const cmCableCommand*); Indentation(int indent): m_Indent(indent) {}
~OutputFile(); void Print(std::ostream& os) const;
std::ostream& GetStream(); Indentation Next() const { return Indentation(m_Indent+2); }
void SetLastReferencingCommand(const cmCableCommand*); Indentation Previous() const { return Indentation(m_Indent-2); }
bool FirstReferencingCommandIs(const cmCableCommand*) const;
bool LastReferencingCommandIs(const cmCableCommand*) const;
private: private:
std::ofstream m_FileStream; int m_Indent;
const cmCableCommand* m_FirstReferencingCommand;
const cmCableCommand* m_LastReferencingCommand;
}; };
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: private:
typedef std::map<std::string, OutputFile*> OutputFiles;
/** /**
* The cmCableCommand which created this instance of cmCableCommand. * The cmCableCommand which created this instance of cmCableCommand.
*/ */
const cmCableCommand* m_Owner; 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 #endif

View File

@ -28,6 +28,9 @@ bool cmCableDefineSetCommand::Invoke(std::vector<std::string>& args)
return false; return false;
} }
// This command needs access to the Cable data.
this->SetupCableData();
std::vector<std::string>::const_iterator arg = args.begin(); std::vector<std::string>::const_iterator arg = args.begin();
// The first argument is the name of the set. // 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)); m_Elements.push_back(Element(this->GenerateTag(*arg), *arg));
} }
// Write this command's configuration output.
this->WriteConfiguration();
return true; return true;
} }
@ -46,15 +52,20 @@ bool cmCableDefineSetCommand::Invoke(std::vector<std::string>& args)
/** /**
* Write the CABLE configuration code to define this Set. * Write the CABLE configuration code to define this Set.
*/ */
void cmCableDefineSetCommand::WriteConfiguration(std::ostream& os) const void cmCableDefineSetCommand::WriteConfiguration() const
{ {
cmRegularExpression needCdataBlock("[&<>]"); 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(); for(Elements::const_iterator e = m_Elements.begin();
e != m_Elements.end(); ++e) e != m_Elements.end(); ++e)
{ {
os << " <Element"; os << indent << " <Element";
// Only output the tag if it is not the empty string. // Only output the tag if it is not the empty string.
if(e->first.length() > 0) if(e->first.length() > 0)
{ {
@ -71,7 +82,7 @@ void cmCableDefineSetCommand::WriteConfiguration(std::ostream& os) const
} }
os << "</Element>" << std::endl; 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. * to makefiles located in subdirectories.
*/ */
virtual bool IsInherited() virtual bool IsInherited()
{return true;} { return true; }
/** /**
* The name of the command as specified in CMakeList.txt. * 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)."; "commands by a '$' immediately followed by the set name (ex. $SetName).";
} }
virtual void WriteConfiguration(std::ostream&) const;
cmTypeMacro(cmCableDefineSetCommand, cmCableCommand); cmTypeMacro(cmCableDefineSetCommand, cmCableCommand);
private: private:
void WriteConfiguration() const;
std::string GenerateTag(const std::string&) const; std::string GenerateTag(const std::string&) const;
private: private:
typedef std::pair<std::string, std::string> Element; typedef std::pair<std::string, std::string> Element;
typedef std::vector<Element> Elements; typedef std::vector<Element> Elements;

View File

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

View File

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

View File

@ -16,96 +16,24 @@
#include "cmCableInstantiateCommand.h" #include "cmCableInstantiateCommand.h"
#include "cmCacheManager.h" #include "cmCacheManager.h"
#include "cmCableDefineSetCommand.h"
#include "cmRegularExpression.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. * 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("[&<>]"); cmRegularExpression needCdataBlock("[&<>]");
os << std::endl os << indent << "<InstantiationSet>" << std::endl;
<< " <InstantiationSet>" << std::endl; for(Entries::const_iterator e = m_Entries.begin();
for(Elements::const_iterator e = m_Elements.begin(); e != m_Entries.end(); ++e)
e != m_Elements.end(); ++e)
{ {
os << " <Element>"; os << indent << " <Element>";
if(needCdataBlock.find(e->c_str())) if(needCdataBlock.find(e->c_str()))
{ {
os << "<![CDATA[" << e->c_str() << "]]>"; os << "<![CDATA[" << e->c_str() << "]]>";
@ -116,5 +44,5 @@ void cmCableInstantiateCommand::WriteConfiguration(std::ostream& os) const
} }
os << "</Element>" << std::endl; os << "</Element>" << std::endl;
} }
os << " </InstantiationSet>" << std::endl; os << indent << "</InstantiationSet>" << std::endl;
} }

View File

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

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 "cmCableCommand.cxx"
#include "cmCableData.cxx" #include "cmCableData.cxx"
#include "cmCableDefineSetCommand.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 "cmCableInstantiateCommand.cxx"
#include "cmCableInstantiateClassCommand.cxx" #include "cmCableInstantiateClassCommand.cxx"
#include "cmFindFileCommand.cxx" #include "cmFindFileCommand.cxx"
@ -58,6 +64,11 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands)
commands.push_back(new cmWin32LibrariesCommand); commands.push_back(new cmWin32LibrariesCommand);
commands.push_back(new cmConfigureFileNoAutoconf); commands.push_back(new cmConfigureFileNoAutoconf);
commands.push_back(new cmCableDefineSetCommand); 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 cmCableInstantiateCommand);
commands.push_back(new cmCableInstantiateClassCommand); commands.push_back(new cmCableInstantiateClassCommand);
commands.push_back(new cmFindFileCommand); commands.push_back(new cmFindFileCommand);