summaryrefslogtreecommitdiffstats
path: root/Source/cmCableWrapTclCommand.cxx
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 /Source/cmCableWrapTclCommand.cxx
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.
Diffstat (limited to 'Source/cmCableWrapTclCommand.cxx')
-rw-r--r--Source/cmCableWrapTclCommand.cxx307
1 files changed, 307 insertions, 0 deletions
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());
+}