wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

brdstr.c (2106B)


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