Skip to content

Commit 54f0d03

Browse files
committed
added strsep
1 parent 2abce72 commit 54f0d03

File tree

5 files changed

+137
-2
lines changed

5 files changed

+137
-2
lines changed

src/libc/include/string.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ char *strcasestr(const char *haystack, const char *needle)
8686
char *strtok(char *__restrict s, const char *__restrict delim)
8787
__attribute__((nonnull(2)));
8888

89+
char *strsep(char **__restrict s, const char *__restrict delim)
90+
__NOEXCEPT __attribute__((nonnull(1, 2)));
91+
8992
char *strdup(const char *s)
9093
__attribute__((__malloc__)) __attribute__((nonnull(1)));
9194

src/libc/strsep.src

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
assume adl=1
2+
3+
section .text
4+
5+
public _strsep
6+
7+
; char *strsep(char **__restrict stringp, const char *__restrict delim)
8+
_strsep:
9+
pop bc
10+
pop hl
11+
pop de
12+
push de
13+
push hl
14+
push bc
15+
push hl ; stringp
16+
ld hl, (hl)
17+
add hl, de
18+
or a, a
19+
sbc hl, de
20+
jr z, .ret_null
21+
push de ; delim
22+
push hl ; *stringp
23+
call _strcspn
24+
pop de
25+
pop de
26+
pop iy ; stringp
27+
ld de, (iy)
28+
add hl, de ; *stringp + length
29+
xor a, a
30+
cp a, (hl) ; test for the nul terminator
31+
jr nz, .not_last_token
32+
sbc hl, hl ; last token
33+
jr .finish
34+
.not_last_token:
35+
ld (hl), a ; nul terminate
36+
inc hl ; next token
37+
.finish:
38+
ld (iy), hl ; store the next token
39+
ex de, hl
40+
; return *stringp
41+
ret
42+
.ret_null:
43+
pop de
44+
ret
45+
46+
extern _strcspn

src/libcxx/include/cstring

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ using ::strstr;
3636
using ::strrstr;
3737
using ::strcasestr;
3838
using ::strtok;
39+
using ::strsep;
3940
using ::strdup;
4041
using ::strndup;
4142
using ::strcspn;

test/standalone/asprintf_fprintf/src/main.c

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ char *T_strchrnul(const char *s, int c)
100100
char *T_strrstr(const char *haystack, const char *needle)
101101
__attribute__((nonnull(1, 2)));
102102

103+
char *T_strsep(char **__restrict s, const char *__restrict delim)
104+
__attribute__((nonnull(1, 2)));
105+
103106
void T_bzero(void* s, size_t n);
104107

105108
#else
@@ -121,6 +124,7 @@ void T_bzero(void* s, size_t n);
121124
#define T_strncmp strncmp
122125
#define T_strchrnul strchrnul
123126
#define T_strrstr strrstr
127+
#define T_strsep strsep
124128
#define T_bzero bzero
125129

126130
#endif
@@ -1017,6 +1021,75 @@ int strchrnul_test(void) {
10171021
return 0;
10181022
}
10191023

