> compile NEMU
221220000 张三 Linux zzy 5.15.146.1-microsoft-standard-WSL2 #1 SMP Thu Jan 11 04:09:03 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux 17:41:09 up 7:55, 1 user, load average: 0.55, 0.41, 0.38
This commit is contained in:
@ -4,8 +4,6 @@
|
||||
void __am_timer_init() {
|
||||
}
|
||||
|
||||
#define put_us(num) for (;num != 0; num /= 10) putch('0' + (num % 10))
|
||||
|
||||
void __am_timer_uptime(AM_TIMER_UPTIME_T *uptime) {
|
||||
uptime->us = inl(RTC_ADDR) | ((uint64_t)inl(RTC_ADDR + 4) << 32);
|
||||
}
|
||||
|
80
abstract-machine/klib/src/printf.c
Normal file
80
abstract-machine/klib/src/printf.c
Normal file
@ -0,0 +1,80 @@
|
||||
#include <klib.h>
|
||||
|
||||
int num_to_ascii(int num, int power, int size, char *buf) {
|
||||
if (size <= 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = 0, i = 0;
|
||||
char _buf[sizeof(num) * 3];
|
||||
if (num == 0) {
|
||||
*buf = '0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 1; num; i ++) {
|
||||
_buf[i] = num % power < 10 ? '0' + num % power : 'a' + num % power;
|
||||
num /= power;
|
||||
}
|
||||
if (i > size) {
|
||||
return 0; // error buffer overflow
|
||||
}
|
||||
ret = i;
|
||||
|
||||
for (i --; i > 0; i --, buf ++ ) {
|
||||
*buf = _buf[i];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int print_fmt(char **out, int n, const char** fmt, va_list* ap) {
|
||||
int ret = 0;
|
||||
switch (**fmt) {
|
||||
case 'd':
|
||||
ret = num_to_ascii(va_arg(*ap, int), 10, n, *out);
|
||||
(*out) += ret;
|
||||
break;
|
||||
case 's':
|
||||
const char* str = va_arg(*ap, const char*);
|
||||
if (ret > n) break;
|
||||
for (; *str; str ++, (*out) ++, ret ++ ) {
|
||||
if (ret >= n) {
|
||||
return ret; // error buffer overflow
|
||||
}
|
||||
**out = *str;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
char ch = va_arg(*ap, int);
|
||||
ret = 1;
|
||||
**out = ch;
|
||||
(*out) ++;
|
||||
break;
|
||||
case 'x':
|
||||
ret = num_to_ascii(va_arg(*ap, int), 16, n, *out);
|
||||
(*out) += ret;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
(*fmt) ++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rvsnprintf(char* out, size_t n, const char* fmt, va_list* ap) {
|
||||
int ret = 0;
|
||||
while(*fmt && n) {
|
||||
if (*fmt == '%') {
|
||||
// FIXME
|
||||
fmt++;
|
||||
print_fmt(&out, 123, &fmt, ap);
|
||||
continue;
|
||||
}
|
||||
*out = *fmt;
|
||||
out ++;
|
||||
fmt ++;
|
||||
n --;
|
||||
}
|
||||
*out = '\0';
|
||||
return ret;
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
#include <am.h>
|
||||
#include <klib.h>
|
||||
#include <klib-macros.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
|
||||
|
||||
@ -16,8 +15,7 @@ int printf(const char *fmt, ...) {
|
||||
}
|
||||
|
||||
int vsprintf(char *out, const char *fmt, va_list ap) {
|
||||
// FIXME
|
||||
return vsnprintf(out, 999, fmt, ap);
|
||||
return vsnprintf(out, SIZE_MAX, fmt, ap);
|
||||
}
|
||||
|
||||
int sprintf(char *out, const char *fmt, ...) {
|
||||
@ -36,72 +34,10 @@ int snprintf(char *out, size_t n, const char *fmt, ...) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rvsnprintf(char* out, size_t n, const char* fmt, va_list ap);
|
||||
int rvsnprintf(char* out, size_t n, const char* fmt, va_list* ap);
|
||||
|
||||
int vsnprintf(char *out, size_t n, const char *fmt, va_list ap) {
|
||||
return rvsnprintf(out, n, fmt, ap);
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
static int print_fmt(char **out, int n, const char** fmt, va_list* ap) {
|
||||
int ret = 0;
|
||||
switch (**fmt) {
|
||||
case 'd':
|
||||
//
|
||||
(*fmt) ++;
|
||||
int num = va_arg(*ap, int);
|
||||
int i = 0;
|
||||
char buf[sizeof(num) * 3];
|
||||
if (num == 0) {
|
||||
buf[i++] = '0';
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
for (i = 1; num; i ++) {
|
||||
buf[i] = '0' + num % 10;
|
||||
num /= 10;
|
||||
}
|
||||
if (i > n) {
|
||||
break; // error buffer overflow
|
||||
}
|
||||
ret = i;
|
||||
|
||||
// reverse buf
|
||||
for (i --; i > 0; i --, (*out) ++ ) {
|
||||
**out = buf[i];
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
(*fmt) ++;
|
||||
const char* str = va_arg(*ap, const char*);
|
||||
int n = 999; // FIXME
|
||||
if (ret > n) break; // error buffer overflow
|
||||
for (; *str; str ++, (*out) ++ ) {
|
||||
**out = *str;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
static int rvsnprintf(char* out, size_t n, const char* fmt, va_list ap) {
|
||||
int ret = 0;
|
||||
while(*fmt) {
|
||||
if (*fmt == '%') {
|
||||
// FIXME
|
||||
fmt++;
|
||||
print_fmt(&out, 123, &fmt, &ap);
|
||||
continue;
|
||||
}
|
||||
*out = *fmt;
|
||||
out ++;
|
||||
fmt ++;
|
||||
}
|
||||
*out = '\0';
|
||||
return ret;
|
||||
return rvsnprintf(out, n, fmt, &ap);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user