source: mainline/src/debug/print.c@ 244f284

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 244f284 was da79d0fd, checked in by Jakub Jermar <jakub@…>, 20 years ago

Add %P and %p formatters to printf for printing pointers in maximum bit width.
Add %Q and %q formatters to printf for printing 64-bit integers.

  • Property mode set to 100644
File size: 6.2 KB
Line 
1/*
2 * Copyright (C) 2001-2004 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <putchar.h>
30#include <print.h>
31#include <synch/spinlock.h>
32#include <arch/arg.h>
33
34
35static char digits[] = "0123456789abcdef"; /**< Hexadecimal characters */
36static spinlock_t printflock; /**< printf spinlock */
37
38
39/** Print NULL terminated string
40 *
41 * Print characters from str using putchar() until
42 * \x00 character is reached.
43 *
44 * @param str Characters to print.
45 *
46 */
47void print_str(const char *str)
48{
49 int i = 0;
50 char c;
51
52 while (c = str[i++])
53 putchar(c);
54}
55
56
57/** Print hexadecimal digits
58 *
59 * Print fixed count of hexadecimal digits from
60 * the number num. The digits are printed in
61 * natural left-to-right order starting with
62 * the width-th digit.
63 *
64 * @param num Number containing digits.
65 * @param width Count of digits to print.
66 *
67 */
68void print_fixed_hex(const __native num, const int width)
69{
70 int i;
71
72 for (i = width*8 - 4; i >= 0; i -= 4)
73 putchar(digits[(num>>i) & 0xf]);
74}
75
76
77/** Print number in given base
78 *
79 * Print significant digits of a number in given
80 * base.
81 *
82 * @param num Number to print.
83 * @param base Base to print the number in (should
84 * be in range 2 .. 16).
85 *
86 */
87void print_number(const __native num, const unsigned int base)
88{
89 int val = num;
90 char d[sizeof(__native)*8+1]; /* this is good enough even for base == 2 */
91 int i = sizeof(__native)*8-1;
92
93 do {
94 d[i--] = digits[val % base];
95 } while (val /= base);
96
97 d[sizeof(__native)*8] = 0;
98 print_str(&d[i + 1]);
99}
100
101
102/** General formatted text print
103 *
104 * Print text formatted according the fmt parameter
105 * and variant arguments. Each formatting directive
106 * begins with % (percentage) character and one of the
107 * following character:
108 *
109 * % Prints the percentage character.
110 * s The next variant argument is treated as char*
111 * and printed as a NULL terminated string.
112 * c The next variant argument is treated as a single char.
113 * p The next variant argument is treated as a maximum
114 * bit-width integer with respect to architecture
115 * and printed in full hexadecimal width.
116 * P As with 'p', but '0x' is prefixed.
117 * q The next variant argument is treated as a 64b integer
118 * and printed in full hexadecimal width.
119 * Q As with 'q', but '0x' is prefixed.
120 * l The next variant argument is treated as a 32b integer
121 * and printed in full hexadecimal width.
122 * L As with 'l', but '0x' is prefixed.
123 * w The next variant argument is treated as a 16b integer
124 * and printed in full hexadecimal width.
125 * W As with 'w', but '0x' is prefixed.
126 * b The next variant argument is treated as a 8b integer
127 * and printed in full hexadecimal width.
128 * N As with 'b', but '0x' is prefixed.
129 * d The next variant argument is treated as integer
130 * and printed in standard decimal format (only significant
131 * digits).
132 * x The next variant argument is treated as integer
133 * and printed in standard hexadecimal format (only significant
134 * digits).
135 * X As with 'x', but '0x' is prefixed.
136 *
137 * All other characters from fmt except the formatting directives
138 * are printed in verbatim.
139 *
140 * @param fmt Formatting NULL terminated string.
141 *
142 */
143void printf(const char *fmt, ...)
144{
145 int irqpri, i = 0;
146 va_list ap;
147 char c;
148
149 va_start(ap, fmt);
150
151 irqpri = cpu_priority_high();
152 spinlock_lock(&printflock);
153
154 while (c = fmt[i++]) {
155 switch (c) {
156
157 /* control character */
158 case '%':
159 switch (c = fmt[i++]) {
160
161 /* percentile itself */
162 case '%':
163 break;
164
165 /*
166 * String and character conversions.
167 */
168 case 's':
169 print_str(va_arg(ap, char_ptr));
170 goto loop;
171
172 case 'c':
173 c = (char) va_arg(ap, int);
174 break;
175
176 /*
177 * Hexadecimal conversions with fixed width.
178 */
179 case 'P':
180 print_str("0x");
181 case 'p':
182 print_fixed_hex(va_arg(ap, __native), sizeof(__native));
183 goto loop;
184
185 case 'Q':
186 print_str("0x");
187 case 'q':
188 print_fixed_hex(va_arg(ap, __native), INT64);
189 goto loop;
190
191 case 'L':
192 print_str("0x");
193 case 'l':
194 print_fixed_hex(va_arg(ap, __native), INT32);
195 goto loop;
196
197 case 'W':
198 print_str("0x");
199 case 'w':
200 print_fixed_hex(va_arg(ap, __native), INT16);
201 goto loop;
202
203 case 'B':
204 print_str("0x");
205 case 'b':
206 print_fixed_hex(va_arg(ap, __native), INT8);
207 goto loop;
208
209 /*
210 * Decimal and hexadecimal conversions.
211 */
212 case 'd':
213 print_number(va_arg(ap, __native), 10);
214 goto loop;
215
216 case 'X':
217 print_str("0x");
218 case 'x':
219 print_number(va_arg(ap, __native), 16);
220 goto loop;
221
222 /*
223 * Bad formatting.
224 */
225 default:
226 goto out;
227 }
228
229 default: putchar(c);
230 }
231
232loop:
233 ;
234 }
235
236out:
237 spinlock_unlock(&printflock);
238 cpu_priority_restore(irqpri);
239
240 va_end(ap);
241}
Note: See TracBrowser for help on using the repository browser.