summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-01-09 11:12:10 +0100
committerThomas Haller <thaller@redhat.com>2020-07-08 12:12:42 +0200
commit597cb7eb6807a88a0088f18da84621ce9b4d5d73 (patch)
tree8db4c172e1d02e9156a824e0cddf6bea1bcd88ee
parentec1e7f3e858937900c3badda94339283fd78a3c2 (diff)
downloadNetworkManager-597cb7eb6807a88a0088f18da84621ce9b4d5d73.tar.gz
libnm: don't include <jansson.h> in libnm but use own variants
It's error prone to include the header and trying not to use it. Don't include <jansson.h>. Instead, redefine our nm variants of everything. Note that we only redefine stuff that is in public headers (like "json_t" typedef). libjansson anyway must not change the struct layout and the like, without breaking all applications. That is because the non-opaque code from the header anyway is part of the applications that include it. Later we will add additional unit test that checks that our redefinition matches to what we had at compile time.
-rw-r--r--libnm-core/nm-json.c2
-rw-r--r--libnm-core/nm-json.h141
-rw-r--r--libnm-core/nm-team-utils.c24
-rw-r--r--libnm-core/nm-utils.c6
4 files changed, 93 insertions, 80 deletions
diff --git a/libnm-core/nm-json.c b/libnm-core/nm-json.c
index 5119252ade..9c66d61027 100644
--- a/libnm-core/nm-json.c
+++ b/libnm-core/nm-json.c
@@ -43,7 +43,7 @@ _nm_json_vt_internal_load (void)
#define TRY_BIND_SYMBOL(symbol) \
G_STMT_START { \
- typeof (symbol) (*_sym) = dlsym (handle, #symbol); \
+ void *_sym = dlsym (handle, #symbol); \
\
if (!_sym) \
goto fail_symbol; \
diff --git a/libnm-core/nm-json.h b/libnm-core/nm-json.h
index a585d521c4..5042cf0f80 100644
--- a/libnm-core/nm-json.h
+++ b/libnm-core/nm-json.h
@@ -8,35 +8,62 @@
/*****************************************************************************/
-#if WITH_JANSSON
-
-#include <jansson.h>
+#define NM_JSON_REJECT_DUPLICATES 0x1
+
+typedef enum {
+ NM_JSON_OBJECT,
+ NM_JSON_ARRAY,
+ NM_JSON_STRING,
+ NM_JSON_INTEGER,
+ NM_JSON_REAL,
+ NM_JSON_TRUE,
+ NM_JSON_FALSE,
+ NM_JSON_NULL,
+} nm_json_type;
+
+typedef struct nm_json_t {
+ nm_json_type type;
+ volatile size_t refcount;
+} nm_json_t;
+
+typedef long long nm_json_int_t;
+
+#define NM_JSON_ERROR_TEXT_LENGTH 160
+#define NM_JSON_ERROR_SOURCE_LENGTH 80
+
+typedef struct nm_json_error_t {
+ int line;
+ int column;
+ int position;
+ char source[NM_JSON_ERROR_SOURCE_LENGTH];
+ char text[NM_JSON_ERROR_TEXT_LENGTH];
+} nm_json_error_t;
typedef struct {
gboolean loaded;
- char *(*nm_json_dumps) (const json_t *json, size_t flags);
- const char *(*nm_json_object_iter_key) (void *iter);
- const char *(*nm_json_string_value) (const json_t *json);
- int (*nm_json_array_append_new) (json_t *json, json_t *value);
- int (*nm_json_object_del) (json_t *json, const char *key);
- int (*nm_json_object_set_new) (json_t *json, const char *key, json_t *value);
- json_int_t (*nm_json_integer_value) (const json_t *json);
- json_t *(*nm_json_array) (void);
- json_t *(*nm_json_array_get) (const json_t *json, size_t index);
- json_t *(*nm_json_false) (void);
- json_t *(*nm_json_integer) (json_int_t value);
- json_t *(*nm_json_loads) (const char *string, size_t flags, json_error_t *error);
- json_t *(*nm_json_object) (void);
- json_t *(*nm_json_object_get) (const json_t *json, const char *key);
- json_t *(*nm_json_object_iter_value) (void *);
- json_t *(*nm_json_string) (const char *value);
- json_t *(*nm_json_true) (void);
- size_t (*nm_json_array_size) (const json_t *json);
- size_t (*nm_json_object_size) (const json_t *json);
- void (*nm_json_delete) (json_t *json);
- void *(*nm_json_object_iter) (json_t *json);
- void *(*nm_json_object_iter_next) (json_t *json, void *iter);
- void *(*nm_json_object_key_to_iter) (const char *key);
+ char *(*nm_json_dumps) (const nm_json_t *json, size_t flags);
+ const char *(*nm_json_object_iter_key) (void *iter);
+ const char *(*nm_json_string_value) (const nm_json_t *json);
+ int (*nm_json_array_append_new) (nm_json_t *json, nm_json_t *value);
+ int (*nm_json_object_del) (nm_json_t *json, const char *key);
+ int (*nm_json_object_set_new) (nm_json_t *json, const char *key, nm_json_t *value);
+ nm_json_int_t (*nm_json_integer_value) (const nm_json_t *json);
+ nm_json_t *(*nm_json_array) (void);
+ nm_json_t *(*nm_json_array_get) (const nm_json_t *json, size_t index);
+ nm_json_t *(*nm_json_false) (void);
+ nm_json_t *(*nm_json_integer) (nm_json_int_t value);
+ nm_json_t *(*nm_json_loads) (const char *string, size_t flags, nm_json_error_t *error);
+ nm_json_t *(*nm_json_object) (void);
+ nm_json_t *(*nm_json_object_get) (const nm_json_t *json, const char *key);
+ nm_json_t *(*nm_json_object_iter_value) (void *);
+ nm_json_t *(*nm_json_string) (const char *value);
+ nm_json_t *(*nm_json_true) (void);
+ size_t (*nm_json_array_size) (const nm_json_t *json);
+ size_t (*nm_json_object_size) (const nm_json_t *json);
+ void (*nm_json_delete) (nm_json_t *json);
+ void *(*nm_json_object_iter) (nm_json_t *json);
+ void *(*nm_json_object_iter_next) (nm_json_t *json, void *iter);
+ void *(*nm_json_object_key_to_iter) (const char *key);
} NMJsonVt;
extern const NMJsonVt *_nm_json_vt_ptr;
@@ -83,7 +110,7 @@ const NMJsonVt *nmtst_json_vt_reset (gboolean loaded);
((val) ? (vt)->nm_json_true () : (vt)->nm_json_false ())
static inline void
-nm_json_decref (const NMJsonVt *vt, json_t *json)
+nm_json_decref (const NMJsonVt *vt, nm_json_t *json)
{
/* Our ref-counting is not threadsafe, unlike libjansson's. But we never
* share one json_t instance between threads, and if we would, we would very likely
@@ -95,7 +122,7 @@ nm_json_decref (const NMJsonVt *vt, json_t *json)
}
static inline void
-_nm_auto_decref_json (json_t **p_json)
+_nm_auto_decref_json (nm_json_t **p_json)
{
if ( *p_json
&& (*p_json)->refcount != (size_t) -1
@@ -111,13 +138,18 @@ _nm_auto_decref_json (json_t **p_json)
* They can be used directly, however, add a nm_json* variant,
* to make it explict we don't accidentally use jansson ABI. */
-#define nm_json_is_boolean(json) json_is_boolean (json)
-#define nm_json_is_integer(json) json_is_integer (json)
-#define nm_json_is_string(json) json_is_string (json)
-#define nm_json_is_object(json) json_is_object (json)
-#define nm_json_is_array(json) json_is_array (json)
-#define nm_json_is_true(json) json_is_true (json)
-#define nm_json_boolean_value(json) json_boolean_value (json)
+#define nm_json_typeof(json) ((json)->type)
+#define nm_json_is_object(json) ((json) && nm_json_typeof(json) == NM_JSON_OBJECT)
+#define nm_json_is_array(json) ((json) && nm_json_typeof(json) == NM_JSON_ARRAY)
+#define nm_json_is_string(json) ((json) && nm_json_typeof(json) == NM_JSON_STRING)
+#define nm_json_is_integer(json) ((json) && nm_json_typeof(json) == NM_JSON_INTEGER)
+#define nm_json_is_real(json) ((json) && nm_json_typeof(json) == NM_JSON_REAL)
+#define nm_json_is_number(json) (nm_json_is_integer(json) || nm_json_is_real(json))
+#define nm_json_is_true(json) ((json) && nm_json_typeof(json) == NM_JSON_TRUE)
+#define nm_json_is_false(json) ((json) && nm_json_typeof(json) == NM_JSON_FALSE)
+#define nm_json_boolean_value nm_json_is_true
+#define nm_json_is_boolean(json) (nm_json_is_true(json) || nm_json_is_false(json))
+#define nm_json_is_null(json) ((json) && nm_json_typeof(json) == NM_JSON_NULL)
#define nm_json_object_foreach(vt, object, key, value) \
for(key = vt->nm_json_object_iter_key (vt->nm_json_object_iter (object)); \
@@ -126,43 +158,26 @@ _nm_auto_decref_json (json_t **p_json)
/*****************************************************************************/
-/* Added in Jansson v2.7 */
-#ifndef json_boolean_value
-#define json_boolean_value json_is_true
-#endif
-
-/* Added in Jansson v2.8 */
-#ifndef json_object_foreach_safe
-#define json_object_foreach_safe(object, n, key, value) \
- for (key = json_object_iter_key(json_object_iter(object)), \
- n = json_object_iter_next(object, json_object_key_to_iter(key)); \
- key && (value = json_object_iter_value(json_object_key_to_iter(key))); \
- key = json_object_iter_key(n), \
- n = json_object_iter_next(object, json_object_key_to_iter(key)))
-#endif
-
-/*****************************************************************************/
-
static inline int
-nm_jansson_json_as_bool (const json_t *elem,
+nm_jansson_json_as_bool (const nm_json_t *elem,
bool *out_val)
{
if (!elem)
return 0;
- if (!json_is_boolean (elem))
+ if (!nm_json_is_boolean (elem))
return -EINVAL;
- NM_SET_OUT (out_val, json_boolean_value (elem));
+ NM_SET_OUT (out_val, nm_json_boolean_value (elem));
return 1;
}
static inline int
nm_jansson_json_as_int32 (const NMJsonVt *vt,
- const json_t *elem,
+ const nm_json_t *elem,
gint32 *out_val)
{
- json_int_t v;
+ nm_json_int_t v;
if (!elem)
return 0;
@@ -181,10 +196,10 @@ nm_jansson_json_as_int32 (const NMJsonVt *vt,
static inline int
nm_jansson_json_as_int (const NMJsonVt *vt,
- const json_t *elem,
+ const nm_json_t *elem,
int *out_val)
{
- json_int_t v;
+ nm_json_int_t v;
if (!elem)
return 0;
@@ -203,13 +218,13 @@ nm_jansson_json_as_int (const NMJsonVt *vt,
static inline int
nm_jansson_json_as_string (const NMJsonVt *vt,
- const json_t *elem,
+ const nm_json_t *elem,
const char **out_val)
{
if (!elem)
return 0;
- if (!json_is_string (elem))
+ if (!nm_json_is_string (elem))
return -EINVAL;
NM_SET_OUT (out_val, vt->nm_json_string_value (elem));
@@ -225,7 +240,7 @@ nm_jansson_json_as_string (const NMJsonVt *vt,
static inline gboolean
nm_value_type_from_json (const NMJsonVt *vt,
NMValueType value_type,
- const json_t *elem,
+ const nm_json_t *elem,
gpointer out_val)
{
switch (value_type) {
@@ -246,6 +261,4 @@ nm_value_type_from_json (const NMJsonVt *vt,
#endif /* NM_VALUE_TYPE_DEFINE_FUNCTIONS */
-#endif /* WITH_JANSSON */
-
#endif /* __NM_JSON_H__ */
diff --git a/libnm-core/nm-team-utils.c b/libnm-core/nm-team-utils.c
index 43dacaaf71..758766a251 100644
--- a/libnm-core/nm-team-utils.c
+++ b/libnm-core/nm-team-utils.c
@@ -1119,19 +1119,19 @@ _link_watcher_to_json (const NMTeamLinkWatcher *link_watcher,
#if WITH_JSON_VALIDATION
static NMTeamLinkWatcher *
_link_watcher_from_json (const NMJsonVt *vt,
- const json_t *root_js_obj,
+ const nm_json_t *root_js_obj,
gboolean *out_unrecognized_content)
{
NMValueTypUnioMaybe args[G_N_ELEMENTS (link_watcher_attr_datas)] = { };
const char *j_key;
- json_t *j_val;
+ nm_json_t *j_val;
const char *v_name;
NMTeamLinkWatcher *result = NULL;
if (!nm_json_is_object (root_js_obj))
goto fail;
- nm_json_object_foreach (vt, (json_t *) root_js_obj, j_key, j_val) {
+ nm_json_object_foreach (vt, (nm_json_t *) root_js_obj, j_key, j_val) {
const LinkWatcherAttrData *attr_data = NULL;
NMValueTypUnioMaybe *parse_result;
@@ -1689,17 +1689,17 @@ _attr_data_find_by_json_key (gboolean is_port,
static void
_js_parse_locate_keys (const NMJsonVt *vt,
NMTeamSetting *self,
- json_t *root_js_obj,
- json_t *found_keys[static _NM_TEAM_ATTRIBUTE_NUM],
+ nm_json_t *root_js_obj,
+ nm_json_t *found_keys[static _NM_TEAM_ATTRIBUTE_NUM],
gboolean *out_unrecognized_content)
{
const char *keys[3];
const char *cur_key1;
const char *cur_key2;
const char *cur_key3;
- json_t *cur_val1;
- json_t *cur_val2;
- json_t *cur_val3;
+ nm_json_t *cur_val1;
+ nm_json_t *cur_val2;
+ nm_json_t *cur_val3;
#define _handle(_self, _cur_key, _cur_val, _keys, _level, _found_keys, _out_unrecognized_content) \
({ \
@@ -1741,7 +1741,7 @@ _js_parse_locate_keys (const NMJsonVt *vt,
static void
_js_parse_unpack (const NMJsonVt *vt,
gboolean is_port,
- json_t *found_keys[static _NM_TEAM_ATTRIBUTE_NUM],
+ nm_json_t *found_keys[static _NM_TEAM_ATTRIBUTE_NUM],
bool out_has_lst[static _NM_TEAM_ATTRIBUTE_NUM],
NMValueTypUnion out_val_lst[static _NM_TEAM_ATTRIBUTE_NUM],
gboolean *out_unrecognized_content,
@@ -1753,7 +1753,7 @@ _js_parse_unpack (const NMJsonVt *vt,
for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
NMValueTypUnion *p_out_val;
gboolean valid = FALSE;
- json_t *arg_js_obj;
+ nm_json_t *arg_js_obj;
if (!_team_attr_data_is_relevant (attr_data, is_port))
continue;
@@ -1874,7 +1874,7 @@ nm_team_setting_config_set (NMTeamSetting *self, const char *js_str)
#if WITH_JSON_VALIDATION
{
- nm_auto_decref_json json_t *root_js_obj = NULL;
+ nm_auto_decref_json nm_json_t *root_js_obj = NULL;
const NMJsonVt *vt;
if ((vt = nm_json_vt ()))
@@ -1887,7 +1887,7 @@ nm_team_setting_config_set (NMTeamSetting *self, const char *js_str)
gboolean unrecognized_content = FALSE;
bool has_lst[_NM_TEAM_ATTRIBUTE_NUM] = { FALSE, };
NMValueTypUnion val_lst[_NM_TEAM_ATTRIBUTE_NUM];
- json_t *found_keys[_NM_TEAM_ATTRIBUTE_NUM] = { NULL, };
+ nm_json_t *found_keys[_NM_TEAM_ATTRIBUTE_NUM] = { NULL, };
gs_unref_ptrarray GPtrArray *ptr_array_master_runner_tx_hash_free = NULL;
gs_unref_ptrarray GPtrArray *ptr_array_link_watchers_free = NULL;
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index 8b6b121332..f188ec8250 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -5494,9 +5494,9 @@ gboolean
nm_utils_is_json_object (const char *str, GError **error)
{
#if WITH_JSON_VALIDATION
- nm_auto_decref_json json_t *json = NULL;
+ nm_auto_decref_json nm_json_t *json = NULL;
const NMJsonVt *vt;
- json_error_t jerror;
+ nm_json_error_t jerror;
g_return_val_if_fail (!error || !*error, FALSE);
@@ -5511,7 +5511,7 @@ nm_utils_is_json_object (const char *str, GError **error)
if (!(vt = nm_json_vt ()))
return _nm_utils_is_json_object_no_validation (str, error);
- json = vt->nm_json_loads (str, JSON_REJECT_DUPLICATES, &jerror);
+ json = vt->nm_json_loads (str, NM_JSON_REJECT_DUPLICATES, &jerror);
if (!json) {
g_set_error (error,
NM_CONNECTION_ERROR,