ucx/cx/printf.h

changeset 440
7c4b9cba09ca
parent 324
ce13a778654a
--- a/ucx/cx/printf.h	Sun Jan 05 17:41:39 2025 +0100
+++ b/ucx/cx/printf.h	Sun Jan 05 22:00:39 2025 +0100
@@ -26,11 +26,11 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 /**
- * \file printf.h
- * \brief Wrapper for write functions with a printf-like interface.
- * \author Mike Becker
- * \author Olaf Wintermann
- * \copyright 2-Clause BSD License
+ * @file printf.h
+ * @brief Wrapper for write functions with a printf-like interface.
+ * @author Mike Becker
+ * @author Olaf Wintermann
+ * @copyright 2-Clause BSD License
  */
 
 #ifndef UCX_PRINTF_H
@@ -40,6 +40,14 @@
 #include "string.h"
 #include <stdarg.h>
 
+/**
+ * Attribute for printf-like functions.
+ * @param fmt_idx index of the format string parameter
+ * @param arg_idx index of the first formatting argument
+ */
+#define cx_attr_printf(fmt_idx, arg_idx) \
+    __attribute__((__format__(printf, fmt_idx, arg_idx)))
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -48,19 +56,21 @@
 /**
  * The maximum string length that fits into stack memory.
  */
-extern unsigned const cx_printf_sbo_size;
+extern const unsigned cx_printf_sbo_size;
 
 /**
- * A \c fprintf like function which writes the output to a stream by
+ * A @c fprintf like function which writes the output to a stream by
  * using a write_func.
  *
  * @param stream the stream the data is written to
  * @param wfc the write function
  * @param fmt format string
  * @param ... additional arguments
- * @return the total number of bytes written
+ * @return the total number of bytes written or an error code from stdlib printf implementation
  */
-__attribute__((__nonnull__(1, 2, 3), __format__(printf, 3, 4)))
+cx_attr_nonnull_arg(1, 2, 3)
+cx_attr_printf(3, 4)
+cx_attr_cstr_arg(3)
 int cx_fprintf(
         void *stream,
         cx_write_func wfc,
@@ -69,17 +79,18 @@
 );
 
 /**
- * A \c vfprintf like function which writes the output to a stream by
+ * A @c vfprintf like function which writes the output to a stream by
  * using a write_func.
  *
  * @param stream the stream the data is written to
  * @param wfc the write function
  * @param fmt format string
  * @param ap argument list
- * @return the total number of bytes written
+ * @return the total number of bytes written or an error code from stdlib printf implementation
  * @see cx_fprintf()
  */
-__attribute__((__nonnull__))
+cx_attr_nonnull
+cx_attr_cstr_arg(3)
 int cx_vfprintf(
         void *stream,
         cx_write_func wfc,
@@ -88,10 +99,12 @@
 );
 
 /**
- * A \c asprintf like function which allocates space for a string
+ * A @c asprintf like function which allocates space for a string
  * the result is written to.
  *
- * \note The resulting string is guaranteed to be zero-terminated.
+ * @note The resulting string is guaranteed to be zero-terminated,
+ * unless there was an error, in which case the string's pointer
+ * will be @c NULL.
  *
  * @param allocator the CxAllocator used for allocating the string
  * @param fmt format string
@@ -99,7 +112,9 @@
  * @return the formatted string
  * @see cx_strfree_a()
  */
-__attribute__((__nonnull__(1, 2), __format__(printf, 2, 3)))
+cx_attr_nonnull_arg(1, 2)
+cx_attr_printf(2, 3)
+cx_attr_cstr_arg(2)
 cxmutstr cx_asprintf_a(
         const CxAllocator *allocator,
         const char *fmt,
@@ -107,24 +122,28 @@
 );
 
 /**
- * A \c asprintf like function which allocates space for a string
+ * A @c asprintf like function which allocates space for a string
  * the result is written to.
  *
- * \note The resulting string is guaranteed to be zero-terminated.
+ * @note The resulting string is guaranteed to be zero-terminated,
+ * unless there was an error, in which case the string's pointer
+ * will be @c NULL.
  *
- * @param fmt format string
+ * @param fmt (@c char*) format string
  * @param ... additional arguments
- * @return the formatted string
+ * @return (@c cxmutstr) the formatted string
  * @see cx_strfree()
  */
 #define cx_asprintf(fmt, ...) \
     cx_asprintf_a(cxDefaultAllocator, fmt, __VA_ARGS__)
 
 /**
-* A \c vasprintf like function which allocates space for a string
+* A @c vasprintf like function which allocates space for a string
  * the result is written to.
  *
- * \note The resulting string is guaranteed to be zero-terminated.
+ * @note The resulting string is guaranteed to be zero-terminated,
+ * unless there was an error, in which case the string's pointer
+ * will be @c NULL.
  *
  * @param allocator the CxAllocator used for allocating the string
  * @param fmt format string
@@ -132,7 +151,8 @@
  * @return the formatted string
  * @see cx_asprintf_a()
  */
