aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libmdsserver/client-list.c197
-rw-r--r--src/libmdsserver/client-list.h4
-rw-r--r--src/libmdsserver/fd-table.c326
-rw-r--r--src/libmdsserver/fd-table.h4
-rw-r--r--src/libmdsserver/hash-list.h581
-rw-r--r--src/libmdsserver/hash-table.c581
-rw-r--r--src/libmdsserver/linked-list.c532
-rw-r--r--src/libmdsserver/macros.h458
-rw-r--r--src/libmdsserver/mds-message.c727
-rw-r--r--src/libmdsserver/util.c867
-rw-r--r--src/mds-base.h6
-rw-r--r--src/mds-clipboard.h12
-rw-r--r--src/mds-colour.h5
-rw-r--r--src/mds-echo.c3
-rw-r--r--src/mds-echo.h1
-rw-r--r--src/mds-kbdc/builtin-functions.c337
-rw-r--r--src/mds-kbdc/builtin-functions.h6
-rw-r--r--src/mds-kbdc/call-stack.c180
-rw-r--r--src/mds-kbdc/call-stack.h9
-rw-r--r--src/mds-kbdc/callables.c191
-rw-r--r--src/mds-kbdc/callables.h9
-rw-r--r--src/mds-kbdc/compile-layout.c3745
-rw-r--r--src/mds-kbdc/compile-layout.h3
-rw-r--r--src/mds-kbdc/eliminate-dead-code.c155
-rw-r--r--src/mds-kbdc/eliminate-dead-code.h3
-rw-r--r--src/mds-kbdc/globals.c3
-rw-r--r--src/mds-kbdc/globals.h3
-rw-r--r--src/mds-kbdc/include-stack.c232
-rw-r--r--src/mds-kbdc/include-stack.h65
-rw-r--r--src/mds-kbdc/make-tree.c1705
-rw-r--r--src/mds-kbdc/make-tree.h3
-rw-r--r--src/mds-kbdc/mds-kbdc.c80
-rw-r--r--src/mds-kbdc/mds-kbdc.h1
-rw-r--r--src/mds-kbdc/parse-error.c210
-rw-r--r--src/mds-kbdc/parse-error.h109
-rw-r--r--src/mds-kbdc/parsed.c168
-rw-r--r--src/mds-kbdc/parsed.h246
-rw-r--r--src/mds-kbdc/paths.c222
-rw-r--r--src/mds-kbdc/paths.h7
-rw-r--r--src/mds-kbdc/process-includes.c397
-rw-r--r--src/mds-kbdc/process-includes.h3
-rw-r--r--src/mds-kbdc/raw-data.c708
-rw-r--r--src/mds-kbdc/raw-data.h86
-rw-r--r--src/mds-kbdc/simplify-tree.c1283
-rw-r--r--src/mds-kbdc/simplify-tree.h3
-rw-r--r--src/mds-kbdc/string.c166
-rw-r--r--src/mds-kbdc/string.h12
-rw-r--r--src/mds-kbdc/tree.c731
-rw-r--r--src/mds-kbdc/tree.h720
-rw-r--r--src/mds-kbdc/validate-tree.c514
-rw-r--r--src/mds-kbdc/validate-tree.h3
-rw-r--r--src/mds-kbdc/variables.c247
-rw-r--r--src/mds-kbdc/variables.h12
-rw-r--r--src/mds-kkbd.c2
-rw-r--r--src/mds-libinput.h1
-rw-r--r--src/mds-registry/mds-registry.c3
-rw-r--r--src/mds-registry/registry.c5
-rw-r--r--src/mds-registry/signals.c3
-rw-r--r--src/mds-registry/slave.h4
-rw-r--r--src/mds-registry/util.c6
-rw-r--r--src/mds-respawn.h5
-rw-r--r--src/mds-server/client.h4
-rw-r--r--src/mds-server/globals.h1
-rw-r--r--src/mds-server/interception-condition.h4
-rw-r--r--src/mds-server/interceptors.h2
-rw-r--r--src/mds-server/multicast.h4
-rw-r--r--src/mds-server/queued-interception.h4
-rw-r--r--src/mds-vt.c2
-rw-r--r--src/mds.h7
69 files changed, 8415 insertions, 8523 deletions
diff --git a/src/libmdsserver/client-list.c b/src/libmdsserver/client-list.c
index 19eaf5a..02d555e 100644
--- a/src/libmdsserver/client-list.c
+++ b/src/libmdsserver/client-list.c
@@ -27,7 +27,7 @@
* The default initial capacity
*/
#ifndef CLIENT_LIST_DEFAULT_INITIAL_CAPACITY
-#define CLIENT_LIST_DEFAULT_INITIAL_CAPACITY 8
+# define CLIENT_LIST_DEFAULT_INITIAL_CAPACITY 8
#endif
@@ -38,19 +38,19 @@
* @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)
+static size_t __attribute__((const))
+to_power_of_two(size_t value)
{
- value -= 1;
- value |= value >> 1;
- value |= value >> 2;
- value |= value >> 4;
- value |= value >> 8;
- value |= value >> 16;
+ value -= 1;
+ value |= value >> 1;
+ value |= value >> 2;
+ value |= value >> 4;
+ value |= value >> 8;
+ value |= value >> 16;
#if SIZE_MAX == UINT64_MAX
- value |= value >> 32;
+ value |= value >> 32;
#endif
- return value + 1;
+ return value + 1;
}
@@ -61,21 +61,22 @@ static size_t to_power_of_two(size_t value)
* @param capacity The minimum initial capacity of the client list, 0 for default
* @return Non-zero on error, `errno` will have been set accordingly
*/
-int client_list_create(client_list_t* restrict this, size_t capacity)
+int
+client_list_create(client_list_t *restrict this, size_t capacity)
{
- /* Use default capacity of zero is specified. */
- if (capacity == 0)
- capacity = CLIENT_LIST_DEFAULT_INITIAL_CAPACITY;
-
- /* Initialise the client list. */
- this->capacity = capacity = to_power_of_two(capacity);
- this->size = 0;
- this->clients = NULL;
- fail_if (xmalloc(this->clients, capacity, uint64_t));
-
- return 0;
- fail:
- return -1;
+ /* Use default capacity of zero is specified. */
+ if (!capacity)
+ capacity = CLIENT_LIST_DEFAULT_INITIAL_CAPACITY;
+
+ /* Initialise the client list. */
+ this->capacity = capacity = to_power_of_two(capacity);
+ this->size = 0;
+ this->clients = NULL;
+ fail_if (xmalloc(this->clients, capacity, uint64_t));
+
+ return 0;
+fail:
+ return -1;
}
@@ -85,10 +86,11 @@ int client_list_create(client_list_t* restrict this, size_t capacity)
*
* @param this The client list
*/
-void client_list_destroy(client_list_t* restrict this)
+void
+client_list_destroy(client_list_t *restrict this)
{
- free(this->clients);
- this->clients = NULL;
+ free(this->clients);
+ this->clients = NULL;
}
@@ -99,17 +101,18 @@ 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
*/
-int client_list_clone(const client_list_t* restrict this, client_list_t* restrict out)
+int
+client_list_clone(const client_list_t *restrict this, client_list_t *restrict out)
{
- fail_if (xmemdup(out->clients, this->clients, this->capacity, uint64_t));
-
- out->capacity = this->capacity;
- out->size = this->size;
-
- return 0;
-
- fail:
- return -1;
+ fail_if (xmemdup(out->clients, this->clients, this->capacity, uint64_t));
+
+ out->capacity = this->capacity;
+ out->size = this->size;
+
+ return 0;
+
+fail:
+ return -1;
}
@@ -120,23 +123,23 @@ 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
*/
-int client_list_add(client_list_t* restrict this, uint64_t client)
+int
+client_list_add(client_list_t *restrict this, uint64_t client)
{
- if (this->size == this->capacity)
- {
- uint64_t* old = this->clients;
- if (xrealloc(old, this->capacity <<= 1, uint64_t))
- {
- this->capacity >>= 1;
- this->clients = old;
- fail_if (1);
+ uint64_t* old;
+ if (this->size == this->capacity) {
+ old = this->clients;
+ if (xrealloc(old, this->capacity <<= 1, uint64_t)) {
+ this->capacity >>= 1;
+ this->clients = old;
+ fail_if (1);
+ }
}
- }
-
- this->clients[this->size++] = client;
- return 0;
- fail:
- return -1;
+
+ this->clients[this->size++] = client;
+ return 0;
+fail:
+ return -1;
}
@@ -146,29 +149,27 @@ int client_list_add(client_list_t* restrict this, uint64_t client)
* @param this The list
* @param client The client to remove
*/
-void client_list_remove(client_list_t* restrict this, uint64_t client)
+void
+client_list_remove(client_list_t *restrict this, uint64_t client)
{
- size_t i;
- for (i = 0; i < this->size; i++)
- {
- if (this->clients[i] == client)
- {
- size_t n = (--(this->size) - i) * sizeof(uint64_t);
- memmove(this->clients + i, this->clients + i + 1, n);
-
- if (this->size << 1 <= this->capacity)
- {
- uint64_t* old = this->clients;
- if (xrealloc(old, this->capacity >>= 1, uint64_t))
- {
- this->capacity <<= 1;
- this->clients = old;
+ size_t i, n;
+ uint64_t *old;
+ for (i = 0; i < this->size; i++) {
+ if (this->clients[i] == client) {
+ n = (--(this->size) - i) * sizeof(uint64_t);
+ memmove(this->clients + i, this->clients + i + 1, n);
+
+ if (this->size << 1 <= this->capacity) {
+ old = this->clients;
+ if (xrealloc(old, this->capacity >>= 1, uint64_t)) {
+ this->capacity <<= 1;
+ this->clients = old;
+ }
+ }
+
+ return;
}
- }
-
- return;
}
- }
}
@@ -178,9 +179,10 @@ 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)
+size_t
+client_list_marshal_size(const client_list_t *restrict this)
{
- return 2 * sizeof(size_t) + this->size * sizeof(uint64_t) + sizeof(int);
+ return 2 * sizeof(size_t) + this->size * sizeof(uint64_t) + sizeof(int);
}
@@ -190,13 +192,14 @@ size_t client_list_marshal_size(const client_list_t* restrict this)
* @param this The list
* @param data Output buffer for the marshalled data
*/
-void client_list_marshal(const client_list_t* restrict this, char* restrict data)
+void
+client_list_marshal(const client_list_t *restrict this, char *restrict data)
{
- buf_set_next(data, int, CLIENT_LIST_T_VERSION);
- buf_set_next(data, size_t, this->capacity);
- buf_set_next(data, size_t, this->size);
-
- memcpy(data, this->clients, this->size * sizeof(uint64_t));
+ buf_set_next(data, int, CLIENT_LIST_T_VERSION);
+ buf_set_next(data, size_t, this->capacity);
+ buf_set_next(data, size_t, this->size);
+
+ memcpy(data, this->clients, this->size * sizeof(uint64_t));
}
@@ -208,21 +211,21 @@ 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.
*/
-int client_list_unmarshal(client_list_t* restrict this, char* restrict data)
+int
+client_list_unmarshal(client_list_t *restrict this, char *restrict data)
{
- /* buf_get(data, int, 0, CLIENT_LIST_T_VERSION); */
- buf_next(data, int, 1);
-
- this->clients = NULL;
-
- buf_get_next(data, size_t, this->capacity);
- buf_get_next(data, size_t, this->size);
-
- fail_if (xmalloc(this->clients, this->capacity, uint64_t));
- memcpy(this->clients, data, this->size * sizeof(uint64_t));
-
- return 0;
- fail:
- return -1;
-}
+ /* buf_get(data, int, 0, CLIENT_LIST_T_VERSION); */
+ buf_next(data, int, 1);
+
+ this->clients = NULL;
+
+ buf_get_next(data, size_t, this->capacity);
+ buf_get_next(data, size_t, this->size);
+ fail_if (xmalloc(this->clients, this->capacity, uint64_t));
+ memcpy(this->clients, data, this->size * sizeof(uint64_t));
+
+ return 0;
+fail:
+ return -1;
+}
diff --git a/src/libmdsserver/client-list.h b/src/libmdsserver/client-list.h
index 4d2bfa7..ffe828a 100644
--- a/src/libmdsserver/client-list.h
+++ b/src/libmdsserver/client-list.h
@@ -30,8 +30,7 @@
/**
* Dynamic array of client ID:s
*/
-typedef struct client_list
-{
+typedef struct client_list {
/**
* The size of the array
*/
@@ -46,7 +45,6 @@ typedef struct client_list
* Stored client ID:s
*/
uint64_t *clients;
-
} client_list_t;
diff --git a/src/libmdsserver/fd-table.c b/src/libmdsserver/fd-table.c
index 1db2d87..fafaa65 100644
--- a/src/libmdsserver/fd-table.c
+++ b/src/libmdsserver/fd-table.c
@@ -31,29 +31,30 @@
* @param initial_capacity The initial capacity of the table
* @return Non-zero on error, `errno` will have been set accordingly
*/
-int fd_table_create_tuned(fd_table_t* restrict this, size_t initial_capacity)
+int
+fd_table_create_tuned(fd_table_t *restrict this, size_t initial_capacity)
{
- size_t bitcap;
-
- this->capacity = initial_capacity ? initial_capacity : 1;
- this->size = 0;
-
- this->values = NULL;
- this->used = NULL;
- this->value_comparator = NULL;
-
- /* It is important that both allocations are done with calloc:
- `this->used` must set all keys as unused at the initial state,
- `this->values` must be initialised for marshaling and it helps
- the time overhead of `fd_table_contains_value`. */
-
- bitcap = (this->capacity + 63) / 64;
- fail_if (xcalloc(this->used, bitcap, size_t));
- fail_if (xcalloc(this->values, this->capacity, size_t));
-
- return 0;
- fail:
- return -1;
+ size_t bitcap;
+
+ this->capacity = initial_capacity ? initial_capacity : 1;
+ this->size = 0;
+
+ this->values = NULL;
+ this->used = NULL;
+ this->value_comparator = NULL;
+
+ /* It is important that both allocations are done with calloc:
+ `this->used` must set all keys as unused at the initial state,
+ `this->values` must be initialised for marshaling and it helps
+ the time overhead of `fd_table_contains_value`. */
+
+ bitcap = (this->capacity + 63) / 64;
+ fail_if (xcalloc(this->used, bitcap, size_t));
+ fail_if (xcalloc(this->values, this->capacity, size_t));
+
+ return 0;
+fail:
+ return -1;
}
@@ -65,20 +66,20 @@ 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
*/
-void fd_table_destroy(fd_table_t* restrict this, free_func* key_freer, free_func* value_freer)
+void
+fd_table_destroy(fd_table_t *restrict this, free_func *key_freer, free_func *value_freer)
{
- if (((key_freer != NULL) || (value_freer != NULL)) && (this->used != NULL) && (this->values != NULL))
- {
- size_t i;
- for (i = 0; i < this->capacity; i++)
- if (this->used[i / 64] & ((uint64_t)1 << (i % 64)))
- {
- if (key_freer != NULL) key_freer(i);
- if (value_freer != NULL) value_freer(this->values[i]);
- }
- }
- free(this->values);
- free(this->used);
+ size_t i;
+ if ((key_freer || value_freer) && this->used && this->values) {
+ for (i = 0; i < this->capacity; i++) {
+ if (this->used[i / 64] & ((uint64_t)1 << (i % 64))) {
+ if (key_freer) key_freer(i);
+ if (value_freer) value_freer(this->values[i]);
+ }
+ }
+ }
+ free(this->values);
+ free(this->used);
}
@@ -89,24 +90,22 @@ 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)
+int
+fd_table_contains_value(const fd_table_t *restrict this, size_t value)
{
- size_t i;
- if (this->value_comparator == NULL)
- {
- for (i = 0; i < this->capacity; i++)
- if (this->values[i] == value)
- if (this->used[i / 64] & ((uint64_t)1 << (i % 64)))
- return 1;
- }
- else
- {
- for (i = 0; i < this->capacity; i++)
- if (this->used[i / 64] & ((uint64_t)1 << (i % 64)))
- if (this->value_comparator(this->values[i], value))
- return 1;
- }
- return 0;
+ size_t i;
+ if (!this->value_comparator) {
+ for (i = 0; i < this->capacity; i++)
+ if (this->values[i] == value)
+ if (this->used[i / 64] & ((uint64_t)1 << (i % 64)))
+ return 1;
+ } else {
+ for (i = 0; i < this->capacity; i++)
+ if (this->used[i / 64] & ((uint64_t)1 << (i % 64)))
+ if (this->value_comparator(this->values[i], value))
+ return 1;
+ }
+ return 0;
}
@@ -117,9 +116,10 @@ int fd_table_contains_value(const fd_table_t* restrict this, size_t value)
* @param key The key
* @return Whether the key is used
*/
-int fd_table_contains_key(const fd_table_t* restrict this, int key)
+int
+fd_table_contains_key(const fd_table_t *restrict this, int key)
{
- return ((size_t)key < this->capacity) && (this->used[key / 64] & ((uint64_t)1 << (key % 64)));
+ return (size_t)key < this->capacity && (this->used[key / 64] & ((uint64_t)1 << (key % 64)));
}
@@ -130,11 +130,10 @@ int fd_table_contains_key(const fd_table_t* restrict this, int key)
* @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)
+size_t
+fd_table_get(const fd_table_t *restrict this, int key)
{
- if (fd_table_contains_key(this, key) == 0)
- return 0;
- return this->values[key];
+ return fd_table_contains_key(this, key) ? this->values[key] : 0;
}
@@ -147,55 +146,53 @@ size_t fd_table_get(const fd_table_t* restrict this, int 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.
*/
-size_t fd_table_put(fd_table_t* restrict this, int key, size_t value)
+size_t
+fd_table_put(fd_table_t *restrict this, int key, size_t value)
{
- /* Override current value if the key is already used. */
- if (fd_table_contains_key(this, key))
- {
- size_t rc = fd_table_get(this, key);
- this->values[key] = value;
- return rc;
- }
-
- /* Grow the table if it is too small. */
- errno = 0;
- if ((size_t)key >= this->capacity)
- {
- size_t* old_values = this->values;
- size_t old_bitcap, new_bitcap;
- if (xrealloc(this->values, this->capacity << 1, size_t))
- {
- this->values = old_values;
- fail_if (1);
+ size_t rc, old_bitcap, new_bitcap, *old_values;
+ uint64_t *old_used;
+
+ /* Override current value if the key is already used. */
+ if (fd_table_contains_key(this, key)) {
+ rc = fd_table_get(this, key);
+ this->values[key] = value;
+ return rc;
}
+
+ /* Grow the table if it is too small. */
+ errno = 0;
+ if ((size_t)key >= this->capacity) {
+ old_values = this->values;
+ if (xrealloc(this->values, this->capacity << 1, size_t)) {
+ this->values = old_values;
+ fail_if (1);
+ }
+
+ memset(this->values + this->capacity, 0, this->capacity * sizeof(size_t));
- memset(this->values + this->capacity, 0, this->capacity * sizeof(size_t));
-
- old_bitcap = (this->capacity + 63) / 64;
- this->capacity <<= 1;
- new_bitcap = (this->capacity + 63) / 64;
-
- if (new_bitcap > old_bitcap)
- {
- uint64_t* old_used = this->used;
- if (xrealloc(this->used, new_bitcap, size_t))
- {
- this->used = old_used;
- this->capacity >>= 1;
- fail_if (1);
- }
-
- memset(this->used + old_bitcap, 0, (new_bitcap - old_bitcap) * sizeof(uint64_t));
+ old_bitcap = (this->capacity + 63) / 64;
+ this->capacity <<= 1;
+ new_bitcap = (this->capacity + 63) / 64;
+
+ if (new_bitcap > old_bitcap) {
+ old_used = this->used;
+ if (xrealloc(this->used, new_bitcap, size_t)) {
+ this->used = old_used;
+ this->capacity >>= 1;
+ fail_if (1);
+ }
+
+ memset(this->used + old_bitcap, 0, (new_bitcap - old_bitcap) * sizeof(uint64_t));
+ }
}
- }
-
- /* Store the entry. */
- this->used[key / 64] |= (uint64_t)1 << (key % 64);
- this->values[key] = value;
- this->size++;
- return 0;
- fail:
- return 0;
+
+ /* Store the entry. */
+ this->used[key / 64] |= (uint64_t)1 << (key % 64);
+ this->values[key] = value;
+ this->size++;
+ return 0;
+fail:
+ return 0;
}
@@ -206,15 +203,15 @@ 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
*/
-size_t fd_table_remove(fd_table_t* restrict this, int key)
+size_t
+fd_table_remove(fd_table_t *restrict this, int key)
{
- size_t rc = fd_table_get(this, key);
- if (rc && fd_table_contains_key(this, key))
- {
- this->used[key / 64] &= ~((uint64_t)1 << (key % 64));
- this->size--;
- }
- return rc;
+ size_t rc = fd_table_get(this, key);
+ if (rc && fd_table_contains_key(this, key)) {
+ this->used[key / 64] &= ~((uint64_t)1 << (key % 64));
+ this->size--;
+ }
+ return rc;
}
@@ -223,12 +220,13 @@ size_t fd_table_remove(fd_table_t* restrict this, int key)
*
* @param this The fd table
*/
-void fd_table_clear(fd_table_t* restrict this)
+void
+fd_table_clear(fd_table_t *restrict this)
{
- size_t bitcap;
- this->size = 0;
- bitcap = (this->capacity + 63) / 64;
- memset(this->used, 0, bitcap * sizeof(uint64_t));
+ size_t bitcap;
+ this->size = 0;
+ bitcap = (this->capacity + 63) / 64;
+ memset(this->used, 0, bitcap * sizeof(uint64_t));
}
@@ -238,10 +236,11 @@ 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)
+size_t
+fd_table_marshal_size(const fd_table_t *restrict this)
{
- size_t bitcap = (this->capacity + 63) / 64;
- return (this->capacity + 2) * sizeof(size_t) + bitcap * sizeof(uint64_t) + sizeof(int);
+ size_t bitcap = (this->capacity + 63) / 64;
+ return (this->capacity + 2) * sizeof(size_t) + bitcap * sizeof(uint64_t) + sizeof(int);
}
@@ -251,18 +250,19 @@ size_t fd_table_marshal_size(const fd_table_t* restrict this)
* @param this The fd table
* @param data Output buffer for the marshalled data
*/
-void fd_table_marshal(const fd_table_t* restrict this, char* restrict data)
+void
+fd_table_marshal(const fd_table_t *restrict this, char *restrict data)
{
- size_t bitcap = (this->capacity + 63) / 64;
-
- buf_set_next(data, int, FD_TABLE_T_VERSION);
- buf_set_next(data, size_t, this->capacity);
- buf_set_next(data, size_t, this->size);
-
- memcpy(data, this->values, this->capacity * sizeof(size_t));
- buf_next(data, size_t, this->capacity);
-
- memcpy(data, this->used, bitcap * sizeof(uint64_t));
+ size_t bitcap = (this->capacity + 63) / 64;
+
+ buf_set_next(data, int, FD_TABLE_T_VERSION);
+ buf_set_next(data, size_t, this->capacity);
+ buf_set_next(data, size_t, this->size);
+
+ memcpy(data, this->values, this->capacity * sizeof(size_t));
+ buf_next(data, size_t, this->capacity);
+
+ memcpy(data, this->used, bitcap * sizeof(uint64_t));
}
@@ -275,38 +275,38 @@ 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.
*/
-int fd_table_unmarshal(fd_table_t* restrict this, char* restrict data, remap_func* remapper)
+int
+fd_table_unmarshal(fd_table_t *restrict this, char *restrict data, remap_func *remapper)
{
- size_t bitcap;
- size_t i;
-
- /* buf_get(data, int, 0, FD_TABLE_T_VERSION) */
- buf_next(data, int, 1);
-
- buf_get_next(data, size_t, this->capacity);
- buf_get_next(data, size_t, this->size);
-
- this->values = NULL;
- this->used = NULL;
- this->value_comparator = NULL;
-
- fail_if (xmalloc(this->values, this->capacity, size_t));
-
- bitcap = (this->capacity + 63) / 64;
- fail_if (xmalloc(this->used, bitcap, size_t));
-
- memcpy(this->values, data, this->capacity * sizeof(size_t));
- buf_next(data, size_t, this->capacity);
-
- memcpy(this->used, data, bitcap * sizeof(uint64_t));
-
- if (remapper != NULL)
- for (i = 0; i < this->capacity; i++)
- if (this->used[i / 64] & ((uint64_t)1 << (i % 64)))
- this->values[i] = remapper(this->values[i]);
-
- return 0;
- fail:
- return -1;
-}
+ size_t bitcap;
+ size_t i;
+
+ /* buf_get(data, int, 0, FD_TABLE_T_VERSION) */
+ buf_next(data, int, 1);
+
+ buf_get_next(data, size_t, this->capacity);
+ buf_get_next(data, size_t, this->size);
+ this->values = NULL;
+ this->used = NULL;
+ this->value_comparator = NULL;
+
+ fail_if (xmalloc(this->values, this->capacity, size_t));
+
+ bitcap = (this->capacity + 63) / 64;
+ fail_if (xmalloc(this->used, bitcap, size_t));
+
+ memcpy(this->values, data, this->capacity * sizeof(size_t));
+ buf_next(data, size_t, this->capacity);
+
+ memcpy(this->used, data, bitcap * sizeof(uint64_t));
+
+ if (remapper)
+ for (i = 0; i < this->capacity; i++)
+ if (this->used[i / 64] & ((uint64_t)1 << (i % 64)))
+ this->values[i] = remapper(this->values[i]);
+
+ return 0;
+fail:
+ return -1;
+}
diff --git a/src/libmdsserver/fd-table.h b/src/libmdsserver/fd-table.h
index e0b3a09..e484937 100644
--- a/src/libmdsserver/fd-table.h
+++ b/src/libmdsserver/fd-table.h
@@ -30,8 +30,7 @@
/**
* Value lookup table optimised for file descriptors as keys
*/
-typedef struct fd_table
-{
+typedef struct fd_table {
/**
* The table's capacity, i.e. how many entries that can be stored,
* in total, before its internal table needs to grow
@@ -61,7 +60,6 @@ typedef struct fd_table
* Be aware, this variable cannot be marshalled
*/
compare_func *value_comparator;
-
} fd_table_t;
diff --git a/src/libmdsserver/hash-list.h b/src/libmdsserver/hash-list.h
index abcbb74..2087bce 100644
--- a/src/libmdsserver/hash-list.h
+++ b/src/libmdsserver/hash-list.h
@@ -34,7 +34,7 @@
* The default initial capacity
*/
#ifndef HASH_LIST_DEFAULT_INITIAL_CAPACITY
-# define HASH_LIST_DEFAULT_INITIAL_CAPACITY 128
+# define HASH_LIST_DEFAULT_INITIAL_CAPACITY 128
#endif
/**
@@ -61,15 +61,15 @@
* that is, have the value `__VA_ARGS__`.
*/
#ifndef HASH_LIST_EXPECTED
-# define HASH_LIST_EXPECTED(...) __builtin_expect((__VA_ARGS__), 1)
+# define HASH_LIST_EXPECTED(...) __builtin_expect((__VA_ARGS__), 1)
#endif
-#define HASH_LIST_HASH(key) (this->hasher != NULL ? this->hasher(key) : (size_t)key)
+#define HASH_LIST_HASH(key) (this->hasher ? this->hasher(key) : (size_t)key)
-#define HASH_LIST_T_VERSION 0
+#define HASH_LIST_T_VERSION 0
/**
@@ -105,7 +105,7 @@ typedef VALUE_T T##_value_t;\
*
* @param entry The entry, will never be `NULL`, any only used entries will be passed
*/\
-typedef void T##_entry_free_func(struct T##_entry* entry);\
+typedef void T##_entry_free_func(struct T##_entry *entry);\
\
/**
* Function-type for the function responsible for hashing keys
@@ -134,7 +134,7 @@ static inline int T##_key_comparer(CKEY_T key_a, CKEY_T key_b);\
* @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);\
+static inline size_t T##_submarshal_size(const struct T##_entry *entry);\
\
/**
* Marshal an entry's key and value
@@ -144,7 +144,7 @@ static inline size_t T##_submarshal_size(const struct T##_entry* entry);\
* @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);\
+static inline size_t T##_submarshal(const struct T##_entry *entry, char *restrict data);\
\
/**
* Unmarshal an entry's key and value
@@ -154,7 +154,7 @@ static inline size_t T##_submarshal(const struct T##_entry* entry, char* restric
* @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);\
+static inline size_t T##_subunmarshal(struct T##_entry *entry, char *restrict data);\
\
\
\
@@ -163,21 +163,21 @@ static inline size_t T##_subunmarshal(struct T##_entry* entry, char* restrict da
*/\
typedef struct T##_entry\
{\
- /**
- * The key of the entry, `NULL` if the slot is unused
- */\
- KEY_T key;\
- \
- /**
- * Hash of `key`, undefined but initialised if the slot is unused
- */\
- size_t key_hash;\
- \
- /**
- * The value of the entry
- */\
- T##_value_t value;\
- \
+ /**
+ * The key of the entry, `NULL` if the slot is unused
+ */\
+ KEY_T key;\
+ \
+ /**
+ * Hash of `key`, undefined but initialised if the slot is unused
+ */\
+ size_t key_hash;\
+ \
+ /**
+ * The value of the entry
+ */\
+ T##_value_t value;\
+ \
} T##_entry_t;\
\
\
@@ -186,55 +186,55 @@ typedef struct T##_entry\
*/\
typedef struct T\
{\
- /**
- * The number of allocated slots
- */\
- size_t allocated;\
- \
- /**
- * The number of unused slot that
- * has previously be used
- */\
- size_t unused;\
- \
- /**
- * The number of slots that have
- * been used, even if no longer used
- */\
- size_t used;\
- \
- /**
- * This variable is used for optimisation, any
- * time `hash_list_get` finds an element, its
- * will be stored, and it will be the first
- * inspected element by `hash_list_put` and
- * `hash_list_remove`
- */\
- size_t last;\
- \
- /**
- * The slots
- */\
- T##_entry_t* slots;\
- \
- /**
- * Function used to free keys and values of entries
- *
- * The freeing is not used if this function pointer is `NULL`
- *
- * Be aware, this variable cannot be marshalled
- */\
- T##_entry_free_func* freer;\
- \
- /**
- * Function used to calculate the hash of a key
- *
- * If this function pointer is `NULL`, the identity hash is used
- *
- * Be aware, this variable cannot be marshalled
- */\
- T##_key_hash_func* hasher;\
- \
+ /**
+ * The number of allocated slots
+ */\
+ size_t allocated;\
+ \
+ /**
+ * The number of unused slot that
+ * has previously be used
+ */\
+ size_t unused;\
+ \
+ /**
+ * The number of slots that have
+ * been used, even if no longer used
+ */\
+ size_t used;\
+ \
+ /**
+ * This variable is used for optimisation, any
+ * time `hash_list_get` finds an element, its
+ * will be stored, and it will be the first
+ * inspected element by `hash_list_put` and
+ * `hash_list_remove`
+ */\
+ size_t last;\
+ \
+ /**
+ * The slots
+ */\
+ T##_entry_t *slots;\
+ \
+ /**
+ * Function used to free keys and values of entries
+ *
+ * The freeing is not used if this function pointer is `NULL`
+ *
+ * Be aware, this variable cannot be marshalled
+ */\
+ T##_entry_free_func *freer;\
+ \
+ /**
+ * Function used to calculate the hash of a key
+ *
+ * If this function pointer is `NULL`, the identity hash is used
+ *
+ * Be aware, this variable cannot be marshalled
+ */\
+ T##_key_hash_func *hasher;\
+ \
} T##_t;\
\
\
@@ -247,24 +247,24 @@ typedef struct T\
* @return Non-zero on error, `errno` will have been set accordingly
*/\
static inline int __attribute__((unused, nonnull))\
-T##_create(T##_t* restrict this, size_t capacity)\
+T##_create(T##_t *restrict this, size_t capacity)\
{\
- if (capacity == 0)\
- capacity = HASH_LIST_DEFAULT_INITIAL_CAPACITY;\
- \
- this->freer = NULL;\
- this->hasher = NULL;\
- this->allocated = 0;\
- this->unused = 0;\
- this->used = 0;\
- this->last = 0;\
- \
- this->slots = malloc(capacity * sizeof(T##_t));\
- if (this->slots == NULL)\
- return -1;\
- \
- this->allocated = capacity;\
- return 0;\
+ if (!capacity)\
+ capacity = HASH_LIST_DEFAULT_INITIAL_CAPACITY;\
+ \
+ this->freer = NULL;\
+ this->hasher = NULL;\
+ this->allocated = 0;\
+ this->unused = 0;\
+ this->used = 0;\
+ this->last = 0;\
+ \
+ this->slots = malloc(capacity * sizeof(T##_t));\
+ if (!this->slots)\
+ return -1;\
+ \
+ this->allocated = capacity;\
+ return 0;\
}\
\
\
@@ -274,19 +274,19 @@ T##_create(T##_t* restrict this, size_t capacity)\
* @param this The hash list
*/\
static inline void __attribute__((unused, nonnull))\
-T##_destroy(T##_t* restrict this)\
+T##_destroy(T##_t *restrict this)\
{\
- size_t i, n;\
- if (this->freer != NULL)\
- for (i = 0, n = this->used; i < n; i++)\
- if (this->slots[i].key)\
- this->freer(this->slots + i);\
- this->used = 0;\
- this->unused = 0;\
- this->allocated = 0;\
- this->last = 0;\
- free(this->slots);\
- this->slots = NULL;\
+ size_t i, n;\
+ if (this->freer)\
+ for (i = 0, n = this->used; i < n; i++)\
+ if (this->slots[i].key)\
+ this->freer(this->slots + i);\
+ this->used = 0;\
+ this->unused = 0;\
+ this->allocated = 0;\
+ this->last = 0;\
+ free(this->slots);\
+ this->slots = NULL;\
}\
\
\
@@ -298,14 +298,14 @@ T##_destroy(T##_t* restrict this)\
* @return Non-zero on error, `errno` will have been set accordingly
*/\
static inline int __attribute__((unused, nonnull))\
-T##_clone(const T##_t* restrict this, T##_t* restrict out)\
+T##_clone(const T##_t *restrict this, T##_t *restrict out)\
{\
- if (T##_create(out, this->allocated) < 0)\
- return -1;\
- out->used = this->used;\
- out->unused = this->unused;\
- out->last = this->last;\
- memcpy(out->slots, this->slots, this->used * sizeof(T##_entry_t));\
+ if (T##_create(out, this->allocated) < 0)\
+ return -1;\
+ out->used = this->used;\
+ out->unused = this->unused;\
+ out->last = this->last;\
+ memcpy(out->slots, this->slots, this->used * sizeof(T##_entry_t));\
}\
\
\
@@ -321,32 +321,30 @@ T##_clone(const T##_t* restrict this, T##_t* restrict out)\
* been set accordingly. Errors are non-fatal.
*/\
static inline int __attribute__((unused, nonnull))\
-T##_pack(T##_t* restrict this)\
+T##_pack(T##_t *restrict this)\
{\
- size_t i, j, n;\
- T##_entry_t* slots = this->slots;\
- \
- if (this->unused > 0)\
- {\
- for (i = 0, j = 0, n = this->used; i < n; i++)\
- if (slots[i].key != NULL)\
- slots[j++] = slots[i];\
- \
- this->used -= this->unused;\
- this->unused = 0;\
- this->last = 0;\
- }\
- \
- if (this->used < this->allocated)\
- {\
- slots = realloc(slots, this->used * sizeof(T##_entry_t));\
- if (slots == NULL)\
- return -1;\
- this->slots = slots;\
- this->allocated = this->used;\
- }\
- \
- return 0;\
+ size_t i, j, n;\
+ T##_entry_t *slots = this->slots;\
+ \
+ if (this->unused > 0) {\
+ for (i = 0, j = 0, n = this->used; i < n; i++)\
+ if (slots[i].key)\
+ slots[j++] = slots[i];\
+ \
+ this->used -= this->unused;\
+ this->unused = 0;\
+ this->last = 0;\
+ }\
+ \
+ if (this->used < this->allocated) {\
+ slots = realloc(slots, this->used * sizeof(T##_entry_t));\
+ if (!slots)\
+ return -1;\
+ this->slots = slots;\
+ this->allocated = this->used;\
+ }\
+ \
+ return 0;\
}\
\
\
@@ -359,14 +357,14 @@ T##_pack(T##_t* restrict this)\
* @return Whether the key was found, error is impossible
*/\
static inline int __attribute__((unused, nonnull))\
-T##_get(T##_t* restrict this, CKEY_T key, T##_value_t* restrict value)\
+T##_get(T##_t *restrict this, CKEY_T key, T##_value_t *restrict value)\
{\
- size_t i, n, hash = HASH_LIST_HASH(key);\
- for (i = 0, n = this->used; i < n; i++)\
- if ((this->slots[i].key_hash == hash) && this->slots[i].key)\
- if (T##_key_comparer(this->slots[i].key, key))\
- return *value = this->slots[this->last = i].value, 1;\
- return this->last = 0, 0;\
+ size_t i, n, hash = HASH_LIST_HASH(key);\
+ for (i = 0, n = this->used; i < n; i++)\
+ if (this->slots[i].key_hash == hash && this->slots[i].key)\
+ if (T##_key_comparer(this->slots[i].key, key))\
+ return *value = this->slots[this->last = i].value, 1;\
+ return this->last = 0, 0;\
}\
\
\
@@ -377,39 +375,39 @@ T##_get(T##_t* restrict this, CKEY_T key, T##_value_t* restrict value)\
* @param key The key of the entry to remove, must not be `NULL`
*/\
static inline void __attribute__((unused, nonnull))\
-T##_remove(T##_t* restrict this, CKEY_T key)\
+T##_remove(T##_t *restrict this, CKEY_T key)\
{\
- size_t i = this->last, n, hash = HASH_LIST_HASH(key);\
- T##_entry_t* slots = this->slots;\
- \
- /* First, try cached index. */\
- if (HASH_LIST_EXPECTED(i && (slots[i].key_hash == hash) && (slots[i].key != NULL)))\
- if (HASH_LIST_EXPECTED(T##_key_comparer(slots[i].key, key)))\
- goto do_remove;\
- /* It is discouraged to use put or remove without
- * doing a get before it, otherwise you do not know
- * what is happening. So we do not expect to get
- * get to the next line. However, if do not expect to
- * run get before put or remove, you should modify the
- * `HASH_LIST_EXPECTED` macro. However, this is single
- * case where will will get to the next line, when the
- * index of the item is zero. */\
- \
- /* Then, search. */\
- for (i = 0, n = this->used; i < n; i++)\
- if ((slots[i].key_hash == hash) && (slots[i].key != NULL))\
- if (T##_key_comparer(slots[i].key, key))\
- goto do_remove;\
- \
- return;\
- do_remove:\
- if (this->freer != NULL)\
- this->freer(slots + i);\
- slots[i].key = NULL;\
- this->unused++;\
- if ((this->unused >> 1) >= this->used)\
- T##_pack(this);\
- this->last = 0;\
+ size_t i = this->last, n, hash = HASH_LIST_HASH(key);\
+ T##_entry_t *slots = this->slots;\
+ \
+ /* First, try cached index. */\
+ if (HASH_LIST_EXPECTED(i && slots[i].key_hash == hash && slots[i].key))\
+ if (HASH_LIST_EXPECTED(T##_key_comparer(slots[i].key, key)))\
+ goto do_remove;\
+ /* It is discouraged to use put or remove without
+ * doing a get before it, otherwise you do not know
+ * what is happening. So we do not expect to get
+ * get to the next line. However, if do not expect to
+ * run get before put or remove, you should modify the
+ * `HASH_LIST_EXPECTED` macro. However, this is single
+ * case where will will get to the next line, when the
+ * index of the item is zero. */\
+ \
+ /* Then, search. */\
+ for (i = 0, n = this->used; i < n; i++)\
+ if (slots[i].key_hash == hash && slots[i].key)\
+ if (T##_key_comparer(slots[i].key, key))\
+ goto do_remove;\
+ \
+ return;\
+do_remove:\
+ if (this->freer)\
+ this->freer(slots + i);\
+ slots[i].key = NULL;\
+ this->unused++;\
+ if (this->unused >> 1 >= this->used)\
+ T##_pack(this);\
+ this->last = 0;\
}\
\
\
@@ -423,66 +421,66 @@ T##_remove(T##_t* restrict this, CKEY_T key)\
* @return Non-zero on error, `errno` will have been set accordingly
*/\
static inline int __attribute__((unused, nonnull(1, 2)))\
-T##_put(T##_t* restrict this, KEY_T key, const T##_value_t* restrict value)\
+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;\
- T##_entry_t* slots = this->slots;\
- \
- /* Remove entry if no value is passed. */\
- if (value == NULL)\
- {\
- T##_remove(this, key);\
- return 0;\
- }\
- \
- /* Hash the input key. */\
- hash = HASH_LIST_HASH(key);\
- \
- /* Try cached index. */\
- if (HASH_LIST_EXPECTED(i && (slots[i].key != NULL)))\
- if (HASH_LIST_EXPECTED(slots[i].key_hash == hash))\
- if (HASH_LIST_EXPECTED(T##_key_comparer(slots[i].key, key)))\
- goto put;\
- /* It is discouraged to use put or remove without
- * doing a get before it, otherwise you do not know
- * what is happening. So we do not expect to get
- * get to the next line. However, if do not expect to
- * run get before put or remove, you should modify the
- * `HASH_LIST_EXPECTED` macro. However, this is single
- * case where will will get to the next line, when the
- * index of the item is zero. */\
- \
- /* Find an unused slot or the current slot. */\
- for (i = 0, n = this->used; i < n; i++)\
- if (slots[i].key == NULL)\
- empty = i;\
- else if (slots[i].key_hash == hash)\
- if (T##_key_comparer(slots[i].key, key))\
- goto put;\
- \
- /* Grow slot allocation is required. */\
- if (empty == this->allocated)\
- {\
- if (empty >= SIZE_MAX >> 1)\
- return errno = ENOMEM, -1;\
- slots = realloc(slots, (empty << 1) * sizeof(T##_entry_t));\
- if (slots == NULL)\
- return -1;\
- this->slots = slots;\
- this->allocated <<= 1;\
- }\
- \
- /* Store entry. */\
- i = empty;\
- goto put_no_free;\
- put:\
- if (this->freer != NULL)\
- this->freer(slots + i);\
- put_no_free:\
- slots[i].key = key;\
- slots[i].key_hash = hash;\
- slots[i].value = *value;\
- return 0;\
+ size_t i = this->last, n, empty = this->used, hash;\
+ T##_entry_t* slots = this->slots;\
+ \
+ /* Remove entry if no value is passed. */\
+ if (!value) {\
+ T##_remove(this, key);\
+ return 0;\
+ }\
+ \
+ /* Hash the input key. */\
+ hash = HASH_LIST_HASH(key);\
+ \
+ /* Try cached index. */\
+ if (HASH_LIST_EXPECTED(i && slots[i].key))\
+ if (HASH_LIST_EXPECTED(slots[i].key_hash == hash))\
+ if (HASH_LIST_EXPECTED(T##_key_comparer(slots[i].key, key)))\
+ goto put;\
+ /* It is discouraged to use put or remove without
+ * doing a get before it, otherwise you do not know
+ * what is happening. So we do not expect to get
+ * get to the next line. However, if do not expect to
+ * run get before put or remove, you should modify the
+ * `HASH_LIST_EXPECTED` macro. However, this is single
+ * case where will will get to the next line, when the
+ * index of the item is zero. */\
+ \
+ /* Find an unused slot or the current slot. */\
+ for (i = 0, n = this->used; i < n; i++) {\
+ if (!slots[i].key) {\
+ empty = i;\
+ } else if (slots[i].key_hash == hash) {\
+ if (T##_key_comparer(slots[i].key, key))\
+ goto put;\
+ }\
+ }\
+ \
+ /* Grow slot allocation is required. */\
+ if (empty == this->allocated) {\
+ if (empty >= SIZE_MAX >> 1)\
+ return errno = ENOMEM, -1;\
+ slots = realloc(slots, (empty << 1) * sizeof(T##_entry_t));\
+ if (!slots)\
+ return -1;\
+ this->slots = slots;\
+ this->allocated <<= 1;\
+ }\
+ \
+ /* Store entry. */\
+ i = empty;\
+ goto put_no_free;\
+put:\
+ if (this->freer)\
+ this->freer(slots + i);\
+put_no_free:\
+ slots[i].key = key;\
+ slots[i].key_hash = hash;\
+ slots[i].value = *value;\
+ return 0;\
}\
\
\
@@ -493,14 +491,14 @@ T##_put(T##_t* restrict this, KEY_T key, const T##_value_t* restrict value)\
* @return The number of bytes to allocate to the output buffer
*/\
static inline size_t __attribute__((unused, pure, nonnull))\
-T##_marshal_size(const T##_t* restrict this)\
+T##_marshal_size(const T##_t *restrict this)\
{\
- size_t i, n = this->used;\
- size_t rc = sizeof(int) + 4 * sizeof(size_t);\
- for (i = 0; i < n; i++)\
- if (this->slots[i].key != NULL)\
- rc += T##_submarshal_size(this->slots + i);\
- return rc + n * sizeof(char) + (n - this->unused) * sizeof(size_t);\
+ size_t i, n = this->used;\
+ size_t rc = sizeof(int) + 4 * sizeof(size_t);\
+ for (i = 0; i < n; i++)\
+ if (this->slots[i].key)\
+ rc += T##_submarshal_size(this->slots + i);\
+ return rc + n * sizeof(char) + (n - this->unused) * sizeof(size_t);\
}\
\
\
@@ -511,26 +509,26 @@ T##_marshal_size(const T##_t* restrict this)\
* @param data Output buffer for the marshalled data
*/\
static inline void __attribute__((unused, nonnull))\
-T##_marshal(const T##_t* restrict this, char* restrict data)\
+T##_marshal(const T##_t *restrict this, char *restrict data)\
{\
- size_t wrote, i, n = this->used;\
- \
- buf_set_next(data, int, HASH_LIST_T_VERSION);\
- buf_set_next(data, size_t, this->allocated);\
- buf_set_next(data, size_t, this->unused);\
- buf_set_next(data, size_t, this->used);\
- buf_set_next(data, size_t, this->last);\
- \
- for (i = 0; i < n; i++)\
- if (this->slots[i].key != NULL)\
- {\
- buf_set_next(data, char, 1);\
- buf_set_next(data, size_t, this->slots[i].key_hash);\
- wrote = T##_submarshal(this->slots + i, data);\
- data += wrote / sizeof(char);\
- }\
- else\
- buf_set_next(data, char, 0);\
+ size_t wrote, i, n = this->used;\
+ \
+ buf_set_next(data, int, HASH_LIST_T_VERSION);\
+ buf_set_next(data, size_t, this->allocated);\
+ buf_set_next(data, size_t, this->unused);\
+ buf_set_next(data, size_t, this->used);\
+ buf_set_next(data, size_t, this->last);\
+ \
+ for (i = 0; i < n; i++) {\
+ if (this->slots[i].key) {\
+ buf_set_next(data, char, 1);\
+ buf_set_next(data, size_t, this->slots[i].key_hash);\
+ wrote = T##_submarshal(this->slots + i, data);\
+ data += wrote / sizeof(char);\
+ } else {\
+ buf_set_next(data, char, 0);\
+ }\
+ }\
}\
\
\
@@ -543,39 +541,38 @@ T##_marshal(const T##_t* restrict this, char* restrict data)\
* Destroy the table on error.
*/\
static inline int __attribute__((unused, nonnull))\
-T##_unmarshal(T##_t* restrict this, char* restrict data)\
+T##_unmarshal(T##_t *restrict this, char *restrict data)\
{\
- size_t i, n, got;\
- char used;\
- \
- this->freer = NULL;\
- this->hasher = NULL;\
- \
- /* buf_get(data, int, 0, HASH_LIST_T_VERSION); */\
- buf_next(data, int, 1);\
- \
- buf_get_next(data, size_t, this->allocated);\
- buf_get_next(data, size_t, this->unused);\
- buf_get_next(data, size_t, this->used);\
- buf_get_next(data, size_t, this->last);\
- \
- this->slots = calloc(this->allocated, sizeof(T##_entry_t));\
- if (this->slots == NULL)\
- return -1;\
- \
- for (i = 0, n = this->used; i < n; i++)\
- {\
- buf_get_next(data, char, used);\
- if (used == 0)\
- continue;\
- buf_set_next(data, size_t, this->slots[i].key_hash);\
- got = T##_subunmarshal(this->slots + i, data);\
- if (got == 0)\
- return -1;\
- data += got / sizeof(char);\
- }\
- \
- return 0;\
+ size_t i, n, got;\
+ char used;\
+ \
+ this->freer = NULL;\
+ this->hasher = NULL;\
+ \
+ /* buf_get(data, int, 0, HASH_LIST_T_VERSION); */\
+ buf_next(data, int, 1);\
+ \
+ buf_get_next(data, size_t, this->allocated);\
+ buf_get_next(data, size_t, this->unused);\
+ buf_get_next(data, size_t, this->used);\
+ buf_get_next(data, size_t, this->last);\
+ \
+ this->slots = calloc(this->allocated, sizeof(T##_entry_t));\
+ if (!this->slots)\
+ return -1;\
+ \
+ for (i = 0, n = this->used; i < n; i++) {\
+ buf_get_next(data, char, used);\
+ if (!used)\
+ continue;\
+ buf_set_next(data, size_t, this->slots[i].key_hash);\
+ got = T##_subunmarshal(this->slots + i, data);\
+ if (!got)\
+ return -1;\
+ data += got / sizeof(char);\
+ }\
+ \
+ return 0;\
}
@@ -586,9 +583,9 @@ T##_unmarshal(T##_t* restrict this, char* restrict data)\
* @param i:size_t The variable to store the buckey index in at each iteration
* @param entry:hash_list_enty_t* The variable to store the entry in at each iteration
*/
-#define foreach_hash_list_entry(this, i, entry) \
- for (i = 0; i < (this).used; i++) \
- if (entry = (this).slots, entry->key != NULL)
+#define foreach_hash_list_entry(this, i, entry)\
+ for (i = 0; i < (this).used; i++)\
+ if ((entry = (this).slots)->key)
#endif
diff --git a/src/libmdsserver/hash-table.c b/src/libmdsserver/hash-table.c
index 000bd20..2a7bc3c 100644
--- a/src/libmdsserver/hash-table.c
+++ b/src/libmdsserver/hash-table.c
@@ -31,8 +31,8 @@
* @param K The key
* @param H The hash of the key
*/
-#define TEST_KEY(T, B, K, H) \
- ((B->key == K) || (T->key_comparator && (B->hash == H) && T->key_comparator(B->key, K)))
+#define TEST_KEY(T, B, K, H)\
+ ((B)->key == (K) || ((T)->key_comparator && (B)->hash == (H) && (T)->key_comparator((B)->key, (K))))
/**
@@ -42,10 +42,10 @@
* @param key The key to hash
* @return The hash of the key
*/
-__attribute__((pure, nonnull))
-static inline size_t hash(const hash_table_t* restrict this, size_t key)
+static inline size_t __attribute__((pure, nonnull))
+hash(const hash_table_t *restrict this, size_t key)
{
- return this->hasher ? this->hasher(key) : key;
+ return this->hasher ? this->hasher(key) : key;
}
@@ -56,10 +56,10 @@ static inline size_t hash(const hash_table_t* restrict this, size_t key)
* @param key The key to hash
* @return A non-negative value less the the table's capacity
*/
-__attribute__((pure, nonnull))
-static inline size_t truncate_hash(const hash_table_t* restrict this, size_t hash)
+static inline size_t __attribute__((pure, nonnull))
+truncate_hash(const hash_table_t *restrict this, size_t hash)
{
- return hash % this->capacity;
+ return hash % this->capacity;
}
@@ -69,49 +69,42 @@ static inline size_t truncate_hash(const hash_table_t* restrict this, size_t has
* @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)
+static int __attribute__((nonnull))
+rehash(hash_table_t *restrict this)
{
- hash_entry_t** old_buckets = this->buckets;
- size_t old_capacity = this->capacity;
- size_t i = old_capacity, index;
- hash_entry_t* bucket;
- hash_entry_t* destination;
- hash_entry_t* next;
-
- fail_if (xcalloc(this->buckets, old_capacity * 2 + 1, hash_entry_t*));
- this->capacity = old_capacity * 2 + 1;
- this->threshold = (size_t)((float)(this->capacity) * this->load_factor);
-
- while (i)
- {
- bucket = this->buckets[--i];
- while (bucket)
- {
- index = truncate_hash(this, bucket->hash);
- if ((destination = this->buckets[index]))
- {
- next = destination->next;
- while (next)
- {
- destination = next;
- next = destination->next;
+ hash_entry_t **old_buckets = this->buckets;
+ size_t old_capacity = this->capacity;
+ size_t i = old_capacity, index;
+ hash_entry_t *bucket;
+ hash_entry_t *destination;
+ hash_entry_t *next;
+
+ fail_if (xcalloc(this->buckets, old_capacity * 2 + 1, hash_entry_t*));
+ this->capacity = old_capacity * 2 + 1;
+ this->threshold = (size_t)((float)(this->capacity) * this->load_factor);
+
+ while (i--) {
+ bucket = this->buckets[i];
+ while (bucket) {
+ index = truncate_hash(this, bucket->hash);
+ if ((destination = this->buckets[index])) {
+ while ((next = destination->next))
+ destination = next;
+ destination->next = bucket;
+ } else {
+ this->buckets[index] = bucket;
+ }
+
+ next = bucket->next;
+ bucket->next = NULL;
+ bucket = next;
}
- destination->next = bucket;
- }
- else
- this->buckets[index] = bucket;
-
- next = bucket->next;
- bucket->next = NULL;
- bucket = next;
}
- }
-
- free(old_buckets);
- return 0;
- fail:
- return -1;
+
+ free(old_buckets);
+ return 0;
+fail:
+ return -1;
}
@@ -123,22 +116,23 @@ static int rehash(hash_table_t* restrict this)
* @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
*/
-int hash_table_create_fine_tuned(hash_table_t* restrict this, size_t initial_capacity, float load_factor)
+int
+hash_table_create_fine_tuned(hash_table_t *restrict this, size_t initial_capacity, float load_factor)
{
- this->buckets = NULL;
-
- this->capacity = initial_capacity ? initial_capacity : 1;
- fail_if (xcalloc(this->buckets, this->capacity, hash_entry_t*));
- this->load_factor = load_factor;
- this->threshold = (size_t)((float)(this->capacity) * load_factor);
- this->size = 0;
- this->value_comparator = NULL;
- this->key_comparator = NULL;
- this->hasher = NULL;
-
- return 0;
- fail:
- return -1;
+ this->buckets = NULL;
+
+ this->capacity = initial_capacity ? initial_capacity : 1;
+ fail_if (xcalloc(this->buckets, this->capacity, hash_entry_t*));
+ this->load_factor = load_factor;
+ this->threshold = (size_t)((float)(this->capacity) * load_factor);
+ this->size = 0;
+ this->value_comparator = NULL;
+ this->key_comparator = NULL;
+ this->hasher = NULL;
+
+ return 0;
+fail:
+ return -1;
}
@@ -150,27 +144,24 @@ 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
*/
-void hash_table_destroy(hash_table_t* restrict this, free_func* key_freer, free_func* value_freer)
+void
+hash_table_destroy(hash_table_t *restrict this, free_func *key_freer, free_func *value_freer)
{
- size_t i = this->capacity;
- hash_entry_t* bucket;
- hash_entry_t* last;
-
- if (this->buckets != NULL)
- {
- while (i)
- {
- bucket = this->buckets[--i];
- while (bucket)
- {
- if (key_freer != NULL) key_freer(bucket->key);
- if (value_freer != NULL) value_freer(bucket->value);
- bucket = (last = bucket)->next;
- free(last);
- }
+ size_t i = this->capacity;
+ hash_entry_t *bucket, *last;
+
+ if (this->buckets) {
+ while (i) {
+ bucket = this->buckets[--i];
+ while (bucket) {
+ if (key_freer) key_freer(bucket->key);
+ if (value_freer) value_freer(bucket->value);
+ bucket = (last = bucket)->next;
+ free(last);
+ }
+ }
+ free(this->buckets);
}
- free(this->buckets);
- }
}
@@ -181,25 +172,24 @@ 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)
+int
+hash_table_contains_value(const hash_table_t *restrict this, size_t value)
{
- size_t i = this->capacity;
- hash_entry_t* restrict bucket;
-
- while (i)
- {
- bucket = this->buckets[--i];
- while (bucket != NULL)
- {
- if (bucket->value == value)
- return 1;
- if (this->value_comparator && this->value_comparator(bucket->value, value))
- return 1;
- bucket = bucket->next;
+ size_t i = this->capacity;
+ hash_entry_t *restrict bucket;
+
+ while (i--) {
+ bucket = this->buckets[i];
+ while (bucket) {
+ if (bucket->value == value)
+ return 1;
+ if (this->value_comparator && this->value_comparator(bucket->value, value))
+ return 1;
+ bucket = bucket->next;
+ }
}
- }
-
- return 0;
+
+ return 0;
}
@@ -210,20 +200,20 @@ 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)
+int
+hash_table_contains_key(const hash_table_t *restrict this, size_t key)
{
- size_t key_hash = hash(this, key);
- size_t index = truncate_hash(this, key_hash);
- hash_entry_t* restrict bucket = this->buckets[index];
-
- while (bucket)
- {
- if (TEST_KEY(this, bucket, key, key_hash))
- return 1;
- bucket = bucket->next;
- }
-
- return 0;
+ size_t key_hash = hash(this, key);
+ size_t index = truncate_hash(this, key_hash);
+ hash_entry_t *restrict bucket = this->buckets[index];
+
+ while (bucket) {
+ if (TEST_KEY(this, bucket, key, key_hash))
+ return 1;
+ bucket = bucket->next;
+ }
+
+ return 0;
}
@@ -234,20 +224,20 @@ int hash_table_contains_key(const hash_table_t* restrict this, size_t key)
* @param key The key associated with the value
* @return The value associated with the key, 0 if the key was not used
*/
-size_t hash_table_get(const hash_table_t* restrict this, size_t key)
+size_t
+hash_table_get(const hash_table_t *restrict this, size_t key)
{
- size_t key_hash = hash(this, key);
- size_t index = truncate_hash(this, key_hash);
- hash_entry_t* restrict bucket = this->buckets[index];
-
- while (bucket)
- {
- if (TEST_KEY(this, bucket, key, key_hash))
- return bucket->value;
- bucket = bucket->next;
- }
-
- return 0;
+ size_t key_hash = hash(this, key);
+ size_t index = truncate_hash(this, key_hash);
+ hash_entry_t *restrict bucket = this->buckets[index];
+
+ while (bucket) {
+ if (TEST_KEY(this, bucket, key, key_hash))
+ return bucket->value;
+ bucket = bucket->next;
+ }
+
+ return 0;
}
@@ -258,20 +248,20 @@ 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
*/
-hash_entry_t* hash_table_get_entry(const hash_table_t* restrict this, size_t key)
+hash_entry_t *
+hash_table_get_entry(const hash_table_t *restrict this, size_t key)
{
- size_t key_hash = hash(this, key);
- size_t index = truncate_hash(this, key_hash);
- hash_entry_t* restrict bucket = this->buckets[index];
-
- while (bucket)
- {
- if (TEST_KEY(this, bucket, key, key_hash))
- return bucket;
- bucket = bucket->next;
- }
-
- return NULL;
+ size_t key_hash = hash(this, key);
+ size_t index = truncate_hash(this, key_hash);
+ hash_entry_t *restrict bucket = this->buckets[index];
+
+ while (bucket) {
+ if (TEST_KEY(this, bucket, key, key_hash))
+ return bucket;
+ bucket = bucket->next;
+ }
+
+ return NULL;
}
@@ -284,41 +274,41 @@ 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.
*/
-size_t hash_table_put(hash_table_t* restrict this, size_t key, size_t value)
+size_t
+hash_table_put(hash_table_t *restrict this, size_t key, size_t value)
{
- size_t key_hash = hash(this, key);
- size_t index = truncate_hash(this, key_hash);
- hash_entry_t* restrict bucket = this->buckets[index];
- size_t rc;
-
- while (bucket)
- if (TEST_KEY(this, bucket, key, key_hash))
- {
- rc = bucket->value;
+ size_t key_hash = hash(this, key);
+ size_t index = truncate_hash(this, key_hash);
+ hash_entry_t *restrict bucket = this->buckets[index];
+ size_t rc;
+
+ while (bucket) {
+ if (TEST_KEY(this, bucket, key, key_hash)) {
+ rc = bucket->value;
+ bucket->value = value;
+ return rc;
+ } else {
+ bucket = bucket->next;
+ }
+ }
+
+ if (++(this->size) > this->threshold) {
+ errno = 0;
+ fail_if (rehash(this));
+ index = truncate_hash(this, key_hash);
+ }
+
+ errno = 0;
+ fail_if (xmalloc(bucket, 1, hash_entry_t));
bucket->value = value;
- return rc;
- }
- else
- bucket = bucket->next;
-
- if (++(this->size) > this->threshold)
- {
- errno = 0;
- fail_if (rehash(this));
- index = truncate_hash(this, key_hash);
- }
-
- errno = 0;
- fail_if (xmalloc(bucket, 1, hash_entry_t));
- bucket->value = value;
- bucket->key = key;
- bucket->hash = key_hash;
- bucket->next = this->buckets[index];
- this->buckets[index] = bucket;
-
- return 0;
- fail:
- return 0;
+ bucket->key = key;
+ bucket->hash = key_hash;
+ bucket->next = this->buckets[index];
+ this->buckets[index] = bucket;
+
+ return 0;
+fail:
+ return 0;
}
@@ -329,32 +319,31 @@ 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
*/
-size_t hash_table_remove(hash_table_t* restrict this, size_t key)
+size_t
+hash_table_remove(hash_table_t *restrict this, size_t key)
{
- size_t key_hash = hash(this, key);
- size_t index = truncate_hash(this, key_hash);
- hash_entry_t* bucket = this->buckets[index];
- hash_entry_t* last = NULL;
- size_t rc;
-
- while (bucket)
- {
- if (TEST_KEY(this, bucket, key, key_hash))
- {
- if (last == NULL)
- this->buckets[index] = bucket->next;
- else
- last->next = bucket->next;
- this->size--;
- rc = bucket->value;
- free(bucket);
- return rc;
+ size_t key_hash = hash(this, key);
+ size_t index = truncate_hash(this, key_hash);
+ hash_entry_t *bucket = this->buckets[index];
+ hash_entry_t *last = NULL;
+ size_t rc;
+
+ while (bucket) {
+ if (TEST_KEY(this, bucket, key, key_hash)) {
+ if (!last)
+ this->buckets[index] = bucket->next;
+ else
+ last->next = bucket->next;
+ this->size--;
+ rc = bucket->value;
+ free(bucket);
+ return rc;
+ }
+ last = bucket;
+ bucket = bucket->next;
}
- last = bucket;
- bucket = bucket->next;
- }
-
- return 0;
+
+ return 0;
}
@@ -363,32 +352,29 @@ size_t hash_table_remove(hash_table_t* restrict this, size_t key)
*
* @param this The hash table
*/
-void hash_table_clear(hash_table_t* restrict this)
+void
+hash_table_clear(hash_table_t *restrict this)
{
- hash_entry_t** buf;
- hash_entry_t* bucket;
- size_t i, ptr;
-
- if (this->size)
- {
- buf = alloca((this->size + 1) * sizeof(hash_entry_t*));
- i = this->capacity;
- while (i)
- {
- bucket = this->buckets[--i];
- ptr = 0;
- buf[ptr++] = bucket;
- while (bucket)
- {
- bucket = bucket->next;
- buf[ptr++] = bucket;
- }
- while (ptr)
- free(buf[--ptr]);
- this->buckets[i] = NULL;
+ hash_entry_t **buf, *bucket;
+ size_t i, ptr;
+
+ if (this->size) {
+ buf = alloca((this->size + 1) * sizeof(hash_entry_t*));
+ i = this->capacity;
+ while (i--) {
+ bucket = this->buckets[i];
+ ptr = 0;
+ buf[ptr++] = bucket;
+ while (bucket) {
+ bucket = bucket->next;
+ buf[ptr++] = bucket;
+ }
+ while (ptr)
+ free(buf[--ptr]);
+ this->buckets[i] = NULL;
+ }
+ this->size = 0;
}
- this->size = 0;
- }
}
@@ -398,23 +384,23 @@ 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)
+size_t
+hash_table_marshal_size(const hash_table_t *restrict this)
{
- size_t n = this->capacity;
- size_t rc = 3 * sizeof(size_t) + sizeof(float) + n * sizeof(size_t);
- size_t i, m = 0;
-
- for (i = 0; i < n; i++)
- {
- hash_entry_t* restrict bucket = this->buckets[i];
- while (bucket != NULL)
- {
- bucket = bucket->next;
- m++;
+ size_t n = this->capacity;
+ size_t rc = 3 * sizeof(size_t) + sizeof(float) + n * sizeof(size_t);
+ size_t i, m = 0;
+ hash_entry_t *restrict bucket;
+
+ for (i = 0; i < n; i++) {
+ bucket = this->buckets[i];
+ while (bucket) {
+ bucket = bucket->next;
+ m++;
+ }
}
- }
-
- return rc + m * 3 * sizeof(size_t) + sizeof(int);
+
+ return rc + m * 3 * sizeof(size_t) + sizeof(int);
}
@@ -424,31 +410,31 @@ size_t hash_table_marshal_size(const hash_table_t* restrict this)
* @param this The hash table
* @param data Output buffer for the marshalled data
*/
-void hash_table_marshal(const hash_table_t* restrict this, char* restrict data)
+void
+hash_table_marshal(const hash_table_t *restrict this, char *restrict data)
{
- size_t i, n = this->capacity;
-
- buf_set_next(data, int, HASH_TABLE_T_VERSION);
- buf_set_next(data, size_t, this->capacity);
- buf_set_next(data, float, this->load_factor);
- buf_set_next(data, size_t, this->threshold);
- buf_set_next(data, size_t, this->size);
-
- for (i = 0; i < n; i++)
- {
- hash_entry_t* restrict bucket = this->buckets[i];
- size_t m = 0;
- while (bucket != NULL)
- {
- buf_set(data, size_t, 1 + m * 3 + 0, bucket->key);
- buf_set(data, size_t, 1 + m * 3 + 1, bucket->value);
- buf_set(data, size_t, 1 + m * 3 + 2, bucket->hash);
- bucket = bucket->next;
- m++;
+ size_t i, n = this->capacity, m;
+ hash_entry_t *restrict bucket;
+
+ buf_set_next(data, int, HASH_TABLE_T_VERSION);
+ buf_set_next(data, size_t, this->capacity);
+ buf_set_next(data, float, this->load_factor);
+ buf_set_next(data, size_t, this->threshold);
+ buf_set_next(data, size_t, this->size);
+
+ for (i = 0; i < n; i++) {
+ bucket = this->buckets[i];
+ m = 0;
+ while (bucket) {
+ buf_set(data, size_t, 1 + m * 3 + 0, bucket->key);
+ buf_set(data, size_t, 1 + m * 3 + 1, bucket->value);
+ buf_set(data, size_t, 1 + m * 3 + 2, bucket->hash);
+ bucket = bucket->next;
+ m++;
+ }
+ buf_set(data, size_t, 0, m);
+ buf_next(data, size_t, 1 + m * 3);
}
- buf_set(data, size_t, 0, m);
- buf_next(data, size_t, 1 + m * 3);
- }
}
@@ -461,48 +447,45 @@ 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.
*/
-int hash_table_unmarshal(hash_table_t* restrict this, char* restrict data, remap_func* remapper)
+int
+hash_table_unmarshal(hash_table_t *restrict this, char *restrict data, remap_func *remapper)
{
- size_t i, n;
-
- /* buf_get(data, int, 0, HASH_TABLE_T_VERSION); */
- buf_next(data, int, 1);
-
- this->value_comparator = NULL;
- this->key_comparator = NULL;
- this->hasher = NULL;
-
- buf_get_next(data, size_t, this->capacity = n);
- buf_get_next(data, float, this->load_factor);
- buf_get_next(data, size_t, this->threshold);
- buf_get_next(data, size_t, this->size);
-
- fail_if (xcalloc(this->buckets, this->capacity, hash_entry_t*));
-
- for (i = 0; i < n; i++)
- {
- size_t m;
- hash_entry_t* restrict bucket;
- buf_get_next(data, size_t, m);
-
- fail_if (xmalloc(this->buckets[i] = bucket, 1, hash_entry_t));
-
- while (m--)
- {
- if (m == 0)
- bucket->next = NULL;
- else
- fail_if (xmalloc(bucket->next, 1, hash_entry_t));
- buf_get_next(data, size_t, bucket->key);
- buf_get_next(data, size_t, bucket->value);
- if (remapper != NULL)
- bucket->value = remapper(bucket->value);
- buf_get_next(data, size_t, bucket->hash);
+ size_t i, n, m;
+ hash_entry_t *restrict bucket;
+
+ /* buf_get(data, int, 0, HASH_TABLE_T_VERSION); */
+ buf_next(data, int, 1);
+
+ this->value_comparator = NULL;
+ this->key_comparator = NULL;
+ this->hasher = NULL;
+
+ buf_get_next(data, size_t, this->capacity = n);
+ buf_get_next(data, float, this->load_factor);
+ buf_get_next(data, size_t, this->threshold);
+ buf_get_next(data, size_t, this->size);
+
+ fail_if (xcalloc(this->buckets, this->capacity, hash_entry_t*));
+
+ for (i = 0; i < n; i++) {
+ buf_get_next(data, size_t, m);
+
+ fail_if (xmalloc(this->buckets[i] = bucket, 1, hash_entry_t));
+
+ while (m--) {
+ if (!m)
+ bucket->next = NULL;
+ else
+ fail_if (xmalloc(bucket->next, 1, hash_entry_t));
+ buf_get_next(data, size_t, bucket->key);
+ buf_get_next(data, size_t, bucket->value);
+ if (remapper)
+ bucket->value = remapper(bucket->value);
+ buf_get_next(data, size_t, bucket->hash);
+ }
}
- }
-
- return 0;
- fail:
- return -1;
-}
+ return 0;
+fail:
+ return -1;
+}
diff --git a/src/libmdsserver/linked-list.c b/src/libmdsserver/linked-list.c
index 401a726..954c6fe 100644
--- a/src/libmdsserver/linked-list.c
+++ b/src/libmdsserver/linked-list.c
@@ -27,7 +27,7 @@
* The default initial capacity
*/
#ifndef LINKED_LIST_DEFAULT_INITIAL_CAPACITY
-# define LINKED_LIST_DEFAULT_INITIAL_CAPACITY 128
+# define LINKED_LIST_DEFAULT_INITIAL_CAPACITY 128
#endif
@@ -38,19 +38,19 @@
* @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)
+static size_t __attribute__((const))
+to_power_of_two(size_t value)
{
- value -= 1;
- value |= value >> 1;
- value |= value >> 2;
- value |= value >> 4;
- value |= value >> 8;
- value |= value >> 16;
+ value -= 1;
+ value |= value >> 1;
+ value |= value >> 2;
+ value |= value >> 4;
+ value |= value >> 8;
+ value |= value >> 16;
#if SIZE_MAX == UINT64_MAX
- value |= value >> 32;
+ value |= value >> 32;
#endif
- return value + 1;
+ return value + 1;
}
@@ -61,32 +61,33 @@ static size_t to_power_of_two(size_t value)
* @param capacity The minimum initial capacity of the linked list, 0 for default
* @return Non-zero on error, `errno` will have been set accordingly
*/
-int linked_list_create(linked_list_t* restrict this, size_t capacity)
+int
+linked_list_create(linked_list_t *restrict this, size_t capacity)
{
- /* Use default capacity of zero is specified. */
- if (capacity == 0)
- capacity = LINKED_LIST_DEFAULT_INITIAL_CAPACITY;
-
- /* Initialise the linked list. */
- this->capacity = capacity = to_power_of_two(capacity);
- this->edge = 0;
- this->end = 1;
- this->reuse_head = 0;
- this->reusable = NULL;
- this->values = NULL;
- this->next = NULL;
- this->previous = NULL;
- fail_if (xmalloc(this->reusable, capacity, ssize_t));
- fail_if (xmalloc(this->values, capacity, size_t));
- fail_if (xmalloc(this->next, capacity, ssize_t));
- fail_if (xmalloc(this->previous, capacity, ssize_t));
- this->values[this->edge] = 0;
- this->next[this->edge] = this->edge;
- this->previous[this->edge] = this->edge;
-
- return 0;
- fail:
- return -1;
+ /* Use default capacity of zero is specified. */
+ if (!capacity)
+ capacity = LINKED_LIST_DEFAULT_INITIAL_CAPACITY;
+
+ /* Initialise the linked list. */
+ this->capacity = capacity = to_power_of_two(capacity);
+ this->edge = 0;
+ this->end = 1;
+ this->reuse_head = 0;
+ this->reusable = NULL;
+ this->values = NULL;
+ this->next = NULL;
+ this->previous = NULL;
+ fail_if (xmalloc(this->reusable, capacity, ssize_t));
+ fail_if (xmalloc(this->values, capacity, size_t));
+ fail_if (xmalloc(this->next, capacity, ssize_t));
+ fail_if (xmalloc(this->previous, capacity, ssize_t));
+ this->values[this->edge] = 0;
+ this->next[this->edge] = this->edge;
+ this->previous[this->edge] = this->edge;
+
+ return 0;
+fail:
+ return -1;
}
@@ -96,12 +97,13 @@ int linked_list_create(linked_list_t* restrict this, size_t capacity)
*
* @param this The linked list
*/
-void linked_list_destroy(linked_list_t* restrict this)
+void
+linked_list_destroy(linked_list_t *restrict this)
{
- free(this->reusable), this->reusable = NULL;
- free(this->values), this->values = NULL;
- free(this->next), this->next = NULL;
- free(this->previous), this->previous = NULL;
+ free(this->reusable), this->reusable = NULL;
+ free(this->values), this->values = NULL;
+ free(this->next), this->next = NULL;
+ free(this->previous), this->previous = NULL;
}
@@ -112,22 +114,23 @@ 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
*/
-int linked_list_clone(const linked_list_t* restrict this, linked_list_t* restrict out)
+int
+linked_list_clone(const linked_list_t *restrict this, linked_list_t *restrict out)
{
- fail_if (xmemdup(out->values, this->values, this->capacity, size_t));
- fail_if (xmemdup(out->next, this->next, this->capacity, ssize_t));
- fail_if (xmemdup(out->previous, this->previous, this->capacity, ssize_t));
- fail_if (xmemdup(out->reusable, this->reusable, this->capacity, ssize_t));
-
- out->capacity = this->capacity;
- out->end = this->end;
- out->reuse_head = this->reuse_head;
- out->edge = this->edge;
-
- return 0;
-
- fail:
- return -1;
+ fail_if (xmemdup(out->values, this->values, this->capacity, size_t));
+ fail_if (xmemdup(out->next, this->next, this->capacity, ssize_t));
+ fail_if (xmemdup(out->previous, this->previous, this->capacity, ssize_t));
+ fail_if (xmemdup(out->reusable, this->reusable, this->capacity, ssize_t));
+
+ out->capacity = this->capacity;
+ out->end = this->end;
+ out->reuse_head = this->reuse_head;
+ out->edge = this->edge;
+
+ return 0;
+
+fail:
+ return -1;
}
@@ -145,64 +148,64 @@ 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
*/
-int linked_list_pack(linked_list_t* restrict this)
+int
+linked_list_pack(linked_list_t *restrict this)
{
- ssize_t* restrict new_next = NULL;
- ssize_t* restrict new_previous = NULL;
- ssize_t* restrict new_reusable = NULL;
- size_t size = this->end - this->reuse_head;
- size_t cap = to_power_of_two(size);
- ssize_t head = 0;
- size_t i = 0;
- ssize_t node;
- size_t* restrict vals;
- int saved_errno;
-
- fail_if (xmalloc(vals, cap, size_t));
- while (((size_t)head != this->end) && (this->next[head] == LINKED_LIST_UNUSED))
- head++;
- if ((size_t)head != this->end)
- for (node = head; (node != head) || (i == 0); i++)
- {
- vals[i] = this->values[node];
- node = this->next[node];
- }
-
- if (cap != this->capacity)
- {
- fail_if (xmalloc(new_next, cap, ssize_t));
- fail_if (xmalloc(new_previous, cap, ssize_t));
- fail_if (xmalloc(new_reusable, cap, ssize_t));
-
- free(this->next);
- free(this->previous);
- free(this->reusable);
-
- this->next = new_next;
- this->previous = new_previous;
- this->reusable = new_reusable;
- }
-
- for (i = 0; i < size; i++)
- this->next[i] = (ssize_t)(i + 1);
- this->next[size - 1] = 0;
-
- for (i = 1; i < size; i++)
- this->previous[i] = (ssize_t)(i - 1);
- this->previous[0] = (ssize_t)(size - 1);
-
- this->values = vals;
- this->end = size;
- this->reuse_head = 0;
-
- return 0;
-
- fail:
- saved_errno = errno;
- free(vals);
- free(new_next);
- free(new_previous);
- return errno = saved_errno, -1;
+ ssize_t *restrict new_next = NULL;
+ ssize_t *restrict new_previous = NULL;
+ ssize_t *restrict new_reusable = NULL;
+ size_t size = this->end - this->reuse_head;
+ size_t cap = to_power_of_two(size);
+ ssize_t head = 0;
+ size_t i = 0;
+ ssize_t node;
+ size_t *restrict vals;
+ int saved_errno;
+
+ fail_if (xmalloc(vals, cap, size_t));
+ while ((size_t)head != this->end && this->next[head] == LINKED_LIST_UNUSED)
+ head++;
+ if ((size_t)head != this->end) {
+ for (node = head; (node != head) || (i == 0); i++) {
+ vals[i] = this->values[node];
+ node = this->next[node];
+ }
+ }
+
+ if (cap != this->capacity) {
+ fail_if (xmalloc(new_next, cap, ssize_t));
+ fail_if (xmalloc(new_previous, cap, ssize_t));
+ fail_if (xmalloc(new_reusable, cap, ssize_t));
+
+ free(this->next);
+ free(this->previous);
+ free(this->reusable);
+
+ this->next = new_next;
+ this->previous = new_previous;
+ this->reusable = new_reusable;
+ }
+
+ for (i = 0; i < size; i++)
+ this->next[i] = (ssize_t)(i + 1);
+ this->next[size - 1] = 0;
+
+ for (i = 1; i < size; i++)
+ this->previous[i] = (ssize_t)(i - 1);
+ this->previous[0] = (ssize_t)(size - 1);
+
+ this->values = vals;
+ this->end = size;
+ this->reuse_head = 0;
+
+ return 0;
+
+fail:
+ saved_errno = errno;
+ free(vals);
+ free(new_next);
+ free(new_previous);
+ return errno = saved_errno, -1;
}
@@ -215,29 +218,28 @@ 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)
+static ssize_t __attribute__((nonnull))
+linked_list_get_next(linked_list_t *restrict this)
{
- size_t* tmp_values;
- ssize_t* tmp;
-
- if (this->reuse_head > 0)
- return this->reusable[--(this->reuse_head)];
- if (this->end == this->capacity)
- {
- if ((ssize_t)(this->end) < 0)
- fail_if ((errno = ENOMEM));
-
- this->capacity <<= 1;
-
- fail_if (yrealloc(tmp_values, this->values, this->capacity, size_t));
- fail_if (yrealloc(tmp, this->next, this->capacity, ssize_t));
- fail_if (yrealloc(tmp, this->previous, this->capacity, ssize_t));
- fail_if (yrealloc(tmp, this->reusable, this->capacity, ssize_t));
- }
- return (ssize_t)(this->end++);
- fail:
- return LINKED_LIST_UNUSED;
+ size_t *tmp_values;
+ ssize_t *tmp;
+
+ if (this->reuse_head > 0)
+ return this->reusable[--(this->reuse_head)];
+ if (this->end == this->capacity) {
+ if ((ssize_t)(this->end) < 0)
+ fail_if ((errno = ENOMEM));
+
+ this->capacity <<= 1;
+
+ fail_if (yrealloc(tmp_values, this->values, this->capacity, size_t));
+ fail_if (yrealloc(tmp, this->next, this->capacity, ssize_t));
+ fail_if (yrealloc(tmp, this->previous, this->capacity, ssize_t));
+ fail_if (yrealloc(tmp, this->reusable, this->capacity, ssize_t));
+ }
+ return (ssize_t)(this->end++);
+fail:
+ return LINKED_LIST_UNUSED;
}
@@ -248,15 +250,15 @@ 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)
+static ssize_t __attribute__((nonnull))
+linked_list_unuse(linked_list_t *restrict this, ssize_t node)
{
- if (node < 0)
- return node;
- this->reusable[this->reuse_head++] = node;
- this->next[node] = LINKED_LIST_UNUSED;
- this->previous[node] = LINKED_LIST_UNUSED;
- return node;
+ if (node < 0)
+ return node;
+ this->reusable[this->reuse_head++] = node;
+ this->next[node] = LINKED_LIST_UNUSED;
+ this->previous[node] = LINKED_LIST_UNUSED;
+ return node;
}
@@ -269,18 +271,19 @@ static ssize_t linked_list_unuse(linked_list_t* restrict this, ssize_t node)
* @return The node that has been created and inserted,
* `LINKED_LIST_UNUSED` on error, `errno` will be set accordingly
*/
-ssize_t linked_list_insert_after(linked_list_t* this, size_t value, ssize_t predecessor)
+ssize_t
+linked_list_insert_after(linked_list_t *this, size_t value, ssize_t predecessor)
{
- ssize_t node = linked_list_get_next(this);
- fail_if (node == LINKED_LIST_UNUSED);
- this->values[node] = value;
- this->next[node] = this->next[predecessor];
- this->next[predecessor] = node;
- this->previous[node] = predecessor;
- this->previous[this->next[node]] = node;
- return node;
- fail:
- return LINKED_LIST_UNUSED;
+ ssize_t node = linked_list_get_next(this);
+ fail_if (node == LINKED_LIST_UNUSED);
+ this->values[node] = value;
+ this->next[node] = this->next[predecessor];
+ this->next[predecessor] = node;
+ this->previous[node] = predecessor;
+ this->previous[this->next[node]] = node;
+ return node;
+fail:
+ return LINKED_LIST_UNUSED;
}
@@ -291,12 +294,13 @@ ssize_t linked_list_insert_after(linked_list_t* this, size_t value, ssize_t pred
* @param predecessor The reference node
* @return The node that has been removed
*/
-ssize_t linked_list_remove_after(linked_list_t* restrict this, ssize_t predecessor)
+ssize_t
+linked_list_remove_after(linked_list_t *restrict this, ssize_t predecessor)
{
- ssize_t node = this->next[predecessor];
- this->next[predecessor] = this->next[node];
- this->previous[this->next[node]] = predecessor;
- return linked_list_unuse(this, node);
+ ssize_t node = this->next[predecessor];
+ this->next[predecessor] = this->next[node];
+ this->previous[this->next[node]] = predecessor;
+ return linked_list_unuse(this, node);
}
@@ -309,18 +313,19 @@ 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
*/
-ssize_t linked_list_insert_before(linked_list_t* restrict this, size_t value, ssize_t successor)
+ssize_t
+linked_list_insert_before(linked_list_t *restrict this, size_t value, ssize_t successor)
{
- ssize_t node = linked_list_get_next(this);
- fail_if (node == LINKED_LIST_UNUSED);
- this->values[node] = value;
- this->previous[node] = this->previous[successor];
- this->previous[successor] = node;
- this->next[node] = successor;
- this->next[this->previous[node]] = node;
- return node;
- fail:
- return LINKED_LIST_UNUSED;
+ ssize_t node = linked_list_get_next(this);
+ fail_if (node == LINKED_LIST_UNUSED);
+ this->values[node] = value;
+ this->previous[node] = this->previous[successor];
+ this->previous[successor] = node;
+ this->next[node] = successor;
+ this->next[this->previous[node]] = node;
+ return node;
+fail:
+ return LINKED_LIST_UNUSED;
}
@@ -331,12 +336,13 @@ 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
*/
-ssize_t linked_list_remove_before(linked_list_t* restrict this, ssize_t successor)
+ssize_t
+linked_list_remove_before(linked_list_t *restrict this, ssize_t successor)
{
- ssize_t node = this->previous[successor];
- this->previous[successor] = this->previous[node];
- this->next[this->previous[node]] = successor;
- return linked_list_unuse(this, node);
+ ssize_t node = this->previous[successor];
+ this->previous[successor] = this->previous[node];
+ this->next[this->previous[node]] = successor;
+ return linked_list_unuse(this, node);
}
@@ -346,11 +352,12 @@ ssize_t linked_list_remove_before(linked_list_t* restrict this, ssize_t successo
* @param this The list
* @param node The node to remove
*/
-void linked_list_remove(linked_list_t* restrict this, ssize_t node)
+void
+linked_list_remove(linked_list_t *restrict this, ssize_t node)
{
- this->next[this->previous[node]] = this->next[node];
- this->previous[this->next[node]] = this->previous[node];
- linked_list_unuse(this, node);
+ this->next[this->previous[node]] = this->next[node];
+ this->previous[this->next[node]] = this->previous[node];
+ linked_list_unuse(this, node);
}
@@ -360,9 +367,10 @@ 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)
+size_t
+linked_list_marshal_size(const linked_list_t *restrict this)
{
- return sizeof(size_t) * (4 + this->reuse_head + 3 * this->end) + sizeof(int);
+ return sizeof(size_t) * (4 + this->reuse_head + 3 * this->end) + sizeof(int);
}
@@ -372,27 +380,28 @@ size_t linked_list_marshal_size(const linked_list_t* restrict this)
* @param this The list
* @param data Output buffer for the marshalled data
*/
-void linked_list_marshal(const linked_list_t* restrict this, char* restrict data)
+void
+linked_list_marshal(const linked_list_t *restrict this, char *restrict data)
{
- buf_set(data, int, 0, LINKED_LIST_T_VERSION);
- buf_next(data, int, 1);
-
- buf_set(data, size_t, 0, this->capacity);
- buf_set(data, size_t, 1, this->end);
- buf_set(data, size_t, 2, this->reuse_head);
- buf_set(data, ssize_t, 3, this->edge);
- buf_next(data, size_t, 4);
-
- memcpy(data, this->reusable, this->reuse_head * sizeof(ssize_t));
- buf_next(data, ssize_t, this->reuse_head);
-
- memcpy(data, this->values, this->end * sizeof(size_t));
- buf_next(data, size_t, this->end);
-
- memcpy(data, this->next, this->end * sizeof(ssize_t));
- buf_next(data, ssize_t, this->end);
-
- memcpy(data, this->previous, this->end * sizeof(ssize_t));
+ buf_set(data, int, 0, LINKED_LIST_T_VERSION);
+ buf_next(data, int, 1);
+
+ buf_set(data, size_t, 0, this->capacity);
+ buf_set(data, size_t, 1, this->end);
+ buf_set(data, size_t, 2, this->reuse_head);
+ buf_set(data, ssize_t, 3, this->edge);
+ buf_next(data, size_t, 4);
+
+ memcpy(data, this->reusable, this->reuse_head * sizeof(ssize_t));
+ buf_next(data, ssize_t, this->reuse_head);
+
+ memcpy(data, this->values, this->end * sizeof(size_t));
+ buf_next(data, size_t, this->end);
+
+ memcpy(data, this->next, this->end * sizeof(ssize_t));
+ buf_next(data, ssize_t, this->end);
+
+ memcpy(data, this->previous, this->end * sizeof(ssize_t));
}
@@ -404,41 +413,42 @@ 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.
*/
-int linked_list_unmarshal(linked_list_t* restrict this, char* restrict data)
+int
+linked_list_unmarshal(linked_list_t *restrict this, char *restrict data)
{
- /* buf_get(data, int, 0, LINKED_LIST_T_VERSION); */
- buf_next(data, int, 1);
-
- this->reusable = NULL;
- this->values = NULL;
- this->next = NULL;
- this->previous = NULL;
-
- buf_get(data, size_t, 0, this->capacity);
- buf_get(data, size_t, 1, this->end);
- buf_get(data, size_t, 2, this->reuse_head);
- buf_get(data, ssize_t, 3, this->edge);
- buf_next(data, size_t, 4);
-
- fail_if (xmalloc(this->reusable, this->capacity, size_t));
- fail_if (xmalloc(this->values, this->capacity, size_t));
- fail_if (xmalloc(this->next, this->capacity, size_t));
- fail_if (xmalloc(this->previous, this->capacity, size_t));
-
- memcpy(this->reusable, data, this->reuse_head * sizeof(ssize_t));
- buf_next(data, ssize_t, this->reuse_head);
-
- memcpy(this->values, data, this->end * sizeof(size_t));
- buf_next(data, size_t, this->end);
-
- memcpy(this->next, data, this->end * sizeof(ssize_t));
- buf_next(data, ssize_t, this->end);
-
- memcpy(this->previous, data, this->end * sizeof(ssize_t));
-
- return 0;
- fail:
- return -1;
+ /* buf_get(data, int, 0, LINKED_LIST_T_VERSION); */
+ buf_next(data, int, 1);
+
+ this->reusable = NULL;
+ this->values = NULL;
+ this->next = NULL;
+ this->previous = NULL;
+
+ buf_get(data, size_t, 0, this->capacity);
+ buf_get(data, size_t, 1, this->end);
+ buf_get(data, size_t, 2, this->reuse_head);
+ buf_get(data, ssize_t, 3, this->edge);
+ buf_next(data, size_t, 4);
+
+ fail_if (xmalloc(this->reusable, this->capacity, size_t));
+ fail_if (xmalloc(this->values, this->capacity, size_t));
+ fail_if (xmalloc(this->next, this->capacity, size_t));
+ fail_if (xmalloc(this->previous, this->capacity, size_t));
+
+ memcpy(this->reusable, data, this->reuse_head * sizeof(ssize_t));
+ buf_next(data, ssize_t, this->reuse_head);
+
+ memcpy(this->values, data, this->end * sizeof(size_t));
+ buf_next(data, size_t, this->end);
+
+ memcpy(this->next, data, this->end * sizeof(ssize_t));
+ buf_next(data, ssize_t, this->end);
+
+ memcpy(this->previous, data, this->end * sizeof(ssize_t));
+
+ return 0;
+fail:
+ return -1;
}
@@ -448,31 +458,31 @@ int linked_list_unmarshal(linked_list_t* restrict this, char* restrict data)
* @param this The list
* @param output Output file
*/
-void linked_list_dump(linked_list_t* restrict this, FILE* restrict output)
+void
+linked_list_dump(linked_list_t *restrict this, FILE *restrict output)
{
- ssize_t i;
- size_t j;
- fprintf(output, "======= LINKED LIST DUMP =======\n");
- fprintf(output, "Capacity: %zu\n", this->capacity);
- fprintf(output, "End: %zu\n", this->end);
- fprintf(output, "Reuse head: %zu\n", this->reuse_head);
- fprintf(output, "Edge: %zi\n", this->edge);
- fprintf(output, "--------------------------------\n");
- fprintf(output, "Node table (Next, Prev, Value):\n");
- i = this->edge;
- fprintf(output, " %zi: %zi, %zi, %zu\n", i, this->next[i], this->previous[i], this->values[i]);
- foreach_linked_list_node((*this), i)
- fprintf(output, " %zi: %zi, %zi, %zu\n", i, this->next[i], this->previous[i], this->values[i]);
- i = this->edge;
- fprintf(output, " %zi: %zi, %zi, %zu\n", i, this->next[i], this->previous[i], this->values[i]);
- fprintf(output, "--------------------------------\n");
- fprintf(output, "Raw node table:\n");
- for (j = 0; j < this->end; j++)
- fprintf(output, " %zu: %zi, %zi, %zu\n", i, this->next[i], this->previous[i], this->values[i]);
- fprintf(output, "--------------------------------\n");
- fprintf(output, "Reuse stack:\n");
- for (j = 0; j < this->reuse_head; j++)
- fprintf(output, " %zu: %zi\n", j, this->reusable[j]);
- fprintf(output, "================================\n");
+ ssize_t i;
+ size_t j;
+ fprintf(output, "======= LINKED LIST DUMP =======\n");
+ fprintf(output, "Capacity: %zu\n", this->capacity);
+ fprintf(output, "End: %zu\n", this->end);
+ fprintf(output, "Reuse head: %zu\n", this->reuse_head);
+ fprintf(output, "Edge: %zi\n", this->edge);
+ fprintf(output, "--------------------------------\n");
+ fprintf(output, "Node table (Next, Prev, Value):\n");
+ i = this->edge;
+ fprintf(output, " %zi: %zi, %zi, %zu\n", i, this->next[i], this->previous[i], this->values[i]);
+ foreach_linked_list_node((*this), i)
+ fprintf(output, " %zi: %zi, %zi, %zu\n", i, this->next[i], this->previous[i], this->values[i]);
+ i = this->edge;
+ fprintf(output, " %zi: %zi, %zi, %zu\n", i, this->next[i], this->previous[i], this->values[i]);
+ fprintf(output, "--------------------------------\n");
+ fprintf(output, "Raw node table:\n");
+ for (j = 0; j < this->end; j++)
+ fprintf(output, " %zu: %zi, %zi, %zu\n", i, this->next[i], this->previous[i], this->values[i]);
+ fprintf(output, "--------------------------------\n");
+ fprintf(output, "Reuse stack:\n");
+ for (j = 0; j < this->reuse_head; j++)
+ fprintf(output, " %zu: %zi\n", j, this->reusable[j]);
+ fprintf(output, "================================\n");
}
-
diff --git a/src/libmdsserver/macros.h b/src/libmdsserver/macros.h
index d4d588c..45412b9 100644
--- a/src/libmdsserver/macros.h
+++ b/src/libmdsserver/macros.h
@@ -44,24 +44,22 @@
/* CLOCK_MONOTONIC_RAW is a Linux-specific bug-fix */
#ifndef CLOCK_MONOTONIC_RAW
-# define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
+# define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
#endif
/* Define TEMP_FAILURE_RETRY if not defined, however
* this version does not return a value, it will hoever
* clear `errno` if no error occurs. */
#ifndef TEMP_FAILURE_RETRY
-# define TEMP_FAILURE_RETRY(expression) \
- do \
- { \
- ssize_t __result; \
- do \
- __result = (ssize_t)(expression); \
- while ((__result < 0) && (errno == EINTR)); \
- if (__result >= 0) \
- errno = 0; \
- } \
- while (0)
+# define TEMP_FAILURE_RETRY(expression)\
+ do {\
+ ssize_t __result;\
+ do\
+ __result = (ssize_t)(expression);\
+ while (__result < 0 && errno == EINTR);\
+ if (__result >= 0)\
+ errno = 0;\
+ } while (0)
# define MDS_LIBMDSSERVER_MACROS_DEFINED_TEMP_FAILURE_RETRY
#endif
@@ -118,16 +116,16 @@
* @param ...:const char*, ... The format string and arguments
* @return :int Zero on success, -1 on error
*/
-#define xasprintf(VAR, ...) \
- (asprintf(&(VAR), __VA_ARGS__) < 0 ? (VAR = NULL, -1) : 0)
+#define xasprintf(VAR, ...)\
+ (asprintf(&(VAR), __VA_ARGS__) < 0 ? (VAR = NULL, -1) : 0)
/*
-#define xasprintf(VAR, ...) \
- ({ \
- int _x_rc = (asprintf(&(VAR), __VA_ARGS__) < 0 ? (VAR = NULL, -1) : 0); \
- fprintf(stderr, "xasprintf(%s, %s)(=%zu) @ %s:%i\n", \
- #VAR, #__VA_ARGS__, _x_rc ? 0 : (strlen(VAR) + 1), __FILE__, __LINE__); \
- _x_rc; \
- })
+#define xasprintf(VAR, ...)\
+ ({\
+ int _x_rc = (asprintf(&(VAR), __VA_ARGS__) < 0 ? (VAR = NULL, -1) : 0);\
+ fprintf(stderr, "xasprintf(%s, %s)(=%zu) @ %s:%i\n",\
+ #VAR, #__VA_ARGS__, _x_rc ? 0 : (strlen(VAR) + 1), __FILE__, __LINE__);\
+ _x_rc;\
+ })
*/
@@ -138,8 +136,8 @@
* @param ...:const char*, ... The format string and arguments
* @return :int The number of bytes written, including the NUL-termination, negative on error
*/
-#define xsnprintf(buffer, ...) \
- snprintf(buffer, sizeof(buffer) / sizeof(char), __VA_ARGS__)
+#define xsnprintf(buffer, ...)\
+ snprintf(buffer, sizeof(buffer) / sizeof(char), __VA_ARGS__)
/**
@@ -149,8 +147,8 @@
* @param format:const char* The format
* @return :int The number of bytes written, including the NUL-termination, negative on error
*/
-#define eprint(format) \
- fprintf(stderr, "%s: " format "\n", *argv)
+#define eprint(format)\
+ fprintf(stderr, "%s: " format "\n", *argv)
/**
@@ -161,8 +159,8 @@
* @param ... The arguments
* @return :int The number of bytes written, including the NUL-termination, negative on error
*/
-#define eprintf(format, ...) \
- fprintf(stderr, "%s: " format "\n", *argv, __VA_ARGS__)
+#define eprintf(format, ...)\
+ fprintf(stderr, "%s: " format "\n", *argv, __VA_ARGS__)
/**
@@ -174,8 +172,8 @@
* @param format:const char* The format
* @return :int The number of bytes written, including the NUL-termination, negative on error
*/
-#define iprint(format) \
- fprintf(stderr, "%s: info: " format "\n", *argv)
+#define iprint(format)\
+ fprintf(stderr, "%s: info: " format "\n", *argv)
/**
@@ -188,8 +186,8 @@
* @param ... The arguments
* @return :int The number of bytes written, including the NUL-termination, negative on error
*/
-#define iprintf(format, ...) \
- fprintf(stderr, "%s: info: " format "\n", *argv, __VA_ARGS__)
+#define iprintf(format, ...)\
+ fprintf(stderr, "%s: info: " format "\n", *argv, __VA_ARGS__)
/**
@@ -198,18 +196,14 @@
* @param mutex:pthread_mutex_t The mutex
* @param instructions The instructions to run while the mutex is locked
*/
-#define with_mutex(mutex, instructions) \
- do \
- { \
- errno = pthread_mutex_lock(&(mutex)); \
- do \
- { \
- instructions ; \
- } \
- while (0); \
- errno = pthread_mutex_unlock(&(mutex)); \
- } \
- while (0)
+#define with_mutex(mutex, instructions)\
+ do {\
+ errno = pthread_mutex_lock(&mutex);\
+ do {\
+ instructions;\
+ } while (0);\
+ errno = pthread_mutex_unlock(&mutex);\
+ } while (0)
/**
* Wrapper for `pthread_mutex_lock` and `pthread_mutex_unlock` with an embedded if-statement
@@ -218,19 +212,14 @@
* @parma condition The condition to test
* @param instructions The instructions to run while the mutex is locked
*/
-#define with_mutex_if(mutex, condition, instructions) \
- do \
- { \
- errno = pthread_mutex_lock(&(mutex)); \
- if (condition) \
- do \
- { \
- instructions ; \
- } \
- while (0); \
- errno = pthread_mutex_unlock(&(mutex)); \
- } \
- while (0)
+#define with_mutex_if(mutex, condition, instructions)\
+ do {\
+ errno = pthread_mutex_lock(&mutex);\
+ if (condition) {\
+ instructions;\
+ }\
+ errno = pthread_mutex_unlock(&mutex);\
+ } while (0)
/**
@@ -240,8 +229,8 @@
* @param b The other one of the values
* @return The maximum value
*/
-#define max(a, b) \
- (a < b ? b : a)
+#define max(a, b)\
+ ((a) < (b) ? (b) : (a))
/**
@@ -251,8 +240,8 @@
* @param b The other one of the values
* @return The minimum value
*/
-#define min(a, b) \
- (a < b ? a : b)
+#define min(a, b)\
+ ((a) < (b) ? (a) : (b))
/**
@@ -263,8 +252,8 @@
* @param index:size_t The index of the element to address
* @return [type] A slot that can be set or get
*/
-#define buf_cast(buffer, type, index) \
- (((type*)(buffer))[index])
+#define buf_cast(buffer, type, index)\
+ (((type *)(buffer))[index])
/**
@@ -276,8 +265,8 @@
* @param variable:type The new value of the element
* @return variable: The new value of the element
*/
-#define buf_set(buffer, type, index, variable) \
- (((type*)(buffer))[index] = (variable))
+#define buf_set(buffer, type, index, variable)\
+ (((type *)(buffer))[index] = (variable))
/**
@@ -289,8 +278,8 @@
* @param variable:type Slot to set with the value of the element
* @return variable: The value of the element
*/
-#define buf_get(buffer, type, index, variable) \
- (variable = ((const type*)(buffer))[index])
+#define buf_get(buffer, type, index, variable)\
+ (variable = ((const type*)(buffer))[index])
/**
@@ -301,8 +290,8 @@
* @param count:size_t The number elements of the data type `type` to increase the pointer with
* @return buffer: The buffer
*/
-#define buf_next(buffer, type, count) \
- (buffer += (count) * sizeof(type) / sizeof(char))
+#define buf_next(buffer, type, count)\
+ (buffer += (count) * sizeof(type) / sizeof(char))
/**
@@ -313,8 +302,8 @@
* @param count:size_t The number elements of the data type `type` to decrease the pointer with
* @return buffer: The buffer
*/
-#define buf_prev(buffer, type, count) \
- (buffer -= (count) * sizeof(type) / sizeof(char))
+#define buf_prev(buffer, type, count)\
+ (buffer -= (count) * sizeof(type) / sizeof(char))
/**
@@ -326,9 +315,9 @@
* @param variable:type The new value of the element
* @return variable: The new value of the element
*/
-#define buf_set_next(buffer, type, variable) \
- (buf_set(buffer, type, 0, variable), \
- buf_next(buffer, type, 1))
+#define buf_set_next(buffer, type, variable)\
+ (buf_set(buffer, type, 0, variable),\
+ buf_next(buffer, type, 1))
/**
@@ -340,9 +329,9 @@
* @param variable:type Slot to set with the value of the element
* @return variable: The value of the element
*/
-#define buf_get_next(buffer, type, variable) \
- (buf_get(buffer, type, 0, variable), \
- buf_next(buffer, type, 1))
+#define buf_get_next(buffer, type, variable)\
+ (buf_get(buffer, type, 0, variable),\
+ buf_next(buffer, type, 1))
/**
@@ -352,8 +341,8 @@
* @param b:const char* The other of the strings
* @return :int Whether the strings are equal
*/
-#define strequals(a, b) \
- (strcmp(a, b) == 0)
+#define strequals(a, b)\
+ (!strcmp(a, b))
/**
@@ -363,8 +352,8 @@
* @param needle:const char* The string `haystack` should start with
* @return :int Whether `haystack` starts with `needle`
*/
-#define startswith(haystack, needle) \
- (strstr(haystack, needle) == haystack)
+#define startswith(haystack, needle)\
+ (strstr(haystack, needle) == haystack)
/**
@@ -374,9 +363,9 @@
*
* @return :int Non-zero on error
*/
-#define drop_privileges() \
- ((getegid() == getgid() ? 0 : setegid(getgid())) || \
- (geteuid() == getuid() ? 0 : seteuid(getuid())))
+#define drop_privileges()\
+ ((getegid() == getgid() ? 0 : setegid(getgid())) ||\
+ (geteuid() == getuid() ? 0 : seteuid(getuid())))
/**
@@ -386,8 +375,8 @@
* @param time_slot:struct timespec* Pointer to the variable in which to store the time
* @return :int Zero on success, -1 on error
*/
-#define monotone(time_slot) \
- clock_gettime(CLOCK_MONOTONIC_RAW, time_slot)
+#define monotone(time_slot)\
+ clock_gettime(CLOCK_MONOTONIC_RAW, time_slot)
/**
@@ -397,15 +386,15 @@
* @param fd:int The file descriptor
*/
#if 1 /* For kernels that ensure that close(2) always closes valid file descriptors. */
-# define xclose(fd) \
- close(fd)
+# define xclose(fd)\
+ close(fd)
#else /* For kernels that ensure that close(2) never closes valid file descriptors on interruption. */
# ifdef MDS_LIBMDSSERVER_MACROS_DEFINED_TEMP_FAILURE_RETRY
-# define xclose(fd) \
- TEMP_FAILURE_RETRY(close(fd))
+# define xclose(fd)\
+ TEMP_FAILURE_RETRY(close(fd))
# else
-# define xclose(fd) \
- (TEMP_FAILURE_RETRY(close(fd)) < 0 ? 0 : (errno = 0))
+# define xclose(fd)\
+ (TEMP_FAILURE_RETRY(close(fd)) < 0 ? 0 : (errno = 0))
# endif
#endif
@@ -417,15 +406,15 @@
* @param f:FILE* The stream
*/
#if 1 /* For kernels that ensure that close(2) always closes valid file descriptors. */
-# define xfclose(f) \
- fclose(f)
+# define xfclose(f)\
+ fclose(f)
#else /* For kernels that ensure that close(2) never closes valid file descriptors on interruption. */
# ifdef MDS_LIBMDSSERVER_MACROS_DEFINED_TEMP_FAILURE_RETRY
-# define xfclose(f) \
- TEMP_FAILURE_RETRY(fclose(f))
+# define xfclose(f)\
+ TEMP_FAILURE_RETRY(fclose(f))
# else
-# define xfclose(f) \
- (TEMP_FAILURE_RETRY(fclose(f)) < 0 ? 0 : (errno = 0))
+# define xfclose(f)\
+ (TEMP_FAILURE_RETRY(fclose(f)) < 0 ? 0 : (errno = 0))
# endif
#endif
@@ -435,29 +424,27 @@
*
* @param condition The condition, it should evaluate the variable `fd`
*/
-#define close_files(condition) \
- do \
- { \
- DIR* dir = opendir(SELF_FD); \
- struct dirent* file; \
- \
- if (dir == NULL) \
- perror(*argv); /* Well, that is just unfortunate, but we cannot really do anything. */ \
- else \
- { \
- int dfd = dirfd(dir); \
- while ((file = readdir(dir)) != NULL) \
- if (strcmp(file->d_name, ".") && strcmp(file->d_name, "..")) \
- { \
- int fd = atoi(file->d_name); \
- if (fd != dfd) \
- if (condition) \
- xclose(fd); \
- } \
- closedir(dir); \
- } \
- } \
- while (0)
+#define close_files(condition)\
+ do {\
+ DIR *dir = opendir(SELF_FD);\
+ struct dirent *file;\
+ int dfd, fd;\
+ \
+ if (!dir) {\
+ perror(*argv); /* Well, that is just unfortunate, but we cannot really do anything. */\
+ } else {\
+ dfd = dirfd(dir);\
+ while ((file = readdir(dir))) {\
+ if (strcmp(file->d_name, ".") && strcmp(file->d_name, "..")) {\
+ fd = atoi(file->d_name);\
+ if (fd != dfd)\
+ if (condition)\
+ xclose(fd);\
+ }\
+ }\
+ closedir(dir);\
+ }\
+ } while (0)
/**
@@ -467,14 +454,13 @@
* @param elements:size_t The number of elements, in the array, to free
* @scope i:size_t The variable `i` must be declared as `size_t` and avaiable for use
*/
-#define xfree(array, elements) \
- do \
- { \
- for (i = 0; i < (elements); i++) \
- free((array)[i]); \
- free(array), (array) = NULL; \
- } \
- while (0)
+#define xfree(array, elements)\
+ do {\
+ for (i = 0; i < (elements); i++)\
+ free((array)[i]);\
+ free(array);\
+ (array) = NULL;\
+ } while (0)
/**
@@ -485,17 +471,17 @@
* @param type The data type of the elements for which to create an allocation
* @return :int Evaluates to true if an only if the allocation failed
*/
-#define xmalloc(var, elements, type) \
- ((var = malloc((elements) * sizeof(type))) == NULL)
+#define xmalloc(var, elements, type)\
+ (!(var = malloc((elements) * sizeof(type))))
/*
-#define xmalloc(var, elements, type) \
- ({ \
- size_t _x_elements = (elements); \
- size_t _x_size = _x_elements * sizeof(type); \
- fprintf(stderr, "xmalloc(%s, %zu, %s)(=%zu) @ %s:%i\n", \
- #var, _x_elements, #type, _x_size, __FILE__, __LINE__); \
- ((var = malloc(_x_size)) == NULL); \
- })
+#define xmalloc(var, elements, type)\
+ ({\
+ size_t _x_elements = (elements);\
+ size_t _x_size = _x_elements * sizeof(type);\
+ fprintf(stderr, "xmalloc(%s, %zu, %s)(=%zu) @ %s:%i\n",\
+ #var, _x_elements, #type, _x_size, __FILE__, __LINE__);\
+ (!(var = malloc(_x_size)));\
+ })
*/
@@ -506,16 +492,16 @@
* @param bytes:size_t The number of bytes to allocate
* @return :int Evaluates to true if an only if the allocation failed
*/
-#define xbmalloc(var, bytes) \
- ((var = malloc(bytes)) == NULL)
+#define xbmalloc(var, bytes) \
+ (!(var = malloc(bytes)))
/*
-#define xbmalloc(var, bytes) \
- ({ \
- size_t _x_bytes = (bytes); \
- fprintf(stderr, "xbmalloc(%s, %zu) @ %s:%i\n", \
- #var, _x_bytes, __FILE__, __LINE__); \
- ((var = malloc(_x_bytes)) == NULL); \
- })
+#define xbmalloc(var, bytes)\
+ ({\
+ size_t _x_bytes = (bytes);\
+ fprintf(stderr, "xbmalloc(%s, %zu) @ %s:%i\n",\
+ #var, _x_bytes, __FILE__, __LINE__);\
+ (!(var = malloc(_x_bytes)));\
+ })
*/
@@ -527,17 +513,17 @@
* @param type The data type of the elements for which to create an allocation
* @return :int Evaluates to true if an only if the allocation failed
*/
-#define xcalloc(var, elements, type) \
- ((var = calloc(elements, sizeof(type))) == NULL)
+#define xcalloc(var, elements, type)\
+ (!(var = calloc(elements, sizeof(type))))
/*
-#define xcalloc(var, elements, type) \
- ({ \
- size_t _x_elements = (elements); \
- size_t _x_size = _x_elements * sizeof(type); \
- fprintf(stderr, "xcalloc(%s, %zu, %s)(=%zu) @ %s:%i\n", \
- #var, _x_elements, #type, _x_size, __FILE__, __LINE__); \
- ((var = calloc(_x_elements, sizeof(type))) == NULL); \
- })
+#define xcalloc(var, elements, type)\
+ ({\
+ size_t _x_elements = (elements);\
+ size_t _x_size = _x_elements * sizeof(type);\
+ fprintf(stderr, "xcalloc(%s, %zu, %s)(=%zu) @ %s:%i\n",\
+ #var, _x_elements, #type, _x_size, __FILE__, __LINE__);\
+ (!(var = calloc(_x_elements, sizeof(type))));\
+ })
*/
@@ -548,16 +534,16 @@
* @param bytes:size_t The number of bytes to allocate
* @return :int Evaluates to true if an only if the allocation failed
*/
-#define xbcalloc(var, bytes) \
- ((var = calloc(bytes, sizeof(char))) == NULL)
+#define xbcalloc(var, bytes)\
+ (!(var = calloc(bytes, sizeof(char))))
/*
-#define xbcalloc(var, bytes) \
- ({ \
- size_t _x_bytes = (bytes); \
- fprintf(stderr, "xbcalloc(%s, %zu) @ %s:%i\n", \
- #var, _x_bytes, __FILE__, __LINE__); \
- ((var = calloc(_x_bytes, sizeof(char))) == NULL); \
- })
+#define xbcalloc(var, bytes)\
+ ({\
+ size_t _x_bytes = (bytes);\
+ fprintf(stderr, "xbcalloc(%s, %zu) @ %s:%i\n",\
+ #var, _x_bytes, __FILE__, __LINE__);\
+ (!(var = calloc(_x_bytes, sizeof(char))));\
+ })
*/
@@ -570,16 +556,16 @@
* @return :int Evaluates to true if an only if the allocation failed
*/
#define xrealloc(var, elements, type) \
- ((var = realloc(var, (elements) * sizeof(type))) == NULL)
+ (!(var = realloc(var, (elements) * sizeof(type))))
/*
-#define xrealloc(var, elements, type) \
- ({ \
- size_t _x_elements = (elements); \
- size_t _x_size = _x_elements * sizeof(type); \
- fprintf(stderr, "xrealloc(%s, %zu, %s)(=%zu) @ %s:%i\n", \
- #var, _x_elements, #type, _x_size, __FILE__, __LINE__); \
- ((var = realloc(var, _x_size)) == NULL); \
- })
+#define xrealloc(var, elements, type)\
+ ({\
+ size_t _x_elements = (elements);\
+ size_t _x_size = _x_elements * sizeof(type);\
+ fprintf(stderr, "xrealloc(%s, %zu, %s)(=%zu) @ %s:%i\n",\
+ #var, _x_elements, #type, _x_size, __FILE__, __LINE__);\
+ (!(var = realloc(var, _x_size)));\
+ })
*/
@@ -593,17 +579,17 @@
* @param type The data type of the elements for which to create an allocation
* @return :int Evaluates to true if an only if the allocation failed
*/
-#define xxrealloc(old, var, elements, type) \
- (old = var, (((var = realloc(var, (elements) * sizeof(type))) == NULL) ? 1 : (old = NULL, 0)))
+#define xxrealloc(old, var, elements, type)\
+ (old = var, ((!(var = realloc(var, (elements) * sizeof(type)))) ? 1 : (old = NULL, 0)))
/*
-#define xxrealloc(old, var, elements, type) \
- ({ \
- size_t _x_elements = (elements); \
- size_t _x_size = _x_elements * sizeof(type); \
- fprintf(stderr, "xxrealloc(%s, %s, %zu, %s)(=%zu) @ %s:%i\n", \
- #old, #var, _x_elements, #type, _x_size, __FILE__, __LINE__); \
- (old = var, (((var = realloc(var, _x_size)) == NULL) ? 1 : (old = NULL, 0))); \
- })
+#define xxrealloc(old, var, elements, type)\
+ ({\
+ size_t _x_elements = (elements);\
+ size_t _x_size = _x_elements * sizeof(type);\
+ fprintf(stderr, "xxrealloc(%s, %s, %zu, %s)(=%zu) @ %s:%i\n",\
+ #old, #var, _x_elements, #type, _x_size, __FILE__, __LINE__);\
+ (old = var, ((!(var = realloc(var, _x_size))) ? 1 : (old = NULL, 0)));\
+ })
*/
@@ -616,19 +602,19 @@
* @param type The data type of the elements for which to create an allocation
* @return :int Evaluates to true if an only if the allocation failed
*/
-#define yrealloc(tmp, var, elements, type) \
- ((tmp = var, (var = realloc(var, (elements) * sizeof(type))) == NULL) \
- ? (var = tmp, tmp = NULL, 1) : (tmp = NULL, 0))
+#define yrealloc(tmp, var, elements, type)\
+ ((tmp = var, !(var = realloc(var, (elements) * sizeof(type))))\
+ ? (var = tmp, tmp = NULL, 1) : (tmp = NULL, 0))
/*
-#define yrealloc(tmp, var, elements, type) \
- ({ \
- size_t _x_elements = (elements); \
- size_t _x_size = _x_elements * sizeof(type); \
- fprintf(stderr, "yrealloc(%s, %s, %zu, %s)(=%zu) @ %s:%i\n", \
- #tmp, #var, _x_elements, #type, _x_size, __FILE__, __LINE__); \
- ((tmp = var, (var = realloc(var, _x_size)) == NULL) \
- ? (var = tmp, tmp = NULL, 1) : (tmp = NULL, 0)); \
- })
+#define yrealloc(tmp, var, elements, type)\
+ ({\
+ size_t _x_elements = (elements);\
+ size_t _x_size = _x_elements * sizeof(type);\
+ fprintf(stderr, "yrealloc(%s, %s, %zu, %s)(=%zu) @ %s:%i\n",\
+ #tmp, #var, _x_elements, #type, _x_size, __FILE__, __LINE__);\
+ ((tmp = var, !(var = realloc(var, _x_size)))\
+ ? (var = tmp, tmp = NULL, 1) : (tmp = NULL, 0));\
+ })
*/
@@ -641,17 +627,17 @@
* @param type The data type of the elements for which to create an allocation
* @return :int Evaluates to true if an only if the allocation failed
*/
-#define growalloc(old, var, elements, type) \
- (old = var, xrealloc(var, (elements) <<= 1, type) ? (var = old, (elements) >>= 1, 1) : 0)
+#define growalloc(old, var, elements, type) \
+ (old = var, xrealloc(var, (elements) <<= 1, type) ? (var = old, (elements) >>= 1, 1) : 0)
/*
-#define growalloc(old, var, elements, type) \
- ({ \
- size_t _x_elements_ = (elements); \
- size_t _x_size_ = _x_elements_ * sizeof(type); \
- fprintf(stderr, "growalloc(%s, %s, %zu, %s)(=%zu)\n--> ", \
- #old, #var, _x_elements_, #type, _x_size_, __FILE__, __LINE__); \
- (old = var, xrealloc(var, (elements) <<= 1, type) ? (var = old, (elements) >>= 1, 1) : 0); \
- })
+#define growalloc(old, var, elements, type)\
+ ({\
+ size_t _x_elements_ = (elements);\
+ size_t _x_size_ = _x_elements_ * sizeof(type);\
+ fprintf(stderr, "growalloc(%s, %s, %zu, %s)(=%zu)\n--> ",\
+ #old, #var, _x_elements_, #type, _x_size_, __FILE__, __LINE__);\
+ (old = var, xrealloc(var, (elements) <<= 1, type) ? (var = old, (elements) >>= 1, 1) : 0);\
+ })
*/
@@ -662,16 +648,16 @@
* @param original:const char* The string to duplicate, may be `NULL`
* @return :int Evaluates to true if an only if the allocation failed
*/
-#define xstrdup(var, original) \
- (original ? ((var = strdup(original)) == NULL) : (var = NULL, 0))
+#define xstrdup(var, original)\
+ (original ? !(var = strdup(original)) : (var = NULL, 0))
/*
-#define xstrdup(var, original) \
- ({ \
- size_t _x_size = original ? strlen(original) : 0; \
- fprintf(stderr, "xstrdup(%s, %s(“%s”=%zu))(=%zu) @ %s:%i\n", \
- #var, #original, original, _x_size, _x_size + !!_x_size, __FILE__, __LINE__); \
- (original ? ((var = strdup(original)) == NULL) : (var = NULL, 0)); \
- })
+#define xstrdup(var, original)\
+ ({\
+ size_t _x_size = original ? strlen(original) : 0;\
+ fprintf(stderr, "xstrdup(%s, %s(“%s”=%zu))(=%zu) @ %s:%i\n",\
+ #var, #original, original, _x_size, _x_size + !!_x_size, __FILE__, __LINE__);\
+ (original ? ((var = strdup(original)) == NULL) : (var = NULL, 0));\
+ })
*/
@@ -685,16 +671,16 @@
* @param original:const char* The string to duplicate, must not be `NULL`
* @return :int Evaluates to true if an only if the allocation failed
*/
-#define xstrdup_nn(var, original) \
- ((var = strdup(original)) == NULL)
+#define xstrdup_nn(var, original)\
+ (!(var = strdup(original)))
/*
-#define xstrdup_nn(var, original) \
- ({ \
- size_t _x_size = strlen(original); \
- fprintf(stderr, "xstrdup_nn(%s, %s(“%s”=%zu))(=%zu) @ %s:%i\n", \
- #var, #original, original, _x_size, _x_size + !!_x_size, __FILE__, __LINE__); \
- (var = strdup(original)) == NULL; \
- })
+#define xstrdup_nn(var, original)\
+ ({\
+ size_t _x_size = strlen(original);\
+ fprintf(stderr, "xstrdup_nn(%s, %s(“%s”=%zu))(=%zu) @ %s:%i\n",\
+ #var, #original, original, _x_size, _x_size + !!_x_size, __FILE__, __LINE__);\
+ !(var = strdup(original));\
+ })
*/
@@ -708,18 +694,18 @@
* @param type The data type of the elements to duplicate
* @return :int Evaluates to true if an only if the allocation failed
*/
-#define xmemdup(var, original, elements, type) \
- (((var = malloc((elements) * sizeof(type))) == NULL) ? 1 : \
- (memcpy(var, original, (elements) * sizeof(type)), 0))
+#define xmemdup(var, original, elements, type)\
+ (!(var = malloc((elements) * sizeof(type))) ? 1 :\
+ (memcpy(var, original, (elements) * sizeof(type)), 0))
/*
-#define xmemdup(var, original, elements, type) \
- ({ \
- size_t _x_elements = (elements); \
- size_t _x_size = _x_elements * sizeof(type); \
- fprintf(stderr, "xmemdup(%s, %s, %zu, %s)(=%zu) @ %s:%i\n", \
- #var, #original, _x_elements, #type, _x_size, __FILE__, __LINE__); \
- (((var = malloc(_x_size)) == NULL) ? 1 : (memcpy(var, original, _x_size), 0)); \
- })
+#define xmemdup(var, original, elements, type)\
+ ({\
+ size_t _x_elements = (elements);\
+ size_t _x_size = _x_elements * sizeof(type);\
+ fprintf(stderr, "xmemdup(%s, %s, %zu, %s)(=%zu) @ %s:%i\n",\
+ #var, #original, _x_elements, #type, _x_size, __FILE__, __LINE__);\
+ !(var = malloc(_x_size)) ? 1 : (memcpy(var, original, _x_size), 0);\
+ })
*/
diff --git a/src/libmdsserver/mds-message.c b/src/libmdsserver/mds-message.c
index 4ec8142..c3d968f 100644
--- a/src/libmdsserver/mds-message.c
+++ b/src/libmdsserver/mds-message.c
@@ -27,7 +27,7 @@
#include <sys/socket.h>
-#define try(INSTRUCTION) if ((r = INSTRUCTION) < 0) return r
+#define try(INSTRUCTION) do { if ((r = INSTRUCTION) < 0) return r; } while (0)
/**
@@ -38,20 +38,21 @@
* @return Non-zero on error, `errno` will be set accordingly.
* Destroy the message on error.
*/
-int mds_message_initialise(mds_message_t* restrict this)
+int
+mds_message_initialise(mds_message_t *restrict this)
{
- this->headers = NULL;
- this->header_count = 0;
- this->payload = NULL;
- this->payload_size = 0;
- this->payload_ptr = 0;
- this->buffer_size = 128;
- this->buffer_ptr = 0;
- this->stage = 0;
- fail_if (xmalloc(this->buffer, this->buffer_size, char));
- return 0;
- fail:
- return -1;
+ this->headers = NULL;
+ this->header_count = 0;
+ this->payload = NULL;
+ this->payload_size = 0;
+ this->payload_ptr = 0;
+ this->buffer_size = 128;
+ this->buffer_ptr = 0;
+ this->stage = 0;
+ fail_if (xmalloc(this->buffer, this->buffer_size, char));
+ return 0;
+fail:
+ return -1;
}
@@ -60,17 +61,18 @@ int mds_message_initialise(mds_message_t* restrict this)
*
* @param this Memory slot in which to store the new message
*/
-void mds_message_zero_initialise(mds_message_t* restrict this)
+void
+mds_message_zero_initialise(mds_message_t *restrict this)
{
- this->headers = NULL;
- this->header_count = 0;
- this->payload = NULL;
- this->payload_size = 0;
- this->payload_ptr = 0;
- this->buffer = NULL;
- this->buffer_size = 0;
- this->buffer_ptr = 0;
- this->stage = 0;
+ this->headers = NULL;
+ this->header_count = 0;
+ this->payload = NULL;
+ this->payload_size = 0;
+ this->payload_ptr = 0;
+ this->buffer = NULL;
+ this->buffer_size = 0;
+ this->buffer_ptr = 0;
+ this->stage = 0;
}
@@ -80,14 +82,15 @@ void mds_message_zero_initialise(mds_message_t* restrict this)
*
* @param this The message
*/
-void mds_message_destroy(mds_message_t* restrict this)
+void
+mds_message_destroy(mds_message_t *restrict this)
{
- size_t i;
- if (this->headers != NULL)
- xfree(this->headers, this->header_count);
-
- free(this->payload), this->payload = NULL;
- free(this->buffer), this->buffer = NULL;
+ size_t i;
+ if (this->headers)
+ xfree(this->headers, this->header_count);
+
+ free(this->payload), this->payload = NULL;
+ free(this->buffer), this->buffer = NULL;
}
@@ -98,14 +101,15 @@ void mds_message_destroy(mds_message_t* restrict this)
* @param extent The number of additional entries
* @return Zero on success, -1 on error
*/
-int mds_message_extend_headers(mds_message_t* restrict this, size_t extent)
+int
+mds_message_extend_headers(mds_message_t *restrict this, size_t extent)
{
- char** new_headers = this->headers;
- fail_if (xrealloc(new_headers, this->header_count + extent, char*));
- this->headers = new_headers;
- return 0;
- fail:
- return -1;
+ char **new_headers = this->headers;
+ fail_if (xrealloc(new_headers, this->header_count + extent, char*));
+ this->headers = new_headers;
+ return 0;
+fail:
+ return -1;
}
@@ -115,16 +119,16 @@ 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)
+static int __attribute__((nonnull))
+mds_message_extend_buffer(mds_message_t *restrict this)
{
- char* new_buf = this->buffer;
- fail_if (xrealloc(new_buf, this->buffer_size << 1, char));
- this->buffer = new_buf;
- this->buffer_size <<= 1;
- return 0;
- fail:
- return -1;
+ char *new_buf = this->buffer;
+ fail_if (xrealloc(new_buf, this->buffer_size << 1, char));
+ this->buffer = new_buf;
+ this->buffer_size <<= 1;
+ return 0;
+fail:
+ return -1;
}
@@ -133,18 +137,18 @@ 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)
+static void __attribute__((nonnull))
+reset_message(mds_message_t *restrict this)
{
- size_t i;
- if (this->headers != NULL)
- xfree(this->headers, this->header_count);
- this->header_count = 0;
-
- free(this->payload);
- this->payload = NULL;
- this->payload_size = 0;
- this->payload_ptr = 0;
+ size_t i;
+ if (this->headers)
+ xfree(this->headers, this->header_count);
+ this->header_count = 0;
+
+ free(this->payload);
+ this->payload = NULL;
+ this->payload_size = 0;
+ this->payload_ptr = 0;
}
@@ -154,29 +158,29 @@ 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)
+static int __attribute__((pure, nonnull))
+get_payload_length(mds_message_t *restrict this)
{
- char* header;
- size_t i;
-
- for (i = 0; i < this->header_count; i++)
- if (strstr(this->headers[i], "Length: ") == this->headers[i])
- {
- /* Store the message length. */
- header = this->headers[i] + strlen("Length: ");
- this->payload_size = atoz(header);
-
- /* Do not except a length that is not correctly formated. */
- for (; *header; header++)
- if ((*header < '0') || ('9' < *header))
- return -2; /* Malformated value, enters unrecoverable state. */
-
- /* Stop searching for the ‘Length’ header, we have found and parsed it. */
- break;
- }
-
- return 0;
+ char *header;
+ size_t i;
+
+ for (i = 0; i < this->header_count; i++) {
+ if (strstr(this->headers[i], "Length: ") == this->headers[i]) {
+ /* Store the message length. */
+ header = this->headers[i] + strlen("Length: ");
+ this->payload_size = atoz(header);
+
+ /* Do not except a length that is not correctly formated. */
+ for (; *header; header++)
+ if (*header < '0' || '9' < *header)
+ return -2; /* Malformated value, enters unrecoverable state. */
+
+ /* Stop searching for the ‘Length’ header, we have found and parsed it. */
+ break;
+ }
+ }
+
+ return 0;
}
@@ -187,21 +191,21 @@ 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)
*/
-__attribute__((pure, nonnull))
-static int validate_header(const char* header, size_t length)
+static int __attribute__((pure, nonnull))
+validate_header(const char *header, size_t length)
{
- char* p = memchr(header, ':', length * sizeof(char));
-
- if (verify_utf8(header, 0) < 0)
- /* Either the string is not UTF-8, or your are under an UTF-8 attack,
- let's just call this unrecoverable because the client will not correct. */
- return -2;
-
- if ((p == NULL) || /* Buck you, rawmemchr should not segfault the program. */
- (p[1] != ' ')) /* Also an invalid format. ' ' is mandated after the ':'. */
- return -2;
-
- return 0;
+ char *p = memchr(header, ':', length * sizeof(char));
+
+ if (verify_utf8(header, 0) < 0)
+ /* Either the string is not UTF-8, or your are under an UTF-8 attack,
+ let's just call this unrecoverable because the client will not correct. */
+ return -2;
+
+ if (!p || /* Buck you, rawmemchr should not segfault the program. */
+ p[1] != ' ') /* Also an invalid format. ' ' is mandated after the ':'. */
+ return -2;
+
+ return 0;
}
@@ -212,12 +216,12 @@ static int validate_header(const char* header, size_t length)
* @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)
+static void __attribute__((nonnull))
+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));
- if (update_ptr)
- this->buffer_ptr -= length;
+ memmove(this->buffer, this->buffer + length, (this->buffer_ptr - length) * sizeof(char));
+ if (update_ptr)
+ this->buffer_ptr -= length;
}
@@ -228,23 +232,23 @@ 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)
+static int __attribute__((nonnull))
+initialise_payload(mds_message_t *restrict this)
{
- /* Remove the \n (end of empty line) we found from the buffer. */
- unbuffer_beginning(this, 1, 1);
-
- /* Get the length of the payload. */
- if (get_payload_length(this) < 0)
- return -2; /* Malformated value, enters unrecoverable state. */
-
- /* Allocate the payload buffer. */
- if (this->payload_size > 0)
- fail_if (xmalloc(this->payload, this->payload_size, char));
-
- return 0;
- fail:
- return -1;
+ /* Remove the \n (end of empty line) we found from the buffer. */
+ unbuffer_beginning(this, 1, 1);
+
+ /* Get the length of the payload. */
+ if (get_payload_length(this) < 0)
+ return -2; /* Malformated value, enters unrecoverable state. */
+
+ /* Allocate the payload buffer. */
+ if (this->payload_size > 0)
+ fail_if (xmalloc(this->payload, this->payload_size, char));
+
+ return 0;
+fail:
+ return -1;
}
@@ -255,35 +259,34 @@ 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)
+static int __attribute__((nonnull))
+store_header(mds_message_t *restrict this, size_t length)
{
- char* header;
-
- /* Allocate the header. */
- fail_if (xmalloc(header, length, char)); /* Last char is a LF, which is substituted with NUL. */
- /* Copy the header data into the allocated header, */
- memcpy(header, this->buffer, length * sizeof(char));
- /* and NUL-terminate it. */
- header[length - 1] = '\0';
-
- /* Remove the header data from the read buffer. */
- unbuffer_beginning(this, length, 1);
-
- /* Make sure the the header syntax is correct so that
- the program does not need to care about it. */
- if (validate_header(header, length))
- {
- free(header);
- return -2;
- }
-
- /* Store the header in the header list. */
- this->headers[this->header_count++] = header;
-
- return 0;
- fail:
- return -1;
+ char *header;
+
+ /* Allocate the header. */
+ fail_if (xmalloc(header, length, char)); /* Last char is a LF, which is substituted with NUL. */
+ /* Copy the header data into the allocated header, */
+ memcpy(header, this->buffer, length * sizeof(char));
+ /* and NUL-terminate it. */
+ header[length - 1] = '\0';
+
+ /* Remove the header data from the read buffer. */
+ unbuffer_beginning(this, length, 1);
+
+ /* Make sure the the header syntax is correct so that
+ the program does not need to care about it. */
+ if (validate_header(header, length)) {
+ free(header);
+ return -2;
+ }
+
+ /* Store the header in the header list. */
+ this->headers[this->header_count++] = header;
+
+ return 0;
+fail:
+ return -1;
}
@@ -294,37 +297,36 @@ 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)
+static int __attribute__((nonnull))
+continue_read(mds_message_t *restrict this, int fd)
{
- size_t n;
- ssize_t got;
- int r;
-
- /* Figure out how much space we have left in the read buffer. */
- n = this->buffer_size - this->buffer_ptr;
-
- /* If we do not have too much left, */
- if (n < 128)
- {
- /* grow the buffer, */
- try (mds_message_extend_buffer(this));
-
- /* and recalculate how much space we have left. */
- n = this->buffer_size - this->buffer_ptr;
- }
-
- /* Then read from the socket. */
- errno = 0;
- got = recv(fd, this->buffer + this->buffer_ptr, n, 0);
- this->buffer_ptr += (size_t)(got < 0 ? 0 : got);
- fail_if (errno);
- if (got == 0)
- fail_if ((errno = ECONNRESET));
-
- return 0;
- fail:
- return -1;
+ size_t n;
+ ssize_t got;
+ int r;
+
+ /* Figure out how much space we have left in the read buffer. */
+ n = this->buffer_size - this->buffer_ptr;
+
+ /* If we do not have too much left, */
+ if (n < 128) {
+ /* grow the buffer, */
+ try (mds_message_extend_buffer(this));
+
+ /* and recalculate how much space we have left. */
+ n = this->buffer_size - this->buffer_ptr;
+ }
+
+ /* Then read from the socket. */
+ errno = 0;
+ got = recv(fd, this->buffer + this->buffer_ptr, n, 0);
+ this->buffer_ptr += (size_t)(got < 0 ? 0 : got);
+ fail_if (errno);
+ if (!got)
+ fail_if ((errno = ECONNRESET));
+
+ return 0;
+fail:
+ return -1;
}
@@ -341,86 +343,78 @@ static int continue_read(mds_message_t* restrict this, int fd)
* -2 indicates that the message is malformated,
* which is a state that cannot be recovered from.
*/
-int mds_message_read(mds_message_t* restrict this, int fd)
+int
+mds_message_read(mds_message_t *restrict this, int fd)
{
- size_t header_commit_buffer = 0;
- int r;
-
- /* If we are at stage 2, we are done and it is time to start over.
- This is important because the function could have been interrupted. */
- if (this->stage == 2)
- {
- reset_message(this);
- this->stage = 0;
- }
-
- /* Read from file descriptor until we have a full message. */
- for (;;)
- {
- char* p;
- size_t length;
-
- /* Stage 0: headers. */
- /* Read all headers that we have stored into the read buffer. */
- while ((this->stage == 0) &&
- ((p = memchr(this->buffer, '\n', this->buffer_ptr * sizeof(char))) != NULL))
- if ((length = (size_t)(p - this->buffer)))
- {
- /* We have found a header. */
-
- /* On every eighth header found with this function call,
- we prepare the header list for eight more headers so
- that it does not need to be reallocated again and again. */
- if (header_commit_buffer == 0)
- try (mds_message_extend_headers(this, header_commit_buffer = 8));
-
- /* Create and store header. */
- try (store_header(this, length + 1));
- header_commit_buffer -= 1;
- }
- else
- {
- /* We have found an empty line, i.e. the end of the headers. */
-
- /* Remove the header–payload delimiter from the buffer,
- get the payload's size and allocate the payload. */
- try (initialise_payload(this));
-
- /* Mark end of stage, next stage is getting the payload. */
- this->stage = 1;
- }
-
-
- /* Stage 1: payload. */
- if ((this->stage == 1) && (this->payload_size > 0))
- {
- /* How much of the payload that has not yet been filled. */
- size_t need = this->payload_size - this->payload_ptr;
- /* How much we have of that what is needed. */
- size_t move = min(this->buffer_ptr, need);
-
- /* Copy what we have, and remove it from the the read buffer. */
- memcpy(this->payload + this->payload_ptr, this->buffer, move * sizeof(char));
- unbuffer_beginning(this, move, 1);
-
- /* Keep track of how much we have read. */
- this->payload_ptr += move;
+ size_t header_commit_buffer = 0, length, need, move;
+ int r;
+ char *p;
+
+ /* If we are at stage 2, we are done and it is time to start over.
+ This is important because the function could have been interrupted. */
+ if (this->stage == 2) {
+ reset_message(this);
+ this->stage = 0;
}
- if ((this->stage == 1) && (this->payload_ptr == this->payload_size))
- {
- /* If we have filled the payload (or there was no payload),
- mark the end of this stage, i.e. that the message is
- complete, and return with success. */
- this->stage = 2;
- return 0;
+
+ /* Read from file descriptor until we have a full message. */
+ for (;;) {
+ /* Stage 0: headers. */
+ /* Read all headers that we have stored into the read buffer. */
+ while (!this->stage && ((p = memchr(this->buffer, '\n', this->buffer_ptr * sizeof(char))))) {
+ if ((length = (size_t)(p - this->buffer))) {
+ /* We have found a header. */
+
+ /* On every eighth header found with this function call,
+ we prepare the header list for eight more headers so
+ that it does not need to be reallocated again and again. */
+ if (!header_commit_buffer)
+ try (mds_message_extend_headers(this, header_commit_buffer = 8));
+
+ /* Create and store header. */
+ try (store_header(this, length + 1));
+ header_commit_buffer -= 1;
+ } else {
+ /* We have found an empty line, i.e. the end of the headers. */
+
+ /* Remove the header–payload delimiter from the buffer,
+ get the payload's size and allocate the payload. */
+ try (initialise_payload(this));
+
+ /* Mark end of stage, next stage is getting the payload. */
+ this->stage = 1;
+ }
+ }
+
+
+ /* Stage 1: payload. */
+ if (this->stage == 1 && this->payload_size > 0) {
+ /* How much of the payload that has not yet been filled. */
+ need = this->payload_size - this->payload_ptr;
+ /* How much we have of that what is needed. */
+ move = min(this->buffer_ptr, need);
+
+ /* Copy what we have, and remove it from the the read buffer. */
+ memcpy(this->payload + this->payload_ptr, this->buffer, move * sizeof(char));
+ unbuffer_beginning(this, move, 1);
+
+ /* Keep track of how much we have read. */
+ this->payload_ptr += move;
+ }
+ if (this->stage == 1 && this->payload_ptr == this->payload_size) {
+ /* If we have filled the payload (or there was no payload),
+ mark the end of this stage, i.e. that the message is
+ complete, and return with success. */
+ this->stage = 2;
+ return 0;
+ }
+
+
+ /* If stage 1 was not completed. */
+
+ /* Continue reading from the socket into the buffer. */
+ try (continue_read(this, fd));
}
-
-
- /* If stage 1 was not completed. */
-
- /* Continue reading from the socket into the buffer. */
- try (continue_read(this, fd));
- }
}
@@ -431,15 +425,15 @@ 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)
+size_t
+mds_message_marshal_size(const mds_message_t *restrict this)
{
- size_t rc = this->header_count + this->payload_size;
- size_t i;
- for (i = 0; i < this->header_count; i++)
- rc += strlen(this->headers[i]);
- rc *= sizeof(char);
- rc += 4 * sizeof(size_t) + 2 * sizeof(int);
- return rc;
+ size_t i, rc = this->header_count + this->payload_size;
+ for (i = 0; i < this->header_count; i++)
+ rc += strlen(this->headers[i]);
+ rc *= sizeof(char);
+ rc += 4 * sizeof(size_t) + 2 * sizeof(int);
+ return rc;
}
@@ -449,29 +443,29 @@ size_t mds_message_marshal_size(const mds_message_t* restrict this)
* @param this The message
* @param data Output buffer for the marshalled data
*/
-void mds_message_marshal(const mds_message_t* restrict this, char* restrict data)
+void
+mds_message_marshal(const mds_message_t *restrict this, char *restrict data)
{
- size_t i, n;
-
- buf_set_next(data, int, MDS_MESSAGE_T_VERSION);
-
- buf_set_next(data, size_t, this->header_count);
- buf_set_next(data, size_t, this->payload_size);
- buf_set_next(data, size_t, this->payload_ptr);
- buf_set_next(data, size_t, this->buffer_ptr);
- buf_set_next(data, int, this->stage);
-
- for (i = 0; i < this->header_count; i++)
- {
- n = strlen(this->headers[i]) + 1;
- memcpy(data, this->headers[i], n * sizeof(char));
- buf_next(data, char, n);
- }
-
- memcpy(data, this->payload, this->payload_ptr * sizeof(char));
- buf_next(data, char, this->payload_ptr);
-
- memcpy(data, this->buffer, this->buffer_ptr * sizeof(char));
+ size_t i, n;
+
+ buf_set_next(data, int, MDS_MESSAGE_T_VERSION);
+
+ buf_set_next(data, size_t, this->header_count);
+ buf_set_next(data, size_t, this->payload_size);
+ buf_set_next(data, size_t, this->payload_ptr);
+ buf_set_next(data, size_t, this->buffer_ptr);
+ buf_set_next(data, int, this->stage);
+
+ for (i = 0; i < this->header_count; i++) {
+ n = strlen(this->headers[i]) + 1;
+ memcpy(data, this->headers[i], n * sizeof(char));
+ buf_next(data, char, n);
+ }
+
+ memcpy(data, this->payload, this->payload_ptr * sizeof(char));
+ buf_next(data, char, this->payload_ptr);
+
+ memcpy(data, this->buffer, this->buffer_ptr * sizeof(char));
}
@@ -483,75 +477,74 @@ 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.
*/
-int mds_message_unmarshal(mds_message_t* restrict this, char* restrict data)
+int
+mds_message_unmarshal(mds_message_t *restrict this, char *restrict data)
{
- size_t i, n, header_count;
-
- /* buf_get(data, int, 0, MDS_MESSAGE_T_VERSION); */
- buf_next(data, int, 1);
-
- this->header_count = 0;
- buf_get_next(data, size_t, header_count);
- buf_get_next(data, size_t, this->payload_size);
- buf_get_next(data, size_t, this->payload_ptr);
- buf_get_next(data, size_t, this->buffer_size = this->buffer_ptr);
- buf_get_next(data, int, this->stage);
-
- /* Make sure that the pointers are NULL so that they are
- not freed without being allocated when the message is
- destroyed if this function fails. */
- this->headers = NULL;
- this->payload = NULL;
- this->buffer = NULL;
-
- /* To 2-power-multiple of 128 bytes. */
- this->buffer_size >>= 7;
- if (this->buffer_size == 0)
- this->buffer_size = 1;
- else
- {
- this->buffer_size -= 1;
- this->buffer_size |= this->buffer_size >> 1;
- this->buffer_size |= this->buffer_size >> 2;
- this->buffer_size |= this->buffer_size >> 4;
- this->buffer_size |= this->buffer_size >> 8;
- this->buffer_size |= this->buffer_size >> 16;
+ size_t i, n, header_count;
+
+ /* buf_get(data, int, 0, MDS_MESSAGE_T_VERSION); */
+ buf_next(data, int, 1);
+
+ this->header_count = 0;
+ buf_get_next(data, size_t, header_count);
+ buf_get_next(data, size_t, this->payload_size);
+ buf_get_next(data, size_t, this->payload_ptr);
+ buf_get_next(data, size_t, this->buffer_size = this->buffer_ptr);
+ buf_get_next(data, int, this->stage);
+
+ /* Make sure that the pointers are NULL so that they are
+ not freed without being allocated when the message is
+ destroyed if this function fails. */
+ this->headers = NULL;
+ this->payload = NULL;
+ this->buffer = NULL;
+
+ /* To 2-power-multiple of 128 bytes. */
+ this->buffer_size >>= 7;
+ if (!this->buffer_size) {
+ this->buffer_size = 1;
+ } else {
+ this->buffer_size -= 1;
+ this->buffer_size |= this->buffer_size >> 1;
+ this->buffer_size |= this->buffer_size >> 2;
+ this->buffer_size |= this->buffer_size >> 4;
+ this->buffer_size |= this->buffer_size >> 8;
+ this->buffer_size |= this->buffer_size >> 16;
#if SIZE_MAX == UINT64_MAX
- this->buffer_size |= this->buffer_size >> 32;
+ this->buffer_size |= this->buffer_size >> 32;
#endif
- this->buffer_size += 1;
- }
- this->buffer_size <<= 7;
-
- /* Allocate header list, payload and read buffer. */
-
- if (header_count > 0)
- fail_if (xmalloc(this->headers, header_count, char*));
-
- if (this->payload_size > 0)
- fail_if (xmalloc(this->payload, this->payload_size, char));
-
- fail_if (xmalloc(this->buffer, this->buffer_size, char));
-
- /* Fill the header list, payload and read buffer. */
-
- for (i = 0; i < header_count; i++)
- {
- n = strlen(data) + 1;
- fail_if (xmemdup(this->headers[i], data, n, char));
- buf_next(data, char, n);
- this->header_count++;
- }
-
- memcpy(this->payload, data, this->payload_ptr * sizeof(char));
- buf_next(data, char, this->payload_ptr);
-
- memcpy(this->buffer, data, this->buffer_ptr * sizeof(char));
-
- return 0;
-
- fail:
- return -1;
+ this->buffer_size += 1;
+ }
+ this->buffer_size <<= 7;
+
+ /* Allocate header list, payload and read buffer. */
+
+ if (header_count > 0)
+ fail_if (xmalloc(this->headers, header_count, char*));
+
+ if (this->payload_size > 0)
+ fail_if (xmalloc(this->payload, this->payload_size, char));
+
+ fail_if (xmalloc(this->buffer, this->buffer_size, char));
+
+ /* Fill the header list, payload and read buffer. */
+
+ for (i = 0; i < header_count; i++) {
+ n = strlen(data) + 1;
+ fail_if (xmemdup(this->headers[i], data, n, char));
+ buf_next(data, char, n);
+ this->header_count++;
+ }
+
+ memcpy(this->payload, data, this->payload_ptr * sizeof(char));
+ buf_next(data, char, this->payload_ptr);
+
+ memcpy(this->buffer, data, this->buffer_ptr * sizeof(char));
+
+ return 0;
+
+fail:
+ return -1;
}
@@ -562,13 +555,14 @@ 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)
+size_t
+mds_message_compose_size(const mds_message_t *restrict this)
{
- size_t rc = 1 + this->payload_size;
- size_t i;
- for (i = 0; i < this->header_count; i++)
- rc += strlen(this->headers[i]) + 1;
- return rc * sizeof(char);
+ size_t rc = 1 + this->payload_size;
+ size_t i;
+ for (i = 0; i < this->header_count; i++)
+ rc += strlen(this->headers[i]) + 1;
+ return rc * sizeof(char);
}
@@ -578,23 +572,22 @@ size_t mds_message_compose_size(const mds_message_t* restrict this)
* @param this The message
* @param data Output buffer for the marshalled data
*/
-void mds_message_compose(const mds_message_t* restrict this, char* restrict data)
+void
+mds_message_compose(const mds_message_t *restrict this, char *restrict data)
{
- size_t i, n;
-
- for (i = 0; i < this->header_count; i++)
- {
- n = strlen(this->headers[i]);
- memcpy(data, this->headers[i], n * sizeof(char));
- data += n;
- buf_set_next(data, char, '\n');
- }
- buf_set_next(data, char, '\n');
-
- if (this->payload_size > 0)
- memcpy(data, this->payload, this->payload_size * sizeof(char));
+ size_t i, n;
+
+ for (i = 0; i < this->header_count; i++) {
+ n = strlen(this->headers[i]);
+ memcpy(data, this->headers[i], n * sizeof(char));
+ data += n;
+ buf_set_next(data, char, '\n');
+ }
+ buf_set_next(data, char, '\n');
+
+ if (this->payload_size > 0)
+ memcpy(data, this->payload, this->payload_size * sizeof(char));
}
#undef try
-
diff --git a/src/libmdsserver/util.c b/src/libmdsserver/util.c
index cac30ad..09d996a 100644
--- a/src/libmdsserver/util.c
+++ b/src/libmdsserver/util.c
@@ -49,20 +49,21 @@ static char self_exe[PATH_MAX] = {0};
* @param str The client ID string
* @return The client ID integer
*/
-uint64_t parse_client_id(const char* str)
+uint64_t
+parse_client_id(const char *str)
{
- char client_words[22];
- char* client_high;
- char* client_low;
- uint64_t client;
-
- strcpy(client_high = client_words, str);
- client_low = rawmemchr(client_words, ':');
- *client_low++ = '\0';
- client = atou64(client_high) << 32;
- client |= atou64(client_low);
-
- return client;
+ char client_words[22];
+ char *client_high;
+ char *client_low;
+ uint64_t client;
+
+ strcpy(client_high = client_words, str);
+ client_low = rawmemchr(client_words, ':');
+ *client_low++ = '\0';
+ client = atou64(client_high) << 32;
+ client |= atou64(client_low);
+
+ return client;
}
@@ -72,12 +73,11 @@ 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
*/
-char* getenv_nonempty(const char* var)
+char *
+getenv_nonempty(const char *var)
{
- char* rc = getenv(var);
- if ((rc == NULL) || (*rc == '\0'))
- return NULL;
- return rc;
+ char *rc = getenv(var);
+ return (rc && *rc) ? rc : NULL;
}
@@ -97,20 +97,21 @@ char* getenv_nonempty(const char* var)
*
* @return Zero on success, -1 on error
*/
-int prepare_reexec(void)
+int
+prepare_reexec(void)
{
- ssize_t len;
- len = readlink(SELF_EXE, self_exe, (sizeof(self_exe) / sizeof(char)) - 1);
- fail_if (len < 0);
- /* ‘readlink() does not append a null byte to buf.’ */
- self_exe[len] = '\0';
- /* Handle possible race condition: file was removed. */
- if (access(self_exe, F_OK) < 0)
- if (!strcmp(self_exe + (len - 10), " (deleted)"))
- self_exe[len - 10] = '\0';
- return 0;
- fail:
- return -1;
+ ssize_t len;
+ len = readlink(SELF_EXE, self_exe, (sizeof(self_exe) / sizeof(char)) - 1);
+ fail_if (len < 0);
+ /* ‘readlink() does not append a null byte to buf.’ */
+ self_exe[len] = '\0';
+ /* Handle possible race condition: file was removed. */
+ if (access(self_exe, F_OK) < 0)
+ if (!strcmp(self_exe + (len - 10), " (deleted)"))
+ self_exe[len - 10] = '\0';
+ return 0;
+fail:
+ return -1;
}
@@ -125,30 +126,30 @@ int prepare_reexec(void)
* @param argv The command line arguments
* @param reexeced Whether the server has previously been re-exec:ed
*/
-void reexec_server(int argc, char** argv, int reexeced)
+void
+reexec_server(int argc, char **argv, int reexeced)
{
- char** reexec_args;
- char** reexec_args_;
- int i;
-
- /* Re-exec the server. */
- reexec_args = alloca(((size_t)argc + 2) * sizeof(char*));
- reexec_args_ = reexec_args;
- if (reexeced == 0)
- {
- *reexec_args_++ = *argv;
- fail_if (xstrdup(*reexec_args_, "--re-exec"));
- for (i = 1; i < argc; i++)
- reexec_args_[i] = argv[i];
- }
- else /* Don't let the --re-exec:s accumulate. */
- *reexec_args_ = *argv;
- for (i = 1; i < argc; i++)
- reexec_args_[i] = argv[i];
- reexec_args_[argc] = NULL;
- execv(self_exe[0] ? self_exe : argv[0], reexec_args);
- fail:
- return;
+ char **reexec_args;
+ char **reexec_args_;
+ int i;
+
+ /* Re-exec the server. */
+ reexec_args = alloca(((size_t)argc + 2) * sizeof(char*));
+ reexec_args_ = reexec_args;
+ if (!reexeced) {
+ *reexec_args_++ = *argv;
+ fail_if (xstrdup(*reexec_args_, "--re-exec"));
+ for (i = 1; i < argc; i++)
+ reexec_args_[i] = argv[i];
+ } else { /* Don't let the --re-exec:s accumulate. */
+ *reexec_args_ = *argv;
+ }
+ for (i = 1; i < argc; i++)
+ reexec_args_[i] = argv[i];
+ reexec_args_[argc] = NULL;
+ execv(self_exe[0] ? self_exe : argv[0], reexec_args);
+fail:
+ return;
}
@@ -164,17 +165,18 @@ void reexec_server(int argc, char** argv, int reexeced)
* @param function The function to run when the signal is caught
* @return Zero on success, -1 on error
*/
-int xsigaction(int signo, void (*function)(int signo))
+int
+xsigaction(int signo, void (*function)(int signo))
{
- struct sigaction action;
- sigset_t sigset;
-
- sigemptyset(&sigset);
- action.sa_handler = function;
- action.sa_mask = sigset;
- action.sa_flags = 0;
-
- return sigaction(signo, &action, NULL);
+ struct sigaction action;
+ sigset_t sigset;
+
+ sigemptyset(&sigset);
+ action.sa_handler = function;
+ action.sa_mask = sigset;
+ action.sa_flags = 0;
+
+ return sigaction(signo, &action, NULL);
}
@@ -186,34 +188,32 @@ int xsigaction(int signo, void (*function)(int signo))
* @param length The length of the message
* @return The number of bytes that have been sent (even on error)
*/
-size_t send_message(int socket, const char* message, size_t length)
+size_t
+send_message(int socket, const char *message, size_t length)
{
- size_t block_size = length;
- size_t sent = 0;
- ssize_t just_sent;
-
- errno = 0;
- while (length > 0)
- if ((just_sent = send(socket, message + sent, min(block_size, length), MSG_NOSIGNAL)) < 0)
- {
- if (errno == EPIPE)
- errno = ECONNRESET;
- if (errno == EMSGSIZE)
- {
- block_size >>= 1;
- if (block_size == 0)
- return sent;
- }
- else
- return sent;
- }
- else
- {
- sent += (size_t)just_sent;
- length -= (size_t)just_sent;
- }
-
- return sent;
+ size_t block_size = length;
+ size_t sent = 0;
+ ssize_t just_sent;
+
+ errno = 0;
+ while (length > 0) {
+ if ((just_sent = send(socket, message + sent, min(block_size, length), MSG_NOSIGNAL)) < 0) {
+ if (errno == EPIPE)
+ errno = ECONNRESET;
+ if (errno == EMSGSIZE) {
+ block_size >>= 1;
+ if (!block_size)
+ return sent;
+ } else {
+ return sent;
+ }
+ } else {
+ sent += (size_t)just_sent;
+ length -= (size_t)just_sent;
+ }
+ }
+
+ return sent;
}
@@ -226,20 +226,21 @@ 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
*/
-int strict_atoi(const char* str, int* value, int min, int max)
+int
+strict_atoi(const char *str, int *value, int min, int max)
{
- long long int r;
- char* endptr;
-
- r = strtoll(str, &endptr, 10);
- if ((*str == '\0') || isspace(*str) ||
- (endptr - str != (ssize_t)strlen(str)) ||
- (r < (long long int)min) ||
- (r > (long long int)max))
- return -1;
-
- *value = (int)r;
- return 0;
+ long long int r;
+ char *endptr;
+
+ r = strtoll(str, &endptr, 10);
+ if (!*str || isspace(*str) ||
+ endptr - str != (ssize_t)strlen(str) ||
+ r < (long long int)min ||
+ r > (long long int)max)
+ return -1;
+
+ *value = (int)r;
+ return 0;
}
@@ -252,51 +253,50 @@ 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
*/
-int strict_atoj(const char* str, intmax_t* value, intmax_t min, intmax_t max)
+int
+strict_atoj(const char *str, intmax_t *value, intmax_t min, intmax_t max)
{
- static char minstr[3 * sizeof(intmax_t) + 2] = { '\0' };
- intmax_t r = 0;
- char c;
- int neg = 0;
-
- if (*str == '-')
- {
- if (*minstr == '\0')
- sprintf(minstr, "%j", INTMAX_MIN);
- if (!strcmp(str, minstr))
- {
- r = INTMAX_MIN;
- goto done;
+ static char minstr[3 * sizeof(intmax_t) + 2] = { '\0' };
+ intmax_t r = 0;
+ char c;
+ int neg = 0;
+
+ if (*str == '-') {
+ if (!*minstr)
+ sprintf(minstr, "%j", INTMAX_MIN);
+ if (!strcmp(str, minstr)) {
+ r = INTMAX_MIN;
+ goto done;
+ }
+ neg = 1, str++;
}
- neg = 1, str++;
- }
-
- if (*str == '\0')
- return -1;
-
- while ((c = *str))
- if (('0' <= c) && (c <= '9'))
- {
- if (r > INTMAX_MAX / 10)
- return -1;
- else if (r == INTMAX_MAX / 10)
- if ((c & 15) > INTMAX_MAX % 10)
- return -1;
- r = r * 10 + (c & 15);
- }
- else
- return -1;
-
- if (neg)
- r = -r;
-
- done:
-
- if ((r < min) || (r > max))
- return -1;
-
- *value = r;
- return 0;
+
+ if (!*str)
+ return -1;
+
+ while ((c = *str)) {
+ if ('0' <= c && c <= '9') {
+ if (r > INTMAX_MAX / 10) {
+ return -1;
+ } else if (r == INTMAX_MAX / 10) {
+ if ((c & 15) > INTMAX_MAX % 10)
+ return -1;
+ }
+ r = r * 10 + (c & 15);
+ } else {
+ return -1;
+ }
+ }
+
+ if (neg)
+ r = -r;
+
+done:
+ if (r < min || r > max)
+ return -1;
+
+ *value = r;
+ return 0;
}
@@ -316,50 +316,53 @@ 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
*/
-int strict_atouj(const char* str, uintmax_t* value, uintmax_t min, uintmax_t max)
+int
+strict_atouj(const char *str, uintmax_t *value, uintmax_t min, uintmax_t max)
{
- uintmax_t r = 0;
- char c;
-
- if (*str == '\0')
- return -1;
-
- while ((c = *str))
- if (('0' <= c) && (c <= '9'))
- {
- if (r > INTMAX_MAX / 10)
- return -1;
- else if (r == INTMAX_MAX / 10)
- if ((c & 15) > INTMAX_MAX % 10)
- return -1;
- r = r * 10 + (c & 15);
- }
- else
- return -1;
-
- if ((r < min) || (r > max))
- return -1;
-
- *value = r;
- return 0;
+ uintmax_t r = 0;
+ char c;
+
+ if (!*str)
+ return -1;
+
+ while ((c = *str)) {
+ if ('0' <= c && c <= '9') {
+ if (r > INTMAX_MAX / 10) {
+ return -1;
+ } else if (r == INTMAX_MAX / 10) {
+ if ((c & 15) > INTMAX_MAX % 10)
+ return -1;
+ }
+ r = r * 10 + (c & 15);
+ } else {
+ return -1;
+ }
+ }
+
+ if (r < min || r > max)
+ return -1;
+
+ *value = r;
+ return 0;
}
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#endif
-#define __strict_y(Y, TYPE, PARA_TYPE, HYPER_Y, HYPER_TYPE) \
- int strict_##Y(const char* str, TYPE* value, PARA_TYPE min, PARA_TYPE max) \
- { \
- HYPER_TYPE intermediate_value; \
- if (strict_##HYPER_Y(str, &intermediate_value, (HYPER_TYPE)min, (HYPER_TYPE)max) < 0) \
- return -1; \
- return *value = (TYPE)intermediate_value, 0; \
- }
+#define __strict_y(Y, TYPE, PARA_TYPE, HYPER_Y, HYPER_TYPE)\
+ int\
+ strict_##Y(const char *str, TYPE *value, PARA_TYPE min, PARA_TYPE max)\
+ {\
+ HYPER_TYPE intermediate_value;\
+ if (strict_##HYPER_Y(str, &intermediate_value, (HYPER_TYPE)min, (HYPER_TYPE)max) < 0)\
+ return -1;\
+ return *value = (TYPE)intermediate_value, 0;\
+ }
-#define __strict_x(X, TYPE, HYPER_X, HYPER_TYPE) \
- __strict_y(X, TYPE, TYPE, HYPER_X, HYPER_TYPE)
+#define __strict_x(X, TYPE, HYPER_X, HYPER_TYPE)\
+ __strict_y(X, TYPE, TYPE, HYPER_X, HYPER_TYPE)
/**
@@ -577,20 +580,20 @@ __strict_x(atou64, uint64_t, atouj, uintmax_t)
* @param length The length of the buffer
* @return Zero on success, -1 on error
*/
-int full_write(int fd, const char* buffer, size_t length)
+int
+full_write(int fd, const char *buffer, size_t length)
{
- ssize_t wrote;
- while (length > 0)
- {
- errno = 0;
- wrote = write(fd, buffer, length);
- fail_if (errno && (errno != EINTR));
- length -= (size_t)max(wrote, 0);
- buffer += (size_t)max(wrote, 0);
- }
- return 0;
- fail:
- return -1;
+ ssize_t wrote;
+ while (length > 0) {
+ errno = 0;
+ wrote = write(fd, buffer, length);
+ fail_if (errno && errno != EINTR);
+ length -= (size_t)max(wrote, 0);
+ buffer += (size_t)max(wrote, 0);
+ }
+ return 0;
+fail:
+ return -1;
}
@@ -601,44 +604,44 @@ int full_write(int fd, const char* buffer, size_t length)
* @param length Output parameter for the length of the file, may be `NULL`
* @return The content of the file, you will need to free it. `NULL` on error.
*/
-char* full_read(int fd, size_t* length)
+char *
+full_read(int fd, size_t *length)
{
- char* old_buf = NULL;
- size_t buffer_size = 8 << 10;
- size_t buffer_ptr = 0;
- char* buffer;
- ssize_t got;
- int saved_errno;
-
- if (length != NULL)
- *length = 0;
-
- /* Allocate buffer for data. */
- fail_if (xmalloc(buffer, buffer_size, char));
-
- /* Read the file. */
- for (;;)
- {
- /* Grow buffer if it is too small. */
- if (buffer_size == buffer_ptr)
- fail_if (xxrealloc(old_buf, buffer, buffer_size <<= 1, char));
-
- /* Read from the file into the buffer. */
- got = read(fd, buffer + buffer_ptr, buffer_size - buffer_ptr);
- fail_if ((got < 0) && (errno != EINTR));
- if (got == 0)
- break;
- buffer_ptr += (size_t)got;
- }
-
- if (length != NULL)
- *length = buffer_ptr;
- return buffer;
- fail:
- saved_errno = errno;
- free(old_buf);
- free(buffer);
- return errno = saved_errno, NULL;
+ char *old_buf = NULL;
+ size_t buffer_size = 8 << 10;
+ size_t buffer_ptr = 0;
+ char *buffer;
+ ssize_t got;
+ int saved_errno;
+
+ if (length)
+ *length = 0;
+
+ /* Allocate buffer for data. */
+ fail_if (xmalloc(buffer, buffer_size, char));
+
+ /* Read the file. */
+ for (;;) {
+ /* Grow buffer if it is too small. */
+ if (buffer_size == buffer_ptr)
+ fail_if (xxrealloc(old_buf, buffer, buffer_size <<= 1, char));
+
+ /* Read from the file into the buffer. */
+ got = read(fd, buffer + buffer_ptr, buffer_size - buffer_ptr);
+ fail_if (got < 0 && errno != EINTR);
+ if (!got)
+ break;
+ buffer_ptr += (size_t)got;
+ }
+
+ if (length)
+ *length = buffer_ptr;
+ return buffer;
+fail:
+ saved_errno = errno;
+ free(old_buf);
+ free(buffer);
+ return errno = saved_errno, NULL;
}
@@ -650,20 +653,20 @@ char* full_read(int fd, size_t* length)
* @param length The length of the message
* @return Zero on success, -1 on error
*/
-int full_send(int socket, const char* message, size_t length)
+int
+full_send(int socket, const char *message, size_t length)
{
- size_t sent;
+ size_t sent;
- while (length > 0)
- {
- sent = send_message(socket, message, length);
- fail_if ((sent < length) && (errno != EINTR));
- message += sent;
- length -= sent;
- }
- return 0;
- fail:
- return -1;
+ while (length > 0) {
+ sent = send_message(socket, message, length);
+ fail_if (sent < length && errno != EINTR);
+ message += sent;
+ length -= sent;
+ }
+ return 0;
+fail:
+ return -1;
}
@@ -677,17 +680,18 @@ 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)
+int
+startswith_n(const char *haystack, const char *needle, size_t haystack_n, size_t needle_n)
{
- size_t i;
- if (haystack_n < needle_n)
- return 0;
-
- for (i = 0; i < needle_n; i++)
- if (haystack[i] != needle[i])
- return 0;
-
- return 1;
+ size_t i;
+ if (haystack_n < needle_n)
+ return 0;
+
+ for (i = 0; i < needle_n; i++)
+ if (haystack[i] != needle[i])
+ return 0;
+
+ return 1;
}
@@ -700,30 +704,30 @@ int startswith_n(const char* haystack, const char* needle, size_t haystack_n, si
* @param options See description of `options` in the documentation for `waitpid`
* @return See the documentation for `waitpid`
*/
-pid_t uninterruptable_waitpid(pid_t pid, int* restrict status, int options)
+pid_t
+uninterruptable_waitpid(pid_t pid, int *restrict status, int options)
{
- struct timespec time_start;
- struct timespec time_intr;
- int intr_count = 0, have_time;
- pid_t rc;
-
- have_time = (monotone(&time_start) >= 0);
-
- rewait:
- rc = waitpid(pid, status, options);
- if (rc == (pid_t)-1)
- {
- fail_if (errno != EINTR);
- if (have_time && (monotone(&time_intr) >= 0))
- if (time_start.tv_sec != time_intr.tv_sec)
- intr_count = 0;
- if (intr_count++ < 100)
- goto rewait;
- /* Don't let the CPU catch fire! */
- errno = EINTR;
- }
- fail:
- return rc;
+ struct timespec time_start;
+ struct timespec time_intr;
+ int intr_count = 0, have_time;
+ pid_t rc;
+
+ have_time = (monotone(&time_start) >= 0);
+
+rewait:
+ rc = waitpid(pid, status, options);
+ if (rc == (pid_t)-1) {
+ fail_if (errno != EINTR);
+ if (have_time && monotone(&time_intr) >= 0)
+ if (time_start.tv_sec != time_intr.tv_sec)
+ intr_count = 0;
+ if (intr_count++ < 100)
+ goto rewait;
+ /* Don't let the CPU catch fire! */
+ errno = EINTR;
+ }
+fail:
+ return rc;
}
@@ -734,72 +738,71 @@ 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)
+int
+verify_utf8(const char *string, int allow_modified_nul)
{
- static long BYTES_TO_MIN_BITS[] = {0, 0, 8, 12, 17, 22, 37};
- static long BYTES_TO_MAX_BITS[] = {0, 7, 11, 16, 21, 26, 31};
- long bytes = 0, read_bytes = 0, bits = 0, c, character;
-
- /* min bits max bits
- 0....... 0 7
- 110..... 10...... 8 11
- 1110.... 10...... 10...... 12 16
- 11110... 10...... 10...... 10...... 17 21
- 111110.. 10...... 10...... 10...... 10...... 22 26
- 1111110. 10...... 10...... 10...... 10...... 10...... 27 31
- */
-
- while ((c = (long)(*string++)))
- if (read_bytes == 0)
- {
- /* First byte of the character. */
-
- if ((c & 0x80) == 0x00)
- /* Single-byte character. */
- continue;
-
- if ((c & 0xC0) == 0x80)
- /* Single-byte character marked as multibyte, or
- a non-first byte in a multibyte character. */
- return -1;
-
- /* Multibyte character. */
- while ((c & 0x80))
- bytes++, c <<= 1;
- read_bytes = 1;
- character = c & 0x7F;
- if (bytes > 6)
- /* 31-bit characters can be encoded with 6-bytes,
- and UTF-8 does not cover higher code points. */
- return -1;
- }
- else
- {
- /* Not first byte of the character. */
-
- if ((c & 0xC0) != 0x80)
- /* Beginning of new character before a
- multibyte character has ended. */
- return -1;
-
- character = (character << 6) | (c & 0x7F);
-
- if (++read_bytes < bytes)
- /* Not at last byte yet. */
- continue;
-
- /* Check that the character is not unnecessarily long. */
- while (character)
- character >>= 1, bits++;
- bits = ((bits == 0) && (bytes == 2) && allow_modified_nul) ? 8 : bits;
- if ((bits < BYTES_TO_MIN_BITS[bytes]) || (BYTES_TO_MAX_BITS[bytes] < bits))
- return -1;
-
- read_bytes = bytes = bits = 0;
- }
-
- /* Make sure we did not stop at the middle of a multibyte character. */
- return read_bytes == 0 ? 0 : -1;
+ static long BYTES_TO_MIN_BITS[] = {0, 0, 8, 12, 17, 22, 37};
+ static long BYTES_TO_MAX_BITS[] = {0, 7, 11, 16, 21, 26, 31};
+ long bytes = 0, read_bytes = 0, bits = 0, c, character;
+
+ /* min bits max bits
+ 0....... 0 7
+ 110..... 10...... 8 11
+ 1110.... 10...... 10...... 12 16
+ 11110... 10...... 10...... 10...... 17 21
+ 111110.. 10...... 10...... 10...... 10...... 22 26
+ 1111110. 10...... 10...... 10...... 10...... 10...... 27 31
+ */
+
+ while ((c = (long)(*string++))) {
+ if (read_bytes == 0) {
+ /* First byte of the character. */
+
+ if (!(c & 0x80))
+ /* Single-byte character. */
+ continue;
+
+ if ((c & 0xC0) == 0x80)
+ /* Single-byte character marked as multibyte, or
+ a non-first byte in a multibyte character. */
+ return -1;
+
+ /* Multibyte character. */
+ while ((c & 0x80))
+ bytes++, c <<= 1;
+ read_bytes = 1;
+ character = c & 0x7F;
+ if (bytes > 6)
+ /* 31-bit characters can be encoded with 6-bytes,
+ and UTF-8 does not cover higher code points. */
+ return -1;
+ } else {
+ /* Not first byte of the character. */
+
+ if ((c & 0xC0) != 0x80)
+ /* Beginning of new character before a
+ multibyte character has ended. */
+ return -1;
+
+ character = (character << 6) | (c & 0x7F);
+
+ if (++read_bytes < bytes)
+ /* Not at last byte yet. */
+ continue;
+
+ /* Check that the character is not unnecessarily long. */
+ while (character)
+ character >>= 1, bits++;
+ bits = ((bits == 0) && (bytes == 2) && allow_modified_nul) ? 8 : bits;
+ if ((bits < BYTES_TO_MIN_BITS[bytes]) || (BYTES_TO_MAX_BITS[bytes] < bits))
+ return -1;
+
+ read_bytes = bytes = bits = 0;
+ }
+ }
+
+ /* Make sure we did not stop at the middle of a multibyte character. */
+ return read_bytes == 0 ? 0 : -1;
}
@@ -828,85 +831,85 @@ int verify_utf8(const char* string, int allow_modified_nul)
* @param message_id The message ID of this message
* @return The length of the message, zero on error
*/
-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)
+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)
{
- ssize_t part_length;
- size_t length;
- char* temp;
-
- /* Measure the maximum length of message, including NUL-termination.. */
- length = sizeof("Command: error\n"
- "To: 4294967296:4294967296\n"
- "In response to: 4294967296\n"
- "Origin command: \n"
- "Message ID: 4294967296\n"
- "Error: custom \n"
- "Length: \n"
- "\n") / sizeof(char) + 3 * (sizeof(int)) + strlen(recv_command);
- if (message != NULL)
- length += (sizeof("Length: \n") / sizeof(char) - 1) + 3 * sizeof(char) + strlen(message) + 1;
-
- /* Ensure that the send buffer is large enough. */
- if (length > *send_buffer_size)
- {
- fail_if (yrealloc(temp, *send_buffer, length, char));
- *send_buffer_size = length;
- }
-
- /* Reset `length` to indicate that the currently written
- message has zero in length. */
- length = 0;
-
- /* Start writting the error message, begin with required
- headers, but exclude the error number. */
- sprintf((*send_buffer) + length,
- "Command: error\n"
- "To: %s\n"
- "In response to: %s\n"
- "Origin command: %s\n"
- "Message ID: %"PRIu32"\n"
- "Error: %s%zn",
- recv_client_id, recv_message_id, recv_command,
- message_id, custom ? "custom" : "",
- &part_length),
- length += (size_t)part_length;
-
- /* If the error is custom and has a number we need
- blank space before we write the error number. */
- if (custom && (errnum >= 0))
- (*send_buffer)[length++] = ' ';
-
- /* Add the error number of there is one. */
- if (errnum >= 0)
- sprintf((*send_buffer) + length, "%i%zn", errnum, &part_length),
- length += (size_t)part_length;
-
- /* End the `Error`-header line. */
- (*send_buffer)[length++] = '\n';
-
- /* Add the `Length`-header if there is a description. */
- if (message != NULL)
- sprintf((*send_buffer) + length, "Length: %zu\n%zn",
- strlen(message) + 1, &part_length),
- length += (size_t)part_length + strlen(message) + 1;
-
- /* Add an empty line to mark the end of headers. */
- (*send_buffer)[length++] = '\n';
-
- /* Write the description if there is one. */
- if (message)
- {
- memcpy((*send_buffer) + length, message, strlen(message) * sizeof(char));
- length += strlen(message);
- (*send_buffer)[length++] = '\n';
- }
-
- return length;
- fail:
- return 0;
+ ssize_t part_length;
+ size_t length;
+ char *temp;
+
+ /* Measure the maximum length of message, including NUL-termination.. */
+ length = sizeof("Command: error\n"
+ "To: 4294967296:4294967296\n"
+ "In response to: 4294967296\n"
+ "Origin command: \n"
+ "Message ID: 4294967296\n"
+ "Error: custom \n"
+ "Length: \n"
+ "\n") / sizeof(char) + 3 * (sizeof(int)) + strlen(recv_command);
+ if (message)
+ length += (sizeof("Length: \n") / sizeof(char) - 1) + 3 * sizeof(char) + strlen(message) + 1;
+
+ /* Ensure that the send buffer is large enough. */
+ if (length > *send_buffer_size) {
+ fail_if (yrealloc(temp, *send_buffer, length, char));
+ *send_buffer_size = length;
+ }
+
+ /* Reset `length` to indicate that the currently written
+ message has zero in length. */
+ length = 0;
+
+ /* Start writting the error message, begin with required
+ headers, but exclude the error number. */
+ sprintf((*send_buffer) + length,
+ "Command: error\n"
+ "To: %s\n"
+ "In response to: %s\n"
+ "Origin command: %s\n"
+ "Message ID: %"PRIu32"\n"
+ "Error: %s%zn",
+ recv_client_id, recv_message_id, recv_command,
+ message_id, custom ? "custom" : "",
+ &part_length);
+ length += (size_t)part_length;
+
+ /* If the error is custom and has a number we need
+ blank space before we write the error number. */
+ if (custom && errnum >= 0)
+ (*send_buffer)[length++] = ' ';
+
+ /* Add the error number of there is one. */
+ if (errnum >= 0)
+ sprintf((*send_buffer) + length, "%i%zn", errnum, &part_length),
+ length += (size_t)part_length;
+
+ /* End the `Error`-header line. */
+ (*send_buffer)[length++] = '\n';
+
+ /* Add the `Length`-header if there is a description. */
+ if (message) {
+ sprintf((*send_buffer) + length, "Length: %zu\n%zn",
+ strlen(message) + 1, &part_length);
+ length += (size_t)part_length + strlen(message) + 1;
+ }
+
+ /* Add an empty line to mark the end of headers. */
+ (*send_buffer)[length++] = '\n';
+
+ /* Write the description if there is one. */
+ if (message) {
+ memcpy((*send_buffer) + length, message, strlen(message) * sizeof(char));
+ length += strlen(message);
+ (*send_buffer)[length++] = '\n';
+ }
+
+ return length;
+fail:
+ return 0;
}
@@ -936,17 +939,17 @@ size_t construct_error_message(const char* restrict recv_client_id, const char*
* @param message_id The message ID of this message
* @return Zero on success, -1 on error
*/
-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)
+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)
{
- size_t length;
- fail_if ((length = construct_error_message(recv_client_id, recv_message_id, recv_command, custom, errnum,
- message, send_buffer, send_buffer_size, message_id)) == 0);
- fail_if (full_send(socket_fd, *send_buffer, length));
- return 0;
- fail:
- return -1;
+ size_t length;
+ fail_if (!(length = construct_error_message(recv_client_id, recv_message_id, recv_command, custom, errnum,
+ message, send_buffer, send_buffer_size, message_id)));
+ fail_if (full_send(socket_fd, *send_buffer, length));
+ return 0;
+fail:
+ return -1;
}
-
diff --git a/src/mds-base.h b/src/mds-base.h
index 9950117..c3bc735 100644
--- a/src/mds-base.h
+++ b/src/mds-base.h
@@ -23,15 +23,14 @@
#include <signal.h>
-#define MDS_BASE_VARS_VERSION 0
+#define MDS_BASE_VARS_VERSION 0
/**
* Characteristics of the server
*/
-typedef struct server_characteristics
-{
+typedef struct server_characteristics {
/**
* Setting this to zero will cause the server to drop privileges as a security precaution
*/
@@ -78,7 +77,6 @@ typedef struct server_characteristics
* --immortal is used.
*/
unsigned danger_is_deadly : 1;
-
} __attribute__((packed)) server_characteristics_t;
diff --git a/src/mds-clipboard.h b/src/mds-clipboard.h
index 26c15a4..f3672ff 100644
--- a/src/mds-clipboard.h
+++ b/src/mds-clipboard.h
@@ -30,30 +30,29 @@
/**
* Delete entry only when needed
*/
-#define CLIPITEM_AUTOPURGE_NEVER 0
+#define CLIPITEM_AUTOPURGE_NEVER 0
/**
* Delete entry when the client closes, or needed
*/
-#define CLIPITEM_AUTOPURGE_UPON_DEATH 1
+#define CLIPITEM_AUTOPURGE_UPON_DEATH 1
/**
* Delete entry when a point in time has elapsed, or needed
*/
-#define CLIPITEM_AUTOPURGE_UPON_CLOCK 2
+#define CLIPITEM_AUTOPURGE_UPON_CLOCK 2
/**
* Delete entry when the client closes or when a
* point in time has elapsed, or when needed
*/
-#define CLIPITEM_AUTOPURGE_UPON_DEATH_OR_CLOCK 3
+#define CLIPITEM_AUTOPURGE_UPON_DEATH_OR_CLOCK 3
/**
* A clipboard entry
*/
-typedef struct clipitem
-{
+typedef struct clipitem {
/**
* The stored content
*/
@@ -78,7 +77,6 @@ typedef struct clipitem
* Rule for automatic deletion
*/
int autopurge;
-
} clipitem_t;
diff --git a/src/mds-colour.h b/src/mds-colour.h
index 3ab718e..1332198 100644
--- a/src/mds-colour.h
+++ b/src/mds-colour.h
@@ -30,8 +30,7 @@
/**
* Data structure for colour
*/
-typedef struct colour
-{
+typedef struct colour {
/**
* The value of the red channel
*/
@@ -52,7 +51,6 @@ typedef struct colour
* each channel is encoded
*/
int bytes;
-
} colour_t;
@@ -139,4 +137,3 @@ void colour_list_entry_free(colour_list_entry_t *entry);
#endif
-
diff --git a/src/mds-echo.c b/src/mds-echo.c
index 2bb505f..72f43f8 100644
--- a/src/mds-echo.c
+++ b/src/mds-echo.c
@@ -30,7 +30,7 @@
-#define MDS_ECHO_VARS_VERSION 0
+#define MDS_ECHO_VARS_VERSION 0
@@ -363,4 +363,3 @@ received_info(int signo)
iprintf("echo buffer size: %zu bytes", echo_buffer_size);
SIGHANDLER_END;
}
-
diff --git a/src/mds-echo.h b/src/mds-echo.h
index 72aedca..5a6e87b 100644
--- a/src/mds-echo.h
+++ b/src/mds-echo.h
@@ -32,4 +32,3 @@ int echo_message(void);
#endif
-
diff --git a/src/mds-kbdc/builtin-functions.c b/src/mds-kbdc/builtin-functions.c
index e0594ab..72593cd 100644
--- a/src/mds-kbdc/builtin-functions.c
+++ b/src/mds-kbdc/builtin-functions.c
@@ -29,35 +29,35 @@
/**
* Define useful data for built-in function with 2 parameters
*/
-#define define_2 \
- const char32_t* restrict a = *args++; \
- const char32_t* restrict b = *args++; \
- size_t an = string_length(a); \
- size_t bn = string_length(b); \
- size_t i, n = an > bn ? an : bn; \
- char32_t* restrict rc; \
- fail_if (xmalloc(rc, n + 1, char32_t)); \
- rc[n] = -1
+#define define_2\
+ const char32_t *restrict a = *args++;\
+ const char32_t *restrict b = *args++;\
+ size_t an = string_length(a);\
+ size_t bn = string_length(b);\
+ size_t i, n = an > bn ? an : bn;\
+ char32_t *restrict rc;\
+ fail_if (xmalloc(rc, n + 1, char32_t));\
+ rc[n] = -1
/**
* Define useful data for built-in function with 1 parameter
*/
-#define define_1 \
- const char32_t* restrict a = *args++; \
- size_t i, n = string_length(a); \
- char32_t* restrict rc; \
- fail_if (xmalloc(rc, n + 1, char32_t)); \
- rc[n] = -1
+#define define_1\
+ const char32_t* restrict a = *args++;\
+ size_t i, n = string_length(a);\
+ char32_t *restrict rc;\
+ fail_if (xmalloc(rc, n + 1, char32_t));\
+ rc[n] = -1
/**
* Return a value, or if there was a failure somewhere, return `NULL`
*
* @param v:void* The value to return on success
*/
-#define return(v) \
- return v; \
- fail: \
- return NULL;
+#define return(v)\
+ return v;\
+fail:\
+ return NULL;
/**
@@ -66,12 +66,13 @@
* @param args The arguments passed to the function
* @return The return value of the function, `NULL` on error
*/
-static char32_t* builtin_function_add_2(const char32_t** restrict args)
+static char32_t *
+builtin_function_add_2(const char32_t **restrict args)
{
- define_2;
- for (i = 0; i < n; i++)
- rc[i] = a[i % an] + b[i % bn];
- return(rc);
+ define_2;
+ for (i = 0; i < n; i++)
+ rc[i] = a[i % an] + b[i % bn];
+ return(rc);
}
@@ -81,12 +82,13 @@ static char32_t* builtin_function_add_2(const char32_t** restrict args)
* @param args The arguments passed to the function
* @return The return value of the function, `NULL` on error
*/
-static char32_t* builtin_function_sub_2(const char32_t** restrict args)
+static char32_t *
+builtin_function_sub_2(const char32_t **restrict args)
{
- define_2;
- for (i = 0; i < n; i++)
- rc[i] = a[i % an] - b[i % bn];
- return(rc);
+ define_2;
+ for (i = 0; i < n; i++)
+ rc[i] = a[i % an] - b[i % bn];
+ return(rc);
}
@@ -96,12 +98,13 @@ static char32_t* builtin_function_sub_2(const char32_t** restrict args)
* @param args The arguments passed to the function
* @return The return value of the function, `NULL` on error
*/
-static char32_t* builtin_function_mul_2(const char32_t** restrict args)
+static char32_t *
+builtin_function_mul_2(const char32_t **restrict args)
{
- define_2;
- for (i = 0; i < n; i++)
- rc[i] = a[i % an] * b[i % bn];
- return(rc);
+ define_2;
+ for (i = 0; i < n; i++)
+ rc[i] = a[i % an] * b[i % bn];
+ return(rc);
}
@@ -111,12 +114,13 @@ static char32_t* builtin_function_mul_2(const char32_t** restrict args)
* @param args The arguments passed to the function
* @return The return value of the function, `NULL` on error
*/
-static char32_t* builtin_function_div_2(const char32_t** restrict args)
+static char32_t *
+builtin_function_div_2(const char32_t **restrict args)
{
- define_2;
- for (i = 0; i < n; i++)
- rc[i] = a[i % an] / b[i % bn];
- return(rc);
+ define_2;
+ for (i = 0; i < n; i++)
+ rc[i] = a[i % an] / b[i % bn];
+ return(rc);
}
@@ -126,12 +130,13 @@ static char32_t* builtin_function_div_2(const char32_t** restrict args)
* @param args The arguments passed to the function
* @return The return value of the function, `NULL` on error
*/
-static char32_t* builtin_function_mod_2(const char32_t** restrict args)
+static char32_t *
+builtin_function_mod_2(const char32_t **restrict args)
{
- define_2;
- for (i = 0; i < n; i++)
- rc[i] = a[i % an] % b[i % bn];
- return(rc);
+ define_2;
+ for (i = 0; i < n; i++)
+ rc[i] = a[i % an] % b[i % bn];
+ return(rc);
}
@@ -141,12 +146,13 @@ static char32_t* builtin_function_mod_2(const char32_t** restrict args)
* @param args The arguments passed to the function
* @return The return value of the function, `NULL` on error
*/
-static char32_t* builtin_function_rsh_2(const char32_t** restrict args)
+static char32_t *
+builtin_function_rsh_2(const char32_t **restrict args)
{
- define_2;
- for (i = 0; i < n; i++)
- rc[i] = a[i % an] >> b[i % bn];
- return(rc);
+ define_2;
+ for (i = 0; i < n; i++)
+ rc[i] = a[i % an] >> b[i % bn];
+ return(rc);
}
@@ -156,12 +162,13 @@ static char32_t* builtin_function_rsh_2(const char32_t** restrict args)
* @param args The arguments passed to the function
* @return The return value of the function, `NULL` on error
*/
-static char32_t* builtin_function_lsh_2(const char32_t** restrict args)
+static char32_t *
+builtin_function_lsh_2(const char32_t **restrict args)
{
- define_2;
- for (i = 0; i < n; i++)
- rc[i] = a[i % an] << b[i % bn];
- return(rc);
+ define_2;
+ for (i = 0; i < n; i++)
+ rc[i] = a[i % an] << b[i % bn];
+ return(rc);
}
@@ -171,12 +178,13 @@ static char32_t* builtin_function_lsh_2(const char32_t** restrict args)
* @param args The arguments passed to the function
* @return The return value of the function, `NULL` on error
*/
-static char32_t* builtin_function_or_2(const char32_t** restrict args)
+static char32_t *
+builtin_function_or_2(const char32_t **restrict args)
{
- define_2;
- for (i = 0; i < n; i++)
- rc[i] = a[i % an] | b[i % bn];
- return(rc);
+ define_2;
+ for (i = 0; i < n; i++)
+ rc[i] = a[i % an] | b[i % bn];
+ return(rc);
}
@@ -186,12 +194,13 @@ static char32_t* builtin_function_or_2(const char32_t** restrict args)
* @param args The arguments passed to the function
* @return The return value of the function, `NULL` on error
*/
-static char32_t* builtin_function_and_2(const char32_t** restrict args)
+static char32_t *
+builtin_function_and_2(const char32_t **restrict args)
{
- define_2;
- for (i = 0; i < n; i++)
- rc[i] = a[i % an] & b[i % bn];
- return(rc);
+ define_2;
+ for (i = 0; i < n; i++)
+ rc[i] = a[i % an] & b[i % bn];
+ return(rc);
}
@@ -201,12 +210,13 @@ static char32_t* builtin_function_and_2(const char32_t** restrict args)
* @param args The arguments passed to the function
* @return The return value of the function, `NULL` on error
*/
-static char32_t* builtin_function_xor_2(const char32_t** restrict args)
+static char32_t *
+builtin_function_xor_2(const char32_t **restrict args)
{
- define_2;
- for (i = 0; i < n; i++)
- rc[i] = a[i % an] ^ b[i % bn];
- return(rc);
+ define_2;
+ for (i = 0; i < n; i++)
+ rc[i] = a[i % an] ^ b[i % bn];
+ return(rc);
}
@@ -216,12 +226,13 @@ static char32_t* builtin_function_xor_2(const char32_t** restrict args)
* @param args The arguments passed to the function
* @return The return value of the function, `NULL` on error
*/
-static char32_t* builtin_function_not_1(const char32_t** restrict args)
+static char32_t *
+builtin_function_not_1(const char32_t **restrict args)
{
- define_1;
- for (i = 0; i < n; i++)
- rc[i] = !a[i];
- return(rc);
+ define_1;
+ for (i = 0; i < n; i++)
+ rc[i] = !a[i];
+ return(rc);
}
@@ -231,12 +242,13 @@ static char32_t* builtin_function_not_1(const char32_t** restrict args)
* @param args The arguments passed to the function
* @return The return value of the function, `NULL` on error
*/
-static char32_t* builtin_function_equals_2(const char32_t** restrict args)
+static char32_t *
+builtin_function_equals_2(const char32_t **restrict args)
{
- define_2;
- for (i = 0; i < n; i++)
- rc[i] = a[i % an] == b[i % bn];
- return(rc);
+ define_2;
+ for (i = 0; i < n; i++)
+ rc[i] = a[i % an] == b[i % bn];
+ return(rc);
}
@@ -246,12 +258,13 @@ static char32_t* builtin_function_equals_2(const char32_t** restrict args)
* @param args The arguments passed to the function
* @return The return value of the function, `NULL` on error
*/
-static char32_t* builtin_function_greater_2(const char32_t** restrict args)
+static char32_t *
+builtin_function_greater_2(const char32_t **restrict args)
{
- define_2;
- for (i = 0; i < n; i++)
- rc[i] = a[i % an] > b[i % bn];
- return(rc);
+ define_2;
+ for (i = 0; i < n; i++)
+ rc[i] = a[i % an] > b[i % bn];
+ return(rc);
}
@@ -261,12 +274,13 @@ static char32_t* builtin_function_greater_2(const char32_t** restrict args)
* @param args The arguments passed to the function
* @return The return value of the function, `NULL` on error
*/
-static char32_t* builtin_function_less_2(const char32_t** restrict args)
+static char32_t *
+builtin_function_less_2(const char32_t **restrict args)
{
- define_2;
- for (i = 0; i < n; i++)
- rc[i] = a[i % an] < b[i % bn];
- return(rc);
+ define_2;
+ for (i = 0; i < n; i++)
+ rc[i] = a[i % an] < b[i % bn];
+ return(rc);
}
@@ -276,17 +290,18 @@ static char32_t* builtin_function_less_2(const char32_t** restrict args)
* @param args The arguments passed to the function
* @return The return value of the function, `NULL` on error
*/
-static char32_t* builtin_function_get_2(const char32_t** restrict args)
+static char32_t *
+builtin_function_get_2(const char32_t **restrict args)
{
- const char32_t* restrict a = *args++;
- const char32_t* restrict b = *args++;
- char32_t* restrict rc;
- size_t n = (size_t)*b;
- mds_kbdc_tree_t* value = variables_get((size_t)*a)->array.elements;
- while (n--)
- value = value->next;
- fail_if (rc = string_dup(value->compiled_string.string), rc == NULL);
- return(rc);
+ const char32_t *restrict a = *args++;
+ const char32_t *restrict b = *args++;
+ char32_t *restrict rc;
+ size_t n = (size_t)*b;
+ mds_kbdc_tree_t *value = variables_get((size_t)*a)->array.elements;
+ while (n--)
+ value = value->next;
+ fail_if (rc = string_dup(value->compiled_string.string), rc == NULL);
+ return(rc);
}
@@ -296,21 +311,22 @@ static char32_t* builtin_function_get_2(const char32_t** restrict args)
* @param args The arguments passed to the function
* @return The return value of the function, `NULL` on error
*/
-static char32_t* builtin_function_set_3(const char32_t** restrict args)
+static char32_t *
+builtin_function_set_3(const char32_t **restrict args)
{
- const char32_t* restrict a = *args++;
- const char32_t* restrict b = *args++;
- const char32_t* restrict c = *args++;
- char32_t* restrict rc;
- size_t n = (size_t)*b;
- mds_kbdc_tree_t* value = variables_get((size_t)*a)->array.elements;
- while (n--)
- value = value->next;
- free(value->compiled_string.string);
- value->compiled_string.string = string_dup(c);
- fail_if (value->compiled_string.string == NULL);
- fail_if (rc = string_dup(c), rc == NULL);
- return(rc);
+ const char32_t *restrict a = *args++;
+ const char32_t *restrict b = *args++;
+ const char32_t *restrict c = *args++;
+ char32_t *restrict rc;
+ size_t n = (size_t)*b;
+ mds_kbdc_tree_t *value = variables_get((size_t)*a)->array.elements;
+ while (n--)
+ value = value->next;
+ free(value->compiled_string.string);
+ value->compiled_string.string = string_dup(c);
+ fail_if (!value->compiled_string.string);
+ fail_if (!(rc = string_dup(c)));
+ return(rc);
}
@@ -326,25 +342,26 @@ static char32_t* builtin_function_set_3(const char32_t** restrict args)
* @param arg_count The number of arguments to pass to the function
* @return Whether the described function is a builtin function
*/
-int builtin_function_defined(const char* restrict name, size_t arg_count)
+int
+builtin_function_defined(const char *restrict name, size_t arg_count)
{
- size_t i;
- static const char* const BUILTIN_FUNCTIONS_2[] =
- {
- "add", "sub", "mul", "div", "mod", "rsh", "lsh", "or",
- "and", "xor", "equals", "greater", "less", "get", NULL
- };
-
- if (arg_count == 3)
- return !strcmp(name, "set");
- else if (arg_count == 1)
- return !strcmp(name, "not");
- else if (arg_count == 2)
- for (i = 0; BUILTIN_FUNCTIONS_2[i]; i++)
- if (!strcmp(name, BUILTIN_FUNCTIONS_2[i]))
- return 1;
-
- return 0;
+ size_t i;
+ static const char* const BUILTIN_FUNCTIONS_2[] = {
+ "add", "sub", "mul", "div", "mod", "rsh", "lsh", "or",
+ "and", "xor", "equals", "greater", "less", "get", NULL
+ };
+
+ if (arg_count == 1) {
+ return !strcmp(name, "not");
+ } else if (arg_count == 2) {
+ for (i = 0; BUILTIN_FUNCTIONS_2[i]; i++)
+ if (!strcmp(name, BUILTIN_FUNCTIONS_2[i]))
+ return 1;
+ } else if (arg_count == 3) {
+ return !strcmp(name, "set");
+ }
+
+ return 0;
}
@@ -362,35 +379,35 @@ int builtin_function_defined(const char* restrict name, size_t arg_count)
* @param args The arguments to pass
* @return The return value of the function, `NULL` on error
*/
-char32_t* builtin_function_invoke(const char* restrict name, size_t arg_count, const char32_t** restrict args)
+char32_t *
+builtin_function_invoke(const char *restrict name, size_t arg_count, const char32_t **restrict args)
{
-#define t(f) do { fail_if (rc = builtin_function_##f(args), rc == NULL); return rc; } while (0)
- char32_t* rc;
-
- if ((arg_count == 3) && !strcmp(name, "set")) t (set_3);
- if ((arg_count == 1) && !strcmp(name, "not")) t (not_1);
-
- if (arg_count != 2)
- abort();
-
- if (!strcmp(name, "add")) t (add_2);
- if (!strcmp(name, "sub")) t (sub_2);
- if (!strcmp(name, "mul")) t (mul_2);
- if (!strcmp(name, "div")) t (div_2);
- if (!strcmp(name, "mod")) t (mod_2);
- if (!strcmp(name, "rsh")) t (rsh_2);
- if (!strcmp(name, "lsh")) t (lsh_2);
- if (!strcmp(name, "or")) t (or_2);
- if (!strcmp(name, "and")) t (and_2);
- if (!strcmp(name, "xor")) t (xor_2);
- if (!strcmp(name, "equals")) t (equals_2);
- if (!strcmp(name, "greater")) t (greater_2);
- if (!strcmp(name, "less")) t (less_2);
- if (!strcmp(name, "get")) t (get_2);
-
- abort();
- fail:
- return NULL;
+#define t(f) do { fail_if (rc = builtin_function_##f(args), rc == NULL); return rc; } while (0)
+ char32_t *rc;
+
+ if (arg_count == 3 && !strcmp(name, "set")) t (set_3);
+ if (arg_count == 1 && !strcmp(name, "not")) t (not_1);
+
+ if (arg_count != 2)
+ abort();
+
+ if (!strcmp(name, "add")) t (add_2);
+ if (!strcmp(name, "sub")) t (sub_2);
+ if (!strcmp(name, "mul")) t (mul_2);
+ if (!strcmp(name, "div")) t (div_2);
+ if (!strcmp(name, "mod")) t (mod_2);
+ if (!strcmp(name, "rsh")) t (rsh_2);
+ if (!strcmp(name, "lsh")) t (lsh_2);
+ if (!strcmp(name, "or")) t (or_2);
+ if (!strcmp(name, "and")) t (and_2);
+ if (!strcmp(name, "xor")) t (xor_2);
+ if (!strcmp(name, "equals")) t (equals_2);
+ if (!strcmp(name, "greater")) t (greater_2);
+ if (!strcmp(name, "less")) t (less_2);
+ if (!strcmp(name, "get")) t (get_2);
+
+ abort();
+fail:
+ return NULL;
#undef t
}
-
diff --git a/src/mds-kbdc/builtin-functions.h b/src/mds-kbdc/builtin-functions.h
index fe94205..8d2cc2d 100644
--- a/src/mds-kbdc/builtin-functions.h
+++ b/src/mds-kbdc/builtin-functions.h
@@ -33,7 +33,8 @@
* @param arg_count The number of arguments to pass to the function
* @return Whether the described function is a builtin function
*/
-int builtin_function_defined(const char* restrict name, size_t arg_count) __attribute__((pure));
+__attribute__((pure))
+int builtin_function_defined(const char *restrict name, size_t arg_count);
/**
* Invoke a builtin function
@@ -49,9 +50,8 @@ int builtin_function_defined(const char* restrict name, size_t arg_count) __attr
* @param args The arguments to pass
* @return The return value of the function, `NULL` on error
*/
-char32_t* builtin_function_invoke(const char* restrict name, size_t arg_count, const char32_t** restrict args);
+char32_t *builtin_function_invoke(const char *restrict name, size_t arg_count, const char32_t **restrict args);
#endif
-
diff --git a/src/mds-kbdc/call-stack.c b/src/mds-kbdc/call-stack.c
index 92c83a7..c864e7c 100644
--- a/src/mds-kbdc/call-stack.c
+++ b/src/mds-kbdc/call-stack.c
@@ -24,31 +24,29 @@
/**
* An entry in the call-stack
*/
-typedef struct mds_kbdc_call
-{
- /**
- * The tree node where the call was made
- */
- const mds_kbdc_tree_t* tree;
-
- /**
- * The position of the line of the tree node
- * where the call begins
- */
- size_t start;
-
- /**
- * The position of the line of the tree node
- * where the call end
- */
- size_t end;
-
- /**
- * A snapshot of the include-stack as it
- * looked when the call was being made
- */
- mds_kbdc_include_stack_t* include_stack;
-
+typedef struct mds_kbdc_call {
+ /**
+ * The tree node where the call was made
+ */
+ const mds_kbdc_tree_t *tree;
+
+ /**
+ * The position of the line of the tree node
+ * where the call begins
+ */
+ size_t start;
+
+ /**
+ * The position of the line of the tree node
+ * where the call end
+ */
+ size_t end;
+
+ /**
+ * A snapshot of the include-stack as it
+ * looked when the call was being made
+ */
+ mds_kbdc_include_stack_t *include_stack;
} mds_kbdc_call_t;
@@ -56,27 +54,27 @@ typedef struct mds_kbdc_call
/**
* Variable whether the latest created error is stored
*/
-static mds_kbdc_parse_error_t* error;
+static mds_kbdc_parse_error_t *error;
/**
* The `result` parameter of root procedure that requires the include-stack
*/
-static mds_kbdc_parsed_t* result;
+static mds_kbdc_parsed_t *result;
/**
* The original value of `result->pathname`
*/
-static char* original_pathname;
+static char *original_pathname;
/**
* The original value of `result->source_code`
*/
-static mds_kbdc_source_code_t* original_source_code;
+static mds_kbdc_source_code_t *original_source_code;
/**
* Stack of visited function- and macro-calls
*/
-static mds_kbdc_call_t* restrict calls = NULL;
+static mds_kbdc_call_t *restrict calls = NULL;
/**
* The number elements allocated for `calls`
@@ -95,57 +93,59 @@ static size_t calls_ptr = 0;
*
* @return Zero on success, -1 on error
*/
-int mds_kbdc_call_stack_dump(void)
+int
+mds_kbdc_call_stack_dump(void)
{
- char* old_pathname = result->pathname;
- mds_kbdc_source_code_t* old_source_code = result->source_code;
- size_t ptr = calls_ptr, iptr;
- mds_kbdc_call_t* restrict call;
- mds_kbdc_include_stack_t* restrict includes;
-
- while (ptr--)
- {
- call = calls + ptr;
- includes = call->include_stack;
- iptr = includes->ptr;
- result->pathname = iptr ? includes->stack[iptr - 1]->filename : original_pathname;
- result->source_code = iptr ? includes->stack[iptr - 1]->source_code : original_source_code;
- NEW_ERROR_(result, NOTE, 1, call->tree->loc_line, call->start, call->end, 1, "called from here");
- DUMP_INCLUDE_STACK(iptr);
- }
-
- result->pathname = old_pathname;
- result->source_code = old_source_code;
- return 0;
- fail:
- result->pathname = old_pathname;
- result->source_code = old_source_code;
- return -1;
+ char *old_pathname = result->pathname;
+ mds_kbdc_source_code_t *old_source_code = result->source_code;
+ size_t ptr = calls_ptr, iptr;
+ mds_kbdc_call_t *restrict call;
+ mds_kbdc_include_stack_t *restrict includes;
+
+ while (ptr--) {
+ call = calls + ptr;
+ includes = call->include_stack;
+ iptr = includes->ptr;
+ result->pathname = iptr ? includes->stack[iptr - 1]->filename : original_pathname;
+ result->source_code = iptr ? includes->stack[iptr - 1]->source_code : original_source_code;
+ NEW_ERROR_(result, NOTE, 1, call->tree->loc_line, call->start, call->end, 1, "called from here");
+ DUMP_INCLUDE_STACK(iptr);
+ }
+
+ result->pathname = old_pathname;
+ result->source_code = old_source_code;
+ return 0;
+fail:
+ result->pathname = old_pathname;
+ result->source_code = old_source_code;
+ return -1;
}
/**
* Prepare for usage of call-stacks
*
-xo * @param result_ The `result` parameter of root procedure that requires the call-stack
+ * @param result_ The `result` parameter of root procedure that requires the call-stack
*/
-void mds_kbdc_call_stack_begin(mds_kbdc_parsed_t* restrict result_)
+void
+mds_kbdc_call_stack_begin(mds_kbdc_parsed_t *restrict result_)
{
- result = result_;
- original_pathname = result_->pathname;
- original_source_code = result_->source_code;
+ result = result_;
+ original_pathname = result_->pathname;
+ original_source_code = result_->source_code;
}
/**
* Cleanup after usage of call-stacks
*/
-void mds_kbdc_call_stack_end(void)
+void
+mds_kbdc_call_stack_end(void)
{
- result->pathname = original_pathname;
- result->source_code = original_source_code;
- free(calls), calls = NULL;
- calls_size = calls_ptr = 0;
+ result->pathname = original_pathname;
+ result->source_code = original_source_code;
+ free(calls), calls = NULL;
+ calls_size = calls_ptr = 0;
}
@@ -157,27 +157,27 @@ void mds_kbdc_call_stack_end(void)
* @param end The position of the line of the tree node where the call end
* @return Zero on success, -1 on error
*/
-int mds_kbdc_call_stack_push(const mds_kbdc_tree_t* restrict tree, size_t start, size_t end)
+int
+mds_kbdc_call_stack_push(const mds_kbdc_tree_t *restrict tree, size_t start, size_t end)
{
- mds_kbdc_call_t* tmp;
- mds_kbdc_call_t* call;
-
- if (calls_ptr == calls_size)
- {
- fail_if (yrealloc(tmp, calls, calls_size + 4, mds_kbdc_call_t));
- calls_size += 4;
- }
-
- call = calls + calls_ptr++;
- call->tree = tree;
- call->start = start;
- call->end = end;
- call->include_stack = mds_kbdc_include_stack_save();
- fail_if (call->include_stack == NULL);
-
- return 0;
- fail:
- return -1;
+ mds_kbdc_call_t *tmp;
+ mds_kbdc_call_t *call;
+
+ if (calls_ptr == calls_size) {
+ fail_if (yrealloc(tmp, calls, calls_size + 4, mds_kbdc_call_t));
+ calls_size += 4;
+ }
+
+ call = calls + calls_ptr++;
+ call->tree = tree;
+ call->start = start;
+ call->end = end;
+ call->include_stack = mds_kbdc_include_stack_save();
+ fail_if (!call->include_stack);
+
+ return 0;
+fail:
+ return -1;
}
@@ -186,10 +186,10 @@ int mds_kbdc_call_stack_push(const mds_kbdc_tree_t* restrict tree, size_t start,
*
* This function is guaranteed not to modify `errno`
*/
-void mds_kbdc_call_stack_pop(void)
+void
+mds_kbdc_call_stack_pop(void)
{
- int saved_errno = errno;
- mds_kbdc_include_stack_free(calls[--calls_ptr].include_stack);
- errno = saved_errno;
+ int saved_errno = errno;
+ mds_kbdc_include_stack_free(calls[--calls_ptr].include_stack);
+ errno = saved_errno;
}
-
diff --git a/src/mds-kbdc/call-stack.h b/src/mds-kbdc/call-stack.h
index db7a18a..94b6dc8 100644
--- a/src/mds-kbdc/call-stack.h
+++ b/src/mds-kbdc/call-stack.h
@@ -27,8 +27,8 @@
/**
* Add “called from here”-notes
*/
-#define DUMP_CALL_STACK \
- fail_if (mds_kbdc_call_stack_dump())
+#define DUMP_CALL_STACK\
+ fail_if (mds_kbdc_call_stack_dump())
@@ -44,7 +44,7 @@ int mds_kbdc_call_stack_dump(void);
*
* @param result The `result` parameter of root procedure that requires the call-stack
*/
-void mds_kbdc_call_stack_begin(mds_kbdc_parsed_t* restrict result);
+void mds_kbdc_call_stack_begin(mds_kbdc_parsed_t *restrict result);
/**
* Cleanup after usage of call-stacks
@@ -59,7 +59,7 @@ void mds_kbdc_call_stack_end(void);
* @param end The position of the line of the tree node where the call end
* @return Zero on success, -1 on error
*/
-int mds_kbdc_call_stack_push(const mds_kbdc_tree_t* restrict tree, size_t start, size_t end);
+int mds_kbdc_call_stack_push(const mds_kbdc_tree_t *restrict tree, size_t start, size_t end);
/**
* Undo the lasted not-undone call to `mds_kbdc_call_stack_push`
@@ -71,4 +71,3 @@ void mds_kbdc_call_stack_pop(void);
#endif
-
diff --git a/src/mds-kbdc/callables.c b/src/mds-kbdc/callables.c
index 24b1e8a..07b08b0 100644
--- a/src/mds-kbdc/callables.c
+++ b/src/mds-kbdc/callables.c
@@ -25,29 +25,29 @@
/**
* Map, by index, from argument count, to list of callable's names
*/
-static char*** restrict names = NULL;
+static char ***restrict names = NULL;
/**
* If `callable_list[callabes[i][j]]` and `callable_include_stack_list[callabes[i][j]]`
* describe the callable named by `named[i][j]` with either `i` parameters, or the
* number of parameters specified by the suffix in `named[i][j]`
*/
-static size_t** restrict callables = NULL;
+static size_t **restrict callables = NULL;
/**
* Map the the number of elements in the, by index, corresponding element in `names`
*/
-static size_t* restrict bucket_sizes = NULL;
+static size_t *restrict bucket_sizes = NULL;
/**
* List of callables
*/
-static mds_kbdc_tree_t** restrict callable_list = NULL;
+static mds_kbdc_tree_t **restrict callable_list = NULL;
/**
* List of callables' include-stacks
*/
-static mds_kbdc_include_stack_t** restrict callable_include_stack_list = NULL;
+static mds_kbdc_include_stack_t **restrict callable_include_stack_list = NULL;
/**
* The number of buckets in `names` and `bucket_sizes`
@@ -64,26 +64,26 @@ static size_t list_ptr = 0;
/**
* Destroy the callable storage
*/
-void callables_terminate(void)
+void
+callables_terminate(void)
{
- size_t i, j, n;
- char** bucket;
- for (i = 0; i < buckets; i++)
- {
- bucket = names[i];
- for (j = 0, n = bucket_sizes[i]; j < n; j++)
- free(bucket[j]);
- free(bucket);
- free(callables[i]);
- }
- for (i = 0; i < list_ptr; i++)
- mds_kbdc_include_stack_free(callable_include_stack_list[i]);
- free(callables), callables = NULL;
- free(names), names = NULL;
- free(bucket_sizes), bucket_sizes = NULL;
- free(callable_list), callable_list = NULL;
- free(callable_include_stack_list), callable_include_stack_list = NULL;
- buckets = list_ptr = 0;
+ size_t i, j, n;
+ char **bucket;
+ for (i = 0; i < buckets; i++) {
+ bucket = names[i];
+ for (j = 0, n = bucket_sizes[i]; j < n; j++)
+ free(bucket[j]);
+ free(bucket);
+ free(callables[i]);
+ }
+ for (i = 0; i < list_ptr; i++)
+ mds_kbdc_include_stack_free(callable_include_stack_list[i]);
+ free(callables), callables = NULL;
+ free(names), names = NULL;
+ free(bucket_sizes), bucket_sizes = NULL;
+ free(callable_list), callable_list = NULL;
+ free(callable_include_stack_list), callable_include_stack_list = NULL;
+ buckets = list_ptr = 0;
}
@@ -97,57 +97,57 @@ void callables_terminate(void)
* @param callable_include_stack The include-stack for the callable
* @return Zero on success, -1 on error
*/
-int callables_set(const char* restrict name, size_t arg_count, mds_kbdc_tree_t* restrict callable,
- mds_kbdc_include_stack_t* restrict callable_include_stack)
+int
+callables_set(const char *restrict name, size_t arg_count, mds_kbdc_tree_t *restrict callable,
+ mds_kbdc_include_stack_t *restrict callable_include_stack)
{
-#define _yrealloc(var, elements, type) (yrealloc(tmp_##var, var, elements, type))
-
- char* dupname = NULL;
- char*** tmp_names = NULL;
- size_t** tmp_callables = NULL;
- size_t* tmp_bucket_sizes = NULL;
- char** old_names = NULL;
- size_t* old_callables = NULL;
- mds_kbdc_tree_t** tmp_callable_list = NULL;
- mds_kbdc_include_stack_t** tmp_callable_include_stack_list = NULL;
- int saved_errno;
-
- fail_if (xstrdup(dupname, name));
-
- if (arg_count >= buckets)
- {
- fail_if (_yrealloc(names, arg_count + 1, char**));
- fail_if (_yrealloc(callables, arg_count + 1, size_t*));
- fail_if (_yrealloc(bucket_sizes, arg_count + 1, size_t));
- memset(names + buckets, 0, (arg_count + 1 - buckets) * sizeof(char**));
- memset(callables + buckets, 0, (arg_count + 1 - buckets) * sizeof(size_t*));
- memset(bucket_sizes + buckets, 0, (arg_count + 1 - buckets) * sizeof(size_t));
- buckets = arg_count + 1;
- }
-
- fail_if (xxrealloc(old_names, names[arg_count], bucket_sizes[arg_count] + 1, char*));
- fail_if (xxrealloc(old_callables, callables[arg_count], bucket_sizes[arg_count] + 1, size_t));
-
- names[arg_count][bucket_sizes[arg_count]] = dupname, dupname = NULL;
- callables[arg_count][bucket_sizes[arg_count]] = list_ptr;
- bucket_sizes[arg_count]++;
-
- fail_if (_yrealloc(callable_list, list_ptr + 1, mds_kbdc_tree_t*));
- fail_if (_yrealloc(callable_include_stack_list, list_ptr + 1, mds_kbdc_include_stack_t*));
-
- callable_list[list_ptr] = callable;
- callable_include_stack_list[list_ptr] = callable_include_stack;
- list_ptr++;
-
- return 0;
- fail:
- saved_errno = errno;
- free(dupname);
- if (old_names)
- names[arg_count] = old_names;
- if (old_callables)
- callables[arg_count] = old_callables;
- return errno = saved_errno, -1;
+#define _yrealloc(var, elements, type) (yrealloc(tmp_##var, var, elements, type))
+
+ char *dupname = NULL;
+ char ***tmp_names = NULL;
+ size_t **tmp_callables = NULL;
+ size_t *tmp_bucket_sizes = NULL;
+ char **old_names = NULL;
+ size_t *old_callables = NULL;
+ mds_kbdc_tree_t **tmp_callable_list = NULL;
+ mds_kbdc_include_stack_t **tmp_callable_include_stack_list = NULL;
+ int saved_errno;
+
+ fail_if (xstrdup(dupname, name));
+
+ if (arg_count >= buckets) {
+ fail_if (_yrealloc(names, arg_count + 1, char**));
+ fail_if (_yrealloc(callables, arg_count + 1, size_t*));
+ fail_if (_yrealloc(bucket_sizes, arg_count + 1, size_t));
+ memset(names + buckets, 0, (arg_count + 1 - buckets) * sizeof(char**));
+ memset(callables + buckets, 0, (arg_count + 1 - buckets) * sizeof(size_t*));
+ memset(bucket_sizes + buckets, 0, (arg_count + 1 - buckets) * sizeof(size_t));
+ buckets = arg_count + 1;
+ }
+
+ fail_if (xxrealloc(old_names, names[arg_count], bucket_sizes[arg_count] + 1, char*));
+ fail_if (xxrealloc(old_callables, callables[arg_count], bucket_sizes[arg_count] + 1, size_t));
+
+ names[arg_count][bucket_sizes[arg_count]] = dupname, dupname = NULL;
+ callables[arg_count][bucket_sizes[arg_count]] = list_ptr;
+ bucket_sizes[arg_count]++;
+
+ fail_if (_yrealloc(callable_list, list_ptr + 1, mds_kbdc_tree_t*));
+ fail_if (_yrealloc(callable_include_stack_list, list_ptr + 1, mds_kbdc_include_stack_t*));
+
+ callable_list[list_ptr] = callable;
+ callable_include_stack_list[list_ptr] = callable_include_stack;
+ list_ptr++;
+
+ return 0;
+fail:
+ saved_errno = errno;
+ free(dupname);
+ if (old_names)
+ names[arg_count] = old_names;
+ if (old_callables)
+ callables[arg_count] = old_callables;
+ return errno = saved_errno, -1;
#undef _yrealloc
}
@@ -161,27 +161,26 @@ int callables_set(const char* restrict name, size_t arg_count, mds_kbdc_tree_t*
* @param callable Output parameter for the callable, `NULL` if not found
* @param callable_include_stack Output parameter for the include-stack for the callable
*/
-void callables_get(const char* restrict name, size_t arg_count, mds_kbdc_tree_t** restrict callable,
- mds_kbdc_include_stack_t** restrict callable_include_stack)
+void
+callables_get(const char *restrict name, size_t arg_count, mds_kbdc_tree_t **restrict callable,
+ mds_kbdc_include_stack_t **restrict callable_include_stack)
{
- char** restrict names_;
- size_t i, n;
-
- *callable = NULL;
- *callable_include_stack = NULL;
-
- if (arg_count >= buckets)
- return;
-
- names_ = names[arg_count];
- for (i = 0, n = bucket_sizes[arg_count]; i < n; i++)
- {
- if (strcmp(names_[i], name))
- continue;
- i = callables[arg_count][i];
- *callable = callable_list[i];
- *callable_include_stack = callable_include_stack_list[i];
- return;
- }
+ char **restrict names_;
+ size_t i, n;
+
+ *callable = NULL;
+ *callable_include_stack = NULL;
+
+ if (arg_count >= buckets)
+ return;
+
+ names_ = names[arg_count];
+ for (i = 0, n = bucket_sizes[arg_count]; i < n; i++) {
+ if (strcmp(names_[i], name))
+ continue;
+ i = callables[arg_count][i];
+ *callable = callable_list[i];
+ *callable_include_stack = callable_include_stack_list[i];
+ return;
+ }
}
-
diff --git a/src/mds-kbdc/callables.h b/src/mds-kbdc/callables.h
index bb453f1..9e0d3b3 100644
--- a/src/mds-kbdc/callables.h
+++ b/src/mds-kbdc/callables.h
@@ -38,8 +38,8 @@ void callables_terminate(void);
* @param callable_include_stack The include-stack for the callable
* @return Zero on success, -1 on error
*/
-int callables_set(const char* restrict name, size_t arg_count, mds_kbdc_tree_t* restrict callable,
- mds_kbdc_include_stack_t* restrict callable_include_stack);
+int callables_set(const char *restrict name, size_t arg_count, mds_kbdc_tree_t *restrict callable,
+ mds_kbdc_include_stack_t *restrict callable_include_stack);
/**
* Get a stored callable
@@ -50,9 +50,8 @@ int callables_set(const char* restrict name, size_t arg_count, mds_kbdc_tree_t*
* @param callable Output parameter for the callable
* @param callable_include_stack Output parameter for the include-stack for the callable
*/
-void callables_get(const char* restrict name, size_t arg_count, mds_kbdc_tree_t** restrict callable,
- mds_kbdc_include_stack_t** restrict callable_include_stack);
+void callables_get(const char *restrict name, size_t arg_count, mds_kbdc_tree_t **restrict callable,
+ mds_kbdc_include_stack_t **restrict callable_include_stack);
#endif
-
diff --git a/src/mds-kbdc/compile-layout.c b/src/mds-kbdc/compile-layout.c
index 199e870..8eb832b 100644
--- a/src/mds-kbdc/compile-layout.c
+++ b/src/mds-kbdc/compile-layout.c
@@ -34,12 +34,12 @@
/**
* This process's value for `mds_kbdc_tree_t.processed`
*/
-#define PROCESS_LEVEL 6
+#define PROCESS_LEVEL 6
/**
* Tree type constant shortener
*/
-#define C(TYPE) MDS_KBDC_TREE_TYPE_##TYPE
+#define C(TYPE) MDS_KBDC_TREE_TYPE_##TYPE
/**
* Add an error with “included from here”-notes and, unless
@@ -50,36 +50,34 @@
* @param ...:const char*, ... Error description format string and arguments
* @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
*/
-#define NEW_ERROR(NODE, SEVERITY, ...) \
- do \
- { \
- NEW_ERROR_WITH_INCLUDES(NODE, includes_ptr, SEVERITY, __VA_ARGS__); \
- if (strcmp(#SEVERITY, "NOTE")) \
- DUMP_CALL_STACK; \
- } \
- while (0)
+#define NEW_ERROR(NODE, SEVERITY, ...)\
+ do {\
+ NEW_ERROR_WITH_INCLUDES(NODE, includes_ptr, SEVERITY, __VA_ARGS__);\
+ if (strcmp(#SEVERITY, "NOTE"))\
+ DUMP_CALL_STACK;\
+ } while (0)
/**
* Beginning of failure clause
*/
-#define FAIL_BEGIN fail: saved_errno = errno
+#define FAIL_BEGIN fail: saved_errno = errno
/**
* End of failure clause
*/
-#define FAIL_END return errno = saved_errno, -1
+#define FAIL_END return errno = saved_errno, -1
/**
* Variable whether the latest created error is stored
*/
-static mds_kbdc_parse_error_t* error;
+static mds_kbdc_parse_error_t *error;
/**
* The parameter of `compile_layout`
*/
-static mds_kbdc_parsed_t* restrict result;
+static mds_kbdc_parsed_t *restrict result;
/**
* 3: `return` is being processed
@@ -101,12 +99,12 @@ static int multiple_variants = 0;
*
* (We will not look too hard.)
*/
-static mds_kbdc_tree_t* last_value_statement = NULL;
+static mds_kbdc_tree_t *last_value_statement = NULL;
/**
* Address of the current return value
*/
-static char32_t** current_return_value = NULL;
+static char32_t **current_return_value = NULL;
/**
* Whether ‘\set/3’ has been called
@@ -121,7 +119,7 @@ static int have_side_effect = 0;
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_subtree(mds_kbdc_tree_t* restrict tree);
+static int compile_subtree(mds_kbdc_tree_t *restrict tree);
/**
* Check that a function used in a part of a literal is defined
@@ -133,8 +131,8 @@ static int compile_subtree(mds_kbdc_tree_t* restrict tree);
* @param rc Success status output parameter: zero on success,
* -1 on error, 1 if an undefined function is used
*/
-static void check_function_call(const mds_kbdc_tree_t* restrict tree, const char* restrict raw,
- size_t lineoff, const char* restrict* restrict end, int* restrict rc);
+static void check_function_call(const mds_kbdc_tree_t *restrict tree, const char *restrict raw,
+ size_t lineoff, const char *restrict *restrict end, int *restrict rc);
/**
* Parse an argument in a function call
@@ -146,8 +144,8 @@ static void check_function_call(const mds_kbdc_tree_t* restrict tree, const char
* @param value Output parameter for the value to which the argument evaulates
* @return Zero on success, -1 on error
*/
-static int parse_function_argument(mds_kbdc_tree_t* restrict tree, const char* restrict raw, size_t lineoff,
- const char* restrict* restrict end, char32_t** restrict value);
+static int parse_function_argument(mds_kbdc_tree_t *restrict tree, const char *restrict raw, size_t lineoff,
+ const char *restrict *restrict end, char32_t **restrict value);
@@ -167,37 +165,36 @@ static int parse_function_argument(mds_kbdc_tree_t* restrict tree, const char* r
* but could easily be mistaked for one that does
* @return Zero on success, -1 on error
*/
-static int let(size_t variable, const char32_t* restrict string, const mds_kbdc_tree_t* restrict value,
- mds_kbdc_tree_t* restrict statement, size_t lineoff, int possibile_shadow_attempt)
+static int
+let(size_t variable, const char32_t *restrict string, const mds_kbdc_tree_t *restrict value,
+ mds_kbdc_tree_t *restrict statement, size_t lineoff, int possibile_shadow_attempt)
{
- mds_kbdc_tree_t* tree = NULL;
- int saved_errno;
-
- /* Warn if this is a possible shadow attempt. */
- if (possibile_shadow_attempt && variables_let_will_override(variable) && statement &&
- (variables_has_been_used_in_for(variable) == 0) && (statement->processed != PROCESS_LEVEL))
- {
- statement->processed = PROCESS_LEVEL;
- NEW_ERROR(statement, WARNING, "does not shadow existing definition");
- error->start = lineoff;
- error->end = lineoff + (size_t)snprintf(NULL, 0, "\\%zu", variable);
- }
-
- /* Duplicate value. */
- if (value)
- fail_if (tree = mds_kbdc_tree_dup(value), tree == NULL);
- if (value == NULL)
- {
- fail_if (tree = mds_kbdc_tree_create(C(COMPILED_STRING)), tree == NULL);
- fail_if ((tree->compiled_string.string = string_dup(string)) == NULL);
- }
-
- /* Assign variable. */
- fail_if (variables_let(variable, tree));
- return 0;
- FAIL_BEGIN;
- mds_kbdc_tree_free(tree);
- FAIL_END;
+ mds_kbdc_tree_t *tree = NULL;
+ int saved_errno;
+
+ /* Warn if this is a possible shadow attempt. */
+ if (possibile_shadow_attempt && variables_let_will_override(variable) && statement &&
+ !variables_has_been_used_in_for(variable) && statement->processed != PROCESS_LEVEL) {
+ statement->processed = PROCESS_LEVEL;
+ NEW_ERROR(statement, WARNING, "does not shadow existing definition");
+ error->start = lineoff;
+ error->end = lineoff + (size_t)snprintf(NULL, 0, "\\%zu", variable);
+ }
+
+ /* Duplicate value. */
+ if (value) {
+ fail_if (!(tree = mds_kbdc_tree_dup(value)));
+ } else {
+ fail_if (!(tree = mds_kbdc_tree_create(C(COMPILED_STRING))));
+ fail_if (!(tree->compiled_string.string = string_dup(string)));
+ }
+
+ /* Assign variable. */
+ fail_if (variables_let(variable, tree));
+ return 0;
+ FAIL_BEGIN;
+ mds_kbdc_tree_free(tree);
+ FAIL_END;
}
@@ -212,48 +209,47 @@ static int let(size_t variable, const char32_t* restrict string, const mds_kbdc_
* @param end The offset on the line where the function call ends
* @return Zero on success, -1 on error, 1 if the call is invalid
*/
-static int check_set_3_get_2_call(mds_kbdc_tree_t* restrict tree, int is_set, const char32_t* variable_arg,
- const char32_t* index_arg, size_t start, size_t end)
+static int
+check_set_3_get_2_call(mds_kbdc_tree_t *restrict tree, int is_set, const char32_t *variable_arg,
+ const char32_t *index_arg, size_t start, size_t end)
{
-#define F (is_set ? "set/3" : "get/2")
-#define FUN_ERROR(...) \
- do \
- { \
- NEW_ERROR(__VA_ARGS__); \
- error->start = start; \
- error->end = end; \
- return 1; \
- } \
- while(0);
-
- mds_kbdc_tree_t* variable;
- mds_kbdc_tree_t* element;
- size_t index, arg_count;
-
- if ((variable_arg[0] <= 0) || (variable_arg[1] != -1))
- FUN_ERROR(tree, ERROR, "first argument in call to function ‘%s’ must be a variable index", F);
-
- if ((index_arg[0] < 0) || (index_arg[1] != -1))
- FUN_ERROR(tree, ERROR, "second argument in call to function ‘%s’ must be an element index", F);
-
- variable = variables_get((size_t)*variable_arg);
- if (variable == NULL)
- FUN_ERROR(tree, ERROR, "‘\\%zu’ is not declared", (size_t)*variable_arg);
- if (variable->type != C(ARRAY))
- FUN_ERROR(tree, ERROR, "‘\\%zu’ is not an array", (size_t)*variable_arg);
-
- arg_count = index = (size_t)*index_arg;
- element = variable->array.elements;
- while (element && index--)
- element = element->next;
-
- if (element == NULL)
- FUN_ERROR(tree, ERROR, "‘\\%zu’ does not hold %zu %s",
- (size_t)*variable_arg, arg_count + 1, arg_count ? "elements" : "element");
-
- return 0;
- fail:
- return -1;
+#define F (is_set ? "set/3" : "get/2")
+#define FUN_ERROR(...)\
+ do {\
+ NEW_ERROR(__VA_ARGS__);\
+ error->start = start;\
+ error->end = end;\
+ return 1;\
+ } while(0);
+
+ mds_kbdc_tree_t *variable;
+ mds_kbdc_tree_t *element;
+ size_t index, arg_count;
+
+ if (variable_arg[0] <= 0 || variable_arg[1] != -1)
+ FUN_ERROR(tree, ERROR, "first argument in call to function ‘%s’ must be a variable index", F);
+
+ if (index_arg[0] < 0 || index_arg[1] != -1)
+ FUN_ERROR(tree, ERROR, "second argument in call to function ‘%s’ must be an element index", F);
+
+ variable = variables_get((size_t)*variable_arg);
+ if (!variable)
+ FUN_ERROR(tree, ERROR, "‘\\%zu’ is not declared", (size_t)*variable_arg);
+ if (variable->type != C(ARRAY))
+ FUN_ERROR(tree, ERROR, "‘\\%zu’ is not an array", (size_t)*variable_arg);
+
+ arg_count = index = (size_t)*index_arg;
+ element = variable->array.elements;
+ while (element && index--)
+ element = element->next;
+
+ if (!element)
+ FUN_ERROR(tree, ERROR, "‘\\%zu’ does not hold %zu %s",
+ (size_t)*variable_arg, arg_count + 1, arg_count ? "elements" : "element");
+
+ return 0;
+fail:
+ return -1;
#undef FUN_ERROR
#undef F
}
@@ -274,125 +270,118 @@ static int check_set_3_get_2_call(mds_kbdc_tree_t* restrict tree, int is_set, co
* as containing an error
* @return Zero on success, -1 on error
*/
-static int call_function(mds_kbdc_tree_t* restrict tree, const char* restrict name,
- const char32_t** restrict arguments, size_t start, size_t end,
- char32_t** restrict return_value)
+static int
+call_function(mds_kbdc_tree_t *restrict tree, const char *restrict name, const char32_t **restrict arguments,
+ size_t start, size_t end, char32_t **restrict return_value)
{
-#define FUN_ERROR(...) \
- do \
- { \
- NEW_ERROR(__VA_ARGS__); \
- error->start = start; \
- error->end = end; \
- tree->processed = PROCESS_LEVEL; \
- free(*return_value), *return_value = NULL; \
- goto done; \
- } \
- while(0);
-
- size_t i, arg_count = 0, empty_count = 0;
- char32_t** old_return_value;
- mds_kbdc_tree_function_t* function = NULL;
- mds_kbdc_include_stack_t* function_include_stack = NULL;
- mds_kbdc_include_stack_t* our_include_stack = NULL;
- int r, is_set, builtin, saved_errno;
-
- /* Push call-stack. */
- mds_kbdc_call_stack_push(tree, start, end);
-
- /* Count the number of arguments we have. */
- while (arguments[arg_count])
- arg_count++;
-
- /* Push return-stack. */
- *return_value = NULL;
- old_return_value = current_return_value;
- current_return_value = return_value;
-
- /* Get function definition. */
- builtin = builtin_function_defined(name, arg_count);
- if (builtin == 0)
- callables_get(name, arg_count, (mds_kbdc_tree_t**)&function, &function_include_stack);
- if ((builtin == 0) && (function == NULL))
- FUN_ERROR(tree, ERROR, "function ‘%s/%zu’ has not been defined yet", name, arg_count);
-
-
- /* Call non-builtin function. */
- if (builtin == 0)
- {
- /* Push call stack and set parameters. */
- variables_stack_push();
- for (i = 0; i < arg_count; i++)
- fail_if (let(i + 1, arguments[i], NULL, NULL, 0, 0));
-
- /* Switch include-stack to the function's. */
- fail_if (our_include_stack = mds_kbdc_include_stack_save(), our_include_stack == NULL);
- fail_if (mds_kbdc_include_stack_restore(function_include_stack));
-
- /* Call the function. */
- fail_if (compile_subtree(function->inner));
-
- /* Switch back the include-stack to ours. */
- fail_if (mds_kbdc_include_stack_restore(our_include_stack));
- mds_kbdc_include_stack_free(our_include_stack), our_include_stack = NULL;
-
- /* Pop call stack. */
- variables_stack_pop();
-
- /* Check that the function returned a value. */
- if (*return_value == NULL)
- FUN_ERROR(tree, ERROR, "function ‘%s/%zu’ did not return a value", name, arg_count);
-
- goto done;
- }
-
-
- /* Call builtin function. */
-
- /* Check argument sanity. */
- is_set = (arg_count == 3) && !strcmp(name, "set");
- if (is_set || ((arg_count == 2) && !strcmp(name, "get")))
- {
- fail_if (r = check_set_3_get_2_call(tree, is_set, arguments[0], arguments[1], start, end), r < 0);
- if (r)
- {
- tree->processed = PROCESS_LEVEL;
- free(*return_value), *return_value = NULL;
- goto done;
+#define FUN_ERROR(...)\
+ do {\
+ NEW_ERROR(__VA_ARGS__);\
+ error->start = start;\
+ error->end = end;\
+ tree->processed = PROCESS_LEVEL;\
+ free(*return_value), *return_value = NULL;\
+ goto done;\
+ } while(0);
+
+ size_t i, arg_count = 0, empty_count = 0;
+ char32_t **old_return_value;
+ mds_kbdc_tree_function_t *function = NULL;
+ mds_kbdc_include_stack_t *function_include_stack = NULL;
+ mds_kbdc_include_stack_t *our_include_stack = NULL;
+ int r, is_set, builtin, saved_errno;
+
+ /* Push call-stack. */
+ mds_kbdc_call_stack_push(tree, start, end);
+
+ /* Count the number of arguments we have. */
+ while (arguments[arg_count])
+ arg_count++;
+
+ /* Push return-stack. */
+ *return_value = NULL;
+ old_return_value = current_return_value;
+ current_return_value = return_value;
+
+ /* Get function definition. */
+ builtin = builtin_function_defined(name, arg_count);
+ if (!builtin)
+ callables_get(name, arg_count, (mds_kbdc_tree_t**)&function, &function_include_stack);
+ if (!builtin && !function)
+ FUN_ERROR(tree, ERROR, "function ‘%s/%zu’ has not been defined yet", name, arg_count);
+
+
+ /* Call non-builtin function. */
+ if (!builtin) {
+ /* Push call stack and set parameters. */
+ variables_stack_push();
+ for (i = 0; i < arg_count; i++)
+ fail_if (let(i + 1, arguments[i], NULL, NULL, 0, 0));
+
+ /* Switch include-stack to the function's. */
+ fail_if (our_include_stack = mds_kbdc_include_stack_save(), our_include_stack == NULL);
+ fail_if (mds_kbdc_include_stack_restore(function_include_stack));
+
+ /* Call the function. */
+ fail_if (compile_subtree(function->inner));
+
+ /* Switch back the include-stack to ours. */
+ fail_if (mds_kbdc_include_stack_restore(our_include_stack));
+ mds_kbdc_include_stack_free(our_include_stack), our_include_stack = NULL;
+
+ /* Pop call stack. */
+ variables_stack_pop();
+
+ /* Check that the function returned a value. */
+ if (!*return_value)
+ FUN_ERROR(tree, ERROR, "function ‘%s/%zu’ did not return a value", name, arg_count);
+
+ goto done;
}
- }
- else
- {
- for (i = 0; i < arg_count; i++)
- empty_count += string_length(arguments[i]) == 0;
- if (empty_count && (empty_count != arg_count))
- FUN_ERROR(tree, ERROR,
- "built-in function ‘%s/%zu’ requires that either none of"
- " the arguments are empty strings or that all of them are",
- name, arg_count);
- }
-
- /* Call the function. */
- *return_value = builtin_function_invoke(name, arg_count, arguments);
- fail_if (*return_value == NULL);
- have_side_effect |= is_set;
- /* XXX ideally, we want to make sure it is in a scope that actually brings side-effects. */
-
-
- done:
- /* Pop call-stack. */
- mds_kbdc_call_stack_pop();
-
- /* Pop return-stack. */
- current_return_value = old_return_value;
- return 0;
-
- FAIL_BEGIN;
- mds_kbdc_call_stack_pop();
- mds_kbdc_include_stack_free(our_include_stack);
- free(*return_value), *return_value = NULL;
- current_return_value = old_return_value;
- FAIL_END;
+
+
+ /* Call builtin function. */
+
+ /* Check argument sanity. */
+ is_set = arg_count == 3 && !strcmp(name, "set");
+ if (is_set || (arg_count == 2 && !strcmp(name, "get"))) {
+ fail_if (r = check_set_3_get_2_call(tree, is_set, arguments[0], arguments[1], start, end), r < 0);
+ if (r) {
+ tree->processed = PROCESS_LEVEL;
+ free(*return_value), *return_value = NULL;
+ goto done;
+ }
+ } else {
+ for (i = 0; i < arg_count; i++)
+ empty_count += !string_length(arguments[i]);
+ if (empty_count && empty_count != arg_count)
+ FUN_ERROR(tree, ERROR,
+ "built-in function ‘%s/%zu’ requires that either none of"
+ " the arguments are empty strings or that all of them are",
+ name, arg_count);
+ }
+
+ /* Call the function. */
+ *return_value = builtin_function_invoke(name, arg_count, arguments);
+ fail_if (!*return_value);
+ have_side_effect |= is_set;
+ /* XXX ideally, we want to make sure it is in a scope that actually brings side-effects. */
+
+
+done:
+ /* Pop call-stack. */
+ mds_kbdc_call_stack_pop();
+
+ /* Pop return-stack. */
+ current_return_value = old_return_value;
+ return 0;
+
+ FAIL_BEGIN;
+ mds_kbdc_call_stack_pop();
+ mds_kbdc_include_stack_free(our_include_stack);
+ free(*return_value), *return_value = NULL;
+ current_return_value = old_return_value;
+ FAIL_END;
#undef FUN_ERROR
}
@@ -408,102 +397,99 @@ static int call_function(mds_kbdc_tree_t* restrict tree, const char* restrict na
* @param end Output parameter for the end of the escape
* @return The text the escape represents, `NULL` on error
*/
-static char32_t* parse_function_call(mds_kbdc_tree_t* restrict tree, const char* restrict raw, size_t lineoff,
- int* restrict escape, const char* restrict* restrict end)
+static char32_t *
+parse_function_call(mds_kbdc_tree_t *restrict tree, const char *restrict raw, size_t lineoff,
+ int *restrict escape, const char *restrict *restrict end)
{
-#define R(LOWER, UPPER) (((LOWER) <= c) && (c <= (UPPER)))
-#define GROW_ARGS \
- if (arguments_ptr == arguments_size) \
- fail_if (xxrealloc(old_arguments, arguments, arguments_size += 4, char32_t*))
-
- const char* restrict bracket = raw + 1;
- char32_t* rc = NULL;
- const char32_t** restrict arguments_;
- char32_t** restrict arguments = NULL;
- char32_t** restrict old_arguments = NULL;
- size_t arguments_ptr = 0, arguments_size = 0;
- char* restrict name;
- char c;
- int r, saved_errno = 0;
-
- /* Find the opening bracket associated with the function call and validate the escape. */
- for (; c = *bracket, 1; bracket++)
- if ((c == '_') || R('0', '9') || R('a', 'z') || R('A', 'Z'));
- else if (c == '(')
- break;
- else
- {
- *end = bracket;
- if (tree->processed != PROCESS_LEVEL)
- NEW_ERROR(tree, ERROR, "invalid escape");
- goto error;
- }
-
- /* Copy the name of the function. */
- name = alloca((size_t)(bracket - raw) * sizeof(char));
- memcpy(name, raw + 1, (size_t)(bracket - raw - 1) * sizeof(char));
- name[bracket - raw - 1] = 0;
-
- /* Get arguments. */
- for (*end = ++bracket;;)
- {
- while (**end == ' ')
- (*end)++;
- GROW_ARGS;
- arguments[arguments_ptr] = NULL;
- if (**end == ')')
- {
- *escape = 0;
- (*end)++;
- arguments_ptr++;
- break;
+#define R(LOWER, UPPER) ((LOWER) <= c && c <= (UPPER))
+#define GROW_ARGS\
+ if (arguments_ptr == arguments_size)\
+ fail_if (xxrealloc(old_arguments, arguments, arguments_size += 4, char32_t*))
+
+ const char *restrict bracket = raw + 1;
+ char32_t *rc = NULL;
+ const char32_t **restrict arguments_;
+ char32_t **restrict arguments = NULL;
+ char32_t **restrict old_arguments = NULL;
+ size_t arguments_ptr = 0, arguments_size = 0;
+ char *restrict name;
+ char c;
+ int r, saved_errno = 0;
+
+ /* Find the opening bracket associated with the function call and validate the escape. */
+ for (; c = *bracket, 1; bracket++) {
+ if (c == '_' || R('0', '9') || R('a', 'z') || R('A', 'Z'));
+ else if (c == '(') {
+ break;
+ } else {
+ *end = bracket;
+ if (tree->processed != PROCESS_LEVEL)
+ NEW_ERROR(tree, ERROR, "invalid escape");
+ goto error;
+ }
}
- else if (**end == '\0')
- {
- if (tree->processed != PROCESS_LEVEL)
- NEW_ERROR(tree, ERROR, "incomplete function call");
- goto error;
+
+ /* Copy the name of the function. */
+ name = alloca((size_t)(bracket - raw) * sizeof(char));
+ memcpy(name, raw + 1, (size_t)(bracket - raw - 1) * sizeof(char));
+ name[bracket - raw - 1] = 0;
+
+ /* Get arguments. */
+ for (*end = ++bracket;;) {
+ while (**end == ' ')
+ (*end)++;
+ GROW_ARGS;
+ arguments[arguments_ptr] = NULL;
+ if (**end == ')') {
+ *escape = 0;
+ (*end)++;
+ arguments_ptr++;
+ break;
+ } else if (!**end) {
+ if (tree->processed != PROCESS_LEVEL)
+ NEW_ERROR(tree, ERROR, "incomplete function call");
+ goto error;
+ }
+ r = parse_function_argument(tree, *end, lineoff + (size_t)(*end - raw), end, arguments + arguments_ptr++);
+ fail_if (r < 0);
}
- r = parse_function_argument(tree, *end, lineoff + (size_t)(*end - raw), end, arguments + arguments_ptr++);
- fail_if (r < 0);
- }
-
- /* Call the function. */
- if (tree->processed == PROCESS_LEVEL)
- goto stop;
- arguments_ = alloca(arguments_ptr * sizeof(const char32_t*));
- memcpy(arguments_, arguments, arguments_ptr * sizeof(const char32_t*));
- fail_if (call_function(tree, name, arguments_, lineoff, lineoff + (size_t)(*end - raw), &rc));
- if (rc == NULL)
- goto stop;
-
- goto done;
-
- error:
- error->start = lineoff;
- error->end = lineoff + (size_t)(*end - raw);
- stop:
- *escape = 0;
- tree->processed = PROCESS_LEVEL;
- fail_if (xmalloc(rc, 1, char32_t));
- *rc = -1;
- goto done;
-
- fail:
- saved_errno = errno;
- free(rc);
- if (old_arguments)
- arguments = old_arguments;
- while (arguments_ptr--)
- free(arguments[arguments_ptr]);
- free(arguments);
- rc = NULL;
- done:
- while (arguments_ptr--)
- free(arguments[arguments_ptr]);
- free(arguments);
- errno = saved_errno;
- return rc;
+
+ /* Call the function. */
+ if (tree->processed == PROCESS_LEVEL)
+ goto stop;
+ arguments_ = alloca(arguments_ptr * sizeof(const char32_t*));
+ memcpy(arguments_, arguments, arguments_ptr * sizeof(const char32_t*));
+ fail_if (call_function(tree, name, arguments_, lineoff, lineoff + (size_t)(*end - raw), &rc));
+ if (!rc)
+ goto stop;
+
+ goto done;
+
+error:
+ error->start = lineoff;
+ error->end = lineoff + (size_t)(*end - raw);
+stop:
+ *escape = 0;
+ tree->processed = PROCESS_LEVEL;
+ fail_if (xmalloc(rc, 1, char32_t));
+ *rc = -1;
+ goto done;
+
+fail:
+ saved_errno = errno;
+ free(rc);
+ if (old_arguments)
+ arguments = old_arguments;
+ while (arguments_ptr--)
+ free(arguments[arguments_ptr]);
+ free(arguments);
+ rc = NULL;
+done:
+ while (arguments_ptr--)
+ free(arguments[arguments_ptr]);
+ free(arguments);
+ errno = saved_errno;
+ return rc;
#undef GROW_ARGS
#undef R
}
@@ -520,41 +506,39 @@ static char32_t* parse_function_call(mds_kbdc_tree_t* restrict tree, const char*
* -1 on error, 1 if an undefined function is used
* @return The number of arguments the part of the literal contains
*/
-static size_t check_function_calls_in_literal_(const mds_kbdc_tree_t* restrict tree,
- const char* restrict raw, size_t lineoff,
- const char* restrict* restrict end, int* restrict rc)
+static size_t
+check_function_calls_in_literal_(const mds_kbdc_tree_t *restrict tree, const char *restrict raw,
+ size_t lineoff, const char *restrict *restrict end, int *restrict rc)
{
-#define R(LOWER, UPPER) (((LOWER) <= c) && (c <= (UPPER)))
- const char* restrict raw_ = raw;
- size_t count = 0;
- int space = 1, quote = 0, escape = 0;
- char c;
-
- while ((c = *raw++))
- {
- if (space && !strchr(" )", c))
- space = 0, count++;
-
- if (escape)
- {
- escape = 0;
- if (((c == '_') || R('a', 'z') || R('A', 'Z')) && (c != 'u'))
- /* \u*() is disallowed because \u* is used for hexadecimal representation. */
- if (check_function_call(tree, raw - 2, lineoff + (size_t)(raw - 2 - raw_), &raw, rc), *rc < 0)
- break;
- }
- else if (c == '\\') escape = 1;
- else if (c == '"') quote ^= 1;
- else if (!quote)
- {
- space = (c == ' ');
- if (c == ')')
- break;
+#define R(LOWER, UPPER) ((LOWER) <= c && c <= (UPPER))
+ const char *restrict raw_ = raw;
+ size_t count = 0;
+ int space = 1, quote = 0, escape = 0;
+ char c;
+
+ while ((c = *raw++)) {
+ if (space && !strchr(" )", c))
+ space = 0, count++;
+
+ if (escape) {
+ escape = 0;
+ if ((c == '_' || R('a', 'z') || R('A', 'Z')) && c != 'u')
+ /* \u*() is disallowed because \u* is used for hexadecimal representation. */
+ if (check_function_call(tree, raw - 2, lineoff + (size_t)(raw - 2 - raw_), &raw, rc), *rc < 0)
+ break;
+ } else if (c == '\\') {
+ escape = 1;
+ } else if (c == '"') {
+ quote ^= 1;
+ } else if (!quote) {
+ space = c == ' ';
+ if (c == ')')
+ break;
+ }
}
- }
-
- *end = raw;
- return count;
+
+ *end = raw;
+ return count;
#undef R
}
@@ -569,45 +553,46 @@ static size_t check_function_calls_in_literal_(const mds_kbdc_tree_t* restrict t
* @param rc Success status output parameter: zero on success,
* -1 on error, 1 if an undefined function is used
*/
-static void check_function_call(const mds_kbdc_tree_t* restrict tree, const char* restrict raw,
- size_t lineoff, const char* restrict* restrict end, int* restrict rc)
+static void
+check_function_call(const mds_kbdc_tree_t *restrict tree, const char *restrict raw,
+ size_t lineoff, const char *restrict *restrict end, int *restrict rc)
{
- mds_kbdc_tree_t* function = NULL;
- mds_kbdc_include_stack_t* _function_include_stack;
- char* restrict bracket = strchr(raw, '(');
- char* restrict name;
- size_t arg_count;
-
- /* Check that it is a function call by check that it has an opening bracket. */
- if (bracket == NULL)
- {
- *end = raw + strlen(raw);
- return;
- }
-
- /* Copy the name of the function. */
- name = alloca((size_t)(bracket - raw) * sizeof(char));
- memcpy(name, raw + 1, (size_t)(bracket - raw - 1) * sizeof(char));
- name[bracket++ - raw - 1] = 0;
-
- /* Get the number of arguments used, and check function calls there too. */
- arg_count = check_function_calls_in_literal_(tree, bracket, lineoff + (size_t)(bracket - raw), end, rc);
- if (*rc < 0) return;
-
- /* Check that the function is defined. */
- if (builtin_function_defined(name, arg_count))
- return;
- callables_get(name, arg_count, &function, &_function_include_stack);
- if (function != NULL)
- return;
- *rc |= 1;
- NEW_ERROR(tree, ERROR, "function ‘%s/%zu’ has not been defined yet", name, arg_count);
- error->start = lineoff;
- error->end = lineoff + (size_t)(*end - raw);
- return;
-
- fail:
- *rc |= -1;
+ mds_kbdc_tree_t *function = NULL;
+ mds_kbdc_include_stack_t *_function_include_stack;
+ char *restrict bracket = strchr(raw, '(');
+ char *restrict name;
+ size_t arg_count;
+
+ /* Check that it is a function call by check that it has an opening bracket. */
+ if (!bracket) {
+ *end = raw + strlen(raw);
+ return;
+ }
+
+ /* Copy the name of the function. */
+ name = alloca((size_t)(bracket - raw) * sizeof(char));
+ memcpy(name, raw + 1, (size_t)(bracket - raw - 1) * sizeof(char));
+ name[bracket++ - raw - 1] = 0;
+
+ /* Get the number of arguments used, and check function calls there too. */
+ arg_count = check_function_calls_in_literal_(tree, bracket, lineoff + (size_t)(bracket - raw), end, rc);
+ if (*rc < 0)
+ return;
+
+ /* Check that the function is defined. */
+ if (builtin_function_defined(name, arg_count))
+ return;
+ callables_get(name, arg_count, &function, &_function_include_stack);
+ if (function)
+ return;
+ *rc |= 1;
+ NEW_ERROR(tree, ERROR, "function ‘%s/%zu’ has not been defined yet", name, arg_count);
+ error->start = lineoff;
+ error->end = lineoff + (size_t)(*end - raw);
+ return;
+
+fail:
+ *rc |= -1;
}
@@ -619,14 +604,15 @@ static void check_function_call(const mds_kbdc_tree_t* restrict tree, const char
* @param lineoff The offset on the line where the literal beings
* @return Zero on success, -1 on error, 1 if an undefined function is used
*/
-static int check_function_calls_in_literal(const mds_kbdc_tree_t* restrict tree,
- const char* restrict raw, size_t lineoff)
+static int
+check_function_calls_in_literal(const mds_kbdc_tree_t *restrict tree,
+ const char *restrict raw, size_t lineoff)
{
- int rc = 0;
- (void) check_function_calls_in_literal_(tree, raw, lineoff, &raw, &rc);
- fail_if (rc < 0);
- fail:
- return rc;
+ int rc = 0;
+ (void) check_function_calls_in_literal_(tree, raw, lineoff, &raw, &rc);
+ fail_if (rc < 0);
+fail:
+ return rc;
}
@@ -641,102 +627,98 @@ static int check_function_calls_in_literal(const mds_kbdc_tree_t* restrict tree,
* @param end Output parameter for the end of the escape
* @return The text the escape represents, `NULL` on error
*/
-static char32_t* parse_escape(mds_kbdc_tree_t* restrict tree, const char* restrict raw, size_t lineoff,
- int* restrict escape, const char* restrict* restrict end)
+static char32_t *
+parse_escape(mds_kbdc_tree_t *restrict tree, const char *restrict raw, size_t lineoff,
+ int *restrict escape, const char *restrict *restrict end)
{
-#define R(LOWER, UPPER) (((LOWER) <= c) && (c <= (UPPER)))
-#define CR(COND, LOWER, UPPER) ((*escape == (COND)) && R(LOWER, UPPER))
-#define VARIABLE (int)(raw - raw_) - (c == '.'), raw_
-#define RETURN_ERROR(...) \
- do \
- { \
- NEW_ERROR(__VA_ARGS__); \
- error->start = lineoff; \
- error->end = lineoff + (size_t)(raw - raw_); \
- tree->processed = PROCESS_LEVEL; \
- *escape = 0; \
- if (rc) \
- goto done; \
- fail_if (xmalloc(rc, 1, char32_t)); \
- *rc = -1; \
- goto done; \
- } \
- while (0)
-
- const char* restrict raw_ = raw++;
- char c = *raw++;
- uintmax_t numbuf = 0;
- char32_t* rc = NULL;
- mds_kbdc_tree_t* value;
- int have = 0, saved_errno;
-
-
- /* Get escape type. */
- if (c == '0')
- /* Octal representation. */
- *escape = 8, have = 1;
- else if (c == 'u')
- /* Hexadecimal representation. */
- *escape = 16;
- else if (R('1', '9'))
- /* Variable dereference. */
- *escape = 10, have = 1, numbuf = (uintmax_t)(c - '0');
- else if ((c == '_') || R('a', 'z') || R('A', 'Z'))
- /* Function call. */
- *escape = 100;
- else
- RETURN_ERROR(tree, ERROR, "invalid escape");
-
-
- /* Read escape. */
- if (*escape == 100)
- /* Function call. */
- {
- fail_if (rc = parse_function_call(tree, raw_, lineoff, escape, end), rc == NULL);
- return rc;
- }
- /* Octal or hexadecimal representation, or variable dereference. */
- for (; (c = *raw); have = 1, raw++)
- if (CR( 8, '0', '7')) numbuf = 8 * numbuf + (c & 15);
- else if (CR(16, '0', '9')) numbuf = 16 * numbuf + (c & 15);
- else if (CR(16, 'a', 'f')) numbuf = 16 * numbuf + (c & 15) + 9;
- else if (CR(16, 'A', 'F')) numbuf = 16 * numbuf + (c & 15) + 9;
- else if (CR(10, '0', '9')) numbuf = 10 * numbuf + (c & 15);
- else break;
- if (c == '.')
- raw++;
- if (have == 0)
- RETURN_ERROR(tree, ERROR, "invalid escape");
-
-
- /* Evaluate escape. */
- if (*escape == 10)
- {
- /* Variable dereference. */
- if (value = variables_get((size_t)numbuf), value == NULL)
- RETURN_ERROR(tree, ERROR, "variable ‘%.*s’ is not defined", VARIABLE);
- if (value->type == C(ARRAY))
- RETURN_ERROR(tree, ERROR, "variable ‘%.*s’ is an array", VARIABLE);
- if (value->type != C(COMPILED_STRING))
- NEW_ERROR(tree, INTERNAL_ERROR, "variable ‘%.*s’ is of impossible type", VARIABLE);
- fail_if (rc = string_dup(value->compiled_string.string), rc == NULL);
- }
- else
- {
- /* Octal or hexadecimal representation. */
- fail_if (xmalloc(rc, 2, char32_t));
- rc[0] = (char32_t)numbuf, rc[1] = -1;
- }
-
-
- done:
- *escape = 0;
- *end = raw;
- return rc;
- fail:
- saved_errno = errno;
- free(rc);
- return errno = saved_errno, NULL;
+#define R(LOWER, UPPER) ((LOWER) <= c && c <= (UPPER))
+#define CR(COND, LOWER, UPPER) (*escape == (COND) && R(LOWER, UPPER))
+#define VARIABLE (int)(raw - raw_) - (c == '.'), raw_
+#define RETURN_ERROR(...)\
+ do {\
+ NEW_ERROR(__VA_ARGS__);\
+ error->start = lineoff;\
+ error->end = lineoff + (size_t)(raw - raw_);\
+ tree->processed = PROCESS_LEVEL;\
+ *escape = 0;\
+ if (rc)\
+ goto done;\
+ fail_if (xmalloc(rc, 1, char32_t));\
+ *rc = -1;\
+ goto done;\
+ } while (0)
+
+ const char* restrict raw_ = raw++;
+ char c = *raw++;
+ uintmax_t numbuf = 0;
+ char32_t* rc = NULL;
+ mds_kbdc_tree_t* value;
+ int have = 0, saved_errno;
+
+
+ /* Get escape type. */
+ if (c == '0')
+ /* Octal representation. */
+ *escape = 8, have = 1;
+ else if (c == 'u')
+ /* Hexadecimal representation. */
+ *escape = 16;
+ else if (R('1', '9'))
+ /* Variable dereference. */
+ *escape = 10, have = 1, numbuf = (uintmax_t)(c - '0');
+ else if (c == '_' || R('a', 'z') || R('A', 'Z'))
+ /* Function call. */
+ *escape = 100;
+ else
+ RETURN_ERROR(tree, ERROR, "invalid escape");
+
+
+ /* Read escape. */
+ if (*escape == 100) {
+ /* Function call. */
+ fail_if (rc = parse_function_call(tree, raw_, lineoff, escape, end), rc == NULL);
+ return rc;
+ }
+ /* Octal or hexadecimal representation, or variable dereference. */
+ for (; (c = *raw); have = 1, raw++) {
+ if (CR( 8, '0', '7')) numbuf = 8 * numbuf + (c & 15);
+ else if (CR(16, '0', '9')) numbuf = 16 * numbuf + (c & 15);
+ else if (CR(16, 'a', 'f')) numbuf = 16 * numbuf + (c & 15) + 9;
+ else if (CR(16, 'A', 'F')) numbuf = 16 * numbuf + (c & 15) + 9;
+ else if (CR(10, '0', '9')) numbuf = 10 * numbuf + (c & 15);
+ else break;
+ }
+ if (c == '.')
+ raw++;
+ if (have == 0)
+ RETURN_ERROR(tree, ERROR, "invalid escape");
+
+
+ /* Evaluate escape. */
+ if (*escape == 10) {
+ /* Variable dereference. */
+ if (!(value = variables_get((size_t)numbuf)))
+ RETURN_ERROR(tree, ERROR, "variable ‘%.*s’ is not defined", VARIABLE);
+ if (value->type == C(ARRAY))
+ RETURN_ERROR(tree, ERROR, "variable ‘%.*s’ is an array", VARIABLE);
+ if (value->type != C(COMPILED_STRING))
+ NEW_ERROR(tree, INTERNAL_ERROR, "variable ‘%.*s’ is of impossible type", VARIABLE);
+ fail_if (!(rc = string_dup(value->compiled_string.string)));
+ } else {
+ /* Octal or hexadecimal representation. */
+ fail_if (xmalloc(rc, 2, char32_t));
+ rc[0] = (char32_t)numbuf, rc[1] = -1;
+ }
+
+
+done:
+ *escape = 0;
+ *end = raw;
+ return rc;
+fail:
+ saved_errno = errno;
+ free(rc);
+ return errno = saved_errno, NULL;
#undef RETURN_ERROR
#undef VARIABLE
#undef CR
@@ -752,127 +734,114 @@ static char32_t* parse_escape(mds_kbdc_tree_t* restrict tree, const char* restri
* @param lineoff The offset on the line where the string beings
* @return The string as pure text, `NULL` on error
*/
-static char32_t* parse_quoted_string(mds_kbdc_tree_t* restrict tree, const char* restrict raw, size_t lineoff)
+static char32_t *
+parse_quoted_string(mds_kbdc_tree_t *restrict tree, const char *restrict raw, size_t lineoff)
{
-#define GROW_BUF \
- if (buf_ptr == buf_size) \
- fail_if (xxrealloc(old_buf, buf, buf_size += 16, char))
-#define COPY \
- n = string_length(subrc); \
- fail_if (xxrealloc(old_rc, rc, rc_ptr + n, char32_t)); \
- memcpy(rc + rc_ptr, subrc, n * sizeof(char32_t)), rc_ptr += n; \
- free(subrc), subrc = NULL
-#define STORE \
- if (buf_ptr) \
- do \
- { \
- GROW_BUF; \
- buf[buf_ptr] = '\0', buf_ptr = 0; \
- fail_if (subrc = string_decode(buf), subrc == NULL); \
- COPY; \
- } \
- while (0)
-#define CHAR_ERROR(...) \
- do \
- { \
- NEW_ERROR(__VA_ARGS__); \
- error->end = lineoff + (size_t)(raw - raw_); \
- error->start = error->end - 1; \
- } \
- while (0)
-
- const char* restrict raw_ = raw;
- char32_t* restrict subrc = NULL;
- char32_t* restrict rc = NULL;
- char32_t* restrict old_rc = NULL;
- char* restrict buf = NULL;
- char* restrict old_buf = NULL;
- size_t rc_ptr = 0, n;
- size_t buf_ptr = 0, buf_size = 0;
- size_t escoff = 0;
- int quote = 0, escape = 0;
- char c;
- int saved_errno;
-
- /* Parse the string. */
- while ((c = *raw++))
- if (escape && quote && strchr("()[]{}<>\"\\,", c))
- {
- /* Buffer UTF-8 text for convertion to UTF-32. */
- GROW_BUF;
- buf[buf_ptr++] = c;
- escape = 0;
- }
- else if (escape)
- {
- /* Parse escape. */
- raw -= 2, escoff = lineoff + (size_t)(raw - raw_);
- subrc = parse_escape(tree, raw, escoff, &escape, &raw);
- fail_if (subrc == NULL);
- COPY;
- }
- else if (c == '"')
- {
- /* Close or open quote, of it got closed, convert the buffered UTF-8 text to UTF-32. */
- if (quote ^= 1) continue;
- if ((quote == 1) && (raw != raw_ + 1))
- CHAR_ERROR(tree, WARNING, "strings should either be unquoted or unclosed in one large quoted");
- STORE;
- }
- else if (c == '\\')
- {
- /* Convert the buffered UTF-8 text to UTF-32, and start an escape. */
- STORE;
- escape = 1;
- }
- else if ((quote == 0) && (tree->processed != PROCESS_LEVEL))
- {
- /* Only escapes may be used without quotes, if the string contains quotes. */
- if (*raw_ == '"')
- CHAR_ERROR(tree, ERROR, "only escapes may be outside quotes in quoted strings");
- else
- CHAR_ERROR(tree, ERROR, "mixing numericals and escapes is not allowed");
- tree->processed = PROCESS_LEVEL;
- }
- else
- {
- /* Buffer UTF-8 text for convertion to UTF-32. */
- GROW_BUF;
- buf[buf_ptr++] = c;
- }
-
- /* Check that no escape is incomplete. */
- if (escape && (tree->processed != PROCESS_LEVEL))
- {
- NEW_ERROR(tree, ERROR, "incomplete escape");
- error->start = escoff;
- error->end = lineoff + strlen(raw_);
- tree->processed = PROCESS_LEVEL;
- }
-
- /* Check that the quote is complete. */
- if (quote && (tree->processed != PROCESS_LEVEL))
- {
- NEW_ERROR(tree, ERROR, "quote is not closed");
- error->start = lineoff;
- error->end = lineoff + strlen(raw_);
- tree->processed = PROCESS_LEVEL;
- }
-
- /* Shrink or grow to string to its minimal size, and -1-terminate it. */
- fail_if (xxrealloc(old_rc, rc, rc_ptr + 1, char32_t));
- rc[rc_ptr] = -1;
-
- free(buf);
- return rc;
- fail:
- saved_errno = errno;
- free(subrc);
- free(old_rc);
- free(old_buf);
- free(rc);
- free(buf);
- return errno = saved_errno, NULL;
+#define GROW_BUF\
+ if (buf_ptr == buf_size)\
+ fail_if (xxrealloc(old_buf, buf, buf_size += 16, char))
+#define COPY\
+ n = string_length(subrc);\
+ fail_if (xxrealloc(old_rc, rc, rc_ptr + n, char32_t));\
+ memcpy(rc + rc_ptr, subrc, n * sizeof(char32_t)), rc_ptr += n;\
+ free(subrc), subrc = NULL
+#define STORE\
+ do {\
+ if (buf_ptr) {\
+ GROW_BUF;\
+ buf[buf_ptr] = '\0', buf_ptr = 0;\
+ fail_if (!(subrc = string_decode(buf)));\
+ COPY;\
+ }\
+ } while (0)
+#define CHAR_ERROR(...)\
+ do {\
+ NEW_ERROR(__VA_ARGS__);\
+ error->end = lineoff + (size_t)(raw - raw_);\
+ error->start = error->end - 1;\
+ } while (0)
+
+ const char *restrict raw_ = raw;
+ char32_t *restrict subrc = NULL;
+ char32_t *restrict rc = NULL;
+ char32_t *restrict old_rc = NULL;
+ char *restrict buf = NULL;
+ char *restrict old_buf = NULL;
+ size_t rc_ptr = 0, n;
+ size_t buf_ptr = 0, buf_size = 0;
+ size_t escoff = 0;
+ int quote = 0, escape = 0;
+ char c;
+ int saved_errno;
+
+ /* Parse the string. */
+ while ((c = *raw++)) {
+ if (escape && quote && strchr("()[]{}<>\"\\,", c)) {
+ /* Buffer UTF-8 text for convertion to UTF-32. */
+ GROW_BUF;
+ buf[buf_ptr++] = c;
+ escape = 0;
+ } else if (escape) {
+ /* Parse escape. */
+ raw -= 2, escoff = lineoff + (size_t)(raw - raw_);
+ subrc = parse_escape(tree, raw, escoff, &escape, &raw);
+ fail_if (!subrc);
+ COPY;
+ } else if (c == '"') {
+ /* Close or open quote, of it got closed, convert the buffered UTF-8 text to UTF-32. */
+ if ((quote ^= 1))
+ continue;
+ if (quote == 1 && raw != raw_ + 1)
+ CHAR_ERROR(tree, WARNING, "strings should either be unquoted or unclosed in one large quoted");
+ STORE;
+ } else if (c == '\\') {
+ /* Convert the buffered UTF-8 text to UTF-32, and start an escape. */
+ STORE;
+ escape = 1;
+ } else if (!quote && tree->processed != PROCESS_LEVEL) {
+ /* Only escapes may be used without quotes, if the string contains quotes. */
+ if (*raw_ == '"')
+ CHAR_ERROR(tree, ERROR, "only escapes may be outside quotes in quoted strings");
+ else
+ CHAR_ERROR(tree, ERROR, "mixing numericals and escapes is not allowed");
+ tree->processed = PROCESS_LEVEL;
+ } else {
+ /* Buffer UTF-8 text for convertion to UTF-32. */
+ GROW_BUF;
+ buf[buf_ptr++] = c;
+ }
+ }
+
+ /* Check that no escape is incomplete. */
+ if (escape && tree->processed != PROCESS_LEVEL) {
+ NEW_ERROR(tree, ERROR, "incomplete escape");
+ error->start = escoff;
+ error->end = lineoff + strlen(raw_);
+ tree->processed = PROCESS_LEVEL;
+ }
+
+ /* Check that the quote is complete. */
+ if (quote && tree->processed != PROCESS_LEVEL) {
+ NEW_ERROR(tree, ERROR, "quote is not closed");
+ error->start = lineoff;
+ error->end = lineoff + strlen(raw_);
+ tree->processed = PROCESS_LEVEL;
+ }
+
+ /* Shrink or grow to string to its minimal size, and -1-terminate it. */
+ fail_if (xxrealloc(old_rc, rc, rc_ptr + 1, char32_t));
+ rc[rc_ptr] = -1;
+
+ free(buf);
+ return rc;
+fail:
+ saved_errno = errno;
+ free(subrc);
+ free(old_rc);
+ free(old_buf);
+ free(rc);
+ free(buf);
+ return errno = saved_errno, NULL;
#undef CHAR_ERROR
#undef STORE
#undef COPY
@@ -888,37 +857,36 @@ static char32_t* parse_quoted_string(mds_kbdc_tree_t* restrict tree, const char*
* @param lineoff The offset on the line where the string beings
* @return The string as pure text, `NULL` on error
*/
-static char32_t* parse_unquoted_string(mds_kbdc_tree_t* restrict tree, const char* restrict raw, size_t lineoff)
+static char32_t *
+parse_unquoted_string(mds_kbdc_tree_t *restrict tree, const char *restrict raw, size_t lineoff)
{
-#define R(LOWER, UPPER) (((LOWER) <= c) && (c <= (UPPER)))
-#define CHAR_ERROR(...) \
- do \
- { \
- NEW_ERROR(__VA_ARGS__); \
- error->end = lineoff + (size_t)(raw - raw_); \
- error->start = error->end - 1; \
- tree->processed = PROCESS_LEVEL; \
- goto done; \
- } \
- while (0)
-
- const char* restrict raw_ = raw;
- char32_t* rc;
- char32_t buf = 0;
- char c;
-
- while ((c = *raw++))
- if (R('0', '9')) buf = 10 * buf + (c & 15);
- else if (c == '\\') CHAR_ERROR(tree, ERROR, "mixing numericals and escapes is not allowed");
- else if (c == '"') CHAR_ERROR(tree, ERROR, "mixing numericals and quotes is not allowed");
- else CHAR_ERROR(tree, ERROR, "stray ‘%c’", c); /* XXX support multibyte */
-
- done:
- fail_if (xmalloc(rc, 2, char32_t));
- return rc[0] = buf, rc[1] = -1, rc;
+#define R(LOWER, UPPER) ((LOWER) <= c && c <= (UPPER))
+#define CHAR_ERROR(...)\
+ do {\
+ NEW_ERROR(__VA_ARGS__);\
+ error->end = lineoff + (size_t)(raw - raw_);\
+ error->start = error->end - 1;\
+ tree->processed = PROCESS_LEVEL;\
+ goto done;\
+ } while (0)
+
+ const char *restrict raw_ = raw;
+ char32_t *rc, buf = 0;
+ char c;
+
+ while ((c = *raw++)) {
+ if (R('0', '9')) buf = 10 * buf + (c & 15);
+ else if (c == '\\') CHAR_ERROR(tree, ERROR, "mixing numericals and escapes is not allowed");
+ else if (c == '"') CHAR_ERROR(tree, ERROR, "mixing numericals and quotes is not allowed");
+ else CHAR_ERROR(tree, ERROR, "stray ‘%c’", c); /* XXX support multibyte */
+ }
+
+done:
+ fail_if (xmalloc(rc, 2, char32_t));
+ return rc[0] = buf, rc[1] = -1, rc;
- fail:
- return NULL;
+fail:
+ return NULL;
#undef CHAR_ERROR
#undef R
}
@@ -932,15 +900,16 @@ static char32_t* parse_unquoted_string(mds_kbdc_tree_t* restrict tree, const cha
* @param lineoff The offset on the line where the string beings
* @return The string as pure text, `NULL` on error
*/
-static char32_t* parse_string(mds_kbdc_tree_t* restrict tree, const char* restrict raw, size_t lineoff)
+static char32_t *
+parse_string(mds_kbdc_tree_t *restrict tree, const char *restrict raw, size_t lineoff)
{
- mds_kbdc_tree_t* old_last_value_statement = last_value_statement;
- char32_t* rc = (strchr("\"\\", *raw) ? parse_quoted_string : parse_unquoted_string)(tree, raw, lineoff);
- last_value_statement = old_last_value_statement;
- fail_if (rc == NULL);
- return rc;
- fail:
- return NULL;
+ mds_kbdc_tree_t *old_last_value_statement = last_value_statement;
+ char32_t *rc = (strchr("\"\\", *raw) ? parse_quoted_string : parse_unquoted_string)(tree, raw, lineoff);
+ last_value_statement = old_last_value_statement;
+ fail_if (!rc);
+ return rc;
+fail:
+ return NULL;
}
@@ -952,120 +921,108 @@ static char32_t* parse_string(mds_kbdc_tree_t* restrict tree, const char* restri
* @param lineoff The offset on the line where the string beings
* @return The string as pure text, `NULL` on error
*/
-static char32_t* parse_keys(mds_kbdc_tree_t* restrict tree, const char* restrict raw, size_t lineoff)
+static char32_t *
+parse_keys(mds_kbdc_tree_t *restrict tree, const char *restrict raw, size_t lineoff)
{
-#define GROW_BUF \
- if (buf_ptr == buf_size) \
- fail_if (xxrealloc(old_buf, buf, buf_size += 16, char))
-#define COPY \
- n = string_length(subrc); \
- fail_if (xxrealloc(old_rc, rc, rc_ptr + n, char32_t)); \
- memcpy(rc + rc_ptr, subrc, n * sizeof(char32_t)), rc_ptr += n; \
- free(subrc), subrc = NULL
-#define STORE \
- if (buf_ptr) \
- do \
- { \
- GROW_BUF; \
- buf[buf_ptr] = '\0', buf_ptr = 0; \
- fail_if (subrc = string_decode(buf), subrc == NULL); \
- COPY; \
- } \
- while (0)
-#define SPECIAL(VAL) \
- STORE; \
- fail_if (xxrealloc(old_rc, rc, rc_ptr + 1, char32_t)); \
- rc[rc_ptr++] = -(VAL + 1)
-
- mds_kbdc_tree_t* old_last_value_statement = last_value_statement;
- const char* restrict raw_ = raw++;
- char32_t* restrict subrc = NULL;
- char32_t* restrict rc = NULL;
- char32_t* restrict old_rc = NULL;
- char* restrict buf = NULL;
- char* restrict old_buf = NULL;
- size_t rc_ptr = 0, n;
- size_t buf_ptr = 0, buf_size = 0;
- size_t escoff = 0;
- int escape = 0, quote = 0;
- char c;
- int saved_errno;
-
- /* Parse the string. */
- while (c = *raw++, c && *raw)
- if (escape && strchr("()[]{}<>\"\\,", c))
- {
- /* Buffer UTF-8 text for convertion to UTF-32. */
- GROW_BUF;
- buf[buf_ptr++] = c;
- escape = 0;
- }
- else if (escape)
- {
- /* Parse escape. */
- raw -= 2, escoff = lineoff + (size_t)(raw - raw_);
- subrc = parse_escape(tree, raw, escoff, &escape, &raw);
- fail_if (subrc == NULL);
- COPY;
- }
- else if (c == '\\')
- {
- /* Convert the buffered UTF-8 text to UTF-32, and start an escape. */
+#define GROW_BUF\
+ if (buf_ptr == buf_size)\
+ fail_if (xxrealloc(old_buf, buf, buf_size += 16, char))
+#define COPY\
+ n = string_length(subrc);\
+ fail_if (xxrealloc(old_rc, rc, rc_ptr + n, char32_t));\
+ memcpy(rc + rc_ptr, subrc, n * sizeof(char32_t)), rc_ptr += n;\
+ free(subrc), subrc = NULL
+#define STORE\
+ do {\
+ if (buf_ptr) {\
+ GROW_BUF;\
+ buf[buf_ptr] = '\0', buf_ptr = 0;\
+ fail_if (!(subrc = string_decode(buf)));\
+ COPY;\
+ }\
+ } while (0)
+#define SPECIAL(VAL)\
+ STORE;\
+ fail_if (xxrealloc(old_rc, rc, rc_ptr + 1, char32_t));\
+ rc[rc_ptr++] = -(VAL + 1)
+
+ mds_kbdc_tree_t *old_last_value_statement = last_value_statement;
+ const char *restrict raw_ = raw++;
+ char32_t *restrict subrc = NULL;
+ char32_t *restrict rc = NULL;
+ char32_t *restrict old_rc = NULL;
+ char *restrict buf = NULL;
+ char *restrict old_buf = NULL;
+ size_t rc_ptr = 0, n;
+ size_t buf_ptr = 0, buf_size = 0;
+ size_t escoff = 0;
+ int escape = 0, quote = 0;
+ char c;
+ int saved_errno;
+
+ /* Parse the string. */
+ while (c = *raw++, c && *raw) {
+ if (escape && strchr("()[]{}<>\"\\,", c)) {
+ /* Buffer UTF-8 text for convertion to UTF-32. */
+ GROW_BUF;
+ buf[buf_ptr++] = c;
+ escape = 0;
+ } else if (escape) {
+ /* Parse escape. */
+ raw -= 2, escoff = lineoff + (size_t)(raw - raw_);
+ subrc = parse_escape(tree, raw, escoff, &escape, &raw);
+ fail_if (!subrc);
+ COPY;
+ } else if (c == '\\') {
+ /* Convert the buffered UTF-8 text to UTF-32, and start an escape. */
+ STORE;
+ escape = 1;
+ } else if (c == ',' && !quote) {
+ /* Sequence in key-combination. */
+ SPECIAL(1);
+ } else if (c == '"') {
+ /* String in key-combination. */
+ quote ^= 1;
+ SPECIAL(2);
+ } else {
+ /* Buffer UTF-8 text for convertion to UTF-32. */
+ GROW_BUF;
+ buf[buf_ptr++] = c;
+ }
+ }
STORE;
- escape = 1;
- }
- else if ((c == ',') && !quote)
- {
- /* Sequence in key-combination. */
- SPECIAL(1);
- }
- else if (c == '"')
- {
- /* String in key-combination. */
- quote ^= 1;
- SPECIAL(2);
- }
- else
- {
- /* Buffer UTF-8 text for convertion to UTF-32. */
- GROW_BUF;
- buf[buf_ptr++] = c;
- }
- STORE;
-
- /* Check that no escape is incomplete. */
- if (escape && (tree->processed != PROCESS_LEVEL))
- {
- NEW_ERROR(tree, ERROR, "incomplete escape");
- error->start = lineoff + (size_t)(strrchr(raw_, '\\') - raw_);
- error->end = lineoff + strlen(raw_);
- tree->processed = PROCESS_LEVEL;
- }
-
- /* Check that key-combination is complete. */
- if ((c != '>') && (tree->processed != PROCESS_LEVEL))
- {
- NEW_ERROR(tree, ERROR, "key-combination is not closed");
- error->start = lineoff;
- error->end = lineoff + strlen(raw_);
- tree->processed = PROCESS_LEVEL;
- }
-
- /* Shrink or grow to string to its minimal size, and -1-terminate it. */
- fail_if (xxrealloc(old_rc, rc, rc_ptr + 1, char32_t));
- rc[rc_ptr] = -1;
-
- free(buf);
- return last_value_statement = old_last_value_statement, rc;
- fail:
- saved_errno = errno;
- free(subrc);
- free(old_rc);
- free(old_buf);
- free(rc);
- free(buf);
- errno = saved_errno;
- return last_value_statement = old_last_value_statement, NULL;
+
+ /* Check that no escape is incomplete. */
+ if (escape && tree->processed != PROCESS_LEVEL) {
+ NEW_ERROR(tree, ERROR, "incomplete escape");
+ error->start = lineoff + (size_t)(strrchr(raw_, '\\') - raw_);
+ error->end = lineoff + strlen(raw_);
+ tree->processed = PROCESS_LEVEL;
+ }
+
+ /* Check that key-combination is complete. */
+ if (c != '>' && tree->processed != PROCESS_LEVEL) {
+ NEW_ERROR(tree, ERROR, "key-combination is not closed");
+ error->start = lineoff;
+ error->end = lineoff + strlen(raw_);
+ tree->processed = PROCESS_LEVEL;
+ }
+
+ /* Shrink or grow to string to its minimal size, and -1-terminate it. */
+ fail_if (xxrealloc(old_rc, rc, rc_ptr + 1, char32_t));
+ rc[rc_ptr] = -1;
+
+ free(buf);
+ return last_value_statement = old_last_value_statement, rc;
+fail:
+ saved_errno = errno;
+ free(subrc);
+ free(old_rc);
+ free(old_buf);
+ free(rc);
+ free(buf);
+ errno = saved_errno;
+ return last_value_statement = old_last_value_statement, NULL;
#undef SPECIAL
#undef STORE
#undef COPY
@@ -1081,54 +1038,55 @@ static char32_t* parse_keys(mds_kbdc_tree_t* restrict tree, const char* restrict
* @param lineoff The offset on the line where the variable string begins
* @return The index of the variable, zero on error
*/
-static size_t parse_variable(mds_kbdc_tree_t* restrict tree, const char* restrict raw, size_t lineoff)
+static size_t
+parse_variable(mds_kbdc_tree_t *restrict tree, const char *restrict raw, size_t lineoff)
{
- size_t var, n;
- const char* restrict raw_ = raw;
- char* restrict dotless;
-
- /* The variable must begin with \. */
- if (*raw++ != '\\') goto bad;
- /* Zero is not a valid varible, nor may there be leading zeroes or be empty. */
- if (*raw == '0') goto bad;
- if (*raw == '.') goto bad;
- if (*raw == '\0') goto bad;
- for (; *raw; raw++)
- /* Check that the variable consists only of digits. */
- if (('0' <= *raw) && (*raw <= '9'));
- /* However, it may end with a dot. */
- else if ((raw[0] == '.') && (raw[1] == '\0'))
- break;
- else
- goto bad;
-
- /* Parse the variable string and check that it did not overflow. */
- n = (size_t)(raw - raw_);
- dotless = alloca((n + 1) * sizeof(char));
- memcpy(dotless, raw_, n * sizeof(char)), dotless[n] = '\0';
- var = atoz(dotless + 1);
- if (strlen(dotless + 1) != (size_t)snprintf(NULL, 0, "%zu", var))
- fail_if ((errno = ERANGE));
- if (var == 0)
- {
- NEW_ERROR(tree, INTERNAL_ERROR,
- "parsed a variable string to be 0, which should not be possible");
- error->start = lineoff;
- error->end = lineoff + strlen(raw_);
- tree->processed = PROCESS_LEVEL;
- return 1;
- }
- return var;
- fail:
- return 0;
-
- bad:
- /* Report an error but return a variable index if the variable-string is invalid. */
- NEW_ERROR(tree, ERROR, "not a variable");
- error->start = lineoff;
- error->end = lineoff + strlen(raw_);
- tree->processed = PROCESS_LEVEL;
- return 1;
+ size_t var, n;
+ const char *restrict raw_ = raw;
+ char *restrict dotless;
+
+ /* The variable must begin with \. */
+ if (*raw++ != '\\') goto bad;
+ /* Zero is not a valid varible, nor may there be leading zeroes or be empty. */
+ if (*raw == '0') goto bad;
+ if (*raw == '.') goto bad;
+ if (*raw == '\0') goto bad;
+ for (; *raw; raw++) {
+ /* Check that the variable consists only of digits. */
+ if ('0' <= *raw && *raw <= '9')
+ /* However, it may end with a dot. */;
+ else if (raw[0] == '.' && raw[1] == '\0')
+ break;
+ else
+ goto bad;
+ }
+
+ /* Parse the variable string and check that it did not overflow. */
+ n = (size_t)(raw - raw_);
+ dotless = alloca((n + 1) * sizeof(char));
+ memcpy(dotless, raw_, n * sizeof(char)), dotless[n] = '\0';
+ var = atoz(dotless + 1);
+ if (strlen(dotless + 1) != (size_t)snprintf(NULL, 0, "%zu", var))
+ fail_if ((errno = ERANGE));
+ if (!var) {
+ NEW_ERROR(tree, INTERNAL_ERROR,
+ "parsed a variable string to be 0, which should not be possible");
+ error->start = lineoff;
+ error->end = lineoff + strlen(raw_);
+ tree->processed = PROCESS_LEVEL;
+ return 1;
+ }
+ return var;
+fail:
+ return 0;
+
+bad:
+ /* Report an error but return a variable index if the variable-string is invalid. */
+ NEW_ERROR(tree, ERROR, "not a variable");
+ error->start = lineoff;
+ error->end = lineoff + strlen(raw_);
+ tree->processed = PROCESS_LEVEL;
+ return 1;
}
@@ -1142,63 +1100,65 @@ static size_t parse_variable(mds_kbdc_tree_t* restrict tree, const char* restric
* @param value Output parameter for the value to which the argument evaulates
* @return Zero on success, -1 on error
*/
-static int parse_function_argument(mds_kbdc_tree_t* restrict tree, const char* restrict raw, size_t lineoff,
- const char* restrict* restrict end, char32_t** restrict value)
+static int
+parse_function_argument(mds_kbdc_tree_t *restrict tree, const char *restrict raw, size_t lineoff,
+ const char *restrict *restrict end, char32_t **restrict value)
{
- size_t size = strlen(raw), ptr = 0, call_end = 0;
- int escape = 0, quote = 0;
- char* raw_argument = NULL;
- int saved_errno;
-
- /* Find the span of the argument. */
- while (ptr < size)
- {
- char c = raw[ptr++];
-
- /* Escapes may be longer than one character,
- but only the first can affect the parsing. */
- if (escape) escape = 0;
- /* Nested function and nested quotes can appear. */
- else if (ptr <= call_end) ;
- /* Quotes end with the same symbols as they start with,
- and quotes automatically escape brackets. */
- /* \ can either start a functon call or an escape. */
- else if (c == '\\')
- {
- /* It may not be an escape, but registering it
- as an escape cannot harm us since we only
- skip the first character, and a function call
- cannot be that short. */
- escape = 1;
- /* Nested quotes can appear at function calls. */
- call_end = get_end_of_call(raw, ptr, size);
- }
- /* " is the quote symbol. */
- else if (quote) quote = (c != '"');
- else if (c == '"') quote = 1;
- /* End of argument? */
- else if (strchr(" )", c))
- {
- ptr--;
- break;
+ size_t size = strlen(raw), ptr = 0, call_end = 0;
+ int escape = 0, quote = 0, saved_errno;
+ char *raw_argument = NULL;
+ char c;
+
+ /* Find the span of the argument. */
+ while (ptr < size) {
+ c = raw[ptr++];
+
+ /* Escapes may be longer than one character,
+ but only the first can affect the parsing. */
+ if (escape)
+ escape = 0;
+ /* Nested function and nested quotes can appear. */
+ else if (ptr <= call_end)
+ ;
+ /* Quotes end with the same symbols as they start with,
+ and quotes automatically escape brackets. */
+ /* \ can either start a functon call or an escape. */
+ else if (c == '\\') {
+ /* It may not be an escape, but registering it
+ as an escape cannot harm us since we only
+ skip the first character, and a function call
+ cannot be that short. */
+ escape = 1;
+ /* Nested quotes can appear at function calls. */
+ call_end = get_end_of_call(raw, ptr, size);
+ }
+ /* " is the quote symbol. */
+ else if (quote)
+ quote = (c != '"');
+ else if (c == '"')
+ quote = 1;
+ /* End of argument? */
+ else if (strchr(" )", c)) {
+ ptr--;
+ break;
+ }
}
- }
- *end = raw + ptr;
-
- /* Copy the argument so that we have a NUL-terminates string. */
- fail_if (xmalloc(raw_argument, ptr + 1, char));
- memcpy(raw_argument, raw, ptr * sizeof(char));
- raw_argument[ptr] = '\0';
-
- /* Evaluate argument. */
- *value = parse_string(tree, raw_argument, lineoff);
- fail_if (*value == NULL);
-
- free(raw_argument);
- return 0;
- FAIL_BEGIN;
- free(raw_argument);
- FAIL_END;
+ *end = raw + ptr;
+
+ /* Copy the argument so that we have a NUL-terminates string. */
+ fail_if (xmalloc(raw_argument, ptr + 1, char));
+ memcpy(raw_argument, raw, ptr * sizeof(char));
+ raw_argument[ptr] = '\0';
+
+ /* Evaluate argument. */
+ *value = parse_string(tree, raw_argument, lineoff);
+ fail_if (!*value);
+
+ free(raw_argument);
+ return 0;
+ FAIL_BEGIN;
+ free(raw_argument);
+ FAIL_END;
}
@@ -1209,13 +1169,13 @@ static int parse_function_argument(mds_kbdc_tree_t* restrict tree, const char* r
* @param macro_include_stack The include-stack for the macro
* @return Zero on success, -1 on error
*/
-static int set_macro(mds_kbdc_tree_macro_t* restrict macro,
- mds_kbdc_include_stack_t* macro_include_stack)
+static int
+set_macro(mds_kbdc_tree_macro_t *restrict macro, mds_kbdc_include_stack_t *macro_include_stack)
{
- fail_if (callables_set(macro->name, 0, (mds_kbdc_tree_t*)macro, macro_include_stack));
- return 0;
- fail:
- return -1;
+ fail_if (callables_set(macro->name, 0, (mds_kbdc_tree_t *)macro, macro_include_stack));
+ return 0;
+fail:
+ return -1;
}
@@ -1226,10 +1186,11 @@ static int set_macro(mds_kbdc_tree_macro_t* restrict macro,
* @param macro Output parameter for the macro, `NULL` if not found
* @param macro_include_stack Output parameter for the include-stack for the macro
*/
-static void get_macro_lax(const char* restrict macro_name, mds_kbdc_tree_macro_t** restrict macro,
- mds_kbdc_include_stack_t** restrict macro_include_stack)
+static void
+get_macro_lax(const char *restrict macro_name, mds_kbdc_tree_macro_t **restrict macro,
+ mds_kbdc_include_stack_t **restrict macro_include_stack)
{
- callables_get(macro_name, 0, (mds_kbdc_tree_t**)macro, macro_include_stack);
+ callables_get(macro_name, 0, (mds_kbdc_tree_t **)macro, macro_include_stack);
}
@@ -1246,29 +1207,29 @@ static void get_macro_lax(const char* restrict macro_name, mds_kbdc_tree_macro_t
* @param macro_include_stack Output parameter for the include-stack for the macro
* @return Zero on success, -1 on error
*/
-static int get_macro(mds_kbdc_tree_macro_call_t* restrict macro_call,
- mds_kbdc_tree_macro_t** restrict macro,
- mds_kbdc_include_stack_t** restrict macro_include_stack)
+static int
+get_macro(mds_kbdc_tree_macro_call_t *restrict macro_call,
+ mds_kbdc_tree_macro_t **restrict macro,
+ mds_kbdc_include_stack_t **restrict macro_include_stack)
{
- char* code = result->source_code->lines[macro_call->loc_line];
- char* end = code + strlen(code) - 1;
-
- get_macro_lax(macro_call->name, macro, macro_include_stack);
- if (*macro == NULL)
- {
- NEW_ERROR(macro_call, ERROR, "macro ‘%s’ has not been defined yet", macro_call->name);
- while (*end == ' ')
- end--;
- error->end = (size_t)(++end - code);
- macro_call->processed = PROCESS_LEVEL;
- return 0;
- }
- if ((*macro)->processed == PROCESS_LEVEL)
- *macro = NULL;
-
- return 0;
- fail:
- return -1;
+ char *code = result->source_code->lines[macro_call->loc_line];
+ char *end = code + strlen(code) - 1;
+
+ get_macro_lax(macro_call->name, macro, macro_include_stack);
+ if (!*macro) {
+ NEW_ERROR(macro_call, ERROR, "macro ‘%s’ has not been defined yet", macro_call->name);
+ while (*end == ' ')
+ end--;
+ error->end = (size_t)(++end - code);
+ macro_call->processed = PROCESS_LEVEL;
+ return 0;
+ }
+ if ((*macro)->processed == PROCESS_LEVEL)
+ *macro = NULL;
+
+ return 0;
+fail:
+ return -1;
}
@@ -1279,20 +1240,21 @@ static int get_macro(mds_kbdc_tree_macro_call_t* restrict macro_call,
* @param function_include_stack The include-stack for the function
* @return Zero on success, -1 on error
*/
-static int set_function(mds_kbdc_tree_function_t* restrict function,
- mds_kbdc_include_stack_t* function_include_stack)
+static int
+set_function(mds_kbdc_tree_function_t *restrict function,
+ mds_kbdc_include_stack_t *function_include_stack)
{
- char* suffixless = function->name;
- char* suffix_start = strchr(suffixless, '/');
- size_t arg_count = atoz(suffix_start + 1);
- int r;
-
- *suffix_start = '\0';
- r = callables_set(suffixless, arg_count, (mds_kbdc_tree_t*)function, function_include_stack);
- fail_if (*suffix_start = '/', r);
- return 0;
- fail:
- return -1;
+ char *suffixless = function->name;
+ char *suffix_start = strchr(suffixless, '/');
+ size_t arg_count = atoz(suffix_start + 1);
+ int r;
+
+ *suffix_start = '\0';
+ r = callables_set(suffixless, arg_count, (mds_kbdc_tree_t *)function, function_include_stack);
+ fail_if (*suffix_start = '/', r);
+ return 0;
+fail:
+ return -1;
}
@@ -1304,11 +1266,12 @@ static int set_function(mds_kbdc_tree_function_t* restrict function,
* @param function Output parameter for the function, `NULL` if not found
* @param function_include_stack Output parameter for the include-stack for the function
*/
-static void get_function_lax(const char* restrict function_name, size_t arg_count,
- mds_kbdc_tree_function_t** restrict function,
- mds_kbdc_include_stack_t** restrict function_include_stack)
+static void
+get_function_lax(const char *restrict function_name, size_t arg_count,
+ mds_kbdc_tree_function_t **restrict function,
+ mds_kbdc_include_stack_t **restrict function_include_stack)
{
- callables_get(function_name, arg_count, (mds_kbdc_tree_t**)function, function_include_stack);
+ callables_get(function_name, arg_count, (mds_kbdc_tree_t **)function, function_include_stack);
}
@@ -1318,21 +1281,23 @@ static void get_function_lax(const char* restrict function_name, size_t arg_coun
* @param value The value the function should return
* @return Zero on success, 1 if no function is currently being called
*/
-static int set_return_value(char32_t* restrict value)
+static int
+set_return_value(char32_t *restrict value)
{
- if (current_return_value == NULL)
- return free(value), 1;
- free(*current_return_value);
- *current_return_value = value;
- return 0;
+ if (!current_return_value)
+ return free(value), 1;
+ free(*current_return_value);
+ *current_return_value = value;
+ return 0;
}
-static int add_mapping(mds_kbdc_tree_map_t* restrict mapping, mds_kbdc_include_stack_t* restrict include_stack)
+static int
+add_mapping(mds_kbdc_tree_map_t *restrict mapping, mds_kbdc_include_stack_t *restrict include_stack)
{
- mds_kbdc_tree_free((mds_kbdc_tree_t*)mapping);
- mds_kbdc_include_stack_free(include_stack);
- return 0; /* TODO */
+ mds_kbdc_tree_free((mds_kbdc_tree_t *)mapping);
+ mds_kbdc_include_stack_free(include_stack);
+ return 0; /* TODO */
}
@@ -1346,23 +1311,24 @@ static int add_mapping(mds_kbdc_tree_map_t* restrict mapping, mds_kbdc_include_s
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_include(mds_kbdc_tree_include_t* restrict tree)
+static int
+compile_include(mds_kbdc_tree_include_t *restrict tree)
{
- void* data;
- int r;
- fail_if (mds_kbdc_include_stack_push(tree, &data));
- r = compile_subtree(tree->inner);
- mds_kbdc_include_stack_pop(data);
-
- /* For simplicity we set `last_value_statement` on includes,
- * so we are sure `last_value_statement` has the same
- * include-stack as its overriding statement. */
- last_value_statement = NULL;
-
- fail_if (r);
- return 0;
- fail:
- return -1;
+ void *data;
+ int r;
+ fail_if (mds_kbdc_include_stack_push(tree, &data));
+ r = compile_subtree(tree->inner);
+ mds_kbdc_include_stack_pop(data);
+
+ /* For simplicity we set `last_value_statement` on includes,
+ * so we are sure `last_value_statement` has the same
+ * include-stack as its overriding statement. */
+ last_value_statement = NULL;
+
+ fail_if (r);
+ return 0;
+fail:
+ return -1;
}
@@ -1372,39 +1338,39 @@ static int compile_include(mds_kbdc_tree_include_t* restrict tree)
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_language(mds_kbdc_tree_information_language_t* restrict tree)
+static int
+compile_language(mds_kbdc_tree_information_language_t *restrict tree)
{
- size_t lineoff;
- char* restrict code = result->source_code->real_lines[tree->loc_line];
- char32_t* restrict data = NULL;
- char** old = NULL;
- int saved_errno;
-
- /* Make sure the language-list fits another entry. */
- if (result->languages_ptr == result->languages_size)
- {
- result->languages_size = result->languages_size ? (result->languages_size << 1) : 1;
- fail_if (xxrealloc(old, result->languages, result->languages_size, char*));
- }
-
- /* Locate the first character in the language-string. */
- for (lineoff = tree->loc_end; code[lineoff] == ' '; lineoff++);
- /* Evaluate function calls, variable dereferences and escapes in the language-string. */
- fail_if (data = parse_string((mds_kbdc_tree_t*)tree, tree->data, lineoff), data == NULL);
- if (tree->processed == PROCESS_LEVEL)
- return free(data), 0;
- /* We want the string in UTF-8, not UTF-16. */
- fail_if (code = string_encode(data), code == NULL);
- free(data);
-
- /* Add the language to the language-list. */
- result->languages[result->languages_ptr++] = code;
-
- return 0;
- FAIL_BEGIN;
- free(old);
- free(data);
- FAIL_END;
+ size_t lineoff;
+ char *restrict code = result->source_code->real_lines[tree->loc_line];
+ char32_t *restrict data = NULL;
+ char **old = NULL;
+ int saved_errno;
+
+ /* Make sure the language-list fits another entry. */
+ if (result->languages_ptr == result->languages_size) {
+ result->languages_size = result->languages_size ? (result->languages_size << 1) : 1;
+ fail_if (xxrealloc(old, result->languages, result->languages_size, char*));
+ }
+
+ /* Locate the first character in the language-string. */
+ for (lineoff = tree->loc_end; code[lineoff] == ' '; lineoff++);
+ /* Evaluate function calls, variable dereferences and escapes in the language-string. */
+ fail_if (!(data = parse_string((mds_kbdc_tree_t*)tree, tree->data, lineoff)));
+ if (tree->processed == PROCESS_LEVEL)
+ return free(data), 0;
+ /* We want the string in UTF-8, not UTF-16. */
+ fail_if (!(code = string_encode(data)));
+ free(data);
+
+ /* Add the language to the language-list. */
+ result->languages[result->languages_ptr++] = code;
+
+ return 0;
+ FAIL_BEGIN;
+ free(old);
+ free(data);
+ FAIL_END;
}
@@ -1414,39 +1380,39 @@ static int compile_language(mds_kbdc_tree_information_language_t* restrict tree)
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_country(mds_kbdc_tree_information_country_t* restrict tree)
+static int
+compile_country(mds_kbdc_tree_information_country_t *restrict tree)
{
- size_t lineoff;
- char* restrict code = result->source_code->real_lines[tree->loc_line];
- char32_t* restrict data = NULL;
- char** old = NULL;
- int saved_errno;
-
- /* Make sure the country-list fits another entry. */
- if (result->countries_ptr == result->countries_size)
- {
- result->countries_size = result->countries_size ? (result->countries_size << 1) : 1;
- fail_if (xxrealloc(old, result->countries, result->countries_size, char*));
- }
-
- /* Locate the first character in the country-string. */
- for (lineoff = tree->loc_end; code[lineoff] == ' '; lineoff++);
- /* Evaluate function calls, variable dereferences and escapes in the country-string. */
- fail_if (data = parse_string((mds_kbdc_tree_t*)tree, tree->data, lineoff), data == NULL);
- if (tree->processed == PROCESS_LEVEL)
- return free(data), 0;
- /* We want the string in UTF-8, not UTF-16. */
- fail_if (code = string_encode(data), code == NULL);
- free(data);
-
- /* Add the country to the country-list. */
- result->countries[result->countries_ptr++] = code;
-
- return 0;
- FAIL_BEGIN;
- free(old);
- free(data);
- FAIL_END;
+ size_t lineoff;
+ char *restrict code = result->source_code->real_lines[tree->loc_line];
+ char32_t *restrict data = NULL;
+ char **old = NULL;
+ int saved_errno;
+
+ /* Make sure the country-list fits another entry. */
+ if (result->countries_ptr == result->countries_size) {
+ result->countries_size = result->countries_size ? (result->countries_size << 1) : 1;
+ fail_if (xxrealloc(old, result->countries, result->countries_size, char *));
+ }
+
+ /* Locate the first character in the country-string. */
+ for (lineoff = tree->loc_end; code[lineoff] == ' '; lineoff++);
+ /* Evaluate function calls, variable dereferences and escapes in the country-string. */
+ fail_if (!(data = parse_string((mds_kbdc_tree_t*)tree, tree->data, lineoff)));
+ if (tree->processed == PROCESS_LEVEL)
+ return free(data), 0;
+ /* We want the string in UTF-8, not UTF-16. */
+ fail_if (!(code = string_encode(data)));
+ free(data);
+
+ /* Add the country to the country-list. */
+ result->countries[result->countries_ptr++] = code;
+
+ return 0;
+ FAIL_BEGIN;
+ free(old);
+ free(data);
+ FAIL_END;
}
@@ -1456,39 +1422,39 @@ static int compile_country(mds_kbdc_tree_information_country_t* restrict tree)
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_variant(mds_kbdc_tree_information_variant_t* restrict tree)
+static int
+compile_variant(mds_kbdc_tree_information_variant_t *restrict tree)
{
- size_t lineoff;
- char* restrict code = result->source_code->real_lines[tree->loc_line];
- char32_t* restrict data = NULL;
- int saved_errno;
-
- /* Make sure the variant has not already been set. */
- if (result->variant)
- {
- if (multiple_variants == 0)
- NEW_ERROR(tree, ERROR, "only one ‘variant’ is allowed");
- multiple_variants = 1;
- return 0;
- }
-
- /* Locate the first character in the variant-string. */
- for (lineoff = tree->loc_end; code[lineoff] == ' '; lineoff++);
- /* Evaluate function calls, variable dereferences and escapes in the variant-string. */
- fail_if (data = parse_string((mds_kbdc_tree_t*)tree, tree->data, lineoff), data == NULL);
- if (tree->processed == PROCESS_LEVEL)
- return free(data), 0;
- /* We want the string in UTF-8, not UTF-16. */
- fail_if (code = string_encode(data), code == NULL);
- free(data);
-
- /* Store the variant. */
- result->variant = code;
-
- return 0;
- FAIL_BEGIN;
- free(data);
- FAIL_END;
+ size_t lineoff;
+ char *restrict code = result->source_code->real_lines[tree->loc_line];
+ char32_t *restrict data = NULL;
+ int saved_errno;
+
+ /* Make sure the variant has not already been set. */
+ if (result->variant) {
+ if (!multiple_variants)
+ NEW_ERROR(tree, ERROR, "only one ‘variant’ is allowed");
+ multiple_variants = 1;
+ return 0;
+ }
+
+ /* Locate the first character in the variant-string. */
+ for (lineoff = tree->loc_end; code[lineoff] == ' '; lineoff++);
+ /* Evaluate function calls, variable dereferences and escapes in the variant-string. */
+ fail_if (!(data = parse_string((mds_kbdc_tree_t*)tree, tree->data, lineoff)));
+ if (tree->processed == PROCESS_LEVEL)
+ return free(data), 0;
+ /* We want the string in UTF-8, not UTF-16. */
+ fail_if (!(code = string_encode(data)));
+ free(data);
+
+ /* Store the variant. */
+ result->variant = code;
+
+ return 0;
+ FAIL_BEGIN;
+ free(data);
+ FAIL_END;
}
@@ -1498,54 +1464,50 @@ static int compile_variant(mds_kbdc_tree_information_variant_t* restrict tree)
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_have(mds_kbdc_tree_assumption_have_t* restrict tree)
+static int
+compile_have(mds_kbdc_tree_assumption_have_t *restrict tree)
{
- mds_kbdc_tree_t* node = tree->data;
- char32_t* data = NULL;
- char32_t** old = NULL;
- size_t new_size = 0;
- int saved_errno;
-
- /* Make sure we can fit all assumption in the assumption list (part 1/2). */
- new_size = (node->type == C(STRING)) ? result->assumed_strings_size : result->assumed_keys_size;
- new_size = new_size ? (new_size << 1) : 1;
-
- if (node->type == C(STRING))
- {
- /* Evaluate function calls, variable dereferences and escapes in the string. */
- fail_if (data = parse_string(node, node->string.string, node->loc_start), data == NULL);
- if (node->processed == PROCESS_LEVEL)
- return free(data), 0;
- /* Make sure we can fit all strings in the assumption list (part 2/2). */
- if (result->assumed_strings_ptr == result->assumed_strings_size)
- {
- fail_if (xxrealloc(old, result->assumed_strings, new_size, char32_t*));
- result->assumed_strings_size = new_size;
+ mds_kbdc_tree_t *node = tree->data;
+ char32_t *data = NULL, **old = NULL;
+ size_t new_size = 0;
+ int saved_errno;
+
+ /* Make sure we can fit all assumption in the assumption list (part 1/2). */
+ new_size = (node->type == C(STRING)) ? result->assumed_strings_size : result->assumed_keys_size;
+ new_size = new_size ? (new_size << 1) : 1;
+
+ if (node->type == C(STRING)) {
+ /* Evaluate function calls, variable dereferences and escapes in the string. */
+ fail_if (!(data = parse_string(node, node->string.string, node->loc_start)));
+ if (node->processed == PROCESS_LEVEL)
+ return free(data), 0;
+ /* Make sure we can fit all strings in the assumption list (part 2/2). */
+ if (result->assumed_strings_ptr == result->assumed_strings_size)
+ {
+ fail_if (xxrealloc(old, result->assumed_strings, new_size, char32_t*));
+ result->assumed_strings_size = new_size;
+ }
+ /* Add the assumption to the list. */
+ result->assumed_strings[result->assumed_strings_ptr++] = data;
+ } else {
+ /* Evaluate function calls, variable dereferences and escapes in the key-combination. */
+ fail_if (!(data = parse_keys(node, node->keys.keys, node->loc_start)));
+ if (node->processed == PROCESS_LEVEL)
+ return free(data), 0;
+ /* Make sure we can fit all key-combinations in the assumption list (part 2/2). */
+ if (result->assumed_keys_ptr == result->assumed_keys_size) {
+ fail_if (xxrealloc(old, result->assumed_keys, new_size, char32_t*));
+ result->assumed_keys_size = new_size;
+ }
+ /* Add the assumption to the list. */
+ result->assumed_keys[result->assumed_keys_ptr++] = data;
}
- /* Add the assumption to the list. */
- result->assumed_strings[result->assumed_strings_ptr++] = data;
- }
- else
- {
- /* Evaluate function calls, variable dereferences and escapes in the key-combination. */
- fail_if (data = parse_keys(node, node->keys.keys, node->loc_start), data == NULL);
- if (node->processed == PROCESS_LEVEL)
- return free(data), 0;
- /* Make sure we can fit all key-combinations in the assumption list (part 2/2). */
- if (result->assumed_keys_ptr == result->assumed_keys_size)
- {
- fail_if (xxrealloc(old, result->assumed_keys, new_size, char32_t*));
- result->assumed_keys_size = new_size;
- }
- /* Add the assumption to the list. */
- result->assumed_keys[result->assumed_keys_ptr++] = data;
- }
-
- return 0;
- FAIL_BEGIN;
- free(old);
- free(data);
- FAIL_END;
+
+ return 0;
+ FAIL_BEGIN;
+ free(old);
+ free(data);
+ FAIL_END;
}
@@ -1555,47 +1517,46 @@ static int compile_have(mds_kbdc_tree_assumption_have_t* restrict tree)
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_have_chars(mds_kbdc_tree_assumption_have_chars_t* restrict tree)
+static int
+compile_have_chars(mds_kbdc_tree_assumption_have_chars_t *restrict tree)
{
- size_t lineoff;
- char* restrict code = result->source_code->real_lines[tree->loc_line];
- char32_t* restrict data = NULL;
- char32_t** old = NULL;
- char32_t* restrict character;
- size_t n;
- int saved_errno;
-
- /* Locate the first character in the list. */
- for (lineoff = tree->loc_end; code[lineoff] == ' '; lineoff++);
- /* Evaluate function calls, variable dereferences
- and escapes in the charcter list. */
- fail_if (data = parse_string((mds_kbdc_tree_t*)tree, tree->chars, lineoff), data == NULL);
- if (tree->processed == PROCESS_LEVEL)
- return free(data), 0;
-
- /* Make sure we can fit all characters in the assumption list. */
- for (n = 0; data[n] >= 0; n++);
- if (result->assumed_strings_ptr + n > result->assumed_strings_size)
- {
- result->assumed_strings_size += n;
- fail_if (xxrealloc(old, result->assumed_strings, result->assumed_strings_size, char32_t*));
- }
-
- /* Add all characters to the assumption list. */
- while (n--)
- {
- fail_if (xmalloc(character, 2, char32_t));
- character[0] = data[n];
- character[1] = -1;
- result->assumed_strings[result->assumed_strings_ptr++] = character;
- }
-
- free(data);
- return 0;
- FAIL_BEGIN;
- free(data);
- free(old);
- FAIL_END;
+ size_t lineoff;
+ char *restrict code = result->source_code->real_lines[tree->loc_line];
+ char32_t *restrict data = NULL;
+ char32_t **old = NULL;
+ char32_t *restrict character;
+ size_t n;
+ int saved_errno;
+
+ /* Locate the first character in the list. */
+ for (lineoff = tree->loc_end; code[lineoff] == ' '; lineoff++);
+ /* Evaluate function calls, variable dereferences
+ and escapes in the charcter list. */
+ fail_if (!(data = parse_string((mds_kbdc_tree_t*)tree, tree->chars, lineoff)));
+ if (tree->processed == PROCESS_LEVEL)
+ return free(data), 0;
+
+ /* Make sure we can fit all characters in the assumption list. */
+ for (n = 0; data[n] >= 0; n++);
+ if (result->assumed_strings_ptr + n > result->assumed_strings_size) {
+ result->assumed_strings_size += n;
+ fail_if (xxrealloc(old, result->assumed_strings, result->assumed_strings_size, char32_t *));
+ }
+
+ /* Add all characters to the assumption list. */
+ while (n--) {
+ fail_if (xmalloc(character, 2, char32_t));
+ character[0] = data[n];
+ character[1] = -1;
+ result->assumed_strings[result->assumed_strings_ptr++] = character;
+ }
+
+ free(data);
+ return 0;
+ FAIL_BEGIN;
+ free(data);
+ free(old);
+ FAIL_END;
}
@@ -1605,88 +1566,85 @@ static int compile_have_chars(mds_kbdc_tree_assumption_have_chars_t* restrict tr
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_have_range(mds_kbdc_tree_assumption_have_range_t* restrict tree)
+static int
+compile_have_range(mds_kbdc_tree_assumption_have_range_t *restrict tree)
{
- size_t lineoff_first;
- size_t lineoff_last;
- char* restrict code = result->source_code->real_lines[tree->loc_line];
- char32_t* restrict first = NULL;
- char32_t* restrict last = NULL;
- char32_t** old = NULL;
- char32_t* restrict character;
- size_t n;
- int saved_errno;
-
-
- /* Locate the first characters of both bound strings. */
- for (lineoff_first = tree->loc_end; code[lineoff_first] == ' '; lineoff_first++);
- for (lineoff_last = lineoff_first + strlen(tree->first); code[lineoff_last] == ' '; lineoff_last++);
-
- /* Duplicate bounds and evaluate function calls,
- variable dereferences and escapes in the bounds. */
- fail_if (first = parse_string((mds_kbdc_tree_t*)tree, tree->first, lineoff_first), first == NULL);
- fail_if (last = parse_string((mds_kbdc_tree_t*)tree, tree->last, lineoff_last), last == NULL);
-
- /* Did one of the bound not evaluate, then stop. */
- if (tree->processed == PROCESS_LEVEL)
- goto done;
-
-
- /* Check that the primary bound is single-character. */
- if ((first[0] == -1) || (first[1] != -1))
- {
- NEW_ERROR(tree, ERROR, "iteration boundary must be a single character string");
- error->start = lineoff_first, lineoff_first = 0;
- error->end = error->start + strlen(tree->first);
- }
- /* Check that the secondary bound is single-character. */
- if ((last[0] == -1) || (last[1] != -1))
- {
- NEW_ERROR(tree, ERROR, "iteration boundary must be a single character string");
- error->start = lineoff_last, lineoff_last = 0;
- error->end = error->start + strlen(tree->last);
- }
-
- /* Was one of the bounds not single-character, then stop. */
- if ((lineoff_first == 0) || (lineoff_last == 0))
- goto done;
-
-
- /* If the range is descending, swap the bounds so it is ascending.
- (This cannot be done in for-loops as that may cause side-effects
- to be created in the wrong order.) */
- if (*first > *last)
- *first ^= *last, *last ^= *first, *first ^= *last;
-
- /* Make sure we can fit all characters in the assumption list. */
- n = (size_t)(*last - *first) + 1;
- if (result->assumed_strings_ptr + n > result->assumed_strings_size)
- {
- result->assumed_strings_size += n;
- fail_if (xxrealloc(old, result->assumed_strings, result->assumed_strings_size, char32_t*));
- }
-
- /* Add all characters to the assumption list. */
- for (;;)
- {
- fail_if (xmalloc(character, 2, char32_t));
- character[0] = *first;
- character[1] = -1;
- result->assumed_strings[result->assumed_strings_ptr++] = character;
- /* Bounds are inclusive. */
- if ((*first)++ == *last)
- break;
- }
-
- done:
- free(first);
- free(last);
- return 0;
- FAIL_BEGIN;
- free(first);
- free(last);
- free(old);
- FAIL_END;
+ size_t lineoff_first;
+ size_t lineoff_last;
+ char *restrict code = result->source_code->real_lines[tree->loc_line];
+ char32_t *restrict first = NULL;
+ char32_t *restrict last = NULL;
+ char32_t **old = NULL;
+ char32_t *restrict character;
+ size_t n;
+ int saved_errno;
+
+
+ /* Locate the first characters of both bound strings. */
+ for (lineoff_first = tree->loc_end; code[lineoff_first] == ' '; lineoff_first++);
+ for (lineoff_last = lineoff_first + strlen(tree->first); code[lineoff_last] == ' '; lineoff_last++);
+
+ /* Duplicate bounds and evaluate function calls,
+ variable dereferences and escapes in the bounds. */
+ fail_if (!(first = parse_string((mds_kbdc_tree_t*)tree, tree->first, lineoff_first)));
+ fail_if (!(last = parse_string((mds_kbdc_tree_t*)tree, tree->last, lineoff_last)));
+
+ /* Did one of the bound not evaluate, then stop. */
+ if (tree->processed == PROCESS_LEVEL)
+ goto done;
+
+
+ /* Check that the primary bound is single-character. */
+ if (first[0] == -1 || first[1] != -1) {
+ NEW_ERROR(tree, ERROR, "iteration boundary must be a single character string");
+ error->start = lineoff_first, lineoff_first = 0;
+ error->end = error->start + strlen(tree->first);
+ }
+ /* Check that the secondary bound is single-character. */
+ if (last[0] == -1 || last[1] != -1) {
+ NEW_ERROR(tree, ERROR, "iteration boundary must be a single character string");
+ error->start = lineoff_last, lineoff_last = 0;
+ error->end = error->start + strlen(tree->last);
+ }
+
+ /* Was one of the bounds not single-character, then stop. */
+ if (!lineoff_first || !lineoff_last)
+ goto done;
+
+
+ /* If the range is descending, swap the bounds so it is ascending.
+ (This cannot be done in for-loops as that may cause side-effects
+ to be created in the wrong order.) */
+ if (*first > *last)
+ *first ^= *last, *last ^= *first, *first ^= *last;
+
+ /* Make sure we can fit all characters in the assumption list. */
+ n = (size_t)(*last - *first) + 1;
+ if (result->assumed_strings_ptr + n > result->assumed_strings_size) {
+ result->assumed_strings_size += n;
+ fail_if (xxrealloc(old, result->assumed_strings, result->assumed_strings_size, char32_t *));
+ }
+
+ /* Add all characters to the assumption list. */
+ for (;;) {
+ fail_if (xmalloc(character, 2, char32_t));
+ character[0] = *first;
+ character[1] = -1;
+ result->assumed_strings[result->assumed_strings_ptr++] = character;
+ /* Bounds are inclusive. */
+ if ((*first)++ == *last)
+ break;
+ }
+
+done:
+ free(first);
+ free(last);
+ return 0;
+ FAIL_BEGIN;
+ free(first);
+ free(last);
+ free(old);
+ FAIL_END;
}
@@ -1696,47 +1654,48 @@ static int compile_have_range(mds_kbdc_tree_assumption_have_range_t* restrict tr
* @param tree The tree to evaluate
* @return Zero on success, -1 on error, 1 if an undefined macro is used
*/
-static int check_marco_calls(mds_kbdc_tree_t* restrict tree)
+static int
+check_marco_calls(mds_kbdc_tree_t *restrict tree)
{
-#define t(...) fail_if (rc |= r = (__VA_ARGS__), r < 0)
- mds_kbdc_tree_macro_t* _macro;
- mds_kbdc_include_stack_t* _macro_include_stack;
- void* data;
- int r, rc = 0;
- again:
- if (tree == NULL)
- return rc;
-
- switch (tree->type)
- {
- case C(INCLUDE):
- t (mds_kbdc_include_stack_push(&(tree->include), &data));
- t (r = check_marco_calls(tree->include.inner), mds_kbdc_include_stack_pop(data), r);
- break;
-
- case C(FOR):
- t (check_marco_calls(tree->for_.inner));
- break;
-
- case C(IF):
- t (check_marco_calls(tree->if_.inner));
- t (check_marco_calls(tree->if_.otherwise));
- break;
-
- case C(MACRO_CALL):
- t (get_macro(&(tree->macro_call), &_macro, &_macro_include_stack));
- break;
-
- default:
- break;
- }
-
- tree = tree->next;
- goto again;
- fail:
- return -1;
- (void) _macro;
- (void) _macro_include_stack;
+#define t(...) fail_if (rc |= r = (__VA_ARGS__), r < 0)
+ mds_kbdc_tree_macro_t *_macro;
+ mds_kbdc_include_stack_t *_macro_include_stack;
+ void *data;
+ int r, rc = 0;
+
+again:
+ if (!tree)
+ return rc;
+
+ switch (tree->type) {
+ case C(INCLUDE):
+ t (mds_kbdc_include_stack_push(&(tree->include), &data));
+ t (r = check_marco_calls(tree->include.inner), mds_kbdc_include_stack_pop(data), r);
+ break;
+
+ case C(FOR):
+ t (check_marco_calls(tree->for_.inner));
+ break;
+
+ case C(IF):
+ t (check_marco_calls(tree->if_.inner));
+ t (check_marco_calls(tree->if_.otherwise));
+ break;
+
+ case C(MACRO_CALL):
+ t (get_macro(&(tree->macro_call), &_macro, &_macro_include_stack));
+ break;
+
+ default:
+ break;
+ }
+
+ tree = tree->next;
+ goto again;
+fail:
+ return -1;
+ (void) _macro;
+ (void) _macro_include_stack;
#undef t
}
@@ -1747,24 +1706,25 @@ static int check_marco_calls(mds_kbdc_tree_t* restrict tree)
* @param tree The tree to evaluate
* @return Zero on success, -1 on error, 1 if an undefined function is used
*/
-static int check_function_calls_in_for(const mds_kbdc_tree_for_t* restrict tree)
+static int
+check_function_calls_in_for(const mds_kbdc_tree_for_t *restrict tree)
{
-#define t(...) fail_if (rc |= r = check_function_calls_in_literal(__VA_ARGS__), r < 0)
- size_t lineoff_first;
- size_t lineoff_last;
- char* restrict code = result->source_code->real_lines[tree->loc_line];
- int r, rc = 0;
-
- for (lineoff_first = tree->loc_end; code[lineoff_first] == ' '; lineoff_first++);
- for (lineoff_last = lineoff_first + strlen(tree->first); code[lineoff_last] == ' '; lineoff_last++);
- for (lineoff_last += strlen("to"); code[lineoff_last] == ' '; lineoff_last++);
-
- t ((const mds_kbdc_tree_t*)tree, tree->first, lineoff_first);
- t ((const mds_kbdc_tree_t*)tree, tree->last, lineoff_last);
-
- return rc;
- fail:
- return -1;
+#define t(...) fail_if (rc |= r = check_function_calls_in_literal(__VA_ARGS__), r < 0)
+ size_t lineoff_first;
+ size_t lineoff_last;
+ char *restrict code = result->source_code->real_lines[tree->loc_line];
+ int r, rc = 0;
+
+ for (lineoff_first = tree->loc_end; code[lineoff_first] == ' '; lineoff_first++);
+ for (lineoff_last = lineoff_first + strlen(tree->first); code[lineoff_last] == ' '; lineoff_last++);
+ for (lineoff_last += strlen("to"); code[lineoff_last] == ' '; lineoff_last++);
+
+ t ((const mds_kbdc_tree_t *)tree, tree->first, lineoff_first);
+ t ((const mds_kbdc_tree_t *)tree, tree->last, lineoff_last);
+
+ return rc;
+fail:
+ return -1;
#undef t
}
@@ -1775,17 +1735,18 @@ static int check_function_calls_in_for(const mds_kbdc_tree_for_t* restrict tree)
* @param tree The tree to evaluate
* @return Zero on success, -1 on error, 1 if an undefined function is used
*/
-static int check_function_calls_in_if(const mds_kbdc_tree_if_t* restrict tree)
+static int
+check_function_calls_in_if(const mds_kbdc_tree_if_t *restrict tree)
{
- size_t lineoff;
- char* restrict code = result->source_code->real_lines[tree->loc_line];
- int r;
-
- for (lineoff = tree->loc_end; code[lineoff] == ' '; lineoff++);
- r = check_function_calls_in_literal((const mds_kbdc_tree_t*)tree, tree->condition, lineoff);
- fail_if (r < 0);
- fail:
- return r;
+ size_t lineoff;
+ char *restrict code = result->source_code->real_lines[tree->loc_line];
+ int r;
+
+ for (lineoff = tree->loc_end; code[lineoff] == ' '; lineoff++);
+ r = check_function_calls_in_literal((const mds_kbdc_tree_t *)tree, tree->condition, lineoff);
+ fail_if (r < 0);
+fail:
+ return r;
}
@@ -1795,13 +1756,14 @@ static int check_function_calls_in_if(const mds_kbdc_tree_if_t* restrict tree)
* @param tree The tree to evaluate
* @return Zero on success, -1 on error, 1 if an undefined function is used
*/
-static int check_function_calls_in_keys(const mds_kbdc_tree_keys_t* restrict tree)
+static int
+check_function_calls_in_keys(const mds_kbdc_tree_keys_t *restrict tree)
{
- int r;
- r = check_function_calls_in_literal((const mds_kbdc_tree_t*)tree, tree->keys, tree->loc_start);
- fail_if (r < 0);
- fail:
- return r;
+ int r;
+ r = check_function_calls_in_literal((const mds_kbdc_tree_t *)tree, tree->keys, tree->loc_start);
+ fail_if (r < 0);
+fail:
+ return r;
}
@@ -1811,13 +1773,14 @@ static int check_function_calls_in_keys(const mds_kbdc_tree_keys_t* restrict tre
* @param tree The tree to evaluate
* @return Zero on success, -1 on error, 1 if an undefined function is used
*/
-static int check_function_calls_in_string(const mds_kbdc_tree_string_t* restrict tree)
+static int
+check_function_calls_in_string(const mds_kbdc_tree_string_t *restrict tree)
{
- int r;
- r = check_function_calls_in_literal((const mds_kbdc_tree_t*)tree, tree->string, tree->loc_start);
- fail_if (r < 0);
- fail:
- return r;
+ int r;
+ r = check_function_calls_in_literal((const mds_kbdc_tree_t *)tree, tree->string, tree->loc_start);
+ fail_if (r < 0);
+fail:
+ return r;
}
@@ -1827,46 +1790,47 @@ static int check_function_calls_in_string(const mds_kbdc_tree_string_t* restrict
* @param tree The tree to evaluate
* @return Zero on success, -1 on error, 1 if an undefined function is used
*/
-static int check_function_calls(const mds_kbdc_tree_t* restrict tree)
+static int
+check_function_calls(const mds_kbdc_tree_t *restrict tree)
{
-#define t(...) fail_if (rc |= r = (__VA_ARGS__), r < 0)
- void* data;
- int r, rc = 0;
- again:
- if (tree == NULL)
- return rc;
-
- switch (tree->type)
- {
- case C(INCLUDE):
- t (mds_kbdc_include_stack_push(&(tree->include), &data));
- t (r = check_function_calls(tree->include.inner), mds_kbdc_include_stack_pop(data), r);
- break;
-
- case C(FOR):
- t (check_function_calls_in_for(&(tree->for_)));
- t (check_function_calls(tree->for_.inner));
- break;
-
- case C(IF):
- t (check_function_calls_in_if(&(tree->if_)));
- t (check_function_calls(tree->if_.inner));
- t (check_function_calls(tree->if_.otherwise));
- break;
-
- case C(LET): t (check_function_calls(tree->let.value)); break;
- case C(ARRAY): t (check_function_calls(tree->array.elements)); break;
- case C(KEYS): t (check_function_calls_in_keys(&(tree->keys))); break;
- case C(STRING): t (check_function_calls_in_string(&(tree->string))); break;
- case C(MAP): t (check_function_calls(tree->map.sequence)); break;
- default:
- break;
- }
-
- tree = tree->next;
- goto again;
- fail:
- return -1;
+#define t(...) fail_if (rc |= r = (__VA_ARGS__), r < 0)
+ void *data;
+ int r, rc = 0;
+
+again:
+ if (!tree)
+ return rc;
+
+ switch (tree->type) {
+ case C(INCLUDE):
+ t (mds_kbdc_include_stack_push(&(tree->include), &data));
+ t (r = check_function_calls(tree->include.inner), mds_kbdc_include_stack_pop(data), r);
+ break;
+
+ case C(FOR):
+ t (check_function_calls_in_for(&(tree->for_)));
+ t (check_function_calls(tree->for_.inner));
+ break;
+
+ case C(IF):
+ t (check_function_calls_in_if(&(tree->if_)));
+ t (check_function_calls(tree->if_.inner));
+ t (check_function_calls(tree->if_.otherwise));
+ break;
+
+ case C(LET): t (check_function_calls(tree->let.value)); break;
+ case C(ARRAY): t (check_function_calls(tree->array.elements)); break;
+ case C(KEYS): t (check_function_calls_in_keys(&(tree->keys))); break;
+ case C(STRING): t (check_function_calls_in_string(&(tree->string))); break;
+ case C(MAP): t (check_function_calls(tree->map.sequence)); break;
+ default:
+ break;
+ }
+
+ tree = tree->next;
+ goto again;
+fail:
+ return -1;
#undef t
}
@@ -1877,52 +1841,50 @@ static int check_function_calls(const mds_kbdc_tree_t* restrict tree)
* @param tree The tree to inspect
* @return Zero on sucess, -1 on error, 1 if the name-suffix in invalid
*/
-static int check_name_suffix(struct mds_kbdc_tree_callable* restrict tree)
+static int
+check_name_suffix(struct mds_kbdc_tree_callable *restrict tree)
{
- const char* restrict name = strchr(tree->name, '/');
- const char* restrict code = result->source_code->real_lines[tree->loc_line];
-
- /* A "/" must exist in the name to tell us how many parameters there are. */
- if (name == NULL)
- {
- NEW_ERROR(tree, ERROR, "name-suffix is missing");
- goto name_error;
- }
- /* Do not let the suffix by just "/". */
- if (*++name == '\0')
- {
- NEW_ERROR(tree, ERROR, "empty name-suffix");
- goto name_error;
- }
-
- /* We are all good if the suffix is simply "/0" */
- if (!strcmp(name, "0"))
- return 0;
-
- /* The suffix may not have leading zeroes. */
- if (*name == '0')
- {
- NEW_ERROR(tree, ERROR, "leading zero in name-suffix");
- goto name_error;
- }
- /* The suffix must be a decimal, non-negative number. */
- for (; *name; name++)
- if ((*name < '0') || ('9' < *name))
- {
- NEW_ERROR(tree, ERROR, "name-suffix may only contain digits");
- goto name_error;
- }
-
- return 0;
- fail:
- return -1;
- name_error:
- error->start = tree->loc_end;
- while (code[error->start] == ' ')
- error->start++;
- error->end = error->start + strlen(tree->name);
- tree->processed = PROCESS_LEVEL;
- return 1;
+ const char *restrict name = strchr(tree->name, '/');
+ const char *restrict code = result->source_code->real_lines[tree->loc_line];
+
+ /* A "/" must exist in the name to tell us how many parameters there are. */
+ if (!name) {
+ NEW_ERROR(tree, ERROR, "name-suffix is missing");
+ goto name_error;
+ }
+ /* Do not let the suffix by just "/". */
+ if (!*++name) {
+ NEW_ERROR(tree, ERROR, "empty name-suffix");
+ goto name_error;
+ }
+
+ /* We are all good if the suffix is simply "/0" */
+ if (!strcmp(name, "0"))
+ return 0;
+
+ /* The suffix may not have leading zeroes. */
+ if (*name == '0') {
+ NEW_ERROR(tree, ERROR, "leading zero in name-suffix");
+ goto name_error;
+ }
+ /* The suffix must be a decimal, non-negative number. */
+ for (; *name; name++) {
+ if (*name < '0' || '9' < *name) {
+ NEW_ERROR(tree, ERROR, "name-suffix may only contain digits");
+ goto name_error;
+ }
+ }
+
+ return 0;
+fail:
+ return -1;
+name_error:
+ error->start = tree->loc_end;
+ while (code[error->start] == ' ')
+ error->start++;
+ error->end = error->start + strlen(tree->name);
+ tree->processed = PROCESS_LEVEL;
+ return 1;
}
@@ -1932,67 +1894,67 @@ static int check_name_suffix(struct mds_kbdc_tree_callable* restrict tree)
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_function(mds_kbdc_tree_function_t* restrict tree)
+static int
+compile_function(mds_kbdc_tree_function_t *restrict tree)
{
-#define t(expr) fail_if (r = (expr), r < 0); if (r) tree->processed = PROCESS_LEVEL
- mds_kbdc_tree_function_t* function;
- mds_kbdc_include_stack_t* function_include_stack;
- mds_kbdc_include_stack_t* our_include_stack = NULL;
- char* suffixless;
- char* suffix_start = NULL;
- size_t arg_count;
- int r, saved_errno;
-
- /* Check that the suffix if properly formatted. */
- t (check_name_suffix((struct mds_kbdc_tree_callable*)tree));
- if (r) return 0;
-
- /* Get the function's name without suffix, and parse the suffix. */
- suffixless = tree->name;
- suffix_start = strchr(suffixless, '/');
- *suffix_start++ = '\0';
- arg_count = atoz(suffix_start--);
-
- /* Check that the function is not already defined as a builtin function. */
- if (builtin_function_defined(suffixless, arg_count))
- {
- NEW_ERROR(tree, ERROR, "function ‘%s/%zu’ is already defined as a builtin function",
- tree->name, arg_count);
- *suffix_start = '/';
- return 0;
- }
- /* Check that the function is not already defined,
- the include-stack is used in the error-clause as
- well as later when we list the function as defined. */
- get_function_lax(suffixless, arg_count, &function, &function_include_stack);
- fail_if (our_include_stack = mds_kbdc_include_stack_save(), our_include_stack == NULL);
- if (function)
- {
- *suffix_start = '/';
- NEW_ERROR(tree, ERROR, "function ‘%s’ is already defined", tree->name);
- fail_if (mds_kbdc_include_stack_restore(function_include_stack));
- NEW_ERROR(function, NOTE, "previously defined here");
- fail_if (mds_kbdc_include_stack_restore(our_include_stack));
- mds_kbdc_include_stack_free(our_include_stack);
- return 0;
- }
-
- /* Check the the function does not call macros or functions
- * before they are defined, otherwise they may get defined
- * between the definition of the function and calls to it. */
- t (check_marco_calls(tree->inner));
- t (check_function_calls(tree->inner));
-
- /* List the function as defined. */
- *suffix_start = '/', suffix_start = NULL;
- t (set_function(tree, our_include_stack));
-
- return 0;
- FAIL_BEGIN;
- if (suffix_start)
- *suffix_start = '/';
- mds_kbdc_include_stack_free(our_include_stack);
- FAIL_END;
+#define t(expr) do { fail_if (r = (expr), r < 0); if (r) tree->processed = PROCESS_LEVEL; } while (0)
+ mds_kbdc_tree_function_t *function;
+ mds_kbdc_include_stack_t *function_include_stack;
+ mds_kbdc_include_stack_t *our_include_stack = NULL;
+ char *suffixless;
+ char *suffix_start = NULL;
+ size_t arg_count;
+ int r, saved_errno;
+
+ /* Check that the suffix if properly formatted. */
+ t (check_name_suffix((struct mds_kbdc_tree_callable*)tree));
+ if (r)
+ return 0;
+
+ /* Get the function's name without suffix, and parse the suffix. */
+ suffixless = tree->name;
+ suffix_start = strchr(suffixless, '/');
+ *suffix_start++ = '\0';
+ arg_count = atoz(suffix_start--);
+
+ /* Check that the function is not already defined as a builtin function. */
+ if (builtin_function_defined(suffixless, arg_count)) {
+ NEW_ERROR(tree, ERROR, "function ‘%s/%zu’ is already defined as a builtin function",
+ tree->name, arg_count);
+ *suffix_start = '/';
+ return 0;
+ }
+ /* Check that the function is not already defined,
+ the include-stack is used in the error-clause as
+ well as later when we list the function as defined. */
+ get_function_lax(suffixless, arg_count, &function, &function_include_stack);
+ fail_if (!(our_include_stack = mds_kbdc_include_stack_save(), our_include_stack));
+ if (function) {
+ *suffix_start = '/';
+ NEW_ERROR(tree, ERROR, "function ‘%s’ is already defined", tree->name);
+ fail_if (mds_kbdc_include_stack_restore(function_include_stack));
+ NEW_ERROR(function, NOTE, "previously defined here");
+ fail_if (mds_kbdc_include_stack_restore(our_include_stack));
+ mds_kbdc_include_stack_free(our_include_stack);
+ return 0;
+ }
+
+ /* Check the the function does not call macros or functions
+ * before they are defined, otherwise they may get defined
+ * between the definition of the function and calls to it. */
+ t (check_marco_calls(tree->inner));
+ t (check_function_calls(tree->inner));
+
+ /* List the function as defined. */
+ *suffix_start = '/', suffix_start = NULL;
+ t (set_function(tree, our_include_stack));
+
+ return 0;
+ FAIL_BEGIN;
+ if (suffix_start)
+ *suffix_start = '/';
+ mds_kbdc_include_stack_free(our_include_stack);
+ FAIL_END;
#undef t
}
@@ -2003,46 +1965,47 @@ static int compile_function(mds_kbdc_tree_function_t* restrict tree)
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_macro(mds_kbdc_tree_macro_t* restrict tree)
+static int
+compile_macro(mds_kbdc_tree_macro_t *restrict tree)
{
-#define t(expr) fail_if (r = (expr), r < 0); if (r) tree->processed = PROCESS_LEVEL
- mds_kbdc_tree_macro_t* macro;
- mds_kbdc_include_stack_t* macro_include_stack;
- mds_kbdc_include_stack_t* our_include_stack = NULL;
- int r, saved_errno;
-
- /* Check that the suffix if properly formatted. */
- t (check_name_suffix((struct mds_kbdc_tree_callable*)tree));
- if (r) return 0;
-
- /* Check that the macro is not already defined,
- the include-stack is used in the error-clause as
- well as later when we list the macro as defined. */
- fail_if (our_include_stack = mds_kbdc_include_stack_save(), our_include_stack == NULL);
- get_macro_lax(tree->name, &macro, &macro_include_stack);
- if (macro)
- {
- NEW_ERROR(tree, ERROR, "macro ‘%s’ is already defined", tree->name);
- fail_if (mds_kbdc_include_stack_restore(macro_include_stack));
- NEW_ERROR(macro, NOTE, "previously defined here");
- fail_if (mds_kbdc_include_stack_restore(our_include_stack));
- mds_kbdc_include_stack_free(our_include_stack);
- return 0;
- }
-
- /* Check the the macro does not call macros or functions
- * before they are defined, otherwise they may get defined
- * between the definition of the macro and calls to it. */
- t (check_marco_calls(tree->inner));
- t (check_function_calls(tree->inner));
-
- /* List the macro as defined. */
- t (set_macro(tree, our_include_stack));
-
- return 0;
- FAIL_BEGIN;
- mds_kbdc_include_stack_free(our_include_stack);
- FAIL_END;
+#define t(expr) do { fail_if (r = (expr), r < 0); if (r) tree->processed = PROCESS_LEVEL; } while (0)
+ mds_kbdc_tree_macro_t *macro;
+ mds_kbdc_include_stack_t *macro_include_stack;
+ mds_kbdc_include_stack_t *our_include_stack = NULL;
+ int r, saved_errno;
+
+ /* Check that the suffix if properly formatted. */
+ t (check_name_suffix((struct mds_kbdc_tree_callable*)tree));
+ if (r)
+ return 0;
+
+ /* Check that the macro is not already defined,
+ the include-stack is used in the error-clause as
+ well as later when we list the macro as defined. */
+ fail_if (!(our_include_stack = mds_kbdc_include_stack_save()));
+ get_macro_lax(tree->name, &macro, &macro_include_stack);
+ if (macro) {
+ NEW_ERROR(tree, ERROR, "macro ‘%s’ is already defined", tree->name);
+ fail_if (mds_kbdc_include_stack_restore(macro_include_stack));
+ NEW_ERROR(macro, NOTE, "previously defined here");
+ fail_if (mds_kbdc_include_stack_restore(our_include_stack));
+ mds_kbdc_include_stack_free(our_include_stack);
+ return 0;
+ }
+
+ /* Check the the macro does not call macros or functions
+ * before they are defined, otherwise they may get defined
+ * between the definition of the macro and calls to it. */
+ t (check_marco_calls(tree->inner));
+ t (check_function_calls(tree->inner));
+
+ /* List the macro as defined. */
+ t (set_macro(tree, our_include_stack));
+
+ return 0;
+ FAIL_BEGIN;
+ mds_kbdc_include_stack_free(our_include_stack);
+ FAIL_END;
#undef t
}
@@ -2053,94 +2016,92 @@ static int compile_macro(mds_kbdc_tree_macro_t* restrict tree)
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_for(mds_kbdc_tree_for_t* restrict tree)
+static int
+compile_for(mds_kbdc_tree_for_t *restrict tree)
{
- size_t lineoff_first;
- size_t lineoff_last;
- size_t lineoff_var;
- char* restrict code = result->source_code->real_lines[tree->loc_line];
- char32_t* restrict first = NULL;
- char32_t* restrict last = NULL;
- char32_t diff;
- char32_t character[2];
- size_t variable;
- int possible_shadow = 1, saved_errno;
-
-
- last_value_statement = NULL;
-
-
- /* Locate the first character of the primary bound's string. */
- for (lineoff_first = tree->loc_end; code[lineoff_first] == ' '; lineoff_first++);
- /* Locate the first character of the secondary bound's string. */
- for (lineoff_last = lineoff_first + strlen(tree->first); code[lineoff_last] == ' '; lineoff_last++);
- for (lineoff_last += strlen("to"); code[lineoff_last] == ' '; lineoff_last++);
- /* Locate the first character of the select variable. */
- for (lineoff_var = lineoff_last + strlen(tree->last); code[lineoff_var] == ' '; lineoff_var++);
- for (lineoff_var += strlen("as"); code[lineoff_var] == ' '; lineoff_var++);
-
- /* Duplicate bounds and evaluate function calls,
- variable dereferences and escapes in the bounds. */
- fail_if (first = parse_string((mds_kbdc_tree_t*)tree, tree->first, lineoff_first), first == NULL);
- fail_if (last = parse_string((mds_kbdc_tree_t*)tree, tree->last, lineoff_last), last == NULL);
- /* Get the index of the selected variable. */
- fail_if (variable = parse_variable((mds_kbdc_tree_t*)tree, tree->variable, lineoff_var), variable == 0);
-
- /* Did one of the bound not evaluate, then stop. */
- if (tree->processed == PROCESS_LEVEL)
- goto done;
-
-
- /* Check that the primary bound is single-character. */
- if ((first[0] == -1) || (first[1] != -1))
- {
- NEW_ERROR(tree, ERROR, "iteration boundary must be a single character string");
- error->start = lineoff_first, lineoff_first = 0;
- error->end = error->start + strlen(tree->first);
- }
- /* Check that the secondary bound is single-character. */
- if ((last[0] == -1) || (last[1] != -1))
- {
- NEW_ERROR(tree, ERROR, "iteration boundary must be a single character string");
- error->start = lineoff_last, lineoff_last = 0;
- error->end = error->start + strlen(tree->last);
- }
-
- /* Was one of the bounds not single-character, then stop. */
- if ((lineoff_first == 0) || (lineoff_last == 0))
- goto done;
-
-
- /* Iterate over the loop for as long as a `return` or `break` has not
- been encountered (without being caught elsewhere). */
- character[1] = -1;
- for (diff = (*first > *last) ? -1 : +1; break_level < 2; *first += diff)
- {
- break_level = 0;
- character[0] = *first;
- fail_if (let(variable, character, NULL, (mds_kbdc_tree_t*)tree, lineoff_var, possible_shadow));
- possible_shadow = 0;
- fail_if (compile_subtree(tree->inner));
- /* Bounds are inclusive. */
- if (*first == *last)
- break;
- }
- fail_if (variables_was_used_in_for(variable));
-
- /* Catch `break` and `continue`, they may not propagate further. */
- if (break_level < 3)
- break_level = 0;
-
-
- done:
- last_value_statement = NULL;
- free(first);
- free(last);
- return 0;
- FAIL_BEGIN;
- free(first);
- free(last);
- FAIL_END;
+ size_t lineoff_first;
+ size_t lineoff_last;
+ size_t lineoff_var;
+ char *restrict code = result->source_code->real_lines[tree->loc_line];
+ char32_t *restrict first = NULL;
+ char32_t *restrict last = NULL;
+ char32_t diff;
+ char32_t character[2];
+ size_t variable;
+ int possible_shadow = 1, saved_errno;
+
+
+ last_value_statement = NULL;
+
+
+ /* Locate the first character of the primary bound's string. */
+ for (lineoff_first = tree->loc_end; code[lineoff_first] == ' '; lineoff_first++);
+ /* Locate the first character of the secondary bound's string. */
+ for (lineoff_last = lineoff_first + strlen(tree->first); code[lineoff_last] == ' '; lineoff_last++);
+ for (lineoff_last += strlen("to"); code[lineoff_last] == ' '; lineoff_last++);
+ /* Locate the first character of the select variable. */
+ for (lineoff_var = lineoff_last + strlen(tree->last); code[lineoff_var] == ' '; lineoff_var++);
+ for (lineoff_var += strlen("as"); code[lineoff_var] == ' '; lineoff_var++);
+
+ /* Duplicate bounds and evaluate function calls,
+ variable dereferences and escapes in the bounds. */
+ fail_if (!(first = parse_string((mds_kbdc_tree_t*)tree, tree->first, lineoff_first)));
+ fail_if (!(last = parse_string((mds_kbdc_tree_t*)tree, tree->last, lineoff_last)));
+ /* Get the index of the selected variable. */
+ fail_if (variable = parse_variable((mds_kbdc_tree_t*)tree, tree->variable, lineoff_var), variable == 0);
+
+ /* Did one of the bound not evaluate, then stop. */
+ if (tree->processed == PROCESS_LEVEL)
+ goto done;
+
+
+ /* Check that the primary bound is single-character. */
+ if (first[0] == -1 || first[1] != -1) {
+ NEW_ERROR(tree, ERROR, "iteration boundary must be a single character string");
+ error->start = lineoff_first, lineoff_first = 0;
+ error->end = error->start + strlen(tree->first);
+ }
+ /* Check that the secondary bound is single-character. */
+ if (last[0] == -1 || last[1] != -1) {
+ NEW_ERROR(tree, ERROR, "iteration boundary must be a single character string");
+ error->start = lineoff_last, lineoff_last = 0;
+ error->end = error->start + strlen(tree->last);
+ }
+
+ /* Was one of the bounds not single-character, then stop. */
+ if (!lineoff_first || !lineoff_last)
+ goto done;
+
+
+ /* Iterate over the loop for as long as a `return` or `break` has not
+ been encountered (without being caught elsewhere). */
+ character[1] = -1;
+ for (diff = (*first > *last) ? -1 : +1; break_level < 2; *first += diff) {
+ break_level = 0;
+ character[0] = *first;
+ fail_if (let(variable, character, NULL, (mds_kbdc_tree_t*)tree, lineoff_var, possible_shadow));
+ possible_shadow = 0;
+ fail_if (compile_subtree(tree->inner));
+ /* Bounds are inclusive. */
+ if (*first == *last)
+ break;
+ }
+ fail_if (variables_was_used_in_for(variable));
+
+ /* Catch `break` and `continue`, they may not propagate further. */
+ if (break_level < 3)
+ break_level = 0;
+
+
+done:
+ last_value_statement = NULL;
+ free(first);
+ free(last);
+ return 0;
+ FAIL_BEGIN;
+ free(first);
+ free(last);
+ FAIL_END;
}
@@ -2150,36 +2111,37 @@ static int compile_for(mds_kbdc_tree_for_t* restrict tree)
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_if(mds_kbdc_tree_if_t* restrict tree)
+static int
+compile_if(mds_kbdc_tree_if_t *restrict tree)
{
- size_t lineoff;
- char* restrict code = result->source_code->real_lines[tree->loc_line];
- char32_t* restrict data = NULL;
- int ok, saved_errno;
- size_t i;
-
- last_value_statement = NULL;
-
- /* Locate the first character in the condition. */
- for (lineoff = tree->loc_end; code[lineoff] == ' '; lineoff++);
- /* Evaluate function calls, variable dereferences and escapes in the condition. */
- fail_if (data = parse_string((mds_kbdc_tree_t*)tree, tree->condition, lineoff), data == NULL);
- if (tree->processed == PROCESS_LEVEL)
- return free(data), 0;
-
- /* Evaluate whether the evaluted value is true. */
- for (ok = 1, i = 0; data[i] >= 0; i++)
- ok &= !!(data[i]);
- free(data), data = NULL;;
-
- /* Compile the appropriate clause. */
- ok = compile_subtree(ok ? tree->inner : tree->otherwise);
- last_value_statement = NULL;
- fail_if (ok < 0);
- return 0;
- FAIL_BEGIN;
- free(data);
- FAIL_END;
+ size_t lineoff;
+ char *restrict code = result->source_code->real_lines[tree->loc_line];
+ char32_t *restrict data = NULL;
+ int ok, saved_errno;
+ size_t i;
+
+ last_value_statement = NULL;
+
+ /* Locate the first character in the condition. */
+ for (lineoff = tree->loc_end; code[lineoff] == ' '; lineoff++);
+ /* Evaluate function calls, variable dereferences and escapes in the condition. */
+ fail_if (!(data = parse_string((mds_kbdc_tree_t*)tree, tree->condition, lineoff)));
+ if (tree->processed == PROCESS_LEVEL)
+ return free(data), 0;
+
+ /* Evaluate whether the evaluted value is true. */
+ for (ok = 1, i = 0; data[i] >= 0; i++)
+ ok &= !!(data[i]);
+ free(data), data = NULL;;
+
+ /* Compile the appropriate clause. */
+ ok = compile_subtree(ok ? tree->inner : tree->otherwise);
+ last_value_statement = NULL;
+ fail_if (ok < 0);
+ return 0;
+ FAIL_BEGIN;
+ free(data);
+ FAIL_END;
}
@@ -2189,35 +2151,36 @@ static int compile_if(mds_kbdc_tree_if_t* restrict tree)
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_let(mds_kbdc_tree_let_t* restrict tree)
+static int
+compile_let(mds_kbdc_tree_let_t *restrict tree)
{
- size_t lineoff;
- char* restrict code = result->source_code->real_lines[tree->loc_line];
- mds_kbdc_tree_t* value = NULL;
- size_t variable;
- int saved_errno;
-
- /* Get the index of the selected variable. */
- for (lineoff = tree->loc_end; code[lineoff] == ' '; lineoff++);
- fail_if (variable = parse_variable((mds_kbdc_tree_t*)tree, tree->variable, lineoff), variable == 0);
- if (tree->processed == PROCESS_LEVEL)
- return 0;
-
- /* Duplicate arguments and evaluate function calls,
- variable dereferences and escapes in the value. */
- fail_if (value = mds_kbdc_tree_dup(tree->value), value == NULL);
- fail_if (compile_subtree(value));
- if ((tree->processed = value->processed) == PROCESS_LEVEL)
- return mds_kbdc_tree_free(value), 0;
-
- /* Set the value of the variable. */
- fail_if (let(variable, NULL, value, NULL, 0, 0));
-
- mds_kbdc_tree_free(value);
- return 0;
- FAIL_BEGIN;
- free(value);
- FAIL_END;
+ size_t lineoff;
+ char *restrict code = result->source_code->real_lines[tree->loc_line];
+ mds_kbdc_tree_t* value = NULL;
+ size_t variable;
+ int saved_errno;
+
+ /* Get the index of the selected variable. */
+ for (lineoff = tree->loc_end; code[lineoff] == ' '; lineoff++);
+ fail_if (!(variable = parse_variable((mds_kbdc_tree_t *)tree, tree->variable, lineoff)));
+ if (tree->processed == PROCESS_LEVEL)
+ return 0;
+
+ /* Duplicate arguments and evaluate function calls,
+ variable dereferences and escapes in the value. */
+ fail_if (!(value = mds_kbdc_tree_dup(tree->value)));
+ fail_if (compile_subtree(value));
+ if ((tree->processed = value->processed) == PROCESS_LEVEL)
+ return mds_kbdc_tree_free(value), 0;
+
+ /* Set the value of the variable. */
+ fail_if (let(variable, NULL, value, NULL, 0, 0));
+
+ mds_kbdc_tree_free(value);
+ return 0;
+ FAIL_BEGIN;
+ free(value);
+ FAIL_END;
}
@@ -2237,26 +2200,26 @@ static int compile_let(mds_kbdc_tree_let_t* restrict tree)
* @param node The element to evaluate
* @return Zero on success, -1 on error, 1 if the element is invalid
*/
-static int evaluate_element(mds_kbdc_tree_t* restrict node)
+static int
+evaluate_element(mds_kbdc_tree_t *restrict node)
{
- char32_t* restrict data = NULL;
- int bad = 0;
-
- for (; node; node = node->next)
- {
- if (node->type == C(STRING))
- fail_if (data = parse_string(node, node->string.string, node->loc_start), data == NULL);
- if (node->type == C(KEYS))
- fail_if (data = parse_keys(node, node->keys.keys, node->loc_start), data == NULL);
- free(node->string.string);
- node->type = (node->type == C(STRING)) ? C(COMPILED_STRING) : C(COMPILED_KEYS);
- node->compiled_string.string = data;
- bad |= (node->processed == PROCESS_LEVEL);
- }
-
- return bad;
- fail:
- return -1;
+ char32_t *restrict data = NULL;
+ int bad = 0;
+
+ for (; node; node = node->next) {
+ if (node->type == C(STRING))
+ fail_if (!(data = parse_string(node, node->string.string, node->loc_start)));
+ if (node->type == C(KEYS))
+ fail_if (!(data = parse_keys(node, node->keys.keys, node->loc_start)));
+ free(node->string.string);
+ node->type = (node->type == C(STRING)) ? C(COMPILED_STRING) : C(COMPILED_KEYS);
+ node->compiled_string.string = data;
+ bad |= (node->processed == PROCESS_LEVEL);
+ }
+
+ return bad;
+fail:
+ return -1;
}
@@ -2266,12 +2229,13 @@ static int evaluate_element(mds_kbdc_tree_t* restrict node)
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_keys(mds_kbdc_tree_keys_t* restrict tree)
+static int
+compile_keys(mds_kbdc_tree_keys_t *restrict tree)
{
- fail_if (evaluate_element((mds_kbdc_tree_t*)tree) < 0);
- return 0;
- fail:
- return -1;
+ fail_if (evaluate_element((mds_kbdc_tree_t *)tree) < 0);
+ return 0;
+fail:
+ return -1;
}
@@ -2281,12 +2245,13 @@ static int compile_keys(mds_kbdc_tree_keys_t* restrict tree)
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_string(mds_kbdc_tree_string_t* restrict tree)
+static int
+compile_string(mds_kbdc_tree_string_t *restrict tree)
{
- fail_if (evaluate_element((mds_kbdc_tree_t*)tree) < 0);
- return 0;
- fail:
- return -1;
+ fail_if (evaluate_element((mds_kbdc_tree_t *)tree) < 0);
+ return 0;
+fail:
+ return -1;
}
@@ -2296,15 +2261,16 @@ static int compile_string(mds_kbdc_tree_string_t* restrict tree)
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_array(mds_kbdc_tree_array_t* restrict tree)
+static int
+compile_array(mds_kbdc_tree_array_t *restrict tree)
{
- int r = evaluate_element(tree->elements);
- fail_if (r < 0);
- if (r)
- tree->processed = PROCESS_LEVEL;
- return 0;
- fail:
- return -1;
+ int r = evaluate_element(tree->elements);
+ fail_if (r < 0);
+ if (r)
+ tree->processed = PROCESS_LEVEL;
+ return 0;
+fail:
+ return -1;
}
@@ -2316,27 +2282,28 @@ static int compile_array(mds_kbdc_tree_array_t* restrict tree)
* @return Zero on success, -1 on error, 1 if any of
* the elements contain a NULL character
*/
-static int check_nonnul(mds_kbdc_tree_t* restrict tree)
+static int
+check_nonnul(mds_kbdc_tree_t *restrict tree)
{
- const char32_t* restrict string;
- int rc = 0;
- again:
- if (tree == NULL)
- return rc;
-
- for (string = tree->compiled_string.string; *string != -1; string++)
- if (*string == 0)
- {
- NEW_ERROR(tree, ERROR, "NULL characters are not allowed in mappings");
- tree->processed = PROCESS_LEVEL;
- rc = 1;
- break;
- }
-
- tree = tree->next;
- goto again;
- fail:
- return -1;
+ const char32_t *restrict string;
+ int rc = 0;
+again:
+ if (!tree)
+ return rc;
+
+ for (string = tree->compiled_string.string; *string != -1; string++) {
+ if (!*string) {
+ NEW_ERROR(tree, ERROR, "NULL characters are not allowed in mappings");
+ tree->processed = PROCESS_LEVEL;
+ rc = 1;
+ break;
+ }
+ }
+
+ tree = tree->next;
+ goto again;
+fail:
+ return -1;
}
@@ -2346,115 +2313,112 @@ static int check_nonnul(mds_kbdc_tree_t* restrict tree)
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_map(mds_kbdc_tree_map_t* restrict tree)
+static int
+compile_map(mds_kbdc_tree_map_t *restrict tree)
{
- int bad = 0, old_have_side_effect = have_side_effect;
- mds_kbdc_include_stack_t* restrict include_stack = NULL;
- mds_kbdc_tree_t* seq = NULL;
- mds_kbdc_tree_t* res = NULL;
- mds_kbdc_tree_t* old_seq = tree->sequence;
- mds_kbdc_tree_t* old_res = tree->result;
- mds_kbdc_tree_map_t* dup_map = NULL;
- int r, saved_errno;
- mds_kbdc_tree_t* previous_last_value_statement = last_value_statement;
-
- have_side_effect = 0;
-
- /* Duplicate arguments and evaluate function calls,
- variable dereferences and escapes in the mapping
- input sequence. */
- fail_if (seq = mds_kbdc_tree_dup(old_seq), seq == NULL);
- fail_if (bad |= evaluate_element(seq), bad < 0);
-
- /* Duplicate arguments and evaluate function calls,
- variable dereferences and escapes in the mapping
- output sequence, unless this is a value-statement. */
- if (tree->result)
- {
- fail_if (res = mds_kbdc_tree_dup(old_res), res == NULL);
- fail_if (bad |= evaluate_element(res), bad < 0);
- }
-
- /* Stop if any of the mapping-arguments could not be evaluated. */
- if (bad)
- goto done;
-
-
- if (tree->result)
- {
- /* Mapping-statement. */
-
- /* Check for invalid characters in the mapping-arguments. */
- fail_if (bad |= check_nonnul(seq), bad < 0);
- fail_if (bad |= check_nonnul(res), bad < 0);
- if (bad)
- goto done;
-
- /* Duplicate the mapping-statement but give it the evaluated mapping-arguments. */
- tree->sequence = NULL;
- tree->result = NULL;
- fail_if (dup_map = &(mds_kbdc_tree_dup((mds_kbdc_tree_t*)tree)->map), dup_map == NULL);
- tree->sequence = old_seq, dup_map->sequence = seq, seq = NULL;
- tree->result = old_res, dup_map->result = res, res = NULL;
-
- /* Enlist the mapping for assembling. */
- fail_if (include_stack = mds_kbdc_include_stack_save(), include_stack == NULL);
- fail_if (add_mapping(dup_map, include_stack));
-
- goto done;
- }
-
-
- /* Value-statement */
-
- /* Save this statement so we can warn later if it is unnecessary,
- * `set_return_value` will set it to `NULL` if there are side-effects,
- * which would make this statement necessary (unless the overridding
- * statement has identical side-effect, but we will not check for that).
- * For simplicity, we do not store the include-stack, instead, we reset
- * `last_value_statement` to `NULL` when we visit an include-statement. */
- last_value_statement = (mds_kbdc_tree_t*)tree;
-
- /* Add the value statement */
- r = set_return_value(seq->compiled_string.string);
- seq->compiled_string.string = NULL;
-
- /* Check that the value-statement is inside a function call, or has
- side-effects by directly or indirectly calling ‘\set/3’ on an
- array that is not shadowed by an inner function- or macro-call. */
- if (r && !have_side_effect)
- {
- NEW_ERROR(tree, ERROR, "value-statement outside function without side-effects");
- tree->processed = PROCESS_LEVEL;
- }
- if (have_side_effect)
- last_value_statement = NULL;
-
- /* Check whether we made a previous value-statement unnecessary. */
- if (previous_last_value_statement)
- {
- /* For simplicity we set `last_value_statement` on includes,
- * so we are sure `last_value_statement` has the same include-stack. */
-
- NEW_ERROR(previous_last_value_statement, WARNING, "value-statement has no effects");
- NEW_ERROR(tree, NOTE, "overridden here");
- }
-
-
- done:
- mds_kbdc_tree_free(seq);
- mds_kbdc_tree_free(res);
- have_side_effect |= old_have_side_effect;
- return 0;
- FAIL_BEGIN;
- mds_kbdc_include_stack_free(include_stack);
- mds_kbdc_tree_free((mds_kbdc_tree_t*)dup_map);
- mds_kbdc_tree_free(seq);
- mds_kbdc_tree_free(res);
- tree->sequence = old_seq;
- tree->result = old_res;
- have_side_effect = old_have_side_effect;
- FAIL_END;
+ int bad = 0, old_have_side_effect = have_side_effect;
+ mds_kbdc_include_stack_t *restrict include_stack = NULL;
+ mds_kbdc_tree_t *seq = NULL;
+ mds_kbdc_tree_t *res = NULL;
+ mds_kbdc_tree_t *old_seq = tree->sequence;
+ mds_kbdc_tree_t *old_res = tree->result;
+ mds_kbdc_tree_map_t *dup_map = NULL;
+ int r, saved_errno;
+ mds_kbdc_tree_t *previous_last_value_statement = last_value_statement;
+
+ have_side_effect = 0;
+
+ /* Duplicate arguments and evaluate function calls,
+ variable dereferences and escapes in the mapping
+ input sequence. */
+ fail_if (!(seq = mds_kbdc_tree_dup(old_seq)));
+ fail_if ((bad |= evaluate_element(seq)) < 0);
+
+ /* Duplicate arguments and evaluate function calls,
+ variable dereferences and escapes in the mapping
+ output sequence, unless this is a value-statement. */
+ if (tree->result) {
+ fail_if (!(res = mds_kbdc_tree_dup(old_res)));
+ fail_if ((bad |= evaluate_element(res)) < 0);
+ }
+
+ /* Stop if any of the mapping-arguments could not be evaluated. */
+ if (bad)
+ goto done;
+
+
+ if (tree->result) {
+ /* Mapping-statement. */
+
+ /* Check for invalid characters in the mapping-arguments. */
+ fail_if ((bad |= check_nonnul(seq)) < 0);
+ fail_if ((bad |= check_nonnul(res)) < 0);
+ if (bad)
+ goto done;
+
+ /* Duplicate the mapping-statement but give it the evaluated mapping-arguments. */
+ tree->sequence = NULL;
+ tree->result = NULL;
+ fail_if (!(dup_map = &mds_kbdc_tree_dup((mds_kbdc_tree_t *)tree)->map));
+ tree->sequence = old_seq, dup_map->sequence = seq, seq = NULL;
+ tree->result = old_res, dup_map->result = res, res = NULL;
+
+ /* Enlist the mapping for assembling. */
+ fail_if (!(include_stack = mds_kbdc_include_stack_save()));
+ fail_if (add_mapping(dup_map, include_stack));
+
+ goto done;
+ }
+
+
+ /* Value-statement */
+
+ /* Save this statement so we can warn later if it is unnecessary,
+ * `set_return_value` will set it to `NULL` if there are side-effects,
+ * which would make this statement necessary (unless the overridding
+ * statement has identical side-effect, but we will not check for that).
+ * For simplicity, we do not store the include-stack, instead, we reset
+ * `last_value_statement` to `NULL` when we visit an include-statement. */
+ last_value_statement = (mds_kbdc_tree_t *)tree;
+
+ /* Add the value statement */
+ r = set_return_value(seq->compiled_string.string);
+ seq->compiled_string.string = NULL;
+
+ /* Check that the value-statement is inside a function call, or has
+ side-effects by directly or indirectly calling ‘\set/3’ on an
+ array that is not shadowed by an inner function- or macro-call. */
+ if (r && !have_side_effect) {
+ NEW_ERROR(tree, ERROR, "value-statement outside function without side-effects");
+ tree->processed = PROCESS_LEVEL;
+ }
+ if (have_side_effect)
+ last_value_statement = NULL;
+
+ /* Check whether we made a previous value-statement unnecessary. */
+ if (previous_last_value_statement) {
+ /* For simplicity we set `last_value_statement` on includes,
+ * so we are sure `last_value_statement` has the same include-stack. */
+
+ NEW_ERROR(previous_last_value_statement, WARNING, "value-statement has no effects");
+ NEW_ERROR(tree, NOTE, "overridden here");
+ }
+
+
+done:
+ mds_kbdc_tree_free(seq);
+ mds_kbdc_tree_free(res);
+ have_side_effect |= old_have_side_effect;
+ return 0;
+ FAIL_BEGIN;
+ mds_kbdc_include_stack_free(include_stack);
+ mds_kbdc_tree_free((mds_kbdc_tree_t*)dup_map);
+ mds_kbdc_tree_free(seq);
+ mds_kbdc_tree_free(res);
+ tree->sequence = old_seq;
+ tree->result = old_res;
+ have_side_effect = old_have_side_effect;
+ FAIL_END;
}
@@ -2464,70 +2428,71 @@ static int compile_map(mds_kbdc_tree_map_t* restrict tree)
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_macro_call(mds_kbdc_tree_macro_call_t* restrict tree)
+static int
+compile_macro_call(mds_kbdc_tree_macro_call_t *restrict tree)
{
- mds_kbdc_tree_t* arg = NULL;
- mds_kbdc_tree_t* arg_;
- mds_kbdc_tree_macro_t* macro;
- mds_kbdc_include_stack_t* macro_include_stack;
- mds_kbdc_include_stack_t* our_include_stack = NULL;
- size_t variable = 0;
- int bad, saved_errno;
-
- last_value_statement = NULL;
-
- /* Push call-stack. */
- mds_kbdc_call_stack_push((mds_kbdc_tree_t*)tree, tree->loc_start, tree->loc_end);
-
- /* Duplicate arguments and evaluate function calls,
- variable dereferences and escapes in the macro
- call arguments. */
- if (tree->arguments)
- fail_if (arg = mds_kbdc_tree_dup(tree->arguments), arg == NULL);
- fail_if (bad = evaluate_element(arg), bad < 0);
- if (bad)
- return mds_kbdc_tree_free(arg), 0;
-
- /* Get the macro's subtree and include-stack, if it has
- not been defined `get_macro` will add an error message
- and return `NULL`. */
- fail_if (get_macro(tree, &macro, &macro_include_stack));
- if (macro == NULL)
- goto done;
-
-
- /* Push variable-stack and set parameters. */
- variables_stack_push();
- for (arg_ = arg; arg_; arg_ = arg_->next)
- fail_if (let(++variable, NULL, arg_, NULL, 0, 0));
-
- /* Switch include-stack to the macro's. */
- fail_if (our_include_stack = mds_kbdc_include_stack_save(), our_include_stack == NULL);
- fail_if (mds_kbdc_include_stack_restore(macro_include_stack));
-
- /* Call the macro. */
- fail_if (compile_subtree(macro->inner));
-
- /* Switch back the include-stack to ours. */
- fail_if (mds_kbdc_include_stack_restore(our_include_stack));
- mds_kbdc_include_stack_free(our_include_stack), our_include_stack = NULL;
-
- /* Pop variable-stack. */
- variables_stack_pop();
-
- done:
- /* Pop call-stack. */
- mds_kbdc_call_stack_pop();
-
- last_value_statement = NULL;
- break_level = 0;
- mds_kbdc_tree_free(arg);
- return 0;
- FAIL_BEGIN;
- mds_kbdc_call_stack_pop();
- mds_kbdc_tree_free(arg);
- mds_kbdc_include_stack_free(our_include_stack);
- FAIL_END;
+ mds_kbdc_tree_t *arg = NULL;
+ mds_kbdc_tree_t *arg_;
+ mds_kbdc_tree_macro_t *macro;
+ mds_kbdc_include_stack_t *macro_include_stack;
+ mds_kbdc_include_stack_t *our_include_stack = NULL;
+ size_t variable = 0;
+ int bad, saved_errno;
+
+ last_value_statement = NULL;
+
+ /* Push call-stack. */
+ mds_kbdc_call_stack_push((mds_kbdc_tree_t *)tree, tree->loc_start, tree->loc_end);
+
+ /* Duplicate arguments and evaluate function calls,
+ variable dereferences and escapes in the macro
+ call arguments. */
+ if (tree->arguments)
+ fail_if (!(arg = mds_kbdc_tree_dup(tree->arguments)));
+ fail_if (bad = evaluate_element(arg), bad < 0);
+ if (bad)
+ return mds_kbdc_tree_free(arg), 0;
+
+ /* Get the macro's subtree and include-stack, if it has
+ not been defined `get_macro` will add an error message
+ and return `NULL`. */
+ fail_if (get_macro(tree, &macro, &macro_include_stack));
+ if (!macro)
+ goto done;
+
+
+ /* Push variable-stack and set parameters. */
+ variables_stack_push();
+ for (arg_ = arg; arg_; arg_ = arg_->next)
+ fail_if (let(++variable, NULL, arg_, NULL, 0, 0));
+
+ /* Switch include-stack to the macro's. */
+ fail_if (!(our_include_stack = mds_kbdc_include_stack_save()));
+ fail_if (mds_kbdc_include_stack_restore(macro_include_stack));
+
+ /* Call the macro. */
+ fail_if (compile_subtree(macro->inner));
+
+ /* Switch back the include-stack to ours. */
+ fail_if (mds_kbdc_include_stack_restore(our_include_stack));
+ mds_kbdc_include_stack_free(our_include_stack), our_include_stack = NULL;
+
+ /* Pop variable-stack. */
+ variables_stack_pop();
+
+done:
+ /* Pop call-stack. */
+ mds_kbdc_call_stack_pop();
+
+ last_value_statement = NULL;
+ break_level = 0;
+ mds_kbdc_tree_free(arg);
+ return 0;
+ FAIL_BEGIN;
+ mds_kbdc_call_stack_pop();
+ mds_kbdc_tree_free(arg);
+ mds_kbdc_include_stack_free(our_include_stack);
+ FAIL_END;
}
@@ -2537,64 +2502,64 @@ static int compile_macro_call(mds_kbdc_tree_macro_call_t* restrict tree)
* @param tree The tree to compile
* @return Zero on success, -1 on error
*/
-static int compile_subtree(mds_kbdc_tree_t* restrict tree)
+static int
+compile_subtree(mds_kbdc_tree_t *restrict tree)
{
-#define t(expr) fail_if ((expr) < 0)
-#define c(type) t (compile_##type(&(tree->type)))
-#define c_(type) t (compile_##type(&(tree->type##_)))
- again:
- if (tree == NULL)
- return 0;
-
- if (tree->processed == PROCESS_LEVEL)
- /* An error has occurred here before, let's skip it so
- * we do not deluge the user with errors. */
- goto next;
-
- switch (tree->type)
- {
- case C(INFORMATION):
- t (compile_subtree(tree->information.inner));
- break;
- case C(INFORMATION_LANGUAGE): c (language); break;
- case C(INFORMATION_COUNTRY): c (country); break;
- case C(INFORMATION_VARIANT): c (variant); break;
- case C(INCLUDE): c (include); break;
- case C(FUNCTION): c (function); break;
- case C(MACRO): c (macro); break;
- case C(ASSUMPTION):
- if (includes_ptr == 0)
- fail_if (compile_subtree(tree->assumption.inner));
- break;
- case C(ASSUMPTION_HAVE): c (have); break;
- case C(ASSUMPTION_HAVE_CHARS): c (have_chars); break;
- case C(ASSUMPTION_HAVE_RANGE): c (have_range); break;
- case C(FOR): c_ (for); break;
- case C(IF): c_ (if); break;
- case C(LET): c (let); break;
- case C(KEYS): c (keys); break;
- case C(STRING): c (string); break;
- case C(ARRAY): c (array); break;
- case C(MAP): c (map); break;
- case C(MACRO_CALL): c (macro_call); break;
- case C(RETURN): break_level = 3; break;
- case C(BREAK): break_level = 2; break;
- case C(CONTINUE): break_level = 1; break;
- default:
- break;
- }
-
+#define t(expr) fail_if ((expr) < 0)
+#define c(type) t (compile_##type(&tree->type))
+#define c_(type) t (compile_##type(&tree->type##_))
+again:
+ if (!tree)
+ return 0;
+
+ if (tree->processed == PROCESS_LEVEL)
+ /* An error has occurred here before, let's skip it so
+ * we do not deluge the user with errors. */
+ goto next;
+
+ switch (tree->type) {
+ case C(INFORMATION):
+ t (compile_subtree(tree->information.inner));
+ break;
+ case C(INFORMATION_LANGUAGE): c (language); break;
+ case C(INFORMATION_COUNTRY): c (country); break;
+ case C(INFORMATION_VARIANT): c (variant); break;
+ case C(INCLUDE): c (include); break;
+ case C(FUNCTION): c (function); break;
+ case C(MACRO): c (macro); break;
+ case C(ASSUMPTION):
+ if (!includes_ptr)
+ fail_if (compile_subtree(tree->assumption.inner));
+ break;
+ case C(ASSUMPTION_HAVE): c (have); break;
+ case C(ASSUMPTION_HAVE_CHARS): c (have_chars); break;
+ case C(ASSUMPTION_HAVE_RANGE): c (have_range); break;
+ case C(FOR): c_ (for); break;
+ case C(IF): c_ (if); break;
+ case C(LET): c (let); break;
+ case C(KEYS): c (keys); break;
+ case C(STRING): c (string); break;
+ case C(ARRAY): c (array); break;
+ case C(MAP): c (map); break;
+ case C(MACRO_CALL): c (macro_call); break;
+ case C(RETURN): break_level = 3; break;
+ case C(BREAK): break_level = 2; break;
+ case C(CONTINUE): break_level = 1; break;
+ default:
+ break;
+ }
+
next:
- if (break_level)
- /* If a `continue`, `break` or `return` has been encountered,
- * we are done here and should return to whence we came and
- * let the subcompiler of that construct deal with it. */
- return 0;
-
- tree = tree->next;
- goto again;
- fail:
- return -1;
+ if (break_level)
+ /* If a `continue`, `break` or `return` has been encountered,
+ * we are done here and should return to whence we came and
+ * let the subcompiler of that construct deal with it. */
+ return 0;
+
+ tree = tree->next;
+ goto again;
+fail:
+ return -1;
#undef c_
#undef c
#undef t
@@ -2607,23 +2572,24 @@ static int compile_subtree(mds_kbdc_tree_t* restrict tree)
* @param result_ `result` from `eliminate_dead_code`, will be updated
* @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
*/
-int compile_layout(mds_kbdc_parsed_t* restrict result_)
+int
+compile_layout(mds_kbdc_parsed_t *restrict result_)
{
- int r, saved_errno;
- result = result_;
- mds_kbdc_include_stack_begin(result_);
- mds_kbdc_call_stack_begin(result_);
- r = compile_subtree(result_->tree);
- saved_errno = errno;
- mds_kbdc_call_stack_end();
- mds_kbdc_include_stack_end();
- variables_terminate();
- callables_terminate();
- errno = saved_errno;
- fail_if (r);
- return 0;
- fail:
- return -1;
+ int r, saved_errno;
+ result = result_;
+ mds_kbdc_include_stack_begin(result_);
+ mds_kbdc_call_stack_begin(result_);
+ r = compile_subtree(result_->tree);
+ saved_errno = errno;
+ mds_kbdc_call_stack_end();
+ mds_kbdc_include_stack_end();
+ variables_terminate();
+ callables_terminate();
+ errno = saved_errno;
+ fail_if (r);
+ return 0;
+fail:
+ return -1;
}
@@ -2633,4 +2599,3 @@ int compile_layout(mds_kbdc_parsed_t* restrict result_)
#undef NEW_ERROR
#undef C
#undef PROCESS_LEVEL
-
diff --git a/src/mds-kbdc/compile-layout.h b/src/mds-kbdc/compile-layout.h
index 6911a71..86604e0 100644
--- a/src/mds-kbdc/compile-layout.h
+++ b/src/mds-kbdc/compile-layout.h
@@ -28,8 +28,7 @@
* @param result `result` from `eliminate_dead_code`, will be updated
* @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
*/
-int compile_layout(mds_kbdc_parsed_t* restrict result);
+int compile_layout(mds_kbdc_parsed_t *restrict result);
#endif
-
diff --git a/src/mds-kbdc/eliminate-dead-code.c b/src/mds-kbdc/eliminate-dead-code.c
index 039b6a8..5a8102f 100644
--- a/src/mds-kbdc/eliminate-dead-code.c
+++ b/src/mds-kbdc/eliminate-dead-code.c
@@ -27,7 +27,7 @@
/**
* Tree type constant shortener
*/
-#define C(TYPE) MDS_KBDC_TREE_TYPE_##TYPE
+#define C(TYPE) MDS_KBDC_TREE_TYPE_##TYPE
/**
* Add an error with “included from here”-notes to the error list
@@ -38,20 +38,20 @@
* @param ...:const char*, ... Error description format string and arguments
* @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
*/
-#define NEW_ERROR(NODE, PTR, SEVERITY, ...) \
- NEW_ERROR_WITH_INCLUDES(NODE, PTR, SEVERITY, __VA_ARGS__)
+#define NEW_ERROR(NODE, PTR, SEVERITY, ...)\
+ NEW_ERROR_WITH_INCLUDES(NODE, PTR, SEVERITY, __VA_ARGS__)
/**
* Variable whether the latest created error is stored
*/
-static mds_kbdc_parse_error_t* error;
+static mds_kbdc_parse_error_t *error;
/**
* The parameter of `eliminate_dead_code`
*/
-static mds_kbdc_parsed_t* restrict result;
+static mds_kbdc_parsed_t *restrict result;
/**
* 2: Eliminating because of a return-statement
@@ -68,7 +68,7 @@ static int elimination_level = 0;
* @param tree The tree to reduce
* @return Zero on success, -1 on error
*/
-static int eliminate_subtree(mds_kbdc_tree_t* restrict tree);
+static int eliminate_subtree(mds_kbdc_tree_t *restrict tree);
@@ -78,17 +78,18 @@ static int eliminate_subtree(mds_kbdc_tree_t* restrict tree);
* @param tree The tree to reduce
* @return Zero on success, -1 on error
*/
-static int eliminate_include(mds_kbdc_tree_include_t* restrict tree)
+static int
+eliminate_include(mds_kbdc_tree_include_t *restrict tree)
{
- void* data;
- int r;
- fail_if (mds_kbdc_include_stack_push(tree, &data));
- r = eliminate_subtree(tree->inner);
- mds_kbdc_include_stack_pop(data);
- fail_if (r);
- return 0;
- fail:
- return -1;
+ void *data;
+ int r;
+ fail_if (mds_kbdc_include_stack_push(tree, &data));
+ r = eliminate_subtree(tree->inner);
+ mds_kbdc_include_stack_pop(data);
+ fail_if (r);
+ return 0;
+fail:
+ return -1;
}
@@ -98,17 +99,18 @@ static int eliminate_include(mds_kbdc_tree_include_t* restrict tree)
* @param tree The tree to reduce
* @return Zero on success, -1 on error
*/
-static int eliminate_if(mds_kbdc_tree_if_t* restrict tree)
+static int
+eliminate_if(mds_kbdc_tree_if_t *restrict tree)
{
- int elimination;
- fail_if (eliminate_subtree(tree->inner));
- elimination = elimination_level, elimination_level = 0;
- fail_if (eliminate_subtree(tree->otherwise));
- if (elimination > elimination_level)
- elimination = elimination_level;
- return 0;
- fail:
- return -1;
+ int elimination;
+ fail_if (eliminate_subtree(tree->inner));
+ elimination = elimination_level, elimination_level = 0;
+ fail_if (eliminate_subtree(tree->otherwise));
+ if (elimination > elimination_level)
+ elimination = elimination_level;
+ return 0;
+fail:
+ return -1;
}
@@ -118,46 +120,51 @@ static int eliminate_if(mds_kbdc_tree_if_t* restrict tree)
* @param tree The tree to reduce
* @return Zero on success, -1 on error
*/
-static int eliminate_subtree(mds_kbdc_tree_t* restrict tree)
+static int
+eliminate_subtree(mds_kbdc_tree_t *restrict tree)
{
-#define e(type) fail_if (eliminate_##type(&(tree->type)))
-#define E(type) fail_if (eliminate_##type(&(tree->type##_)))
- again:
- if (tree == NULL)
- return 0;
+#define e(type) fail_if (eliminate_##type(&tree->type))
+#define E(type) fail_if (eliminate_##type(&tree->type##_))
+again:
+ if (!tree)
+ return 0;
- switch (tree->type)
- {
- case C(INCLUDE): e(include); break;
- case C(IF): E(if); break;
- case C(INFORMATION):
- case C(FUNCTION):
- case C(MACRO):
- case C(ASSUMPTION):
- case C(FOR):
- fail_if (eliminate_subtree(tree->information.inner));
- if ((tree->type == C(FUNCTION)) || (tree->type == C(MACRO))) elimination_level = 0;
- else if ((tree->type == C(FOR)) && (elimination_level == 1)) elimination_level = 0;
- break;
- case C(RETURN):
- case C(BREAK):
- case C(CONTINUE):
- elimination_level = tree->type == C(RETURN) ? 2 : 1;
- break;
- default:
- break;
- }
-
- if (tree->next && elimination_level)
- {
- NEW_ERROR(tree->next, includes_ptr, WARNING, "statement is unreachable");
- mds_kbdc_tree_free(tree->next), tree->next = NULL;
- }
-
- tree = tree->next;
- goto again;
- fail:
- return -1;
+ switch (tree->type) {
+ case C(INCLUDE):
+ e(include);
+ break;
+ case C(IF):
+ E(if);
+ break;
+ case C(INFORMATION):
+ case C(FUNCTION):
+ case C(MACRO):
+ case C(ASSUMPTION):
+ case C(FOR):
+ fail_if (eliminate_subtree(tree->information.inner));
+ if (tree->type == C(FUNCTION) || tree->type == C(MACRO))
+ elimination_level = 0;
+ else if (tree->type == C(FOR) && elimination_level == 1)
+ elimination_level = 0;
+ break;
+ case C(RETURN):
+ case C(BREAK):
+ case C(CONTINUE):
+ elimination_level = tree->type == C(RETURN) ? 2 : 1;
+ break;
+ default:
+ break;
+ }
+
+ if (tree->next && elimination_level) {
+ NEW_ERROR(tree->next, includes_ptr, WARNING, "statement is unreachable");
+ mds_kbdc_tree_free(tree->next), tree->next = NULL;
+ }
+
+ tree = tree->next;
+ goto again;
+fail:
+ return -1;
#undef E
#undef e
}
@@ -169,20 +176,20 @@ static int eliminate_subtree(mds_kbdc_tree_t* restrict tree)
* @param result_ `result` from `validate_tree`, will be updated
* @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
*/
-int eliminate_dead_code(mds_kbdc_parsed_t* restrict result_)
+int
+eliminate_dead_code(mds_kbdc_parsed_t *restrict result_)
{
- int r;
- mds_kbdc_include_stack_begin(result = result_);
- r = eliminate_subtree(result_->tree);
- mds_kbdc_include_stack_end();
- fail_if (r);
- return 0;
- fail:
- return -1;
+ int r;
+ mds_kbdc_include_stack_begin(result = result_);
+ r = eliminate_subtree(result_->tree);
+ mds_kbdc_include_stack_end();
+ fail_if (r);
+ return 0;
+fail:
+ return -1;
}
#undef NEW_ERROR
#undef C
-
diff --git a/src/mds-kbdc/eliminate-dead-code.h b/src/mds-kbdc/eliminate-dead-code.h
index cbdf731..84bc3b6 100644
--- a/src/mds-kbdc/eliminate-dead-code.h
+++ b/src/mds-kbdc/eliminate-dead-code.h
@@ -28,8 +28,7 @@
* @param result `result` from `validate_tree`, will be updated
* @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
*/
-int eliminate_dead_code(mds_kbdc_parsed_t* restrict result);
+int eliminate_dead_code(mds_kbdc_parsed_t *restrict result);
#endif
-
diff --git a/src/mds-kbdc/globals.c b/src/mds-kbdc/globals.c
index 8e17020..01feca9 100644
--- a/src/mds-kbdc/globals.c
+++ b/src/mds-kbdc/globals.c
@@ -26,10 +26,9 @@ int argc;
/**
* The command line arguments
*/
-char** argv;
+char **argv;
/**
* Whether ‘--force’ is used
*/
int argv_force = 0;
-
diff --git a/src/mds-kbdc/globals.h b/src/mds-kbdc/globals.h
index b2b5cf1..1acf4bc 100644
--- a/src/mds-kbdc/globals.h
+++ b/src/mds-kbdc/globals.h
@@ -27,7 +27,7 @@ extern int argc;
/**
* The command line arguments
*/
-extern char** argv;
+extern char **argv;
/**
* Whether ‘--force’ is used
@@ -36,4 +36,3 @@ extern int argv_force;
#endif
-
diff --git a/src/mds-kbdc/include-stack.c b/src/mds-kbdc/include-stack.c
index 18b13d7..8ba787f 100644
--- a/src/mds-kbdc/include-stack.c
+++ b/src/mds-kbdc/include-stack.c
@@ -27,27 +27,27 @@
/**
* Variable whether the latest created error is stored
*/
-static mds_kbdc_parse_error_t* error;
+static mds_kbdc_parse_error_t *error;
/**
* The `result` parameter of root procedure that requires the include-stack
*/
-static mds_kbdc_parsed_t* result;
+static mds_kbdc_parsed_t *result;
/**
* The original value of `result->pathname`
*/
-static char* original_pathname;
+static char *original_pathname;
/**
* The original value of `result->source_code`
*/
-static mds_kbdc_source_code_t* original_source_code;
+static mds_kbdc_source_code_t *original_source_code;
/**
* Stack of visited include-statements
*/
-static const mds_kbdc_tree_include_t** restrict includes = NULL;
+static const mds_kbdc_tree_include_t **restrict includes = NULL;
/**
* The number elements allocated for `includes`
@@ -62,7 +62,7 @@ size_t includes_ptr = 0;
/**
* The latest saved include-stack
*/
-static mds_kbdc_include_stack_t* latest_save = NULL;
+static mds_kbdc_include_stack_t *latest_save = NULL;
@@ -72,23 +72,23 @@ static mds_kbdc_include_stack_t* latest_save = NULL;
* @param ptr The number of “included from here”-notes
* @return Zero on success, -1 on error
*/
-int mds_kbdc_include_stack_dump(size_t ptr)
+int
+mds_kbdc_include_stack_dump(size_t ptr)
{
- char* old_pathname = result->pathname;
- mds_kbdc_source_code_t* old_source_code = result->source_code;
- while (ptr--)
- {
- result->pathname = ptr ? includes[ptr - 1]->filename : original_pathname;
- result->source_code = ptr ? includes[ptr - 1]->source_code : original_source_code;
- NEW_ERROR_WITHOUT_INCLUDES(includes[ptr], NOTE, "included from here");
- }
- result->pathname = old_pathname;
- result->source_code = old_source_code;
- return 0;
- fail:
- result->pathname = old_pathname;
- result->source_code = old_source_code;
- return -1;
+ char *old_pathname = result->pathname;
+ mds_kbdc_source_code_t *old_source_code = result->source_code;
+ while (ptr--) {
+ result->pathname = ptr ? includes[ptr - 1]->filename : original_pathname;
+ result->source_code = ptr ? includes[ptr - 1]->source_code : original_source_code;
+ NEW_ERROR_WITHOUT_INCLUDES(includes[ptr], NOTE, "included from here");
+ }
+ result->pathname = old_pathname;
+ result->source_code = old_source_code;
+ return 0;
+fail:
+ result->pathname = old_pathname;
+ result->source_code = old_source_code;
+ return -1;
}
@@ -97,11 +97,12 @@ int mds_kbdc_include_stack_dump(size_t ptr)
*
* @param result_ The `result` parameter of root procedure that requires the include-stack
*/
-void mds_kbdc_include_stack_begin(mds_kbdc_parsed_t* restrict result_)
+void
+mds_kbdc_include_stack_begin(mds_kbdc_parsed_t *restrict result_)
{
- result = result_;
- original_pathname = result_->pathname;
- original_source_code = result_->source_code;
+ result = result_;
+ original_pathname = result_->pathname;
+ original_source_code = result_->source_code;
}
@@ -109,13 +110,14 @@ void mds_kbdc_include_stack_begin(mds_kbdc_parsed_t* restrict result_)
* Mark the root of the tree as no longer being visited,
* and release clean up after the use of this module
*/
-void mds_kbdc_include_stack_end(void)
+void
+mds_kbdc_include_stack_end(void)
{
- latest_save = NULL;
- result->pathname = original_pathname;
- result->source_code = original_source_code;
- free(includes), includes = NULL;
- includes_size = includes_ptr = 0;
+ latest_save = NULL;
+ result->pathname = original_pathname;
+ result->source_code = original_source_code;
+ free(includes), includes = NULL;
+ includes_size = includes_ptr = 0;
}
@@ -128,30 +130,31 @@ void mds_kbdc_include_stack_end(void)
* is undefined on error
* @return Zero on success, -1 on error
*/
-int mds_kbdc_include_stack_push(const mds_kbdc_tree_include_t* restrict tree, void** data)
+int
+mds_kbdc_include_stack_push(const mds_kbdc_tree_include_t *restrict tree, void **data)
{
- const mds_kbdc_tree_include_t** old = NULL;
- int saved_errno;
-
- if (includes_ptr == includes_size)
- fail_if (xxrealloc(old, includes, includes_size += 4, const mds_kbdc_tree_include_t*));
-
- fail_if (xmalloc(*data, 3, void*));
-
- ((char**)(*data))[0] = result->pathname;
- ((mds_kbdc_source_code_t**)(*data))[1] = result->source_code;
- ((mds_kbdc_include_stack_t**)(*data))[2] = latest_save;
-
- includes[includes_ptr++] = tree;
- result->pathname = tree->filename;
- result->source_code = tree->source_code;
- latest_save = NULL;
-
- return 0;
- fail:
- saved_errno = errno;
- free(old);
- return errno = saved_errno, -1;
+ const mds_kbdc_tree_include_t **old = NULL;
+ int saved_errno;
+
+ if (includes_ptr == includes_size)
+ fail_if (xxrealloc(old, includes, includes_size += 4, const mds_kbdc_tree_include_t*));
+
+ fail_if (xmalloc(*data, 3, void*));
+
+ ((char **)(*data))[0] = result->pathname;
+ ((mds_kbdc_source_code_t **)(*data))[1] = result->source_code;
+ ((mds_kbdc_include_stack_t **)(*data))[2] = latest_save;
+
+ includes[includes_ptr++] = tree;
+ result->pathname = tree->filename;
+ result->source_code = tree->source_code;
+ latest_save = NULL;
+
+ return 0;
+fail:
+ saved_errno = errno;
+ free(old);
+ return errno = saved_errno, -1;
}
@@ -162,15 +165,16 @@ int mds_kbdc_include_stack_push(const mds_kbdc_tree_include_t* restrict tree, vo
*
* @param data `*data` from `mds_kbdc_include_stack_push`
*/
-void mds_kbdc_include_stack_pop(void* data)
+void
+mds_kbdc_include_stack_pop(void *data)
{
- int saved_errno = errno;
- result->pathname = ((char**)data)[0];
- result->source_code = ((mds_kbdc_source_code_t**)data)[1];
- latest_save = ((mds_kbdc_include_stack_t**)data)[2];
- includes_ptr--;
- free(data);
- errno = saved_errno;
+ int saved_errno = errno;
+ result->pathname = ((char **)data)[0];
+ result->source_code = ((mds_kbdc_source_code_t **)data)[1];
+ latest_save = ((mds_kbdc_include_stack_t **)data)[2];
+ includes_ptr--;
+ free(data);
+ errno = saved_errno;
}
@@ -179,34 +183,34 @@ void mds_kbdc_include_stack_pop(void* data)
*
* @return The include-stack, `NULL` on error
*/
-mds_kbdc_include_stack_t* mds_kbdc_include_stack_save(void)
+mds_kbdc_include_stack_t *
+mds_kbdc_include_stack_save(void)
{
- int saved_errno;
-
- if (latest_save)
- {
- latest_save->duplicates++;
- return latest_save;
- }
-
- fail_if (xmalloc(latest_save, 1, mds_kbdc_include_stack_t));
-
- latest_save->stack = NULL;
- latest_save->ptr = includes_ptr;
- latest_save->duplicates = 0;
-
- if (latest_save->ptr == 0)
- return latest_save;
-
- fail_if (xmemdup(latest_save->stack, includes, latest_save->ptr, const mds_kbdc_tree_include_t*));
-
- return latest_save;
- fail:
- saved_errno = errno;
- if (latest_save)
- free(latest_save->stack), latest_save = NULL;
- errno = saved_errno;
- return NULL;
+ int saved_errno;
+
+ if (latest_save) {
+ latest_save->duplicates++;
+ return latest_save;
+ }
+
+ fail_if (xmalloc(latest_save, 1, mds_kbdc_include_stack_t));
+
+ latest_save->stack = NULL;
+ latest_save->ptr = includes_ptr;
+ latest_save->duplicates = 0;
+
+ if (!latest_save->ptr)
+ return latest_save;
+
+ fail_if (xmemdup(latest_save->stack, includes, latest_save->ptr, const mds_kbdc_tree_include_t*));
+
+ return latest_save;
+fail:
+ saved_errno = errno;
+ if (latest_save)
+ free(latest_save->stack), latest_save = NULL;
+ errno = saved_errno;
+ return NULL;
}
@@ -216,23 +220,23 @@ mds_kbdc_include_stack_t* mds_kbdc_include_stack_save(void)
* @param stack The include-stack
* @return Zero on success, -1 on error
*/
-int mds_kbdc_include_stack_restore(mds_kbdc_include_stack_t* restrict stack)
+int
+mds_kbdc_include_stack_restore(mds_kbdc_include_stack_t *restrict stack)
{
- const mds_kbdc_tree_include_t** tmp;
-
- latest_save = stack;
-
- if (stack->ptr > includes_size)
- {
- fail_if (yrealloc(tmp, includes, stack->ptr, const mds_kbdc_tree_include_t*));
- includes_size = stack->ptr;
- }
-
- memcpy(includes, stack->stack, stack->ptr * sizeof(const mds_kbdc_tree_include_t*));
- includes_ptr = stack->ptr;
- return 0;
- fail:
- return -1;
+ const mds_kbdc_tree_include_t **tmp;
+
+ latest_save = stack;
+
+ if (stack->ptr > includes_size) {
+ fail_if (yrealloc(tmp, includes, stack->ptr, const mds_kbdc_tree_include_t *));
+ includes_size = stack->ptr;
+ }
+
+ memcpy(includes, stack->stack, stack->ptr * sizeof(const mds_kbdc_tree_include_t *));
+ includes_ptr = stack->ptr;
+ return 0;
+fail:
+ return -1;
}
@@ -241,13 +245,13 @@ int mds_kbdc_include_stack_restore(mds_kbdc_include_stack_t* restrict stack)
*
* @param stack The include-stack
*/
-void mds_kbdc_include_stack_free(mds_kbdc_include_stack_t* restrict stack)
+void
+mds_kbdc_include_stack_free(mds_kbdc_include_stack_t *restrict stack)
{
- if ((stack == NULL) || (stack->duplicates--))
- return;
- free(stack->stack);
- free(stack);
- if (latest_save == stack)
- latest_save = NULL;
+ if (!stack || stack->duplicates--)
+ return;
+ free(stack->stack);
+ free(stack);
+ if (latest_save == stack)
+ latest_save = NULL;
}
-
diff --git a/src/mds-kbdc/include-stack.h b/src/mds-kbdc/include-stack.h
index c077e2b..284bb02 100644
--- a/src/mds-kbdc/include-stack.h
+++ b/src/mds-kbdc/include-stack.h
@@ -31,17 +31,17 @@
* @param ...:const char*, ... Error description format string and arguments
* @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
*/
-#define NEW_ERROR_WITHOUT_INCLUDES(NODE, SEVERITY, ...) \
- NEW_ERROR_(result, SEVERITY, 1, (NODE)->loc_line, \
- (NODE)->loc_start, (NODE)->loc_end, 1, __VA_ARGS__)
+#define NEW_ERROR_WITHOUT_INCLUDES(NODE, SEVERITY, ...)\
+ NEW_ERROR_(result, SEVERITY, 1, (NODE)->loc_line,\
+ (NODE)->loc_start, (NODE)->loc_end, 1, __VA_ARGS__)
/**
* Add “included from here”-notes
*
* @param PTR:size_t The number of “included from here”-notes
*/
-#define DUMP_INCLUDE_STACK(PTR) \
- fail_if (mds_kbdc_include_stack_dump(PTR))
+#define DUMP_INCLUDE_STACK(PTR)\
+ fail_if (mds_kbdc_include_stack_dump(PTR))
/**
* Add an error with “included from here”-notes to the error list
@@ -52,36 +52,32 @@
* @param ...:const char*, ... Error description format string and arguments
* @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
*/
-#define NEW_ERROR_WITH_INCLUDES(NODE, PTR, SEVERITY, ...) \
- do \
- { \
- NEW_ERROR_WITHOUT_INCLUDES(NODE, SEVERITY, __VA_ARGS__); \
- DUMP_INCLUDE_STACK(PTR); \
- } \
- while (0)
+#define NEW_ERROR_WITH_INCLUDES(NODE, PTR, SEVERITY, ...)\
+ do {\
+ NEW_ERROR_WITHOUT_INCLUDES(NODE, SEVERITY, __VA_ARGS__);\
+ DUMP_INCLUDE_STACK(PTR);\
+ } while (0)
/**
* A saved state of the include-stack
*/
-typedef struct mds_kbdc_include_stack
-{
- /**
- * Stack of visited include-statements
- */
- const mds_kbdc_tree_include_t** stack;
-
- /**
- * The number elements stored in `stack` (do not edit)
- */
- size_t ptr;
-
- /**
- * The number of duplicates there are of this object
- */
- size_t duplicates;
-
+typedef struct mds_kbdc_include_stack {
+ /**
+ * Stack of visited include-statements
+ */
+ const mds_kbdc_tree_include_t **stack;
+
+ /**
+ * The number elements stored in `stack` (do not edit)
+ */
+ size_t ptr;
+
+ /**
+ * The number of duplicates there are of this object
+ */
+ size_t duplicates;
} mds_kbdc_include_stack_t;
@@ -107,7 +103,7 @@ int mds_kbdc_include_stack_dump(size_t ptr);
*
* @param result The `result` parameter of root procedure that requires the include-stack
*/
-void mds_kbdc_include_stack_begin(mds_kbdc_parsed_t* restrict result);
+void mds_kbdc_include_stack_begin(mds_kbdc_parsed_t *restrict result);
/**
* Mark the root of the tree as no longer being visited,
@@ -124,7 +120,7 @@ void mds_kbdc_include_stack_end(void);
* is undefined on error
* @return Zero on success, -1 on error
*/
-int mds_kbdc_include_stack_push(const mds_kbdc_tree_include_t* restrict tree, void** data);
+int mds_kbdc_include_stack_push(const mds_kbdc_tree_include_t *restrict tree, void **data);
/**
* Undo the lasted not-undone call to `mds_kbdc_include_stack_push`
@@ -133,7 +129,7 @@ int mds_kbdc_include_stack_push(const mds_kbdc_tree_include_t* restrict tree, vo
*
* @param data `*data` from `mds_kbdc_include_stack_push`
*/
-void mds_kbdc_include_stack_pop(void* data);
+void mds_kbdc_include_stack_pop(void *data);
/**
* Save the current include-stack
@@ -148,15 +144,14 @@ mds_kbdc_include_stack_t* mds_kbdc_include_stack_save(void);
* @param stack The include-stack
* @return Zero on success, -1 on error
*/
-int mds_kbdc_include_stack_restore(mds_kbdc_include_stack_t* restrict stack);
+int mds_kbdc_include_stack_restore(mds_kbdc_include_stack_t *restrict stack);
/**
* Destroy a previous include-stack and free its allocation
*
* @param stack The include-stack
*/
-void mds_kbdc_include_stack_free(mds_kbdc_include_stack_t* restrict stack);
+void mds_kbdc_include_stack_free(mds_kbdc_include_stack_t *restrict stack);
#endif
-
diff --git a/src/mds-kbdc/make-tree.c b/src/mds-kbdc/make-tree.c
index 1b5e8a5..f5bdf55 100644
--- a/src/mds-kbdc/make-tree.c
+++ b/src/mds-kbdc/make-tree.c
@@ -31,7 +31,7 @@
#ifndef DEBUG
# define DEBUG_PROC(statements)
#else
-# define DEBUG_PROC(statements) statements
+# define DEBUG_PROC(statements) statements
#endif
@@ -40,16 +40,14 @@
* as a compiler debugging feature and should be used from
* inside `DEBUG_PROC`
*/
-#define PRINT_STACK \
- do \
- { \
- size_t i = stack_ptr; \
- fprintf(stderr, "stack {\n"); \
- while (i--) \
- fprintf(stderr, " %s\n", keyword_stack[i]); \
- fprintf(stderr, "}\n"); \
- } \
- while (0)
+#define PRINT_STACK\
+ do {\
+ size_t i = stack_ptr;\
+ fprintf(stderr, "stack {\n");\
+ while (i--)\
+ fprintf(stderr, " %s\n", keyword_stack[i]);\
+ fprintf(stderr, "}\n");\
+ } while (0)
/**
@@ -60,8 +58,8 @@
* @param UPPER:¿T? The upper bound, inclusive
* @return :int 1 if `LOWER` ≤ `VALUE` ≤ `UPPER`, otherwise 0
*/
-#define in_range(LOWER, VALUE, UPPER) \
- (((LOWER) <= (VALUE)) && ((VALUE) <= (UPPER)))
+#define in_range(LOWER, VALUE, UPPER)\
+ ((LOWER) <= (VALUE) && (VALUE) <= (UPPER))
/**
@@ -70,23 +68,23 @@
* @param C:char The character
* @return :int Zero if `C` is a valid callable name character or a forward slash, otherwise 0
*/
-#define is_name_char(C) \
- (in_range('a', C, 'z') || in_range('A', C, 'Z') || strchr("0123456789_/", C))
+#define is_name_char(C)\
+ (in_range('a', C, 'z') || in_range('A', C, 'Z') || strchr("0123456789_/", C))
/**
* Pointer to the beginning of the current line
*/
-#define LINE \
- (result->source_code->lines[line_i])
+#define LINE\
+ (result->source_code->lines[line_i])
/**
* Update the tip of the stack to point to the address
* of the current stack's tip's `next`-member
*/
-#define NEXT \
- tree_stack[stack_ptr] = &(tree_stack[stack_ptr][0]->next)
+#define NEXT\
+ tree_stack[stack_ptr] = &(tree_stack[stack_ptr][0]->next)
/**
@@ -97,9 +95,9 @@
* @param ...:const char*, ... Error description format string and arguments
* @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
*/
-#define NEW_ERROR(ERROR_IS_IN_FILE, SEVERITY, ...) \
- NEW_ERROR_(result, SEVERITY, ERROR_IS_IN_FILE, line_i, \
- (size_t)(line - LINE), (size_t)(end - LINE), 1, __VA_ARGS__)
+#define NEW_ERROR(ERROR_IS_IN_FILE, SEVERITY, ...)\
+ NEW_ERROR_(result, SEVERITY, ERROR_IS_IN_FILE, line_i,\
+ (size_t)(line - LINE), (size_t)(end - LINE), 1, __VA_ARGS__)
/**
@@ -108,13 +106,13 @@
* @param LOWERCASE:identifier The keyword, for the node type, in lower case
* @param UPPERCASE:identifier The keyword, for the node type, in upper case
*/
-#define NEW_NODE(LOWERCASE, UPPERCASE) \
- mds_kbdc_tree_##LOWERCASE##_t* node; \
- fail_if (xcalloc(node, 1, mds_kbdc_tree_##LOWERCASE##_t)); \
- node->type = MDS_KBDC_TREE_TYPE_##UPPERCASE; \
- node->loc_line = line_i; \
- node->loc_start = (size_t)(line - LINE); \
- node->loc_end = (size_t)(end - LINE)
+#define NEW_NODE(LOWERCASE, UPPERCASE)\
+ mds_kbdc_tree_##LOWERCASE##_t *node;\
+ fail_if (xcalloc(node, 1, mds_kbdc_tree_##LOWERCASE##_t));\
+ node->type = MDS_KBDC_TREE_TYPE_##UPPERCASE;\
+ node->loc_line = line_i;\
+ node->loc_start = (size_t)(line - LINE);\
+ node->loc_end = (size_t)(end - LINE)
/**
@@ -123,13 +121,13 @@
* @param LOWERCASE:identifier The keyword, for the node type, in lower case
* @param UPPERCASE:identifier The keyword, for the node type, in upper case
*/
-#define NEW_SUBNODE(LOWERCASE, UPPERCASE) \
- mds_kbdc_tree_##LOWERCASE##_t* subnode; \
- fail_if (xcalloc(subnode, 1, mds_kbdc_tree_##LOWERCASE##_t)); \
- subnode->type = MDS_KBDC_TREE_TYPE_##UPPERCASE; \
- subnode->loc_line = line_i; \
- subnode->loc_start = (size_t)(line - LINE); \
- subnode->loc_end = (size_t)(end - LINE)
+#define NEW_SUBNODE(LOWERCASE, UPPERCASE)\
+ mds_kbdc_tree_##LOWERCASE##_t *subnode;\
+ fail_if (xcalloc(subnode, 1, mds_kbdc_tree_##LOWERCASE##_t));\
+ subnode->type = MDS_KBDC_TREE_TYPE_##UPPERCASE;\
+ subnode->loc_line = line_i;\
+ subnode->loc_start = (size_t)(line - LINE);\
+ subnode->loc_end = (size_t)(end - LINE)
/**
@@ -142,10 +140,10 @@
*
* @param KEYWORD:const char* The keyword for the current node's type
*/
-#define BRANCH(KEYWORD) \
- (*(tree_stack[stack_ptr]) = (mds_kbdc_tree_t*)node, \
- tree_stack[stack_ptr + 1] = &(node->inner), \
- keyword_stack[stack_ptr++] = KEYWORD)
+#define BRANCH(KEYWORD)\
+ (*(tree_stack[stack_ptr]) = (mds_kbdc_tree_t *)node,\
+ tree_stack[stack_ptr + 1] = &(node->inner),\
+ keyword_stack[stack_ptr++] = KEYWORD)
/**
@@ -156,9 +154,9 @@
* This is what should be done when a leaf node has been
* created and should be added to the result tree
*/
-#define LEAF \
- (*(tree_stack[stack_ptr]) = (mds_kbdc_tree_t*)node, \
- NEXT)
+#define LEAF\
+ (*(tree_stack[stack_ptr]) = (mds_kbdc_tree_t*)node,\
+ NEXT)
/**
@@ -166,9 +164,9 @@
*
* @param var:const char* The variable
*/
-#define SKIP_SPACES(var) \
- while (*var && (*var == ' ')) \
- var++
+#define SKIP_SPACES(var)\
+ while (*var && *var == ' ')\
+ var++
/**
@@ -176,8 +174,8 @@
*
* @param KEYWORD:const char* The keyword
*/
-#define NO_PARAMETERS(KEYWORD) \
- fail_if (no_parameters(KEYWORD))
+#define NO_PARAMETERS(KEYWORD)\
+ fail_if (no_parameters(KEYWORD))
/**
@@ -187,18 +185,18 @@
* @param var:identifier The name of the member variable, for the current
* node, where the parameter should be stored
*/
-#define NAMES_1(var) \
- fail_if (names_1(&(node->var)))
+#define NAMES_1(var)\
+ fail_if (names_1(&node->var))
/**
* Suppress the next `line = STREND(line)`
*/
-#define NO_JUMP \
- (*end = prev_end_char, \
- end = line, \
- prev_end_char = *end, \
- *end = '\0')
+#define NO_JUMP\
+ (*end = prev_end_char,\
+ end = line,\
+ prev_end_char = *end,\
+ *end = '\0')
/**
@@ -206,8 +204,8 @@
*
* @param c:char The character
*/
-#define IS_END(c) \
- strchr(" >}])", c)
+#define IS_END(c)\
+ strchr(" >}])", c)
/**
@@ -217,31 +215,28 @@
* @param var:identifier The name of the member variable, for the current
* node, where the parameter should be stored
*/
-#define CHARS(var) \
- fail_if (chars(&(node->var)))
+#define CHARS(var)\
+ fail_if (chars(&node->var))
/**
* Test that there are no more parameters
*/
-#define END \
- do \
- { \
- SKIP_SPACES(line); \
- if (*line) \
- { \
- NEW_ERROR(1, ERROR, "too many parameters"); \
- error->end = strlen(LINE); \
- } \
- } \
- while (0)
+#define END\
+ do {\
+ SKIP_SPACES(line);\
+ if (*line) {\
+ NEW_ERROR(1, ERROR, "too many parameters");\
+ error->end = strlen(LINE);\
+ }\
+ } while (0)
/**
* Test that the next parameter is in quotes
*/
-#define QUOTES \
- fail_if (quotes())
+#define QUOTES\
+ fail_if (quotes())
/**
@@ -251,14 +246,12 @@
* @param var:identifier The name of the member variable, for the current
* node, where the parameter should be stored
*/
-#define QUOTES_1(var) \
- do \
- { \
- QUOTES; \
- CHARS(var); \
- END; \
- } \
- while (0)
+#define QUOTES_1(var)\
+ do {\
+ QUOTES;\
+ CHARS(var);\
+ END;\
+ } while (0)
/**
@@ -266,8 +259,8 @@
*
* @param KEYWORD:const char* The keyword
*/
-#define TEST_FOR_KEYWORD(KEYWORD) \
- fail_if (test_for_keyword(KEYWORD))
+#define TEST_FOR_KEYWORD(KEYWORD)\
+ fail_if (test_for_keyword(KEYWORD))
/**
@@ -277,8 +270,8 @@
* @param var:identifier The name of the member variable, for the current
* node, where the parameter should be stored
*/
-#define KEYS(var) \
- fail_if (keys(&(node->var)))
+#define KEYS(var)\
+ fail_if (keys(&node->var))
/**
@@ -288,8 +281,8 @@
* @param var:identifier The name of the member variable, for the current
* node, where the parameter should be stored
*/
-#define PURE_KEYS(var) \
- fail_if (pure_keys(&(node->var)))
+#define PURE_KEYS(var)\
+ fail_if (pure_keys(&node->var))
@@ -299,23 +292,21 @@
* @param mapseq:int Whether this is a mapping sequence, otherwise
* it is treated as macro call arguments
*/
-#define SEQUENCE(mapseq) \
- do /* for(;;) */ \
- { \
- *end = prev_end_char; \
- SKIP_SPACES(line); \
- if ((*line == '\0') || (*line == (mapseq ? ':' : ')'))) \
- break; \
- fail_if (sequence(mapseq, stack_orig)); \
- } \
- while (1)
+#define SEQUENCE(mapseq)\
+ do /* for(;;) */ {\
+ *end = prev_end_char;\
+ SKIP_SPACES(line);\
+ if (!*line || *line == (mapseq ? ':' : ')'))\
+ break;\
+ fail_if (sequence(mapseq, stack_orig));\
+ } while (1)
/**
* Check that the scopes created in `SEQUENCE` has all been popped
*/
-#define SEQUENCE_FULLY_POPPED \
- fail_if (sequence_fully_popped(stack_orig))
+#define SEQUENCE_FULLY_POPPED\
+ fail_if (sequence_fully_popped(stack_orig))
/**
@@ -325,14 +316,12 @@
* @param UPPERCASE:identifier The keyword, for the node type, in upper case
* @param PARSE:expression Statement, without final semicolon, to retrieve members
*/
-#define MAKE_LEAF(LOWERCASE, UPPERCASE, PARSE) \
- do \
- { \
- NEW_NODE(LOWERCASE, UPPERCASE); \
- PARSE; \
- LEAF; \
- } \
- while (0)
+#define MAKE_LEAF(LOWERCASE, UPPERCASE, PARSE)\
+ do {\
+ NEW_NODE(LOWERCASE, UPPERCASE);\
+ PARSE;\
+ LEAF;\
+ } while (0)
/**
@@ -342,26 +331,24 @@
* @param UPPERCASE:identifier The keyword, for the node type, in upper case
* @param PARSE:expression Statement, without final semicolon, to retrieve members
*/
-#define MAKE_BRANCH(LOWERCASE, UPPERCASE, PARSE) \
- do \
- { \
- NEW_NODE(LOWERCASE, UPPERCASE); \
- PARSE; \
- BRANCH(#LOWERCASE); \
- } \
- while (0)
+#define MAKE_BRANCH(LOWERCASE, UPPERCASE, PARSE)\
+ do {\
+ NEW_NODE(LOWERCASE, UPPERCASE);\
+ PARSE;\
+ BRANCH(#LOWERCASE);\
+ } while (0)
/**
* Variable whether the latest created error is stored
*/
-static mds_kbdc_parse_error_t* error;
+static mds_kbdc_parse_error_t *error;
/**
* Output parameter for the parsing result
*/
-static mds_kbdc_parsed_t* restrict result;
+static mds_kbdc_parsed_t *restrict result;
/**
* The head of the parsing-stack
@@ -371,12 +358,12 @@ static size_t stack_ptr;
/**
* The keyword portion of the parsing-stack
*/
-static const char** restrict keyword_stack;
+static const char **restrict keyword_stack;
/**
* The tree portion of the parsing-stack
*/
-static mds_kbdc_tree_t*** restrict tree_stack;
+static mds_kbdc_tree_t ***restrict tree_stack;
/**
* The index of the currently parsed line
@@ -392,12 +379,12 @@ static int in_array;
* The beginning of what has not get been parsed
* on the current line
*/
-static char* line = NULL;
+static char *line = NULL;
/**
* The end of what has been parsed on the current line
*/
-static char* end = NULL;
+static char *end = NULL;
/**
* The previous value of `*end`
@@ -408,7 +395,7 @@ static char prev_end_char;
* Pointer to the first non-whitespace character
* on the current line
*/
-static char* original;
+static char *original;
/**
* Whether it has been identified that the
@@ -427,40 +414,39 @@ static int too_few;
* @param filename The filename of the parsed file
* @return The value the caller should return, or 1 if the caller should not return, -1 on error
*/
-static int get_pathname(const char* restrict filename)
+static int
+get_pathname(const char *restrict filename)
{
- char* cwd = NULL;
- int saved_errno;
-
- /* Get a non-relative pathname for the file, relative filenames
- * can be misleading as the program can have changed working
- * directory to be able to resolve filenames. */
- result->pathname = abspath(filename);
- if (result->pathname == NULL)
- {
- fail_if (errno != ENOENT);
- saved_errno = errno;
- fail_if (cwd = curpath(), cwd == NULL);
- fail_if (xstrdup(result->pathname, filename));
- NEW_ERROR_(result, ERROR, 0, 0, 0, 0, 1, "no such file or directory in ‘%s’", cwd);
- free(cwd);
- return 0;
- }
-
- /* Check that the file exists and can be read. */
- if (access(result->pathname, R_OK) < 0)
- {
- saved_errno = errno;
- NEW_ERROR_(result, ERROR, 0, 0, 0, 0, 0, NULL);
- fail_if (xstrdup(error->description, strerror(saved_errno)));
- return 0;
- }
-
- return 1;
- fail:
- saved_errno = errno;
- free(cwd);
- return errno = saved_errno, -1;
+ char *cwd = NULL;
+ int saved_errno;
+
+ /* Get a non-relative pathname for the file, relative filenames
+ * can be misleading as the program can have changed working
+ * directory to be able to resolve filenames. */
+ result->pathname = abspath(filename);
+ if (!result->pathname) {
+ fail_if (errno != ENOENT);
+ saved_errno = errno;
+ fail_if (!(cwd = curpath()));
+ fail_if (xstrdup(result->pathname, filename));
+ NEW_ERROR_(result, ERROR, 0, 0, 0, 0, 1, "no such file or directory in ‘%s’", cwd);
+ free(cwd);
+ return 0;
+ }
+
+ /* Check that the file exists and can be read. */
+ if (access(result->pathname, R_OK) < 0) {
+ saved_errno = errno;
+ NEW_ERROR_(result, ERROR, 0, 0, 0, 0, 0, NULL);
+ fail_if (xstrdup(error->description, strerror(saved_errno)));
+ return 0;
+ }
+
+ return 1;
+fail:
+ saved_errno = errno;
+ free(cwd);
+ return errno = saved_errno, -1;
}
@@ -469,25 +455,25 @@ static int get_pathname(const char* restrict filename)
*
* @return Zero on success, -1 on error
*/
-static int allocate_stacks(void)
+static int
+allocate_stacks(void)
{
- size_t max_line_length = 0, cur_line_length, line_n;
-
- /* The maximum line-length is needed because lines can have there own stacking,
- * like sequence mapping lines, additionally, let statements can have one array. */
- for (line_i = 0, line_n = result->source_code->line_count; line_i < line_n; line_i++)
- {
- cur_line_length = strlen(LINE);
- if (max_line_length < cur_line_length)
- max_line_length = cur_line_length;
- }
-
- fail_if (xmalloc(keyword_stack, line_n + max_line_length, const char*));
- fail_if (xmalloc(tree_stack, line_n + max_line_length + 1, mds_kbdc_tree_t**));
-
- return 0;
- fail:
- return -1;
+ size_t max_line_length = 0, cur_line_length, line_n;
+
+ /* The maximum line-length is needed because lines can have there own stacking,
+ * like sequence mapping lines, additionally, let statements can have one array. */
+ for (line_i = 0, line_n = result->source_code->line_count; line_i < line_n; line_i++) {
+ cur_line_length = strlen(LINE);
+ if (max_line_length < cur_line_length)
+ max_line_length = cur_line_length;
+ }
+
+ fail_if (xmalloc(keyword_stack, line_n + max_line_length, const char*));
+ fail_if (xmalloc(tree_stack, line_n + max_line_length + 1, mds_kbdc_tree_t**));
+
+ return 0;
+fail:
+ return -1;
}
@@ -496,14 +482,15 @@ static int allocate_stacks(void)
*
* @return Zero on success, -1 on error
*/
-static int read_source_code(void)
+static int
+read_source_code(void)
{
- /* Read the file and simplify it a bit. */
- fail_if (read_source_lines(result->pathname, result->source_code) < 0);
-
- return 0;
- fail:
- return -1;
+ /* Read the file and simplify it a bit. */
+ fail_if (read_source_lines(result->pathname, result->source_code) < 0);
+
+ return 0;
+fail:
+ return -1;
}
@@ -517,34 +504,32 @@ static int read_source_code(void)
*
* @return Zero on success, -1 on error
*/
-static int check_for_premature_end_of_file(void)
+static int
+check_for_premature_end_of_file(void)
{
- /* Check that all scopes have been popped. */
- if (stack_ptr)
- {
- while (stack_ptr && keyword_stack[stack_ptr - 1] == NULL)
- stack_ptr--;
- if (stack_ptr)
- {
- NEW_ERROR(0, ERROR, "premature end of file");
- while (stack_ptr--)
- {
- if (keyword_stack[stack_ptr] == NULL)
- continue;
- line_i = tree_stack[stack_ptr][0]->loc_line;
- line = LINE + tree_stack[stack_ptr][0]->loc_start;
- end = LINE + tree_stack[stack_ptr][0]->loc_end;
- if (!strcmp(keyword_stack[stack_ptr], "}"))
- NEW_ERROR(1, NOTE, "missing associated ‘%s’", keyword_stack[stack_ptr]);
- else
- NEW_ERROR(1, NOTE, "missing associated ‘end %s’", keyword_stack[stack_ptr]);
- }
+ /* Check that all scopes have been popped. */
+ if (stack_ptr) {
+ while (stack_ptr && !keyword_stack[stack_ptr - 1])
+ stack_ptr--;
+ if (stack_ptr) {
+ NEW_ERROR(0, ERROR, "premature end of file");
+ while (stack_ptr--) {
+ if (!keyword_stack[stack_ptr])
+ continue;
+ line_i = tree_stack[stack_ptr][0]->loc_line;
+ line = LINE + tree_stack[stack_ptr][0]->loc_start;
+ end = LINE + tree_stack[stack_ptr][0]->loc_end;
+ if (!strcmp(keyword_stack[stack_ptr], "}"))
+ NEW_ERROR(1, NOTE, "missing associated ‘%s’", keyword_stack[stack_ptr]);
+ else
+ NEW_ERROR(1, NOTE, "missing associated ‘end %s’", keyword_stack[stack_ptr]);
+ }
+ }
}
- }
-
- return 0;
- fail:
- return -1;
+
+ return 0;
+fail:
+ return -1;
}
@@ -555,16 +540,16 @@ static int check_for_premature_end_of_file(void)
*
* @return Zero on success, -1 on error
*/
-static int check_whether_file_is_empty(void)
+static int
+check_whether_file_is_empty(void)
{
- /* Warn about empty files. */
- if (result->tree == NULL)
- if (result->errors_ptr == 0)
- NEW_ERROR(0, WARNING, "file is empty");
-
- return 0;
- fail:
- return -1;
+ /* Warn about empty files. */
+ if (!result->tree && !result->errors_ptr)
+ NEW_ERROR(0, WARNING, "file is empty");
+
+ return 0;
+fail:
+ return -1;
}
@@ -578,20 +563,20 @@ static int check_whether_file_is_empty(void)
* @param keyword The keyword
* @return Zero on success, -1 on error
*/
-static int no_parameters(const char* restrict keyword)
+static int
+no_parameters(const char *restrict keyword)
{
- line = STREND(line);
- *end = prev_end_char, prev_end_char = '\0';
- SKIP_SPACES(line);
- if (*line)
- {
- end = STREND(line);
- NEW_ERROR(1, ERROR, "extra token after ‘%s’", keyword);
- }
-
- return 0;
- fail:
- return -1;
+ line = STREND(line);
+ *end = prev_end_char, prev_end_char = '\0';
+ SKIP_SPACES(line);
+ if (*line) {
+ end = STREND(line);
+ NEW_ERROR(1, ERROR, "extra token after ‘%s’", keyword);
+ }
+
+ return 0;
+fail:
+ return -1;
}
@@ -604,55 +589,51 @@ static int no_parameters(const char* restrict keyword)
* node, where the parameter should be stored
* @return Zero on success, -1 on error
*/
-static int names_1(char** restrict var)
+static int
+names_1(char **restrict var)
{
- char* name_end;
- char* test;
- int stray_char = 0;
- char* end_end;
-
- line = STREND(line);
- *end = prev_end_char, prev_end_char = '\0';
- SKIP_SPACES(line);
- if (*line == '\0')
- {
- line = original, end = STREND(line);
- NEW_ERROR(1, ERROR, "a name is expected");
- }
- else
- {
- name_end = line;
- while (*name_end && is_name_char(*name_end))
- name_end++;
- if (*name_end && (*name_end != ' '))
- {
- end_end = name_end + 1;
- while ((*end_end & 0xC0) == 0x80)
- end_end++;
- prev_end_char = *end_end, *end_end = '\0';
- NEW_ERROR(1, ERROR, "stray ‘%s’ character", name_end);
- error->start = (size_t)(name_end - LINE);
- error->end = (size_t)(end_end - LINE);
- *end_end = prev_end_char;
- stray_char = 1;
+ char *name_end;
+ char *test;
+ int stray_char = 0;
+ char *end_end;
+
+ line = STREND(line);
+ *end = prev_end_char, prev_end_char = '\0';
+ SKIP_SPACES(line);
+ if (!*line) {
+ line = original, end = STREND(line);
+ NEW_ERROR(1, ERROR, "a name is expected");
+ } else {
+ name_end = line;
+ while (*name_end && is_name_char(*name_end))
+ name_end++;
+ if (*name_end && (*name_end != ' ')) {
+ end_end = name_end + 1;
+ while ((*end_end & 0xC0) == 0x80)
+ end_end++;
+ prev_end_char = *end_end, *end_end = '\0';
+ NEW_ERROR(1, ERROR, "stray ‘%s’ character", name_end);
+ error->start = (size_t)(name_end - LINE);
+ error->end = (size_t)(end_end - LINE);
+ *end_end = prev_end_char;
+ stray_char = 1;
+ }
+ test = name_end;
+ SKIP_SPACES(test);
+ if (*test && !stray_char) {
+ NEW_ERROR(1, ERROR, "too many parameters");
+ error->start = (size_t)(test - LINE);
+ error->end = strlen(LINE);
+ }
+ end = name_end;
+ prev_end_char = *end;
+ *end = '\0';
+ fail_if (xstrdup(*var, line));
}
- test = name_end;
- SKIP_SPACES(test);
- if (*test && !stray_char)
- {
- NEW_ERROR(1, ERROR, "too many parameters");
- error->start = (size_t)(test - LINE);
- error->end = strlen(LINE);
- }
- end = name_end;
- prev_end_char = *end;
- *end = '\0';
- fail_if (xstrdup(*var, line));
- }
-
- return 0;
- fail:
- return -1;
+
+ return 0;
+fail:
+ return -1;
}
@@ -664,46 +645,49 @@ static int names_1(char** restrict var)
* node, where the parameter should be stored
* @return Zero on success, -1 on error
*/
-static int chars(char** restrict var)
+static int
+chars(char **restrict var)
{
- if (too_few)
- return 0;
- line = STREND(line);
- *end = prev_end_char, prev_end_char = '\0';
- SKIP_SPACES(line);
- if (*line == '\0')
- {
- line = original, end = STREND(line);
- NEW_ERROR(1, ERROR, "too few parameters");
- line = end, too_few = 1;
- }
- else
- {
- char* arg_end = line;
- char* call_end = arg_end;
- int escape = 0, quote = 0;
- while (*arg_end)
- {
- char c = *arg_end++;
- if (escape) escape = 0;
- else if (arg_end <= call_end) ;
- else if (c == '\\')
- {
- escape = 1;
- call_end = arg_end + get_end_of_call(arg_end, 0, strlen(arg_end));
- }
- else if (quote) quote = (c != '"');
- else if (IS_END(c)) { arg_end--; break; }
- else quote = (c == '"');
+ char *arg_end, *call_end, c;
+ int escape, quote;
+ if (too_few)
+ return 0;
+ line = STREND(line);
+ *end = prev_end_char, prev_end_char = '\0';
+ SKIP_SPACES(line);
+ if (!*line) {
+ line = original, end = STREND(line);
+ NEW_ERROR(1, ERROR, "too few parameters");
+ line = end, too_few = 1;
+ } else {
+ arg_end = line;
+ call_end = arg_end;
+ escape = quote = 0;
+ while (*arg_end) {
+ c = *arg_end++;
+ if (escape) {
+ escape = 0;
+ } else if (arg_end <= call_end) { ;
+ } else if (c == '\\') {
+ escape = 1;
+ call_end = arg_end + get_end_of_call(arg_end, 0, strlen(arg_end));
+ } else if (quote) {
+ quote = c != '"';
+ } else if (IS_END(c)) {
+ arg_end--;
+ break;
+ } else {
+ quote = c == '"';
+ }
+ }
+ prev_end_char = *arg_end, *arg_end = '\0', end = arg_end;
+ fail_if (xstrdup(*var, line));
+ line = end;
}
- prev_end_char = *arg_end, *arg_end = '\0', end = arg_end;
- fail_if (xstrdup(*var, line));
- line = end;
- }
-
- return 0;
- fail:
- return -1;
+
+ return 0;
+fail:
+ return -1;
}
@@ -712,25 +696,25 @@ static int chars(char** restrict var)
*
* @return Zero on success, -1 on error
*/
-static int quotes(void)
+static int
+quotes(void)
{
- char* line_ = line;
- line = STREND(line);
- *end = prev_end_char;
- SKIP_SPACES(line);
- if (*line && (*line != '"'))
- {
- char* arg_end = line;
- SKIP_SPACES(arg_end);
- NEW_ERROR(1, ERROR, "parameter must be in quotes");
- error->end = (size_t)(arg_end - LINE);
- }
- *end = '\0';
- line = line_;
-
- return 0;
- fail:
- return -1;
+ char *line_ = line, *arg_end;
+ line = STREND(line);
+ *end = prev_end_char;
+ SKIP_SPACES(line);
+ if (*line && *line != '"') {
+ arg_end = line;
+ SKIP_SPACES(arg_end);
+ NEW_ERROR(1, ERROR, "parameter must be in quotes");
+ error->end = (size_t)(arg_end - LINE);
+ }
+ *end = '\0';
+ line = line_;
+
+ return 0;
+fail:
+ return -1;
}
@@ -739,23 +723,23 @@ static int quotes(void)
*
* @return Whether the currently line has unparsed parameters, -1 on error
*/
-static int have_more_parameters(void)
+static int
+have_more_parameters(void)
{
- if (too_few)
- return 0;
- line = STREND(line);
- *end = prev_end_char, prev_end_char = '\0';
- SKIP_SPACES(line);
- if (*line == '\0')
- {
- line = original, end = STREND(line);
- NEW_ERROR(1, ERROR, "too few parameters");
- line = end, too_few = 1;
- return 0;
- }
- return 1;
- fail:
- return -1;
+ if (too_few)
+ return 0;
+ line = STREND(line);
+ *end = prev_end_char, prev_end_char = '\0';
+ SKIP_SPACES(line);
+ if (!*line) {
+ line = original, end = STREND(line);
+ NEW_ERROR(1, ERROR, "too few parameters");
+ line = end, too_few = 1;
+ return 0;
+ }
+ return 1;
+fail:
+ return -1;
}
@@ -765,32 +749,33 @@ static int have_more_parameters(void)
* @param keyword The keyword
* @return Zero on success, -1 on error
*/
-static int test_for_keyword(const char* restrict keyword)
+static int
+test_for_keyword(const char *restrict keyword)
{
- int ok, r = have_more_parameters();
- fail_if (r < 0);
- if (r == 0)
- return 0;
-
- ok = (strstr(line, keyword) == line);
- line += strlen(keyword);
- ok = ok && ((*line == '\0') || (*line == ' '));
- if (ok)
- {
- end = line;
- prev_end_char = *end, *end = '\0';
- return 0;
- }
- line -= strlen(keyword);
- end = line;
- SKIP_SPACES(end);
- prev_end_char = *end, *end = '\0';
- NEW_ERROR(1, ERROR, "expecting keyword ‘%s’", keyword);
- error->end = error->start + 1;
-
- return 0;
- fail:
- return -1;
+ int ok, r = have_more_parameters();
+ fail_if (r < 0);
+ if (!r)
+ return 0;
+
+ ok = (strstr(line, keyword) == line);
+ line += strlen(keyword);
+ ok = ok && (!*line || *line == ' ');
+ if (ok) {
+ end = line;
+ prev_end_char = *end;
+ *end = '\0';
+ return 0;
+ }
+ line -= strlen(keyword);
+ end = line;
+ SKIP_SPACES(end);
+ prev_end_char = *end, *end = '\0';
+ NEW_ERROR(1, ERROR, "expecting keyword ‘%s’", keyword);
+ error->end = error->start + 1;
+
+ return 0;
+fail:
+ return -1;
}
@@ -802,52 +787,53 @@ static int test_for_keyword(const char* restrict keyword)
* node, where the parameter should be stored
* @return Zero on success, -1 on error
*/
-static int keys(mds_kbdc_tree_t** restrict var)
+static int
+keys(mds_kbdc_tree_t **restrict var)
{
- char* arg_end;
- char* call_end;
- int r, escape = 0, quote = 0, triangle;
- r = have_more_parameters();
- fail_if (r < 0);
- if (r == 0)
- return 0;
-
- arg_end = line;
- call_end = arg_end;
- triangle = (*arg_end == '<');
- while (*arg_end)
- {
- char c = *arg_end++ ;
- if (escape) escape = 0;
- else if (arg_end <= call_end) ;
- else if (c == '\\')
- {
- escape = 1;
- call_end = arg_end + get_end_of_call(arg_end, 0, strlen(arg_end));
+ char *arg_end, *call_end, c;
+ int r, escape = 0, quote = 0, triangle;
+ r = have_more_parameters();
+ fail_if (r < 0);
+ if (!r)
+ return 0;
+
+ arg_end = line;
+ call_end = arg_end;
+ triangle = *arg_end == '<';
+ while (*arg_end) {
+ c = *arg_end++;
+ if (escape) {
+ escape = 0;
+ } else if (arg_end <= call_end) { ;
+ } else if (c == '\\') {
+ escape = 1;
+ call_end = arg_end + get_end_of_call(arg_end, 0, strlen(arg_end));
+ } else if (quote) {
+ quote = c != '"';
+ } else if (c == '\"') {
+ quote = 1;
+ } else if (c == '>') {
+ triangle = 0;
+ } else if (IS_END(c) && !triangle) {
+ arg_end--;
+ break;
+ }
}
- else if (quote) quote = (c != '"');
- else if (c == '\"') quote = 1;
- else if (c == '>') triangle = 0;
- else if (IS_END(c) && !triangle) { arg_end--; break; }
- }
- prev_end_char = *arg_end, *arg_end = '\0', end = arg_end;
- if (*line == '<')
- {
- NEW_SUBNODE(keys, KEYS);
- *var = (mds_kbdc_tree_t*)subnode;
- fail_if (xstrdup(subnode->keys, line));
- }
- else
- {
- NEW_SUBNODE(string, STRING);
- *var = (mds_kbdc_tree_t*)subnode;
- fail_if (xstrdup(subnode->string, line));
- }
- line = end;
-
- return 0;
- fail:
- return -1;
+ prev_end_char = *arg_end, *arg_end = '\0', end = arg_end;
+ if (*line == '<') {
+ NEW_SUBNODE(keys, KEYS);
+ *var = (mds_kbdc_tree_t *)subnode;
+ fail_if (xstrdup(subnode->keys, line));
+ } else {
+ NEW_SUBNODE(string, STRING);
+ *var = (mds_kbdc_tree_t *)subnode;
+ fail_if (xstrdup(subnode->string, line));
+ }
+ line = end;
+
+ return 0;
+fail:
+ return -1;
}
@@ -860,41 +846,45 @@ static int keys(mds_kbdc_tree_t** restrict var)
* node, where the parameter should be stored
* @return Zero on success, -1 on error
*/
-static int pure_keys(char** restrict var)
+static int
+pure_keys(char **restrict var)
{
- char* arg_end;
- char* call_end;
- int r, escape = 0, quote = 0, triangle;
- r = have_more_parameters();
- fail_if (r < 0);
- if (r == 0)
- return 0;
-
- arg_end = line;
- call_end = arg_end;
- triangle = (*arg_end == '<');
- while (*arg_end)
- {
- char c = *arg_end++ ;
- if (escape) escape = 0;
- else if (arg_end <= call_end) ;
- else if (c == '\\')
- {
- escape = 1;
- call_end = arg_end + get_end_of_call(arg_end, 0, strlen(arg_end));
+ char *arg_end, *call_end, c;
+ int r, escape = 0, quote = 0, triangle;
+ r = have_more_parameters();
+ fail_if (r < 0);
+ if (!r)
+ return 0;
+
+ arg_end = line;
+ call_end = arg_end;
+ triangle = *arg_end == '<';
+ while (*arg_end) {
+ c = *arg_end++;
+ if (escape) {
+ escape = 0;
+ } else if (arg_end <= call_end) { ;
+ } else if (c == '\\') {
+ escape = 1;
+ call_end = arg_end + get_end_of_call(arg_end, 0, strlen(arg_end));
+ } else if (quote) {
+ quote = c != '"';
+ } else if (c == '\"') {
+ quote = 1;
+ } else if (c == '>') {
+ triangle = 0;
+ } else if (IS_END(c) && !triangle) {
+ arg_end--;
+ break;
+ }
}
- else if (quote) quote = (c != '"');
- else if (c == '\"') quote = 1;
- else if (c == '>') triangle = 0;
- else if (IS_END(c) && !triangle) { arg_end--; break; }
- }
- prev_end_char = *arg_end, *arg_end = '\0';
- fail_if (xstrdup(*var, line));
- end = arg_end, line = end;
-
- return 0;
- fail:
- return -1;
+ prev_end_char = *arg_end, *arg_end = '\0';
+ fail_if (xstrdup(*var, line));
+ end = arg_end, line = end;
+
+ return 0;
+fail:
+ return -1;
}
@@ -906,65 +896,54 @@ static int pure_keys(char** restrict var)
* @param stack_orig The size of the stack when `SEQUENCE` was called
* @return Zero on success, -1 on error
*/
-static int sequence(int mapseq, size_t stack_orig)
+static int
+sequence(int mapseq, size_t stack_orig)
{
- if (mapseq && (*line == '('))
- {
- NEW_NODE(unordered, UNORDERED);
- node->loc_end = node->loc_start + 1;
- BRANCH(")");
- line++;
- }
- else if (*line == '[')
- {
- NEW_NODE(alternation, ALTERNATION);
- node->loc_end = node->loc_start + 1;
- BRANCH("]");
- line++;
- }
- else if (*line == '.')
- {
- NEW_NODE(nothing, NOTHING);
- node->loc_end = node->loc_start + 1;
- LEAF;
- line++;
- }
- else if (strchr("])", *line))
- {
- end = line + 1;
- prev_end_char = *end, *end = '\0';
- if (stack_ptr == stack_orig)
- NEW_ERROR(1, ERROR, "runaway ‘%s’", line);
- else
- {
- stack_ptr--;
- if (strcmp(line, keyword_stack[stack_ptr]))
- NEW_ERROR(1, ERROR, "expected ‘%s’ but got ‘%s’", keyword_stack[stack_ptr], line);
- NEXT;
+ if (mapseq && *line == '(') {
+ NEW_NODE(unordered, UNORDERED);
+ node->loc_end = node->loc_start + 1;
+ BRANCH(")");
+ line++;
+ } else if (*line == '[') {
+ NEW_NODE(alternation, ALTERNATION);
+ node->loc_end = node->loc_start + 1;
+ BRANCH("]");
+ line++;
+ } else if (*line == '.') {
+ NEW_NODE(nothing, NOTHING);
+ node->loc_end = node->loc_start + 1;
+ LEAF;
+ line++;
+ } else if (strchr("])", *line)) {
+ end = line + 1;
+ prev_end_char = *end, *end = '\0';
+ if (stack_ptr == stack_orig) {
+ NEW_ERROR(1, ERROR, "runaway ‘%s’", line);
+ } else {
+ stack_ptr--;
+ if (strcmp(line, keyword_stack[stack_ptr]))
+ NEW_ERROR(1, ERROR, "expected ‘%s’ but got ‘%s’", keyword_stack[stack_ptr], line);
+ NEXT;
+ }
+ *end = prev_end_char;
+ line++;
+ } else if (*line == '<') {
+ NEW_NODE(keys, KEYS);
+ NO_JUMP;
+ PURE_KEYS(keys);
+ LEAF;
+ node->loc_end = (size_t)(line - LINE);
+ } else {
+ NEW_NODE(string, STRING);
+ NO_JUMP;
+ CHARS(string);
+ LEAF;
+ node->loc_end = (size_t)(line - LINE);
}
- *end = prev_end_char;
- line++;
- }
- else if (*line == '<')
- {
- NEW_NODE(keys, KEYS);
- NO_JUMP;
- PURE_KEYS(keys);
- LEAF;
- node->loc_end = (size_t)(line - LINE);
- }
- else
- {
- NEW_NODE(string, STRING);
- NO_JUMP;
- CHARS(string);
- LEAF;
- node->loc_end = (size_t)(line - LINE);
- }
-
- return 0;
+
+ return 0;
fail:
- return -1;
+ return -1;
}
@@ -973,23 +952,23 @@ static int sequence(int mapseq, size_t stack_orig)
*
* @param stack_orig The size of the stack when `SEQUENCE` was called
*/
-static int sequence_fully_popped(size_t stack_orig)
+static int
+sequence_fully_popped(size_t stack_orig)
{
- if (stack_ptr == stack_orig)
- return 0;
- end = line + 1;
- NEW_ERROR(1, ERROR, "premature end of sequence");
- while (stack_ptr > stack_orig)
- {
- stack_ptr--;
- NEW_ERROR(1, NOTE, "missing associated ‘%s’", keyword_stack[stack_ptr]);
- error->start = tree_stack[stack_ptr][0]->loc_start;
- error->end = tree_stack[stack_ptr][0]->loc_end;
- }
-
- return 0;
- fail:
- return -1;
+ if (stack_ptr == stack_orig)
+ return 0;
+ end = line + 1;
+ NEW_ERROR(1, ERROR, "premature end of sequence");
+ while (stack_ptr > stack_orig) {
+ stack_ptr--;
+ NEW_ERROR(1, NOTE, "missing associated ‘%s’", keyword_stack[stack_ptr]);
+ error->start = tree_stack[stack_ptr][0]->loc_start;
+ error->end = tree_stack[stack_ptr][0]->loc_end;
+ }
+
+ return 0;
+fail:
+ return -1;
}
@@ -1002,62 +981,54 @@ static int sequence_fully_popped(size_t stack_orig)
*
* @return Zero on success, -1 on error, 1 if the caller should go to `redo`
*/
-static int parse_else(void)
+static int
+parse_else(void)
{
- size_t i;
- if (stack_ptr == 0)
- {
- NEW_ERROR(1, ERROR, "runaway ‘else’ statement");
- return 0;
- }
- line = STREND(line);
- *end = prev_end_char, prev_end_char = '\0';
- end = STREND(line);
- SKIP_SPACES(line);
- i = stack_ptr - 1;
- while (keyword_stack[i] == NULL)
- i--;
- if (strcmp(keyword_stack[i], "if"))
- {
- stack_ptr--;
- line = original, end = STREND(line);
- NEW_ERROR(1, ERROR, "runaway ‘else’ statement");
- }
- else if (*line == '\0')
- {
- /* else */
- mds_kbdc_tree_if_t* supernode = &(tree_stack[stack_ptr - 1][0]->if_);
- if (supernode->otherwise)
- {
- line = strstr(LINE, "else");
- end = line + 4, prev_end_char = *end;
- NEW_ERROR(1, ERROR, "multiple ‘else’ statements");
- mds_kbdc_tree_free(supernode->otherwise);
- supernode->otherwise = NULL;
+ size_t i;
+ if (!stack_ptr) {
+ NEW_ERROR(1, ERROR, "runaway ‘else’ statement");
+ return 0;
}
- tree_stack[stack_ptr] = &(supernode->otherwise);
- }
- else if ((strstr(line, "if") == line) && ((line[2] == ' ') || (line[2] == '\0')))
- {
- /* else if */
- mds_kbdc_tree_if_t* supernode = &(tree_stack[stack_ptr - 1][0]->if_);
- NEW_NODE(if, IF);
- node->loc_end = node->loc_start + 2;
- end = line += 2, prev_end_char = *end, *end = '\0';
- CHARS(condition);
- END;
- tree_stack[stack_ptr] = &(supernode->otherwise);
- BRANCH(NULL);
- }
- else
- {
- NEW_ERROR(1, ERROR, "expecting nothing or ‘if’");
- stack_ptr--;
- }
-
- return 0;
- fail:
- return -1;
+ line = STREND(line);
+ *end = prev_end_char, prev_end_char = '\0';
+ end = STREND(line);
+ SKIP_SPACES(line);
+ i = stack_ptr - 1;
+ while (!keyword_stack[i])
+ i--;
+ if (strcmp(keyword_stack[i], "if")) {
+ stack_ptr--;
+ line = original, end = STREND(line);
+ NEW_ERROR(1, ERROR, "runaway ‘else’ statement");
+ } else if (!*line) {
+ /* else */
+ mds_kbdc_tree_if_t *supernode = &tree_stack[stack_ptr - 1][0]->if_;
+ if (supernode->otherwise) {
+ line = strstr(LINE, "else");
+ end = line + 4, prev_end_char = *end;
+ NEW_ERROR(1, ERROR, "multiple ‘else’ statements");
+ mds_kbdc_tree_free(supernode->otherwise);
+ supernode->otherwise = NULL;
+ }
+ tree_stack[stack_ptr] = &supernode->otherwise;
+ } else if (strstr(line, "if") == line && (line[2] == ' ' || !line[2])) {
+ /* else if */
+ mds_kbdc_tree_if_t *supernode = &tree_stack[stack_ptr - 1][0]->if_;
+ NEW_NODE(if, IF);
+ node->loc_end = node->loc_start + 2;
+ end = line += 2, prev_end_char = *end, *end = '\0';
+ CHARS(condition);
+ END;
+ tree_stack[stack_ptr] = &(supernode->otherwise);
+ BRANCH(NULL);
+ } else {
+ NEW_ERROR(1, ERROR, "expecting nothing or ‘if’");
+ stack_ptr--;
+ }
+
+ return 0;
+fail:
+ return -1;
}
@@ -1066,20 +1037,21 @@ static int parse_else(void)
*
* @return Zero on success, -1 on error, 1 if the caller should go to `redo`
*/
-static int parse_for(void)
+static int
+parse_for(void)
{
- NEW_NODE(for, FOR);
- CHARS(first);
- TEST_FOR_KEYWORD("to");
- CHARS(last);
- TEST_FOR_KEYWORD("as");
- CHARS(variable);
- END;
- BRANCH("for");
-
- return 0;
- fail:
- return -1;
+ NEW_NODE(for, FOR);
+ CHARS(first);
+ TEST_FOR_KEYWORD("to");
+ CHARS(last);
+ TEST_FOR_KEYWORD("as");
+ CHARS(variable);
+ END;
+ BRANCH("for");
+
+ return 0;
+fail:
+ return -1;
}
@@ -1088,52 +1060,48 @@ static int parse_for(void)
*
* @return Zero on success, -1 on error, 1 if the caller should go to `redo`
*/
-static int parse_let(void)
+static int
+parse_let(void)
{
- NEW_NODE(let, LET);
- CHARS(variable);
- TEST_FOR_KEYWORD(":");
- *end = prev_end_char;
- SKIP_SPACES(line);
- if (*line == '{')
+ NEW_NODE(let, LET);
+ CHARS(variable);
+ TEST_FOR_KEYWORD(":");
+ *end = prev_end_char;
+ SKIP_SPACES(line);
+ if (*line == '{')
#define inner value
- BRANCH(NULL);
+ BRANCH(NULL);
#undef inner
- else
- LEAF;
- if (*line == '\0')
- {
- line = original, end = STREND(line), prev_end_char = '\0';
- NEW_ERROR(1, ERROR, "too few parameters");
- }
- else if (*line != '{')
- {
+ else
+ LEAF;
+ if (!*line) {
+ line = original, end = STREND(line), prev_end_char = '\0';
+ NEW_ERROR(1, ERROR, "too few parameters");
+ } else if (*line != '{') {
#define node subnode
- NEW_NODE(string, STRING);
- NO_JUMP;
- CHARS(string);
- node->loc_end = (size_t)(end - LINE);
+ NEW_NODE(string, STRING);
+ NO_JUMP;
+ CHARS(string);
+ node->loc_end = (size_t)(end - LINE);
#undef node
- node->value = (mds_kbdc_tree_t*)subnode;
- END;
- }
- else
- {
+ node->value = (mds_kbdc_tree_t*)subnode;
+ END;
+ } else {
#define node subnode
#define inner elements
- NEW_NODE(array, ARRAY);
- BRANCH("}");
- node->loc_end = node->loc_start + 1;
+ NEW_NODE(array, ARRAY);
+ BRANCH("}");
+ node->loc_end = node->loc_start + 1;
#undef inner
#undef node
- in_array = 1;
- line++;
- return 1;
- }
-
- return 0;
- fail:
- return -1;
+ in_array = 1;
+ line++;
+ return 1;
+ }
+
+ return 0;
+fail:
+ return -1;
}
@@ -1142,29 +1110,28 @@ static int parse_let(void)
*
* @return Zero on success, -1 on error, 1 if the caller should go to `redo`
*/
-static int parse_end(void)
+static int
+parse_end(void)
{
- if (stack_ptr == 0)
- {
- NEW_ERROR(1, ERROR, "runaway ‘end’ statement");
- return 0;
- }
- line = STREND(line);
- *end = prev_end_char, prev_end_char = '\0';
- SKIP_SPACES(line);
- while (keyword_stack[--stack_ptr] == NULL);
- if (*line == '\0')
- {
- line = original, end = STREND(line);
- NEW_ERROR(1, ERROR, "expecting a keyword after ‘end’");
- }
- else if (strcmp(line, keyword_stack[stack_ptr]))
- NEW_ERROR(1, ERROR, "expected ‘%s’ but got ‘%s’", keyword_stack[stack_ptr], line);
- NEXT;
-
- return 0;
- fail:
- return -1;
+ if (!stack_ptr) {
+ NEW_ERROR(1, ERROR, "runaway ‘end’ statement");
+ return 0;
+ }
+ line = STREND(line);
+ *end = prev_end_char, prev_end_char = '\0';
+ SKIP_SPACES(line);
+ while (!keyword_stack[--stack_ptr]);
+ if (!*line) {
+ line = original, end = STREND(line);
+ NEW_ERROR(1, ERROR, "expecting a keyword after ‘end’");
+ } else if (strcmp(line, keyword_stack[stack_ptr])) {
+ NEW_ERROR(1, ERROR, "expected ‘%s’ but got ‘%s’", keyword_stack[stack_ptr], line);
+ }
+ NEXT;
+
+ return 0;
+fail:
+ return -1;
}
@@ -1173,57 +1140,56 @@ static int parse_end(void)
*
* @return Zero on success, -1 on error, 1 if the caller should go to `redo`
*/
-static int parse_map(void)
+static int
+parse_map(void)
{
- size_t stack_orig = stack_ptr + 1;
- char* colon;
+ size_t stack_orig = stack_ptr + 1;
+ char *colon;
#define node supernode
#define inner sequence
- NEW_NODE(map, MAP);
- node->loc_end = node->loc_start;
- BRANCH(":");
+ NEW_NODE(map, MAP);
+ node->loc_end = node->loc_start;
+ BRANCH(":");
#undef inner
#undef node
- SEQUENCE(1);
- SEQUENCE_FULLY_POPPED;
+ SEQUENCE(1);
+ SEQUENCE_FULLY_POPPED;
#define node supernode
#define inner result
- stack_ptr--;
- *end = prev_end_char;
- supernode->loc_end = (size_t)(end - LINE);
- SKIP_SPACES(line);
- if (colon = line, *line++ != ':')
- {
- LEAF;
- prev_end_char = *end;
- return 0; /* Not an error in functions, or if \set is access, even indirectly. */
- }
- BRANCH(":");
+ stack_ptr--;
+ *end = prev_end_char;
+ supernode->loc_end = (size_t)(end - LINE);
+ SKIP_SPACES(line);
+ if (colon = line, *line++ != ':') {
+ LEAF;
+ prev_end_char = *end;
+ return 0; /* Not an error in functions, or if \set is access, even indirectly. */
+ }
+ BRANCH(":");
#undef inner
#undef node
- SEQUENCE(1);
- SEQUENCE_FULLY_POPPED;
- stack_ptr--;
- *end = prev_end_char;
- supernode->loc_end = (size_t)(end - LINE);
- SKIP_SPACES(line);
+ SEQUENCE(1);
+ SEQUENCE_FULLY_POPPED;
+ stack_ptr--;
+ *end = prev_end_char;
+ supernode->loc_end = (size_t)(end - LINE);
+ SKIP_SPACES(line);
#define node supernode
- LEAF;
+ LEAF;
#undef node
- if (supernode->result == NULL)
- {
- NEW_ERROR(1, ERROR, "output missing");
- error->start = (size_t)(colon - LINE);
- error->end = error->start + 1;
- }
- if (*line == '\0')
- return prev_end_char = *end, 0;
- end = STREND(line), prev_end_char = *end;
- NEW_ERROR(1, ERROR, "too many parameters");
-
- return 0;
- fail:
- return -1;
+ if (!supernode->result) {
+ NEW_ERROR(1, ERROR, "output missing");
+ error->start = (size_t)(colon - LINE);
+ error->end = error->start + 1;
+ }
+ if (!*line)
+ return prev_end_char = *end, 0;
+ end = STREND(line), prev_end_char = *end;
+ NEW_ERROR(1, ERROR, "too many parameters");
+
+ return 0;
+fail:
+ return -1;
}
@@ -1232,63 +1198,59 @@ static int parse_map(void)
*
* @return Zero on success, -1 on error, 1 if the caller should go to `redo`
*/
-static int parse_macro_call(void)
+static int
+parse_macro_call(void)
{
- char* old_end = end;
- char old_prev_end_char = prev_end_char;
- size_t stack_orig = stack_ptr + 1;
- *end = prev_end_char;
- end = strchrnul(line, '(');
- prev_end_char = *end, *end = '\0';
- if (prev_end_char)
- {
+ char *old_end = end;
+ char old_prev_end_char = prev_end_char;
+ size_t stack_orig = stack_ptr + 1;
+ *end = prev_end_char;
+ end = strchrnul(line, '(');
+ prev_end_char = *end, *end = '\0';
+ if (prev_end_char) {
#define node supernode
#define inner arguments
- NEW_NODE(macro_call, MACRO_CALL);
- old_end = end, old_prev_end_char = prev_end_char;
- NO_JUMP;
- *old_end = '\0';
- CHARS(name);
- BRANCH(NULL);
- end = old_end, prev_end_char = old_prev_end_char;
- line++;
+ NEW_NODE(macro_call, MACRO_CALL);
+ old_end = end, old_prev_end_char = prev_end_char;
+ NO_JUMP;
+ *old_end = '\0';
+ CHARS(name);
+ BRANCH(NULL);
+ end = old_end, prev_end_char = old_prev_end_char;
+ line++;
#undef inner
#undef node
- SEQUENCE(0);
- SEQUENCE_FULLY_POPPED;
+ SEQUENCE(0);
+ SEQUENCE_FULLY_POPPED;
#define node supernode
- if (*line == ')')
- {
- line++;
- SKIP_SPACES(line);
- if (*line)
- {
- NEW_ERROR(1, ERROR, "extra token after macro call");
- error->end = strlen(LINE);
- }
- }
- else
- {
- NEW_ERROR(1, ERROR, "missing ‘)’");
- error->start = (size_t)(strchr(LINE, '(') - LINE);
- error->end = error->start + 1;
- }
- stack_ptr--;
- NEXT;
- return 0;
+ if (*line == ')') {
+ line++;
+ SKIP_SPACES(line);
+ if (*line) {
+ NEW_ERROR(1, ERROR, "extra token after macro call");
+ error->end = strlen(LINE);
+ }
+ } else {
+ NEW_ERROR(1, ERROR, "missing ‘)’");
+ error->start = (size_t)(strchr(LINE, '(') - LINE);
+ error->end = error->start + 1;
+ }
+ stack_ptr--;
+ NEXT;
+ return 0;
#undef node
- }
- *old_end = '\0';
- end = old_end;
- prev_end_char = old_prev_end_char;
- if (strchr("}", *line))
- NEW_ERROR(1, ERROR, "runaway ‘%c’", *line);
- else
- NEW_ERROR(1, ERROR, "invalid syntax ‘%s’", line);
-
- return 0;
- fail:
- return -1;
+ }
+ *old_end = '\0';
+ end = old_end;
+ prev_end_char = old_prev_end_char;
+ if (strchr("}", *line))
+ NEW_ERROR(1, ERROR, "runaway ‘%c’", *line);
+ else
+ NEW_ERROR(1, ERROR, "invalid syntax ‘%s’", line);
+
+ return 0;
+fail:
+ return -1;
}
@@ -1297,48 +1259,44 @@ static int parse_macro_call(void)
*
* @return Zero on success, -1 on error, 1 if the caller should go to `redo`
*/
-static int parse_array_elements(void)
+static int
+parse_array_elements(void)
{
- for (;;)
- {
- SKIP_SPACES(line);
- if (*line == '\0')
- return 0;
- else if (*line == '}')
- {
- line++;
- end = STREND(line);
- END;
- line = end, prev_end_char = '\0';
- goto done;
+ for (;;) {
+ SKIP_SPACES(line);
+ if (!*line) {
+ return 0;
+ } else if (*line == '}') {
+ line++;
+ end = STREND(line);
+ END;
+ line = end, prev_end_char = '\0';
+ goto done;
+ } else {
+ NEW_NODE(string, STRING);
+ if (strchr("[]()<>{}", *line)) {
+ mds_kbdc_tree_free((mds_kbdc_tree_t*)node);
+ NEW_ERROR(1, ERROR, "x-stray ‘%c’", *line);
+ error->end = error->start + 1;
+ goto done;
+ }
+ NO_JUMP;
+ CHARS(string);
+ LEAF;
+ node->loc_end = (size_t)(end - LINE);
+ *end = prev_end_char;
+ line = end;
+ }
}
- else
- {
- NEW_NODE(string, STRING);
- if (strchr("[]()<>{}", *line))
- {
- mds_kbdc_tree_free((mds_kbdc_tree_t*)node);
- NEW_ERROR(1, ERROR, "x-stray ‘%c’", *line);
- error->end = error->start + 1;
- goto done;
- }
- NO_JUMP;
- CHARS(string);
- LEAF;
- node->loc_end = (size_t)(end - LINE);
- *end = prev_end_char;
- line = end;
- }
- }
-
- fail:
- return -1;
-
- done:
- in_array = 0;
- stack_ptr -= 2;
- NEXT;
- return 0;
+
+fail:
+ return -1;
+
+done:
+ in_array = 0;
+ stack_ptr -= 2;
+ NEXT;
+ return 0;
}
@@ -1347,50 +1305,47 @@ static int parse_array_elements(void)
*
* @return Zero on success, -1 on error
*/
-static int parse_line(void)
+static int
+parse_line(void)
{
-#define p(function) \
- do \
- { \
- fail_if (r = function(), r < 0); \
- if (r > 0) \
- goto redo; \
- } \
- while (0)
-
- int r;
-
- redo:
- if (in_array) p (parse_array_elements);
- else if (!strcmp(line, "have_chars"))
- MAKE_LEAF(assumption_have_chars, ASSUMPTION_HAVE_CHARS, QUOTES_1(chars));
- else if (!strcmp(line, "have_range"))
- MAKE_LEAF(assumption_have_range, ASSUMPTION_HAVE_RANGE, CHARS(first); CHARS(last); END);
- else if (!strcmp(line, "have")) MAKE_LEAF(assumption_have, ASSUMPTION_HAVE, KEYS(data); END);
- else if (!strcmp(line, "information")) MAKE_BRANCH(information, INFORMATION, NO_PARAMETERS("information"));
- else if (!strcmp(line, "assumption")) MAKE_BRANCH(assumption, ASSUMPTION, NO_PARAMETERS("assumption"));
- else if (!strcmp(line, "return")) MAKE_LEAF(return, RETURN, NO_PARAMETERS("return"));
- else if (!strcmp(line, "continue")) MAKE_LEAF(continue, CONTINUE, NO_PARAMETERS("continue"));
- else if (!strcmp(line, "break")) MAKE_LEAF(break, BREAK, NO_PARAMETERS("break"));
- else if (!strcmp(line, "language")) MAKE_LEAF(information_language, INFORMATION_LANGUAGE, QUOTES_1(data));
- else if (!strcmp(line, "country")) MAKE_LEAF(information_country, INFORMATION_COUNTRY, QUOTES_1(data));
- else if (!strcmp(line, "variant")) MAKE_LEAF(information_variant, INFORMATION_VARIANT, QUOTES_1(data));
- else if (!strcmp(line, "include")) MAKE_LEAF(include, INCLUDE, QUOTES_1(filename));
- else if (!strcmp(line, "function")) MAKE_BRANCH(function, FUNCTION, NAMES_1(name));
- else if (!strcmp(line, "macro")) MAKE_BRANCH(macro, MACRO, NAMES_1(name));
- else if (!strcmp(line, "if")) MAKE_BRANCH(if, IF, CHARS(condition); END);
- else if (!strcmp(line, "else")) p (parse_else);
- else if (!strcmp(line, "for")) p (parse_for);
- else if (!strcmp(line, "let")) p (parse_let);
- else if (!strcmp(line, "end")) p (parse_end);
- else if (strchr("\\\"<([0123456789", *line)) p (parse_map);
- else p (parse_macro_call);
-
- *end = prev_end_char;
-
- return 0;
- fail:
- return -1;
+#define p(function)\
+ do {\
+ fail_if ((r = function()) < 0);\
+ if (r > 0)\
+ goto redo;\
+ } while (0)
+
+ int r;
+
+redo:
+ if (in_array) p (parse_array_elements);
+ else if (!strcmp(line, "have_chars")) MAKE_LEAF(assumption_have_chars, ASSUMPTION_HAVE_CHARS, QUOTES_1(chars));
+ else if (!strcmp(line, "have_range")) MAKE_LEAF(assumption_have_range, ASSUMPTION_HAVE_RANGE, CHARS(first); CHARS(last); END);
+ else if (!strcmp(line, "have")) MAKE_LEAF(assumption_have, ASSUMPTION_HAVE, KEYS(data); END);
+ else if (!strcmp(line, "information")) MAKE_BRANCH(information, INFORMATION, NO_PARAMETERS("information"));
+ else if (!strcmp(line, "assumption")) MAKE_BRANCH(assumption, ASSUMPTION, NO_PARAMETERS("assumption"));
+ else if (!strcmp(line, "return")) MAKE_LEAF(return, RETURN, NO_PARAMETERS("return"));
+ else if (!strcmp(line, "continue")) MAKE_LEAF(continue, CONTINUE, NO_PARAMETERS("continue"));
+ else if (!strcmp(line, "break")) MAKE_LEAF(break, BREAK, NO_PARAMETERS("break"));
+ else if (!strcmp(line, "language")) MAKE_LEAF(information_language, INFORMATION_LANGUAGE, QUOTES_1(data));
+ else if (!strcmp(line, "country")) MAKE_LEAF(information_country, INFORMATION_COUNTRY, QUOTES_1(data));
+ else if (!strcmp(line, "variant")) MAKE_LEAF(information_variant, INFORMATION_VARIANT, QUOTES_1(data));
+ else if (!strcmp(line, "include")) MAKE_LEAF(include, INCLUDE, QUOTES_1(filename));
+ else if (!strcmp(line, "function")) MAKE_BRANCH(function, FUNCTION, NAMES_1(name));
+ else if (!strcmp(line, "macro")) MAKE_BRANCH(macro, MACRO, NAMES_1(name));
+ else if (!strcmp(line, "if")) MAKE_BRANCH(if, IF, CHARS(condition); END);
+ else if (!strcmp(line, "else")) p (parse_else);
+ else if (!strcmp(line, "for")) p (parse_for);
+ else if (!strcmp(line, "let")) p (parse_let);
+ else if (!strcmp(line, "end")) p (parse_end);
+ else if (strchr("\\\"<([0123456789", *line)) p (parse_map);
+ else p (parse_macro_call);
+
+ *end = prev_end_char;
+
+ return 0;
+fail:
+ return -1;
#undef p
}
@@ -1406,63 +1361,62 @@ static int parse_line(void)
* @param result_ Output parameter for the parsing result
* @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
*/
-int parse_to_tree(const char* restrict filename, mds_kbdc_parsed_t* restrict result_)
+int
+parse_to_tree(const char *restrict filename, mds_kbdc_parsed_t *restrict result_)
{
- size_t line_n;
- int r, saved_errno;
-
-
- /* Prepare parsing. */
- result = result_;
- stack_ptr = 0;
- keyword_stack = NULL;
- tree_stack = NULL;
- in_array = 0;
-
- fail_if (xmalloc(result->source_code, 1, mds_kbdc_source_code_t));
- mds_kbdc_source_code_initialise(result->source_code);
-
- r = get_pathname(filename);
- fail_if (r < 0);
- if (r == 0)
- return 0;
-
- fail_if (read_source_code());
- fail_if (allocate_stacks());
-
-
- /* Create a node-slot for the tree root. */
- *tree_stack = &(result->tree);
-
- /* Parse the file. */
- for (line_i = 0, line_n = result->source_code->line_count; line_i < line_n; line_i++)
- {
- line = LINE;
- SKIP_SPACES(line);
- if (end = strchrnul(line, ' '), end == line)
- continue;
- prev_end_char = *end, *end = '\0';
- original = line;
- too_few = 0;
-
- parse_line();
- }
-
-
- /* Check parsing state. */
- fail_if (check_for_premature_end_of_file());
- fail_if (check_whether_file_is_empty());
-
- /* Clean up. */
- free(keyword_stack);
- free(tree_stack);
- return 0;
-
- fail:
- saved_errno = errno;
- free(keyword_stack);
- free(tree_stack);
- return errno = saved_errno, -1;
+ size_t line_n;
+ int r, saved_errno;
+
+
+ /* Prepare parsing. */
+ result = result_;
+ stack_ptr = 0;
+ keyword_stack = NULL;
+ tree_stack = NULL;
+ in_array = 0;
+
+ fail_if (xmalloc(result->source_code, 1, mds_kbdc_source_code_t));
+ mds_kbdc_source_code_initialise(result->source_code);
+
+ fail_if ((r = get_pathname(filename)) < 0);
+ if (!r)
+ return 0;
+
+ fail_if (read_source_code());
+ fail_if (allocate_stacks());
+
+
+ /* Create a node-slot for the tree root. */
+ *tree_stack = &(result->tree);
+
+ /* Parse the file. */
+ for (line_i = 0, line_n = result->source_code->line_count; line_i < line_n; line_i++) {
+ line = LINE;
+ SKIP_SPACES(line);
+ if ((end = strchrnul(line, ' ')) == line)
+ continue;
+ prev_end_char = *end, *end = '\0';
+ original = line;
+ too_few = 0;
+
+ parse_line();
+ }
+
+
+ /* Check parsing state. */
+ fail_if (check_for_premature_end_of_file());
+ fail_if (check_whether_file_is_empty());
+
+ /* Clean up. */
+ free(keyword_stack);
+ free(tree_stack);
+ return 0;
+
+fail:
+ saved_errno = errno;
+ free(keyword_stack);
+ free(tree_stack);
+ return errno = saved_errno, -1;
}
@@ -1493,4 +1447,3 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_parsed_t* restrict res
#undef in_range
#undef PRINT_STACK
#undef DEBUG_PROC
-
diff --git a/src/mds-kbdc/make-tree.h b/src/mds-kbdc/make-tree.h
index c645d94..0878414 100644
--- a/src/mds-kbdc/make-tree.h
+++ b/src/mds-kbdc/make-tree.h
@@ -29,8 +29,7 @@
* @param result Output parameter for the parsing result
* @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
*/
-int parse_to_tree(const char* restrict filename, mds_kbdc_parsed_t* restrict result);
+int parse_to_tree(const char *restrict filename, mds_kbdc_parsed_t *restrict result);
#endif
-
diff --git a/src/mds-kbdc/mds-kbdc.c b/src/mds-kbdc/mds-kbdc.c
index 1c5a6e8..0f668e4 100644
--- a/src/mds-kbdc/mds-kbdc.c
+++ b/src/mds-kbdc/mds-kbdc.c
@@ -37,15 +37,13 @@
/**
* Parse command line arguments
*/
-static void parse_cmdline(void)
+static void
+parse_cmdline(void)
{
- int i;
- for (i = 0; i < argc; i++)
- {
- char* arg = argv[i];
- if (strequals(arg, "--force"))
- argv_force = 1;
- }
+ int i;
+ for (i = 0; i < argc; i++)
+ if (strequals(argv[i], "--force"))
+ argv_force = 1;
}
@@ -56,39 +54,39 @@ static void parse_cmdline(void)
* @param argv_ The command line arguments
* @return Zero on and only one success
*/
-int main(int argc_, char** argv_)
+int
+main(int argc_, char **argv_)
{
-#define process(expr) \
- fail_if ((expr) < 0); \
- if (fatal = mds_kbdc_parsed_is_fatal(&result), fatal) \
- goto stop;
-
- mds_kbdc_parsed_t result;
- int fatal;
-
- argc = argc_;
- argv = argv_;
-
- parse_cmdline();
-
- mds_kbdc_parsed_initialise(&result);
- process (parse_to_tree(argv[1], &result));
- process (simplify_tree(&result));
- process (process_includes(&result));
- process (validate_tree(&result));
- process (eliminate_dead_code(&result));
- process (compile_layout(&result));
- /* TODO process (assemble_layout(&result)); */
- stop:
- /* mds_kbdc_tree_print(result.tree, stderr); // for testing passes parse_to_tree–eliminate_dead_code */
- mds_kbdc_parsed_print_errors(&result, stderr);
- mds_kbdc_parsed_destroy(&result);
- return fatal;
-
- fail:
- xperror(*argv);
- mds_kbdc_parsed_destroy(&result);
- return 1;
+#define process(expr)\
+ fail_if ((expr) < 0);\
+ if ((fatal = mds_kbdc_parsed_is_fatal(&result)))\
+ goto stop;
+
+ mds_kbdc_parsed_t result;
+ int fatal;
+
+ argc = argc_;
+ argv = argv_;
+
+ parse_cmdline();
+
+ mds_kbdc_parsed_initialise(&result);
+ process (parse_to_tree(argv[1], &result));
+ process (simplify_tree(&result));
+ process (process_includes(&result));
+ process (validate_tree(&result));
+ process (eliminate_dead_code(&result));
+ process (compile_layout(&result));
+ /* TODO process (assemble_layout(&result)); */
+stop:
+ /* mds_kbdc_tree_print(result.tree, stderr); // for testing passes parse_to_tree–eliminate_dead_code */
+ mds_kbdc_parsed_print_errors(&result, stderr);
+ mds_kbdc_parsed_destroy(&result);
+ return fatal;
+
+fail:
+ xperror(*argv);
+ mds_kbdc_parsed_destroy(&result);
+ return 1;
#undef process
}
-
diff --git a/src/mds-kbdc/mds-kbdc.h b/src/mds-kbdc/mds-kbdc.h
index a0f0d0f..8cf6204 100644
--- a/src/mds-kbdc/mds-kbdc.h
+++ b/src/mds-kbdc/mds-kbdc.h
@@ -23,4 +23,3 @@
#endif
-
diff --git a/src/mds-kbdc/parse-error.c b/src/mds-kbdc/parse-error.c
index 242b730..6a31424 100644
--- a/src/mds-kbdc/parse-error.c
+++ b/src/mds-kbdc/parse-error.c
@@ -32,46 +32,45 @@
* @param output The output file
* @param desc The description of the error
*/
-static void print(const mds_kbdc_parse_error_t* restrict this, FILE* restrict output, const char* restrict desc)
+static void
+print(const mds_kbdc_parse_error_t *restrict this, FILE *restrict output, const char *restrict desc)
{
- size_t i, n, start = 0, end = 0;
- const char* restrict code = this->code;
- char* restrict path = relpath(this->pathname, NULL);
-
- /* Convert bytes count to character count for the code position. */
- for (i = 0, n = this->start; i < n; i++)
- if ((code[i] & 0xC0) != 0x80)
- start++;
- for (n = this->end; i < n; i++)
- if ((code[i] & 0xC0) != 0x80)
- end++;
- end += start;
-
- /* Print error information. */
- fprintf(output, "\033[01m%s\033[21m:", path ? path : this->pathname);
- free(path);
- if (this->error_is_in_file)
- fprintf(output, "%zu:%zu–%zu:", this->line + 1, start, end);
- switch (this->severity)
- {
- case MDS_KBDC_PARSE_ERROR_NOTE: fprintf(output, " \033[01;36mnote:\033[00m "); break;
- case MDS_KBDC_PARSE_ERROR_WARNING: fprintf(output, " \033[01;35mwarning:\033[00m "); break;
- case MDS_KBDC_PARSE_ERROR_ERROR: fprintf(output, " \033[01;31merror:\033[00m "); break;
- case MDS_KBDC_PARSE_ERROR_INTERNAL_ERROR: fprintf(output, " \033[01;31minternal error:\033[00m "); break;
- default:
- abort();
- break;
- }
- if (this->error_is_in_file)
- {
- fprintf(output, "%s\n %s\n \033[01;32m", desc, code);
- i = 0;
- for (n = start; i < n; i++) fputc(' ', output);
- for (n = end; i < n; i++) fputc('^', output);
- }
- else
- fprintf(output, "%s\n", desc);
- fprintf(output, "\033[00m\n");
+ size_t i, n, start = 0, end = 0;
+ const char *restrict code = this->code;
+ char *restrict path = relpath(this->pathname, NULL);
+
+ /* Convert bytes count to character count for the code position. */
+ for (i = 0, n = this->start; i < n; i++)
+ if ((code[i] & 0xC0) != 0x80)
+ start++;
+ for (n = this->end; i < n; i++)
+ if ((code[i] & 0xC0) != 0x80)
+ end++;
+ end += start;
+
+ /* Print error information. */
+ fprintf(output, "\033[01m%s\033[21m:", path ? path : this->pathname);
+ free(path);
+ if (this->error_is_in_file)
+ fprintf(output, "%zu:%zu–%zu:", this->line + 1, start, end);
+ switch (this->severity) {
+ case MDS_KBDC_PARSE_ERROR_NOTE: fprintf(output, " \033[01;36mnote:\033[00m "); break;
+ case MDS_KBDC_PARSE_ERROR_WARNING: fprintf(output, " \033[01;35mwarning:\033[00m "); break;
+ case MDS_KBDC_PARSE_ERROR_ERROR: fprintf(output, " \033[01;31merror:\033[00m "); break;
+ case MDS_KBDC_PARSE_ERROR_INTERNAL_ERROR: fprintf(output, " \033[01;31minternal error:\033[00m "); break;
+ default:
+ abort();
+ break;
+ }
+ if (this->error_is_in_file) {
+ fprintf(output, "%s\n %s\n \033[01;32m", desc, code);
+ i = 0;
+ for (n = start; i < n; i++) fputc(' ', output);
+ for (n = end; i < n; i++) fputc('^', output);
+ } else {
+ fprintf(output, "%s\n", desc);
+ }
+ fprintf(output, "\033[00m\n");
}
@@ -81,49 +80,57 @@ static void print(const mds_kbdc_parse_error_t* restrict this, FILE* restrict ou
* @param this The error structure
* @param output The output file
*/
-void mds_kbdc_parse_error_print(const mds_kbdc_parse_error_t* restrict this, FILE* restrict output)
+void
+mds_kbdc_parse_error_print(const mds_kbdc_parse_error_t *restrict this, FILE *restrict output)
{
- ssize_t m;
- size_t n;
- char* desc;
- char* dend = this->description + strlen(this->description);
- char* dstart;
- char* dptr;
- char* p;
- char* q;
-
- /* Count the number points in the description we should modify to format it. */
- for (p = this->description, n = 0;;)
- {
- if (q = strstr(p, "‘"), q == NULL) q = dend;
- if (p = strstr(p, "’"), p == NULL) p = dend;
- if (q < p) p = q;
- if (*p++) n++;
- else break;
- }
-
- /* Allocate string for the formatted description. */
- n = 1 + strlen(this->description) + strlen("\033[xxm’") * n;
- dptr = desc = alloca(n * sizeof(char));
-
- /* Format description. */
- for (p = this->description;;)
- {
- dstart = p;
- if (q = strstr(p, "‘"), q == NULL) q = dend;
- if (p = strstr(p, "’"), p == NULL) p = dend;
- if (q < p) p = q;
- if ((n = (size_t)(p - dstart)))
- memcpy(dptr, dstart, n), dptr += n;
- if (p == dend)
- break;
- if (strstr(p, "‘") == p) sprintf(dptr, "\033[01m‘%zn", &m), dptr += (size_t)m, p += strlen("‘");
- else sprintf(dptr, "’\033[21m%zn", &m), dptr += (size_t)m, p += strlen("’");
- }
- *dptr = '\0';
-
- /* Print the error. */
- print(this, output, desc);
+ size_t n;
+ char *desc;
+ char *dend = this->description + strlen(this->description);
+ char *dstart;
+ char *dptr;
+ char *p;
+ char *q;
+
+ /* Count the number points in the description we should modify to format it. */
+ for (p = this->description, n = 0;;) {
+ if (!(q = strstr(p, "‘")))
+ q = dend;
+ if (!(p = strstr(p, "’")))
+ p = dend;
+ if (q < p)
+ p = q;
+ if (*p++)
+ n++;
+ else
+ break;
+ }
+
+ /* Allocate string for the formatted description. */
+ n = 1 + strlen(this->description) + strlen("\033[xxm’") * n;
+ dptr = desc = alloca(n * sizeof(char));
+
+ /* Format description. */
+ for (p = this->description;;) {
+ dstart = p;
+ if (!(q = strstr(p, "‘")))
+ q = dend;
+ if (!(p = strstr(p, "’")))
+ p = dend;
+ if (q < p)
+ p = q;
+ if ((n = (size_t)(p - dstart)))
+ memcpy(dptr, dstart, n), dptr += n;
+ if (p == dend)
+ break;
+ if (strstr(p, "‘") == p)
+ dptr += sprintf(dptr, "\033[01m‘"), p += strlen("‘");
+ else
+ dptr += sprintf(dptr, "’\033[21m"), p += strlen("’");
+ }
+ *dptr = '\0';
+
+ /* Print the error. */
+ print(this, output, desc);
}
@@ -133,13 +140,14 @@ void mds_kbdc_parse_error_print(const mds_kbdc_parse_error_t* restrict this, FIL
*
* @param this The error structure
*/
-void mds_kbdc_parse_error_destroy(mds_kbdc_parse_error_t* restrict this)
+void
+mds_kbdc_parse_error_destroy(mds_kbdc_parse_error_t *restrict this)
{
- if (this == NULL)
- return;
- free(this->pathname), this->pathname = NULL;
- free(this->code), this->code = NULL;
- free(this->description), this->description = NULL;
+ if (!this)
+ return;
+ free(this->pathname), this->pathname = NULL;
+ free(this->code), this->code = NULL;
+ free(this->description), this->description = NULL;
}
@@ -149,10 +157,11 @@ void mds_kbdc_parse_error_destroy(mds_kbdc_parse_error_t* restrict this)
*
* @param this The error structure
*/
-void mds_kbdc_parse_error_free(mds_kbdc_parse_error_t* restrict this)
+void
+mds_kbdc_parse_error_free(mds_kbdc_parse_error_t *restrict this)
{
- mds_kbdc_parse_error_destroy(this);
- free(this);
+ mds_kbdc_parse_error_destroy(this);
+ free(this);
}
@@ -162,13 +171,14 @@ void mds_kbdc_parse_error_free(mds_kbdc_parse_error_t* restrict this)
*
* @param this The group of error structures
*/
-void mds_kbdc_parse_error_destroy_all(mds_kbdc_parse_error_t** restrict these)
+void
+mds_kbdc_parse_error_destroy_all(mds_kbdc_parse_error_t **restrict these)
{
- mds_kbdc_parse_error_t* restrict that;
- if (these == NULL)
- return;
- while (that = *these, that != NULL)
- mds_kbdc_parse_error_free(that), *these++ = NULL;
+ mds_kbdc_parse_error_t *restrict that;
+ if (!these)
+ return;
+ while ((that = *these))
+ mds_kbdc_parse_error_free(that), *these++ = NULL;
}
@@ -178,9 +188,9 @@ void mds_kbdc_parse_error_destroy_all(mds_kbdc_parse_error_t** restrict these)
*
* @param this The group of error structures
*/
-void mds_kbdc_parse_error_free_all(mds_kbdc_parse_error_t** restrict these)
+void
+mds_kbdc_parse_error_free_all(mds_kbdc_parse_error_t**restrict these)
{
- mds_kbdc_parse_error_destroy_all(these);
- free(these);
+ mds_kbdc_parse_error_destroy_all(these);
+ free(these);
}
-
diff --git a/src/mds-kbdc/parse-error.h b/src/mds-kbdc/parse-error.h
index b7e879c..9668f8f 100644
--- a/src/mds-kbdc/parse-error.h
+++ b/src/mds-kbdc/parse-error.h
@@ -27,74 +27,72 @@
/**
* Not an error, simply a note about the previous error or warning
*/
-#define MDS_KBDC_PARSE_ERROR_NOTE 1
+#define MDS_KBDC_PARSE_ERROR_NOTE 1
/**
* A warning, must likely an error that is not fatal to the compilation
*/
-#define MDS_KBDC_PARSE_ERROR_WARNING 2
+#define MDS_KBDC_PARSE_ERROR_WARNING 2
/**
* An error, the compilation will halt
*/
-#define MDS_KBDC_PARSE_ERROR_ERROR 3
+#define MDS_KBDC_PARSE_ERROR_ERROR 3
/**
* Internal compiler error or system error, compilation halts
*/
-#define MDS_KBDC_PARSE_ERROR_INTERNAL_ERROR 4
+#define MDS_KBDC_PARSE_ERROR_INTERNAL_ERROR 4
/**
* Description of an parsing error
*/
-typedef struct mds_kbdc_parse_error
-{
- /**
- * Either of:
- * - `MDS_KBDC_PARSE_ERROR_NOTE`
- * - `MDS_KBDC_PARSE_ERROR_WARNING`
- * - `MDS_KBDC_PARSE_ERROR_ERROR`
- * - `MDS_KBDC_PARSE_ERROR_INTERNAL_ERROR`
- */
- int severity;
-
- /**
- * If zero, disregard `.line`, `.start`, `.end` and `.code`
- */
- int error_is_in_file;
-
- /**
- * The pathname of the file with the error
- */
- char* pathname;
-
- /**
- * The line where the error occurred, zero-based
- */
- size_t line;
-
- /**
- * The byte where the error started, inclusive, zero-based
- */
- size_t start;
-
- /**
- * The byte where the error ended, exclusive, zero-based
- */
- size_t end;
-
- /**
- * The code on the line where the error occurred
- */
- char* code;
-
- /**
- * Description of the error
- */
- char* description;
-
+typedef struct mds_kbdc_parse_error {
+ /**
+ * Either of:
+ * - `MDS_KBDC_PARSE_ERROR_NOTE`
+ * - `MDS_KBDC_PARSE_ERROR_WARNING`
+ * - `MDS_KBDC_PARSE_ERROR_ERROR`
+ * - `MDS_KBDC_PARSE_ERROR_INTERNAL_ERROR`
+ */
+ int severity;
+
+ /**
+ * If zero, disregard `.line`, `.start`, `.end` and `.code`
+ */
+ int error_is_in_file;
+
+ /**
+ * The pathname of the file with the error
+ */
+ char *pathname;
+
+ /**
+ * The line where the error occurred, zero-based
+ */
+ size_t line;
+
+ /**
+ * The byte where the error started, inclusive, zero-based
+ */
+ size_t start;
+
+ /**
+ * The byte where the error ended, exclusive, zero-based
+ */
+ size_t end;
+
+ /**
+ * The code on the line where the error occurred
+ */
+ char *code;
+
+ /**
+ * Description of the error
+ */
+ char *description;
} mds_kbdc_parse_error_t;
@@ -105,7 +103,7 @@ typedef struct mds_kbdc_parse_error
* @param this The error structure
* @param output The output file
*/
-void mds_kbdc_parse_error_print(const mds_kbdc_parse_error_t* restrict this, FILE* restrict output);
+void mds_kbdc_parse_error_print(const mds_kbdc_parse_error_t *restrict this, FILE *restrict output);
/**
@@ -113,7 +111,7 @@ void mds_kbdc_parse_error_print(const mds_kbdc_parse_error_t* restrict this, FIL
*
* @param this The error structure
*/
-void mds_kbdc_parse_error_destroy(mds_kbdc_parse_error_t* restrict this);
+void mds_kbdc_parse_error_destroy(mds_kbdc_parse_error_t *restrict this);
/**
* Release all resources allocated in a `mds_kbdc_parse_error_t*`
@@ -121,7 +119,7 @@ void mds_kbdc_parse_error_destroy(mds_kbdc_parse_error_t* restrict this);
*
* @param this The error structure
*/
-void mds_kbdc_parse_error_free(mds_kbdc_parse_error_t* restrict this);
+void mds_kbdc_parse_error_free(mds_kbdc_parse_error_t *restrict this);
/**
* Release all resources allocated in a `NULL`-terminated group
@@ -129,7 +127,7 @@ void mds_kbdc_parse_error_free(mds_kbdc_parse_error_t* restrict this);
*
* @param this The group of error structures
*/
-void mds_kbdc_parse_error_destroy_all(mds_kbdc_parse_error_t** restrict these);
+void mds_kbdc_parse_error_destroy_all(mds_kbdc_parse_error_t **restrict these);
/**
* Release all resources allocated in a `NULL`-terminated group of
@@ -137,9 +135,8 @@ void mds_kbdc_parse_error_destroy_all(mds_kbdc_parse_error_t** restrict these);
*
* @param this The group of error structures
*/
-void mds_kbdc_parse_error_free_all(mds_kbdc_parse_error_t** restrict these);
+void mds_kbdc_parse_error_free_all(mds_kbdc_parse_error_t **restrict these);
#endif
-
diff --git a/src/mds-kbdc/parsed.c b/src/mds-kbdc/parsed.c
index d9c8f23..e4c23dc 100644
--- a/src/mds-kbdc/parsed.c
+++ b/src/mds-kbdc/parsed.c
@@ -28,9 +28,10 @@
*
* @param this The `mds_kbdc_parsed_t*`
*/
-void mds_kbdc_parsed_initialise(mds_kbdc_parsed_t* restrict this)
+void
+mds_kbdc_parsed_initialise(mds_kbdc_parsed_t *restrict this)
{
- memset(this, 0, sizeof(mds_kbdc_parsed_t));
+ memset(this, 0, sizeof(mds_kbdc_parsed_t));
}
@@ -39,27 +40,28 @@ void mds_kbdc_parsed_initialise(mds_kbdc_parsed_t* restrict this)
*
* @param this The `mds_kbdc_parsed_t*`
*/
-void mds_kbdc_parsed_destroy(mds_kbdc_parsed_t* restrict this)
+void
+mds_kbdc_parsed_destroy(mds_kbdc_parsed_t *restrict this)
{
- mds_kbdc_tree_free(this->tree);
- mds_kbdc_source_code_destroy(this->source_code);
- free(this->source_code);
- free(this->pathname);
- mds_kbdc_parse_error_free_all(this->errors);
- while (this->languages_ptr--)
- free(this->languages[this->languages_ptr]);
- free(this->languages);
- while (this->countries_ptr--)
- free(this->countries[this->countries_ptr]);
- free(this->countries);
- free(this->variant);
- while (this->assumed_strings_ptr--)
- free(this->assumed_strings[this->assumed_strings_ptr]);
- free(this->assumed_strings);
- while (this->assumed_keys_ptr--)
- free(this->assumed_keys[this->assumed_keys_ptr]);
- free(this->assumed_keys);
- memset(this, 0, sizeof(mds_kbdc_parsed_t));
+ mds_kbdc_tree_free(this->tree);
+ mds_kbdc_source_code_destroy(this->source_code);
+ free(this->source_code);
+ free(this->pathname);
+ mds_kbdc_parse_error_free_all(this->errors);
+ while (this->languages_ptr--)
+ free(this->languages[this->languages_ptr]);
+ free(this->languages);
+ while (this->countries_ptr--)
+ free(this->countries[this->countries_ptr]);
+ free(this->countries);
+ free(this->variant);
+ while (this->assumed_strings_ptr--)
+ free(this->assumed_strings[this->assumed_strings_ptr]);
+ free(this->assumed_strings);
+ while (this->assumed_keys_ptr--)
+ free(this->assumed_keys[this->assumed_keys_ptr]);
+ free(this->assumed_keys);
+ memset(this, 0, sizeof(mds_kbdc_parsed_t));
}
@@ -69,9 +71,10 @@ void mds_kbdc_parsed_destroy(mds_kbdc_parsed_t* restrict this)
* @param this The parsing result
* @return Whether a fatal errors has occurred
*/
-int mds_kbdc_parsed_is_fatal(mds_kbdc_parsed_t* restrict this)
+int
+mds_kbdc_parsed_is_fatal(mds_kbdc_parsed_t *restrict this)
{
- return this->severest_error_level >= MDS_KBDC_PARSE_ERROR_ERROR;
+ return this->severest_error_level >= MDS_KBDC_PARSE_ERROR_ERROR;
}
@@ -81,23 +84,22 @@ int mds_kbdc_parsed_is_fatal(mds_kbdc_parsed_t* restrict this)
* @param this The parsing result
* @param output The output file
*/
-void mds_kbdc_parsed_print_errors(mds_kbdc_parsed_t* restrict this, FILE* output)
+void
+mds_kbdc_parsed_print_errors(mds_kbdc_parsed_t *restrict this, FILE *output)
{
- mds_kbdc_parse_error_t** errors = this->errors;
- char* env = getenv("MDS_KBDC_ERRORS_ORDER");
- if (errors == NULL)
- return;
- if (env && (strcasecmp(env, "reversed") || strcasecmp(env, "reverse")))
- {
- while (*errors)
- errors++;
- while (errors-- != this->errors)
- mds_kbdc_parse_error_print(*errors, output);
- }
- else
- while (*errors)
- mds_kbdc_parse_error_print(*errors++, output);
-
+ mds_kbdc_parse_error_t **errors = this->errors;
+ char *env = getenv("MDS_KBDC_ERRORS_ORDER");
+ if (!errors) {
+ return;
+ } else if (env && (strcasecmp(env, "reversed") || strcasecmp(env, "reverse"))) {
+ while (*errors)
+ errors++;
+ while (errors-- != this->errors)
+ mds_kbdc_parse_error_print(*errors, output);
+ } else {
+ while (*errors)
+ mds_kbdc_parse_error_print(*errors++, output);
+ }
}
@@ -112,49 +114,47 @@ void mds_kbdc_parsed_print_errors(mds_kbdc_parsed_t* restrict this, FILE* output
* @param end The byte where the error ended, on the line, exclusive, zero-based
* @return The new error on success, `NULL` on error
*/
-mds_kbdc_parse_error_t* mds_kbdc_parsed_new_error(mds_kbdc_parsed_t* restrict this, int severity,
- int error_is_in_file, size_t line, size_t start, size_t end)
+mds_kbdc_parse_error_t *
+mds_kbdc_parsed_new_error(mds_kbdc_parsed_t *restrict this, int severity,
+ int error_is_in_file, size_t line, size_t start, size_t end)
{
- mds_kbdc_parse_error_t* error = NULL;
- size_t old_errors_ptr = this->errors_ptr;
- int saved_errno;
-
- if (this->errors_ptr + 1 >= this->errors_size)
- {
- size_t new_errors_size = this->errors_size ? (this->errors_size << 1) : 2;
- mds_kbdc_parse_error_t** new_errors = this->errors;
-
- fail_if (xrealloc(new_errors, new_errors_size, mds_kbdc_parse_error_t*));
- this->errors = new_errors;
- this->errors_size = new_errors_size;
- }
-
- fail_if (xcalloc(error, 1, mds_kbdc_parse_error_t));
- this->errors[this->errors_ptr + 0] = error;
- this->errors[this->errors_ptr + 1] = NULL;
- this->errors_ptr++;
-
- error->severity = severity;
- if (this->severest_error_level < severity)
- this->severest_error_level = severity;
-
- fail_if (xstrdup(error->pathname, this->pathname));
-
- if ((error->error_is_in_file = error_is_in_file))
- {
- error->line = line;
- error->start = start;
- error->end = end;
- fail_if (xstrdup(error->code, this->source_code->real_lines[line]));
- }
-
- return error;
- fail:
- saved_errno = errno;
- free(error);
- this->errors_ptr = old_errors_ptr;
- this->errors[this->errors_ptr] = NULL;
- errno = saved_errno;
- return NULL;
-}
+ mds_kbdc_parse_error_t *error = NULL, **new_errors;
+ size_t old_errors_ptr = this->errors_ptr, new_errors_size;
+ int saved_errno;
+
+ if (this->errors_ptr + 1 >= this->errors_size) {
+ new_errors_size = this->errors_size ? (this->errors_size << 1) : 2;
+ new_errors = this->errors;
+
+ fail_if (xrealloc(new_errors, new_errors_size, mds_kbdc_parse_error_t*));
+ this->errors = new_errors;
+ this->errors_size = new_errors_size;
+ }
+
+ fail_if (xcalloc(error, 1, mds_kbdc_parse_error_t));
+ this->errors[this->errors_ptr + 0] = error;
+ this->errors[this->errors_ptr + 1] = NULL;
+ this->errors_ptr++;
+ error->severity = severity;
+ if (this->severest_error_level < severity)
+ this->severest_error_level = severity;
+
+ fail_if (xstrdup(error->pathname, this->pathname));
+
+ if ((error->error_is_in_file = error_is_in_file)) {
+ error->line = line;
+ error->start = start;
+ error->end = end;
+ fail_if (xstrdup(error->code, this->source_code->real_lines[line]));
+ }
+
+ return error;
+fail:
+ saved_errno = errno;
+ free(error);
+ this->errors_ptr = old_errors_ptr;
+ this->errors[this->errors_ptr] = NULL;
+ errno = saved_errno;
+ return NULL;
+}
diff --git a/src/mds-kbdc/parsed.h b/src/mds-kbdc/parsed.h
index 7d01695..58ad6fa 100644
--- a/src/mds-kbdc/parsed.h
+++ b/src/mds-kbdc/parsed.h
@@ -42,15 +42,13 @@
* @param ...:const char*, ... Error description format string and arguments
* @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
*/
-#define NEW_ERROR_(RESULT, SEVERITY, ERROR_IS_IN_FILE, LINE, START, END, WITH_DESCRIPTION, ...) \
- do \
- { \
- error = mds_kbdc_parsed_new_error(RESULT, MDS_KBDC_PARSE_ERROR_##SEVERITY, \
- ERROR_IS_IN_FILE, LINE, START, END); \
- fail_if (error == NULL); \
- fail_if (WITH_DESCRIPTION && xasprintf(error->description, __VA_ARGS__)); \
- } \
- while (0)
+#define NEW_ERROR_(RESULT, SEVERITY, ERROR_IS_IN_FILE, LINE, START, END, WITH_DESCRIPTION, ...)\
+ do {\
+ error = mds_kbdc_parsed_new_error(RESULT, MDS_KBDC_PARSE_ERROR_##SEVERITY,\
+ ERROR_IS_IN_FILE, LINE, START, END);\
+ fail_if (!error);\
+ fail_if (WITH_DESCRIPTION && xasprintf(error->description, __VA_ARGS__));\
+ } while (0)
@@ -58,115 +56,113 @@
* Structure with parsed tree, error list
* source code and the file's pathname
*/
-typedef struct mds_kbdc_parsed
-{
- /**
- * The parsed tree
- */
- mds_kbdc_tree_t* tree;
-
- /**
- * The source code of the parsed file
- */
- mds_kbdc_source_code_t* source_code;
-
- /**
- * A non-relative pathname to the parsed file.
- * Relative filenames can be misleading as the
- * program can have changed working directory
- * to be able to resolve filenames.
- */
- char* pathname;
-
- /**
- * `NULL`-terminated list of found errors
- * `NULL` if no errors that could be listed
- * were found
- */
- mds_kbdc_parse_error_t** errors;
-
- /**
- * The number of elements allocated to `errors`
- */
- size_t errors_size;
-
- /**
- * The number of elements stored in `errors`
- */
- size_t errors_ptr;
-
- /**
- * The level of the severest countered error,
- * 0 if none has been encountered.
- */
- int severest_error_level;
-
- /**
- * List of languages for which the layout is designed
- */
- char** languages;
-
- /**
- * The number of elements allocated to `languages`
- */
- size_t languages_size;
-
- /**
- * The number of elements stored in `languages`
- */
- size_t languages_ptr;
-
- /**
- * List of countries for which the layout is designed
- */
- char** countries;
-
- /**
- * The number of elements allocated to `countries`
- */
- size_t countries_size;
-
- /**
- * The number of elements stored in `countries`
- */
- size_t countries_ptr;
-
- /**
- * The variant of the keyboard for the languages/countries,
- * `NULL` if not specified
- */
- char* variant;
-
- /**
- * List of strings the assembler should assume are provided
- */
- char32_t** assumed_strings;
-
- /**
- * The number of elements allocated to `assumed_strings`
- */
- size_t assumed_strings_size;
-
- /**
- * The number of elements stored in `assumed_strings`
- */
- size_t assumed_strings_ptr;
-
- /**
- * List of keys the assembler should assume are provided
- */
- char32_t** assumed_keys;
-
- /**
- * The number of elements allocated to `assumed_keys`
- */
- size_t assumed_keys_size;
-
- /**
- * The number of elements stored in `assumed_keys`
- */
- size_t assumed_keys_ptr;
-
+typedef struct mds_kbdc_parsed {
+ /**
+ * The parsed tree
+ */
+ mds_kbdc_tree_t *tree;
+
+ /**
+ * The source code of the parsed file
+ */
+ mds_kbdc_source_code_t *source_code;
+
+ /**
+ * A non-relative pathname to the parsed file.
+ * Relative filenames can be misleading as the
+ * program can have changed working directory
+ * to be able to resolve filenames.
+ */
+ char *pathname;
+
+ /**
+ * `NULL`-terminated list of found errors
+ * `NULL` if no errors that could be listed
+ * were found
+ */
+ mds_kbdc_parse_error_t **errors;
+
+ /**
+ * The number of elements allocated to `errors`
+ */
+ size_t errors_size;
+
+ /**
+ * The number of elements stored in `errors`
+ */
+ size_t errors_ptr;
+
+ /**
+ * The level of the severest countered error,
+ * 0 if none has been encountered.
+ */
+ int severest_error_level;
+
+ /**
+ * List of languages for which the layout is designed
+ */
+ char **languages;
+
+ /**
+ * The number of elements allocated to `languages`
+ */
+ size_t languages_size;
+
+ /**
+ * The number of elements stored in `languages`
+ */
+ size_t languages_ptr;
+
+ /**
+ * List of countries for which the layout is designed
+ */
+ char **countries;
+
+ /**
+ * The number of elements allocated to `countries`
+ */
+ size_t countries_size;
+
+ /**
+ * The number of elements stored in `countries`
+ */
+ size_t countries_ptr;
+
+ /**
+ * The variant of the keyboard for the languages/countries,
+ * `NULL` if not specified
+ */
+ char *variant;
+
+ /**
+ * List of strings the assembler should assume are provided
+ */
+ char32_t **assumed_strings;
+
+ /**
+ * The number of elements allocated to `assumed_strings`
+ */
+ size_t assumed_strings_size;
+
+ /**
+ * The number of elements stored in `assumed_strings`
+ */
+ size_t assumed_strings_ptr;
+
+ /**
+ * List of keys the assembler should assume are provided
+ */
+ char32_t **assumed_keys;
+
+ /**
+ * The number of elements allocated to `assumed_keys`
+ */
+ size_t assumed_keys_size;
+
+ /**
+ * The number of elements stored in `assumed_keys`
+ */
+ size_t assumed_keys_ptr;
} mds_kbdc_parsed_t;
@@ -176,14 +172,14 @@ typedef struct mds_kbdc_parsed
*
* @param this The `mds_kbdc_parsed_t*`
*/
-void mds_kbdc_parsed_initialise(mds_kbdc_parsed_t* restrict this);
+void mds_kbdc_parsed_initialise(mds_kbdc_parsed_t *restrict this);
/**
* Release all resources allocated in a `mds_kbdc_parsed_t*`
*
* @param this The `mds_kbdc_parsed_t*`
*/
-void mds_kbdc_parsed_destroy(mds_kbdc_parsed_t* restrict this);
+void mds_kbdc_parsed_destroy(mds_kbdc_parsed_t *restrict this);
/**
* Check whether a fatal errors has occurred
@@ -191,7 +187,8 @@ void mds_kbdc_parsed_destroy(mds_kbdc_parsed_t* restrict this);
* @param this The parsing result
* @return Whether a fatal errors has occurred
*/
-int mds_kbdc_parsed_is_fatal(mds_kbdc_parsed_t* restrict this) __attribute__((pure));
+__attribute__((pure))
+int mds_kbdc_parsed_is_fatal(mds_kbdc_parsed_t *restrict this);
/**
* Print all encountered errors
@@ -199,7 +196,7 @@ int mds_kbdc_parsed_is_fatal(mds_kbdc_parsed_t* restrict this) __attribute__((pu
* @param this The parsing result
* @param output The output file
*/
-void mds_kbdc_parsed_print_errors(mds_kbdc_parsed_t* restrict this, FILE* output);
+void mds_kbdc_parsed_print_errors(mds_kbdc_parsed_t *restrict this, FILE *output);
/**
* Add a new error to the list
@@ -212,9 +209,8 @@ void mds_kbdc_parsed_print_errors(mds_kbdc_parsed_t* restrict this, FILE* output
* @param end The byte where the error ended, on the line, exclusive, zero-based
* @return The new error on success, `NULL` on error
*/
-mds_kbdc_parse_error_t* mds_kbdc_parsed_new_error(mds_kbdc_parsed_t* restrict this, int severity,
- int error_is_in_file, size_t line, size_t start, size_t end);
+mds_kbdc_parse_error_t *mds_kbdc_parsed_new_error(mds_kbdc_parsed_t *restrict this, int severity,
+ int error_is_in_file, size_t line, size_t start, size_t end);
#endif
-
diff --git a/src/mds-kbdc/paths.c b/src/mds-kbdc/paths.c
index 53ae6fa..70bddf1 100644
--- a/src/mds-kbdc/paths.c
+++ b/src/mds-kbdc/paths.c
@@ -31,32 +31,32 @@
*
* @return The current working directory
*/
-char* curpath(void)
+char *
+curpath(void)
{
- static size_t cwd_size = 4096;
- char* cwd = NULL;
- char* old = NULL;
- int saved_errno;
-
- /* glibc offers ways to do this in just one function call,
- * but we will not assume that glibc is used here. */
- for (;;)
- {
- fail_if (xxrealloc(old, cwd, cwd_size + 1, char));
- if (getcwd(cwd, cwd_size))
- break;
- else
- fail_if (errno != ERANGE);
- cwd_size <<= 1;
- }
-
- return cwd;
- fail:
- saved_errno = errno;
- free(old);
- free(cwd);
- errno = saved_errno;
- return NULL;
+ static size_t cwd_size = 4096;
+ char *cwd = NULL;
+ char *old = NULL;
+ int saved_errno;
+
+ /* glibc offers ways to do this in just one function call,
+ * but we will not assume that glibc is used here. */
+ for (;;) {
+ fail_if (xxrealloc(old, cwd, cwd_size + 1, char));
+ if (getcwd(cwd, cwd_size))
+ break;
+ else
+ fail_if (errno != ERANGE);
+ cwd_size <<= 1;
+ }
+
+ return cwd;
+fail:
+ saved_errno = errno;
+ free(old);
+ free(cwd);
+ errno = saved_errno;
+ return NULL;
}
@@ -66,53 +66,51 @@ char* curpath(void)
* @param path The filename of the file
* @return The file's absolute path, `NULL` on error
*/
-char* abspath(const char* path)
+char *
+abspath(const char *path)
{
- char* cwd = NULL;
- char* buf = NULL;
- int saved_errno, slash = 1;
- size_t size, p;
-
- if (*path == '/')
- {
- fail_if (xstrdup(buf, path));
- return buf;
- }
-
- fail_if (cwd = curpath(), cwd == NULL);
- size = (p = strlen(cwd)) + strlen(path) + 2;
- fail_if (xmalloc(buf, size + 1, char));
- memcpy(buf, cwd, (p + 1) * sizeof(char));
- if (buf[p - 1] != '/')
- buf[p++] = '/';
-
- while (*path)
- if (slash && (path[0] == '/'))
- path += 1;
- else if (slash && (path[0] == '.') && (path[1] == '/'))
- path += 2;
- else if (slash && (path[0] == '.') && (path[1] == '.') && (path[2] == '/'))
- {
- path += 3;
- p--;
- while (p && (buf[--p] != '/'));
- p++;
- }
- else
- {
- buf[p++] = *path;
- slash = (*path++ == '/');
- }
-
- buf[p] = '\0';
-
- free(cwd);
- return buf;
- fail:
- saved_errno = errno;
- free(cwd);
- errno = saved_errno;
- return NULL;
+ char *cwd = NULL;
+ char *buf = NULL;
+ int saved_errno, slash = 1;
+ size_t size, p;
+
+ if (*path == '/') {
+ fail_if (xstrdup(buf, path));
+ return buf;
+ }
+
+ fail_if (!(cwd = curpath()));
+ size = (p = strlen(cwd)) + strlen(path) + 2;
+ fail_if (xmalloc(buf, size + 1, char));
+ memcpy(buf, cwd, (p + 1) * sizeof(char));
+ if (buf[p - 1] != '/')
+ buf[p++] = '/';
+
+ while (*path) {
+ if (slash && path[0] == '/') {
+ path += 1;
+ } else if (slash && path[0] == '.' && path[1] == '/') {
+ path += 2;
+ } else if (slash && path[0] == '.' && path[1] == '.' && path[2] == '/') {
+ path += 3;
+ p--;
+ while (p && buf[--p] != '/');
+ p++;
+ } else {
+ buf[p++] = *path;
+ slash = *path++ == '/';
+ }
+ }
+
+ buf[p] = '\0';
+
+ free(cwd);
+ return buf;
+fail:
+ saved_errno = errno;
+ free(cwd);
+ errno = saved_errno;
+ return NULL;
}
@@ -124,46 +122,46 @@ char* abspath(const char* path)
* `NULL` for the current working directroy
* @return The file's relative path, `NULL` on error
*/
-char* relpath(const char* path, const char* base)
+char *
+relpath(const char *path, const char *base)
{
- char* abs = abspath(path);
- char* absbase = NULL;
- char* buf = NULL;
- char* old = NULL;
- int saved_errno;
- size_t p, slash = 1, back = 0;
-
- fail_if (abs == NULL);
- absbase = base ? abspath(base) : curpath();
- fail_if (absbase == NULL);
-
- if (absbase[strlen(absbase) - 1] != '/')
- /* Both `abspath` and `curpath` (and `relpath`) allocates one extra slot. */
- absbase[strlen(absbase) + 1] = '\0', absbase[strlen(absbase)] = '/';
-
- for (p = 1; abs[p] && absbase[p] && (abs[p] == absbase[p]); p++)
- if (abs[p] == '/')
- slash = p + 1;
-
- for (p = slash; absbase[p]; p++)
- if (absbase[p] == '/')
- back++;
-
- fail_if (xmalloc(buf, back * 3 + strlen(abs + slash) + 2, char));
-
- for (p = 0; back--;)
- buf[p++] = '.', buf[p++] = '.', buf[p++] = '/';
- memcpy(buf + p, abs + slash, (strlen(abs + slash) + 1) * sizeof(char));
-
- free(abs);
- free(absbase);
- return buf;
- fail:
- saved_errno = errno;
- free(abs);
- free(absbase);
- free(old);
- errno = saved_errno;
- return NULL;
-}
+ char *abs = abspath(path);
+ char *absbase = NULL;
+ char *buf = NULL;
+ char *old = NULL;
+ int saved_errno;
+ size_t p, slash = 1, back = 0;
+ fail_if (!abs);
+ absbase = base ? abspath(base) : curpath();
+ fail_if (!absbase);
+
+ if (absbase[strlen(absbase) - 1] != '/')
+ /* Both `abspath` and `curpath` (and `relpath`) allocates one extra slot. */
+ absbase[strlen(absbase) + 1] = '\0', absbase[strlen(absbase)] = '/';
+
+ for (p = 1; abs[p] && absbase[p] && abs[p] == absbase[p]; p++)
+ if (abs[p] == '/')
+ slash = p + 1;
+
+ for (p = slash; absbase[p]; p++)
+ if (absbase[p] == '/')
+ back++;
+
+ fail_if (xmalloc(buf, back * 3 + strlen(abs + slash) + 2, char));
+
+ for (p = 0; back--;)
+ buf[p++] = '.', buf[p++] = '.', buf[p++] = '/';
+ memcpy(buf + p, abs + slash, (strlen(abs + slash) + 1) * sizeof(char));
+
+ free(abs);
+ free(absbase);
+ return buf;
+fail:
+ saved_errno = errno;
+ free(abs);
+ free(absbase);
+ free(old);
+ errno = saved_errno;
+ return NULL;
+}
diff --git a/src/mds-kbdc/paths.h b/src/mds-kbdc/paths.h
index 6c24042..6dbe007 100644
--- a/src/mds-kbdc/paths.h
+++ b/src/mds-kbdc/paths.h
@@ -24,7 +24,7 @@
*
* @return The current working directory
*/
-char* curpath(void);
+char *curpath(void);
/**
* Get the absolute path of a file
@@ -32,7 +32,7 @@ char* curpath(void);
* @param path The filename of the file
* @return The file's absolute path, `NULL` on error
*/
-char* abspath(const char* path);
+char *abspath(const char *path);
/**
* Get a relative path of a file
@@ -42,8 +42,7 @@ char* abspath(const char* path);
* `NULL` for the current working directroy
* @return The file's relative path, `NULL` on error
*/
-char* relpath(const char* path, const char* base);
+char *relpath(const char* path, const char *base);
#endif
-
diff --git a/src/mds-kbdc/process-includes.c b/src/mds-kbdc/process-includes.c
index 69b9c73..a46533c 100644
--- a/src/mds-kbdc/process-includes.c
+++ b/src/mds-kbdc/process-includes.c
@@ -32,7 +32,7 @@
/**
* Tree type constant shortener
*/
-#define C(TYPE) MDS_KBDC_TREE_TYPE_##TYPE
+#define C(TYPE) MDS_KBDC_TREE_TYPE_##TYPE
/**
* Add an error to the error list
@@ -42,26 +42,26 @@
* @param ...:const char*, ... Error description format string and arguments
* @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
*/
-#define NEW_ERROR(NODE, SEVERITY, ...) \
- NEW_ERROR_(result, SEVERITY, 1, (NODE)->loc_line, \
- (NODE)->loc_start, (NODE)->loc_end, 1, __VA_ARGS__)
+#define NEW_ERROR(NODE, SEVERITY, ...)\
+ NEW_ERROR_(result, SEVERITY, 1, (NODE)->loc_line,\
+ (NODE)->loc_start, (NODE)->loc_end, 1, __VA_ARGS__)
/**
* Variable whether the latest created error is stored
*/
-static mds_kbdc_parse_error_t* error;
+static mds_kbdc_parse_error_t *error;
/**
* The parameter of `process_includes`
*/
-static mds_kbdc_parsed_t* restrict result;
+static mds_kbdc_parsed_t *restrict result;
/**
* Stack of attributes of already included files
*/
-static struct stat* restrict included;
+static struct stat *restrict included;
/**
* The number elements allocated for `included`
@@ -81,66 +81,62 @@ static size_t included_ptr = 0;
* @param subresult The results of the processed include
* @param tree The include statement
*/
-static int transfer_errors(mds_kbdc_parsed_t* restrict subresult, mds_kbdc_tree_include_t* restrict tree)
+static int
+transfer_errors(mds_kbdc_parsed_t *restrict subresult, mds_kbdc_tree_include_t *restrict tree)
{
- mds_kbdc_parse_error_t** errors = NULL;
- mds_kbdc_parse_error_t* suberror;
- size_t errors_ptr = 0;
- int saved_errno, annotated = 0;
-
- /* Allocate temporary list for errors. */
- if (subresult->errors_ptr == 0)
- return 0;
- fail_if (xmalloc(errors, subresult->errors_ptr * 2, mds_kbdc_parse_error_t*));
-
- /* List errors backwards, so that we can easily handle errors and add “included from here”-note. */
- while (subresult->errors_ptr--)
- {
- suberror = subresult->errors[subresult->errors_ptr];
-
- /* If it is more severe than a note, we want to say there it was included. */
- if (annotated == 0)
- {
- NEW_ERROR(tree, NOTE, "included from here");
- errors[errors_ptr++] = error;
- result->errors[--(result->errors_ptr)] = NULL;
- annotated = 1;
+ mds_kbdc_parse_error_t **errors = NULL, *suberror, **new_errors;
+ size_t errors_ptr = 0, new_errors_size;
+ int saved_errno, annotated = 0;
+
+ /* Allocate temporary list for errors. */
+ if (!subresult->errors_ptr)
+ return 0;
+ fail_if (xmalloc(errors, subresult->errors_ptr * 2, mds_kbdc_parse_error_t*));
+
+ /* List errors backwards, so that we can easily handle errors and add “included from here”-note. */
+ while (subresult->errors_ptr--) {
+ suberror = subresult->errors[subresult->errors_ptr];
+
+ /* If it is more severe than a note, we want to say there it was included. */
+ if (!annotated) {
+ NEW_ERROR(tree, NOTE, "included from here");
+ errors[errors_ptr++] = error;
+ result->errors[--(result->errors_ptr)] = NULL;
+ annotated = 1;
+ }
+
+ /* Include error. */
+ errors[errors_ptr++] = suberror;
+ subresult->errors[subresult->errors_ptr] = NULL;
+
+ /* Make sure when there are nested inclusions that the outermost inclusion * is annotated last. */
+ if (suberror->severity > MDS_KBDC_PARSE_ERROR_NOTE)
+ annotated = 0;
}
-
- /* Include error. */
- errors[errors_ptr++] = suberror;
- subresult->errors[subresult->errors_ptr] = NULL;
-
- /* Make sure when there are nested inclusions that the outermost inclusion * is annotated last. */
- if (suberror->severity > MDS_KBDC_PARSE_ERROR_NOTE)
- annotated = 0;
- }
-
- /* Append errors. */
- for (; errors_ptr--; errors[errors_ptr] = NULL)
- {
- if (result->errors_ptr + 1 >= result->errors_size)
- {
- size_t new_errors_size = result->errors_size ? (result->errors_size << 1) : 2;
- mds_kbdc_parse_error_t** new_errors = result->errors;
-
- fail_if (xrealloc(new_errors, new_errors_size, mds_kbdc_parse_error_t*));
- result->errors = new_errors;
- result->errors_size = new_errors_size;
+
+ /* Append errors. */
+ for (; errors_ptr--; errors[errors_ptr] = NULL) {
+ if (result->errors_ptr + 1 >= result->errors_size) {
+ new_errors_size = result->errors_size ? (result->errors_size << 1) : 2;
+ new_errors = result->errors;
+
+ fail_if (xrealloc(new_errors, new_errors_size, mds_kbdc_parse_error_t*));
+ result->errors = new_errors;
+ result->errors_size = new_errors_size;
+ }
+
+ result->errors[result->errors_ptr++] = errors[errors_ptr];
+ result->errors[result->errors_ptr] = NULL;
}
-
- result->errors[result->errors_ptr++] = errors[errors_ptr];
- result->errors[result->errors_ptr] = NULL;
- }
-
- free(errors);
- return 0;
- fail:
- saved_errno = errno;
- while (errors_ptr--)
- mds_kbdc_parse_error_free(errors[errors_ptr]);
- free(errors);
- return errno = saved_errno, -1;
+
+ free(errors);
+ return 0;
+fail:
+ saved_errno = errno;
+ while (errors_ptr--)
+ mds_kbdc_parse_error_free(errors[errors_ptr]);
+ free(errors);
+ return errno = saved_errno, -1;
}
@@ -150,86 +146,83 @@ static int transfer_errors(mds_kbdc_parsed_t* restrict subresult, mds_kbdc_tree_
* @param tree The include-statement
* @return Zero on success, -1 on error
*/
-static int process_include(mds_kbdc_tree_include_t* restrict tree)
+static int
+process_include(mds_kbdc_tree_include_t *restrict tree)
{
-#define process(expr) \
- fail_if ((expr) < 0); \
- if (mds_kbdc_parsed_is_fatal(&subresult)) \
- goto stop;
-
- mds_kbdc_parsed_t subresult;
- mds_kbdc_parsed_t* our_result;
- char* dirname = NULL;
- char* cwd = NULL;
- char* old = NULL;
- size_t cwd_size = 4096 >> 1;
- int saved_errno;
-
- /* Initialise result structure for the included file. */
- mds_kbdc_parsed_initialise(&subresult);
-
- /* Get dirname of current file. */
- fail_if (xstrdup(dirname, result->pathname));
- *(strrchr(dirname, '/')) = '\0';
-
- /* Get the current working directory. */
- /* glibc offers ways to do this in just one function call,
- * but we will not assume that glibc is used here. */
- for (;;)
- {
- fail_if (xxrealloc(old, cwd, cwd_size <<= 1, char));
- if (getcwd(cwd, cwd_size))
- break;
- else
- fail_if (errno != ERANGE);
- }
-
- /* Switch working directory. */
- fail_if (chdir(dirname));
- free(dirname), dirname = NULL;
-
- /* Store `result` as it will be switched by the inner `process_includes`. */
- our_result = result;
-
- /* Process include. */
- old = tree->filename, tree->filename = NULL;
- tree->filename = parse_raw_string(old);
- fail_if (tree->filename == NULL);
- free(old), old = NULL;
- process (parse_to_tree(tree->filename, &subresult));
- process (simplify_tree(&subresult));
- process (process_includes(&subresult));
- stop:
-
- /* Switch back `result`. */
- result = our_result;
-
- /* Switch back to the old working directory. */
- fail_if (chdir(cwd));
- free(cwd), cwd = NULL;
-
- /* Move over data to our result. */
- free(tree->filename);
- tree->filename = subresult.pathname, subresult.pathname = NULL;
- tree->source_code = subresult.source_code, subresult.source_code = NULL;
- tree->inner = subresult.tree, subresult.tree = NULL;
- if (result->severest_error_level < subresult.severest_error_level)
- result->severest_error_level = subresult.severest_error_level;
-
- /* Move over errors. */
- fail_if (transfer_errors(&subresult, tree));
-
- /* Release resources. */
- mds_kbdc_parsed_destroy(&subresult);
-
- return 0;
- fail:
- saved_errno = errno;
- free(dirname);
- free(cwd);
- free(old);
- mds_kbdc_parsed_destroy(&subresult);
- return errno = saved_errno, -1;
+#define process(expr)\
+ fail_if ((expr) < 0);\
+ if (mds_kbdc_parsed_is_fatal(&subresult))\
+ goto stop;
+
+ mds_kbdc_parsed_t subresult, *our_result;
+ char *dirname = NULL, *cwd = NULL, *old = NULL;
+ size_t cwd_size = 4096 >> 1;
+ int saved_errno;
+
+ /* Initialise result structure for the included file. */
+ mds_kbdc_parsed_initialise(&subresult);
+
+ /* Get dirname of current file. */
+ fail_if (xstrdup(dirname, result->pathname));
+ *(strrchr(dirname, '/')) = '\0';
+
+ /* Get the current working directory. */
+ /* glibc offers ways to do this in just one function call,
+ * but we will not assume that glibc is used here. */
+ for (;;) {
+ fail_if (xxrealloc(old, cwd, cwd_size <<= 1, char));
+ if (getcwd(cwd, cwd_size))
+ break;
+ else
+ fail_if (errno != ERANGE);
+ }
+
+ /* Switch working directory. */
+ fail_if (chdir(dirname));
+ free(dirname), dirname = NULL;
+
+ /* Store `result` as it will be switched by the inner `process_includes`. */
+ our_result = result;
+
+ /* Process include. */
+ old = tree->filename, tree->filename = NULL;
+ tree->filename = parse_raw_string(old);
+ fail_if (tree->filename == NULL);
+ free(old), old = NULL;
+ process (parse_to_tree(tree->filename, &subresult));
+ process (simplify_tree(&subresult));
+ process (process_includes(&subresult));
+stop:
+
+ /* Switch back `result`. */
+ result = our_result;
+
+ /* Switch back to the old working directory. */
+ fail_if (chdir(cwd));
+ free(cwd), cwd = NULL;
+
+ /* Move over data to our result. */
+ free(tree->filename);
+ tree->filename = subresult.pathname, subresult.pathname = NULL;
+ tree->source_code = subresult.source_code, subresult.source_code = NULL;
+ tree->inner = subresult.tree, subresult.tree = NULL;
+ if (result->severest_error_level < subresult.severest_error_level)
+ result->severest_error_level = subresult.severest_error_level;
+
+ /* Move over errors. */
+ fail_if (transfer_errors(&subresult, tree));
+
+ /* Release resources. */
+ mds_kbdc_parsed_destroy(&subresult);
+
+ return 0;
+fail:
+ saved_errno = errno;
+ free(dirname);
+ free(cwd);
+ free(old);
+ mds_kbdc_parsed_destroy(&subresult);
+ return errno = saved_errno, -1;
#undef process
}
@@ -240,32 +233,32 @@ static int process_include(mds_kbdc_tree_include_t* restrict tree)
* @param tree The tree
* @return Zero on success, -1 on error
*/
-static int process_includes_in_tree(mds_kbdc_tree_t* restrict tree)
+static int
+process_includes_in_tree(mds_kbdc_tree_t *restrict tree)
{
-#define p(expr) fail_if (process_includes_in_tree(tree->expr))
- again:
- if (tree == NULL)
- return 0;
-
- switch (tree->type)
- {
- case C(INFORMATION): p (information.inner); break;
- case C(FUNCTION): p (function.inner); break;
- case C(MACRO): p (macro.inner); break;
- case C(ASSUMPTION): p (assumption.inner); break;
- case C(FOR): p (for_.inner); break;
- case C(IF): p (if_.inner); p (if_.otherwise); break;
- case C(INCLUDE):
- fail_if (process_include(&(tree->include)));
- break;
- default:
- break;
- }
-
- tree = tree->next;
- goto again;
- fail:
- return -1;
+#define p(expr) fail_if (process_includes_in_tree(tree->expr))
+again:
+ if (!tree)
+ return 0;
+
+ switch (tree->type) {
+ case C(INFORMATION): p (information.inner); break;
+ case C(FUNCTION): p (function.inner); break;
+ case C(MACRO): p (macro.inner); break;
+ case C(ASSUMPTION): p (assumption.inner); break;
+ case C(FOR): p (for_.inner); break;
+ case C(IF): p (if_.inner); p (if_.otherwise); break;
+ case C(INCLUDE):
+ fail_if (process_include(&(tree->include)));
+ break;
+ default:
+ break;
+ }
+
+ tree = tree->next;
+ goto again;
+fail:
+ return -1;
#undef p
}
@@ -276,45 +269,43 @@ static int process_includes_in_tree(mds_kbdc_tree_t* restrict tree)
* @param result_ `result` from `simplify_tree`, will be updated
* @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
*/
-int process_includes(mds_kbdc_parsed_t* restrict result_)
+int
+process_includes(mds_kbdc_parsed_t *restrict result_)
{
- int r, saved_errno;
- struct stat attr;
- size_t i;
-
- result = result_;
-
- fail_if (stat(result->pathname, &attr));
-
- if (included_ptr == included_size)
- {
- struct stat* old;
- if (xxrealloc(old, included, included_size += 4, struct stat))
- fail_if (included = old, 1);
- }
-
- for (i = 0; i < included_ptr; i++)
- if ((included[i].st_dev == attr.st_dev) && (included[i].st_ino == attr.st_ino))
- {
- NEW_ERROR_(result, ERROR, 0, 0, 0, 0, 1, "resursive inclusion");
- return 0;
- }
-
- included[included_ptr++] = attr;
-
- r = process_includes_in_tree(result_->tree);
- saved_errno = errno;
-
- if (--included_ptr == 0)
- free(included), included_size = 0;
-
- return errno = saved_errno, r;
- fail:
- return -1;
+ int r, saved_errno;
+ struct stat attr, *old;
+ size_t i;
+
+ result = result_;
+
+ fail_if (stat(result->pathname, &attr));
+
+ if (included_ptr == included_size) {
+ if (xxrealloc(old, included, included_size += 4, struct stat))
+ fail_if (included = old, 1);
+ }
+
+ for (i = 0; i < included_ptr; i++) {
+ if ((included[i].st_dev == attr.st_dev) && (included[i].st_ino == attr.st_ino)) {
+ NEW_ERROR_(result, ERROR, 0, 0, 0, 0, 1, "resursive inclusion");
+ return 0;
+ }
+ }
+
+ included[included_ptr++] = attr;
+
+ r = process_includes_in_tree(result_->tree);
+ saved_errno = errno;
+
+ if (!--included_ptr)
+ free(included), included_size = 0;
+
+ return errno = saved_errno, r;
+fail:
+ return -1;
}
#undef NEW_ERROR
#undef C
-
diff --git a/src/mds-kbdc/process-includes.h b/src/mds-kbdc/process-includes.h
index 5644dd9..6146600 100644
--- a/src/mds-kbdc/process-includes.h
+++ b/src/mds-kbdc/process-includes.h
@@ -28,8 +28,7 @@
* @param result `result` from `simplify_tree`, will be updated
* @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
*/
-int process_includes(mds_kbdc_parsed_t* restrict result);
+int process_includes(mds_kbdc_parsed_t *restrict result);
#endif
-
diff --git a/src/mds-kbdc/raw-data.c b/src/mds-kbdc/raw-data.c
index e40be68..2b89840 100644
--- a/src/mds-kbdc/raw-data.c
+++ b/src/mds-kbdc/raw-data.c
@@ -39,14 +39,15 @@
*
* @param this The `mds_kbdc_source_code_t*`
*/
-void mds_kbdc_source_code_initialise(mds_kbdc_source_code_t* restrict this)
+void
+mds_kbdc_source_code_initialise(mds_kbdc_source_code_t *restrict this)
{
- this->lines = NULL;
- this->real_lines = NULL;
- this->content = NULL;
- this->real_content = NULL;
- this->line_count = 0;
- this->duplicates = 0;
+ this->lines = NULL;
+ this->real_lines = NULL;
+ this->content = NULL;
+ this->real_content = NULL;
+ this->line_count = 0;
+ this->duplicates = 0;
}
@@ -55,16 +56,17 @@ void mds_kbdc_source_code_initialise(mds_kbdc_source_code_t* restrict this)
*
* @param this The `mds_kbdc_source_code_t*`
*/
-void mds_kbdc_source_code_destroy(mds_kbdc_source_code_t* restrict this)
+void
+mds_kbdc_source_code_destroy(mds_kbdc_source_code_t *restrict this)
{
- if (this == NULL)
- return;
- if (this->duplicates--)
- return;
- free(this->lines), this->lines = NULL;
- free(this->real_lines), this->real_lines = NULL;
- free(this->content), this->content = NULL;
- free(this->real_content), this->real_content = NULL;
+ if (!this)
+ return;
+ if (this->duplicates--)
+ return;
+ free(this->lines), this->lines = NULL;
+ free(this->real_lines), this->real_lines = NULL;
+ free(this->content), this->content = NULL;
+ free(this->real_content), this->real_content = NULL;
}
@@ -73,17 +75,18 @@ void mds_kbdc_source_code_destroy(mds_kbdc_source_code_t* restrict this)
*
* @param this The `mds_kbdc_source_code_t*`
*/
-void mds_kbdc_source_code_free(mds_kbdc_source_code_t* restrict this)
+void
+mds_kbdc_source_code_free(mds_kbdc_source_code_t *restrict this)
{
- if (this == NULL)
- return;
- if (this->duplicates--)
- return;
- free(this->lines);
- free(this->real_lines);
- free(this->content);
- free(this->real_content);
- free(this);
+ if (!this)
+ return;
+ if (this->duplicates--)
+ return;
+ free(this->lines);
+ free(this->real_lines);
+ free(this->content);
+ free(this->real_content);
+ free(this);
}
/**
@@ -92,10 +95,11 @@ void mds_kbdc_source_code_free(mds_kbdc_source_code_t* restrict this)
* @param this The `mds_kbdc_source_code_t*`
* @return `this` is returned
*/
-mds_kbdc_source_code_t* mds_kbdc_source_code_dup(mds_kbdc_source_code_t* restrict this)
+mds_kbdc_source_code_t *
+mds_kbdc_source_code_dup(mds_kbdc_source_code_t *restrict this)
{
- this->duplicates++;
- return this;
+ this->duplicates++;
+ return this;
}
@@ -107,51 +111,51 @@ mds_kbdc_source_code_t* mds_kbdc_source_code_dup(mds_kbdc_source_code_t* restric
* @param size Output parameter for the size of the read content, in char:s
* @return The read content, `NULL` on error
*/
-static char* read_file(const char* restrict pathname, size_t* restrict size)
+static char *
+read_file(const char *restrict pathname, size_t *restrict size)
{
- size_t buf_size = 8096;
- size_t buf_ptr = 0;
- char* restrict content = NULL;
- char* restrict old = NULL;
- int fd = -1;
- ssize_t got;
-
- /* Allocate buffer for the file's content. */
- fail_if (xmalloc(content, buf_size, char));
- /* Open the file to compile. */
- fail_if ((fd = open(pathname, O_RDONLY)) < 0);
-
- /* Read the file to compile. */
- for (;;)
- {
- /* Make sure the buffer is not small. */
- if (buf_size - buf_ptr < 2048)
- fail_if (xxrealloc(old, content, buf_size <<= 1, char));
- /* Read a chunk of the file. */
- got = read(fd, content + buf_ptr, (buf_size - buf_ptr) * sizeof(char));
- if ((got < 0) && (errno == EINTR)) continue;
- if (got == 0) break;
- fail_if (got < 0);
- buf_ptr += (size_t)got;
- }
-
- /* Shrink the buffer so it is not excessively large. */
- if (buf_ptr) /* Simplest way to handle empty files: let the have the initial allocation size. */
- fail_if (xxrealloc(old, content, buf_ptr, char));
-
- /* Close file decriptor for the file. */
- xclose(fd);
-
- *size = buf_ptr;
- return content;
-
- fail:
- xperror(*argv);
- free(old);
- free(content);
- if (fd >= 0)
- xclose(fd);
- return NULL;
+ size_t buf_size = 8096;
+ size_t buf_ptr = 0;
+ char *restrict content = NULL;
+ char *restrict old = NULL;
+ int fd = -1;
+ ssize_t got;
+
+ /* Allocate buffer for the file's content. */
+ fail_if (xmalloc(content, buf_size, char));
+ /* Open the file to compile. */
+ fail_if ((fd = open(pathname, O_RDONLY)) < 0);
+
+ /* Read the file to compile. */
+ for (;;) {
+ /* Make sure the buffer is not small. */
+ if (buf_size - buf_ptr < 2048)
+ fail_if (xxrealloc(old, content, buf_size <<= 1, char));
+ /* Read a chunk of the file. */
+ got = read(fd, content + buf_ptr, (buf_size - buf_ptr) * sizeof(char));
+ if (got < 0 && errno == EINTR) continue;
+ if (got == 0) break;
+ fail_if (got < 0);
+ buf_ptr += (size_t)got;
+ }
+
+ /* Shrink the buffer so it is not excessively large. */
+ if (buf_ptr) /* Simplest way to handle empty files: let the have the initial allocation size. */
+ fail_if (xxrealloc(old, content, buf_ptr, char));
+
+ /* Close file decriptor for the file. */
+ xclose(fd);
+
+ *size = buf_ptr;
+ return content;
+
+fail:
+ xperror(*argv);
+ free(old);
+ free(content);
+ if (fd >= 0)
+ xclose(fd);
+ return NULL;
}
@@ -167,54 +171,59 @@ static char* read_file(const char* restrict pathname, size_t* restrict size)
* or `size` if the call do not end (that is, the code ends
* prematurely), or zero if there is no function call at `offset`
*/
-size_t get_end_of_call(const char* restrict content, size_t offset, size_t size)
+size_t
+get_end_of_call(const char *restrict content, size_t offset, size_t size)
{
-#define C content[ptr]
-#define r(lower, upper) (((lower) <= C) && (C <= (upper)))
-
- size_t ptr = offset, call_end = 0;
- int escape = 0, quote = 0;
-
- /* Skip to end of function name. */
- while ((ptr < size) && (r('a', 'z') || r('A', 'Z') || r('0', '9') || (C == '_')))
- ptr++;
-
- /* Check that it is a function call. */
- if ((ptr == size) || (ptr == offset) || (C != '('))
- return 0;
-
- /* Find the end of the function call. */
- while (ptr < size)
- {
- char c = content[ptr++];
-
- /* Escapes may be longer than one character,
- but only the first can affect the parsing. */
- if (escape) escape = 0;
- /* Nested function and nested quotes can appear. */
- else if (ptr <= call_end) ;
- /* Quotes end with the same symbols as they start with,
- and quotes automatically escape brackets. */
- /* \ can either start a functon call or an escape. */
- else if (c == '\\')
- {
- /* It may not be an escape, but registering it
- as an escape cannot harm us since we only
- skip the first character, and a function call
- cannot be that short. */
- escape = 1;
- /* Nested quotes can appear at function calls. */
- call_end = get_end_of_call(content, ptr, size);
+#define C content[ptr]
+#define r(lower, upper) ((lower) <= C && C <= (upper))
+
+ size_t ptr = offset, call_end = 0;
+ int escape = 0, quote = 0;
+ char c;
+
+ /* Skip to end of function name. */
+ while (ptr < size && (r('a', 'z') || r('A', 'Z') || r('0', '9') || (C == '_')))
+ ptr++;
+
+ /* Check that it is a function call. */
+ if (ptr == size || ptr == offset || C != '(')
+ return 0;
+
+ /* Find the end of the function call. */
+ while (ptr < size) {
+ c = content[ptr++];
+
+ if (escape) {
+ /* Escapes may be longer than one character,
+ but only the first can affect the parsing. */
+ escape = 0;
+ } else if (ptr <= call_end) {
+ /* Nested function and nested quotes can appear. */;
+ } else if (c == '\\') {
+ /* Quotes end with the same symbols as they start with,
+ and quotes automatically escape brackets. */
+ /* \ can either start a functon call or an escape. */
+
+ /* It may not be an escape, but registering it
+ as an escape cannot harm us since we only
+ skip the first character, and a function call
+ cannot be that short. */
+ escape = 1;
+ /* Nested quotes can appear at function calls. */
+ call_end = get_end_of_call(content, ptr, size);
+ } else if (quote) {
+ quote = (c != '"');
+ } else if (c == ')') {
+ /* End of function call, end of fun. */
+ break;
+ } else if (c == '"') {
+ /* " is the quote symbol. */
+ quote = 1;
+ }
}
- else if (quote) quote = (c != '"');
- /* End of function call, end of fun. */
- else if (c == ')') break;
- /* " is the quote symbol. */
- else if (c == '"') quote = 1;
- }
-
- return ptr;
-
+
+ return ptr;
+
#undef r
#undef C
}
@@ -227,55 +236,58 @@ size_t get_end_of_call(const char* restrict content, size_t offset, size_t size)
* @param size The size of `content`, in char:s
* @return The new size of `content`, in char:s; this function cannot fail
*/
-static size_t remove_comments(char* restrict content, size_t size)
+static size_t
+remove_comments(char *restrict content, size_t size)
{
-#define t content[n_ptr++] = c
-
- size_t n_ptr = 0, o_ptr = 0, call_end = 0;
- int comment = 0, quote = 0, escape = 0;
-
- while (o_ptr < size)
- {
- char c = content[o_ptr++];
- /* Remove comment. */
- if (comment)
- {
- if (c == '\n') t, comment = 0;
- }
- /* Escapes may be longer than one character,
- but only the first can affect the parsing. */
- else if (escape) t, escape = 0;
- /* Nested quotes can appear at function calls. */
- else if (o_ptr <= call_end) t;
- /* \ can either start a functon call or an escape. */
- else if (c == '\\')
- {
- t;
- /* It may not be an escape, but registering it
- as an escape cannot harm us since we only
- skip the first character, and a function call
- cannot be that short. */
- escape = 1;
- /* Nested quotes can appear at function calls. */
- call_end = get_end_of_call(content, o_ptr, size);
- }
- /* Quotes end with the same symbols as they start with,
- and quotes automatically escape comments. */
- else if (quote)
- {
- t;
- if (strchr("\"\n", c)) quote = 0;
+#define t content[n_ptr++] = c
+
+ size_t n_ptr = 0, o_ptr = 0, call_end = 0;
+ int comment = 0, quote = 0, escape = 0;
+ char c;
+
+ while (o_ptr < size) {
+ c = content[o_ptr++];
+ if (comment) {
+ /* Remove comment. */
+ if (c == '\n')
+ t, comment = 0;
+ } else if (escape) {
+ /* Escapes may be longer than one character,
+ but only the first can affect the parsing. */
+ t, escape = 0;
+ } else if (o_ptr <= call_end) {
+ /* Nested quotes can appear at function calls. */
+ t;
+ } else if (c == '\\') {
+ /* \ can either start a functon call or an escape. */
+ t;
+ /* It may not be an escape, but registering it
+ as an escape cannot harm us since we only
+ skip the first character, and a function call
+ cannot be that short. */
+ escape = 1;
+ /* Nested quotes can appear at function calls. */
+ call_end = get_end_of_call(content, o_ptr, size);
+ } else if (quote) {
+ /* Quotes end with the same symbols as they start with,
+ and quotes automatically escape comments. */
+ t;
+ if (strchr("\"\n", c))
+ quote = 0;
+ } else if (c == '#') {
+ /* # is the comment symbol. */
+ comment = 1;
+ } else if (c == '"') {
+ /* " is the quote symbol. */
+ t, quote = 1;
+ } else {
+ /* Code and whitespace. */
+ t;
+ }
}
- /* # is the comment symbol. */
- else if (c == '#') comment = 1;
- /* " is the quote symbol. */
- else if (c == '"') t, quote = 1;
- /* Code and whitespace. */
- else t;
- }
-
- return n_ptr;
-
+
+ return n_ptr;
+
#undef t
}
@@ -298,36 +310,35 @@ static size_t remove_comments(char* restrict content, size_t size)
* `NULL` is returned, and `content` will not
* have been modified.
*/
-static char** line_split(char* content, size_t length)
+static char **
+line_split(char *content, size_t length)
{
- char** restrict lines = NULL;
- size_t count = 0;
- size_t i, j;
- int new_line = 1;
-
- for (i = 0; i < length; i++)
- if (content[i] == '\n')
- count++;
-
- fail_if (xmalloc(lines, count + 1, char*));
- lines[count] = NULL;
-
- for (i = j = 0; i < length; i++)
- {
- if (new_line)
- new_line = 0, lines[j++] = content + i;
- if (content[i] == '\n')
- {
- new_line = 1;
- content[i] = '\0';
+ char **restrict lines = NULL;
+ size_t count = 0;
+ size_t i, j;
+ int new_line = 1;
+
+ for (i = 0; i < length; i++)
+ if (content[i] == '\n')
+ count++;
+
+ fail_if (xmalloc(lines, count + 1, char*));
+ lines[count] = NULL;
+
+ for (i = j = 0; i < length; i++) {
+ if (new_line)
+ new_line = 0, lines[j++] = content + i;
+ if (content[i] == '\n') {
+ new_line = 1;
+ content[i] = '\0';
+ }
}
- }
-
- return lines;
-
- fail:
- xperror(*argv);
- return NULL;
+
+ return lines;
+
+fail:
+ xperror(*argv);
+ return NULL;
}
@@ -338,40 +349,44 @@ static char** line_split(char* content, size_t length)
* @param content_size Input and output parameter for the size of the file's content
* @return Zero on success, -1 on error
*/
-static int expand(char** restrict content, size_t* restrict content_size)
+static int
+expand(char **restrict content, size_t *restrict content_size)
{
- size_t extra = 0, added = 0, ptr, col, n = *content_size;
- char* restrict data = *content;
-
- /* Calculate the new size of the file. */
- for (ptr = col = 0; ptr < n; ptr++)
- if (data[ptr] == '\n')
- col = 0;
- else if (data[ptr] == '\t')
- extra += 8 - (col % 8) - 1;
-
- /* Extend the allocation. */
- if (extra == 0)
- return 0;
- *content_size += extra;
- fail_if (xrealloc(data, *content_size, char));
- *content = data;
-
- /* Expand tab spaces. */
- memmove(data + extra, data, n);
- for (ptr = 0; ptr < n; ptr++, added--)
- if (data[ptr + extra] == '\n')
- data[ptr + added++] = data[ptr + extra], col = 0;
- else if (data[ptr + extra] != '\t')
- data[ptr + added++] = data[ptr + extra], col++;
- else
- do
- data[ptr + added++] = ' ';
- while (++col % 8);
-
- return 0;
- fail:
- return -1;
+ size_t extra = 0, added = 0, ptr, col, n = *content_size;
+ char *restrict data = *content;
+
+ /* Calculate the new size of the file. */
+ for (ptr = col = 0; ptr < n; ptr++) {
+ if (data[ptr] == '\n')
+ col = 0;
+ else if (data[ptr] == '\t')
+ extra += 8 - (col % 8) - 1;
+ }
+
+ /* Extend the allocation. */
+ if (!extra)
+ return 0;
+ *content_size += extra;
+ fail_if (xrealloc(data, *content_size, char));
+ *content = data;
+
+ /* Expand tab spaces. */
+ memmove(data + extra, data, n);
+ for (ptr = 0; ptr < n; ptr++, added--) {
+ if (data[ptr + extra] == '\n') {
+ data[ptr + added++] = data[ptr + extra], col = 0;
+ } else if (data[ptr + extra] != '\t') {
+ data[ptr + added++] = data[ptr + extra], col++;
+ } else {
+ do
+ data[ptr + added++] = ' ';
+ while (++col % 8);
+ }
+ }
+
+ return 0;
+fail:
+ return -1;
}
@@ -382,60 +397,60 @@ static int expand(char** restrict content, size_t* restrict content_size)
* @param source_code Output parameter for read data
* @return Zero on success, -1 on error
*/
-int read_source_lines(const char* restrict pathname, mds_kbdc_source_code_t* restrict source_code)
+int
+read_source_lines(const char *restrict pathname, mds_kbdc_source_code_t *restrict source_code)
{
- char* content = NULL;
- char* real_content = NULL;
- char* old = NULL;
- size_t content_size;
- size_t real_content_size;
- char** lines = NULL;
- char** real_lines = NULL;
- size_t line_count = 0;
-
- /* Read the file. */
- content = read_file(pathname, &content_size);
- fail_if (content == NULL);
-
- /* Expand tab spaces. */
- fail_if (expand(&content, &content_size));
-
- /* Make sure the content ends with a new line. */
- if (!content_size || (content[content_size - 1] != '\n'))
- {
- fail_if (xxrealloc(old, content, content_size + 1, char));
- content[content_size++] = '\n';
- }
-
- /* Simplify file. */
- fail_if (xmemdup(real_content, content, content_size, char));
- real_content_size = content_size;
- content_size = remove_comments(content, content_size);
- fail_if (xxrealloc(old, content, content_size, char));
-
- /* Split by line. */
- fail_if ((lines = line_split(content, content_size)) == NULL);
- fail_if ((real_lines = line_split(real_content, real_content_size)) == NULL);
-
- /* Count the number of lines. */
- while (lines[line_count] != NULL)
- line_count++;
-
- source_code->lines = lines;
- source_code->real_lines = real_lines;
- source_code->content = content;
- source_code->real_content = real_content;
- source_code->line_count = line_count;
- return 0;
-
- fail:
- xperror(*argv);
- free(old);
- free(content);
- free(real_content);
- free(lines);
- free(real_lines);
- return -1;
+ char *content = NULL;
+ char *real_content = NULL;
+ char *old = NULL;
+ size_t content_size;
+ size_t real_content_size;
+ char **lines = NULL;
+ char **real_lines = NULL;
+ size_t line_count = 0;
+
+ /* Read the file. */
+ content = read_file(pathname, &content_size);
+ fail_if (!content);
+
+ /* Expand tab spaces. */
+ fail_if (expand(&content, &content_size));
+
+ /* Make sure the content ends with a new line. */
+ if (!content_size || content[content_size - 1] != '\n') {
+ fail_if (xxrealloc(old, content, content_size + 1, char));
+ content[content_size++] = '\n';
+ }
+
+ /* Simplify file. */
+ fail_if (xmemdup(real_content, content, content_size, char));
+ real_content_size = content_size;
+ content_size = remove_comments(content, content_size);
+ fail_if (xxrealloc(old, content, content_size, char));
+
+ /* Split by line. */
+ fail_if (!(lines = line_split(content, content_size)));
+ fail_if (!(real_lines = line_split(real_content, real_content_size)));
+
+ /* Count the number of lines. */
+ while (lines[line_count])
+ line_count++;
+
+ source_code->lines = lines;
+ source_code->real_lines = real_lines;
+ source_code->content = content;
+ source_code->real_content = real_content;
+ source_code->line_count = line_count;
+ return 0;
+
+fail:
+ xperror(*argv);
+ free(old);
+ free(content);
+ free(real_content);
+ free(lines);
+ free(real_lines);
+ return -1;
}
@@ -446,24 +461,25 @@ int read_source_lines(const char* restrict pathname, mds_kbdc_source_code_t* res
* @param character The character
* @return The of the character in `buffer`, `NULL` on error
*/
-static char* encode_utf8(char* buffer, char32_t character)
+static char *
+encode_utf8(char *buffer, char32_t character)
{
- char32_t text[2];
- char* restrict str;
- char* restrict str_;
-
- text[0] = character;
- text[1] = -1;
-
- fail_if (str_ = str = string_encode(text), str == NULL);
-
- while (*str)
- *buffer++ = *str++;
-
- free(str_);
- return buffer;
- fail:
- return NULL;
+ char32_t text[2];
+ char *restrict str;
+ char *restrict str_;
+
+ text[0] = character;
+ text[1] = -1;
+
+ fail_if (!(str_ = str = string_encode(text)));
+
+ while (*str)
+ *buffer++ = *str++;
+
+ free(str_);
+ return buffer;
+fail:
+ return NULL;
}
@@ -473,53 +489,57 @@ static char* encode_utf8(char* buffer, char32_t character)
* @param string The string
* @return The string in machine-readable format, `NULL` on error
*/
-char* parse_raw_string(const char* restrict string)
+char *
+parse_raw_string(const char *restrict string)
{
-#define r(cond, lower, upper) ((cond) && ((lower) <= c) && (c <= (upper)))
- char* rc;
- char* p;
- int escape = 0;
- char32_t buf = 0;
- char c;
-
- /* We know that the output string can only be shorter because
- * it is surrounded by 2 quotes and escape can only be longer
- * then what they escape, for example \uA0, is four characters,
- * but when parsed it generateds 2 bytes in UTF-8, and their
- * is not code point whose UTF-8 encoding is longer than its
- * hexadecimal representation. */
- fail_if (xmalloc(p = rc, strlen(string), char));
-
- while ((c = *string++))
- if (r(escape == 8, '0', '7')) buf = (buf << 3) | (c & 15);
- else if (r(escape == 16, '0', '9')) buf = (buf << 4) | (c & 15);
- else if (r(escape == 16, 'a', 'f')) buf = (buf << 4) | ((c & 15) + 9);
- else if (r(escape == 16, 'A', 'F')) buf = (buf << 4) | ((c & 15) + 9);
- else if (escape > 1)
- {
- escape = 0;
- fail_if ((p = encode_utf8(p, buf), p == NULL));
- if (c != '.')
- *p++ = c;
- }
- else if (escape == 1)
- {
- escape = 0, buf = 0;
- switch (c)
- {
- case '0': escape = 8; break;
- case 'u': escape = 16; break;
- default: *p++ = c; break;
- }
- }
- else if (c == '\\') escape = 1;
- else if (c != '\"') *p++ = c;
-
- *p = '\0';
- return rc;
- fail:
- free(rc);
- return NULL;
+#define r(cond, lower, upper) ((cond) && ((lower) <= c) && (c <= (upper)))
+ char *rc, *p;
+ int escape = 0;
+ char32_t buf = 0;
+ char c;
+
+ /* We know that the output string can only be shorter because
+ * it is surrounded by 2 quotes and escape can only be longer
+ * then what they escape, for example \uA0, is four characters,
+ * but when parsed it generateds 2 bytes in UTF-8, and their
+ * is not code point whose UTF-8 encoding is longer than its
+ * hexadecimal representation. */
+ fail_if (xmalloc(p = rc, strlen(string), char));
+
+ while ((c = *string++)) {
+ if (r(escape == 8, '0', '7')) {
+ buf = (buf << 3) | (c & 15);
+ } else if (r(escape == 16, '0', '9')) {
+ buf = (buf << 4) | (c & 15);
+ } else if (r(escape == 16, 'a', 'f')) {
+ buf = (buf << 4) | ((c & 15) + 9);
+ } else if (r(escape == 16, 'A', 'F')) {
+ buf = (buf << 4) | ((c & 15) + 9);
+ } else if (escape > 1) {
+ escape = 0;
+ fail_if (!(p = encode_utf8(p, buf)));
+ if (c != '.')
+ *p++ = c;
+ } else if (escape == 1) {
+ escape = 0;
+ buf = 0;
+ if (c == '0')
+ escape = 8;
+ else if (c == 'u')
+ escape = 16;
+ else
+ *p++ = c;
+ } else if (c == '\\') {
+ escape = 1;
+ } else if (c != '\"') {
+ *p++ = c;
+ }
+ }
+
+ *p = '\0';
+ return rc;
+fail:
+ free(rc);
+ return NULL;
#undef r
}
-
diff --git a/src/mds-kbdc/raw-data.h b/src/mds-kbdc/raw-data.h
index 3638042..bdc1078 100644
--- a/src/mds-kbdc/raw-data.h
+++ b/src/mds-kbdc/raw-data.h
@@ -25,42 +25,40 @@
/**
* Source code by lines, with and without comments
*/
-typedef struct mds_kbdc_source_code
-{
- /**
- * Source code by lines without comments,
- * `NULL`-terminated.
- */
- char** restrict lines;
-
- /**
- * Source code by lines with comments,
- * `NULL`-terminated.
- */
- char** restrict real_lines;
-
- /**
- * Data for `lines` (internal data)
- */
- char* content;
-
- /**
- * Data for `real_lines` (internal data)
- */
- char* real_content;
-
- /**
- * The number of lines, that is, the number of
- * elements in `lines` and `real_lines`.
- */
- size_t line_count;
-
- /**
- * The number of duplicates there are of this
- * structure that shared the memory
- */
- size_t duplicates;
-
+typedef struct mds_kbdc_source_code {
+ /**
+ * Source code by lines without comments,
+ * `NULL`-terminated.
+ */
+ char **restrict lines;
+
+ /**
+ * Source code by lines with comments,
+ * `NULL`-terminated.
+ */
+ char **restrict real_lines;
+
+ /**
+ * Data for `lines` (internal data)
+ */
+ char *content;
+
+ /**
+ * Data for `real_lines` (internal data)
+ */
+ char *real_content;
+
+ /**
+ * The number of lines, that is, the number of
+ * elements in `lines` and `real_lines`.
+ */
+ size_t line_count;
+
+ /**
+ * The number of duplicates there are of this
+ * structure that shared the memory
+ */
+ size_t duplicates;
} mds_kbdc_source_code_t;
@@ -69,21 +67,21 @@ typedef struct mds_kbdc_source_code
*
* @param this The `mds_kbdc_source_code_t*`
*/
-void mds_kbdc_source_code_initialise(mds_kbdc_source_code_t* restrict this);
+void mds_kbdc_source_code_initialise(mds_kbdc_source_code_t *restrict this);
/**
* Release all data in a `mds_kbdc_source_code_t*`
*
* @param this The `mds_kbdc_source_code_t*`
*/
-void mds_kbdc_source_code_destroy(mds_kbdc_source_code_t* restrict this);
+void mds_kbdc_source_code_destroy(mds_kbdc_source_code_t *restrict this);
/**
* Release all data in a `mds_kbdc_source_code_t*`, and free it
*
* @param this The `mds_kbdc_source_code_t*`
*/
-void mds_kbdc_source_code_free(mds_kbdc_source_code_t* restrict this);
+void mds_kbdc_source_code_free(mds_kbdc_source_code_t *restrict this);
/**
* Create a duplicate of a `mds_kbdc_source_code_t*`
@@ -91,7 +89,7 @@ void mds_kbdc_source_code_free(mds_kbdc_source_code_t* restrict this);
* @param this The `mds_kbdc_source_code_t*`
* @return `this` is returned
*/
-mds_kbdc_source_code_t* mds_kbdc_source_code_dup(mds_kbdc_source_code_t* restrict this);
+mds_kbdc_source_code_t *mds_kbdc_source_code_dup(mds_kbdc_source_code_t *restrict this);
/**
@@ -106,7 +104,8 @@ mds_kbdc_source_code_t* mds_kbdc_source_code_dup(mds_kbdc_source_code_t* restric
* or `size` if the call do not end (that is, the code ends
* prematurely), or zero if there is no function call at `offset`
*/
-size_t get_end_of_call(const char* restrict content, size_t offset, size_t size) __attribute__((pure));
+__attribute__((pure))
+size_t get_end_of_call(const char *restrict content, size_t offset, size_t size);
/**
* Read lines of a source file
@@ -115,7 +114,7 @@ size_t get_end_of_call(const char* restrict content, size_t offset, size_t size)
* @param source_code Output parameter for read data
* @return Zero on success, -1 on error
*/
-int read_source_lines(const char* restrict pathname, mds_kbdc_source_code_t* restrict source_code);
+int read_source_lines(const char *restrict pathname, mds_kbdc_source_code_t *restrict source_code);
/**
@@ -124,8 +123,7 @@ int read_source_lines(const char* restrict pathname, mds_kbdc_source_code_t* res
* @param string The string
* @return The string in machine-readable format, `NULL` on error
*/
-char* parse_raw_string(const char* restrict string);
+char *parse_raw_string(const char *restrict string);
#endif
-
diff --git a/src/mds-kbdc/simplify-tree.c b/src/mds-kbdc/simplify-tree.c
index d559e2e..b3f588c 100644
--- a/src/mds-kbdc/simplify-tree.c
+++ b/src/mds-kbdc/simplify-tree.c
@@ -27,13 +27,13 @@
/**
* This process's value for `mds_kbdc_tree_t.processed`
*/
-#define PROCESS_LEVEL 2
+#define PROCESS_LEVEL 2
/**
* Tree type constant shortener
*/
-#define C(TYPE) MDS_KBDC_TREE_TYPE_##TYPE
+#define C(TYPE) MDS_KBDC_TREE_TYPE_##TYPE
/**
@@ -44,9 +44,9 @@
* @param ...:const char*, ... Error description format string and arguments
* @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
*/
-#define NEW_ERROR(NODE, SEVERITY, ...) \
- NEW_ERROR_(result, SEVERITY, 1, (NODE)->loc_line, \
- (NODE)->loc_start, (NODE)->loc_end, 1, __VA_ARGS__)
+#define NEW_ERROR(NODE, SEVERITY, ...)\
+ NEW_ERROR_(result, SEVERITY, 1, (NODE)->loc_line,\
+ (NODE)->loc_start, (NODE)->loc_end, 1, __VA_ARGS__)
@@ -58,25 +58,25 @@
* @scope here:mds_kbdc_tree_t** Help variable that must be available for use
* @scope argument:mds_kbdc_tree_t* Help variable that must be available for use
*/
-#define REMOVE_NOTHING(START) \
- do \
- { \
- long processed = tree->processed; \
- tree->processed = PROCESS_LEVEL; \
- for (here = &(tree->START); *here;) \
- if ((*here)->type != C(NOTHING)) \
- here = &((*here)->next); \
- else \
- while (*here && (*here)->type == C(NOTHING)) \
- { \
- argument = (*here)->next, (*here)->next = NULL; \
- if ((processed != PROCESS_LEVEL) && ((*here)->processed != PROCESS_LEVEL)) \
- NEW_ERROR(*here, WARNING, "‘.’ outside alternation has no effect"); \
- mds_kbdc_tree_free(*here); \
- *here = argument; \
- } \
- } \
- while (0)
+#define REMOVE_NOTHING(START)\
+ do {\
+ long int processed = tree->processed;\
+ tree->processed = PROCESS_LEVEL;\
+ for (here = &(tree->START); *here;) {\
+ if ((*here)->type != C(NOTHING)) {\
+ here = &((*here)->next);\
+ } else {\
+ while (*here && (*here)->type == C(NOTHING)) {\
+ argument = (*here)->next;\
+ (*here)->next = NULL;\
+ if (processed != PROCESS_LEVEL && (*here)->processed != PROCESS_LEVEL)\
+ NEW_ERROR(*here, WARNING, "‘.’ outside alternation has no effect");\
+ mds_kbdc_tree_free(*here);\
+ *here = argument;\
+ }\
+ }\
+ }\
+ } while (0)
@@ -89,38 +89,36 @@
* @scope here:mds_kbdc_tree_t** Pointer to the space where the argument was found
* @scope temp:mds_kbdc_tree_t* Help variable that must be available for use
*/
-#define FLATTEN(argument) \
- do \
- { \
- /* Remember the alternation/subsequence and the argument that follows it. */ \
- mds_kbdc_tree_t* eliminated_argument = argument; \
- temp = argument->next; \
- /* Find the last alternative/element. */ \
- for (argument->next = argument->ordered.inner; argument->next;) \
- argument = argument->next; \
- /* Attach the argument that was after the alternation/subsequence to the */ \
- /* end of the alternation/subsequence, that is, flatten the right side. */ \
- argument->next = temp; \
- /* Flatten the left side. */ \
- *here = eliminated_argument->next; \
- /* Free the memory of the alternation/subsequence. */ \
- eliminated_argument->ordered.inner = NULL; \
- eliminated_argument->next = NULL; \
- mds_kbdc_tree_free(eliminated_argument); \
- } \
- while (0)
+#define FLATTEN(argument)\
+ do {\
+ /* Remember the alternation/subsequence and the argument that follows it. */\
+ mds_kbdc_tree_t *eliminated_argument = argument;\
+ temp = argument->next;\
+ /* Find the last alternative/element. */\
+ for (argument->next = argument->ordered.inner; argument->next;)\
+ argument = argument->next;\
+ /* Attach the argument that was after the alternation/subsequence to the */\
+ /* end of the alternation/subsequence, that is, flatten the right side. */\
+ argument->next = temp;\
+ /* Flatten the left side. */\
+ *here = eliminated_argument->next;\
+ /* Free the memory of the alternation/subsequence. */\
+ eliminated_argument->ordered.inner = NULL;\
+ eliminated_argument->next = NULL;\
+ mds_kbdc_tree_free(eliminated_argument);\
+ } while (0)
/**
* Variable whether the latest created error is stored
*/
-static mds_kbdc_parse_error_t* error;
+static mds_kbdc_parse_error_t *error;
/**
* The parameter of `simplify_tree`
*/
-static mds_kbdc_parsed_t* restrict result;
+static mds_kbdc_parsed_t *restrict result;
@@ -130,7 +128,7 @@ static mds_kbdc_parsed_t* restrict result;
* @param tree The tree
* @return Zero on success, -1 on error
*/
-static int simplify(mds_kbdc_tree_t* restrict tree);
+static int simplify(mds_kbdc_tree_t *restrict tree);
/**
* Simplify an unordered subsequence-subtree
@@ -138,7 +136,7 @@ static int simplify(mds_kbdc_tree_t* restrict tree);
* @param tree The unordered subsequence-subtree
* @return Zero on success, -1 on error
*/
-static int simplify_unordered(mds_kbdc_tree_unordered_t* restrict tree);
+static int simplify_unordered(mds_kbdc_tree_unordered_t *restrict tree);
@@ -150,60 +148,61 @@ static int simplify_unordered(mds_kbdc_tree_unordered_t* restrict tree);
* @param argument_index The index of the argument to eliminate
* @return Zero on sucess, -1 on error
*/
-static int eliminate_alternation(mds_kbdc_tree_t* tree, mds_kbdc_tree_t* argument, size_t argument_index)
+static int
+eliminate_alternation(mds_kbdc_tree_t *tree, mds_kbdc_tree_t *argument, size_t argument_index)
{
- mds_kbdc_tree_t** here;
- mds_kbdc_tree_t* first;
- mds_kbdc_tree_t* last;
- mds_kbdc_tree_t* new_tree;
- mds_kbdc_tree_t* alternative;
- mds_kbdc_tree_t* next_statement;
- mds_kbdc_tree_t* next_alternative;
- mds_kbdc_tree_t* new_argument;
- size_t i;
- int saved_errno;
-
- /* Detach next statement, we do not want to duplicate all following statements. */
- next_statement = tree->next, tree->next = NULL;
- /* Detach alternation, we replace it in all duplcates,
- no need to duplicate all alternatives. */
- alternative = argument->alternation.inner, argument->alternation.inner = NULL;
- /* Eliminate. */
- for (first = last = NULL; alternative; alternative = next_alternative)
- {
- /* Duplicate statement. */
- fail_if (new_tree = mds_kbdc_tree_dup(tree), new_tree == NULL);
- /* Join trees. */
- if (last)
- last->next = new_tree;
- last = new_tree;
- first = first ? first : new_tree;
- /* Jump to the alternation. */
- here = &(new_tree->macro_call.arguments); /* `new_tree->macro_call.arguments` and
- * `new_tree->map.sequence` as the same address. */
- for (new_argument = *here, i = 0; i < argument_index; i++, here = &((*here)->next))
- new_argument = new_argument->next;
- /* Detach alternative. */
- next_alternative = alternative->next;
- /* Right-join alternative. */
- alternative->next = new_argument->next, new_argument->next = NULL;
- mds_kbdc_tree_free(new_argument);
- /* Left-join alternative. */
- *here = alternative;
- }
- /* Replace the statement with the first generated statement without the alternation. */
- mds_kbdc_tree_destroy((mds_kbdc_tree_t*)tree);
- memcpy(tree, first, sizeof(mds_kbdc_tree_t));
- if (first == last) last = (mds_kbdc_tree_t*)tree;
- free(first);
- /* Reattach the statement that followed to the last generated statement. */
- last->next = next_statement;
- return 0;
- fail:
- saved_errno = errno;
- argument->alternation.inner = alternative;
- tree->next = next_statement;
- return errno = saved_errno, -1;
+ mds_kbdc_tree_t **here;
+ mds_kbdc_tree_t *first;
+ mds_kbdc_tree_t *last;
+ mds_kbdc_tree_t *new_tree;
+ mds_kbdc_tree_t *alternative;
+ mds_kbdc_tree_t *next_statement;
+ mds_kbdc_tree_t *next_alternative;
+ mds_kbdc_tree_t *new_argument;
+ size_t i;
+ int saved_errno;
+
+ /* Detach next statement, we do not want to duplicate all following statements. */
+ next_statement = tree->next, tree->next = NULL;
+ /* Detach alternation, we replace it in all duplcates,
+ no need to duplicate all alternatives. */
+ alternative = argument->alternation.inner, argument->alternation.inner = NULL;
+ /* Eliminate. */
+ for (first = last = NULL; alternative; alternative = next_alternative) {
+ /* Duplicate statement. */
+ fail_if (!(new_tree = mds_kbdc_tree_dup(tree)));
+ /* Join trees. */
+ if (last)
+ last->next = new_tree;
+ last = new_tree;
+ first = first ? first : new_tree;
+ /* Jump to the alternation. */
+ here = &(new_tree->macro_call.arguments); /* `new_tree->macro_call.arguments` and
+ * `new_tree->map.sequence` as the same address. */
+ for (new_argument = *here, i = 0; i < argument_index; i++, here = &((*here)->next))
+ new_argument = new_argument->next;
+ /* Detach alternative. */
+ next_alternative = alternative->next;
+ /* Right-join alternative. */
+ alternative->next = new_argument->next, new_argument->next = NULL;
+ mds_kbdc_tree_free(new_argument);
+ /* Left-join alternative. */
+ *here = alternative;
+ }
+ /* Replace the statement with the first generated statement without the alternation. */
+ mds_kbdc_tree_destroy((mds_kbdc_tree_t*)tree);
+ memcpy(tree, first, sizeof(mds_kbdc_tree_t));
+ if (first == last)
+ last = (mds_kbdc_tree_t*)tree;
+ free(first);
+ /* Reattach the statement that followed to the last generated statement. */
+ last->next = next_statement;
+ return 0;
+fail:
+ saved_errno = errno;
+ argument->alternation.inner = alternative;
+ tree->next = next_statement;
+ return errno = saved_errno, -1;
}
@@ -213,118 +212,119 @@ static int eliminate_alternation(mds_kbdc_tree_t* tree, mds_kbdc_tree_t* argumen
* @param tree The macro call-subtree
* @return Zero on success, -1 on error
*/
-static int simplify_macro_call(mds_kbdc_tree_macro_call_t* restrict tree)
+static int
+simplify_macro_call(mds_kbdc_tree_macro_call_t *restrict tree)
{
- mds_kbdc_tree_t* argument;
- mds_kbdc_tree_t* dup_arguments = NULL;
- mds_kbdc_tree_t** here;
- char* full_macro_name;
- size_t argument_index = 0;
- int saved_errno;
-
- /* Simplify arguments. */
- for (argument = tree->arguments; argument; argument = argument->next)
- fail_if (simplify(argument));
-
- /* Remove ‘.’:s. */
- REMOVE_NOTHING(arguments);
-
- /* Copy arguments. */
- if (tree->arguments == NULL)
- goto no_args;
- fail_if (dup_arguments = mds_kbdc_tree_dup(tree->arguments), dup_arguments == NULL);
-
- /* Eliminate alterations. */
- for (argument = dup_arguments; argument; argument = argument->next, argument_index++)
- if (argument->type == C(ALTERNATION))
- fail_if (eliminate_alternation((mds_kbdc_tree_t*)tree, argument, argument_index));
- mds_kbdc_tree_free(dup_arguments), dup_arguments = NULL;
-
- /* Add argument count suffix. */
- no_args:
- for (argument_index = 0, argument = tree->arguments; argument; argument = argument->next)
- argument_index++;
- fail_if (xasprintf(full_macro_name, "%s/%zu", tree->name, argument_index));
- free(tree->name), tree->name = full_macro_name;
-
- /* Example of what will happend:
- *
- * my_macro([1 2] [1 2] [1 2]) ## call 1
- *
- * simplify_macro_call on call 1
- * after processing argument 1
- * my_macro(1 [1 2] [1 2]) ## call 1
- * my_macro(2 [1 2] [1 2]) ## call 5
- * after processing argument 2
- * my_macro(1 1 [1 2]) ## call 1
- * my_macro(1 2 [1 2]) ## call 3
- * my_macro(2 [1 2] [1 2]) ## call 5
- * after processing argument 3
- * my_macro(1 1 1) ## call 1
- * my_macro(1 1 2) ## call 2
- * my_macro(1 2 [1 2]) ## call 3
- * my_macro(2 [1 2] [1 2]) ## call 5
- *
- * no difference after simplify_macro_call on call 2
- *
- * simplify_macro_call on call 3
- * no difference after processing argument 1
- * no difference after processing argument 2
- * after processing argument 3
- * my_macro(1 1 1) ## (call 1)
- * my_macro(1 1 2) ## (call 2)
- * my_macro(1 2 1) ## call 3
- * my_macro(1 2 1) ## call 4
- * my_macro(2 [1 2] [1 2]) ## call 5
- *
- * no difference after simplify_macro_call on call 4
- *
- * simplify_macro_call on call 5
- * no difference after processing argument 1
- * after processing argument 2
- * my_macro(1 1 1) ## (call 1)
- * my_macro(1 1 2) ## (call 2)
- * my_macro(1 2 1) ## (call 3)
- * my_macro(1 2 2) ## (call 4)
- * my_macro(2 1 [1 2]) ## call 5
- * my_macro(2 2 [1 2]) ## call 7
- * after processing argument 3
- * my_macro(1 1 1) ## (call 1)
- * my_macro(1 1 2) ## (call 2)
- * my_macro(1 2 1) ## (call 3)
- * my_macro(1 2 2) ## (call 4)
- * my_macro(2 1 1) ## call 5
- * my_macro(2 1 2) ## call 6
- * my_macro(2 2 [1 2]) ## call 7
- *
- * no difference after simplify_macro_call on call 6
- *
- * simplify_macro_call on call 7
- * no difference after processing argument 1
- * no difference after processing argument 2
- * after processing argument 3
- * my_macro(1 1 1) ## (call 1)
- * my_macro(1 1 2) ## (call 2)
- * my_macro(1 2 1) ## (call 3)
- * my_macro(1 2 2) ## (call 4)
- * my_macro(2 1 1) ## (call 5)
- * my_macro(2 1 2) ## (call 6)
- * my_macro(2 2 1) ## call 7
- * my_macro(2 2 2) ## call 8
- *
- * no difference after simplify_macro_call on call 8
- *
- * Nothings (‘.’) are removed before processing the alternations.
- *
- * It should also be noticed that all macro names are update to
- * with the argument count suffix.
- */
-
- return 0;
- fail:
- saved_errno = errno;
- mds_kbdc_tree_free(dup_arguments);
- return errno = saved_errno, -1;
+ mds_kbdc_tree_t *argument;
+ mds_kbdc_tree_t *dup_arguments = NULL;
+ mds_kbdc_tree_t **here;
+ char *full_macro_name;
+ size_t argument_index = 0;
+ int saved_errno;
+
+ /* Simplify arguments. */
+ for (argument = tree->arguments; argument; argument = argument->next)
+ fail_if (simplify(argument));
+
+ /* Remove ‘.’:s. */
+ REMOVE_NOTHING(arguments);
+
+ /* Copy arguments. */
+ if (!tree->arguments)
+ goto no_args;
+ fail_if (!(dup_arguments = mds_kbdc_tree_dup(tree->arguments)));
+
+ /* Eliminate alterations. */
+ for (argument = dup_arguments; argument; argument = argument->next, argument_index++)
+ if (argument->type == C(ALTERNATION))
+ fail_if (eliminate_alternation((mds_kbdc_tree_t*)tree, argument, argument_index));
+ mds_kbdc_tree_free(dup_arguments), dup_arguments = NULL;
+
+ /* Add argument count suffix. */
+no_args:
+ for (argument_index = 0, argument = tree->arguments; argument; argument = argument->next)
+ argument_index++;
+ fail_if (xasprintf(full_macro_name, "%s/%zu", tree->name, argument_index));
+ free(tree->name), tree->name = full_macro_name;
+
+ /* Example of what will happend:
+ *
+ * my_macro([1 2] [1 2] [1 2]) ## call 1
+ *
+ * simplify_macro_call on call 1
+ * after processing argument 1
+ * my_macro(1 [1 2] [1 2]) ## call 1
+ * my_macro(2 [1 2] [1 2]) ## call 5
+ * after processing argument 2
+ * my_macro(1 1 [1 2]) ## call 1
+ * my_macro(1 2 [1 2]) ## call 3
+ * my_macro(2 [1 2] [1 2]) ## call 5
+ * after processing argument 3
+ * my_macro(1 1 1) ## call 1
+ * my_macro(1 1 2) ## call 2
+ * my_macro(1 2 [1 2]) ## call 3
+ * my_macro(2 [1 2] [1 2]) ## call 5
+ *
+ * no difference after simplify_macro_call on call 2
+ *
+ * simplify_macro_call on call 3
+ * no difference after processing argument 1
+ * no difference after processing argument 2
+ * after processing argument 3
+ * my_macro(1 1 1) ## (call 1)
+ * my_macro(1 1 2) ## (call 2)
+ * my_macro(1 2 1) ## call 3
+ * my_macro(1 2 1) ## call 4
+ * my_macro(2 [1 2] [1 2]) ## call 5
+ *
+ * no difference after simplify_macro_call on call 4
+ *
+ * simplify_macro_call on call 5
+ * no difference after processing argument 1
+ * after processing argument 2
+ * my_macro(1 1 1) ## (call 1)
+ * my_macro(1 1 2) ## (call 2)
+ * my_macro(1 2 1) ## (call 3)
+ * my_macro(1 2 2) ## (call 4)
+ * my_macro(2 1 [1 2]) ## call 5
+ * my_macro(2 2 [1 2]) ## call 7
+ * after processing argument 3
+ * my_macro(1 1 1) ## (call 1)
+ * my_macro(1 1 2) ## (call 2)
+ * my_macro(1 2 1) ## (call 3)
+ * my_macro(1 2 2) ## (call 4)
+ * my_macro(2 1 1) ## call 5
+ * my_macro(2 1 2) ## call 6
+ * my_macro(2 2 [1 2]) ## call 7
+ *
+ * no difference after simplify_macro_call on call 6
+ *
+ * simplify_macro_call on call 7
+ * no difference after processing argument 1
+ * no difference after processing argument 2
+ * after processing argument 3
+ * my_macro(1 1 1) ## (call 1)
+ * my_macro(1 1 2) ## (call 2)
+ * my_macro(1 2 1) ## (call 3)
+ * my_macro(1 2 2) ## (call 4)
+ * my_macro(2 1 1) ## (call 5)
+ * my_macro(2 1 2) ## (call 6)
+ * my_macro(2 2 1) ## call 7
+ * my_macro(2 2 2) ## call 8
+ *
+ * no difference after simplify_macro_call on call 8
+ *
+ * Nothings (‘.’) are removed before processing the alternations.
+ *
+ * It should also be noticed that all macro names are update to
+ * with the argument count suffix.
+ */
+
+ return 0;
+fail:
+ saved_errno = errno;
+ mds_kbdc_tree_free(dup_arguments);
+ return errno = saved_errno, -1;
}
@@ -334,26 +334,27 @@ static int simplify_macro_call(mds_kbdc_tree_macro_call_t* restrict tree)
* @param tree The value statement-tree
* @return Zero on success, -1 on error
*/
-static int check_value_statement_before_simplification(mds_kbdc_tree_map_t* restrict tree)
+static int
+check_value_statement_before_simplification(mds_kbdc_tree_map_t *restrict tree)
{
- again:
- /* Check for alternation. */
- if ((tree->sequence->type == C(ALTERNATION)) && (tree->processed != PROCESS_LEVEL))
- NEW_ERROR(tree->sequence, WARNING,
- "alternated value statement is undefined unless the alternatives are identical");
-
- /* Check for unordered. */
- if (tree->sequence->type != C(UNORDERED))
- return 0;
- if (tree->processed != PROCESS_LEVEL)
- NEW_ERROR(tree->sequence, WARNING, "use of sequence in value statement is discouraged");
-
- /* Simplify argument and start over. */
- fail_if (simplify(tree->sequence));
- goto again;
-
- fail:
- return -1;
+again:
+ /* Check for alternation. */
+ if (tree->sequence->type == C(ALTERNATION) && tree->processed != PROCESS_LEVEL)
+ NEW_ERROR(tree->sequence, WARNING,
+ "alternated value statement is undefined unless the alternatives are identical");
+
+ /* Check for unordered. */
+ if (tree->sequence->type != C(UNORDERED))
+ return 0;
+ if (tree->processed != PROCESS_LEVEL)
+ NEW_ERROR(tree->sequence, WARNING, "use of sequence in value statement is discouraged");
+
+ /* Simplify argument and start over. */
+ fail_if (simplify(tree->sequence));
+ goto again;
+
+fail:
+ return -1;
}
@@ -363,19 +364,20 @@ static int check_value_statement_before_simplification(mds_kbdc_tree_map_t* rest
* @param tree The value statement-tree
* @return Zero on success, -1 on error
*/
-static int check_value_statement_after_simplification(mds_kbdc_tree_map_t* restrict tree)
+static int
+check_value_statement_after_simplification(mds_kbdc_tree_map_t *restrict tree)
{
- /* Check that there is only one value. */
- if (tree->sequence->next)
- NEW_ERROR(tree->sequence->next, ERROR, "more the one value in value statement");
-
- /* Check the type of the value */
- if (tree->sequence->type != C(STRING))
- NEW_ERROR(tree->sequence, ERROR, "bad value type");
-
- return 0;
- fail:
- return -1;
+ /* Check that there is only one value. */
+ if (tree->sequence->next)
+ NEW_ERROR(tree->sequence->next, ERROR, "more the one value in value statement");
+
+ /* Check the type of the value */
+ if (tree->sequence->type != C(STRING))
+ NEW_ERROR(tree->sequence, ERROR, "bad value type");
+
+ return 0;
+fail:
+ return -1;
}
@@ -385,155 +387,154 @@ static int check_value_statement_after_simplification(mds_kbdc_tree_map_t* restr
* @param tree The mapping-subtree
* @return Zero on success, -1 on error
*/
-static int simplify_map(mds_kbdc_tree_map_t* restrict tree)
+static int
+simplify_map(mds_kbdc_tree_map_t *restrict tree)
{
- mds_kbdc_tree_t* argument;
- mds_kbdc_tree_t** here;
- mds_kbdc_tree_t* dup_sequence = NULL;
- mds_kbdc_tree_t* temp;
- size_t argument_index;
- int redo = 0, need_reelimination, saved_errno;
-
- /* Check for bad things in the result. */
- for (argument = tree->result; argument; argument = argument->next)
- if ((argument->type != C(KEYS)) && (argument->type != C(STRING)))
- NEW_ERROR(argument, ERROR, "not allowed in mapping output");
-
- /* Valid value properties. */
- if (tree->result == NULL)
- fail_if (check_value_statement_before_simplification(tree));
-
- /* Simplify sequence. */
- for (argument = tree->sequence; argument; argument = argument->next)
- fail_if (simplify(argument));
-
- /* Test predicted emptyness. */
- for (argument = tree->sequence; argument; argument = argument->next)
- if (argument->type != C(NOTHING))
- goto will_not_be_empty;
- if (tree->sequence->processed != PROCESS_LEVEL)
- {
- if (tree->result)
- NEW_ERROR(tree->sequence, ERROR, "mapping of null sequence");
- else
- NEW_ERROR(tree->sequence, ERROR, "nothing in value statement");
- }
- /* The tree parsing process will not allow a mapping statement
- * to start with a ‘.’. Thus if we select to highlight it we
- * know that it is either an empty alternation, an empty
- * unordered subsequence or a nothing inside an alternation.
- * If it is already been processed by the simplifier, it is an
- * error because it is an empty alternation or empty unordered
- * subsequence, and there is not reason to print an additional
- * error. If however it is a nothing inside an alternation we
- * know that it is the cause of the error, however possibily
- * in conjunction with additional such constructs, but those
- * are harder to locate. */
- return 0;
- will_not_be_empty:
-
- /* Remove ‘.’:s. */
- REMOVE_NOTHING(sequence);
-
- /* Because unordered are simplified to alternations of ordered subsequences, which
- in turn can contain alternations, possibiled from simplification of nested
- unordered sequenceses, we need to reeliminated until there are not alternations. */
- for (need_reelimination = 1; need_reelimination ? (need_reelimination = 0, 1) : 0; redo = 0)
- {
- /* Copy sequence. */
- fail_if (dup_sequence = mds_kbdc_tree_dup(tree->sequence), dup_sequence == NULL);
-
- /* Eliminate alterations, remember, unordered subsequences have
- been simplified to alternations of ordered subsequences. */
- for (argument_index = 0, argument = dup_sequence; argument; argument = argument->next, argument_index++)
- if (argument->type == C(ALTERNATION))
- fail_if (eliminate_alternation((mds_kbdc_tree_t*)tree, argument, argument_index));
-
- mds_kbdc_tree_free(dup_sequence), dup_sequence = NULL;
-
- /* Eliminated ordered subsequences. */
- for (here = &(tree->sequence); (argument = *here); redo ? (redo = 0) : (here = &(argument->next), 0))
- if (argument->type == C(ORDERED))
- {
- FLATTEN(argument);
- redo = 1;
- }
- else if (argument->type == C(ALTERNATION))
- need_reelimination = 1;
- }
-
- /* Valid value properties. */
- if (tree->result == NULL)
- fail_if (check_value_statement_after_simplification(tree));
-
- /* Mapping statements are simplified in a manner similar
- * to how macro calls are simplified. However mapping
- * statements can also contain unordered subsequences,
- * there are translated into alternations of ordered
- * subsequences. Thus after the elimination of alternations,
- * ordered subsequences are eliminated too.
- *
- * Example of what will happen, ‘{ }’ represents an
- * ordered subsequence:
- *
- * (1 2) (3 4) : 0 ## mapping 1
- *
- * simplify_map on mapping 1
- * after simplification
- * [{1 2} {2 1}] [{3 4} {4 3}] ## mapping 1
- * after alternation elimination on argument 1
- * {1 2} [{3 4} {4 3}] ## mapping 1
- * {2 1} [{3 4} {4 3}] ## mapping 3
- * after alternation elimination on argument 2
- * {1 2} {3 4} ## mapping 1
- * {1 2} {4 3} ## mapping 2
- * {2 1} [{3 4} {4 3}] ## mapping 3
- * after ordered subsequence elimination
- * 1 2 3 4 ## mapping 1
- * {1 2} {4 3} ## mapping 2
- * {2 1} [{3 4} {4 3}] ## mapping 3
- *
- * simplify_map on mapping 2
- * no difference after simplification
- * no difference after alternation elimination on argument 1
- * no difference after alternation elimination on argument 2
- * after ordered subsequence elimination
- * 1 2 3 4 ## (mapping 1)
- * 1 2 4 3 ## mapping 2
- * {2 1} [{3 4} {4 3}] ## mapping 3
- *
- * simplify_map on mapping 3
- * no difference after simplification
- * no difference after alternation elimination on argument 1
- * after alternation elimination on argument 2
- * 1 2 3 4 ## (mapping 1)
- * 1 2 4 3 ## (mapping 2)
- * {2 1} {3 4} ## mapping 3
- * {2 1} {4 3} ## mapping 4
- * after ordered subsequence elimination
- * 1 2 3 4 ## (mapping 1)
- * 1 2 4 3 ## (mapping 2)
- * 2 1 3 4 ## mapping 3
- * {2 1} {4 3} ## mapping 4
- *
- * simplify_map on mapping 4
- * no difference after simplification
- * no difference after alternation elimination on argument 1
- * no difference after alternation elimination on argument 2
- * after ordered subsequence elimination
- * 1 2 3 4 ## (mapping 1)
- * 1 2 4 3 ## (mapping 2)
- * 2 1 3 4 ## (mapping 3)
- * 2 1 4 3 ## mapping 4
- *
- * Nothings (‘.’) are removed before processing the alternations.
- */
-
- return 0;
- fail:
- saved_errno = errno;
- mds_kbdc_tree_free(dup_sequence);
- return errno = saved_errno, -1;
+ mds_kbdc_tree_t *argument;
+ mds_kbdc_tree_t **here;
+ mds_kbdc_tree_t *dup_sequence = NULL;
+ mds_kbdc_tree_t *temp;
+ size_t argument_index;
+ int redo = 0, need_reelimination, saved_errno;
+
+ /* Check for bad things in the result. */
+ for (argument = tree->result; argument; argument = argument->next)
+ if (argument->type != C(KEYS) && argument->type != C(STRING))
+ NEW_ERROR(argument, ERROR, "not allowed in mapping output");
+
+ /* Valid value properties. */
+ if (!tree->result)
+ fail_if (check_value_statement_before_simplification(tree));
+
+ /* Simplify sequence. */
+ for (argument = tree->sequence; argument; argument = argument->next)
+ fail_if (simplify(argument));
+
+ /* Test predicted emptyness. */
+ for (argument = tree->sequence; argument; argument = argument->next)
+ if (argument->type != C(NOTHING))
+ goto will_not_be_empty;
+ if (tree->sequence->processed != PROCESS_LEVEL) {
+ if (tree->result)
+ NEW_ERROR(tree->sequence, ERROR, "mapping of null sequence");
+ else
+ NEW_ERROR(tree->sequence, ERROR, "nothing in value statement");
+ }
+ /* The tree parsing process will not allow a mapping statement
+ * to start with a ‘.’. Thus if we select to highlight it we
+ * know that it is either an empty alternation, an empty
+ * unordered subsequence or a nothing inside an alternation.
+ * If it is already been processed by the simplifier, it is an
+ * error because it is an empty alternation or empty unordered
+ * subsequence, and there is not reason to print an additional
+ * error. If however it is a nothing inside an alternation we
+ * know that it is the cause of the error, however possibily
+ * in conjunction with additional such constructs, but those
+ * are harder to locate. */
+ return 0;
+will_not_be_empty:
+
+ /* Remove ‘.’:s. */
+ REMOVE_NOTHING(sequence);
+
+ /* Because unordered are simplified to alternations of ordered subsequences, which
+ in turn can contain alternations, possibiled from simplification of nested
+ unordered sequenceses, we need to reeliminated until there are not alternations. */
+ for (need_reelimination = 1; need_reelimination ? (need_reelimination = 0, 1) : 0; redo = 0) {
+ /* Copy sequence. */
+ fail_if (!(dup_sequence = mds_kbdc_tree_dup(tree->sequence)));
+
+ /* Eliminate alterations, remember, unordered subsequences have
+ been simplified to alternations of ordered subsequences. */
+ for (argument_index = 0, argument = dup_sequence; argument; argument = argument->next, argument_index++)
+ if (argument->type == C(ALTERNATION))
+ fail_if (eliminate_alternation((mds_kbdc_tree_t*)tree, argument, argument_index));
+
+ mds_kbdc_tree_free(dup_sequence), dup_sequence = NULL;
+
+ /* Eliminated ordered subsequences. */
+ for (here = &(tree->sequence); (argument = *here); redo ? (redo = 0) : (here = &(argument->next), 0)) {
+ if (argument->type == C(ORDERED)) {
+ FLATTEN(argument);
+ redo = 1;
+ } else if (argument->type == C(ALTERNATION)) {
+ need_reelimination = 1;
+ }
+ }
+ }
+
+ /* Valid value properties. */
+ if (!tree->result)
+ fail_if (check_value_statement_after_simplification(tree));
+
+ /* Mapping statements are simplified in a manner similar
+ * to how macro calls are simplified. However mapping
+ * statements can also contain unordered subsequences,
+ * there are translated into alternations of ordered
+ * subsequences. Thus after the elimination of alternations,
+ * ordered subsequences are eliminated too.
+ *
+ * Example of what will happen, ‘{ }’ represents an
+ * ordered subsequence:
+ *
+ * (1 2) (3 4) : 0 ## mapping 1
+ *
+ * simplify_map on mapping 1
+ * after simplification
+ * [{1 2} {2 1}] [{3 4} {4 3}] ## mapping 1
+ * after alternation elimination on argument 1
+ * {1 2} [{3 4} {4 3}] ## mapping 1
+ * {2 1} [{3 4} {4 3}] ## mapping 3
+ * after alternation elimination on argument 2
+ * {1 2} {3 4} ## mapping 1
+ * {1 2} {4 3} ## mapping 2
+ * {2 1} [{3 4} {4 3}] ## mapping 3
+ * after ordered subsequence elimination
+ * 1 2 3 4 ## mapping 1
+ * {1 2} {4 3} ## mapping 2
+ * {2 1} [{3 4} {4 3}] ## mapping 3
+ *
+ * simplify_map on mapping 2
+ * no difference after simplification
+ * no difference after alternation elimination on argument 1
+ * no difference after alternation elimination on argument 2
+ * after ordered subsequence elimination
+ * 1 2 3 4 ## (mapping 1)
+ * 1 2 4 3 ## mapping 2
+ * {2 1} [{3 4} {4 3}] ## mapping 3
+ *
+ * simplify_map on mapping 3
+ * no difference after simplification
+ * no difference after alternation elimination on argument 1
+ * after alternation elimination on argument 2
+ * 1 2 3 4 ## (mapping 1)
+ * 1 2 4 3 ## (mapping 2)
+ * {2 1} {3 4} ## mapping 3
+ * {2 1} {4 3} ## mapping 4
+ * after ordered subsequence elimination
+ * 1 2 3 4 ## (mapping 1)
+ * 1 2 4 3 ## (mapping 2)
+ * 2 1 3 4 ## mapping 3
+ * {2 1} {4 3} ## mapping 4
+ *
+ * simplify_map on mapping 4
+ * no difference after simplification
+ * no difference after alternation elimination on argument 1
+ * no difference after alternation elimination on argument 2
+ * after ordered subsequence elimination
+ * 1 2 3 4 ## (mapping 1)
+ * 1 2 4 3 ## (mapping 2)
+ * 2 1 3 4 ## (mapping 3)
+ * 2 1 4 3 ## mapping 4
+ *
+ * Nothings (‘.’) are removed before processing the alternations.
+ */
+
+ return 0;
+fail:
+ saved_errno = errno;
+ mds_kbdc_tree_free(dup_sequence);
+ return errno = saved_errno, -1;
}
@@ -543,69 +544,63 @@ static int simplify_map(mds_kbdc_tree_map_t* restrict tree)
* @param tree The alternation-subtree
* @return Zero on success, -1 on error
*/
-static int simplify_alternation(mds_kbdc_tree_alternation_t* restrict tree)
+static int
+simplify_alternation(mds_kbdc_tree_alternation_t *restrict tree)
{
- mds_kbdc_tree_t* argument;
- mds_kbdc_tree_t* first_nothing = NULL;
- mds_kbdc_tree_t* temp;
- mds_kbdc_tree_t** here;
- int redo = 0;
-
- /* Test emptyness. */
- if (tree->inner == NULL)
- {
- NEW_ERROR(tree, ERROR, "empty alternation");
- tree->type = C(NOTHING);
- tree->processed = PROCESS_LEVEL;
- return 0;
- }
-
- /* Test singletonness. */
- if (tree->inner->next == NULL)
- {
- temp = tree->inner;
- NEW_ERROR(tree, WARNING, "singleton alternation");
- memcpy(tree, temp, sizeof(mds_kbdc_tree_t));
- free(temp);
- fail_if (simplify((mds_kbdc_tree_t*)tree));
- return 0;
- }
-
- /* Simplify. */
- for (here = &(tree->inner); (argument = *here); redo ? (redo = 0) : (here = &(argument->next), 0))
- if ((argument->type == C(NOTHING)) && (argument->processed != PROCESS_LEVEL))
- {
- /* Test multiple nothings. */
- if (first_nothing == NULL)
- first_nothing = argument;
- else
- {
- NEW_ERROR(argument, WARNING, "multiple ‘.’ inside an alternation");
- NEW_ERROR(first_nothing, NOTE, "first ‘.’ was here");
- }
- }
- else if (argument->type == C(ALTERNATION))
- {
- /* Alternation nesting. */
- if (argument->processed != PROCESS_LEVEL)
- NEW_ERROR(argument, WARNING, "alternation inside alternation is unnessary");
- fail_if (simplify_alternation(&(argument->alternation)));
- if (argument->type == C(ALTERNATION))
- FLATTEN(argument);
- redo = 1;
- }
- else if (argument->type == C(UNORDERED))
- {
- /* Nesting unordered subsequence,
- simplifies to alternation of ordered subsequence, or simpler. */
- NEW_ERROR(argument, WARNING, "unordered subsequence inside alternation is discouraged");
- fail_if (simplify_unordered(&(argument->unordered)));
- redo = 1;
- }
-
- return 0;
- fail:
- return -1;
+ mds_kbdc_tree_t *argument;
+ mds_kbdc_tree_t *first_nothing = NULL;
+ mds_kbdc_tree_t *temp;
+ mds_kbdc_tree_t **here;
+ int redo = 0;
+
+ /* Test emptyness. */
+ if (!tree->inner) {
+ NEW_ERROR(tree, ERROR, "empty alternation");
+ tree->type = C(NOTHING);
+ tree->processed = PROCESS_LEVEL;
+ return 0;
+ }
+
+ /* Test singletonness. */
+ if (!tree->inner->next) {
+ temp = tree->inner;
+ NEW_ERROR(tree, WARNING, "singleton alternation");
+ memcpy(tree, temp, sizeof(mds_kbdc_tree_t));
+ free(temp);
+ fail_if (simplify((mds_kbdc_tree_t*)tree));
+ return 0;
+ }
+
+ /* Simplify. */
+ for (here = &(tree->inner); (argument = *here); redo ? (redo = 0) : (here = &(argument->next), 0)) {
+ if (argument->type == C(NOTHING) && argument->processed != PROCESS_LEVEL) {
+ /* Test multiple nothings. */
+ if (!first_nothing) {
+ first_nothing = argument;
+ } else{
+ NEW_ERROR(argument, WARNING, "multiple ‘.’ inside an alternation");
+ NEW_ERROR(first_nothing, NOTE, "first ‘.’ was here");
+ }
+ } else if (argument->type == C(ALTERNATION)) {
+ /* Alternation nesting. */
+ if (argument->processed != PROCESS_LEVEL)
+ NEW_ERROR(argument, WARNING, "alternation inside alternation is unnessary");
+ fail_if (simplify_alternation(&(argument->alternation)));
+ if (argument->type == C(ALTERNATION))
+ FLATTEN(argument);
+ redo = 1;
+ } else if (argument->type == C(UNORDERED)) {
+ /* Nesting unordered subsequence,
+ simplifies to alternation of ordered subsequence, or simpler. */
+ NEW_ERROR(argument, WARNING, "unordered subsequence inside alternation is discouraged");
+ fail_if (simplify_unordered(&(argument->unordered)));
+ redo = 1;
+ }
+ }
+
+ return 0;
+fail:
+ return -1;
}
@@ -616,77 +611,75 @@ static int simplify_alternation(mds_kbdc_tree_alternation_t* restrict tree)
* @param elements The subtrees, chained
* @return Chain of ordered subsequence, `NULL` on error
*/
-static mds_kbdc_tree_t* create_permutations(mds_kbdc_tree_t* elements)
+static mds_kbdc_tree_t *
+create_permutations(mds_kbdc_tree_t *elements)
{
- mds_kbdc_tree_t* first = NULL;
- mds_kbdc_tree_t** here = &first;
- mds_kbdc_tree_t** previous_next = &elements;
- mds_kbdc_tree_t* argument;
- mds_kbdc_tree_t* temp;
- mds_kbdc_tree_t* subperms = NULL;
- mds_kbdc_tree_t* perm;
- mds_kbdc_tree_t ordered;
- int saved_errno, no_perms, stage = 0;
-
- /* Error case. */
- fail_if (elements == NULL);
-
- /* Base case. */
- if (elements->next == NULL)
- {
- fail_if ((first = mds_kbdc_tree_create(C(ORDERED))) == NULL);
- fail_if ((first->ordered.inner = mds_kbdc_tree_dup(elements)) == NULL);
- return first;
- }
-
- stage++;
- for (previous_next = &elements; (argument = *previous_next); previous_next = &((*previous_next)->next))
- {
- /* Created ordered alternative for a permutation prototype. */
- mds_kbdc_tree_initialise(&ordered, C(ORDERED));
- /* Select the first element. */
- temp = argument->next, argument->next = NULL;
- ordered.ordered.inner = mds_kbdc_tree_dup(argument);
- argument->next = temp;
- fail_if (ordered.ordered.inner == NULL);
- /* Create subpermutations. */
- *previous_next = argument->next;
- argument->next = NULL;
- no_perms = (elements == NULL);
- subperms = create_permutations(elements);
- argument->next = *previous_next;
- *previous_next = argument;
- fail_if (no_perms ? 0 : (subperms == NULL));
- /* Join first element with subpermutations. */
- while (subperms)
- {
- /* Join. */
- fail_if (perm = mds_kbdc_tree_dup(&ordered), perm == NULL);
- perm->ordered.inner->next = subperms->ordered.inner;
- subperms->ordered.inner = NULL;
- /* Add the permutation to the chain. */
- *here = perm;
- here = &(perm->next);
- /* Select next permutation. */
- temp = subperms;
- subperms = subperms->next;
- temp->next = NULL;
- mds_kbdc_tree_free(temp);
+ mds_kbdc_tree_t *first = NULL;
+ mds_kbdc_tree_t **here = &first;
+ mds_kbdc_tree_t **previous_next = &elements;
+ mds_kbdc_tree_t *argument;
+ mds_kbdc_tree_t *temp;
+ mds_kbdc_tree_t *subperms = NULL;
+ mds_kbdc_tree_t *perm;
+ mds_kbdc_tree_t ordered;
+ int saved_errno, no_perms, stage = 0;
+
+ /* Error case. */
+ fail_if (!elements);
+
+ /* Base case. */
+ if (!elements->next) {
+ fail_if (!(first = mds_kbdc_tree_create(C(ORDERED))));
+ fail_if (!(first->ordered.inner = mds_kbdc_tree_dup(elements)));
+ return first;
}
- /* Destroy prototype. */
- mds_kbdc_tree_destroy(&ordered);
- }
-
- return first;
-
- fail:
- saved_errno = errno;
- mds_kbdc_tree_free(first);
- mds_kbdc_tree_free(subperms);
- if (stage > 0)
- mds_kbdc_tree_destroy(&ordered);
- errno = saved_errno;
- return NULL;
+
+ stage++;
+ for (previous_next = &elements; (argument = *previous_next); previous_next = &(*previous_next)->next) {
+ /* Created ordered alternative for a permutation prototype. */
+ mds_kbdc_tree_initialise(&ordered, C(ORDERED));
+ /* Select the first element. */
+ temp = argument->next, argument->next = NULL;
+ ordered.ordered.inner = mds_kbdc_tree_dup(argument);
+ argument->next = temp;
+ fail_if (!ordered.ordered.inner);
+ /* Create subpermutations. */
+ *previous_next = argument->next;
+ argument->next = NULL;
+ no_perms = !elements;
+ subperms = create_permutations(elements);
+ argument->next = *previous_next;
+ *previous_next = argument;
+ fail_if (no_perms && !subperms);
+ /* Join first element with subpermutations. */
+ while (subperms) {
+ /* Join. */
+ fail_if (!(perm = mds_kbdc_tree_dup(&ordered)));
+ perm->ordered.inner->next = subperms->ordered.inner;
+ subperms->ordered.inner = NULL;
+ /* Add the permutation to the chain. */
+ *here = perm;
+ here = &perm->next;
+ /* Select next permutation. */
+ temp = subperms;
+ subperms = subperms->next;
+ temp->next = NULL;
+ mds_kbdc_tree_free(temp);
+ }
+ /* Destroy prototype. */
+ mds_kbdc_tree_destroy(&ordered);
+ }
+
+ return first;
+
+fail:
+ saved_errno = errno;
+ mds_kbdc_tree_free(first);
+ mds_kbdc_tree_free(subperms);
+ if (stage > 0)
+ mds_kbdc_tree_destroy(&ordered);
+ errno = saved_errno;
+ return NULL;
}
@@ -696,105 +689,97 @@ static mds_kbdc_tree_t* create_permutations(mds_kbdc_tree_t* elements)
* @param tree The unordered subsequence-subtree
* @return Zero on success, -1 on error
*/
-static int simplify_unordered(mds_kbdc_tree_unordered_t* restrict tree)
+static int
+simplify_unordered(mds_kbdc_tree_unordered_t *restrict tree)
{
- mds_kbdc_tree_t* arguments;
- mds_kbdc_tree_t* argument;
- mds_kbdc_tree_t* temp;
- mds_kbdc_tree_t** here;
- int allow_long = 0;
- size_t argument_count;
-
- /* Test for ‘(( ))’. */
- if (tree->inner && (tree->inner->next == NULL) && (tree->inner->type == C(UNORDERED)))
- {
- tree->loc_end = tree->inner->loc_end;
- temp = tree->inner;
- tree->inner = tree->inner->unordered.inner;
- temp->unordered.inner = NULL;
- mds_kbdc_tree_free(temp);
- allow_long = 1;
- }
-
- /* Test emptyness. */
- if (tree->inner == NULL)
- {
- NEW_ERROR(tree, ERROR, "empty unordered subsequence");
- tree->type = C(NOTHING);
- tree->processed = PROCESS_LEVEL;
- return 0;
- }
-
- /* Test singletonness. */
- if (tree->inner->next == NULL)
- {
- temp = tree->inner;
- NEW_ERROR(tree, WARNING, "singleton unordered subsequence");
- memcpy(tree, temp, sizeof(mds_kbdc_tree_t));
- free(temp);
- fail_if (simplify((mds_kbdc_tree_t*)tree));
- return -1;
- }
-
- /* Remove ‘.’:s. */
- REMOVE_NOTHING(inner);
-
- /* Check that the sequnced contained anything else. */
- if (tree->inner == NULL)
- {
- NEW_ERROR(tree, ERROR, "unordered subsequence contained nothing else than ‘.’");
- tree->type = C(NOTHING);
- tree->processed = PROCESS_LEVEL;
- return 0;
- }
-
- /* Simplify. */
- for (argument = tree->inner, argument_count = 0; argument; argument = argument->next, argument_count++)
- if (argument->type == C(ALTERNATION))
- {
- fail_if (simplify_alternation(&(argument->alternation)));
- argument->processed = PROCESS_LEVEL;
- }
- else if (argument->type == C(UNORDERED))
- {
- NEW_ERROR(argument, WARNING, "unordered subsequence inside unordered subsequence is discouraged");
- fail_if (simplify_unordered(&(argument->unordered)));
- argument->processed = PROCESS_LEVEL;
- }
-
- /* Check the size of the subsequence. */
- if ((argument_count > 5) && (allow_long * argv_force == 0))
- {
- if (allow_long == 0)
- NEW_ERROR(tree->inner, ERROR,
- "unordered subsequence longer than 5 elements need double brackets");
- else if (argv_force == 0)
- NEW_ERROR(tree->inner, ERROR,
- "unordered subsequence of size %zu found, requires ‘--force’ to compile", argument_count);
- return 0;
- }
-
- /* Generate permutations. */
- tree->type = C(ALTERNATION);
- tree->processed = PROCESS_LEVEL;
- arguments = tree->inner;
- if (tree->inner = create_permutations(arguments), tree->inner == NULL)
- {
- if (errno == 0)
- {
- /* `create_permutations` can return `NULL` without setting `errno`
- * if it does not list any permutations. */
- NEW_ERROR_(result, INTERNAL_ERROR, 0, 0, 0, 0, 1,
- "Fail to create permutations of an unordered sequence");
- return 0;
+ mds_kbdc_tree_t *arguments;
+ mds_kbdc_tree_t *argument;
+ mds_kbdc_tree_t *temp;
+ mds_kbdc_tree_t **here;
+ int allow_long = 0;
+ size_t argument_count;
+
+ /* Test for ‘(( ))’. */
+ if (tree->inner && !tree->inner->next && tree->inner->type == C(UNORDERED)) {
+ tree->loc_end = tree->inner->loc_end;
+ temp = tree->inner;
+ tree->inner = tree->inner->unordered.inner;
+ temp->unordered.inner = NULL;
+ mds_kbdc_tree_free(temp);
+ allow_long = 1;
}
- fail_if (tree->inner = arguments, 1);
- }
- mds_kbdc_tree_free(arguments);
-
- return 0;
- fail:
- return -1;
+
+ /* Test emptyness. */
+ if (!tree->inner) {
+ NEW_ERROR(tree, ERROR, "empty unordered subsequence");
+ tree->type = C(NOTHING);
+ tree->processed = PROCESS_LEVEL;
+ return 0;
+ }
+
+ /* Test singletonness. */
+ if (!tree->inner->next) {
+ temp = tree->inner;
+ NEW_ERROR(tree, WARNING, "singleton unordered subsequence");
+ memcpy(tree, temp, sizeof(mds_kbdc_tree_t));
+ free(temp);
+ fail_if (simplify((mds_kbdc_tree_t*)tree));
+ return -1;
+ }
+
+ /* Remove ‘.’:s. */
+ REMOVE_NOTHING(inner);
+
+ /* Check that the sequnced contained anything else. */
+ if (!tree->inner) {
+ NEW_ERROR(tree, ERROR, "unordered subsequence contained nothing else than ‘.’");
+ tree->type = C(NOTHING);
+ tree->processed = PROCESS_LEVEL;
+ return 0;
+ }
+
+ /* Simplify. */
+ for (argument = tree->inner, argument_count = 0; argument; argument = argument->next, argument_count++) {
+ if (argument->type == C(ALTERNATION)) {
+ fail_if (simplify_alternation(&(argument->alternation)));
+ argument->processed = PROCESS_LEVEL;
+ } else if (argument->type == C(UNORDERED)) {
+ NEW_ERROR(argument, WARNING, "unordered subsequence inside unordered subsequence is discouraged");
+ fail_if (simplify_unordered(&(argument->unordered)));
+ argument->processed = PROCESS_LEVEL;
+ }
+ }
+
+ /* Check the size of the subsequence. */
+ if (argument_count > 5 && (!allow_long || !argv_force)) {
+ if (!allow_long)
+ NEW_ERROR(tree->inner, ERROR,
+ "unordered subsequence longer than 5 elements need double brackets");
+ else if (!argv_force)
+ NEW_ERROR(tree->inner, ERROR,
+ "unordered subsequence of size %zu found, requires ‘--force’ to compile", argument_count);
+ return 0;
+ }
+
+ /* Generate permutations. */
+ tree->type = C(ALTERNATION);
+ tree->processed = PROCESS_LEVEL;
+ arguments = tree->inner;
+ if (!(tree->inner = create_permutations(arguments))) {
+ if (!errno) {
+ /* `create_permutations` can return `NULL` without setting `errno`
+ * if it does not list any permutations. */
+ NEW_ERROR_(result, INTERNAL_ERROR, 0, 0, 0, 0, 1,
+ "Fail to create permutations of an unordered sequence");
+ return 0;
+ }
+ fail_if (tree->inner = arguments, 1);
+ }
+ mds_kbdc_tree_free(arguments);
+
+ return 0;
+fail:
+ return -1;
}
@@ -804,34 +789,34 @@ static int simplify_unordered(mds_kbdc_tree_unordered_t* restrict tree)
* @param tree The tree
* @return Zero on success, -1 on error
*/
-static int simplify(mds_kbdc_tree_t* restrict tree)
+static int
+simplify(mds_kbdc_tree_t *restrict tree)
{
-#define s(expr) fail_if (simplify(tree->expr))
-#define S(type) fail_if (simplify_##type(&(tree->type)))
- again:
- if (tree == NULL)
- return 0;
-
- switch (tree->type)
- {
- case C(INFORMATION): s (information.inner); break;
- case C(FUNCTION): s (function.inner); break;
- case C(MACRO): s (macro.inner); break;
- case C(ASSUMPTION): s (assumption.inner); break;
- case C(FOR): s (for_.inner); break;
- case C(IF): s (if_.inner); s (if_.otherwise); break;
- case C(MAP): S (map); break;
- case C(ALTERNATION): S (alternation); break;
- case C(UNORDERED): S (unordered); break;
- case C(MACRO_CALL): S (macro_call); break;
- default:
- break;
- }
-
- tree = tree->next;
- goto again;
+#define s(expr) fail_if (simplify(tree->expr))
+#define S(type) fail_if (simplify_##type(&(tree->type)))
+again:
+ if (!tree)
+ return 0;
+
+ switch (tree->type) {
+ case C(INFORMATION): s (information.inner); break;
+ case C(FUNCTION): s (function.inner); break;
+ case C(MACRO): s (macro.inner); break;
+ case C(ASSUMPTION): s (assumption.inner); break;
+ case C(FOR): s (for_.inner); break;
+ case C(IF): s (if_.inner); s (if_.otherwise); break;
+ case C(MAP): S (map); break;
+ case C(ALTERNATION): S (alternation); break;
+ case C(UNORDERED): S (unordered); break;
+ case C(MACRO_CALL): S (macro_call); break;
+ default:
+ break;
+ }
+
+ tree = tree->next;
+ goto again;
fail:
- return -1;
+ return -1;
#undef s
#undef S
}
@@ -843,10 +828,11 @@ static int simplify(mds_kbdc_tree_t* restrict tree)
* @param result_ `result` from `parse_to_tree`, same sematics, will be updated
* @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
*/
-int simplify_tree(mds_kbdc_parsed_t* restrict result_)
+int
+simplify_tree(mds_kbdc_parsed_t *restrict result_)
{
- result = result_;
- return simplify(result_->tree);
+ result = result_;
+ return simplify(result_->tree);
}
@@ -856,4 +842,3 @@ int simplify_tree(mds_kbdc_parsed_t* restrict result_)
#undef NEW_ERROR
#undef C
#undef PROCESS_LEVEL
-
diff --git a/src/mds-kbdc/simplify-tree.h b/src/mds-kbdc/simplify-tree.h
index b5e5ce2..e648a46 100644
--- a/src/mds-kbdc/simplify-tree.h
+++ b/src/mds-kbdc/simplify-tree.h
@@ -28,8 +28,7 @@
* @param result `result` from `parse_to_tree`, same sematics, will be updated
* @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
*/
-int simplify_tree(mds_kbdc_parsed_t* restrict result);
+int simplify_tree(mds_kbdc_parsed_t *restrict result);
#endif
-
diff --git a/src/mds-kbdc/string.c b/src/mds-kbdc/string.c
index a334611..c0e9852 100644
--- a/src/mds-kbdc/string.c
+++ b/src/mds-kbdc/string.c
@@ -30,12 +30,13 @@
* @param string The string
* @return The length of the string
*/
-size_t string_length(const char32_t* restrict string)
+size_t
+string_length(const char32_t *restrict string)
{
- size_t i = 0;
- while (string[i] != -1)
- i++;
- return i;
+ size_t i = 0;
+ while (string[i] != -1)
+ i++;
+ return i;
}
@@ -45,43 +46,41 @@ size_t string_length(const char32_t* restrict string)
* @param string The UTF-8 string
* @return The string in UTF-32, `NULL` on error
*/
-char32_t* string_decode(const char* restrict string)
+char32_t *
+string_decode(const char *restrict string)
{
- size_t i, j, n, length = 0;
- char32_t* rc;
-
- /* Get the length of the UTF-32 string, excluding termination. */
- for (i = 0; string[i]; i++)
- if ((string[i] & 0xC0) != 0x80)
- length++;
-
- /* Allocated UTF-32 string. */
- fail_if (xmalloc(rc, length + 1, char32_t));
-
- /* Convert to UTF-32. */
- for (i = j = n = 0; string[i]; i++)
- {
- char c = string[i];
- if (n)
- {
- rc[j] <<= 6, rc[j] |= c & 0x3F;
- if (--n == 0)
- j++;
- }
- else if ((c & 0xC0) == 0xC0)
- {
- while (c & 0x80)
- n++, c = (char)(c << 1);
- rc[j] = c >> n--;
+ size_t i, j, n, length = 0;
+ char32_t *rc;
+ char c;
+
+ /* Get the length of the UTF-32 string, excluding termination. */
+ for (i = 0; string[i]; i++)
+ if ((string[i] & 0xC0) != 0x80)
+ length++;
+
+ /* Allocated UTF-32 string. */
+ fail_if (xmalloc(rc, length + 1, char32_t));
+
+ /* Convert to UTF-32. */
+ for (i = j = n = 0; string[i]; i++) {
+ c = string[i];
+ if (n) {
+ rc[j] <<= 6, rc[j] |= c & 0x3F;
+ if (!--n)
+ j++;
+ } else if ((c & 0xC0) == 0xC0) {
+ while (c & 0x80)
+ n++, c = (char)(c << 1);
+ rc[j] = c >> n--;
+ } else {
+ rc[j++] = c & 255;
+ }
}
- else
- rc[j++] = c & 255;
- }
- /* -1-terminate and return. */
- return rc[length] = -1, rc;
- fail:
- return NULL;
+ /* -1-terminate and return. */
+ return rc[length] = -1, rc;
+fail:
+ return NULL;
}
@@ -93,42 +92,43 @@ char32_t* string_decode(const char* restrict string)
* @param string The UTF-32 string
* @return The string in UTF-8, `NULL` on error
*/
-char* string_encode(const char32_t* restrict string)
+char *
+string_encode(const char32_t *restrict string)
{
- size_t i, j, n = string_length(string);
- char* restrict rc;
-
- /* Allocated Modified UTF-8 string. */
- fail_if (xmalloc(rc, 7 * n + 1, char));
-
- /* Convert to Modified UTF-8. */
- for (i = j = 0; i < n; i++)
- {
-#define _c(s) rc[j++] = (char)(((c >> (s)) & 0x3F) | 0x80)
-#define _t(s) (0 < c) && ((uint32_t)c < (uint32_t)(1ULL << s))
- char32_t c = string[i];
- if (c == 0) rc[j++] = (char)0xC0, rc[j++] = (char)0x80;
- else if (_t( 7)) rc[j++] = (char)c;
- else if (_t(11)) rc[j++] = (char)((c >> 6) | 0xC0), _c( 0);
- else if (_t(16)) rc[j++] = (char)((c >> 12) | 0xE0), _c( 6), _c( 0);
- else if (_t(21)) rc[j++] = (char)((c >> 18) | 0xF0), _c(12), _c( 6), _c( 0);
- /* UTF-8 actually ends here, fits 32 planes. */
- else if (_t(26)) rc[j++] = (char)((c >> 24) | 0xF8), _c(18), _c(12), _c( 6), _c(0);
- else if (_t(31)) rc[j++] = (char)((c >> 30) | 0xFC), _c(24), _c(18), _c(12), _c(6), _c(0);
- /* The orginal UTF-8 specification ended here, fits 31 bits.
- * However, we added another byte so we can fit 32 bits
- * (actually we ca now fit 36 bits.)
- * However, we only needed this in `string_decode` which would
- * not require any changed, but we added it here for symmetry. */
- else rc[j++] = (char)0xFE, _c(30), _c(24), _c(18), _c(12), _c(6), _c(0);
+ size_t i, j, n = string_length(string);
+ char *restrict rc;
+ char32_t c;
+
+ /* Allocated Modified UTF-8 string. */
+ fail_if (xmalloc(rc, 7 * n + 1, char));
+
+ /* Convert to Modified UTF-8. */
+ for (i = j = 0; i < n; i++) {
+#define _c(s) rc[j++] = (char)(((c >> (s)) & 0x3F) | 0x80)
+#define _t(s) (0 < c) && ((uint32_t)c < (uint32_t)(1ULL << (s)))
+ c = string[i];
+ if (!c) rc[j++] = (char)0xC0, rc[j++] = (char)0x80;
+ else if (_t( 7)) rc[j++] = (char)c;
+ else if (_t(11)) rc[j++] = (char)((c >> 6) | 0xC0), _c( 0);
+ else if (_t(16)) rc[j++] = (char)((c >> 12) | 0xE0), _c( 6), _c( 0);
+ else if (_t(21)) rc[j++] = (char)((c >> 18) | 0xF0), _c(12), _c( 6), _c( 0);
+ /* UTF-8 actually ends here, fits 32 planes. */
+ else if (_t(26)) rc[j++] = (char)((c >> 24) | 0xF8), _c(18), _c(12), _c( 6), _c(0);
+ else if (_t(31)) rc[j++] = (char)((c >> 30) | 0xFC), _c(24), _c(18), _c(12), _c(6), _c(0);
+ /* The orginal UTF-8 specification ended here, fits 31 bits.
+ * However, we added another byte so we can fit 32 bits
+ * (actually we ca now fit 36 bits.)
+ * However, we only needed this in `string_decode` which would
+ * not require any changed, but we added it here for symmetry. */
+ else rc[j++] = (char)0xFE, _c(30), _c(24), _c(18), _c(12), _c(6), _c(0);
#undef _t
#undef _c
- }
-
- /* NUL-terminate and return. */
- return rc[j] = '\0', rc;
- fail:
- return NULL;
+ }
+
+ /* NUL-terminate and return. */
+ return rc[j] = '\0', rc;
+fail:
+ return NULL;
}
@@ -138,16 +138,16 @@ char* string_encode(const char32_t* restrict string)
* @param string The string
* @return A duplicate of the string, `NULL` on error or if `string` is `NULL`
*/
-char32_t* string_dup(const char32_t* restrict string)
+char32_t *
+string_dup(const char32_t *restrict string)
{
- size_t n;
- char32_t* rc;
- if (string == NULL)
- return NULL;
- n = string_length(string) + 1;
- fail_if (xmemdup(rc, string, n, char32_t));
- return rc;
- fail:
- return NULL;
+ size_t n;
+ char32_t *rc;
+ if (!string)
+ return NULL;
+ n = string_length(string) + 1;
+ fail_if (xmemdup(rc, string, n, char32_t));
+ return rc;
+fail:
+ return NULL;
}
-
diff --git a/src/mds-kbdc/string.h b/src/mds-kbdc/string.h
index a58eb91..81155ed 100644
--- a/src/mds-kbdc/string.h
+++ b/src/mds-kbdc/string.h
@@ -35,7 +35,8 @@ typedef int32_t char32_t;
* @param string The string
* @return The length of the string
*/
-size_t string_length(const char32_t* restrict string) __attribute__((pure, nonnull));
+__attribute__((pure, nonnull))
+size_t string_length(const char32_t *restrict string);
/**
* Convert a NUL-terminated UTF-8 string to a -1-terminated UTF-32 string
@@ -43,7 +44,8 @@ size_t string_length(const char32_t* restrict string) __attribute__((pure, nonnu
* @param string The UTF-8 string
* @return The string in UTF-32, `NULL` on error
*/
-char32_t* string_decode(const char* restrict string) __attribute__((nonnull));
+__attribute__((nonnull))
+char32_t *string_decode(const char *restrict string);
/**
* Convert a -1-terminated UTF-32 string to a NUL-terminated Modified UTF-8 string
@@ -51,7 +53,8 @@ char32_t* string_decode(const char* restrict string) __attribute__((nonnull));
* @param string The UTF-32 string
* @return The string in UTF-8, `NULL` on error
*/
-char* string_encode(const char32_t* restrict string) __attribute__((nonnull));
+__attribute__((nonnull))
+char *string_encode(const char32_t *restrict string);
/**
* Create duplicate of a string
@@ -59,9 +62,8 @@ char* string_encode(const char32_t* restrict string) __attribute__((nonnull));
* @param string The string
* @return A duplicate of the string, `NULL` on error or if `string` is `NULL`
*/
-char32_t* string_dup(const char32_t* restrict string);
+char32_t *string_dup(const char32_t *restrict string);
#endif
-
diff --git a/src/mds-kbdc/tree.c b/src/mds-kbdc/tree.c
index 289ccac..33db89e 100644
--- a/src/mds-kbdc/tree.c
+++ b/src/mds-kbdc/tree.c
@@ -36,7 +36,7 @@ typedef struct mds_kbdc_tree_information_data mds_kbdc_tree_information_data_t;
/**
* Tree type constant shortener
*/
-#define C(t) MDS_KBDC_TREE_TYPE_##t
+#define C(t) MDS_KBDC_TREE_TYPE_##t
/**
@@ -45,10 +45,11 @@ typedef struct mds_kbdc_tree_information_data mds_kbdc_tree_information_data_t;
* @param this The memory slot for the tree node
* @param type The type of the node
*/
-void mds_kbdc_tree_initialise(mds_kbdc_tree_t* restrict this, int type)
+void
+mds_kbdc_tree_initialise(mds_kbdc_tree_t *restrict this, int type)
{
- memset(this, 0, sizeof(mds_kbdc_tree_t));
- this->type = type;
+ memset(this, 0, sizeof(mds_kbdc_tree_t));
+ this->type = type;
}
@@ -58,14 +59,15 @@ void mds_kbdc_tree_initialise(mds_kbdc_tree_t* restrict this, int type)
* @param type The type of the node
* @return The tree node, `NULL` on error
*/
-mds_kbdc_tree_t* mds_kbdc_tree_create(int type)
+mds_kbdc_tree_t *
+mds_kbdc_tree_create(int type)
{
- mds_kbdc_tree_t* this;
- fail_if (xmalloc(this, 1, mds_kbdc_tree_t));
- mds_kbdc_tree_initialise(this, type);
- return this;
- fail:
- return NULL;
+ mds_kbdc_tree_t *this;
+ fail_if (xmalloc(this, 1, mds_kbdc_tree_t));
+ mds_kbdc_tree_initialise(this, type);
+ return this;
+fail:
+ return NULL;
}
@@ -75,110 +77,109 @@ mds_kbdc_tree_t* mds_kbdc_tree_create(int type)
* @param this The tree node
* @param recursive Whether subtree should be destroyed and freed
*/
-static void mds_kbdc_tree_destroy_(mds_kbdc_tree_t* restrict this, int recursive)
+static void mds_kbdc_tree_destroy_(mds_kbdc_tree_t *restrict this, int recursive)
{
-#define V(type, var) (((type)this)->var)
-#define xfree(t, v) (free(V(t, v)), V(t, v) = NULL)
-#define xdestroy(t, v) (recursive ? (mds_kbdc_tree_destroy_(V(t, v), 1), xfree(t, v)) : (V(t, v) = NULL))
-
- mds_kbdc_tree_t* prev = NULL;
- mds_kbdc_tree_t* first = this;
-
- again:
- if (this == NULL)
- return;
-
- switch (this->type)
- {
- case C(INFORMATION):
- case C(ASSUMPTION):
- case C(ALTERNATION):
- case C(UNORDERED):
- case C(ORDERED):
- xdestroy(mds_kbdc_tree_nesting_t*, inner);
- break;
-
- case C(INFORMATION_LANGUAGE):
- case C(INFORMATION_COUNTRY):
- case C(INFORMATION_VARIANT):
- xfree(mds_kbdc_tree_information_data_t*, data);
- break;
-
- case C(FUNCTION):
- case C(MACRO):
- xfree(mds_kbdc_tree_callable_t*, name);
- xdestroy(mds_kbdc_tree_callable_t*, inner);
- break;
-
- case C(INCLUDE):
- xfree(mds_kbdc_tree_include_t*, filename);
- xdestroy(mds_kbdc_tree_include_t*, inner);
- mds_kbdc_source_code_free(this->include.source_code);
- break;
-
- case C(ASSUMPTION_HAVE):
- xdestroy(mds_kbdc_tree_assumption_have_t*, data);
- break;
-
- case C(ASSUMPTION_HAVE_CHARS):
- xfree(mds_kbdc_tree_assumption_have_chars_t*, chars);
- break;
-
- case C(ASSUMPTION_HAVE_RANGE):
- xfree(mds_kbdc_tree_assumption_have_range_t*, first);
- xfree(mds_kbdc_tree_assumption_have_range_t*, last);
- break;
-
- case C(FOR):
- xfree(mds_kbdc_tree_for_t*, first);
- xfree(mds_kbdc_tree_for_t*, last);
- xfree(mds_kbdc_tree_for_t*, variable);
- xdestroy(mds_kbdc_tree_for_t*, inner);
- break;
-
- case C(IF):
- xfree(mds_kbdc_tree_if_t*, condition);
- xdestroy(mds_kbdc_tree_if_t*, inner);
- xdestroy(mds_kbdc_tree_if_t*, otherwise);
- break;
-
- case C(LET):
- xfree(mds_kbdc_tree_let_t*, variable);
- xdestroy(mds_kbdc_tree_let_t*, value);
- break;
-
- case C(MAP):
- xdestroy(mds_kbdc_tree_map_t*, sequence);
- xdestroy(mds_kbdc_tree_map_t*, result);
- break;
-
- case C(ARRAY):
- xdestroy(mds_kbdc_tree_array_t*, elements);
- break;
-
- case C(KEYS):
- case C(STRING):
- case C(COMPILED_KEYS):
- case C(COMPILED_STRING):
- xfree(mds_kbdc_tree_keys_t*, keys);
- /* We are abusing the similaries of the structures. */
- break;
-
- case C(MACRO_CALL):
- xfree(mds_kbdc_tree_macro_call_t*, name);
- xdestroy(mds_kbdc_tree_macro_call_t*, arguments);
- break;
-
- default:
- break;
- }
-
- prev = this;
- this = this->next;
- if (prev != first)
- free(prev);
- goto again;
-
+#define V(type, var) (((type)this)->var)
+#define xfree(t, v) (free(V(t, v)), V(t, v) = NULL)
+#define xdestroy(t, v) (recursive ? (mds_kbdc_tree_destroy_(V(t, v), 1), xfree(t, v)) : (V(t, v) = NULL))
+
+ mds_kbdc_tree_t *prev = NULL;
+ mds_kbdc_tree_t *first = this;
+
+again:
+ if (!this)
+ return;
+
+ switch (this->type) {
+ case C(INFORMATION):
+ case C(ASSUMPTION):
+ case C(ALTERNATION):
+ case C(UNORDERED):
+ case C(ORDERED):
+ xdestroy(mds_kbdc_tree_nesting_t *, inner);
+ break;
+
+ case C(INFORMATION_LANGUAGE):
+ case C(INFORMATION_COUNTRY):
+ case C(INFORMATION_VARIANT):
+ xfree(mds_kbdc_tree_information_data_t *, data);
+ break;
+
+ case C(FUNCTION):
+ case C(MACRO):
+ xfree(mds_kbdc_tree_callable_t *, name);
+ xdestroy(mds_kbdc_tree_callable_t *, inner);
+ break;
+
+ case C(INCLUDE):
+ xfree(mds_kbdc_tree_include_t *, filename);
+ xdestroy(mds_kbdc_tree_include_t *, inner);
+ mds_kbdc_source_code_free(this->include.source_code);
+ break;
+
+ case C(ASSUMPTION_HAVE):
+ xdestroy(mds_kbdc_tree_assumption_have_t *, data);
+ break;
+
+ case C(ASSUMPTION_HAVE_CHARS):
+ xfree(mds_kbdc_tree_assumption_have_chars_t *, chars);
+ break;
+
+ case C(ASSUMPTION_HAVE_RANGE):
+ xfree(mds_kbdc_tree_assumption_have_range_t *, first);
+ xfree(mds_kbdc_tree_assumption_have_range_t *, last);
+ break;
+
+ case C(FOR):
+ xfree(mds_kbdc_tree_for_t *, first);
+ xfree(mds_kbdc_tree_for_t *, last);
+ xfree(mds_kbdc_tree_for_t *, variable);
+ xdestroy(mds_kbdc_tree_for_t *, inner);
+ break;
+
+ case C(IF):
+ xfree(mds_kbdc_tree_if_t *, condition);
+ xdestroy(mds_kbdc_tree_if_t *, inner);
+ xdestroy(mds_kbdc_tree_if_t *, otherwise);
+ break;
+
+ case C(LET):
+ xfree(mds_kbdc_tree_let_t *, variable);
+ xdestroy(mds_kbdc_tree_let_t *, value);
+ break;
+
+ case C(MAP):
+ xdestroy(mds_kbdc_tree_map_t *, sequence);
+ xdestroy(mds_kbdc_tree_map_t *, result);
+ break;
+
+ case C(ARRAY):
+ xdestroy(mds_kbdc_tree_array_t *, elements);
+ break;
+
+ case C(KEYS):
+ case C(STRING):
+ case C(COMPILED_KEYS):
+ case C(COMPILED_STRING):
+ xfree(mds_kbdc_tree_keys_t *, keys);
+ /* We are abusing the similaries of the structures. */
+ break;
+
+ case C(MACRO_CALL):
+ xfree(mds_kbdc_tree_macro_call_t *, name);
+ xdestroy(mds_kbdc_tree_macro_call_t *, arguments);
+ break;
+
+ default:
+ break;
+ }
+
+ prev = this;
+ this = this->next;
+ if (prev != first)
+ free(prev);
+ goto again;
+
#undef xdestroy
#undef xfree
#undef V
@@ -192,9 +193,10 @@ static void mds_kbdc_tree_destroy_(mds_kbdc_tree_t* restrict this, int recursive
*
* @param this The tree node
*/
-void mds_kbdc_tree_destroy_nonrecursive(mds_kbdc_tree_t* restrict this)
+void
+mds_kbdc_tree_destroy_nonrecursive(mds_kbdc_tree_t *restrict this)
{
- mds_kbdc_tree_destroy_(this, 0);
+ mds_kbdc_tree_destroy_(this, 0);
}
@@ -206,10 +208,11 @@ void mds_kbdc_tree_destroy_nonrecursive(mds_kbdc_tree_t* restrict this)
*
* @param this The tree node
*/
-void mds_kbdc_tree_free_nonrecursive(mds_kbdc_tree_t* restrict this)
+void
+mds_kbdc_tree_free_nonrecursive(mds_kbdc_tree_t *restrict this)
{
- mds_kbdc_tree_destroy_nonrecursive(this);
- free(this);
+ mds_kbdc_tree_destroy_nonrecursive(this);
+ free(this);
}
@@ -220,9 +223,10 @@ void mds_kbdc_tree_free_nonrecursive(mds_kbdc_tree_t* restrict this)
*
* @param this The tree node
*/
-void mds_kbdc_tree_destroy(mds_kbdc_tree_t* restrict this)
+void
+mds_kbdc_tree_destroy(mds_kbdc_tree_t *restrict this)
{
- mds_kbdc_tree_destroy_(this, 1);
+ mds_kbdc_tree_destroy_(this, 1);
}
@@ -233,10 +237,11 @@ void mds_kbdc_tree_destroy(mds_kbdc_tree_t* restrict this)
*
* @param this The tree node
*/
-void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this)
+void
+mds_kbdc_tree_free(mds_kbdc_tree_t *restrict this)
{
- mds_kbdc_tree_destroy(this);
- free(this);
+ mds_kbdc_tree_destroy(this);
+ free(this);
}
@@ -246,7 +251,7 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this)
*
* @param member:identifer The member in the tree to duplicate
*/
-#define T(member) fail_if (t->member && (n->member = mds_kbdc_tree_dup(t->member), n->member == NULL))
+#define T(member) fail_if (t->member && !(n->member = mds_kbdc_tree_dup(t->member)))
/**
@@ -254,7 +259,7 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this)
*
* @param member:identifer The member in the tree to duplicate
*/
-#define S(member) fail_if (t->member && xstrdup(n->member, t->member))
+#define S(member) fail_if (t->member && xstrdup(n->member, t->member))
/**
@@ -262,7 +267,7 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this)
*
* @param member:identifer The member in the tree to duplicate
*/
-#define Z(member) fail_if (t->member && (n->member = string_dup(t->member), n->member == NULL))
+#define Z(member) fail_if (t->member && !(n->member = string_dup(t->member)))
/**
@@ -270,7 +275,7 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this)
*
* @param member:identifer The member in the tree to copied
*/
-#define R(member) fail_if (t->member && (n->member = mds_kbdc_source_code_dup(t->member), n->member == NULL))
+#define R(member) fail_if (t->member && !(n->member = mds_kbdc_source_code_dup(t->member)))
@@ -280,62 +285,109 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this)
* @param this The tree node
* @return A duplicate of `this`, `NULL` on error
*/
-mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this)
+mds_kbdc_tree_t *
+mds_kbdc_tree_dup(const mds_kbdc_tree_t *restrict this)
{
-#define t this
-#define n (*node)
- mds_kbdc_tree_t* rc = NULL;
- mds_kbdc_tree_t** node = &rc;
- int saved_errno;
-
- again:
- if (t == NULL) return rc;
- fail_if (xcalloc(n, 1, mds_kbdc_tree_t));
+#define t this
+#define n (*node)
+ mds_kbdc_tree_t *rc = NULL;
+ mds_kbdc_tree_t **node = &rc;
+ int saved_errno;
+
+again:
+ if (!t)
+ return rc;
+ fail_if (xcalloc(n, 1, mds_kbdc_tree_t));
+
+ n->type = t->type;
+ n->loc_line = t->loc_line;
+ n->loc_start = t->loc_start;
+ n->loc_end = t->loc_end;
+ n->processed = t->processed;
+
+ switch (this->type) {
+ case C(INFORMATION):
+ case C(ASSUMPTION):
+ case C(ALTERNATION):
+ case C(UNORDERED):
+ case C(ORDERED):
+ T(ordered.inner);
+ break;
+ case C(FUNCTION):
+ case C(MACRO):
+ S(macro.name);
+ T(macro.inner);
+ break;
+ case C(ASSUMPTION_HAVE):
+ T(have.data);
+ break;
+ case C(ARRAY):
+ T(array.elements);
+ break;
+ case C(LET):
+ S(let.variable);
+ T(let.value);
+ break;
+ case C(MACRO_CALL):
+ S(macro_call.name);
+ T(macro_call.arguments);
+ break;
+ case C(INFORMATION_LANGUAGE):
+ case C(INFORMATION_COUNTRY):
+ case C(INFORMATION_VARIANT):
+ S(variant.data);
+ break;
+ case C(INCLUDE):
+ S(include.filename);
+ T(include.inner);
+ R(include.source_code);
+ break;
+ case C(ASSUMPTION_HAVE_CHARS):
+ S(have_chars.chars);
+ break;
+ case C(KEYS):
+ S(keys.keys);
+ break;
+ case C(STRING):
+ S(string.string);
+ break;
+ case C(COMPILED_KEYS):
+ Z(compiled_keys.keys);
+ break;
+ case C(COMPILED_STRING):
+ Z(compiled_string.string);
+ break;
+ case C(ASSUMPTION_HAVE_RANGE):
+ S(have_range.first);
+ S(have_range.last);
+ break;
+ case C(FOR):
+ S(for_.first);
+ S(for_.last);
+ S(for_.variable);
+ T(for_.inner);
+ break;
+ case C(IF):
+ S(if_.condition);
+ T(if_.inner);
+ T(if_.otherwise);
+ break;
+ case C(MAP):
+ T(map.sequence);
+ T(map.result);
+ break;
+ default:
+ break;
+ }
+
+ t = t->next;
+ node = &(n->next);
+ goto again;
- n->type = t->type;
- n->loc_line = t->loc_line;
- n->loc_start = t->loc_start;
- n->loc_end = t->loc_end;
- n->processed = t->processed;
-
- switch (this->type)
- {
- case C(INFORMATION):
- case C(ASSUMPTION):
- case C(ALTERNATION):
- case C(UNORDERED):
- case C(ORDERED): T(ordered.inner); break;
- case C(FUNCTION):
- case C(MACRO): S(macro.name); T(macro.inner); break;
- case C(ASSUMPTION_HAVE): T(have.data); break;
- case C(ARRAY): T(array.elements); break;
- case C(LET): S(let.variable); T(let.value); break;
- case C(MACRO_CALL): S(macro_call.name); T(macro_call.arguments); break;
- case C(INFORMATION_LANGUAGE):
- case C(INFORMATION_COUNTRY):
- case C(INFORMATION_VARIANT): S(variant.data); break;
- case C(INCLUDE): S(include.filename); T(include.inner); R(include.source_code); break;
- case C(ASSUMPTION_HAVE_CHARS): S(have_chars.chars); break;
- case C(KEYS): S(keys.keys); break;
- case C(STRING): S(string.string); break;
- case C(COMPILED_KEYS): Z(compiled_keys.keys); break;
- case C(COMPILED_STRING): Z(compiled_string.string); break;
- case C(ASSUMPTION_HAVE_RANGE): S(have_range.first); S(have_range.last); break;
- case C(FOR): S(for_.first); S(for_.last); S(for_.variable); T(for_.inner); break;
- case C(IF): S(if_.condition); T(if_.inner); T(if_.otherwise); break;
- case C(MAP): T(map.sequence); T(map.result); break;
- default:
- break;
- }
-
- t = t->next;
- node = &(n->next);
- goto again;
-
- fail:
- saved_errno = errno;
- mds_kbdc_tree_free(rc);
- return errno = saved_errno, NULL;
+fail:
+ saved_errno = errno;
+ mds_kbdc_tree_free(rc);
+ return errno = saved_errno, NULL;
#undef n
#undef t
}
@@ -355,12 +407,12 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this)
* @param LOWERCASE:identifer The name of subtype
* @param NOTATION:const char* The notation for the subtype
*/
-#define NODE(LOWERCASE, NOTATION) \
- const mds_kbdc_tree_##LOWERCASE##_t* node; \
- node = (const mds_kbdc_tree_##LOWERCASE##_t*)this; \
- fprintf(output, "%*.s(\033[01m%s\033[00m", indent, "", NOTATION); \
- fprintf(output, " \033[36m(@ %zu %zu-%zu)\033[00m", \
- node->loc_line + 1, node->loc_start, node->loc_end)
+#define NODE(LOWERCASE, NOTATION)\
+ const mds_kbdc_tree_##LOWERCASE##_t *node;\
+ node = (const mds_kbdc_tree_##LOWERCASE##_t *)this;\
+ fprintf(output, "%*.s(\033[01m%s\033[00m", indent, "", NOTATION);\
+ fprintf(output, " \033[36m(@ %zu %zu-%zu)\033[00m",\
+ node->loc_line + 1, node->loc_start, node->loc_end)
/**
@@ -368,22 +420,23 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this)
*
* @param MEMBER:identifier The tree structure's member
*/
-#define BRANCH(MEMBER) \
- if (node->MEMBER) \
- { \
- fprintf(output, "\n%*.s(.%s\n", indent + 2, "", #MEMBER); \
- mds_kbdc_tree_print_indented(node->MEMBER, output, indent + 4); \
- fprintf(output, "%*.s)", indent + 2, ""); \
- } \
- else \
- fprintf(output, "\n%*.s(.%s \033[35mnil\033[00m)", indent + 2, "", #MEMBER)
+#define BRANCH(MEMBER)\
+ do {\
+ if (node->MEMBER) {\
+ fprintf(output, "\n%*.s(.%s\n", indent + 2, "", #MEMBER);\
+ mds_kbdc_tree_print_indented(node->MEMBER, output, indent + 4);\
+ fprintf(output, "%*.s)", indent + 2, "");\
+ } else {\
+ fprintf(output, "\n%*.s(.%s \033[35mnil\033[00m)", indent + 2, "", #MEMBER);\
+ }\
+ } while (0)
/**
* End a tree which has at least one member that is a subtree
*/
-#define COMPLEX \
- fprintf(output, "\n%*.s)\n", indent, "")
+#define COMPLEX\
+ fprintf(output, "\n%*.s)\n", indent, "")
/**
@@ -391,11 +444,13 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this)
*
* @param MEMBER:identifier The tree structure's member
*/
-#define STRING(MEMBER) \
- if (node->MEMBER) \
- fprintf(output, " ‘\033[32m%s\033[00m’", node->MEMBER); \
- else \
- fprintf(output, " \033[35mnil\033[00m")
+#define STRING(MEMBER)\
+ do {\
+ if (node->MEMBER)\
+ fprintf(output, " ‘\033[32m%s\033[00m’", node->MEMBER);\
+ else\
+ fprintf(output, " \033[35mnil\033[00m");\
+ } while (0)
/**
@@ -404,9 +459,11 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this)
*
* @param MEMBER:identifier The tree structure's member
*/
-#define SIMPLE(MEMBER) \
- STRING(MEMBER); \
- fprintf(output, ")\n")
+#define SIMPLE(MEMBER)\
+ do {\
+ STRING(MEMBER);\
+ fprintf(output, ")\n");\
+ } while (0)
/**
@@ -417,12 +474,12 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this)
* @param NOTATION:const char* See `NODE`
* @param MEMBER:identifier See `STRING`
*/
-#define SIMPLEX(LOWERCASE, NOTATION, MEMBER) \
- { \
- NODE(LOWERCASE, NOTATION); \
- SIMPLE(MEMBER); \
- } \
- break
+#define SIMPLEX(LOWERCASE, NOTATION, MEMBER)\
+ {\
+ NODE(LOWERCASE, NOTATION);\
+ SIMPLE(MEMBER);\
+ }\
+ break
/**
@@ -434,13 +491,13 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this)
* @param FIRST:identifier See `STRING`, the first member
* @param LAST:identifier See `STRING`, the second member
*/
-#define DUPLEX(LOWERCASE, NOTATION, FIRST, LAST) \
- { \
- NODE(LOWERCASE, NOTATION); \
- STRING(FIRST); \
- SIMPLE(LAST); \
- } \
- break
+#define DUPLEX(LOWERCASE, NOTATION, FIRST, LAST)\
+ {\
+ NODE(LOWERCASE, NOTATION);\
+ STRING(FIRST);\
+ SIMPLE(LAST);\
+ }\
+ break
/**
@@ -451,13 +508,13 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this)
* @param NOTATION:const char* See `NODE`
* @param MEMBER:identifier See `BRANCH`
*/
-#define NESTING(LOWERCASE, NOTATION, MEMBER) \
- { \
- NODE(LOWERCASE, NOTATION); \
- BRANCH(MEMBER); \
- COMPLEX; \
- } \
- break
+#define NESTING(LOWERCASE, NOTATION, MEMBER)\
+ {\
+ NODE(LOWERCASE, NOTATION);\
+ BRANCH(MEMBER);\
+ COMPLEX;\
+ }\
+ break
/**
@@ -470,14 +527,14 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this)
* @param NAMER:identifier See `STRING`
* @param MEMBER:identifier See `BRANCH`
*/
-#define NAMED_NESTING(LOWERCASE, NOTATION, NAMER, MEMBER) \
- { \
- NODE(LOWERCASE, NOTATION); \
- STRING(NAMER); \
- BRANCH(MEMBER); \
- COMPLEX; \
- } \
- break
+#define NAMED_NESTING(LOWERCASE, NOTATION, NAMER, MEMBER)\
+ {\
+ NODE(LOWERCASE, NOTATION);\
+ STRING(NAMER);\
+ BRANCH(MEMBER);\
+ COMPLEX;\
+ }\
+ break
/**
@@ -485,12 +542,12 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this)
*
* @param NOTATION:const char* See `NODE`
*/
-#define NOTHING(NOTATION) \
- fprintf(output, "%*.s(\033[01m%s\033[00m", indent, "", NOTATION); \
- fprintf(output, " \033[36m(@ %zu %zu-%zu)\033[00m", \
- this->loc_line + 1, this->loc_start, this->loc_end); \
- fprintf(output, ")\n"); \
- break
+#define NOTHING(NOTATION)\
+ fprintf(output, "%*.s(\033[01m%s\033[00m", indent, "", NOTATION);\
+ fprintf(output, " \033[36m(@ %zu %zu-%zu)\033[00m",\
+ this->loc_line + 1, this->loc_start, this->loc_end);\
+ fprintf(output, ")\n");\
+ break
@@ -501,100 +558,100 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this)
* @param output The output file
* @param indent The indent
*/
-static void mds_kbdc_tree_print_indented(const mds_kbdc_tree_t* restrict this, FILE* output, int indent)
+static void
+mds_kbdc_tree_print_indented(const mds_kbdc_tree_t *restrict this, FILE *output, int indent)
{
- again:
- if (this == NULL)
- return;
-
- switch (this->type)
- {
- /* These have their break built into their macro. */
- case C(INFORMATION): NESTING(information, "information", inner);
- case C(INFORMATION_LANGUAGE): SIMPLEX(information_language, "language", data);
- case C(INFORMATION_COUNTRY): SIMPLEX(information_country, "country", data);
- case C(INFORMATION_VARIANT): SIMPLEX(information_variant, "variant", data);
- case C(INCLUDE): NAMED_NESTING(include, "include", filename, inner);
- case C(FUNCTION): NAMED_NESTING(function, "function", name, inner);
- case C(MACRO): NAMED_NESTING(macro, "macro", name, inner);
- case C(ASSUMPTION): NESTING(assumption, "assumption", inner);
- case C(ASSUMPTION_HAVE): NESTING(assumption_have, "have", data);
- case C(ASSUMPTION_HAVE_CHARS): SIMPLEX(assumption_have_chars, "have_chars", chars);
- case C(ASSUMPTION_HAVE_RANGE): DUPLEX(assumption_have_range, "have_range", first, last);
- case C(LET): NAMED_NESTING(let, "let", variable, value);
- case C(ARRAY): NESTING(array, "array", elements);
- case C(KEYS): SIMPLEX(keys, "keys", keys);
- case C(STRING): SIMPLEX(string, "string", string);
- case C(NOTHING): NOTHING("nothing");
- case C(ALTERNATION): NESTING(alternation, "alternation", inner);
- case C(UNORDERED): NESTING(unordered, "unordered", inner);
- case C(ORDERED): NESTING(ordered, "ordered", inner);
- case C(MACRO_CALL): NAMED_NESTING(macro_call, "macro_call", name, arguments);
- case C(RETURN): NOTHING("return");
- case C(BREAK): NOTHING("break");
- case C(CONTINUE): NOTHING("continue");
-
- case C(COMPILED_KEYS):
- {
- NODE(compiled_keys, "compiled_keys");
- if (node->keys)
- fprintf(output, " ‘\033[32m%s\033[00m’", string_encode(node->keys));
- else
- fprintf(output, " \033[35mnil\033[00m");
- fprintf(output, ")\n");
- }
- break;
-
- case C(COMPILED_STRING):
- {
- NODE(compiled_string, "compiled_string");
- if (node->string)
- fprintf(output, " ‘\033[32m%s\033[00m’", string_encode(node->string));
- else
- fprintf(output, " \033[35mnil\033[00m");
- fprintf(output, ")\n");
- }
- break;
-
- case C(FOR):
- {
- NODE(for, "for");
- STRING(first);
- STRING(last);
- fprintf(output, " (.variable");
- STRING(variable);
- fprintf(output, ")");
- BRANCH(inner);
- COMPLEX;
- }
- break;
-
- case C(IF):
- {
- NODE(if, "if");
- STRING(condition);
- BRANCH(inner);
- BRANCH(otherwise);
- COMPLEX;
- }
- break;
-
- case C(MAP):
- {
- NODE(map, "map");
- BRANCH(sequence);
- BRANCH(result);
- COMPLEX;
- }
- break;
-
- default:
- abort();
- break;
- }
-
- this = this->next;
- goto again;
+again:
+ if (!this)
+ return;
+
+ switch (this->type) {
+ /* These have their break built into their macro. */
+ case C(INFORMATION): NESTING(information, "information", inner);
+ case C(INFORMATION_LANGUAGE): SIMPLEX(information_language, "language", data);
+ case C(INFORMATION_COUNTRY): SIMPLEX(information_country, "country", data);
+ case C(INFORMATION_VARIANT): SIMPLEX(information_variant, "variant", data);
+ case C(INCLUDE): NAMED_NESTING(include, "include", filename, inner);
+ case C(FUNCTION): NAMED_NESTING(function, "function", name, inner);
+ case C(MACRO): NAMED_NESTING(macro, "macro", name, inner);
+ case C(ASSUMPTION): NESTING(assumption, "assumption", inner);
+ case C(ASSUMPTION_HAVE): NESTING(assumption_have, "have", data);
+ case C(ASSUMPTION_HAVE_CHARS): SIMPLEX(assumption_have_chars, "have_chars", chars);
+ case C(ASSUMPTION_HAVE_RANGE): DUPLEX(assumption_have_range, "have_range", first, last);
+ case C(LET): NAMED_NESTING(let, "let", variable, value);
+ case C(ARRAY): NESTING(array, "array", elements);
+ case C(KEYS): SIMPLEX(keys, "keys", keys);
+ case C(STRING): SIMPLEX(string, "string", string);
+ case C(NOTHING): NOTHING("nothing");
+ case C(ALTERNATION): NESTING(alternation, "alternation", inner);
+ case C(UNORDERED): NESTING(unordered, "unordered", inner);
+ case C(ORDERED): NESTING(ordered, "ordered", inner);
+ case C(MACRO_CALL): NAMED_NESTING(macro_call, "macro_call", name, arguments);
+ case C(RETURN): NOTHING("return");
+ case C(BREAK): NOTHING("break");
+ case C(CONTINUE): NOTHING("continue");
+
+ case C(COMPILED_KEYS):
+ {
+ NODE(compiled_keys, "compiled_keys");
+ if (node->keys)
+ fprintf(output, " ‘\033[32m%s\033[00m’", string_encode(node->keys));
+ else
+ fprintf(output, " \033[35mnil\033[00m");
+ fprintf(output, ")\n");
+ }
+ break;
+
+ case C(COMPILED_STRING):
+ {
+ NODE(compiled_string, "compiled_string");
+ if (node->string)
+ fprintf(output, " ‘\033[32m%s\033[00m’", string_encode(node->string));
+ else
+ fprintf(output, " \033[35mnil\033[00m");
+ fprintf(output, ")\n");
+ }
+ break;
+
+ case C(FOR):
+ {
+ NODE(for, "for");
+ STRING(first);
+ STRING(last);
+ fprintf(output, " (.variable");
+ STRING(variable);
+ fprintf(output, ")");
+ BRANCH(inner);
+ COMPLEX;
+ }
+ break;
+
+ case C(IF):
+ {
+ NODE(if, "if");
+ STRING(condition);
+ BRANCH(inner);
+ BRANCH(otherwise);
+ COMPLEX;
+ }
+ break;
+
+ case C(MAP):
+ {
+ NODE(map, "map");
+ BRANCH(sequence);
+ BRANCH(result);
+ COMPLEX;
+ }
+ break;
+
+ default:
+ abort();
+ break;
+ }
+
+ this = this->next;
+ goto again;
}
@@ -604,9 +661,10 @@ static void mds_kbdc_tree_print_indented(const mds_kbdc_tree_t* restrict this, F
* @param this The tree node
* @param output The output file
*/
-void mds_kbdc_tree_print(const mds_kbdc_tree_t* restrict this, FILE* output)
+void
+mds_kbdc_tree_print(const mds_kbdc_tree_t *restrict this, FILE *output)
{
- mds_kbdc_tree_print_indented(this, output, 0);
+ mds_kbdc_tree_print_indented(this, output, 0);
}
@@ -622,4 +680,3 @@ void mds_kbdc_tree_print(const mds_kbdc_tree_t* restrict this, FILE* output)
#undef NODE
#undef C
-
diff --git a/src/mds-kbdc/tree.h b/src/mds-kbdc/tree.h
index e9d28f4..392c85b 100644
--- a/src/mds-kbdc/tree.h
+++ b/src/mds-kbdc/tree.h
@@ -32,142 +32,142 @@
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_information_t`
*/
-#define MDS_KBDC_TREE_TYPE_INFORMATION 0
+#define MDS_KBDC_TREE_TYPE_INFORMATION 0
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_information_language_t`
*/
-#define MDS_KBDC_TREE_TYPE_INFORMATION_LANGUAGE 1
+#define MDS_KBDC_TREE_TYPE_INFORMATION_LANGUAGE 1
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_information_country_t`
*/
-#define MDS_KBDC_TREE_TYPE_INFORMATION_COUNTRY 2
+#define MDS_KBDC_TREE_TYPE_INFORMATION_COUNTRY 2
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_information_variant_t`
*/
-#define MDS_KBDC_TREE_TYPE_INFORMATION_VARIANT 3
+#define MDS_KBDC_TREE_TYPE_INFORMATION_VARIANT 3
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_include_t`
*/
-#define MDS_KBDC_TREE_TYPE_INCLUDE 4
+#define MDS_KBDC_TREE_TYPE_INCLUDE 4
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_function_t`
*/
-#define MDS_KBDC_TREE_TYPE_FUNCTION 5
+#define MDS_KBDC_TREE_TYPE_FUNCTION 5
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_macro_t`
*/
-#define MDS_KBDC_TREE_TYPE_MACRO 6
+#define MDS_KBDC_TREE_TYPE_MACRO 6
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_assumption`
*/
-#define MDS_KBDC_TREE_TYPE_ASSUMPTION 7
+#define MDS_KBDC_TREE_TYPE_ASSUMPTION 7
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_assumption_have_t`
*/
-#define MDS_KBDC_TREE_TYPE_ASSUMPTION_HAVE 8
+#define MDS_KBDC_TREE_TYPE_ASSUMPTION_HAVE 8
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_assumption_have_chars_t`
*/
-#define MDS_KBDC_TREE_TYPE_ASSUMPTION_HAVE_CHARS 9
+#define MDS_KBDC_TREE_TYPE_ASSUMPTION_HAVE_CHARS 9
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_assumption_have_range_t`
*/
-#define MDS_KBDC_TREE_TYPE_ASSUMPTION_HAVE_RANGE 10
+#define MDS_KBDC_TREE_TYPE_ASSUMPTION_HAVE_RANGE 10
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_for_t`
*/
-#define MDS_KBDC_TREE_TYPE_FOR 11
+#define MDS_KBDC_TREE_TYPE_FOR 11
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_if_t`
*/
-#define MDS_KBDC_TREE_TYPE_IF 12
+#define MDS_KBDC_TREE_TYPE_IF 12
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_let_t`
*/
-#define MDS_KBDC_TREE_TYPE_LET 13
+#define MDS_KBDC_TREE_TYPE_LET 13
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_map_t`
*/
-#define MDS_KBDC_TREE_TYPE_MAP 14
+#define MDS_KBDC_TREE_TYPE_MAP 14
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_array_t`
*/
-#define MDS_KBDC_TREE_TYPE_ARRAY 15
+#define MDS_KBDC_TREE_TYPE_ARRAY 15
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_keys_t`
*/
-#define MDS_KBDC_TREE_TYPE_KEYS 16
+#define MDS_KBDC_TREE_TYPE_KEYS 16
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_string_t`
*/
-#define MDS_KBDC_TREE_TYPE_STRING 17
+#define MDS_KBDC_TREE_TYPE_STRING 17
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_compiled_keys_t`
*/
-#define MDS_KBDC_TREE_TYPE_COMPILED_KEYS 18
+#define MDS_KBDC_TREE_TYPE_COMPILED_KEYS 18
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_compiled_string_t`
*/
-#define MDS_KBDC_TREE_TYPE_COMPILED_STRING 19
+#define MDS_KBDC_TREE_TYPE_COMPILED_STRING 19
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_nothing_t`
*/
-#define MDS_KBDC_TREE_TYPE_NOTHING 20
+#define MDS_KBDC_TREE_TYPE_NOTHING 20
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_alternation_t`
*/
-#define MDS_KBDC_TREE_TYPE_ALTERNATION 21
+#define MDS_KBDC_TREE_TYPE_ALTERNATION 21
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_unordered_t`
*/
-#define MDS_KBDC_TREE_TYPE_UNORDERED 22
+#define MDS_KBDC_TREE_TYPE_UNORDERED 22
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_ordered_t`
*/
-#define MDS_KBDC_TREE_TYPE_ORDERED 23
+#define MDS_KBDC_TREE_TYPE_ORDERED 23
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_macro_call_t`
*/
-#define MDS_KBDC_TREE_TYPE_MACRO_CALL 24
+#define MDS_KBDC_TREE_TYPE_MACRO_CALL 24
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_return_t`
*/
-#define MDS_KBDC_TREE_TYPE_RETURN 25
+#define MDS_KBDC_TREE_TYPE_RETURN 25
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_break_t`
*/
-#define MDS_KBDC_TREE_TYPE_BREAK 26
+#define MDS_KBDC_TREE_TYPE_BREAK 26
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_continue_t`
*/
-#define MDS_KBDC_TREE_TYPE_CONTINUE 27
+#define MDS_KBDC_TREE_TYPE_CONTINUE 27
@@ -196,13 +196,13 @@ typedef union mds_kbdc_tree mds_kbdc_tree_t;
* - size_t loc_end; -- The last byte in the source code where this is found, exclusive
* - long processed; -- The lasted step where the statement has already been processed once
*/
-#define MDS_KBDC_TREE_COMMON \
- int type; \
- mds_kbdc_tree_t* next; \
- size_t loc_line; \
- size_t loc_start; \
- size_t loc_end; \
- long processed
+#define MDS_KBDC_TREE_COMMON\
+ int type;\
+ mds_kbdc_tree_t *next;\
+ size_t loc_line;\
+ size_t loc_start;\
+ size_t loc_end;\
+ long processed
/**
* This macro is used in this header file, and is then
@@ -211,7 +211,7 @@ typedef union mds_kbdc_tree mds_kbdc_tree_t;
* @param S:size_t The size of the data structure excluding this padding and
* the members defined by the macro `MDS_KBDC_TREE_COMMON`
*/
-#define MDS_KBDC_TREE_PADDING_(S) char _padding[(5 * sizeof(void*) - (S)) / sizeof(char)]
+#define MDS_KBDC_TREE_PADDING_(S) char _padding[(5 * sizeof(void*) - (S)) / sizeof(char)]
/**
* This macro is used in this header file, and is then
@@ -221,7 +221,7 @@ typedef union mds_kbdc_tree mds_kbdc_tree_t;
* structure excluding this padding and the members defined
* by the macro `MDS_KBDC_TREE_COMMON`
*/
-#define MDS_KBDC_TREE_PADDING(N) MDS_KBDC_TREE_PADDING_((N) * sizeof(void*))
+#define MDS_KBDC_TREE_PADDING(N) MDS_KBDC_TREE_PADDING_((N) * sizeof(void*))
@@ -232,17 +232,16 @@ typedef union mds_kbdc_tree mds_kbdc_tree_t;
* the common members, a pointer to the first
* node on next level in the tree
*/
-struct mds_kbdc_tree_nesting
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The first child node, `.inner.next`
- * is used to access the second child node.
- */
- mds_kbdc_tree_t* inner;
-
- MDS_KBDC_TREE_PADDING(1);
+struct mds_kbdc_tree_nesting {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The first child node, `.inner.next`
+ * is used to access the second child node.
+ */
+ mds_kbdc_tree_t *inner;
+
+ MDS_KBDC_TREE_PADDING(1);
};
@@ -258,16 +257,15 @@ typedef struct mds_kbdc_tree_nesting mds_kbdc_tree_information_t;
* for the tree structurs for the information
* entries: the children of `mds_kbdc_tree_information_t`
*/
-struct mds_kbdc_tree_information_data
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The value of the information entry
- */
- char* data;
-
- MDS_KBDC_TREE_PADDING(1);
+struct mds_kbdc_tree_information_data {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The value of the information entry
+ */
+ char *data;
+
+ MDS_KBDC_TREE_PADDING(1);
};
@@ -290,27 +288,25 @@ typedef struct mds_kbdc_tree_information_data mds_kbdc_tree_information_variant_
/**
* Leaf structure for inclusion of a file
*/
-typedef struct mds_kbdc_tree_include
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The included layout code tree
- */
- mds_kbdc_tree_t* inner;
-
- /**
- * The filename of the file to include
- */
- char* filename;
-
- /**
- * The source code of the file included by this statement
- */
- mds_kbdc_source_code_t* source_code;
-
- MDS_KBDC_TREE_PADDING(3);
-
+typedef struct mds_kbdc_tree_include {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The included layout code tree
+ */
+ mds_kbdc_tree_t *inner;
+
+ /**
+ * The filename of the file to include
+ */
+ char *filename;
+
+ /**
+ * The source code of the file included by this statement
+ */
+ mds_kbdc_source_code_t* source_code;
+
+ MDS_KBDC_TREE_PADDING(3);
} mds_kbdc_tree_include_t;
@@ -320,28 +316,27 @@ typedef struct mds_kbdc_tree_include
* for tree structurs that define a callable
* element
*/
-struct mds_kbdc_tree_callable
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The first child node, `.inner.next`
- * is used to access the second child node
- */
- mds_kbdc_tree_t* inner;
-
- /* It is important that `.inner` is first because
- * it is first in `struct mds_kbdc_tree_nesting`
- * too which means that `.inner` has to same
- * offset everyever (except in `mds_kbdc_tree_if_t`).
- */
-
- /**
- * The name of the callable
- */
- char* name;
-
- MDS_KBDC_TREE_PADDING(2);
+struct mds_kbdc_tree_callable {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The first child node, `.inner.next`
+ * is used to access the second child node
+ */
+ mds_kbdc_tree_t *inner;
+
+ /* It is important that `.inner` is first because
+ * it is first in `struct mds_kbdc_tree_nesting`
+ * too which means that `.inner` has to same
+ * offset everyever (except in `mds_kbdc_tree_if_t`).
+ */
+
+ /**
+ * The name of the callable
+ */
+ char *name;
+
+ MDS_KBDC_TREE_PADDING(2);
};
@@ -366,17 +361,15 @@ typedef struct mds_kbdc_tree_nesting mds_kbdc_tree_assumption_t;
* Tree structure for making the assumption
* that there is a mapping to a key or string
*/
-typedef struct mds_kbdc_tree_assumption_have
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The key or string
- */
- mds_kbdc_tree_t* data;
-
- MDS_KBDC_TREE_PADDING(1);
-
+typedef struct mds_kbdc_tree_assumption_have {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The key or string
+ */
+ mds_kbdc_tree_t *data;
+
+ MDS_KBDC_TREE_PADDING(1);
} mds_kbdc_tree_assumption_have_t;
@@ -384,17 +377,15 @@ typedef struct mds_kbdc_tree_assumption_have
* Leaf structure for making the assumption
* that there are mappings to a set of characters
*/
-typedef struct mds_kbdc_tree_assumption_have_chars
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The characters
- */
- char* chars;
-
- MDS_KBDC_TREE_PADDING(1);
-
+typedef struct mds_kbdc_tree_assumption_have_chars {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The characters
+ */
+ char *chars;
+
+ MDS_KBDC_TREE_PADDING(1);
} mds_kbdc_tree_assumption_have_chars_t;
@@ -402,91 +393,85 @@ typedef struct mds_kbdc_tree_assumption_have_chars
* Leaf structure for making the assumption
* that there are mappings to a range of characters
*/
-typedef struct mds_kbdc_tree_assumption_have_range
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The first character, inclusive
- */
- char* first;
-
- /**
- * The last character, inclusive
- */
- char* last;
-
- MDS_KBDC_TREE_PADDING(2);
-
+typedef struct mds_kbdc_tree_assumption_have_range {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The first character, inclusive
+ */
+ char *first;
+
+ /**
+ * The last character, inclusive
+ */
+ char *last;
+
+ MDS_KBDC_TREE_PADDING(2);
} mds_kbdc_tree_assumption_have_range_t;
/**
* Tree structure for a "for"-loop
*/
-typedef struct mds_kbdc_tree_for
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The first child node, `.inner.next` is
- * used to access the second child node.
- * This is what should be done inside the loop.
- */
- mds_kbdc_tree_t* inner;
-
- /* It is important that `.inner` is first because
- * it is first in `struct mds_kbdc_tree_nesting`
- * too which means that `.inner` has to same
- * offset everyever (except in `mds_kbdc_tree_if_t`).
- */
-
- /**
- * The first value to variable should take, inclusive
- */
- char* first;
-
- /**
- * The last value the variable should take, inclusive
- */
- char* last;
-
- /**
- * The variable
- */
- char* variable;
-
- MDS_KBDC_TREE_PADDING(4);
-
+typedef struct mds_kbdc_tree_for {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The first child node, `.inner.next` is
+ * used to access the second child node.
+ * This is what should be done inside the loop.
+ */
+ mds_kbdc_tree_t *inner;
+
+ /* It is important that `.inner` is first because
+ * it is first in `struct mds_kbdc_tree_nesting`
+ * too which means that `.inner` has to same
+ * offset everyever (except in `mds_kbdc_tree_if_t`).
+ */
+
+ /**
+ * The first value to variable should take, inclusive
+ */
+ char *first;
+
+ /**
+ * The last value the variable should take, inclusive
+ */
+ char *last;
+
+ /**
+ * The variable
+ */
+ char *variable;
+
+ MDS_KBDC_TREE_PADDING(4);
} mds_kbdc_tree_for_t;
/**
* Tree structure for a "if"-statement
*/
-typedef struct mds_kbdc_tree_if
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The condition
- */
- char* condition;
-
- /**
- * This is what should be done inside
- * if the condition is satisfied
- */
- mds_kbdc_tree_t* inner;
-
- /**
- * This is what should be done inside
- * if the condition is not satisfied
- */
- mds_kbdc_tree_t* otherwise;
-
- MDS_KBDC_TREE_PADDING(3);
-
+typedef struct mds_kbdc_tree_if {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The condition
+ */
+ char *condition;
+
+ /**
+ * This is what should be done inside
+ * if the condition is satisfied
+ */
+ mds_kbdc_tree_t *inner;
+
+ /**
+ * This is what should be done inside
+ * if the condition is not satisfied
+ */
+ mds_kbdc_tree_t *otherwise;
+
+ MDS_KBDC_TREE_PADDING(3);
} mds_kbdc_tree_if_t;
@@ -494,22 +479,20 @@ typedef struct mds_kbdc_tree_if
* Tree structure for assigning a value to a variable,
* possibly declaring the variable in the process
*/
-typedef struct mds_kbdc_tree_let
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The variable
- */
- char* variable;
-
- /**
- * The value to assign to the variable
- */
- mds_kbdc_tree_t* value;
-
- MDS_KBDC_TREE_PADDING(2);
-
+typedef struct mds_kbdc_tree_let {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The variable
+ */
+ char *variable;
+
+ /**
+ * The value to assign to the variable
+ */
+ mds_kbdc_tree_t *value;
+
+ MDS_KBDC_TREE_PADDING(2);
} mds_kbdc_tree_let_t;
@@ -522,127 +505,115 @@ typedef struct mds_kbdc_tree_let
* in such case `sequence` should not be `NULL` but
* `sequence.next` and `result` should be `NULL`
*/
-typedef struct mds_kbdc_tree_map
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The input sequence
- */
- mds_kbdc_tree_t* sequence;
-
- /**
- * The output sequence
- */
- mds_kbdc_tree_t* result;
-
- /*
- * These are ordered so that `mds_kbdc_tree_t.macro_call.arguments`
- * and `mds_kbdc_tree_t.map.sequence` have the same address.
- */
-
- MDS_KBDC_TREE_PADDING(2);
-
+typedef struct mds_kbdc_tree_map {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The input sequence
+ */
+ mds_kbdc_tree_t *sequence;
+
+ /**
+ * The output sequence
+ */
+ mds_kbdc_tree_t *result;
+
+ /*
+ * These are ordered so that `mds_kbdc_tree_t.macro_call.arguments`
+ * and `mds_kbdc_tree_t.map.sequence` have the same address.
+ */
+
+ MDS_KBDC_TREE_PADDING(2);
} mds_kbdc_tree_map_t;
/**
* Tree structure for an array of values
*/
-typedef struct mds_kbdc_tree_array
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The first value, `.elements.next`
- * is used to access the second value.
- */
- mds_kbdc_tree_t* elements;
-
- MDS_KBDC_TREE_PADDING(1);
-
+typedef struct mds_kbdc_tree_array {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The first value, `.elements.next`
+ * is used to access the second value.
+ */
+ mds_kbdc_tree_t *elements;
+
+ MDS_KBDC_TREE_PADDING(1);
} mds_kbdc_tree_array_t;
/**
* Leaf structure for a key-combination
*/
-typedef struct mds_kbdc_tree_keys
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The key-combination
- */
- char* keys;
-
- MDS_KBDC_TREE_PADDING(1);
-
+typedef struct mds_kbdc_tree_keys {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The key-combination
+ */
+ char *keys;
+
+ MDS_KBDC_TREE_PADDING(1);
} mds_kbdc_tree_keys_t;
/**
* Leaf structure for a string
*/
-typedef struct mds_kbdc_tree_string
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The string
- */
- char* string;
-
- /*
- * `evaluate_element` in "compile-layout.c" utilises
- * that `mds_kbdc_tree_string.string` has the same
- * offset as `mds_kbdc_tree_keys.keys`.
- */
-
- MDS_KBDC_TREE_PADDING(1);
-
+typedef struct mds_kbdc_tree_string {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The string
+ */
+ char *string;
+
+ /*
+ * `evaluate_element` in "compile-layout.c" utilises
+ * that `mds_kbdc_tree_string.string` has the same
+ * offset as `mds_kbdc_tree_keys.keys`.
+ */
+
+ MDS_KBDC_TREE_PADDING(1);
} mds_kbdc_tree_string_t;
/**
* Leaf structure for a compiled key-combination
*/
-typedef struct mds_kbdc_tree_compiled_keys
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The key-combination
- *
- * Strictly terminated by -1
- */
- char32_t* keys;
-
- MDS_KBDC_TREE_PADDING(1);
-
+typedef struct mds_kbdc_tree_compiled_keys {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The key-combination
+ *
+ * Strictly terminated by -1
+ */
+ char32_t *keys;
+
+ MDS_KBDC_TREE_PADDING(1);
} mds_kbdc_tree_compiled_keys_t;
/**
* Leaf structure for a compiled string
*/
-typedef struct mds_kbdc_tree_compiled_string
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The string
- */
- char32_t* string;
-
- /*
- * `evaluate_element` in "compile-layout.c" utilises
- * that `mds_kbdc_tree_string.compiled_string` has the
- * same offset as `mds_kbdc_tree_keys.compiled_keys`.
- */
-
- MDS_KBDC_TREE_PADDING(1);
-
+typedef struct mds_kbdc_tree_compiled_string {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The string
+ */
+ char32_t *string;
+
+ /*
+ * `evaluate_element` in "compile-layout.c" utilises
+ * that `mds_kbdc_tree_string.compiled_string` has the
+ * same offset as `mds_kbdc_tree_keys.compiled_keys`.
+ */
+
+ MDS_KBDC_TREE_PADDING(1);
} mds_kbdc_tree_compiled_string_t;
@@ -652,11 +623,9 @@ typedef struct mds_kbdc_tree_compiled_string
* Other leaf structures without any content may `typedef`
* this structure
*/
-typedef struct mds_kbdc_tree_nothing
-{
- MDS_KBDC_TREE_COMMON;
- MDS_KBDC_TREE_PADDING(0);
-
+typedef struct mds_kbdc_tree_nothing {
+ MDS_KBDC_TREE_COMMON;
+ MDS_KBDC_TREE_PADDING(0);
} mds_kbdc_tree_nothing_t;
@@ -682,29 +651,27 @@ typedef struct mds_kbdc_tree_nesting mds_kbdc_tree_ordered_t;
/**
* Tree structure for a macro call
*/
-typedef struct mds_kbdc_tree_macro_call
-{
- MDS_KBDC_TREE_COMMON;
-
- /**
- * The first input argument for the
- * macro call, the second is accessed
- * using `.arguments.next`
- */
- mds_kbdc_tree_t* arguments;
-
- /**
- * The name of the macro
- */
- char* name;
-
- /*
- * These are ordered so that `mds_kbdc_tree_t.macro_call.arguments`
- * and `mds_kbdc_tree_t.map.sequence` have the same address.
- */
-
- MDS_KBDC_TREE_PADDING(2);
-
+typedef struct mds_kbdc_tree_macro_call {
+ MDS_KBDC_TREE_COMMON;
+
+ /**
+ * The first input argument for the
+ * macro call, the second is accessed
+ * using `.arguments.next`
+ */
+ mds_kbdc_tree_t *arguments;
+
+ /**
+ * The name of the macro
+ */
+ char *name;
+
+ /*
+ * These are ordered so that `mds_kbdc_tree_t.macro_call.arguments`
+ * and `mds_kbdc_tree_t.map.sequence` have the same address.
+ */
+
+ MDS_KBDC_TREE_PADDING(2);
} mds_kbdc_tree_macro_call_t;
@@ -728,45 +695,47 @@ typedef struct mds_kbdc_tree_nothing mds_kbdc_tree_continue_t;
/**
* Keyboard layout syntax tree
*/
-union mds_kbdc_tree
-{
+union mds_kbdc_tree {
+#if defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wpedantic" /* unnamed struct */
- struct
- {
- MDS_KBDC_TREE_COMMON;
- MDS_KBDC_TREE_PADDING(0);
- };
+#endif
+ struct {
+ MDS_KBDC_TREE_COMMON;
+ MDS_KBDC_TREE_PADDING(0);
+ };
+#if defined(__GNUC__)
# pragma GCC diagnostic pop
-
- mds_kbdc_tree_information_t information;
- mds_kbdc_tree_information_language_t language;
- mds_kbdc_tree_information_country_t country;
- mds_kbdc_tree_information_variant_t variant;
- mds_kbdc_tree_include_t include;
- mds_kbdc_tree_function_t function;
- mds_kbdc_tree_macro_t macro;
- mds_kbdc_tree_assumption_t assumption;
- mds_kbdc_tree_assumption_have_t have;
- mds_kbdc_tree_assumption_have_chars_t have_chars;
- mds_kbdc_tree_assumption_have_range_t have_range;
- mds_kbdc_tree_for_t for_;
- mds_kbdc_tree_if_t if_;
- mds_kbdc_tree_let_t let;
- mds_kbdc_tree_map_t map;
- mds_kbdc_tree_array_t array;
- mds_kbdc_tree_keys_t keys;
- mds_kbdc_tree_string_t string;
- mds_kbdc_tree_compiled_keys_t compiled_keys;
- mds_kbdc_tree_compiled_string_t compiled_string;
- mds_kbdc_tree_nothing_t nothing;
- mds_kbdc_tree_alternation_t alternation;
- mds_kbdc_tree_unordered_t unordered;
- mds_kbdc_tree_ordered_t ordered;
- mds_kbdc_tree_macro_call_t macro_call;
- mds_kbdc_tree_return_t return_;
- mds_kbdc_tree_break_t break_;
- mds_kbdc_tree_continue_t continue_;
+#endif
+
+ mds_kbdc_tree_information_t information;
+ mds_kbdc_tree_information_language_t language;
+ mds_kbdc_tree_information_country_t country;
+ mds_kbdc_tree_information_variant_t variant;
+ mds_kbdc_tree_include_t include;
+ mds_kbdc_tree_function_t function;
+ mds_kbdc_tree_macro_t macro;
+ mds_kbdc_tree_assumption_t assumption;
+ mds_kbdc_tree_assumption_have_t have;
+ mds_kbdc_tree_assumption_have_chars_t have_chars;
+ mds_kbdc_tree_assumption_have_range_t have_range;
+ mds_kbdc_tree_for_t for_;
+ mds_kbdc_tree_if_t if_;
+ mds_kbdc_tree_let_t let;
+ mds_kbdc_tree_map_t map;
+ mds_kbdc_tree_array_t array;
+ mds_kbdc_tree_keys_t keys;
+ mds_kbdc_tree_string_t string;
+ mds_kbdc_tree_compiled_keys_t compiled_keys;
+ mds_kbdc_tree_compiled_string_t compiled_string;
+ mds_kbdc_tree_nothing_t nothing;
+ mds_kbdc_tree_alternation_t alternation;
+ mds_kbdc_tree_unordered_t unordered;
+ mds_kbdc_tree_ordered_t ordered;
+ mds_kbdc_tree_macro_call_t macro_call;
+ mds_kbdc_tree_return_t return_;
+ mds_kbdc_tree_break_t break_;
+ mds_kbdc_tree_continue_t continue_;
};
@@ -777,7 +746,7 @@ union mds_kbdc_tree
* @param this The memory slot for the tree node
* @param type The type of the node
*/
-void mds_kbdc_tree_initialise(mds_kbdc_tree_t* restrict this, int type);
+void mds_kbdc_tree_initialise(mds_kbdc_tree_t *restrict this, int type);
/**
* Create a tree node
@@ -785,7 +754,7 @@ void mds_kbdc_tree_initialise(mds_kbdc_tree_t* restrict this, int type);
* @param type The type of the node
* @return The tree node, `NULL` on error
*/
-mds_kbdc_tree_t* mds_kbdc_tree_create(int type);
+mds_kbdc_tree_t *mds_kbdc_tree_create(int type);
/**
* Release all resources stored in a tree node,
@@ -794,7 +763,7 @@ mds_kbdc_tree_t* mds_kbdc_tree_create(int type);
*
* @param this The tree node
*/
-void mds_kbdc_tree_destroy_nonrecursive(mds_kbdc_tree_t* restrict this);
+void mds_kbdc_tree_destroy_nonrecursive(mds_kbdc_tree_t *restrict this);
/**
* Release all resources stored in a tree node,
@@ -804,7 +773,7 @@ void mds_kbdc_tree_destroy_nonrecursive(mds_kbdc_tree_t* restrict this);
*
* @param this The tree node
*/
-void mds_kbdc_tree_free_nonrecursive(mds_kbdc_tree_t* restrict this);
+void mds_kbdc_tree_free_nonrecursive(mds_kbdc_tree_t *restrict this);
/**
* Release all resources stored in a tree node
@@ -813,7 +782,7 @@ void mds_kbdc_tree_free_nonrecursive(mds_kbdc_tree_t* restrict this);
*
* @param this The tree node
*/
-void mds_kbdc_tree_destroy(mds_kbdc_tree_t* restrict this);
+void mds_kbdc_tree_destroy(mds_kbdc_tree_t *restrict this);
/**
* Release all resources stored in a tree node
@@ -822,7 +791,7 @@ void mds_kbdc_tree_destroy(mds_kbdc_tree_t* restrict this);
*
* @param this The tree node
*/
-void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this);
+void mds_kbdc_tree_free(mds_kbdc_tree_t *restrict this);
/**
@@ -832,7 +801,7 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this);
* @param this The tree node
* @return A duplicate of `this`, `NULL` on error
*/
-mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this);
+mds_kbdc_tree_t *mds_kbdc_tree_dup(const mds_kbdc_tree_t *restrict this);
/**
@@ -841,7 +810,7 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this);
* @param this The tree node
* @param output The output file
*/
-void mds_kbdc_tree_print(const mds_kbdc_tree_t* restrict this, FILE* output);
+void mds_kbdc_tree_print(const mds_kbdc_tree_t *restrict this, FILE *output);
@@ -850,4 +819,3 @@ void mds_kbdc_tree_print(const mds_kbdc_tree_t* restrict this, FILE* output);
#undef MDS_KBDC_TREE_COMMON
#endif
-
diff --git a/src/mds-kbdc/validate-tree.c b/src/mds-kbdc/validate-tree.c
index 632b9a8..80ef7d5 100644
--- a/src/mds-kbdc/validate-tree.c
+++ b/src/mds-kbdc/validate-tree.c
@@ -28,12 +28,12 @@
/**
* Tree type constant shortener
*/
-#define C(TYPE) MDS_KBDC_TREE_TYPE_##TYPE
+#define C(TYPE) MDS_KBDC_TREE_TYPE_##TYPE
/**
* Check the value of `innermost_visit`
*/
-#define VISITING(TYPE) (innermost_visit == MDS_KBDC_TREE_TYPE_##TYPE)
+#define VISITING(TYPE) (innermost_visit == MDS_KBDC_TREE_TYPE_##TYPE)
/**
* Add an error with “included from here”-notes to the error list
@@ -44,20 +44,20 @@
* @param ...:const char*, ... Error description format string and arguments
* @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
*/
-#define NEW_ERROR(NODE, PTR, SEVERITY, ...) \
- NEW_ERROR_WITH_INCLUDES(NODE, PTR, SEVERITY, __VA_ARGS__)
+#define NEW_ERROR(NODE, PTR, SEVERITY, ...)\
+ NEW_ERROR_WITH_INCLUDES(NODE, PTR, SEVERITY, __VA_ARGS__)
/**
* Variable whether the latest created error is stored
*/
-static mds_kbdc_parse_error_t* error;
+static mds_kbdc_parse_error_t *error;
/**
* The parameter of `validate_tree`
*/
-static mds_kbdc_parsed_t* restrict result;
+static mds_kbdc_parsed_t *restrict result;
/**
* The number visited for-statements
@@ -67,22 +67,22 @@ static size_t fors = 0;
/**
* The function definition that is currently being visited
*/
-static mds_kbdc_tree_function_t* function = NULL;
+static mds_kbdc_tree_function_t *function = NULL;
/**
* The macro definition that is currently being visited
*/
-static mds_kbdc_tree_macro_t* macro = NULL;
+static mds_kbdc_tree_macro_t *macro = NULL;
/**
* The information clause that is currently being visited
*/
-static mds_kbdc_tree_information_t* information = NULL;
+static mds_kbdc_tree_information_t *information = NULL;
/**
* The assumption clause that is currently being visited
*/
-static mds_kbdc_tree_assumption_t* assumption = NULL;
+static mds_kbdc_tree_assumption_t *assumption = NULL;
/**
* The value `includes_ptr` had when `function`,
@@ -105,7 +105,7 @@ static int innermost_visit = -1;
* @param tree The tree to validate
* @return Zero on success, -1 on error
*/
-static int validate_subtree(mds_kbdc_tree_t* restrict tree);
+static int validate_subtree(mds_kbdc_tree_t *restrict tree);
@@ -115,17 +115,18 @@ static int validate_subtree(mds_kbdc_tree_t* restrict tree);
* @param tree The tree to validate
* @return Zero on success, -1 on error
*/
-static int validate_include(mds_kbdc_tree_include_t* restrict tree)
+static int
+validate_include(mds_kbdc_tree_include_t *restrict tree)
{
- void* data;
- int r;
- fail_if (mds_kbdc_include_stack_push(tree, &data));
- r = validate_subtree(tree->inner);
- mds_kbdc_include_stack_pop(data);
- fail_if (r);
- return 0;
- fail:
- return -1;
+ void *data;
+ int r;
+ fail_if (mds_kbdc_include_stack_push(tree, &data));
+ r = validate_subtree(tree->inner);
+ mds_kbdc_include_stack_pop(data);
+ fail_if (r);
+ return 0;
+fail:
+ return -1;
}
@@ -135,34 +136,30 @@ static int validate_include(mds_kbdc_tree_include_t* restrict tree)
* @param tree The tree to validate
* @return Zero on success, -1 on error
*/
-static int validate_function(mds_kbdc_tree_function_t* restrict tree)
+static int
+validate_function(mds_kbdc_tree_function_t *restrict tree)
{
- int r;
- if (VISITING(FUNCTION))
- {
- NEW_ERROR(tree, includes_ptr, ERROR, "nested function definition");
- NEW_ERROR(function, def_includes_ptr, NOTE, "outer function defined here");
- return 0;
- }
- else if (VISITING(MACRO))
- {
- NEW_ERROR(tree, includes_ptr, ERROR, "function definition inside macro definition");
- NEW_ERROR(macro, def_includes_ptr, NOTE, "outer macro defined here");
- return 0;
- }
- else if (VISITING(INFORMATION))
- {
- NEW_ERROR(tree, includes_ptr, ERROR, "function definition inside information clause");
- NEW_ERROR(information, def_includes_ptr, NOTE, "outer information clause defined here");
- return 0;
- }
- innermost_visit = tree->type;
- function = tree;
- def_includes_ptr = includes_ptr;
- r = validate_subtree(tree->inner);
- return function = NULL, r;
- fail:
- return -1;
+ int r;
+ if (VISITING(FUNCTION)) {
+ NEW_ERROR(tree, includes_ptr, ERROR, "nested function definition");
+ NEW_ERROR(function, def_includes_ptr, NOTE, "outer function defined here");
+ return 0;
+ } else if (VISITING(MACRO)) {
+ NEW_ERROR(tree, includes_ptr, ERROR, "function definition inside macro definition");
+ NEW_ERROR(macro, def_includes_ptr, NOTE, "outer macro defined here");
+ return 0;
+ } else if (VISITING(INFORMATION)) {
+ NEW_ERROR(tree, includes_ptr, ERROR, "function definition inside information clause");
+ NEW_ERROR(information, def_includes_ptr, NOTE, "outer information clause defined here");
+ return 0;
+ }
+ innermost_visit = tree->type;
+ function = tree;
+ def_includes_ptr = includes_ptr;
+ r = validate_subtree(tree->inner);
+ return function = NULL, r;
+fail:
+ return -1;
}
@@ -172,34 +169,30 @@ static int validate_function(mds_kbdc_tree_function_t* restrict tree)
* @param tree The tree to validate
* @return Zero on success, -1 on error
*/
-static int validate_macro(mds_kbdc_tree_macro_t* restrict tree)
+static int
+validate_macro(mds_kbdc_tree_macro_t *restrict tree)
{
- int r;
- if (VISITING(FUNCTION))
- {
- NEW_ERROR(tree, includes_ptr, ERROR, "macro definition inside function definition");
- NEW_ERROR(function, def_includes_ptr, NOTE, "outer function definition defined here");
- return 0;
- }
- else if (VISITING(MACRO))
- {
- NEW_ERROR(tree, includes_ptr, ERROR, "nested macro definition");
- NEW_ERROR(macro, def_includes_ptr, NOTE, "outer macro defined here");
- return 0;
- }
- else if (VISITING(INFORMATION))
- {
- NEW_ERROR(tree, includes_ptr, ERROR, "macro definition inside information clause");
- NEW_ERROR(information, def_includes_ptr, NOTE, "outer information clause defined here");
- return 0;
- }
- innermost_visit = tree->type;
- macro = tree;
- def_includes_ptr = includes_ptr;
- r = validate_subtree(tree->inner);
- return macro = NULL, r;
- fail:
- return -1;
+ int r;
+ if (VISITING(FUNCTION)) {
+ NEW_ERROR(tree, includes_ptr, ERROR, "macro definition inside function definition");
+ NEW_ERROR(function, def_includes_ptr, NOTE, "outer function definition defined here");
+ return 0;
+ } else if (VISITING(MACRO)) {
+ NEW_ERROR(tree, includes_ptr, ERROR, "nested macro definition");
+ NEW_ERROR(macro, def_includes_ptr, NOTE, "outer macro defined here");
+ return 0;
+ } else if (VISITING(INFORMATION)) {
+ NEW_ERROR(tree, includes_ptr, ERROR, "macro definition inside information clause");
+ NEW_ERROR(information, def_includes_ptr, NOTE, "outer information clause defined here");
+ return 0;
+ }
+ innermost_visit = tree->type;
+ macro = tree;
+ def_includes_ptr = includes_ptr;
+ r = validate_subtree(tree->inner);
+ return macro = NULL, r;
+fail:
+ return -1;
}
@@ -209,40 +202,34 @@ static int validate_macro(mds_kbdc_tree_macro_t* restrict tree)
* @param tree The tree to validate
* @return Zero on success, -1 on error
*/
-static int validate_information(mds_kbdc_tree_information_t* restrict tree)
+static int
+validate_information(mds_kbdc_tree_information_t *restrict tree)
{
- int r;
- if (VISITING(FUNCTION))
- {
- NEW_ERROR(tree, includes_ptr, ERROR, "information clause inside function definition");
- NEW_ERROR(function, def_includes_ptr, NOTE, "outer function definition defined here");
- return 0;
- }
- else if (VISITING(MACRO))
- {
- NEW_ERROR(tree, includes_ptr, ERROR, "information clause inside macro definition");
- NEW_ERROR(macro, def_includes_ptr, NOTE, "outer macro defined here");
- return 0;
- }
- else if (VISITING(INFORMATION))
- {
- NEW_ERROR(tree, includes_ptr, ERROR, "nested information clause");
- NEW_ERROR(information, def_includes_ptr, NOTE, "outer information clause defined here");
- return 0;
- }
- else if (VISITING(ASSUMPTION))
- {
- NEW_ERROR(tree, includes_ptr, ERROR, "information clause inside assumption clause");
- NEW_ERROR(assumption, def_includes_ptr, NOTE, "outer assumption clause defined here");
- return 0;
- }
- innermost_visit = tree->type;
- information = tree;
- def_includes_ptr = includes_ptr;
- r = validate_subtree(tree->inner);
- return information = NULL, r;
- fail:
- return -1;
+ int r;
+ if (VISITING(FUNCTION)) {
+ NEW_ERROR(tree, includes_ptr, ERROR, "information clause inside function definition");
+ NEW_ERROR(function, def_includes_ptr, NOTE, "outer function definition defined here");
+ return 0;
+ } else if (VISITING(MACRO)) {
+ NEW_ERROR(tree, includes_ptr, ERROR, "information clause inside macro definition");
+ NEW_ERROR(macro, def_includes_ptr, NOTE, "outer macro defined here");
+ return 0;
+ } else if (VISITING(INFORMATION)) {
+ NEW_ERROR(tree, includes_ptr, ERROR, "nested information clause");
+ NEW_ERROR(information, def_includes_ptr, NOTE, "outer information clause defined here");
+ return 0;
+ } else if (VISITING(ASSUMPTION)) {
+ NEW_ERROR(tree, includes_ptr, ERROR, "information clause inside assumption clause");
+ NEW_ERROR(assumption, def_includes_ptr, NOTE, "outer assumption clause defined here");
+ return 0;
+ }
+ innermost_visit = tree->type;
+ information = tree;
+ def_includes_ptr = includes_ptr;
+ r = validate_subtree(tree->inner);
+ return information = NULL, r;
+fail:
+ return -1;
}
@@ -252,40 +239,34 @@ static int validate_information(mds_kbdc_tree_information_t* restrict tree)
* @param tree The tree to validate
* @return Zero on success, -1 on error
*/
-static int validate_assumption(mds_kbdc_tree_assumption_t* restrict tree)
+static int
+validate_assumption(mds_kbdc_tree_assumption_t *restrict tree)
{
- int r;
- if (VISITING(FUNCTION))
- {
- NEW_ERROR(tree, includes_ptr, ERROR, "assumption clause inside function definition");
- NEW_ERROR(function, def_includes_ptr, NOTE, "outer function definition defined here");
- return 0;
- }
- else if (VISITING(MACRO))
- {
- NEW_ERROR(tree, includes_ptr, ERROR, "assumption clause inside macro definition");
- NEW_ERROR(macro, def_includes_ptr, NOTE, "outer macro defined here");
- return 0;
- }
- else if (VISITING(INFORMATION))
- {
- NEW_ERROR(tree, includes_ptr, ERROR, "assumption clause inside information clause");
- NEW_ERROR(information, def_includes_ptr, NOTE, "outer information clause defined here");
- return 0;
- }
- else if (VISITING(ASSUMPTION))
- {
- NEW_ERROR(tree, includes_ptr, ERROR, "nested assumption clause");
- NEW_ERROR(assumption, def_includes_ptr, NOTE, "outer assumption clause defined here");
- return 0;
- }
- innermost_visit = tree->type;
- assumption = tree;
- def_includes_ptr = includes_ptr;
- r = validate_subtree(tree->inner);
- return assumption = NULL, r;
- fail:
- return -1;
+ int r;
+ if (VISITING(FUNCTION)) {
+ NEW_ERROR(tree, includes_ptr, ERROR, "assumption clause inside function definition");
+ NEW_ERROR(function, def_includes_ptr, NOTE, "outer function definition defined here");
+ return 0;
+ } else if (VISITING(MACRO)) {
+ NEW_ERROR(tree, includes_ptr, ERROR, "assumption clause inside macro definition");
+ NEW_ERROR(macro, def_includes_ptr, NOTE, "outer macro defined here");
+ return 0;
+ } else if (VISITING(INFORMATION)) {
+ NEW_ERROR(tree, includes_ptr, ERROR, "assumption clause inside information clause");
+ NEW_ERROR(information, def_includes_ptr, NOTE, "outer information clause defined here");
+ return 0;
+ } else if (VISITING(ASSUMPTION)) {
+ NEW_ERROR(tree, includes_ptr, ERROR, "nested assumption clause");
+ NEW_ERROR(assumption, def_includes_ptr, NOTE, "outer assumption clause defined here");
+ return 0;
+ }
+ innermost_visit = tree->type;
+ assumption = tree;
+ def_includes_ptr = includes_ptr;
+ r = validate_subtree(tree->inner);
+ return assumption = NULL, r;
+fail:
+ return -1;
}
@@ -295,25 +276,26 @@ static int validate_assumption(mds_kbdc_tree_assumption_t* restrict tree)
* @param tree The tree to validate
* @return Zero on success, -1 on error
*/
-static int validate_map(mds_kbdc_tree_map_t* restrict tree)
+static int
+validate_map(mds_kbdc_tree_map_t *restrict tree)
{
- int is_value = tree->result == NULL;
- if (is_value);
- /* We do not want value-statments outside function
- * definitions, however, we do want \set/3 to be usable,
- * from anywhere, even indirectly, therefore we cannot,
- * at this process level, determine whether a
- * value-statement is used correctly or not.
- */
- else if (VISITING(INFORMATION))
- NEW_ERROR(tree, includes_ptr, ERROR, "mapping-statement inside information clause");
- else if (VISITING(ASSUMPTION))
- NEW_ERROR(tree, includes_ptr, ERROR, "mapping-statement inside assumption clause");
- else if (VISITING(FUNCTION))
- NEW_ERROR(tree, includes_ptr, ERROR, "mapping-statement inside function definition");
- return 0;
+ int is_value = tree->result == NULL;
+ if (is_value)
+ /* We do not want value-statments outside function
+ * definitions, however, we do want \set/3 to be usable,
+ * from anywhere, even indirectly, therefore we cannot,
+ * at this process level, determine whether a
+ * value-statement is used correctly or not.
+ */;
+ else if (VISITING(INFORMATION))
+ NEW_ERROR(tree, includes_ptr, ERROR, "mapping-statement inside information clause");
+ else if (VISITING(ASSUMPTION))
+ NEW_ERROR(tree, includes_ptr, ERROR, "mapping-statement inside assumption clause");
+ else if (VISITING(FUNCTION))
+ NEW_ERROR(tree, includes_ptr, ERROR, "mapping-statement inside function definition");
+ return 0;
fail:
- return -1;
+ return -1;
}
@@ -323,17 +305,18 @@ static int validate_map(mds_kbdc_tree_map_t* restrict tree)
* @param tree The tree to validate
* @return Zero on success, -1 on error
*/
-static int validate_macro_call(mds_kbdc_tree_macro_call_t* restrict tree)
+static int
+validate_macro_call(mds_kbdc_tree_macro_call_t *restrict tree)
{
- if (VISITING(INFORMATION))
- NEW_ERROR(tree, includes_ptr, ERROR, "macro call inside information clause");
- else if (VISITING(ASSUMPTION))
- NEW_ERROR(tree, includes_ptr, ERROR, "macro call inside assumption clause");
- else if (VISITING(FUNCTION))
- NEW_ERROR(tree, includes_ptr, ERROR, "macro call inside function definition");
- return 0;
- fail:
- return -1;
+ if (VISITING(INFORMATION))
+ NEW_ERROR(tree, includes_ptr, ERROR, "macro call inside information clause");
+ else if (VISITING(ASSUMPTION))
+ NEW_ERROR(tree, includes_ptr, ERROR, "macro call inside assumption clause");
+ else if (VISITING(FUNCTION))
+ NEW_ERROR(tree, includes_ptr, ERROR, "macro call inside function definition");
+ return 0;
+fail:
+ return -1;
}
@@ -343,14 +326,15 @@ static int validate_macro_call(mds_kbdc_tree_macro_call_t* restrict tree)
* @param tree The tree to validate
* @return Zero on success, -1 on error
*/
-static int validate_for(mds_kbdc_tree_for_t* restrict tree)
+static int
+validate_for(mds_kbdc_tree_for_t *restrict tree)
{
- int r;
- fors++, r = validate_subtree(tree->inner), fors--;
- fail_if (r);
- return 0;
- fail:
- return -1;
+ int r;
+ fors++, r = validate_subtree(tree->inner), fors--;
+ fail_if (r);
+ return 0;
+fail:
+ return -1;
}
@@ -360,12 +344,13 @@ static int validate_for(mds_kbdc_tree_for_t* restrict tree)
* @param tree The tree to validate
* @return Zero on success, -1 on error
*/
-static int validate_if(mds_kbdc_tree_if_t* restrict tree)
+static int
+validate_if(mds_kbdc_tree_if_t *restrict tree)
{
- fail_if ((validate_subtree(tree->inner) || validate_subtree(tree->otherwise)));
- return 0;
- fail:
- return -1;
+ fail_if ((validate_subtree(tree->inner) || validate_subtree(tree->otherwise)));
+ return 0;
+fail:
+ return -1;
}
@@ -375,13 +360,14 @@ static int validate_if(mds_kbdc_tree_if_t* restrict tree)
* @param tree The tree to validate
* @return Zero on success, -1 on error
*/
-static int validate_return(mds_kbdc_tree_return_t* restrict tree)
+static int
+validate_return(mds_kbdc_tree_return_t *restrict tree)
{
- if ((function == NULL) && (macro == NULL))
- NEW_ERROR(tree, includes_ptr, ERROR, "‘return’ outside function and macro definition");
- return 0;
- fail:
- return -1;
+ if (!function && !macro)
+ NEW_ERROR(tree, includes_ptr, ERROR, "‘return’ outside function and macro definition");
+ return 0;
+fail:
+ return -1;
}
@@ -391,13 +377,14 @@ static int validate_return(mds_kbdc_tree_return_t* restrict tree)
* @param tree The tree to validate
* @return Zero on success, -1 on error
*/
-static int validate_break(mds_kbdc_tree_break_t* restrict tree)
+static int
+validate_break(mds_kbdc_tree_break_t *restrict tree)
{
- if (fors == 0)
- NEW_ERROR(tree, includes_ptr, ERROR, "‘break’ outside ‘for’");
- return 0;
- fail:
- return -1;
+ if (!fors)
+ NEW_ERROR(tree, includes_ptr, ERROR, "‘break’ outside ‘for’");
+ return 0;
+fail:
+ return -1;
}
@@ -407,13 +394,14 @@ static int validate_break(mds_kbdc_tree_break_t* restrict tree)
* @param tree The tree to validate
* @return Zero on success, -1 on error
*/
-static int validate_continue(mds_kbdc_tree_continue_t* restrict tree)
+static int
+validate_continue(mds_kbdc_tree_continue_t *restrict tree)
{
- if (fors == 0)
- NEW_ERROR(tree, includes_ptr, ERROR, "‘continue’ outside ‘for’");
- return 0;
- fail:
- return -1;
+ if (!fors)
+ NEW_ERROR(tree, includes_ptr, ERROR, "‘continue’ outside ‘for’");
+ return 0;
+fail:
+ return -1;
}
@@ -423,13 +411,14 @@ static int validate_continue(mds_kbdc_tree_continue_t* restrict tree)
* @param tree The tree to validate
* @return Zero on success, -1 on error
*/
-static int validate_assumption_data(mds_kbdc_tree_t* restrict tree)
+static int
+validate_assumption_data(mds_kbdc_tree_t *restrict tree)
{
- if (assumption == NULL)
- NEW_ERROR(tree, includes_ptr, ERROR, "assumption outside assumption clause");
- return 0;
- fail:
- return -1;
+ if (!assumption)
+ NEW_ERROR(tree, includes_ptr, ERROR, "assumption outside assumption clause");
+ return 0;
+fail:
+ return -1;
}
@@ -439,13 +428,14 @@ static int validate_assumption_data(mds_kbdc_tree_t* restrict tree)
* @param tree The tree to validate
* @return Zero on success, -1 on error
*/
-static int validate_information_data(mds_kbdc_tree_t* restrict tree)
+static int
+validate_information_data(mds_kbdc_tree_t *restrict tree)
{
- if (information == NULL)
- NEW_ERROR(tree, includes_ptr, ERROR, "information outside information clause");
- return 0;
- fail:
- return -1;
+ if (!information)
+ NEW_ERROR(tree, includes_ptr, ERROR, "information outside information clause");
+ return 0;
+fail:
+ return -1;
}
@@ -455,48 +445,48 @@ static int validate_information_data(mds_kbdc_tree_t* restrict tree)
* @param tree The tree to validate
* @return Zero on success, -1 on error
*/
-static int validate_subtree(mds_kbdc_tree_t* restrict tree)
+static int
+validate_subtree(mds_kbdc_tree_t *restrict tree)
{
-#define v(type) fail_if (validate_##type(&(tree->type)))
-#define V(type) fail_if (validate_##type(&(tree->type##_)))
- int old_innermost_visit = innermost_visit;
- again:
- if (tree == NULL)
- return 0;
-
- switch (tree->type)
- {
- case C(INFORMATION): v(information); break;
- case C(INCLUDE): v(include); break;
- case C(FUNCTION): v(function); break;
- case C(MACRO): v(macro); break;
- case C(ASSUMPTION): v(assumption); break;
- case C(FOR): V(for); break;
- case C(IF): V(if); break;
- case C(MAP): v(map); break;
- case C(MACRO_CALL): v(macro_call); break;
- case C(RETURN): V(return); break;
- case C(BREAK): V(break); break;
- case C(CONTINUE): V(continue); break;
- case C(INFORMATION_LANGUAGE):
- case C(INFORMATION_COUNTRY):
- case C(INFORMATION_VARIANT):
- fail_if (validate_information_data(tree));
- break;
- case C(ASSUMPTION_HAVE):
- case C(ASSUMPTION_HAVE_CHARS):
- case C(ASSUMPTION_HAVE_RANGE):
- fail_if (validate_assumption_data(tree));
- break;
- default:
- break;
- }
-
- innermost_visit = old_innermost_visit;
- tree = tree->next;
- goto again;
- fail:
- return innermost_visit = old_innermost_visit, -1;
+#define v(type) fail_if (validate_##type(&(tree->type)))
+#define V(type) fail_if (validate_##type(&(tree->type##_)))
+ int old_innermost_visit = innermost_visit;
+again:
+ if (!tree)
+ return 0;
+
+ switch (tree->type) {
+ case C(INFORMATION): v(information); break;
+ case C(INCLUDE): v(include); break;
+ case C(FUNCTION): v(function); break;
+ case C(MACRO): v(macro); break;
+ case C(ASSUMPTION): v(assumption); break;
+ case C(FOR): V(for); break;
+ case C(IF): V(if); break;
+ case C(MAP): v(map); break;
+ case C(MACRO_CALL): v(macro_call); break;
+ case C(RETURN): V(return); break;
+ case C(BREAK): V(break); break;
+ case C(CONTINUE): V(continue); break;
+ case C(INFORMATION_LANGUAGE):
+ case C(INFORMATION_COUNTRY):
+ case C(INFORMATION_VARIANT):
+ fail_if (validate_information_data(tree));
+ break;
+ case C(ASSUMPTION_HAVE):
+ case C(ASSUMPTION_HAVE_CHARS):
+ case C(ASSUMPTION_HAVE_RANGE):
+ fail_if (validate_assumption_data(tree));
+ break;
+ default:
+ break;
+ }
+
+ innermost_visit = old_innermost_visit;
+ tree = tree->next;
+ goto again;
+fail:
+ return innermost_visit = old_innermost_visit, -1;
#undef V
#undef v
}
@@ -508,17 +498,18 @@ static int validate_subtree(mds_kbdc_tree_t* restrict tree)
* @param result_ `result` from `process_includes`, will be updated
* @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
*/
-int validate_tree(mds_kbdc_parsed_t* restrict result_)
+int
+validate_tree(mds_kbdc_parsed_t *restrict result_)
{
- int r;
- mds_kbdc_include_stack_begin(result = result_);
- r = validate_subtree(result_->tree);
- fors = 0;
- mds_kbdc_include_stack_end();
- fail_if (r);
- return 0;
- fail:
- return -1;
+ int r;
+ mds_kbdc_include_stack_begin(result = result_);
+ r = validate_subtree(result_->tree);
+ fors = 0;
+ mds_kbdc_include_stack_end();
+ fail_if (r);
+ return 0;
+fail:
+ return -1;
}
@@ -526,4 +517,3 @@ int validate_tree(mds_kbdc_parsed_t* restrict result_)
#undef NEW_ERROR
#undef VISITING
#undef C
-
diff --git a/src/mds-kbdc/validate-tree.h b/src/mds-kbdc/validate-tree.h
index e32b2f2..5ca9277 100644
--- a/src/mds-kbdc/validate-tree.h
+++ b/src/mds-kbdc/validate-tree.h
@@ -28,8 +28,7 @@
* @param result `result` from `process_includes`, will be updated
* @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
*/
-int validate_tree(mds_kbdc_parsed_t* restrict result);
+int validate_tree(mds_kbdc_parsed_t *restrict result);
#endif
-
diff --git a/src/mds-kbdc/variables.c b/src/mds-kbdc/variables.c
index 3b2e128..15a1cb6 100644
--- a/src/mds-kbdc/variables.c
+++ b/src/mds-kbdc/variables.c
@@ -27,32 +27,30 @@
/**
* The state of a variable
*/
-typedef struct variable
-{
- /**
- * The current value of the variable
- */
- mds_kbdc_tree_t* value;
-
- /**
- * The previous version of variable,
- * before it was shadowed
- */
- struct variable* restrict previous;
-
- /**
- * The original scope in which the current
- * shadow of the variable was created
- */
- size_t scope;
-
- /**
- * The latest scope the in which the
- * variable has been used in a for-loop,
- * `~0' if never, or below `scope`
- */
- size_t used_in_for;
-
+typedef struct variable {
+ /**
+ * The current value of the variable
+ */
+ mds_kbdc_tree_t *value;
+
+ /**
+ * The previous version of variable,
+ * before it was shadowed
+ */
+ struct variable *restrict previous;
+
+ /**
+ * The original scope in which the current
+ * shadow of the variable was created
+ */
+ size_t scope;
+
+ /**
+ * The latest scope the in which the
+ * variable has been used in a for-loop,
+ * `~0' if never, or below `scope`
+ */
+ size_t used_in_for;
} variable_t;
@@ -60,7 +58,7 @@ typedef struct variable
/**
* Map (by index) of defined variables
*/
-static variable_t** restrict variables = NULL;
+static variable_t **restrict variables = NULL;
/**
* The size of `variables`
@@ -79,20 +77,21 @@ static size_t current_scope = 0;
/**
* Destroy the variable storage
*/
-void variables_terminate(void)
+void
+variables_terminate(void)
{
- size_t i;
- variable_t* old;
- for (i = 0; i < variable_count; i++)
- while (variables[i])
- {
- old = variables[i];
- variables[i] = variables[i]->previous;
- mds_kbdc_tree_free(old->value);
- free(old);
- }
- free(variables), variables = NULL;
- variable_count = current_scope = 0;
+ size_t i;
+ variable_t *old;
+ for (i = 0; i < variable_count; i++) {
+ while (variables[i]) {
+ old = variables[i];
+ variables[i] = variables[i]->previous;
+ mds_kbdc_tree_free(old->value);
+ free(old);
+ }
+ }
+ free(variables), variables = NULL;
+ variable_count = current_scope = 0;
}
@@ -100,9 +99,10 @@ void variables_terminate(void)
* Push the variable-stack, making it
* possible to shadow all variables
*/
-void variables_stack_push(void)
+void
+variables_stack_push(void)
{
- current_scope++;
+ current_scope++;
}
@@ -112,19 +112,20 @@ void variables_stack_push(void)
* since it was last called (without a
* corresponding call to this function)
*/
-void variables_stack_pop(void)
+void
+variables_stack_pop(void)
{
- size_t i;
- variable_t* old;
- for (i = 0; i < variable_count; i++)
- if (variables[i] && (variables[i]->scope == current_scope))
- {
- old = variables[i];
- variables[i] = variables[i]->previous;
- mds_kbdc_tree_free(old->value);
- free(old);
- }
- current_scope--;
+ size_t i;
+ variable_t *old;
+ for (i = 0; i < variable_count; i++) {
+ if (variables[i] && variables[i]->scope == current_scope) {
+ old = variables[i];
+ variables[i] = variables[i]->previous;
+ mds_kbdc_tree_free(old->value);
+ free(old);
+ }
+ }
+ current_scope--;
}
@@ -135,11 +136,12 @@ void variables_stack_pop(void)
* @param variable The variable index
* @return Whether a let will override the variable
*/
-int variables_let_will_override(size_t variable)
+int
+variables_let_will_override(size_t variable)
{
- if (variable >= variable_count) return 0;
- if (variables[variable] == NULL) return 0;
- return variables[variable]->scope == current_scope;
+ if (variable >= variable_count) return 0;
+ if (!variables[variable]) return 0;
+ return variables[variable]->scope == current_scope;
}
@@ -150,42 +152,39 @@ int variables_let_will_override(size_t variable)
* @param value The variable's new value
* @return Zero on success, -1 on error
*/
-int variables_let(size_t variable, mds_kbdc_tree_t* restrict value)
+int
+variables_let(size_t variable, mds_kbdc_tree_t *restrict value)
{
- variable_t** new;
- variable_t* previous;
-
- /* Grow the table if necessary to fit the variable. */
- if (variable >= variable_count)
- {
- new = variables;
- fail_if (xrealloc(new, variable + 1, variable_t*));
- variables = new;
- memset(variables + variable_count, 0, (variable + 1 - variable_count) * sizeof(variable_t*));
- variable_count = variable + 1;
- }
+ variable_t **new;
+ variable_t *previous;
+
+ /* Grow the table if necessary to fit the variable. */
+ if (variable >= variable_count) {
+ new = variables;
+ fail_if (xrealloc(new, variable + 1, variable_t*));
+ variables = new;
+ memset(variables + variable_count, 0, (variable + 1 - variable_count) * sizeof(variable_t*));
+ variable_count = variable + 1;
+ }
+
+ if (variables_let_will_override(variable)) {
+ /* Override. */
+ mds_kbdc_tree_free(variables[variable]->value);
+ variables[variable]->value = value;
+ } else {
+ /* Shadow or define. */
+ previous = variables[variable];
+ if (xmalloc(variables[variable], 1, variable_t))
+ fail_if (variables[variable] = previous, 1);
+ variables[variable]->value = value;
+ variables[variable]->previous = previous;
+ variables[variable]->scope = current_scope;
+ variables[variable]->used_in_for = (size_t)(~0LL);
+ }
- if (variables_let_will_override(variable))
- {
- /* Override. */
- mds_kbdc_tree_free(variables[variable]->value);
- variables[variable]->value = value;
- }
- else
- {
- /* Shadow or define. */
- previous = variables[variable];
- if (xmalloc(variables[variable], 1, variable_t))
- fail_if (variables[variable] = previous, 1);
- variables[variable]->value = value;
- variables[variable]->previous = previous;
- variables[variable]->scope = current_scope;
- variables[variable]->used_in_for = (size_t)(~0LL);
- }
-
- return 0;
- fail:
- return -1;
+ return 0;
+fail:
+ return -1;
}
@@ -198,11 +197,12 @@ int variables_let(size_t variable, mds_kbdc_tree_t* restrict value)
* @param variable The variable index
* @return The variable's value, `NULL` if not defined
*/
-mds_kbdc_tree_t* variables_get(size_t variable)
+mds_kbdc_tree_t *
+variables_get(size_t variable)
{
- if (variable >= variable_count) return NULL;
- if (variables[variable] == NULL) return NULL;
- return variables[variable]->value;
+ if (variable >= variable_count) return NULL;
+ if (!variables[variable]) return NULL;
+ return variables[variable]->value;
}
@@ -212,31 +212,32 @@ mds_kbdc_tree_t* variables_get(size_t variable)
* @param variable The variable index, must already be defined
* @return Zero on success, -1 on error
*/
-int variables_was_used_in_for(size_t variable)
+int
+variables_was_used_in_for(size_t variable)
{
- variable_t* previous;
-
- /* Already marked. */
- if (variables[variable]->used_in_for == current_scope)
- return 0;
-
- /* Not marked. */
- if (variables[variable]->used_in_for == (size_t)(~0LL))
- return variables[variable]->used_in_for = current_scope, 0;
-
- /* Marked for another scope. */
- previous = variables[variable];
- if (xmalloc(variables[variable], 1, variable_t))
- fail_if (variables[variable] = previous, 1);
- variables[variable]->value = mds_kbdc_tree_dup(previous->value);
- fail_if (variables[variable]->value == NULL);
- variables[variable]->previous = previous;
- variables[variable]->scope = current_scope;
- variables[variable]->used_in_for = current_scope;
-
- return 0;
- fail:
- return -1;
+ variable_t *previous;
+
+ /* Already marked. */
+ if (variables[variable]->used_in_for == current_scope)
+ return 0;
+
+ /* Not marked. */
+ if (variables[variable]->used_in_for == (size_t)(~0LL))
+ return variables[variable]->used_in_for = current_scope, 0;
+
+ /* Marked for another scope. */
+ previous = variables[variable];
+ if (xmalloc(variables[variable], 1, variable_t))
+ fail_if (variables[variable] = previous, 1);
+ variables[variable]->value = mds_kbdc_tree_dup(previous->value);
+ fail_if (variables[variable]->value == NULL);
+ variables[variable]->previous = previous;
+ variables[variable]->scope = current_scope;
+ variables[variable]->used_in_for = current_scope;
+
+ return 0;
+fail:
+ return -1;
}
@@ -246,8 +247,8 @@ int variables_was_used_in_for(size_t variable)
* @param variable The variable index, must already be defined
* @return Whether `variables_was_used_in_for` has been unused on the variable
*/
-int variables_has_been_used_in_for(size_t variable)
+int
+variables_has_been_used_in_for(size_t variable)
{
- return variables[variable]->used_in_for == current_scope;
+ return variables[variable]->used_in_for == current_scope;
}
-
diff --git a/src/mds-kbdc/variables.h b/src/mds-kbdc/variables.h
index 485961b..a175ab7 100644
--- a/src/mds-kbdc/variables.h
+++ b/src/mds-kbdc/variables.h
@@ -52,7 +52,8 @@ void variables_stack_pop(void);
* @param variable The variable index
* @return Whether a let will override the variable
*/
-int variables_let_will_override(size_t variable) __attribute__((pure));
+__attribute__((pure))
+int variables_let_will_override(size_t variable);
/**
* Assign a value to a variable, and define or shadow it in the process
@@ -61,7 +62,7 @@ int variables_let_will_override(size_t variable) __attribute__((pure));
* @param value The variable's new value
* @return Zero on success, -1 on error
*/
-int variables_let(size_t variable, mds_kbdc_tree_t* restrict value);
+int variables_let(size_t variable, mds_kbdc_tree_t *restrict value);
/**
* Get the value currently assigned to a variable
@@ -72,7 +73,8 @@ int variables_let(size_t variable, mds_kbdc_tree_t* restrict value);
* @param variable The variable index
* @return The variable's value, `NULL` if not defined
*/
-mds_kbdc_tree_t* variables_get(size_t variable) __attribute__((pure));
+__attribute__((pure))
+mds_kbdc_tree_t *variables_get(size_t variable);
/**
* Mark a variable as having been unsed in a for-loop in the current scope
@@ -88,8 +90,8 @@ int variables_was_used_in_for(size_t variable);
* @param variable The variable index, must already be defined
* @return Whether `variables_was_used_in_for` has been unused on the variable
*/
-int variables_has_been_used_in_for(size_t variable) __attribute__((pure));
+__attribute__((pure))
+int variables_has_been_used_in_for(size_t variable);
#endif
-
diff --git a/src/mds-kkbd.c b/src/mds-kkbd.c
index e57e6b5..31915bd 100644
--- a/src/mds-kkbd.c
+++ b/src/mds-kkbd.c
@@ -1718,7 +1718,7 @@ void
shrink_map(void)
{
size_t i, greatest_mapping = 0;
- int* old;
+ int *old;
for (i = mapping_size; i > 0; i--) {
if (mapping[i] != (int)i) {
diff --git a/src/mds-libinput.h b/src/mds-libinput.h
index 85ad5d5..6474e6d 100644
--- a/src/mds-libinput.h
+++ b/src/mds-libinput.h
@@ -105,4 +105,3 @@ void dump_info(void);
#endif
-
diff --git a/src/mds-registry/mds-registry.c b/src/mds-registry/mds-registry.c
index 57a0b92..3d17247 100644
--- a/src/mds-registry/mds-registry.c
+++ b/src/mds-registry/mds-registry.c
@@ -66,7 +66,8 @@ server_characteristics_t server_characteristics = {
*
* @return Non-zero on error
*/
-int preinitialise_server(void)
+int
+preinitialise_server(void)
{
int stage = 0;
diff --git a/src/mds-registry/registry.c b/src/mds-registry/registry.c
index f5a9b8a..0c4d5a5 100644
--- a/src/mds-registry/registry.c
+++ b/src/mds-registry/registry.c
@@ -465,7 +465,8 @@ handle_register_message(void)
* @return Zero on success, -1 on error or interruption,
* `errno` will be set accordingly
*/
-int handle_message(void)
+int
+handle_message(void)
{
size_t i;
for (i = 0; i < received.header_count; i++) {
@@ -476,6 +477,6 @@ int handle_message(void)
}
fail_if (handle_close_message());
return 0;
- fail:
+fail:
return -1;
}
diff --git a/src/mds-registry/signals.c b/src/mds-registry/signals.c
index 9b0a7a0..8fb90dd 100644
--- a/src/mds-registry/signals.c
+++ b/src/mds-registry/signals.c
@@ -34,7 +34,8 @@
*
* @param signo The signal
*/
-void signal_all(int signo)
+void
+signal_all(int signo)
{
pthread_t current_thread;
ssize_t node;
diff --git a/src/mds-registry/slave.h b/src/mds-registry/slave.h
index f9f748b..0b4f7b2 100644
--- a/src/mds-registry/slave.h
+++ b/src/mds-registry/slave.h
@@ -35,8 +35,7 @@
/**
* Slave information, a thread waiting for protocols to become available
*/
-typedef struct slave
-{
+typedef struct slave {
/**
* Set of protocols for which to wait that they become available
*/
@@ -82,7 +81,6 @@ typedef struct slave
* Whether `dethklok` should apply
*/
int timed;
-
} slave_t;
diff --git a/src/mds-registry/util.c b/src/mds-registry/util.c
index c8d2015..77dff5a 100644
--- a/src/mds-registry/util.c
+++ b/src/mds-registry/util.c
@@ -37,7 +37,8 @@
*
* @param obj The key
*/
-void reg_table_free_key(size_t obj)
+void
+reg_table_free_key(size_t obj)
{
char *command = (void *)obj;
free(command);
@@ -49,7 +50,8 @@ void reg_table_free_key(size_t obj)
*
* @param obj The value
*/
-void reg_table_free_value(size_t obj)
+void
+reg_table_free_value(size_t obj)
{
client_list_t *list = (void *)obj;
client_list_destroy(list);
diff --git a/src/mds-respawn.h b/src/mds-respawn.h
index c614cf4..b664c05 100644
--- a/src/mds-respawn.h
+++ b/src/mds-respawn.h
@@ -66,8 +66,7 @@
/**
* The state and identifier of a server
*/
-typedef struct server_state
-{
+typedef struct server_state {
/**
* The server's process ID
*/
@@ -82,10 +81,8 @@ typedef struct server_state
* The time (monotonic) the server started
*/
struct timespec started;
-
} server_state_t;
#endif
-
diff --git a/src/mds-server/client.h b/src/mds-server/client.h
index 91ab0c2..b003d31 100644
--- a/src/mds-server/client.h
+++ b/src/mds-server/client.h
@@ -36,8 +36,7 @@
/**
* Client information structure
*/
-typedef struct client
-{
+typedef struct client {
/**
* The client's entry in the list of clients
*/
@@ -134,7 +133,6 @@ typedef struct client
* Whether `modify_cond` has been initialised
*/
int modify_cond_created;
-
} client_t;
diff --git a/src/mds-server/globals.h b/src/mds-server/globals.h
index 94a3651..8083717 100644
--- a/src/mds-server/globals.h
+++ b/src/mds-server/globals.h
@@ -93,4 +93,3 @@ extern hash_table_t modify_map;
#endif
-
diff --git a/src/mds-server/interception-condition.h b/src/mds-server/interception-condition.h
index 1ca3823..78383f4 100644
--- a/src/mds-server/interception-condition.h
+++ b/src/mds-server/interception-condition.h
@@ -28,8 +28,7 @@
/**
* A condition for a message being intercepted by a client
*/
-typedef struct interception_condition
-{
+typedef struct interception_condition {
/**
* The header of messages to intercept, optionally with a value,
* empty (most not be NULL) for all messages.
@@ -52,7 +51,6 @@ typedef struct interception_condition
* Whether the messages may get modified by the client
*/
int modifying;
-
} interception_condition_t;
diff --git a/src/mds-server/interceptors.h b/src/mds-server/interceptors.h
index 99cd0a3..21f74d4 100644
--- a/src/mds-server/interceptors.h
+++ b/src/mds-server/interceptors.h
@@ -52,7 +52,7 @@ void add_intercept_condition(client_t *client, char *condition, int64_t priority
*/
__attribute__((pure, nonnull(1)))
int is_condition_matching(interception_condition_t *cond, size_t *hashes,
- char **keys, char **headers, size_t count);
+ char **keys, char **headers, size_t count);
/**
diff --git a/src/mds-server/multicast.h b/src/mds-server/multicast.h
index 611298f..126c4ba 100644
--- a/src/mds-server/multicast.h
+++ b/src/mds-server/multicast.h
@@ -27,8 +27,7 @@
/**
* Message multicast state
*/
-typedef struct multicast
-{
+typedef struct multicast {
/**
* Queue of clients that is listening this message
*/
@@ -63,7 +62,6 @@ typedef struct multicast
* How much of the message to skip if the recipient is not a modifier
*/
size_t message_prefix;
-
} multicast_t;
diff --git a/src/mds-server/queued-interception.h b/src/mds-server/queued-interception.h
index 2a072bc..1555801 100644
--- a/src/mds-server/queued-interception.h
+++ b/src/mds-server/queued-interception.h
@@ -29,8 +29,7 @@
/**
* A queued interception
*/
-typedef struct queued_interception
-{
+typedef struct queued_interception {
/**
* The intercepting client
*/
@@ -50,7 +49,6 @@ typedef struct queued_interception
* The file descriptor of the intercepting client's socket (used for unmarshalling)
*/
int socket_fd;
-
} queued_interception_t;
diff --git a/src/mds-vt.c b/src/mds-vt.c
index c009d65..7a34dd6 100644
--- a/src/mds-vt.c
+++ b/src/mds-vt.c
@@ -38,7 +38,7 @@
-#define MDS_VT_VARS_VERSION 0
+#define MDS_VT_VARS_VERSION 0
diff --git a/src/mds.h b/src/mds.h
index 45ebbbf..49c911c 100644
--- a/src/mds.h
+++ b/src/mds.h
@@ -57,7 +57,7 @@ int spawn_and_respawn_server(int fd);
* @return Non-zero on error
*/
__attribute__((nonnull))
-int create_directory_root(const char* pathname);
+int create_directory_root(const char *pathname);
/**
* Create a directory owned by the real user and nobody group
@@ -66,7 +66,7 @@ int create_directory_root(const char* pathname);
* @return Non-zero on error
*/
__attribute__((nonnull))
-int create_directory_user(const char* pathname);
+int create_directory_user(const char *pathname);
/**
* Recursively remove a directory
@@ -75,8 +75,7 @@ int create_directory_user(const char* pathname);
* @return Non-zero on error
*/
__attribute__((nonnull))
-int unlink_recursive(const char* pathname);
+int unlink_recursive(const char *pathname);
#endif
-