1.1 --- a/src/cx/printf.h Tue Jan 16 23:12:43 2024 +0100 1.2 +++ b/src/cx/printf.h Tue Jan 16 23:13:01 2024 +0100 1.3 @@ -164,6 +164,170 @@ 1.4 #define cx_bprintf(buffer, fmt, ...) cx_fprintf((CxBuffer*)buffer, \ 1.5 (cx_write_func) cxBufferWrite, fmt, __VA_ARGS__) 1.6 1.7 + 1.8 +/** 1.9 + * An \c sprintf like function which reallocates the string when the buffer is not large enough. 1.10 + * 1.11 + * \note The resulting string is guaranteed to be zero-terminated. 1.12 + * That means, when the buffer needed to be reallocated, the new size of the buffer will be 1.13 + * the length returned by this function plus one. 1.14 + * 1.15 + * @param str a pointer to the string buffer 1.16 + * @param len the current length of the buffer 1.17 + * @param fmt the format string 1.18 + * @param ... additional arguments 1.19 + * @return the length of produced string 1.20 + */ 1.21 +#define cx_sprintf(str, len, fmt, ...) cx_sprintf_a(cxDefaultAllocator, str, len, fmt, __VA_ARGS__) 1.22 + 1.23 +/** 1.24 + * An \c sprintf like function which reallocates the string when the buffer is not large enough. 1.25 + * 1.26 + * \note The resulting string is guaranteed to be zero-terminated. 1.27 + * That means, when the buffer needed to be reallocated, the new size of the buffer will be 1.28 + * the length returned by this function plus one. 1.29 + * 1.30 + * \attention The original buffer MUST have been allocated with the same allocator! 1.31 + * 1.32 + * @param alloc the allocator to use 1.33 + * @param str a pointer to the string buffer 1.34 + * @param len the current length of the buffer 1.35 + * @param fmt the format string 1.36 + * @param ... additional arguments 1.37 + * @return the length of produced string 1.38 + */ 1.39 +__attribute__((__nonnull__(1, 2, 4), __format__(printf, 4, 5))) 1.40 +int cx_sprintf_a(CxAllocator *alloc, char **str, size_t len, const char *fmt, ... ); 1.41 + 1.42 + 1.43 +/** 1.44 + * An \c sprintf like function which reallocates the string when the buffer is not large enough. 1.45 + * 1.46 + * \note The resulting string is guaranteed to be zero-terminated. 1.47 + * That means, when the buffer needed to be reallocated, the new size of the buffer will be 1.48 + * the length returned by this function plus one. 1.49 + * 1.50 + * @param str a pointer to the string buffer 1.51 + * @param len the current length of the buffer 1.52 + * @param fmt the format string 1.53 + * @param ap argument list 1.54 + * @return the length of produced string 1.55 + */ 1.56 +#define cx_vsprintf(str, len, fmt, ap) cx_vsprintf_a(cxDefaultAllocator, str, len, fmt, ap) 1.57 + 1.58 +/** 1.59 + * An \c sprintf like function which reallocates the string when the buffer is not large enough. 1.60 + * 1.61 + * \note The resulting string is guaranteed to be zero-terminated. 1.62 + * That means, when the buffer needed to be reallocated, the new size of the buffer will be 1.63 + * the length returned by this function plus one. 1.64 + * 1.65 + * \attention The original buffer MUST have been allocated with the same allocator! 1.66 + * 1.67 + * @param alloc the allocator to use 1.68 + * @param str a pointer to the string buffer 1.69 + * @param len the current length of the buffer 1.70 + * @param fmt the format string 1.71 + * @param ap argument list 1.72 + * @return the length of produced string 1.73 + */ 1.74 +__attribute__((__nonnull__)) 1.75 +int cx_vsprintf_a(CxAllocator *alloc, char **str, size_t len, const char *fmt, va_list ap); 1.76 + 1.77 + 1.78 +/** 1.79 + * An \c sprintf like function which allocates a new string when the buffer is not large enough. 1.80 + * 1.81 + * The location of the resulting string will \em always be stored to \p str. When the buffer 1.82 + * was sufficiently large, \p buf itself will be stored to the location of \p str. 1.83 + * 1.84 + * \note The resulting string is guaranteed to be zero-terminated. 1.85 + * That means, when the buffer needed to be reallocated, the new size of the buffer will be 1.86 + * the length returned by this function plus one. 1.87 + * 1.88 + * \remark When a new string needed to be allocated, the contents of \p buf will be 1.89 + * poisoned after the call, because this function tries to produce the string in \p buf, first. 1.90 + * 1.91 + * @param buf a pointer to the buffer 1.92 + * @param len the length of the buffer 1.93 + * @param str a pointer to the location 1.94 + * @param fmt the format string 1.95 + * @param ... additional arguments 1.96 + * @return the length of produced string 1.97 + */ 1.98 +#define cx_sprintf_s(buf, len, str, fmt, ...) cx_sprintf_sa(cxDefaultAllocator, buf, len, str, fmt, __VA_ARGS__) 1.99 + 1.100 +/** 1.101 + * An \c sprintf like function which allocates a new string when the buffer is not large enough. 1.102 + * 1.103 + * The location of the resulting string will \em always be stored to \p str. When the buffer 1.104 + * was sufficiently large, \p buf itself will be stored to the location of \p str. 1.105 + * 1.106 + * \note The resulting string is guaranteed to be zero-terminated. 1.107 + * That means, when the buffer needed to be reallocated, the new size of the buffer will be 1.108 + * the length returned by this function plus one. 1.109 + * 1.110 + * \remark When a new string needed to be allocated, the contents of \p buf will be 1.111 + * poisoned after the call, because this function tries to produce the string in \p buf, first. 1.112 + * 1.113 + * @param alloc the allocator to use 1.114 + * @param buf a pointer to the buffer 1.115 + * @param len the length of the buffer 1.116 + * @param str a pointer to the location 1.117 + * @param fmt the format string 1.118 + * @param ... additional arguments 1.119 + * @return the length of produced string 1.120 + */ 1.121 +__attribute__((__nonnull__(1, 2, 4, 5), __format__(printf, 5, 6))) 1.122 +int cx_sprintf_sa(CxAllocator *alloc, char *buf, size_t len, char **str, const char *fmt, ... ); 1.123 + 1.124 +/** 1.125 + * An \c sprintf like function which allocates a new string when the buffer is not large enough. 1.126 + * 1.127 + * The location of the resulting string will \em always be stored to \p str. When the buffer 1.128 + * was sufficiently large, \p buf itself will be stored to the location of \p str. 1.129 + * 1.130 + * \note The resulting string is guaranteed to be zero-terminated. 1.131 + * That means, when the buffer needed to be reallocated, the new size of the buffer will be 1.132 + * the length returned by this function plus one. 1.133 + * 1.134 + * \remark When a new string needed to be allocated, the contents of \p buf will be 1.135 + * poisoned after the call, because this function tries to produce the string in \p buf, first. 1.136 + * 1.137 + * @param buf a pointer to the buffer 1.138 + * @param len the length of the buffer 1.139 + * @param str a pointer to the location 1.140 + * @param fmt the format string 1.141 + * @param ap argument list 1.142 + * @return the length of produced string 1.143 + */ 1.144 +#define cx_vsprintf_s(buf, len, str, fmt, ap) cx_vsprintf_sa(cxDefaultAllocator, buf, len, str, fmt, ap) 1.145 + 1.146 +/** 1.147 + * An \c sprintf like function which allocates a new string when the buffer is not large enough. 1.148 + * 1.149 + * The location of the resulting string will \em always be stored to \p str. When the buffer 1.150 + * was sufficiently large, \p buf itself will be stored to the location of \p str. 1.151 + * 1.152 + * \note The resulting string is guaranteed to be zero-terminated. 1.153 + * That means, when the buffer needed to be reallocated, the new size of the buffer will be 1.154 + * the length returned by this function plus one. 1.155 + * 1.156 + * \remark When a new string needed to be allocated, the contents of \p buf will be 1.157 + * poisoned after the call, because this function tries to produce the string in \p buf, first. 1.158 + * 1.159 + * @param alloc the allocator to use 1.160 + * @param buf a pointer to the buffer 1.161 + * @param len the length of the buffer 1.162 + * @param str a pointer to the location 1.163 + * @param fmt the format string 1.164 + * @param ap argument list 1.165 + * @return the length of produced string 1.166 + */ 1.167 +__attribute__((__nonnull__)) 1.168 +int cx_vsprintf_sa(CxAllocator *alloc, char *buf, size_t len, char **str, const char *fmt, va_list ap); 1.169 + 1.170 + 1.171 #ifdef __cplusplus 1.172 } // extern "C" 1.173 #endif