The Gaudi Framework  master (bef125d4)
Loading...
Searching...
No Matches
GraphDumper.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2026 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11#include "GraphDumper.h"
12
13#include <boost/algorithm/string/replace.hpp>
14
15namespace {
16 std::string escapeSpecialCharactersForMl( std::string_view view ) {
17 std::string result;
18 result.reserve( view.size() * 6 ); // Worst case: all characters become "&quot;" (6 chars)
19 for ( char c : view ) {
20 switch ( c ) {
21 case '&':
22 result += "&amp;";
23 break;
24 case '<':
25 result += "&lt;";
26 break;
27 case '>':
28 result += "&gt;";
29 break;
30 case '"':
31 result += "&quot;";
32 break;
33 default:
34 result.push_back( c );
35 break;
36 }
37 }
38
39 return std::string{ result };
40 }
41} // namespace
42
43namespace Gaudi::Hive {
44
45 Graph::Graph( std::string_view fileName, FileType type ) : m_fileName{ fileName }, m_type{ type } {
46 // find out type of file if not given
47 if ( type == FileType::UNKNOWN ) {
48 // Check file extension
49 if ( m_fileName.ends_with( ".dot" ) ) {
51 } else if ( m_fileName.ends_with( ".md" ) ) {
53 } else if ( m_fileName.ends_with( ".graphml" ) ) {
55 } else {
57 m_fileName += ".dot";
58 }
59 }
60 // open file
61 m_stream = std::ofstream{ m_fileName, std::ofstream::out };
63 }
64
67 m_stream.close();
68 }
69
70 std::string const& Graph::fileName() { return m_fileName; }
71
72 void Graph::addNode( std::string_view id, std::string_view name ) {
73 switch ( m_type ) {
74 case FileType::DOT:
75 m_stream << " " << id << " [label=\"" << name << "\";shape=box];\n";
76 break;
77 case FileType::MD:
78 m_stream << " " << id << "{{" << name << "}}\n";
79 break;
80 case FileType::ML:
81 m_stream << " <node id=\"" << id
82 << "\">\n"
83 " <data key=\"d0\">"
84 << escapeSpecialCharactersForMl( name )
85 << "</data>\n"
86 " </node>\n";
87 break;
89 break;
90 }
91 };
92
93 void Graph::addEdge( std::string_view srcId, std::string_view tgtId, std::string_view label ) {
94 switch ( m_type ) {
95 case FileType::DOT:
96 m_stream << " " << srcId << " -> " << tgtId;
97 if ( label != "" ) m_stream << " [label=\"" << label << "\"]";
98 m_stream << ";\n";
99 break;
100 case FileType::MD:
101 m_stream << " " << srcId << " --> " << tgtId;
102 if ( label != "" ) m_stream << " : " << label;
103 m_stream << "\n";
104 break;
105 case FileType::ML:
106 if ( label != "" ) {
107 m_stream << " <edge source=\"" << srcId << "\" target=\"" << tgtId
108 << "\">\n"
109 " <data key=\"d1\">"
110 << escapeSpecialCharactersForMl( label )
111 << "</data>\n"
112 " </edge>\n";
113 } else {
114 m_stream << " <edge source=\"" << srcId << "\" target=\"" << tgtId << "\"/>\n";
115 }
116 break;
118 break;
119 }
120 };
121
122 //---------------------------------------------------------------------------
123
125 switch ( m_type ) {
126 case FileType::DOT:
127 m_stream << "digraph datadeps {\n rankdir=\"LR\";\n";
128 break;
129 case FileType::MD:
130 m_stream << "```mermaid\ngraph LR;\n\n";
131 break;
132 case FileType::ML:
133 m_stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
134 "<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\"\n"
135 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
136 " xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns "
137 "http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">\n"
138 " <key id=\"d1\" for=\"edge\" attr.name=\"label\" attr.type=\"string\"/>\n"
139 " <key id=\"d0\" for=\"node\" attr.name=\"label\" attr.type=\"string\"/>\n"
140 " <graph id=\"Dependencies\" edgedefault=\"directed\">\n";
141 break;
143 break;
144 }
145 }
146
148 switch ( m_type ) {
149 case FileType::DOT:
150 m_stream << "}\n";
151 break;
152 case FileType::MD:
153 m_stream << "```\n";
154 break;
155 case FileType::ML:
156 m_stream << " </graph>\n</graphml>";
157 break;
159 break;
160 }
161 }
162
163} // end namespace Gaudi::Hive
void addNode(std::string_view id, std::string_view name)
FileType m_type
type of file used
Definition GraphDumper.h:60
void addEdge(std::string_view srcId, std::string_view tgtId, std::string_view label="")
std::string m_fileName
name of the filed used for storing the graph
Definition GraphDumper.h:56
std::string const & fileName()
Graph(std::string_view fileName, FileType type=FileType::UNKNOWN)
Creates a graph with given type and given file name.
std::ofstream m_stream
stream to the graph file
Definition GraphDumper.h:58