src/cx/printf.h

Tue, 16 Jan 2024 23:13:01 +0100

author
Mike Becker <universe@uap-core.de>
date
Tue, 16 Jan 2024 23:13:01 +0100
changeset 810
85859399a0cc
parent 805
26500fc24058
child 849
edb9f875b7f9
permissions
-rw-r--r--

add cx_sprintf() variants - fixes #353

universe@599 1 /*
universe@599 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@599 3 *
universe@599 4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
universe@599 5 *
universe@599 6 * Redistribution and use in source and binary forms, with or without
universe@599 7 * modification, are permitted provided that the following conditions are met:
universe@599 8 *
universe@599 9 * 1. Redistributions of source code must retain the above copyright
universe@599 10 * notice, this list of conditions and the following disclaimer.
universe@599 11 *
universe@599 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@599 13 * notice, this list of conditions and the following disclaimer in the
universe@599 14 * documentation and/or other materials provided with the distribution.
universe@599 15 *
universe@599 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@599 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@599 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@599 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@599 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@599 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@599 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@599 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@599 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@599 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@599 26 * POSSIBILITY OF SUCH DAMAGE.
universe@599 27 */
universe@599 28 /**
universe@599 29 * \file printf.h
universe@599 30 * \brief Wrapper for write functions with a printf-like interface.
universe@599 31 * \author Mike Becker
universe@599 32 * \author Olaf Wintermann
universe@599 33 * \copyright 2-Clause BSD License
universe@599 34 */
universe@599 35
universe@599 36 #ifndef UCX_PRINTF_H
universe@599 37 #define UCX_PRINTF_H
universe@599 38
universe@599 39 #include "common.h"
universe@599 40 #include "string.h"
universe@599 41 #include <stdarg.h>
universe@599 42
universe@599 43 #ifdef __cplusplus
universe@599 44 extern "C" {
universe@599 45 #endif
universe@599 46
universe@805 47
universe@805 48 /**
universe@805 49 * The maximum string length that fits into stack memory.
universe@805 50 */
universe@805 51 extern unsigned const cx_printf_sbo_size;
universe@805 52
universe@599 53 /**
universe@599 54 * A \c fprintf like function which writes the output to a stream by
universe@599 55 * using a write_func.
universe@599 56 *
universe@599 57 * @param stream the stream the data is written to
universe@599 58 * @param wfc the write function
universe@599 59 * @param fmt format string
universe@599 60 * @param ... additional arguments
universe@599 61 * @return the total number of bytes written
universe@599 62 */
universe@635 63 __attribute__((__nonnull__(1, 2, 3), __format__(printf, 3, 4)))
universe@635 64 int cx_fprintf(
universe@635 65 void *stream,
universe@635 66 cx_write_func wfc,
universe@635 67 char const *fmt,
universe@635 68 ...
universe@635 69 );
universe@599 70
universe@599 71 /**
universe@599 72 * A \c vfprintf like function which writes the output to a stream by
universe@599 73 * using a write_func.
universe@599 74 *
universe@599 75 * @param stream the stream the data is written to
universe@599 76 * @param wfc the write function
universe@599 77 * @param fmt format string
universe@599 78 * @param ap argument list
universe@599 79 * @return the total number of bytes written
universe@599 80 * @see cx_fprintf()
universe@599 81 */
universe@635 82 __attribute__((__nonnull__))
universe@635 83 int cx_vfprintf(
universe@635 84 void *stream,
universe@635 85 cx_write_func wfc,
universe@635 86 char const *fmt,
universe@635 87 va_list ap
universe@635 88 );
universe@599 89
universe@599 90 /**
universe@599 91 * A \c asprintf like function which allocates space for a string
universe@599 92 * the result is written to.
universe@599 93 *
universe@599 94 * \note The resulting string is guaranteed to be zero-terminated.
universe@599 95 *
universe@599 96 * @param allocator the CxAllocator used for allocating the string
universe@599 97 * @param fmt format string
universe@599 98 * @param ... additional arguments
universe@599 99 * @return the formatted string
universe@599 100 * @see cx_strfree_a()
universe@599 101 */
universe@635 102 __attribute__((__nonnull__(1, 2), __format__(printf, 2, 3)))
universe@635 103 cxmutstr cx_asprintf_a(
universe@693 104 CxAllocator const *allocator,
universe@635 105 char const *fmt,
universe@635 106 ...
universe@635 107 );
universe@599 108
universe@599 109 /**
universe@599 110 * A \c asprintf like function which allocates space for a string
universe@599 111 * the result is written to.
universe@599 112 *
universe@599 113 * \note The resulting string is guaranteed to be zero-terminated.
universe@599 114 *
universe@599 115 * @param fmt format string
universe@599 116 * @param ... additional arguments
universe@599 117 * @return the formatted string
universe@599 118 * @see cx_strfree()
universe@599 119 */
universe@599 120 #define cx_asprintf(fmt, ...) \
universe@599 121 cx_asprintf_a(cxDefaultAllocator, fmt, __VA_ARGS__)
universe@599 122
universe@599 123 /**
universe@599 124 * A \c vasprintf like function which allocates space for a string
universe@599 125 * the result is written to.
universe@599 126 *
universe@599 127 * \note The resulting string is guaranteed to be zero-terminated.
universe@599 128 *
universe@599 129 * @param allocator the CxAllocator used for allocating the string
universe@599 130 * @param fmt format string
universe@599 131 * @param ap argument list
universe@599 132 * @return the formatted string
universe@599 133 * @see cx_asprintf_a()
universe@599 134 */
universe@635 135 __attribute__((__nonnull__))
universe@635 136 cxmutstr cx_vasprintf_a(
universe@693 137 CxAllocator const *allocator,
universe@635 138 char const *fmt,
universe@635 139 va_list ap
universe@635 140 );
universe@599 141
universe@599 142 /**
universe@599 143 * A \c vasprintf like function which allocates space for a string
universe@599 144 * the result is written to.
universe@599 145 *
universe@599 146 * \note The resulting string is guaranteed to be zero-terminated.
universe@599 147 *
universe@599 148 * @param fmt format string
universe@599 149 * @param ap argument list
universe@599 150 * @return the formatted string
universe@599 151 * @see cx_asprintf()
universe@599 152 */
universe@599 153 #define cx_vasprintf(fmt, ap) cx_vasprintf_a(cxDefaultAllocator, fmt, ap)
universe@599 154
universe@599 155 /**
universe@599 156 * A \c printf like function which writes the output to a CxBuffer.
universe@599 157 *
universe@635 158 * @param buffer a pointer to the buffer the data is written to
universe@599 159 * @param fmt the format string
universe@599 160 * @param ... additional arguments
universe@599 161 * @return the total number of bytes written
universe@599 162 * @see ucx_fprintf()
universe@599 163 */
universe@599 164 #define cx_bprintf(buffer, fmt, ...) cx_fprintf((CxBuffer*)buffer, \
universe@599 165 (cx_write_func) cxBufferWrite, fmt, __VA_ARGS__)
universe@599 166
universe@810 167
universe@810 168 /**
universe@810 169 * An \c sprintf like function which reallocates the string when the buffer is not large enough.
universe@810 170 *
universe@810 171 * \note The resulting string is guaranteed to be zero-terminated.
universe@810 172 * That means, when the buffer needed to be reallocated, the new size of the buffer will be
universe@810 173 * the length returned by this function plus one.
universe@810 174 *
universe@810 175 * @param str a pointer to the string buffer
universe@810 176 * @param len the current length of the buffer
universe@810 177 * @param fmt the format string
universe@810 178 * @param ... additional arguments
universe@810 179 * @return the length of produced string
universe@810 180 */
universe@810 181 #define cx_sprintf(str, len, fmt, ...) cx_sprintf_a(cxDefaultAllocator, str, len, fmt, __VA_ARGS__)
universe@810 182
universe@810 183 /**
universe@810 184 * An \c sprintf like function which reallocates the string when the buffer is not large enough.
universe@810 185 *
universe@810 186 * \note The resulting string is guaranteed to be zero-terminated.
universe@810 187 * That means, when the buffer needed to be reallocated, the new size of the buffer will be
universe@810 188 * the length returned by this function plus one.
universe@810 189 *
universe@810 190 * \attention The original buffer MUST have been allocated with the same allocator!
universe@810 191 *
universe@810 192 * @param alloc the allocator to use
universe@810 193 * @param str a pointer to the string buffer
universe@810 194 * @param len the current length of the buffer
universe@810 195 * @param fmt the format string
universe@810 196 * @param ... additional arguments
universe@810 197 * @return the length of produced string
universe@810 198 */
universe@810 199 __attribute__((__nonnull__(1, 2, 4), __format__(printf, 4, 5)))
universe@810 200 int cx_sprintf_a(CxAllocator *alloc, char **str, size_t len, const char *fmt, ... );
universe@810 201
universe@810 202
universe@810 203 /**
universe@810 204 * An \c sprintf like function which reallocates the string when the buffer is not large enough.
universe@810 205 *
universe@810 206 * \note The resulting string is guaranteed to be zero-terminated.
universe@810 207 * That means, when the buffer needed to be reallocated, the new size of the buffer will be
universe@810 208 * the length returned by this function plus one.
universe@810 209 *
universe@810 210 * @param str a pointer to the string buffer
universe@810 211 * @param len the current length of the buffer
universe@810 212 * @param fmt the format string
universe@810 213 * @param ap argument list
universe@810 214 * @return the length of produced string
universe@810 215 */
universe@810 216 #define cx_vsprintf(str, len, fmt, ap) cx_vsprintf_a(cxDefaultAllocator, str, len, fmt, ap)
universe@810 217
universe@810 218 /**
universe@810 219 * An \c sprintf like function which reallocates the string when the buffer is not large enough.
universe@810 220 *
universe@810 221 * \note The resulting string is guaranteed to be zero-terminated.
universe@810 222 * That means, when the buffer needed to be reallocated, the new size of the buffer will be
universe@810 223 * the length returned by this function plus one.
universe@810 224 *
universe@810 225 * \attention The original buffer MUST have been allocated with the same allocator!
universe@810 226 *
universe@810 227 * @param alloc the allocator to use
universe@810 228 * @param str a pointer to the string buffer
universe@810 229 * @param len the current length of the buffer
universe@810 230 * @param fmt the format string
universe@810 231 * @param ap argument list
universe@810 232 * @return the length of produced string
universe@810 233 */
universe@810 234 __attribute__((__nonnull__))
universe@810 235 int cx_vsprintf_a(CxAllocator *alloc, char **str, size_t len, const char *fmt, va_list ap);
universe@810 236
universe@810 237
universe@810 238 /**
universe@810 239 * An \c sprintf like function which allocates a new string when the buffer is not large enough.
universe@810 240 *
universe@810 241 * The location of the resulting string will \em always be stored to \p str. When the buffer
universe@810 242 * was sufficiently large, \p buf itself will be stored to the location of \p str.
universe@810 243 *
universe@810 244 * \note The resulting string is guaranteed to be zero-terminated.
universe@810 245 * That means, when the buffer needed to be reallocated, the new size of the buffer will be
universe@810 246 * the length returned by this function plus one.
universe@810 247 *
universe@810 248 * \remark When a new string needed to be allocated, the contents of \p buf will be
universe@810 249 * poisoned after the call, because this function tries to produce the string in \p buf, first.
universe@810 250 *
universe@810 251 * @param buf a pointer to the buffer
universe@810 252 * @param len the length of the buffer
universe@810 253 * @param str a pointer to the location
universe@810 254 * @param fmt the format string
universe@810 255 * @param ... additional arguments
universe@810 256 * @return the length of produced string
universe@810 257 */
universe@810 258 #define cx_sprintf_s(buf, len, str, fmt, ...) cx_sprintf_sa(cxDefaultAllocator, buf, len, str, fmt, __VA_ARGS__)
universe@810 259
universe@810 260 /**
universe@810 261 * An \c sprintf like function which allocates a new string when the buffer is not large enough.
universe@810 262 *
universe@810 263 * The location of the resulting string will \em always be stored to \p str. When the buffer
universe@810 264 * was sufficiently large, \p buf itself will be stored to the location of \p str.
universe@810 265 *
universe@810 266 * \note The resulting string is guaranteed to be zero-terminated.
universe@810 267 * That means, when the buffer needed to be reallocated, the new size of the buffer will be
universe@810 268 * the length returned by this function plus one.
universe@810 269 *
universe@810 270 * \remark When a new string needed to be allocated, the contents of \p buf will be
universe@810 271 * poisoned after the call, because this function tries to produce the string in \p buf, first.
universe@810 272 *
universe@810 273 * @param alloc the allocator to use
universe@810 274 * @param buf a pointer to the buffer
universe@810 275 * @param len the length of the buffer
universe@810 276 * @param str a pointer to the location
universe@810 277 * @param fmt the format string
universe@810 278 * @param ... additional arguments
universe@810 279 * @return the length of produced string
universe@810 280 */
universe@810 281 __attribute__((__nonnull__(1, 2, 4, 5), __format__(printf, 5, 6)))
universe@810 282 int cx_sprintf_sa(CxAllocator *alloc, char *buf, size_t len, char **str, const char *fmt, ... );
universe@810 283
universe@810 284 /**
universe@810 285 * An \c sprintf like function which allocates a new string when the buffer is not large enough.
universe@810 286 *
universe@810 287 * The location of the resulting string will \em always be stored to \p str. When the buffer
universe@810 288 * was sufficiently large, \p buf itself will be stored to the location of \p str.
universe@810 289 *
universe@810 290 * \note The resulting string is guaranteed to be zero-terminated.
universe@810 291 * That means, when the buffer needed to be reallocated, the new size of the buffer will be
universe@810 292 * the length returned by this function plus one.
universe@810 293 *
universe@810 294 * \remark When a new string needed to be allocated, the contents of \p buf will be
universe@810 295 * poisoned after the call, because this function tries to produce the string in \p buf, first.
universe@810 296 *
universe@810 297 * @param buf a pointer to the buffer
universe@810 298 * @param len the length of the buffer
universe@810 299 * @param str a pointer to the location
universe@810 300 * @param fmt the format string
universe@810 301 * @param ap argument list
universe@810 302 * @return the length of produced string
universe@810 303 */
universe@810 304 #define cx_vsprintf_s(buf, len, str, fmt, ap) cx_vsprintf_sa(cxDefaultAllocator, buf, len, str, fmt, ap)
universe@810 305
universe@810 306 /**
universe@810 307 * An \c sprintf like function which allocates a new string when the buffer is not large enough.
universe@810 308 *
universe@810 309 * The location of the resulting string will \em always be stored to \p str. When the buffer
universe@810 310 * was sufficiently large, \p buf itself will be stored to the location of \p str.
universe@810 311 *
universe@810 312 * \note The resulting string is guaranteed to be zero-terminated.
universe@810 313 * That means, when the buffer needed to be reallocated, the new size of the buffer will be
universe@810 314 * the length returned by this function plus one.
universe@810 315 *
universe@810 316 * \remark When a new string needed to be allocated, the contents of \p buf will be
universe@810 317 * poisoned after the call, because this function tries to produce the string in \p buf, first.
universe@810 318 *
universe@810 319 * @param alloc the allocator to use
universe@810 320 * @param buf a pointer to the buffer
universe@810 321 * @param len the length of the buffer
universe@810 322 * @param str a pointer to the location
universe@810 323 * @param fmt the format string
universe@810 324 * @param ap argument list
universe@810 325 * @return the length of produced string
universe@810 326 */
universe@810 327 __attribute__((__nonnull__))
universe@810 328 int cx_vsprintf_sa(CxAllocator *alloc, char *buf, size_t len, char **str, const char *fmt, va_list ap);
universe@810 329
universe@810 330
universe@599 331 #ifdef __cplusplus
universe@599 332 } // extern "C"
universe@599 333 #endif
universe@599 334
universe@599 335 #endif //UCX_PRINTF_H

mercurial