1LIBCGRAPH(3)               Library Functions Manual               LIBCGRAPH(3)
2
3
4

NAME

6       libcgraph - abstract graph library
7

SYNOPSIS

9       #include <graphviz/cgraph.h>
10
11   TYPES
12       Agraph_t;
13       Agnode_t;
14       Agedge_t;
15       Agdesc_t;
16       Agdisc_t;
17       Agsym_t;
18       Agrec_t;
19       Agcbdisc_t;
20
21   GLOBALS
22       Agmemdisc_t AgMemDisc;
23       Agiddisc_t  AgIdDisc;
24       Agiodisc_t  AgIoDisc;
25       Agdisc_t    AgDefaultDisc;
26
27   GRAPHS
28       Agraph_t  *agopen(char *name, Agdesc_t kind, Agdisc_t *disc);
29       int       agclose(Agraph_t *g);
30       Agraph_t  *agread(void *channel, Agdisc_t *);
31       Agraph_t  *agmemread(char *);
32       void      agreadline(int line_no);
33       void      agsetfile(char *file_name);
34       Agraph_t  *agconcat(Agraph_t *g, void *channel, Agdisc_t *disc)
35       int       agwrite(Agraph_t *g, void *channel);
36       int       agnnodes(Agraph_t *g),agnedges(Agraph_t *g), agnsubg(Agraph_t * g);
37       int       agisdirected(Agraph_t * g),agisundirected(Agraph_t * g),agisstrict(Agraph_t * g), agissimple(Agraph_t * g);
38
39   SUBGRAPHS
40       Agraph_t  *agsubg(Agraph_t *g, char *name, int createflag);
41       Agraph_t  *agidsubg(Agraph_t * g, unsigned long id, int cflag);
42       Agraph_t  *agfstsubg(Agraph_t *g), agnxtsubg(Agraph_t *);
43       Agraph_t  *agparent(Agraph_t *g);
44       int       agdelsubg(Agraph_t * g, Agraph_t * sub);    /* same as agclose() */
45
46   NODES
47       Agnode_t  *agnode(Agraph_t *g, char *name, int createflag);
48       Agnode_t  *agidnode(Agraph_t *g, ulong id, int createflag);
49       Agnode_t  *agsubnode(Agraph_t *g, Agnode_t *n, int createflag);
50       Agnode_t  *agfstnode(Agraph_t *g);
51       Agnode_t  *agnxtnode(Agraph_t *g, Agnode_t *n);
52       Agnode_t  *agprvnode(Agraph_t *g, Agnode_t *n);
53       Agnode_t  *aglstnode(Agraph_t *g);
54       int       agdelnode(Agraph_t *g, Agnode_t *n);
55       int       agdegree(Agraph_t *g, Agnode_t *n, int use_inedges, int use_outedges);
56       int       agcountuniqedges(Agraph_t * g, Agnode_t * n, int in, int out);
57
58   EDGES
59       Agedge_t  *agedge(Agraph_t* g, Agnode_t *t, Agnode_t *h, char *name, int createflag);
60       Agedge_t  *agidedge(Agraph_t * g, Agnode_t * t, Agnode_t * h, unsigned long id, int createflag);
61       Agedge_t  *agsubedge(Agraph_t *g, Agedge_t *e, int createflag);
62       Agnode_t  *aghead(Agedge_t *e), *agtail(Agedge_t *e);
63       Agedge_t  *agfstedge(Agraph_t* g, Agnode_t *n);
64       Agedge_t  *agnxtedge(Agraph_t* g, Agedge_t *e, Agnode_t *n);
65       Agedge_t  *agfstin(Agraph_t* g, Agnode_t *n);
66       Agedge_t  *agnxtin(Agraph_t* g, Agedge_t *e);
67       Agedge_t  *agfstout(Agraph_t* g, Agnode_t *n);
68       Agedge_t  *agnxtout(Agraph_t* g, Agedge_t *e);
69       int       agdeledge(Agraph_t *g, Agedge_t *e);
70       Agedge_t  *agopp(Agedge_t *e);
71       int       ageqedge(Agedge_t *e0, Agedge_t *e1);
72
73   STRING ATTRIBUTES
74       Agsym_t   *agattr(Agraph_t *g, int kind, char *name, const char *value);
75       Agsym_t   *agattrsym(void *obj, char *name);
76       Agsym_t   *agnxtattr(Agraph_t *g, int kind, Agsym_t *attr);
77       char      *agget(void *obj, char *name);
78       char      *agxget(void *obj, Agsym_t *sym);
79       int       agset(void *obj, char *name, char *value);
80       int       agxset(void *obj, Agsym_t *sym, char *value);
81       int       agsafeset(void *obj, char *name, char *value, char *def);
82       int       agcopyattr(void *, void *);
83
84   RECORDS
85       void      *agbindrec(void *obj, char *name, unsigned int size, move_to_front);
86       Agrec_t        *aggetrec(void *obj, char *name, int move_to_front);
87       int       agdelrec(Agraph_t *g, void *obj, char *name);
88       void      aginit(Agraph_t * g, int kind, char *rec_name, int rec_size, int move_to_front);
89       void      agclean(Agraph_t * g, int kind, char *rec_name);
90
91   CALLBACKS
92       int            *agpopdisc(Agraph_t *g);
93       void      agpushdisc(Agraph_t *g, Agcbdisc_t *disc);
94       int            agcallbacks(Agraph_t * g, int flag);
95
96   MEMORY
97       void      *agalloc(Agraph_t *g, size_t request);
98       void      *agrealloc(Agraph_t *g, void *ptr, size_t oldsize, size_t newsize);
99       void      agfree(Agraph_t *g, void *ptr);
100
101   STRINGS
102       char      *agstrdup(Agraph_t *, char *);
103       char      *agstrdup_html(Agraph_t *, char *);
104       int       aghtmlstr(char *);
105       char      *agstrbind(Agraph_t * g, char *);
106       int       strfree(Agraph_t *, char *);
107       char      *agcanonStr(char *);
108       char      *agstrcanon(char *, char *);
109       char      *agcanon(char *, int);
110
111   GENERIC OBJECTS
112       Agraph_t  *agraphof(void*);
113       Agraph_t  *agroot(void*);
114       int       agcontains(Agraph_t*, void*);
115       char      *agnameof(void*);
116       void      agdelete(Agraph_t *g, void *obj);
117       int       agobjkind(void *obj);
118       Agrec_t        *AGDATA(void *obj);
119       ulong          AGID(void *obj);
120       int       AGTYPE(void *obj);
121
122   ERROR REPORTING
123       typedef enum { AGWARN, AGERR, AGMAX, AGPREV } agerrlevel_t;
124       typedef int (*agusererrf) (char*);
125       agerrlevel_t   agerrno;
126       agerrlevel_t   agseterr(agerrlevel_t);
127       char      *aglasterr(void);
128       int       agerr(agerrlevel_t level, char *fmt, ...);
129       void      agerrorf(char *fmt, ...);
130       void      agwarningf(char *fmt, ...);
131       int       agerrors(void);
132       agusererrf     agseterrf(agusererrf);
133

DESCRIPTION

135       Libcgraph  supports  graph  programming by maintaining graphs in memory
136       and reading and writing graph files.  Graphs  are  composed  of  nodes,
137       edges,  and  nested  subgraphs.   These graph objects may be attributed
138       with string name-value pairs and programmer-defined  records  (see  At‐
139       tributes).
140
141       All  of  Libcgraph's  global symbols have the prefix ag (case varying).
142       In the following, if a function has a parameter int createflag and  the
143       object does not exist, the function will create the specified object if
144       createflag is non-zero; otherwise, it will return NULL.
145

GRAPH AND SUBGRAPHS

147       A ``main'' or ``root'' graph defines a namespace for  a  collection  of
148       graph  objects (subgraphs, nodes, edges) and their attributes.  Objects
149       may be named by unique strings or by integer IDs.
150
151       agopen creates a new graph with the given name and kind.  (Graph  kinds
152       are Agdirected, Agundirected, Agstrictdirected, and Agstrictundirected.
153       A strict graph cannot have multi-edges or self-arcs.)  The final  argu‐
154       ment  points  to a discpline structure which can be used to tailor I/O,
155       memory allocation, and ID allocation. Typically, a NULL value  will  be
156       used to indicate the default discipline AgDefaultDisc.  agclose deletes
157       a graph, freeing its associated storage.  agread, agwrite, and agconcat
158       perform  file I/O using the graph file language described below. agread
159       constructs a new graph while agconcat merges the file contents  with  a
160       pre-existing  graph.  Though I/O methods may be overridden, the default
161       is that the channel argument is a stdio FILE pointer. In that case,  if
162       any  of  the streams are wide-oriented, the behavior is undefined.  ag‐
163       memread attempts to read a graph from the input string.  agsetfile  and
164       agreadline  are  helper functions that simply set the current file name
165       and input line number for subsequent error reporting.
166
167       The functions agisdirected, agisundirected, agisstrict, and  agissimple
168       can  be  used  to  query if a graph is directed, undirected, strict (at
169       most one edge with a given tail and head), or simple  (strict  with  no
170       loops), respectively,
171
172       agsubg finds or creates a subgraph by name.  agidsubg allows a program‐
173       mer to specify the subgraph by a unique integer ID.  A new subgraph  is
174       initially empty and is of the same kind as its parent.  Nested subgraph
175       trees may be created.  A subgraph's name is only  interpreted  relative
176       to  its parent.  A program can scan subgraphs under a given graph using
177       agfstsubg and agnxtsubg.  A subgraph is deleted with agdelsubg (or  ag‐
178       close).   The agparent function returns the immediate parent graph of a
179       subgraph, or itself if the graph is already a root graph.
180
181       By default, nodes are stored in ordered sets for efficient  random  ac‐
182       cess  to  insert, find, and delete nodes.  The edges of a node are also
183       stored in ordered sets.  The sets are maintained  internally  as  splay
184       tree dictionaries using Phong Vo's cdt library.
185
186       agnnodes, agnedges, and agnsubg return the sizes of node, edge and sub‐
187       graph sets of a graph.  The function agdegree returns the size  of  the
188       edge  set of a nodes, and takes flags to select in-edges, out-edges, or
189       both.  The function agcountuniqedges returns the size of the  edge  set
190       of a nodes, and takes flags to select in-edges, out-edges, or both. Un‐
191       like agdegree, each loop is only counted once.
192

