#include #include static char *sbuild(char *format, ...) { // (1) overapproximate the length of the string. adapted from man va_start unsigned long max_len = 1; char *s; va_list ap; va_start(ap, format); for (char *c = format; *c; c++) { if (*c != '%') { max_len++; continue; } switch (*(++c)) { case 's': s = va_arg(ap, char*); max_len += strlen(s); break; case 'l': // not quite accurate va_arg(ap, unsigned long); max_len += 64; break; case 'd': va_arg(ap, int); max_len += 32; break; case 'u': va_arg(ap, unsigned); max_len += 32; break; case 'f': va_arg(ap, double); max_len += 64; break; default: assert(0); } } va_end(ap); char *str = calloc(max_len, sizeof(char)); va_list ap_; va_start(ap_, format); vsprintf(str, format, ap_); va_end(ap_); return str; }