-__attribute__((__nonnull__))
+cx_attr_nonnull
+cx_attr_cstr_arg(2)
 cxmutstr cx_vasprintf_a(
         const CxAllocator *allocator,
         const char *fmt,
@@ -140,192 +160,232 @@
 );
 
 /**
-* A \c vasprintf like function which allocates space for a string
+* A @c vasprintf like function which allocates space for a string
  * the result is written to.
  *
- * \note The resulting string is guaranteed to be zero-terminated.
+ * @note The resulting string is guaranteed to be zero-terminated,
+ * unless there was in error, in which case the string's pointer
+ * will be @c NULL.
  *
- * @param fmt format string
- * @param ap argument list
- * @return the formatted string
+ * @param fmt (@c char*) format string
+ * @param ap (@c va_list) argument list
+ * @return (@c cxmutstr) the formatted string
  * @see cx_asprintf()
  */
 #define cx_vasprintf(fmt, ap) cx_vasprintf_a(cxDefaultAllocator, fmt, ap)
 
 /**
- * A \c printf like function which writes the output to a CxBuffer.
+ * A @c printf like function which writes the output to a CxBuffer.
  *
- * @param buffer a pointer to the buffer the data is written to
- * @param fmt the format string
+ * @param buffer (@c CxBuffer*) a pointer to the buffer the data is written to
+ * @param fmt (@c char*) the format string
  * @param ... additional arguments
- * @return the total number of bytes written
- * @see ucx_fprintf()
+ * @return (@c int) the total number of bytes written or an error code from stdlib printf implementation
+ * @see cx_fprintf()
+ * @see cxBufferWrite()
  */
-#define cx_bprintf(buffer, fmt, ...) cx_fprintf((CxBuffer*)buffer, \
+#define cx_bprintf(buffer, fmt, ...) cx_fprintf((void*)buffer, \
     (cx_write_func) cxBufferWrite, fmt, __VA_ARGS__)
 
 
 /**
- * An \c sprintf like function which reallocates the string when the buffer is not large enough.
+ * An @c sprintf like function which reallocates the string when the buffer is not large enough.
  *
- * The size of the buffer will be updated in \p len when necessary.
+ * The size of the buffer will be updated in @p len when necessary.
  *
- * \note The resulting string is guaranteed to be zero-terminated.
+ * @note The resulting string, if successful, is guaranteed to be zero-terminated.
  *
- * @param str a pointer to the string buffer
- * @param len a pointer to the length of the buffer
- * @param fmt the format string
+ * @param str (@c char**) a pointer to the string buffer
+ * @param len (@c size_t*) a pointer to the length of the buffer
+ * @param fmt (@c char*) the format string
  * @param ... additional arguments
- * @return the length of produced string
+ * @return (@c int) the length of produced string or an error code from stdlib printf implementation
  */
 #define cx_sprintf(str, len, fmt, ...) cx_sprintf_a(cxDefaultAllocator, str, len, fmt, __VA_ARGS__)
 
 /**
- * An \c sprintf like function which reallocates the string when the buffer is not large enough.
+ * An @c sprintf like function which reallocates the string when the buffer is not large enough.
  *
- * The size of the buffer will be updated in \p len when necessary.
+ * The size of the buffer will be updated in @p len when necessary.
  *
- * \note The resulting string is guaranteed to be zero-terminated.
+ * @note The resulting string, if successful, is guaranteed to be zero-terminated.
  *
- * \attention The original buffer MUST have been allocated with the same allocator!
+ * @attention The original buffer MUST have been allocated with the same allocator!
  *
  * @param alloc the allocator to use
  * @param str a pointer to the string buffer
  * @param len a pointer to the length of the buffer
  * @param fmt the format string
  * @param ... additional arguments
- * @return the length of produced string
+ * @return the length of produced string or an error code from stdlib printf implementation
  */
