Skip to content

Commit d9d0f24

Browse files
calc84maniacZERICO2005
authored andcommitted
Implement strspn, strcspn, strpbrk in place of broken OS functions. Fixes #646
1 parent 1a3f733 commit d9d0f24

File tree

6 files changed

+206
-6
lines changed

6 files changed

+206
-6
lines changed

src/libc/os.src

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,10 @@ _strcat := 0000C0h
1616
_strchr := 0000C4h
1717
public _strcpy
1818
_strcpy := 0000CCh
19-
public _strcspn
20-
_strcspn := 0000D0h
2119
public _strncat
2220
_strncat := 0000D8h
2321
public _strncpy
2422
_strncpy := 0000E0h
25-
public _strpbrk
26-
_strpbrk := 0000E4h
27-
public _strspn
28-
_strspn := 0000ECh
2923
public _strstr
3024
_strstr := 0000F0h
3125
public _strtok

src/libc/strcspn.src

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
assume adl=1
2+
3+
section .text
4+
public _strcspn
5+
_strcspn:
6+
call __strcspn_strpbrk_common
7+
sbc hl, de ; Calculate number of mismatching characters
8+
ret
9+
10+
section .text
11+
public _strpbrk
12+
_strpbrk:
13+
call __strcspn_strpbrk_common
14+
ret nz ; Return pointer if not end of string
15+
sbc hl, hl ; Return NULL
16+
ret
17+
18+
section .text
19+
private __strcspn_strpbrk_common
20+
__strcspn_strpbrk_common:
21+
ld hl, 6
22+
add hl, sp
23+
ld de, (hl) ; DE = str
24+
ld bc, 3
25+
add hl, bc ; Always resets carry
26+
ld hl, (hl) ; HL = reject
27+
28+
; Calculate strlen(reject)
29+
push hl
30+
xor a, a
31+
ld c, a
32+
cpir
33+
sbc hl, hl
34+
sbc hl, bc
35+
ex (sp), hl
36+
pop iy ; IY = strlen(reject) + 1
37+
dec hl ; HL = reject - 1
38+
push de
39+
.loop:
40+
ld a, (de) ; A = *str++
41+
inc de
42+
lea bc, iy ; BC = strlen(reject) + 1
43+
add hl, bc ; HL = reject + strlen(reject)
44+
cpdr ; Find A in reject, including null terminator
45+
jr nz, .loop ; Loop if no match
46+
ex de, hl
47+
dec hl ; HL = pointer to matching character
48+
pop de ; DE = str
49+
or a, a ; Check if A is null terminator and reset carry
50+
ret

src/libc/strspn.src

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
assume adl=1
2+
3+
section .text
4+
public _strspn
5+
_strspn:
6+
xor a, a
7+
sbc hl, hl
8+
add hl, sp
9+
ld bc, 3
10+
add hl, bc
11+
ld de, (hl) ; DE = str
12+
add hl, bc ; Always resets carry
13+
ld iy, (hl) ; IY = accept
14+
15+
; Calculate strlen(accept)
16+
ld c, a
17+
lea hl, iy
18+
cpir
19+
sbc hl, hl
20+
scf
21+
sbc hl, bc ; Always sets carry
22+
ret z ; Return 0 if accept is empty
23+
24+
push hl
25+
ex (sp), ix ; IX = strlen(accept)
26+
push de
27+
.loop:
28+
ld a, (de) ; A = *str++
29+
inc de
30+
lea hl, iy ; HL = accept
31+
lea bc, ix ; BC = strlen(accept)
32+
cpir ; Find A in accept
33+
jr z, .loop ; Loop if match
34+
ex de, hl ; Calculate number of matching characters
35+
pop de
36+
sbc hl, de ; Input carry is set
37+
pop ix
38+
ret

