rumpk/core/cstubs.c

194 lines
4.1 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;
}
int strncmp(const char *s1, const char *s2, size_t n) {
while (n && *s1 && (*s1 == *s2)) {
s1++; s2++; n--;
}
if (n == 0) return 0;
return *(unsigned char*)s1 - *(unsigned char*)s2;
}
char *strncpy(char *dest, const char *src, size_t n) {
char *d = dest;
while (n && (*d++ = *src++)) n--;
while (n--) *d++ = '\0';
return dest;
}
// abort is used by Nim panic
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;
}
#include <stdarg.h>
void itoa(int n, char s[]) {
int i, sign;
if ((sign = n) < 0) n = -n;
i = 0;
do { s[i++] = n % 10 + '0'; } while ((n /= 10) > 0);
if (sign < 0) s[i++] = '-';
s[i] = '\0';
// reverse
for (int j = 0, k = i-1; j < k; j++, k--) {
char temp = s[j]; s[j] = s[k]; s[k] = temp;
}
}
int printf(const char *format, ...) {
va_list args;
va_start(args, format);
while (*format) {
if (*format == '%' && *(format + 1)) {
format++;
if (*format == 's') {
char *s = va_arg(args, char *);
if (s) console_write(s, strlen(s));
} else if (*format == 'd') {
int d = va_arg(args, int);
char buf[16];
itoa(d, buf);
console_write(buf, strlen(buf));
} else {
putchar('%');
putchar(*format);
}
} else {
putchar(*format);
}
format++;
}
va_end(args);
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);
}
int atoi(const char *nptr) {
int res = 0;
while (*nptr >= '0' && *nptr <= '9') {
res = res * 10 + (*nptr - '0');
nptr++;
}
return res;
}
int errno = 0;
/* LwIP sys_now implementation */
extern unsigned int get_ticks(void);
unsigned int sys_now(void) {
return get_ticks();
}