#include #include #include #include #include #define mstring(x) (x)->string #define minit(x) { (x)->string = NULL; (x)->string_len=0; } #define mfree(x) { if((x)->string) { free((x)->string); (x)->string=NULL; } (x)->string_len=0; } typedef struct { char *string; int string_len; } mpointer; int mprintf (mpointer * p, const char *format, ...) { va_list arg; int len, size = 256, curlen; if(p->string == NULL) { p->string=malloc(size); p->string[0] = 0; p->string_len = 0; curlen = 0; } else { p->string=realloc(p->string, (p->string_len + size)); curlen = strlen(p->string); } while(1) { va_start (arg, format); len = vsnprintf(p->string+curlen, size, format, arg); va_end (arg); /* Some glibc versions apparently return -1 if buffer too small */ if(len > -1 && len < size) break; /* The return value doesn't include end null */ size = ( len < 0 ? size * 2 : len + 1 ); p->string=realloc(p->string, (p->string_len + size)); } p->string_len += size; return len; } int main(int argc, char **argv) { mpointer test; minit(&test); mprintf(&test, "Hello world\n"); mprintf(&test, "This is a funny test\n"); mprintf(&test, "Of an self reallocating function\n"); mprintf(&test, "that shud work with %s\n", "variables"); printf("This is test (%i): \n\"%s\"\n", strlen(test.string), test.string); mfree(&test); exit(0); }