2
This software may only be used by you under license from AT&T Corp.
3
("AT&T"). A copy of AT&T's Source Code Agreement is available at
4
AT&T's Internet website having the URL:
5
<http://www.research.att.com/sw/tools/graphviz/license/source.html>
6
If you received this software without first entering into a license
7
with AT&T, you have an infringing copy of this software and cannot use
8
it without violating AT&T's intellectual property rights.
18
int agobjidcmpf(Dict_t *dict, void *arg0, void *arg1, Dtdisc_t *disc)
23
obj0 = arg0; obj1 = arg1;
25
return AGID(obj0) - AGID(obj1);
28
int agobjseqcmpf(Dict_t *dict, void *arg0, void *arg1, Dtdisc_t *disc)
33
obj0 = arg0; obj1 = arg1;
35
return AGSEQ(obj0) - AGSEQ(obj1);
38
int agdelete(Agraph_t *g, void *obj)
43
if ((g != h) && ((AGTYPE((Agobj_t*)obj) != AGRAPH) || (g != agparent(h))))
44
agerror(AGERROR_WRONGGRAPH,"agdelete");
46
switch (AGTYPE((Agobj_t*)obj)) {
47
case AGNODE: return agdelnode(obj);
48
case AGINEDGE: case AGOUTEDGE: return agdeledge(obj);
49
case AGRAPH: return agclose(obj);
52
return SUCCESS; /* not reached */
56
int agrename(void *obj, char *newname)
59
unsigned long old_id, new_id;
62
g->disc->id.convert(g, g->disc->id_state, AGTAG(obj), newname);
63
if (g->disc->id.alloc(g, g->disc->id_state, AGTAG(obj), new_id)) {
65
switch (AGTYPE((Agobj_t *)obj)) {
66
case AGRAPH: agstrfree(g,g->name); g->name = agstrdup(g,newname); break;
67
case AGNODE: agrename_node((Agnode_t*)obj,newname); break;
68
case AGINEDGE: case AGEDGEOUT: agerror(AGERROR_UNIMPL,"edge renaming");
74
/* perform initialization/update/finalization method invocation.
75
* skip over nil pointers to next method below.
78
void agmethod_init(Agraph_t *g, void *obj)
80
if (g->clos->callbacks_enabled)
81
aginitcb(obj,g->clos->cb);
82
else agrecord_callback(obj, CB_INITIALIZE, NILsym);
85
void aginitcb(void *obj, Agcbstack_t *cbstack)
89
if (cbstack == NIL(Agcbstack_t*)) return;
90
aginitcb(obj,cbstack->prev);
92
switch (AGTYPE(obj)) {
94
fn = cbstack->f->graph.ins;
97
fn = cbstack->f->node.ins;
100
fn = cbstack->f->edge.ins;
103
if (fn) fn(obj,cbstack->state);
106
void agmethod_upd(Agraph_t *g, void *obj, Agsym_t *sym)
108
if (g->clos->callbacks_enabled)
109
agupdcb(obj,sym,g->clos->cb);
110
else agrecord_callback(obj, CB_UPDATE, sym);
113
void agupdcb(void *obj, Agsym_t *sym, Agcbstack_t *cbstack)
117
if (cbstack == NIL(Agcbstack_t*)) return;
118
agupdcb(obj,sym,cbstack->prev);
119
fn = NIL(agobjupdfn_t);
120
switch (AGTYPE(obj)) {
122
fn = cbstack->f->graph.mod;
125
fn = cbstack->f->node.mod;
128
fn = cbstack->f->edge.mod;
131
if (fn) fn(obj,cbstack->state,sym);
134
void agmethod_delete(Agraph_t *g, void *obj)
136
if (g->clos->callbacks_enabled)
137
agdelcb(obj,g->clos->cb);
138
else agrecord_callback(obj, CB_DELETION, NILsym);
141
void agdelcb(void *obj, Agcbstack_t *cbstack)
145
if (cbstack == NIL(Agcbstack_t*)) return;
146
agdelcb(obj,cbstack->prev);
148
switch (AGTYPE(obj)) {
150
fn = cbstack->f->graph.del;
153
fn = cbstack->f->node.del;
156
fn = cbstack->f->edge.del;
159
if (fn) fn(obj,cbstack->state);
162
Agraph_t *agraphof(void *obj)
164
switch (AGTYPE(obj)) {
165
case AGINEDGE: case AGOUTEDGE:
166
return ((Agedge_t*)obj)->node->g;
168
return ((Agnode_t*)obj)->g;
170
return (Agraph_t*)obj;
171
default: /* actually can't occur if only 2 bit tags */
172
agerror(AGERROR_BADOBJ,"agraphof");
177
int agisarootobj(void *obj)
179
return (agraphof(obj)->desc.maingraph);
182
/* to manage disciplines */
184
void agpushdisc(Agraph_t *g, Agcbdisc_t *cbd, void *state)
186
Agcbstack_t *stack_ent;
188
stack_ent = AGNEW(g,Agcbstack_t);
190
stack_ent->state = state;
191
stack_ent->prev = g->clos->cb;
192
g->clos->cb = stack_ent;
195
int agpopdisc(Agraph_t *g, Agcbdisc_t *cbd)
197
Agcbstack_t *stack_ent;
199
stack_ent = g->clos->cb;
201
if (stack_ent->f == cbd) g->clos->cb = stack_ent->prev;
203
while (stack_ent && (stack_ent->prev->f != cbd))
204
stack_ent = stack_ent->prev;
205
if (stack_ent && stack_ent->prev)
206
stack_ent->prev = stack_ent->prev->prev;
208
if (stack_ent) {agfree(g,stack_ent); return SUCCESS;}
213
void *aggetuserptr(Agraph_t *g, Agcbdisc_t *cbd)
215
Agcbstack_t *stack_ent;
217
for (stack_ent = g->clos->cb; stack_ent; stack_ent = stack_ent->prev)
218
if (stack_ent->f == cbd) return stack_ent->state;
222
Dtdisc_t Ag_obj_id_disc = {
223
0, /* pass object ptr */
224
0, /* size (ignored) */
225
offsetof(Agobj_t,id_link), /* link offset */
234
Dtdisc_t Ag_obj_seq_disc = {
235
0, /* pass object ptr */
236
0, /* size (ignored) */
237
offsetof(Agobj_t,seq_link), /* link offset */