From 76300601d9cb3f8756dd94f0f8a354ff844ae686 Mon Sep 17 00:00:00 2001 From: Sean Bright Date: Fri, 8 Mar 2019 12:57:59 -0500 Subject: [PATCH] Add runtime version checking functions This patch adds two new exported functions: * `jansson_version_str` - Returns a human-readable version number * `jansson_version_cmp` - Returns an integer less than, equal to, or greater than zero if the runtime version of Jansson is found, respectively, to be less than, to match, or be greater than the provided major, minor, and micro. --- doc/apiref.rst | 19 +++++++++++ src/Makefile.am | 3 +- src/jansson.def | 2 ++ src/jansson.h | 5 +++ src/version.c | 32 +++++++++++++++++++ test/.gitignore | 1 + test/suites/api/Makefile.am | 4 ++- test/suites/api/test_version.c | 58 ++++++++++++++++++++++++++++++++++ 8 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 src/version.c create mode 100644 test/suites/api/test_version.c diff --git a/doc/apiref.rst b/doc/apiref.rst index 3945c11..1b305f5 100644 --- a/doc/apiref.rst +++ b/doc/apiref.rst @@ -58,6 +58,25 @@ the library: /* Code specific to version 1.3 and above */ #endif +Additionally, there are functions to determine the version of Jansson at +runtime: + +.. function:: const char *jansson_version_str() + + Return the version of the Jansson library, in the same format as + the ``JANSSON_VERSION`` preprocessor constant. + + .. versionadded:: 2.13 + +.. function:: int jansson_version_cmp(int major, int minor, int micro) + + Returns an integer less than, equal to, or greater than zero if + the runtime version of Jansson is found, respectively, to be less + than, to match, or be greater than the provided *major*, *minor*, and + *micro*. + + .. versionadded:: 2.13 + ``JANSSON_THREAD_SAFE_REFCOUNT`` If this value is defined all read-only operations and reference counting in Jansson are thread safe. This value is not defined for versions older than diff --git a/src/Makefile.am b/src/Makefile.am index 37cfaac..bd996cd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,7 +20,8 @@ libjansson_la_SOURCES = \ strconv.c \ utf.c \ utf.h \ - value.c + value.c \ + version.c libjansson_la_LDFLAGS = \ -no-undefined \ -export-symbols-regex '^json_' \ diff --git a/src/jansson.def b/src/jansson.def index 15f35c9..ed72829 100644 --- a/src/jansson.def +++ b/src/jansson.def @@ -72,4 +72,6 @@ EXPORTS json_vunpack_ex json_set_alloc_funcs json_get_alloc_funcs + jansson_version_str + jansson_version_cmp diff --git a/src/jansson.h b/src/jansson.h index e4e73e2..b2b980b 100644 --- a/src/jansson.h +++ b/src/jansson.h @@ -360,6 +360,11 @@ typedef void (*json_free_t)(void *); void json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn); void json_get_alloc_funcs(json_malloc_t *malloc_fn, json_free_t *free_fn); +/* runtime version checking */ + +const char *jansson_version_str(void); +int jansson_version_cmp(int major, int minor, int micro); + #ifdef __cplusplus } #endif diff --git a/src/version.c b/src/version.c new file mode 100644 index 0000000..11435dd --- /dev/null +++ b/src/version.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 Sean Bright + * + * Jansson is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include "jansson.h" + +const char *jansson_version_str(void) +{ + return JANSSON_VERSION; +} + +int jansson_version_cmp(int major, int minor, int micro) +{ + int diff; + + if ((diff = JANSSON_MAJOR_VERSION - major)) { + return diff; + } + + if ((diff = JANSSON_MINOR_VERSION - minor)) { + return diff; + } + + return JANSSON_MICRO_VERSION - micro; +} diff --git a/test/.gitignore b/test/.gitignore index 401ca5c..d643dc8 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -17,6 +17,7 @@ suites/api/test_pack suites/api/test_simple suites/api/test_sprintf suites/api/test_unpack +suites/api/test_version run-suites.log run-suites.trs test-suite.log diff --git a/test/suites/api/Makefile.am b/test/suites/api/Makefile.am index 63548ac..e109e56 100644 --- a/test/suites/api/Makefile.am +++ b/test/suites/api/Makefile.am @@ -16,7 +16,8 @@ check_PROGRAMS = \ test_pack \ test_simple \ test_sprintf \ - test_unpack + test_unpack \ + test_version test_array_SOURCES = test_array.c util.h test_chaos_SOURCES = test_chaos.c util.h @@ -32,6 +33,7 @@ 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 +test_version_SOURCES = test_version.c util.h AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src LDFLAGS = -static # for speed and Valgrind diff --git a/test/suites/api/test_version.c b/test/suites/api/test_version.c new file mode 100644 index 0000000..73c406c --- /dev/null +++ b/test/suites/api/test_version.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019 Sean Bright + * + * Jansson is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + */ + +#include +#include +#include "util.h" + +static void test_version_str(void) +{ + if (strcmp(jansson_version_str(), JANSSON_VERSION)) { + fail("jansson_version_str returned invalid version string"); + } +} + +static void test_version_cmp() +{ + if (jansson_version_cmp(JANSSON_MAJOR_VERSION, JANSSON_MINOR_VERSION, JANSSON_MICRO_VERSION)) { + fail("jansson_version_cmp equality check failed"); + } + + if (jansson_version_cmp(JANSSON_MAJOR_VERSION - 1, 0, 0) <= 0) { + fail("jansson_version_cmp less than check failed"); + } + + if (JANSSON_MINOR_VERSION) { + if (jansson_version_cmp(JANSSON_MAJOR_VERSION, JANSSON_MINOR_VERSION - 1, JANSSON_MICRO_VERSION) <= 0) { + fail("jansson_version_cmp less than check failed"); + } + } + + if (JANSSON_MICRO_VERSION) { + if (jansson_version_cmp(JANSSON_MAJOR_VERSION, JANSSON_MINOR_VERSION, JANSSON_MICRO_VERSION - 1) <= 0) { + fail("jansson_version_cmp less than check failed"); + } + } + + if (jansson_version_cmp(JANSSON_MAJOR_VERSION + 1, JANSSON_MINOR_VERSION, JANSSON_MICRO_VERSION) >= 0) { + fail("jansson_version_cmp greater than check failed"); + } + + if (jansson_version_cmp(JANSSON_MAJOR_VERSION, JANSSON_MINOR_VERSION + 1, JANSSON_MICRO_VERSION) >= 0) { + fail("jansson_version_cmp greater than check failed"); + } + + if (jansson_version_cmp(JANSSON_MAJOR_VERSION, JANSSON_MINOR_VERSION, JANSSON_MICRO_VERSION + 1) >= 0) { + fail("jansson_version_cmp greater than check failed"); + } +} + +static void run_tests() +{ + test_version_str(); + test_version_cmp(); +}