|
|
1.1 root 1: /* A reduced version of the printf function.
2:
3: Copyright (C) 2011 Richard Henderson
4:
5: This file is part of QEMU PALcode.
6:
7: This program is free software; you can redistribute it and/or modify
8: it under the terms of the GNU General Public License as published by
9: the Free Software Foundation; either version 2 of the License or
10: (at your option) any later version.
11:
12: This program is distributed in the hope that it will be useful,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the text
15: of the GNU General Public License for more details.
16:
17: You should have received a copy of the GNU General Public License
18: along with this program; see the file COPYING. If not see
19: <http://www.gnu.org/licenses/>. */
20:
21: #include <stdarg.h>
22: #include <stdbool.h>
23: #include <string.h>
24: #include "console.h"
25:
26: static int print_buf_pad(char *buf, int buflen, char *p, int width, int pad)
27: {
28: int len = buf + buflen - p;
29: int r = 0;
30:
31: if (width > len)
32: {
33: *--p = pad;
34: len++;
35:
36: while (width > buflen)
37: {
38: crb_puts(0, p, 1);
39: width--;
40: r++;
41: }
42: while (width > len)
43: *--p = pad, len++;
44: }
45:
46: crb_puts(0, p, len);
47: return r + len;
48: }
49:
50: static int print_decimal(unsigned long val, int width, int pad)
51: {
52: char buf[32];
53: char *p = buf + sizeof(buf);
54:
55: if (val == 0)
56: *--p = '0';
57: else
58: {
59: do
60: {
61: unsigned long d, r;
62:
63: /* Compiling with -Os results in a call to the division routine.
64: Do what the compiler ought to have done. */
65: d = __builtin_alpha_umulh(val, 0xcccccccccccccccd);
66: d >>= 3;
67: r = val - (d * 10);
68:
69: *--p = r + '0';
70: val = d;
71: }
72: while (val);
73: }
74:
75: return print_buf_pad(buf, sizeof(buf), p, width, pad);
76: }
77:
78: static int print_hex(unsigned long val, int width, char pad)
79: {
80: char buf[32];
81: char *p = buf + sizeof(buf);
82:
83: if (val == 0)
84: *--p = '0';
85: else
86: {
87: do
88: {
89: int d = val % 16;
90: *--p = (d < 10 ? '0' : 'a' - 10) + d;
91: val /= 16;
92: }
93: while (val);
94: }
95:
96: return print_buf_pad(buf, sizeof(buf), p, width, pad);
97: }
98:
99: int printf(const char *fmt, ...)
100: {
101: va_list args;
102: unsigned long val;
103: int r = 0;
104:
105: va_start(args, fmt);
106:
107: for (; *fmt ; fmt++)
108: if (*fmt != '%')
109: {
110: crb_puts(0, fmt, 1);
111: r++;
112: }
113: else
114: {
115: const char *percent = fmt;
116: bool is_long = false;
117: char pad = ' ';
118: int width = 0;
119:
120: restart:
121: switch (*++fmt)
122: {
123: case '%':
124: crb_puts(0, "%", 1);
125: r++;
126: break;
127:
128: case 'l':
129: is_long = true;
130: goto restart;
131:
132: case 'd':
133: if (is_long)
134: {
135: long d = va_arg (args, long);
136: if (d < 0)
137: {
138: crb_puts(0, "-", 1);
139: d = -d;
140: }
141: val = d;
142: }
143: else
144: {
145: int d = va_arg (args, int);
146: if (d < 0)
147: {
148: crb_puts(0, "-", 1);
149: d = -d;
150: r++;
151: }
152: val = d;
153: }
154: goto do_unsigned;
155:
156: case 'u':
157: if (is_long)
158: val = va_arg (args, unsigned long);
159: else
160: val = va_arg (args, unsigned int);
161:
162: do_unsigned:
163: r += print_decimal (val, width, pad);
164: break;
165:
166: case 'x':
167: if (is_long)
168: val = va_arg (args, unsigned long);
169: else
170: val = va_arg (args, unsigned int);
171: r += print_hex (val, width, pad);
172: break;
173:
174: case 's':
175: {
176: const char *s = va_arg (args, const char *);
177: int len = strlen(s);
178: crb_puts(0, s, len);
179: r += len;
180: }
181: break;
182:
183: case '0':
184: pad = '0';
185: case '1' ... '9':
186: width = *fmt - '0';
187: while (fmt[1] >= '0' && fmt[1] <= '9')
188: width = width * 10 + *++fmt - '0';
189: goto restart;
190:
191: default:
192: {
193: int len = fmt - percent;
194: crb_puts(0, percent, len);
195: r += len;
196: }
197: break;
198: }
199: }
200:
201: va_end(args);
202: return r;
203: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.