aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--doc/apiref.rst10
-rw-r--r--src/jansson.def2
-rw-r--r--src/jansson.h5
-rw-r--r--src/value.c34
-rw-r--r--test/.gitignore3
-rw-r--r--test/suites/api/Makefile.am2
-rw-r--r--test/suites/api/test_sprintf.c22
8 files changed, 78 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7c1082b..310be26 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -496,6 +496,7 @@ if (NOT JANSSON_WITHOUT_TESTS)
test_object
test_pack
test_simple
+ test_sprintf
test_unpack)
# Doing arithmetic on void pointers is not allowed by Microsofts compiler
diff --git a/doc/apiref.rst b/doc/apiref.rst
index 3ad406d..b429d0b 100644
--- a/doc/apiref.rst
+++ b/doc/apiref.rst
@@ -399,6 +399,16 @@ length-aware functions if you wish to embed null bytes in strings.
.. versionadded:: 2.7
+.. function:: json_t *json_sprintf(const char *format, ...)
+ json_t *json_vsprintf(const char *format, va_list ap)
+
+ .. refcounting:: new
+
+ Construct a JSON string from a format string and varargs, just like
+ :func:`printf()`.
+
+ .. versionadded:: 2.11
+
Number
======
diff --git a/src/jansson.def b/src/jansson.def
index cbebefb..15f35c9 100644
--- a/src/jansson.def
+++ b/src/jansson.def
@@ -3,6 +3,8 @@ EXPORTS
json_true
json_false
json_null
+ json_sprintf
+ json_vsprintf
json_string
json_stringn
json_string_nocheck
diff --git a/src/jansson.h b/src/jansson.h
index b17e8f4..82709eb 100644
--- a/src/jansson.h
+++ b/src/jansson.h
@@ -289,6 +289,11 @@ int json_unpack(json_t *root, const char *fmt, ...);
int json_unpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, ...);
int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, va_list ap);
+/* sprintf */
+
+json_t *json_sprintf(const char *fmt, ...);
+json_t *json_vsprintf(const char *fmt, va_list ap);
+
/* equality */
diff --git a/src/value.c b/src/value.c
index d27bb12..b3b3141 100644
--- a/src/value.c
+++ b/src/value.c
@@ -787,6 +787,40 @@ static json_t *json_string_copy(const json_t *string)
return json_stringn_nocheck(s->value, s->length);
}
+json_t *json_vsprintf(const char *fmt, va_list ap) {
+ int length;
+ char *buf;
+ va_list aq;
+ va_copy(aq, ap);
+
+ length = vsnprintf(NULL, 0, fmt, ap);
+ if (length == 0)
+ return json_string("");
+
+ buf = jsonp_malloc(length + 1);
+ if (!buf)
+ return NULL;
+
+ vsnprintf(buf, length + 1, fmt, aq);
+ if (!utf8_check_string(buf, length)) {
+ jsonp_free(buf);
+ return NULL;
+ }
+
+ return jsonp_stringn_nocheck_own(buf, length);
+}
+
+json_t *json_sprintf(const char *fmt, ...) {
+ json_t *result;
+ va_list ap;
+
+ va_start(ap, fmt);
+ result = json_vsprintf(fmt, ap);
+ va_end(ap);
+
+ return result;
+}
+
/*** integer ***/
diff --git a/test/.gitignore b/test/.gitignore
index 58e5e31..9c638ac 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -7,14 +7,15 @@ suites/api/test_dump
suites/api/test_dump_callback
suites/api/test_equal
suites/api/test_load
+suites/api/test_load_callback
suites/api/test_loadb
suites/api/test_memory_funcs
suites/api/test_number
suites/api/test_object
suites/api/test_pack
suites/api/test_simple
+suites/api/test_sprintf
suites/api/test_unpack
-suites/api/test_load_callback
run-suites.log
run-suites.trs
test-suite.log
diff --git a/test/suites/api/Makefile.am b/test/suites/api/Makefile.am
index 1dbdd2b..a1bc4d3 100644
--- a/test/suites/api/Makefile.am
+++ b/test/suites/api/Makefile.am
@@ -14,6 +14,7 @@ check_PROGRAMS = \
test_object \
test_pack \
test_simple \
+ test_sprintf \
test_unpack
test_array_SOURCES = test_array.c util.h
@@ -27,6 +28,7 @@ test_number_SOURCES = test_number.c util.h
test_object_SOURCES = test_object.c util.h
test_pack_SOURCES = test_pack.c util.h
test_simple_SOURCES = test_simple.c util.h
+test_sprintf_SOURCES = test_sprintf.c util.h
test_unpack_SOURCES = test_unpack.c util.h
AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src
diff --git a/test/suites/api/test_sprintf.c b/test/suites/api/test_sprintf.c
new file mode 100644
index 0000000..34908d8
--- /dev/null
+++ b/test/suites/api/test_sprintf.c
@@ -0,0 +1,22 @@
+#include <string.h>
+#include <jansson.h>
+#include "util.h"
+
+
+static void test_sprintf() {
+ json_t *s = json_sprintf("foo bar %d", 42);
+ if (!s)
+ fail("json_sprintf returned NULL");
+ if (!json_is_string(s))
+ fail("json_sprintf didn't return a JSON string");
+ if (strcmp(json_string_value(s), "foo bar 42"))
+ fail("json_sprintf generated an unexpected string");
+
+ json_decref(s);
+}
+
+
+static void run_tests()
+{
+ test_sprintf();
+}