136 lines
2.7 KiB
C
136 lines
2.7 KiB
C
// C runtime stubs for freestanding Nim
|
|
#include <stddef.h>
|
|
|
|
void *memcpy(void *dest, const void *src, size_t n) {
|
|
unsigned char *d = dest;
|
|
const unsigned char *s = src;
|
|
while (n--) *d++ = *s++;
|
|
return dest;
|
|
}
|
|
|
|
void *memset(void *s, int c, size_t n) {
|
|
unsigned char *p = s;
|
|
while (n--) *p++ = (unsigned char)c;
|
|
return s;
|
|
}
|
|
|
|
void *memmove(void *dest, const void *src, size_t n) {
|
|
unsigned char *d = dest;
|
|
const unsigned char *s = src;
|
|
if (d < s) {
|
|
while (n--) *d++ = *s++;
|
|
} else {
|
|
d += n;
|
|
s += n;
|
|
while (n--) *--d = *--s;
|
|
}
|
|
return dest;
|
|
}
|
|
|
|
int memcmp(const void *s1, const void *s2, size_t n) {
|
|
const unsigned char *p1 = s1, *p2 = s2;
|
|
while (n--) {
|
|
if (*p1 != *p2) return *p1 - *p2;
|
|
p1++; p2++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
size_t strlen(const char *s) {
|
|
size_t len = 0;
|
|
while (*s++) len++;
|
|
return len;
|
|
}
|
|
|
|
char *strcpy(char *dest, const char *src) {
|
|
char *d = dest;
|
|
while ((*d++ = *src++));
|
|
return dest;
|
|
}
|
|
|
|
int strcmp(const char *s1, const char *s2) {
|
|
while (*s1 && (*s1 == *s2)) { s1++; s2++; }
|
|
return *(unsigned char*)s1 - *(unsigned char*)s2;
|
|
}
|
|
|
|
void *calloc(size_t nmemb, size_t size) {
|
|
/* Use the Nim allocator */
|
|
extern void *malloc(size_t);
|
|
size_t total = nmemb * size;
|
|
void *p = malloc(total);
|
|
if (p) memset(p, 0, total);
|
|
return p;
|
|
}
|
|
|
|
void abort(void) {
|
|
/* Call Nim panic */
|
|
extern void panic(const char*);
|
|
panic("abort() called");
|
|
while(1) {}
|
|
}
|
|
|
|
/* Stdio stubs - these call into Zig UART */
|
|
extern void console_write(const char*, unsigned long);
|
|
|
|
int puts(const char *s) {
|
|
if (s) {
|
|
unsigned long len = strlen(s);
|
|
console_write(s, len);
|
|
console_write("\n", 1);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int putchar(int c) {
|
|
char buf[1] = {(char)c};
|
|
console_write(buf, 1);
|
|
return c;
|
|
}
|
|
|
|
int printf(const char *format, ...) {
|
|
/* Minimal printf - just output the format string */
|
|
if (format) {
|
|
console_write(format, strlen(format));
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int fprintf(void *stream, const char *format, ...) {
|
|
return printf(format);
|
|
}
|
|
|
|
int fflush(void *stream) {
|
|
return 0;
|
|
}
|
|
|
|
unsigned long fwrite(const void *ptr, unsigned long size, unsigned long nmemb, void *stream) {
|
|
console_write(ptr, size * nmemb);
|
|
return nmemb;
|
|
}
|
|
|
|
/* Signal stubs - no signals in freestanding */
|
|
typedef void (*sighandler_t)(int);
|
|
|
|
sighandler_t signal(int signum, sighandler_t handler) {
|
|
(void)signum;
|
|
(void)handler;
|
|
return (sighandler_t)0;
|
|
}
|
|
|
|
int raise(int sig) {
|
|
(void)sig;
|
|
return 0;
|
|
}
|
|
|
|
/* Exit stubs */
|
|
void exit(int status) {
|
|
extern void panic(const char*);
|
|
panic("exit() called - system halt");
|
|
while(1) {}
|
|
}
|
|
|
|
void _Exit(int status) {
|
|
exit(status);
|
|
}
|
|
|