X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Flibc%2Fstdio.c;h=1f2bb13e029f923a3ecb464915b86435657e0636;hb=9358438bef42dbbcd1492a52d9010899a9756d2c;hp=82f036fb8f4549a6c518a6d0b5c476db63495407;hpb=d1e8a437c1fab4535f82c4c214ec3330ac32e48d;p=bootcensus diff --git a/src/libc/stdio.c b/src/libc/stdio.c index 82f036f..1f2bb13 100644 --- a/src/libc/stdio.c +++ b/src/libc/stdio.c @@ -1,12 +1,37 @@ +/* +pcboot - bootable PC demo/game kernel +Copyright (C) 2018 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY, without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ #include #include #include #include "contty.h" +#include "serial.h" + +enum { + OUT_DEF, + OUT_BUF, + OUT_SCR, + OUT_SER +}; extern void pcboot_putchar(int c); -static void bwrite(char *buf, size_t buf_sz, char *str, int sz); -static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap); +static void bwrite(int out, char *buf, size_t buf_sz, char *str, int sz); +static int intern_printf(int out, char *buf, size_t sz, const char *fmt, va_list ap); int putchar(int c) { @@ -35,14 +60,14 @@ int printf(const char *fmt, ...) va_list ap; va_start(ap, fmt); - res = intern_printf(0, 0, fmt, ap); + res = intern_printf(OUT_DEF, 0, 0, fmt, ap); va_end(ap); return res; } int vprintf(const char *fmt, va_list ap) { - return intern_printf(0, 0, fmt, ap); + return intern_printf(OUT_DEF, 0, 0, fmt, ap); } int sprintf(char *buf, const char *fmt, ...) @@ -51,14 +76,14 @@ int sprintf(char *buf, const char *fmt, ...) va_list ap; va_start(ap, fmt); - res = intern_printf(buf, 0, fmt, ap); + res = intern_printf(OUT_BUF, buf, 0, fmt, ap); va_end(ap); return res; } int vsprintf(char *buf, const char *fmt, va_list ap) { - return intern_printf(buf, 0, fmt, ap); + return intern_printf(OUT_BUF, buf, 0, fmt, ap); } int snprintf(char *buf, size_t sz, const char *fmt, ...) @@ -67,16 +92,31 @@ int snprintf(char *buf, size_t sz, const char *fmt, ...) va_list ap; va_start(ap, fmt); - res = intern_printf(buf, sz, fmt, ap); + res = intern_printf(OUT_BUF, buf, sz, fmt, ap); va_end(ap); return res; } int vsnprintf(char *buf, size_t sz, const char *fmt, va_list ap) { - return intern_printf(buf, sz, fmt, ap); + return intern_printf(OUT_BUF, buf, sz, fmt, ap); } +int ser_printf(const char *fmt, ...) +{ + int res; + va_list ap; + + va_start(ap, fmt); + res = intern_printf(OUT_SER, 0, 0, fmt, ap); + va_end(ap); + return res; +} + +int ser_vprintf(const char *fmt, va_list ap) +{ + return intern_printf(OUT_SER, 0, 0, fmt, ap); +} /* intern_printf provides all the functionality needed by all the printf * variants. @@ -91,7 +131,7 @@ int vsnprintf(char *buf, size_t sz, const char *fmt, va_list ap) #define BUF(x) ((x) ? (x) + cnum : (x)) #define SZ(x) ((x) ? (x) - cnum : (x)) -static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap) +static int intern_printf(int out, char *buf, size_t sz, const char *fmt, va_list ap) { char conv_buf[32]; char *str; @@ -126,7 +166,7 @@ static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap) base = 16; if(alt) { - bwrite(BUF(buf), SZ(sz), "0x", 2); + bwrite(out, BUF(buf), SZ(sz), "0x", 2); } case 'u': @@ -137,7 +177,7 @@ static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap) base = 8; if(alt) { - bwrite(BUF(buf), SZ(sz), "0", 1); + bwrite(out, BUF(buf), SZ(sz), "0", 1); } } @@ -156,18 +196,18 @@ static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap) slen = strlen(conv_buf); for(i=slen; i