1*3e12c5d1SDavid du Colombier /*
2*3e12c5d1SDavid du Colombier * pANS stdio -- rdline
3*3e12c5d1SDavid du Colombier * This is not a pANS routine.
4*3e12c5d1SDavid du Colombier */
5*3e12c5d1SDavid du Colombier #include "iolib.h"
6*3e12c5d1SDavid du Colombier #include <string.h>
7*3e12c5d1SDavid du Colombier
rdline(FILE * f,char ** ep)8*3e12c5d1SDavid du Colombier char *rdline(FILE *f, char **ep){
9*3e12c5d1SDavid du Colombier int cnt;
10*3e12c5d1SDavid du Colombier char *nlp, *vp;
11*3e12c5d1SDavid du Colombier switch(f->state){
12*3e12c5d1SDavid du Colombier default: /* CLOSED, WR, ERR, EOF */
13*3e12c5d1SDavid du Colombier return NULL;
14*3e12c5d1SDavid du Colombier case OPEN:
15*3e12c5d1SDavid du Colombier _IO_setvbuf(f);
16*3e12c5d1SDavid du Colombier case RDWR:
17*3e12c5d1SDavid du Colombier f->state=RD;
18*3e12c5d1SDavid du Colombier case RD:
19*3e12c5d1SDavid du Colombier if(f->bufl==0){ /* Called by a comedian! */
20*3e12c5d1SDavid du Colombier f->state=ERR;
21*3e12c5d1SDavid du Colombier return NULL;
22*3e12c5d1SDavid du Colombier }
23*3e12c5d1SDavid du Colombier vp=f->rp;
24*3e12c5d1SDavid du Colombier for(;;){
25*3e12c5d1SDavid du Colombier /*
26*3e12c5d1SDavid du Colombier * Look for a newline.
27*3e12c5d1SDavid du Colombier * If none found, slide the partial line to the beginning
28*3e12c5d1SDavid du Colombier * of the buffer, read some more and keep looking.
29*3e12c5d1SDavid du Colombier */
30*3e12c5d1SDavid du Colombier nlp=memchr(f->rp, '\n', f->wp-f->rp);
31*3e12c5d1SDavid du Colombier if(nlp!=0) break;
32*3e12c5d1SDavid du Colombier if(f->flags&STRING){
33*3e12c5d1SDavid du Colombier f->rp=f->wp;
34*3e12c5d1SDavid du Colombier if(ep) *ep=f->wp;
35*3e12c5d1SDavid du Colombier return vp;
36*3e12c5d1SDavid du Colombier }
37*3e12c5d1SDavid du Colombier if(f->rp!=f->buf){
38*3e12c5d1SDavid du Colombier memmove(f->buf, f->rp, f->wp-f->rp);
39*3e12c5d1SDavid du Colombier f->wp-=f->rp-f->buf;
40*3e12c5d1SDavid du Colombier f->rp=f->buf;
41*3e12c5d1SDavid du Colombier vp=f->rp;
42*3e12c5d1SDavid du Colombier }
43*3e12c5d1SDavid du Colombier cnt=f->bufl-(f->wp-f->buf);
44*3e12c5d1SDavid du Colombier if(cnt==0){ /* no room left */
45*3e12c5d1SDavid du Colombier nlp=f->wp-1;
46*3e12c5d1SDavid du Colombier break;
47*3e12c5d1SDavid du Colombier }
48*3e12c5d1SDavid du Colombier cnt=read(f->fd, f->wp, cnt);
49*3e12c5d1SDavid du Colombier if(cnt==-1){
50*3e12c5d1SDavid du Colombier f->state=ERR;
51*3e12c5d1SDavid du Colombier return NULL;
52*3e12c5d1SDavid du Colombier }
53*3e12c5d1SDavid du Colombier if(cnt==0){ /* is this ok? */
54*3e12c5d1SDavid du Colombier f->state=EOF;
55*3e12c5d1SDavid du Colombier return NULL;
56*3e12c5d1SDavid du Colombier }
57*3e12c5d1SDavid du Colombier f->rp=f->wp;
58*3e12c5d1SDavid du Colombier f->wp+=cnt;
59*3e12c5d1SDavid du Colombier }
60*3e12c5d1SDavid du Colombier *nlp='\0';
61*3e12c5d1SDavid du Colombier f->rp=nlp+1;
62*3e12c5d1SDavid du Colombier if(ep) *ep=nlp;
63*3e12c5d1SDavid du Colombier return vp;
64*3e12c5d1SDavid du Colombier }
65*3e12c5d1SDavid du Colombier }
66