NODES

194       A node is created by giving a unique string name or programmer  defined
195       integer  ID,  and  is  represented  by  a unique internal object. (Node
196       equality can checked by pointer comparison.)
197
198       agnode searches in a graph or subgraph for a node with the given  name,
199       and  returns  it if found.  agidnode allows a programmer to specify the
200       node by a unique integer ID.  agsubnode performs a similar operation on
201       an existing node and a subgraph.
202
203       agfstnode  and  agnxtnode scan node lists.  agprvnode and aglstnode are
204       symmetric but scan backward.  The default sequence is order of creation
205       (object timestamp.)  agdelnode removes a node from a graph or subgraph.
206

EDGES

208       An  abstract edge has two endpoint nodes called tail and head where all
209       outedges of the same node have it as the tail value and  similarly  all
210       inedges have it as the head.  In an undirected graph, head and tail are
211       interchangeable.  If a graph has multi-edges between the same  pair  of
212       nodes, the edge's string name behaves as a secondary key.
213
214       agedge  searches  in  a graph or subgraph for an edge between the given
215       endpoints (with an optional multi-edge selector name) and returns it if
216       found or created.  Note that, in undirected graphs, a search tries both
217       orderings of the tail and head nodes.  If the name  is  NULL,  then  an
218       anonymous  internal value is generated. agidedge allows a programmer to
219       create an edge by giving its unique integer ID.  agsubedge  performs  a
220       similar  operation  on an existing edge and a subgraph.  agfstin, agnx‐
221       tin, agfstout, and agnxtout visit directed in- and out- edge lists, and
222       ordinarily  apply  only  in  directed  graphs.  agfstedge and agnxtedge
223       visit all edges incident to a node.  agtail and aghead get the endpoint
224       of an edge.  agdeledge removes an edge from a graph or subgraph.
225
226       Note  that  an abstract edge has two distinct concrete representations:
227       as an in-edge and as an out-edge. In particular, the pointer as an out-
228       edge is different from the pointer as an in-edge. The function ageqedge
229       canonicalizes the pointers before doing a comparison and so can be used
230       to test edge equality. The sense of an edge can be flipped using agopp.
231

INTERNAL ATTRIBUTES

233       Programmer-defined  values  may be dynamically attached to graphs, sub‐
234       graphs, nodes, and edges.  Such values are either character string data
235       (for  I/O) or uninterpreted binary records (for implementing algorithms
236       efficiently).
237

STRING ATTRIBUTES

