Implement strcasestr as part of strstr

This commit is contained in:
Colin Leroy-Mira 2024-03-18 19:52:04 +01:00
parent 82165c1a77
commit b5d259bafb
3 changed files with 38 additions and 57 deletions

View File

@ -1,36 +0,0 @@
/*
** strcasestr.c
**
** Colin Leroy-Mira, 2024
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*****************************************************************************/
/* Code */
/*****************************************************************************/
char* __fastcall__ strcasestr(const char *str, const char *substr) {
size_t len_a = strlen(str);
size_t len_b = strlen(substr);
const char *end_str;
if (len_a < len_b)
return NULL;
len_a -= len_b;
for (end_str = str + len_a + 1; str < end_str; str++) {
if (!strncasecmp(str, substr, len_b))
return (char *)str;
}
return NULL;
}

View File

@ -4,11 +4,18 @@
; char* strstr (const char* haystack, const char* needle);
;
.export _strstr
.import popptr1
.importzp ptr1, ptr2, ptr3, ptr4, tmp1
.export _strstr, _strcasestr
.import popptr1, _tolower
.importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3
_strstr:
ldy #$01
bne :+
_strcasestr:
ldy #$00
:
sty tmp2 ; Set case sensitivity
sta ptr2 ; Save needle
stx ptr2+1
sta ptr4 ; Setup temp copy for later
@ -24,10 +31,19 @@ _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).
sta tmp1 ; Save start of needle
ldx tmp2 ; Lowercase if needed
bne :+
jsr _tolower
: sta tmp1 ; Save start of needle
@L1: lda (ptr1),y ; Get next char from haystack
beq @NotFound ; Jump if end
cmp tmp1 ; Start of needle found?
ldx tmp2 ; Lowercase if needed
bne :+
jsr _tolower
: cmp tmp1 ; Start of needle found?
beq @L2 ; Jump if so
iny ; Next char
bne @L1
@ -43,7 +59,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 +73,19 @@ _strstr:
@L4: lda (ptr4),y ; Get char from needle
beq @Found ; Jump if end of needle (-> found)
cmp (ptr3),y ; Compare with haystack
ldx tmp2 ; Lowercase if needed
bne :+
jsr _tolower
: sta tmp3
lda (ptr3),y ; Compare with haystack
ldx tmp2 ; Lowercase if needed
bne :+
jsr _tolower
: cmp tmp3
bne @L5 ; Jump if not equal
iny ; Next char
bne @L4
@ -82,14 +110,3 @@ _strstr:
lda #$00 ; return NULL
tax
rts

View File

@ -17,12 +17,12 @@
_tolower:
cpx #$00 ; out of range?
bne @L2 ; if so, return the argument unchanged
tay ; save char
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
@L1: pla ; restore char
@L2: rts