diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmCableWrapTclCommand.cxx | 98 | ||||
-rw-r--r-- | Source/cmCableWrapTclCommand.h | 2 |
2 files changed, 74 insertions, 26 deletions
diff --git a/Source/cmCableWrapTclCommand.cxx b/Source/cmCableWrapTclCommand.cxx index feb24c8..c1227b9 100644 --- a/Source/cmCableWrapTclCommand.cxx +++ b/Source/cmCableWrapTclCommand.cxx @@ -113,24 +113,85 @@ bool cmCableWrapTclCommand::InitialPass(std::vector<std::string>& args) */ void cmCableWrapTclCommand::GenerateCableFiles() const { - // Setup the output directory. + // 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<std::string, 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<std::string, 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; + std::string packageTclFullName = outDir+"/"+packageTclFileName; - // Generate the main package configuration file for CABLE. + // 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(unsigned int i=0; i < m_CableClassSet->Size(); ++i) + for(std::vector<std::string>::const_iterator g = groupTags.begin(); + g != groupTags.end(); ++g) { packageConfig << - " <Group name=\"" << m_TargetName.c_str() << "_" << i << "\"/>\n"; + " <Group name=\"" << m_TargetName.c_str() << g->c_str() << "\"/>\n"; } packageConfig << "</CableConfiguration>\n"; @@ -142,8 +203,8 @@ void cmCableWrapTclCommand::GenerateCableFiles() const 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; @@ -161,37 +222,24 @@ void cmCableWrapTclCommand::GenerateCableFiles() const commandArgs.c_str(), depends, outputs, m_TargetName.c_str()); - } - - // Add the generated source to the package's source list. + + // 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("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(); - + const char* groupTag) const +{ std::string outDir = m_Makefile->GetCurrentOutputDirectory(); std::string className = name; - std::string groupName = m_TargetName+"_"+indexStr; + 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"; diff --git a/Source/cmCableWrapTclCommand.h b/Source/cmCableWrapTclCommand.h index a86f8ff..bb35ac8 100644 --- a/Source/cmCableWrapTclCommand.h +++ b/Source/cmCableWrapTclCommand.h @@ -97,7 +97,7 @@ public: protected: void GenerateCableFiles() const; - void GenerateCableClassFiles(const char*, const cmCableClass&, unsigned int) const; + void GenerateCableClassFiles(const char*, const cmCableClass&, const char*) const; std::string GetGccXmlFromCache() const; std::string GetGccXmlFlagsFromCache() const; std::string GetCableFromCache() const; |