klibc-bot for Ben Hutchings
2020-Mar-28 21:48 UTC
[klibc] [klibc:update-dash] Implement stpcpy() and stpncpy()
Commit-ID: 89742f0fc6f93a4a748ab783856a9d441511b808 Gitweb: http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=89742f0fc6f93a4a748ab783856a9d441511b808 Author: Ben Hutchings <ben at decadent.org.uk> AuthorDate: Sat, 28 Mar 2020 21:04:54 +0000 Committer: Ben Hutchings <ben at decadent.org.uk> CommitDate: Sat, 28 Mar 2020 21:42:12 +0000 [klibc] Implement stpcpy() and stpncpy() These functions are included in POSIX.1-2008, and current upstream dash now uses stpncpy() without providing a fallback definition. Also add tests for these functions. Signed-off-by: Ben Hutchings <ben at decadent.org.uk> --- usr/include/string.h | 2 ++ usr/klibc/Kbuild | 1 + usr/klibc/stpcpy.c | 19 ++++++++++++ usr/klibc/stpncpy.c | 23 +++++++++++++++ usr/klibc/tests/Kbuild | 1 + usr/klibc/tests/stpcpy.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 121 insertions(+) diff --git a/usr/include/string.h b/usr/include/string.h index 0c8c0461..86d5b6c6 100644 --- a/usr/include/string.h +++ b/usr/include/string.h @@ -45,5 +45,7 @@ __extern size_t strspn(const char *, const char *); __extern char *strstr(const char *, const char *); __extern char *strtok(char *, const char *); __extern char *strtok_r(char *, const char *, char **); +__extern char *stpcpy(char *, const char *); +__extern char *stpncpy(char *, const char *, size_t); #endif /* _STRING_H */ diff --git a/usr/klibc/Kbuild b/usr/klibc/Kbuild index 19ccfbec..b966e306 100644 --- a/usr/klibc/Kbuild +++ b/usr/klibc/Kbuild @@ -46,6 +46,7 @@ klib-y += vsnprintf.o snprintf.o vsprintf.o sprintf.o \ strstr.o strncmp.o strncpy.o strrchr.o \ strxspn.o strspn.o strcspn.o strpbrk.o strsep.o strtok.o \ strtok_r.o \ + stpcpy.o stpncpy.o \ fnmatch.o \ gethostname.o getdomainname.o getcwd.o \ seteuid.o setegid.o \ diff --git a/usr/klibc/stpcpy.c b/usr/klibc/stpcpy.c new file mode 100644 index 00000000..c5fc607d --- /dev/null +++ b/usr/klibc/stpcpy.c @@ -0,0 +1,19 @@ +/* + * stpcpy.c + */ + +#include <string.h> + +char *stpcpy(char *dst, const char *src) +{ + char ch; + + for (;;) { + *dst = ch = *src++; + if (!ch) + break; + dst++; + } + + return dst; +} diff --git a/usr/klibc/stpncpy.c b/usr/klibc/stpncpy.c new file mode 100644 index 00000000..f28992ab --- /dev/null +++ b/usr/klibc/stpncpy.c @@ -0,0 +1,23 @@ +/* + * stpncpy.c + */ + +#include <string.h> + +char *stpncpy(char *dst, const char *src, size_t n) +{ + char *end; + char ch; + + while (n) { + ch = *src++; + if (!ch) + break; + n--; + *dst++ = ch; + } + + end = dst; + memset(dst, 0, n); + return end; +} diff --git a/usr/klibc/tests/Kbuild b/usr/klibc/tests/Kbuild index c7ca531f..50e38160 100644 --- a/usr/klibc/tests/Kbuild +++ b/usr/klibc/tests/Kbuild @@ -42,6 +42,7 @@ sscanf.shared-y := sscanf.o stat.shared-y := stat.o statfs.shared-y := statfs.o stdio.shared-y := stdio.o +stpcpy.shared-y := stpcpy.o strlcpycat.shared-y := strlcpycat.o strtoimax.shared-y := strtoimax.o strtotime.shared-y := strtotime.o diff --git a/usr/klibc/tests/stpcpy.c b/usr/klibc/tests/stpcpy.c new file mode 100644 index 00000000..4340f61a --- /dev/null +++ b/usr/klibc/tests/stpcpy.c @@ -0,0 +1,75 @@ +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +int main(void) +{ + char temp[10]; +#define clear_temp() strcpy(temp, "XXXXXXXXX") + char *end; + + printf("stpcpy:\n"); + + clear_temp(); + end = stpcpy(temp, "123"); + printf("'%s'len:%zu strlen:%zu\n", temp, end - temp, strlen(temp)); + if (end != temp + 3 || memcmp(temp, "123\0XXXXX", 10)) + goto error; + + clear_temp(); + end = stpcpy(temp, ""); + printf("'%s'len:%zu strlen:%zu\n", temp, end - temp, strlen(temp)); + if (end != temp || memcmp(temp, "\0XXXXXXXX", 10)) + goto error; + + clear_temp(); + end = stpcpy(temp, "1234567"); + printf("'%s'len:%zu strlen:%zu\n", temp, end - temp, strlen(temp)); + if (end != temp + 7 || memcmp(temp, "1234567\0X", 10)) + goto error; + + printf("\n"); + printf("stpncpy:\n"); + + clear_temp(); + end = stpncpy(temp, "123", 8); + printf("'%s'len:%zu strnlen:%zu\n", temp, end - temp, strnlen(temp, 8)); + if (end != temp + 3 || memcmp(temp, "123\0\0\0\0\0X", 10)) + goto error; + + clear_temp(); + end = stpncpy(temp, "", 8); + printf("'%s'len:%zu strnlen:%zu\n", temp, end - temp, strnlen(temp, 8)); + if (end != temp || memcmp(temp, "\0\0\0\0\0\0\0\0X", 10)) + goto error; + + clear_temp(); + end = stpncpy(temp, "1234567890", 8); + printf("'%s'len:%zu strnlen:%zu\n", temp, end - temp, strnlen(temp, 8)); + if (end != temp + 8 || memcmp(temp, "12345678X", 10)) + goto error; + + clear_temp(); + end = stpncpy(temp, "123", 5); + printf("'%s'len:%zu strnlen:%zu\n", temp, end - temp, strnlen(temp, 5)); + if (end != temp + 3 || memcmp(temp, "123\0\0XXXX", 10)) + goto error; + + clear_temp(); + end = stpncpy(temp, "123", 1); + printf("'%s'len:%zu strnlen:%zu\n", temp, end - temp, strnlen(temp, 1)); + if (end != temp + 1 || memcmp(temp, "1XXXXXXXX", 10)) + goto error; + + clear_temp(); + end = stpncpy(temp, "123", 0); + printf("'%s'len:%zu strnlen:%zu\n", temp, end - temp, strnlen(temp, 0)); + if (end != temp || memcmp(temp, "XXXXXXXXX", 10)) + goto error; + + exit(0); +error: + printf("unexpected result\n"); + exit(1); +}