m3dev

cortex m3 debug tools -- superceded by mdebug
git clone http://frotz.net/git/m3dev.git
Log | Files | Refs | README | LICENSE

print.c (2711B)


      1 /* print.c
      2  *
      3  * Copyright 2011 Brian Swetland <swetland@frotz.net>
      4  * 
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 #include <fw/lib.h>
     19 
     20 static const char hex[16] = "0123456789ABCDEF";
     21 
     22 char *printhex(char *tmp, unsigned c, unsigned n)
     23 {
     24 	tmp[c] = 0;
     25 	while (c-- > 0) {
     26 		tmp[c] = hex[n & 0x0F];
     27 		n >>= 4;
     28 	}
     29 
     30 	return tmp;
     31 }
     32 
     33 char *print_unsigned(char *tmp, int len, unsigned n, int w)
     34 {
     35 	len--;
     36 	tmp[len] = '\0';
     37 
     38 	if (w < 0 && n == 0) {
     39 		tmp[--len] = '0';
     40 	} else {
     41 		while ((len >= 0) && (n || (w > 0))) {
     42 			tmp[--len] = hex[n % 10];
     43 			n /= 10;
     44 			w--;
     45 		}
     46 	}
     47 
     48 	return &tmp[len];
     49 }
     50 
     51 char *print_signed(char *tmp, int len, signed n, int w)
     52 {
     53 	char *s;
     54 
     55 	if (n >= 0)
     56 		return print_unsigned(tmp, len, n, w);
     57 
     58 	s = print_unsigned(tmp + 1, len - 1, n * -1, w - 1);
     59 	s--;
     60 	*s = '-';
     61 	return s;
     62 }
     63 
     64 char *print_ufixed(char *tmp, int len, unsigned n)
     65 {
     66 	char * s;
     67 	char * point;
     68 
     69 	n >>= 2;
     70 
     71 	/* XXX: does not account for overflow */
     72 	n *= 15625;
     73 	s = print_unsigned(tmp + 1, len - 1, (n + 50000) / 100000 % 10, 1);
     74 	point = s - 1;
     75 	s = print_unsigned(tmp, (s - tmp), n / 1000000, -1);
     76 	*point = '.';
     77 
     78 	return s;
     79 }
     80 
     81 char *print_fixed(char *tmp, int len, signed n)
     82 {
     83 	char * s;
     84 
     85 	if (n >= 0)
     86 		return print_ufixed(tmp, len, n);
     87 
     88 	s = print_ufixed(tmp + 1, len - 1, n * -1);
     89 	s--;
     90 	*s = '-';
     91 
     92 	return s;
     93 }
     94 
     95 void vprintx(void (*_putc)(unsigned), const char *fmt, va_list ap) {
     96 	unsigned c;
     97 	const char *s;
     98 	char tmp[16];
     99 
    100 	while ((c = *fmt++)) {
    101 		if (c != '%') {
    102 			_putc(c);
    103 			continue;
    104 		}
    105 
    106 		switch((c = *fmt++)) {
    107 		case 0:
    108 			return;
    109 
    110 		case 'x':
    111 			s = printhex(tmp, 8, va_arg(ap, unsigned));
    112 			break;
    113 
    114 		case 'h':
    115 			s = printhex(tmp, 4, va_arg(ap, unsigned));
    116 			break;
    117 
    118 		case 'b':
    119 			s = printhex(tmp, 2, va_arg(ap, unsigned));
    120 			break;
    121 
    122 		case 'u':
    123 			s = print_unsigned(tmp, sizeof(tmp), va_arg(ap, unsigned), -1);
    124 			break;
    125 
    126 		case 'd':
    127 			s = print_signed(tmp, sizeof(tmp), va_arg(ap, signed), -1);
    128 			break;
    129 
    130 		case 'f':
    131 			s = print_fixed(tmp, sizeof(tmp), va_arg(ap, signed));
    132 			break;
    133 
    134 		case 's':
    135 			s = va_arg(ap, const char *);
    136 			break;
    137 
    138 		case 'c':
    139 			c = va_arg(ap, unsigned); /* fall through */
    140 
    141 		default:
    142 			_putc(c); continue;
    143 		}
    144 
    145 		while (*s)
    146 			_putc(*s++);
    147 	}
    148 }
    149