-__attribute__((__nonnull__(1, 2, 3, 4), __format__(printf, 4, 5)))
-int cx_sprintf_a(CxAllocator *alloc, char **str, size_t *len, const char *fmt, ... );
+cx_attr_nonnull_arg(1, 2, 3, 4)
+cx_attr_printf(4, 5)
+cx_attr_cstr_arg(4)
+int cx_sprintf_a(
+        CxAllocator *alloc,
+        char **str,
+        size_t *len,
+        const char *fmt,
+        ...
+);
 
 
 /**
- * An \c sprintf like function which reallocates the string when the buffer is not large enough.
+ * An @c sprintf like function which reallocates the string when the buffer is not large enough.
  *
- * The size of the buffer will be updated in \p len when necessary.
+ * The size of the buffer will be updated in @p len when necessary.
  *
- * \note The resulting string is guaranteed to be zero-terminated.
+ * @note The resulting string, if successful, is guaranteed to be zero-terminated.
  *
- * @param str a pointer to the string buffer
- * @param len a pointer to the length of the buffer
- * @param fmt the format string
- * @param ap argument list
- * @return the length of produced string
+ * @param str (@c char**) a pointer to the string buffer
+ * @param len (@c size_t*) a pointer to the length of the buffer
+ * @param fmt (@c char*) the format string
+ * @param ap (@c va_list) argument list
+ * @return (@c int) the length of produced string or an error code from stdlib printf implementation
  */
 #define cx_vsprintf(str, len, fmt, ap) cx_vsprintf_a(cxDefaultAllocator, str, len, fmt, ap)
 
 /**
- * An \c sprintf like function which reallocates the string when the buffer is not large enough.
+ * An @c sprintf like function which reallocates the string when the buffer is not large enough.
  *
- * The size of the buffer will be updated in \p len when necessary.
+ * The size of the buffer will be updated in @p len when necessary.
  *
- * \note The resulting string is guaranteed to be zero-terminated.
+ * @note The resulting string is guaranteed to be zero-terminated.
  *
- * \attention The original buffer MUST have been allocated with the same allocator!
+ * @attention The original buffer MUST have been allocated with the same allocator!
  *
  * @param alloc the allocator to use
  * @param str a pointer to the string buffer
  * @param len a pointer to the length of the buffer
  * @param fmt the format string
  * @param ap argument list
- * @return the length of produced string
+ * @return the length of produced string or an error code from stdlib printf implementation
  */
-__attribute__((__nonnull__))
-int cx_vsprintf_a(CxAllocator *alloc, char **str, size_t *len, const char *fmt, va_list ap);
+cx_attr_nonnull
+cx_attr_cstr_arg(4)
+cx_attr_access_rw(2)
+cx_attr_access_rw(3)
+int cx_vsprintf_a(
+        CxAllocator *alloc,
+        char **str,
+        size_t *len,
+        const char *fmt,
+        va_list ap
+);
 
 
 /**
- * An \c sprintf like function which allocates a new string when the buffer is not large enough.
+ * An @c sprintf like function which allocates a new string when the buffer is not large enough.
  *
- * The size of the buffer will be updated in \p len when necessary.
+ * The size of the buffer will be updated in @p len when necessary.
  *
- * The location of the resulting string will \em always be stored to \p str. When the buffer
- * was sufficiently large, \p buf itself will be stored to the location of \p str.
+ * The location of the resulting string will @em always be stored to @p str. When the buffer
+ * was sufficiently large, @p buf itself will be stored to the location of @p str.
  *
- * \note The resulting string is guaranteed to be zero-terminated.
+ * @note The resulting string, if successful, is guaranteed to be zero-terminated.
  * 
- * \remark When a new string needed to be allocated, the contents of \p buf will be
- * poisoned after the call, because this function tries to produce the string in \p buf, first.
+ * @remark When a new string needed to be allocated, the contents of @p buf will be
+ * poisoned after the call, because this function tries to produce the string in @p buf, first.
  *
- * @param buf a pointer to the buffer
- * @param len a pointer to the length of the buffer
- * @param str a pointer to the location
- * @param fmt the format string
+ * @param buf (@c char*) a pointer to the buffer
+ * @param len (@c size_t*) a pointer to the length of the buffer
+ * @param str (@c char**) a pointer where the location of the result shall be stored
+ * @param fmt (@c char*) the format string
  * @param ... additional arguments
- * @return the length of produced string
+ * @return (@c int) the length of produced string or an error code from stdlib printf implementation
  */
 #define cx_sprintf_s(buf, len, str, fmt, ...) cx_sprintf_sa(cxDefaultAllocator, buf, len, str, fmt, __VA_ARGS__)
 
 /**
- * An \c sprintf like function which allocates a new string when the buffer is not large enough.
+ * An @c sprintf like function which allocates a new string when the buffer is not large enough.
  *
- * The size of the buffer will be updated in \p len when necessary.
+ * The size of the buffer will be updated in @p len when necessary.
  *
- * The location of the resulting string will \em always be stored to \p str. When the buffer
- * was sufficiently large, \p buf itself will be stored to the location of \p str.
+ * The location of the resulting string will @em always be stored to @p str. When the buffer
+ * was sufficiently large, @p buf itself will be stored to the location of @p str.
  *
- * \note The resulting string is guaranteed to be zero-terminated.
+ * @note The resulting string, if successful, is guaranteed to be zero-terminated.
  *
- * \remark When a new string needed to be allocated, the contents of \p buf will be
- * poisoned after the call, because this function tries to produce the string in \p buf, first.
+ * @remark When a new string needed to be allocated, the contents of @p buf will be
+ * poisoned after the call, because this function tries to produce the string in @p buf, first.
  *
  * @param alloc the allocator to use
  * @param buf a pointer to the buffer
  * @param len a pointer to the length of the buffer
- * @param str a pointer to the location
+ * @param str a pointer where the location of the result shall be stored
  * @param fmt the format string
  * @param ... additional arguments
- * @return the length of produced string
+ * @return the length of produced string or an error code from stdlib printf implementation
  */
