From 97476a28d8aa0c1403d4ba4815f8f07a7caa7b4e Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Tue, 19 Apr 2016 19:02:18 -0700 Subject: Allow unlimited character pushback in unget-char. Fixing read_until_match will require this feature. * socket.c (dgram_get_char): Treat unget_c as a cons-based stack; pop a character from it if available. (dgram_unget_char): Push the character onto unget_c rather than storing the characer into unget_c. * stream.c (stdio_get_char, stdio_unget_char): Closely analogous changes to the ones in dgram_get_char and dgram_unget_char, respectively. * txr.1: Documentation improved and updated. --- socket.c | 15 ++++----------- stream.c | 15 +++++---------- txr.1 | 17 ++++++++++++++++- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/socket.c b/socket.c index 7cb119ae..102127b9 100644 --- a/socket.c +++ b/socket.c @@ -434,10 +434,9 @@ static int dgram_get_byte_callback(mem_t *ctx) static val dgram_get_char(val stream) { struct dgram_stream *d = coerce(struct dgram_stream *, stream->co.handle); - val uc = d->unget_c; - if (uc) { - d->unget_c = nil; - return uc; + + if (d->unget_c) { + return pop(&d->unget_c); } else { wint_t ch = utf8_decode(&d->ud, dgram_get_byte_callback, coerce(mem_t *, d)); @@ -455,13 +454,7 @@ static val dgram_get_byte(val stream) static val dgram_unget_char(val stream, val ch) { struct dgram_stream *d = coerce(struct dgram_stream *, stream->co.handle); - - if (d->unget_c){ - d->err = EOVERFLOW; - uw_throwf(file_error_s, lit("unget-char overflow on ~a: "), stream, nao); - } - - d->unget_c = ch; + mpush(ch, mkloc(d->unget_c, stream)); return ch; } diff --git a/stream.c b/stream.c index 6b234e22..24dc79d2 100644 --- a/stream.c +++ b/stream.c @@ -683,11 +683,10 @@ val generic_get_line(val stream) static val stdio_get_char(val stream) { struct stdio_handle *h = coerce(struct stdio_handle *, stream->co.handle); - val uc = h->unget_c; - if (uc) { - h->unget_c = nil; - return uc; - } + + if (h->unget_c) + return pop(&h->unget_c); + if (h->f) { wint_t ch = utf8_decode(&h->ud, stdio_get_char_callback, coerce(mem_t *, h->f)); @@ -709,11 +708,7 @@ static val stdio_get_byte(val stream) static val stdio_unget_char(val stream, val ch) { struct stdio_handle *h = coerce(struct stdio_handle *, stream->co.handle); - - if (h->unget_c) - uw_throwf(file_error_s, lit("unget-char overflow on ~a: "), stream, nao); - - h->unget_c = ch; + mpush(ch, mkloc(h->unget_c, stream)); return ch; } diff --git a/txr.1 b/txr.1 index 7a1d5b05..c07ca2c8 100644 --- a/txr.1 +++ b/txr.1 @@ -34230,7 +34230,18 @@ and likewise for and .codn unget-byte . -Space is available for only one character or byte of pushback. +Streams may require a pushed back byte or character to match +the character which was previously read from that stream +position, and may not allow a byte or character to be pushed +back beyond the beginning of the stream. + +Space may be available for only one byte of pushback under the +.code unget-byte +operation. + +The number of characters that may be pushed back by +.code unget-char +is not limited. Pushing both a byte and a character, in either order, is also unsupported. Pushing a byte and then reading a character, or pushing a character and @@ -34240,6 +34251,10 @@ If the stream is binary, then pushing back a byte decrements its position, except if the position is already zero. At that point, the position becomes indeterminate. +The behavior of pushing back immediately after a +.code seek-stream +positioning operation is unspecified. + .coNP Functions @, put-string @, put-line @ put-char and @ put-byte .synb .mets (put-string < string <> [ stream ]) -- cgit v1.2.3