2 pcboot - bootable PC demo/game kernel
3 Copyright (C) 2018 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY, without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
31 extern void pcboot_putchar(int c);
33 static void bwrite(int out, char *buf, size_t buf_sz, char *str, int sz);
34 static int intern_printf(int out, char *buf, size_t sz, const char *fmt, va_list ap);
42 int puts(const char *s)
51 /* -- printf and friends -- */
53 static char *convc = "dioxXucsfeEgGpn%";
55 #define IS_CONV(c) strchr(convc, c)
57 int printf(const char *fmt, ...)
63 res = intern_printf(OUT_DEF, 0, 0, fmt, ap);
68 int vprintf(const char *fmt, va_list ap)
70 return intern_printf(OUT_DEF, 0, 0, fmt, ap);
73 int sprintf(char *buf, const char *fmt, ...)
79 res = intern_printf(OUT_BUF, buf, 0, fmt, ap);
84 int vsprintf(char *buf, const char *fmt, va_list ap)
86 return intern_printf(OUT_BUF, buf, 0, fmt, ap);
89 int snprintf(char *buf, size_t sz, const char *fmt, ...)
95 res = intern_printf(OUT_BUF, buf, sz, fmt, ap);
100 int vsnprintf(char *buf, size_t sz, const char *fmt, va_list ap)
102 return intern_printf(OUT_BUF, buf, sz, fmt, ap);
105 int ser_printf(const char *fmt, ...)
111 res = intern_printf(OUT_SER, 0, 0, fmt, ap);
116 int ser_vprintf(const char *fmt, va_list ap)
118 return intern_printf(OUT_SER, 0, 0, fmt, ap);
121 /* intern_printf provides all the functionality needed by all the printf
123 * - buf: optional buffer onto which the formatted results are written. If null
124 * then the output goes to the terminal through putchar calls. This is used
125 * by the (v)sprintf variants which write to an array of char.
126 * - sz: optional maximum size of the output, 0 means unlimited. This is used
127 * by the (v)snprintf variants to avoid buffer overflows.
128 * The rest are obvious, format string and variable argument list.
131 #define BUF(x) ((x) ? (x) + cnum : (x))
132 #define SZ(x) ((x) ? (x) - cnum : (x))
134 static int intern_printf(int out, char *buf, size_t sz, const char *fmt, va_list ap)
139 const char *fstart = 0;
148 int left_align = 0; /* not implemented yet */
169 bwrite(out, BUF(buf), SZ(sz), "0x", 2);
180 bwrite(out, BUF(buf), SZ(sz), "0", 1);
187 utoa(va_arg(ap, unsigned int), conv_buf, base);
189 itoa(va_arg(ap, int), conv_buf, base);
192 for(i=0; conv_buf[i]; i++) {
193 conv_buf[i] = toupper(conv_buf[i]);
197 slen = strlen(conv_buf);
198 for(i=slen; i<fwidth; i++) {
199 bwrite(out, BUF(buf), SZ(sz), (char*)&padc, 1);
203 bwrite(out, BUF(buf), SZ(sz), conv_buf, strlen(conv_buf));
209 char c = va_arg(ap, int);
210 bwrite(out, BUF(buf), SZ(sz), &c, 1);
216 str = va_arg(ap, char*);
219 for(i=slen; i<fwidth; i++) {
220 bwrite(out, BUF(buf), SZ(sz), (char*)&padc, 1);
223 bwrite(out, BUF(buf), SZ(sz), str, slen);
228 *va_arg(ap, int*) = cnum;
235 /* restore default conversion state */
268 const char *fw = fmt;
269 while(*fmt && isdigit(*fmt)) fmt++;
278 bwrite(out, BUF(buf), SZ(sz), (char*)fmt++, 1);
287 /* bwrite is called by intern_printf to transparently handle writing into a
288 * buffer or to the terminal
290 static void bwrite(int out, char *buf, size_t buf_sz, char *str, int sz)
295 if(buf_sz && buf_sz <= sz) sz = buf_sz - 1;
296 memcpy(buf, str, sz);
302 for(i=0; i<sz; i++) {
308 for(i=0; i<sz; i++) {