Build: Add JANSSON_ATTRS macro.

This macro is used to conditionally generate GCC/CLANG __attribute__
declarations if supported.

This allows the compiler to produce warnings on certain incorrect
usages.  json_sprintf and json_vsprintf will produce warnings on invalid
format string.  Many functions will produce a warning if the result is
unused.  Specifically functions which allocate new objects will warn if
the result is ignored as this always results in a memory leak.
This commit is contained in:
Corey Farrell 2018-02-28 04:55:48 -05:00
parent d098c0ff86
commit ea664722d4
3 changed files with 27 additions and 21 deletions

View File

@ -55,7 +55,7 @@ typedef struct hashtable {
* *
* Returns 0 on success, -1 on error (out of memory). * Returns 0 on success, -1 on error (out of memory).
*/ */
int hashtable_init(hashtable_t *hashtable); int hashtable_init(hashtable_t *hashtable) JANSSON_ATTRS(warn_unused_result);
/** /**
* hashtable_close - Release all resources used by a hashtable object * hashtable_close - Release all resources used by a hashtable object

View File

@ -39,6 +39,12 @@ extern "C" {
#define JANSSON_THREAD_SAFE_REFCOUNT 1 #define JANSSON_THREAD_SAFE_REFCOUNT 1
#endif #endif
#if defined(__GNUC__) || defined(__clang__)
#define JANSSON_ATTRS(...) __attribute__((__VA_ARGS__))
#else
#define JANSSON_ATTRS(...)
#endif
/* types */ /* types */
typedef enum { typedef enum {
@ -185,7 +191,7 @@ static JSON_INLINE enum json_error_code json_error_code(const json_error_t *e) {
void json_object_seed(size_t seed); void json_object_seed(size_t seed);
size_t json_object_size(const json_t *object); size_t json_object_size(const json_t *object);
json_t *json_object_get(const json_t *object, const char *key); json_t *json_object_get(const json_t *object, const char *key) JANSSON_ATTRS(warn_unused_result);
int json_object_set_new(json_t *object, const char *key, json_t *value); int json_object_set_new(json_t *object, const char *key, json_t *value);
int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value); int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value);
int json_object_del(json_t *object, const char *key); int json_object_del(json_t *object, const char *key);
@ -237,7 +243,7 @@ int json_object_iter_set(json_t *object, void *iter, json_t *value)
} }
size_t json_array_size(const json_t *array); size_t json_array_size(const json_t *array);
json_t *json_array_get(const json_t *array, size_t index); json_t *json_array_get(const json_t *array, size_t index) JANSSON_ATTRS(warn_unused_result);
int json_array_set_new(json_t *array, size_t index, json_t *value); int json_array_set_new(json_t *array, size_t index, json_t *value);
int json_array_append_new(json_t *array, json_t *value); int json_array_append_new(json_t *array, json_t *value);
int json_array_insert_new(json_t *array, size_t index, json_t *value); int json_array_insert_new(json_t *array, size_t index, json_t *value);
@ -278,9 +284,9 @@ int json_real_set(json_t *real, double value);
/* pack, unpack */ /* pack, unpack */
json_t *json_pack(const char *fmt, ...); json_t *json_pack(const char *fmt, ...) JANSSON_ATTRS(warn_unused_result);
json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...); json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...) JANSSON_ATTRS(warn_unused_result);
json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap); json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap) JANSSON_ATTRS(warn_unused_result);
#define JSON_VALIDATE_ONLY 0x1 #define JSON_VALIDATE_ONLY 0x1
#define JSON_STRICT 0x2 #define JSON_STRICT 0x2
@ -291,8 +297,8 @@ int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags, const char
/* sprintf */ /* sprintf */
json_t *json_sprintf(const char *fmt, ...); json_t *json_sprintf(const char *fmt, ...) JANSSON_ATTRS(warn_unused_result, format(printf, 1, 2));
json_t *json_vsprintf(const char *fmt, va_list ap); json_t *json_vsprintf(const char *fmt, va_list ap) JANSSON_ATTRS(warn_unused_result, format(printf, 1, 0));
/* equality */ /* equality */
@ -302,8 +308,8 @@ int json_equal(const json_t *value1, const json_t *value2);
/* copying */ /* copying */
json_t *json_copy(json_t *value); json_t *json_copy(json_t *value) JANSSON_ATTRS(warn_unused_result);
json_t *json_deep_copy(const json_t *value); json_t *json_deep_copy(const json_t *value) JANSSON_ATTRS(warn_unused_result);
/* decoding */ /* decoding */
@ -316,12 +322,12 @@ json_t *json_deep_copy(const json_t *value);
typedef size_t (*json_load_callback_t)(void *buffer, size_t buflen, void *data); typedef size_t (*json_load_callback_t)(void *buffer, size_t buflen, void *data);
json_t *json_loads(const char *input, size_t flags, json_error_t *error); json_t *json_loads(const char *input, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error); json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
json_t *json_loadf(FILE *input, size_t flags, json_error_t *error); json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
json_t *json_loadfd(int input, size_t flags, json_error_t *error); json_t *json_loadfd(int input, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
json_t *json_load_file(const char *path, size_t flags, json_error_t *error); json_t *json_load_file(const char *path, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
json_t *json_load_callback(json_load_callback_t callback, void *data, size_t flags, json_error_t *error); json_t *json_load_callback(json_load_callback_t callback, void *data, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
/* encoding */ /* encoding */
@ -339,7 +345,7 @@ json_t *json_load_callback(json_load_callback_t callback, void *data, size_t fla
typedef int (*json_dump_callback_t)(const char *buffer, size_t size, void *data); typedef int (*json_dump_callback_t)(const char *buffer, size_t size, void *data);
char *json_dumps(const json_t *json, size_t flags); char *json_dumps(const json_t *json, size_t flags) JANSSON_ATTRS(warn_unused_result);
size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags); size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags);
int json_dumpf(const json_t *json, FILE *output, size_t flags); int json_dumpf(const json_t *json, FILE *output, size_t flags);
int json_dumpfd(const json_t *json, int output, size_t flags); int json_dumpfd(const json_t *json, int output, size_t flags);

View File

@ -84,11 +84,11 @@ int jsonp_strtod(strbuffer_t *strbuffer, double *out);
int jsonp_dtostr(char *buffer, size_t size, double value, int prec); int jsonp_dtostr(char *buffer, size_t size, double value, int prec);
/* Wrappers for custom memory functions */ /* Wrappers for custom memory functions */
void* jsonp_malloc(size_t size); void* jsonp_malloc(size_t size) JANSSON_ATTRS(warn_unused_result);
void jsonp_free(void *ptr); void jsonp_free(void *ptr);
char *jsonp_strndup(const char *str, size_t length); char *jsonp_strndup(const char *str, size_t length) JANSSON_ATTRS(warn_unused_result);
char *jsonp_strdup(const char *str); char *jsonp_strdup(const char *str) JANSSON_ATTRS(warn_unused_result);
char *jsonp_strndup(const char *str, size_t len); char *jsonp_strndup(const char *str, size_t len) JANSSON_ATTRS(warn_unused_result);
/* Windows compatibility */ /* Windows compatibility */