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