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