diff --git a/Source/cmCableCloseNamespaceCommand.cxx b/Source/cmCableCloseNamespaceCommand.cxx new file mode 100644 index 000000000..9e97f8222 --- /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& 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 << " " << std::endl; +} diff --git a/Source/cmCableCloseNamespaceCommand.h b/Source/cmCableCloseNamespaceCommand.h new file mode 100644 index 000000000..1b2d45beb --- /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& 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 29cfddc29..260be4ee5 100644 --- a/Source/cmCableCommand.cxx +++ b/Source/cmCableCommand.cxx @@ -39,25 +39,6 @@ cmCableCommand::~cmCableCommand() } -/** - * Write a CABLE configuration file header. - */ -void cmCableCommand::WriteConfigurationHeader(std::ostream& os) const -{ - os << "" << std::endl - << "" << std::endl; -} - - -/** - * Write a CABLE configuration file footer. - */ -void cmCableCommand::WriteConfigurationFooter(std::ostream& os) const -{ - os << "" << std::endl; -} - - /** * Ensure that this cmCableCommand has a valid m_CableData pointer. */ diff --git a/Source/cmCableCommand.h b/Source/cmCableCommand.h index 60e0ed9ec..216b65f35 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 15954b995..02fd0f653 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 << "" << std::endl + << m_Indentation << "" << 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 << "" << 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; } diff --git a/Source/cmCableData.h b/Source/cmCableData.h index ba9d23889..53ff41210 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; } + + void OpenNamespace(const std::string&); + void CloseNamespace(const std::string&); + + void BeginPackage(cmCablePackageCommand*); + void EndPackage(); private: - typedef std::map 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 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 95f02183c..2c3f3333e 100644 --- a/Source/cmCableDefineSetCommand.cxx +++ b/Source/cmCableDefineSetCommand.cxx @@ -28,6 +28,9 @@ bool cmCableDefineSetCommand::Invoke(std::vector& args) return false; } + // This command needs access to the Cable data. + this->SetupCableData(); + std::vector::const_iterator arg = args.begin(); // The first argument is the name of the set. @@ -39,6 +42,9 @@ bool cmCableDefineSetCommand::Invoke(std::vector& 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& args) /** * Write the CABLE configuration code to define this Set. */ -void cmCableDefineSetCommand::WriteConfiguration(std::ostream& os) const +void cmCableDefineSetCommand::WriteConfiguration() const { cmRegularExpression needCdataBlock("[&<>]"); - os << " " << 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 << "" << std::endl; for(Elements::const_iterator e = m_Elements.begin(); e != m_Elements.end(); ++e) { - os << " first.length() > 0) { @@ -71,7 +82,7 @@ void cmCableDefineSetCommand::WriteConfiguration(std::ostream& os) const } os << "" << std::endl; } - os << " " << std::endl; + os << indent << "" << std::endl; } diff --git a/Source/cmCableDefineSetCommand.h b/Source/cmCableDefineSetCommand.h index 8d002cf5a..618990bd6 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 Element; typedef std::vector Elements; diff --git a/Source/cmCableInstantiateClassCommand.cxx b/Source/cmCableInstantiateClassCommand.cxx index ba1f36469..939f53074 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 - << " " << std::endl; - for(Elements::const_iterator e = m_Elements.begin(); - e != m_Elements.end(); ++e) + os << indent << "" << std::endl; + for(Entries::const_iterator e = m_Entries.begin(); + e != m_Entries.end(); ++e) { - os << " class "; + os << indent << " class "; if(needCdataBlock.find(e->c_str())) { os << "c_str() << "]]>"; @@ -43,5 +45,5 @@ void cmCableInstantiateClassCommand::WriteConfiguration(std::ostream& os) const } os << "" << std::endl; } - os << " " << std::endl; + os << indent << "" << std::endl; } diff --git a/Source/cmCableInstantiateClassCommand.h b/Source/cmCableInstantiateClassCommand.h index 11629924c..b592cd7a2 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 705c313f4..629e6dafe 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& 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::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& usedCommands = - m_Makefile->GetUsedCommands(); - for(std::vector::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 - << " " << std::endl; - for(Elements::const_iterator e = m_Elements.begin(); - e != m_Elements.end(); ++e) + os << indent << "" << std::endl; + for(Entries::const_iterator e = m_Entries.begin(); + e != m_Entries.end(); ++e) { - os << " "; + os << indent << " "; if(needCdataBlock.find(e->c_str())) { os << "c_str() << "]]>"; @@ -116,5 +44,5 @@ void cmCableInstantiateCommand::WriteConfiguration(std::ostream& os) const } os << "" << std::endl; } - os << " " << std::endl; + os << indent << "" << std::endl; } diff --git a/Source/cmCableInstantiateCommand.h b/Source/cmCableInstantiateCommand.h index d61eb7702..4f8f2bdeb 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: /** @@ -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& 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 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 000000000..1ed9269a6 --- /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& 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 << "" << std::endl; + m_CableData->Indent(); +} diff --git a/Source/cmCableOpenNamespaceCommand.h b/Source/cmCableOpenNamespaceCommand.h new file mode 100644 index 000000000..49dda6c07 --- /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& 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 000000000..a6787e2ad --- /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& 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 << "" + << 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 << " " + << std::endl; +} + diff --git a/Source/cmCablePackageCommand.h b/Source/cmCablePackageCommand.h new file mode 100644 index 000000000..854655600 --- /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& 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 000000000..593027214 --- /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& 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::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 000000000..e4ef3bd31 --- /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& args); + + cmTypeMacro(cmCablePackageEntryCommand, cmCableCommand); + + virtual void WriteConfiguration() const =0; +protected: + typedef std::vector Entries; + + /** + * The package entries. + */ + Entries m_Entries; +}; + + + +#endif diff --git a/Source/cmCableSourceFilesCommand.cxx b/Source/cmCableSourceFilesCommand.cxx new file mode 100644 index 000000000..d1dd40dfc --- /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 << "" << std::endl; + for(Entries::const_iterator f = m_Entries.begin(); + f != m_Entries.end(); ++f) + { + os << indent << " c_str() << ".h\"/>" << std::endl; + } + os << indent << "" << std::endl; +} diff --git a/Source/cmCableSourceFilesCommand.h b/Source/cmCableSourceFilesCommand.h new file mode 100644 index 000000000..24f185c6e --- /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 000000000..c42f81fd1 --- /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 << "" << std::endl; + for(Entries::const_iterator e = m_Entries.begin(); + e != m_Entries.end(); ++e) + { + os << indent << " "; + if(needCdataBlock.find(e->c_str())) + { + os << "c_str() << "]]>"; + } + else + { + os << e->c_str(); + } + os << "" << std::endl; + } + os << indent << "" << std::endl; +} diff --git a/Source/cmCableWrapCommand.h b/Source/cmCableWrapCommand.h new file mode 100644 index 000000000..9054795af --- /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 b9d250872..d529b092f 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& 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);