Berry fix list.concat

This commit is contained in:
Stephan Hadinger 2021-11-27 11:20:02 +01:00
parent abf7f828ec
commit f60bd05eed
2 changed files with 65 additions and 6 deletions

View File

@ -333,24 +333,23 @@ static int m_merge(bvm *vm)
be_return(vm); /* return self */
}
static void connect(bvm *vm, bvalue *begin, bvalue *end, const char * delimiter)
static void connect(bvm *vm, bvalue *begin, bvalue *end, const char * delimiter, bbool first_element)
{
size_t l0 = be_strlen(vm, -1), len = l0;
size_t d = delimiter ? strlen(delimiter) : 0; /* len of delimiter */
bbool non_empty = l0 > 0; /* is the string non-empty, i.e. needs a prefix delimiter */
char *buf, *p;
bvalue *it;
for (it = begin; it < end; ++it) {
len += str_len(var_tostr(it)) + d;
}
if (!non_empty) {
if (first_element) {
len -= d; /* remove size for first delimiter non needed */
}
buf = be_pushbuffer(vm, len);
memcpy(buf, be_tostring(vm, -2), l0);
p = buf + l0;
for (it = begin; it < end; ++it) {
if ((it != begin || non_empty) && delimiter) {
if ((it != begin || !first_element) && delimiter) {
/* add delimiter */
memcpy(p, delimiter, d);
p += d;
@ -370,11 +369,15 @@ static void list_concat(bvm *vm, blist *list, const char * delimiter)
bvalue *it, *begin = be_list_data(list);
bvalue *end = be_list_end(list);
be_pushstring(vm, ""); /* push a empty string */
bbool first_element = btrue;
for (it = begin; it < end;) {
for (; it < end && var_isstr(it); ++it);
connect(vm, begin, it, delimiter); /* connect string list */
if (begin < it) {
connect(vm, begin, it, delimiter, first_element); /* connect string list */
first_element = bfalse;
}
if (it < end) {
if (delimiter && be_strlen(vm, -1) > 0) {
if (delimiter && !first_element) {
be_pushstring(vm, delimiter);
be_strconcat(vm, -2);
be_pop(vm, 1);
@ -386,6 +389,7 @@ static void list_concat(bvm *vm, blist *list, const char * delimiter)
be_strconcat(vm, -2);
be_pop(vm, 1);
begin = ++it;
first_element = bfalse;
}
}
}

View File

@ -72,3 +72,58 @@ assert(l2 == [2, 3])
assert(l1+[2] == [0, 1, 2])
assert([-1]+l1 == [-1, 0, 1])
assert(l1 == [0, 1])
#- find -#
#- if no argument return nil -#
assert([].find() == nil)
assert([1,2].find() == nil)
assert([1,1,nil,2].find() == nil)
#- nil if not found -#
assert([1,2].find(3) == nil)
assert([1,2].find(true) == nil)
assert([1,2].find('foo') == nil)
#- if found -#
assert([1,2,3,4].find(1) == 0)
assert([1,2,3,4].find(2) == 1)
assert([1,2,3,4].find(3) == 2)
assert([1,2,3,4].find(4) == 3)
assert([1,2,"foo",4].find('foo') == 2)
#- if multiple occurrences -#
assert([1,1,2,2].find(1) == 0)
assert([1,1,2,2].find(2) == 2)
#- look for nil -#
assert([1,1,nil,2].find(nil) == 2)
#- sub-structure -#
assert([1,[1,nil,2],3,[3]].find(3) == 2)
assert([1,[1,nil,2],3,[3]].find([3]) == 3)
assert([1,[1,nil,2],3,[3]].find([1,nil,2]) == 1)
#- keys() -#
assert(str(["a",'b',0].keys()) == "(0..2)")
assert(str([nil].keys()) == "(0..0)")
assert(str([].keys()) == "(0..-1)")
#- concat with delimiter -#
assert(["foo","bar",0].concat() == "foobar0")
assert([1,2,3].concat() == "123")
assert(["foo","bar",0].concat('') == "foobar0")
assert([1,2,3].concat('') == "123")
assert(["foo","bar",0].concat('-') == "foo-bar-0")
assert([].concat('<->') == "")
assert(["foo"].concat('<->') == "foo")
assert(["foo","bar",0].concat('<->') == "foo<->bar<->0")
assert(["","foo","bar",0].concat('<->') == "<->foo<->bar<->0")
assert(["","",1,"bar",0].concat('<->') == "<-><->1<->bar<->0")
assert(["","",1,"bar",0].concat('') == "1bar0")
assert([1,2,3].concat('-') == "1-2-3")
assert([1,"2",3].concat('-') == "1-2-3")
assert(["",2,3].concat('-') == "-2-3")