Graphviz  2.41.20170921.2350
tcldot-io.c
Go to the documentation of this file.
1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 
15 #include "tcldot.h"
16 
17 /*
18  * myiodisc_afread - same api as read for libcgraph
19  *
20  * gets one line at a time from a Tcl_Channel and places it in a user buffer
21  * up to a maximum of n characters
22  *
23  * returns pointer to obtained line in user buffer, or
24  * returns NULL when last line read from memory buffer
25  *
26  * This is probably innefficient because it introduces
27  * one more stage of line buffering during reads (at least)
28  * but it is needed so that we can take full advantage
29  * of the Tcl_Channel mechanism.
30  */
31 int myiodisc_afread(void* channel, char *ubuf, int n)
32 {
33  static Tcl_DString dstr;
34  static int strpos;
35  int nput;
36 
37  if (!n) { /* a call with n==0 (from aglexinit) resets */
38  *ubuf = '\0';
39  strpos = 0;
40  return 0;
41  }
42 
43  /*
44  * the user buffer might not be big enough to hold the line.
45  */
46  if (strpos) {
47  nput = Tcl_DStringLength(&dstr) - strpos;
48  if (nput > n) {
49  /* chunk between first and last */
50  memcpy(ubuf, (strpos + Tcl_DStringValue(&dstr)), n);
51  strpos += n;
52  nput = n;
53  ubuf[n] = '\0';
54  } else {
55  /* last chunk */
56  memcpy(ubuf, (strpos + Tcl_DStringValue(&dstr)), nput);
57  strpos = 0;
58  }
59  } else {
60  Tcl_DStringFree(&dstr);
61  Tcl_DStringInit(&dstr);
62  if (Tcl_Gets((Tcl_Channel) channel, &dstr) < 0) {
63  /* probably EOF, but could be other read errors */
64  *ubuf = '\0';
65  return 0;
66  }
67  /* linend char(s) were stripped off by Tcl_Gets,
68  * append a canonical linenend. */
69  Tcl_DStringAppend(&dstr, "\n", 1);
70  if (Tcl_DStringLength(&dstr) > n) {
71  /* first chunk */
72  nput = n;
73  memcpy(ubuf, Tcl_DStringValue(&dstr), n);
74  strpos = n;
75  } else {
76  /* single chunk */
77  nput = Tcl_DStringLength(&dstr);
78  memcpy(ubuf, Tcl_DStringValue(&dstr),nput);
79  }
80  }
81  return nput;
82 }
83 
84 
85 /* exact copy from cgraph/io.c - but that one is static */
86 int myiodisc_memiofread(void *chan, char *buf, int bufsize)
87 {
88  const char *ptr;
89  char *optr;
90  char c;
91  int l;
92  rdr_t *s;
93 
94  if (bufsize == 0) return 0;
95  s = (rdr_t *) chan;
96  if (s->cur >= s->len)
97  return 0;
98  l = 0;
99  ptr = s->data + s->cur;
100  optr = buf;
101  do {
102  *optr++ = c = *ptr++;
103  l++;
104  } while (c && (c != '\n') && (l < bufsize));
105  s->cur += l;
106  return l;
107 }
108 
109 #if 0
110 Agraph_t *agread_usergets (ictx_t *ictx, FILE * fp, int (*usergets)(void *chan, char *buf, int bufsize))
111 {
112  Agraph_t* g;
113  Agiodisc_t ioDisc;
114 
115  ioDisc.afread = usergets;
116  ioDisc.putstr = AgIoDisc.putstr;
117  ioDisc.flush = AgIoDisc.flush;
118 
119  ictx->mydisc.io = &ioDisc;
120  g = agread (fp, (Agdisc_t *)ictx);
121  ictx->mydisc.io = &AgIoDisc; /* restore io */
122  return g;
123 }
124 
125 #endif
CGRAPH_API Agiodisc_t AgIoDisc
Definition: cgraph.h:199
int myiodisc_memiofread(void *chan, char *buf, int bufsize)
Definition: tcldot-io.c:86
Definition: tcldot.h:46
Definition: io.c:93
CGRAPH_API Agraph_t * agread(void *chan, Agdisc_t *disc)
Definition: grammar.c:2349
int len
Definition: io.c:95
int(* flush)(void *chan)
Definition: cgraph.h:185
int(* afread)(void *chan, char *buf, int bufsize)
Definition: cgraph.h:183
int cur
Definition: io.c:96
const char * data
Definition: io.c:94
Definition: grammar.c:79
Agraph_t * agread_usergets(ictx_t *ictx, FILE *fp, int(*usergets)(void *chan, char *buf, int bufsize))
int myiodisc_afread(void *channel, char *ubuf, int n)
Definition: tcldot-io.c:31
Agiodisc_t * io
Definition: cgraph.h:192
int(* putstr)(void *chan, const char *str)
Definition: cgraph.h:184
Agdisc_t mydisc
Definition: tcldot.h:47