aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2024-06-15 11:43:10 -0700
committer3gg <3gg@shellblade.net>2024-06-15 11:43:10 -0700
commitbec2d50c843ec4fd98bbbb212848ce4f24b96ebb (patch)
tree59c33bc964e723350886035fe249e41d0f8b397e
parent04e3ded4c28c0b559620609daaae7b939d776b61 (diff)
More convenient list iteration.
-rw-r--r--list/include/list.h44
-rw-r--r--list/test/list_test.c20
-rw-r--r--plugin/src/plugin.c15
3 files changed, 39 insertions, 40 deletions
diff --git a/list/include/list.h b/list/include/list.h
index facf820..24291e1 100644
--- a/list/include/list.h
+++ b/list/include/list.h
@@ -5,15 +5,15 @@
5#include <stddef.h> 5#include <stddef.h>
6#include <stdlib.h> 6#include <stdlib.h>
7 7
8#define DEF_LIST(type) \ 8#define DEF_LIST(name, type) \
9 typedef struct type##_node { \ 9 typedef struct name##_node { \
10 type val; \ 10 type val; \
11 struct type##_node* prev; \ 11 struct name##_node* prev; \
12 struct type##_node* next; \ 12 struct name##_node* next; \
13 } type##_node; \ 13 } name##_node; \
14 typedef struct type##_list { \ 14 typedef struct name##_list { \
15 type##_node* head; \ 15 name##_node* head; \
16 } type##_list; 16 } name##_list;
17 17
18static inline void* alloc(size_t size) { 18static inline void* alloc(size_t size) {
19 void* ptr = calloc(1, size); 19 void* ptr = calloc(1, size);
@@ -35,7 +35,7 @@ static inline void* alloc(size_t size) {
35 list.head = 0; 35 list.head = 0;
36 36
37/// Prepend a value to the list. 37/// Prepend a value to the list.
38#define list_push(list, value) \ 38#define list_add(list, value) \
39 { \ 39 { \
40 __typeof__(list.head) node = alloc(sizeof(*list.head)); \ 40 __typeof__(list.head) node = alloc(sizeof(*list.head)); \
41 node->val = value; \ 41 node->val = value; \
@@ -86,13 +86,13 @@ static inline void* alloc(size_t size) {
86/// 86///
87/// Use 'value' to refer to the address of the current node's value during 87/// Use 'value' to refer to the address of the current node's value during
88/// iteration. 88/// iteration.
89#define list_foreach(list, body) \ 89#define list_foreach(list, value, body) \
90 { \ 90 { \
91 __typeof__(list.head) node = list.head; \ 91 __typeof__(list.head)* pNode = &list.head; \
92 while (node) { \ 92 while (*pNode) { \
93 const __typeof__(node->val)* value = &node->val; \ 93 __typeof__((*pNode)->val) value = (*pNode)->val; \
94 body; \ 94 body; \
95 node = node->next; \ 95 pNode = &(*pNode)->next; \
96 } \ 96 } \
97 } 97 }
98 98
@@ -100,12 +100,12 @@ static inline void* alloc(size_t size) {
100/// 100///
101/// Use 'value' to refer to the address of the current node's value during 101/// Use 'value' to refer to the address of the current node's value during
102/// iteration. 102/// iteration.
103#define list_foreach_mut(list, body) \ 103#define list_foreach_mut(list, value, body) \
104 { \ 104 { \
105 __typeof__(list.head) node = list.head; \ 105 __typeof__(list.head) node = list.head; \
106 while (node) { \ 106 while (node) { \
107 __typeof__(node->val)* value = &node->val; \ 107 __typeof__(node->val) value = node->val; \
108 body; \ 108 body; \
109 node = node->next; \ 109 node = node->next; \
110 } \ 110 } \
111 } 111 }
diff --git a/list/test/list_test.c b/list/test/list_test.c
index 9ff10c1..418e156 100644
--- a/list/test/list_test.c
+++ b/list/test/list_test.c
@@ -4,20 +4,20 @@
4 4
5#define TEST_LIST_SIZE 10 5#define TEST_LIST_SIZE 10
6 6
7DEF_LIST(int); 7DEF_LIST(int, int);
8 8
9// Iterate over a list. 9// Iterate over a list.
10TEST_CASE(list_traverse) { 10TEST_CASE(list_traverse) {
11 int_list list = make_list(int); 11 int_list list = make_list(int);
12 for (int i = 0; i < TEST_LIST_SIZE; ++i) { 12 for (int i = 0; i < TEST_LIST_SIZE; ++i) {
13 list_push(list, i + 1); 13 list_add(list, i + 1);
14 } 14 }
15 15
16 int count = 0; 16 int count = 0;
17 int sum = 0; 17 int sum = 0;
18 list_foreach(list, { 18 list_foreach(list, value, {
19 count++; 19 count++;
20 sum += *value; 20 sum += value;
21 }); 21 });
22 22
23 TEST_EQUAL(count, TEST_LIST_SIZE); 23 TEST_EQUAL(count, TEST_LIST_SIZE);
@@ -30,16 +30,16 @@ TEST_CASE(list_traverse) {
30TEST_CASE(list_remove_by_value) { 30TEST_CASE(list_remove_by_value) {
31 int_list list = make_list(int); 31 int_list list = make_list(int);
32 for (int i = 0; i < TEST_LIST_SIZE; ++i) { 32 for (int i = 0; i < TEST_LIST_SIZE; ++i) {
33 list_push(list, i + 1); 33 list_add(list, i + 1);
34 } 34 }
35 35
36 list_remove(list, 5); 36 list_remove(list, 5);
37 37
38 int count = 0; 38 int count = 0;
39 int sum = 0; 39 int sum = 0;
40 list_foreach(list, { 40 list_foreach(list, value, {
41 count++; 41 count++;
42 sum += *value; 42 sum += value;
43 }); 43 });
44 44
45 TEST_EQUAL(count, TEST_LIST_SIZE - 1); 45 TEST_EQUAL(count, TEST_LIST_SIZE - 1);
@@ -56,7 +56,7 @@ TEST_CASE(list_remove_by_address) {
56 56
57 int_list list = make_list(int); 57 int_list list = make_list(int);
58 for (int i = 0; i < N; ++i) { 58 for (int i = 0; i < N; ++i) {
59 list_push(list, i + 1); 59 list_add(list, i + 1);
60 ptrs[i] = &list.head->val; 60 ptrs[i] = &list.head->val;
61 } 61 }
62 62
@@ -64,9 +64,9 @@ TEST_CASE(list_remove_by_address) {
64 64
65 int count = 0; 65 int count = 0;
66 int sum = 0; 66 int sum = 0;
67 list_foreach(list, { 67 list_foreach(list, value, {
68 count++; 68 count++;
69 sum += *value; 69 sum += value;
70 }); 70 });
71 71
72 TEST_EQUAL(count, 2); 72 TEST_EQUAL(count, 2);
diff --git a/plugin/src/plugin.c b/plugin/src/plugin.c
index cd05faf..e2aae1f 100644
--- a/plugin/src/plugin.c
+++ b/plugin/src/plugin.c
@@ -34,7 +34,7 @@ typedef struct Plugin {
34 mstring filename; 34 mstring filename;
35} Plugin; 35} Plugin;
36 36
37DEF_LIST(Plugin); 37DEF_LIST(Plugin, Plugin);
38 38
39/// Plugin engine. 39/// Plugin engine.
40typedef struct PluginEngine { 40typedef struct PluginEngine {
@@ -121,7 +121,7 @@ Plugin* load_plugin(PluginEngine* eng, const char* filename) {
121 return 0; 121 return 0;
122 } 122 }
123 123
124 list_push(eng->plugins, plugin); 124 list_add(eng->plugins, plugin);
125 return &eng->plugins.head->val; 125 return &eng->plugins.head->val;
126} 126}
127 127
@@ -180,7 +180,7 @@ void delete_plugin_engine(PluginEngine** pEng) {
180 assert(pEng); 180 assert(pEng);
181 PluginEngine* eng = *pEng; 181 PluginEngine* eng = *pEng;
182 if (eng) { 182 if (eng) {
183 list_foreach_mut(eng->plugins, { destroy_plugin(value); }); 183 list_foreach_mut(eng->plugins, plugin, { destroy_plugin(&plugin); });
184 del_list(eng->plugins); 184 del_list(eng->plugins);
185 if (eng->dir_watch != -1) { 185 if (eng->dir_watch != -1) {
186 inotify_rm_watch(eng->dir_watch, eng->inotify_instance); 186 inotify_rm_watch(eng->dir_watch, eng->inotify_instance);
@@ -226,11 +226,10 @@ void plugin_engine_update(PluginEngine* eng) {
226 if (event->len > 0) { 226 if (event->len > 0) {
227 // Name does not include directory, e.g., libfoo.so 227 // Name does not include directory, e.g., libfoo.so
228 const mstring file = mstring_make(event->name); 228 const mstring file = mstring_make(event->name);
229 list_foreach_mut(eng->plugins, { 229 list_foreach_mut(eng->plugins, plugin, {
230 Plugin* plugin = value; 230 if (mstring_eq(file, plugin_lib_name(&plugin))) {
231 if (mstring_eq(file, plugin_lib_name(plugin))) { 231 if (load_library(&plugin)) {
232 if (load_library(plugin)) { 232 plugin.reloaded = true;
233 plugin->reloaded = true;
234 } 233 }
235 break; 234 break;
236 } 235 }