wolffd@0
|
1 /* $Id: cgraph.h,v 1.16 2009/07/10 21:10:32 erg Exp $ $Revision: 1.16 $ */
|
wolffd@0
|
2 /* vim:set shiftwidth=4 ts=8: */
|
wolffd@0
|
3
|
wolffd@0
|
4 /**********************************************************
|
wolffd@0
|
5 * This software is part of the graphviz package *
|
wolffd@0
|
6 * http://www.graphviz.org/ *
|
wolffd@0
|
7 * *
|
wolffd@0
|
8 * Copyright (c) 1994-2004 AT&T Corp. *
|
wolffd@0
|
9 * and is licensed under the *
|
wolffd@0
|
10 * Common Public License, Version 1.0 *
|
wolffd@0
|
11 * by AT&T Corp. *
|
wolffd@0
|
12 * *
|
wolffd@0
|
13 * Information and Software Systems Research *
|
wolffd@0
|
14 * AT&T Research, Florham Park NJ *
|
wolffd@0
|
15 **********************************************************/
|
wolffd@0
|
16
|
wolffd@0
|
17 #ifndef ATT_GRAPH_H
|
wolffd@0
|
18 #define ATT_GRAPH_H
|
wolffd@0
|
19
|
wolffd@0
|
20 #include "cdt.h"
|
wolffd@0
|
21
|
wolffd@0
|
22 #ifdef __cplusplus
|
wolffd@0
|
23 extern "C" {
|
wolffd@0
|
24 #endif
|
wolffd@0
|
25
|
wolffd@0
|
26 #ifndef FALSE
|
wolffd@0
|
27 #define FALSE (0)
|
wolffd@0
|
28 #endif
|
wolffd@0
|
29 #ifndef TRUE
|
wolffd@0
|
30 #define TRUE (!FALSE)
|
wolffd@0
|
31 #endif
|
wolffd@0
|
32 #ifndef NOT
|
wolffd@0
|
33 #define NOT(x) (!(x))
|
wolffd@0
|
34 #endif
|
wolffd@0
|
35 #ifndef NIL
|
wolffd@0
|
36 #define NIL(type) ((type)0)
|
wolffd@0
|
37 #endif
|
wolffd@0
|
38 #define NILgraph NIL(Agraph_t*)
|
wolffd@0
|
39 #define NILnode NIL(Agnode_t*)
|
wolffd@0
|
40 #define NILedge NIL(Agedge_t*)
|
wolffd@0
|
41 #define NILsym NIL(Agsym_t*)
|
wolffd@0
|
42
|
wolffd@0
|
43 /* forward struct type declarations */
|
wolffd@0
|
44 typedef struct Agtag_s Agtag_t;
|
wolffd@0
|
45 typedef struct Agobj_s Agobj_t; /* generic object header */
|
wolffd@0
|
46 typedef struct Agraph_s Agraph_t; /* graph, subgraph (or hyperedge) */
|
wolffd@0
|
47 typedef struct Agnode_s Agnode_t; /* node (atom) */
|
wolffd@0
|
48 typedef struct Agedge_s Agedge_t; /* node pair */
|
wolffd@0
|
49 typedef struct Agdesc_s Agdesc_t; /* graph descriptor */
|
wolffd@0
|
50 typedef struct Agmemdisc_s Agmemdisc_t; /* memory allocator */
|
wolffd@0
|
51 typedef struct Agiddisc_s Agiddisc_t; /* object ID allocator */
|
wolffd@0
|
52 typedef struct Agiodisc_s Agiodisc_t; /* IO services */
|
wolffd@0
|
53 typedef struct Agdisc_s Agdisc_t; /* union of client discipline methods */
|
wolffd@0
|
54 typedef struct Agdstate_s Agdstate_t; /* client state (closures) */
|
wolffd@0
|
55 typedef struct Agsym_s Agsym_t; /* string attribute descriptors */
|
wolffd@0
|
56 typedef struct Agattr_s Agattr_t; /* string attribute container */
|
wolffd@0
|
57 typedef struct Agcbdisc_s Agcbdisc_t; /* client event callbacks */
|
wolffd@0
|
58 typedef struct Agcbstack_s Agcbstack_t; /* enclosing state for cbdisc */
|
wolffd@0
|
59 typedef struct Agclos_s Agclos_t; /* common fields for graph/subgs */
|
wolffd@0
|
60 typedef struct Agrec_s Agrec_t; /* generic runtime record */
|
wolffd@0
|
61 typedef struct Agdatadict_s Agdatadict_t; /* set of dictionaries per graph */
|
wolffd@0
|
62 typedef struct Agedgepair_s Agedgepair_t; /* the edge object */
|
wolffd@0
|
63 typedef struct Agsubnode_s Agsubnode_t;
|
wolffd@0
|
64
|
wolffd@0
|
65 /* Header of a user record. These records are attached by client programs
|
wolffd@0
|
66 dynamically at runtime. A unique string ID must be given to each record
|
wolffd@0
|
67 attached to the same object. Cgraph has functions to create, search for,
|
wolffd@0
|
68 and delete these records. The records are maintained in a circular list,
|
wolffd@0
|
69 with obj->data pointing somewhere in the list. The search function has
|
wolffd@0
|
70 an option to lock this pointer on a given record. The application must
|
wolffd@0
|
71 be written so only one such lock is outstanding at a time. */
|
wolffd@0
|
72
|
wolffd@0
|
73 struct Agrec_s {
|
wolffd@0
|
74 char *name;
|
wolffd@0
|
75 Agrec_t *next;
|
wolffd@0
|
76 /* following this would be any programmer-defined data */
|
wolffd@0
|
77 };
|
wolffd@0
|
78
|
wolffd@0
|
79 /* Object tag for graphs, nodes, and edges. While there may be several structs
|
wolffd@0
|
80 for a given node or edges, there is only one unique ID (per main graph). */
|
wolffd@0
|
81 struct Agtag_s {
|
wolffd@0
|
82 unsigned objtype:2; /* see literal tags below */
|
wolffd@0
|
83 unsigned mtflock:1; /* move-to-front lock, see above */
|
wolffd@0
|
84 unsigned attrwf:1; /* attrs written (parity, write.c) */
|
wolffd@0
|
85 unsigned seq:(sizeof(unsigned) * 8 - 4); /* sequence no. */
|
wolffd@0
|
86 unsigned long id; /* client ID */
|
wolffd@0
|
87 };
|
wolffd@0
|
88
|
wolffd@0
|
89 /* object tags */
|
wolffd@0
|
90 #define AGRAPH 0 /* can't exceed 2 bits. see Agtag_t. */
|
wolffd@0
|
91 #define AGNODE 1
|
wolffd@0
|
92 #define AGOUTEDGE 2
|
wolffd@0
|
93 #define AGINEDGE 3 /* (1 << 1) indicates an edge tag. */
|
wolffd@0
|
94 #define AGEDGE AGOUTEDGE /* synonym in object kind args */
|
wolffd@0
|
95
|
wolffd@0
|
96 /* a generic graph/node/edge header */
|
wolffd@0
|
97 struct Agobj_s {
|
wolffd@0
|
98 Agtag_t tag;
|
wolffd@0
|
99 Agrec_t *data;
|
wolffd@0
|
100 };
|
wolffd@0
|
101
|
wolffd@0
|
102 #define AGTAG(obj) (((Agobj_t*)(obj))->tag)
|
wolffd@0
|
103 #define AGTYPE(obj) (AGTAG(obj).objtype)
|
wolffd@0
|
104 #define AGID(obj) (AGTAG(obj).id)
|
wolffd@0
|
105 #define AGSEQ(obj) (AGTAG(obj).seq)
|
wolffd@0
|
106 #define AGATTRWF(obj) (AGTAG(obj).attrwf)
|
wolffd@0
|
107 #define AGDATA(obj) (((Agobj_t*)(obj))->data)
|
wolffd@0
|
108
|
wolffd@0
|
109 /* This is the node struct allocated per graph (or subgraph). It resides
|
wolffd@0
|
110 in the n_dict of the graph. The node set is maintained by libdict, but
|
wolffd@0
|
111 transparently to libgraph callers. Every node may be given an optional
|
wolffd@0
|
112 string name at its time of creation, or it is permissible to pass NIL(char*)
|
wolffd@0
|
113 for the name. */
|
wolffd@0
|
114
|
wolffd@0
|
115 struct Agsubnode_s { /* the node-per-graph-or-subgraph record */
|
wolffd@0
|
116 Dtlink_t seq_link; /* must be first */
|
wolffd@0
|
117 Dtlink_t id_link;
|
wolffd@0
|
118 Agnode_t *node; /* the object */
|
wolffd@0
|
119 Dtlink_t *in_id, *out_id; /* by node/ID for random access */
|
wolffd@0
|
120 Dtlink_t *in_seq, *out_seq; /* by node/sequence for serial access */
|
wolffd@0
|
121 };
|
wolffd@0
|
122
|
wolffd@0
|
123 struct Agnode_s {
|
wolffd@0
|
124 Agobj_t base;
|
wolffd@0
|
125 Agraph_t *root;
|
wolffd@0
|
126 Agsubnode_t mainsub; /* embedded for main graph */
|
wolffd@0
|
127 };
|
wolffd@0
|
128
|
wolffd@0
|
129 struct Agedge_s {
|
wolffd@0
|
130 Agobj_t base;
|
wolffd@0
|
131 Dtlink_t id_link; /* main graph only */
|
wolffd@0
|
132 Dtlink_t seq_link;
|
wolffd@0
|
133 Agnode_t *node; /* the endpoint node */
|
wolffd@0
|
134 };
|
wolffd@0
|
135
|
wolffd@0
|
136 struct Agedgepair_s {
|
wolffd@0
|
137 Agedge_t out, in;
|
wolffd@0
|
138 };
|
wolffd@0
|
139
|
wolffd@0
|
140 struct Agdesc_s { /* graph descriptor */
|
wolffd@0
|
141 unsigned directed:1; /* if edges are asymmetric */
|
wolffd@0
|
142 unsigned strict:1; /* if multi-edges forbidden */
|
wolffd@0
|
143 unsigned no_loop:1; /* if no loops */
|
wolffd@0
|
144 unsigned maingraph:1; /* if this is the top level graph */
|
wolffd@0
|
145 unsigned flatlock:1; /* if sets are flattened into lists in cdt */
|
wolffd@0
|
146 unsigned no_write:1; /* if a temporary subgraph */
|
wolffd@0
|
147 unsigned has_attrs:1; /* if string attr tables should be initialized */
|
wolffd@0
|
148 unsigned has_cmpnd:1; /* if may contain collapsed nodes */
|
wolffd@0
|
149 };
|
wolffd@0
|
150
|
wolffd@0
|
151 /* disciplines for external resources needed by libgraph */
|
wolffd@0
|
152
|
wolffd@0
|
153 struct Agmemdisc_s { /* memory allocator */
|
wolffd@0
|
154 void *(*open) (void); /* independent of other resources */
|
wolffd@0
|
155 void *(*alloc) (void *state, size_t req);
|
wolffd@0
|
156 void *(*resize) (void *state, void *ptr, size_t old, size_t req);
|
wolffd@0
|
157 void (*free) (void *state, void *ptr);
|
wolffd@0
|
158 void (*close) (void *state);
|
wolffd@0
|
159 };
|
wolffd@0
|
160
|
wolffd@0
|
161 struct Agiddisc_s { /* object ID allocator */
|
wolffd@0
|
162 void *(*open) (Agraph_t * g); /* associated with a graph */
|
wolffd@0
|
163 long (*map) (void *state, int objtype, char *str, unsigned long *id,
|
wolffd@0
|
164 int createflag);
|
wolffd@0
|
165 long (*alloc) (void *state, int objtype, unsigned long id);
|
wolffd@0
|
166 void (*free) (void *state, int objtype, unsigned long id);
|
wolffd@0
|
167 char *(*print) (void *state, int objtype, unsigned long id);
|
wolffd@0
|
168 void (*close) (void *state);
|
wolffd@0
|
169 };
|
wolffd@0
|
170
|
wolffd@0
|
171 struct Agiodisc_s {
|
wolffd@0
|
172 int (*afread) (void *chan, char *buf, int bufsize);
|
wolffd@0
|
173 int (*putstr) (void *chan, const char *str);
|
wolffd@0
|
174 int (*flush) (void *chan); /* sync */
|
wolffd@0
|
175 /* error messages? */
|
wolffd@0
|
176 };
|
wolffd@0
|
177
|
wolffd@0
|
178 struct Agdisc_s { /* user's discipline */
|
wolffd@0
|
179 Agmemdisc_t *mem;
|
wolffd@0
|
180 Agiddisc_t *id;
|
wolffd@0
|
181 Agiodisc_t *io;
|
wolffd@0
|
182 };
|
wolffd@0
|
183
|
wolffd@0
|
184 /* default resource disciplines */
|
wolffd@0
|
185 #if !defined(_BLD_cgraph) && defined(GVDLL)
|
wolffd@0
|
186 #define extern __declspec(dllimport)
|
wolffd@0
|
187 #endif
|
wolffd@0
|
188
|
wolffd@0
|
189 /*visual studio*/
|
wolffd@0
|
190 #ifdef WIN32_DLL
|
wolffd@0
|
191 #ifndef CGRAPH_EXPORTS
|
wolffd@0
|
192 #define extern __declspec(dllimport)
|
wolffd@0
|
193 #endif
|
wolffd@0
|
194 #endif
|
wolffd@0
|
195 /*end visual studio*/
|
wolffd@0
|
196
|
wolffd@0
|
197 extern Agmemdisc_t AgMemDisc;
|
wolffd@0
|
198 extern Agiddisc_t AgIdDisc;
|
wolffd@0
|
199 extern Agiodisc_t AgIoDisc;
|
wolffd@0
|
200
|
wolffd@0
|
201 extern Agdisc_t AgDefaultDisc;
|
wolffd@0
|
202 #undef extern
|
wolffd@0
|
203
|
wolffd@0
|
204 struct Agdstate_s {
|
wolffd@0
|
205 void *mem;
|
wolffd@0
|
206 void *id;
|
wolffd@0
|
207 /* IO must be initialized and finalized outside Cgraph,
|
wolffd@0
|
208 * and channels (FILES) are passed as void* arguments. */
|
wolffd@0
|
209 };
|
wolffd@0
|
210
|
wolffd@0
|
211 typedef void (*agobjfn_t) (Agraph_t * g, Agobj_t * obj, void *arg);
|
wolffd@0
|
212 typedef void (*agobjupdfn_t) (Agraph_t * g, Agobj_t * obj, void *arg,
|
wolffd@0
|
213 Agsym_t * sym);
|
wolffd@0
|
214
|
wolffd@0
|
215 struct Agcbdisc_s {
|
wolffd@0
|
216 struct {
|
wolffd@0
|
217 agobjfn_t ins;
|
wolffd@0
|
218 agobjupdfn_t mod;
|
wolffd@0
|
219 agobjfn_t del;
|
wolffd@0
|
220 } graph, node, edge;
|
wolffd@0
|
221 };
|
wolffd@0
|
222
|
wolffd@0
|
223 struct Agcbstack_s { /* object event callbacks */
|
wolffd@0
|
224 Agcbdisc_t *f; /* methods */
|
wolffd@0
|
225 void *state; /* closure */
|
wolffd@0
|
226 Agcbstack_t *prev; /* kept in a stack, unlike other disciplines */
|
wolffd@0
|
227 };
|
wolffd@0
|
228
|
wolffd@0
|
229 struct Agclos_s {
|
wolffd@0
|
230 Agdisc_t disc; /* resource discipline functions */
|
wolffd@0
|
231 Agdstate_t state; /* resource closures */
|
wolffd@0
|
232 Dict_t *strdict; /* shared string dict */
|
wolffd@0
|
233 unsigned long seq[3]; /* local object sequence number counter */
|
wolffd@0
|
234 Agcbstack_t *cb; /* user and system callback function stacks */
|
wolffd@0
|
235 unsigned char callbacks_enabled; /* issue user callbacks or hold them? */
|
wolffd@0
|
236 Dict_t *lookup_by_name[3];
|
wolffd@0
|
237 Dict_t *lookup_by_id[3];
|
wolffd@0
|
238 };
|
wolffd@0
|
239
|
wolffd@0
|
240 struct Agraph_s {
|
wolffd@0
|
241 Agobj_t base;
|
wolffd@0
|
242 Agdesc_t desc;
|
wolffd@0
|
243 Dtlink_t link;
|
wolffd@0
|
244 Dict_t *n_seq; /* the node set in sequence */
|
wolffd@0
|
245 Dict_t *n_id; /* the node set indexed by ID */
|
wolffd@0
|
246 Dict_t *e_seq, *e_id; /* holders for edge sets */
|
wolffd@0
|
247 Dict_t *g_dict; /* subgraphs - descendants */
|
wolffd@0
|
248 Agraph_t *parent, *root; /* subgraphs - ancestors */
|
wolffd@0
|
249 Agclos_t *clos; /* shared resources */
|
wolffd@0
|
250 };
|
wolffd@0
|
251
|
wolffd@0
|
252
|
wolffd@0
|
253 #if _PACKAGE_ast
|
wolffd@0
|
254 /* fine control of object callbacks */
|
wolffd@0
|
255 # if defined(_BLD_cgraph) && defined(__EXPORT__)
|
wolffd@0
|
256 # define extern __EXPORT__
|
wolffd@0
|
257 # endif
|
wolffd@0
|
258 # if !defined(_BLD_cgraph) && defined(__IMPORT__)
|
wolffd@0
|
259 # define extern __IMPORT__
|
wolffd@0
|
260 # endif
|
wolffd@0
|
261 #endif
|
wolffd@0
|
262
|
wolffd@0
|
263 extern void agpushdisc(Agraph_t * g, Agcbdisc_t * disc, void *state);
|
wolffd@0
|
264 extern int agpopdisc(Agraph_t * g, Agcbdisc_t * disc);
|
wolffd@0
|
265 extern int agcallbacks(Agraph_t * g, int flag); /* return prev value */
|
wolffd@0
|
266
|
wolffd@0
|
267 /* graphs */
|
wolffd@0
|
268 extern Agraph_t *agopen(char *name, Agdesc_t desc, Agdisc_t * disc);
|
wolffd@0
|
269 extern int agclose(Agraph_t * g);
|
wolffd@0
|
270 extern Agraph_t *agread(void *chan, Agdisc_t * disc);
|
wolffd@0
|
271 extern void agreadline(int);
|
wolffd@0
|
272 extern void agsetfile(char *);
|
wolffd@0
|
273 extern Agraph_t *agconcat(Agraph_t * g, void *chan, Agdisc_t * disc);
|
wolffd@0
|
274 extern int agwrite(Agraph_t * g, void *chan);
|
wolffd@0
|
275 extern int agisdirected(Agraph_t * g);
|
wolffd@0
|
276 extern int agisundirected(Agraph_t * g);
|
wolffd@0
|
277 extern int agisstrict(Agraph_t * g);
|
wolffd@0
|
278 extern int agissimple(Agraph_t * g);
|
wolffd@0
|
279
|
wolffd@0
|
280 /* nodes */
|
wolffd@0
|
281 extern Agnode_t *agnode(Agraph_t * g, char *name, int createflag);
|
wolffd@0
|
282 extern Agnode_t *agidnode(Agraph_t * g, unsigned long id, int createflag);
|
wolffd@0
|
283 extern Agnode_t *agsubnode(Agraph_t * g, Agnode_t * n, int createflag);
|
wolffd@0
|
284 extern Agnode_t *agfstnode(Agraph_t * g);
|
wolffd@0
|
285 extern Agnode_t *agnxtnode(Agraph_t * g, Agnode_t * n);
|
wolffd@0
|
286 extern Agnode_t *aglstnode(Agraph_t * g);
|
wolffd@0
|
287 extern Agnode_t *agprvnode(Agraph_t * g, Agnode_t * n);
|
wolffd@0
|
288
|
wolffd@0
|
289 extern Agsubnode_t *agsubrep(Agraph_t * g, Agnode_t * n);
|
wolffd@0
|
290
|
wolffd@0
|
291 /* edges */
|
wolffd@0
|
292 extern Agedge_t *agedge(Agraph_t * g, Agnode_t * t, Agnode_t * h,
|
wolffd@0
|
293 char *name, int createflag);
|
wolffd@0
|
294 extern Agedge_t *agidedge(Agraph_t * g, Agnode_t * t, Agnode_t * h,
|
wolffd@0
|
295 unsigned long id, int createflag);
|
wolffd@0
|
296 extern Agedge_t *agsubedge(Agraph_t * g, Agedge_t * e, int createflag);
|
wolffd@0
|
297 extern Agedge_t *agfstin(Agraph_t * g, Agnode_t * n);
|
wolffd@0
|
298 extern Agedge_t *agnxtin(Agraph_t * g, Agedge_t * e);
|
wolffd@0
|
299 extern Agedge_t *agfstout(Agraph_t * g, Agnode_t * n);
|
wolffd@0
|
300 extern Agedge_t *agnxtout(Agraph_t * g, Agedge_t * e);
|
wolffd@0
|
301 extern Agedge_t *agfstedge(Agraph_t * g, Agnode_t * n);
|
wolffd@0
|
302 extern Agedge_t *agnxtedge(Agraph_t * g, Agedge_t * e, Agnode_t * n);
|
wolffd@0
|
303
|
wolffd@0
|
304 /* generic */
|
wolffd@0
|
305 extern Agraph_t *agraphof(void* obj);
|
wolffd@0
|
306 extern Agraph_t *agroot(void* obj);
|
wolffd@0
|
307 extern int agcontains(Agraph_t *, void *);
|
wolffd@0
|
308 extern char *agnameof(void *);
|
wolffd@0
|
309 extern int agrelabel(void *obj, char *name); /* scary */
|
wolffd@0
|
310 extern int agrelabel_node(Agnode_t * n, char *newname);
|
wolffd@0
|
311 extern int agdelete(Agraph_t * g, void *obj);
|
wolffd@0
|
312 extern long agdelsubg(Agraph_t * g, Agraph_t * sub); /* could be agclose */
|
wolffd@0
|
313 extern int agdelnode(Agraph_t * g, Agnode_t * arg_n);
|
wolffd@0
|
314 extern int agdeledge(Agraph_t * g, Agedge_t * arg_e);
|
wolffd@0
|
315 extern int agobjkind(void *);
|
wolffd@0
|
316
|
wolffd@0
|
317 /* strings */
|
wolffd@0
|
318 extern char *agstrdup(Agraph_t *, char *);
|
wolffd@0
|
319 extern char *agstrdup_html(Agraph_t *, char *);
|
wolffd@0
|
320 extern int aghtmlstr(char *);
|
wolffd@0
|
321 extern char *agstrbind(Agraph_t * g, char *);
|
wolffd@0
|
322 extern int agstrfree(Agraph_t *, char *);
|
wolffd@0
|
323 extern char *agstrcanon(char *, char *);
|
wolffd@0
|
324 char *agcanonStr(char *str); /* manages its own buf */
|
wolffd@0
|
325
|
wolffd@0
|
326 /* definitions for dynamic string attributes */
|
wolffd@0
|
327 struct Agattr_s { /* dynamic string attributes */
|
wolffd@0
|
328 Agrec_t h; /* common data header */
|
wolffd@0
|
329 Dict_t *dict; /* shared dict to interpret attr field */
|
wolffd@0
|
330 char **str; /* the attribute string values */
|
wolffd@0
|
331 };
|
wolffd@0
|
332
|
wolffd@0
|
333 struct Agsym_s { /* symbol in one of the above dictionaries */
|
wolffd@0
|
334 Dtlink_t link;
|
wolffd@0
|
335 char *name; /* attribute's name */
|
wolffd@0
|
336 char *defval; /* its default value for initialization */
|
wolffd@0
|
337 int id; /* its index in attr[] */
|
wolffd@0
|
338 unsigned char kind; /* referent object type */
|
wolffd@0
|
339 unsigned char fixed; /* immutable value */
|
wolffd@0
|
340 };
|
wolffd@0
|
341
|
wolffd@0
|
342 struct Agdatadict_s { /* set of dictionaries per graph */
|
wolffd@0
|
343 Agrec_t h; /* installed in list of graph recs */
|
wolffd@0
|
344 struct {
|
wolffd@0
|
345 Dict_t *n, *e, *g;
|
wolffd@0
|
346 } dict;
|
wolffd@0
|
347 };
|
wolffd@0
|
348
|
wolffd@0
|
349 extern Agsym_t *agattr(Agraph_t * g, int kind, char *name, char *value);
|
wolffd@0
|
350 extern Agsym_t *agattrsym(void *obj, char *name);
|
wolffd@0
|
351 extern Agsym_t *agnxtattr(Agraph_t * g, int kind, Agsym_t * attr);
|
wolffd@0
|
352 extern int agcopyattr(void *oldobj, void *newobj);
|
wolffd@0
|
353
|
wolffd@0
|
354 extern void *agbindrec(void *obj, char *name, unsigned int size,
|
wolffd@0
|
355 int move_to_front);
|
wolffd@0
|
356 extern Agrec_t *aggetrec(void *obj, char *name, int move_to_front);
|
wolffd@0
|
357 extern int agdelrec(void *obj, char *name);
|
wolffd@0
|
358 extern void aginit(Agraph_t * g, int kind, char *rec_name, int rec_size,
|
wolffd@0
|
359 int move_to_front);
|
wolffd@0
|
360 extern void agclean(Agraph_t * g, int kind, char *rec_name);
|
wolffd@0
|
361
|
wolffd@0
|
362 extern char *agget(void *obj, char *name);
|
wolffd@0
|
363 extern char *agxget(void *obj, Agsym_t * sym);
|
wolffd@0
|
364 extern int agset(void *obj, char *name, char *value);
|
wolffd@0
|
365 extern int agxset(void *obj, Agsym_t * sym, char *value);
|
wolffd@0
|
366 extern int agsafeset(void* obj, char* name, char* value, char* def);
|
wolffd@0
|
367
|
wolffd@0
|
368 /* defintions for subgraphs */
|
wolffd@0
|
369 extern Agraph_t *agsubg(Agraph_t * g, char *name, int cflag); /* constructor */
|
wolffd@0
|
370 extern Agraph_t *agidsubg(Agraph_t * g, unsigned long id, int cflag); /* constructor */
|
wolffd@0
|
371 extern Agraph_t *agfstsubg(Agraph_t * g), *agnxtsubg(Agraph_t * subg);
|
wolffd@0
|
372 extern Agraph_t *agparent(Agraph_t * g);
|
wolffd@0
|
373
|
wolffd@0
|
374 /* set cardinality */
|
wolffd@0
|
375 extern int agnnodes(Agraph_t * g), agnedges(Agraph_t * g);
|
wolffd@0
|
376 extern int agdegree(Agraph_t * g, Agnode_t * n, int in, int out);
|
wolffd@0
|
377 extern int agcountuniqedges(Agraph_t * g, Agnode_t * n, int in, int out);
|
wolffd@0
|
378
|
wolffd@0
|
379 /* memory */
|
wolffd@0
|
380 extern void *agalloc(Agraph_t * g, size_t size);
|
wolffd@0
|
381 extern void *agrealloc(Agraph_t * g, void *ptr, size_t oldsize,
|
wolffd@0
|
382 size_t size);
|
wolffd@0
|
383 extern void agfree(Agraph_t * g, void *ptr);
|
wolffd@0
|
384 extern struct _vmalloc_s *agheap(Agraph_t * g);
|
wolffd@0
|
385
|
wolffd@0
|
386 /* an engineering compromise is a joy forever */
|
wolffd@0
|
387 extern void aginternalmapclearlocalnames(Agraph_t * g);
|
wolffd@0
|
388
|
wolffd@0
|
389 #define agnew(g,t) ((t*)agalloc(g,sizeof(t)))
|
wolffd@0
|
390 #define agnnew(g,n,t) ((t*)agalloc(g,(n)*sizeof(t)))
|
wolffd@0
|
391
|
wolffd@0
|
392 /* error handling */
|
wolffd@0
|
393 typedef enum { AGWARN, AGERR, AGMAX, AGPREV } agerrlevel_t;
|
wolffd@0
|
394 extern agerrlevel_t agerrno;
|
wolffd@0
|
395 extern void agseterr(agerrlevel_t);
|
wolffd@0
|
396 extern char *aglasterr(void);
|
wolffd@0
|
397 extern int agerr(agerrlevel_t level, char *fmt, ...);
|
wolffd@0
|
398 extern void agerrorf(char *fmt, ...);
|
wolffd@0
|
399 extern void agwarningf(char *fmt, ...);
|
wolffd@0
|
400 extern int agerrors(void);
|
wolffd@0
|
401
|
wolffd@0
|
402 /* data access macros */
|
wolffd@0
|
403 /* this assumes that e[0] is out and e[1] is inedge, see edgepair in edge.c */
|
wolffd@0
|
404 #define AGIN2OUT(e) ((e)-1)
|
wolffd@0
|
405 #define AGOUT2IN(e) ((e)+1)
|
wolffd@0
|
406 #define AGOPP(e) ((AGTYPE(e)==AGINEDGE)?AGIN2OUT(e):AGOUT2IN(e))
|
wolffd@0
|
407 #define AGMKOUT(e) (AGTYPE(e) == AGOUTEDGE? (e): AGIN2OUT(e))
|
wolffd@0
|
408 #define AGMKIN(e) (AGTYPE(e) == AGINEDGE? (e): AGOUT2IN(e))
|
wolffd@0
|
409 #define AGTAIL(e) (AGMKIN(e)->node)
|
wolffd@0
|
410 #define AGHEAD(e) (AGMKOUT(e)->node)
|
wolffd@0
|
411 #define agtail(e) AGTAIL(e)
|
wolffd@0
|
412 #define aghead(e) AGHEAD(e)
|
wolffd@0
|
413 #define agopp(e) AGOPP(e)
|
wolffd@0
|
414
|
wolffd@0
|
415 #define TAILPORT_ID "tailport"
|
wolffd@0
|
416 #define HEADPORT_ID "headport"
|
wolffd@0
|
417
|
wolffd@0
|
418 #if _PACKAGE_ast
|
wolffd@0
|
419 # if !defined(_BLD_cgraph) && defined(__IMPORT__)
|
wolffd@0
|
420 # define extern __IMPORT__
|
wolffd@0
|
421 # endif
|
wolffd@0
|
422 #endif
|
wolffd@0
|
423 #if !defined(_BLD_cgraph) && defined(GVDLL)
|
wolffd@0
|
424 #define extern __declspec(dllimport)
|
wolffd@0
|
425 #endif
|
wolffd@0
|
426
|
wolffd@0
|
427 extern Agdesc_t Agdirected, Agstrictdirected, Agundirected,
|
wolffd@0
|
428 Agstrictundirected;
|
wolffd@0
|
429
|
wolffd@0
|
430 #undef extern
|
wolffd@0
|
431
|
wolffd@0
|
432 /* fast graphs */
|
wolffd@0
|
433 void agflatten(Agraph_t * g, int flag);
|
wolffd@0
|
434 typedef Agsubnode_t Agnoderef_t;
|
wolffd@0
|
435 typedef Dtlink_t Agedgeref_t;
|
wolffd@0
|
436
|
wolffd@0
|
437 #define AGHEADPOINTER(g) ((Agnoderef_t*)(g->n_seq->data->hh._head))
|
wolffd@0
|
438 #define AGRIGHTPOINTER(rep) ((Agnoderef_t*)((rep)->seq_link.right?((void*)((rep)->seq_link.right) - offsetof(Agsubnode_t,seq_link)):0))
|
wolffd@0
|
439 #define AGLEFTPOINTER(rep) ((Agnoderef_t*)((rep)->seq_link.hl._left?((void*)((rep)->seq_link.hl._left) - offsetof(Agsubnode_t,seq_link)):0))
|
wolffd@0
|
440
|
wolffd@0
|
441 #define FIRSTNREF(g) (agflatten(g,1), AGHEADPOINTER(g))
|
wolffd@0
|
442
|
wolffd@0
|
443 #define NEXTNREF(g,rep) (AGRIGHTPOINTER(rep) == AGHEADPOINTER(g)?0:AGRIGHTPOINTER(rep))
|
wolffd@0
|
444
|
wolffd@0
|
445 #define PREVNREF(g,rep) (((rep)==AGHEADPOINTER(g))?0:(AGLEFTPOINTER(rep)))
|
wolffd@0
|
446
|
wolffd@0
|
447 #define LASTNREF(g) (agflatten(g,1), AGHEADPOINTER(g)?AGLEFTPOINTER(AGHEADPOINTER(g)):0)
|
wolffd@0
|
448 #define NODEOF(rep) ((rep)->node)
|
wolffd@0
|
449
|
wolffd@0
|
450 #define FIRSTOUTREF(g,sn) (agflatten(g,1), (sn)->out_seq)
|
wolffd@0
|
451 #define LASTOUTREF(g,sn) (agflatten(g,1), (Agedgeref_t*)dtlast(sn->out_seq))
|
wolffd@0
|
452 #define FIRSTINREF(g,sn) (agflatten(g,1), (sn)->in_seq)
|
wolffd@0
|
453 #define NEXTEREF(g,rep) ((rep)->right)
|
wolffd@0
|
454 #define PREVEREF(g,rep) ((rep)->hl._left)
|
wolffd@0
|
455 /* this is expedient but a bit slimey because it "knows" that dict entries of both nodes
|
wolffd@0
|
456 and edges are embedded in main graph objects but allocated separately in subgraphs */
|
wolffd@0
|
457 #define AGSNMAIN(sn) ((sn)==(&((sn)->node->mainsub)))
|
wolffd@0
|
458 #define EDGEOF(sn,rep) (AGSNMAIN(sn)?((Agedge_t*)((unsigned char*)(rep) - offsetof(Agedge_t,seq_link))) : ((Dthold_t*)(rep))->obj)
|
wolffd@0
|
459
|
wolffd@0
|
460 #undef extern
|
wolffd@0
|
461 #if _PACKAGE_ast
|
wolffd@0
|
462 _END_EXTERNS_
|
wolffd@0
|
463 #endif
|
wolffd@0
|
464 #ifdef __cplusplus
|
wolffd@0
|
465 }
|
wolffd@0
|
466 #endif
|
wolffd@0
|
467 #endif
|