Module: Mesa Branch: main Commit: 2db5536a461734a818caf4f519e3286accb0818f URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=2db5536a461734a818caf4f519e3286accb0818f
Author: Yevhenii Kolesnikov <[email protected]> Date: Thu Sep 23 20:23:33 2021 +0300 vulkan: Add vk_asprintf and vk_vasprintf helpers Signed-off-by: Yevhenii Kolesnikov <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10318> --- src/util/ralloc.c | 52 +++++----------------------------------------- src/util/u_printf.cpp | 43 ++++++++++++++++++++++++++++++++++++++ src/util/u_printf.h | 8 +++++++ src/vulkan/util/vk_alloc.h | 29 +++++++++++++++++++++++++- 4 files changed, 84 insertions(+), 48 deletions(-) diff --git a/src/util/ralloc.c b/src/util/ralloc.c index 4c2cf0772ce..705614478b6 100644 --- a/src/util/ralloc.c +++ b/src/util/ralloc.c @@ -30,23 +30,10 @@ #include "util/macros.h" #include "util/u_math.h" - -/* Some versions of MinGW are missing _vscprintf's declaration, although they - * still provide the symbol in the import library. */ -#ifdef __MINGW32__ -_CRTIMP int _vscprintf(const char *format, va_list argptr); -#endif +#include "util/u_printf.h" #include "ralloc.h" -#ifndef va_copy -#ifdef __va_copy -#define va_copy(dest, src) __va_copy((dest), (src)) -#else -#define va_copy(dest, src) (dest) = (src) -#endif -#endif - #define CANARY 0x5A1106 /* Align the header's size so that ralloc() allocations will return with the @@ -474,39 +461,10 @@ ralloc_asprintf(const void *ctx, const char *fmt, ...) return ptr; } -/* Return the length of the string that would be generated by a printf-style - * format and argument list, not including the \0 byte. - */ -static size_t -printf_length(const char *fmt, va_list untouched_args) -{ - int size; - char junk; - - /* Make a copy of the va_list so the original caller can still use it */ - va_list args; - va_copy(args, untouched_args); - -#ifdef _WIN32 - /* We need to use _vcsprintf to calculate the size as vsnprintf returns -1 - * if the number of characters to write is greater than count. - */ - size = _vscprintf(fmt, args); - (void)junk; -#else - size = vsnprintf(&junk, 1, fmt, args); -#endif - assert(size >= 0); - - va_end(args); - - return size; -} - char * ralloc_vasprintf(const void *ctx, const char *fmt, va_list args) { - size_t size = printf_length(fmt, args) + 1; + size_t size = u_printf_length(fmt, args) + 1; char *ptr = ralloc_size(ctx, size); if (ptr != NULL) @@ -562,7 +520,7 @@ ralloc_vasprintf_rewrite_tail(char **str, size_t *start, const char *fmt, return true; } - new_length = printf_length(fmt, args); + new_length = u_printf_length(fmt, args); ptr = resize(*str, *start + new_length + 1); if (unlikely(ptr == NULL)) @@ -841,7 +799,7 @@ linear_asprintf(void *parent, const char *fmt, ...) char * linear_vasprintf(void *parent, const char *fmt, va_list args) { - unsigned size = printf_length(fmt, args) + 1; + unsigned size = u_printf_length(fmt, args) + 1; char *ptr = linear_alloc_child(parent, size); if (ptr != NULL) @@ -897,7 +855,7 @@ linear_vasprintf_rewrite_tail(void *parent, char **str, size_t *start, return true; } - new_length = printf_length(fmt, args); + new_length = u_printf_length(fmt, args); ptr = linear_realloc(parent, *str, *start + new_length + 1); if (unlikely(ptr == NULL)) diff --git a/src/util/u_printf.cpp b/src/util/u_printf.cpp index 02449d294ad..81a8c148147 100644 --- a/src/util/u_printf.cpp +++ b/src/util/u_printf.cpp @@ -22,6 +22,23 @@ // Extract from Serge's printf clover code by airlied. #include "u_printf.h" +#include <assert.h> +#include <stdarg.h> +#include "util/macros.h" + +/* Some versions of MinGW are missing _vscprintf's declaration, although they + * still provide the symbol in the import library. */ +#ifdef __MINGW32__ +_CRTIMP int _vscprintf(const char *format, va_list argptr); +#endif + +#ifndef va_copy +#ifdef __va_copy +#define va_copy(dest, src) __va_copy((dest), (src)) +#else +#define va_copy(dest, src) (dest) = (src) +#endif +#endif size_t util_printf_next_spec_pos(const std::string &s, size_t pos) { @@ -51,3 +68,29 @@ size_t util_printf_next_spec_pos(const char *str, size_t pos) { return util_printf_next_spec_pos(std::string(str), pos); } + +size_t +u_printf_length(const char *fmt, va_list untouched_args) +{ + int size; + char junk; + + /* Make a copy of the va_list so the original caller can still use it */ + va_list args; + va_copy(args, untouched_args); + +#ifdef _WIN32 + /* We need to use _vcsprintf to calculate the size as vsnprintf returns -1 + * if the number of characters to write is greater than count. + */ + size = _vscprintf(fmt, args); + (void)junk; +#else + size = vsnprintf(&junk, 1, fmt, args); +#endif + assert(size >= 0); + + va_end(args); + + return size; +} diff --git a/src/util/u_printf.h b/src/util/u_printf.h index 2ffa66dd351..44dcce5529f 100644 --- a/src/util/u_printf.h +++ b/src/util/u_printf.h @@ -34,6 +34,14 @@ extern "C" { /* find next valid printf specifier in a C string wrapper */ size_t util_printf_next_spec_pos(const char *str, size_t pos); + +/* Return the length of the string that would be generated by a printf-style + * format and argument list, not including the \0 byte. + * The untouched_args parameter is left untouched so it can be re-used by the + * caller in a vsnprintf() call or similar. + */ +size_t u_printf_length(const char *fmt, va_list untouched_args); + #ifdef __cplusplus } #endif diff --git a/src/vulkan/util/vk_alloc.h b/src/vulkan/util/vk_alloc.h index 56d3d7744fb..ee31d8ae396 100644 --- a/src/vulkan/util/vk_alloc.h +++ b/src/vulkan/util/vk_alloc.h @@ -25,12 +25,13 @@ /* common allocation inlines for vulkan drivers */ +#include <stdio.h> #include <string.h> #include <vulkan/vulkan.h> #include "util/u_math.h" #include "util/macros.h" - +#include "util/u_printf.h" const VkAllocationCallbacks * vk_default_allocator(void); @@ -91,6 +92,32 @@ vk_strdup(const VkAllocationCallbacks *alloc, const char *s, return copy; } +static inline char * +vk_vasprintf(const VkAllocationCallbacks *alloc, + VkSystemAllocationScope scope, + const char *fmt, va_list args) +{ + size_t size = u_printf_length(fmt, args) + 1; + char *ptr = vk_alloc(alloc, size, 1, scope); + if (ptr != NULL) + vsnprintf(ptr, size, fmt, args); + + return ptr; +} + +PRINTFLIKE(3, 4) static inline char * +vk_asprintf(const VkAllocationCallbacks *alloc, + VkSystemAllocationScope scope, + const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + char *ptr = vk_vasprintf(alloc, scope, fmt, args); + va_end(args); + + return ptr; +} + static inline void * vk_alloc2(const VkAllocationCallbacks *parent_alloc, const VkAllocationCallbacks *alloc,
