stdlib.h: quick exit

This commit is contained in:
bumbread 2022-06-27 13:04:46 +11:00
parent e1a2205fc7
commit d232486a11
2 changed files with 117 additions and 91 deletions

View File

@ -30,8 +30,8 @@ typedef struct lldiv_t {
long long rem; long long rem;
} lldiv_t; } lldiv_t;
// #define EXIT_FAILURE 1 #define EXIT_FAILURE 1
// #define EXIT_SUCCESS 0 #define EXIT_SUCCESS 0
#define RAND_MAX 65536 #define RAND_MAX 65536
#define MB_CUR_MAX 4 #define MB_CUR_MAX 4
@ -41,48 +41,54 @@ typedef struct lldiv_t {
#define COUNTOF(...) (sizeof(__VA_ARGS__) / sizeof((__VA_ARGS__)[0])) #define COUNTOF(...) (sizeof(__VA_ARGS__) / sizeof((__VA_ARGS__)[0]))
#endif #endif
double atof(const char *nptr); // Some number stuff
int atoi(const char *nptr); int abs (int i);
long int atol(const char *nptr); long labs (long i);
long long int atoll(const char *nptr); long long llabs(long long i);
double strtod(const char * restrict nptr, char ** restrict endptr); div_t div (int numer, int denom);
float strtof(const char * restrict nptr, char ** restrict endptr); ldiv_t ldiv (long numer, long denom);
long double strtold(const char * restrict nptr, char ** restrict endptr); lldiv_t lldiv(long long numer, long long denom);
long int strtol(const char *restrict nptr, char **restrict endptr, int base);
long long int strtoll(const char *restrict nptr, char **restrict endptr, int base); // String conversion routines
unsigned long int strtoul(const char *restrict nptr, char **restrict endptr, int base); double atof (const char *nptr);
unsigned long long int strtoull(const char *restrict nptr, char **restrict endptr, int base); int atoi (const char *nptr);
long atol (const char *nptr);
long long atoll (const char *nptr);
double strtod (const char *restrict nptr, char **restrict endptr);
float strtof (const char *restrict nptr, char **restrict endptr);
long double strtold (const char *restrict nptr, char **restrict endptr);
long strtol (const char *restrict nptr, char **restrict endptr, int base);
long long strtoll (const char *restrict nptr, char **restrict endptr, int base);
unsigned long strtoul (const char *restrict nptr, char **restrict endptr, int base);
unsigned long long strtoull(const char *restrict nptr, char **restrict endptr, int base);
char *itoa(int value, char *str, int base); char *itoa(int value, char *str, int base);
int rand(void); // PRNG
int rand (void);
void srand(unsigned int seed); void srand(unsigned int seed);
typedef struct _os_heap _os_heap; // Memory management functions
void _heap_setup(_os_heap *heap); void *malloc (size_t size);
void *aligned_alloc(size_t alignment, size_t size); void *calloc (size_t nmemb, size_t size);
void *calloc(size_t nmemb, size_t size); void *aligned_alloc(size_t align, size_t size);
void free(void *ptr); void *realloc (void *ptr, size_t size);
void *malloc(size_t size); void free (void *ptr);
void *realloc(void *ptr, size_t size);
// Communication with environment
_Noreturn void abort (void);
_Noreturn void quick_exit (int status);
_Noreturn void _Exit (int status);
_Noreturn void exit (int status);
int atexit (void (*func)(void));
int at_quick_exit(void (*func)(void));
char *getenv (const char *name);
int system (const char *string);
_Noreturn void abort(void);
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);
// _Noreturn void quick_exit(int status);
int system(const char *string);
const void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); const void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
// void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); // void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
// int abs(int j);
// long int labs(long int j); // Multibyte strings
// long long int llabs(long long int j);
// div_t div(int numer, int denom);
// ldiv_t ldiv(long int numer, long int denom);
// lldiv_t lldiv(long long int numer, long long int denom);
// int mblen(const char *s, size_t n); // int mblen(const char *s, size_t n);
// int mbtowc(wchar_t * restrict pwc, const char * restrict s, size_t n); // int mbtowc(wchar_t * restrict pwc, const char * restrict s, size_t n);
// int wctomb(char *s, wchar_t wchar); // int wctomb(char *s, wchar_t wchar);

View File

