xref: /kvm-unit-tests/lib/printf.c (revision 7d36db351752e29ad27eaafe3f102de7064e429b)
1*7d36db35SAvi Kivity #include "libcflat.h"
2*7d36db35SAvi Kivity 
3*7d36db35SAvi Kivity typedef struct pstream {
4*7d36db35SAvi Kivity     char *buffer;
5*7d36db35SAvi Kivity     int remain;
6*7d36db35SAvi Kivity     int added;
7*7d36db35SAvi Kivity } pstream_t;
8*7d36db35SAvi Kivity 
9*7d36db35SAvi Kivity static void addchar(pstream_t *p, char c)
10*7d36db35SAvi Kivity {
11*7d36db35SAvi Kivity     if (p->remain) {
12*7d36db35SAvi Kivity 	*p->buffer++ = c;
13*7d36db35SAvi Kivity 	--p->remain;
14*7d36db35SAvi Kivity     }
15*7d36db35SAvi Kivity     ++p->added;
16*7d36db35SAvi Kivity }
17*7d36db35SAvi Kivity 
18*7d36db35SAvi Kivity void print_str(pstream_t *p, const char *s)
19*7d36db35SAvi Kivity {
20*7d36db35SAvi Kivity     while (*s)
21*7d36db35SAvi Kivity 	addchar(p, *s++);
22*7d36db35SAvi Kivity }
23*7d36db35SAvi Kivity 
24*7d36db35SAvi Kivity static char digits[16] = "0123456789abcdef";
25*7d36db35SAvi Kivity 
26*7d36db35SAvi Kivity void print_int(pstream_t *ps, long long n, int base)
27*7d36db35SAvi Kivity {
28*7d36db35SAvi Kivity     char buf[sizeof(long) * 3 + 2], *p = buf;
29*7d36db35SAvi Kivity     int s = 0, i;
30*7d36db35SAvi Kivity 
31*7d36db35SAvi Kivity     if (n < 0) {
32*7d36db35SAvi Kivity 	n = -n;
33*7d36db35SAvi Kivity 	s = 1;
34*7d36db35SAvi Kivity     }
35*7d36db35SAvi Kivity 
36*7d36db35SAvi Kivity     while (n) {
37*7d36db35SAvi Kivity 	*p++ = digits[n % base];
38*7d36db35SAvi Kivity 	n /= base;
39*7d36db35SAvi Kivity     }
40*7d36db35SAvi Kivity 
41*7d36db35SAvi Kivity     if (s)
42*7d36db35SAvi Kivity 	*p++ = '-';
43*7d36db35SAvi Kivity 
44*7d36db35SAvi Kivity     if (p == buf)
45*7d36db35SAvi Kivity 	*p++ = '0';
46*7d36db35SAvi Kivity 
47*7d36db35SAvi Kivity     for (i = 0; i < (p - buf) / 2; ++i) {
48*7d36db35SAvi Kivity 	char tmp;
49*7d36db35SAvi Kivity 
50*7d36db35SAvi Kivity 	tmp = buf[i];
51*7d36db35SAvi Kivity 	buf[i] = p[-1-i];
52*7d36db35SAvi Kivity 	p[-1-i] = tmp;
53*7d36db35SAvi Kivity     }
54*7d36db35SAvi Kivity 
55*7d36db35SAvi Kivity     *p = 0;
56*7d36db35SAvi Kivity 
57*7d36db35SAvi Kivity     print_str(ps, buf);
58*7d36db35SAvi Kivity }
59*7d36db35SAvi Kivity 
60*7d36db35SAvi Kivity void print_unsigned(pstream_t *ps, unsigned long long n, int base)
61*7d36db35SAvi Kivity {
62*7d36db35SAvi Kivity     char buf[sizeof(long) * 3 + 1], *p = buf;
63*7d36db35SAvi Kivity     int i;
64*7d36db35SAvi Kivity 
65*7d36db35SAvi Kivity     while (n) {
66*7d36db35SAvi Kivity 	*p++ = digits[n % base];
67*7d36db35SAvi Kivity 	n /= base;
68*7d36db35SAvi Kivity     }
69*7d36db35SAvi Kivity 
70*7d36db35SAvi Kivity     if (p == buf)
71*7d36db35SAvi Kivity 	*p++ = '0';
72*7d36db35SAvi Kivity 
73*7d36db35SAvi Kivity     for (i = 0; i < (p - buf) / 2; ++i) {
74*7d36db35SAvi Kivity 	char tmp;
75*7d36db35SAvi Kivity 
76*7d36db35SAvi Kivity 	tmp = buf[i];
77*7d36db35SAvi Kivity 	buf[i] = p[-1-i];
78*7d36db35SAvi Kivity 	p[-1-i] = tmp;
79*7d36db35SAvi Kivity     }
80*7d36db35SAvi Kivity 
81*7d36db35SAvi Kivity     *p = 0;
82*7d36db35SAvi Kivity 
83*7d36db35SAvi Kivity     print_str(ps, buf);
84*7d36db35SAvi Kivity }
85*7d36db35SAvi Kivity 
86*7d36db35SAvi Kivity int vsnprintf(char *buf, int size, const char *fmt, va_list va)
87*7d36db35SAvi Kivity {
88*7d36db35SAvi Kivity     pstream_t s;
89*7d36db35SAvi Kivity 
90*7d36db35SAvi Kivity     s.buffer = buf;
91*7d36db35SAvi Kivity     s.remain = size - 1;
92*7d36db35SAvi Kivity     s.added = 0;
93*7d36db35SAvi Kivity     while (*fmt) {
94*7d36db35SAvi Kivity 	char f = *fmt++;
95*7d36db35SAvi Kivity 	int nlong = 0;
96*7d36db35SAvi Kivity 
97*7d36db35SAvi Kivity 	if (f != '%') {
98*7d36db35SAvi Kivity 	    addchar(&s, f);
99*7d36db35SAvi Kivity 	    continue;
100*7d36db35SAvi Kivity 	}
101*7d36db35SAvi Kivity     morefmt:
102*7d36db35SAvi Kivity 	f = *fmt++;
103*7d36db35SAvi Kivity 	switch (f) {
104*7d36db35SAvi Kivity 	case '%':
105*7d36db35SAvi Kivity 	    addchar(&s, '%');
106*7d36db35SAvi Kivity 	    break;
107*7d36db35SAvi Kivity 	case '\0':
108*7d36db35SAvi Kivity 	    --fmt;
109*7d36db35SAvi Kivity 	    break;
110*7d36db35SAvi Kivity 	case 'l':
111*7d36db35SAvi Kivity 	    ++nlong;
112*7d36db35SAvi Kivity 	    goto morefmt;
113*7d36db35SAvi Kivity 	case 'd':
114*7d36db35SAvi Kivity 	    switch (nlong) {
115*7d36db35SAvi Kivity 	    case 0:
116*7d36db35SAvi Kivity 		print_int(&s, va_arg(va, int), 10);
117*7d36db35SAvi Kivity 		break;
118*7d36db35SAvi Kivity 	    case 1:
119*7d36db35SAvi Kivity 		print_int(&s, va_arg(va, long), 10);
120*7d36db35SAvi Kivity 		break;
121*7d36db35SAvi Kivity 	    default:
122*7d36db35SAvi Kivity 		print_int(&s, va_arg(va, long long), 10);
123*7d36db35SAvi Kivity 		break;
124*7d36db35SAvi Kivity 	    }
125*7d36db35SAvi Kivity 	    break;
126*7d36db35SAvi Kivity 	case 'x':
127*7d36db35SAvi Kivity 	    switch (nlong) {
128*7d36db35SAvi Kivity 	    case 0:
129*7d36db35SAvi Kivity 		print_unsigned(&s, va_arg(va, unsigned), 16);
130*7d36db35SAvi Kivity 		break;
131*7d36db35SAvi Kivity 	    case 1:
132*7d36db35SAvi Kivity 		print_unsigned(&s, va_arg(va, unsigned long), 16);
133*7d36db35SAvi Kivity 		break;
134*7d36db35SAvi Kivity 	    default:
135*7d36db35SAvi Kivity 		print_unsigned(&s, va_arg(va, unsigned long long), 16);
136*7d36db35SAvi Kivity 		break;
137*7d36db35SAvi Kivity 	    }
138*7d36db35SAvi Kivity 	    break;
139*7d36db35SAvi Kivity 	case 'p':
140*7d36db35SAvi Kivity 	    print_str(&s, "0x");
141*7d36db35SAvi Kivity 	    print_unsigned(&s, (unsigned long)va_arg(va, void *), 16);
142*7d36db35SAvi Kivity 	    break;
143*7d36db35SAvi Kivity 	case 's':
144*7d36db35SAvi Kivity 	    print_str(&s, va_arg(va, const char *));
145*7d36db35SAvi Kivity 	    break;
146*7d36db35SAvi Kivity 	default:
147*7d36db35SAvi Kivity 	    addchar(&s, f);
148*7d36db35SAvi Kivity 	    break;
149*7d36db35SAvi Kivity 	}
150*7d36db35SAvi Kivity     }
151*7d36db35SAvi Kivity     *s.buffer = 0;
152*7d36db35SAvi Kivity     ++s.added;
153*7d36db35SAvi Kivity     return s.added;
154*7d36db35SAvi Kivity }
155*7d36db35SAvi Kivity 
156*7d36db35SAvi Kivity 
157*7d36db35SAvi Kivity int snprintf(char *buf, int size, const char *fmt, ...)
158*7d36db35SAvi Kivity {
159*7d36db35SAvi Kivity     va_list va;
160*7d36db35SAvi Kivity     int r;
161*7d36db35SAvi Kivity 
162*7d36db35SAvi Kivity     va_start(va, fmt);
163*7d36db35SAvi Kivity     r = vsnprintf(buf, size, fmt, va);
164*7d36db35SAvi Kivity     va_end(va);
165*7d36db35SAvi Kivity     return r;
166*7d36db35SAvi Kivity }
167*7d36db35SAvi Kivity 
168*7d36db35SAvi Kivity int printf(const char *fmt, ...)
169*7d36db35SAvi Kivity {
170*7d36db35SAvi Kivity     va_list va;
171*7d36db35SAvi Kivity     char buf[2000];
172*7d36db35SAvi Kivity     int r;
173*7d36db35SAvi Kivity 
174*7d36db35SAvi Kivity     va_start(va, fmt);
175*7d36db35SAvi Kivity     r = vsnprintf(buf, sizeof buf, fmt, va);
176*7d36db35SAvi Kivity     va_end(va);
177*7d36db35SAvi Kivity     puts(buf);
178*7d36db35SAvi Kivity     return r;
179*7d36db35SAvi Kivity }
180