From: Brendan Shanks bshanks@codeweavers.com
--- tools/tools.h | 52 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-)
diff --git a/tools/tools.h b/tools/tools.h index 5372b5bd303..37649a4c1ef 100644 --- a/tools/tools.h +++ b/tools/tools.h @@ -135,6 +135,40 @@ static inline char *xstrdup( const char *str ) return strcpy( xmalloc( strlen(str)+1 ), str ); }
+static int xvasprintf( char **ret, const char *format, va_list ap ) __attribute__ ((__format__ (__printf__, 2, 0))); +static inline int xvasprintf( char **ret, const char *fmt, va_list ap ) +{ +#ifdef _WIN32 + int n; + char *p; + va_list copy; + size_t size = 100; + + for (;;) + { + p = xmalloc( size ); + va_copy( copy, ap ); + n = vsnprintf( p, size, fmt, copy ); + va_end( copy ); + if (n == -1) size *= 2; + else if ((size_t)n >= size) size = n + 1; + else break; + free( p ); + } + *ret = p; + return n; +#else + int n = vasprintf( ret, fmt, ap ); + + if (n == -1) + { + fprintf( stderr, "Virtual memory exhausted.\n" ); + exit(1); + } + return n; +#endif +} + static inline int strendswith( const char *str, const char *end ) { int l = strlen( str ); @@ -145,21 +179,13 @@ static inline int strendswith( const char *str, const char *end ) static char *strmake( const char* fmt, ... ) __attribute__ ((__format__ (__printf__, 1, 2))); static inline char *strmake( const char* fmt, ... ) { - int n; - size_t size = 100; va_list ap; + char *ret;
- for (;;) - { - char *p = xmalloc( size ); - va_start( ap, fmt ); - n = vsnprintf( p, size, fmt, ap ); - va_end( ap ); - if (n == -1) size *= 2; - else if ((size_t)n >= size) size = n + 1; - else return p; - free( p ); - } + va_start( ap, fmt ); + xvasprintf( &ret, fmt, ap ); + va_end( ap ); + return ret; }
/* string array functions */
Marking this as a draft for now. Older glibc versions require `_GNU_SOURCE` to be defined to expose `vasprintf()`. Wine's `config.h` does define that, but the `flex`-generated files include `stdio.h` before we can include `config.h`. Not sure there's a way to fix that other than through compiler flags, and that's not worth the trouble for this.
I'll revisit this once the build environment is on a newer glibc.