239       String attributes are handled  automatically  in  reading  and  writing
240       graph files.  A string attribute is identified by name and by an inter‐
241       nal symbol table entry (Agsym_t) created by Libcgraph.   Attributes  of
242       nodes,  edges,  and  graphs  (with their subgraphs) have separate name‐
243       spaces.  The contents of an Agsym_t have a char* name  for  the  attri‐
244       bute's  name,  a  char* defval field for the attribute's default value,
245       and an int id field containing the index of  the  attribute's  specific
246       value for an object in the object's array of attribute values.
247
248       agattr  creates or looks up attributes.  kind may be AGRAPH, AGNODE, or
249       AGEDGE.  If value is (char*)0), the request is to search for an  exist‐
250       ing  attribute of the given kind and name.  Otherwise, if the attribute
251       already exists, its default for creating new  objects  is  set  to  the
252       given  value; if it does not exist, a new attribute is created with the
253       given default, and the default is applied to all  pre-existing  objects
254       of the given kind. If g is NULL, the default is set for all graphs cre‐
255       ated subsequently.  agattrsym is a helper function that looks up an at‐
256       tribute  for  a  graph  object given as an argument.  agnxtattr permits
257       traversing the list of attributes of a given type.  If NULL  is  passed
258       as  an  argument  it gets the first attribute; otherwise it returns the
259       next one in succession or returns NULL at the end of the  list.   agget
260       and  agset allow fetching and updating a string attribute for an object
261       taking the attribute name as an argument.  agxget and  agxset  do  this
262       but  with  an attribute symbol table entry as an argument (to avoid the
263       cost of the string lookup).  Note that agset will fail unless  the  at‐
264       tribute  is  first  defined  using  agattr.  agsafeset is a convenience
265       function that ensures the given attribute is declared before setting it
266       locally on an object.
267
268       It  is  sometimes convenient to copy all of the attributes from one ob‐
269       ject to another. This can be done using agcopyattr. This fails and  re‐
270       turns  non-zero  of  argument objects are different kinds, or if all of
271       the attributes of the source object have not been declared for the tar‐
272       get object.
273

STRINGS

275       Libcgraph  performs its own storage management of strings as reference-
276       counted strings.  The caller does  not  need  to  dynamically  allocate
277       storage.
278
279       agstrdup  returns a pointer to a reference-counted copy of the argument
280       string, creating one if necessary. agstrbind returns  a  pointer  to  a
281       reference-counted  string  if  it  exists, or NULL if not.  All uses of
282       cgraph strings need to be freed using agstrfree in order  to  correctly
283       maintain the reference count.
284
285       The  cgraph parser handles HTML-like strings. These should be indistin‐
286       guishable from other strings for most purposes. To create an  HTML-like
287       string,  use agstrdup_html. The aghtmlstr function can be used to query
288       if a string is an ordinary string or an HTML-like string.
289
290       agcanonStr returns a pointer to a version of the input  string  canoni‐
291       calized  for output for later re-parsing. This includes quoting special
292       characters and keywords. It uses its own internal buffer, so the  value
293       will  be  lost on the next call to agcanonStr.  agstrcanon is an unsafe
294       version of agcanonStr, in which the application passes in a  buffer  as
295       the second argument. Note that the buffer may not be used; if the input
296       string is in canonical form, the function will just return a pointer to
297       it.  For both of the functions, the input string must have been created
298       using agstrdup or agstrdup_html.  Finally, agcanonStr is identical with
299       agcanonStr  except it can be used with any character string. The second
300       argument indicates whether or not the string should be canonicalized as
301       an HTML-like string.
302

RECORDS

