summaryrefslogtreecommitdiffstats
path: root/Source/cmCableWrapTclCommand.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmCableWrapTclCommand.cxx')
-rw-r--r--Source/cmCableWrapTclCommand.cxx562
1 files changed, 0 insertions, 562 deletions
diff --git a/Source/cmCableWrapTclCommand.cxx b/Source/cmCableWrapTclCommand.cxx
deleted file mode 100644
index 96076b7..0000000
--- a/Source/cmCableWrapTclCommand.cxx
+++ /dev/null
@@ -1,562 +0,0 @@
-/*=========================================================================
-
- Program: Insight Segmentation & Registration Toolkit
- Module: $RCSfile$
- Language: C++
- Date: $Date$
- Version: $Revision$
-
- Copyright (c) 2002 Insight Consortium. All rights reserved.
- See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
-#include "cmCableWrapTclCommand.h"
-#include "cmCacheManager.h"
-#include "cmTarget.h"
-#include "cmGeneratedFileStream.h"
-#include "cmMakeDepend.h"
-
-#include "cmData.h"
-
-/**
- * One instance of this is associated with the makefile to hold a
- * vector of the GCC-XML flags pre-parsed from the string in the
- * cache. The first cmCableWrapTclCommand to need it creates the
- * instance. The others find it and use it.
- */
-class cmCableWrapTclCommand::cmGccXmlFlagsParser: public cmData
-{
-public:
- cmGccXmlFlagsParser(const char* name): cmData(name) {}
-
- void Parse(const char*);
- void AddParsedFlags(std::vector<std::string>& resultArgs);
-
-private:
- void AddFlag(const std::string&);
-
- std::vector<std::string> m_Flags;
-};
-
-void cmCableWrapTclCommand::cmGccXmlFlagsParser::Parse(const char* in_flags)
-{
- // Prepare a work string for searching.
- std::string flags = in_flags;
-
- // Look for " -" separating arguments.
-
- // The first argument starts at the first "-" character.
- std::string::size_type leftPos = flags.find_first_of("-");
- if(leftPos == std::string::npos) { return; }
- std::string::size_type rightPos = flags.find(" -", leftPos);
- while(rightPos != std::string::npos)
- {
- // Pull out and store this argument.
- this->AddFlag(flags.substr(leftPos, rightPos-leftPos));
-
- // The next argument starts at the '-' from the previously found " -".
- leftPos = rightPos+1;
- rightPos = flags.find(" -", leftPos);
- }
- // Pull out and store the last argument.
- this->AddFlag(flags.substr(leftPos, std::string::npos));
-}
-
-void
-cmCableWrapTclCommand::cmGccXmlFlagsParser
-::AddParsedFlags(std::vector<std::string>& resultArgs)
-{
- for(std::vector<std::string>::const_iterator flag = m_Flags.begin();
- flag != m_Flags.end(); ++flag)
- {
- resultArgs.push_back(*flag);
- }
-}
-
-/**
- * Used by Parse() to insert a parsed flag. Strips trailing whitespace from
- * the argument.
- *
- * Includes a hack to split "-o /dev/null" into two arguments since
- * the parser only splits arguments with " -" occurrences.
- */
-void
-cmCableWrapTclCommand::cmGccXmlFlagsParser
-::AddFlag(const std::string& flag)
-{
- std::string tmp = flag.substr(0, flag.find_last_not_of(" \t")+1);
- if(tmp == "-o /dev/null")
- {
- m_Flags.push_back("-o");
- m_Flags.push_back("/dev/null");
- }
- else if(tmp == "-D__int64='long long'")
- {
- m_Flags.push_back("-D__int64='long");
- m_Flags.push_back("long'");
- }
- else
- {
- m_Flags.push_back(tmp);
- }
-}
-
-cmCableWrapTclCommand::cmCableWrapTclCommand():
- m_CableClassSet(NULL), m_MakeDepend(new cmMakeDepend)
-{
-}
-
-cmCableWrapTclCommand::~cmCableWrapTclCommand()
-{
- if(m_CableClassSet)
- {
- delete m_CableClassSet;
- }
- delete m_MakeDepend;
-}
-
-
-
-// cmCableWrapTclCommand
-bool cmCableWrapTclCommand::InitialPass(std::vector<std::string> const& argsIn)
-{
- if(argsIn.size() < 2)
- {
- this->SetError("called with incorrect number of arguments");
- return false;
- }
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
-
- // 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
-{
- // Make sure the dependency generator is ready to go.
- m_MakeDepend->SetMakefile(m_Makefile);
-
- // Each wrapped class may have an associated "tag" that represents
- // an alternative name without funky C++ syntax in it. This makes
- // it easier to refer to the class in a Tcl script. We will also
- // use the tags to make easy-to-read, unique file names for each
- // class's wrapper. Count the number of times each tag is used.
- // Warn if a tag is used more than once.
- std::map<cmStdString, unsigned int> tagCounts;
- for(cmCableClassSet::CableClassMap::const_iterator
- c = m_CableClassSet->Begin(); c != m_CableClassSet->End(); ++c)
- {
- std::string tag = c->second->GetTag();
- if((++tagCounts[tag] > 1) && (tag != ""))
- {
- std::string message =
- "CABLE_WRAP_TCL has found two classes with the tag "+tag
- +" for target "+m_TargetName;
- cmSystemTools::Message(message.c_str(), "Warning");
- }
- }
-
- // Each class wrapper will be written into its own CABLE "group"
- // file. This should hold the names of the groups generated so that
- // the package configuration file can tell cable how to generate the
- // package initialization code.
- std::vector<std::string> groupTags;
-
- // Setup the output directory name and make sure it exists.
- std::string outDir = m_Makefile->GetCurrentOutputDirectory();
- cmSystemTools::MakeDirectory((outDir+"/Tcl").c_str());
-
- // Write out the cable configuration files with one class per group.
- // Try to name the groups based on their class's tag, but use an
- // index to disambiguate tag repeats (mostly used for empty tags).
- std::map<cmStdString, unsigned int> tagIndexes;
- for(cmCableClassSet::CableClassMap::const_iterator
- c = m_CableClassSet->Begin(); c != m_CableClassSet->End(); ++c)
- {
- // Construct the group's tag-based name, with index if necessary.
- std::string tag = c->second->GetTag();
- std::string groupTag;
- if(tagCounts[tag] > 1)
- {
- unsigned int tagIndex = tagIndexes[tag]++;
- std::strstream indexStrStream;
- indexStrStream << tagIndex << std::ends;
- std::string indexStr = indexStrStream.str();
- groupTag = "_"+indexStr;
- }
- if(tag != "")
- {
- groupTag += "_"+tag;
- }
-
- // Save this group tag in the list of tags for the main package
- // configuration file below.
- groupTags.push_back(groupTag);
-
- // Actually generate the class's configuration file.
- this->GenerateCableClassFiles(c->first.c_str(), *(c->second),
- groupTag.c_str());
- }
-
- // Construct the output file names.
- std::string packageConfigName = outDir+"/Tcl/"+m_TargetName+"_config.xml";
- std::string packageTclFileName = "Tcl/"+m_TargetName+"_tcl";
- std::string packageTclFullName = outDir+"/"+packageTclFileName;
-
- // Generate the main package configuration file for CABLE. This
- // just lists the "group" files generated above.
- cmGeneratedFileStream packageConfig(packageConfigName.c_str());
- if(packageConfig)
- {
- packageConfig <<
- "<CableConfiguration package=\"" << m_TargetName.c_str() << "\">\n";
- for(std::vector<std::string>::const_iterator g = groupTags.begin();
- g != groupTags.end(); ++g)
- {
- packageConfig <<
- " <Group name=\"" << m_TargetName.c_str() << g->c_str() << "\"/>\n";
- }
- packageConfig <<
- "</CableConfiguration>\n";
-
- packageConfig.close();
- }
- else
- {
- cmSystemTools::Error("Error opening CABLE configuration file for writing: ",
- packageConfigName.c_str());
- }
-
- // Generate the rule to run CABLE for the package configuration file.
- std::string command = "${CABLE}";
- m_Makefile->ExpandVariablesInString(command);
- std::vector<std::string> depends;
- depends.push_back(command);
- std::vector<std::string> commandArgs;
- commandArgs.push_back(packageConfigName);
- commandArgs.push_back("-tcl");
- std::string tmp = packageTclFullName+".cxx";
- commandArgs.push_back(tmp);
-
- depends.push_back(packageConfigName);
-
- std::vector<std::string> outputs;
- outputs.push_back(packageTclFullName+".cxx");
-
- m_Makefile->AddCustomCommand(packageConfigName.c_str(),
- command.c_str(),
- commandArgs,
- depends,
- outputs, m_TargetName.c_str());
-
- // Add the generated source to the package target's source list.
- cmSourceFile file;
- file.SetName(packageTclFileName.c_str(), outDir.c_str(), "cxx", false);
- // Set dependency hints.
- file.GetDepends().push_back("WrapTclFacility/wrapCalls.h");
- m_Makefile->AddSource(file, m_TargetName.c_str());
-}
-
-
-void cmCableWrapTclCommand::GenerateCableClassFiles(const char* name,
- const cmCableClass& c,
- const char* groupTag) const
-{
- std::string outDir = m_Makefile->GetCurrentOutputDirectory();
-
- std::string className = name;
- std::string groupName = m_TargetName+groupTag;
- std::string classConfigName = outDir+"/Tcl/"+groupName+"_config_tcl.xml";
- std::string classCxxName = outDir+"/Tcl/"+groupName+"_cxx.cc";
- std::string classXmlName = outDir+"/Tcl/"+groupName+"_cxx.xml";
- std::string classTclFileName = "Tcl/"+groupName+"_tcl";
- std::string classTclFullName = outDir+"/"+classTclFileName;
-
- 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 <<
- " <Class name=\"_wrap_::wrapper::Wrapper\">\n";
- if(c.GetTag() != "")
- {
- classConfig <<
- " <AlternateName name=\"" << c.GetTag().c_str() << "\"/>\n";
- }
- classConfig <<
- " </Class>\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());
- }
-
- // Generate the rule to have GCC-XML parse the classes to be wrapped.
- {
- std::string command = this->GetGccXmlFromCache();
- std::vector<std::string> depends;
- depends.push_back(command);
-
- // Get the dependencies of the file.
- const cmDependInformation* dependInfo =
- m_MakeDepend->FindDependencies(classCxxName.c_str());
- if(dependInfo)
- {
- for(cmDependInformation::DependencySet::const_iterator d =
- dependInfo->m_DependencySet.begin();
- d != dependInfo->m_DependencySet.end(); ++d)
- {
- // Make sure the full path is given. If not, the dependency was
- // not found.
- if((*d)->m_FullPath != "")
- {
- depends.push_back((*d)->m_FullPath);
- }
- }
- }
-
- std::vector<std::string> commandArgs;
- this->AddGccXmlFlagsFromCache(commandArgs);
-
- {
- std::string tmp = "-I";
- tmp += m_Makefile->GetStartDirectory();
- commandArgs.push_back(tmp.c_str());
- }
-
- const std::vector<std::string>& includes =
- m_Makefile->GetIncludeDirectories();
- for(std::vector<std::string>::const_iterator i = includes.begin();
- i != includes.end(); ++i)
- {
- std::string tmp = "-I";
- tmp += i->c_str();
- m_Makefile->ExpandVariablesInString(tmp);
- commandArgs.push_back(tmp.c_str());
- }
- std::string tmp = "-fxml=";
- tmp += classXmlName;
- commandArgs.push_back(tmp);
- commandArgs.push_back(classCxxName);
-
- std::vector<std::string> outputs;
- outputs.push_back(classXmlName);
-
- m_Makefile->AddCustomCommand(classCxxName.c_str(),
- command.c_str(),
- commandArgs,
- depends,
- outputs, m_TargetName.c_str());
- }
-
- // Generate the rule to run cable on the GCC-XML output to generate wrappers.
- {
- std::string command = this->GetCableFromCache();
- std::vector<std::string> depends;
- depends.push_back(command);
- std::vector<std::string > commandArgs;
- commandArgs.push_back(classConfigName);
- commandArgs.push_back("-tcl");
- std::string tmp = classTclFullName+".cxx";
- commandArgs.push_back(tmp);
-
- depends.push_back(classConfigName);
- depends.push_back(classXmlName);
-
- std::vector<std::string> outputs;
- outputs.push_back(classTclFullName+".cxx");
-
- m_Makefile->AddCustomCommand(classConfigName.c_str(),
- command.c_str(),
- commandArgs, depends,
- outputs, m_TargetName.c_str());
- }
-
- // Add the generated source to the package's source list.
- cmSourceFile file;
- file.SetName(classTclFileName.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("WrapTclFacility/wrapCalls.h");
- m_Makefile->AddSource(file, m_TargetName.c_str());
-}
-
-
-/**
- * Get the "GCCXML" cache entry value. If there is no cache entry for GCCXML,
- * one will be created and initialized to NOTFOUND.
- */
-std::string cmCableWrapTclCommand::GetGccXmlFromCache() const
-{
- const char* gccxml =
- m_Makefile->GetDefinition("GCCXML");
- if(gccxml)
- { return gccxml; }
-
- m_Makefile->AddCacheDefinition("GCCXML",
- "NOTFOUND",
- "Path to GCC-XML executable.",
- cmCacheManager::FILEPATH);
- return "NOTFOUND";
-}
-
-
-/**
- * Get the "GCCXML_FLAGS" cache entry value. If there is no cache
- * entry for GCCXML_FLAGS, one will be created and initialized "".
- */
-std::string cmCableWrapTclCommand::GetGccXmlFlagsFromCache() const
-{
- const char* gccxmlFlags =
- m_Makefile->GetDefinition("GCCXML_FLAGS");
- if(gccxmlFlags)
- { return gccxmlFlags; }
-
- m_Makefile->AddCacheDefinition(
- "GCCXML_FLAGS",
- "",
- "Flags to GCC-XML to get it to parse the native compiler's headers.",
- cmCacheManager::STRING);
- return "";
-}
-
-
-/**
- * Get the "CABLE" cache entry value. If there is no cache entry for CABLE,
- * one will be created and initialized to NOTFOUND.
- */
-std::string cmCableWrapTclCommand::GetCableFromCache() const
-{
- const char* cable =
- m_Makefile->GetDefinition("CABLE");
- if(cable)
- { return cable; }
-
- m_Makefile->AddCacheDefinition("CABLE",
- "NOTFOUND",
- "Path to CABLE executable.",
- cmCacheManager::FILEPATH);
- return "NOTFOUND";
-}
-
-
-/**
- * Parse flags from the result of GetGccXmlFlagsFromCache() and push
- * them onto the back of the given vector, in order. This uses an
- * instance of cmGccXmlFlagsParser associated with the makefile so
- * that parsing need only be done once.
- */
-void
-cmCableWrapTclCommand
-::AddGccXmlFlagsFromCache(std::vector<std::string>& resultArgs) const
-{
- cmGccXmlFlagsParser* parser = 0;
-
- // See if the instance already exists with the parsed flags.
- cmData* data = m_Makefile->LookupData("cmGccXmlFlagsParser");
- if(data)
- {
- // Yes, use it.
- parser = static_cast<cmGccXmlFlagsParser*>(data);
- }
- else
- {
- // No, create the instance and ask it to parse the flags.
- parser = new cmGccXmlFlagsParser("cmGccXmlFlagsParser");
- m_Makefile->RegisterData(parser);
- parser->Parse(this->GetGccXmlFlagsFromCache().c_str());
- parser->Parse(m_Makefile->GetDefineFlags());
- }
-
- // Use the parsed flags in the single instance.
- parser->AddParsedFlags(resultArgs);
-}