klib: printf support
This commit is contained in:
parent
f38674ce79
commit
955f1f2d79
19 changed files with 438 additions and 245 deletions
|
@ -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)
|
||||
|
||||
|
|
|
@ -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, ...) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue