Now, common attribute manipulations can be used.
modules = io.lines('/proc/modules')
G = gv.digraph("G")
+N = gv.protonode(G)
+E = gv.protoedge(G)
gv.setv(G, 'rankdir', 'LR')
gv.setv(G, 'nodesep', '0.05')
-gv.setv(G, 'node', 'shape', 'box')
-gv.setv(G, 'node', 'width', '0')
-gv.setv(G, 'node', 'height', '0')
-gv.setv(G, 'node', 'margin', '.03')
-gv.setv(G, 'node', 'fontsize', '8')
-gv.setv(G, 'node', 'fontname', 'helvetica')
-gv.setv(G, 'edge', 'arrowsize', '.4')
+gv.setv(N, 'shape', 'box')
+gv.setv(N, 'width', '0')
+gv.setv(N, 'height', '0')
+gv.setv(N, 'margin', '.03')
+gv.setv(N, 'fontsize', '8')
+gv.setv(N, 'fontname', 'helvetica')
+gv.setv(E, 'arrowsize', '.4')
for rec in modules do
for mod, usedbylist in string.gfind(rec, "([_%w]+) %w+ %w+ ([-,_%w]+)") do
use lib "/usr/lib/graphviz/perl";
use gv;
-$g = gv::digraph "G";
-gv::setv($g, "rankdir", "LR");
-gv::setv($g, "nodesep", "0.05");
-gv::setv($g, "node", "shape", "box");
-gv::setv($g, "node", "width", "0");
-gv::setv($g, "node", "height", "0");
-gv::setv($g, "node", "margin", ".03");
-gv::setv($g, "node", "fontsize", "8");
-gv::setv($g, "node", "fontname", "helvetica");
-gv::setv($g, "edge", "arrowsize", ".4");
+$G = gv::digraph("G");
+$N = gv::protonode($G);
+$E = gv::protoedge($G);
+
+gv::setv($G, "rankdir", "LR");
+gv::setv($G, "nodesep", "0.05");
+gv::setv($N, "shape", "box");
+gv::setv($N, "width", "0");
+gv::setv($N, "height", "0");
+gv::setv($N, "margin", ".03");
+gv::setv($N, "fontsize", "8");
+gv::setv($N, "fontname", "helvetica");
+gv::setv($E, "arrowsize", ".4");
#FIXME - complete translation to perl
#end
#f.close
-gv::layout($g, "dot");
-gv::render($g, "gtk");
+gv::layout($G, "dot");
+gv::render($G, "gtk");
modules = open("/proc/modules", 'r').readlines()
G = gv.digraph("G")
+N = gv.protonode(G)
+E = gv.protoedge(G)
+
gv.setv(G, 'rankdir', 'LR')
gv.setv(G, 'nodesep', '0.05')
-gv.setv(G, 'node', 'shape', 'box')
-gv.setv(G, 'node', 'width', '0')
-gv.setv(G, 'node', 'height', '0')
-gv.setv(G, 'node', 'margin', '.03')
-gv.setv(G, 'node', 'fontsize', '8')
-gv.setv(G, 'node', 'fontname', 'helvetica')
-gv.setv(G, 'edge', 'arrowsize', '.4')
+gv.setv(N, 'shape', 'box')
+gv.setv(N, 'width', '0')
+gv.setv(N, 'height', '0')
+gv.setv(N, 'margin', '.03')
+gv.setv(N, 'fontsize', '8')
+gv.setv(N, 'fontname', 'helvetica')
+gv.setv(E, 'arrowsize', '.4')
for rec in modules:
fields = rec.split(' ')
require 'gv'
G = Gv.digraph("G")
+N = Gv.protonode(G)
+E = Gv.protoedge(G)
+
Gv.setv(G, 'rankdir', 'LR')
Gv.setv(G, 'nodesep', '0.05')
-Gv.setv(G, 'node', 'shape', 'box')
-Gv.setv(G, 'node', 'width', '0')
-Gv.setv(G, 'node', 'height', '0')
-Gv.setv(G, 'node', 'margin', '.03')
-Gv.setv(G, 'node', 'fontsize', '8')
-Gv.setv(G, 'node', 'fontname', 'helvetica')
-Gv.setv(G, 'edge', 'arrowsize', '.4')
+Gv.setv(N, 'shape', 'box')
+Gv.setv(N, 'width', '0')
+Gv.setv(N, 'height', '0')
+Gv.setv(N, 'margin', '.03')
+Gv.setv(N, 'fontsize', '8')
+Gv.setv(N, 'fontname', 'helvetica')
+Gv.setv(E, 'arrowsize', '.4')
f = File.open('/proc/modules', mode="r")
while ! f.eof do
set modules [read -nonewline $f]
close $f
-set g [gv::digraph G]
-gv::setv $g rankdir LR
-gv::setv $g nodesep .05
-
-gv::setv $g node shape box
-gv::setv $g node width 0
-gv::setv $g node height 0
-gv::setv $g node margin .03
-gv::setv $g node fontsize 8
-gv::setv $g node fontname helvetica
-
-gv::setv $g edge arrowsize .4
+set G [gv::digraph G]
+set N [gv::protonode $G]
+set E [gv::protoedge $G]
+
+gv::setv $G rankdir LR
+gv::setv $G nodesep .05
+gv::setv $N shape box
+gv::setv $N width 0
+gv::setv $N height 0
+gv::setv $N margin .03
+gv::setv $N fontsize 8
+gv::setv $N fontname helvetica
+gv::setv $E arrowsize .4
foreach rec [split $modules \n] {
- set n [gv::node $g [lindex $rec 0]]
+ set n [gv::node $G [lindex $rec 0]]
foreach usedby [split [lindex $rec 3] ,] {
if {[string equal $usedby -] || [string equal $usedby {}]} {continue}
- set e [gv::edge $n [gv::node $g $usedby]]
+ set e [gv::edge $n [gv::node $G $usedby]]
}
}
-gv::layout $g dot
-gv::render $g gtk
+gv::layout $G dot
+gv::render $G gtk
Agedge_t *edge(Agnode_t *t, Agnode_t *h)
{
+ // edges from/to the protonode are not permitted
+ if ((t->name[0] == '\001' && strcmp (t->name, "\001proto") == 0)
+ || (h->name[0] == '\001' && strcmp (h->name, "\001proto") == 0))
+ return NULL;
return agedge(t->graph, t, h);
}
Agedge_t *edge(char *tname, Agnode_t *h)
{
- return agedge(h->graph, agnode(h->graph, tname), h);
+ return edge(agnode(h->graph, tname), h);
}
Agedge_t *edge(Agnode_t *t, char *hname)
{
- return agedge(t->graph, t, agnode(t->graph, hname));
+ return edge(t, agnode(t->graph, hname));
}
Agedge_t *edge(Agraph_t *g, char *tname, char *hname)
{
- return agedge(g, agnode(g, tname), agnode(g, hname));
+ return edge(agnode(g, tname), agnode(g, hname));
}
//-------------------------------------------------
return empty_string;
return val;
}
-char *getv(Agraph_t *g, char *gne, Agsym_t *a)
-{
- char *val;
- int len;
-
- if (!g || !gne || !gne[0] || !a)
- return NULL;
- len = strlen(gne);
- if (strncmp(gne,"graph",len) == 0)
- val = agxget(g, a->index);
- else if (strncmp(gne,"node",len) == 0)
- val = agxget(g->proto->n, a->index);
- else if (strncmp(gne,"edge",len) == 0)
- val = agxget(g->proto->e, a->index);
- else
- return NULL;
- if (!val)
- return empty_string;
- return val;
-}
char *getv(Agraph_t *g, char *attr)
{
Agsym_t *a;
return empty_string;
return val;
}
-char *getv(Agraph_t *g, char *gne, char *attr)
-{
- Agsym_t *a;
- char *val;
- int len;
-
- if (!g || !gne || !gne[0] || !attr)
- return NULL;
- len = strlen(gne);
- if (strncmp(gne,"graph",len) == 0) {
- a = agfindattr(g->root, attr);
- if (!a)
- return empty_string;
- val = agxget(g, a->index);
- }
- else if (strncmp(gne,"node",len) == 0) {
- a = agfindattr(g->proto->n, attr);
- if (!a)
- return empty_string;
- val = agxget(g->proto->n, a->index);
- }
- else if (strncmp(gne,"edge",len) == 0) {
- a = agfindattr(g->proto->e, attr);
- if (!a)
- return empty_string;
- val = agxget(g->proto->e, a->index);
- }
- else
- return NULL;
- if (!val)
- return empty_string;
- return val;
-}
char *setv(Agraph_t *g, Agsym_t *a, char *val)
{
if (!g || !a || !val)
agxset(g, a->index, val);
return val;
}
-char *setv(Agraph_t *g, char *gne, Agsym_t *a, char *val)
-{
- int len;
-
- if (!g || !gne || !gne[0] || !a || !val)
- return NULL;
- len = strlen(gne);
- if (strncmp(gne,"graph",len) == 0)
- agxset(g, a->index, val);
- else if (strncmp(gne,"node",len) == 0)
- agxset(g->proto->n, a->index, val);
- else if (strncmp(gne,"edge",len) == 0)
- agxset(g->proto->e, a->index, val);
- else
- return NULL;
- return val;
-}
char *setv(Agraph_t *g, char *attr, char *val)
{
Agsym_t *a;
agxset(g, a->index, val);
return val;
}
-char *setv(Agraph_t *g, char *gne, char *attr, char *val)
-{
- Agsym_t *a;
- int len;
-
- if (!g || !gne || !gne[0] || !attr || !val)
- return NULL;
- len = strlen(gne);
- if (strncmp(gne,"graph",len) == 0) {
- a = agfindattr(g->root, attr);
- if (!a)
- a = agraphattr(g->root, attr, empty_string);
- agxset(g, a->index, val);
- }
- else if (strncmp(gne,"node",len) == 0) {
- a = agfindattr(g->proto->n, attr);
- if (!a)
- a = agnodeattr(g->root, attr, empty_string);
- agxset(g->proto->n, a->index, val);
- }
- else if (strncmp(gne,"edge",len) == 0) {
- a = agfindattr(g->proto->e, attr);
- if (!a)
- a = agedgeattr(g->root, attr, empty_string);
- agxset(g->proto->e, a->index, val);
- }
- else
- return NULL;
- return val;
-}
//-------------------------------------------------
char *getv(Agnode_t *n, Agsym_t *a)
{
return g->root;
}
+//-------------------------------------------------
+Agnode_t *protonode(Agraph_t *g)
+{
+ if (!g)
+ return NULL;
+ return g->proto->n;
+}
+
+Agedge_t *protoedge(Agraph_t *g)
+{
+ if (!g)
+ return NULL;
+ return g->proto->e;
+}
+
//-------------------------------------------------
char *nameof(Agraph_t *g)
{
return NULL;
return g->univ->globattr->list[i];
}
-Agsym_t *firstattr(Agraph_t *g, char *gne)
-{
- int len;
-
- if (!g || !gne || !gne[0])
- return NULL;
- g = g->root;
- len = strlen(gne);
- if (strncmp(gne,"graph",len) == 0) {
- if (dtsize(g->univ->globattr->dict) == 0)
- return NULL;
- return g->univ->globattr->list[0];
- }
- else if (strncmp(gne,"node",len) == 0) {
- if (dtsize(g->univ->nodeattr->dict) == 0)
- return NULL;
- return g->univ->nodeattr->list[0];
- }
- else if (strncmp(gne,"edge",len) == 0) {
- if (dtsize(g->univ->edgeattr->dict) == 0)
- return NULL;
- return g->univ->edgeattr->list[0];
- }
- return NULL;
-}
-
-Agsym_t *nextattr(Agraph_t *g, char *gne, Agsym_t *a)
-{
- int i, len;
-
- if (!g || !gne || !gne[0] || !a)
- return NULL;
- g = g->root;
- len = strlen(gne);
- if (strncmp(gne,"graph",len) == 0) {
- for (i = 0; i < dtsize(g->univ->globattr->dict); i++)
- if (a == g->univ->globattr->list[i])
- break;
- i++;
- if (i > dtsize(g->univ->globattr->dict))
- return NULL;
- return g->univ->globattr->list[i];
- }
- else if (strncmp(gne,"node",len) == 0) {
- for (i = 0; i < dtsize(g->univ->nodeattr->dict); i++)
- if (a == g->univ->nodeattr->list[i])
- break;
- i++;
- if (i > dtsize(g->univ->nodeattr->dict))
- return NULL;
- return g->univ->nodeattr->list[i];
- }
- else if (strncmp(gne,"edge",len) == 0) {
- for (i = 0; i < dtsize(g->univ->edgeattr->dict); i++)
- if (a == g->univ->edgeattr->list[i])
- break;
- i++;
- if (i > dtsize(g->univ->edgeattr->dict))
- return NULL;
- return g->univ->edgeattr->list[i];
- }
- return NULL;
-}
Agsym_t *firstattr(Agnode_t *n)
{
void rm(Agnode_t *n)
{
+ // removal of the protonode is not permitted
+ if (n->name[0] == '\001' && strcmp (n->name, "\001proto") ==0)
+ return;
agdelete(n->graph, n);
}
void rm(Agedge_t *e)
{
+ // removal of the protoedge is not permitted
+ if ((e->head->name[0] == '\001' && strcmp (e->head->name, "\001proto") == 0)
+ || (e->tail->name[0] == '\001' && strcmp (e->tail->name, "\001proto") == 0))
+ return;
agdelete(e->head->graph->root, e);
}
extern char *setv(Agnode_t *n, char *attr, char *val);
extern char *setv(Agedge_t *e, char *attr, char *val);
-/*** Set default value of graph/node/edge named attribute - creating attribute if necessary */
-extern char *setv(Agraph_t *g, char *gne, char *attr, char *val);
-
/*** Set value of existing attribute of graph/node/edge (using attribute handle) */
extern char *setv(Agraph_t *g, Agsym_t *a, char *val);
extern char *setv(Agnode_t *n, Agsym_t *a, char *val);
extern char *setv(Agedge_t *e, Agsym_t *a, char *val);
-/*** Set default value of existing graph/node/edge attribute (using attribute handle) */
-extern char *setv(Agraph_t *g, char *gne, Agsym_t *a, char *val);
-
/** Getting attribute values */
/*** Get value of named attribute of graph/node/edge */
extern char *getv(Agraph_t *g, char *attr);
extern char *getv(Agnode_t *n, char *attr);
extern char *getv(Agedge_t *e, char *attr);
-/*** Get default value of graph/node/edge named attribute */
-extern char *getv(Agraph_t *g, char *gne, char *attr);
-
/*** Get value of attribute of graph/node/edge (using attribute handle) */
extern char *getv(Agraph_t *g, Agsym_t *a);
extern char *getv(Agnode_t *n, Agsym_t *a);
extern char *getv(Agedge_t *e, Agsym_t *a);
-/*** Get default value of attribute of graph/node/edge (using attribute handle) */
-extern char *getv(Agraph_t *g, char *gne, Agsym_t *a);
-
/** Obtain names from handles */
extern char *nameof(Agraph_t *g);
extern char *nameof(Agnode_t *n);
extern Agraph_t *graphof(Agnode_t *n);
extern Agraph_t *rootof(Agraph_t *g);
+/** Obtain handles of proto node/edge for setting default attribute values */
+extern Agnode_t *protonode(Agraph_t *g);
+extern Agedge_t *protoedge(Agraph_t *g);
+
/** Iterators */
/*** Iteration termination tests */
extern bool ok(Agraph_t *g);
extern Agsym_t *firstattr(Agraph_t *g);
extern Agsym_t *nextattr(Agraph_t *g, Agsym_t *a);
-/*** Iterate over default graph/node/edge attributes of a graph */
-extern Agsym_t *firstattr(Agraph_t *g, char *gne);
-extern Agsym_t *nextattr(Agraph_t *g, char *gne, Agsym_t *a);
-
/*** Iterate over attributes of an edge */
extern Agsym_t *firstattr(Agedge_t *e);
extern Agsym_t *nextattr(Agedge_t *e, Agsym_t *a);