unified VC4 and ARM runtime code (including C++ runtime), updated some minor bits
[rpi-open-firmware.git] / lib / xprintf.c
1 /*------------------------------------------------------------------------/
2 / Universal string handler for user console interface
3 /-------------------------------------------------------------------------/
4 /
5 / Copyright (C) 2011, ChaN, all right reserved.
6 /
7 / * This software is a free software and there is NO WARRANTY.
8 / * No restriction on use. You can use, modify and redistribute it for
9 / personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
10 / * Redistributions of source code must retain the above copyright notice.
11 /
12 /-------------------------------------------------------------------------*/
13
14 #include "xprintf.h"
15
16 extern void uart_putc(unsigned int ch);
17
18 /*----------------------------------------------*/
19 /* Put a character */
20 /*----------------------------------------------*/
21
22 int putchar (int c)
23 {
24 if (_CR_CRLF && c == '\n') putchar('\r'); /* CR -> CRLF */
25
26 uart_putc(c);
27 }
28
29 /*----------------------------------------------*/
30 /* Put a null-terminated string */
31 /*----------------------------------------------*/
32
33 static int __puts ( /* Put a string to the default device */
34 const char* str /* Pointer to the string */
35 )
36 {
37 while (*str)
38 putchar(*str++);
39 }
40
41 int puts ( /* Put a string to the default device */
42 const char* str /* Pointer to the string */
43 )
44 {
45 __puts(str);
46 putchar('\n');
47 }
48
49 /*----------------------------------------------*/
50 /* Formatted string output */
51 /*----------------------------------------------*/
52 /* xprintf("%d", 1234); "1234"
53 xprintf("%6d,%3d%%", -200, 5); " -200, 5%"
54 xprintf("%-6u", 100); "100 "
55 xprintf("%ld", 12345678L); "12345678"
56 xprintf("%04x", 0xA3); "00a3"
57 xprintf("%08LX", 0x123ABC); "00123ABC"
58 xprintf("%016b", 0x550F); "0101010100001111"
59 xprintf("%s", "String"); "String"
60 xprintf("%-4s", "abc"); "abc "
61 xprintf("%4s", "abc"); " abc"
62 xprintf("%c", 'a'); "a"
63 xprintf("%f", 10.0); <xprintf lacks floating point support>
64 */
65
66 int vprintf (
67 const char* fmt, /* Pointer to the format string */
68 va_list arp /* Pointer to arguments */
69 )
70 {
71 unsigned int r, i, j, w, f;
72 unsigned long v;
73 char s[16], c, d, *p;
74
75
76 for (;;) {
77 c = *fmt++; /* Get a char */
78 if (!c) break; /* End of format? */
79 if (c != '%') { /* Pass through it if not a % sequense */
80 putchar(c); continue;
81 }
82 f = 0;
83 c = *fmt++; /* Get first char of the sequense */
84 if (c == '0') { /* Flag: '0' padded */
85 f = 1; c = *fmt++;
86 } else {
87 if (c == '-') { /* Flag: left justified */
88 f = 2; c = *fmt++;
89 }
90 }
91 for (w = 0; c >= '0' && c <= '9'; c = *fmt++) /* Minimum width */
92 w = w * 10 + c - '0';
93 if (c == 'l' || c == 'L') { /* Prefix: Size is long int */
94 f |= 4; c = *fmt++;
95 }
96 if (!c) break; /* End of format? */
97 d = c;
98 if (d >= 'a') d -= 0x20;
99 switch (d) { /* Type is... */
100 case 'S' : /* String */
101 p = va_arg(arp, char*);
102 for (j = 0; p[j]; j++) ;
103 while (!(f & 2) && j++ < w) putchar(' ');
104 __puts(p);
105 while (j++ < w) putchar(' ');
106 continue;
107 case 'C' : /* Character */
108 putchar((char)va_arg(arp, int)); continue;
109 case 'B' : /* Binary */
110 r = 2; break;
111 case 'O' : /* Octal */
112 r = 8; break;
113 case 'D' : /* Signed decimal */
114 case 'U' : /* Unsigned decimal */
115 r = 10; break;
116 case 'X' : /* Hexdecimal */
117 r = 16; break;
118 default: /* Unknown type (passthrough) */
119 putchar(c); continue;
120 }
121
122 /* Get an argument and put it in numeral */
123 v = (f & 4) ? va_arg(arp, long) : ((d == 'D') ? (long)va_arg(arp, int) : (long)va_arg(arp, unsigned int));
124 if (d == 'D' && (v & 0x80000000)) {
125 v = 0 - v;
126 f |= 8;
127 }
128 i = 0;
129 do {
130 d = (char)(v % r); v /= r;
131 if (d > 9) d += (c == 'x') ? 0x27 : 0x07;
132 s[i++] = d + '0';
133 } while (v && i < sizeof(s));
134 if (f & 8) s[i++] = '-';
135 j = i; d = (f & 1) ? '0' : ' ';
136 while (!(f & 2) && j++ < w) putchar(d);
137 do putchar(s[--i]); while(i);
138 while (j++ < w) putchar(' ');
139 }
140 }
141
142
143 int printf ( /* Put a formatted string to the default device */
144 const char* fmt, /* Pointer to the format string */
145 ... /* Optional arguments */
146 )
147 {
148 va_list arp;
149
150 va_start(arp, fmt);
151 vprintf(fmt, arp);
152 va_end(arp);
153 }
154
155
156 /*----------------------------------------------*/
157 /* Dump a line of binary dump */
158 /*----------------------------------------------*/
159
160 void put_dump (
161 const void* buff, /* Pointer to the array to be dumped */
162 unsigned long addr, /* Heading address value */
163 int len, /* Number of items to be dumped */
164 int width /* Size of the items (DF_CHAR, DF_SHORT, DF_LONG) */
165 )
166 {
167 int i;
168 const unsigned char *bp;
169 const unsigned short *sp;
170 const unsigned long *lp;
171
172
173 printf("%08lX ", addr); /* address */
174
175 switch (width) {
176 case DW_CHAR:
177 bp = buff;
178 for (i = 0; i < len; i++) /* Hexdecimal dump */
179 printf(" %02X", bp[i]);
180 putchar(' ');
181 for (i = 0; i < len; i++) /* ASCII dump */
182 putchar((bp[i] >= ' ' && bp[i] <= '~') ? bp[i] : '.');
183 break;
184 case DW_SHORT:
185 sp = buff;
186 do /* Hexdecimal dump */
187 printf(" %04X", *sp++);
188 while (--len);
189 break;
190 case DW_LONG:
191 lp = buff;
192 do /* Hexdecimal dump */
193 printf(" %08X", *lp++);
194 while (--len);
195 break;
196 }
197
198 putchar('\n');
199 }
This page took 0.12997 seconds and 4 git commands to generate.