diff options
Diffstat (limited to 'src/libmdsserver')
-rw-r--r-- | src/libmdsserver/client-list.c | 1 | ||||
-rw-r--r-- | src/libmdsserver/client-list.h | 10 | ||||
-rw-r--r-- | src/libmdsserver/fd-table.h | 19 | ||||
-rw-r--r-- | src/libmdsserver/hash-help.h | 6 | ||||
-rw-r--r-- | src/libmdsserver/hash-list.h | 26 | ||||
-rw-r--r-- | src/libmdsserver/hash-table.c | 7 | ||||
-rw-r--r-- | src/libmdsserver/hash-table.h | 18 | ||||
-rw-r--r-- | src/libmdsserver/linked-list.c | 3 | ||||
-rw-r--r-- | src/libmdsserver/linked-list.h | 15 | ||||
-rw-r--r-- | src/libmdsserver/mds-message.c | 10 | ||||
-rw-r--r-- | src/libmdsserver/mds-message.h | 14 | ||||
-rw-r--r-- | src/libmdsserver/util.h | 35 |
12 files changed, 133 insertions, 31 deletions
diff --git a/src/libmdsserver/client-list.c b/src/libmdsserver/client-list.c index 3576d4e..0196e10 100644 --- a/src/libmdsserver/client-list.c +++ b/src/libmdsserver/client-list.c @@ -38,6 +38,7 @@ * @param value The value to be rounded up to a power of two * @return The nearest, but not smaller, power of two */ +__attribute__((const)) static size_t to_power_of_two(size_t value) { value -= 1; diff --git a/src/libmdsserver/client-list.h b/src/libmdsserver/client-list.h index 077f9e4..34d23bc 100644 --- a/src/libmdsserver/client-list.h +++ b/src/libmdsserver/client-list.h @@ -58,6 +58,7 @@ typedef struct client_list * @param capacity The minimum initial capacity of the client list, 0 for default * @return Non-zero on error, `errno` will have been set accordingly */ +__attribute__((nonnull)) int client_list_create(client_list_t* restrict this, size_t capacity); /** @@ -66,6 +67,7 @@ int client_list_create(client_list_t* restrict this, size_t capacity); * * @param this The client list */ +__attribute__((nonnull)) void client_list_destroy(client_list_t* restrict this); /** @@ -75,6 +77,7 @@ void client_list_destroy(client_list_t* restrict this); * @param out Memory slot in which to store the new client list * @return Non-zero on error, `errno` will have been set accordingly */ +__attribute__((nonnull)) int client_list_clone(const client_list_t* restrict this, client_list_t* restrict out); /** @@ -84,6 +87,7 @@ int client_list_clone(const client_list_t* restrict this, client_list_t* restric * @param client The client to add * @return Non-zero on error, `errno` will be set accordingly */ +__attribute__((nonnull)) int client_list_add(client_list_t* restrict this, uint64_t client); /** @@ -92,6 +96,7 @@ int client_list_add(client_list_t* restrict this, uint64_t client); * @param this The list * @param client The client to remove */ +__attribute__((nonnull)) void client_list_remove(client_list_t* restrict this, uint64_t client); /** @@ -100,7 +105,8 @@ void client_list_remove(client_list_t* restrict this, uint64_t client); * @param this The list * @return The number of bytes to allocate to the output buffer */ -size_t client_list_marshal_size(const client_list_t* restrict this) __attribute__((pure)); +__attribute__((pure, nonnull)) +size_t client_list_marshal_size(const client_list_t* restrict this); /** * Marshals a client list @@ -108,6 +114,7 @@ size_t client_list_marshal_size(const client_list_t* restrict this) __attribute_ * @param this The list * @param data Output buffer for the marshalled data */ +__attribute__((nonnull)) void client_list_marshal(const client_list_t* restrict this, char* restrict data); /** @@ -118,6 +125,7 @@ void client_list_marshal(const client_list_t* restrict this, char* restrict data * @return Non-zero on error, `errno` will be set accordingly. * Destroy the list on error. */ +__attribute__((nonnull)) int client_list_unmarshal(client_list_t* restrict this, char* restrict data); diff --git a/src/libmdsserver/fd-table.h b/src/libmdsserver/fd-table.h index f4e468b..284eada 100644 --- a/src/libmdsserver/fd-table.h +++ b/src/libmdsserver/fd-table.h @@ -73,6 +73,7 @@ typedef struct fd_table * @param initial_capacity The initial capacity of the table * @return Non-zero on error, `errno` will have been set accordingly */ +__attribute__((nonnull)) int fd_table_create_tuned(fd_table_t* restrict this, size_t initial_capacity); /** @@ -92,6 +93,7 @@ int fd_table_create_tuned(fd_table_t* restrict this, size_t initial_capacity); * @param keys_freer Function that frees a key, `NULL` if keys should not be freed * @param values_freer Function that frees a value, `NULL` if value should not be freed */ +__attribute__((nonnull(1))) void fd_table_destroy(fd_table_t* restrict this, free_func* key_freer, free_func* value_freer); /** @@ -101,7 +103,8 @@ void fd_table_destroy(fd_table_t* restrict this, free_func* key_freer, free_func * @param value The value * @return Whether the value is stored in the table */ -int fd_table_contains_value(const fd_table_t* restrict this, size_t value) __attribute__((pure)); +__attribute__((pure, nonnull)) +int fd_table_contains_value(const fd_table_t* restrict this, size_t value); /** * Check whether a key is used in the table @@ -110,7 +113,8 @@ int fd_table_contains_value(const fd_table_t* restrict this, size_t value) __att * @param key The key * @return Whether the key is used */ -int fd_table_contains_key(const fd_table_t* restrict this, int key) __attribute__((pure)); +__attribute__((pure, nonnull)) +int fd_table_contains_key(const fd_table_t* restrict this, int key); /** * Look up a value in the table @@ -119,7 +123,8 @@ int fd_table_contains_key(const fd_table_t* restrict this, int key) __attribute_ * @param key The key associated with the value * @return The value associated with the key, 0 if the key was not used */ -size_t fd_table_get(const fd_table_t* restrict this, int key) __attribute__((pure)); +__attribute__((pure, nonnull)) +size_t fd_table_get(const fd_table_t* restrict this, int key); /** * Add an entry to the table @@ -130,6 +135,7 @@ size_t fd_table_get(const fd_table_t* restrict this, int key) __attribute__((pur * @return The previous value associated with the key, 0 if the key was not used. * 0 will also be returned on error, check the `errno` variable. */ +__attribute__((nonnull)) size_t fd_table_put(fd_table_t* restrict this, int key, size_t value); /** @@ -139,6 +145,7 @@ size_t fd_table_put(fd_table_t* restrict this, int key, size_t value); * @param key The key of the entry to remove * @return The previous value associated with the key, 0 if the key was not used */ +__attribute__((nonnull)) size_t fd_table_remove(fd_table_t* restrict this, int key); /** @@ -146,6 +153,7 @@ size_t fd_table_remove(fd_table_t* restrict this, int key); * * @param this The fd table */ +__attribute__((nonnull)) void fd_table_clear(fd_table_t* restrict this); /** @@ -154,7 +162,8 @@ void fd_table_clear(fd_table_t* restrict this); * @param this The fd table * @return The number of bytes to allocate to the output buffer */ -size_t fd_table_marshal_size(const fd_table_t* restrict this) __attribute__((pure)); +__attribute__((pure, nonnull)) +size_t fd_table_marshal_size(const fd_table_t* restrict this); /** * Marshals a fd table @@ -162,6 +171,7 @@ size_t fd_table_marshal_size(const fd_table_t* restrict this) __attribute__((pur * @param this The fd table * @param data Output buffer for the marshalled data */ +__attribute__((nonnull)) void fd_table_marshal(const fd_table_t* restrict this, char* restrict data); /** @@ -173,6 +183,7 @@ void fd_table_marshal(const fd_table_t* restrict this, char* restrict data); * @return Non-zero on error, `errno` will be set accordingly. * Destroy the table on error. */ +__attribute__((nonnull)) int fd_table_unmarshal(fd_table_t* restrict this, char* restrict data, remap_func* remapper); diff --git a/src/libmdsserver/hash-help.h b/src/libmdsserver/hash-help.h index 2216434..f011236 100644 --- a/src/libmdsserver/hash-help.h +++ b/src/libmdsserver/hash-help.h @@ -29,7 +29,8 @@ * @param str The string * @return The hash of the string */ -static inline size_t __attribute__((pure)) string_hash(const char* str) +__attribute__((pure)) +static inline size_t string_hash(const char* str) { size_t hash = 0; @@ -48,7 +49,8 @@ static inline size_t __attribute__((pure)) string_hash(const char* str) * @param str_b The second string * @return Whether the strings are equals */ -static inline int __attribute__((pure)) string_comparator(char* str_a, char* str_b) +__attribute__((pure)) +static inline int string_comparator(char* str_a, char* str_b) { if ((str_a != NULL) && (str_b != NULL) && (str_a != str_b)) return !strcmp((char*)str_a, (char*)str_b); diff --git a/src/libmdsserver/hash-list.h b/src/libmdsserver/hash-list.h index 630c130..4f2c8cb 100644 --- a/src/libmdsserver/hash-list.h +++ b/src/libmdsserver/hash-list.h @@ -124,6 +124,7 @@ typedef size_t T##_key_hash_func(CKEY_T key);\ * @param key_b The second key, will never be `NULL` * @return Whether the keys are equal */\ +__attribute__((pure, nonnull))\ static inline int T##_key_comparer(CKEY_T key_a, CKEY_T key_b);\ \ /** @@ -132,22 +133,27 @@ static inline int T##_key_comparer(CKEY_T key_a, CKEY_T key_b);\ * @param entry The entry, will never be `NULL`, any only used entries will be passed * @return The marshal-size of the entry's key and value */\ +__attribute__((pure, nonnull))\ static inline size_t T##_submarshal_size(const struct T##_entry* entry);\ \ /** * Marshal an entry's key and value * * @param entry The entry, will never be `NULL`, any only used entries will be passed + * @param data The buffer where the entry's key and value will be stored * @return The marshal-size of the entry's key and value */\ +__attribute__((pure, nonnull))\ static inline size_t T##_submarshal(const struct T##_entry* entry, char* restrict data);\ \ /** * Unmarshal an entry's key and value * * @param entry The entry, will never be `NULL`, any only used entries will be passed + * @param data The buffer where the entry's key and value is stored * @return The number of read bytes, zero on error */\ +__attribute__((pure, nonnull))\ static inline size_t T##_subunmarshal(struct T##_entry* entry, char* restrict data);\ \ \ @@ -240,7 +246,7 @@ typedef struct T\ * @param capacity The minimum initial capacity of the hash list, 0 for default * @return Non-zero on error, `errno` will have been set accordingly */\ -static inline int __attribute__((unused))\ +static inline int __attribute__((unused, nonnull))\ T##_create(T##_t* restrict this, size_t capacity)\ {\ if (capacity == 0)\ @@ -267,7 +273,7 @@ T##_create(T##_t* restrict this, size_t capacity)\ * * @param this The hash list */\ -static inline void __attribute__((unused))\ +static inline void __attribute__((unused, nonnull))\ T##_destroy(T##_t* restrict this)\ {\ size_t i, n;\ @@ -291,7 +297,7 @@ T##_destroy(T##_t* restrict this)\ * @param out Memory slot in which to store the new hash list * @return Non-zero on error, `errno` will have been set accordingly */\ -static inline int __attribute__((unused))\ +static inline int __attribute__((unused, nonnull))\ T##_clone(const T##_t* restrict this, T##_t* restrict out)\ {\ if (T##_create(out, this->allocated) < 0)\ @@ -314,7 +320,7 @@ T##_clone(const T##_t* restrict this, T##_t* restrict out)\ * @return Non-zero on error, `errno` will have * been set accordingly. Errors are non-fatal. */\ -static inline int __attribute__((unused))\ +static inline int __attribute__((unused, nonnull))\ T##_pack(T##_t* restrict this)\ {\ size_t i, j, n;\ @@ -352,7 +358,7 @@ T##_pack(T##_t* restrict this)\ * @param value Output parameter for the value * @return Whether the key was found, error is impossible */\ -static inline int __attribute__((unused))\ +static inline int __attribute__((unused, nonnull))\ T##_get(T##_t* restrict this, CKEY_T key, T##_value_t* restrict value)\ {\ size_t i, n, hash = HASH_LIST_HASH(key);\ @@ -370,7 +376,7 @@ T##_get(T##_t* restrict this, CKEY_T key, T##_value_t* restrict value)\ * @param this The hash list * @param key The key of the entry to remove, must not be `NULL` */\ -static inline void __attribute__((unused))\ +static inline void __attribute__((unused, nonnull))\ T##_remove(T##_t* restrict this, CKEY_T key)\ {\ size_t i = this->last, n, hash = HASH_LIST_HASH(key);\ @@ -416,7 +422,7 @@ T##_remove(T##_t* restrict this, CKEY_T key)\ * `NULL` if the entry should be removed instead * @return Non-zero on error, `errno` will have been set accordingly */\ -static inline int __attribute__((unused))\ +static inline int __attribute__((unused, nonnull(1, 2)))\ T##_put(T##_t* restrict this, KEY_T key, const T##_value_t* restrict value)\ {\ size_t i = this->last, n, empty = this->used, hash;\ @@ -486,7 +492,7 @@ T##_put(T##_t* restrict this, KEY_T key, const T##_value_t* restrict value)\ * @param this The hash table * @return The number of bytes to allocate to the output buffer */\ -static inline size_t __attribute__((unused))\ +static inline size_t __attribute__((unused, pure, nonnull))\ T##_marshal_size(const T##_t* restrict this)\ {\ size_t i, n = this->used;\ @@ -504,7 +510,7 @@ T##_marshal_size(const T##_t* restrict this)\ * @param this The hash list * @param data Output buffer for the marshalled data */\ -static inline void __attribute__((unused))\ +static inline void __attribute__((unused, nonnull))\ T##_marshal(const T##_t* restrict this, char* restrict data)\ {\ size_t wrote, i, n = this->used;\ @@ -536,7 +542,7 @@ T##_marshal(const T##_t* restrict this, char* restrict data)\ * @return Non-zero on error, `errno` will be set accordingly. * Destroy the table on error. */\ -static inline int __attribute__((unused))\ +static inline int __attribute__((unused, nonnull))\ T##_unmarshal(T##_t* restrict this, char* restrict data)\ {\ size_t i, n, got;\ diff --git a/src/libmdsserver/hash-table.c b/src/libmdsserver/hash-table.c index 1e637e0..4de2ac5 100644 --- a/src/libmdsserver/hash-table.c +++ b/src/libmdsserver/hash-table.c @@ -42,7 +42,8 @@ * @param key The key to hash * @return The hash of the key */ -static inline size_t __attribute__((const)) hash(const hash_table_t* restrict this, size_t key) +__attribute__((pure, nonnull)) +static inline size_t hash(const hash_table_t* restrict this, size_t key) { return this->hasher ? this->hasher(key) : key; } @@ -55,7 +56,8 @@ static inline size_t __attribute__((const)) hash(const hash_table_t* restrict th * @param key The key to hash * @return A non-negative value less the the table's capacity */ -static inline size_t __attribute__((pure)) truncate_hash(const hash_table_t* restrict this, size_t hash) +__attribute__((pure, nonnull)) +static inline size_t truncate_hash(const hash_table_t* restrict this, size_t hash) { return hash % this->capacity; } @@ -67,6 +69,7 @@ static inline size_t __attribute__((pure)) truncate_hash(const hash_table_t* res * @param this The hash table * @return Non-zero on error, `errno` will be set accordingly */ +__attribute__((nonnull)) static int rehash(hash_table_t* restrict this) { hash_entry_t** old_buckets = this->buckets; diff --git a/src/libmdsserver/hash-table.h b/src/libmdsserver/hash-table.h index 8e20b6e..cbdd509 100644 --- a/src/libmdsserver/hash-table.h +++ b/src/libmdsserver/hash-table.h @@ -125,6 +125,7 @@ typedef struct hash_table * @param load_factor The load factor of the table, i.e. when to grow the table * @return Non-zero on error, `errno` will have been set accordingly */ +__attribute__((nonnull)) int hash_table_create_fine_tuned(hash_table_t* restrict this, size_t initial_capacity, float load_factor); /** @@ -154,6 +155,7 @@ int hash_table_create_fine_tuned(hash_table_t* restrict this, size_t initial_cap * @param keys_freer Function that frees a key, `NULL` if keys should not be freed * @param values_freer Function that frees a value, `NULL` if value should not be freed */ +__attribute__((nonnull(1))) void hash_table_destroy(hash_table_t* restrict this, free_func* key_freer, free_func* value_freer); /** @@ -163,7 +165,8 @@ void hash_table_destroy(hash_table_t* restrict this, free_func* key_freer, free_ * @param value The value * @return Whether the value is stored in the table */ -int hash_table_contains_value(const hash_table_t* restrict this, size_t value) __attribute__((pure)); +__attribute__((pure, nonnull)) +int hash_table_contains_value(const hash_table_t* restrict this, size_t value); /** * Check whether a key is used in the table @@ -172,7 +175,8 @@ int hash_table_contains_value(const hash_table_t* restrict this, size_t value) _ * @param key The key * @return Whether the key is used */ -int hash_table_contains_key(const hash_table_t* restrict this, size_t key) __attribute__((pure)); +__attribute__((pure, nonnull)) +int hash_table_contains_key(const hash_table_t* restrict this, size_t key); /** * Look up a value in the table @@ -181,6 +185,7 @@ int hash_table_contains_key(const hash_table_t* restrict this, size_t key) __att * @param key The key associated with the value * @return The value associated with the key, 0 if the key was not used */ +__attribute__((pure, nonnull)) size_t hash_table_get(const hash_table_t* restrict this, size_t key); /** @@ -190,6 +195,7 @@ size_t hash_table_get(const hash_table_t* restrict this, size_t key); * @param key The key associated with the value * @return The entry associated with the key, `NULL` if the key was not used */ +__attribute__((pure, nonnull)) hash_entry_t* hash_table_get_entry(const hash_table_t* restrict this, size_t key); /** @@ -201,6 +207,7 @@ hash_entry_t* hash_table_get_entry(const hash_table_t* restrict this, size_t key * @return The previous value associated with the key, 0 if the key was not used. * 0 will also be returned on error, check the `errno` variable. */ +__attribute__((nonnull)) size_t hash_table_put(hash_table_t* restrict this, size_t key, size_t value); /** @@ -210,6 +217,7 @@ size_t hash_table_put(hash_table_t* restrict this, size_t key, size_t value); * @param key The key of the entry to remove * @return The previous value associated with the key, 0 if the key was not used */ +__attribute__((nonnull)) size_t hash_table_remove(hash_table_t* restrict this, size_t key); /** @@ -217,6 +225,7 @@ size_t hash_table_remove(hash_table_t* restrict this, size_t key); * * @param this The hash table */ +__attribute__((nonnull)) void hash_table_clear(hash_table_t* restrict this); /** @@ -236,7 +245,8 @@ void hash_table_clear(hash_table_t* restrict this); * @param this The hash table * @return The number of bytes to allocate to the output buffer */ -size_t hash_table_marshal_size(const hash_table_t* restrict this) __attribute__((pure)); +__attribute__((pure, nonnull)) +size_t hash_table_marshal_size(const hash_table_t* restrict this); /** * Marshals a hash table @@ -244,6 +254,7 @@ size_t hash_table_marshal_size(const hash_table_t* restrict this) __attribute__( * @param this The hash table * @param data Output buffer for the marshalled data */ +__attribute__((nonnull)) void hash_table_marshal(const hash_table_t* restrict this, char* restrict data); /** @@ -255,6 +266,7 @@ void hash_table_marshal(const hash_table_t* restrict this, char* restrict data); * @return Non-zero on error, `errno` will be set accordingly. * Destroy the table on error. */ +__attribute__((nonnull)) int hash_table_unmarshal(hash_table_t* restrict this, char* restrict data, remap_func* remapper); diff --git a/src/libmdsserver/linked-list.c b/src/libmdsserver/linked-list.c index f94ea50..8cdd1bd 100644 --- a/src/libmdsserver/linked-list.c +++ b/src/libmdsserver/linked-list.c @@ -38,6 +38,7 @@ * @param value The value to be rounded up to a power of two * @return The nearest, but not smaller, power of two */ +__attribute__((const)) static size_t to_power_of_two(size_t value) { value -= 1; @@ -214,6 +215,7 @@ int linked_list_pack(linked_list_t* restrict this) * @return The next free position, * `LINKED_LIST_UNUSED` on error, `errno` will be set accordingly */ +__attribute__((nonnull)) static ssize_t linked_list_get_next(linked_list_t* restrict this) { size_t* tmp_values; @@ -246,6 +248,7 @@ static ssize_t linked_list_get_next(linked_list_t* restrict this) * @param node The position * @return The position */ +__attribute__((nonnull)) static ssize_t linked_list_unuse(linked_list_t* restrict this, ssize_t node) { if (node < 0) diff --git a/src/libmdsserver/linked-list.h b/src/libmdsserver/linked-list.h index 1a22623..a99204c 100644 --- a/src/libmdsserver/linked-list.h +++ b/src/libmdsserver/linked-list.h @@ -118,6 +118,7 @@ typedef struct linked_list * @param capacity The minimum initial capacity of the linked list, 0 for default * @return Non-zero on error, `errno` will have been set accordingly */ +__attribute__((nonnull)) int linked_list_create(linked_list_t* restrict this, size_t capacity); /** @@ -126,6 +127,7 @@ int linked_list_create(linked_list_t* restrict this, size_t capacity); * * @param this The linked list */ +__attribute__((nonnull)) void linked_list_destroy(linked_list_t* restrict this); /** @@ -135,6 +137,7 @@ void linked_list_destroy(linked_list_t* restrict this); * @param out Memory slot in which to store the new linked list * @return Non-zero on error, `errno` will have been set accordingly */ +__attribute__((nonnull)) int linked_list_clone(const linked_list_t* restrict this, linked_list_t* restrict out); /** @@ -151,6 +154,7 @@ int linked_list_clone(const linked_list_t* restrict this, linked_list_t* restric * @param this The list * @return Non-zero on error, `errno` will have been set accordingly */ +__attribute__((nonnull)) int linked_list_pack(linked_list_t* restrict this); /** @@ -182,6 +186,7 @@ int linked_list_pack(linked_list_t* restrict this); * @return The node that has been created and inserted, * `LINKED_LIST_UNUSED` on error, `errno` will be set accordingly */ +__attribute__((nonnull)) ssize_t linked_list_insert_after(linked_list_t* restrict this, size_t value, ssize_t predecessor); /** @@ -191,6 +196,7 @@ ssize_t linked_list_insert_after(linked_list_t* restrict this, size_t value, ssi * @param predecessor The reference node * @return The node that has been removed */ +__attribute__((nonnull)) ssize_t linked_list_remove_after(linked_list_t* restrict this, ssize_t predecessor); /** @@ -202,6 +208,7 @@ ssize_t linked_list_remove_after(linked_list_t* restrict this, ssize_t predecess * @return The node that has been created and inserted, * `LINKED_LIST_UNUSED` on error, `errno` will be set accordingly */ +__attribute__((nonnull)) ssize_t linked_list_insert_before(linked_list_t* restrict this, size_t value, ssize_t successor); /** @@ -211,6 +218,7 @@ ssize_t linked_list_insert_before(linked_list_t* restrict this, size_t value, ss * @param successor The reference node * @return The node that has been removed */ +__attribute__((nonnull)) ssize_t linked_list_remove_before(linked_list_t* restrict this, ssize_t successor); /** @@ -219,6 +227,7 @@ ssize_t linked_list_remove_before(linked_list_t* restrict this, ssize_t successo * @param this The list * @param node The node to remove */ +__attribute__((nonnull)) void linked_list_remove(linked_list_t* restrict this, ssize_t node); /** @@ -247,7 +256,8 @@ void linked_list_remove(linked_list_t* restrict this, ssize_t node); * @param this The list * @return The number of bytes to allocate to the output buffer */ -size_t linked_list_marshal_size(const linked_list_t* restrict this) __attribute__((pure)); +__attribute__((pure, nonnull)) +size_t linked_list_marshal_size(const linked_list_t* restrict this); /** * Marshals a linked list @@ -255,6 +265,7 @@ size_t linked_list_marshal_size(const linked_list_t* restrict this) __attribute_ * @param this The list * @param data Output buffer for the marshalled data */ +__attribute__((nonnull)) void linked_list_marshal(const linked_list_t* restrict this, char* restrict data); /** @@ -265,6 +276,7 @@ void linked_list_marshal(const linked_list_t* restrict this, char* restrict data * @return Non-zero on error, `errno` will be set accordingly. * Destroy the list on error. */ +__attribute__((nonnull)) int linked_list_unmarshal(linked_list_t* restrict this, char* restrict data); /** @@ -282,6 +294,7 @@ int linked_list_unmarshal(linked_list_t* restrict this, char* restrict data); * @param this The list * @param output Output file */ +__attribute__((nonnull)) void linked_list_dump(linked_list_t* restrict this, FILE* restrict output); diff --git a/src/libmdsserver/mds-message.c b/src/libmdsserver/mds-message.c index 78adc0f..f673324 100644 --- a/src/libmdsserver/mds-message.c +++ b/src/libmdsserver/mds-message.c @@ -115,6 +115,7 @@ int mds_message_extend_headers(mds_message_t* restrict this, size_t extent) * @param this The message * @return Zero on success, -1 on error */ +__attribute__((nonnull)) static int mds_message_extend_buffer(mds_message_t* restrict this) { char* new_buf = this->buffer; @@ -132,6 +133,7 @@ static int mds_message_extend_buffer(mds_message_t* restrict this) * * @param this The message */ +__attribute__((nonnull)) static void reset_message(mds_message_t* restrict this) { size_t i; @@ -152,6 +154,7 @@ static void reset_message(mds_message_t* restrict this) * @param this The message * @return Zero on success, negative on error (malformated message: unrecoverable state) */ +__attribute__((pure, nonnull)) static int get_payload_length(mds_message_t* restrict this) { char* header; @@ -184,7 +187,8 @@ static int get_payload_length(mds_message_t* restrict this) * @param length The length of the header * @return Zero if valid, negative if invalid (malformated message: unrecoverable state) */ -static int __attribute__((pure)) validate_header(const char* header, size_t length) +__attribute__((pure, nonnull)) +static int validate_header(const char* header, size_t length) { char* p = memchr(header, ':', length * sizeof(char)); @@ -208,6 +212,7 @@ static int __attribute__((pure)) validate_header(const char* header, size_t leng * @param length The number of characters to remove * @param update_ptr Whether to update the buffer pointer */ +__attribute__((nonnull)) static void unbuffer_beginning(mds_message_t* restrict this, size_t length, int update_ptr) { memmove(this->buffer, this->buffer + length, (this->buffer_ptr - length) * sizeof(char)); @@ -223,6 +228,7 @@ static void unbuffer_beginning(mds_message_t* restrict this, size_t length, int * @param this The message * @return The return value follows the rules of `mds_message_read` */ +__attribute__((nonnull)) static int initialise_payload(mds_message_t* restrict this) { /* Remove the \n (end of empty line) we found from the buffer. */ @@ -249,6 +255,7 @@ static int initialise_payload(mds_message_t* restrict this) * @param length The length of the header, including LF-termination * @return The return value follows the rules of `mds_message_read` */ +__attribute__((nonnull)) static int store_header(mds_message_t* restrict this, size_t length) { char* header; @@ -287,6 +294,7 @@ static int store_header(mds_message_t* restrict this, size_t length) * @param fd The file descriptor of the socket * @return The return value follows the rules of `mds_message_read` */ +__attribute__((nonnull)) static int continue_read(mds_message_t* restrict this, int fd) { size_t n; diff --git a/src/libmdsserver/mds-message.h b/src/libmdsserver/mds-message.h index 10dfaf5..d8a26bb 100644 --- a/src/libmdsserver/mds-message.h +++ b/src/libmdsserver/mds-message.h @@ -90,6 +90,7 @@ typedef struct mds_message * @return Non-zero on error, `errno` will be set accordingly. * Destroy the message on error. */ +__attribute__((nonnull)) int mds_message_initialise(mds_message_t* restrict this); /** @@ -97,6 +98,7 @@ int mds_message_initialise(mds_message_t* restrict this); * * @param this Memory slot in which to store the new message */ +__attribute__((nonnull)) void mds_message_zero_initialise(mds_message_t* restrict this); /** @@ -105,6 +107,7 @@ void mds_message_zero_initialise(mds_message_t* restrict this); * * @param this The message */ +__attribute__((nonnull)) void mds_message_destroy(mds_message_t* restrict this); /** @@ -114,6 +117,7 @@ void mds_message_destroy(mds_message_t* restrict this); * @param extent The number of additional entries * @return Zero on success, -1 on error */ +__attribute__((nonnull)) int mds_message_extend_headers(mds_message_t* restrict this, size_t extent); /** @@ -129,6 +133,7 @@ int mds_message_extend_headers(mds_message_t* restrict this, size_t extent); * -2 indicates that the message is malformated, * which is a state that cannot be recovered from. */ +__attribute__((nonnull)) int mds_message_read(mds_message_t* restrict this, int fd); /** @@ -138,7 +143,8 @@ int mds_message_read(mds_message_t* restrict this, int fd); * @param this The message * @return The size of the message when marshalled */ -size_t mds_message_marshal_size(const mds_message_t* restrict this) __attribute__((pure)); +__attribute__((pure, nonnull)) +size_t mds_message_marshal_size(const mds_message_t* restrict this); /** * Marshal a message for state serialisation @@ -146,6 +152,7 @@ size_t mds_message_marshal_size(const mds_message_t* restrict this) __attribute_ * @param this The message * @param data Output buffer for the marshalled data */ +__attribute__((nonnull)) void mds_message_marshal(const mds_message_t* restrict this, char* restrict data); /** @@ -156,6 +163,7 @@ void mds_message_marshal(const mds_message_t* restrict this, char* restrict data * @return Non-zero on error, `errno` will be set accordingly. * Destroy the message on error. */ +__attribute__((nonnull)) int mds_message_unmarshal(mds_message_t* restrict this, char* restrict data); /** @@ -165,7 +173,8 @@ int mds_message_unmarshal(mds_message_t* restrict this, char* restrict data); * @param this The message * @return The size of the message when marshalled */ -size_t mds_message_compose_size(const mds_message_t* restrict this) __attribute__((pure)); +__attribute__((pure, nonnull)) +size_t mds_message_compose_size(const mds_message_t* restrict this); /** * Marshal a message for communication @@ -173,6 +182,7 @@ size_t mds_message_compose_size(const mds_message_t* restrict this) __attribute_ * @param this The message * @param data Output buffer for the marshalled data */ +__attribute__((nonnull)) void mds_message_compose(const mds_message_t* restrict this, char* restrict data); diff --git a/src/libmdsserver/util.h b/src/libmdsserver/util.h index e6fa5ee..b86ffd5 100644 --- a/src/libmdsserver/util.h +++ b/src/libmdsserver/util.h @@ -30,6 +30,7 @@ * @param str The client ID string * @return The client ID integer */ +__attribute__((pure, nonnull)) uint64_t parse_client_id(const char* str); /** @@ -38,6 +39,7 @@ uint64_t parse_client_id(const char* str); * @param var The environment variable's name * @return The environment variable's value, `NULL` if empty or not defined */ +__attribute__((nonnull)) char* getenv_nonempty(const char* var); /** @@ -107,6 +109,7 @@ size_t send_message(int socket, const char* message, size_t length); * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_atoi(const char* str, int* value, int min, int max); /** @@ -118,6 +121,7 @@ int strict_atoi(const char* str, int* value, int min, int max); * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_atoj(const char* str, intmax_t* value, intmax_t min, intmax_t max); /** @@ -129,6 +133,7 @@ int strict_atoj(const char* str, intmax_t* value, intmax_t min, intmax_t max); * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_atouj(const char* str, uintmax_t* value, uintmax_t min, uintmax_t max); /** @@ -140,6 +145,7 @@ int strict_atouj(const char* str, uintmax_t* value, uintmax_t min, uintmax_t max * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_atoh(const char* str, short int* value, int min, int max); /** @@ -151,6 +157,7 @@ int strict_atoh(const char* str, short int* value, int min, int max); * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_atouh(const char* str, unsigned short int* value, unsigned int min, unsigned int max); /** @@ -162,6 +169,7 @@ int strict_atouh(const char* str, unsigned short int* value, unsigned int min, u * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_atou(const char* str, unsigned int* value, unsigned int min, unsigned int max); /** @@ -173,6 +181,7 @@ int strict_atou(const char* str, unsigned int* value, unsigned int min, unsigned * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_atol(const char* str, long int* value, long int min, long int max); /** @@ -184,6 +193,7 @@ int strict_atol(const char* str, long int* value, long int min, long int max); * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_atoul(const char* str, unsigned long int* value, unsigned long int min, unsigned long int max); /** @@ -195,6 +205,7 @@ int strict_atoul(const char* str, unsigned long int* value, unsigned long int mi * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_atoll(const char* str, long long int* value, long long int min, long long int max); /** @@ -206,6 +217,7 @@ int strict_atoll(const char* str, long long int* value, long long int min, long * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_atoull(const char* str, unsigned long long int* value, unsigned long long int min, unsigned long long int max); @@ -218,6 +230,7 @@ int strict_atoull(const char* str, unsigned long long int* value, * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_atoz(const char* str, size_t* value, size_t min, size_t max); /** @@ -229,6 +242,7 @@ int strict_atoz(const char* str, size_t* value, size_t min, size_t max); * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_atosz(const char* str, ssize_t* value, ssize_t min, ssize_t max); /** @@ -240,6 +254,7 @@ int strict_atosz(const char* str, ssize_t* value, ssize_t min, ssize_t max); * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_ato8(const char* str, int8_t* value, int min, int max); /** @@ -251,6 +266,7 @@ int strict_ato8(const char* str, int8_t* value, int min, int max); * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_atou8(const char* str, uint8_t* value, int min, int max); /** @@ -262,6 +278,7 @@ int strict_atou8(const char* str, uint8_t* value, int min, int max); * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_ato16(const char* str, int16_t* value, int min, int max); /** @@ -273,6 +290,7 @@ int strict_ato16(const char* str, int16_t* value, int min, int max); * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_atou16(const char* str, uint16_t* value, unsigned int min, unsigned int max); /** @@ -284,6 +302,7 @@ int strict_atou16(const char* str, uint16_t* value, unsigned int min, unsigned i * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_ato32(const char* str, int32_t* value, int32_t min, int32_t max); /** @@ -295,6 +314,7 @@ int strict_ato32(const char* str, int32_t* value, int32_t min, int32_t max); * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_atou32(const char* str, uint32_t* value, uint32_t min, uint32_t max); /** @@ -306,6 +326,7 @@ int strict_atou32(const char* str, uint32_t* value, uint32_t min, uint32_t max); * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_ato64(const char* str, int64_t* value, int64_t min, int64_t max); /** @@ -317,6 +338,7 @@ int strict_ato64(const char* str, int64_t* value, int64_t min, int64_t max); * @param max The maximum accepted value * @return Zero on success, -1 on syntax error */ +__attribute__((nonnull)) int strict_atou64(const char* str, uint64_t* value, uint64_t min, uint64_t max); /** @@ -358,7 +380,8 @@ int full_send(int socket, const char* message, size_t length); * @param needle_n The length of `needle` * @return Whether the `haystack` begins with `needle` */ -int startswith_n(const char* haystack, const char* needle, size_t haystack_n, size_t needle_n) __attribute__((pure)); +__attribute__((pure, nonnull)) +int startswith_n(const char* haystack, const char* needle, size_t haystack_n, size_t needle_n); /** * Wrapper around `waitpid` that never returns on an interruption unless @@ -378,7 +401,8 @@ pid_t uninterruptable_waitpid(pid_t pid, int* restrict status, int options); * @param allow_modified_nul Whether Modified UTF-8 is allowed, which allows a two-byte encoding for NUL * @return Zero if good, -1 on encoding error */ -int verify_utf8(const char* string, int allow_modified_nul) __attribute__((pure)); +__attribute__((pure, nonnull)) +int verify_utf8(const char* string, int allow_modified_nul); /** * Construct an error message to be sent to a client @@ -405,11 +429,11 @@ int verify_utf8(const char* string, int allow_modified_nul) __attribute__((pure) * @param message_id The message ID of this message * @return The length of the message, zero on error */ +__attribute__((nonnull(1, 2, 3, 7, 8))) size_t construct_error_message(const char* restrict recv_client_id, const char* restrict recv_message_id, const char* restrict recv_command, int custom, int errnum, const char* restrict message, char** restrict send_buffer, - size_t* restrict send_buffer_size, - uint32_t message_id) __attribute__((nonnull(1, 2, 3, 7, 8))); + size_t* restrict send_buffer_size, uint32_t message_id); /** * Send an error message @@ -437,10 +461,11 @@ size_t construct_error_message(const char* restrict recv_client_id, const char* * @param socket_fd The file descriptor of the socket * @return Zero on success, -1 on error */ +__attribute__((nonnull(1, 2, 3, 7, 8))) int send_error(const char* restrict recv_client_id, const char* restrict recv_message_id, const char* restrict recv_command, int custom, int errnum, const char* restrict message, char** restrict send_buffer, size_t* restrict send_buffer_size, uint32_t message_id, - int socket_fd) __attribute__((nonnull(1, 2, 3, 7, 8))); + int socket_fd); #endif |