source: mainline/libc/generic/io/print.c@ 7d1562e9

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

Add -N to ia64 libc/Makefile.

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