304       Uninterpreted  records may be attached to graphs, subgraphs, nodes, and
305       edges for efficient  operations  on  values  such  as  marks,  weights,
306       counts, and pointers needed by algorithms.  Application programmers de‐
307       fine the fields of these records, but they must be declared with a com‐
308       mon header as shown below.
309
310       typedef struct {
311           Agrec_t        header;
312           /* programmer-defined fields follow */
313       } user_data_t;
314
315       Records are created and managed by Libcgraph. A programmer must explic‐
316       itly attach them to the objects in a graph, either  to  individual  ob‐
317       jects  one  at  a time via agbindrec, or to all the objects of the same
318       class in a graph via aginit.  (Note that for graphs, aginit is  applied
319       recursively  to the graph and its subgraphs if rec_size is negative (of
320       the actual rec_size.))  The name argument  of  a  record  distinguishes
321       various types of records, and is programmer defined (Libcgraph reserves
322       the prefix _ag).  If size is 0, the  call  to  agbindrec  is  simply  a
323       lookup.   The  function aggetrec can also be used for lookup.  agdelrec
324       deletes a named record from one object.  agclean does the same for  all
325       objects of the same class in an entire graph.
326
327       Internally, records are maintained in circular linked lists attached to
328       graph objects.  To allow referencing application-dependent data without
329       function calls or search, Libcgraph allows setting and locking the list
330       pointer of a graph, node, or edge on a particular record.  This pointer
331       can be obtained with the macro AGDATA(obj).  A cast, generally within a
332       macro or inline function,  is  usually  applied  to  convert  the  list
333       pointer to an appropriate programmer-defined type.
334
335       To  control  the setting of this pointer, the move_to_front flag may be
336       TRUE or FALSE.  If move_to_front is TRUE, the record will be locked  at
337       the  head  of  the list, so it can be accessed directly by AGDATA(obj).
338       The lock can be subsequently released or reset by a call to aggetrec.
339
340

DISCIPLINES

342       (This section is not intended for  casual  users.)   Programmer-defined
343       disciplines  customize certain resources- ID namespace, memory, and I/O
344       - needed by Libcgraph.  A discipline struct  (or  NULL)  is  passed  at
345       graph creation time.
346
347       struct Agdisc_s {            /* user's discipline */
348           Agmemdisc_t            *mem;
349           Agiddisc_t            *id;
350           Agiodisc_t            *io;
351       } ;
352
353       A  default  discipline  is supplied when NULL is given for any of these
354       fields.
355
356

ID DISCIPLINE

