summaryrefslogtreecommitdiff
path: root/Source/cmGraphVizWriter.cxx
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2021-10-08 09:20:10 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2021-10-08 09:20:10 +0900
commitf58f7a233a9b66287e1a0fad0d149e3202a098b4 (patch)
treecc0cea82fae3f153df9299b27650e17c58da1125 /Source/cmGraphVizWriter.cxx
parent46f8b5215bbbfcf4bc0caed1daf52b678fd2b976 (diff)
downloadcmake-upstream/3.18.0.tar.gz
cmake-upstream/3.18.0.tar.bz2
cmake-upstream/3.18.0.zip
Imported Upstream version 3.18.0upstream/3.18.0
Diffstat (limited to 'Source/cmGraphVizWriter.cxx')
-rw-r--r--Source/cmGraphVizWriter.cxx224
1 files changed, 56 insertions, 168 deletions
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index e03b2ca6c..0fcda4e3e 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -67,36 +67,6 @@ const char* getShapeForTarget(const cmLinkItem& item)
return GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN;
}
}
-
-struct DependeesDir
-{
- template <typename T>
- static const cmLinkItem& src(const T& con)
- {
- return con.src;
- }
-
- template <typename T>
- static const cmLinkItem& dst(const T& con)
- {
- return con.dst;
- }
-};
-
-struct DependersDir
-{
- template <typename T>
- static const cmLinkItem& src(const T& con)
- {
- return con.dst;
- }
-
- template <typename T>
- static const cmLinkItem& dst(const T& con)
- {
- return con.src;
- }
-};
}
cmGraphVizWriter::cmGraphVizWriter(std::string const& fileName,
@@ -203,16 +173,18 @@ void cmGraphVizWriter::VisitLink(cmLinkItem const& depender,
return;
}
- // write global data directly
this->WriteConnection(this->GlobalFileStream, depender, dependee, scopeType);
if (this->GeneratePerTarget) {
- PerTargetConnections[depender].emplace_back(depender, dependee, scopeType);
+ auto fileStream = PerTargetFileStreams[depender.AsStr()].get();
+ this->WriteNode(*fileStream, dependee);
+ this->WriteConnection(*fileStream, depender, dependee, scopeType);
}
if (this->GenerateDependers) {
- TargetDependersConnections[dependee].emplace_back(dependee, depender,
- scopeType);
+ auto fileStream = TargetDependersFileStreams[dependee.AsStr()].get();
+ this->WriteNode(*fileStream, depender);
+ this->WriteConnection(*fileStream, depender, dependee, scopeType);
}
}
@@ -316,99 +288,23 @@ void cmGraphVizWriter::Write()
}
}
- // write global data and collect all connection data for per target graphs
for (auto const gt : sortedGeneratorTargets) {
auto item = cmLinkItem(gt, false, gt->GetBacktrace());
this->VisitItem(item);
}
-
- if (this->GeneratePerTarget) {
- WritePerTargetConnections<DependeesDir>(PerTargetConnections,
- PerTargetFileStreams);
- }
-
- if (this->GenerateDependers) {
- WritePerTargetConnections<DependersDir>(TargetDependersConnections,
- TargetDependersFileStreams);
- }
-}
-
-void cmGraphVizWriter::FindAllConnections(const ConnectionsMap& connectionMap,
- const cmLinkItem& rootItem,
- Connections& extendedCons,
- std::set<cmLinkItem>& visitedItems)
-{
- // some "targets" are not in map, e.g. linker flags as -lm or
- // targets without dependency.
- // in both cases we are finished with traversing the graph
- if (connectionMap.find(rootItem) == connectionMap.cend()) {
- return;
- }
-
- const Connections& origCons = connectionMap.at(rootItem);
-
- for (const Connection& con : origCons) {
- extendedCons.emplace_back(con);
- const cmLinkItem& dstItem = con.dst;
- bool const visited = visitedItems.find(dstItem) != visitedItems.cend();
- if (!visited) {
- visitedItems.insert(dstItem);
- FindAllConnections(connectionMap, dstItem, extendedCons, visitedItems);
- }
- }
-}
-
-void cmGraphVizWriter::FindAllConnections(const ConnectionsMap& connectionMap,
- const cmLinkItem& rootItem,
- Connections& extendedCons)
-{
- std::set<cmLinkItem> visitedItems = { rootItem };
- FindAllConnections(connectionMap, rootItem, extendedCons, visitedItems);
-}
-
-template <typename DirFunc>
-void cmGraphVizWriter::WritePerTargetConnections(
- const ConnectionsMap& connections, const FileStreamMap& streams)
-{
- // the per target connections must be extended by indirect dependencies
- ConnectionsMap extendedConnections;
- for (auto const& conPerTarget : connections) {
- const cmLinkItem& rootItem = conPerTarget.first;
- Connections& extendedCons = extendedConnections[conPerTarget.first];
- FindAllConnections(connections, rootItem, extendedCons);
- }
-
- for (auto const& conPerTarget : extendedConnections) {
- const cmLinkItem& rootItem = conPerTarget.first;
-
- // some of the nodes are excluded completely and are not written
- if (this->ItemExcluded(rootItem)) {
- continue;
- }
-
- const Connections& cons = conPerTarget.second;
- auto fileStream = streams.at(rootItem.AsStr()).get();
-
- for (const Connection& con : cons) {
- const cmLinkItem& src = DirFunc::src(con);
- const cmLinkItem& dst = DirFunc::dst(con);
- this->WriteNode(*fileStream, con.dst);
- this->WriteConnection(*fileStream, src, dst, con.scopeType);
- }
- }
}
void cmGraphVizWriter::WriteHeader(cmGeneratedFileStream& fs,
const std::string& name)
{
auto const escapedGraphName = EscapeForDotFile(name);
- fs << "digraph \"" << escapedGraphName << "\" {" << std::endl;
- fs << this->GraphHeader << std::endl;
+ fs << "digraph \"" << escapedGraphName << "\" {\n"
+ << this->GraphHeader << '\n';
}
void cmGraphVizWriter::WriteFooter(cmGeneratedFileStream& fs)
{
- fs << "}" << std::endl;
+ fs << "}\n";
}
void cmGraphVizWriter::WriteLegend(cmGeneratedFileStream& fs)
@@ -416,52 +312,46 @@ void cmGraphVizWriter::WriteLegend(cmGeneratedFileStream& fs)
// Note that the subgraph name must start with "cluster", as done here, to
// make Graphviz layout engines do the right thing and keep the nodes
// together.
- fs << "subgraph clusterLegend {" << std::endl;
- fs << " label = \"Legend\";" << std::endl;
- // Set the color of the box surrounding the legend.
- fs << " color = black;" << std::endl;
- // We use invisible edges just to enforce the layout.
- fs << " edge [ style = invis ];" << std::endl;
-
- // Nodes.
- fs << " legendNode0 [ label = \"Executable\", shape = "
- << GRAPHVIZ_NODE_SHAPE_EXECUTABLE << " ];" << std::endl;
-
- fs << " legendNode1 [ label = \"Static Library\", shape = "
- << GRAPHVIZ_NODE_SHAPE_LIBRARY_STATIC << " ];" << std::endl;
- fs << " legendNode2 [ label = \"Shared Library\", shape = "
- << GRAPHVIZ_NODE_SHAPE_LIBRARY_SHARED << " ];" << std::endl;
- fs << " legendNode3 [ label = \"Module Library\", shape = "
- << GRAPHVIZ_NODE_SHAPE_LIBRARY_MODULE << " ];" << std::endl;
-
- fs << " legendNode4 [ label = \"Interface Library\", shape = "
- << GRAPHVIZ_NODE_SHAPE_LIBRARY_INTERFACE << " ];" << std::endl;
- fs << " legendNode5 [ label = \"Object Library\", shape = "
- << GRAPHVIZ_NODE_SHAPE_LIBRARY_OBJECT << " ];" << std::endl;
- fs << " legendNode6 [ label = \"Unknown Library\", shape = "
- << GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN << " ];" << std::endl;
-
- fs << " legendNode7 [ label = \"Custom Target\", shape = "
- << GRAPHVIZ_NODE_SHAPE_UTILITY << " ];" << std::endl;
-
- // Edges.
- // Some of those are dummy (invisible) edges to enforce a layout.
- fs << " legendNode0 -> legendNode1 [ style = " << GRAPHVIZ_EDGE_STYLE_PUBLIC
- << " ];" << std::endl;
- fs << " legendNode0 -> legendNode2 [ style = " << GRAPHVIZ_EDGE_STYLE_PUBLIC
- << " ];" << std::endl;
- fs << " legendNode0 -> legendNode3;" << std::endl;
-
- fs << " legendNode1 -> legendNode4 [ label = \"Interface\", style = "
- << GRAPHVIZ_EDGE_STYLE_INTERFACE << " ];" << std::endl;
- fs << " legendNode2 -> legendNode5 [ label = \"Private\", style = "
- << GRAPHVIZ_EDGE_STYLE_PRIVATE << " ];" << std::endl;
- fs << " legendNode3 -> legendNode6 [ style = " << GRAPHVIZ_EDGE_STYLE_PUBLIC
- << " ];" << std::endl;
-
- fs << " legendNode0 -> legendNode7;" << std::endl;
-
- fs << "}" << std::endl;
+ /* clang-format off */
+ fs << "subgraph clusterLegend {\n"
+ " label = \"Legend\";\n"
+ // Set the color of the box surrounding the legend.
+ " color = black;\n"
+ // We use invisible edges just to enforce the layout.
+ " edge [ style = invis ];\n"
+ // Nodes.
+ " legendNode0 [ label = \"Executable\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_EXECUTABLE << " ];\n"
+ " legendNode1 [ label = \"Static Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_STATIC << " ];\n"
+ " legendNode2 [ label = \"Shared Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_SHARED << " ];\n"
+ " legendNode3 [ label = \"Module Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_MODULE << " ];\n"
+ " legendNode4 [ label = \"Interface Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_INTERFACE << " ];\n"
+ " legendNode5 [ label = \"Object Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_OBJECT << " ];\n"
+ " legendNode6 [ label = \"Unknown Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN << " ];\n"
+ " legendNode7 [ label = \"Custom Target\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_UTILITY << " ];\n"
+ // Edges.
+ // Some of those are dummy (invisible) edges to enforce a layout.
+ " legendNode0 -> legendNode1 [ style = "
+ << GRAPHVIZ_EDGE_STYLE_PUBLIC << " ];\n"
+ " legendNode0 -> legendNode2 [ style = "
+ << GRAPHVIZ_EDGE_STYLE_PUBLIC << " ];\n"
+ " legendNode0 -> legendNode3;\n"
+ " legendNode1 -> legendNode4 [ label = \"Interface\", style = "
+ << GRAPHVIZ_EDGE_STYLE_INTERFACE << " ];\n"
+ " legendNode2 -> legendNode5 [ label = \"Private\", style = "
+ << GRAPHVIZ_EDGE_STYLE_PRIVATE << " ];\n"
+ " legendNode3 -> legendNode6 [ style = "
+ << GRAPHVIZ_EDGE_STYLE_PUBLIC << " ];\n"
+ " legendNode0 -> legendNode7;\n"
+ "}\n";
+ /* clang-format off */
}
void cmGraphVizWriter::WriteNode(cmGeneratedFileStream& fs,
@@ -474,7 +364,7 @@ void cmGraphVizWriter::WriteNode(cmGeneratedFileStream& fs,
auto const escapedLabel = EscapeForDotFile(itemNameWithAliases);
fs << " \"" << nodeName << "\" [ label = \"" << escapedLabel
- << "\", shape = " << getShapeForTarget(item) << " ];" << std::endl;
+ << "\", shape = " << getShapeForTarget(item) << " ];\n";
}
void cmGraphVizWriter::WriteConnection(cmGeneratedFileStream& fs,
@@ -486,11 +376,9 @@ void cmGraphVizWriter::WriteConnection(cmGeneratedFileStream& fs,
auto const& dependeeName = dependee.AsStr();
fs << " \"" << this->NodeNames[dependerName] << "\" -> \""
- << this->NodeNames[dependeeName] << "\" ";
-
- fs << edgeStyle;
-
- fs << " // " << dependerName << " -> " << dependeeName << std::endl;
+ << this->NodeNames[dependeeName] << "\" "
+ << edgeStyle
+ << " // " << dependerName << " -> " << dependeeName << '\n';
}
bool cmGraphVizWriter::ItemExcluded(cmLinkItem const& item)
@@ -506,9 +394,9 @@ bool cmGraphVizWriter::ItemExcluded(cmLinkItem const& item)
}
if (item.Target->GetType() == cmStateEnums::UTILITY) {
- if ((itemName.find("Nightly") == 0) ||
- (itemName.find("Continuous") == 0) ||
- (itemName.find("Experimental") == 0)) {
+ if (cmHasLiteralPrefix(itemName, "Nightly") ||
+ cmHasLiteralPrefix(itemName, "Continuous") ||
+ cmHasLiteralPrefix(itemName, "Experimental")) {
return true;
}
}