source: mainline/arch/ppc64/loader/printf.c@ a8844e0

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a8844e0 was a8844e0, checked in by Martin Decky <martin@…>, 19 years ago

fix types, 64b arguments (breaks things yet)

  • Property mode set to 100644
File size: 5.9 KB
Line 
1/*
2 * Copyright (C) 2006 Martin Decky
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 "printf.h"
30#include "ofw.h"
31
32static char digits[] = "0123456789abcdef"; /**< Hexadecimal characters */
33
34
35void puts(const char *str)
36{
37 long len = 0;
38
39 while (str[len] != 0)
40 len++;
41
42 ofw_write(str, len);
43}
44
45
46/** Print hexadecimal digits
47 *
48 * Print fixed count of hexadecimal digits from
49 * the number num. The digits are printed in
50 * natural left-to-right order starting with
51 * the width-th digit.
52 *
53 * @param num Number containing digits.
54 * @param width Count of digits to print.
55 *
56 */
57static void print_fixed_hex(const __u64 num, const int width)
58{
59 int i;
60
61 for (i = width * 8 - 4; i >= 0; i -= 4)
62 ofw_write(digits + ((num >> i) & 0xf), 1);
63}
64
65
66/** Print number in given base
67 *
68 * Print significant digits of a number in given
69 * base.
70 *
71 * @param num Number to print.
72 * @param base Base to print the number in (should
73 * be in range 2 .. 16).
74 *
75 */
76static void print_number(const __native num, const unsigned int base)
77{
78 int val = num;
79 char d[sizeof(__native) * 8 + 1]; /* this is good enough even for base == 2 */
80 int i = sizeof(__native) * 8 - 1;
81
82 do {
83 d[i--] = digits[val % base];
84 } while (val /= base);
85
86 d[sizeof(__native) * 8] = 0;
87 puts(&d[i + 1]);
88}
89
90
91/** General formatted text print
92 *
93 * Print text formatted according the fmt parameter
94 * and variant arguments. Each formatting directive
95 * begins with \% (percentage) character and one of the
96 * following character:
97 *
98 * \% Prints the percentage character.
99 *
100 * s The next variant argument is treated as char*
101 * and printed as a NULL terminated string.
102 *
103 * c The next variant argument is treated as a single char.
104 *
105 * p The next variant argument is treated as a maximum
106 * bit-width integer with respect to architecture
107 * and printed in full hexadecimal width.
108 *
109 * P As with 'p', but '0x' is prefixed.
110 *
111 * q The next variant argument is treated as a 64b integer
112 * and printed in full hexadecimal width.
113 *
114 * Q As with 'q', but '0x' is prefixed.
115 *
116 * l The next variant argument is treated as a 32b integer
117 * and printed in full hexadecimal width.
118 *
119 * L As with 'l', but '0x' is prefixed.
120 *
121 * w The next variant argument is treated as a 16b integer
122 * and printed in full hexadecimal width.
123 *
124 * W As with 'w', but '0x' is prefixed.
125 *
126 * b The next variant argument is treated as a 8b integer
127 * and printed in full hexadecimal width.
128 *
129 * B As with 'b', but '0x' is prefixed.
130 *
131 * d The next variant argument is treated as integer
132 * and printed in standard decimal format (only significant
133 * digits).
134 *
135 * x The next variant argument is treated as integer
136 * and printed in standard hexadecimal format (only significant
137 * digits).
138 *
139 * X As with 'x', but '0x' is prefixed.
140 *
141 * All other characters from fmt except the formatting directives
142 * are printed in verbatim.
143 *
144 * @param fmt Formatting NULL terminated string.
145 */
146void printf(const char *fmt, ...)
147{
148 long i = 0;
149 va_list ap;
150 char c;
151
152 va_start(ap, fmt);
153
154 while ((c = fmt[i++])) {
155 switch (c) {
156
157 /* control character */
158 case '%':
159
160 switch (c = fmt[i++]) {
161
162 /* percentile itself */
163 case '%':
164 break;
165
166 /*
167 * String and character conversions.
168 */
169 case 's':
170 puts(va_arg(ap, char_ptr));
171 goto loop;
172
173 case 'c':
174 c = (char) va_arg(ap, int);
175 break;
176
177 /*
178 * Hexadecimal conversions with fixed width.
179 */
180 case 'P':
181 puts("0x");
182 case 'p':
183 print_fixed_hex(va_arg(ap, __native), sizeof(__native));
184 goto loop;
185
186 case 'Q':
187 puts("0x");
188 case 'q':
189 print_fixed_hex(va_arg(ap, __u64), INT64);
190 goto loop;
191
192 case 'L':
193 puts("0x");
194 case 'l':
195 print_fixed_hex(va_arg(ap, __native), INT32);
196 goto loop;
197
198 case 'W':
199 puts("0x");
200 case 'w':
201 print_fixed_hex(va_arg(ap, __native), INT16);
202 goto loop;
203
204 case 'B':
205 puts("0x");
206 case 'b':
207 print_fixed_hex(va_arg(ap, __native), INT8);
208 goto loop;
209
210 /*
211 * Decimal and hexadecimal conversions.
212 */
213 case 'd':
214 print_number(va_arg(ap, __native), 10);
215 goto loop;
216
217 case 'X':
218 puts("0x");
219 case 'x':
220 print_number(va_arg(ap, __native), 16);
221 goto loop;
222
223 /*
224 * Bad formatting.
225 */
226 default:
227 goto out;
228 }
229
230 default:
231 if (c == '\n')
232 ofw_write("\r", 1);
233 ofw_write(&c, 1);
234 }
235
236loop:
237 ;
238 }
239
240out:
241
242 va_end(ap);
243}
Note: See TracBrowser for help on using the repository browser.