strtok and some changes to string.h

This commit is contained in:
bumbread 2022-06-07 20:26:13 +11:00
parent a8d1afdea2
commit 3c0baa113f
4 changed files with 132 additions and 83 deletions

View File

@ -75,6 +75,12 @@ inline static int FMT_FUNC_NAME (void *ctx, OutputFunc out, const FMT_CHAR_TYPE
FMT_CHAR_TYPE ch = *fmt++; FMT_CHAR_TYPE ch = *fmt++;
switch (ch) { switch (ch) {
case 'c': {
const char chr = va_arg(args, int);
out(ctx, 1, &chr);
full_length ++;
break;
}
case 's': { case 's': {
const FMT_CHAR_TYPE *str = va_arg(args, FMT_CHAR_TYPE*); const FMT_CHAR_TYPE *str = va_arg(args, FMT_CHAR_TYPE*);
size_t len = FMT_STRLEN_S(str, precision ? precision : SIZE_MAX); size_t len = FMT_STRLEN_S(str, precision ? precision : SIZE_MAX);

View File

@ -20,8 +20,7 @@ void *memcpy(void *restrict s1, const void *restrict s2, size_t n) {
return s1; 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); void *buffer = malloc(n);
memcpy(buffer, s2, n); memcpy(buffer, s2, n);
memcpy(s1, buffer, n); memcpy(s1, buffer, n);
@ -29,16 +28,7 @@ void *memmove(void *s1, const void *s2, size_t n)
return s1; return s1;
} }
void *memset(void *s, int c, size_t n) { char *strcpy(char *restrict s1, const char *restrict s2) {
byte *restrict buf = s;
while (n--) {
*buf++ = c;
}
return s;
}
char *strcpy(char *restrict s1, const char *restrict s2)
{
while(*s2 != 0) { while(*s2 != 0) {
*s1++ = *s2++; *s1++ = *s2++;
} }
@ -46,25 +36,26 @@ char *strcpy(char *restrict s1, const char *restrict s2)
return s1; return s1;
} }
char *strncpy(char *restrict s1, const char *restrict s2, size_t n) char *strncpy(char *restrict s1, const char *restrict s2, size_t n) {
{ size_t i = 0;
while(n-->0 && *s2 != 0) { for(; i < n && *s2 != 0; ++ i) {
*s1++ = *s2++; *s1++ = *s2++;
} }
while(n-->0) { for(; i < n; ++i) {
*s1++ = 0; *s1++ = 0;
} }
return s1; 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); size_t start = strlen(s1);
for(size_t i = 0; i != n && *s2 != 0; ++i) { return strcpy(s1+start, s2);
s1[start+i] = s2[i]; }
}
s1[start+n] = 0; char *strncat(char *restrict s1, const char *restrict s2, size_t n) {
size_t start = strlen(s1);
strncpy(s1+start, s2, n);
return s1; return s1;
} }
@ -78,6 +69,14 @@ int memcmp(const void *s1, const void *s2, size_t n) {
return 0; 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 strcmp(const char *s1, const char *s2) {
int diff; int diff;
do { do {
@ -86,8 +85,7 @@ int strcmp(const char *s1, const char *s2) {
return diff; 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; int diff = 0;
size_t i = 0; size_t i = 0;
if(n != 0) do { if(n != 0) do {
@ -96,15 +94,13 @@ int strncmp(const char *s1, const char *s2, size_t n)
return diff; return diff;
} }
// fuck locales int strcoll(const char *s1, const char *s2) {
int strcoll(const char *s1, const char *s2)
{
return strcmp(s1, s2); return strcmp(s1, s2);
} }
// fuck bad implementation of strcoll // TODO: I don't quite understand the intent nor use behind this function
size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n) // 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); size_t len = strlen(s2);
if(s1 != NULL && n != 0) { if(s1 != NULL && n != 0) {
for(size_t i = 0; i != n; ++i) { 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; return len;
} }
void *memchr(const void *ptr, int c, size_t n) void *memchr(const void *ptr, int c, size_t n) {
{ const char *s = ptr;
const byte *s = ptr; for(size_t i = 0; i != n; ++i) {
size_t i = 0; if(s[i] == c) {
for(; i != n && *s != c; ++i, ++s) { // Casting away const because clang warnings
++s; return (void *)(s+i);
} }
if(i == n) return NULL; }
return (void *)s; // fuck clang return NULL;
} }
char *strchr(const char *s, int c) char *strchr(const char *s, int c) {
{ do {
while(*s && *s != c) ++s; if(*s == c) return (char *)s;
if(*s != c) return NULL; } while(*s++);
return (void *)s; // fuck clang return NULL;
} }
size_t strcspn(const char *s1, const char *s2) size_t strspn(const char *s1, const char *s2) {
{
size_t i = 0; size_t i = 0;
while(*s1) { for(; *s1; ++s1) {
if(strchr(s2, *s1) != NULL) { if(strchr(s2, *s1) == NULL) {
break; break;
} }
++s1;
++i; ++i;
} }
return 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) { while(*s1) {
if(strchr(s2, *s1) == NULL) { if(strchr(s2, *s1) == NULL) {
break; break;
@ -156,26 +160,47 @@ char *strpbrk(const char *s1, const char *s2)
return (char *)s1; return (char *)s1;
} }
char *strstr(const char *s1, const char *s2) char *strrchr(const char *s, int c) {
{ char const *last = NULL;
if(!*s2) return (char *)s1; 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); size_t len = strlen(s2);
while(*s1 != 0) { for(; *s1 != 0; ++s1) {
bool match = true; if(strncmp(s1, s2, len) == 0) return (char *)s1;
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; 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) { switch(errnum) {
case 0: return "No errors"; case 0: return "No errors";
case EDOM: return "Value is out of domain of the function"; case EDOM: return "Value is out of domain of the function";

View File

@ -1,6 +1,11 @@
#pragma once #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 <stddef.h>
#if !defined(NULL) #if !defined(NULL)
#define NULL ((void *)0) #define NULL ((void *)0)
#endif #endif
@ -19,17 +24,17 @@
// int _wcsicmp(const wchar_t *string1, const wchar_t *string2); // 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); void *memmove(void *s1, const void *s2, size_t n);
char *strcpy(char * restrict s1, const char * restrict s2); char *strcpy(char *restrict s1, const char *restrict s2);
char *strncpy(char * restrict s1, const char * restrict s2, size_t n); char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
char *strcat(char * restrict s1, const char * restrict s2); char *strcat(char *restrict s1, const char *restrict s2);
char *strncat(char * restrict s1, const char * restrict s2, size_t n); char *strncat(char *restrict s1, const char *restrict s2, size_t n);
int memcmp(const void *s1, const void *s2, size_t n); int memcmp(const void *s1, const void *s2, size_t n);
int strcmp(const char *s1, const char *s2); int strcmp(const char *s1, const char *s2);
int strcoll(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); 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); void *memchr(const void *s, int c, size_t n);
char *strchr(const char *s, int c); char *strchr(const char *s, int c);
size_t strcspn(const char *s1, const char *s2); 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); char *strrchr(const char *s, int c);
size_t strspn(const char *s1, const char *s2); size_t strspn(const char *s1, const char *s2);
char *strstr(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); void *memset(void *s, int c, size_t n);
char *strerror(int errnum); char *strerror(int errnum);
size_t strlen(const char *s); size_t strlen(const char *s);
#if __STDC_WANT_LIB_EXT1__ == 1 #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 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 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 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 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); 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); 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 memset_s(void *s, rsize_t smax, int c, rsize_t n);
errno_t strerror_s(char *s, rsize_t maxsize, errno_t errnum); errno_t strerror_s(char *s, rsize_t maxsize, errno_t errnum);
size_t strerrorlen_s(errno_t errnum); size_t strerrorlen_s(errno_t errnum);

View File

@ -7,15 +7,28 @@
#include <stdbool.h> #include <stdbool.h>
#include <inttypes.h> #include <inttypes.h>
#include <string.h>
#include <signal.h> #include <signal.h>
void onabort(int a) { int test() {
printf("I don't want to live anymore\n"); static int a = 2;
exit(-69); a += 1;
return a;
} }
int main(int argc, char** argv) { int main(int argc, char** argv) {
signal(SIGABRT, onabort); test();
assert(0 != 0); 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; return 0;
} }