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