summaryrefslogtreecommitdiff
path: root/libstd
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-04-20 20:27:37 -0700
committerOri Bernstein <ori@eigenstate.org>2015-04-20 20:27:37 -0700
commit3f5c8ac0d8e012fe3385b8dba39ac5d8d554a4c2 (patch)
tree9b765e33439e2f75cb8c1c70698958c67c38331c /libstd
parent1044e6f057ce380ec514738996693d762d59c3f8 (diff)
downloadmc-3f5c8ac0d8e012fe3385b8dba39ac5d8d554a4c2.tar.gz
Add support for fixed size str buffers.
Diffstat (limited to 'libstd')
-rw-r--r--libstd/strbuf.myr50
-rw-r--r--libstd/test/strbuf.myr16
2 files changed, 51 insertions, 15 deletions
diff --git a/libstd/strbuf.myr b/libstd/strbuf.myr
index 88e24ec..beca30e 100644
--- a/libstd/strbuf.myr
+++ b/libstd/strbuf.myr
@@ -14,6 +14,7 @@ pkg std =
;;
const mksb : (-> strbuf#)
+ const mkbufsb : (buf : byte[:] -> strbuf#)
const sbfin : (sb : strbuf# -> byte[:])
const sbfree : (sb : strbuf# -> void)
const sbpeek : (sb : strbuf# -> byte[:])
@@ -21,24 +22,40 @@ pkg std =
const sbputc : (sb : strbuf#, v : char -> bool)
const sbputs : (sb : strbuf#, v : byte[:] -> bool)
const sbputb : (sb : strbuf#, v : byte -> bool)
- const sbtrim : (sb : strbuf#, len : std.size -> void)
+ const sbtrim : (sb : strbuf#, len : size -> void)
;;
-const mksb = {
+const mksb = {
var sb
- sb = std.zalloc()
- sb.buf = std.slalloc(1)
+ sb = zalloc()
+ sb.buf = slalloc(1)
-> sb
}
-const sbfin = {sb : strbuf#
+const mkbufsb = {buf
+ var sb
+ sb = zalloc()
+ sb.buf = buf
+ sb.fixed = true
+ -> sb
+}
+
+const sbfin = {sb
var sl
sl = sb.buf[:sb.len]
- std.free(sb)
+ free(sb)
-> sl
}
+const sbfree = {sb
+ if !sb.fixed
+ slfree(sb.buf)
+ ;;
+ free(sb)
+}
+
+
const sbpeek = {sb : strbuf#
-> sb.buf[:sb.len]
}
@@ -51,12 +68,15 @@ const sbputc = {sb, v
-> true
}
const sbputs = {sb, v
- if !ensure(sb, v.len)
- -> false
- ;;
- std.slcp(sb.buf[sb.len:sb.len + v.len], v)
- sb.len += v.len
- -> true
+ var ok
+ var len
+
+ ok = ensure(sb, v.len)
+ /* copy what we can */
+ len = min(sb.buf.len - sb.len, v.len)
+ slcp(sb.buf[sb.len:sb.len + len], v[:len])
+ sb.len += len
+ -> ok
}
const sbputb = {sb, v
if !ensure(sb, 1)
@@ -67,16 +87,16 @@ const sbputb = {sb, v
}
const sbtrim = {sb, len
- std.assert(std.abs(len) <= sb.len, "trim out of range\n")
+ assert(abs(len) <= sb.len, "trim out of range\n")
if len < 0
- sb.len -= std.abs(len)
+ sb.len -= abs(len)
else
sb.len = len
;;
}
const ensure = {sb, len
- if sb.fixed && sb.len + len >= sb.buf.len
+ if sb.fixed && sb.len + len > sb.buf.len
-> false
;;
while sb.buf.len < sb.len + len
diff --git a/libstd/test/strbuf.myr b/libstd/test/strbuf.myr
index 92c5a7c..2643da5 100644
--- a/libstd/test/strbuf.myr
+++ b/libstd/test/strbuf.myr
@@ -2,6 +2,7 @@ use std
const main = {
var sb
+ var buf : byte[16]
sb = std.mksb()
std.assert(std.sleq(std.sbpeek(sb), ""), "mismatched empty str\n")
@@ -20,5 +21,20 @@ const main = {
std.assert(std.sleq(std.sbpeek(sb), "hello, 世界"), "mismatched unicode\n")
std.sbputb(sb, 10)
std.assert(std.sleq(std.sbpeek(sb), "hello, 世界\n"), "mismatched byte\n")
+
+ sb = std.mkbufsb(buf[:])
+ std.assert(std.sbputs(sb, "hello"), "failed to add hello\n") /* 5 characters */
+ std.assert(std.sbputs(sb, "hello"), "failed to add hello\n") /* 10 characters */
+ std.assert(std.sbputs(sb, "hello"), "failed to add hello\n") /* 15 characters */
+ std.assert(!std.sbputs(sb, "hello"), "erronous success\n") /* 16 characters */
+ std.assert(std.sleq(std.sbpeek(sb), "hellohellohelloh"), "failed to copy as much as possible\n")
+ std.sbtrim(sb, -1)
+ std.assert(std.sleq(std.sbpeek(sb), "hellohellohello"), "failed rtrim\n")
+ std.sbputc(sb, '世')
+ std.assert(std.sleq(std.sbpeek(sb), "hellohellohello"), "modified overflowed putc\n")
+ std.sbtrim(sb, -2)
+ std.assert(std.sleq(std.sbpeek(sb), "hellohellohel"), "failed rtrim\n")
+ std.sbputc(sb, '世')
+ std.assert(std.sleq(std.sbpeek(sb), "hellohellohel世"), "failed to append with putc\n")
}