From: John Ellson Date: Sat, 11 Aug 2012 21:50:15 +0000 (-0400) Subject: split out mygets() X-Git-Tag: LAST_LIBGRAPH~32^2~355^2~8 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c817efcc015e846a5f39bf464354c746c548b9a5;p=graphviz split out mygets() --- diff --git a/tclpkg/tcldot/Makefile.am b/tclpkg/tcldot/Makefile.am index bae74128a..b282a6407 100644 --- a/tclpkg/tcldot/Makefile.am +++ b/tclpkg/tcldot/Makefile.am @@ -43,7 +43,14 @@ if WITH_LIBGD GDTCLFT = $(top_srcdir)/tclpkg/gdtclft/gdtclft.c endif -libtcldot_la_SOURCES = tcldot.c tcldot-graphcmd.c tcldot-nodecmd.c tcldot-edgecmd.c tcldot-util.c no_builtins.c $(GDTCLFT) +libtcldot_la_SOURCES = \ + tcldot.c \ + tcldot-graphcmd.c \ + tcldot-nodecmd.c \ + tcldot-edgecmd.c \ + tcldot-util.c \ + tcldot-mygets.c \ + no_builtins.c $(GDTCLFT) libtcldot_la_CPPFLAGS = $(AM_CPPFLAGS) -DDEMAND_LOADING=1 libtcldot_la_LDFLAGS = -no-undefined @@ -63,7 +70,14 @@ endif libtcldot_la_LIBADD += $(LIBGEN_LIBS) $(MATH_LIBS) -libtcldot_builtin_la_SOURCES = tcldot.c tcldot-graphcmd.c tcldot-nodecmd.c tcldot-edgecmd.c tcldot-util.c tcldot_builtins.c $(GDTCLFT) +libtcldot_builtin_la_SOURCES = \ + tcldot.c \ + tcldot-graphcmd.c \ + tcldot-nodecmd.c \ + tcldot-edgecmd.c \ + tcldot-util.c \ + tcldot-mygets.c \ + tcldot_builtins.c $(GDTCLFT) libtcldot_builtin_la_CPPFLAGS = $(AM_CPPFLAGS) -DDEMAND_LOADING=1 libtcldot_builtin_la_LDFLAGS = diff --git a/tclpkg/tcldot/tcldot-mygets.c b/tclpkg/tcldot/tcldot-mygets.c new file mode 100644 index 000000000..170dbf285 --- /dev/null +++ b/tclpkg/tcldot/tcldot-mygets.c @@ -0,0 +1,159 @@ +/* $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" + +/* + * mygets - same api as gets for libgraph, or 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 + * + * 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. + */ +#ifdef WITH_CGRAPH +int mygets(void* channel, char *ubuf, int n) +{ + static Tcl_DString dstr; + static int strpos; + int nput; + + if (!n) { /* a call with n==0 (from aglexinit) resets */ + *ubuf = '\0'; + strpos = 0; + return 0; + } + + /* + * the user buffer might not be big enough to hold the line. + */ + if (strpos) { + nput = Tcl_DStringLength(&dstr) - strpos; + if (nput > n) { + /* chunk between first and last */ + memcpy(ubuf, (strpos + Tcl_DStringValue(&dstr)), n); + strpos += n; + nput = n; + ubuf[n] = '\0'; + } else { + /* last chunk */ + memcpy(ubuf, (strpos + Tcl_DStringValue(&dstr)), nput); + strpos = 0; + } + } else { + Tcl_DStringFree(&dstr); + Tcl_DStringInit(&dstr); + if (Tcl_Gets((Tcl_Channel) channel, &dstr) < 0) { + /* probably EOF, but could be other read errors */ + *ubuf = '\0'; + return 0; + } + /* linend char(s) were stripped off by Tcl_Gets, + * append a canonical linenend. */ + Tcl_DStringAppend(&dstr, "\n", 1); + if (Tcl_DStringLength(&dstr) > n) { + /* first chunk */ + nput = n; + memcpy(ubuf, Tcl_DStringValue(&dstr), n); + strpos = n; + } else { + /* single chunk */ + nput = Tcl_DStringLength(&dstr); + memcpy(ubuf, Tcl_DStringValue(&dstr),nput); + } + } + return nput; +} +#else +char *mygets(char *ubuf, int n, FILE * channel) +{ + static Tcl_DString dstr; + static int strpos; + + if (!n) { /* a call with n==0 (from aglexinit) resets */ + *ubuf = '\0'; + strpos = 0; + return NULL; + } + + /* + * the user buffer might not be big enough to hold the line. + */ + if (strpos) { + if (Tcl_DStringLength(&dstr) > (n + strpos)) { + /* chunk between first and last */ + strncpy(ubuf, (strpos + Tcl_DStringValue(&dstr)), n - 1); + strpos += (n - 1); + ubuf[n] = '\0'; + } else { + /* last chunk */ + strcpy(ubuf, (strpos + Tcl_DStringValue(&dstr))); + strpos = 0; + } + } else { + Tcl_DStringFree(&dstr); + Tcl_DStringInit(&dstr); + if (Tcl_Gets((Tcl_Channel) channel, &dstr) < 0) { + /* probably EOF, but could be other read errors */ + *ubuf = '\0'; + return NULL; + } + /* linend char(s) were stripped off by Tcl_Gets, + * append a canonical linenend. */ + Tcl_DStringAppend(&dstr, "\n", 1); + if (Tcl_DStringLength(&dstr) >= n) { + /* first chunk */ + strncpy(ubuf, Tcl_DStringValue(&dstr), n - 1); + strpos = n - 1; + ubuf[n] = '\0'; + } else { + /* single chunk */ + strcpy(ubuf, Tcl_DStringValue(&dstr)); + } + } + return ubuf; + +#if 0 + if (!n) { /* a call with n==0 (from aglexinit) resets */ + mempos = (char *) mbuf; /* cast from FILE* required by API */ + } + + clp = to = ubuf; + for (i = 0; i < n - 1; i++) { /* leave room for terminator */ + if (*mempos == '\0') { + if (i) { /* if mbuf doesn't end in \n, provide one */ + *to++ = '\n'; + } else { /* all done */ + clp = NULL; + mempos = NULL; + } + break; /* last line or end-of-buffer */ + } + if (*mempos == '\n') { + *to++ = *mempos++; + break; /* all done with this line */ + } + *to++ = *mempos++; /* copy character */ + } + *to++ = '\0'; /* place terminator in ubuf */ + return clp; +#endif +} +#endif /* WITH_CGRAPH */ diff --git a/tclpkg/tcldot/tcldot.c b/tclpkg/tcldot/tcldot.c index 1d3c795b5..e86631de0 100644 --- a/tclpkg/tcldot/tcldot.c +++ b/tclpkg/tcldot/tcldot.c @@ -319,152 +319,7 @@ static int tcldot_fixup(mycontext_t *mycontext, graph_t * g) return TCL_OK; } -/* - * mygets - same api as gets for libgraph, or 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 - * - * 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. - */ -#ifdef WITH_CGRAPH -static int mygets(void* channel, char *ubuf, int n) -{ - static Tcl_DString dstr; - static int strpos; - int nput; - - if (!n) { /* a call with n==0 (from aglexinit) resets */ - *ubuf = '\0'; - strpos = 0; - return 0; - } - - /* - * the user buffer might not be big enough to hold the line. - */ - if (strpos) { - nput = Tcl_DStringLength(&dstr) - strpos; - if (nput > n) { - /* chunk between first and last */ - memcpy(ubuf, (strpos + Tcl_DStringValue(&dstr)), n); - strpos += n; - nput = n; - ubuf[n] = '\0'; - } else { - /* last chunk */ - memcpy(ubuf, (strpos + Tcl_DStringValue(&dstr)), nput); - strpos = 0; - } - } else { - Tcl_DStringFree(&dstr); - Tcl_DStringInit(&dstr); - if (Tcl_Gets((Tcl_Channel) channel, &dstr) < 0) { - /* probably EOF, but could be other read errors */ - *ubuf = '\0'; - return 0; - } - /* linend char(s) were stripped off by Tcl_Gets, - * append a canonical linenend. */ - Tcl_DStringAppend(&dstr, "\n", 1); - if (Tcl_DStringLength(&dstr) > n) { - /* first chunk */ - nput = n; - memcpy(ubuf, Tcl_DStringValue(&dstr), n); - strpos = n; - } else { - /* single chunk */ - nput = Tcl_DStringLength(&dstr); - memcpy(ubuf, Tcl_DStringValue(&dstr),nput); - } - } - return nput; -} -#else -static char *mygets(char *ubuf, int n, FILE * channel) -{ - static Tcl_DString dstr; - static int strpos; - - if (!n) { /* a call with n==0 (from aglexinit) resets */ - *ubuf = '\0'; - strpos = 0; - return NULL; - } - - /* - * the user buffer might not be big enough to hold the line. - */ - if (strpos) { - if (Tcl_DStringLength(&dstr) > (n + strpos)) { - /* chunk between first and last */ - strncpy(ubuf, (strpos + Tcl_DStringValue(&dstr)), n - 1); - strpos += (n - 1); - ubuf[n] = '\0'; - } else { - /* last chunk */ - strcpy(ubuf, (strpos + Tcl_DStringValue(&dstr))); - strpos = 0; - } - } else { - Tcl_DStringFree(&dstr); - Tcl_DStringInit(&dstr); - if (Tcl_Gets((Tcl_Channel) channel, &dstr) < 0) { - /* probably EOF, but could be other read errors */ - *ubuf = '\0'; - return NULL; - } - /* linend char(s) were stripped off by Tcl_Gets, - * append a canonical linenend. */ - Tcl_DStringAppend(&dstr, "\n", 1); - if (Tcl_DStringLength(&dstr) >= n) { - /* first chunk */ - strncpy(ubuf, Tcl_DStringValue(&dstr), n - 1); - strpos = n - 1; - ubuf[n] = '\0'; - } else { - /* single chunk */ - strcpy(ubuf, Tcl_DStringValue(&dstr)); - } - } - return ubuf; - -#if 0 - if (!n) { /* a call with n==0 (from aglexinit) resets */ - mempos = (char *) mbuf; /* cast from FILE* required by API */ - } - - clp = to = ubuf; - for (i = 0; i < n - 1; i++) { /* leave room for terminator */ - if (*mempos == '\0') { - if (i) { /* if mbuf doesn't end in \n, provide one */ - *to++ = '\n'; - } else { /* all done */ - clp = NULL; - mempos = NULL; - } - break; /* last line or end-of-buffer */ - } - if (*mempos == '\n') { - *to++ = *mempos++; - break; /* all done with this line */ - } - *to++ = *mempos++; /* copy character */ - } - *to++ = '\0'; /* place terminator in ubuf */ - return clp; -#endif -} -#endif /* WITH_CGRAPH */ - #ifdef WITH_CGRAPH - Agraph_t *agread_usergets (FILE * fp, int (*usergets)(void *chan, char *buf, int bufsize)) { Agraph_t* g; @@ -631,10 +486,13 @@ int Tcldot_Init(Tcl_Interp * interp) (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL); #endif /* TCLOBJ */ +#ifdef WITH_CGRAPH + mycontext->graphTblPtr = (void *) tclhandleInit("tcldot", sizeof(graph_context_t *), 10); +#else mycontext->graphTblPtr = (void *) tclhandleInit("graph", sizeof(Agraph_t *), 10); mycontext->nodeTblPtr = (void *) tclhandleInit("node", sizeof(Agnode_t *), 100); mycontext->edgeTblPtr = (void *) tclhandleInit("edge", sizeof(Agedge_t *), 100); - +#endif return TCL_OK; } diff --git a/tclpkg/tcldot/tcldot.h b/tclpkg/tcldot/tcldot.h index dfc56d4d1..2d6b3539d 100644 --- a/tclpkg/tcldot/tcldot.h +++ b/tclpkg/tcldot/tcldot.h @@ -40,16 +40,30 @@ Tcl_GetString(Tcl_Obj *obj) { #endif ********* */ +/* + * mycontext - one per tcl interpreter, may support multiple graph namespaces + */ typedef struct { #ifdef WITH_CGRAPH Agdisc_t mydisc; // must be first to allow casting mydisc to mycontext #endif - void *graphTblPtr, *nodeTblPtr, *edgeTblPtr; + void *graphTblPtr; +/* **FIXME** #ifndef WITH_CGRAPH */ + void *nodeTblPtr, *edgeTblPtr; +/* #endif */ Tcl_Interp *interp; GVC_t *gvc; } mycontext_t; -/* Globals */ +#ifdef WITH_CGRAPH +/* + * graph_context - one for each graph in a tcl interp + */ +typedef struct { + Agraph_t *g; /* the graph */ + mycontext_t *mycontext; /* refer back to top context */ +} graph_context_t; +#endif #if HAVE_LIBGD extern void *GDHandleTable; @@ -90,6 +104,7 @@ extern void deleteGraph(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 deleteEdges(mycontext_t * mycontext, Agraph_t * g, Agnode_t * n); extern void deleteNodes(mycontext_t * mycontext, Agraph_t * g); @@ -97,6 +112,7 @@ extern void deleteGraph(mycontext_t * mycontext, 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 char *mygets(char *ubuf, int n, FILE * channel); #endif extern void setgraphattributes(Agraph_t * g, char *argv[], int argc); @@ -110,9 +126,3 @@ extern void tcldot_layout(GVC_t *gvc, Agraph_t * g, char *engine); extern void reset_layout(GVC_t *gvc, Agraph_t * sg); - - - - - -