Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions src/libc/os.src
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,10 @@ _strcat := 0000C0h
_strchr := 0000C4h
public _strcpy
_strcpy := 0000CCh
public _strcspn
_strcspn := 0000D0h
public _strncat
_strncat := 0000D8h
public _strncpy
_strncpy := 0000E0h
public _strpbrk
_strpbrk := 0000E4h
public _strspn
_strspn := 0000ECh
public _strstr
_strstr := 0000F0h
public _strtok
Expand Down
50 changes: 50 additions & 0 deletions src/libc/strcspn.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
assume adl=1

section .text
public _strcspn
_strcspn:
call __strcspn_strpbrk_common
sbc hl, de ; Calculate number of mismatching characters
ret

section .text
public _strpbrk
_strpbrk:
call __strcspn_strpbrk_common
ret nz ; Return pointer if not end of string
sbc hl, hl ; Return NULL
ret

section .text
private __strcspn_strpbrk_common
__strcspn_strpbrk_common:
ld hl, 6
add hl, sp
ld de, (hl) ; DE = str
ld bc, 3
add hl, bc ; Always resets carry
ld hl, (hl) ; HL = reject

; Calculate strlen(reject)
push hl
xor a, a
ld c, a
cpir
sbc hl, hl
sbc hl, bc
ex (sp), hl
pop iy ; IY = strlen(reject) + 1
dec hl ; HL = reject - 1
push de
.loop:
ld a, (de) ; A = *str++
inc de
lea bc, iy ; BC = strlen(reject) + 1
add hl, bc ; HL = reject + strlen(reject)
cpdr ; Find A in reject, including null terminator
jr nz, .loop ; Loop if no match
ex de, hl
dec hl ; HL = pointer to matching character
pop de ; DE = str
or a, a ; Check if A is null terminator and reset carry
ret
38 changes: 38 additions & 0 deletions src/libc/strspn.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
assume adl=1

section .text
public _strspn
_strspn:
xor a, a
sbc hl, hl
add hl, sp
ld bc, 3
add hl, bc
ld de, (hl) ; DE = str
add hl, bc ; Always resets carry
ld iy, (hl) ; IY = accept

; Calculate strlen(accept)
ld c, a
lea hl, iy
cpir
sbc hl, hl
scf
sbc hl, bc ; Always sets carry
ret z ; Return 0 if accept is empty

push hl
ex (sp), ix ; IX = strlen(accept)
push de
.loop:
ld a, (de) ; A = *str++
inc de
lea hl, iy ; HL = accept
lea bc, ix ; BC = strlen(accept)
cpir ; Find A in accept
jr z, .loop ; Loop if match
ex de, hl ; Calculate number of matching characters
pop de
sbc hl, de ; Input carry is set
pop ix
ret
36 changes: 36 additions & 0 deletions test/issues/646/autotest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"transfer_files":
[
"bin/DEMO.8xp"
],
"target":
{
"name": "DEMO",
"isASM": true
},
"sequence":
[
"action|launch",
"delay|100",
"hashWait|1",
"key|enter",
"hashWait|2"
],
"hashes":
{
"1":
{
"description": "Test functions",
"start": "vram_start",
"size": "vram_16_size",
"expected_CRCs": [ "36DD9C48" ]
},
"2":
{
"description": "Test program exit",
"start": "vram_start",
"size": "vram_16_size",
"expected_CRCs": [ "FFAF89BA", "101734A5", "9DA19F44", "A32840C8", "349F4775" ]
}
}
}
15 changes: 15 additions & 0 deletions test/issues/646/makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# ----------------------------
# Makefile Options
# ----------------------------

NAME = DEMO
ICON = icon.png
DESCRIPTION = "CE C Toolchain Demo"
COMPRESSED = NO

CFLAGS = -Wall -Wextra -Oz -fno-builtin-strspn -fno-builtin-strcspn -fno-builtin-strpbrk
CXXFLAGS = -Wall -Wextra -Oz -fno-builtin-strspn -fno-builtin-strcspn -fno-builtin-strpbrk

# ----------------------------

include $(shell cedev-config --makefile)
67 changes: 67 additions & 0 deletions test/issues/646/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include <stdio.h>
#include <string.h>
#include <ti/screen.h>
#include <ti/getkey.h>

#define C(expr) if (!(expr)) { return __LINE__; }
static int libc_test(void) {

char const * str = "abcdef";
char const * empty = "";

C(strspn(str, "abc") == 3);
C(strspn(str, "cba") == 3);
C(strspn(str, "def") == 0);
C(strspn(str, "fed") == 0);
C(strspn(str, "ABCDEF") == 0);
C(strspn(str, "bbeebe") == 0);
C(strspn(str, "eebbeb") == 0);
C(strspn(str, "aaffaf") == 1);
C(strspn(str, "ffaafa") == 1);
C(strspn(str, str) == 6);
C(strspn(str, empty) == 0);
C(strspn(empty, str) == 0);
C(strspn(empty, empty) == 0);

C(strcspn(str, "abc") == 0);
C(strcspn(str, "cba") == 0);
C(strcspn(str, "def") == 3);
C(strcspn(str, "fed") == 3);
C(strcspn(str, "ABCDEF") == 6);
C(strcspn(str, "bbeebe") == 1);
C(strcspn(str, "eebbeb") == 1);
C(strcspn(str, "aaffaf") == 0);
C(strcspn(str, "ffaafa") == 0);
C(strcspn(str, str) == 0);
C(strcspn(str, empty) == 6);
C(strcspn(empty, str) == 0);
C(strcspn(empty, empty) == 0);

C(strpbrk(str, "abc") == str + 0);
C(strpbrk(str, "cba") == str + 0);
C(strpbrk(str, "def") == str + 3);
C(strpbrk(str, "fed") == str + 3);
C(strpbrk(str, "ABCDEF") == NULL);
C(strpbrk(str, "bbeebe") == str + 1);
C(strpbrk(str, "eebbeb") == str + 1);
C(strpbrk(str, "aaffaf") == str + 0);
C(strpbrk(str, "ffaafa") == str + 0);
C(strpbrk(str, str) == str);
C(strpbrk(str, empty) == NULL);
C(strpbrk(empty, str) == NULL);
C(strpbrk(empty, empty) == NULL);

return 0;
}
#undef C

int main(void)
{
os_ClrHome();

printf("%d\n", libc_test());

os_GetKey();

return 0;
}
Loading