voron

experimental ARM OS
git clone git://git.2f30.org/voron
Log | Files | Refs | README | LICENSE

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 }