@ -14,61 +14,13 @@ extern int main(int argc, char** argv);
// Exit routines // Exit routines
#define ATEXIT_FUNC_COUNT 64 #define ATEXIT_FUNC_COUNT 64
static void (*atexit_funcs[ATEXIT_FUNC_COUNT])(void); #define ATQEXIT_FUNC_COUNT 64
static void (*atexit_funcs [ATEXIT_FUNC_COUNT])(void);
static void (*atqexit_funcs[ATQEXIT_FUNC_COUNT])(void);
static int atexit_func_count; static int atexit_func_count;
static int atqexit_func_count;
static char **get_command_args(int *argc_ptr);
int _wcsicmp(wchar_t const* s1, wchar_t const* s2) {
int diff;
do {
diff = *s1 - *s2;
} while(diff != 0 && *s1 != 0 && *s2 != 0);
return diff;
}
static size_t count_wide_chars(const wchar_t* str) {
size_t len = 0;
while (str[len] != 0) len++;
return len;
}
static bool wchar_to_ansi(char* out, const wchar_t* str, size_t len) {
for (size_t i = 0; i < len; i++) {
wchar_t ch = *str++;
if (ch < 0 || ch > 0x7F) {
*out++ = 0;
return false;
}
*out++ = ch;
}
*out++ = 0;
return true;
}
static char **get_command_args(int *argc_ptr) {
int argc;
char** args;
LPCWSTR command_line = GetCommandLineW();
LPWSTR* args_wide = CommandLineToArgvW(command_line, &argc);
if (!args_wide || argc <= 0) {
ExitProcess(-69420);
}
args = calloc(argc, sizeof(char*));
// Convert wide chars into ANSI
for (int i = 0; i < argc; i++) {
size_t arg_len = count_wide_chars(args_wide[i]);
args[i] = malloc(arg_len+1);
wchar_to_ansi(args[i], args_wide[i], arg_len+1);
}
*argc_ptr = argc;
return args;
}
void mainCRTStartup() { void mainCRTStartup() {
// Set-up some platform stuff // Set-up some platform stuff
@ -91,9 +43,17 @@ void mainCRTStartup() {
exit(exit_code); exit(exit_code);
} }
_Noreturn void quick_exit(int status) {
while(atqexit_func_count--) {
atqexit_funcs[atqexit_func_count]();
}
ExitProcess(status);
}
_Noreturn void exit(int status) { _Noreturn void exit(int status) {
for (int i = atexit_func_count; i--;) { while(atexit_func_count--) {
atexit_funcs[i](); atexit_funcs[atqexit_func_count]();
} }
_close_io(); _close_io();
ExitProcess(status); ExitProcess(status);
@ -116,6 +76,14 @@ int atexit(void (*func)(void)) {
return 1; return 1;
} }
int at_quick_exit(void (*func)(void)) {
if(atqexit_func_count >= ATQEXIT_FUNC_COUNT) {
return 0;
}
atqexit_funcs[atqexit_func_count++] = func;
return 1;
}
char *getenv(const char *name) { char *getenv(const char *name) {
// The string pointed to shall not be modified by the program, but may be // The string pointed to shall not be modified by the program, but may be
// overwritten by a subsequent call to the getenv function // overwritten by a subsequent call to the getenv function
@ -184,3 +152,55 @@ int system(const char* string) {
free(cmd_line); free(cmd_line);
return -1; return -1;
} }
int _wcsicmp(wchar_t const* s1, wchar_t const* s2) {
int diff;
do {
diff = *s1 - *s2;
} while(diff != 0 && *s1 != 0 && *s2 != 0);
return diff;
}
static size_t count_wide_chars(const wchar_t* str) {
size_t len = 0;
while (str[len] != 0) len++;
return len;
}
static bool wchar_to_ansi(char* out, const wchar_t* str, size_t len) {
for (size_t i = 0; i < len; i++) {
wchar_t ch = *str++;
if (ch < 0 || ch > 0x7F) {
*out++ = 0;
return false;
}
*out++ = ch;
}
*out++ = 0;
return true;
}
static char **get_command_args(int *argc_ptr) {
int argc;
char** args;
LPCWSTR command_line = GetCommandLineW();
LPWSTR* args_wide = CommandLineToArgvW(command_line, &argc);
if (!args_wide || argc <= 0) {
ExitProcess(-69420);
}
args = calloc(argc, sizeof(char*));
// Convert wide chars into ANSI
for (int i = 0; i < argc; i++) {
size_t arg_len = count_wide_chars(args_wide[i]);
args[i] = malloc(arg_len+1);
wchar_to_ansi(args[i], args_wide[i], arg_len+1);
}
*argc_ptr = argc;
return args;
}