summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-12-06 15:54:59 -0800
committerKaz Kylheku <kaz@kylheku.com>2011-12-06 15:54:59 -0800
commitd12fd4bf61209806c780031d81e0b142e147e815 (patch)
tree5efcd5a796c10220cd645027db699963d19e17ab
parent6f051c69587d159cafbb6bcf79ba245e8ca0d6c0 (diff)
downloadtxr-d12fd4bf61209806c780031d81e0b142e147e815.tar.gz
txr-d12fd4bf61209806c780031d81e0b142e147e815.tar.bz2
txr-d12fd4bf61209806c780031d81e0b142e147e815.zip
* stream.c (find_char): New function.
(string_in_get_line): Following up TODO. Fixed broken function. Now get_line on a string stream properly returns characters up to and not including the next newlne character, and also consumes the newline character. Other cases are handled properly, also: the stream being at EOF already, or at the last line not being newline-terminated.
-rw-r--r--ChangeLog10
-rw-r--r--stream.c21
2 files changed, 28 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 78d206ff..1fcfd10c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2011-12-06 Kaz Kylheku <kaz@kylheku.com>
+ * stream.c (find_char): New function.
+ (string_in_get_line): Following up TODO. Fixed broken
+ function. Now get_line on a string stream properly returns characters
+ up to and not including the next newlne character, and also consumes
+ the newline character. Other cases are handled properly, also:
+ the stream being at EOF already, or at the last line not being
+ newline-terminated.
+
+2011-12-06 Kaz Kylheku <kaz@kylheku.com>
+
* eval.c (op_unwind_protect): Fixed uninitialized variable
warning.
(eval_init): New functions registered: typeof and vector functions,
diff --git a/stream.c b/stream.c
index be638608..a7ddbb66 100644
--- a/stream.c
+++ b/stream.c
@@ -306,16 +306,31 @@ static void string_in_stream_mark(val stream)
gc_mark(stuff);
}
+static val find_char(val string, val start, val ch)
+{
+ const wchar_t *str = c_str(string);
+ cnum pos = c_num(start);
+ cnum len = c_num(length_str(string));
+ wchar_t c = c_chr(ch);
+
+ for (; pos < len; pos++) {
+ if (str[pos] == c)
+ return num(pos);
+ }
+
+ return nil;
+}
+
static val string_in_get_line(val stream)
{
val pair = (val) stream->co.handle;
val string = car(pair);
val pos = cdr(pair);
- /* TODO: broken, should only scan to newline */
if (lt(pos, length_str(string))) {
- val result = sub_str(string, pos, nil);
- *cdr_l(pair) = length_str(string);
+ val nlpos = find_char(string, pos, chr('\n'));
+ val result = sub_str(string, pos, nlpos);
+ *cdr_l(pair) = nlpos ? plus(nlpos, one) : length_str(string);
return result;
}