summaryrefslogtreecommitdiff
path: root/lib/bio
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-10-04 02:51:57 -0700
committerOri Bernstein <ori@eigenstate.org>2015-10-04 02:51:57 -0700
commit35bde60621ecf5cbcf07b743cafd9724f87faccb (patch)
tree645c627fad5240bdeb4f979be874ce7255a855af /lib/bio
parent7264545dc13abc231f1f5b386619990caec195b4 (diff)
downloadmc-35bde60621ecf5cbcf07b743cafd9724f87faccb.tar.gz
Fix handling '\r\n' with libbio.
Diffstat (limited to 'lib/bio')
-rw-r--r--lib/bio/bio.myr35
-rw-r--r--lib/bio/test/bio-delim.myr12
-rw-r--r--lib/bio/test/data/bio-delim-expected2
-rw-r--r--lib/bio/test/data/lines3
4 files changed, 49 insertions, 3 deletions
diff --git a/lib/bio/bio.myr b/lib/bio/bio.myr
index 17b9508..a546152 100644
--- a/lib/bio/bio.myr
+++ b/lib/bio/bio.myr
@@ -370,9 +370,39 @@ const skipspace = {f
;;
}
-/* 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 @@ const readdelim = {f, delim, drop
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)
diff --git a/lib/bio/test/bio-delim.myr b/lib/bio/test/bio-delim.myr
index af9adf5..7bb0dcf 100644
--- a/lib/bio/test/bio-delim.myr
+++ b/lib/bio/test/bio-delim.myr
@@ -22,6 +22,18 @@ const main = {
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)
diff --git a/lib/bio/test/data/bio-delim-expected b/lib/bio/test/data/bio-delim-expected
index b90f595..b6f289e 100644
--- 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
diff --git a/lib/bio/test/data/lines b/lib/bio/test/data/lines
index 781db66..23b0c6e 100644
--- 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