]> granicus.if.org Git - graphviz/commitdiff
Initial version of Cgraph created.
authornorth <devnull@localhost>
Thu, 25 Oct 2007 20:27:57 +0000 (20:27 +0000)
committernorth <devnull@localhost>
Thu, 25 Oct 2007 20:27:57 +0000 (20:27 +0000)
lib/cgraph/agxbuf.h [new file with mode: 0644]
lib/cgraph/apply.c [new file with mode: 0644]

diff --git a/lib/cgraph/agxbuf.h b/lib/cgraph/agxbuf.h
new file mode 100644 (file)
index 0000000..767fe7c
--- /dev/null
@@ -0,0 +1,107 @@
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef         AGXBUF_H
+#define         AGXBUF_H
+
+/* Extensible buffer:
+ *  Malloc'ed memory is never released until agxbfree is called.
+ */
+    typedef struct {
+       unsigned char *buf;     /* start of buffer */
+       unsigned char *ptr;     /* next place to write */
+       unsigned char *eptr;    /* end of buffer */
+       int dyna;               /* true if buffer is malloc'ed */
+    } agxbuf;
+
+/* agxbinit:
+ * Initializes new agxbuf; caller provides memory.
+ * Assume if init is non-null, hint = sizeof(init[])
+ */
+    extern void agxbinit(agxbuf * xb, unsigned int hint,
+                        unsigned char *init);
+
+/* agxbput_n:
+ * Append string s of length n into xb
+ */
+    extern int agxbput_n(agxbuf * xb, char *s, unsigned int n);
+
+/* agxbput:
+ * Append string s into xb
+ */
+    extern int agxbput(agxbuf * xb, char *s);
+
+/* agxbfree:
+ * Free any malloced resources.
+ */
+    extern void agxbfree(agxbuf * xb);
+
+/* agxbpop:
+ * Removes last character added, if any.
+ */
+    extern int agxbpop(agxbuf * xb);
+
+/* agxbmore:
+ * Expand buffer to hold at least ssz more bytes.
+ */
+    extern int agxbmore(agxbuf * xb, int unsigned ssz);
+
+/* agxbputc:
+ * Add character to buffer.
+ *  int agxbputc(agxbuf*, char)
+ */
+#define agxbputc(X,C) ((((X)->ptr >= (X)->eptr) ? agxbmore(X,1) : 0), \
+          (int)(*(X)->ptr++ = ((unsigned char)C)))
+
+/* agxbuse:
+ * Null-terminates buffer; resets and returns pointer to data;
+ *  char* agxbuse(agxbuf* xb)
+ */
+#define agxbuse(X) (agxbputc(X,'\0'),(char*)((X)->ptr = (X)->buf))
+
+/* agxbstart:
+ * Return pointer to beginning of buffer.
+ *  char* agxbstart(agxbuf* xb)
+ */
+#define agxbstart(X) ((char*)((X)->buf))
+
+/* agxblen:
+ * Return number of characters currently stored.
+ *  int agxblen(agxbuf* xb)
+ */
+#define agxblen(X) (((X)->ptr)-((X)->buf))
+
+/* agxbclear:
+ * Resets pointer to data;
+ *  void agxbclear(agxbuf* xb)
+ */
+#define agxbclear(X) ((void)((X)->ptr = (X)->buf))
+
+/* agxbnext:
+ * Next position for writing.
+ *  char* agxbnext(agxbuf* xb)
+ */
+#define agxbnext(X) ((char*)((X)->ptr))
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/lib/cgraph/apply.c b/lib/cgraph/apply.c
new file mode 100644 (file)
index 0000000..3eb70a0
--- /dev/null
@@ -0,0 +1,89 @@
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
+
+#include       <cghdr.h>
+
+/* The following functions take a graph and a template (node/edge/graph)
+ * and return the object representing the template within the local graph.
+ */
+static Agobj_t *subnode_search(Agraph_t * sub, Agobj_t * n)
+{
+    if (agraphof(n) == sub)
+       return n;
+    return (Agobj_t *) agsubnode(sub, (Agnode_t *) n, FALSE);
+}
+
+static Agobj_t *subedge_search(Agraph_t * sub, Agobj_t * e)
+{
+    if (agraphof(e) == sub)
+       return e;
+    return (Agobj_t *) agsubedge(sub, (Agedge_t *) e, FALSE);
+}
+
+static Agobj_t *subgraph_search(Agraph_t * sub, Agobj_t * g)
+{
+    NOTUSED(g);
+    return (Agobj_t *) sub;
+}
+
+/* recursively apply objfn within the hierarchy of a graph.
+ * if obj is a node or edge, it and its images in every subg are visited.
+ * if obj is a graph, then it and its subgs are visited.
+ */
+static void rec_apply(Agraph_t * g, Agobj_t * obj, agobjfn_t fn, void *arg,
+                     agobjsearchfn_t objsearch, int preorder)
+{
+    Agraph_t *sub;
+    Agobj_t *subobj;
+
+    if (preorder)
+       fn(g, obj, arg);
+    for (sub = agfstsubg(g); sub; sub = agnxtsubg(sub)) {
+       if ((subobj = objsearch(sub, obj)))
+           rec_apply(sub, subobj, fn, arg, objsearch, preorder);
+    }
+    if (NOT(preorder))
+       fn(g, obj, arg);
+}
+
+/* external entry point (this seems to be one of those ineffective
+ * comments censured in books on programming style) */
+int agapply(Agraph_t * g, Agobj_t * obj, agobjfn_t fn, void *arg,
+           int preorder)
+{
+    Agobj_t *subobj;
+
+    agobjsearchfn_t objsearch;
+    switch (AGTYPE(obj)) {
+    case AGRAPH:
+       objsearch = subgraph_search;
+       break;
+    case AGNODE:
+       objsearch = subnode_search;
+       break;
+    case AGOUTEDGE:
+    case AGINEDGE:
+       objsearch = subedge_search;
+       break;
+    default:
+       abort();
+    }
+    if ((subobj = objsearch(g, obj))) {
+       rec_apply(g, subobj, fn, arg, objsearch, preorder);
+       return SUCCESS;
+    } else
+       return FAILURE;
+}