summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2024-02-27 20:46:33 -0800
committerKaz Kylheku <kaz@kylheku.com>2024-02-27 20:46:33 -0800
commitb3a440ca242a07ed86f89d06208f15757d947e12 (patch)
tree805e1862a39da0c730627a0a30ecb78ad219ec52 /lib.c
parentd36f90235fcf1561a43bf79283a40b042efff84a (diff)
downloadtxr-b3a440ca242a07ed86f89d06208f15757d947e12.tar.gz
txr-b3a440ca242a07ed86f89d06208f15757d947e12.tar.bz2
txr-b3a440ca242a07ed86f89d06208f15757d947e12.zip
seq_build: fix: incompatible items must create list.
In the make_like function, the list is converted to string or buffer if the first element of the list is a character, or integer. We need similar logic in seq_build. We can make it better. When any item is added which is incompatible, we can convert what we have so far to a list, change the seq_build type to list, and keep going. * lib.c (seq_build_convert_to_list): New static function. (seq_build_str_add, seq_build_buf_add): If the item is incompatible, convert the string or buffer to a list and pass to seq_build_convert_to_list. Then call bu->ops->add to add the item, now as a list. (seq_build_buf_pend): Function removed. (sb_buf_ops): Use the seq_build_generic_pend function for the pend operation. This is because we have to check each item one by one; we cannot use replace_buf.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/lib.c b/lib.c
index 8d928c66..a0c26ff0 100644
--- a/lib.c
+++ b/lib.c
@@ -1438,9 +1438,16 @@ static void seq_build_vec_add(seq_build_t *bu, val item)
vec_push(bu->obj, item);
}
+static void seq_build_convert_to_list(seq_build_t *bu, val list);
+
static void seq_build_str_add(seq_build_t *bu, val item)
{
- string_extend(bu->obj, item, nil);
+ if (chrp(item)) {
+ string_extend(bu->obj, item, nil);
+ } else {
+ seq_build_convert_to_list(bu, list_str(bu->obj));
+ bu->ops->add(bu, item);
+ }
}
static void seq_build_str_finish(seq_build_t *bu)
@@ -1451,17 +1458,14 @@ static void seq_build_str_finish(seq_build_t *bu)
static void seq_build_buf_add(seq_build_t *bu, val item)
{
val buf = bu->obj;
- val len = length_buf(buf);
-
- buf_put_uchar(buf, len, item);
-}
-static void seq_build_buf_pend(seq_build_t *bu, val seq)
-{
- val buf = bu->obj;
- val len = length_buf(buf);
-
- replace_buf(buf, seq, len, len);
+ if (integerp(item)) {
+ val len = length_buf(buf);
+ buf_put_uchar(buf, len, item);
+ } else {
+ seq_build_convert_to_list(bu, mapcar_listout(identity_f, buf));
+ bu->ops->add(bu, item);
+ }
}
static void seq_build_buf_finish(seq_build_t *bu)
@@ -1522,7 +1526,7 @@ static struct seq_build_ops
static struct seq_build_ops
sb_buf_ops = seq_build_ops_init(seq_build_buf_add,
- seq_build_buf_pend,
+ seq_build_generic_pend,
seq_build_buf_finish,
seq_build_obj_mark);
@@ -1544,6 +1548,20 @@ static struct seq_build_ops
seq_build_list_finish,
seq_build_obj_mark);
+static void seq_build_convert_to_list(seq_build_t *bu, val list)
+{
+ if (list) {
+ val tail = lastcons(list);
+ us_rplacd(tail, list);
+ bu->obj = tail;
+ } else {
+ bu->obj = nil;
+ }
+
+ bu->ops = &sb_list_ops;
+}
+
+
void seq_build_init(val self, seq_build_t *bu, val likeobj)
{
bu->self = self;