print.c (3008B)
1 #include <kernel.h> 2 #include <rs232.h> 3 4 int 5 kputs(const char *s) 6 { 7 return rs232_puts(s); 8 } 9 10 int 11 kputchar(int c) 12 { 13 return rs232_putchar(c); 14 } 15 16 static inline int 17 abs(int n) 18 { 19 if (n < 0) 20 return -n; 21 return n; 22 } 23 24 static int 25 print_int(int n) 26 { 27 int ret = 0, i = 1; 28 29 if (n > 0) { 30 while (n/i >= 10) 31 i *= 10; 32 } else if (n < 0) { 33 kputchar('-'); 34 ret++; 35 while (n/i <= -10) 36 i *= 10; 37 } 38 39 while (i > 0) { 40 kputchar('0' + abs(n/i)); 41 ret++; 42 n -= (n/i)*i; 43 i /= 10; 44 } 45 46 return ret; 47 } 48 49 static int 50 print_ssize_t(ssize_t n) 51 { 52 int ret = 0; 53 ssize_t i = 1; 54 55 if (n > 0) { 56 while (n/i >= 10) 57 i *= 10; 58 } else if (n < 0) { 59 kputchar('-'); 60 ret++; 61 while (n/i <= -10) 62 i *= 10; 63 } 64 65 while (i > 0) { 66 kputchar('0' + abs(n/i)); 67 ret++; 68 n -= (n/i)*i; 69 i /= 10; 70 } 71 72 return ret; 73 } 74 75 static int 76 print_size_t(size_t n) 77 { 78 int ret = 0; 79 size_t i = 1; 80 81 while (n/i >= 10) 82 i *= 10; 83 84 while (i > 0) { 85 kputchar('0' + abs(n/i)); 86 ret++; 87 n -= (n/i)*i; 88 i /= 10; 89 } 90 91 return ret; 92 } 93 94 static int 95 print_hexint(uint_t n) 96 { 97 uint_t x, mask; 98 int i, bits, b, ret = 0; 99 100 if (n == 0) { 101 kputchar('0'); 102 return 1; 103 } else { 104 bits = sizeof(uint_t) * 8; 105 b = bits; 106 mask = 0xf << (bits - 4); 107 108 for (i = 1; i <= b/4; i++) { 109 if (n & mask) 110 break; 111 bits -= 4; 112 mask >>= 4; 113 } 114 115 for (; i <= b/4; i++) { 116 bits -= 4; 117 x = (n & mask) >> bits; 118 mask >>= 4; 119 if (x < 0xa) 120 kputchar('0' + x); 121 else 122 kputchar('a' + x - 10); 123 ret++; 124 } 125 } 126 127 return ret; 128 } 129 130 static int 131 print_pointer(uintptr_t p) 132 { 133 uintptr_t x, mask; 134 int i, bits, b, ret = 0; 135 136 if (p == 0) { 137 kputs("(nil)"); 138 return 5; 139 } else { 140 bits = sizeof(uintptr_t) * 8; 141 b = bits; 142 mask = 0xf << (bits - 4); 143 144 kputs("0x"); 145 ret += 2; 146 147 for (i = 1; i <= b/4; i++) { 148 bits -= 4; 149 x = (p & mask) >> bits; 150 mask >>= 4; 151 if (x < 0xa) 152 kputchar('0' + x); 153 else 154 kputchar('a' + x - 10); 155 ret++; 156 } 157 } 158 159 return ret; 160 } 161 162 int 163 kprintf(const char *fmt, ...) 164 { 165 va_list ap; 166 int ret; 167 168 va_start(ap, fmt); 169 ret = kvprintf(fmt, ap); 170 va_end(ap); 171 172 return ret; 173 } 174 175 int 176 kvprintf(const char *fmt, va_list ap) 177 { 178 int d, ret = 0; 179 uint_t x; 180 uintptr_t p; 181 size_t sz; 182 ssize_t ssz; 183 char c, *s; 184 185 while (*fmt) { 186 switch (*fmt) { 187 case '%': 188 fmt++; 189 switch (*fmt) { 190 case 'd': 191 d = va_arg(ap, int); 192 ret += print_int(d); 193 break; 194 case 'x': 195 x = va_arg(ap, uint_t); 196 ret += print_hexint(x); 197 break; 198 case 'p': 199 p = va_arg(ap, uintptr_t); 200 ret += print_pointer(p); 201 break; 202 case 's': 203 s = va_arg(ap, char*); 204 ret += kputs(s); 205 break; 206 case 'c': 207 c = va_arg(ap, char); 208 kputchar(c); 209 ret++; 210 break; 211 case 'z': 212 fmt++; 213 if (*fmt == 'u') { 214 sz = va_arg(ap, size_t); 215 ret += print_size_t(sz); 216 } else if (*fmt == 'd') { 217 ssz = va_arg(ap, ssize_t); 218 ret += print_ssize_t(ssz); 219 } 220 break; 221 case '%': 222 kputchar('%'); 223 ret++; 224 } 225 break; 226 default: 227 kputchar(*fmt); 228 ret++; 229 } 230 if (*fmt) 231 fmt++; 232 } 233 234 return ret; 235 }