diff options
author | 3gg <3gg@shellblade.net> | 2024-06-15 11:43:10 -0700 |
---|---|---|
committer | 3gg <3gg@shellblade.net> | 2024-06-15 11:43:10 -0700 |
commit | bec2d50c843ec4fd98bbbb212848ce4f24b96ebb (patch) | |
tree | 59c33bc964e723350886035fe249e41d0f8b397e | |
parent | 04e3ded4c28c0b559620609daaae7b939d776b61 (diff) |
More convenient list iteration.
-rw-r--r-- | list/include/list.h | 44 | ||||
-rw-r--r-- | list/test/list_test.c | 20 | ||||
-rw-r--r-- | plugin/src/plugin.c | 15 |
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 | ||
18 | static inline void* alloc(size_t size) { | 18 | static 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 | ||
7 | DEF_LIST(int); | 7 | DEF_LIST(int, int); |
8 | 8 | ||
9 | // Iterate over a list. | 9 | // Iterate over a list. |
10 | TEST_CASE(list_traverse) { | 10 | TEST_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) { | |||
30 | TEST_CASE(list_remove_by_value) { | 30 | TEST_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 | ||
37 | DEF_LIST(Plugin); | 37 | DEF_LIST(Plugin, Plugin); |
38 | 38 | ||
39 | /// Plugin engine. | 39 | /// Plugin engine. |
40 | typedef struct PluginEngine { | 40 | typedef 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 | } |