90 lines
2.3 KiB
C
90 lines
2.3 KiB
C
|
/*
|
||
|
Copyright (C) 2002 Vladimir Oleynik <dzo@simtreas.ru>
|
||
|
*/
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdarg.h>
|
||
|
|
||
|
|
||
|
#ifdef TEST
|
||
|
extern void *xrealloc(void *p, size_t size);
|
||
|
#else
|
||
|
#include "libbb.h" /* busybox source */
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/* Exchange glibc vasprintf - minimize allocate memory version */
|
||
|
/* libc5 and uclibc have not vasprintf function */
|
||
|
void bb_vasprintf(char **string_ptr, const char *format, va_list args)
|
||
|
{
|
||
|
int bs = 128;
|
||
|
char stack_buff[128];
|
||
|
char *buff = stack_buff;
|
||
|
int done;
|
||
|
|
||
|
/* two or more loop, first - calculate memory size only */
|
||
|
while(1) {
|
||
|
done = vsnprintf (buff, bs, format, args);
|
||
|
/* Different libc have different interpretation vsnprintf returned value */
|
||
|
if(done >= 0) {
|
||
|
if(done < bs && buff != stack_buff) {
|
||
|
/* allocated */
|
||
|
*string_ptr = buff;
|
||
|
return;
|
||
|
} else {
|
||
|
/* true calculate memory size */
|
||
|
bs = done+1;
|
||
|
}
|
||
|
} else {
|
||
|
/*
|
||
|
* Old libc. Incrementaly test.
|
||
|
* Exact not minimize allocate memory.
|
||
|
*/
|
||
|
bs += 128;
|
||
|
}
|
||
|
buff = xrealloc((buff == stack_buff ? NULL : buff), bs);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void bb_asprintf(char **string_ptr, const char *format, ...)
|
||
|
{
|
||
|
va_list p;
|
||
|
|
||
|
va_start(p, format);
|
||
|
bb_vasprintf(string_ptr, format, p);
|
||
|
va_end(p);
|
||
|
}
|
||
|
|
||
|
#ifdef TEST
|
||
|
int main(int argc, char **argv)
|
||
|
{
|
||
|
char *out_buf;
|
||
|
char big_buf[200];
|
||
|
int i;
|
||
|
|
||
|
bb_asprintf(&out_buf, "Hi!\nargc=%d argv[0]=%s\n", argc, argv[0]);
|
||
|
printf(out_buf);
|
||
|
free(out_buf);
|
||
|
|
||
|
for(i=0; i < sizeof(big_buf)-1; i++)
|
||
|
big_buf[i]='x';
|
||
|
big_buf[i]=0;
|
||
|
bb_asprintf(&out_buf, "Test Big\n%s\n", big_buf);
|
||
|
printf(out_buf);
|
||
|
free(out_buf);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void *xrealloc(void *p, size_t size)
|
||
|
{
|
||
|
void *p2 = realloc(p, size);
|
||
|
if(p2==0) {
|
||
|
fprintf(stderr, "TEST: memory_exhausted\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
return p2;
|
||
|
}
|
||
|
#endif
|