summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2001-05-16 20:41:30 (GMT)
committerBrad King <brad.king@kitware.com>2001-05-16 20:41:30 (GMT)
commitf08a1b88853fda7376808cb8ebbb63201dde10f6 (patch)
treee663e1e7f0064a70a027ac39695a73e56cb92b37
parent8011fe0fadb8a57e5086b97a0d3cd783207fae07 (diff)
downloadCMake-f08a1b88853fda7376808cb8ebbb63201dde10f6.zip
CMake-f08a1b88853fda7376808cb8ebbb63201dde10f6.tar.gz
CMake-f08a1b88853fda7376808cb8ebbb63201dde10f6.tar.bz2
ENH: Adding CABLE_CLASS_SET and CABLE_WRAP_TCL commands. They cannot yet be used with the main branch of CABLE, though.
-rw-r--r--Source/Makefile.in2
-rw-r--r--Source/cmCableClassSet.cxx199
-rw-r--r--Source/cmCableClassSet.h105
-rw-r--r--Source/cmCableClassSetCommand.cxx81
-rw-r--r--Source/cmCableClassSetCommand.h106
-rw-r--r--Source/cmCableWrapTclCommand.cxx307
-rw-r--r--Source/cmCableWrapTclCommand.h121
-rw-r--r--Source/cmCommands.cxx4
8 files changed, 925 insertions, 0 deletions
diff --git a/Source/Makefile.in b/Source/Makefile.in
index 19abbb0..4fce232 100644
--- a/Source/Makefile.in
+++ b/Source/Makefile.in
@@ -25,6 +25,7 @@ cmCommands.o \
cmTarget.o \
cmCustomCommand.o \
cmCacheManager.o \
+cmCableClassSet.o \
cmSourceGroup.o
DEPENDS = $(srcdir)/*.h ${CMAKE_CONFIG_DIR}/CMake/Source/cmConfigure.h
@@ -43,6 +44,7 @@ cmUnixMakefileGenerator.o : $(DEPENDS)
cmCommands.o : $(DEPENDS) $(srcdir)/*Command*.cxx
cmTarget.o : $(DEPENDS)
cmCacheManager.o : $(DEPENDS)
+cmCableClassSet.o: $(DEPENDS)
cmSourceGroup.o : $(DEPENDS)
diff --git a/Source/cmCableClassSet.cxx b/Source/cmCableClassSet.cxx
new file mode 100644
index 0000000..a84a63d
--- /dev/null
+++ b/Source/cmCableClassSet.cxx
@@ -0,0 +1,199 @@
+/*=========================================================================
+
+ Program: Insight Segmentation & Registration Toolkit
+ Module: $RCSfile$
+ Language: C++
+ Date: $Date$
+ Version: $Revision$
+
+Copyright (c) 2001 Insight Consortium
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * The name of the Insight Consortium, nor the names of any consortium members,
+ nor of any contributors, may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ * Modified source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=========================================================================*/
+#include "cmCableClassSet.h"
+
+
+/**
+ * Add to the set of required sources to define the class.
+ */
+void cmCableClass::AddSource(const char* source)
+{
+ m_Sources.insert(source);
+}
+
+
+/**
+ * Add a class to the set.
+ */
+void cmCableClassSet::AddClass(const char* name,
+ const cmCableClass& cableClass)
+{
+ m_CableClassMap.insert(CableClassMap::value_type(name, cableClass));
+}
+
+
+/**
+ * Add a source to every class in the set. This should only be done after
+ * all classes have been inserted.
+ */
+void cmCableClassSet::AddSource(const char* name)
+{
+ for(CableClassMap::iterator c = m_CableClassMap.begin();
+ c != m_CableClassMap.end(); ++c)
+ {
+ c->second.AddSource(name);
+ }
+}
+
+/**
+ * Get the size of the internal CableClassMap used to store the set.
+ */
+unsigned int cmCableClassSet::Size() const
+{
+ return m_CableClassMap.size();
+}
+
+
+/**
+ * Get a begin iterator to the internal CableClassMap used to store the
+ * set.
+ */
+cmCableClassSet::CableClassMap::const_iterator cmCableClassSet::Begin() const
+{
+ return m_CableClassMap.begin();
+}
+
+
+/**
+ * Get an end iterator to the internal CableClassMap used to store the
+ * set.
+ */
+cmCableClassSet::CableClassMap::const_iterator cmCableClassSet::End() const
+{
+ return m_CableClassMap.end();
+}
+
+/**
+ * Parse the given string to extract the class information specified.
+ *
+ * The format of the string is
+ * [tag:]class_name[;source1;source2;...]
+ *
+ */
+void cmCableClassSet::ParseAndAddElement(const char* element,
+ cmMakefile* makefile)
+{
+ // A regular expression to match the tagged element specification.
+ cmRegularExpression tagGiven("^([A-Za-z_0-9]*)[ \t]*:[ \t]*([^:].*|::.*)$");
+
+ // A regular expression to match the element when more source files are given.
+ cmRegularExpression sourcesRemain("^([^;]*);(.*)$");
+
+ std::string tag;
+ std::string elementWithoutTag;
+ std::string className;
+ std::string sourceString;
+
+ if(tagGiven.find(element))
+ {
+ // A tag was given. Use it.
+ tag = tagGiven.match(1);
+ elementWithoutTag = tagGiven.match(2);
+ }
+ else
+ {
+ // No tag was given. Try to generate one.
+ //if(!this->GenerateTag(element, tag))
+ // { return false; }
+ elementWithoutTag = element;
+ }
+
+ if(sourcesRemain.find(elementWithoutTag.c_str()))
+ {
+ className = sourcesRemain.match(1);
+ sourceString = sourcesRemain.match(2);
+ }
+ else
+ {
+ className = elementWithoutTag;
+ }
+
+ cmCableClass::Sources sources;
+
+ while(sourcesRemain.find(sourceString.c_str()))
+ {
+ sources.insert(sourcesRemain.match(1));
+ sourceString = sourcesRemain.match(2);
+ }
+ if(sourceString != "")
+ {
+ sources.insert(sourceString);
+ }
+
+ // A regular expression to match a class name that is just a set.
+ cmRegularExpression setDereference("^\\$(.*)$");
+ if(setDereference.find(className))
+ {
+ std::string setName = setDereference.match(1);
+ cmData* d = makefile->LookupData(setName.c_str());
+ cmCableClassSet* classSet = dynamic_cast<cmCableClassSet*>(d);
+ if(classSet)
+ {
+ this->AddCableClassSet(*classSet, sources);
+ }
+ else
+ {
+ cmSystemTools::Error("Unknown CABLE class set ", setName.c_str());
+ }
+ }
+ else
+ {
+ cmCableClass cableClass;
+ cableClass.AddSources(sources.begin(), sources.end());
+ this->AddClass(className.c_str(), cableClass);
+ }
+}
+
+
+/**
+ * Add all elements from the given cmCableClassSet to this set, with the given
+ * sources added to each element.
+ */
+void cmCableClassSet::AddCableClassSet(const cmCableClassSet& set,
+ const cmCableClass::Sources& sources)
+{
+ for(CableClassMap::const_iterator c = set.Begin(); c != set.End(); ++c)
+ {
+ cmCableClass cableClass = c->second;
+ cableClass.AddSources(sources.begin(), sources.end());
+ this->AddClass(c->first.c_str(), cableClass);
+ }
+}
diff --git a/Source/cmCableClassSet.h b/Source/cmCableClassSet.h
new file mode 100644
index 0000000..422f1e9
--- /dev/null
+++ b/Source/cmCableClassSet.h
@@ -0,0 +1,105 @@
+/*=========================================================================
+
+ Program: Insight Segmentation & Registration Toolkit
+ Module: $RCSfile$
+ Language: C++
+ Date: $Date$
+ Version: $Revision$
+
+Copyright (c) 2001 Insight Consortium
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * The name of the Insight Consortium, nor the names of any consortium members,
+ nor of any contributors, may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ * Modified source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=========================================================================*/
+#ifndef cmCableClassSet_h
+#define cmCableClassSet_h
+
+#include "cmStandardIncludes.h"
+#include "cmData.h"
+#include "cmMakefile.h"
+
+
+/** \class cmCableClass
+ * \brief Holds one class and the set of header files needed to use it.
+ */
+class cmCableClass
+{
+public:
+ typedef std::set<std::string> Sources;
+
+ template <typename InputIterator>
+ void AddSources(InputIterator first, InputIterator last)
+ { for(InputIterator i = first; i != last; ++i) { m_Sources.insert(*i); } }
+ void AddSource(const char*);
+
+ Sources::const_iterator SourcesBegin() const { return m_Sources.begin(); }
+ Sources::const_iterator SourcesEnd() const { return m_Sources.end(); }
+
+private:
+ /**
+ * Store the set of source files (headers) needed to define this class.
+ */
+ Sources m_Sources;
+};
+
+
+/** \class cmCableClassSet
+ * \brief Holds a set of classes, each with their own set of required headers.
+ */
+class cmCableClassSet: public cmData
+{
+public:
+ cmCableClassSet(const char* name): cmData(name) {}
+ virtual ~cmCableClassSet() {}
+
+ /**
+ * The set is stored internally as a map from class name to cmCableClass
+ * instance.
+ */
+ typedef std::map<std::string, cmCableClass> CableClassMap;
+
+ void AddClass(const char*, const cmCableClass&);
+ void AddSource(const char* name);
+ unsigned int Size() const;
+ CableClassMap::const_iterator Begin() const;
+ CableClassMap::const_iterator End() const;
+
+ void ParseAndAddElement(const char*, cmMakefile*);
+ void AddCableClassSet(const cmCableClassSet&, const cmCableClass::Sources&);
+
+private:
+ /**
+ * The set is stored internally as a map from class name to cmCableClass
+ * instance.
+ */
+ CableClassMap m_CableClassMap;
+};
+
+#endif
diff --git a/Source/cmCableClassSetCommand.cxx b/Source/cmCableClassSetCommand.cxx
new file mode 100644
index 0000000..89ce446
--- /dev/null
+++ b/Source/cmCableClassSetCommand.cxx
@@ -0,0 +1,81 @@
+/*=========================================================================
+
+ Program: Insight Segmentation & Registration Toolkit
+ Module: $RCSfile$
+ Language: C++
+ Date: $Date$
+ Version: $Revision$
+
+Copyright (c) 2001 Insight Consortium
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * The name of the Insight Consortium, nor the names of any consortium members,
+ nor of any contributors, may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ * Modified source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=========================================================================*/
+#include "cmCableClassSetCommand.h"
+#include "cmCacheManager.h"
+#include "cmTarget.h"
+
+// cmCableClassSetCommand
+bool cmCableClassSetCommand::Invoke(std::vector<std::string>& args)
+{
+ if(args.size() < 2)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // The first argument is the name of the set.
+ std::vector<std::string>::const_iterator arg = args.begin();
+ m_ClassSetName = *arg++;
+
+ // Create the new class set.
+ cmCableClassSet* classSet = new cmCableClassSet(m_ClassSetName.c_str());
+
+ // Add all the regular entries.
+ for(; (arg != args.end()) && (*arg != "SOURCES_BEGIN"); ++arg)
+ {
+ classSet->ParseAndAddElement(arg->c_str(), m_Makefile);
+ }
+
+ // Add any sources that are associated with all the members.
+ if(arg != args.end())
+ {
+ for(++arg; arg != args.end(); ++arg)
+ {
+ classSet->AddSource(arg->c_str());
+ }
+ }
+
+ // Store the class set in the makefile.
+ m_Makefile->RegisterData(classSet);
+
+ return true;
+}
+
diff --git a/Source/cmCableClassSetCommand.h b/Source/cmCableClassSetCommand.h
new file mode 100644
index 0000000..1520a06
--- /dev/null
+++ b/Source/cmCableClassSetCommand.h
@@ -0,0 +1,106 @@
+/*=========================================================================
+
+ Program: Insight Segmentation & Registration Toolkit
+ Module: $RCSfile$
+ Language: C++
+ Date: $Date$
+ Version: $Revision$
+
+Copyright (c) 2001 Insight Consortium
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * The name of the Insight Consortium, nor the names of any consortium members,
+ nor of any contributors, may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ * Modified source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=========================================================================*/
+#ifndef cmCableClassSetCommand_h
+#define cmCableClassSetCommand_h
+
+#include "cmStandardIncludes.h"
+#include "cmCommand.h"
+#include "cmCableClassSet.h"
+
+/** \class cmCableClassSetCommand
+ *
+ */
+class cmCableClassSetCommand : public cmCommand
+{
+public:
+ cmCableClassSetCommand() {}
+ virtual ~cmCableClassSetCommand() {}
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmCableClassSetCommand;
+ }
+
+ /**
+ * 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_CLASS_SET";}
+
+ /**
+ * Succinct documentation.
+ */
+ virtual const char* GetTerseDocumentation()
+ {
+ return "Define a set of classes for use in other CABLE commands.";
+ }
+
+ /**
+ * More documentation.
+ */
+ virtual const char* GetFullDocumentation()
+ {
+ return
+ "CABLE_CLASS_SET(set_name class1 class2 ...)\n"
+ "Defines a set with the given name containing classes and their\n"
+ "associated header files. The set can later be used by other CABLE\n"
+ "commands.";
+ }
+
+ cmTypeMacro(cmCableClassSetCommand, cmCommand);
+private:
+ /**
+ * The name of the class set.
+ */
+ std::string m_ClassSetName;
+};
+
+
+
+#endif
diff --git a/Source/cmCableWrapTclCommand.cxx b/Source/cmCableWrapTclCommand.cxx
new file mode 100644
index 0000000..0fe880c
--- /dev/null
+++ b/Source/cmCableWrapTclCommand.cxx
@@ -0,0 +1,307 @@
+/*=========================================================================
+
+ Program: Insight Segmentation & Registration Toolkit
+ Module: $RCSfile$
+ Language: C++
+ Date: $Date$
+ Version: $Revision$
+
+Copyright (c) 2001 Insight Consortium
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * The name of the Insight Consortium, nor the names of any consortium members,
+ nor of any contributors, may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ * Modified source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=========================================================================*/
+#include "cmCableWrapTclCommand.h"
+#include "cmCacheManager.h"
+#include "cmTarget.h"
+#include "cmGeneratedFileStream.h"
+#include <strstream>
+
+cmCableWrapTclCommand::cmCableWrapTclCommand():
+ m_CableClassSet(NULL)
+{
+}
+
+cmCableWrapTclCommand::~cmCableWrapTclCommand()
+{
+ if(m_CableClassSet)
+ {
+ delete m_CableClassSet;
+ }
+}
+
+
+
+// cmCableWrapTclCommand
+bool cmCableWrapTclCommand::Invoke(std::vector<std::string>& args)
+{
+ if(args.size() < 2)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // Prepare to iterate through the arguments.
+ std::vector<std::string>::const_iterator arg = args.begin();
+
+ // The first argument is the name of the target.
+ m_TargetName = *arg++;
+
+ // Create the new class set.
+ m_CableClassSet = new cmCableClassSet(m_TargetName.c_str());
+
+ // Add all the regular entries.
+ for(; (arg != args.end()) && (*arg != "SOURCES_BEGIN"); ++arg)
+ {
+ m_CableClassSet->ParseAndAddElement(arg->c_str(), m_Makefile);
+ }
+
+ // Add any sources that are associated with all the members.
+ if(arg != args.end())
+ {
+ for(++arg; arg != args.end(); ++arg)
+ {
+ m_CableClassSet->AddSource(arg->c_str());
+ }
+ }
+
+ this->GenerateCableFiles();
+
+ // Add the source list to the target.
+ m_Makefile->GetTargets()[m_TargetName.c_str()].GetSourceLists().push_back(m_TargetName);
+
+ return true;
+}
+
+
+/**
+ * Generate the files that CABLE will use to generate the wrappers.
+ */
+void cmCableWrapTclCommand::GenerateCableFiles() const
+{
+ // Setup the output directory.
+ std::string outDir = m_Makefile->GetCurrentOutputDirectory();
+ cmSystemTools::MakeDirectory((outDir+"/Tcl").c_str());
+
+ std::string packageConfigName = outDir+"/Tcl/"+m_TargetName+"_config.xml";
+ std::string packageTclName = outDir+"/Tcl/"+m_TargetName+"_tcl";
+
+ // Generate the main package configuration file for CABLE.
+ cmGeneratedFileStream packageConfig(packageConfigName.c_str());
+ if(packageConfig)
+ {
+ packageConfig <<
+ "<CableConfiguration package=\"" << m_TargetName.c_str() << "\">\n"
+ " <Groups>\n";
+ for(unsigned int i=0; i < m_CableClassSet->Size(); ++i)
+ {
+ packageConfig <<
+ " " << m_TargetName.c_str() << "_" << i << "\n";
+ }
+ packageConfig <<
+ " </Groups>\n"
+ "</CableConfiguration>\n";
+
+ packageConfig.close();
+ }
+ else
+ {
+ cmSystemTools::Error("Error opening CABLE configuration file for writing: ",
+ packageConfigName.c_str());
+ }
+
+ {
+ std::string command = "${CABLE}";
+ m_Makefile->ExpandVariablesInString(command);
+ std::vector<std::string> depends;
+ depends.push_back(command);
+ command = cmSystemTools::EscapeSpaces(command.c_str());
+ command += " "+packageConfigName+" -tcl "+packageTclName+".cxx";
+
+ depends.push_back(packageConfigName);
+
+ std::vector<std::string> outputs;
+ outputs.push_back(packageTclName+".cxx");
+
+ m_Makefile->AddCustomCommand(packageConfigName.c_str(),
+ command.c_str(),
+ depends,
+ outputs, m_TargetName.c_str());
+ }
+
+ // Add the generated source to the package's source list.
+ cmSourceFile file;
+ file.SetName(packageTclName.c_str(), outDir.c_str(), "cxx", false);
+ // Set dependency hints.
+ file.GetDepends().push_back("wrapCalls.h");
+ m_Makefile->AddSource(file, m_TargetName.c_str());
+
+ unsigned int index = 0;
+ for(cmCableClassSet::CableClassMap::const_iterator
+ c = m_CableClassSet->Begin(); c != m_CableClassSet->End(); ++c, ++index)
+ {
+ this->GenerateCableClassFiles(c->first.c_str(), c->second, index);
+ }
+
+}
+
+
+void cmCableWrapTclCommand::GenerateCableClassFiles(const char* name,
+ const cmCableClass& c,
+ unsigned int index) const
+{
+ std::strstream indexStrStream;
+ indexStrStream << index << std::ends;
+ std::string indexStr = indexStrStream.str();
+
+ std::string outDir = m_Makefile->GetCurrentOutputDirectory();
+
+ std::string className = name;
+ std::string groupName = m_TargetName+"_"+indexStr;
+ std::string classConfigName = outDir+"/Tcl/"+groupName+"_config_tcl.xml";
+ std::string classCxxName = outDir+"/Tcl/"+groupName+"_cxx_tcl.cxx";
+ std::string classXmlName = outDir+"/Tcl/"+groupName+"_cxx_tcl.xml";
+ std::string classTclName = outDir+"/Tcl/"+groupName+"_tcl";
+
+ cmGeneratedFileStream classConfig(classConfigName.c_str());
+ if(classConfig)
+ {
+ classConfig <<
+ "<CableConfiguration source=\"" << classXmlName.c_str() << "\" "
+ "group=\"" << groupName.c_str() << "\">\n";
+ for(cmCableClass::Sources::const_iterator source = c.SourcesBegin();
+ source != c.SourcesEnd(); ++source)
+ {
+ classConfig <<
+ " <Header name=\"" << source->c_str() << "\"/>\n";
+ }
+ classConfig <<
+ " <WrapperSet>\n"
+ " _wrap_::wrapper::Wrapper\n"
+ " </WrapperSet>\n"
+ "</CableConfiguration>\n";
+
+ classConfig.close();
+ }
+ else
+ {
+ cmSystemTools::Error("Error opening CABLE configuration file for writing: ",
+ classConfigName.c_str());
+ }
+
+ cmGeneratedFileStream classCxx(classCxxName.c_str());
+ if(classCxx)
+ {
+ for(cmCableClass::Sources::const_iterator source = c.SourcesBegin();
+ source != c.SourcesEnd(); ++source)
+ {
+ classCxx <<
+ "#include \"" << source->c_str() << "\"\n";
+ }
+ classCxx <<
+ "\n"
+ "namespace _wrap_\n"
+ "{\n"
+ "\n"
+ "struct wrapper\n"
+ "{\n"
+ " typedef ::" << className.c_str() << " Wrapper;\n"
+ "};\n"
+ "\n"
+ "template <typename T> void Eat(T) {}\n"
+ "\n"
+ "void InstantiateMemberDeclarations()\n"
+ "{\n"
+ " Eat(sizeof(wrapper::Wrapper));\n"
+ "}\n"
+ "\n"
+ "}\n";
+
+ classCxx.close();
+ }
+ else
+ {
+ cmSystemTools::Error("Error opening file for writing: ",
+ classCxxName.c_str());
+ }
+
+ {
+ std::string command = "${GCCXML}";
+ m_Makefile->ExpandVariablesInString(command);
+ // Only add the rule if GCC-XML is available.
+ if((command != "") && (command != "${GCCXML}"))
+ {
+ std::vector<std::string> depends;
+ depends.push_back(command);
+ command = cmSystemTools::EscapeSpaces(command.c_str());
+ command += " ${CMAKE_CXXFLAGS} ${INCLUDE_FLAGS} -fsyntax-only -fxml=" + classXmlName + " " + classCxxName;
+
+ std::vector<std::string> outputs;
+ outputs.push_back(classXmlName);
+
+ m_Makefile->AddCustomCommand(classCxxName.c_str(),
+ command.c_str(),
+ depends,
+ outputs, m_TargetName.c_str());
+ }
+ }
+
+ {
+ std::string command = "${CABLE}";
+ m_Makefile->ExpandVariablesInString(command);
+ std::vector<std::string> depends;
+ depends.push_back(command);
+ command = cmSystemTools::EscapeSpaces(command.c_str());
+ command += " "+classConfigName+" -tcl "+classTclName+".cxx";
+
+ depends.push_back(classConfigName);
+ depends.push_back(classXmlName);
+
+ std::vector<std::string> outputs;
+ outputs.push_back(classTclName+".cxx");
+
+ m_Makefile->AddCustomCommand(classConfigName.c_str(),
+ command.c_str(),
+ depends,
+ outputs, m_TargetName.c_str());
+ }
+
+ // Add the generated source to the package's source list.
+ cmSourceFile file;
+ file.SetName(classTclName.c_str(), outDir.c_str(), "cxx", false);
+ // Set dependency hints.
+ for(cmCableClass::Sources::const_iterator source = c.SourcesBegin();
+ source != c.SourcesEnd(); ++source)
+ {
+ file.GetDepends().push_back(*source);
+ }
+ file.GetDepends().push_back("wrapCalls.h");
+ m_Makefile->AddSource(file, m_TargetName.c_str());
+}
diff --git a/Source/cmCableWrapTclCommand.h b/Source/cmCableWrapTclCommand.h
new file mode 100644
index 0000000..6e6c741
--- /dev/null
+++ b/Source/cmCableWrapTclCommand.h
@@ -0,0 +1,121 @@
+/*=========================================================================
+
+ Program: Insight Segmentation & Registration Toolkit
+ Module: $RCSfile$
+ Language: C++
+ Date: $Date$
+ Version: $Revision$
+
+Copyright (c) 2001 Insight Consortium
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * The name of the Insight Consortium, nor the names of any consortium members,
+ nor of any contributors, may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ * Modified source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=========================================================================*/
+#ifndef cmCableWrapTclCommand_h
+#define cmCableWrapTclCommand_h
+
+#include "cmStandardIncludes.h"
+#include "cmCommand.h"
+#include "cmCableClassSet.h"
+
+/** \class cmCableWrapTclCommand
+ * \brief Define a command that wraps a set of classes in Tcl.
+ */
+class cmCableWrapTclCommand : public cmCommand
+{
+public:
+ cmCableWrapTclCommand();
+ virtual ~cmCableWrapTclCommand();
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmCableWrapTclCommand;
+ }
+
+ /**
+ * 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_WRAP_TCL";}
+
+ /**
+ * Succinct documentation.
+ */
+ virtual const char* GetTerseDocumentation()
+ {
+ return "Wrap a set of classes in Tcl.";
+ }
+
+ /**
+ * More documentation.
+ */
+ virtual const char* GetFullDocumentation()
+ {
+ return
+ "CABLE_WRAP_TCL(target class1 class2 ...)\n"
+ "Wrap the given set of classes in Tcl using the CABLE tool. The set\n"
+ "of source files produced for the given package name will be added to\n"
+ "a source list with the given name.";
+ }
+
+ cmTypeMacro(cmCableWrapTclCommand, cmCommand);
+
+protected:
+ void GenerateCableFiles() const;
+ void GenerateCableClassFiles(const char*, const cmCableClass&, unsigned int) const;
+
+private:
+ /**
+ * The name of the package of wrappers to produce.
+ */
+ std::string m_TargetName;
+
+ /**
+ * The name of the source list into which the files needed for the package
+ * will be placed.
+ */
+ std::string m_SourceListName;
+
+ /**
+ * The set of classes to be wrapped in the package. This is also implicitly
+ * added to the makefile as another set.
+ */
+ cmCableClassSet* m_CableClassSet;
+};
+
+#endif
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index ef1393e..91872fa 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -12,6 +12,7 @@
#include "cmBuildCommand.cxx"
#include "cmBuildNameCommand.cxx"
#include "cmBuildSharedLibrariesCommand.cxx"
+#include "cmCableClassSetCommand.cxx"
#include "cmCableCloseNamespaceCommand.cxx"
#include "cmCableCommand.cxx"
#include "cmCableData.cxx"
@@ -22,6 +23,7 @@
#include "cmCablePackageCommand.cxx"
#include "cmCablePackageEntryCommand.cxx"
#include "cmCableSourceFilesCommand.cxx"
+#include "cmCableWrapTclCommand.cxx"
#include "cmCableWrapCommand.cxx"
#include "cmConfigureFileCommand.cxx"
#include "cmConfigureFileNoAutoconf.cxx"
@@ -67,6 +69,7 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands)
commands.push_back(new cmBuildCommand);
commands.push_back(new cmBuildNameCommand);
commands.push_back(new cmBuildSharedLibrariesCommand);
+ commands.push_back(new cmCableClassSetCommand);
commands.push_back(new cmCableCloseNamespaceCommand);
commands.push_back(new cmCableDefineSetCommand);
commands.push_back(new cmCableInstantiateCommand);
@@ -74,6 +77,7 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands)
commands.push_back(new cmCableOpenNamespaceCommand);
commands.push_back(new cmCablePackageCommand);
commands.push_back(new cmCableSourceFilesCommand);
+ commands.push_back(new cmCableWrapTclCommand);
commands.push_back(new cmCableWrapCommand);
commands.push_back(new cmConfigureFileCommand);
commands.push_back(new cmConfigureFileNoAutoconf);