From 3c0baa113f5af677e4045af9c8aa3a96426c97b1 Mon Sep 17 00:00:00 2001 From: bumbread Date: Tue, 7 Jun 2022 20:26:13 +1100 Subject: [PATCH] strtok and some changes to string.h --- code/printf.h | 6 ++ code/string.c | 155 +++++++++++++++++++++++++++++--------------------- inc/string.h | 31 +++++----- test/test.c | 23 ++++++-- 4 files changed, 132 insertions(+), 83 deletions(-) diff --git a/code/printf.h b/code/printf.h index 5e68ca1..f097aa3 100644 --- a/code/printf.h +++ b/code/printf.h @@ -75,6 +75,12 @@ inline static int FMT_FUNC_NAME (void *ctx, OutputFunc out, const FMT_CHAR_TYPE FMT_CHAR_TYPE ch = *fmt++; switch (ch) { + case 'c': { + const char chr = va_arg(args, int); + out(ctx, 1, &chr); + full_length ++; + break; + } case 's': { const FMT_CHAR_TYPE *str = va_arg(args, FMT_CHAR_TYPE*); size_t len = FMT_STRLEN_S(str, precision ? precision : SIZE_MAX); diff --git a/code/string.c b/code/string.c index 938cfef..a2713fd 100644 --- a/code/string.c +++ b/code/string.c @@ -20,8 +20,7 @@ void *memcpy(void *restrict s1, const void *restrict s2, size_t n) { return s1; } -void *memmove(void *s1, const void *s2, size_t n) -{ +void *memmove(void *s1, const void *s2, size_t n) { void *buffer = malloc(n); memcpy(buffer, s2, n); memcpy(s1, buffer, n); @@ -29,16 +28,7 @@ void *memmove(void *s1, const void *s2, size_t n) return s1; } -void *memset(void *s, int c, size_t n) { - byte *restrict buf = s; - while (n--) { - *buf++ = c; - } - return s; -} - -char *strcpy(char *restrict s1, const char *restrict s2) -{ +char *strcpy(char *restrict s1, const char *restrict s2) { while(*s2 != 0) { *s1++ = *s2++; } @@ -46,25 +36,26 @@ char *strcpy(char *restrict s1, const char *restrict s2) return s1; } -char *strncpy(char *restrict s1, const char *restrict s2, size_t n) -{ - while(n-->0 && *s2 != 0) { +char *strncpy(char *restrict s1, const char *restrict s2, size_t n) { + size_t i = 0; + for(; i < n && *s2 != 0; ++ i) { *s1++ = *s2++; } - while(n-->0) { + for(; i < n; ++i) { *s1++ = 0; } return s1; } -char *strncat(char *restrict s1, const char *restrict s2, size_t n) -{ +char *strcat(char *restrict s1, const char *restrict s2) { size_t start = strlen(s1); - for(size_t i = 0; i != n && *s2 != 0; ++i) { - s1[start+i] = s2[i]; - } - s1[start+n] = 0; + return strcpy(s1+start, s2); +} + +char *strncat(char *restrict s1, const char *restrict s2, size_t n) { + size_t start = strlen(s1); + strncpy(s1+start, s2, n); return s1; } @@ -78,6 +69,14 @@ int memcmp(const void *s1, const void *s2, size_t n) { return 0; } +void *memset(void *s, int c, size_t n) { + byte *restrict buf = s; + while (n--) { + *buf++ = c; + } + return s; +} + int strcmp(const char *s1, const char *s2) { int diff; do { @@ -86,8 +85,7 @@ int strcmp(const char *s1, const char *s2) { return diff; } -int strncmp(const char *s1, const char *s2, size_t n) -{ +int strncmp(const char *s1, const char *s2, size_t n) { int diff = 0; size_t i = 0; if(n != 0) do { @@ -96,15 +94,13 @@ int strncmp(const char *s1, const char *s2, size_t n) return diff; } -// fuck locales -int strcoll(const char *s1, const char *s2) -{ +int strcoll(const char *s1, const char *s2) { return strcmp(s1, s2); } -// fuck bad implementation of strcoll -size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n) -{ +// TODO: I don't quite understand the intent nor use behind this function +// so I'm just going to ignore locales for now. +size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n) { size_t len = strlen(s2); if(s1 != NULL && n != 0) { for(size_t i = 0; i != n; ++i) { @@ -114,39 +110,47 @@ size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n) return len; } -void *memchr(const void *ptr, int c, size_t n) -{ - const byte *s = ptr; - size_t i = 0; - for(; i != n && *s != c; ++i, ++s) { - ++s; +void *memchr(const void *ptr, int c, size_t n) { + const char *s = ptr; + for(size_t i = 0; i != n; ++i) { + if(s[i] == c) { + // Casting away const because clang warnings + return (void *)(s+i); + } } - if(i == n) return NULL; - return (void *)s; // fuck clang + return NULL; } -char *strchr(const char *s, int c) -{ - while(*s && *s != c) ++s; - if(*s != c) return NULL; - return (void *)s; // fuck clang +char *strchr(const char *s, int c) { + do { + if(*s == c) return (char *)s; + } while(*s++); + return NULL; } -size_t strcspn(const char *s1, const char *s2) -{ +size_t strspn(const char *s1, const char *s2) { size_t i = 0; - while(*s1) { - if(strchr(s2, *s1) != NULL) { + for(; *s1; ++s1) { + if(strchr(s2, *s1) == NULL) { break; } - ++s1; ++i; } return i; } -char *strpbrk(const char *s1, const char *s2) -{ +size_t strcspn(const char *s1, const char *s2) { + size_t i = 0; + for(; *s1; ++s1) { + if(strchr(s2, *s1) != NULL) { + break; + } + ++i; + } + return i; +} + +char *strpbrk(const char *s1, const char *s2) { while(*s1) { if(strchr(s2, *s1) == NULL) { break; @@ -156,26 +160,47 @@ char *strpbrk(const char *s1, const char *s2) return (char *)s1; } -char *strstr(const char *s1, const char *s2) -{ - if(!*s2) return (char *)s1; +char *strrchr(const char *s, int c) { + char const *last = NULL; + for(; *s != 0; ++s) { + if(*s == c) last = s; + } + return (char *)last; +} + +char *strstr(const char *s1, const char *s2) { + if(*s2 == 0) return (char *)s1; size_t len = strlen(s2); - while(*s1 != 0) { - bool match = true; - for(size_t i = 0; i != len; ++i) { - if(!*s1 || s1[i] != s2[i]) { - match = false; - break; - } - } - ++s1; - if(match) return (char *)s1; + for(; *s1 != 0; ++s1) { + if(strncmp(s1, s2, len) == 0) return (char *)s1; } return NULL; } -char *strerror(int errnum) -{ +// TODO: there may be restrict-related UB +char *strtok(char *restrict s1, const char *restrict s2) { + static char *restrict str; + if(s1 != NULL) str = s1; + if(str == NULL) return NULL; + + size_t junk_len = strspn(str, s2); + char *tok_start = str+junk_len; + if(*tok_start == 0) { + str = NULL; + return NULL; + } + + size_t tok_len = strcspn(str, s2); + + char *tok_end = tok_start + tok_len; + *tok_end = 0; + str = tok_end+1; + + return tok_start; +} + + +char *strerror(int errnum) { switch(errnum) { case 0: return "No errors"; case EDOM: return "Value is out of domain of the function"; diff --git a/inc/string.h b/inc/string.h index e9f0f0d..774499a 100644 --- a/inc/string.h +++ b/inc/string.h @@ -1,6 +1,11 @@ #pragma once +// Technically all we should have here is typedef for size_t. +// but I can't get that without macro shittery so +// for now I'm just doing this, which is not quite correct +#include + #if !defined(NULL) #define NULL ((void *)0) #endif @@ -19,17 +24,17 @@ // int _wcsicmp(const wchar_t *string1, const wchar_t *string2); -void *memcpy(void * restrict s1, const void * restrict s2, size_t n); +void *memcpy(void *restrict s1, const void *restrict s2, size_t n); void *memmove(void *s1, const void *s2, size_t n); -char *strcpy(char * restrict s1, const char * restrict s2); -char *strncpy(char * restrict s1, const char * restrict s2, size_t n); -char *strcat(char * restrict s1, const char * restrict s2); -char *strncat(char * restrict s1, const char * restrict s2, size_t n); +char *strcpy(char *restrict s1, const char *restrict s2); +char *strncpy(char *restrict s1, const char *restrict s2, size_t n); +char *strcat(char *restrict s1, const char *restrict s2); +char *strncat(char *restrict s1, const char *restrict s2, size_t n); int memcmp(const void *s1, const void *s2, size_t n); int strcmp(const char *s1, const char *s2); int strcoll(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t n); -size_t strxfrm(char * restrict s1, const char * restrict s2, size_t n); +size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n); void *memchr(const void *s, int c, size_t n); char *strchr(const char *s, int c); size_t strcspn(const char *s1, const char *s2); @@ -37,19 +42,19 @@ char *strpbrk(const char *s1, const char *s2); char *strrchr(const char *s, int c); size_t strspn(const char *s1, const char *s2); char *strstr(const char *s1, const char *s2); -char *strtok(char * restrict s1, const char * restrict s2); +char *strtok(char *restrict s1, const char *restrict s2); void *memset(void *s, int c, size_t n); char *strerror(int errnum); size_t strlen(const char *s); #if __STDC_WANT_LIB_EXT1__ == 1 - errno_t memcpy_s(void * restrict s1, rsize_t s1max, const void * restrict s2, rsize_t n); + errno_t memcpy_s(void *restrict s1, rsize_t s1max, const void *restrict s2, rsize_t n); errno_t memmove_s(void *s1, rsize_t s1max, const void *s2, rsize_t n); - errno_t strcpy_s(char * restrict s1, rsize_t s1max, const char * restrict s2); - errno_t strncpy_s(char * restrict s1, rsize_t s1max,const char * restrict s2, rsize_t n); - errno_t strcat_s(char * restrict s1, rsize_t s1max, const char * restrict s2); - errno_t strncat_s(char * restrict s1, rsize_t s1max, const char * restrict s2, rsize_t n); - char *strtok_s(char * restrict s1, rsize_t * restrict s1max, const char * restrict s2, char ** restrict ptr); + errno_t strcpy_s(char *restrict s1, rsize_t s1max, const char *restrict s2); + errno_t strncpy_s(char *restrict s1, rsize_t s1max,const char *restrict s2, rsize_t n); + errno_t strcat_s(char *restrict s1, rsize_t s1max, const char *restrict s2); + errno_t strncat_s(char *restrict s1, rsize_t s1max, const char *restrict s2, rsize_t n); + char *strtok_s(char *restrict s1, rsize_t *restrict s1max, const char *restrict s2, char **restrict ptr); errno_t memset_s(void *s, rsize_t smax, int c, rsize_t n); errno_t strerror_s(char *s, rsize_t maxsize, errno_t errnum); size_t strerrorlen_s(errno_t errnum); diff --git a/test/test.c b/test/test.c index c214f30..d26020f 100644 --- a/test/test.c +++ b/test/test.c @@ -7,15 +7,28 @@ #include #include +#include #include -void onabort(int a) { - printf("I don't want to live anymore\n"); - exit(-69); +int test() { + static int a = 2; + a += 1; + return a; } int main(int argc, char** argv) { - signal(SIGABRT, onabort); - assert(0 != 0); + test(); + char input[] = "A bird came down the walk"; + printf("Parsing the input string '%s'\n", input); + char *token = strtok(input, " "); + while(token) { + printf("%s\n", token); + token = strtok(NULL, " "); + } + + printf("Contents of the input string now: '"); + for(size_t n = 0; n < sizeof input; ++n) + input[n] ? printf("%c", input[n]) : printf("\\0"); + printf("'"); return 0; } \ No newline at end of file