CS350 COS
COS
Loading...
Searching...
No Matches
printf.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2006-2023 Ali Mashtizadeh
3 * All rights reserved.
4 */
5
6#include <stdbool.h>
7#include <stdint.h>
8#include <stdarg.h>
9#include <string.h>
10
11#include <sys/kassert.h>
12
13#include "../dev/console.h"
14
15// static unsigned long getuint(va_list *ap, int lflag)
16#define getuint(ap, lflag) \
17 (lflag == 8) ? va_arg(ap, uint64_t) : \
18 (lflag == 4) ? va_arg(ap, uint32_t) : \
19 (lflag == 2) ? va_arg(ap, uint32_t) : \
20 (lflag == 1) ? va_arg(ap, uint32_t) : 0
21
22// static long getint(va_list *ap, int lflag)
23#define getint(ap, lflag) \
24 (lflag == 8) ? va_arg(ap, int64_t) : \
25 (lflag == 4) ? va_arg(ap, int32_t) : \
26 (lflag == 2) ? va_arg(ap, int32_t) : \
27 (lflag == 1) ? va_arg(ap, int32_t) : 0
28
29static const char *numberstring_lower = "0123456789abcdef";
30static const char *numberstring_upper = "0123456789ABCDEF";
31
32static void printnum(void (*func)(int, void*),void *handle,
33 uint64_t num,int base,int width,int padc)
34{
35 char buf[64];
36 char *p = buf;
37 int spaces;
38 if (base < 0)
39 {
40 base = -base;
41 do {
42 *p = numberstring_upper[num % base];
43 p++;
44 } while (num /= base);
45 } else {
46 do {
47 *p = numberstring_lower[num % base];
48 p++;
49 } while (num /= base);
50 }
51
52 // Print spacers (pre-number)
53 spaces = width - (p - buf);
54 if (padc == ' ' || padc == '0') {
55 while (spaces > 0)
56 {
57 func(padc, handle);
58 spaces--;
59 }
60 }
61
62 // Print Number
63 while (p != buf) {
64 p--;
65 func((int)*p, handle);
66 }
67
68 // Print spacers (post-number)
69 if (padc == '-') {
70 while (spaces > 0)
71 {
72 func(' ', handle);
73 spaces--;
74 }
75 }
76}
77
78int kvprintf(char const *fmt, void (*func)(int,void *), void *handle, va_list ap)
79{
80 const char *p;
81 int ch;
82 uint64_t unum;
83 int64_t num;
84 int lflag, width, padc;
85
86 while (1) {
87 while ((ch = *(unsigned char *)fmt++) != '%') {
88 if (ch == '\0') return -1;
89 func(ch, handle);
90 }
91
92 width = -1;
93 lflag = 4;
94 padc = ' ';
95again:
96 switch (ch = *(unsigned char *)fmt++) {
97 case '-':
98 padc = '-';
99 goto again;
100 case '0':
101 padc = '0';
102 goto again;
103 case '1':
104 case '2':
105 case '3':
106 case '4':
107 case '5':
108 case '6':
109 case '7':
110 case '8':
111 case '9':
112 width = 0;
113 while (1) {
114 width = 10 * width + ch - '0';
115 ch = *fmt;
116 if (ch < '0' || ch > '9')
117 {
118 break;
119 }
120 fmt++;
121 if (ch == '\0')
122 {
123 fmt--;
124 goto again;
125 }
126 }
127 goto again;
128 case 'c':
129 func(va_arg(ap, int) & 0xff, handle);
130 break;
131 case 's': {
132 int spaces;
133
134 p = va_arg(ap, char *);
135 ASSERT(p != 0);
136 spaces = width - strlen(p);
137
138 if (padc == ' ') {
139 while (spaces > 0)
140 {
141 func(' ', handle);
142 spaces--;
143 }
144 }
145
146 while (*p != '\0')
147 {
148 func(*p++, handle);
149 }
150
151 if (padc == '-') {
152 while (spaces > 0)
153 {
154 func(' ', handle);
155 spaces--;
156 }
157 }
158 break;
159 }
160 case 'd':
161 num = getint(ap, lflag);
162 if (num < 0) {
163 func('-', handle);
164 unum = -num;
165 } else {
166 unum = num;
167 }
168 printnum(func, handle, unum, 10, width, padc);
169 break;
170 case 'u':
171 unum = getuint(ap, lflag);
172 printnum(func, handle, unum, 10, width, padc);
173 break;
174 case 'o':
175 unum = getuint(ap, lflag);
176 printnum(func, handle, unum, 8, width, padc);
177 break;
178 case 'p':
179 unum = (unsigned long)va_arg(ap, void *);
180 printnum(func, handle, unum, 8, width, padc);
181 break;
182 case 'x':
183 unum = getuint(ap, lflag);
184 printnum(func, handle, unum, 16, width, padc);
185 break;
186 case 'X':
187 unum = getuint(ap, lflag);
188 printnum(func, handle, unum, -16, width, padc);
189 break;
190 case 'l':
191 lflag = 8;
192 goto again;
193 case '%':
194 default: // Print Literally
195 func(ch, handle);
196 break;
197 }
198 }
199 return 0;
200}
201
202void consoleputc(int c,void* handle)
203{
204 if (c == '\n') {
205 Console_Putc('\r');
206 }
207 Console_Putc(c);
208}
209
210int kprintf(const char *fmt, ...)
211{
212 int ret;
213 va_list ap;
214
215 va_start(ap, fmt);
216 ret = kvprintf(fmt, consoleputc, 0, ap);
217 va_end(ap);
218
219 return ret;
220}
221
222void Debug_Assert(const char *fmt, ...)
223{
224 va_list ap;
225
226 va_start(ap, fmt);
227 kvprintf(fmt, consoleputc, 0, ap);
228 va_end(ap);
229
230#if 0
231 kprintf("PC %lx FP %lx\n", __builtin_return_address(0), __builtin_frame_address(0));
232 kprintf("PC %lx FP %lx\n", __builtin_return_address(1), __builtin_frame_address(1));
233 kprintf("PC %lx FP %lx\n", __builtin_return_address(2), __builtin_frame_address(2));
234 kprintf("PC %lx FP %lx\n", __builtin_return_address(3), __builtin_frame_address(3));
235 kprintf("PC %lx FP %lx\n", __builtin_return_address(4), __builtin_frame_address(4));
236 kprintf("PC %lx FP %lx\n", __builtin_return_address(5), __builtin_frame_address(5));
237#endif
238
239 Panic("");
240}
241
void Console_Putc(char ch)
Definition: console.c:131
static char buf[4096]
Definition: ethdump.c:10
#define ASSERT(_x)
Definition: kassert.h:8
#define getuint(ap, lflag)
Definition: printf.c:13
static void printnum(void(*func)(int, void *), void *handle, uint64_t num, int base, int width, int padc)
Definition: printf.c:29
static int kvprintf(char const *fmt, void(*func)(int, void *), void *handle, va_list ap)
Definition: printf.c:75
#define getint(ap, lflag)
Definition: printf.c:20
static const char * numberstring_upper
Definition: printf.c:27
static const char * numberstring_lower
Definition: printf.c:26
static uint16_t base
Definition: sercons.c:37
#define va_arg(ap, type)
Definition: stdarg.h:12
#define va_end(ap)
Definition: stdarg.h:21
#define va_start(ap, last)
Definition: stdarg.h:9
__builtin_va_list va_list
Definition: stdarg.h:6
size_t strlen(const char *str)
Definition: string.c:112
int kprintf(const char *fmt,...)
Definition: printf.c:210
void Debug_Assert(const char *fmt,...)
Definition: printf.c:222
void consoleputc(int c, void *handle)
Definition: printf.c:202
unsigned long uint64_t
Definition: types.h:13
signed long int64_t
Definition: types.h:8
void Panic(const char *str)
Definition: vgacons.c:164