diff options
author | dzwdz | 2021-10-09 11:53:38 +0000 |
---|---|---|
committer | dzwdz | 2021-10-09 11:53:38 +0000 |
commit | d9463f6e977ce686ac7a55f22b0b25b0ce67b025 (patch) | |
tree | 768fbb673945dba63dc8c5e02f8a4238da4148d7 /src/init/stdlib.c | |
parent | faed927869451cf4070abba91b5a9cf9e32c9a6c (diff) | |
parent | acf41ff6fee44dd24f9383d96fecd992dcb072e2 (diff) |
Merge branch 'main' of github.com:dzwdz/camellia
Diffstat (limited to 'src/init/stdlib.c')
-rw-r--r-- | src/init/stdlib.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/init/stdlib.c b/src/init/stdlib.c index 6ed5a0a..a60854b 100644 --- a/src/init/stdlib.c +++ b/src/init/stdlib.c @@ -1,4 +1,6 @@ #include <init/stdlib.h> +#include <shared/syscalls.h> +#include <stdarg.h> int memcmp(const void *s1, const void *s2, size_t n) { const unsigned char *c1 = s1, *c2 = s2; @@ -10,3 +12,54 @@ int memcmp(const void *s1, const void *s2, size_t n) { } return 0; } + +size_t strlen(const char *s) { + size_t c = 0; + while (*s++) c++; + return c; +} + +int printf(const char *fmt, ...) { + const char *seg = fmt; // beginning of the current segment + int total = 0; + va_list argp; + va_start(argp, fmt); + for (;;) { + char c = *fmt++; + switch (c) { + case '\0': + // TODO don't assume that stdout is @ fd 0 + _syscall_write(0, seg, fmt - seg - 1, 0); + return total + (fmt - seg - 1); + + case '%': + _syscall_write(0, seg, fmt - seg - 1, 0); + total += fmt - seg - 1; + c = *fmt++; + switch (c) { + case 's': + const char *s = va_arg(argp, char*); + _syscall_write(0, s, strlen(s), 0); + total += strlen(s); + break; + + case 'x': + unsigned int n = va_arg(argp, int); + size_t i = 4; // nibbles * 4 + while (n >> i && i < (sizeof(int) * 8)) + i += 4; + + while (i > 0) { + i -= 4; + char h = '0' + ((n >> i) & 0xf); + if (h > '9') h += 'a' - '9' - 1; + _syscall_write(0, &h, 1, 0); + total++; + } + break; + } + seg = fmt; + break; + } + } +} |