typedef void* va_list;
#define va_size(type) (((sizeof(type) + sizeof(unsigned long) - 1) / sizeof(unsigned long)) * sizeof(unsigned long))
#define va_start(ap, last) ((ap) = (va_list)&(last) + va_size(last))
#define va_arg(ap, type) (*(type *)((ap) += va_size(type), (ap) - va_size(type)))
#define va_end(ap)
#define parce_num(p, b, num, base) \
do { \
unsigned long tmpnum; \
char *ptmp; \
p = b + sizeof(b) - 1; \
*(p--) = '\0'; \
ptmp = p; \
tmpnum = num; \
while (tmpnum) { \
*(p--) = "0123456789abcdef"[tmpnum % base]; \
tmpnum /= base; \
} \
if (p == ptmp) { \
*p = '0'; \
} else { \
p++; \
} \
} while (0)
int
vsnprintf(char *buf, int n, const char *format, va_list args)
{
int num;
int i, j, k;
char *pnum, tmp[16];
for (i = j = 0; j < n && format[i] != '\0';) {
if (format[i] != '%') {
buf[j++] = format[i++];
continue;
}
i++;
switch(format[i++]) {
case 'c':
num = va_arg(args, int);
buf[j++] = (char)(num & 0x0ff);
break;
case 'u':
num = va_arg(args, int);
parce_num(pnum, tmp, num, 10);
goto output_buf;
case 'x':
num = va_arg(args, int);
parce_num(pnum, tmp, num, 16);
goto output_buf;
case 's':
pnum = va_arg(args, char *);
output_buf:
for (k = 0; pnum[k] != '\0';) {
buf[j++] = pnum[k++];
}
break;
default:
break;
}
}
buf[j] = '\0';
return j;
}
void
printf(const char *format, ...) {
va_list args;
char buf[192];
va_start(args, format);
vsnprintf(buf, 192, format, args);
va_end(args);
puts(buf);
}