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 92c978d9bSAndrew Jones typedef struct strprops { 102c978d9bSAndrew Jones char pad; 112c978d9bSAndrew Jones int npad; 122c978d9bSAndrew Jones } strprops_t; 132c978d9bSAndrew Jones 147d36db35SAvi Kivity static void addchar(pstream_t *p, char c) 157d36db35SAvi Kivity { 167d36db35SAvi Kivity if (p->remain) { 177d36db35SAvi Kivity *p->buffer++ = c; 187d36db35SAvi Kivity --p->remain; 197d36db35SAvi Kivity } 207d36db35SAvi Kivity ++p->added; 217d36db35SAvi Kivity } 227d36db35SAvi Kivity 232c978d9bSAndrew Jones void print_str(pstream_t *p, const char *s, strprops_t props) 247d36db35SAvi Kivity { 252c978d9bSAndrew Jones const char *s_orig = s; 262c978d9bSAndrew Jones int npad = props.npad; 272c978d9bSAndrew Jones 282c978d9bSAndrew Jones if (npad > 0) { 292c978d9bSAndrew Jones npad -= strlen(s_orig); 302c978d9bSAndrew Jones while (npad > 0) { 312c978d9bSAndrew Jones addchar(p, props.pad); 322c978d9bSAndrew Jones --npad; 332c978d9bSAndrew Jones } 342c978d9bSAndrew Jones } 352c978d9bSAndrew Jones 367d36db35SAvi Kivity while (*s) 377d36db35SAvi Kivity addchar(p, *s++); 382c978d9bSAndrew Jones 392c978d9bSAndrew Jones if (npad < 0) { 402c978d9bSAndrew Jones props.pad = ' '; /* ignore '0' flag with '-' flag */ 412c978d9bSAndrew Jones npad += strlen(s_orig); 422c978d9bSAndrew Jones while (npad < 0) { 432c978d9bSAndrew Jones addchar(p, props.pad); 442c978d9bSAndrew Jones ++npad; 452c978d9bSAndrew Jones } 462c978d9bSAndrew Jones } 477d36db35SAvi Kivity } 487d36db35SAvi Kivity 497d36db35SAvi Kivity static char digits[16] = "0123456789abcdef"; 507d36db35SAvi Kivity 512c978d9bSAndrew Jones void print_int(pstream_t *ps, long long n, int base, strprops_t props) 527d36db35SAvi Kivity { 537d36db35SAvi Kivity char buf[sizeof(long) * 3 + 2], *p = buf; 547d36db35SAvi Kivity int s = 0, i; 557d36db35SAvi Kivity 567d36db35SAvi Kivity if (n < 0) { 577d36db35SAvi Kivity n = -n; 587d36db35SAvi Kivity s = 1; 597d36db35SAvi Kivity } 607d36db35SAvi Kivity 617d36db35SAvi Kivity while (n) { 627d36db35SAvi Kivity *p++ = digits[n % base]; 637d36db35SAvi Kivity n /= base; 647d36db35SAvi Kivity } 657d36db35SAvi Kivity 667d36db35SAvi Kivity if (s) 677d36db35SAvi Kivity *p++ = '-'; 687d36db35SAvi Kivity 697d36db35SAvi Kivity if (p == buf) 707d36db35SAvi Kivity *p++ = '0'; 717d36db35SAvi Kivity 727d36db35SAvi Kivity for (i = 0; i < (p - buf) / 2; ++i) { 737d36db35SAvi Kivity char tmp; 747d36db35SAvi Kivity 757d36db35SAvi Kivity tmp = buf[i]; 767d36db35SAvi Kivity buf[i] = p[-1-i]; 777d36db35SAvi Kivity p[-1-i] = tmp; 787d36db35SAvi Kivity } 797d36db35SAvi Kivity 807d36db35SAvi Kivity *p = 0; 817d36db35SAvi Kivity 822c978d9bSAndrew Jones print_str(ps, buf, props); 837d36db35SAvi Kivity } 847d36db35SAvi Kivity 852c978d9bSAndrew Jones void print_unsigned(pstream_t *ps, unsigned long long n, int base, 862c978d9bSAndrew Jones strprops_t props) 877d36db35SAvi Kivity { 887d36db35SAvi Kivity char buf[sizeof(long) * 3 + 1], *p = buf; 897d36db35SAvi Kivity int i; 907d36db35SAvi Kivity 917d36db35SAvi Kivity while (n) { 927d36db35SAvi Kivity *p++ = digits[n % base]; 937d36db35SAvi Kivity n /= base; 947d36db35SAvi Kivity } 957d36db35SAvi Kivity 967d36db35SAvi Kivity if (p == buf) 977d36db35SAvi Kivity *p++ = '0'; 987d36db35SAvi Kivity 997d36db35SAvi Kivity for (i = 0; i < (p - buf) / 2; ++i) { 1007d36db35SAvi Kivity char tmp; 1017d36db35SAvi Kivity 1027d36db35SAvi Kivity tmp = buf[i]; 1037d36db35SAvi Kivity buf[i] = p[-1-i]; 1047d36db35SAvi Kivity p[-1-i] = tmp; 1057d36db35SAvi Kivity } 1067d36db35SAvi Kivity 1077d36db35SAvi Kivity *p = 0; 1087d36db35SAvi Kivity 1092c978d9bSAndrew Jones print_str(ps, buf, props); 1102c978d9bSAndrew Jones } 1112c978d9bSAndrew Jones 1122c978d9bSAndrew Jones static int fmtnum(const char **fmt) 1132c978d9bSAndrew Jones { 1142c978d9bSAndrew Jones const char *f = *fmt; 1152c978d9bSAndrew Jones int len = 0, num; 1162c978d9bSAndrew Jones 1172c978d9bSAndrew Jones if (*f == '-') 1182c978d9bSAndrew Jones ++f, ++len; 1192c978d9bSAndrew Jones 1202c978d9bSAndrew Jones while (*f >= '0' && *f <= '9') 1212c978d9bSAndrew Jones ++f, ++len; 1222c978d9bSAndrew Jones 1232c978d9bSAndrew Jones num = atol(*fmt); 1242c978d9bSAndrew Jones *fmt += len; 1252c978d9bSAndrew Jones return num; 1267d36db35SAvi Kivity } 1277d36db35SAvi Kivity 1287d36db35SAvi Kivity int vsnprintf(char *buf, int size, const char *fmt, va_list va) 1297d36db35SAvi Kivity { 1307d36db35SAvi Kivity pstream_t s; 1317d36db35SAvi Kivity 1327d36db35SAvi Kivity s.buffer = buf; 1337d36db35SAvi Kivity s.remain = size - 1; 1347d36db35SAvi Kivity s.added = 0; 1357d36db35SAvi Kivity while (*fmt) { 1367d36db35SAvi Kivity char f = *fmt++; 1377d36db35SAvi Kivity int nlong = 0; 1382c978d9bSAndrew Jones strprops_t props; 1392c978d9bSAndrew Jones memset(&props, 0, sizeof(props)); 1402c978d9bSAndrew Jones props.pad = ' '; 1417d36db35SAvi Kivity 1427d36db35SAvi Kivity if (f != '%') { 1437d36db35SAvi Kivity addchar(&s, f); 1447d36db35SAvi Kivity continue; 1457d36db35SAvi Kivity } 1467d36db35SAvi Kivity morefmt: 1477d36db35SAvi Kivity f = *fmt++; 1487d36db35SAvi Kivity switch (f) { 1497d36db35SAvi Kivity case '%': 1507d36db35SAvi Kivity addchar(&s, '%'); 1517d36db35SAvi Kivity break; 1523d7d5195SMichael S. Tsirkin case 'c': 1533d7d5195SMichael S. Tsirkin addchar(&s, va_arg(va, int)); 1543d7d5195SMichael S. Tsirkin break; 1557d36db35SAvi Kivity case '\0': 1567d36db35SAvi Kivity --fmt; 1577d36db35SAvi Kivity break; 1582c978d9bSAndrew Jones case '0': 1592c978d9bSAndrew Jones props.pad = '0'; 1602c978d9bSAndrew Jones ++fmt; 1612c978d9bSAndrew Jones /* fall through */ 1622c978d9bSAndrew Jones case '1'...'9': 1632c978d9bSAndrew Jones case '-': 1642c978d9bSAndrew Jones --fmt; 1652c978d9bSAndrew Jones props.npad = fmtnum(&fmt); 1662c978d9bSAndrew Jones goto morefmt; 1677d36db35SAvi Kivity case 'l': 1687d36db35SAvi Kivity ++nlong; 1697d36db35SAvi Kivity goto morefmt; 1707d36db35SAvi Kivity case 'd': 1717d36db35SAvi Kivity switch (nlong) { 1727d36db35SAvi Kivity case 0: 1732c978d9bSAndrew Jones print_int(&s, va_arg(va, int), 10, props); 1747d36db35SAvi Kivity break; 1757d36db35SAvi Kivity case 1: 1762c978d9bSAndrew Jones print_int(&s, va_arg(va, long), 10, props); 1777d36db35SAvi Kivity break; 1787d36db35SAvi Kivity default: 1792c978d9bSAndrew Jones print_int(&s, va_arg(va, long long), 10, props); 1807d36db35SAvi Kivity break; 1817d36db35SAvi Kivity } 1827d36db35SAvi Kivity break; 183*3a08f439SAlex Bennée case 'u': 184*3a08f439SAlex Bennée switch (nlong) { 185*3a08f439SAlex Bennée case 0: 186*3a08f439SAlex Bennée print_unsigned(&s, va_arg(va, unsigned), 10, props); 187*3a08f439SAlex Bennée break; 188*3a08f439SAlex Bennée case 1: 189*3a08f439SAlex Bennée print_unsigned(&s, va_arg(va, unsigned long), 10, props); 190*3a08f439SAlex Bennée break; 191*3a08f439SAlex Bennée default: 192*3a08f439SAlex Bennée print_unsigned(&s, va_arg(va, unsigned long long), 10, props); 193*3a08f439SAlex Bennée break; 194*3a08f439SAlex Bennée } 195*3a08f439SAlex Bennée break; 1967d36db35SAvi Kivity case 'x': 1977d36db35SAvi Kivity switch (nlong) { 1987d36db35SAvi Kivity case 0: 1992c978d9bSAndrew Jones print_unsigned(&s, va_arg(va, unsigned), 16, props); 2007d36db35SAvi Kivity break; 2017d36db35SAvi Kivity case 1: 2022c978d9bSAndrew Jones print_unsigned(&s, va_arg(va, unsigned long), 16, props); 2037d36db35SAvi Kivity break; 2047d36db35SAvi Kivity default: 2052c978d9bSAndrew Jones print_unsigned(&s, va_arg(va, unsigned long long), 16, props); 2067d36db35SAvi Kivity break; 2077d36db35SAvi Kivity } 2087d36db35SAvi Kivity break; 2097d36db35SAvi Kivity case 'p': 2102c978d9bSAndrew Jones print_str(&s, "0x", props); 2112c978d9bSAndrew Jones print_unsigned(&s, (unsigned long)va_arg(va, void *), 16, props); 2127d36db35SAvi Kivity break; 2137d36db35SAvi Kivity case 's': 2142c978d9bSAndrew Jones print_str(&s, va_arg(va, const char *), props); 2157d36db35SAvi Kivity break; 2167d36db35SAvi Kivity default: 2177d36db35SAvi Kivity addchar(&s, f); 2187d36db35SAvi Kivity break; 2197d36db35SAvi Kivity } 2207d36db35SAvi Kivity } 2217d36db35SAvi Kivity *s.buffer = 0; 2227d36db35SAvi Kivity ++s.added; 2237d36db35SAvi Kivity return s.added; 2247d36db35SAvi Kivity } 2257d36db35SAvi Kivity 2267d36db35SAvi Kivity 2277d36db35SAvi Kivity int snprintf(char *buf, int size, const char *fmt, ...) 2287d36db35SAvi Kivity { 2297d36db35SAvi Kivity va_list va; 2307d36db35SAvi Kivity int r; 2317d36db35SAvi Kivity 2327d36db35SAvi Kivity va_start(va, fmt); 2337d36db35SAvi Kivity r = vsnprintf(buf, size, fmt, va); 2347d36db35SAvi Kivity va_end(va); 2357d36db35SAvi Kivity return r; 2367d36db35SAvi Kivity } 2377d36db35SAvi Kivity 2387d36db35SAvi Kivity int printf(const char *fmt, ...) 2397d36db35SAvi Kivity { 2407d36db35SAvi Kivity va_list va; 2417d36db35SAvi Kivity char buf[2000]; 2427d36db35SAvi Kivity int r; 2437d36db35SAvi Kivity 2447d36db35SAvi Kivity va_start(va, fmt); 2457d36db35SAvi Kivity r = vsnprintf(buf, sizeof buf, fmt, va); 2467d36db35SAvi Kivity va_end(va); 2477d36db35SAvi Kivity puts(buf); 2487d36db35SAvi Kivity return r; 2497d36db35SAvi Kivity } 250