Although bio(2) says:
Bungetc and Bungetrune may back up a maximum of five bytes.
I’ve found that Bungetrune is idempotent.
The code in question is from my lexer (switching on the return value from
Bgetrune):
case 'l': case 'L':
switch(Bgetrune(bin)) {
case '\'':
return charlex(1);
case '"':
return strlex(1);
default:
Bungetrune(bin);
}
// fall through
case 'a': case 'b': case 'c': case 'd': case
'e':
case 'f': case 'g': case 'h': case 'i': case
'j':
case 'k': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case
't':
case 'u': case 'v': case 'w': case 'x': case
'y':
case 'z':
case 'A': case 'B': case 'C': case 'D': case
'E':
case 'F': case 'G': case 'H': case 'I': case
'J':
case 'K': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case
'T':
case 'U': case 'V': case 'W': case 'X': case
'Y':
case 'Z':
case '_':
Bungetrune(bin);
return idlex();
This doesn’t work; identifiers beginning with ‘l’ lose their initial character.
>From a cursory reading of /sys/src/libbio/bgetc.c and
/sys/src/libbio/bgetrune.c, it seems that Bungetc will allow itself to
be called more than once where Bungetrune sets a condition to prevent
that (bp->runesize = 0;). (Actually, it seems that there is no
hard-coded limit to how many times Bungetc can be called. Will
arbitrary back-up work, or will something break deep within the Biobuf
if I abuse it?)
For this case anyway, where I know that the Rune read was a
single-byte character, is it safe to use Bungetc, and will that allow
me to back-up more than once? I need (I think) three bytes of
back-up.
--Joel