diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 116 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.h | 5 |
2 files changed, 71 insertions, 50 deletions
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index a22a315..71fe300 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -28,14 +28,23 @@ static std::string cmVS10EscapeXML(std::string arg) return arg; } +static std::string cmVS10EscapeAttr(std::string arg) +{ + cmSystemTools::ReplaceString(arg, "&", "&"); + cmSystemTools::ReplaceString(arg, "<", "<"); + cmSystemTools::ReplaceString(arg, ">", ">"); + cmSystemTools::ReplaceString(arg, "\"", """); + return arg; +} + struct cmVisualStudio10TargetGenerator::Elem { - cmGeneratedFileStream& S; + std::ostream& S; int Indent; bool HasElements = false; const char* Tag = nullptr; - Elem(cmGeneratedFileStream& s, int i) + Elem(std::ostream& s, int i) : S(s) , Indent(i) { @@ -61,22 +70,39 @@ struct cmVisualStudio10TargetGenerator::Elem HasElements = true; } } - cmGeneratedFileStream& WriteString(const char* line); - void StartElement(const char* tag) + std::ostream& WriteString(const char* line); + Elem& StartElement(const char* tag) { this->Tag = tag; this->WriteString("<") << tag; + return *this; } template <typename T> void WriteElem(const char* tag, const T& val) { this->WriteString("<") << tag << ">" << val << "</" << tag << ">\n"; } + void Element(const char* tag, const std::string& val) + { + Elem(*this).WriteElem(tag, cmVS10EscapeXML(val)); + } template <typename T> void Attr(const char* an, const T& av) { this->S << " " << an << "=\"" << av << "\""; } + Elem& Attribute(const char* an, const std::string& av) + { + Attr(an, cmVS10EscapeAttr(av)); + return *this; + } + // This method for now assumes that this->Tag has been set, e.g. by calling + // StartElement(). Also, it finishes the element so it should be the last + // one called + void Content(const std::string& val) + { + S << ">" << cmVS10EscapeXML(val) << "</" << this->Tag << ">\n"; + } void WriteEndTag(const char* tag) { if (HasElements) { @@ -142,15 +168,6 @@ inline void cmVisualStudio10TargetGenerator::WriteElemEscapeXML( this->WriteElem(tag, cmVS10EscapeXML(val), indentLevel); } -static std::string cmVS10EscapeAttr(std::string arg) -{ - cmSystemTools::ReplaceString(arg, "&", "&"); - cmSystemTools::ReplaceString(arg, "<", "<"); - cmSystemTools::ReplaceString(arg, ">", ">"); - cmSystemTools::ReplaceString(arg, "\"", """); - return arg; -} - static std::string cmVS10EscapeComment(std::string comment) { // MSBuild takes the CDATA of a <Message></Message> element and just @@ -242,38 +259,46 @@ cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator() delete this->BuildFileStream; } +std::string cmVisualStudio10TargetGenerator::CalcCondition( + const std::string& config) const +{ + std::ostringstream oss; + oss << "'$(Configuration)|$(Platform)'=='"; + oss << config << "|" << this->Platform; + oss << "'"; + // handle special case for 32 bit C# targets + if (this->ProjectType == csproj && this->Platform == "Win32") { + oss << " Or "; + oss << "'$(Configuration)|$(Platform)'=='"; + oss << config << "|x86"; + oss << "'"; + } + return oss.str(); +} + void cmVisualStudio10TargetGenerator::WritePlatformConfigTag( const char* tag, const std::string& config, int indentLevel, const char* attribute) { - std::ostream* stream = this->BuildFileStream; - stream->fill(' '); - stream->width(indentLevel * 2); - (*stream) << ""; // applies indentation - (*stream) << "<" << tag << " Condition=\""; - (*stream) << "'$(Configuration)|$(Platform)'=='"; - (*stream) << config << "|" << this->Platform; - (*stream) << "'"; - // handle special case for 32 bit C# targets - if (this->ProjectType == csproj && this->Platform == "Win32") { - (*stream) << " Or "; - (*stream) << "'$(Configuration)|$(Platform)'=='"; - (*stream) << config << "|x86"; - (*stream) << "'"; - } - (*stream) << "\""; + std::ostream& stream = *this->BuildFileStream; + stream.fill(' '); + stream.width(indentLevel * 2); + stream << ""; // applies indentation + stream << "<" << tag << " Condition=\""; + stream << this->CalcCondition(config); + stream << "\""; if (attribute) { - (*stream) << attribute; + stream << attribute; } // close the tag - (*stream) << ">"; + stream << ">"; if (attribute) { - (*stream) << "\n"; + stream << "\n"; } } -cmGeneratedFileStream& cmVisualStudio10TargetGenerator::Elem::WriteString( +std::ostream& cmVisualStudio10TargetGenerator::Elem::WriteString( const char* line) { this->S.fill(' '); @@ -1299,7 +1324,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( this->WriteCustomRuleCSharp(c, name, script, inputs.str(), outputs.str(), comment); } else { - this->WriteCustomRuleCpp(c, script, inputs.str(), outputs.str(), + this->WriteCustomRuleCpp(e2, c, script, inputs.str(), outputs.str(), comment); } } @@ -1309,26 +1334,21 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( } void cmVisualStudio10TargetGenerator::WriteCustomRuleCpp( - std::string const& config, std::string const& script, + Elem& e2, std::string const& config, std::string const& script, std::string const& inputs, std::string const& outputs, std::string const& comment) { - this->WritePlatformConfigTag("Message", config, 3); - (*this->BuildFileStream) << cmVS10EscapeXML(comment) << "</Message>\n"; - this->WritePlatformConfigTag("Command", config, 3); - (*this->BuildFileStream) << cmVS10EscapeXML(script) << "</Command>\n"; - this->WritePlatformConfigTag("AdditionalInputs", config, 3); - (*this->BuildFileStream) << cmVS10EscapeXML(inputs); - (*this->BuildFileStream) << ";%(AdditionalInputs)" - "</AdditionalInputs>\n"; - this->WritePlatformConfigTag("Outputs", config, 3); - (*this->BuildFileStream) << cmVS10EscapeXML(outputs) << "</Outputs>\n"; + const std::string cond = this->CalcCondition(config); + Elem(e2, "Message").Attribute("Condition", cond).Content(comment); + Elem(e2, "Command").Attribute("Condition", cond).Content(script); + Elem(e2, "AdditionalInputs") + .Attribute("Condition", cond) + .Content(inputs + ";%(AdditionalInputs)"); + Elem(e2, "Outputs").Attribute("Condition", cond).Content(outputs); if (this->LocalGenerator->GetVersion() > cmGlobalVisualStudioGenerator::VS10) { // VS >= 11 let us turn off linking of custom command outputs. - this->WritePlatformConfigTag("LinkObjects", config, 3); - (*this->BuildFileStream) << "false" - "</LinkObjects>\n"; + Elem(e2, "LinkObjects").Attribute("Condition", cond).Content("false"); } } diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index bbe3f7f..4d74afd 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -33,6 +33,7 @@ public: ~cmVisualStudio10TargetGenerator(); void Generate(); // used by cmVisualStudioGeneratorOptions + std::string CalcCondition(const std::string& config) const; void WritePlatformConfigTag(const char* tag, const std::string& config, int indentLevel, const char* attribute = 0); @@ -131,8 +132,8 @@ private: void OutputLinkIncremental(std::string const& configName); void WriteCustomRule(cmSourceFile const* source, cmCustomCommand const& command); - void WriteCustomRuleCpp(std::string const& config, std::string const& script, - std::string const& inputs, + void WriteCustomRuleCpp(Elem& e2, std::string const& config, + std::string const& script, std::string const& inputs, std::string const& outputs, std::string const& comment); void WriteCustomRuleCSharp(std::string const& config, |