1024+
static char *truth_strsep(char **__restrict stringp, const char *__restrict delim) {
1025+
char * const begin_str = *stringp;
1026+
if (begin_str == NULL) {
1027+
return NULL;
1028+
}
1029+
size_t length = strcspn(begin_str, delim);
1030+
char * end_str = begin_str + length;
1031+
if (*end_str != '\0') {
1032+
*end_str++ = '\0';
1033+
*stringp = end_str;
1034+
} else {
1035+
*stringp = NULL;
1036+
}
1037+
return begin_str;
1038+
}
1039+
1040+
static int strsep_loop_test(char * str_1, char * str_2) {
1041+
for (;;) {
1042+
char *__restrict prev_1 = T_strsep(&str_1, ", .");
1043+
char *__restrict prev_2 = truth_strsep(&str_2, ", .");
1044+
if (str_1 == NULL || str_2 == NULL) {
1045+
break;
1046+
}
1047+
ptrdiff_t diff_1 = (str_1 - prev_1);
1048+
ptrdiff_t diff_2 = (str_2 - prev_2);
1049+
if (diff_1 != diff_2) {
1050+
test_printf("%td != %td\n%p %p\n1: %.20s\n2: %.20s\n", diff_1, diff_2, prev_1, prev_2, str_1, str_2);
1051+
return __LINE__;
1052+
}
1053+
C(diff_1 == diff_2);
1054+
}
1055+
C(str_1 == NULL && str_2 == NULL);
1056+
return 0;
1057+
}
1058+
1059+
int strsep_test(char** dup_1, char** dup_2) {
1060+
{
1061+
char *ptr = NULL_ptr;
1062+
C(T_strsep(&ptr, SINK) == NULL);
1063+
C(T_strsep(&ptr, NULL_ptr) == NULL);
1064+
C(T_strsep((char**)SINK, SINK) == NULL);
1065+
C(T_strsep((char**)SINK, NULL_ptr) == NULL);
1066+
}
1067+
const size_t len = strlen(gnu_copypasta);
1068+
const size_t size = len + 1;
1069+
*dup_1 = strdup(gnu_copypasta);
1070+
*dup_2 = strndup(gnu_copypasta, len);
1071+
C(*dup_1 != NULL && *dup_2 != NULL);
1072+
C(strcmp(*dup_1, *dup_2) == 0);
1073+
{
1074+
char *ptr, *prev;
1075+
ptr = *dup_2;
1076+
prev = T_strsep(&ptr, "");
1077+
C(ptr == NULL);
1078+
C(prev == *dup_2);
1079+
ptr = *dup_2;
1080+
prev = T_strsep(&ptr, "zZ");
1081+
C(ptr == NULL);
1082+
C(prev == *dup_2);
1083+
C(memcmp(*dup_1, *dup_2, size) == 0);
1084+
}
1085+
{
1086+
int ret;
1087+
TEST(strsep_loop_test(*dup_1, *dup_2));
1088+
C(memcmp(*dup_1, *dup_2, size) == 0);
1089+
}
1090+
return 0;
1091+
}
1092+
10201093
int run_tests(void) {
10211094
int ret = 0;
10221095

@@ -1051,6 +1124,17 @@ int run_tests(void) {
10511124
TEST(strrstr_test());
10521125
TEST(strchrnul_test());
10531126

1127+
/* strsep */ {
1128+
char *dup_1 = SINK, *dup_2 = SINK;
1129+
ret = strsep_test(&dup_1, &dup_2);
1130+
if (dup_1 == NULL || dup_2 == NULL) {
1131+
perror("str(n)dup returned NULL");
1132+
}
1133+
free(dup_1); dup_1 = NULL;
1134+
free(dup_2); dup_2 = NULL;
1135+
if (ret != 0) { return ret; }
1136+
}
1137+
10541138
return 0;
10551139
}
10561140

test/standalone/asprintf_fprintf/src/rename.asm

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
section .text
44

55
public _T_memset, _T_memcpy, _T_memmove, _T_memcmp, _T_memccpy, _T_mempcpy, _T_memrchr, _T_memmem, _T_memrmem
6-
public _T_strlen, _T_strcmp, _T_strncmp, _T_stpcpy, _T_stpncpy, _T_strlcat, _T_strchrnul, _T_strrstr
6+
public _T_strlen, _T_strcmp, _T_strncmp, _T_stpcpy, _T_stpncpy, _T_strlcat, _T_strchrnul, _T_strrstr, _T_strsep
77
public _T_bzero
88

99
_T_memset := _memset
@@ -24,6 +24,7 @@ _T_stpncpy := _stpncpy
2424
_T_strlcat := _strlcat
2525
_T_strchrnul := _strchrnul
2626
_T_strrstr := _strrstr
27+
_T_strsep := _strsep
2728

2829
_T_bzero := _bzero
2930

@@ -35,5 +36,5 @@ _ZERO_size:
3536
db $00, $00, $00
3637

3738
extern _memset, _memcpy, _memmove, _memcmp, _memccpy, _mempcpy, _memrchr, _memmem, _memrmem
38-
extern _strlen, _strcmp, _strncmp, _stpcpy, _stpncpy, _strlcat, _strchrnul, _strrstr
39+
extern _strlen, _strcmp, _strncmp, _stpcpy, _stpncpy, _strlcat, _strchrnul, _strrstr, _strsep
3940
extern _bzero

0 commit comments

Comments
 (0)