diff options
author | Brad King <brad.king@kitware.com> | 2001-02-27 21:28:56 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2001-02-27 21:28:56 (GMT) |
commit | 711c652edbc47e123a22878e39a4944b31e4708e (patch) | |
tree | 771e17e651b09144265b41fae290aa779dfa7d82 /Source | |
parent | 41d198ed40fcae8cbd2fae163af48d3c518c9628 (diff) | |
download | CMake-711c652edbc47e123a22878e39a4944b31e4708e.zip CMake-711c652edbc47e123a22878e39a4944b31e4708e.tar.gz CMake-711c652edbc47e123a22878e39a4944b31e4708e.tar.bz2 |
ENH: Implemented automatic tag generation for CABIL_DEFINE_SET command. Added tag output to WriteConfiguration methods. Added CABIL_INSTANTIATE_CLASS command to generate explicit class template instantiation configuration output.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmCableCommand.h | 10 | ||||
-rw-r--r-- | Source/cmCableDefineSetCommand.cxx | 104 | ||||
-rw-r--r-- | Source/cmCableDefineSetCommand.h | 12 | ||||
-rw-r--r-- | Source/cmCableInstantiateClassCommand.cxx | 47 | ||||
-rw-r--r-- | Source/cmCableInstantiateClassCommand.h | 75 | ||||
-rw-r--r-- | Source/cmCableInstantiateCommand.cxx | 14 | ||||
-rw-r--r-- | Source/cmCableInstantiateCommand.h | 9 | ||||
-rw-r--r-- | Source/cmCommands.cxx | 2 |
8 files changed, 264 insertions, 9 deletions
diff --git a/Source/cmCableCommand.h b/Source/cmCableCommand.h index b00c199..211b70e 100644 --- a/Source/cmCableCommand.h +++ b/Source/cmCableCommand.h @@ -21,7 +21,15 @@ #include "cmCabilData.h" /** \class cmCabilCommand - * \brief Superclass for all CABIL_ command classes. + * \brief Superclass for all cmCabil command classes. + * + * cmCabilCommand is the superclass for all CABIL-related commands. + * The C++ Automated Bindings for Interpreted Languages (CABIL, + * pronounced "sawbill") tool is configured using an XML input file. + * The input format is quite flexible, but XML is hard for humans to + * write by hand. The CABIL commands in CMake are designed to simplify + * the interface with only a small loss in functionality. These commands + * can be used to automatically generate CABIL configuration files. */ class cmCabilCommand : public cmCommand { diff --git a/Source/cmCableDefineSetCommand.cxx b/Source/cmCableDefineSetCommand.cxx index e1f1377..725ea0e 100644 --- a/Source/cmCableDefineSetCommand.cxx +++ b/Source/cmCableDefineSetCommand.cxx @@ -16,6 +16,8 @@ #include "cmCabilDefineSetCommand.h" #include "cmCacheManager.h" +#include "cmRegularExpression.h" + // cmCabilDefineSetCommand bool cmCabilDefineSetCommand::Invoke(std::vector<std::string>& args) @@ -34,7 +36,7 @@ bool cmCabilDefineSetCommand::Invoke(std::vector<std::string>& args) // The rest of the arguments are the elements to be placed in the set. for(; arg != args.end(); ++arg) { - m_Elements.push_back(*arg); + m_Elements.push_back(Element(this->GenerateTag(*arg), *arg)); } return true; @@ -46,11 +48,109 @@ bool cmCabilDefineSetCommand::Invoke(std::vector<std::string>& args) */ void cmCabilDefineSetCommand::WriteConfiguration(std::ostream& os) const { + cmRegularExpression needCdataBlock("[&<>]"); + os << " <Set name=\"" << m_SetName.c_str() << "\">" << std::endl; for(Elements::const_iterator e = m_Elements.begin(); e != m_Elements.end(); ++e) { - os << " <Element>" << e->c_str() << "</Element>" << std::endl; + os << " <Element"; + // Only output the tag if it is not the empty string. + if(e->first.length() > 0) + { + os << " tag=\"" << e->first.c_str() << "\""; + } + os << ">"; + if(needCdataBlock.find(e->second.c_str())) + { + os << "<![CDATA[" << e->second.c_str() << "]]>"; + } + else + { + os << e->second.c_str(); + } + os << "</Element>" << std::endl; } os << " </Set>" << std::endl; } + + +/** + * Given the string representing a set element, automatically generate + * the CABIL element tag for it. + * + * **This function determines how the output language of all + * CABIL-generated wrappers will look!** + */ +std::string +cmCabilDefineSetCommand::GenerateTag(const std::string& element) const +{ + // Hold the regular expressions for matching against the element. + cmRegularExpression regex; + + // If the element's code begins in a $, it is referring to a set name. + // The set's elements have their own tags, so we don't need one. + regex.compile("^[ \t]*\\$"); + if(regex.find(element)) + { return ""; } + + // Test for simple integer + regex.compile("^[ \t]*([0-9]*)[ \t]*$"); + if(regex.find(element)) + { + std::string tag = "_"; + tag.append(regex.match(1)); + return tag; + } + + // Test for basic integer type + regex.compile("^[ \t]*(unsigned[ ]|signed[ ])?[ \t]*(char|short|int|long|long[ ]long)[ \t]*$"); + if(regex.find(element)) + { + std::string tag = "_"; + if(regex.match(1) == "unsigned ") + { tag.append("u"); } + if(regex.match(2) == "long long") + { tag.append("llong"); } + else + { tag.append(regex.match(2)); } + return tag; + } + + // Test for basic floating-point type + regex.compile("^[ \t]*(long[ ])?[ \t]*(float|double)[ \t]*$"); + if(regex.find(element)) + { + std::string tag = "_"; + if(regex.match(1) == "long ") + tag.append("l"); + tag.append(regex.match(2)); + return tag; + } + + // Test for basic wide-character type + regex.compile("^[ \t]*(wchar_t)[ \t]*$"); + if(regex.find(element)) + { + return "_wchar"; + } + + // Test for plain type name (without template arguments). + regex.compile("^[ \t]*([A-Za-z_][A-Za-z0-9_]*)[ \t]*$"); + if(regex.find(element)) + { + // The tag is the same as the type. + return regex.match(1); + } + + // Test for template class instance. + regex.compile("^[ \t]*([A-Za-z_][A-Za-z0-9_]*)<.*[ \t]*$"); + if(regex.find(element)) + { + // The tag is the type without arguments (the arguments may have + // their own tags). + return regex.match(1); + } + + return "NO_AUTO_TAG"; +} diff --git a/Source/cmCableDefineSetCommand.h b/Source/cmCableDefineSetCommand.h index 345ac06..3d598b1 100644 --- a/Source/cmCableDefineSetCommand.h +++ b/Source/cmCableDefineSetCommand.h @@ -69,14 +69,22 @@ public: virtual const char* GetFullDocumentation() { return - "CABIL_DEFINE_SET(name_of_set member1 member2 ...)"; + "CABIL_DEFINE_SET(name_of_set member1 member2 ...)\n" + "Generates a Set definition in the CABIL configuration. Tags are\n" + "automatically generated. The sets are referenced in other CABIL\n" + "commands by a '$' immediately followed by the set name (ex. $SetName)."; } virtual void WriteConfiguration(std::ostream&) const; cmTypeMacro(cmCabilDefineSetCommand, cmCabilCommand); + +private: + std::string GenerateTag(const std::string&) const; + private: - typedef std::vector<std::string> Elements; + typedef std::pair<std::string, std::string> Element; + typedef std::vector<Element> Elements; /** * The name of the set. diff --git a/Source/cmCableInstantiateClassCommand.cxx b/Source/cmCableInstantiateClassCommand.cxx new file mode 100644 index 0000000..2491632 --- /dev/null +++ b/Source/cmCableInstantiateClassCommand.cxx @@ -0,0 +1,47 @@ +/*========================================================================= + + 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 "cmCabilInstantiateClassCommand.h" +#include "cmCacheManager.h" + +#include "cmRegularExpression.h" + + +/** + * Write the CABIL configuration code to define this InstantiationSet. + * This includes the "class" keyword to do class template instantiations. + */ +void cmCabilInstantiateClassCommand::WriteConfiguration(std::ostream& os) const +{ + cmRegularExpression needCdataBlock("[&<>]"); + + os << std::endl + << " <InstantiationSet>" << std::endl; + for(Elements::const_iterator e = m_Elements.begin(); + e != m_Elements.end(); ++e) + { + os << " <Element>class "; + if(needCdataBlock.find(e->c_str())) + { + os << "<![CDATA[" << e->c_str() << "]]>"; + } + else + { + os << e->c_str(); + } + os << "</Element>" << std::endl; + } + os << " </InstantiationSet>" << std::endl; +} diff --git a/Source/cmCableInstantiateClassCommand.h b/Source/cmCableInstantiateClassCommand.h new file mode 100644 index 0000000..b02b28a --- /dev/null +++ b/Source/cmCableInstantiateClassCommand.h @@ -0,0 +1,75 @@ +/*========================================================================= + + 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 cmCabilInstantiateClassCommand_h +#define cmCabilInstantiateClassCommand_h + +#include "cmStandardIncludes.h" +#include "cmCabilInstantiateCommand.h" + +/** \class cmCabilInstantiateClassCommand + * \brief Define a command that generates a rule for explicit template + * instantiations of classes. + * + * cmCabilInstantiateCommand is used to generate a rule in a CABIL + * configuration file to create explicit template instantiations of + * classes. + */ +class cmCabilInstantiateClassCommand : public cmCabilInstantiateCommand +{ +public: + /** + * This is a virtual constructor for the command. + */ + virtual cmCommand* Clone() + { + return new cmCabilInstantiateClassCommand; + } + + /** + * The name of the command as specified in CMakeList.txt. + */ + virtual const char* GetName() { return "CABIL_INSTANTIATE_CLASS";} + + /** + * Succinct documentation. + */ + virtual const char* GetTerseDocumentation() + { + return "Define CABIL InstantiationSet of classes."; + } + + /** + * More documentation. + */ + virtual const char* GetFullDocumentation() + { + return + "CABIL_INSTANTIATE_CLASS(cabil_config_file member1 member2 ...)\n" + "Generates an InstantiationSet in the CABIL 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; + + cmTypeMacro(cmCabilInstantiateClassCommand, cmCabilInstantiateCommand); +protected: + typedef cmCabilInstantiateCommand::Elements Elements; +}; + + + +#endif diff --git a/Source/cmCableInstantiateCommand.cxx b/Source/cmCableInstantiateCommand.cxx index c82eabb..b30a1c5 100644 --- a/Source/cmCableInstantiateCommand.cxx +++ b/Source/cmCableInstantiateCommand.cxx @@ -17,6 +17,7 @@ #include "cmCacheManager.h" #include "cmCabilDefineSetCommand.h" +#include "cmRegularExpression.h" // cmCabilInstantiateCommand bool cmCabilInstantiateCommand::Invoke(std::vector<std::string>& args) @@ -97,12 +98,23 @@ void cmCabilInstantiateCommand::FinalPass() */ void cmCabilInstantiateCommand::WriteConfiguration(std::ostream& os) const { + cmRegularExpression needCdataBlock("[&<>]"); + os << std::endl << " <InstantiationSet>" << std::endl; for(Elements::const_iterator e = m_Elements.begin(); e != m_Elements.end(); ++e) { - os << " <Element>" << e->c_str() << "</Element>" << std::endl; + os << " <Element>"; + if(needCdataBlock.find(e->c_str())) + { + os << "<![CDATA[" << e->c_str() << "]]>"; + } + else + { + os << e->c_str(); + } + os << "</Element>" << std::endl; } os << " </InstantiationSet>" << std::endl; } diff --git a/Source/cmCableInstantiateCommand.h b/Source/cmCableInstantiateCommand.h index 477fee2..1bb3722 100644 --- a/Source/cmCableInstantiateCommand.h +++ b/Source/cmCableInstantiateCommand.h @@ -65,7 +65,7 @@ public: */ virtual const char* GetTerseDocumentation() { - return "Define a rule for creating explicit template instantiations."; + return "Define CABIL InstantiationSet."; } /** @@ -74,13 +74,16 @@ public: virtual const char* GetFullDocumentation() { return - "CABIL_INSTANTIATE(cabil_config_file member1 member2 ...)"; + "CABIL_INSTANTIATE(cabil_config_file member1 member2 ...)\n" + "Generates an InstantiationSet in the CABIL 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; cmTypeMacro(cmCabilInstantiateCommand, cmCabilCommand); -private: +protected: typedef std::vector<std::string> Elements; /** diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index a2e6c5a..b693495 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -28,6 +28,7 @@ #include "cmCabilData.cxx" #include "cmCabilDefineSetCommand.cxx" #include "cmCabilInstantiateCommand.cxx" +#include "cmCabilInstantiateClassCommand.cxx" #include "cmFindFileCommand.cxx" #include "cmWrapTclCommand.cxx" @@ -56,6 +57,7 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands) commands.push_back(new cmConfigureFileNoAutoconf); commands.push_back(new cmCabilDefineSetCommand); commands.push_back(new cmCabilInstantiateCommand); + commands.push_back(new cmCabilInstantiateClassCommand); commands.push_back(new cmFindFileCommand); commands.push_back(new cmWrapTclCommand); } |