1
2
3
4
5
6
7
8
9
10
11
12
13
14#include "minilib.h"
15
16typedef __builtin_va_list va_list;
17#define va_start(ap, X) __builtin_va_start(ap, X)
18#define va_arg(ap, type) __builtin_va_arg(ap, type)
19#define va_end(ap) __builtin_va_end(ap)
20
21static void print_str(char *s)
22{
23 while (*s) {
24 __sys_outc(*s++);
25 }
26}
27
28static void print_num(unsigned long long value, int base)
29{
30 char digits[] = "0123456789abcdef";
31 char buf[32];
32 int i = sizeof(buf) - 2, j;
33
34
35 for (j = 0; j < 32; j++) {
36 buf[j] = 0;
37 }
38
39 do {
40 buf[i--] = digits[value % base];
41 value /= base;
42 } while (value);
43
44 print_str(&buf[i + 1]);
45}
46
47void ml_printf(const char *fmt, ...)
48{
49 va_list ap;
50 char *str;
51 int base;
52 int has_long;
53 int alt_form;
54 unsigned long long val;
55
56 va_start(ap, fmt);
57
58 for (; *fmt; fmt++) {
59 if (*fmt != '%') {
60 __sys_outc(*fmt);
61 continue;
62 }
63 fmt++;
64
65 if (*fmt == '#') {
66 fmt++;
67 alt_form = 1;
68 } else {
69 alt_form = 0;
70 }
71
72 if (*fmt == 'l') {
73 fmt++;
74 if (*fmt == 'l') {
75 fmt++;
76 has_long = 2;
77 } else {
78 has_long = 1;
79 }
80 } else {
81 has_long = 0;
82 }
83
84 switch (*fmt) {
85 case 'x':
86 case 'p':
87 base = 16;
88 goto convert_number;
89 case 'd':
90 case 'i':
91 case 'u':
92 base = 10;
93 goto convert_number;
94 case 'o':
95 base = 8;
96 goto convert_number;
97
98 convert_number:
99 switch (has_long) {
100 case 0:
101 val = va_arg(ap, unsigned int);
102 break;
103 case 1:
104 val = va_arg(ap, unsigned long);
105 break;
106 case 2:
107 val = va_arg(ap, unsigned long long);
108 break;
109 }
110
111 if (alt_form && base == 16) {
112 print_str("0x");
113 }
114
115 print_num(val, base);
116 break;
117
118 case 's':
119 str = va_arg(ap, char*);
120 print_str(str);
121 break;
122 case 'c':
123 __sys_outc(va_arg(ap, int));
124 break;
125 case '%':
126 __sys_outc(*fmt);
127 break;
128 default:
129 __sys_outc('%');
130 __sys_outc(*fmt);
131 break;
132 }
133 }
134
135 va_end(ap);
136}
137