Skip to content

Commit 03a410c

Browse files
ZERICO2005adriweb
authored andcommitted
added memrmem and strrstr
1 parent a802ef4 commit 03a410c

File tree

6 files changed

+320
-6
lines changed

6 files changed

+320
-6
lines changed

src/libc/include/string.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ void *memrchr(const void *s, int c, size_t n)
2929
void *memmem(const void *haystack, size_t haystack_len, const void *needle, size_t needle_len)
3030
__NOEXCEPT __attribute__((nonnull(1, 3))) __attribute((__pure__));
3131

32+
void *memrmem(const void *haystack, size_t haystack_len, const void *needle, size_t needle_len)
33+
__NOEXCEPT __attribute__((nonnull(1, 3))) __attribute((__pure__));
34+
3235
void *memccpy(void *__restrict dest, const void *__restrict src, int c, size_t n)
3336
__NOEXCEPT __attribute__((nonnull(1, 2)));
3437

@@ -74,6 +77,9 @@ char *strpbrk(const char *s, const char *accept)
7477
char *strstr(const char *haystack, const char *needle)
7578
__attribute__((nonnull(1, 2)));
7679

80+
char *strrstr(const char *haystack, const char *needle)
81+
__NOEXCEPT __attribute__((nonnull(1, 2))) __attribute__((__pure__));
82+
7783
char *strcasestr(const char *haystack, const char *needle)
7884
__NOEXCEPT __attribute__((nonnull(1, 2))) __attribute__((__pure__));
7985

src/libc/memrmem.src

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
assume adl=1
2+
3+
section .text
4+
5+
public _memrmem
6+
7+
; void *memrmem(const void *haystack, size_t haystack_len, const void *needle, size_t needle_len)
8+
haystack := iy + 3
9+
haystack_len := iy + 6
10+
needle := iy + 9
11+
needle_len := iy + 12
12+
_memrmem:
13+
ld iy, 0
14+
add iy, sp
15+
ld hl, (haystack_len)
16+
ld bc, (needle_len)
17+
sbc hl, bc
18+
jr c, .ret_null ; (haystack_len < needle_len)
19+
; (haystack_len >= needle_len)
20+
21+
push hl
22+
adc hl, bc
23+
ex de, hl
24+
; DE = needle_len
25+
26+
; move to the end of the needle
27+
ld hl, (needle)
28+
; return haystack when haystack_len is zero (implies that needle_len is also zero)
29+
jr z, .zero_haystack_len
30+
add hl, bc
31+
dec hl
32+
ld (needle), hl
33+
34+
sbc hl, hl
35+
adc hl, bc
36+
pop bc
37+
ld hl, (haystack)
38+
39+
; move to the end of the haystack
40+
add hl, de
41+
dec hl
42+
43+
ret z ; return (haystack + haystack_len - 1) if needle_len is zero
44+
45+
inc bc
46+
; BC = (haystack_len - needle_len + 1) = search_len
47+
; haystack_len >= needle_len && needle_len != 0, therefore haystack_len >= 1
48+
call .begin_loop
49+
jr nz, .ret_null
50+
; test for a match at the last possible position
51+
call _memrcmp_fast
52+
inc hl
53+
ret z
54+
.ret_null:
55+
or a, a
56+
sbc hl, hl
57+
ret
58+
59+
.loop:
60+
pop hl
61+
pop bc
62+
.begin_loop:
63+
ld de, (needle)
64+
ld a, (de)
65+
cpdr ; search for the start of the string
66+
ret po ; end of search_len
67+
push bc
68+
push hl
69+
call _memrcmp_fast
70+
jr nz, .loop
71+
inc hl
72+
ld sp, iy
73+
ret
74+
75+
.zero_haystack_len:
76+
pop hl
77+
ld hl, (haystack)
78+
ret
79+
80+
_memrcmp_fast:
81+
; Input:
82+
; HL = haystack + needle_len - 1
83+
; DE = needle + needle_len - 1
84+
; A = (DE)
85+
; Output:
86+
; Z = match
87+
; NZ = no match
88+
inc hl
89+
ld bc, (needle_len)
90+
.loop:
91+
cpd
92+
ret po
93+
dec de
94+
ld a, (de)
95+
jr z, .loop
96+
ret

src/libc/strrstr.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+
5+
public _strrstr
6+
7+
_strrstr:
8+
pop bc
9+
pop de
10+
ex (sp), hl
11+
push de
12+
push bc
13+
14+
push hl
15+
xor a, a
16+
ld bc, 0
17+
cpir
18+
sbc hl, hl
19+
dec hl
20+
sbc hl, bc ; carry will be cleared
21+
ex (sp), hl ; strlen(needle)
22+
push hl ; needle
23+
24+
ex de, hl
25+
push hl
26+
ld bc, 0
27+
cpir
28+
sbc hl, hl
29+
dec hl
30+
sbc hl, bc
31+
ex (sp), hl ; strlen(haystack)
32+
push hl ; haystack
33+
34+
call _memrmem
35+
pop bc, bc, bc, bc
36+
ret
37+
38+
extern _memrmem

src/libcxx/include/cstring

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ using ::memcmp;
1717
using ::memchr;
1818
using ::memrchr;
1919
using ::memmem;
20+
using ::memrmem;
2021
using ::memccpy;
2122
using ::mempcpy;
2223
using ::strcpy;
@@ -32,6 +33,7 @@ using ::strrchr;
3233
using ::strchrnul;
3334
using ::strpbrk;
3435
using ::strstr;
36+
using ::strrstr;
3537
using ::strcasestr;
3638
using ::strtok;
3739
using ::strdup;

0 commit comments

Comments
 (0)