fixed realloc behavior, added getenv and reentrant strtok variant

This commit is contained in:
NeGate 2022-06-07 22:36:49 -04:00
parent 911841be30
commit 9458655faf
7 changed files with 80 additions and 35 deletions

View File

@ -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);
} }

View File

@ -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);
}
}

View File

@ -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);
} }

View File

@ -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";

View File

@ -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 *));

View File

@ -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

View File

@ -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);