1
0
mirror of https://github.com/cc65/cc65.git synced 2024-09-27 19:55:09 +00:00
This commit is contained in:
Colin Leroy-Mira 2024-03-22 16:19:54 +00:00 committed by GitHub
commit 0faf13c98f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 74 additions and 25 deletions

View File

@ -81,6 +81,7 @@ void __fastcall__ bzero (void* ptr, size_t n); /* BSD */
char* __fastcall__ strdup (const char* s); /* SYSV/BSD */
int __fastcall__ stricmp (const char* s1, const char* s2); /* DOS/Windows */
int __fastcall__ strcasecmp (const char* s1, const char* s2); /* Same for Unix */
char* __fastcall__ strcasestr (const char* str, const char* substr);
int __fastcall__ strnicmp (const char* s1, const char* s2, size_t count); /* DOS/Windows */
int __fastcall__ strncasecmp (const char* s1, const char* s2, size_t count); /* Same for Unix */
size_t __fastcall__ strnlen (const char* s, size_t maxlen); /* POSIX.1-2008 */

View File

@ -4,11 +4,20 @@
; char* strstr (const char* haystack, const char* needle);
;
.export _strstr
.import popptr1
.importzp ptr1, ptr2, ptr3, ptr4, tmp1
.export _strstr, _strcasestr
.import popptr1, return0, tolowerdirect
.importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2
maybe_lower: ; Lowercase char in A if needed
jmp tolowerdirect ; patched on entry with either JMP or RTS
_strstr:
ldy #$60 ; RTS
bne :+
_strcasestr:
ldy #$4C ; JMP absolute
: sty maybe_lower
sta ptr2 ; Save needle
stx ptr2+1
sta ptr4 ; Setup temp copy for later
@ -24,9 +33,12 @@ _strstr:
; Search for the beginning of the string (this is not an optimal search
; strategy [in fact, it's pretty dumb], but it's simple to implement).
jsr maybe_lower ; Lowercase if needed
sta tmp1 ; Save start of needle
@L1: lda (ptr1),y ; Get next char from haystack
beq @NotFound ; Jump if end
jsr maybe_lower ; Lowercase if needed
cmp tmp1 ; Start of needle found?
beq @L2 ; Jump if so
iny ; Next char
@ -43,7 +55,7 @@ _strstr:
bcc @L3
inc ptr1+1
; ptr1 points to the start of needle now. Setup temporary pointers for the
; ptr1 points to the start of needle in haystack now. Setup temporary pointers for the
; search. The low byte of ptr4 is already set.
@L3: sta ptr3
@ -57,7 +69,14 @@ _strstr:
@L4: lda (ptr4),y ; Get char from needle
beq @Found ; Jump if end of needle (-> found)
cmp (ptr3),y ; Compare with haystack
jsr maybe_lower ; Lowercase if needed
sta tmp2
lda (ptr3),y ; Compare with haystack
jsr maybe_lower ; Lowercase if needed
cmp tmp2
bne @L5 ; Jump if not equal
iny ; Next char
bne @L4
@ -79,17 +98,4 @@ _strstr:
; We reached end of haystack without finding needle
@NotFound:
lda #$00 ; return NULL
tax
rts
jmp return0 ; return NULL

View File

@ -10,19 +10,20 @@
; int tolower (int c);
;
.export _tolower
.export _tolower, tolowerdirect
.include "ctype.inc"
.import ctypemaskdirect
_tolower:
cpx #$00 ; out of range?
bne @L2 ; if so, return the argument unchanged
tay ; save char
bne out ; if so, return the argument unchanged
tolowerdirect:
pha ; save char
jsr ctypemaskdirect ; get character classification
and #CT_UPPER ; upper case char?
beq @L1 ; jump if no
tya ; restore char
pla ; restore char
adc #<('a'-'A') ; make lower case char (ctypemaskdirect ensures carry clear)
rts
@L1: tya ; restore char
@L2: rts
@L1: pla ; restore char
out: rts

41
test/val/strstr-test.c Normal file
View File

@ -0,0 +1,41 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int fails = 0;
#define STRSTR_TEST(needle,expected) \
if (strstr(haystack, (needle)) != (expected)) { \
printf("strstr failure: expected %p for \"%s\", " \
"got %p\n", \
expected, needle, strstr(haystack, (needle)));\
fails++; \
}
#define STRCASESTR_TEST(needle,expected) \
if (strcasestr(haystack, (needle)) != (expected)) { \
printf("strcasestr failure: expected %p for \"%s\", " \
"got %p\n", \
expected, needle, strcasestr(haystack, (needle)));\
fails++; \
}
int main (void)
{
const char *haystack = "This is a string to search in";
STRSTR_TEST("This is", haystack + 0);
STRSTR_TEST("a string", haystack + 8);
STRSTR_TEST("This is a string to search in", haystack);
STRSTR_TEST("search in", haystack + 20);
STRSTR_TEST("This is a string to search in with extra chars", NULL);
STRSTR_TEST("nowhere", NULL);
STRCASESTR_TEST("this is", haystack + 0);
STRCASESTR_TEST("a STRING", haystack + 8);
STRCASESTR_TEST("this is a string TO search in", haystack);
STRCASESTR_TEST("This is a string to search in with extra chars", NULL);
STRCASESTR_TEST("search IN", haystack + 20);
return fails;
}