test/issues/646/autotest.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"transfer_files":
3+
[
4+
"bin/DEMO.8xp"
5+
],
6+
"target":
7+
{
8+
"name": "DEMO",
9+
"isASM": true
10+
},
11+
"sequence":
12+
[
13+
"action|launch",
14+
"delay|100",
15+
"hashWait|1",
16+
"key|enter",
17+
"hashWait|2"
18+
],
19+
"hashes":
20+
{
21+
"1":
22+
{
23+
"description": "Test functions",
24+
"start": "vram_start",
25+
"size": "vram_16_size",
26+
"expected_CRCs": [ "36DD9C48" ]
27+
},
28+
"2":
29+
{
30+
"description": "Test program exit",
31+
"start": "vram_start",
32+
"size": "vram_16_size",
33+
"expected_CRCs": [ "FFAF89BA", "101734A5", "9DA19F44", "A32840C8", "349F4775" ]
34+
}
35+
}
36+
}

test/issues/646/makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# ----------------------------
2+
# Makefile Options
3+
# ----------------------------
4+
5+
NAME = DEMO
6+
ICON = icon.png
7+
DESCRIPTION = "CE C Toolchain Demo"
8+
COMPRESSED = NO
9+
10+
CFLAGS = -Wall -Wextra -Oz -fno-builtin-strspn -fno-builtin-strcspn -fno-builtin-strpbrk
11+
CXXFLAGS = -Wall -Wextra -Oz -fno-builtin-strspn -fno-builtin-strcspn -fno-builtin-strpbrk
12+
13+
# ----------------------------
14+
15+
include $(shell cedev-config --makefile)

test/issues/646/src/main.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
#include <ti/screen.h>
4+
#include <ti/getkey.h>
5+
6+
#define C(expr) if (!(expr)) { return __LINE__; }
7+
static int libc_test(void) {
8+
9+
char const * str = "abcdef";
10+
char const * empty = "";
11+
12+
C(strspn(str, "abc") == 3);
13+
C(strspn(str, "cba") == 3);
14+
C(strspn(str, "def") == 0);
15+
C(strspn(str, "fed") == 0);
16+
C(strspn(str, "ABCDEF") == 0);
17+
C(strspn(str, "bbeebe") == 0);
18+
C(strspn(str, "eebbeb") == 0);
19+
C(strspn(str, "aaffaf") == 1);
20+
C(strspn(str, "ffaafa") == 1);
21+
C(strspn(str, str) == 6);
22+
C(strspn(str, empty) == 0);
23+
C(strspn(empty, str) == 0);
24+
C(strspn(empty, empty) == 0);
25+
26+
C(strcspn(str, "abc") == 0);
27+
C(strcspn(str, "cba") == 0);
28+
C(strcspn(str, "def") == 3);
29+
C(strcspn(str, "fed") == 3);
30+
C(strcspn(str, "ABCDEF") == 6);
31+
C(strcspn(str, "bbeebe") == 1);
32+
C(strcspn(str, "eebbeb") == 1);
33+
C(strcspn(str, "aaffaf") == 0);
34+
C(strcspn(str, "ffaafa") == 0);
35+
C(strcspn(str, str) == 0);
36+
C(strcspn(str, empty) == 6);
37+
C(strcspn(empty, str) == 0);
38+
C(strcspn(empty, empty) == 0);
39+
40+
C(strpbrk(str, "abc") == str + 0);
41+
C(strpbrk(str, "cba") == str + 0);
42+
C(strpbrk(str, "def") == str + 3);
43+
C(strpbrk(str, "fed") == str + 3);
44+
C(strpbrk(str, "ABCDEF") == NULL);
45+
C(strpbrk(str, "bbeebe") == str + 1);
46+
C(strpbrk(str, "eebbeb") == str + 1);
47+
C(strpbrk(str, "aaffaf") == str + 0);
48+
C(strpbrk(str, "ffaafa") == str + 0);
49+
C(strpbrk(str, str) == str);
50+
C(strpbrk(str, empty) == NULL);
51+
C(strpbrk(empty, str) == NULL);
52+
C(strpbrk(empty, empty) == NULL);
53+
54+
return 0;
55+
}
56+
#undef C
57+
58+
int main(void)
59+
{
60+
os_ClrHome();
61+
62+
printf("%d\n", libc_test());
63+
64+
os_GetKey();
65+
66+
return 0;
67+
}

0 commit comments

Comments
 (0)