ref: 35bde60621ecf5cbcf07b743cafd9724f87faccb
parent: 7264545dc13abc231f1f5b386619990caec195b4
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Oct 3 22:51:57 EDT 2015
Fix handling '\r\n' with libbio.
--- /dev/null
+++ b/.gitattributes
@@ -1,0 +1,1 @@
+lib/bio/test/data/bio-delim-expected binary
--- a/lib/bio/bio.myr
+++ b/lib/bio/bio.myr
@@ -370,9 +370,39 @@
;;
}
-/* Same as readto, but the delimiter is always a '\n' */
+/* Same as delim, but with special handling for '\n', '\r', and '\r\n' */
const readln = {f
- -> readto(f, "\n")
+ var ret, c, n
+
+ ret = [][:]
+ while true
+ /* get at least delimiter count of characters */
+ if !ensureread(f, 1)
+ ret = readinto(f, ret, f.rend - f.rstart)
+ if ret.len > 0
+ -> `std.Some ret
+ else
+ -> `std.None
+ ;;
+ ;;
+ /* scan for delimiter */
+ for var i = f.rstart; i < f.rend; i++
+ c = f.rbuf[i] castto(char)
+ if c == '\r' || c == '\n'
+ n = 1
+ /* if we have '\r', we can get '\r\n'. */
+ if c == '\r' && std.getv(peekc(f), -1) == '\n'
+ n = 2
+ ;;
+ ret = readinto(f, ret, i - f.rstart)
+ f.rstart += n
+ -> `std.Some ret
+ ;;
+:nextitergetln
+ ;;
+ ret = readinto(f, ret, f.rend - f.rstart)
+ ;;
+ std.die("unreachable")
}
const readdelim = {f, delim, drop
@@ -380,6 +410,7 @@
ret = [][:]
while true
+ /* get at least delimiter count of characters */
if !ensureread(f, delim.len)
if !drop
ret = readinto(f, ret, f.rend - f.rstart)
--- a/lib/bio/test/bio-delim.myr
+++ b/lib/bio/test/bio-delim.myr
@@ -22,6 +22,18 @@
std.write(1, "\n")
std.slfree(d)
+ /* read second line, should not include \r\n */
+ d = readln(f)
+ std.write(1, d)
+ std.write(1, "\n")
+ std.slfree(d)
+
+ /* read second line, should not include \r */
+ d = readln(f)
+ std.write(1, d)
+ std.write(1, "\n")
+ std.slfree(d)
+
/* read to ';' */
d = readto(f, ";")
std.write(1, d)
--- a/lib/bio/test/data/bio-delim-expected
+++ b/lib/bio/test/data/bio-delim-expected
@@ -1,5 +1,7 @@
first line
second line
+with-\r\n
+with-\r
data with
semicolons
--- a/lib/bio/test/data/lines
+++ b/lib/bio/test/data/lines
@@ -1,4 +1,5 @@
first line
second line
-data with;semicolons;
+with-\r\n
+with-\r data with;semicolons;
and--no-terminator