xref: /plan9/sys/src/ape/lib/ap/stdio/_IO_putc.c (revision 3e12c5d1bb89fc02707907988834ef147769ddaf)
1 /*
2  * pANS stdio -- _IO_putc, _IO_cleanup
3  */
4 #include "iolib.h"
5 
_IO_cleanup(void)6 void _IO_cleanup(void){
7 	fflush(NULL);
8 }
9 /*
10  * Look this over for simplification
11  */
_IO_putc(int c,FILE * f)12 int _IO_putc(int c, FILE *f){
13 	int cnt;
14 	static int first=1;
15 	switch(f->state){
16 	case RD:
17 		f->state=ERR;
18 	case ERR:
19 	case CLOSED:
20 		return EOF;
21 	case OPEN:
22 		_IO_setvbuf(f);
23 		/* fall through */
24 	case RDWR:
25 	case END:
26 		f->rp=f->buf+f->bufl;
27 		if(f->flags&LINEBUF){
28 			f->wp=f->rp;
29 			f->lp=f->buf;
30 		}
31 		else
32 			f->wp=f->buf;
33 		break;
34 	}
35 	if(first){
36 		atexit(_IO_cleanup);
37 		first=0;
38 	}
39 	if(f->flags&STRING){
40 		f->rp=f->buf+f->bufl;
41 		if(f->wp==f->rp){
42 			if(f->flags&BALLOC)
43 				f->buf=realloc(f->buf, f->bufl+BUFSIZ);
44 			else{
45 				f->state=ERR;
46 				return EOF;
47 			}
48 			if(f->buf==NULL){
49 				f->state=ERR;
50 				return EOF;
51 			}
52 			f->rp=f->buf+f->bufl;
53 			f->bufl+=BUFSIZ;
54 		}
55 		*f->wp++=c;
56 	}
57 	else if(f->flags&LINEBUF){
58 		if(f->lp==f->rp){
59 			cnt=f->lp-f->buf;
60 			if(f->flags&APPEND) lseek(f->fd, 0L, SEEK_END);
61 			if(cnt!=0 && write(f->fd, f->buf, cnt)!=cnt){
62 				f->state=ERR;
63 				return EOF;
64 			}
65 			f->lp=f->buf;
66 		}
67 		*f->lp++=c;
68 		if(c=='\n'){
69 			cnt=f->lp-f->buf;
70 			if(f->flags&APPEND) lseek(f->fd, 0L, SEEK_END);
71 			if(cnt!=0 && write(f->fd, f->buf, cnt)!=cnt){
72 				f->state=ERR;
73 				return EOF;
74 			}
75 			f->lp=f->buf;
76 		}
77 	}
78 	else if(f->buf==f->unbuf){
79 		f->unbuf[0]=c;
80 		if(f->flags&APPEND) lseek(f->fd, 0L, SEEK_END);
81 		if(write(f->fd, f->buf, 1)!=1){
82 			f->state=ERR;
83 			return EOF;
84 		}
85 	}
86 	else{
87 		if(f->wp==f->rp){
88 			cnt=f->wp-f->buf;
89 			if(f->flags&APPEND) lseek(f->fd, 0L, SEEK_END);
90 			if(cnt!=0 && write(f->fd, f->buf, cnt)!=cnt){
91 				f->state=ERR;
92 				return EOF;
93 			}
94 			f->wp=f->buf;
95 			f->rp=f->buf+f->bufl;
96 		}
97 		*f->wp++=c;
98 	}
99 	f->state=WR;
100 	/*
101 	 * Make sure EOF looks different from putc(-1)
102 	 * Should be able to cast to unsigned char, but
103 	 * there's a vc bug preventing that from working
104 	 */
105 	return c&0xff;
106 }
107