9os

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 53c6ad2c93c5468c14cf32746b5860d30bad86d2
parent 6ed9f65751c404328c6c2e52d599397ef988d3d7
Author: Roberto Vargas <roberto.vargas@arm.com>
Date:   Tue, 13 Nov 2018 10:34:54 +0000

[libk] Add ksnprint()

Change-Id: Ie4f29793cbb5fd55056be00139dae4fcc26a1886

Diffstat:
Minclude/rcode.h | 13++++++++-----
Msrc/libk/Makefile | 6++++--
Msrc/libk/__assert.c | 2+-
Asrc/libk/doprnt.c | 126+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libk/kprint.c | 16++++++++++++++++
Asrc/libk/ksnprint.c | 20++++++++++++++++++++
Asrc/libk/libk.h | 11+++++++++++
Dsrc/libk/printk.c | 118-------------------------------------------------------------------------------
Msrc/rmc.c | 12++++++------
9 files changed, 192 insertions(+), 132 deletions(-)

diff --git a/include/rcode.h b/include/rcode.h @@ -3,9 +3,11 @@ #include <stdint.h> #if __GNUC__ || __clang__ -#define PRINTKFMT __attribute__ ((format (printf, 1, 2))) +#define KPRINTFMT __attribute__ ((format (printf, 1, 2))) +#define KSNPRINTFMT __attribute__ ((format (printf, 3, 4))) #else -#define PRINTKFMT +#define KPRINTFMT +#define KSNPRINTFMT #endif #if __STDC_VERSION__ >= 201112L @@ -16,9 +18,9 @@ #endif #ifndef NDEBUG -#define dbg printk +#define dbg kprint #else -#define dbg(fmt, ...) +#define dbg #endif #define PAGESIZE 4096 @@ -137,8 +139,9 @@ extern void rmc(Rmucmd *cmd); extern int debug(void); /* libk */ -extern void printk(const char * restrict fmt, ...) PRINTKFMT; extern struct bssmap *bss(void); +extern int kprint(const char *fmt, ...) KPRINTFMT; +extern int ksnprint(char *str, size_t len, const char *fmt, ...) KSNPRINTFMT; extern char *kgetln(char *s, int n); extern int kgetc(void); diff --git a/src/libk/Makefile b/src/libk/Makefile @@ -2,8 +2,10 @@ PROJECTDIR=../.. include $(PROJECTDIR)/scripts/rules.mk -OBJS = printk.o \ - bss-$(SYS).o \ +OBJS = bss-$(SYS).o \ + doprnt.o \ + kprint.o \ + ksnprint.o \ kgetc-$(SYS).o \ kgetln.o \ __assert.o \ diff --git a/src/libk/__assert.c b/src/libk/__assert.c @@ -5,6 +5,6 @@ extern void printk(const char * restrict fmt, ...); void __assert(char *exp, char *file, long line) { - printk("%s:%ld: assertion failed '%s'\n", file, line, exp); + kprint("%s:%ld: assertion failed '%s'\n", file, line, exp); abort(); } diff --git a/src/libk/doprnt.c b/src/libk/doprnt.c @@ -0,0 +1,126 @@ +#include <stdarg.h> +#include <stddef.h> + +#include "libk.h" +#include "../libc/syscall.h" + +static void +putch(Stream *sp, int c) +{ + char ch; + + if (sp->fd < 0) { + if (sp->cnt < sp->len) + sp->base[sp->cnt++] = c; + } else { + ch = c; + _write(sp->fd, &ch, 1); + sp->cnt++; + } +} + +static void +printn(Stream *sp, long long n, int base, int sign) +{ + int first, d; + unsigned long long div; + const static char digits[] = "0123456789ABCDEF"; + + switch (base) { + case 8: + div = 01000000000000000000000u; + break; + case 10: + div = 10000000000000000000u; + break; + case 16: + div = 0x1000000000000000u; + break; + } + + if (sign && n < 0) { + n = -n; + putch(sp, '-'); + } + + for (first = 1; div > 0; div /= base) { + d = n / div; + if (d == 0 && first && div != 1) + continue; + n -= d * div; + putch(sp, digits[d]); + first = 0; + } +} + +static long long +getnum(va_list *va, int size) +{ + switch (size) { + case 0: + return va_arg(*va, int); + case 1: + return va_arg(*va, long); + case 2: + return va_arg(*va, long long); + case 3: + default: + return (long long) va_arg(*va, void *); + } +} + +void +doprnt(Stream *sp, const char * restrict fmt, va_list va) +{ + char c; + va_list va2; + int base, sign, size; + char *s; + + va_copy(va2, va); + while (( c = *fmt++) != '\0') { + if (c != '%') { + putch(sp, c); + continue; + } + + sign = 0; + size = 0; +flags: + switch (c = *fmt++) { + case 'l': + size++; + goto flags; + case 'o': + base = 8; + goto print_number; + case 'd': + sign = 1; + case 'u': + base = 10; + goto print_number; + case 'p': + size = 3; + case 'X': + case 'x': + base = 16; + print_number: + printn(sp, getnum(&va2, size), base, sign); + break; + case 's': + for (s = va_arg(va, char *); *s; s++) + putch(sp, *s); + break; + case 'c': + c = va_arg(va, int); + case '%': + putch(sp, c); + break; + case '\0': + goto out_loop; + } + } + +out_loop: + va_end(va2); +} diff --git a/src/libk/kprint.c b/src/libk/kprint.c @@ -0,0 +1,16 @@ +#include <stdarg.h> + +#include "libk.h" + +int +kprint(const char *fmt, ...) +{ + va_list ap; + Stream stream = {.fd = 1}; + + va_start(ap, fmt); + doprnt(&stream, fmt, ap); + va_end(ap); + + return stream.cnt; +} diff --git a/src/libk/ksnprint.c b/src/libk/ksnprint.c @@ -0,0 +1,20 @@ +#include <stdarg.h> +#include <stddef.h> + +#include "libk.h" + +int +ksnprint(char *str, size_t len, const char *fmt, ...) +{ + va_list ap; + Stream stream = {.fd = -1, .base = str, .len = len}; + + va_start(ap, fmt); + doprnt(&stream, fmt, ap); + va_end(ap); + + if (stream.cnt < len) + str[stream.cnt++] = '\0'; + + return stream.cnt; +} diff --git a/src/libk/libk.h b/src/libk/libk.h @@ -0,0 +1,11 @@ +#include <stddef.h> + +typedef struct stream Stream; +struct stream { + int fd; + char *base; + size_t len; + size_t cnt; +}; + +extern void print(Stream *sp, const char * restrict fmt, va_list va); diff --git a/src/libk/printk.c b/src/libk/printk.c @@ -1,118 +0,0 @@ - -#include <stdarg.h> -#include <stddef.h> - -#include "../libc/syscall.h" - -static void -putch(int c) -{ - char ch = c; - _write(1, &ch, 1); -} - -static void -printn(long long n, int base, int sign) -{ - int first, d; - unsigned long long div; - const static char digits[] = "0123456789ABCDEF"; - - switch (base) { - case 8: - div = 01000000000000000000000u; - break; - case 10: - div = 10000000000000000000u; - break; - case 16: - div = 0x1000000000000000u; - break; - } - - if (sign && n < 0) { - n = -n; - putch('-'); - } - - for (first = 1; div > 0; div /= base) { - d = n / div; - if (d == 0 && first && div != 1) - continue; - n -= d * div; - putch(digits[d]); - first = 0; - } -} - -static long long -getnum(va_list *va, int size) -{ - switch (size) { - case 0: - return va_arg(*va, int); - case 1: - return va_arg(*va, long); - case 2: - return va_arg(*va, long long); - case 3: - default: - return (long long) va_arg(*va, void *); - } -} - -void -printk(const char * restrict fmt, ...) -{ - char c; - va_list va; - int base, sign, size; - char *s; - - va_start(va, fmt); - while (( c = *fmt++) != '\0') { - if (c != '%') { - putch(c); - continue; - } - - sign = 0; - size = 0; -flags: - switch (c = *fmt++) { - case 'l': - size++; - goto flags; - case 'o': - base = 8; - goto print_number; - case 'd': - sign = 1; - case 'u': - base = 10; - goto print_number; - case 'p': - size = 3; - case 'X': - case 'x': - base = 16; - print_number: - printn(getnum(&va, size), base, sign); - break; - case 's': - for (s = va_arg(va, char *); *s; s++) - putch(*s); - break; - case 'c': - c = va_arg(va, int); - case '%': - putch(c); - break; - case '\0': - goto out_loop; - } - } - -out_loop: - va_end(va); -} diff --git a/src/rmc.c b/src/rmc.c @@ -4,7 +4,7 @@ static void dumpregs(struct trapframe *fp) { - printk("x0=%llx\tx1=%llx\tx2=%llx\tx3=%llx\n" + kprint("x0=%llx\tx1=%llx\tx2=%llx\tx3=%llx\n" "x4=%llx\tx5=%llx\tx6=%llx\tx7=%llx\n" "x8=%llx\tx9=%llx\tx10=%llx\tx11=%llx\n" "x12=%llx\tx13=%llx\tx14=%llx\tx15=%llx\n" @@ -32,9 +32,9 @@ backtrace(struct trapframe *fp) if (!bss->backtrace) return; - printk("backtrace:\n"); + kprint("backtrace:\n"); for (bp = (void **) fp->x29; *bp; bp = (void **) *bp) - printk("%p\n", bp[1]); + kprint("%p\n", bp[1]); } static void @@ -44,10 +44,10 @@ dumpstack(struct trapframe *fp) if (!bss->dumpstack) return; - printk("stack dump:\n"); + kprint("stack dump:\n"); sp = fp->sp; for (i = 1; i <= 16; i++) - printk("%x%c", *sp++, (i % 4 == 0) ? '\n' : ' '); + kprint("%x%c", *sp++, (i % 4 == 0) ? '\n' : ' '); } static void @@ -59,7 +59,7 @@ panicfmt(const char *msg, struct trapframe *fp) */ if (bss->in_panic != 1) { bss->in_panic = 1; - printk("panic: %s\n", msg); + kprint("panic: %s\n", msg); dumpregs(fp); backtrace(fp);