xref: /kvm-unit-tests/lib/printf.c (revision 3d7d51954e1d7ac001da788c09329f7bd893f355)
17d36db35SAvi Kivity #include "libcflat.h"
27d36db35SAvi Kivity 
37d36db35SAvi Kivity typedef struct pstream {
47d36db35SAvi Kivity     char *buffer;
57d36db35SAvi Kivity     int remain;
67d36db35SAvi Kivity     int added;
77d36db35SAvi Kivity } pstream_t;
87d36db35SAvi Kivity 
97d36db35SAvi Kivity static void addchar(pstream_t *p, char c)
107d36db35SAvi Kivity {
117d36db35SAvi Kivity     if (p->remain) {
127d36db35SAvi Kivity 	*p->buffer++ = c;
137d36db35SAvi Kivity 	--p->remain;
147d36db35SAvi Kivity     }
157d36db35SAvi Kivity     ++p->added;
167d36db35SAvi Kivity }
177d36db35SAvi Kivity 
187d36db35SAvi Kivity void print_str(pstream_t *p, const char *s)
197d36db35SAvi Kivity {
207d36db35SAvi Kivity     while (*s)
217d36db35SAvi Kivity 	addchar(p, *s++);
227d36db35SAvi Kivity }
237d36db35SAvi Kivity 
247d36db35SAvi Kivity static char digits[16] = "0123456789abcdef";
257d36db35SAvi Kivity 
267d36db35SAvi Kivity void print_int(pstream_t *ps, long long n, int base)
277d36db35SAvi Kivity {
287d36db35SAvi Kivity     char buf[sizeof(long) * 3 + 2], *p = buf;
297d36db35SAvi Kivity     int s = 0, i;
307d36db35SAvi Kivity 
317d36db35SAvi Kivity     if (n < 0) {
327d36db35SAvi Kivity 	n = -n;
337d36db35SAvi Kivity 	s = 1;
347d36db35SAvi Kivity     }
357d36db35SAvi Kivity 
367d36db35SAvi Kivity     while (n) {
377d36db35SAvi Kivity 	*p++ = digits[n % base];
387d36db35SAvi Kivity 	n /= base;
397d36db35SAvi Kivity     }
407d36db35SAvi Kivity 
417d36db35SAvi Kivity     if (s)
427d36db35SAvi Kivity 	*p++ = '-';
437d36db35SAvi Kivity 
447d36db35SAvi Kivity     if (p == buf)
457d36db35SAvi Kivity 	*p++ = '0';
467d36db35SAvi Kivity 
477d36db35SAvi Kivity     for (i = 0; i < (p - buf) / 2; ++i) {
487d36db35SAvi Kivity 	char tmp;
497d36db35SAvi Kivity 
507d36db35SAvi Kivity 	tmp = buf[i];
517d36db35SAvi Kivity 	buf[i] = p[-1-i];
527d36db35SAvi Kivity 	p[-1-i] = tmp;
537d36db35SAvi Kivity     }
547d36db35SAvi Kivity 
557d36db35SAvi Kivity     *p = 0;
567d36db35SAvi Kivity 
577d36db35SAvi Kivity     print_str(ps, buf);
587d36db35SAvi Kivity }
597d36db35SAvi Kivity 
607d36db35SAvi Kivity void print_unsigned(pstream_t *ps, unsigned long long n, int base)
617d36db35SAvi Kivity {
627d36db35SAvi Kivity     char buf[sizeof(long) * 3 + 1], *p = buf;
637d36db35SAvi Kivity     int i;
647d36db35SAvi Kivity 
657d36db35SAvi Kivity     while (n) {
667d36db35SAvi Kivity 	*p++ = digits[n % base];
677d36db35SAvi Kivity 	n /= base;
687d36db35SAvi Kivity     }
697d36db35SAvi Kivity 
707d36db35SAvi Kivity     if (p == buf)
717d36db35SAvi Kivity 	*p++ = '0';
727d36db35SAvi Kivity 
737d36db35SAvi Kivity     for (i = 0; i < (p - buf) / 2; ++i) {
747d36db35SAvi Kivity 	char tmp;
757d36db35SAvi Kivity 
767d36db35SAvi Kivity 	tmp = buf[i];
777d36db35SAvi Kivity 	buf[i] = p[-1-i];
787d36db35SAvi Kivity 	p[-1-i] = tmp;
797d36db35SAvi Kivity     }
807d36db35SAvi Kivity 
817d36db35SAvi Kivity     *p = 0;
827d36db35SAvi Kivity 
837d36db35SAvi Kivity     print_str(ps, buf);
847d36db35SAvi Kivity }
857d36db35SAvi Kivity 
867d36db35SAvi Kivity int vsnprintf(char *buf, int size, const char *fmt, va_list va)
877d36db35SAvi Kivity {
887d36db35SAvi Kivity     pstream_t s;
897d36db35SAvi Kivity 
907d36db35SAvi Kivity     s.buffer = buf;
917d36db35SAvi Kivity     s.remain = size - 1;
927d36db35SAvi Kivity     s.added = 0;
937d36db35SAvi Kivity     while (*fmt) {
947d36db35SAvi Kivity 	char f = *fmt++;
957d36db35SAvi Kivity 	int nlong = 0;
967d36db35SAvi Kivity 
977d36db35SAvi Kivity 	if (f != '%') {
987d36db35SAvi Kivity 	    addchar(&s, f);
997d36db35SAvi Kivity 	    continue;
1007d36db35SAvi Kivity 	}
1017d36db35SAvi Kivity     morefmt:
1027d36db35SAvi Kivity 	f = *fmt++;
1037d36db35SAvi Kivity 	switch (f) {
1047d36db35SAvi Kivity 	case '%':
1057d36db35SAvi Kivity 	    addchar(&s, '%');
1067d36db35SAvi Kivity 	    break;
107*3d7d5195SMichael S. Tsirkin 	case 'c':
108*3d7d5195SMichael S. Tsirkin             addchar(&s, va_arg(va, int));
109*3d7d5195SMichael S. Tsirkin 	    break;
1107d36db35SAvi Kivity 	case '\0':
1117d36db35SAvi Kivity 	    --fmt;
1127d36db35SAvi Kivity 	    break;
1137d36db35SAvi Kivity 	case 'l':
1147d36db35SAvi Kivity 	    ++nlong;
1157d36db35SAvi Kivity 	    goto morefmt;
1167d36db35SAvi Kivity 	case 'd':
1177d36db35SAvi Kivity 	    switch (nlong) {
1187d36db35SAvi Kivity 	    case 0:
1197d36db35SAvi Kivity 		print_int(&s, va_arg(va, int), 10);
1207d36db35SAvi Kivity 		break;
1217d36db35SAvi Kivity 	    case 1:
1227d36db35SAvi Kivity 		print_int(&s, va_arg(va, long), 10);
1237d36db35SAvi Kivity 		break;
1247d36db35SAvi Kivity 	    default:
1257d36db35SAvi Kivity 		print_int(&s, va_arg(va, long long), 10);
1267d36db35SAvi Kivity 		break;
1277d36db35SAvi Kivity 	    }
1287d36db35SAvi Kivity 	    break;
1297d36db35SAvi Kivity 	case 'x':
1307d36db35SAvi Kivity 	    switch (nlong) {
1317d36db35SAvi Kivity 	    case 0:
1327d36db35SAvi Kivity 		print_unsigned(&s, va_arg(va, unsigned), 16);
1337d36db35SAvi Kivity 		break;
1347d36db35SAvi Kivity 	    case 1:
1357d36db35SAvi Kivity 		print_unsigned(&s, va_arg(va, unsigned long), 16);
1367d36db35SAvi Kivity 		break;
1377d36db35SAvi Kivity 	    default:
1387d36db35SAvi Kivity 		print_unsigned(&s, va_arg(va, unsigned long long), 16);
1397d36db35SAvi Kivity 		break;
1407d36db35SAvi Kivity 	    }
1417d36db35SAvi Kivity 	    break;
1427d36db35SAvi Kivity 	case 'p':
1437d36db35SAvi Kivity 	    print_str(&s, "0x");
1447d36db35SAvi Kivity 	    print_unsigned(&s, (unsigned long)va_arg(va, void *), 16);
1457d36db35SAvi Kivity 	    break;
1467d36db35SAvi Kivity 	case 's':
1477d36db35SAvi Kivity 	    print_str(&s, va_arg(va, const char *));
1487d36db35SAvi Kivity 	    break;
1497d36db35SAvi Kivity 	default:
1507d36db35SAvi Kivity 	    addchar(&s, f);
1517d36db35SAvi Kivity 	    break;
1527d36db35SAvi Kivity 	}
1537d36db35SAvi Kivity     }
1547d36db35SAvi Kivity     *s.buffer = 0;
1557d36db35SAvi Kivity     ++s.added;
1567d36db35SAvi Kivity     return s.added;
1577d36db35SAvi Kivity }
1587d36db35SAvi Kivity 
1597d36db35SAvi Kivity 
1607d36db35SAvi Kivity int snprintf(char *buf, int size, const char *fmt, ...)
1617d36db35SAvi Kivity {
1627d36db35SAvi Kivity     va_list va;
1637d36db35SAvi Kivity     int r;
1647d36db35SAvi Kivity 
1657d36db35SAvi Kivity     va_start(va, fmt);
1667d36db35SAvi Kivity     r = vsnprintf(buf, size, fmt, va);
1677d36db35SAvi Kivity     va_end(va);
1687d36db35SAvi Kivity     return r;
1697d36db35SAvi Kivity }
1707d36db35SAvi Kivity 
1717d36db35SAvi Kivity int printf(const char *fmt, ...)
1727d36db35SAvi Kivity {
1737d36db35SAvi Kivity     va_list va;
1747d36db35SAvi Kivity     char buf[2000];
1757d36db35SAvi Kivity     int r;
1767d36db35SAvi Kivity 
1777d36db35SAvi Kivity     va_start(va, fmt);
1787d36db35SAvi Kivity     r = vsnprintf(buf, sizeof buf, fmt, va);
1797d36db35SAvi Kivity     va_end(va);
1807d36db35SAvi Kivity     puts(buf);
1817d36db35SAvi Kivity     return r;
1827d36db35SAvi Kivity }
183