mirror of https://github.com/flysand7/ciabatta.git
strtok and some changes to string.h
This commit is contained in:
parent
a8d1afdea2
commit
3c0baa113f
|
@ -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);
|
||||||
|
|
155
code/string.c
155
code/string.c
|
@ -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 NULL;
|
||||||
return (void *)s; // fuck clang
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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";
|
||||||
|
|
31
inc/string.h
31
inc/string.h
|
@ -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);
|
||||||
|
|
23
test/test.c
23
test/test.c
|
@ -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;
|
||||||
}
|
}
|
Loading…
Reference in New Issue