From: Eric Haszlakiewicz Date: Tue, 30 Nov 2021 03:27:55 +0000 (+0000) Subject: Add linkhash accessor functions (lh_table_head(), lh_entry_next(), etc...) to pave... X-Git-Tag: json-c-0.16-20220414~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2d2382d709951c4941ad6ce5e58e5e63c79be786;p=thirdparty%2Fjson-c.git Add linkhash accessor functions (lh_table_head(), lh_entry_next(), etc...) to pave the way for making the lh_table and lh_entry structure opaque in the future. Update the docs to mark all members of those structures deprecated, and suggest what to use instead. --- diff --git a/ChangeLog b/ChangeLog index 12ccba02..1c562b7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,9 +4,11 @@ Next Release 0.16 Significant changes and bug fixes --------------------------------- -* Introduction of constant JSON_C_OBJECT_ADD_CONSTANT_KEY +* Introduce constant JSON_C_OBJECT_ADD_CONSTANT_KEY as a replacement of JSON_C_OBJECT_KEY_IS_CONSTANT, JSON_C_OBJECT_KEY_IS_CONSTANT becoming legacy. +* Direct access to lh_table and lh_entry structure members is deprecated. + Use access functions instead, lh_table_head(), lh_entry_next(), etc... * Drop REFCOUNT_DEBUG code. *** diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index e4110230..f064f604 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -427,7 +427,7 @@ EXTRACT_PACKAGE = NO # included in the documentation. # The default value is: NO. -EXTRACT_STATIC = NO +EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined # locally in source files will be included in the documentation. If set to NO @@ -1984,7 +1984,9 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = THIS_FUNCTION_IS_DEPRECATED(f)=f +PREDEFINED = \ + _LH_INLINE=inline \ + JSON_C_CONST_FUNCTION(func)=func # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/json_object.c b/json_object.c index 66fd725a..d59a317e 100644 --- a/json_object.c +++ b/json_object.c @@ -498,7 +498,7 @@ static int json_object_object_to_json_string(struct json_object *jso, struct pri static void json_object_lh_entry_free(struct lh_entry *ent) { - if (!ent->k_is_constant) + if (!lh_entry_k_is_constant(ent)) free(lh_entry_k(ent)); json_object_put((struct json_object *)lh_entry_v(ent)); } @@ -569,7 +569,7 @@ int json_object_object_add_ex(struct json_object *jso, const char *const key, existing_value = (json_object *)lh_entry_v(existing_entry); if (existing_value) json_object_put(existing_value); - existing_entry->v = val; + lh_entry_set_val(existing_entry, val); return 0; } diff --git a/json_object.h b/json_object.h index c5928974..0f779a52 100644 --- a/json_object.h +++ b/json_object.h @@ -483,14 +483,14 @@ JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key #define json_object_object_foreach(obj, key, val) \ char *key = NULL; \ struct json_object *val __attribute__((__unused__)) = NULL; \ - for (struct lh_entry *entry##key = json_object_get_object(obj)->head, \ + for (struct lh_entry *entry##key = lh_table_head(json_object_get_object(obj)), \ *entry_next##key = NULL; \ ({ \ if (entry##key) \ { \ key = (char *)lh_entry_k(entry##key); \ val = (struct json_object *)lh_entry_v(entry##key); \ - entry_next##key = entry##key->next; \ + entry_next##key = lh_entry_next(entry##key); \ }; \ entry##key; \ }); \ @@ -503,10 +503,10 @@ JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key struct json_object *val = NULL; \ struct lh_entry *entry##key; \ struct lh_entry *entry_next##key = NULL; \ - for (entry##key = json_object_get_object(obj)->head; \ + for (entry##key = lh_table_head(json_object_get_object(obj)); \ (entry##key ? (key = (char *)lh_entry_k(entry##key), \ val = (struct json_object *)lh_entry_v(entry##key), \ - entry_next##key = entry##key->next, entry##key) \ + entry_next##key = lh_entry_next(entry##key), entry##key) \ : 0); \ entry##key = entry_next##key) @@ -517,11 +517,11 @@ JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key * @param iter the object iterator, use type json_object_iter */ #define json_object_object_foreachC(obj, iter) \ - for (iter.entry = json_object_get_object(obj)->head; \ + for (iter.entry = lh_table_head(json_object_get_object(obj)); \ (iter.entry ? (iter.key = (char *)lh_entry_k(iter.entry), \ iter.val = (struct json_object *)lh_entry_v(iter.entry), iter.entry) \ : 0); \ - iter.entry = iter.entry->next) + iter.entry = lh_entry_next(iter.entry)) /* Array type methods */ diff --git a/json_object_iterator.c b/json_object_iterator.c index 1c2b3f2c..db8488ae 100644 --- a/json_object_iterator.c +++ b/json_object_iterator.c @@ -71,7 +71,7 @@ struct json_object_iterator json_object_iter_begin(struct json_object *obj) /// @note For a pair-less Object, head is NULL, which matches our /// definition of the "end" iterator - iter.opaque_ = pTable->head; + iter.opaque_ = lh_table_head(pTable); return iter; } @@ -98,7 +98,7 @@ void json_object_iter_next(struct json_object_iterator *iter) JASSERT(NULL != iter); JASSERT(kObjectEndIterValue != iter->opaque_); - iter->opaque_ = ((const struct lh_entry *)iter->opaque_)->next; + iter->opaque_ = lh_entry_next(((const struct lh_entry *)iter->opaque_)); } /** diff --git a/linkhash.h b/linkhash.h index 610ffc1d..cb6e3b42 100644 --- a/linkhash.h +++ b/linkhash.h @@ -80,64 +80,84 @@ typedef unsigned long(lh_hash_fn)(const void *k); typedef int(lh_equal_fn)(const void *k1, const void *k2); /** - * An entry in the hash table + * An entry in the hash table. Outside of linkhash.c, treat this as opaque. */ struct lh_entry { /** - * The key. Use lh_entry_k() instead of accessing this directly. + * The key. + * @deprecated Use lh_entry_k() instead of accessing this directly. */ const void *k; /** * A flag for users of linkhash to know whether or not they * need to free k. + * @deprecated use lh_entry_k_is_constant() instead. */ int k_is_constant; /** - * The value. Use lh_entry_v() instead of accessing this directly. + * The value. + * @deprecated Use lh_entry_v() instead of accessing this directly. */ const void *v; /** - * The next entry + * The next entry. + * @deprecated Use lh_entry_next() instead of accessing this directly. */ struct lh_entry *next; /** * The previous entry. + * @deprecated Use lh_entry_prev() instead of accessing this directly. */ struct lh_entry *prev; }; /** - * The hash table structure. + * The hash table structure. Outside of linkhash.c, treat this as opaque. */ struct lh_table { /** * Size of our hash. + * @deprecated do not use outside of linkhash.c */ int size; /** * Numbers of entries. + * @deprecated Use lh_table_length() instead. */ int count; /** * The first entry. + * @deprecated Use lh_table_head() instead. */ struct lh_entry *head; /** * The last entry. + * @deprecated Do not use, may be removed in a future release. */ struct lh_entry *tail; + /** + * Internal storage of the actual table of entries. + * @deprecated do not use outside of linkhash.c + */ struct lh_entry *table; /** - * A pointer onto the function responsible for freeing an entry. + * A pointer to the function responsible for freeing an entry. + * @deprecated do not use outside of linkhash.c */ lh_entry_free_fn *free_fn; + /** + * @deprecated do not use outside of linkhash.c + */ lh_hash_fn *hash_fn; + /** + * @deprecated do not use outside of linkhash.c + */ lh_equal_fn *equal_fn; }; typedef struct lh_table lh_table; @@ -145,7 +165,7 @@ typedef struct lh_table lh_table; /** * Convenience list iterator. */ -#define lh_foreach(table, entry) for (entry = table->head; entry; entry = entry->next) +#define lh_foreach(table, entry) for (entry = lh_table_head(table); entry; entry = lh_entry_next(entry)) /** * lh_foreach_safe allows calling of deletion routine while iterating. @@ -155,7 +175,7 @@ typedef struct lh_table lh_table; * @param tmp a struct lh_entry * variable to hold a temporary pointer to the next element */ #define lh_foreach_safe(table, entry, tmp) \ - for (entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp) + for (entry = lh_table_head(table); entry && ((tmp = lh_entry_next(entry)) || 1); entry = tmp) /** * Create a new linkhash table. @@ -295,6 +315,9 @@ extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e); */ extern int lh_table_delete(struct lh_table *t, const void *k); +/** + * Return the number of entries in the table. + */ extern int lh_table_length(struct lh_table *t); /** @@ -318,6 +341,15 @@ int lh_table_resize(struct lh_table *t, int new_size); #define _LH_INLINE inline #endif +/** + * Return the first entry in the lh_table. + * @see lh_entry_next() + */ +static _LH_INLINE struct lh_entry *lh_table_head(const lh_table *t) +{ + return t->head; +} + /** * Calculate the hash of a key for a given table. * @@ -334,7 +366,6 @@ static _LH_INLINE unsigned long lh_get_hash(const struct lh_table *t, const void return t->hash_fn(k); } -#undef _LH_INLINE /** * @deprecated Don't use this outside of linkhash.h: @@ -350,9 +381,22 @@ static _LH_INLINE unsigned long lh_get_hash(const struct lh_table *t, const void * * lh_entry.k is const to indicate and help ensure that linkhash itself doesn't modify * it, but callers are allowed to do what they want with it. - * See also lh_entry.k_is_constant + * @see lh_entry_k_is_constant() + */ +static _LH_INLINE void *lh_entry_k(const struct lh_entry *e) +{ + return _LH_UNCONST(e->k); +} + +/** + * Returns 1 if the key for the given entry is constant, and thus + * does not need to be freed when the lh_entry is freed. + * @see lh_table_insert_w_hash() */ -#define lh_entry_k(entry) _LH_UNCONST((entry)->k) +static _LH_INLINE int lh_entry_k_is_constant(const struct lh_entry *e) +{ + return e->k_is_constant; +} /** * Return a non-const version of lh_entry.v. @@ -360,7 +404,41 @@ static _LH_INLINE unsigned long lh_get_hash(const struct lh_table *t, const void * v is const to indicate and help ensure that linkhash itself doesn't modify * it, but callers are allowed to do what they want with it. */ -#define lh_entry_v(entry) _LH_UNCONST((entry)->v) +static _LH_INLINE void *lh_entry_v(const struct lh_entry *e) +{ + return _LH_UNCONST(e->v); +} + +/** + * Change the value for an entry. The caller is responsible for freeing + * the previous value. + */ +static _LH_INLINE void lh_entry_set_val(struct lh_entry *e, void *newval) +{ + e->v = newval; +} + +/** + * Return the next element, or NULL if there is no next element. + * @see lh_table_head() + * @see lh_entry_prev() + */ +static _LH_INLINE struct lh_entry *lh_entry_next(const struct lh_entry *e) +{ + return e->next; +} + +/** + * Return the previous element, or NULL if there is no previous element. + * @see lh_table_head() + * @see lh_entry_next() + */ +static _LH_INLINE struct lh_entry *lh_entry_prev(const struct lh_entry *e) +{ + return e->prev; +} + +#undef _LH_INLINE #ifdef __cplusplus }