xref: /plan9/sys/src/libbio/bgetrune.c (revision eaba85aa6b158bdf68fdb77f770e3ba0899a8b5e)
13e12c5d1SDavid du Colombier #include	<u.h>
23e12c5d1SDavid du Colombier #include	<libc.h>
33e12c5d1SDavid du Colombier #include	<bio.h>
43e12c5d1SDavid du Colombier 
53e12c5d1SDavid du Colombier long
Bgetrune(Biobufhdr * bp)63e12c5d1SDavid du Colombier Bgetrune(Biobufhdr *bp)
73e12c5d1SDavid du Colombier {
83e12c5d1SDavid du Colombier 	int c, i;
93e12c5d1SDavid du Colombier 	Rune rune;
10*eaba85aaSDavid du Colombier 	char str[UTFmax];
113e12c5d1SDavid du Colombier 
123e12c5d1SDavid du Colombier 	c = Bgetc(bp);
133e12c5d1SDavid du Colombier 	if(c < Runeself) {		/* one char */
143e12c5d1SDavid du Colombier 		bp->runesize = 1;
153e12c5d1SDavid du Colombier 		return c;
163e12c5d1SDavid du Colombier 	}
173e12c5d1SDavid du Colombier 	str[0] = c;
18*eaba85aaSDavid du Colombier 	bp->runesize = 0;
193e12c5d1SDavid du Colombier 
203e12c5d1SDavid du Colombier 	for(i=1;;) {
213e12c5d1SDavid du Colombier 		c = Bgetc(bp);
223e12c5d1SDavid du Colombier 		if(c < 0)
233e12c5d1SDavid du Colombier 			return c;
24*eaba85aaSDavid du Colombier 		if (i >= sizeof str)
25*eaba85aaSDavid du Colombier 			return Runeerror;
263e12c5d1SDavid du Colombier 		str[i++] = c;
273e12c5d1SDavid du Colombier 
283e12c5d1SDavid du Colombier 		if(fullrune(str, i)) {
29*eaba85aaSDavid du Colombier 			/* utf is long enough to be a rune, but could be bad. */
30219b2ee8SDavid du Colombier 			bp->runesize = chartorune(&rune, str);
31*eaba85aaSDavid du Colombier 			if (rune == Runeerror)
32*eaba85aaSDavid du Colombier 				bp->runesize = 0;	/* push back nothing */
33*eaba85aaSDavid du Colombier 			else
34*eaba85aaSDavid du Colombier 				/* push back bytes unconsumed by chartorune */
35*eaba85aaSDavid du Colombier 				for(; i > bp->runesize; i--)
36219b2ee8SDavid du Colombier 					Bungetc(bp);
373e12c5d1SDavid du Colombier 			return rune;
383e12c5d1SDavid du Colombier 		}
393e12c5d1SDavid du Colombier 	}
403e12c5d1SDavid du Colombier }
413e12c5d1SDavid du Colombier 
423e12c5d1SDavid du Colombier int
Bungetrune(Biobufhdr * bp)433e12c5d1SDavid du Colombier Bungetrune(Biobufhdr *bp)
443e12c5d1SDavid du Colombier {
453e12c5d1SDavid du Colombier 
463e12c5d1SDavid du Colombier 	if(bp->state == Bracteof)
473e12c5d1SDavid du Colombier 		bp->state = Bractive;
483e12c5d1SDavid du Colombier 	if(bp->state != Bractive)
493e12c5d1SDavid du Colombier 		return Beof;
503e12c5d1SDavid du Colombier 	bp->icount -= bp->runesize;
513e12c5d1SDavid du Colombier 	bp->runesize = 0;
523e12c5d1SDavid du Colombier 	return 1;
533e12c5d1SDavid du Colombier }
54