Skip to content

Commit

Permalink
Merge pull request #406 from s-hadinger/string_startswith_endswith
Browse files Browse the repository at this point in the history
Add string.startswith and string.endswith
  • Loading branch information
skiars authored Mar 19, 2024
2 parents d537226 + cfa87a7 commit 708755d
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 0 deletions.
58 changes: 58 additions & 0 deletions src/be_strlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,60 @@ static int str_escape(bvm *vm)
be_return_nil(vm);
}

static int str_startswith(bvm *vm)
{
int top = be_top(vm);
if (top >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) {
bbool case_insensitive = bfalse;
if (top >= 3 && be_isbool(vm, 3)) {
case_insensitive = be_tobool(vm, 3);
}
bbool result = bfalse;
const char *s = be_tostring(vm, 1);
const char *p = be_tostring(vm, 2);
size_t len = (size_t)be_strlen(vm, 2);
if (case_insensitive) {
if (strncasecmp(s, p, len) == 0) {
result = btrue;
}
} else {
if (strncmp(s, p, len) == 0) {
result = btrue;
}
}
be_pushbool(vm, result);
be_return(vm);
}
be_return_nil(vm);
}

static int str_endswith(bvm *vm)
{
int top = be_top(vm);
if (top >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) {
bbool case_insensitive = bfalse;
if (top >= 3 && be_isbool(vm, 3)) {
case_insensitive = be_tobool(vm, 3);
}
bbool result = bfalse;
const char *s = be_tostring(vm, 1);
const char *p = be_tostring(vm, 2);
size_t len = (size_t)be_strlen(vm, 2);
if (case_insensitive) {
if (strncasecmp(s + (int)strlen(s) - (int)len, p, len) == 0) {
result = btrue;
}
} else {
if (strncmp(s + (int)strlen(s) - (int)len, p, len) == 0) {
result = btrue;
}
}
be_pushbool(vm, result);
be_return(vm);
}
be_return_nil(vm);
}

#if !BE_USE_PRECOMPILED_OBJECT
be_native_module_attr_table(string) {
be_native_module_function("format", be_str_format),
Expand All @@ -965,6 +1019,8 @@ be_native_module_attr_table(string) {
be_native_module_function("tr", str_tr),
be_native_module_function("escape", str_escape),
be_native_module_function("replace", str_replace),
be_native_module_function("startswith", str_startswith),
be_native_module_function("endswith", str_endswith),
};

be_define_native_module(string, NULL);
Expand All @@ -983,6 +1039,8 @@ module string (scope: global, depend: BE_USE_STRING_MODULE) {
tr, func(str_tr)
escape, func(str_escape)
replace, func(str_replace)
startswith, func(str_startswith)
endswith, func(str_endswith)
}
@const_object_info_end */
#include "../generate/be_fixed_string.h"
Expand Down
39 changes: 39 additions & 0 deletions tests/string.be
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,42 @@ var a = 'foobar{0}'
assert(f"S = {a}" == 'S = foobar{0}')
assert(f"S = {a:i}" == 'S = 0')
assert(f"{a=}" == 'a=foobar{0}')

# startswith case sensitive
assert(string.startswith("", "") == true)
assert(string.startswith("qwerty", "qw") == true)
assert(string.startswith("qwerty", "qwerty") == true)
assert(string.startswith("qwerty", "") == true)
assert(string.startswith("qwerty", "qW") == false)
assert(string.startswith("qwerty", "QW") == false)
assert(string.startswith("qwerty", "qz") == false)
assert(string.startswith("qwerty", "qwertyw") == false)

# startswith case insensitive
assert(string.startswith("qwerty", "qw", true) == true)
assert(string.startswith("qwerty", "qwerty", true) == true)
assert(string.startswith("qwerty", "", true) == true)
assert(string.startswith("qwerty", "qW", true) == true)
assert(string.startswith("qwerty", "QW", true) == true)
assert(string.startswith("qwerty", "qz", true) == false)
assert(string.startswith("qwerty", "qwertyw", true) == false)

# endswith case sensitive
assert(string.endswith("", "") == true)
assert(string.endswith("qwerty", "ty") == true)
assert(string.endswith("qwerty", "qwerty") == true)
assert(string.endswith("qwerty", "") == true)
assert(string.endswith("qwerty", "tY") == false)
assert(string.endswith("qwerty", "TY") == false)
assert(string.endswith("qwerty", "tr") == false)
assert(string.endswith("qwerty", "qwertyw") == false)

# endswith case insensitive
assert(string.endswith("", "", true) == true)
assert(string.endswith("qwerty", "ty", true) == true)
assert(string.endswith("qwerty", "qwerty", true) == true)
assert(string.endswith("qwerty", "", true) == true)
assert(string.endswith("qwerty", "tY", true) == true)
assert(string.endswith("qwerty", "TY", true) == true)
assert(string.endswith("qwerty", "tr", true) == false)
assert(string.endswith("qwerty", "qwertyw", true) == false)

0 comments on commit 708755d

Please sign in to comment.