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