194 lines
4.1 KiB
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();
|
|
}
|
|
|