Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1743)

Side by Side Diff: components/keyed_service/core/dependency_graph.cc

Issue 1414843004: [Reland] Properly escape node names in DependencyGraph Graphviz export (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix by using checked_cast Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/keyed_service/core/dependency_graph.h" 5 #include "components/keyed_service/core/dependency_graph.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <deque> 8 #include <deque>
9 #include <iterator> 9 #include <iterator>
10 10
11 #include "base/strings/string_piece.h"
12
13 namespace {
14
15 // Escapes |id| to be a valid ID in the DOT format [1]. This is implemented as
16 // enclosing the string in quotation marks, and escaping any quotation marks
17 // found with backslashes.
18 // [1] http://www.graphviz.org/content/dot-language
19 std::string Escape(base::StringPiece id) {
20 std::string result = "\"";
21 result.reserve(id.size() + 2); // +2 for the enclosing quotes.
22 size_t after_last_quot = 0;
23 size_t next_quot = id.find('"');
24 while (next_quot != base::StringPiece::npos) {
25 result.append(id.data() + after_last_quot, next_quot - after_last_quot);
26 result.append("\"");
27 after_last_quot = next_quot + 1;
28 next_quot = id.find('"', after_last_quot);
29 }
30 result.append(id.data() + after_last_quot, id.size() - after_last_quot);
31 result.append("\"");
32 return result;
33 }
34
35 } // namespace
36
11 DependencyGraph::DependencyGraph() {} 37 DependencyGraph::DependencyGraph() {}
12 38
13 DependencyGraph::~DependencyGraph() {} 39 DependencyGraph::~DependencyGraph() {}
14 40
15 void DependencyGraph::AddNode(DependencyNode* node) { 41 void DependencyGraph::AddNode(DependencyNode* node) {
16 all_nodes_.push_back(node); 42 all_nodes_.push_back(node);
17 construction_order_.clear(); 43 construction_order_.clear();
18 } 44 }
19 45
20 void DependencyGraph::RemoveNode(DependencyNode* node) { 46 void DependencyGraph::RemoveNode(DependencyNode* node) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 135
110 construction_order_ = output; 136 construction_order_ = output;
111 return true; 137 return true;
112 } 138 }
113 139
114 std::string DependencyGraph::DumpAsGraphviz( 140 std::string DependencyGraph::DumpAsGraphviz(
115 const std::string& toplevel_name, 141 const std::string& toplevel_name,
116 const base::Callback<std::string(DependencyNode*)>& node_name_callback) 142 const base::Callback<std::string(DependencyNode*)>& node_name_callback)
117 const { 143 const {
118 std::string result("digraph {\n"); 144 std::string result("digraph {\n");
145 std::string escaped_toplevel_name = Escape(toplevel_name);
119 146
120 // Make a copy of all nodes. 147 // Make a copy of all nodes.
121 std::deque<DependencyNode*> nodes; 148 std::deque<DependencyNode*> nodes;
122 std::copy(all_nodes_.begin(), all_nodes_.end(), std::back_inserter(nodes)); 149 std::copy(all_nodes_.begin(), all_nodes_.end(), std::back_inserter(nodes));
123 150
124 // State all dependencies and remove |second| so we don't generate an 151 // State all dependencies and remove |second| so we don't generate an
125 // implicit dependency on the top level node. 152 // implicit dependency on the top level node.
126 std::deque<DependencyNode*>::iterator nodes_end(nodes.end()); 153 std::deque<DependencyNode*>::iterator nodes_end(nodes.end());
127 result.append(" /* Dependencies */\n"); 154 result.append(" /* Dependencies */\n");
128 for (EdgeMap::const_iterator it = edges_.begin(); it != edges_.end(); ++it) { 155 for (EdgeMap::const_iterator it = edges_.begin(); it != edges_.end(); ++it) {
129 result.append(" "); 156 result.append(" ");
130 result.append(node_name_callback.Run(it->second)); 157 result.append(Escape(node_name_callback.Run(it->second)));
131 result.append(" -> "); 158 result.append(" -> ");
132 result.append(node_name_callback.Run(it->first)); 159 result.append(Escape(node_name_callback.Run(it->first)));
133 result.append(";\n"); 160 result.append(";\n");
134 161
135 nodes_end = std::remove(nodes.begin(), nodes_end, it->second); 162 nodes_end = std::remove(nodes.begin(), nodes_end, it->second);
136 } 163 }
137 nodes.erase(nodes_end, nodes.end()); 164 nodes.erase(nodes_end, nodes.end());
138 165
139 // Every node that doesn't depend on anything else will implicitly depend on 166 // Every node that doesn't depend on anything else will implicitly depend on
140 // the top level node. 167 // the top level node.
141 result.append("\n /* Toplevel attachments */\n"); 168 result.append("\n /* Toplevel attachments */\n");
142 for (std::deque<DependencyNode*>::const_iterator it = nodes.begin(); 169 for (std::deque<DependencyNode*>::const_iterator it = nodes.begin();
143 it != nodes.end(); 170 it != nodes.end();
144 ++it) { 171 ++it) {
145 result.append(" "); 172 result.append(" ");
146 result.append(node_name_callback.Run(*it)); 173 result.append(Escape(node_name_callback.Run(*it)));
147 result.append(" -> "); 174 result.append(" -> ");
148 result.append(toplevel_name); 175 result.append(escaped_toplevel_name);
149 result.append(";\n"); 176 result.append(";\n");
150 } 177 }
151 178
152 result.append("\n /* Toplevel node */\n"); 179 result.append("\n /* Toplevel node */\n");
153 result.append(" "); 180 result.append(" ");
154 result.append(toplevel_name); 181 result.append(escaped_toplevel_name);
155 result.append(" [shape=box];\n"); 182 result.append(" [shape=box];\n");
156 183
157 result.append("}\n"); 184 result.append("}\n");
158 return result; 185 return result;
159 } 186 }
OLDNEW
« no previous file with comments | « components/keyed_service/core/DEPS ('k') | components/keyed_service/core/dependency_graph_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698