diff options
author | erw7 <erw7.github@gmail.com> | 2019-10-16 16:23:07 +0200 |
---|---|---|
committer | Jan Edmund Lazo <jan.lazo@mail.utoronto.ca> | 2021-03-30 21:55:50 -0400 |
commit | 36caafeb281bf872f11d475e594eb212636daa4d (patch) | |
tree | 11a0922ed39166ab9fa54249d03fd8d6244a78ce | |
parent | 4c76b1e981f072229944a22e5d5ee76fe42d994a (diff) | |
download | rneovim-36caafeb281bf872f11d475e594eb212636daa4d.tar.gz rneovim-36caafeb281bf872f11d475e594eb212636daa4d.tar.bz2 rneovim-36caafeb281bf872f11d475e594eb212636daa4d.zip |
Change QUEUE_FOREACH macro to use while instead of for
-rw-r--r-- | src/nvim/eval.c | 4 | ||||
-rw-r--r-- | src/nvim/eval/typval.c | 8 | ||||
-rw-r--r-- | src/nvim/event/multiqueue.c | 6 | ||||
-rw-r--r-- | src/nvim/lib/queue.h | 16 | ||||
-rw-r--r-- | src/nvim/os/pty_process_win.c | 14 |
5 files changed, 26 insertions, 22 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index b4f0c86f24..9c3941b0fd 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -5289,10 +5289,10 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, QUEUE *w = NULL; DictWatcher *watcher = NULL; - QUEUE_FOREACH(w, &dd->watchers) { + QUEUE_FOREACH(w, &dd->watchers, { watcher = tv_dict_watcher_node_data(w); set_ref_in_callback(&watcher->callback, copyID, ht_stack, list_stack); - } + }) } break; } diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index f8b48d0139..5b3e31b324 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1183,7 +1183,7 @@ bool tv_dict_watcher_remove(dict_T *const dict, const char *const key_pattern, QUEUE *w = NULL; DictWatcher *watcher = NULL; bool matched = false; - QUEUE_FOREACH(w, &dict->watchers) { + QUEUE_FOREACH(w, &dict->watchers, { watcher = tv_dict_watcher_node_data(w); if (tv_callback_equal(&watcher->callback, &callback) && watcher->key_pattern_len == key_pattern_len @@ -1191,7 +1191,7 @@ bool tv_dict_watcher_remove(dict_T *const dict, const char *const key_pattern, matched = true; break; } - } + }) if (!matched) { return false; @@ -1265,7 +1265,7 @@ void tv_dict_watcher_notify(dict_T *const dict, const char *const key, dict->dv_refcount++; QUEUE *w; - QUEUE_FOREACH(w, &dict->watchers) { + QUEUE_FOREACH(w, &dict->watchers, { DictWatcher *watcher = tv_dict_watcher_node_data(w); if (!watcher->busy && tv_dict_watcher_matches(watcher, key)) { rettv = TV_INITIAL_VALUE; @@ -1277,7 +1277,7 @@ void tv_dict_watcher_notify(dict_T *const dict, const char *const key, tv_dict_watcher_free(watcher); } } - } + }) tv_dict_unref(dict); for (size_t i = 1; i < ARRAY_SIZE(argv); i++) { diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index c9aa3acc4d..1e6d62135c 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -119,8 +119,8 @@ static MultiQueue *multiqueue_new(MultiQueue *parent, put_callback put_cb, void multiqueue_free(MultiQueue *this) { assert(this); - while (!QUEUE_EMPTY(&this->headtail)) { - QUEUE *q = QUEUE_HEAD(&this->headtail); + QUEUE *q; + QUEUE_FOREACH(q, &this->headtail, { MultiQueueItem *item = multiqueue_node_data(q); if (this->parent) { QUEUE_REMOVE(&item->data.item.parent_item->node); @@ -128,7 +128,7 @@ void multiqueue_free(MultiQueue *this) } QUEUE_REMOVE(q); xfree(item); - } + }) xfree(this); } diff --git a/src/nvim/lib/queue.h b/src/nvim/lib/queue.h index ab9270081e..452998a5a4 100644 --- a/src/nvim/lib/queue.h +++ b/src/nvim/lib/queue.h @@ -33,11 +33,17 @@ typedef struct _queue { #define QUEUE_DATA(ptr, type, field) \ ((type *)((char *)(ptr) - offsetof(type, field))) -// Important note: mutating the list while QUEUE_FOREACH is -// iterating over its elements results in undefined behavior. -#define QUEUE_FOREACH(q, h) \ - for ( /* NOLINT(readability/braces) */ \ - (q) = (h)->next; (q) != (h); (q) = (q)->next) +// Important note: the node currently being processed can be safely deleted. +// otherwise, mutating the list while QUEUE_FOREACH is iterating over its +// elements results in undefined behavior. +#define QUEUE_FOREACH(q, h, code) \ + (q) = (h)->next; \ + while((q) != (h)) { \ + QUEUE *next = q->next; \ + code \ + (q) = next; \ + } + // ffi.cdef is unable to swallow `bool` in place of `int` here. static inline int QUEUE_EMPTY(const QUEUE *const q) diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index 52d2f84ace..502b7ffa53 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -343,19 +343,17 @@ static int build_cmd_line(char **argv, wchar_t **cmd_line, bool is_cmdexe) utf8_cmd_line_len += argc; char *utf8_cmd_line = xmalloc(utf8_cmd_line_len); *utf8_cmd_line = NUL; - while (1) { - QUEUE *head = QUEUE_HEAD(&args_q); - QUEUE_REMOVE(head); - ArgNode *arg_node = QUEUE_DATA(head, ArgNode, node); + QUEUE *q; + QUEUE_FOREACH(q, &args_q, { + ArgNode *arg_node = QUEUE_DATA(q, ArgNode, node); xstrlcat(utf8_cmd_line, arg_node->arg, utf8_cmd_line_len); xfree(arg_node->arg); xfree(arg_node); - if (QUEUE_EMPTY(&args_q)) { - break; - } else { + QUEUE_REMOVE(q); + if (!QUEUE_EMPTY(&args_q)) { xstrlcat(utf8_cmd_line, " ", utf8_cmd_line_len); } - } + }) int result = utf8_to_utf16(utf8_cmd_line, -1, cmd_line); xfree(utf8_cmd_line); |