kvm: testsuite: silence warnings on x86_64
[qemu-kvm/amd-iommu.git] / kvm / user / test / x86 / lib / printf.c
blobf70eb1fc34ae2bb8306f4b02a3aeda971f90da0e
1 #include "printf.h"
2 #include "smp.h"
3 #include <stdarg.h>
4 #include "string.h"
6 static struct spinlock lock;
8 void print(const char *s);
10 typedef struct pstream {
11 char *buffer;
12 int remain;
13 int added;
14 } pstream_t;
16 static void addchar(pstream_t *p, char c)
18 if (p->remain) {
19 *p->buffer++ = c;
20 --p->remain;
22 ++p->added;
25 void print_str(pstream_t *p, const char *s)
27 while (*s)
28 addchar(p, *s++);
31 static char digits[16] = "0123456789abcdef";
33 void print_int(pstream_t *ps, long long n, int base)
35 char buf[sizeof(long) * 3 + 2], *p = buf;
36 int s = 0, i;
38 if (n < 0) {
39 n = -n;
40 s = 1;
43 while (n) {
44 *p++ = digits[n % base];
45 n /= base;
48 if (s)
49 *p++ = '-';
51 if (p == buf)
52 *p++ = '0';
54 for (i = 0; i < (p - buf) / 2; ++i) {
55 char tmp;
57 tmp = buf[i];
58 buf[i] = p[-1-i];
59 p[-1-i] = tmp;
62 *p = 0;
64 print_str(ps, buf);
67 void print_unsigned(pstream_t *ps, unsigned long long n, int base)
69 char buf[sizeof(long) * 3 + 1], *p = buf;
70 int i;
72 while (n) {
73 *p++ = digits[n % base];
74 n /= base;
77 if (p == buf)
78 *p++ = '0';
80 for (i = 0; i < (p - buf) / 2; ++i) {
81 char tmp;
83 tmp = buf[i];
84 buf[i] = p[-1-i];
85 p[-1-i] = tmp;
88 *p = 0;
90 print_str(ps, buf);
93 int vsnprintf(char *buf, int size, const char *fmt, va_list va)
95 pstream_t s;
97 s.buffer = buf;
98 s.remain = size - 1;
99 s.added = 0;
100 while (*fmt) {
101 char f = *fmt++;
102 int nlong = 0;
104 if (f != '%') {
105 addchar(&s, f);
106 continue;
108 morefmt:
109 f = *fmt++;
110 switch (f) {
111 case '%':
112 addchar(&s, '%');
113 break;
114 case '\0':
115 --fmt;
116 break;
117 case 'l':
118 ++nlong;
119 goto morefmt;
120 case 'd':
121 switch (nlong) {
122 case 0:
123 print_int(&s, va_arg(va, int), 10);
124 break;
125 case 1:
126 print_int(&s, va_arg(va, long), 10);
127 break;
128 default:
129 print_int(&s, va_arg(va, long long), 10);
130 break;
132 break;
133 case 'x':
134 switch (nlong) {
135 case 0:
136 print_unsigned(&s, va_arg(va, unsigned), 16);
137 break;
138 case 1:
139 print_unsigned(&s, va_arg(va, unsigned long), 16);
140 break;
141 default:
142 print_unsigned(&s, va_arg(va, unsigned long long), 16);
143 break;
145 break;
146 case 'p':
147 print_str(&s, "0x");
148 print_unsigned(&s, (unsigned long)va_arg(va, void *), 16);
149 break;
150 case 's':
151 print_str(&s, va_arg(va, const char *));
152 break;
153 default:
154 addchar(&s, f);
155 break;
158 *s.buffer = 0;
159 ++s.added;
160 return s.added;
164 int snprintf(char *buf, int size, const char *fmt, ...)
166 va_list va;
167 int r;
169 va_start(va, fmt);
170 r = vsnprintf(buf, size, fmt, va);
171 va_end(va);
172 return r;
175 void print_serial(const char *buf)
177 unsigned long len = strlen(buf);
179 asm volatile ("rep/outsb" : "+S"(buf), "+c"(len) : "d"(0xf1));
182 int printf(const char *fmt, ...)
184 va_list va;
185 char buf[2000];
186 int r;
188 va_start(va, fmt);
189 r = vsnprintf(buf, sizeof buf, fmt, va);
190 va_end(va);
191 spin_lock(&lock);
192 print_serial(buf);
193 spin_unlock(&lock);
194 return r;