|
14 | 14 | #include <algorithm> |
15 | 15 | #include <deque> |
16 | 16 | #include <iostream> |
| 17 | +#include <set> |
17 | 18 |
|
18 | 19 | static bool MatchesGlob(std::string_view haystack, std::string_view pattern) |
19 | 20 | { |
@@ -156,6 +157,49 @@ ROOT::CmdLine::ParseRootSources(const std::vector<std::string> &sourcesRaw, std: |
156 | 157 | return sources; |
157 | 158 | } |
158 | 159 |
|
| 160 | +void ROOT::CmdLine::PrintObjTree(const RootObjTree &tree, std::ostream &out) |
| 161 | +{ |
| 162 | + if (tree.fNodes.empty()) |
| 163 | + return; |
| 164 | + |
| 165 | + struct RevNode { |
| 166 | + std::set<NodeIdx_t> fChildren; |
| 167 | + }; |
| 168 | + std::vector<RevNode> revNodes; |
| 169 | + revNodes.resize(tree.fNodes.size()); |
| 170 | + |
| 171 | + // Un-linearize the tree |
| 172 | + for (int i = (int)tree.fNodes.size() - 1; i >= 0; --i) { |
| 173 | + const auto *node = &tree.fNodes[i]; |
| 174 | + NodeIdx_t childIdx = i; |
| 175 | + NodeIdx_t parentIdx = node->fParent; |
| 176 | + while (childIdx != parentIdx) { |
| 177 | + auto &revNodeParent = revNodes[parentIdx]; |
| 178 | + revNodeParent.fChildren.insert(childIdx); |
| 179 | + node = &tree.fNodes[parentIdx]; |
| 180 | + childIdx = parentIdx; |
| 181 | + parentIdx = node->fParent; |
| 182 | + } |
| 183 | + } |
| 184 | + |
| 185 | + // Print out the tree. |
| 186 | + // Vector of {nesting, nodeIdx} |
| 187 | + std::vector<std::pair<std::uint32_t, NodeIdx_t>> nodesToVisit = {{0, 0}}; |
| 188 | + while (!nodesToVisit.empty()) { |
| 189 | + const auto [nesting, nodeIdx] = nodesToVisit.back(); |
| 190 | + nodesToVisit.pop_back(); |
| 191 | + const auto &cur = revNodes[nodeIdx]; |
| 192 | + const auto &node = tree.fNodes[nodeIdx]; |
| 193 | + for (auto i = 0u; i < 2 * nesting; ++i) |
| 194 | + out << ' '; |
| 195 | + out << node.fName << " : " << node.fClassName << "\n"; |
| 196 | + // Add the children in reverse order to preserve alphabetical order during depth-first visit. |
| 197 | + for (auto it = cur.fChildren.rbegin(); it != cur.fChildren.rend(); ++it) { |
| 198 | + nodesToVisit.push_back({nesting + 1, *it}); |
| 199 | + } |
| 200 | + } |
| 201 | +} |
| 202 | + |
159 | 203 | std::string ROOT::CmdLine::NodeFullPath(const ROOT::CmdLine::RootObjTree &tree, ROOT::CmdLine::NodeIdx_t nodeIdx, |
160 | 204 | ROOT::CmdLine::ENodeFullPathOpt opt) |
161 | 205 | { |
|
0 commit comments