summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-06-11 19:47:32 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-06-11 19:47:32 -0700
commitc54df81f05e622bd3ce6daa0bc4ba5d3999f958d (patch)
treeb926c2b5cab254dcb3d783bd3fcb50afa79ec6b3
parent2ec0f6e63f9c42750f09af4a7f03be832a2ca28a (diff)
downloadtxr-c54df81f05e622bd3ce6daa0bc4ba5d3999f958d.tar.gz
txr-c54df81f05e622bd3ce6daa0bc4ba5d3999f958d.tar.bz2
txr-c54df81f05e622bd3ce6daa0bc4ba5d3999f958d.zip
buffers: allow sub operation.
* buf.c (sub_buf): New function. * buf.h (sub_buf): Declared. * lib.c (sub): Hook in BUF type. (replace): Diagnose BUF specially as unsupported.
-rw-r--r--buf.c32
-rw-r--r--buf.h1
-rw-r--r--lib.c8
3 files changed, 40 insertions, 1 deletions
diff --git a/buf.c b/buf.c
index 5e5a5d66..06fb0abf 100644
--- a/buf.c
+++ b/buf.c
@@ -239,6 +239,38 @@ void buf_fill(val buf, mem_t *src, val self)
memcpy(b->data, src, c_num(b->len));
}
+val sub_buf(val buf, val from, val to)
+{
+ struct buf *b = buf_handle(buf, lit("sub"));
+ val len = b->len;
+
+ if (null_or_missing_p(from))
+ from = zero;
+ else if (from == t)
+ from = len;
+ else if (lt(from, zero)) {
+ from = plus(from, len);
+ if (to == zero)
+ to = len;
+ }
+
+ if (null_or_missing_p(to) || to == t)
+ to = len;
+ else if (lt(to, zero))
+ to = plus(to, len);
+
+ from = max2(zero, min2(from, len));
+ to = max2(zero, min2(to, len));
+
+ if (ge(from, to)) {
+ return make_buf(zero, nil, zero);
+ } else if (from == 0 && to == len) {
+ return buf;
+ } else {
+ return make_duplicate_buf(minus(to, from), b->data + c_num(from));
+ }
+}
+
static void buf_put_bytes(val buf, val pos, mem_t *ptr, cnum size, val self)
{
struct buf *b = buf_handle(buf, self);
diff --git a/buf.h b/buf.h
index 60004112..db83f2a3 100644
--- a/buf.h
+++ b/buf.h
@@ -37,6 +37,7 @@ val length_buf(val buf);
val buf_alloc_size(val buf);
mem_t *buf_get(val buf, val self);
void buf_fill(val buf, mem_t *src, val self);
+val sub_buf(val seq, val from, val to);
#if HAVE_I8
val buf_put_i8(val buf, val pos, val num);
diff --git a/lib.c b/lib.c
index e3e1909e..1794fa99 100644
--- a/lib.c
+++ b/lib.c
@@ -9996,6 +9996,8 @@ val sub(val seq, val from, val to)
return sub_str(seq, from, to);
case VEC:
return sub_vec(seq, from, to);
+ case BUF:
+ return sub_buf(seq, from, to);
case COBJ:
if (seq->co.cls == carray_s)
return carray_sub(seq, from, to);
@@ -10097,6 +10099,8 @@ val refset(val seq, val ind, val newval)
val replace(val seq, val items, val from, val to)
{
+ val self = lit("replace");
+
switch (type(seq)) {
case NIL:
case CONS:
@@ -10114,8 +10118,10 @@ val replace(val seq, val items, val from, val to)
if (obj_struct_p(seq))
return replace_obj(seq, items, from, to);
/* fallthrough */
+ case BUF:
+ type_mismatch(lit("~a: operation doesn't support buf type"), self, nao);
default:
- type_mismatch(lit("replace: ~s is not a sequence"), seq, nao);
+ type_mismatch(lit("~a: ~s is not a sequence"), self, seq, nao);
}
}