358       An ID allocator discipline allows a client to control assignment of IDs
359       (uninterpreted  integer  values)  to objects, and possibly how they are
360       mapped to and from strings.
361
362       struct Agiddisc_s {             /* object ID allocator */
363           void *(*open) (Agraph_t * g, Agdisc_t*);       /* associated with a graph */
364           long (*map) (void *state, int objtype, char *str, unsigned long *id, int createflag);
365           long (*alloc) (void *state, int objtype, unsigned long id);
366           void (*free) (void *state, int objtype, unsigned long id);
367           char *(*print) (void *state, int objtype, unsigned long id);
368           void (*close) (void *state);
369       };
370
371       open permits the ID discipline to initialize any data  structures  that
372       it  maintains per individual graph.  Its return value is then passed as
373       the first argument (void *state) to all subsequent ID manager calls.
374
375       alloc informs the ID manager that Libcgraph is attempting to create  an
376       object  with  a specific ID that was given by a client.  The ID manager
377       should return TRUE (nonzero) if the  ID  can  be  allocated,  or  FALSE
378       (which aborts the operation).
379
380       free  is  called  to inform the ID manager that the object labeled with
381       the given ID is about to go out of existence.
382
383       map is called to create or look-up IDs by string name (if supported  by
384       the  ID manager).  Returning TRUE (nonzero) in all cases means that the
385       request succeeded (with a valid ID stored through  result.   There  are
386       four cases:
387
388       name  != NULL and createflag == 1: This requests mapping a string (e.g.
389       a name in a graph file) into a new ID.  If the ID manager  can  comply,
390       then  it stores the result and returns TRUE.  It is then also responsi‐
391       ble for being able to print the ID again as a string.  Otherwise the ID
392       manager  may return FALSE but it must implement the following (at least
393       for graph file reading and writing to work):
394
395       name == NULL and createflag == 1: The ID manager creates a  unique  new
396       ID  of  its  own choosing.  Although it may return FALSE if it does not
397       support anonymous objects, but this is strongly discouraged (to support
398       "local names" in graph files.)
399
400       name  !=  NULL  and createflag == 0: This is a namespace probe.  If the
401       name was previously mapped into an allocated ID by the ID manager, then
402       the  manager must return this ID.  Otherwise, the ID manager may either
403       return FALSE, or may store any unallocated ID  into  result.  (This  is
404       convenient,  for  example,  if names are known to be digit strings that
405       are directly converted into integer values.)
406
407       name == NULL and createflag == 0: forbidden.
408
409       print is allowed to return a pointer to a static buffer; a caller  must
410       copy  its  value  if  needed past subsequent calls.  NULL should be re‐
411       turned by ID managers that do not map names.
412
413       The map and alloc calls do not pass a pointer to  the  newly  allocated
414       object.   If  a client needs to install object pointers in a handle ta‐
415       ble, it can obtain them via new object callbacks.
416

IO DISCIPLINE

418       The I/O discipline provides an abstraction for the reading and  writing
419       of graphs.
420       struct Agiodisc_s {
421           int        (*fread)(void *chan, char *buf, int bufsize);
422           int        (*putstr)(void *chan, char *str);
423           int        (*flush)(void *chan);    /* sync */
424       } ;
425       Normally,  the  FILE  structure  and its related functions are used for
426       I/O. At times, though, an application may need to use a totally differ‐
427       ent  type  of character source. The associated state or stream informa‐
428       tion is provided by the chan argument to agread or agwrite.  The disci‐
429       pline function fread and putstr provide the corresponding functions for
430       read and writing.
431
432

MEMORY DISCIPLINE

434       Memory management in Libcgraph is handled on a per  graph  basis  using
435       the memory discipline.
436       struct Agmemdisc_s {    /* memory allocator */
437           void    *(*open)(Agdisc_t*);        /* independent of other resources */
438           void    *(*alloc)(void *state, size_t req);
439           void    *(*resize)(void *state, void *ptr, size_t old, size_t req);
440           void    (*free)(void *state, void *ptr);
441           void    (*close)(void *state);
442       } ;
443       The open function is used to initialize the memory subsystem, returning
444       state information that is passed to the calls  to  alloc,  resize,  and
445       free.   The  semantics  of these should be comparable to the standard C
446       library functions malloc, realloc, and free, except that new space cre‐
447       ated by agalloc and agrealloc should be zeroed out.  The close function
448       is used to terminate the memory subsystem, freeing any additional  open
449       resources.  For actual allocation, the library uses the functions agal‐
450       loc, agrealloc, and agfree, which provide simple wrappers for  the  un‐
451       derlying discipline functions alloc, resize, and free.
452
453       When  Libcgraph  is  compiled  with Vmalloc (which is not the default),
454       each graph has its own heap.  Programmers may allocate  application-de‐
455       pendent data within the same heap as the rest of the graph.  The advan‐
456       tage is that a graph can be deleted by atomically  freeing  its  entire
457       heap without scanning each individual node and edge.
458
459

CALLBACKS

461       An  Agcbdisc_t  defines  callbacks to be invoked by Libcgraph when ini‐
462       tializing, modifying, or finalizing  graph  objects.   Disciplines  are
463       kept  on  a  stack.   Libcgraph  automatically calls the methods on the
464       stack, top-down.  Callbacks are installed with agpushdisc,  uninstalled
465       with agpopdisc, and can be held pending or released via agcallbacks.
466

GENERIC OBJECTS

468       agroot takes any graph object (graph, subgraph, node, edge) and returns
469       the root graph in which it lives. agraphof does the same, except it  is
470       the  identity  function  on graphs and subgraphs. Note that there is no
471       function to return the least subgraph containing an object, in part be‐
472       cause  this is not well-defined as nodes and edges may be in incompara‐
473       ble subgraphs.
474
475       agcontains(g,obj) returns non-zero if obj is a member of (sub)graph  g.
476       agdelete(g,obj)  is equivalent to agclose, agdelnode, and agdeledge for
477       obj being a graph, node or edge, respectively. It  returns  -1  if  obj
478       does not belong to g.
479
480       AGDATA,  AGID,  and AGTYPE are macros returning the specified fields of
481       the argument object. The first is  described  in  the  RECORDS  section
482       above. The second returns the unique integer ID associated with the ob‐
483       ject. The last returns AGRAPH, AGNODE, and AGEDGE depending on the type
484       of the object.
485
486       agnameof  returns  a  string  descriptor for the object. It returns the
487       name of the node or graph, and the key of an edge.  agobjkind is a syn‐
488       onym for AGTYPE.
489
490

ERROR REPORTING

492       The  library  provides a variety of mechanisms to control the reporting
493       of errors and warnings. At present, there are basically  two  types  of
494       messages:  warnings  and  errors. A message is only written if its type
495       has higher priority than a programmer-controlled minimum, which is  AG‐
496       WARN  by  default.  The  programmer  can set this value using agseterr,
497       which returns the previous value. Calling agseterr(AGMAX) turns off the
498       writing of messages.
499
500       The  function  agerr  if the main entry point for reporting an anomaly.
501       The first argument indicates the type of message.  Usually,  the  first
502       argument  in  AGWARN  or AGERR to indicate warnings and errors, respec‐
503       tively. Sometimes additional context information is only  available  in
504       functions  calling  the function where the error is actually caught. In
505       this case, the calling function can indicate that it is continuing  the
506       current  error by using AGPREV as the first argument. The remaining ar‐
507       guments to agerr are the same as the arguments to printf.
508
509       The   functions   agwarningf   and   agerrorf   are    shorthand    for
510       agerr(AGERR,...) and agerr(AGWARN,...), respectively.
511
512       Some  applications  desire to directly control the writing of messages.
513       Such an application can use the  function  agseterrf  to  register  the
514       function  that  the  library should call to actually write the message.
515       The previous error function is returned. By  default,  the  message  is
516       written to stderr.
517
518       Errors  not  written  are stored in a log file. The last recorded error
519       can be retreived by calling aglasterr.  Unless the  printing  of  error
520       messages  has  been  completely  disabled by a call to agseterr(AGMAX),
521       standard error must not be wide-oriented, even if a user-provided error
522       printing function is provided.
523
524       The function agerrors returns non-zero if errors have been reported.
525

EXAMPLE PROGRAM

527       #include <stdio.h>
528       #include <cgraph.h>
529
530       typedef struct {Agrec_t hdr; int x,y,z;} mydata;
531
532       void main(int argc, char **argv)
533       {
534           Agraph_t    *g, *h;
535           Agnode_t    *v;
536           Agedge_t    *e;
537           Agsym_t     *attr;
538           Dict_t      *d;
539           int         cnt;
540           mydata      *p;
541
542           if (g = agread(stdin,NIL(Agdisc_t*))) {
543               cnt = 0; attr = 0;
544               while (attr = agnxtattr(g, AGNODE, attr)) cnt++;
545               printf("The graph %s has %d attributes\n",agnameof(g),cnt);
546
547               /* make the graph have a node color attribute, default is blue */
548               attr = agattr(g,AGNODE,"color","blue");
549
550               /* create a new graph of the same kind as g */
551               h = agopen("tmp",g->desc, NULL);
552
553               /* this is a way of counting all the edges of the graph */
554               cnt = 0;
555               for (v = agfstnode(g); v; v = agnxtnode(g,v))
556                   for (e = agfstout(g,v); e; e = agnxtout(g,e))
557                       cnt++;
558
559               /* attach records to edges */
560               for (v = agfstnode(g); v; v = agnxtnode(g,v))
561                   for (e = agfstout(g,v); e; e = agnxtout(g,e)) {
562                       p = (mydata*) agbindrec(e,"mydata",sizeof(mydata),TRUE);
563                       p->x = 27;  /* meaningless data access example */
564                       ((mydata*)(AGDATA(e)))->y = 999; /* another example */
565               }
566           }
567       }
568
569

EXAMPLE GRAPH FILES

571       digraph G {
572           a -> b;
573           c [shape=box];
574           a -> c [weight=29,label="some text"];
575           subgraph anything {
576               /* the following affects only x,y,z */
577               node [shape=circle];
578               a; x; y -> z; y -> z;  /* multiple edges */
579           }
580       }
581
582       strict graph H {
583           n0 -- n1 -- n2 -- n0;  /* a cycle */
584           n0 -- {a b c d};       /* a star */
585           n0 -- n3;
586           n0 -- n3 [weight=1];   /* same edge because graph is strict */
587       }
588

SEE ALSO

590       Libcdt(3)
591
592

BUGS

594       It  is difficult to change endpoints of edges, delete string attributes
595       or modify edge keys.  The work-around is to create  a  new  object  and
596       copy the contents of an old one (but new object obviously has a differ‐
597       ent ID, internal address, and object creation timestamp).
598
599       The API lacks convenient functions to substitute programmer-defined or‐
600       dering of nodes and edges but in principle this can be supported.
601
602       The library is not thread safe.
603

AUTHOR

605       Stephen North, north@research.att.com, AT&T Research.
606
607
608
609                               28 FEBRUARY 2013                   LIBCGRAPH(3)
Impressum