src/standard.c
char *memprintf(char **out, const char *format, ...)
{
	va_list args;
	char *ret = NULL;
	int allocated = 0;
	int needed = 0;

	if (!out)
		return NULL;

	do {
		/* vsnprintf() will return the required length even when the
		 * target buffer is NULL. We do this in a loop just in case
		 * intermediate evaluations get wrong.
		 */
		va_start(args, format);
		needed = vsnprintf(ret, allocated, format, args);
		va_end(args);

		if (needed < allocated) {
			/* Note: on Solaris 8, the first iteration always
			 * returns -1 if allocated is zero, so we force a
			 * retry.
			 */
			if (!allocated)
				needed = 0;
			else
				break;
		}

		allocated = needed + 1;
		ret = realloc(ret, allocated);
	} while (ret);

	if (needed < 0) {
		/* an error was encountered */
		free(ret);
		ret = NULL;
	}

	if (out) {
		free(*out);
		*out = ret;
	}

	return ret;
}
/* Dynamically allocates a string of the proper length to hold the formatted
 * output. NULL is returned on error. The caller is responsible for freeing the
 * memory area using free(). The resulting string is returned in <out> if the
 * pointer is not NULL. A previous version of <out> might be used to build the
 * new string, and it will be freed before returning if it is not NULL, which
 * makes it possible to build complex strings from iterative calls without
 * having to care about freeing intermediate values, as in the example below :
 *
 *     memprintf(&err, "invalid argument: '%s'", arg);
 *     ...
 *     memprintf(&err, "parser said : <%s>\n", *err);
 *     ...
 *     free(*err);
 *
 * This means that <err> must be initialized to NULL before first invocation.
 * The return value also holds the allocated string, which eases error checking
 * and immediate consumption. If the output pointer is not used, NULL must be
 * passed instead and it will be ignored. The returned message will then also
 * be NULL so that the caller does not have to bother with freeing anything.
 *
 * It is also convenient to use it without any free except the last one :
 *    err = NULL;
 *    if (!fct1(err)) report(*err);
 *    if (!fct2(err)) report(*err);
 *    if (!fct3(err)) report(*err);
 *    free(*err);
 */
Dynamically allocates a string of the proper length to hold the formatted
output. NULL is returned on error. The caller is responsible for freeing the
memory area using free(). The resulting string is returned in  if the
pointer is not NULL. A previous version of  might be used to build the
new string, and it will be freed before returning if it is not NULL, which
makes it possible to build complex strings from iterative calls without
having to care about freeing intermediate values, as in the example below .



This means that  must be initialized to NULL before first invocation.
The return value also holds the allocated string, which eases error checking
and immediate consumption. If the output pointer is not used, NULL must be
passed instead and it will be ignored. The returned message will then also
be NULL so that the caller does not have to bother with freeing anything.


Dynamically allocates a string of the proper length to hold the formatted output . NULL is returned on error . The caller is responsible for freeing the memory area using free () . The resulting string is returned in if the pointer is not NULL . A previous version of might be used to build the new string and it will be freed before returning if it is not NULL which makes it possible to build complex strings from iterative calls without having to care about freeing intermediate values as in the example below . This means that must be initialized to NULL before first invocation . The return value also holds the allocated string which eases error checking and immediate consumption . If the output pointer is not used NULL must be passed instead and it will be ignored . The returned message will then also be NULL so that the caller does not have to bother with freeing anything .
char *memprintf(char **out, const char *format, ...)
{
	va_list args;
	char *ret = NULL;
	int allocated = 0;
	int needed = 0;
	if (!out)
		return NULL;
	do {
		va_start(args, format);
		needed = vsnprintf(ret, allocated, format, args);
		va_end(args);
		if (needed < allocated) {
			if (!allocated)
				needed = 0;
			else
				break;
		}
		allocated = needed + 1;
		ret = realloc(ret, allocated);
	} while (ret);
	if (needed < 0) {
		free(ret);
		ret = NULL;
	}
	if (out) {
		free(*out);
		*out = ret;
	}
	return ret;
}
char * memprintf ( char * * out , const char * format , ... ) { va_list args ; char * ret = NULL ; int allocated = 0 ; int needed = 0 ; if ( ! out ) return NULL ; do { va_start ( args , format ) ; needed = vsnprintf ( ret , allocated , format , args ) ; va_end ( args ) ; if ( needed < allocated ) { if ( ! allocated ) needed = 0 ; else break ; } allocated = needed + 1 ; ret = realloc ( ret , allocated ) ; } while ( ret ) ; if ( needed < 0 ) { free ( ret ) ; ret = NULL ; } if ( out ) { free ( * out ) ; * out = ret ; } return ret ; }
Dynamically allocates a string of the proper length to hold the formatted
 output.
Dynamically allocates a string of the proper length to hold the formatted output .
/* vsnprintf() will return the required length even when the
		 * target buffer is NULL. We do this in a loop just in case
		 * intermediate evaluations get wrong.
		 */ /* Note: on Solaris 8, the first iteration always
			 * returns -1 if allocated is zero, so we force a
			 * retry.
			 */ /* an error was encountered */