Sat, 05 Nov 2022 17:17:17 +0100
#222 add printf-like functions
src/CMakeLists.txt | file | annotate | diff | comparison | revisions | |
src/cx/printf.h | file | annotate | diff | comparison | revisions | |
src/printf.c | file | annotate | diff | comparison | revisions |
1.1 --- a/src/CMakeLists.txt Sun Oct 23 17:02:07 2022 +0200 1.2 +++ b/src/CMakeLists.txt Sat Nov 05 17:17:17 2022 +0100 1.3 @@ -9,6 +9,7 @@ 1.4 hash_key.c 1.5 hash_map.c 1.6 basic_mempool.c 1.7 + printf.c 1.8 ) 1.9 set(headers 1.10 cx/common.h 1.11 @@ -25,6 +26,7 @@ 1.12 cx/hash_map.h 1.13 cx/mempool.h 1.14 cx/basic_mempool.h 1.15 + cx/printf.h 1.16 ) 1.17 1.18 add_library(ucx SHARED ${sources})
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/cx/printf.h Sat Nov 05 17:17:17 2022 +0100 2.3 @@ -0,0 +1,144 @@ 2.4 +/* 2.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 2.6 + * 2.7 + * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. 2.8 + * 2.9 + * Redistribution and use in source and binary forms, with or without 2.10 + * modification, are permitted provided that the following conditions are met: 2.11 + * 2.12 + * 1. Redistributions of source code must retain the above copyright 2.13 + * notice, this list of conditions and the following disclaimer. 2.14 + * 2.15 + * 2. Redistributions in binary form must reproduce the above copyright 2.16 + * notice, this list of conditions and the following disclaimer in the 2.17 + * documentation and/or other materials provided with the distribution. 2.18 + * 2.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2.29 + * POSSIBILITY OF SUCH DAMAGE. 2.30 + */ 2.31 +/** 2.32 + * \file printf.h 2.33 + * \brief Wrapper for write functions with a printf-like interface. 2.34 + * \author Mike Becker 2.35 + * \author Olaf Wintermann 2.36 + * \version 3.0 2.37 + * \copyright 2-Clause BSD License 2.38 + */ 2.39 + 2.40 +#ifndef UCX_PRINTF_H 2.41 +#define UCX_PRINTF_H 2.42 + 2.43 +#include "common.h" 2.44 +#include "string.h" 2.45 +#include <stdarg.h> 2.46 + 2.47 +#ifdef __cplusplus 2.48 +extern "C" { 2.49 +#endif 2.50 + 2.51 +/** 2.52 + * A \c fprintf like function which writes the output to a stream by 2.53 + * using a write_func. 2.54 + * 2.55 + * @param stream the stream the data is written to 2.56 + * @param wfc the write function 2.57 + * @param fmt format string 2.58 + * @param ... additional arguments 2.59 + * @return the total number of bytes written 2.60 + */ 2.61 +int cx_fprintf(void *stream, cx_write_func wfc, char const *fmt, ...); 2.62 + 2.63 +/** 2.64 + * A \c vfprintf like function which writes the output to a stream by 2.65 + * using a write_func. 2.66 + * 2.67 + * @param stream the stream the data is written to 2.68 + * @param wfc the write function 2.69 + * @param fmt format string 2.70 + * @param ap argument list 2.71 + * @return the total number of bytes written 2.72 + * @see cx_fprintf() 2.73 + */ 2.74 +int cx_vfprintf(void *stream, cx_write_func wfc, char const *fmt, va_list ap); 2.75 + 2.76 +/** 2.77 + * A \c asprintf like function which allocates space for a string 2.78 + * the result is written to. 2.79 + * 2.80 + * \note The resulting string is guaranteed to be zero-terminated. 2.81 + * 2.82 + * @param allocator the CxAllocator used for allocating the string 2.83 + * @param fmt format string 2.84 + * @param ... additional arguments 2.85 + * @return the formatted string 2.86 + * @see cx_strfree_a() 2.87 + */ 2.88 +cxmutstr cx_asprintf_a(CxAllocator *allocator, char const *fmt, ...); 2.89 + 2.90 +/** 2.91 + * A \c asprintf like function which allocates space for a string 2.92 + * the result is written to. 2.93 + * 2.94 + * \note The resulting string is guaranteed to be zero-terminated. 2.95 + * 2.96 + * @param fmt format string 2.97 + * @param ... additional arguments 2.98 + * @return the formatted string 2.99 + * @see cx_strfree() 2.100 + */ 2.101 +#define cx_asprintf(fmt, ...) \ 2.102 + cx_asprintf_a(cxDefaultAllocator, fmt, __VA_ARGS__) 2.103 + 2.104 +/** 2.105 +* A \c vasprintf like function which allocates space for a string 2.106 + * the result is written to. 2.107 + * 2.108 + * \note The resulting string is guaranteed to be zero-terminated. 2.109 + * 2.110 + * @param allocator the CxAllocator used for allocating the string 2.111 + * @param fmt format string 2.112 + * @param ap argument list 2.113 + * @return the formatted string 2.114 + * @see cx_asprintf_a() 2.115 + */ 2.116 +cxmutstr cx_vasprintf_a(CxAllocator *allocator, char const *fmt, va_list ap); 2.117 + 2.118 +/** 2.119 +* A \c vasprintf like function which allocates space for a string 2.120 + * the result is written to. 2.121 + * 2.122 + * \note The resulting string is guaranteed to be zero-terminated. 2.123 + * 2.124 + * @param fmt format string 2.125 + * @param ap argument list 2.126 + * @return the formatted string 2.127 + * @see cx_asprintf() 2.128 + */ 2.129 +#define cx_vasprintf(fmt, ap) cx_vasprintf_a(cxDefaultAllocator, fmt, ap) 2.130 + 2.131 +/** 2.132 + * A \c printf like function which writes the output to a CxBuffer. 2.133 + * 2.134 + * @param buffer the buffer the data is written to 2.135 + * @param fmt the format string 2.136 + * @param ... additional arguments 2.137 + * @return the total number of bytes written 2.138 + * @see ucx_fprintf() 2.139 + */ 2.140 +#define cx_bprintf(buffer, fmt, ...) cx_fprintf((CxBuffer*)buffer, \ 2.141 + (cx_write_func) cxBufferWrite, fmt, __VA_ARGS__) 2.142 + 2.143 +#ifdef __cplusplus 2.144 +} // extern "C" 2.145 +#endif 2.146 + 2.147 +#endif //UCX_PRINTF_H
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/printf.c Sat Nov 05 17:17:17 2022 +0100 3.3 @@ -0,0 +1,109 @@ 3.4 +/* 3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3.6 + * 3.7 + * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. 3.8 + * 3.9 + * Redistribution and use in source and binary forms, with or without 3.10 + * modification, are permitted provided that the following conditions are met: 3.11 + * 3.12 + * 1. Redistributions of source code must retain the above copyright 3.13 + * notice, this list of conditions and the following disclaimer. 3.14 + * 3.15 + * 2. Redistributions in binary form must reproduce the above copyright 3.16 + * notice, this list of conditions and the following disclaimer in the 3.17 + * documentation and/or other materials provided with the distribution. 3.18 + * 3.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 3.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 3.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 3.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3.29 + * POSSIBILITY OF SUCH DAMAGE. 3.30 + */ 3.31 + 3.32 +#include "cx/printf.h" 3.33 + 3.34 +#include <stdio.h> 3.35 +#include <string.h> 3.36 + 3.37 +#define UCX_PRINTF_BUFSIZE 256 3.38 + 3.39 +int cx_fprintf(void *stream, cx_write_func wfc, const char *fmt, ...) { 3.40 + int ret; 3.41 + va_list ap; 3.42 + va_start(ap, fmt); 3.43 + ret = cx_vfprintf(stream, wfc, fmt, ap); 3.44 + va_end(ap); 3.45 + return ret; 3.46 +} 3.47 + 3.48 +int cx_vfprintf(void *stream, cx_write_func wfc, const char *fmt, va_list ap) { 3.49 + char buf[UCX_PRINTF_BUFSIZE]; 3.50 + va_list ap2; 3.51 + va_copy(ap2, ap); 3.52 + int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap); 3.53 + if (ret < 0) { 3.54 + return ret; 3.55 + } else if (ret < UCX_PRINTF_BUFSIZE) { 3.56 + return (int) wfc(buf, 1, ret, stream); 3.57 + } else { 3.58 + int len = ret + 1; 3.59 + char *newbuf = malloc(len); 3.60 + if (!newbuf) { 3.61 + return -1; 3.62 + } 3.63 + 3.64 + ret = vsnprintf(newbuf, len, fmt, ap2); 3.65 + if (ret > 0) { 3.66 + ret = (int) wfc(newbuf, 1, ret, stream); 3.67 + } 3.68 + free(newbuf); 3.69 + } 3.70 + return ret; 3.71 +} 3.72 + 3.73 +cxmutstr cx_asprintf_a(CxAllocator *allocator, const char *fmt, ...) { 3.74 + va_list ap; 3.75 + cxmutstr ret; 3.76 + va_start(ap, fmt); 3.77 + ret = cx_vasprintf_a(allocator, fmt, ap); 3.78 + va_end(ap); 3.79 + return ret; 3.80 +} 3.81 + 3.82 +cxmutstr cx_vasprintf_a(CxAllocator *a, const char *fmt, va_list ap) { 3.83 + cxmutstr s; 3.84 + s.ptr = NULL; 3.85 + s.length = 0; 3.86 + char buf[UCX_PRINTF_BUFSIZE]; 3.87 + va_list ap2; 3.88 + va_copy(ap2, ap); 3.89 + int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap); 3.90 + if (ret > 0 && ret < UCX_PRINTF_BUFSIZE) { 3.91 + s.ptr = cxMalloc(a, ret + 1); 3.92 + if (s.ptr) { 3.93 + s.length = (size_t) ret; 3.94 + memcpy(s.ptr, buf, ret); 3.95 + s.ptr[s.length] = '\0'; 3.96 + } 3.97 + } else { 3.98 + int len = ret + 1; 3.99 + s.ptr = cxMalloc(a, len); 3.100 + if (s.ptr) { 3.101 + ret = vsnprintf(s.ptr, len, fmt, ap2); 3.102 + if (ret < 0) { 3.103 + free(s.ptr); 3.104 + s.ptr = NULL; 3.105 + } else { 3.106 + s.length = (size_t) ret; 3.107 + } 3.108 + } 3.109 + } 3.110 + return s; 3.111 +} 3.112 +