2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
6 #include "DotSerializer.hpp"
8 #include <boost/assert.hpp>
9 #include <boost/algorithm/string/replace.hpp>
18 std::string Indent(int numSpaces)
21 for (int i = 0; i < numSpaces; i++)
28 std::string Escape(std::string s)
30 boost::replace_all(s, "<", "\\<");
31 boost::replace_all(s, ">", "\\>");
38 HtmlFont::HtmlFont(std::ostream& stream, int fontSize, const char *color, const char *face)
41 GetStream() << "<FONT";
45 GetStream() << " POINT-SIZE=" << "\"" << fontSize << "\"";
48 if (color && std::strlen(color) != 0)
50 GetStream() << " COLOR=\"" << color << "\" ";
53 if (face && std::strlen(face) != 0)
55 GetStream() << " FACE=\"" << face << "\" ";
62 HtmlFont::HtmlFont(std::ostream& stream)
63 : HtmlFont(stream, -1, nullptr, nullptr)
68 GetStream() << "</FONT>";
72 DotAttributeSet::DotAttributeSet(std::ostream& stream)
78 DotAttributeSet::~DotAttributeSet()
81 for (auto&& attrib : m_Attributes)
88 GetStream() << attrib;
95 DotAttributeSet & DotAttributeSet::AddAttribute(const std::string& name, const std::stringstream& value)
98 ss << name <<"=" << value.str();
99 m_Attributes.push_back(ss.str());
103 DotAttributeSet & DotAttributeSet::AddAttribute(const std::string& name, int value)
105 std::stringstream ss;
106 ss << name <<"=" << value;
107 m_Attributes.push_back(ss.str());
111 DotAttributeSet & DotAttributeSet::AddAttribute(const std::string& name, const std::string& value)
113 std::stringstream ss;
114 ss << name <<"=\"" << value << "\"";
115 m_Attributes.push_back(ss.str());
119 DotEdge::DotEdge(std::ostream& stream, unsigned int fromNodeId, unsigned int toNodeId)
122 std::stringstream ss;
123 ss << Indent(4) << fromNodeId << " -> " << toNodeId << " ";
124 GetStream() << ss.str();
126 m_Attributes = std::make_unique<DotAttributeSet>(stream);
131 m_Attributes.reset(nullptr);
132 GetStream() << ";" << std::endl;
136 NodeContent::NodeContent(std::ostream& stream)
141 NodeContent & NodeContent::SetName(const std::string & name)
147 NodeContent & NodeContent::AddContent(const std::string & content)
149 m_Contents.push_back(content);
153 NodeContent::~NodeContent()
155 std::stringstream ss;
156 ss << "label=\"{" << m_Name;
157 if (!m_Contents.empty())
161 for (auto & content : m_Contents)
163 ss << Escape(content);
171 // Coverity fix: std::stringstream::str() may throw an exception of type std::length_error.
174 catch (const std::exception&) { } // Swallow any exception.
179 DotNode::DotNode(std::ostream& stream, unsigned int nodeId, const char* label)
182 std::stringstream ss;
183 ss << Indent(4) << nodeId;
185 GetStream() << ss.str() << " ";
187 m_Contents = std::make_unique<NodeContent>(stream);
188 m_Attributes = std::make_unique<DotAttributeSet>(stream);
190 if (std::strlen(label) != 0)
192 m_Contents->SetName(label);
196 m_Contents->SetName("<noname>");
202 m_Contents.reset(nullptr);
203 m_Attributes.reset(nullptr);
204 GetStream() << ";" << std::endl;
208 DotDefaults::DotDefaults(std::ostream& stream, const char* type)
211 std::stringstream ss;
212 ss << Indent(4) << type;
214 GetStream() << ss.str() << " ";
215 m_Attributes = std::make_unique<DotAttributeSet>(stream);
218 DotDefaults::~DotDefaults()
220 m_Attributes.reset(nullptr);
221 GetStream() << ";" << std::endl;
224 DotGraph::DotGraph(std::ostream& stream, const char* name)
227 GetStream() << "digraph " << name << " {" << std::endl;
230 DotGraph::~DotGraph()
232 GetStream() << "}" << std::endl;