cmVisualStudio10TargetGenerator: Code improvement

Disallow incompletely initialized Elem objects
This commit is contained in:
Vitaly Stakhovsky
2018-10-14 18:32:53 -04:00
parent f77a9576e5
commit 1601388212
2 changed files with 31 additions and 46 deletions

View File

@@ -45,24 +45,21 @@ struct cmVisualStudio10TargetGenerator::Elem
bool HasContent = false;
std::string Tag;
Elem(std::ostream& s)
Elem(std::ostream& s, const char* tag)
: S(s)
, Indent(0)
, Tag(tag)
{
this->StartElement();
}
Elem(const Elem&) = delete;
Elem(Elem& par)
: S(par.S)
, Indent(par.Indent + 1)
{
par.SetHasElements();
}
Elem(Elem& par, const char* tag)
: S(par.S)
, Indent(par.Indent + 1)
, Tag(tag)
{
par.SetHasElements();
this->StartElement(tag);
this->StartElement();
}
void SetHasElements()
{
@@ -72,12 +69,7 @@ struct cmVisualStudio10TargetGenerator::Elem
}
}
std::ostream& WriteString(const char* line);
Elem& StartElement(const std::string& tag)
{
this->Tag = tag;
this->WriteString("<") << tag;
return *this;
}
void StartElement() { this->WriteString("<") << this->Tag; }
void Element(const char* tag, const std::string& val)
{
Elem(*this, tag).Content(val);
@@ -87,8 +79,6 @@ struct cmVisualStudio10TargetGenerator::Elem
this->S << " " << an << "=\"" << cmVS10EscapeAttr(av) << "\"";
return *this;
}
// This method for now assumes that this->Tag has been set, e.g. by calling
// StartElement().
void Content(const std::string& val)
{
if (!this->HasContent) {
@@ -380,8 +370,7 @@ void cmVisualStudio10TargetGenerator::Generate()
<< this->GlobalGenerator->Encoding() << "\"?>"
<< "\n";
{
Elem e0(BuildFileStream);
e0.StartElement("Project");
Elem e0(BuildFileStream, "Project");
e0.Attribute("DefaultTargets", "Build");
e0.Attribute("ToolsVersion", this->GlobalGenerator->GetToolsVersion());
e0.Attribute("xmlns",
@@ -922,8 +911,8 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup(Elem& e0)
xamlType = "Page";
}
Elem e2(e1);
this->WriteSource(e2, xamlType, oi);
Elem e2(e1, xamlType);
this->WriteSource(e2, oi);
e2.SetHasElements();
if (this->ProjectType == csproj && !this->InSourceBuild) {
// add <Link> tag to written XAML source if necessary
@@ -1275,15 +1264,15 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
std::unique_ptr<Elem> spe2;
if (this->ProjectType != csproj) {
spe1 = cm::make_unique<Elem>(e0, "ItemGroup");
spe2 = cm::make_unique<Elem>(*spe1);
this->WriteSource(*spe2, "CustomBuild", source);
spe2 = cm::make_unique<Elem>(*spe1, "CustomBuild");
this->WriteSource(*spe2, source);
spe2->SetHasElements();
} else {
Elem e1(e0, "ItemGroup");
Elem e2(e1);
Elem e2(e1, "None");
std::string link;
this->GetCSharpSourceLink(source, link);
this->WriteSource(e2, "None", source);
this->WriteSource(e2, source);
e2.SetHasElements();
if (!link.empty()) {
e2.Element("Link", link);
@@ -1417,8 +1406,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
<< this->GlobalGenerator->Encoding() << "\"?>"
<< "\n";
{
Elem e0(fout);
e0.StartElement("Project");
Elem e0(fout, "Project");
e0.Attribute("ToolsVersion", this->GlobalGenerator->GetToolsVersion());
e0.Attribute("xmlns",
"http://schemas.microsoft.com/developer/msbuild/2003");
@@ -1569,8 +1557,8 @@ void cmVisualStudio10TargetGenerator::WriteHeaderSource(Elem& e1,
cmSourceFile const* sf)
{
std::string const& fileName = sf->GetFullPath();
Elem e2(e1);
this->WriteSource(e2, "ClInclude", sf);
Elem e2(e1, "ClInclude");
this->WriteSource(e2, sf);
if (this->IsResxHeader(fileName)) {
e2.Element("FileType", "CppForm");
} else if (this->IsXamlHeader(fileName)) {
@@ -1738,8 +1726,8 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
}
}
Elem e2(e1);
this->WriteSource(e2, tool, sf);
Elem e2(e1, tool);
this->WriteSource(e2, sf);
if (toolHasSettings) {
e2.SetHasElements();
@@ -1859,7 +1847,6 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
}
void cmVisualStudio10TargetGenerator::WriteSource(Elem& e2,
std::string const& tool,
cmSourceFile const* sf)
{
// Visual Studio tools append relative paths to the current dir, as in:
@@ -1895,11 +1882,10 @@ void cmVisualStudio10TargetGenerator::WriteSource(Elem& e2,
}
}
ConvertToWindowsSlash(sourceFile);
e2.StartElement(tool);
e2.Attribute("Include", sourceFile);
ToolSource toolSource = { sf, forceRelative };
this->Tools[tool].push_back(toolSource);
this->Tools[e2.Tag].push_back(toolSource);
}
void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
@@ -2003,8 +1989,8 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
include_configs.begin(), include_configs.end(),
std::back_inserter(exclude_configs));
Elem e2(e1);
this->WriteSource(e2, tool, si.Source);
Elem e2(e1, tool);
this->WriteSource(e2, si.Source);
if (si.Kind == cmGeneratorTarget::SourceKindObjectSource) {
this->OutputSourceSpecificFlags(e2, si.Source);
}
@@ -3882,15 +3868,13 @@ void cmVisualStudio10TargetGenerator::WriteSinglePlatformExtension(
void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0)
{
std::vector<std::string> sdkReferences;
Elem e1(e0);
bool hasWrittenItemGroup = false;
std::unique_ptr<Elem> spe1;
if (const char* vsSDKReferences =
this->GeneratorTarget->GetProperty("VS_SDK_REFERENCES")) {
cmSystemTools::ExpandListArgument(vsSDKReferences, sdkReferences);
e1.StartElement("ItemGroup");
hasWrittenItemGroup = true;
spe1 = cm::make_unique<Elem>(e0, "ItemGroup");
for (std::string const& ri : sdkReferences) {
Elem(e1, "SDKReference").Attribute("Include", ri);
Elem(*spe1, "SDKReference").Attribute("Include", ri);
}
}
@@ -3906,19 +3890,20 @@ void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0)
if (desktopExtensionsVersion || mobileExtensionsVersion ||
iotExtensionsVersion) {
if (!hasWrittenItemGroup) {
e1.StartElement("ItemGroup");
if (!spe1) {
spe1 = cm::make_unique<Elem>(e0, "ItemGroup");
}
if (desktopExtensionsVersion) {
this->WriteSingleSDKReference(e1, "WindowsDesktop",
this->WriteSingleSDKReference(*spe1, "WindowsDesktop",
desktopExtensionsVersion);
}
if (mobileExtensionsVersion) {
this->WriteSingleSDKReference(e1, "WindowsMobile",
this->WriteSingleSDKReference(*spe1, "WindowsMobile",
mobileExtensionsVersion);
}
if (iotExtensionsVersion) {
this->WriteSingleSDKReference(e1, "WindowsIoT", iotExtensionsVersion);
this->WriteSingleSDKReference(*spe1, "WindowsIoT",
iotExtensionsVersion);
}
}
}

View File

@@ -63,7 +63,7 @@ private:
void WriteExtraSource(Elem& e1, cmSourceFile const* sf);
void WriteNsightTegraConfigurationValues(Elem& e1,
std::string const& config);
void WriteSource(Elem& e2, std::string const& tool, cmSourceFile const* sf);
void WriteSource(Elem& e2, cmSourceFile const* sf);
void WriteExcludeFromBuild(Elem& e2,
std::vector<size_t> const& exclude_configs);
void WriteAllSources(Elem& e0);