From 423c7c8086c92585759901eb5f2cb46d57900847 Mon Sep 17 00:00:00 2001 From: unknown <71151164+ZERICO2005@users.noreply.github.com> Date: Thu, 13 Mar 2025 11:48:04 -0600 Subject: [PATCH 1/5] Added asprintf and fprintf along with ti_sprintf macros --- src/ce/include/ti_sprintf.h | 65 +++++++++++++++++++ .../ti_routines.src => ce/ti_sprintf.src} | 18 ++--- src/libc/errno_str.c | 10 +-- src/libc/include/stdio.h | 25 ++++--- src/libc/include/time.h | 3 +- src/libc/nanoprintf.c | 64 +++++++++++++++--- src/libc/printf.src | 16 ++++- src/libcxx/include/cstdio | 6 +- 8 files changed, 171 insertions(+), 36 deletions(-) create mode 100644 src/ce/include/ti_sprintf.h rename src/{libc/ti_routines.src => ce/ti_sprintf.src} (75%) diff --git a/src/ce/include/ti_sprintf.h b/src/ce/include/ti_sprintf.h new file mode 100644 index 000000000..2c34e7964 --- /dev/null +++ b/src/ce/include/ti_sprintf.h @@ -0,0 +1,65 @@ +#ifndef TI_SPRINTF_H +#define TI_SPRINTF_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief C89 `sprintf`. `long` arguments and width specifiers are unsupported. + * @note `%s` will write up to 255 characters. + */ +int ti_sprintf( + char *__restrict buffer, const char *__restrict format, ... +) __attribute__((format (__printf__, 2, 3))); + +/** + * @brief Returns an empty string if the output from sprintf does not fit. + * @warning `__VA_ARGS__` is evaluated twice. + * @note Undefined behaviour if the output is longer than ~258000 characters. + */ +#define ti_snprintf(buffer, count, ...)\ +({\ + char * const __buffer = buffer;\ + const int __count = count;\ + int __ret = -1;\ + int __str_len = ti_sprintf((char*)0xFC1000, __VA_ARGS__);\ + if (__buffer == NULL || __count == 0) {\ + __ret = __str_len;\ + } else if ((size_t)__str_len > __count) {\ + *__buffer = '\0'; /* won't fit or invalid formatting */\ + } else {\ + __ret = ti_sprintf(__buffer, __VA_ARGS__);\ + }\ + __ret;\ +}) + +/** + * @brief Allocates a null terminated string containing the output of sprintf. + * The returned pointer shall be deallocated with `free`. + * @warning `__VA_ARGS__` is evaluated twice. + * @note Undefined behaviour if the output is longer than ~258000 characters. + */ +#define ti_asprintf(p_buffer, ...)\ +({\ + char** const __p_buffer = p_buffer;\ + int __ret = -1;\ + int __str_len = ti_sprintf((char*)0xFC1000, __VA_ARGS__);\ + if (__str_len >= 0) {\ + size_t __buffer_size = (size_t)__str_len + 1;\ + *__p_buffer = (char*)malloc(__buffer_size);\ + if (*__p_buffer != NULL) {\ + __ret = ti_sprintf(*__p_buffer, __VA_ARGS__);\ + }\ + }\ + __ret;\ +}) + +#ifdef __cplusplus +} +#endif + +#endif /* TI_SPRINTF_H */ diff --git a/src/libc/ti_routines.src b/src/ce/ti_sprintf.src similarity index 75% rename from src/libc/ti_routines.src rename to src/ce/ti_sprintf.src index 8854e82ab..1097099fb 100644 --- a/src/libc/ti_routines.src +++ b/src/ce/ti_sprintf.src @@ -1,9 +1,9 @@ - assume adl=1 - - section .text - -; to reduce binary size (or performance in the case of sprintf), ti's routines -; can be linked instead of the toolchain's routines - - public __ti_sprintf -__ti_sprintf := 0000BCh + assume adl=1 + + section .text + +; to reduce binary size (or performance in the case of sprintf), ti's routines +; can be linked instead of the toolchain's routines + + public _ti_sprintf +_ti_sprintf := 0000BCh diff --git a/src/libc/errno_str.c b/src/libc/errno_str.c index 636a659ab..9a708ff21 100644 --- a/src/libc/errno_str.c +++ b/src/libc/errno_str.c @@ -2,10 +2,7 @@ #include #include #include - -int _ti_sprintf( - char *__restrict buffer, const char *__restrict format, ... -) __attribute__ ((format (__printf__, 2, 3))); +#include static char const * const errno_strings[] = { "no error", @@ -32,7 +29,7 @@ static_assert( char* strerror(int errnum) { if ((unsigned int)errnum >= errno_strings_count) { - _ti_sprintf(&(unknown_errno_string[unknown_errno_number_offset]), "%d", errnum); + ti_sprintf(&(unknown_errno_string[unknown_errno_number_offset]), "%d", errnum); return (char*)unknown_errno_string; } return (char*)errno_strings[errnum]; @@ -48,8 +45,7 @@ size_t strerrorlen_s(errno_t errnum) { void perror(const char *str) { if (str != NULL && *str != '\0') { fputs(str, stderr); - fputc(':', stderr); - fputc(' ', stderr); + fputs(": ", stderr); } fputs(strerror(errno), stderr); fputc('\n', stderr); diff --git a/src/libc/include/stdio.h b/src/libc/include/stdio.h index 5cf5bbef6..309a8e9c1 100644 --- a/src/libc/include/stdio.h +++ b/src/libc/include/stdio.h @@ -89,20 +89,29 @@ int printf(const char *__restrict format, ...) int vprintf(const char *__restrict format, va_list va) __attribute__((format(__printf__, 1, 0))); -int vsprintf(char *__restrict buffer, const char *__restrict format, - va_list va) - __attribute__((format(__printf__, 1, 0))); +int sprintf(char *__restrict buffer, const char *__restrict format, ...) + __attribute__((format (__printf__, 2, 3))); + +int vsprintf(char *__restrict buffer, const char *__restrict format, va_list va) + __attribute__((format(__printf__, 2, 0))); int snprintf(char* buffer, size_t count, const char *__restrict format, ...) __attribute__((format(__printf__, 3, 4))); -int vsnprintf(char* buffer, size_t count, const char *__restrict format, - va_list va) +int vsnprintf(char* buffer, size_t count, const char *__restrict format, va_list va) __attribute__((format(__printf__, 3, 0))); -int sprintf(char *__restrict buffer, - const char *__restrict format, ...) - __attribute__ ((format (__printf__, 2, 3))); +int fprintf(FILE* __restrict stream, const char* __restrict format, ...) + __attribute__((format (__printf__, 2, 3))); + +int vfprintf(FILE* __restrict stream, const char* __restrict format, va_list va) + __attribute__((format(__printf__, 2, 0))); + +int asprintf(char **__restrict p_buffer, const char *__restrict format, ...) + __attribute__((format (__printf__, 2, 3))); + +int vasprintf(char **__restrict p_buffer, const char *__restrict format, va_list va) + __attribute__((format(__printf__, 2, 0))); void perror(const char* str); diff --git a/src/libc/include/time.h b/src/libc/include/time.h index 9dc41579a..e5da9ab0a 100644 --- a/src/libc/include/time.h +++ b/src/libc/include/time.h @@ -45,7 +45,8 @@ char *asctime(const struct tm *tmp); char *ctime(const time_t *timer); -size_t strftime(char* ptr, size_t maxsize, const char* format, const struct tm* timeptr); +size_t strftime(char* ptr, size_t maxsize, const char* format, const struct tm* timeptr) + __attribute__((format(__strftime__, 3, 0))); __END_DECLS diff --git a/src/libc/nanoprintf.c b/src/libc/nanoprintf.c index f7b869795..16e71a623 100644 --- a/src/libc/nanoprintf.c +++ b/src/libc/nanoprintf.c @@ -48,6 +48,7 @@ #include #include #include +#include /* malloc */ // Pick reasonable defaults if nothing's been configured. #if !defined(NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS) && \ @@ -640,6 +641,10 @@ static void npf_putc_std(int c, void *ctx) { outchar(c); } +static void npf_fputc_std(int c, void *ctx) { + fputc(c, (FILE*)ctx); +} + typedef struct npf_cnt_putc_ctx { npf_putc pc; void *ctx; @@ -978,10 +983,10 @@ int npf_vpprintf(npf_putc pc, void *pc_ctx, char const *format, va_list args) { #undef NPF_WRITEBACK int _printf_c(char const *format, ...) { - va_list val; - va_start(val, format); - int const rv = vprintf(format, val); - va_end(val); + va_list va; + va_start(va, format); + int const rv = vprintf(format, va); + va_end(va); return rv; } @@ -1005,10 +1010,10 @@ int _vsnprintf_c(char *buffer, size_t bufsz, char const *format, va_list vlist) } int _snprintf_c(char *buffer, size_t bufsz, const char *format, ...) { - va_list val; - va_start(val, format); - int const rv = vsnprintf(buffer, bufsz, format, val); - va_end(val); + va_list va; + va_start(va, format); + int const rv = vsnprintf(buffer, bufsz, format, va); + va_end(va); return rv; } @@ -1031,6 +1036,49 @@ int _sprintf_c(char *buffer, const char *format, ...) return ret; } +int _vasprintf_c(char **__restrict p_str, const char *__restrict format, va_list vlist) { + *p_str = NULL; + int str_len = vsnprintf(NULL, 0, format, vlist); + if (str_len <= 0) { + return str_len; + } + size_t buf_len = (size_t)str_len + 1; + char* buf = (char*)malloc(buf_len); + if (buf == NULL) { + // malloc failure + return -1; + } + int ret = vsnprintf(buf, buf_len, format, vlist); + if (ret <= 0) { + free(buf); + return ret; + } + *p_str = buf; + return ret; +} + +int _asprintf_c(char **__restrict p_str, const char *__restrict format, ...) { + va_list va; + va_start(va, format); + const int ret = vasprintf(p_str, format, va); + va_end(va); + return ret; +} + +int _vfprintf_c(FILE* __restrict stream, const char* __restrict format, va_list vlist) +{ + return npf_vpprintf(npf_fputc_std, (void*)stream, format, vlist); +} + +int _fprintf_c(FILE* __restrict stream, const char* __restrict format, ...) +{ + va_list va; + va_start(va, format); + const int ret = vfprintf(stream, format, va); + va_end(va); + return ret; +} + #if NANOPRINTF_HAVE_GCC_WARNING_PRAGMAS #pragma GCC diagnostic pop #endif diff --git a/src/libc/printf.src b/src/libc/printf.src index 4b6f1a01d..c7eb99ce0 100644 --- a/src/libc/printf.src +++ b/src/libc/printf.src @@ -10,20 +10,32 @@ if HAS_PRINTF public _vsprintf public _snprintf public _vsnprintf + public _asprintf + public _vasprintf + public _fprintf + public _vfprintf _printf := __printf_c _vprintf := __vprintf_c +_sprintf := __sprintf_c _vsprintf := __vsprintf_c _snprintf := __snprintf_c _vsnprintf := __vsnprintf_c -_sprintf := __sprintf_c +_asprintf := __asprintf_c +_vasprintf := __vasprintf_c +_fprintf := __fprintf_c +_vfprintf := __vfprintf_c extern __printf_c extern __vprintf_c + extern __sprintf_c extern __vsprintf_c extern __snprintf_c extern __vsnprintf_c - extern __sprintf_c + extern __asprintf_c + extern __vasprintf_c + extern __fprintf_c + extern __vfprintf_c else diff --git a/src/libcxx/include/cstdio b/src/libcxx/include/cstdio index accb75612..fe616946a 100644 --- a/src/libcxx/include/cstdio +++ b/src/libcxx/include/cstdio @@ -31,10 +31,14 @@ using ::putchar; using ::puts; using ::printf; using ::vprintf; +using ::sprintf; using ::vsprintf; using ::snprintf; using ::vsnprintf; -using ::sprintf; +using ::fprintf; +using ::vfprintf; +using ::asprintf; +using ::vasprintf; using ::perror; } // namespace std From b7b4ee9ea6b4ea8f7e838e66abf42771e4f976af Mon Sep 17 00:00:00 2001 From: unknown <71151164+ZERICO2005@users.noreply.github.com> Date: Thu, 20 Mar 2025 23:18:41 -0600 Subject: [PATCH 2/5] Added stpcpy and memccpy calc84maniac --- src/libc/include/string.h | 74 ++++++++++++++++++++++++-------------- src/libc/memccpy.src | 30 ++++++++++++++++ src/libc/stpcpy.src | 24 +++++++++++++ src/libcxx/include/cstring | 5 +++ 4 files changed, 106 insertions(+), 27 deletions(-) create mode 100644 src/libc/memccpy.src create mode 100644 src/libc/stpcpy.src diff --git a/src/libc/include/string.h b/src/libc/include/string.h index 937569047..0280cb9d9 100644 --- a/src/libc/include/string.h +++ b/src/libc/include/string.h @@ -5,72 +5,92 @@ __BEGIN_DECLS -extern void *memcpy(void *__restrict dest, const void *__restrict src, - size_t n) __attribute__((nonnull(1, 2))); +extern void *memcpy(void *__restrict dest, const void *__restrict src, size_t n) + __attribute__((nonnull(1, 2))); void *memmove(void *dest, const void *src, size_t n) - __attribute__((nonnull(1, 2))); + __attribute__((nonnull(1, 2))); -void *memset(void *s, int c, size_t n) __attribute__((nonnull(1))); +void *memset(void *s, int c, size_t n) + __attribute__((nonnull(1))); int memcmp(const void *s1, const void *s2, size_t n) - __attribute__((nonnull(1, 2))); + __attribute__((nonnull(1, 2))); -void *memchr(const void *s, int c, size_t n) __attribute__((nonnull(1))); +void *memchr(const void *s, int c, size_t n) + __attribute__((nonnull(1))); + +void* memccpy(void *__restrict dest, const void *__restrict src, int c, size_t n) __NOEXCEPT + __attribute__((nonnull(1, 2))); char *strcpy(char *__restrict dest, const char *__restrict src) - __attribute__((nonnull(1, 2))); + __attribute__((nonnull(1, 2))); char *strncpy(char *__restrict dest, const char *__restrict src, size_t n) - __attribute__((nonnull(1, 2))); + __attribute__((nonnull(1, 2))); + +char *stpcpy(char *__restrict dest, const char *__restrict src) __NOEXCEPT + __attribute__((nonnull(1, 2))); + +char *stpncpy(char *__restrict dest, const char *__restrict src, size_t n) __NOEXCEPT + __attribute__((nonnull(1, 2))); + +char *strlcpy(char *__restrict dest, const char *__restrict src, size_t n) __NOEXCEPT + __attribute__((nonnull(1, 2))); char *strcat(char *__restrict dest, const char *__restrict src) - __attribute__((nonnull(1, 2))); + __attribute__((nonnull(1, 2))); char *strncat(char *__restrict dest, const char *__restrict src, size_t n) - __attribute__((nonnull(1, 2))); + __attribute__((nonnull(1, 2))); + +char *strlcat(char *__restrict dest, const char *__restrict src, size_t n) __NOEXCEPT + __attribute__((nonnull(1, 2))); -char *strchr(const char *s, int c) __attribute__((nonnull(1))); +char *strchr(const char *s, int c) + __attribute__((nonnull(1))); -char *strrchr(const char *s, int c) __attribute__((nonnull(1))); +char *strrchr(const char *s, int c) + __attribute__((nonnull(1))); -char *strpbrk(const char *s, const char *accept) __attribute__((nonnull(1, 2))); +char *strpbrk(const char *s, const char *accept) + __attribute__((nonnull(1, 2))); char *strstr(const char *haystack, const char *needle) - __attribute__((nonnull(1, 2))); + __attribute__((nonnull(1, 2))); char *strtok(char *__restrict s, const char *__restrict delim) - __attribute__((nonnull(2))); + __attribute__((nonnull(2))); char *strdup(const char *s) - __attribute__ ((__malloc__)) __attribute__((nonnull(1))); + __attribute__((__malloc__)) __attribute__((nonnull(1))); char *strndup(const char *s, size_t n) - __attribute__ ((__malloc__)) __attribute__((nonnull(1))); + __attribute__((__malloc__)) __attribute__((nonnull(1))); size_t strcspn(const char *s, const char *reject) - __attribute__((nonnull(1, 2))); + __attribute__((nonnull(1, 2))); size_t strspn(const char *s, const char *accept) - __attribute__((nonnull(1, 2))); + __attribute__((nonnull(1, 2))); size_t strlen(const char *s) - __attribute__((nonnull(1))); + __attribute__((nonnull(1))); size_t strnlen(const char *s, size_t maxlen) - __attribute__((nonnull(1))); + __attribute__((nonnull(1))); int strcmp(const char *s1, const char *s2) - __attribute__((nonnull(1, 2))); + __attribute__((nonnull(1, 2))); int strncmp(const char *s1, const char *s2, size_t n) - __attribute__((nonnull(1, 2))); + __attribute__((nonnull(1, 2))); -int strcasecmp(const char *s1, const char *s2) - __attribute__((nonnull(1, 2))); +int strcasecmp(const char *s1, const char *s2) __NOEXCEPT + __attribute__((nonnull(1, 2))) __attribute__((__pure__)); -int strncasecmp(const char *s1, const char *s2, size_t n) - __attribute__((nonnull(1, 2))); +int strncasecmp(const char *s1, const char *s2, size_t n) __NOEXCEPT + __attribute__((nonnull(1, 2))) __attribute__((__pure__)); char* strerror(int errnum); diff --git a/src/libc/memccpy.src b/src/libc/memccpy.src new file mode 100644 index 000000000..fa729cd68 --- /dev/null +++ b/src/libc/memccpy.src @@ -0,0 +1,30 @@ + assume adl=1 + + section .text + + public _memccpy + +_memccpy: + ld iy, 0 + add iy, sp + ld bc, (iy + 12) + sbc hl, hl + adc hl, bc + ret z + ld de, (iy + 6) + push de + sbc hl, hl + sbc hl, de + ex de, hl + ld a, (iy + 9) + cpir + add hl, de + ex (sp), hl + pop bc + ld de, (iy + 3) + ldir + ex de, hl + ret z + or a, a + sbc hl, hl + ret diff --git a/src/libc/stpcpy.src b/src/libc/stpcpy.src new file mode 100644 index 000000000..17fae2250 --- /dev/null +++ b/src/libc/stpcpy.src @@ -0,0 +1,24 @@ + assume adl=1 + + section .text + + public _stpcpy + +_stpcpy: + pop bc + pop de + ex (sp), hl + push de + push bc + xor a, a + ld bc, 0 + push hl + cpir + sbc hl, hl + sbc hl, bc + ex (sp), hl + pop bc + ldir + ex de, hl + dec hl + ret diff --git a/src/libcxx/include/cstring b/src/libcxx/include/cstring index 90c5655f8..141419748 100644 --- a/src/libcxx/include/cstring +++ b/src/libcxx/include/cstring @@ -14,10 +14,15 @@ using ::memmove; using ::memset; using ::memcmp; using ::memchr; +using ::memccpy; using ::strcpy; using ::strncpy; +using ::stpcpy; +using ::stpncpy; +using ::strlcpy; using ::strcat; using ::strncat; +using ::strlcat; using ::strchr; using ::strrchr; using ::strpbrk; From a9056ac73c255bfa1846c2ea7ab25dd50d617af6 Mon Sep 17 00:00:00 2001 From: unknown <71151164+ZERICO2005@users.noreply.github.com> Date: Fri, 21 Mar 2025 16:31:31 -0600 Subject: [PATCH 3/5] Added tests for asprintf, fprintf, stpcpy, memccpy, and --- src/libc/include/stdio.h | 4 +- .../standalone/asprintf_fprintf/autotest.json | 40 +++ test/standalone/asprintf_fprintf/makefile | 18 ++ test/standalone/asprintf_fprintf/src/main.c | 275 ++++++++++++++++++ 4 files changed, 335 insertions(+), 2 deletions(-) create mode 100644 test/standalone/asprintf_fprintf/autotest.json create mode 100644 test/standalone/asprintf_fprintf/makefile create mode 100644 test/standalone/asprintf_fprintf/src/main.c diff --git a/src/libc/include/stdio.h b/src/libc/include/stdio.h index 309a8e9c1..879239b6e 100644 --- a/src/libc/include/stdio.h +++ b/src/libc/include/stdio.h @@ -108,10 +108,10 @@ int vfprintf(FILE* __restrict stream, const char* __restrict format, va_list va) __attribute__((format(__printf__, 2, 0))); int asprintf(char **__restrict p_buffer, const char *__restrict format, ...) - __attribute__((format (__printf__, 2, 3))); + __attribute__((format (__printf__, 2, 3))) __attribute__((nonnull(1))); int vasprintf(char **__restrict p_buffer, const char *__restrict format, va_list va) - __attribute__((format(__printf__, 2, 0))); + __attribute__((format(__printf__, 2, 0))) __attribute__((nonnull(1))); void perror(const char* str); diff --git a/test/standalone/asprintf_fprintf/autotest.json b/test/standalone/asprintf_fprintf/autotest.json new file mode 100644 index 000000000..e02763d68 --- /dev/null +++ b/test/standalone/asprintf_fprintf/autotest.json @@ -0,0 +1,40 @@ +{ + "transfer_files": [ + "bin/DEMO.8xp" + ], + "target": { + "name": "DEMO", + "isASM": true + }, + "sequence": [ + "action|launch", + "delay|1500", + "hashWait|1", + "key|enter", + "delay|300", + "hashWait|2" + ], + "hashes": { + "1": { + "description": "All tests passed", + "timeout": 5000, + "start": "vram_start", + "size": "vram_16_size", + "expected_CRCs": [ + "38E2AD5A" + ] + }, + "2": { + "description": "Exit", + "start": "vram_start", + "size": "vram_16_size", + "expected_CRCs": [ + "FFAF89BA", + "101734A5", + "9DA19F44", + "A32840C8", + "349F4775" + ] + } + } +} diff --git a/test/standalone/asprintf_fprintf/makefile b/test/standalone/asprintf_fprintf/makefile new file mode 100644 index 000000000..3efc55361 --- /dev/null +++ b/test/standalone/asprintf_fprintf/makefile @@ -0,0 +1,18 @@ +# ---------------------------- +# Makefile Options +# ---------------------------- + +NAME = DEMO +ICON = icon.png +DESCRIPTION = "CE C Toolchain Demo" +COMPRESSED = NO +ARCHIVED = NO + +CFLAGS = -Wall -Wextra -Oz +CXXFLAGS = -Wall -Wextra -Oz + +PREFER_OS_LIBC = NO + +# ---------------------------- + +include $(shell cedev-config --makefile) diff --git a/test/standalone/asprintf_fprintf/src/main.c b/test/standalone/asprintf_fprintf/src/main.c new file mode 100644 index 000000000..a85f8fd01 --- /dev/null +++ b/test/standalone/asprintf_fprintf/src/main.c @@ -0,0 +1,275 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * @brief Tests the following functions/macros: + * ti_sprintf + * ti_snprintf + * ti_asprintf + * asprintf + * fprintf + * stpcpy + * memccpy + */ + +static char const * const test_1 = +"+123 asprintf% 076543 0x9abcd 0XFE1 0\n"; +static char const * const test_2 = +"+123 asprintf% 076543 0x9abcd 0XFE1 0\nfoo"; +static const int pos_1 = 30; +static const int pos_2 = 42; + +static char* buf = NULL; +static FILE* file = NULL; + +int ti_tests(void) { + int pos; + int len = ti_asprintf( + &buf, "%+d %s%% %#o %#x %n %#X %i\n", + 123, "asprintf", 076543, 0x9abcd, &pos, 0xFE1, 0 + ); + if (buf == NULL || len <= 0) { + printf("buf %p len %d\n", buf, len); + return __LINE__; + } + if (buf[len] != '\0') { + return __LINE__; + } + size_t buf_len = strlen(buf); + if (buf_len != strlen(test_1) || buf_len != (size_t)len) { + printf("E: %zu != %zu != %d\n", strlen(test_1), buf_len, len); + return __LINE__; + } + if (pos != pos_1) { + printf("E: %d != %d\n", pos, pos_1); + return __LINE__; + } + int cmp = strcmp(buf, test_1); + if (cmp != 0) { + printf("cmp: %d\n", cmp); + return __LINE__; + } + char append[128]; + int snprintf_test = ti_snprintf(append, 20, "%s", test_1); + if (snprintf_test >= 0) { + printf("sprintf_test: %d\n", snprintf_test); + return __LINE__; + } + int len_2 = ti_snprintf(append, sizeof(append), "%s", test_1); + if (len_2 != strlen(test_1)) { + printf("E: %d != %zu\n", len_2, strlen(test_1)); + return __LINE__; + } + char str2[128]; + char* end; + end = stpcpy(str2, append); + end = stpcpy(end, ""); + end = stpcpy(end, "foo"); + if (*end != '\0') { + return __LINE__; + } + if (end != &str2[pos_2]) { + printf("diff %p - %p = %td\n", end, str2, (ptrdiff_t)(end - str2)); + return __LINE__; + } + int cmp2 = strcmp(str2, test_2); + if (cmp2 != 0) { + printf("cmp: %d\n", cmp2); + return __LINE__; + } + return 0; +} + +int nano_tests(void) { + int pos; + int len = asprintf( + &buf, "%+d %s%% %#o %#x %n %#X %i\n", + 123, "asprintf", 076543, 0x9abcd, &pos, 0xFE1, 0 + ); + if (buf == NULL || len <= 0) { + printf("buf %p len %d\n", buf, len); + return __LINE__; + } + if (buf[len] != '\0') { + return __LINE__; + } + size_t buf_len = strlen(buf); + if (buf_len != strlen(test_1) || buf_len != (size_t)len) { + printf("E: %zu != %zu != %d\n", strlen(test_1), buf_len, len); + return __LINE__; + } + if (pos != pos_1) { + printf("E: %d != %d\n", pos, pos_1); + return __LINE__; + } + int cmp = strcmp(buf, test_1); + if (cmp != 0) { + printf("cmp: %d\n", cmp); + return __LINE__; + } + return 0; +} + +static char const * const fprintf_test = + "Terminal ':' (found):\t\"Stars:\"\n" + "Terminal ' ' (found):\t\"Stars: \"\n" + "Terminal ',' (found):\t\"Stars: Altair,\"\n" + "Terminal '.' (found):\t\"Stars: Altair, Sun, Vega.\"\n" + "Terminal '!' (absent):\t\"Stars: Altair, Sun, Vega.@\"\n" + "\n" + "Separate star names from distances (ly):\n" + "Arcturus Vega Capella Rigel Procyon \n" +/* fprintf_test */; + +static char const * const file_name = "FPRINTST"; + +static void get_diff_char(const char* buf, const char* test) { + size_t char_pos = 0; + char prev = '\0'; + while (*buf != '\0' && *test != '\0') { + if (*buf != *test) { + printf("prev %02X: %02X != %02X at %zu\n", prev, *buf, *test, char_pos); + break; + } + prev = *buf; + buf++; + test++; + char_pos++; + } +} + +int memccpy_tests(void) { + file = fopen(file_name, "wb"); + + // Check if the file was opened successfully + if (file == NULL) { + perror("Error opening file"); + return __LINE__; + } + // https://en.cppreference.com/w/c/string/byte/memccpy + const char src[] = "Stars: Altair, Sun, Vega."; + const char terminal[] = {':', ' ', ',', '.', '!'}; + char dest[sizeof src]; + const char alt = '@'; + + for (size_t i = 0; i != sizeof terminal; ++i) + { + void* to = memccpy(dest, src, terminal[i], sizeof dest); + + fprintf(file,"Terminal '%c' (%s):\t\"", terminal[i], to ? "found" : "absent"); + + // if `terminal` character was not found - print the whole `dest` + to = to ? to : dest + sizeof dest; + + for (char* from = dest; from != to; ++from) { + fputc(isprint(*from) ? *from : alt, file); + } + + fputs("\"\n", file); + } + + + fprintf(file, "%c%s", '\n', "Separate star names from distances (ly):\n"); + const char *star_distance[] = { + "Arcturus : 37", "Vega : 25", "Capella : 43", "Rigel : 860", "Procyon : 11" + }; + char names_only[64]; + char *first = names_only; + char *last = names_only + sizeof names_only; + + for (size_t t = 0; t != (sizeof star_distance) / (sizeof star_distance[0]); ++t) + { + if (first) { + first = memccpy(first, star_distance[t], ' ', last - first); + } else { + break; + } + } + + if (first) { + *first = '\0'; + fprintf(file, "%s%c", names_only, '\n'); + } else { + printf("Error Buffer is too small.\n"); + } + + fseek(file, 0, SEEK_END); + int file_size = ftell(file); + fseek(file, 0, SEEK_SET); + + if (file_size <= 0) { + perror("file_size <= 0"); + return __LINE__; + } + + int alloc_size = (int)ftell(file); + buf = (char*)calloc(alloc_size + 2, sizeof(char)); + if (buf == NULL) { + perror("calloc failure"); + return __LINE__; + } + + size_t bytes_read = fread(buf, 1, file_size, file); + if (bytes_read != (size_t)file_size) { + perror("Error reading from file"); + return __LINE__; + } + if (strlen(buf) != strlen(fprintf_test)) { + printf("E: %zu != %zu\n", strlen(buf), strlen(fprintf_test)); + get_diff_char(buf, fprintf_test); + return __LINE__; + } + int cmp = strcmp(buf, fprintf_test); + if (cmp != 0) { + printf("fprintf_cmp: %d\n", cmp); + get_diff_char(buf, fprintf_test); + return __LINE__; + } + return 0; +} + +int run_tests(void) { + int ret = 0; + /* ti_asprintf */ + ret = ti_tests(); + free(buf); buf = NULL; + if (ret != 0) { return ret; } + + /* nano_asprintf */ + ret = nano_tests(); + free(buf); buf = NULL; + if (ret != 0) { return ret; } + + /* nano_fprintf */ + ret = memccpy_tests(); + free(buf); buf = NULL; + fclose(file); + if (remove(file_name) != 0) { + perror("Couldn't delete file"); + } + if (ret != 0) { return ret; } + + return 0; +} + +int main(void) +{ + os_ClrHome(); + int ret = run_tests(); + if (ret != 0) { + printf("Failed test L%d\n", ret); + } else { + fprintf(stdout, "All tests %s", "passed"); + } + + while (!os_GetCSC()); + + return 0; +} From aaf199df8e0d9a221ca0944d390874629f726743 Mon Sep 17 00:00:00 2001 From: ZERICO2005 <71151164+ZERICO2005@users.noreply.github.com> Date: Sat, 22 Mar 2025 01:06:25 -0600 Subject: [PATCH 4/5] Added mempcpy and prototypes for additional functions --- src/libc/include/string.h | 40 +++++++++----- src/libc/mempcpy.src | 18 ++++++ src/libcxx/include/cstring | 4 ++ test/standalone/asprintf_fprintf/makefile | 4 +- test/standalone/asprintf_fprintf/src/main.c | 61 +++++++++++++++++---- 5 files changed, 101 insertions(+), 26 deletions(-) create mode 100644 src/libc/mempcpy.src diff --git a/src/libc/include/string.h b/src/libc/include/string.h index 0280cb9d9..2311a8a90 100644 --- a/src/libc/include/string.h +++ b/src/libc/include/string.h @@ -20,8 +20,17 @@ int memcmp(const void *s1, const void *s2, size_t n) void *memchr(const void *s, int c, size_t n) __attribute__((nonnull(1))); -void* memccpy(void *__restrict dest, const void *__restrict src, int c, size_t n) __NOEXCEPT - __attribute__((nonnull(1, 2))); +void *memrchr(const void *s, int c, size_t n) + __NOEXCEPT __attribute__((nonnull(1))) __attribute((__pure__)); + +void *memmem(const void *haystack, size_t haystack_len, const void *needle, size_t needle_len) + __NOEXCEPT __attribute__((nonnull(1, 3))) __attribute((__pure__)); + +void *memccpy(void *__restrict dest, const void *__restrict src, int c, size_t n) + __NOEXCEPT __attribute__((nonnull(1, 2))); + +void *mempcpy(void *__restrict dest, const void *__restrict src, size_t n) + __NOEXCEPT __attribute__((nonnull(1, 2))); char *strcpy(char *__restrict dest, const char *__restrict src) __attribute__((nonnull(1, 2))); @@ -29,14 +38,14 @@ char *strcpy(char *__restrict dest, const char *__restrict src) char *strncpy(char *__restrict dest, const char *__restrict src, size_t n) __attribute__((nonnull(1, 2))); -char *stpcpy(char *__restrict dest, const char *__restrict src) __NOEXCEPT - __attribute__((nonnull(1, 2))); +char *stpcpy(char *__restrict dest, const char *__restrict src) + __NOEXCEPT __attribute__((nonnull(1, 2))); -char *stpncpy(char *__restrict dest, const char *__restrict src, size_t n) __NOEXCEPT - __attribute__((nonnull(1, 2))); +char *stpncpy(char *__restrict dest, const char *__restrict src, size_t n) + __NOEXCEPT __attribute__((nonnull(1, 2))); -char *strlcpy(char *__restrict dest, const char *__restrict src, size_t n) __NOEXCEPT - __attribute__((nonnull(1, 2))); +char *strlcpy(char *__restrict dest, const char *__restrict src, size_t n) + __NOEXCEPT __attribute__((nonnull(1, 2))); char *strcat(char *__restrict dest, const char *__restrict src) __attribute__((nonnull(1, 2))); @@ -44,8 +53,8 @@ char *strcat(char *__restrict dest, const char *__restrict src) char *strncat(char *__restrict dest, const char *__restrict src, size_t n) __attribute__((nonnull(1, 2))); -char *strlcat(char *__restrict dest, const char *__restrict src, size_t n) __NOEXCEPT - __attribute__((nonnull(1, 2))); +char *strlcat(char *__restrict dest, const char *__restrict src, size_t n) + __NOEXCEPT __attribute__((nonnull(1, 2))); char *strchr(const char *s, int c) __attribute__((nonnull(1))); @@ -59,6 +68,9 @@ char *strpbrk(const char *s, const char *accept) char *strstr(const char *haystack, const char *needle) __attribute__((nonnull(1, 2))); +char *strcasestr(const char *haystack, const char *needle) + __NOEXCEPT __attribute__((nonnull(1, 2))) __attribute__((__pure__)); + char *strtok(char *__restrict s, const char *__restrict delim) __attribute__((nonnull(2))); @@ -86,11 +98,11 @@ int strcmp(const char *s1, const char *s2) int strncmp(const char *s1, const char *s2, size_t n) __attribute__((nonnull(1, 2))); -int strcasecmp(const char *s1, const char *s2) __NOEXCEPT - __attribute__((nonnull(1, 2))) __attribute__((__pure__)); +int strcasecmp(const char *s1, const char *s2) + __NOEXCEPT __attribute__((nonnull(1, 2))) __attribute__((__pure__)); -int strncasecmp(const char *s1, const char *s2, size_t n) __NOEXCEPT - __attribute__((nonnull(1, 2))) __attribute__((__pure__)); +int strncasecmp(const char *s1, const char *s2, size_t n) + __NOEXCEPT __attribute__((nonnull(1, 2))) __attribute__((__pure__)); char* strerror(int errnum); diff --git a/src/libc/mempcpy.src b/src/libc/mempcpy.src new file mode 100644 index 000000000..74da50541 --- /dev/null +++ b/src/libc/mempcpy.src @@ -0,0 +1,18 @@ + assume adl=1 + + section .text + + public _mempcpy + +_mempcpy: + ld iy, 0 + add iy, sp + ld bc, (iy + 9) ; Load count + sbc hl, hl + sbc hl, bc + ld hl, (iy + 3) ; Load destination + ret z ; zero bytes to copy + ld de, (iy + 6) ; Load source + ex de, hl + ldir + ret diff --git a/src/libcxx/include/cstring b/src/libcxx/include/cstring index 141419748..d0622af3e 100644 --- a/src/libcxx/include/cstring +++ b/src/libcxx/include/cstring @@ -14,7 +14,10 @@ using ::memmove; using ::memset; using ::memcmp; using ::memchr; +using ::memrchr; +using ::memmem; using ::memccpy; +using ::mempcpy; using ::strcpy; using ::strncpy; using ::stpcpy; @@ -27,6 +30,7 @@ using ::strchr; using ::strrchr; using ::strpbrk; using ::strstr; +using ::strcasestr; using ::strtok; using ::strdup; using ::strndup; diff --git a/test/standalone/asprintf_fprintf/makefile b/test/standalone/asprintf_fprintf/makefile index 3efc55361..90ffb4c9d 100644 --- a/test/standalone/asprintf_fprintf/makefile +++ b/test/standalone/asprintf_fprintf/makefile @@ -8,8 +8,8 @@ DESCRIPTION = "CE C Toolchain Demo" COMPRESSED = NO ARCHIVED = NO -CFLAGS = -Wall -Wextra -Oz -CXXFLAGS = -Wall -Wextra -Oz +CFLAGS = -Wall -Wextra -Wformat=2 -Wshadow -Oz +CXXFLAGS = -Wall -Wextra -Wformat=2 -Wshadow -Oz PREFER_OS_LIBC = NO diff --git a/test/standalone/asprintf_fprintf/src/main.c b/test/standalone/asprintf_fprintf/src/main.c index a85f8fd01..62ac74600 100644 --- a/test/standalone/asprintf_fprintf/src/main.c +++ b/test/standalone/asprintf_fprintf/src/main.c @@ -130,22 +130,28 @@ static char const * const fprintf_test = static char const * const file_name = "FPRINTST"; -static void get_diff_char(const char* buf, const char* test) { +static void get_diff_char(const char* data, const char* test) { size_t char_pos = 0; char prev = '\0'; - while (*buf != '\0' && *test != '\0') { - if (*buf != *test) { - printf("prev %02X: %02X != %02X at %zu\n", prev, *buf, *test, char_pos); - break; + while (*data != '\0' && *test != '\0') { + if (*data != *test) { + printf("prev %02X: %02X != %02X at %zu\n", prev, *data, *test, char_pos); + return; } - prev = *buf; - buf++; + prev = *data; + data++; test++; char_pos++; } } int memccpy_tests(void) { + // test zero byte case + void* ptr = memccpy((void*)0xC0FFEE, (void*)0x123456, 123, 0); + if (ptr != NULL) { + printf("%p != NULL\n", ptr); + return __LINE__; + } file = fopen(file_name, "wb"); // Check if the file was opened successfully @@ -209,8 +215,7 @@ int memccpy_tests(void) { return __LINE__; } - int alloc_size = (int)ftell(file); - buf = (char*)calloc(alloc_size + 2, sizeof(char)); + buf = (char*)calloc(file_size + 1, sizeof(char)); if (buf == NULL) { perror("calloc failure"); return __LINE__; @@ -235,6 +240,38 @@ int memccpy_tests(void) { return 0; } +int mempcpy_test(void) { + // test zero byte case + void* ptr = mempcpy((void*)0xC0FFEE, (void*)0x123456, 0); + if (ptr != (void*)0xC0FFEE) { + printf("%p != %p\n", ptr, (void*)0xC0FFEE); + return __LINE__; + } + char data[192 + 1]; + memset(&data[ 0], 0x12, 64); + memset(&data[ 64], 0x12, 64); + memset(&data[128], 0x56, 64); + char append[64 + 1]; + memset(append, 0x34, 64); + char* res = mempcpy(&data[64], append, 64); + if (res != &data[128]) { + printf("%p != %p\n", res, data); + return __LINE__; + } + + char truth[192 + 1]; + memset(&truth[ 0], 0x12, 64); + memset(&truth[ 64], 0x34, 64); + memset(&truth[128], 0x56, 64); + + int cmp = memcmp(data, truth, 192); + if (cmp != 0) { + printf("cmp: %d\n", cmp); + return __LINE__; + } + return 0; +} + int run_tests(void) { int ret = 0; /* ti_asprintf */ @@ -247,7 +284,7 @@ int run_tests(void) { free(buf); buf = NULL; if (ret != 0) { return ret; } - /* nano_fprintf */ + /* nano_fprintf memccpy */ ret = memccpy_tests(); free(buf); buf = NULL; fclose(file); @@ -256,6 +293,10 @@ int run_tests(void) { } if (ret != 0) { return ret; } + /* mempcpy */ + ret = mempcpy_test(); + if (ret != 0) { return ret; } + return 0; } From e25ba16e30d4e08004fbafd4416d1e4980dda4c1 Mon Sep 17 00:00:00 2001 From: ZERICO2005 <71151164+ZERICO2005@users.noreply.github.com> Date: Sat, 22 Mar 2025 02:27:11 -0600 Subject: [PATCH 5/5] Disabled Clang builtins for mempcpy/memccpy tests. Defined C95 functions since Clang can inline the functions with its own builtins --- src/libc/include/wchar.h | 66 +++++++++++++ src/libc/mempcpy.src | 59 +++++++---- test/standalone/asprintf_fprintf/src/main.c | 98 +++++++++++++------ .../asprintf_fprintf/src/rename.asm | 19 ++++ 4 files changed, 195 insertions(+), 47 deletions(-) create mode 100644 test/standalone/asprintf_fprintf/src/rename.asm diff --git a/src/libc/include/wchar.h b/src/libc/include/wchar.h index 44b0efe0d..140babd77 100644 --- a/src/libc/include/wchar.h +++ b/src/libc/include/wchar.h @@ -1,6 +1,8 @@ #ifndef _WCHAR_H #define _WCHAR_H +#include + #ifndef _WCHAR_T_DEFINED #define _WCHAR_T_DEFINED #ifndef __cplusplus @@ -17,4 +19,68 @@ typedef __WCHAR_TYPE__ wchar_t; #define WEOF -1 +__BEGIN_DECLS + +wchar_t *wmemcpy(wchar_t *__restrict dest, const wchar_t *__restrict src, size_t n) + __attribute__((nonnull(1, 2))); + +wchar_t *wmemmove(wchar_t *dest, const wchar_t *src, size_t n) + __attribute__((nonnull(1, 2))); + +wchar_t *wmemset(wchar_t *s, wchar_t c, size_t n) + __attribute__((nonnull(1))); + +int wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n) + __attribute__((nonnull(1, 2))); + +wchar_t *wmemchr(const wchar_t *s, int c, size_t n) + __attribute__((nonnull(1))); + +wchar_t *wcscpy(wchar_t *__restrict dest, const wchar_t *__restrict src) + __attribute__((nonnull(1, 2))); + +wchar_t *wcsncpy(wchar_t *__restrict dest, const wchar_t *__restrict src, size_t n) + __attribute__((nonnull(1, 2))); + +wchar_t *wcscat(wchar_t *__restrict dest, const wchar_t *__restrict src) + __attribute__((nonnull(1, 2))); + +wchar_t *wcsncat(wchar_t *__restrict dest, const wchar_t *__restrict src, size_t n) + __attribute__((nonnull(1, 2))); + +wchar_t *wcschr(const wchar_t *s, int c) + __attribute__((nonnull(1))); + +wchar_t *wcsrchr(const wchar_t *s, int c) + __attribute__((nonnull(1))); + +wchar_t *wcspbrk(const wchar_t *s, const wchar_t *accept) + __attribute__((nonnull(1, 2))); + +wchar_t *wcsstr(const wchar_t *haystack, const wchar_t *needle) + __attribute__((nonnull(1, 2))); + +wchar_t *wcstok(wchar_t *__restrict s, const wchar_t *__restrict delim) + __attribute__((nonnull(2))); + +size_t wcscspn(const wchar_t *s, const wchar_t *reject) + __attribute__((nonnull(1, 2))); + +size_t wcsspn(const wchar_t *s, const wchar_t *accept) + __attribute__((nonnull(1, 2))); + +size_t wcslen(const wchar_t *s) + __attribute__((nonnull(1))); + +size_t wcsnlen(const wchar_t *s, size_t maxlen) + __attribute__((nonnull(1))); + +int wcscmp(const wchar_t *s1, const wchar_t *s2) + __attribute__((nonnull(1, 2))); + +int wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n) + __attribute__((nonnull(1, 2))); + +__END_DECLS + #endif /* _WCHAR_H */ diff --git a/src/libc/mempcpy.src b/src/libc/mempcpy.src index 74da50541..e7a938248 100644 --- a/src/libc/mempcpy.src +++ b/src/libc/mempcpy.src @@ -1,18 +1,41 @@ - assume adl=1 - - section .text - - public _mempcpy - -_mempcpy: - ld iy, 0 - add iy, sp - ld bc, (iy + 9) ; Load count - sbc hl, hl - sbc hl, bc - ld hl, (iy + 3) ; Load destination - ret z ; zero bytes to copy - ld de, (iy + 6) ; Load source - ex de, hl - ldir - ret + assume adl=1 + + section .text + + public _mempcpy + +if 0 + +; faster when count is zero +_mempcpy: + ld iy, 0 + add iy, sp + ld bc, (iy + 9) ; Load count + sbc hl, hl + sbc hl, bc + ld hl, (iy + 3) ; Load destination + ret z ; zero bytes to copy + ld de, (iy + 6) ; Load source + ex de, hl + ldir + ex de, hl + ret + +else + +; faster in full execution case by 0F + 1 clock cycles +_mempcpy: + ld iy, 0 + add iy, sp + ld bc, (iy + 9) ; Load count + sbc hl, hl + sbc hl, bc + ld de, (iy + 3) ; Load destination + jr z, .zero_byte_copy ; zero bytes to copy + ld hl, (iy + 6) ; Load source + ldir +.zero_byte_copy: + ex de, hl + ret + +end if diff --git a/test/standalone/asprintf_fprintf/src/main.c b/test/standalone/asprintf_fprintf/src/main.c index 62ac74600..05e0b9144 100644 --- a/test/standalone/asprintf_fprintf/src/main.c +++ b/test/standalone/asprintf_fprintf/src/main.c @@ -19,6 +19,46 @@ * memccpy */ +// prevents Clang from replacing function calls with builtins +#if 1 + +void *T_memcpy(void *__restrict dest, const void *__restrict src, size_t n) + __attribute__((nonnull(1, 2))); + +void *T_memset(void *s, int c, size_t n) + __attribute__((nonnull(1))); + +int T_memcmp(const void *s1, const void *s2, size_t n) + __attribute__((nonnull(1, 2))); + +void *T_memccpy(void *__restrict dest, const void *__restrict src, int c, size_t n) + __attribute__((nonnull(1, 2))); + +void *T_mempcpy(void *__restrict dest, const void *__restrict src, size_t n) + __attribute__((nonnull(1, 2))); + +char *T_stpcpy(char *__restrict dest, const char *__restrict src) + __attribute__((nonnull(1, 2))); + +size_t T_strlen(const char *s) + __attribute__((nonnull(1))); + +int T_strcmp(const char *s1, const char *s2) + __attribute__((nonnull(1, 2))); + +#else + +#define T_memcpy memcpy +#define T_memset memset +#define T_memcmp memcmp +#define T_memccpy memccpy +#define T_mempcpy mempcpy +#define T_stpcpy stpcpy +#define T_strlen strlen +#define T_strcmp strcmp + +#endif + static char const * const test_1 = "+123 asprintf% 076543 0x9abcd 0XFE1 0\n"; static char const * const test_2 = @@ -42,9 +82,9 @@ int ti_tests(void) { if (buf[len] != '\0') { return __LINE__; } - size_t buf_len = strlen(buf); - if (buf_len != strlen(test_1) || buf_len != (size_t)len) { - printf("E: %zu != %zu != %d\n", strlen(test_1), buf_len, len); + size_t buf_len = T_strlen(buf); + if (buf_len != T_strlen(test_1) || buf_len != (size_t)len) { + printf("E: %zu != %zu != %d\n", T_strlen(test_1), buf_len, len); return __LINE__; } if (pos != pos_1) { @@ -63,15 +103,15 @@ int ti_tests(void) { return __LINE__; } int len_2 = ti_snprintf(append, sizeof(append), "%s", test_1); - if (len_2 != strlen(test_1)) { - printf("E: %d != %zu\n", len_2, strlen(test_1)); + if (len_2 != (int)T_strlen(test_1)) { + printf("E: %d != %zu\n", len_2, T_strlen(test_1)); return __LINE__; } char str2[128]; char* end; - end = stpcpy(str2, append); - end = stpcpy(end, ""); - end = stpcpy(end, "foo"); + end = T_stpcpy(str2, append); + end = T_stpcpy(end, ""); + end = T_stpcpy(end, "foo"); if (*end != '\0') { return __LINE__; } @@ -79,7 +119,7 @@ int ti_tests(void) { printf("diff %p - %p = %td\n", end, str2, (ptrdiff_t)(end - str2)); return __LINE__; } - int cmp2 = strcmp(str2, test_2); + int cmp2 = T_strcmp(str2, test_2); if (cmp2 != 0) { printf("cmp: %d\n", cmp2); return __LINE__; @@ -100,16 +140,16 @@ int nano_tests(void) { if (buf[len] != '\0') { return __LINE__; } - size_t buf_len = strlen(buf); - if (buf_len != strlen(test_1) || buf_len != (size_t)len) { - printf("E: %zu != %zu != %d\n", strlen(test_1), buf_len, len); + size_t buf_len = T_strlen(buf); + if (buf_len != T_strlen(test_1) || buf_len != (size_t)len) { + printf("E: %zu != %zu != %d\n", T_strlen(test_1), buf_len, len); return __LINE__; } if (pos != pos_1) { printf("E: %d != %d\n", pos, pos_1); return __LINE__; } - int cmp = strcmp(buf, test_1); + int cmp = T_strcmp(buf, test_1); if (cmp != 0) { printf("cmp: %d\n", cmp); return __LINE__; @@ -147,7 +187,7 @@ static void get_diff_char(const char* data, const char* test) { int memccpy_tests(void) { // test zero byte case - void* ptr = memccpy((void*)0xC0FFEE, (void*)0x123456, 123, 0); + void* ptr = T_memccpy((void*)0xC0FFEE, (void*)0x123456, 123, 0); if (ptr != NULL) { printf("%p != NULL\n", ptr); return __LINE__; @@ -167,7 +207,7 @@ int memccpy_tests(void) { for (size_t i = 0; i != sizeof terminal; ++i) { - void* to = memccpy(dest, src, terminal[i], sizeof dest); + void* to = T_memccpy(dest, src, terminal[i], sizeof dest); fprintf(file,"Terminal '%c' (%s):\t\"", terminal[i], to ? "found" : "absent"); @@ -193,7 +233,7 @@ int memccpy_tests(void) { for (size_t t = 0; t != (sizeof star_distance) / (sizeof star_distance[0]); ++t) { if (first) { - first = memccpy(first, star_distance[t], ' ', last - first); + first = T_memccpy(first, star_distance[t], ' ', last - first); } else { break; } @@ -226,8 +266,8 @@ int memccpy_tests(void) { perror("Error reading from file"); return __LINE__; } - if (strlen(buf) != strlen(fprintf_test)) { - printf("E: %zu != %zu\n", strlen(buf), strlen(fprintf_test)); + if (T_strlen(buf) != T_strlen(fprintf_test)) { + printf("E: %zu != %zu\n", T_strlen(buf), T_strlen(fprintf_test)); get_diff_char(buf, fprintf_test); return __LINE__; } @@ -242,29 +282,29 @@ int memccpy_tests(void) { int mempcpy_test(void) { // test zero byte case - void* ptr = mempcpy((void*)0xC0FFEE, (void*)0x123456, 0); + void* ptr = T_mempcpy((void*)0xC0FFEE, (void*)0x123456, 0); if (ptr != (void*)0xC0FFEE) { printf("%p != %p\n", ptr, (void*)0xC0FFEE); return __LINE__; } char data[192 + 1]; - memset(&data[ 0], 0x12, 64); - memset(&data[ 64], 0x12, 64); - memset(&data[128], 0x56, 64); + T_memset(&data[ 0], 0x12, 64); + T_memset(&data[ 64], 0x12, 64); + T_memset(&data[128], 0x56, 64); char append[64 + 1]; - memset(append, 0x34, 64); - char* res = mempcpy(&data[64], append, 64); + T_memset(append, 0x34, 64); + char* res = T_mempcpy(&data[64], append, 64); if (res != &data[128]) { - printf("%p != %p\n", res, data); + printf("%p != %p\n", res, &data[128]); return __LINE__; } char truth[192 + 1]; - memset(&truth[ 0], 0x12, 64); - memset(&truth[ 64], 0x34, 64); - memset(&truth[128], 0x56, 64); + T_memset(&truth[ 0], 0x12, 64); + T_memset(&truth[ 64], 0x34, 64); + T_memset(&truth[128], 0x56, 64); - int cmp = memcmp(data, truth, 192); + int cmp = T_memcmp(data, truth, 192); if (cmp != 0) { printf("cmp: %d\n", cmp); return __LINE__; diff --git a/test/standalone/asprintf_fprintf/src/rename.asm b/test/standalone/asprintf_fprintf/src/rename.asm new file mode 100644 index 000000000..5b66c080a --- /dev/null +++ b/test/standalone/asprintf_fprintf/src/rename.asm @@ -0,0 +1,19 @@ + assume adl = 1 + + section .text + + public _T_memset, _T_memcpy, _T_memcmp, _T_memccpy, _T_mempcpy + public _T_strlen, _T_strcmp, _T_stpcpy + +_T_memset := _memset +_T_memcpy := _memcpy +_T_memcmp := _memcmp +_T_memccpy := _memccpy +_T_mempcpy := _mempcpy + +_T_strlen := _strlen +_T_strcmp := _strcmp +_T_stpcpy := _stpcpy + + extern _memset, _memcpy, _memcmp, _memccpy, _mempcpy + extern _strlen, _strcmp, _stpcpy