# HG changeset patch # User David Demelier # Date 1329123148 -3600 # Node ID 21e0ed613dd91d16cf6c252ed03849580e9a7ae9 # Parent a70010512a1f922e2c8714d099679f6fafd422ca Port of asprintf and vasprintf diff -r a70010512a1f -r 21e0ed613dd9 port/asprintf.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/port/asprintf.c Mon Feb 13 09:52:28 2012 +0100 @@ -0,0 +1,60 @@ +/* + * asprintf.c -- basic port of asprintf / vsprintf functions + * + * Copyright (c) 2011, 2012 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#define BASE 80 + +int +vasprintf(char **res, const char *format, va_list ap) +{ + int rvalue, ok; + size_t base = BASE; + + if ((*res = malloc(base)) == NULL) + return -1; + + ok = 0; + do { + rvalue = vsnprintf(*res, base, format, ap); + + if ((signed int)base <= rvalue || rvalue <= 0) { + *res = realloc(*res, base + BASE); + base += BASE; + } else + ok = 1; + } while (!ok && *res != NULL); + + return rvalue; +} + +int +asprintf(char **res, const char *fmt, ...) +{ + va_list ap; + int rvalue; + + va_start(ap, fmt); + rvalue = xvasprintf(res, fmt, ap); + va_end(ap); + + return rvalue; +}