aboutsummaryrefslogtreecommitdiffstats
path: root/src/libmdsserver
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmdsserver')
-rw-r--r--src/libmdsserver/client-list.c1
-rw-r--r--src/libmdsserver/client-list.h10
-rw-r--r--src/libmdsserver/fd-table.h19
-rw-r--r--src/libmdsserver/hash-help.h6
-rw-r--r--src/libmdsserver/hash-list.h26
-rw-r--r--src/libmdsserver/hash-table.c7
-rw-r--r--src/libmdsserver/hash-table.h18
-rw-r--r--src/libmdsserver/linked-list.c3
-rw-r--r--src/libmdsserver/linked-list.h15
-rw-r--r--src/libmdsserver/mds-message.c10
-rw-r--r--src/libmdsserver/mds-message.h14
-rw-r--r--src/libmdsserver/util.h35
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