44#include <stddef.h>
55#include <stdlib.h>
66
7+ #include <stdarg.h>
8+
79#ifdef __cplusplus
810extern "C" {
911#endif
@@ -12,49 +14,40 @@ extern "C" {
1214 * @brief C89 `sprintf`. `long` arguments and width specifiers are unsupported.
1315 * @note `%s` will write up to 255 characters.
1416 */
15- int boot_sprintf (
16- char * __restrict buffer , const char * __restrict format , ...
17- ) __attribute__((format (__printf__ , 2 , 3 )));
17+ int boot_sprintf (char * __restrict buffer , const char * __restrict format , ...)
18+ __attribute__((format (__printf__ , 2 , 3 )));
19+
20+ /**
21+ * @note calls va_copy to wrap boot_sprintf
22+ */
23+ int boot_vsprintf (char * __restrict buffer , const char * __restrict format , va_list va )
24+ __attribute__((format (__printf__ , 2 , 0 )));
1825
1926/**
2027 * @brief Returns an empty string if the output from sprintf does not fit.
21- * @warning `__VA_ARGS__` is evaluated twice.
2228 */
23- #define boot_snprintf (buffer , count , ...)\
24- ({\
25- char * const __buffer = buffer;\
26- const int __count = count;\
27- int __ret = -1;\
28- int __str_len = boot_sprintf((char*)0xE40000, __VA_ARGS__);\
29- if (__buffer == NULL || __count == 0) {\
30- __ret = __str_len;\
31- } else if ((size_t)__str_len > __count) {\
32- *__buffer = '\0'; /* won't fit or invalid formatting */ \
33- } else {\
34- __ret = boot_sprintf ( __buffer , __VA_ARGS__ );\
35- }\
36- __ret ;\
37- })
29+ int boot_snprintf (char * __restrict buffer , size_t count , const char * __restrict format , ...)
30+ __attribute__(( format ( __printf__ , 3 , 4 )));
31+
32+ /**
33+ * @brief Returns an empty string if the output from sprintf does not fit.
34+ */
35+ int boot_vsnprintf ( char * __restrict buffer , size_t count , const char * __restrict format , va_list va )
36+ __attribute__(( format ( __printf__ , 3 , 0 )));
37+
38+ /**
39+ * @brief Allocates a null terminated string containing the output of sprintf.
40+ * The returned pointer shall be deallocated with `free`.
41+ */
42+ int boot_asprintf ( char * * __restrict p_buffer , const char * __restrict format , ...)
43+ __attribute__(( format ( __printf__ , 2 , 3 ))) __attribute__(( nonnull ( 1 )));
3844
3945/**
4046 * @brief Allocates a null terminated string containing the output of sprintf.
4147 * The returned pointer shall be deallocated with `free`.
42- * @warning `__VA_ARGS__` is evaluated twice.
4348 */
44- #define boot_asprintf (p_buffer , ...)\
45- ({\
46- char** const __p_buffer = p_buffer;\
47- int __ret = -1;\
48- int __str_len = boot_sprintf((char*)0xE40000, __VA_ARGS__);\
49- if (__str_len >= 0) {\
50- size_t __buffer_size = (size_t)__str_len + 1;\
51- *__p_buffer = (char*)malloc(__buffer_size);\
52- if (*__p_buffer != NULL) {\
53- __ret = boot_sprintf(*__p_buffer, __VA_ARGS__);\
54- }\
55- }\
56- __ret;\
57- })
49+ int boot_vasprintf (char * * __restrict p_buffer , const char * __restrict format , va_list va )
50+ __attribute__((format (__printf__ , 2 , 0 ))) __attribute__((nonnull (1 )));
5851
5952#ifdef __cplusplus
6053}
0 commit comments