97 lines
2.9 KiB
C
97 lines
2.9 KiB
C
// C runtime stubs for freestanding Nim
|
|
#include <stddef.h>
|
|
|
|
/* Duplicates provided by libnexus.a (clib.o) */
|
|
#if 0
|
|
void *memcpy(void *dest, const void *src, size_t n) { ... }
|
|
void *memset(void *s, int c, size_t n) { ... }
|
|
void *memmove(void *dest, const void *src, size_t n) { ... }
|
|
int memcmp(const void *s1, const void *s2, size_t n) { ... }
|
|
|
|
/* Externs from libnexus.a */
|
|
extern size_t strlen(const char *s);
|
|
extern int atoi(const char *nptr);
|
|
extern int strncmp(const char *s1, const char *s2, size_t n);
|
|
|
|
char *strcpy(char *dest, const char *src) { ... }
|
|
int strcmp(const char *s1, const char *s2) { ... }
|
|
char *strncpy(char *dest, const char *src, size_t n) { ... }
|
|
#endif
|
|
|
|
// panic is used by abort/exit
|
|
void panic(const char* msg) {
|
|
extern void console_write(const char*, unsigned long);
|
|
extern size_t strlen(const char*);
|
|
console_write("\n[KERNEL PANIC] ", 16);
|
|
if (msg) console_write(msg, strlen(msg));
|
|
else console_write("Unknown Error", 13);
|
|
console_write("\n", 1);
|
|
while(1) {
|
|
// Halt
|
|
}
|
|
}
|
|
|
|
// abort is used by Nim panic
|
|
void abort(void) {
|
|
panic("abort() called");
|
|
while(1) {}
|
|
}
|
|
|
|
#if 0
|
|
/* Stdio stubs - these call into Zig UART */
|
|
extern void console_write(const char*, unsigned long);
|
|
|
|
int puts(const char *s) { ... }
|
|
int putchar(int c) { ... }
|
|
// ... (printf, etc)
|
|
int snprintf(char *str, size_t size, const char *format, ...) { ... }
|
|
int fflush(void *stream) { ... }
|
|
unsigned long fwrite(const void *ptr, unsigned long size, unsigned long nmemb, void *stream) { ... }
|
|
sighandler_t signal(int signum, sighandler_t handler) { ... }
|
|
int raise(int sig) { ... }
|
|
int sprintf(char *str, const char *format, ...) { ... }
|
|
double strtod(const char *nptr, char **endptr) { ... }
|
|
#endif
|
|
|
|
/* Exit stubs */
|
|
void exit(int status) {
|
|
extern void panic(const char*);
|
|
panic("exit() called - system halt");
|
|
while(1) {}
|
|
}
|
|
|
|
void _Exit(int status) {
|
|
exit(status);
|
|
}
|
|
|
|
// qsort uses existing memcpy
|
|
// Note: We need memcpy for qsort!
|
|
// libnexus.a provides memcpy. We need to declare it.
|
|
extern void *memcpy(void *dest, const void *src, size_t n);
|
|
|
|
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) {
|
|
// Bubble sort for simplicity (O(n^2))
|
|
if (nmemb < 2) return;
|
|
char *b = (char *)base;
|
|
char tmp[256]; // Max item size 256 bytes for swap
|
|
// Verify size? If size > 256, we fail or use loop.
|
|
// mu_Container* is pointer size (8).
|
|
|
|
for (size_t i = 0; i < nmemb - 1; i++) {
|
|
for (size_t j = 0; j < nmemb - i - 1; j++) {
|
|
char *p1 = b + j * size;
|
|
char *p2 = b + (j + 1) * size;
|
|
if (compar(p1, p2) > 0) {
|
|
// Swap
|
|
if (size <= 256) {
|
|
memcpy(tmp, p1, size);
|
|
memcpy(p1, p2, size);
|
|
memcpy(p2, tmp, size);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// int errno = 0; // Provided by clib.c
|