1*72335078SCharles Forsyth #include "lib9.h"
2*72335078SCharles Forsyth #include <bio.h>
3*72335078SCharles Forsyth
4*72335078SCharles Forsyth static char*
badd(char * p,int * np,char * data,int ndata,int delim,int nulldelim)5*72335078SCharles Forsyth badd(char *p, int *np, char *data, int ndata, int delim, int nulldelim)
6*72335078SCharles Forsyth {
7*72335078SCharles Forsyth int n;
8*72335078SCharles Forsyth
9*72335078SCharles Forsyth n = *np;
10*72335078SCharles Forsyth p = realloc(p, n+ndata+1);
11*72335078SCharles Forsyth if(p){
12*72335078SCharles Forsyth memmove(p+n, data, ndata);
13*72335078SCharles Forsyth n += ndata;
14*72335078SCharles Forsyth if(n>0 && nulldelim && p[n-1]==delim)
15*72335078SCharles Forsyth p[--n] = '\0';
16*72335078SCharles Forsyth else
17*72335078SCharles Forsyth p[n] = '\0';
18*72335078SCharles Forsyth *np = n;
19*72335078SCharles Forsyth }
20*72335078SCharles Forsyth return p;
21*72335078SCharles Forsyth }
22*72335078SCharles Forsyth
23*72335078SCharles Forsyth char*
Brdstr(Biobuf * bp,int delim,int nulldelim)24*72335078SCharles Forsyth Brdstr(Biobuf *bp, int delim, int nulldelim)
25*72335078SCharles Forsyth {
26*72335078SCharles Forsyth char *ip, *ep, *p;
27*72335078SCharles Forsyth int i, j;
28*72335078SCharles Forsyth
29*72335078SCharles Forsyth i = -bp->icount;
30*72335078SCharles Forsyth bp->rdline = 0;
31*72335078SCharles Forsyth if(i == 0) {
32*72335078SCharles Forsyth /*
33*72335078SCharles Forsyth * eof or other error
34*72335078SCharles Forsyth */
35*72335078SCharles Forsyth if(bp->state != Bractive) {
36*72335078SCharles Forsyth if(bp->state == Bracteof)
37*72335078SCharles Forsyth bp->state = Bractive;
38*72335078SCharles Forsyth bp->gbuf = bp->ebuf;
39*72335078SCharles Forsyth return nil;
40*72335078SCharles Forsyth }
41*72335078SCharles Forsyth }
42*72335078SCharles Forsyth
43*72335078SCharles Forsyth /*
44*72335078SCharles Forsyth * first try in remainder of buffer (gbuf doesn't change)
45*72335078SCharles Forsyth */
46*72335078SCharles Forsyth ip = (char*)bp->ebuf - i;
47*72335078SCharles Forsyth ep = memchr(ip, delim, i);
48*72335078SCharles Forsyth if(ep) {
49*72335078SCharles Forsyth j = (ep - ip) + 1;
50*72335078SCharles Forsyth bp->icount += j;
51*72335078SCharles Forsyth return badd(nil, &bp->rdline, ip, j, delim, nulldelim);
52*72335078SCharles Forsyth }
53*72335078SCharles Forsyth
54*72335078SCharles Forsyth /*
55*72335078SCharles Forsyth * copy data to beginning of buffer
56*72335078SCharles Forsyth */
57*72335078SCharles Forsyth if(i < bp->bsize)
58*72335078SCharles Forsyth memmove(bp->bbuf, ip, i);
59*72335078SCharles Forsyth bp->gbuf = bp->bbuf;
60*72335078SCharles Forsyth
61*72335078SCharles Forsyth /*
62*72335078SCharles Forsyth * append to buffer looking for the delim
63*72335078SCharles Forsyth */
64*72335078SCharles Forsyth p = nil;
65*72335078SCharles Forsyth for(;;){
66*72335078SCharles Forsyth ip = (char*)bp->bbuf + i;
67*72335078SCharles Forsyth while(i < bp->bsize) {
68*72335078SCharles Forsyth j = read(bp->fid, ip, bp->bsize-i);
69*72335078SCharles Forsyth if(j <= 0 && i == 0)
70*72335078SCharles Forsyth return p;
71*72335078SCharles Forsyth if(j <= 0 && i > 0){
72*72335078SCharles Forsyth /*
73*72335078SCharles Forsyth * end of file but no delim. pretend we got a delim
74*72335078SCharles Forsyth * by making the delim \0 and smashing it with nulldelim.
75*72335078SCharles Forsyth */
76*72335078SCharles Forsyth j = 1;
77*72335078SCharles Forsyth ep = ip;
78*72335078SCharles Forsyth delim = '\0';
79*72335078SCharles Forsyth nulldelim = 1;
80*72335078SCharles Forsyth *ep = delim; /* there will be room for this */
81*72335078SCharles Forsyth }else{
82*72335078SCharles Forsyth bp->offset += j;
83*72335078SCharles Forsyth ep = memchr(ip, delim, j);
84*72335078SCharles Forsyth }
85*72335078SCharles Forsyth i += j;
86*72335078SCharles Forsyth if(ep) {
87*72335078SCharles Forsyth /*
88*72335078SCharles Forsyth * found in new piece
89*72335078SCharles Forsyth * copy back up and reset everything
90*72335078SCharles Forsyth */
91*72335078SCharles Forsyth ip = (char*)bp->ebuf - i;
92*72335078SCharles Forsyth if(i < bp->bsize){
93*72335078SCharles Forsyth memmove(ip, bp->bbuf, i);
94*72335078SCharles Forsyth bp->gbuf = (uchar*)ip;
95*72335078SCharles Forsyth }
96*72335078SCharles Forsyth j = (ep - (char*)bp->bbuf) + 1;
97*72335078SCharles Forsyth bp->icount = j - i;
98*72335078SCharles Forsyth return badd(p, &bp->rdline, ip, j, delim, nulldelim);
99*72335078SCharles Forsyth }
100*72335078SCharles Forsyth ip += j;
101*72335078SCharles Forsyth }
102*72335078SCharles Forsyth
103*72335078SCharles Forsyth /*
104*72335078SCharles Forsyth * full buffer without finding; add to user string and continue
105*72335078SCharles Forsyth */
106*72335078SCharles Forsyth p = badd(p, &bp->rdline, (char*)bp->bbuf, bp->bsize, 0, 0);
107*72335078SCharles Forsyth i = 0;
108*72335078SCharles Forsyth bp->icount = 0;
109*72335078SCharles Forsyth bp->gbuf = bp->ebuf;
110*72335078SCharles Forsyth }
111*72335078SCharles Forsyth }
112