summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-03-05 07:06:13 -0800
committerKaz Kylheku <kaz@kylheku.com>2016-03-05 07:06:13 -0800
commit68cf1642e9b1d0ae04f6bdeb6b7c8a2fd5ac5e9e (patch)
tree5ab65bf9e41d987a1118354d85fa19a8772e0be4
parente66d53a35c7b59f46e31451da90b306a9beeacc6 (diff)
downloadtxr-68cf1642e9b1d0ae04f6bdeb6b7c8a2fd5ac5e9e.tar.gz
txr-68cf1642e9b1d0ae04f6bdeb6b7c8a2fd5ac5e9e.tar.bz2
txr-68cf1642e9b1d0ae04f6bdeb6b7c8a2fd5ac5e9e.zip
Replace stdio_get_line with generic routine.
* stream.c (snarf_line): Function renamed to generic_get_line. Interface and implementation changed so it can be used directly as get_line virtual. (stdio_get_line): Function removed. (stdio_ops, pipe_ops): Point get_line to generic_get_line. (tail_get_line): Call generic_get_line instead of stdio_get_line.
-rw-r--r--stream.c48
1 files changed, 23 insertions, 25 deletions
diff --git a/stream.c b/stream.c
index 6e23d0f7..e1cc7c58 100644
--- a/stream.c
+++ b/stream.c
@@ -588,22 +588,20 @@ static val stdio_clear_error(val stream)
return ret;
}
-static wchar_t *snarf_line(struct stdio_handle *h)
+static val generic_get_line(val stream)
{
+ struct strm_ops *ops = coerce(struct strm_ops *, cobj_ops(stream, stream_s));
const size_t min_size = 512;
size_t size = 0;
size_t fill = 0;
wchar_t *buf = 0;
+ val out = nil;
- for (;;) {
- wint_t ch;
+ uw_simple_catch_begin;
- if (h->unget_c) {
- ch = c_chr(h->unget_c);
- h->unget_c = nil;
- } else {
- ch = utf8_decode(&h->ud, stdio_get_char_callback, coerce(mem_t *, h->f));
- }
+ for (;;) {
+ val chr = ops->get_char(stream);
+ wint_t ch = chr ? c_chr(chr) : WEOF;
if (ch == WEOF && buf == 0)
break;
@@ -623,23 +621,23 @@ static wchar_t *snarf_line(struct stdio_handle *h)
}
/* Trim to actual size */
- if (buf)
- buf = coerce(wchar_t *, chk_realloc(coerce(mem_t *, buf),
- fill * sizeof *buf));
+ if (buf) {
+ wchar_t *sbuf = coerce(wchar_t *, chk_realloc(coerce(mem_t *, buf),
+ fill * sizeof *buf));
+ if (sbuf)
+ buf = sbuf;
- return buf;
-}
+ out = string_own(buf);
+ buf = 0;
+ }
-static val stdio_get_line(val stream)
-{
- struct stdio_handle *h = coerce(struct stdio_handle *, stream->co.handle);
- if (h->f) {
- wchar_t *line = snarf_line(h);
- if (line)
- return string_own(line);
+ uw_unwind {
+ free(buf);
}
- return stdio_maybe_read_error(stream);
+ uw_catch_end;
+
+ return out;
}
static val stdio_get_char(val stream)
@@ -770,7 +768,7 @@ static struct strm_ops stdio_ops =
stdio_put_string,
stdio_put_char,
stdio_put_byte,
- stdio_get_line,
+ generic_get_line,
stdio_get_char,
stdio_get_byte,
stdio_unget_char,
@@ -919,7 +917,7 @@ static val tail_get_line(val stream)
unsigned long state = 0;
val ret;
- while ((ret = stdio_get_line(stream)) == nil)
+ while ((ret = generic_get_line(stream)) == nil)
tail_strategy(stream, &state);
return ret;
@@ -1051,7 +1049,7 @@ static struct strm_ops pipe_ops =
stdio_put_string,
stdio_put_char,
stdio_put_byte,
- stdio_get_line,
+ generic_get_line,
stdio_get_char,
stdio_get_byte,
stdio_unget_char,