-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdoxygen_dot_merge.pl
148 lines (121 loc) · 3.77 KB
/
doxygen_dot_merge.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/perl
use Data::Dumper;
use feature 'say';
my $gindex = 1;
my %node2node = ();
my %connections = ();
my %sym2node = ();
my %sym2url = ();
my %file2nodes = ();
my %node2sym = ();
my $main_fn_index = 1;
foreach $argnum (0 .. $#ARGV) {
for (keys %node2node)
{
delete $node2node{$_};
}
# pass 1:: node mappings
open (dotf,$ARGV[$argnum]) || die "Cannot read logfile!\n";;
while (<dotf>) {
if (/Node/) {
my ($num, $sym, $rest) = /^ *Node(\d+) \[label=\"([^\"]+)"(.*)$/;
if ($num) {
if ($sym eq "main") {
$sym = $sym.$main_fn_index;
# if your code has many test files each having a main() function, this will give each main fn a nerw node.
# commented out for now.
#$main_fn_index ++;
}
if (exists $sym2node{$sym}) {
$node2node{$num} = $sym2node{$sym};
} else {
my ($url) = ($rest =~ m/^.*URL=\"([^\"]+)".*$/);
$sym2node{$sym} = $gindex;
$node2sym{$gindex} = $sym;
$sym2url{$sym} = $url;
$node2node{$num} = $gindex;
$gindex ++;
}
if ($num == 1) {
my ($file) = ($ARGV[$argnum] =~ m/(^.*)_8[ch].*$/);
push(@{$file2nodes{$file}}, $sym2node{$sym});
}
}
}
}
close(dotf);
# pass 2:: renaming
open (dotf,$ARGV[$argnum]) || die "Cannot read dot file!\n";;
while (<dotf>) {
if (/Node/) {
my ($num1, $num2, $rest) = /^ *Node(\d+) -> Node(\d+)(.*)$/;
if ($num1) {
if ($rest =~ m/dir=back/) {
my $t = $num1;
$num1 = $num2;
$num2 = $t;
}
my $key=$node2node{$num1}.".".$node2node{$num2};
if (exists $connections{$key}) {
} else {
$connections{$key} = "yes";
}
}
}
}
close(dotf);
}
########### print df the .dot file
open (df, '>html/merged.dot');
print df "digraph G\n";
print df "{\n";
print df " edge [fontname=\"FreeSans\",fontsize=\"10\",labelfontname=\"FreeSans\",labelfontsize=\"10\"];\n";
print df " node [fontname=\"FreeSans\",fontsize=\"10\",shape=record];\n";
print df " rankdir=LR;\n";
for (sort keys %sym2node) {
print df " Node".$sym2node{$_}." [label=\"".$_."\",height=0.2,width=0.4,color=\"black\", fillcolor=\"white\", style=\"filled\",URL=\"".$sym2url{$_}."\"];\n";
}
for (sort keys %connections) {
my ($n1,$n2) = /(\d+)\.(\d+)/;
print df " Node".$n1." -> Node".$n2." [dir=front,color=\"midnightblue\",fontsize=\"10\",style=\"solid\",fontname=\"FreeSans\"];\n";
}
#say Dumper(%file2nodes);
## the below tries to place functions from the same file in a same rank
## sometimes the dot layout is too vertical because of this.
## hence we are only placing @ max 6 fn/s in the same rank
for (sort keys %file2nodes) {
print df "#file >> ".$_."\n";
if ((@{$file2nodes{$_}}-1) < 6) {
print df "{ rank=same; ";
foreach $i (0 .. (@{$file2nodes{$_}}-1)) {
print df " Node".$file2nodes{$_}[$i]."; ";
}
print df "}\n";
}
}
print df "}\n";
close(df);
########### generate png and map files
os.system("dot html/merged.dot -Tpng -o html/merged.png");
os.system("dot html/merged.dot -Tcmapx -o html/merged.map");
########## create html file and embed map in it
open (hf, '>html/merged.html');
print hf "<html>\n";
print hf "<div>\n";
print hf "<div class=\"center\">\n";
print hf "<img border=\"0\" alt=\"\" usemap=\"#merged_map\" src=\"merged.png\">\n";
print hf "</div>\n";
print hf "<map id=\"merged\" name=\"merged_map\">\n";
# contents of merged.map with $ removed
open (mf,"html/merged.map") || die "Cannot read map file!\n";;
while (<mf>) {
if(/area/) {
s/\$//;
print hf $_;
}
}
close(mf);
print hf "</map>\n";
print hf "</div>\n";
print hf "</html>\n";
close(hf);