Loading...
Searching...
No Matches
asprintf.c
Go to the documentation of this file.
/*!
* \file lib/gis/asprintf.c
*
* \brief GIS Library - GRASS implementation of asprintf().
*
* Eric G. Miller - Thu, 2 May 2002 17:51:54 -0700
*
* Rewritten by Glynn Clements, Sat, 6 Feb 2010
* Assumes that vsnprintf() is available
*
* (C) 2002-2014 by the GRASS Development Team
* (C) 2010 by Glynn Clements
*
* This program is free software under the GNU General Public License
* (>=v2). Read the file COPYING that comes with GRASS for details.
*/
#define _GNU_SOURCE /* enable asprintf */
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <grass/gis.h>
#ifndef G_asprintf
/**
* \brief Safe replacement for <i>asprintf()</i>.
*
* Allocate a string large enough to hold the new output, including the
* terminating NULL, and return the number of characters printed. The
* pointer out is set to the output string and should be passed to
* <i>G_free()</i> to release the allocated storage when it is no longer
* needed.
*
* \param[out] out
* \param[in] fmt
* \param ap
* \return number of bytes written
*/
int G_vasprintf(char **out, const char *fmt, va_list ap)
{
#ifdef HAVE_ASPRINTF
return vasprintf(out, fmt, ap);
#else
size_t size = strlen(fmt) + 50;
char *buf = G_malloc(size);
int count;
for (;;) {
/* BUG: according to man vsnprintf,
* va_start() should be called immediately before vsnprintf(),
* and va_end() immediately after vsnprintf()
* otherwise there will be memory corruption */
count = vsnprintf(buf, size, fmt, ap);
if (count >= 0 && count < size)
break;
size *= 2;
buf = G_realloc(buf, size);
}
buf = G_realloc(buf, count + 1);
*out = buf;
return count;
#endif /* HAVE_ASPRINTF */
}
int G_asprintf(char **out, const char *fmt, ...)
{
va_list ap;
int count;
va_start(ap, fmt);
count = G_vasprintf(out, fmt, ap);
va_end(ap);
return count;
}
#endif /* G_asprintf */
/**
* \brief Reallocating version of <i>asprintf()</i>.
*
* Reallocate a string large enough to hold the output, including the
* terminating NULL, and return the number of characters printed.
* Contrary to <i>G_asprintf()</i>, any existing buffer pointed to by
* out of size osize is used to hold the output and enlarged if
* necessary. This is useful when <i>G_rasprintf</i> is called many
* times in a loop.
*
* \param[out] out
* \param[out] size
* \param[in] fmt
* \param ap
* \return number of bytes written
*/
int G_rasprintf(char **out, size_t *size, const char *fmt, ...)
{
va_list ap;
int count;
char *buf = *out;
size_t osize = *size;
if (osize < strlen(fmt) + 50) {
osize = strlen(fmt) + 50;
buf = G_realloc(buf, osize);
}
for (;;) {
va_start(ap, fmt);
count = vsnprintf(buf, osize, fmt, ap);
va_end(ap);
if (count >= 0 && (size_t)count < osize)
break;
if (count > -1)
osize = count + 1;
else
osize *= 2;
buf = G_realloc(buf, osize);
}
*out = buf;
*size = osize;
return count;
}
G_rasprintf
int G_rasprintf(char **out, size_t *size, const char *fmt,...)
Reallocating version of asprintf().
Definition asprintf.c:98
G_asprintf
int G_asprintf(char **out, const char *fmt,...)
Definition asprintf.c:68
G_vasprintf
int G_vasprintf(char **out, const char *fmt, va_list ap)
Safe replacement for asprintf().
Definition asprintf.c:40
count
int count