summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-06-12 07:51:58 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-06-12 07:51:58 -0700
commit5ee7422f1f2968a8999bbb96b068ef9567c20325 (patch)
tree912855c05e61f0cbc9913ea6d9c687d2fbebe1f1 /lib.c
parent77ae026de432a7ecf1ddf779eb5529bf0e67ffce (diff)
downloadtxr-5ee7422f1f2968a8999bbb96b068ef9567c20325.tar.gz
txr-5ee7422f1f2968a8999bbb96b068ef9567c20325.tar.bz2
txr-5ee7422f1f2968a8999bbb96b068ef9567c20325.zip
replace-vec, replace-str: refactor with sequence iteration.
* lib.c (replace_vec, replace_str): Don't use dubious toseq on input items, which converts non-sequence atoms into lists of one. Use sequence iterators to reduce number of cases in the code.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c150
1 files changed, 53 insertions, 97 deletions
diff --git a/lib.c b/lib.c
index ba659526..3eacaa3d 100644
--- a/lib.c
+++ b/lib.c
@@ -3765,55 +3765,37 @@ val sub_str(val str_in, val from, val to)
val replace_str(val str_in, val items, val from, val to)
{
- val itseq = toseq(items);
+ val self = lit("replace-str");
val len = length_str(str_in);
if (type(str_in) != STR) {
- uw_throwf(error_s, lit("replace-str: ~s of type ~s is not "
+ uw_throwf(error_s, lit("~a: ~s of type ~s is not "
"a modifiable string"),
- str_in, typeof(str_in), nao);
+ self, str_in, typeof(str_in), nao);
}
- if (listp(from)) {
- val where = from;
- val len = length_str(str_in);
-
- if (!missingp(to))
- uw_throwf(error_s,
- lit("replace-str: to-arg not applicable when from-arg is a list"),
- nao);
-
- for (; where && itseq; where = cdr(where)) {
- val wh = car(where);
- if (ge(wh, len))
- break;
- chr_str_set(str_in, wh, pop(&itseq));
- }
-
- return str_in;
- } else if (vectorp(from)) {
- val where = from;
- val len = length_str(str_in);
- val wlen = length_vec(from);
- val i;
+ if (missingp(from)) {
+ from = zero;
+ } else if (from == t) {
+ from = len;
+ } else if (!integerp(from)) {
+ val len = length_str(str_in), wh, item;
+ seq_iter_t wh_iter, item_iter;
+ seq_iter_init(self, &item_iter, items);
+ seq_iter_init(self, &wh_iter, from);
if (!missingp(to))
uw_throwf(error_s,
- lit("replace-str: to-arg not applicable when from-arg is a vector"),
- nao);
+ lit("~a: to-arg not applicable when from-arg is a list"),
+ self, nao);
- for (i = zero; lt(i, wlen) && itseq; i = plus(i, one)) {
- val wh = vecref(where, i);
+ while (seq_get(&wh_iter, &wh) && seq_get(&item_iter, &item)) {
if (ge(wh, len))
break;
- chr_str_set(str_in, wh, pop(&itseq));
+ chr_str_set(str_in, wh, item);
}
return str_in;
- } else if (missingp(from)) {
- from = zero;
- } else if (from == t) {
- from = len;
} else if (lt(from, zero)) {
from = plus(from, len);
if (to == zero)
@@ -3831,7 +3813,7 @@ val replace_str(val str_in, val items, val from, val to)
{
val len_rep = minus(to, from);
- val len_it = length(itseq);
+ val len_it = length(items);
if (gt(len_rep, len_it)) {
val len_diff = minus(len_rep, len_it);
@@ -3855,24 +3837,16 @@ val replace_str(val str_in, val items, val from, val to)
if (zerop(len_it))
return str_in;
- if (stringp(itseq)) {
- wmemcpy(str_in->st.str + c_num(from), c_str(itseq), c_num(len_it));
+ if (stringp(items)) {
+ wmemcpy(str_in->st.str + c_num(from), c_str(items), c_num(len_it));
} else {
- val iter;
+ seq_iter_t item_iter;
+ seq_iter_init(self, &item_iter, items);
cnum f = c_num(from);
cnum t = c_num(to);
- cnum s;
-
- if (listp(itseq)) {
- for (iter = itseq; iter && f != t; iter = cdr(iter), f++)
- str_in->st.str[f] = c_chr(car(iter));
- } else if (vectorp(itseq)) {
- for (s = 0; f != t; f++, s++)
- str_in->st.str[f] = c_chr(vecref(itseq, num(s)));
- } else {
- uw_throwf(error_s, lit("replace-str: source object ~s not supported"),
- itseq, nao);
- }
+
+ for (; f != t; f++)
+ str_in->st.str[f] = c_chr(seq_geti(&item_iter));
}
}
@@ -7204,49 +7178,31 @@ val sub_vec(val vec_in, val from, val to)
val replace_vec(val vec_in, val items, val from, val to)
{
- val it_seq = toseq(items);
+ val self = lit("replace-vec");
val len = length_vec(vec_in);
- if (listp(from)) {
- val where = from;
- val len = length_vec(vec_in);
-
- if (!missingp(to))
- uw_throwf(error_s,
- lit("replace-vec: to-arg not applicable when from-arg is a list"),
- nao);
-
- for (; where && it_seq; where = cdr(where)) {
- val wh = car(where);
- if (ge(wh, len))
- break;
- set(vecref_l(vec_in, wh), pop(&it_seq));
- }
-
- return vec_in;
- } else if (vectorp(from)) {
- val where = from;
- val len = length_vec(vec_in);
- val wlen = length_vec(from);
- val i;
+ if (missingp(from)) {
+ from = zero;
+ } else if (from == t) {
+ from = len;
+ } else if (!integerp(from)) {
+ seq_iter_t wh_iter, item_iter;
+ val len = length_vec(vec_in), wh, item;
+ seq_iter_init(self, &wh_iter, from);
+ seq_iter_init(self, &item_iter, items);
if (!missingp(to))
uw_throwf(error_s,
- lit("replace-vec: to-arg not applicable when from-arg is a vector"),
- nao);
+ lit("~a: to-arg not applicable when from-arg is a list"),
+ self, nao);
- for (i = zero; lt(i, wlen) && it_seq; i = plus(i, one)) {
- val wh = vecref(where, i);
+ while (seq_get(&wh_iter, &wh) && seq_get(&item_iter, &item)) {
if (ge(wh, len))
break;
- set(vecref_l(vec_in, wh), pop(&it_seq));
+ set(vecref_l(vec_in, wh), item);
}
return vec_in;
- } else if (missingp(from)) {
- from = zero;
- } else if (from == t) {
- from = len;
} else if (lt(from, zero)) {
from = plus(from, len);
if (to == zero)
@@ -7263,7 +7219,7 @@ val replace_vec(val vec_in, val items, val from, val to)
{
val len_rep = minus(to, from);
- val len_it = length(it_seq);
+ val len_it = length(items);
if (gt(len_rep, len_it)) {
val len_diff = minus(len_rep, len_it);
@@ -7291,26 +7247,26 @@ val replace_vec(val vec_in, val items, val from, val to)
if (zerop(len_it))
return vec_in;
- if (vectorp(it_seq)) {
- memcpy(vec_in->v.vec + c_num(from), it_seq->v.vec,
+ if (vectorp(items)) {
+ memcpy(vec_in->v.vec + c_num(from), items->v.vec,
sizeof *vec_in->v.vec * c_num(len_it));
mut(vec_in);
- } else if (stringp(it_seq)) {
- cnum f = c_num(from);
- cnum t = c_num(to);
- cnum s;
- const wchar_t *str = c_str(it_seq);
-
- for (s = 0; f != t; f++, s++)
- vec_in->v.vec[f] = chr(str[s]);
} else {
- val iter;
+ seq_iter_t item_iter;
+ seq_iter_init(self, &item_iter, items);
+ int mut_needed = 0;
cnum f = c_num(from);
cnum t = c_num(to);
- for (iter = it_seq; iter && f != t; iter = cdr(iter), f++)
- vec_in->v.vec[f] = car(iter);
- mut(vec_in);
+ for (; f != t; f++) {
+ val item = seq_geti(&item_iter);
+ if (is_ptr(item))
+ mut_needed = 1;
+ vec_in->v.vec[f] = item;
+ }
+
+ if (mut_needed)
+ mut(vec_in);
}
}