-__attribute__((__nonnull__(1, 2, 4, 5), __format__(printf, 5, 6)))
-int cx_sprintf_sa(CxAllocator *alloc, char *buf, size_t *len, char **str, const char *fmt, ... );
+cx_attr_nonnull_arg(1, 2, 4, 5)
+cx_attr_printf(5, 6)
+cx_attr_cstr_arg(5)
+cx_attr_access_rw(2)
+cx_attr_access_rw(3)
+cx_attr_access_rw(4)
+int cx_sprintf_sa(
+        CxAllocator *alloc,
+        char *buf,
+        size_t *len,
+        char **str,
+        const char *fmt,
+        ...
+);
 
 /**
- * An \c sprintf like function which allocates a new string when the buffer is not large enough.
+ * An @c sprintf like function which allocates a new string when the buffer is not large enough.
  *
- * The size of the buffer will be updated in \p len when necessary.
+ * The size of the buffer will be updated in @p len when necessary.
  *
- * The location of the resulting string will \em always be stored to \p str. When the buffer
- * was sufficiently large, \p buf itself will be stored to the location of \p str.
+ * The location of the resulting string will @em always be stored to @p str. When the buffer
+ * was sufficiently large, @p buf itself will be stored to the location of @p str.
  *
- * \note The resulting string is guaranteed to be zero-terminated.
+ * @note The resulting string is guaranteed to be zero-terminated.
  *
- * \remark When a new string needed to be allocated, the contents of \p buf will be
- * poisoned after the call, because this function tries to produce the string in \p buf, first.
+ * @remark When a new string needed to be allocated, the contents of @p buf will be
+ * poisoned after the call, because this function tries to produce the string in @p buf, first.
  *
- * @param buf a pointer to the buffer
- * @param len a pointer to the length of the buffer
- * @param str a pointer to the location
- * @param fmt the format string
- * @param ap argument list
- * @return the length of produced string
+ * @param buf (@c char*) a pointer to the buffer
+ * @param len (@c size_t*) a pointer to the length of the buffer
+ * @param str (@c char**) a pointer where the location of the result shall be stored
+ * @param fmt (@c char*) the format string
+ * @param ap (@c va_list) argument list
+ * @return (@c int) the length of produced string or an error code from stdlib printf implementation
  */
 #define cx_vsprintf_s(buf, len, str, fmt, ap) cx_vsprintf_sa(cxDefaultAllocator, buf, len, str, fmt, ap)
 
 /**
- * An \c sprintf like function which allocates a new string when the buffer is not large enough.
+ * An @c sprintf like function which allocates a new string when the buffer is not large enough.
  *
- * The size of the buffer will be updated in \p len when necessary.
+ * The size of the buffer will be updated in @p len when necessary.
  *
- * The location of the resulting string will \em always be stored to \p str. When the buffer
- * was sufficiently large, \p buf itself will be stored to the location of \p str.
+ * The location of the resulting string will @em always be stored to @p str. When the buffer
+ * was sufficiently large, @p buf itself will be stored to the location of @p str.
  *
- * \note The resulting string is guaranteed to be zero-terminated.
+ * @note The resulting string is guaranteed to be zero-terminated.
  *
- * \remark When a new string needed to be allocated, the contents of \p buf will be
- * poisoned after the call, because this function tries to produce the string in \p buf, first.
+ * @remark When a new string needed to be allocated, the contents of @p buf will be
+ * poisoned after the call, because this function tries to produce the string in @p buf, first.
  *
  * @param alloc the allocator to use
  * @param buf a pointer to the buffer
  * @param len a pointer to the length of the buffer
- * @param str a pointer to the location
+ * @param str a pointer where the location of the result shall be stored
  * @param fmt the format string
  * @param ap argument list
- * @return the length of produced string
+ * @return the length of produced string or an error code from stdlib printf implementation
  */
-__attribute__((__nonnull__))
-int cx_vsprintf_sa(CxAllocator *alloc, char *buf, size_t *len, char **str, const char *fmt, va_list ap);
+cx_attr_nonnull
+cx_attr_cstr_arg(5)
+int cx_vsprintf_sa(
+        CxAllocator *alloc,
+        char *buf,
+        size_t *len,
+        char **str,
+        const char *fmt,
+        va_list ap
+);
 
 
 #ifdef __cplusplus

mercurial