klib: printf support

This commit is contained in:
xinyangli 2024-07-09 17:26:11 +08:00
parent f38674ce79
commit 955f1f2d79
Signed by: xin
SSH key fingerprint: SHA256:qZ/tzd8lYRtUFSrfBDBMcUqV4GHKxqeqRA3huItgvbk
19 changed files with 438 additions and 245 deletions

View file

@ -1,32 +1,30 @@
# find_package(FLEX)
# find_package(BISON)
# find_package(FLEX) find_package(BISON)
# FLEX_TARGET(fmt_scanner fmt_scanner.l fmt_scanner.c)
set(SOURCES
cpp.c
int64.c
stdio.c
stdlib.c
string.c
# ${FLEX_fmt_scanner_OUTPUTS}
set(SOURCES cpp.c int64.c stdio.c stdlib.c string.c
# ${FLEX_fmt_scanner_OUTPUTS}
)
add_library(klib ${SOURCES})
target_link_libraries(klib PRIVATE am_interface klib_interface)
target_link_libraries(klib PUBLIC am_interface klib_interface)
target_compile_options(klib PUBLIC -fno-builtin)
target_link_options(klib PUBLIC -nostartfiles -nolibc)
install(TARGETS klib
EXPORT klibTargets
LIBRARY DESTINATION lib)
install(
TARGETS klib
EXPORT klibTargets
LIBRARY DESTINATION lib)
install(EXPORT klibTargets
FILE klibTargets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib)
install(
EXPORT klibTargets
FILE klibTargets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib)
configure_package_config_file(${CMAKE_SOURCE_DIR}/cmake/klib-config.cmake.in
configure_package_config_file(
${CMAKE_SOURCE_DIR}/cmake/klib-config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/klib-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/klib-config.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib)

View file

@ -1,16 +1,91 @@
#include <am.h>
#include <klib.h>
#include <klib-macros.h>
#include <klib.h>
#include <stdarg.h>
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
int vprintf(const char *fmt, va_list ap) {
const char *p = fmt;
while(*p != '\0') {
putch(*p);
void print_int(int num, int width, char pad) {
int reverse = 0;
int count = 0;
if (num == 0) {
reverse = 0;
count = 1;
} else {
if (num < 0) {
putch('-');
num = -num;
}
while (num != 0) {
reverse = reverse * 10 + (num % 10);
num /= 10;
count++;
}
}
while (width > count) {
putch(pad);
width--;
}
if (reverse == 0) {
putch('0');
} else {
while (reverse != 0) {
putch('0' + (reverse % 10));
reverse /= 10;
}
}
}
int vprintf(const char *format, va_list args) {
const char *p = format;
while (*p) {
if (*p == '%') {
p++; // Skip the '%'
char pad = ' ';
int width = 0;
if (*p == '0') {
pad = '0';
p++;
}
while (*p >= '0' && *p <= '9') {
width = width * 10 + (*p - '0');
p++;
}
switch (*p) {
case 'd': { // Integer
int ival = va_arg(args, int);
print_int(ival, width, pad);
break;
}
case 'c': { // Character
char c = (char)va_arg(args, int);
putch(c);
break;
}
case 's': { // String
char *s = va_arg(args, char *);
putstr(s);
break;
}
case '%': {
putch('%');
break;
}
default:
panic("Wrong formatter provided to printf");
}
} else {
putch(*p);
}
p++;
}
return 0;
}
int printf(const char *fmt, ...) {
@ -21,12 +96,103 @@ int printf(const char *fmt, ...) {
return 0;
}
int vsprintf(char *out, const char *fmt, va_list ap) {
panic("Not implemented");
void append_to_buffer(char **buf, int *pos, char c) { (*buf)[(*pos)++] = c; }
void print_int_to_buf(char **buf, int *pos, int num, int width, char pad) {
int reverse = 0, count = 0, neg = 0;
if (num == 0) {
reverse = 0;
count = 1;
} else {
if (num < 0) {
append_to_buffer(buf, pos, '-');
num = -num;
neg = 1;
}
while (num != 0) {
reverse = reverse * 10 + (num % 10);
num /= 10;
count++;
}
}
width -= neg;
while (width > count) {
append_to_buffer(buf, pos, pad);
width--;
}
if (reverse == 0) {
append_to_buffer(buf, pos, '0');
} else {
while (reverse != 0) {
append_to_buffer(buf, pos, '0' + (reverse % 10));
reverse /= 10;
}
}
}
int vsprintf(char *buf, const char *format, va_list args) {
const char *p = format;
int pos = 0; // Position in buf
while (*p) {
if (*p == '%') {
p++; // Skip the '%'
char pad = ' ';
int width = 0;
if (*p == '0') {
pad = '0';
p++;
}
while (*p >= '0' && *p <= '9') {
width = width * 10 + (*p - '0');
p++;
}
switch (*p) {
case 'd': { // Integer
int ival = va_arg(args, int);
print_int_to_buf(&buf, &pos, ival, width, pad);
break;
}
case 'c': { // Character
char c = (char)va_arg(args, int);
append_to_buffer(&buf, &pos, c);
break;
}
case 's': { // String
char *s = va_arg(args, char *);
while (*s) {
append_to_buffer(&buf, &pos, *s++);
}
break;
}
case '%': {
append_to_buffer(&buf, &pos, '%');
break;
}
default:
panic("Unsupported format specifier");
}
} else {
append_to_buffer(&buf, &pos, *p);
}
p++;
}
buf[pos] = '\0'; // Null-terminate the string
return pos;
}
int sprintf(char *out, const char *fmt, ...) {
panic("Not implemented");
va_list args;
va_start(args, fmt);
vsprintf(out, fmt, args);
va_end(args);
return 0;
}
int snprintf(char *out, size_t n, const char *fmt, ...) {

View file

@ -1,6 +1,6 @@
#include <am.h>
#include <klib.h>
#include <klib-macros.h>
#include <klib.h>
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
static unsigned long int next = 1;
@ -8,23 +8,21 @@ static unsigned long int next = 1;
int rand(void) {
// RAND_MAX assumed to be 32767
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
return (unsigned int)(next / 65536) % 32768;
}
void srand(unsigned int seed) {
next = seed;
}
void srand(unsigned int seed) { next = seed; }
int abs(int x) {
return (x < 0 ? -x : x);
}
int abs(int x) { return (x < 0 ? -x : x); }
int atoi(const char* nptr) {
int atoi(const char *nptr) {
int x = 0;
while (*nptr == ' ') { nptr ++; }
while (*nptr == ' ') {
nptr++;
}
while (*nptr >= '0' && *nptr <= '9') {
x = x * 10 + *nptr - '0';
nptr ++;
nptr++;
}
return x;
}
@ -33,13 +31,19 @@ void *malloc(size_t size) {
// On native, malloc() will be called during initializaion of C runtime.
// Therefore do not call panic() here, else it will yield a dead recursion:
// panic() -> putchar() -> (glibc) -> malloc() -> panic()
#if !(defined(__ISA_NATIVE__) && defined(__NATIVE_USE_KLIB__))
panic("Not implemented");
#endif
return NULL;
static void *addr = NULL;
void *ret = NULL;
if (addr == 0) {
addr = heap.start;
ret = addr;
} else {
panic_on(addr + size > heap.end, "Memory space not enough");
ret = addr;
addr += size;
}
return ret;
}
void free(void *ptr) {
}
void free(void *ptr) {}
#endif