rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

commit 99fe39ccd3388bf966db0f8b6c03f349c641b5b6
parent 8502b22b8ec0bf65595190a8dfb8d8f8f4afa6e5
Author: vaplv <vaplv@free.fr>
Date:   Mon,  6 Jul 2020 11:39:30 +0200

Merge branch 'release_0.9.1'

Diffstat:
MREADME.md | 8++++++++
Mcmake/CMakeLists.txt | 2+-
Msrc/rsys.h | 6++++--
Msrc/str.c | 34+++++++++++++++++++++++++++++++++-
Msrc/str.h | 10++++++++++
Msrc/test_str.c | 11+++++++++++
6 files changed, 67 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md @@ -17,6 +17,14 @@ project can be now edited, built, tested and installed as any CMake project. ## Release notes +### Version 0.9.1 + +- Add the `VFATAL` macro that works as the regular `FATAL` macro but with an + additional variadic argument allowing to format the displayed error message + as in `printf`. +- Add the `str_printf` function to the string API: it sets the string content + with the data formatted wrt the `printf` syntax. + ### Version 0.9 - Add the text reader API. A text reader reads lines from a text stream. In diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -39,7 +39,7 @@ include(rcmake) ################################################################################ set(VERSION_MAJOR 0) set(VERSION_MINOR 9) -set(VERSION_PATCH 0) +set(VERSION_PATCH 1) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set(RSYS_FILES_SRC diff --git a/src/rsys.h b/src/rsys.h @@ -220,13 +220,15 @@ [1 - 2*(!(Cond))]; #endif -#define FATAL(Msg) \ +#define VFATAL(Fmt, Args) \ { \ - fprintf(stderr, Msg); \ + fprintf(stderr, Fmt COMMA_##Args LIST_##Args); \ ASSERT(0); \ abort(); \ } (void)0 +#define FATAL(Msg) VFATAL(Msg, ARG0()) + #define CHK(Cond) \ { \ if(!(Cond)) \ diff --git a/src/str.c b/src/str.c @@ -13,7 +13,11 @@ * You should have received a copy of the GNU Lesser General Public License * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ +#define _POSIX_C_SOURCE 200112L /* vsnprintf support */ +#include "io_c99.h" #include "str.h" + +#include <stdarg.h> #include <string.h> /******************************************************************************* @@ -156,7 +160,7 @@ str_append_char(struct str* str, const char ch) { size_t len = 0; res_T res = RES_OK; - ASSERT( str ); + ASSERT(str); if(ch == '\0') return RES_OK; @@ -176,3 +180,31 @@ str_reserve(struct str* str, const size_t capacity) return ensure_allocated(str, capacity / sizeof(char), 1); } + +res_T +str_printf(struct str* str, const char* fmt, ...) +{ + va_list ap; + size_t len; + res_T res = RES_OK; + ASSERT(str && fmt); + + va_start(ap, fmt); + len = (size_t)vsnprintf(str->cstr, str->allocated, fmt, ap); + va_end(ap); + + if(len >= str->allocated) { + res = ensure_allocated(str, len + 1/* Null char */, 0); + if(res != RES_OK) goto error; + + va_start(ap, fmt); + len = (size_t)vsnprintf(str->cstr, str->allocated, fmt, ap); + va_end(ap); + CHK(len < str->allocated); + } + +exit: + return res; +error: + goto exit; +} diff --git a/src/str.h b/src/str.h @@ -105,6 +105,16 @@ RSYS_API res_T str_append(struct str* str, const char* cstr); RSYS_API res_T str_append_char(struct str* str, const char ch); RSYS_API res_T str_reserve(struct str* str, const size_t capacity); +RSYS_API res_T +str_printf + (struct str* str, + const char* fmt, + ...) +#ifdef COMPILER_GCC + __attribute__((format(printf, 2, 3))) +#endif +; + END_DECLS static INLINE res_T diff --git a/src/test_str.c b/src/test_str.c @@ -139,6 +139,17 @@ main(int argc, char** argv) str_release(&str); str_init(&allocator_proxy, &str); + CHK(str_printf(&str, "Hello world!") == RES_OK); + CHK(!strcmp(str_cget(&str), "Hello world!")); + CHK(str_printf(&str, "XARR-QRRC VA GUR QRNQ") == RES_OK); + CHK(!strcmp(str_cget(&str), "XARR-QRRC VA GUR QRNQ")); + CHK(str_printf(&str, "Rcvfbqr %d, GUR FUBERF BS URYY", 2) == RES_OK); + CHK(!strcmp(str_cget(&str), "Rcvfbqr 2, GUR FUBERF BS URYY")); + CHK(str_printf(&str, "%s:%lu:%s", __FILE__, 0xDECAFBADlu,__FILE__) == RES_OK); + CHK(!strcmp(str_cget(&str), __FILE__":3737844653:"__FILE__)); + str_release(&str); + + str_init(&allocator_proxy, &str); CHK(str_set(&str, "abcd") == RES_OK); CHK(str_len(&str) == 4); str_get(&str)[3] = '\0';