From 8c6bda878aaa004c9a843c4823bfbfb0fb218ef5 Mon Sep 17 00:00:00 2001 From: bumbread Date: Mon, 6 Jun 2022 12:30:01 +1100 Subject: [PATCH] Some string functions (untested) --- code/string.c | 186 ++++++++++++++++++++++++++++++++++++++----- inc/locale.h | 8 +- inc/signal.h | 6 +- inc/stdlib.h | 2 +- inc/string.h | 11 ++- inc/threads.h | 3 +- inc/time.h | 7 +- platform/win32/env.c | 2 + 8 files changed, 197 insertions(+), 28 deletions(-) create mode 100644 platform/win32/env.c diff --git a/code/string.c b/code/string.c index b2e128b..97f5b78 100644 --- a/code/string.c +++ b/code/string.c @@ -1,8 +1,17 @@ #include +#include +#include +#include +#include +#include + +// TODO: rewrite memmove to not allocate anything + +typedef unsigned char byte; void *memcpy(void *restrict s1, const void *restrict s2, size_t n) { - const unsigned char *restrict c2 = s2; - unsigned char *restrict c1 = s1; + const byte *restrict c2 = s2; + byte *restrict c1 = s1; while (n--) { *c1++ = *c2++; @@ -10,35 +19,173 @@ void *memcpy(void *restrict s1, const void *restrict s2, size_t n) { return s1; } -int memcmp(const void *s1, const void *s2, size_t n) { - const unsigned char *u1 = s1; - const unsigned char *u2 = s2; - - for (; n--; u1++, u2++) { - if (*u1 != *u2) return *u1 - *u2; - } - - return 0; +void *memmove(void *s1, const void *s2, size_t n) +{ + byte *u1 = s1; + byte const *u2 = s2; + void *buffer = malloc(n); + strcpy(buffer, s2); + strcpy(s1, buffer); + free(buffer); + return s1; } void *memset(void *s, int c, size_t n) { - unsigned char *restrict buf = s; + byte *restrict buf = s; while (n--) { *buf++ = c; } return s; } -int strcmp(const char *s1, const char *s2) { - while (*s1 != 0 && *s2 != 0) { - if (*s1 != *s2) break; +char *strcpy(char *restrict s1, const char *restrict s2) +{ + while(*s2 != 0) { + *s1++ = *s2++; } + *s1 = 0; + return s1; +} - if(*s1 > *s2) return 1; - if(*s1 < *s2) return -1; +char *strncpy(char *restrict s1, const char *restrict s2, size_t n) +{ + while(n-->0 && *s2 != 0) { + *s1++ = *s2++; + } + while(n-->0) { + *s1++ = 0; + } + return s1; +} + + +char *strncat(char *restrict s1, const char *restrict s2, size_t n) +{ + int start = strlen(s1); + for(int i = 0; i != n && *s2 != 0; ++i) { + s1[start+i] = s2[i]; + } + s1[start+n] = 0; + return s1; +} + + +int memcmp(const void *s1, const void *s2, size_t n) { + const byte *u1 = s1; + const byte *u2 = s2; + for (; n--; u1++, u2++) { + if (*u1 != *u2) return *u1 - *u2; + } return 0; } +int strcmp(const char *s1, const char *s2) { + int diff; + do { + diff = *s1 - *s2; + } while(diff != 0 && *s1 != 0 && *s2 != 0); + return diff; +} + +int strncmp(const char *s1, const char *s2, size_t n) +{ + int diff; + int i = 0; + if(n != 0) do { + diff = *s1 - *s2; + } while(++i < n && diff != 0 && *s1 != 0 && *s2 != 0); + return diff; +} + +// fuck locales +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) +{ + size_t len = strlen(s2); + if(s1 != NULL && n != 0) { + for(int i = 0; i != n; ++i) { + *s1 = *s2; + } + } + return len; +} + +void *memchr(const void *ptr, int c, size_t n) +{ + const byte *s = ptr; + int i = 0; + for(; i != n && *s != c; ++i, ++s) { + ++s; + } + if(i == n) return NULL; + return (void *)s; // fuck clang +} + +char *strchr(const char *s, int c) +{ + while(*s && *s != c) ++s; + if(*s != c) return NULL; + return (void *)s; // fuck clang +} + +size_t strcspn(const char *s1, const char *s2) +{ + size_t i = 0; + while(*s1) { + if(strchr(s2, *s1) != NULL) { + break; + } + ++s1; + ++i; + } + return i; +} + +char *strpbrk(const char *s1, const char *s2) +{ + while(*s1) { + if(strchr(s2, *s1) == NULL) { + break; + } + ++s1; + } + return (char *)s1; +} + +char *strstr(const char *s1, const char *s2) +{ + if(!*s2) 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; + } + return NULL; +} + +char *strerror(int errnum) +{ + switch(errnum) { + case 0: return "No errors"; + case EDOM: return "Value is out of domain of the function"; + case EILSEQ: return "Illegal byte sequence"; + case ERANGE: return "Value is out of range"; + } + return "Unkown error"; +} + size_t strlen(const char *s) { size_t i = 0; while (s[i]) { @@ -47,7 +194,8 @@ size_t strlen(const char *s) { return i; } -// __STDC_WANT_LIB_EXT1__ +#if __STDC_WANT_LIB_EXT1__ == 1 + size_t strnlen_s(const char *s, size_t maxsize) { if (s == NULL) return 0; @@ -57,3 +205,5 @@ size_t strnlen_s(const char *s, size_t maxsize) { } return i; } + +#endif \ No newline at end of file diff --git a/inc/locale.h b/inc/locale.h index cf963d7..a59a17e 100644 --- a/inc/locale.h +++ b/inc/locale.h @@ -1,9 +1,15 @@ -#include "_platform.h" + +#pragma once + +#define _COL_IGNORE_SPACE 0x1 +#define _COL_IGNORE_SYMBOL 0x2 struct lconv { + // LC_NUMERIC char *decimal_point; // "." char *thousands_sep; // "" char *grouping; // "" + // LC_MONETARY char *mon_decimal_point; // "" char *mon_thousands_sep; // "" char *mon_grouping; // "" diff --git a/inc/signal.h b/inc/signal.h index 0cde095..03a3551 100644 --- a/inc/signal.h +++ b/inc/signal.h @@ -3,9 +3,9 @@ typedef int sig_atomic_t; // TODO: implement this -#define SIG_DFL (-1) -#define SIG_ERR (-1) -#define SIG_IGN (-1) +#define SIG_DFL 0 +#define SIG_ERR 1 +#define SIG_IGN 2 // not sure why but windows picked these, we can change it later #define SIGINT 2 diff --git a/inc/stdlib.h b/inc/stdlib.h index 19aad8f..9cb01a5 100644 --- a/inc/stdlib.h +++ b/inc/stdlib.h @@ -1,7 +1,7 @@ #pragma once #if !defined(NULL) -#define NULL ((void *)0) + #define NULL ((void *)0) #endif // typedef struct div_t { diff --git a/inc/string.h b/inc/string.h index 201bc70..a062ac3 100644 --- a/inc/string.h +++ b/inc/string.h @@ -1,6 +1,11 @@ -#include "_platform.h" -int _wcsicmp(const wchar_t *string1, const wchar_t *string2); +#pragma once + +#if !defined(NULL) + #define NULL ((void *)0) +#endif + +// int _wcsicmp(const wchar_t *string1, const wchar_t *string2); void *memcpy(void * restrict s1, const void * restrict s2, size_t n); void *memmove(void *s1, const void *s2, size_t n); @@ -25,7 +30,7 @@ void *memset(void *s, int c, size_t n); char *strerror(int errnum); size_t strlen(const char *s); -#if __STDC_WANT_LIB_EXT1__ +#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 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); diff --git a/inc/threads.h b/inc/threads.h index 722407e..293a063 100644 --- a/inc/threads.h +++ b/inc/threads.h @@ -1,4 +1,5 @@ -#include "_platform.h" + +#include #define thread_local _Thread_local #define ONCE_FLAG_INIT 1 diff --git a/inc/time.h b/inc/time.h index 412ff11..0fa12e7 100644 --- a/inc/time.h +++ b/inc/time.h @@ -1,4 +1,9 @@ -#include "_platform.h" + +#pragma once + +#if !defined(NULL) + #define NULL ((void *)0) +#endif // The number of clock ticks per second #define CLOCKS_PER_SEC ((clock_t)1000) diff --git a/platform/win32/env.c b/platform/win32/env.c new file mode 100644 index 0000000..c97a4f3 --- /dev/null +++ b/platform/win32/env.c @@ -0,0 +1,2 @@ + +#include