blob: c0c5cdedafd5c7c1703b1c22b472a8dd81db059a [file] [log] [blame]
Robert Grieblefd49832002-07-19 20:27:11 +00001/*
2 Copyright (C) 2002 Vladimir Oleynik <dzo@simtreas.ru>
3*/
4
5#include <stdlib.h>
6#include <stdio.h>
7#include <stdarg.h>
8
9
10#ifdef TEST
11extern void *xrealloc(void *p, size_t size);
12#else
13#include "libbb.h" /* busybox source */
14#endif
15
16
17/* Exchange glibc vasprintf - minimize allocate memory version */
18/* libc5 and uclibc have not vasprintf function */
19void bb_vasprintf(char **string_ptr, const char *format, va_list args)
20{
21 int bs = 128;
22 char stack_buff[128];
23 char *buff = stack_buff;
24 int done;
25
26 /* two or more loop, first - calculate memory size only */
27 while(1) {
28 done = vsnprintf (buff, bs, format, args);
29/* Different libc have different interpretation vsnprintf returned value */
30 if(done >= 0) {
31 if(done < bs && buff != stack_buff) {
32 /* allocated */
33 *string_ptr = buff;
34 return;
35 } else {
36 /* true calculate memory size */
37 bs = done+1;
38 }
39 } else {
40 /*
41 * Old libc. Incrementaly test.
42 * Exact not minimize allocate memory.
43 */
44 bs += 128;
45 }
46 buff = xrealloc((buff == stack_buff ? NULL : buff), bs);
47 }
48}
49
50void bb_asprintf(char **string_ptr, const char *format, ...)
51{
52 va_list p;
53
54 va_start(p, format);
55 bb_vasprintf(string_ptr, format, p);
56 va_end(p);
57}
58
59#ifdef TEST
60int main(int argc, char **argv)
61{
62 char *out_buf;
63 char big_buf[200];
64 int i;
65
66 bb_asprintf(&out_buf, "Hi!\nargc=%d argv[0]=%s\n", argc, argv[0]);
67 printf(out_buf);
68 free(out_buf);
69
70 for(i=0; i < sizeof(big_buf)-1; i++)
71 big_buf[i]='x';
72 big_buf[i]=0;
73 bb_asprintf(&out_buf, "Test Big\n%s\n", big_buf);
74 printf(out_buf);
75 free(out_buf);
76
77 return 0;
78}
79
80void *xrealloc(void *p, size_t size)
81{
82 void *p2 = realloc(p, size);
83 if(p2==0) {
84 fprintf(stderr, "TEST: memory_exhausted\n");
85 exit(1);
86 }
87 return p2;
88}
89#endif