Skip to content

Commit ed4ca25

Browse files
committed
added stpncpy
1 parent 51eaffb commit ed4ca25

File tree

3 files changed

+108
-2
lines changed

3 files changed

+108
-2
lines changed

src/libc/stpncpy.src

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
assume adl=1
2+
3+
section .text
4+
5+
public _stpncpy
6+
7+
_stpncpy:
8+
ld iy, 0
9+
add iy, sp
10+
ld bc, (iy + 9) ; max_len
11+
12+
; inlined strnlen
13+
xor a, a
14+
sbc hl, hl
15+
sbc hl, bc
16+
jr z, .zero_size
17+
add hl, bc
18+
ld de, (iy + 6) ; src
19+
sbc hl, de
20+
ex de, hl
21+
cpir
22+
jr z, .finish_strnlen
23+
inc hl
24+
.finish_strnlen:
25+
xor a, a
26+
adc hl, de
27+
.zero_size:
28+
29+
; copy strnlen bytes from src
30+
push hl
31+
ld de, (iy + 3) ; dst
32+
jr z, .zero_byte_copy
33+
ld hl, (iy + 6) ; src
34+
pop bc
35+
push bc
36+
ldir
37+
.zero_byte_copy:
38+
pop bc
39+
40+
; zero pad the remainder
41+
ld hl, (iy + 9) ; max_len
42+
scf
43+
sbc hl, bc ; clear_size - 1 = max_len - src_len - 1
44+
ex de, hl
45+
ret c ; clear_size <= 0 (or max_len <= src_len)
46+
; HL = dst + src_len
47+
; DE = clear_size - 1
48+
add hl, de
49+
ld (hl), a
50+
ret z ; clear_size == 1
51+
push de
52+
pop bc
53+
push hl
54+
pop de
55+
dec de
56+
lddr
57+
ret

test/standalone/asprintf_fprintf/src/main.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ void *T_memrchr(const void *s, int c, size_t n)
5656
char *T_stpcpy(char *__restrict dest, const char *__restrict src)
5757
__attribute__((nonnull(1, 2)));
5858

59+
char *T_stpncpy(char *__restrict dest, const char *__restrict src, size_t n)
60+
__attribute__((nonnull(1, 2)));
61+
5962
size_t T_strlcat(void *__restrict dest, const void *__restrict src, size_t n)
6063
__attribute__((nonnull(1, 2)));
6164

@@ -80,6 +83,7 @@ void T_bzero(void* s, size_t n);
8083
#define T_mempcpy mempcpy
8184
#define T_memrchr memrchr
8285
#define T_stpcpy stpcpy
86+
#define T_stpncpy stpncpy
8387
#define T_strlcat strlcat
8488
#define T_strlen strlen
8589
#define T_strcmp strcmp
@@ -653,6 +657,49 @@ int strlcat_test(void) {
653657
return 0;
654658
}
655659

660+
int stpncpy_test(void) {
661+
char text[6];
662+
663+
C(T_stpncpy(NULL_ptr, "", 0) == NULL_ptr + 0);
664+
C(T_stpncpy(NULL_ptr, "foobar", 0) == NULL_ptr + 0);
665+
666+
memset(text, '\xee', 6);
667+
668+
C(T_stpncpy(text, "1", 5) == text + 1);
669+
C(memcmp(text, "1\0\0\0\0\xee", 6) == 0);
670+
671+
C(T_stpncpy(text, "1234", 5) == text + 4);
672+
C(memcmp(text, "1234\0\xee", 6) == 0);
673+
674+
C(T_stpncpy(text, "12345", 5) == text + 5);
675+
C(memcmp(text, "12345\xee", 6) == 0);
676+
677+
C(T_stpncpy(text, "123456", 5) == text + 5);
678+
C(memcmp(text, "12345\xee", 6) == 0);
679+
680+
memset(text, '\xff', 6);
681+
682+
C(T_stpncpy(text, "", 0) == text + 0);
683+
C(memcmp(text, "\xff\xff\xff\xff\xff\xff", 6) == 0);
684+
685+
C(T_stpncpy(text, "123456", 1) == text + 1);
686+
C(memcmp(text, "1\xff\xff\xff\xff\xff", 1) == 0);
687+
688+
C(T_stpncpy(text, "6", 1) == text + 1);
689+
C(memcmp(text, "6\xff\xff\xff\xff\xff", 1) == 0);
690+
691+
C(T_stpncpy(text, "", 1) == text + 0);
692+
C(memcmp(text, "\0\xff\xff\xff\xff\xff", 1) == 0);
693+
694+
C(T_stpncpy(text, "a", 2) == text + 1);
695+
C(memcmp(text, "a\0\xff\xff\xff\xff", 1) == 0);
696+
697+
C(T_stpncpy(text, "", 5) == text + 0);
698+
C(memcmp(text, "\0\0\0\0\0\xff", 1) == 0);
699+
700+
return 0;
701+
}
702+
656703
int run_tests(void) {
657704
int ret = 0;
658705
/* boot_asprintf */
@@ -680,6 +727,7 @@ int run_tests(void) {
680727
TEST(memrchr_test());
681728
TEST(memmove_test());
682729
TEST(strlcat_test());
730+
TEST(stpncpy_test());
683731

684732
return 0;
685733
}

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
6-
public _T_strlen, _T_strcmp, _T_strncmp, _T_stpcpy, _T_strlcat
6+
public _T_strlen, _T_strcmp, _T_strncmp, _T_stpcpy, _T_stpncpy, _T_strlcat
77
public _T_bzero
88

99
_T_memset := _memset
@@ -18,6 +18,7 @@ _T_strlen := _strlen
1818
_T_strcmp := _strcmp
1919
_T_strncmp := _strncmp
2020
_T_stpcpy := _stpcpy
21+
_T_stpncpy := _stpncpy
2122
_T_strlcat := _strlcat
2223

2324
_T_bzero := _bzero
@@ -29,5 +30,5 @@ _NULL_ptr:
2930
db $00, $00, $00
3031

3132
extern _memset, _memcpy, _memmove, _memcmp, _memccpy, _mempcpy, _memrchr
32-
extern _strlen, _strcmp, _strncmp, _stpcpy, _strlcat
33+
extern _strlen, _strcmp, _strncmp, _stpcpy, _stpncpy, _strlcat
3334
extern _bzero

0 commit comments

Comments
 (0)