summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2001-02-27 21:28:56 (GMT)
committerBrad King <brad.king@kitware.com>2001-02-27 21:28:56 (GMT)
commit711c652edbc47e123a22878e39a4944b31e4708e (patch)
tree771e17e651b09144265b41fae290aa779dfa7d82 /Source
parent41d198ed40fcae8cbd2fae163af48d3c518c9628 (diff)
downloadCMake-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.h10
-rw-r--r--Source/cmCableDefineSetCommand.cxx104
-rw-r--r--Source/cmCableDefineSetCommand.h12
-rw-r--r--Source/cmCableInstantiateClassCommand.cxx47
-rw-r--r--Source/cmCableInstantiateClassCommand.h75
-rw-r--r--Source/cmCableInstantiateCommand.cxx14
-rw-r--r--Source/cmCableInstantiateCommand.h9
-rw-r--r--Source/cmCommands.cxx2
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);
}