Re: [PATCH v2 1/3] util: Add xa{v}sprintf_append functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



On Sat, Nov 24, 2018 at 02:47:54PM -0600, Rob Herring wrote:
> Add variadic and va_list functions, xa{v}sprintf, which appends a
> formatted string to an existing string and re-allocate the string buffer
> if necessary. xasprintf becomes just a special case of xasprintf_append
> with a NULL starting string.
> 
> Rather than looping to get a big enough buffer, simply the implementation
> by assuming we have a C99 compliant vsnprintf implementation to return the
> necessary size. A side effect is glibc 2.0 support is dropped which seems
> unnecessary.
> 
> Signed-off-by: Rob Herring <robh@xxxxxxxxxx>

Series applied, thanks.

> ---
>  util.c | 60 ++++++++++++++++++++++++++++++++++++++--------------------
>  util.h |  2 ++
>  2 files changed, 41 insertions(+), 21 deletions(-)
> 
> diff --git a/util.c b/util.c
> index a69b7a13463d..9c6fb5f286ae 100644
> --- a/util.c
> +++ b/util.c
> @@ -46,36 +46,54 @@ char *xstrdup(const char *s)
>  	return d;
>  }
>  
> -/* based in part from (3) vsnprintf */
> -int xasprintf(char **strp, const char *fmt, ...)
> +int xavsprintf_append(char **strp, const char *fmt, va_list ap)
>  {
> -	int n, size = 128;	/* start with 128 bytes */
> +	int n, size = 0;	/* start with 128 bytes */
>  	char *p;
> -	va_list ap;
> +	va_list ap_copy;
>  
> -	/* initial pointer is NULL making the fist realloc to be malloc */
> -	p = NULL;
> -	while (1) {
> -		p = xrealloc(p, size);
> +	p = *strp;
> +	if (p)
> +		size = strlen(p);
>  
> -		/* Try to print in the allocated space. */
> -		va_start(ap, fmt);
> -		n = vsnprintf(p, size, fmt, ap);
> -		va_end(ap);
> +	va_copy(ap_copy, ap);
> +	n = vsnprintf(NULL, 0, fmt, ap_copy) + 1;
> +	va_end(ap_copy);
> +
> +	p = xrealloc(p, size + n);
> +
> +	n = vsnprintf(p + size, n, fmt, ap);
>  
> -		/* If that worked, return the string. */
> -		if (n > -1 && n < size)
> -			break;
> -		/* Else try again with more space. */
> -		if (n > -1)	/* glibc 2.1 */
> -			size = n + 1; /* precisely what is needed */
> -		else		/* glibc 2.0 */
> -			size *= 2; /* twice the old size */
> -	}
>  	*strp = p;
>  	return strlen(p);
>  }
>  
> +int xasprintf_append(char **strp, const char *fmt, ...)
> +{
> +	int n;
> +	va_list ap;
> +
> +	va_start(ap, fmt);
> +	n = xavsprintf_append(strp, fmt, ap);
> +	va_end(ap);
> +
> +	return n;
> +}
> +
> +int xasprintf(char **strp, const char *fmt, ...)
> +{
> +	int n;
> +	va_list ap;
> +
> +	*strp = NULL;
> +
> +	va_start(ap, fmt);
> +	n = xavsprintf_append(strp, fmt, ap);
> +	va_end(ap);
> +
> +	return n;
> +}
> +
>  char *join_path(const char *path, const char *name)
>  {
>  	int lenp = strlen(path);
> diff --git a/util.h b/util.h
> index f6cea8274174..7658781a6200 100644
> --- a/util.h
> +++ b/util.h
> @@ -72,6 +72,8 @@ static inline void *xrealloc(void *p, size_t len)
>  extern char *xstrdup(const char *s);
>  
>  extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...);
> +extern int PRINTF(2, 3) xasprintf_append(char **strp, const char *fmt, ...);
> +extern int xavsprintf_append(char **strp, const char *fmt, va_list ap);
>  extern char *join_path(const char *path, const char *name);
>  
>  /**

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Device Tree]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux