GNU General Public License for more details.
*/
-#include "opkg.h"
#include <stdarg.h>
#include "sprintf_alloc.h"
+#include "libbb/libbb.h"
int sprintf_alloc(char **str, const char *fmt, ...)
{
va_list ap;
- char *new_str;
- int n, size = 100;
+ int n;
+ unsigned size = 100;
if (!str) {
- fprintf(stderr, "Null string pointer passed to sprintf_alloc\n");
+ opkg_msg(ERROR, "Internal error: str=NULL.\n");
return -1;
}
if (!fmt) {
- fprintf(stderr, "Null fmt string passed to sprintf_alloc\n");
+ opkg_msg(ERROR, "Internal error: fmt=NULL.\n");
return -1;
}
- /* On x86_64 systems, any strings over 100 were segfaulting.
+ /* On x86_64 systems, any strings over 100 were segfaulting.
It seems that the ap needs to be reinitalized before every
use of the v*printf() functions. I pulled the functionality out
- of vsprintf_alloc and combined it all here instead.
+ of vsprintf_alloc and combined it all here instead.
*/
-
+
/* ripped more or less straight out of PRINTF(3) */
- if ((new_str = malloc(size)) == NULL)
- return -1;
+ *str = xcalloc(1, size);
- *str = new_str;
while(1) {
va_start(ap, fmt);
- n = vsnprintf (new_str, size, fmt, ap);
+ n = vsnprintf (*str, size, fmt, ap);
va_end(ap);
/* If that worked, return the size. */
if (n > -1 && n < size)
size = n+1; /* precisely what is needed */
else /* glibc 2.0 */
size *= 2; /* twice the old size */
- new_str = realloc(new_str, size);
- if (new_str == NULL) {
- free(new_str);
- *str = NULL;
- return -1;
- }
- *str = new_str;
+ *str = xrealloc(*str, size);
}
return -1; /* Just to be correct - it probably won't get here */