Provide a fallback implementation of [v]asprintf()
Some environments (e.g. Windows + MSVC) do not provide asprintf() or vasprintf(). This tries to detect their presence, and provides suitable fallback implementations when not available.master
parent
93a13050d6
commit
bdff8ebe3c
|
@ -102,6 +102,11 @@ endif
|
|||
if cc.has_header_symbol('string.h', 'strndup', prefix: system_ext_define)
|
||||
configh_data.set('HAVE_STRNDUP', 1)
|
||||
endif
|
||||
if cc.has_header_symbol('stdio.h', 'asprintf', prefix: system_ext_define)
|
||||
configh_data.set('HAVE_ASPRINTF', 1)
|
||||
elif cc.has_header_symbol('stdio.h', 'vasprintf', prefix: system_ext_define)
|
||||
configh_data.set('HAVE_VASPRINTF', 1)
|
||||
endif
|
||||
if cc.has_header_symbol('stdlib.h', 'secure_getenv', prefix: system_ext_define)
|
||||
configh_data.set('HAVE_SECURE_GETENV', 1)
|
||||
elif cc.has_header_symbol('stdlib.h', '__secure_getenv', prefix: system_ext_define)
|
||||
|
|
45
src/utils.c
45
src/utils.c
|
@ -161,3 +161,48 @@ istrncmp(const char *a, const char *b, size_t n)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !(defined(HAVE_ASPRINTF) && HAVE_ASPRINTF)
|
||||
int
|
||||
asprintf(char **strp, const char *fmt, ...)
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
ret = vasprintf(strp, fmt, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
# if !(defined(HAVE_VASPRINTF) && HAVE_VASPRINTF)
|
||||
int
|
||||
vasprintf(char **strp, const char *fmt, va_list ap)
|
||||
{
|
||||
int ret;
|
||||
char *buf;
|
||||
va_list ap_copy;
|
||||
|
||||
/*
|
||||
* The value of the va_list parameter is undefined after the call to
|
||||
* vsnprintf() returns: pass a copy to make sure "ap" remains valid.
|
||||
*/
|
||||
va_copy(ap_copy, ap);
|
||||
ret = vsnprintf(NULL, 0, fmt, ap_copy);
|
||||
va_end(ap_copy);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!(buf = malloc(ret + 1)))
|
||||
return -1;
|
||||
|
||||
if ((ret = vsnprintf(buf, ret + 1, fmt, ap)) < 0) {
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*strp = buf;
|
||||
return ret;
|
||||
}
|
||||
# endif /* !HAVE_VASPRINTF */
|
||||
#endif /* !HAVE_ASPRINTF */
|
||||
|
|
|
@ -259,4 +259,12 @@ unmap_file(char *string, size_t size);
|
|||
#define ATTR_PACKED
|
||||
#endif
|
||||
|
||||
#if !(defined(HAVE_ASPRINTF) && HAVE_ASPRINTF)
|
||||
int asprintf(char **strp, const char *fmt, ...) ATTR_PRINTF(2, 3);
|
||||
# if !(defined(HAVE_VASPRINTF) && HAVE_VASPRINTF)
|
||||
# include <stdarg.h>
|
||||
int vasprintf(char **strp, const char *fmt, va_list ap);
|
||||
# endif /* !HAVE_VASPRINTF */
|
||||
#endif /* !HAVE_ASPRINTF */
|
||||
|
||||
#endif /* UTILS_H */
|
||||
|
|
Loading…
Reference in New Issue