mirror of https://github.com/flysand7/ciabatta.git
fixed realloc behavior, added getenv and reentrant strtok variant
This commit is contained in:
parent
911841be30
commit
9458655faf
|
@ -3,7 +3,33 @@
|
||||||
|
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
|
|
||||||
_Noreturn void _os_exit(int code)
|
char* getenv(const char *name) {
|
||||||
{
|
// The string pointed to shall not be modified by the program, but may be
|
||||||
|
// overwritten by a subsequent call to the getenv function
|
||||||
|
static size_t env_string_cap;
|
||||||
|
static char* env_string;
|
||||||
|
|
||||||
|
DWORD env_length = GetEnvironmentVariable(name, NULL, 0);
|
||||||
|
if (env_length == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upscale the internal string
|
||||||
|
if (env_length > env_string_cap) {
|
||||||
|
char* newstr = realloc(env_string, env_length);
|
||||||
|
if (newstr == NULL) {
|
||||||
|
free(env_string);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
env_string = newstr;
|
||||||
|
env_string_cap = env_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetEnvironmentVariable(name, env_string, env_length);
|
||||||
|
return env_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Noreturn void _os_exit(int code) {
|
||||||
ExitProcess(code);
|
ExitProcess(code);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ void *aligned_alloc(size_t alignment, size_t size) {
|
||||||
if(alignment > 8) {
|
if(alignment > 8) {
|
||||||
min_req_size += alignment;
|
min_req_size += alignment;
|
||||||
}
|
}
|
||||||
void *block_start = HeapAlloc(_heap, HEAP_ZERO_MEMORY, min_req_size);
|
void *block_start = HeapAlloc(_heap, 0, min_req_size);
|
||||||
intptr_t block_start_i = (intptr_t)block_start;
|
intptr_t block_start_i = (intptr_t)block_start;
|
||||||
intptr_t aligned_block_start_i = align_forward(block_start_i, alignment);
|
intptr_t aligned_block_start_i = align_forward(block_start_i, alignment);
|
||||||
void *aligned_block_start = (void *)aligned_block_start_i;
|
void *aligned_block_start = (void *)aligned_block_start_i;
|
||||||
|
@ -69,7 +69,14 @@ void *malloc(size_t size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void *realloc(void *ptr, size_t size) {
|
void *realloc(void *ptr, size_t size) {
|
||||||
void *buffer = HeapReAlloc(_heap, 0, ptr, size);
|
if (ptr == NULL) {
|
||||||
return buffer;
|
if (size == 0) return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
|
return HeapAlloc(_heap, 0, size);
|
||||||
|
} else if (size == 0) {
|
||||||
|
HeapFree(_heap, 0, ptr);
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
return HeapReAlloc(_heap, 0, ptr, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -38,4 +38,3 @@ _Noreturn void _Exit(int status) {
|
||||||
// doesn't run atexit routines
|
// doesn't run atexit routines
|
||||||
_os_exit(status);
|
_os_exit(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,27 +179,30 @@ char *strstr(const char *s1, const char *s2) {
|
||||||
|
|
||||||
// TODO: there may be restrict-related UB
|
// TODO: there may be restrict-related UB
|
||||||
char *strtok(char *restrict s1, const char *restrict s2) {
|
char *strtok(char *restrict s1, const char *restrict s2) {
|
||||||
static char *restrict str;
|
static char *str;
|
||||||
if(s1 != NULL) str = s1;
|
return strtok_r(s1, s2, &str);
|
||||||
if(str == NULL) return NULL;
|
}
|
||||||
|
|
||||||
size_t junk_len = strspn(str, s2);
|
char *strtok_r(char *restrict s1, const char *restrict s2, char **restrict ctx) {
|
||||||
char *tok_start = str+junk_len;
|
if(s1 != NULL) *ctx = s1;
|
||||||
|
if(*ctx == NULL) return NULL;
|
||||||
|
|
||||||
|
size_t junk_len = strspn(*ctx, s2);
|
||||||
|
char *tok_start = *ctx + junk_len;
|
||||||
if(*tok_start == 0) {
|
if(*tok_start == 0) {
|
||||||
str = NULL;
|
*ctx = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t tok_len = strcspn(str, s2);
|
size_t tok_len = strcspn(*ctx, s2);
|
||||||
|
|
||||||
char *tok_end = tok_start + tok_len;
|
char *tok_end = tok_start + tok_len;
|
||||||
*tok_end = 0;
|
*tok_end = 0;
|
||||||
str = tok_end+1;
|
*ctx = tok_end+1;
|
||||||
|
|
||||||
return tok_start;
|
return tok_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *strerror(int errnum) {
|
char *strerror(int errnum) {
|
||||||
switch(errnum) {
|
switch(errnum) {
|
||||||
case 0: return "No errors";
|
case 0: return "No errors";
|
||||||
|
|
|
@ -68,7 +68,7 @@ int atexit(void (*func)(void));
|
||||||
// int at_quick_exit(void (*func)(void));
|
// int at_quick_exit(void (*func)(void));
|
||||||
_Noreturn void exit(int status);
|
_Noreturn void exit(int status);
|
||||||
_Noreturn void _Exit(int status);
|
_Noreturn void _Exit(int status);
|
||||||
// char *getenv(const char *name);
|
char *getenv(const char *name);
|
||||||
// _Noreturn void quick_exit(int status);
|
// _Noreturn void quick_exit(int status);
|
||||||
// int system(const char *string);
|
// int system(const char *string);
|
||||||
// void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
|
// void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
|
||||||
|
|
39
inc/string.h
39
inc/string.h
|
@ -7,19 +7,19 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#if !defined(NULL)
|
#if !defined(NULL)
|
||||||
#define NULL ((void *)0)
|
#define NULL ((void *)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(__STDC_LIB_EXT1__)
|
#if !defined(__STDC_LIB_EXT1__)
|
||||||
#define __STDC_LIB_EXT1__
|
#define __STDC_LIB_EXT1__
|
||||||
typedef int errno_t;
|
typedef int errno_t;
|
||||||
typedef size_t rsize_t;
|
typedef size_t rsize_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __STDC_WANT_SECURE_LIB__ == 1
|
#if __STDC_WANT_SECURE_LIB__ == 1
|
||||||
#if !defined(__STDC_WANT_LIB_EXT1__)
|
#if !defined(__STDC_WANT_LIB_EXT1__)
|
||||||
#define __STDC_WANT_LIB_EXT1__ 1
|
#define __STDC_WANT_LIB_EXT1__ 1
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// int _wcsicmp(const wchar_t *string1, const wchar_t *string2);
|
// int _wcsicmp(const wchar_t *string1, const wchar_t *string2);
|
||||||
|
@ -47,16 +47,19 @@ 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);
|
||||||
|
|
||||||
|
// Linux extension: reentrant strtok
|
||||||
|
char *strtok_r(char *restrict s1, const char *restrict s2, char **restrict ctx);
|
||||||
|
|
||||||
#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);
|
||||||
size_t strnlen_s(const char *str, size_t strsz);
|
size_t strnlen_s(const char *str, size_t strsz);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,6 +23,13 @@ void wack() {
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
atexit(wack);
|
atexit(wack);
|
||||||
|
|
||||||
|
char* path_env = getenv("PATH");
|
||||||
|
char *ctx, *path_token = strtok_r(path_env, ";", &ctx);
|
||||||
|
while(path_token) {
|
||||||
|
printf("%s\n", path_token);
|
||||||
|
path_token = strtok_r(NULL, ";", &ctx);
|
||||||
|
}
|
||||||
|
|
||||||
test();
|
test();
|
||||||
char input[] = "A bird came down the walk";
|
char input[] = "A bird came down the walk";
|
||||||
printf("Parsing the input string '%s'\n", input);
|
printf("Parsing the input string '%s'\n", input);
|
||||||
|
|
Loading…
Reference in New Issue