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:
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';