17d36db35SAvi Kivity #include "libcflat.h" 27d36db35SAvi Kivity 3*cb12ecccSAndrew Jones #define BUFSZ 2000 4*cb12ecccSAndrew Jones 57d36db35SAvi Kivity typedef struct pstream { 67d36db35SAvi Kivity char *buffer; 77d36db35SAvi Kivity int remain; 87d36db35SAvi Kivity int added; 97d36db35SAvi Kivity } pstream_t; 107d36db35SAvi Kivity 112c978d9bSAndrew Jones typedef struct strprops { 122c978d9bSAndrew Jones char pad; 132c978d9bSAndrew Jones int npad; 142c978d9bSAndrew Jones } strprops_t; 152c978d9bSAndrew Jones 167d36db35SAvi Kivity static void addchar(pstream_t *p, char c) 177d36db35SAvi Kivity { 187d36db35SAvi Kivity if (p->remain) { 197d36db35SAvi Kivity *p->buffer++ = c; 207d36db35SAvi Kivity --p->remain; 217d36db35SAvi Kivity } 227d36db35SAvi Kivity ++p->added; 237d36db35SAvi Kivity } 247d36db35SAvi Kivity 252c978d9bSAndrew Jones void print_str(pstream_t *p, const char *s, strprops_t props) 267d36db35SAvi Kivity { 272c978d9bSAndrew Jones const char *s_orig = s; 282c978d9bSAndrew Jones int npad = props.npad; 292c978d9bSAndrew Jones 302c978d9bSAndrew Jones if (npad > 0) { 312c978d9bSAndrew Jones npad -= strlen(s_orig); 322c978d9bSAndrew Jones while (npad > 0) { 332c978d9bSAndrew Jones addchar(p, props.pad); 342c978d9bSAndrew Jones --npad; 352c978d9bSAndrew Jones } 362c978d9bSAndrew Jones } 372c978d9bSAndrew Jones 387d36db35SAvi Kivity while (*s) 397d36db35SAvi Kivity addchar(p, *s++); 402c978d9bSAndrew Jones 412c978d9bSAndrew Jones if (npad < 0) { 422c978d9bSAndrew Jones props.pad = ' '; /* ignore '0' flag with '-' flag */ 432c978d9bSAndrew Jones npad += strlen(s_orig); 442c978d9bSAndrew Jones while (npad < 0) { 452c978d9bSAndrew Jones addchar(p, props.pad); 462c978d9bSAndrew Jones ++npad; 472c978d9bSAndrew Jones } 482c978d9bSAndrew Jones } 497d36db35SAvi Kivity } 507d36db35SAvi Kivity 517d36db35SAvi Kivity static char digits[16] = "0123456789abcdef"; 527d36db35SAvi Kivity 532c978d9bSAndrew Jones void print_int(pstream_t *ps, long long n, int base, strprops_t props) 547d36db35SAvi Kivity { 557d36db35SAvi Kivity char buf[sizeof(long) * 3 + 2], *p = buf; 567d36db35SAvi Kivity int s = 0, i; 577d36db35SAvi Kivity 587d36db35SAvi Kivity if (n < 0) { 597d36db35SAvi Kivity n = -n; 607d36db35SAvi Kivity s = 1; 617d36db35SAvi Kivity } 627d36db35SAvi Kivity 637d36db35SAvi Kivity while (n) { 647d36db35SAvi Kivity *p++ = digits[n % base]; 657d36db35SAvi Kivity n /= base; 667d36db35SAvi Kivity } 677d36db35SAvi Kivity 687d36db35SAvi Kivity if (s) 697d36db35SAvi Kivity *p++ = '-'; 707d36db35SAvi Kivity 717d36db35SAvi Kivity if (p == buf) 727d36db35SAvi Kivity *p++ = '0'; 737d36db35SAvi Kivity 747d36db35SAvi Kivity for (i = 0; i < (p - buf) / 2; ++i) { 757d36db35SAvi Kivity char tmp; 767d36db35SAvi Kivity 777d36db35SAvi Kivity tmp = buf[i]; 787d36db35SAvi Kivity buf[i] = p[-1-i]; 797d36db35SAvi Kivity p[-1-i] = tmp; 807d36db35SAvi Kivity } 817d36db35SAvi Kivity 827d36db35SAvi Kivity *p = 0; 837d36db35SAvi Kivity 842c978d9bSAndrew Jones print_str(ps, buf, props); 857d36db35SAvi Kivity } 867d36db35SAvi Kivity 872c978d9bSAndrew Jones void print_unsigned(pstream_t *ps, unsigned long long n, int base, 882c978d9bSAndrew Jones strprops_t props) 897d36db35SAvi Kivity { 907d36db35SAvi Kivity char buf[sizeof(long) * 3 + 1], *p = buf; 917d36db35SAvi Kivity int i; 927d36db35SAvi Kivity 937d36db35SAvi Kivity while (n) { 947d36db35SAvi Kivity *p++ = digits[n % base]; 957d36db35SAvi Kivity n /= base; 967d36db35SAvi Kivity } 977d36db35SAvi Kivity 987d36db35SAvi Kivity if (p == buf) 997d36db35SAvi Kivity *p++ = '0'; 1007d36db35SAvi Kivity 1017d36db35SAvi Kivity for (i = 0; i < (p - buf) / 2; ++i) { 1027d36db35SAvi Kivity char tmp; 1037d36db35SAvi Kivity 1047d36db35SAvi Kivity tmp = buf[i]; 1057d36db35SAvi Kivity buf[i] = p[-1-i]; 1067d36db35SAvi Kivity p[-1-i] = tmp; 1077d36db35SAvi Kivity } 1087d36db35SAvi Kivity 1097d36db35SAvi Kivity *p = 0; 1107d36db35SAvi Kivity 1112c978d9bSAndrew Jones print_str(ps, buf, props); 1122c978d9bSAndrew Jones } 1132c978d9bSAndrew Jones 1142c978d9bSAndrew Jones static int fmtnum(const char **fmt) 1152c978d9bSAndrew Jones { 1162c978d9bSAndrew Jones const char *f = *fmt; 1172c978d9bSAndrew Jones int len = 0, num; 1182c978d9bSAndrew Jones 1192c978d9bSAndrew Jones if (*f == '-') 1202c978d9bSAndrew Jones ++f, ++len; 1212c978d9bSAndrew Jones 1222c978d9bSAndrew Jones while (*f >= '0' && *f <= '9') 1232c978d9bSAndrew Jones ++f, ++len; 1242c978d9bSAndrew Jones 1252c978d9bSAndrew Jones num = atol(*fmt); 1262c978d9bSAndrew Jones *fmt += len; 1272c978d9bSAndrew Jones return num; 1287d36db35SAvi Kivity } 1297d36db35SAvi Kivity 1307d36db35SAvi Kivity int vsnprintf(char *buf, int size, const char *fmt, va_list va) 1317d36db35SAvi Kivity { 1327d36db35SAvi Kivity pstream_t s; 1337d36db35SAvi Kivity 1347d36db35SAvi Kivity s.buffer = buf; 1357d36db35SAvi Kivity s.remain = size - 1; 1367d36db35SAvi Kivity s.added = 0; 1377d36db35SAvi Kivity while (*fmt) { 1387d36db35SAvi Kivity char f = *fmt++; 1397d36db35SAvi Kivity int nlong = 0; 1402c978d9bSAndrew Jones strprops_t props; 1412c978d9bSAndrew Jones memset(&props, 0, sizeof(props)); 1422c978d9bSAndrew Jones props.pad = ' '; 1437d36db35SAvi Kivity 1447d36db35SAvi Kivity if (f != '%') { 1457d36db35SAvi Kivity addchar(&s, f); 1467d36db35SAvi Kivity continue; 1477d36db35SAvi Kivity } 1487d36db35SAvi Kivity morefmt: 1497d36db35SAvi Kivity f = *fmt++; 1507d36db35SAvi Kivity switch (f) { 1517d36db35SAvi Kivity case '%': 1527d36db35SAvi Kivity addchar(&s, '%'); 1537d36db35SAvi Kivity break; 1543d7d5195SMichael S. Tsirkin case 'c': 1553d7d5195SMichael S. Tsirkin addchar(&s, va_arg(va, int)); 1563d7d5195SMichael S. Tsirkin break; 1577d36db35SAvi Kivity case '\0': 1587d36db35SAvi Kivity --fmt; 1597d36db35SAvi Kivity break; 1602c978d9bSAndrew Jones case '0': 1612c978d9bSAndrew Jones props.pad = '0'; 1622c978d9bSAndrew Jones ++fmt; 1632c978d9bSAndrew Jones /* fall through */ 1642c978d9bSAndrew Jones case '1'...'9': 1652c978d9bSAndrew Jones case '-': 1662c978d9bSAndrew Jones --fmt; 1672c978d9bSAndrew Jones props.npad = fmtnum(&fmt); 1682c978d9bSAndrew Jones goto morefmt; 1697d36db35SAvi Kivity case 'l': 1707d36db35SAvi Kivity ++nlong; 1717d36db35SAvi Kivity goto morefmt; 1727d36db35SAvi Kivity case 'd': 1737d36db35SAvi Kivity switch (nlong) { 1747d36db35SAvi Kivity case 0: 1752c978d9bSAndrew Jones print_int(&s, va_arg(va, int), 10, props); 1767d36db35SAvi Kivity break; 1777d36db35SAvi Kivity case 1: 1782c978d9bSAndrew Jones print_int(&s, va_arg(va, long), 10, props); 1797d36db35SAvi Kivity break; 1807d36db35SAvi Kivity default: 1812c978d9bSAndrew Jones print_int(&s, va_arg(va, long long), 10, props); 1827d36db35SAvi Kivity break; 1837d36db35SAvi Kivity } 1847d36db35SAvi Kivity break; 1853a08f439SAlex Bennée case 'u': 1863a08f439SAlex Bennée switch (nlong) { 1873a08f439SAlex Bennée case 0: 1883a08f439SAlex Bennée print_unsigned(&s, va_arg(va, unsigned), 10, props); 1893a08f439SAlex Bennée break; 1903a08f439SAlex Bennée case 1: 1913a08f439SAlex Bennée print_unsigned(&s, va_arg(va, unsigned long), 10, props); 1923a08f439SAlex Bennée break; 1933a08f439SAlex Bennée default: 1943a08f439SAlex Bennée print_unsigned(&s, va_arg(va, unsigned long long), 10, props); 1953a08f439SAlex Bennée break; 1963a08f439SAlex Bennée } 1973a08f439SAlex Bennée break; 1987d36db35SAvi Kivity case 'x': 1997d36db35SAvi Kivity switch (nlong) { 2007d36db35SAvi Kivity case 0: 2012c978d9bSAndrew Jones print_unsigned(&s, va_arg(va, unsigned), 16, props); 2027d36db35SAvi Kivity break; 2037d36db35SAvi Kivity case 1: 2042c978d9bSAndrew Jones print_unsigned(&s, va_arg(va, unsigned long), 16, props); 2057d36db35SAvi Kivity break; 2067d36db35SAvi Kivity default: 2072c978d9bSAndrew Jones print_unsigned(&s, va_arg(va, unsigned long long), 16, props); 2087d36db35SAvi Kivity break; 2097d36db35SAvi Kivity } 2107d36db35SAvi Kivity break; 2117d36db35SAvi Kivity case 'p': 2122c978d9bSAndrew Jones print_str(&s, "0x", props); 2132c978d9bSAndrew Jones print_unsigned(&s, (unsigned long)va_arg(va, void *), 16, props); 2147d36db35SAvi Kivity break; 2157d36db35SAvi Kivity case 's': 2162c978d9bSAndrew Jones print_str(&s, va_arg(va, const char *), props); 2177d36db35SAvi Kivity break; 2187d36db35SAvi Kivity default: 2197d36db35SAvi Kivity addchar(&s, f); 2207d36db35SAvi Kivity break; 2217d36db35SAvi Kivity } 2227d36db35SAvi Kivity } 2237d36db35SAvi Kivity *s.buffer = 0; 2247d36db35SAvi Kivity ++s.added; 2257d36db35SAvi Kivity return s.added; 2267d36db35SAvi Kivity } 2277d36db35SAvi Kivity 2287d36db35SAvi Kivity 2297d36db35SAvi Kivity int snprintf(char *buf, int size, const char *fmt, ...) 2307d36db35SAvi Kivity { 2317d36db35SAvi Kivity va_list va; 2327d36db35SAvi Kivity int r; 2337d36db35SAvi Kivity 2347d36db35SAvi Kivity va_start(va, fmt); 2357d36db35SAvi Kivity r = vsnprintf(buf, size, fmt, va); 2367d36db35SAvi Kivity va_end(va); 2377d36db35SAvi Kivity return r; 2387d36db35SAvi Kivity } 2397d36db35SAvi Kivity 240*cb12ecccSAndrew Jones int vprintf(const char *fmt, va_list va) 241*cb12ecccSAndrew Jones { 242*cb12ecccSAndrew Jones char buf[BUFSZ]; 243*cb12ecccSAndrew Jones int r; 244*cb12ecccSAndrew Jones 245*cb12ecccSAndrew Jones r = vsnprintf(buf, sizeof(buf), fmt, va); 246*cb12ecccSAndrew Jones puts(buf); 247*cb12ecccSAndrew Jones return r; 248*cb12ecccSAndrew Jones } 249*cb12ecccSAndrew Jones 2507d36db35SAvi Kivity int printf(const char *fmt, ...) 2517d36db35SAvi Kivity { 2527d36db35SAvi Kivity va_list va; 253*cb12ecccSAndrew Jones char buf[BUFSZ]; 2547d36db35SAvi Kivity int r; 2557d36db35SAvi Kivity 2567d36db35SAvi Kivity va_start(va, fmt); 2577d36db35SAvi Kivity r = vsnprintf(buf, sizeof buf, fmt, va); 2587d36db35SAvi Kivity va_end(va); 2597d36db35SAvi Kivity puts(buf); 2607d36db35SAvi Kivity return r; 2617d36db35SAvi Kivity } 262