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"
_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);
}

View File

@ -39,7 +39,7 @@ void *aligned_alloc(size_t alignment, size_t size) {
if(alignment > 8) {
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 aligned_block_start_i = align_forward(block_start_i, alignment);
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 *buffer = HeapReAlloc(_heap, 0, ptr, size);
return buffer;
}
if (ptr == NULL) {
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
_os_exit(status);
}

View File

@ -179,27 +179,30 @@ char *strstr(const char *s1, const char *s2) {
// 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;
static char *str;
return strtok_r(s1, s2, &str);
}
size_t junk_len = strspn(str, s2);
char *tok_start = str+junk_len;
char *strtok_r(char *restrict s1, const char *restrict s2, char **restrict ctx) {
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) {
str = NULL;
*ctx = NULL;
return NULL;
}
size_t tok_len = strcspn(str, s2);
size_t tok_len = strcspn(*ctx, s2);
char *tok_end = tok_start + tok_len;
*tok_end = 0;
str = tok_end+1;
*ctx = tok_end+1;
return tok_start;
}
char *strerror(int errnum) {
switch(errnum) {
case 0: return "No errors";

View File

@ -68,7 +68,7 @@ int atexit(void (*func)(void));
// int at_quick_exit(void (*func)(void));
_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);
// 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 *));

View File

@ -47,6 +47,9 @@ void *memset(void *s, int c, size_t n);
char *strerror(int errnum);
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
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);

View File

@ -23,6 +23,13 @@ void wack() {
int main(int argc, char** argv) {
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();
char input[] = "A bird came down the walk";
printf("Parsing the input string '%s'\n", input);