Add utility function agmemread (as in libgraph) to cgraph
authorEmden Gansner <erg@research.att.com>
Fri, 25 Nov 2011 19:19:02 +0000 (14:19 -0500)
committerEmden Gansner <erg@research.att.com>
Fri, 25 Nov 2011 19:19:02 +0000 (14:19 -0500)
lib/cgraph/cgraph.h
lib/cgraph/grammar.y

index f1672ab08897daf1406bcc4201e698d57db1fc49..a815e8494bae267428a49d549d89c0fb05f99816 100644 (file)
@@ -265,6 +265,7 @@ extern int agcallbacks(Agraph_t * g, int flag);     /* return prev value */
 extern Agraph_t *agopen(char *name, Agdesc_t desc, Agdisc_t * disc);
 extern int agclose(Agraph_t * g);
 extern Agraph_t *agread(void *chan, Agdisc_t * disc);
+extern Agraph_t *agmemread(const char *cp);
 extern void agreadline(int);
 extern void agsetfile(char *);
 extern Agraph_t *agconcat(Agraph_t * g, void *chan, Agdisc_t * disc);
index e2128b817b2a4a91c2228fc786ec26f79ebe689f..3c01ae49b7f613a68c93b71f0825dadba8a6e6a1 100644 (file)
@@ -540,3 +540,51 @@ Agraph_t *agconcat(Agraph_t *g, void *chan, Agdisc_t *disc)
 }
 
 Agraph_t *agread(void *fp, Agdisc_t *disc) {return agconcat(NILgraph,fp,disc); }
+
+typedef struct {
+    const char *data;
+    int len;
+    int cur;
+} rdr_t;
+
+static int
+iofread(void *chan, char *buf, int bufsize)
+{
+    const char *ptr;
+    char *optr;
+    char c;
+    int l;
+    rdr_t *s;
+
+    if (bufsize == 0) return 0;
+    s = (rdr_t *) chan;
+    if (s->cur >= s->len)
+        return 0;
+    l = 0;
+    ptr = s->data + s->cur;
+    optr = buf;
+    do {
+        *optr++ = c = *ptr++;
+        l++;
+    } while (c && (c != '\n') && (l < bufsize));
+    s->cur += l;
+    return l;
+}
+
+static Agiodisc_t memIoDisc = { iofread, AgIoDisc.putstr, AgIoDisc.flush };
+
+Agraph_t *agmemread(const char *cp)
+{
+    Agraph_t* g;
+    rdr_t rdr;
+
+    rdr.data = cp;
+    rdr.len = strlen(cp);
+    rdr.cur = 0;
+    disc.mem = &AgMemDisc;
+    disc.id = &AgIdDisc;
+    disc.io = &memIoDisc;
+    g = agread (&rdr, &disc);
+    return g;
+}
+