From: John Ellson Date: Tue, 14 Aug 2012 19:52:52 +0000 (-0400) Subject: dotnew(), dotread(), dotstring() - cgraph & graph - working X-Git-Tag: LAST_LIBGRAPH~32^2~355^2~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d5cac7effedaafc204652cc5ebcc7a3923b1a0fc;p=graphviz dotnew(), dotread(), dotstring() - cgraph & graph - working --- diff --git a/tclpkg/tcldot/Makefile.am b/tclpkg/tcldot/Makefile.am index 9a855bdbc..6a768e633 100644 --- a/tclpkg/tcldot/Makefile.am +++ b/tclpkg/tcldot/Makefile.am @@ -54,7 +54,6 @@ libtcldot_la_SOURCES = \ tcldot-util.c \ tcldot-id.c \ tcldot-io.c \ - tcldot-mem.c \ no_builtins.c $(GDTCLFT) libtcldot_la_CPPFLAGS = $(AM_CPPFLAGS) -DDEMAND_LOADING=1 libtcldot_la_LDFLAGS = -no-undefined @@ -83,7 +82,6 @@ libtcldot_builtin_la_SOURCES = \ tcldot-util.c \ tcldot-id.c \ tcldot-io.c \ - tcldot-mem.c \ tcldot_builtins.c $(GDTCLFT) libtcldot_builtin_la_CPPFLAGS = $(AM_CPPFLAGS) -DDEMAND_LOADING=1 libtcldot_builtin_la_LDFLAGS = diff --git a/tclpkg/tcldot/tcldot-id.c b/tclpkg/tcldot/tcldot-id.c index 4a3be388e..d430ea966 100644 --- a/tclpkg/tcldot/tcldot-id.c +++ b/tclpkg/tcldot/tcldot-id.c @@ -80,7 +80,7 @@ static char *myiddisc_print(void *state, int objtype, unsigned long id) { static void myiddisc_close(void *state) { free(state); } -static void myiddisc_register(void *state, int objtype, void *obj) { +static void myiddisc_idregister(void *state, int objtype, void *obj) { gctx_t *gctx = (gctx_t *)state; ictx_t *ictx = gctx->ictx; Tcl_Interp *interp = ictx->interp; @@ -106,6 +106,6 @@ Agiddisc_t myiddisc = { myiddisc_free, myiddisc_print, myiddisc_close, - myiddisc_register + myiddisc_idregister }; #endif diff --git a/tclpkg/tcldot/tcldot-io.c b/tclpkg/tcldot/tcldot-io.c index c257ba06c..6e4750a9d 100644 --- a/tclpkg/tcldot/tcldot-io.c +++ b/tclpkg/tcldot/tcldot-io.c @@ -14,8 +14,9 @@ #include "tcldot.h" +#ifdef WITH_CGRAPH /* - * mygets - same api as gets for libgraph, or read for libcgraph + * myiodisc_afread - same api as read for libcgraph * * gets one line at a time from a Tcl_Channel and places it in a user buffer * up to a maximum of n characters @@ -28,8 +29,7 @@ * but it is needed so that we can take full advantage * of the Tcl_Channel mechanism. */ -#ifdef WITH_CGRAPH -int mygets(void* channel, char *ubuf, int n) +int myiodisc_afread(void* channel, char *ubuf, int n) { static Tcl_DString dstr; static int strpos; @@ -81,7 +81,48 @@ int mygets(void* channel, char *ubuf, int n) } return nput; } + + +/* exact copy from cgraph/io.c - but that one is static */ +int myiodisc_memiofread(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; +} + #else +/* + * mygets - same api as gets + * + * gets one line at a time from a Tcl_Channel and places it in a user buffer + * up to a maximum of n characters + * + * returns pointer to obtained line in user buffer, or + * returns NULL when last line read from memory buffer + * + * This is probably innefficient because it introduces + * one more stage of line buffering during reads (at least) + * but it is needed so that we can take full advantage + * of the Tcl_Channel mechanism. + */ + char *mygets(char *ubuf, int n, FILE * channel) { static Tcl_DString dstr; @@ -158,8 +199,7 @@ char *mygets(char *ubuf, int n, FILE * channel) } #endif /* WITH_CGRAPH */ -#ifdef WITH_CGRAPH - +#if 0 Agraph_t *agread_usergets (ictx_t *ictx, FILE * fp, int (*usergets)(void *chan, char *buf, int bufsize)) { Agraph_t* g; diff --git a/tclpkg/tcldot/tcldot-mem.c b/tclpkg/tcldot/tcldot-mem.c deleted file mode 100644 index ee5797181..000000000 --- a/tclpkg/tcldot/tcldot-mem.c +++ /dev/null @@ -1,18 +0,0 @@ -/* $Id$ $Revision$ */ -/* vim:set shiftwidth=4 ts=8: */ - -/************************************************************************* - * Copyright (c) 2011 AT&T Intellectual Property - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: See CVS logs. Details at http://www.graphviz.org/ - *************************************************************************/ - - -#include "tcldot.h" - -#ifdef WITH_CGRAPH -#endif diff --git a/tclpkg/tcldot/tcldot.c b/tclpkg/tcldot/tcldot.c index 89ba5e55d..bc54eac5c 100644 --- a/tclpkg/tcldot/tcldot.c +++ b/tclpkg/tcldot/tcldot.c @@ -211,6 +211,9 @@ static int dotread(ClientData clientData, Tcl_Interp * interp, int mode; #ifdef WITH_CGRAPH char buf[32]; + ictx_t *ictx = (ictx_t *)clientData; + + ictx->myioDisc.afread = myiodisc_afread; /* replace afread to use Tcl Channels */ #endif if (argc < 2) { @@ -228,7 +231,11 @@ static int dotread(ClientData clientData, Tcl_Interp * interp, * a properly parsed graph. If the graph doesn't parse * during reading then the channel will be left at EOF */ - g = agread_usergets((ictx_t *)clientData, (FILE *) channel, (mygets)); +#ifndef WITH_CGRAPH + g = agread_usergets((FILE *) channel, (mygets)); +#else + g = agread ((FILE*)channel, (Agdisc_t *)clientData); +#endif if (!g) { Tcl_AppendResult(interp, "\nFailure to read graph \"", argv[1], "\"", NULL); if (agerrors()) { @@ -264,13 +271,26 @@ static int dotstring(ClientData clientData, Tcl_Interp * interp, Agraph_t *g; #ifdef WITH_CGRAPH char buf[32]; + ictx_t *ictx = (ictx_t *)clientData; + rdr_t rdr; + + ictx->myioDisc.afread = myiodisc_memiofread; /* replace afread to use memory range */ + rdr.data = argv[1]; + rdr.len = strlen(rdr.data); + rdr.cur = 0; #endif if (argc < 2) { Tcl_AppendResult(interp, "Wrong # args: should be \"", argv[0], " string\"", NULL); return TCL_ERROR; } - if (!(g = agmemread(argv[1]))) { +#ifndef WITH_CGRAPH + g = agmemread(argv[1]); +#else + /* agmemread() is broken for our use because it replaces the id disc */ + g = agread(&rdr, (Agdisc_t *)clientData); +#endif + if (!g) { Tcl_AppendResult(interp, "\nFailure to read string \"", argv[1], "\"", NULL); if (agerrors()) { Tcl_AppendResult(interp, " because of syntax errors.", NULL); @@ -308,9 +328,16 @@ int Tcldot_Init(Tcl_Interp * interp) ictx->interp = interp; #ifdef WITH_CGRAPH - ictx->mydisc.mem = &AgMemDisc; - ictx->mydisc.id = &myiddisc; - ictx->mydisc.io = &AgIoDisc; + /* build disciplines dynamically so we can selectively replace functions */ + + ictx->myioDisc.afread = NULL; /* set in dotread() or dotstring() according to need */ + ictx->myioDisc.putstr = AgIoDisc.putstr; /* no change */ + ictx->myioDisc.flush = AgIoDisc.flush; /* no change */ + + ictx->mydisc.mem = &AgMemDisc; /* no change */ + ictx->mydisc.id = &myiddisc; /* complete replacement */ + ictx->mydisc.io = &(ictx->myioDisc); /* change parts */ + ictx->ctr = 1; /* init to first odd number, increment by 2 */ #endif diff --git a/tclpkg/tcldot/tcldot.h b/tclpkg/tcldot/tcldot.h index d4ebaec80..a6fcefda4 100644 --- a/tclpkg/tcldot/tcldot.h +++ b/tclpkg/tcldot/tcldot.h @@ -46,6 +46,7 @@ Tcl_GetString(Tcl_Obj *obj) { typedef struct { #ifdef WITH_CGRAPH Agdisc_t mydisc; /* must be first to allow casting mydisc to ictx */ + Agiodisc_t myioDisc; unsigned long ctr; /* odd number counter for anon objects over all g's in interp */ #else void *graphTblPtr, *nodeTblPtr, *edgeTblPtr; @@ -98,9 +99,16 @@ extern int edgecmd(ClientData clientData, Tcl_Interp * interp, ); #ifdef WITH_CGRAPH +/* rdr_t isn't exposed by cgraph/io.c */ +typedef struct { + const char *data; + int len; + int cur; +} rdr_t; + +extern int myiodisc_afread(void* channel, char *ubuf, int n); +extern int myiodisc_memiofread(void *chan, char *buf, int bufsize); extern Agiddisc_t myiddisc; -extern Agiodisc_t myiodisc; -extern Agmemdisc_t mymemdisc; extern Agraph_t *agread_usergets (ictx_t *ictx, FILE * fp, int (*usergets)(void *chan, char *buf, int bufsize)); extern Agraph_t *cmd2g(gctx_t *gctx, char *cmd); extern Agnode_t *cmd2n(gctx_t *gctx, char *cmd); @@ -111,7 +119,6 @@ extern void deleteGraph(gctx_t *gctx, Agraph_t * g); extern void listGraphAttrs (Tcl_Interp * interp, Agraph_t* g); extern void listNodeAttrs (Tcl_Interp * interp, Agraph_t* g); extern void listEdgeAttrs (Tcl_Interp * interp, Agraph_t* g); -extern int mygets(void* channel, char *ubuf, int n); #else extern void deleteEdge(ictx_t * ictx, Agraph_t * g, Agedge_t * e); extern void deleteNode(ictx_t * ictx, Agraph_t * g, Agnode_t * n);