Go-Callvis Viewer

Home|gocallvis/dot.go
1package main
2
3import (
4    "bytes"
5    "fmt"
6    "io"
7    "log"
8    "os"
9    "os/exec"
10    "path/filepath"
11    "strings"
12    "text/template"
13)
14
15var (
16    minlen    uint
17    nodesep   float64
18    nodeshape string
19    nodestyle string
20    rankdir   string
21)
22
23const tmplCluster = `{{define "cluster" -}}
24    {{printf "subgraph %q {" .}}
25        {{printf "%s" .Attrs.Lines}}
26        {{range .Nodes}}
27        {{template "node" .}}
28        {{- end}}
29        {{range .Clusters}}
30        {{template "cluster" .}}
31        {{- end}}
32    {{println "}" }}
33{{- end}}`
34
35const tmplNode = `{{define "edge" -}}
36    {{printf "%q -> %q [ %s ]" .From .To .Attrs}}
37{{- end}}`
38
39const tmplEdge = `{{define "node" -}}
40    {{printf "%q [ %s ]" .ID .Attrs}}
41{{- end}}`
42
43const tmplGraph = `digraph gocallvis {
44    label="{{.Title}}";
45    labeljust="l";
46    fontname="Arial";
47    fontsize="14";
48    rankdir="{{.Options.rankdir}}";
49    bgcolor="lightgray";
50    style="solid";
51    penwidth="0.5";
52    pad="0.0";
53    nodesep="{{.Options.nodesep}}";
54
55    node [shape="{{.Options.nodeshape}}" style="{{.Options.nodestyle}}" fillcolor="honeydew" fontname="Verdana" penwidth="1.0" margin="0.05,0.0"];
56    edge [minlen="{{.Options.minlen}}"]
57
58    {{template "cluster" .Cluster}}
59
60    {{- range .Edges}}
61    {{template "edge" .}}
62    {{- end}}
63}
64`
65
66//==[ type def/func: dotCluster ]===============================================
67type dotCluster struct {
68    ID       string
69    Clusters map[string]*dotCluster
70    Nodes    []*dotNode
71    Attrs    dotAttrs
72}
73
74func NewDotCluster(id string) *dotCluster {
75    return &dotCluster{
76        ID:       id,
77        Clustersmake(map[string]*dotCluster),
78        Attrs:    make(dotAttrs),
79    }
80}
81
82func (c *dotClusterString() string {
83    return fmt.Sprintf("cluster_%s"c.ID)
84}
85
86//==[ type def/func: dotNode    ]===============================================
87type dotNode struct {
88    ID    string
89    Attrs dotAttrs
90}
91
92func (n *dotNodeString() string {
93    return n.ID
94}
95
96//==[ type def/func: dotEdge    ]===============================================
97type dotEdge struct {
98    From  *dotNode
99    To    *dotNode
100    Attrs dotAttrs
101}
102
103//==[ type def/func: dotAttrs   ]===============================================
104type dotAttrs map[string]string
105
106func (p dotAttrsList() []string {
107    l := []string{}
108    for kv := range p {
109        l = append(lfmt.Sprintf("%s=%q"kv))
110    }
111    return l
112}
113
114func (p dotAttrsString() string {
115    return strings.Join(p.List(), " ")
116}
117
118func (p dotAttrsLines() string {
119    return fmt.Sprintf("%s;"strings.Join(p.List(), ";\n"))
120}
121
122//==[ type def/func: dotGraph   ]===============================================
123type dotGraph struct {
124    Title   string
125    Minlen  uint
126    Attrs   dotAttrs
127    Cluster *dotCluster
128    Nodes   []*dotNode
129    Edges   []*dotEdge
130    Options map[string]string
131}
132
133func (g *dotGraphWriteDot(w io.Writererror {
134    t := template.New("dot")
135    for _s := range []string{tmplClustertmplNodetmplEdgetmplGraph} {
136        if _err := t.Parse(s); err != nil {
137            return err
138        }
139    }
140    var buf bytes.Buffer
141    if err := t.Execute(&bufg); err != nil {
142        return err
143    }
144    _err := buf.WriteTo(w)
145    return err
146}
147
148func dotToImage(outfname stringformat stringdot []byte) (stringerror) {
149    if *graphvizFlag {
150        return runDotToImageCallSystemGraphviz(outfnameformatdot)
151    }
152
153    return runDotToImage(outfnameformatdot)
154}
155
156// location of dot executable for converting from .dot to .svg
157// it's usually at: /usr/bin/dot
158var dotSystemBinary string
159
160// runDotToImageCallSystemGraphviz generates a SVG using the 'dot' utility, returning the filepath
161func runDotToImageCallSystemGraphviz(outfname stringformat stringdot []byte) (stringerror) {
162    if dotSystemBinary == "" {
163        doterr := exec.LookPath("dot")
164        if err != nil {
165            log.Fatalln("unable to find program 'dot', please install it or check your PATH")
166        }
167        dotSystemBinary = dot
168    }
169
170    var img string
171    if outfname == "" {
172        img = filepath.Join(os.TempDir(), fmt.Sprintf("go-callvis_export.%s"format))
173    } else {
174        img = fmt.Sprintf("%s.%s"outfnameformat)
175    }
176    cmd := exec.Command(dotSystemBinaryfmt.Sprintf("-T%s"format), "-o"img)
177    cmd.Stdin = bytes.NewReader(dot)
178    var stderr bytes.Buffer
179    cmd.Stderr = &stderr
180    if err := cmd.Run(); err != nil {
181        return ""fmt.Errorf("command '%v': %v\n%v"cmderrstderr.String())
182    }
183    return imgnil
184}
185
MembersX
NewDotCluster.id
dotAttrs
dotAttrs.List.p
dotAttrs.List.l
dotGraph.Nodes
dotGraph.Options
rankdir
tmplGraph
dotGraph
dotGraph.WriteDot.RangeStmt_2941.BlockStmt._
dotGraph.WriteDot.RangeStmt_2941.BlockStmt.err
dotCluster
dotNode
runDotToImageCallSystemGraphviz
runDotToImageCallSystemGraphviz.BlockStmt.err
runDotToImageCallSystemGraphviz.err
dotAttrs.String
dotToImage.outfname
runDotToImageCallSystemGraphviz.format
dotGraph.WriteDot.g
dotToImage.dot
dotGraph.Minlen
dotGraph.Attrs
runDotToImageCallSystemGraphviz.img
runDotToImageCallSystemGraphviz.stderr
nodesep
nodestyle
dotNode.Attrs
dotEdge.From
dotAttrs.List.RangeStmt_2324.k
dotSystemBinary
nodeshape
dotCluster.String
dotEdge
dotEdge.To
dotGraph.WriteDot.w
bytes
tmplEdge
runDotToImageCallSystemGraphviz.outfname
runDotToImageCallSystemGraphviz.dot
runDotToImageCallSystemGraphviz.BlockStmt.dot
dotGraph.Edges
dotGraph.WriteDot.err
dotGraph.Title
dotGraph.WriteDot
dotGraph.WriteDot.RangeStmt_2941.s
runDotToImageCallSystemGraphviz.cmd
dotCluster.ID
NewDotCluster
dotEdge.Attrs
dotGraph.WriteDot.t
dotCluster.Nodes
dotCluster.Attrs
dotAttrs.Lines
tmplNode
dotCluster.Clusters
dotAttrs.Lines.p
dotGraph.Cluster
tmplCluster
dotNode.String.n
dotAttrs.String.p
dotGraph.WriteDot.buf
dotToImage
dotToImage.format
exec
minlen
dotNode.ID
dotAttrs.List
dotAttrs.List.RangeStmt_2324.v
dotGraph.WriteDot._
template
dotCluster.String.c
dotNode.String
Members
X