diff options
author | Brad King <brad.king@kitware.com> | 2001-03-01 21:47:05 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2001-03-01 21:47:05 (GMT) |
commit | dc72655414eb8a611524b6480dad92d46b08fecb (patch) | |
tree | eae01169b53d5e67156e5562ed53b4e447947658 /Source | |
parent | af30fe67458fd26054696ce018f7ae6faaebcca4 (diff) | |
download | CMake-dc72655414eb8a611524b6480dad92d46b08fecb.zip CMake-dc72655414eb8a611524b6480dad92d46b08fecb.tar.gz CMake-dc72655414eb8a611524b6480dad92d46b08fecb.tar.bz2 |
ENH: Change to new CABLE command architecture. CABLE configuration code is now generated on the first pass, during the Invoke() calls.
Diffstat (limited to 'Source')
23 files changed, 1016 insertions, 232 deletions
diff --git a/Source/cmCableCloseNamespaceCommand.cxx b/Source/cmCableCloseNamespaceCommand.cxx new file mode 100644 index 0000000..9e97f82 --- /dev/null +++ b/Source/cmCableCloseNamespaceCommand.cxx @@ -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; +} diff --git a/Source/cmCableCloseNamespaceCommand.h b/Source/cmCableCloseNamespaceCommand.h new file mode 100644 index 0000000..1b2d45b --- /dev/null +++ b/Source/cmCableCloseNamespaceCommand.h @@ -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 diff --git a/Source/cmCableCommand.cxx b/Source/cmCableCommand.cxx index 29cfddc..260be4e 100644 --- a/Source/cmCableCommand.cxx +++ b/Source/cmCableCommand.cxx @@ -40,25 +40,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. */ void cmCableCommand::SetupCableData() diff --git a/Source/cmCableCommand.h b/Source/cmCableCommand.h index 60e0ed9..216b65f 100644 --- a/Source/cmCableCommand.h +++ b/Source/cmCableCommand.h @@ -37,9 +37,6 @@ public: cmCableCommand(); virtual ~cmCableCommand(); - void WriteConfigurationHeader(std::ostream&) const; - void WriteConfigurationFooter(std::ostream&) const; - cmTypeMacro(cmCableCommand, cmCommand); protected: void SetupCableData(); diff --git a/Source/cmCableData.cxx b/Source/cmCableData.cxx index 15954b9..02fd0f6 100644 --- a/Source/cmCableData.cxx +++ b/Source/cmCableData.cxx @@ -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 +{ + 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 << " "; + } +} + + +/** + * Open a namespace with the given name. + */ +void cmCableData::OpenNamespace(const std::string& name) { - m_LastReferencingCommand = command; + m_NamespaceStack.push_back(name); } -bool -cmCableData::OutputFile -::FirstReferencingCommandIs(const cmCableCommand* command) const +/** + * Close the current namespace, checking whether it has the given name. + */ +void cmCableData::CloseNamespace(const std::string& name) { - return (m_FirstReferencingCommand == command); + 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(); } -bool -cmCableData::OutputFile -::LastReferencingCommandIs(const cmCableCommand* command) const +/** + * Begin a new package definition. If there is a current one, it + * will be ended. + */ +void cmCableData::BeginPackage(cmCablePackageCommand* command) { - return (m_LastReferencingCommand == 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(); } /** - * Get the OutputFile for the file with the given name. Automatically - * maintains first and last referencing commands. + * End a package definition. */ -cmCableData::OutputFile* -cmCableData::GetOutputFile(const std::string& name, - const cmCableCommand* command) +void cmCableData::EndPackage() { - 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()) + // Make sure we have an open package. + if(!m_Package) { - OutputFile* outputFile = new OutputFile(name, command); - m_OutputFiles[name] = outputFile; - - return outputFile; + return; } - // The file has already been opened. Set the command as the last - // referencing command. - f->second->SetLastReferencingCommand(command); + // 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(); - return f->second; + // 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; } diff --git a/Source/cmCableData.h b/Source/cmCableData.h index ba9d238..53ff412 100644 --- a/Source/cmCableData.h +++ b/Source/cmCableData.h @@ -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; } -private: - typedef std::map<std::string, OutputFile*> OutputFiles; + void OpenNamespace(const std::string&); + void CloseNamespace(const std::string&); + + void BeginPackage(cmCablePackageCommand*); + void EndPackage(); +private: /** * The cmCableCommand which created this instance of cmCableCommand. */ const cmCableCommand* m_Owner; /** - * Hold all output streams by file name. + * Current indentation for output. + */ + Indentation m_Indentation; + + /** + * The output file to which the configuration is written. + */ + std::ofstream m_OutputFile; + + /** + * The stack of namespaces. */ - OutputFiles m_OutputFiles; + 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 diff --git a/Source/cmCableDefineSetCommand.cxx b/Source/cmCableDefineSetCommand.cxx index 95f0218..2c3f333 100644 --- a/Source/cmCableDefineSetCommand.cxx +++ b/Source/cmCableDefineSetCommand.cxx @@ -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; } diff --git a/Source/cmCableDefineSetCommand.h b/Source/cmCableDefineSetCommand.h index 8d002cf..618990b 100644 --- a/Source/cmCableDefineSetCommand.h +++ b/Source/cmCableDefineSetCommand.h @@ -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; diff --git a/Source/cmCableInstantiateClassCommand.cxx b/Source/cmCableInstantiateClassCommand.cxx index ba1f364..939f530 100644 --- a/Source/cmCableInstantiateClassCommand.cxx +++ b/Source/cmCableInstantiateClassCommand.cxx @@ -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; } diff --git a/Source/cmCableInstantiateClassCommand.h b/Source/cmCableInstantiateClassCommand.h index 1162992..b592cd7 100644 --- a/Source/cmCableInstantiateClassCommand.h +++ b/Source/cmCableInstantiateClassCommand.h @@ -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; }; diff --git a/Source/cmCableInstantiateCommand.cxx b/Source/cmCableInstantiateCommand.cxx index 705c313..629e6da 100644 --- a/Source/cmCableInstantiateCommand.cxx +++ b/Source/cmCableInstantiateCommand.cxx @@ -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; } diff --git a/Source/cmCableInstantiateCommand.h b/Source/cmCableInstantiateCommand.h index d61eb77..4f8f2bd 100644 --- a/Source/cmCableInstantiateCommand.h +++ b/Source/cmCableInstantiateCommand.h @@ -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: /** @@ -38,24 +38,6 @@ public: } /** - * 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 "CABLE_INSTANTIATE";} @@ -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; }; diff --git a/Source/cmCableOpenNamespaceCommand.cxx b/Source/cmCableOpenNamespaceCommand.cxx new file mode 100644 index 0000000..1ed9269 --- /dev/null +++ b/Source/cmCableOpenNamespaceCommand.cxx @@ -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(); +} diff --git a/Source/cmCableOpenNamespaceCommand.h b/Source/cmCableOpenNamespaceCommand.h new file mode 100644 index 0000000..49dda6c --- /dev/null +++ b/Source/cmCableOpenNamespaceCommand.h @@ -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 diff --git a/Source/cmCablePackageCommand.cxx b/Source/cmCablePackageCommand.cxx new file mode 100644 index 0000000..a6787e2 --- /dev/null +++ b/Source/cmCablePackageCommand.cxx @@ -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; +} + diff --git a/Source/cmCablePackageCommand.h b/Source/cmCablePackageCommand.h new file mode 100644 index 0000000..8546556 --- /dev/null +++ b/Source/cmCablePackageCommand.h @@ -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 diff --git a/Source/cmCablePackageEntryCommand.cxx b/Source/cmCablePackageEntryCommand.cxx new file mode 100644 index 0000000..5930272 --- /dev/null +++ b/Source/cmCablePackageEntryCommand.cxx @@ -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; +} diff --git a/Source/cmCablePackageEntryCommand.h b/Source/cmCablePackageEntryCommand.h new file mode 100644 index 0000000..e4ef3bd --- /dev/null +++ b/Source/cmCablePackageEntryCommand.h @@ -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 diff --git a/Source/cmCableSourceFilesCommand.cxx b/Source/cmCableSourceFilesCommand.cxx new file mode 100644 index 0000000..d1dd40d --- /dev/null +++ b/Source/cmCableSourceFilesCommand.cxx @@ -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; +} diff --git a/Source/cmCableSourceFilesCommand.h b/Source/cmCableSourceFilesCommand.h new file mode 100644 index 0000000..24f185c --- /dev/null +++ b/Source/cmCableSourceFilesCommand.h @@ -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 diff --git a/Source/cmCableWrapCommand.cxx b/Source/cmCableWrapCommand.cxx new file mode 100644 index 0000000..c42f81f --- /dev/null +++ b/Source/cmCableWrapCommand.cxx @@ -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; +} diff --git a/Source/cmCableWrapCommand.h b/Source/cmCableWrapCommand.h new file mode 100644 index 0000000..9054795 --- /dev/null +++ b/Source/cmCableWrapCommand.h @@ -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 diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index b9d2508..d529b09 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -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); |