From 921e54917268637498610d5fb41c3836bf8b384a Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Fri, 24 Dec 2021 23:44:57 +0100 Subject: [PATCH 1/6] Add standard C library function strnlen(). --- include/string.h | 1 + libsrc/common/strnlen.s | 54 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 libsrc/common/strnlen.s diff --git a/include/string.h b/include/string.h index 2f5953196..74442415f 100644 --- a/include/string.h +++ b/include/string.h @@ -50,6 +50,7 @@ char* __fastcall__ strcpy (char* dest, const char* src); size_t __fastcall__ strcspn (const char* s1, const char* s2); char* __fastcall__ strerror (int errcode); size_t __fastcall__ strlen (const char* s); +size_t __fastcall__ strnlen (const char* s, size_t maxlen); char* __fastcall__ strncat (char* s1, const char* s2, size_t count); int __fastcall__ strncmp (const char* s1, const char* s2, size_t count); char* __fastcall__ strncpy (char* dest, const char* src, size_t count); diff --git a/libsrc/common/strnlen.s b/libsrc/common/strnlen.s new file mode 100644 index 000000000..e748325e2 --- /dev/null +++ b/libsrc/common/strnlen.s @@ -0,0 +1,54 @@ +; size_t __fastcall__ strnlen (const char* s, size_t maxlen); + +.export _strnlen +.import popax +.importzp ptr1, tmp1, tmp2, tmp3, tmp4 + +.proc _strnlen + ; Fetch string pointer. + sta ptr1 + stx ptr1+1 + + ; Clear return value. + lda #0 + sta tmp1 + sta tmp2 + + ; Get maximum length. + jsr popax + sta tmp3 + inc tmp3 + inx + stx tmp4 + + ;;; Loop over string. + ldy #0 + + ; Decrement maximum length. +next: dec tmp3 + bne l2 + dec tmp4 + beq done +l2: + + lda (ptr1),y + beq done + + ; Step to next character. + inc ptr1 + bne l1 + inc ptr1+1 +l1: + + ; Increment return value. + inc tmp1 + bne next + inc tmp2 + + jmp next + + +done: lda tmp1 + ldx tmp2 + rts +.endproc From 0b84465276dc2c6e2f380a3d26b1e08c3015b0ac Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Sat, 25 Dec 2021 09:11:58 +0100 Subject: [PATCH 2/6] Fix strnlen(). --- libsrc/common/strnlen.s | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/libsrc/common/strnlen.s b/libsrc/common/strnlen.s index e748325e2..eb2c16006 100644 --- a/libsrc/common/strnlen.s +++ b/libsrc/common/strnlen.s @@ -5,25 +5,25 @@ .importzp ptr1, tmp1, tmp2, tmp3, tmp4 .proc _strnlen + ; Get maximum length. + tay + iny + sty tmp3 + inx + stx tmp4 + ; Fetch string pointer. + jsr popax sta ptr1 stx ptr1+1 ; Clear return value. - lda #0 - sta tmp1 - sta tmp2 + ldy #0 + sty tmp1 + sty tmp2 - ; Get maximum length. - jsr popax - sta tmp3 - inc tmp3 - inx - stx tmp4 ;;; Loop over string. - ldy #0 - ; Decrement maximum length. next: dec tmp3 bne l2 @@ -35,7 +35,7 @@ l2: beq done ; Step to next character. - inc ptr1 + iny bne l1 inc ptr1+1 l1: @@ -45,7 +45,7 @@ l1: bne next inc tmp2 - jmp next + bne next ; (jmp) done: lda tmp1 From c9ccc82b9f8d43daf489c4139d8383206a7aa925 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Sat, 25 Dec 2021 09:12:13 +0100 Subject: [PATCH 3/6] strnlen(): Add comment with POSIX standard. --- include/string.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/string.h b/include/string.h index 74442415f..70abd5851 100644 --- a/include/string.h +++ b/include/string.h @@ -50,7 +50,7 @@ char* __fastcall__ strcpy (char* dest, const char* src); size_t __fastcall__ strcspn (const char* s1, const char* s2); char* __fastcall__ strerror (int errcode); size_t __fastcall__ strlen (const char* s); -size_t __fastcall__ strnlen (const char* s, size_t maxlen); +size_t __fastcall__ strnlen (const char* s, size_t maxlen); /* POSIX.1-2008 */ char* __fastcall__ strncat (char* s1, const char* s2, size_t count); int __fastcall__ strncmp (const char* s1, const char* s2, size_t count); char* __fastcall__ strncpy (char* dest, const char* src, size_t count); From 87fe2f5d0ea7536fcfbf2dd9523bcf47cc30a227 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Sat, 25 Dec 2021 09:13:43 +0100 Subject: [PATCH 4/6] Add test of strnlen(). --- targettest/Makefile | 4 ++++ targettest/strnlen.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 targettest/strnlen.c diff --git a/targettest/Makefile b/targettest/Makefile index f3694335c..44933949a 100644 --- a/targettest/Makefile +++ b/targettest/Makefile @@ -160,6 +160,7 @@ EXELIST_c64 = \ scanf-test \ ser-test \ strdup-test \ + strnlen \ stroserror-test \ strqtok-test \ tinyshell \ @@ -190,6 +191,7 @@ EXELIST_vic20 = \ rename-test \ scanf-test \ strdup-test \ + strnlen \ stroserror-test \ strqtok-test \ tinyshell \ @@ -222,6 +224,7 @@ EXELIST_apple2 = \ seek \ ser-test \ strdup-test \ + strnlen \ stroserror-test \ strqtok-test \ tinyshell \ @@ -257,6 +260,7 @@ EXELIST_atari = \ seek \ ser-test \ strdup-test \ + strnlen \ stroserror-test \ strqtok-test \ tinyshell \ diff --git a/targettest/strnlen.c b/targettest/strnlen.c new file mode 100644 index 000000000..d07b7628c --- /dev/null +++ b/targettest/strnlen.c @@ -0,0 +1,32 @@ +#include +#include +#include + +const char * str = "0123456789"; + +void +check (size_t result, size_t expected) +{ + if (result != expected) { + printf ("Expected strnlen() to return %d, got %d.\n", + expected, result); + exit (EXIT_FAILURE); + } +} + +int +main (void) +{ + size_t maxlen = strlen (str); + size_t result; + size_t expected; + + for (expected = 0; expected < maxlen; expected++) + check (strnlen (str, expected), expected); + + check (strnlen (str, maxlen << 1), maxlen); + + printf ("strnlen() OK.\n"); + + return EXIT_SUCCESS; +} From 666f266e900653fc4f27ba5839b08630af36136b Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Sat, 25 Dec 2021 14:21:47 +0100 Subject: [PATCH 5/6] Move strnlen() to non-ANSI section. --- include/string.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/string.h b/include/string.h index 70abd5851..83970493e 100644 --- a/include/string.h +++ b/include/string.h @@ -50,7 +50,6 @@ char* __fastcall__ strcpy (char* dest, const char* src); size_t __fastcall__ strcspn (const char* s1, const char* s2); char* __fastcall__ strerror (int errcode); size_t __fastcall__ strlen (const char* s); -size_t __fastcall__ strnlen (const char* s, size_t maxlen); /* POSIX.1-2008 */ char* __fastcall__ strncat (char* s1, const char* s2, size_t count); int __fastcall__ strncmp (const char* s1, const char* s2, size_t count); char* __fastcall__ strncpy (char* dest, const char* src, size_t count); @@ -79,6 +78,7 @@ int __fastcall__ stricmp (const char* s1, const char* s2); /* DOS/Windows */ int __fastcall__ strcasecmp (const char* s1, const char* s2); /* Same for Unix */ 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 */ char* __fastcall__ strlwr (char* s); char* __fastcall__ strlower (char* s); char* __fastcall__ strupr (char* s); From d1cbb1deebe0b015f90e954b7a07ab78fe96f165 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Sat, 25 Dec 2021 20:04:10 +0100 Subject: [PATCH 6/6] More strict printf() format string. --- targettest/strnlen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targettest/strnlen.c b/targettest/strnlen.c index d07b7628c..ac39f2396 100644 --- a/targettest/strnlen.c +++ b/targettest/strnlen.c @@ -8,7 +8,7 @@ void check (size_t result, size_t expected) { if (result != expected) { - printf ("Expected strnlen() to return %d, got %d.\n", + printf ("Expected strnlen() to return %u, got %u.\n", expected, result); exit (EXIT_FAILURE); }