Blame missing/asprintf.c

Packit 209cc3
#include <stdio.h>
Packit 209cc3
#include <stdlib.h>
Packit 209cc3
#include <stdarg.h>
Packit 209cc3
Packit 209cc3
#include "portability.h"
Packit 209cc3
Packit 209cc3
/*
Packit 209cc3
 * vasprintf() and asprintf() for platforms with a C99-compliant
Packit 209cc3
 * snprintf() - so that, if you format into a 1-byte buffer, it
Packit 209cc3
 * will return how many characters it would have produced had
Packit 209cc3
 * it been given an infinite-sized buffer.
Packit 209cc3
 */
Packit 209cc3
int
Packit 209cc3
pcap_vasprintf(char **strp, const char *format, va_list args)
Packit 209cc3
{
Packit 209cc3
	char buf;
Packit 209cc3
	int len;
Packit 209cc3
	size_t str_size;
Packit 209cc3
	char *str;
Packit 209cc3
	int ret;
Packit 209cc3
Packit 209cc3
	/*
Packit 209cc3
	 * XXX - the C99 standard says, in section 7.19.6.5 "Thes
Packit 209cc3
	 * nprintf function":
Packit 209cc3
	 *
Packit 209cc3
	 *    The snprintf function is equivalent to fprintf, except that
Packit 209cc3
	 *    the output is written into an array (specified by argument s)
Packit 209cc3
	 *    rather than to a stream.  If n is zero, nothing is written,
Packit 209cc3
	 *    and s may be a null pointer.  Otherwise, output characters
Packit 209cc3
	 *    beyond the n-1st are discarded rather than being written
Packit 209cc3
	 *    to the array, and a null character is written at the end
Packit 209cc3
	 *    of the characters actually written into the array.
Packit 209cc3
	 *
Packit 209cc3
	 *        ...
Packit 209cc3
	 *
Packit 209cc3
	 *    The snprintf function returns the number of characters that
Packit 209cc3
	 *    would have been written had n been sufficiently large, not
Packit 209cc3
	 *    counting the terminating null character, or a negative value
Packit 209cc3
	 *    if an encoding error occurred. Thus, the null-terminated
Packit 209cc3
	 *    output has been completely written if and only if the returned
Packit 209cc3
	 *    value is nonnegative and less than n.
Packit 209cc3
	 *
Packit 209cc3
	 * That doesn't make it entirely clear whether, if a null buffer
Packit 209cc3
	 * pointer and a zero count are passed, it will return the number
Packit 209cc3
	 * of characters that would have been written had a buffer been
Packit 209cc3
	 * passed.
Packit 209cc3
	 *
Packit 209cc3
	 * And, even if C99 *does*, in fact, say it has to work, it
Packit 209cc3
	 * doesn't work in Solaris 8, for example - it returns -1 for
Packit 209cc3
	 * NULL/0, but returns the correct character count for a 1-byte
Packit 209cc3
	 * buffer.
Packit 209cc3
	 *
Packit 209cc3
	 * So we pass a one-character pointer in order to find out how
Packit 209cc3
	 * many characters this format and those arguments will need
Packit 209cc3
	 * without actually generating any more of those characters
Packit 209cc3
	 * than we need.
Packit 209cc3
	 *
Packit 209cc3
	 * (The fact that it might happen to work with GNU libc or with
Packit 209cc3
	 * various BSD libcs is completely uninteresting, as those tend
Packit 209cc3
	 * to have asprintf() already and thus don't even *need* this
Packit 209cc3
	 * code; this is for use in those UN*Xes that *don't* have
Packit 209cc3
	 * asprintf().)
Packit 209cc3
	 */
Packit 209cc3
	len = vsnprintf(&buf, sizeof buf, format, args);
Packit 209cc3
	if (len == -1) {
Packit 209cc3
		*strp = NULL;
Packit 209cc3
		return (-1);
Packit 209cc3
	}
Packit 209cc3
	str_size = len + 1;
Packit 209cc3
	str = malloc(str_size);
Packit 209cc3
	if (str == NULL) {
Packit 209cc3
		*strp = NULL;
Packit 209cc3
		return (-1);
Packit 209cc3
	}
Packit 209cc3
	ret = vsnprintf(str, str_size, format, args);
Packit 209cc3
	if (ret == -1) {
Packit 209cc3
		free(str);
Packit 209cc3
		*strp = NULL;
Packit 209cc3
		return (-1);
Packit 209cc3
	}
Packit 209cc3
	*strp = str;
Packit 209cc3
	/*
Packit 209cc3
	 * vsnprintf() shouldn't truncate the string, as we have
Packit 209cc3
	 * allocated a buffer large enough to hold the string, so its
Packit 209cc3
	 * return value should be the number of characters written.
Packit 209cc3
	 */
Packit 209cc3
	return (ret);
Packit 209cc3
}
Packit 209cc3
Packit 209cc3
int
Packit 209cc3
pcap_asprintf(char **strp, const char *format, ...)
Packit 209cc3
{
Packit 209cc3
	va_list args;
Packit 209cc3
	int ret;
Packit 209cc3
Packit 209cc3
	va_start(args, format);
Packit 209cc3
	ret = pcap_vasprintf(strp, format, args);
Packit 209cc3
	va_end(args);
Packit 209cc3
	return (ret);
Packit 209cc3
}
Packit 209cc3