From 6bfeb57f037c03cf2c2706dafed128fb0e3f3846 Mon Sep 17 00:00:00 2001 From: Pietro Cerutti Date: Tue, 25 Jul 2017 19:52:29 +0000 Subject: [PATCH] Convert Hooks to TAILQ For this one I have chosen to use a doubly-linked tail queue. See how it simplifies the delete_hooks function. Issue #374 --- hook.c | 65 ++++++++++++++++++++++------------------------------------ 1 file changed, 25 insertions(+), 40 deletions(-) diff --git a/hook.c b/hook.c index 138c88bed..4810dcf53 100644 --- a/hook.c +++ b/hook.c @@ -50,16 +50,17 @@ /** * struct Hook - A list of user hooks */ +TAILQ_HEAD(HookHead, Hook); struct Hook { int type; /**< hook type */ struct Regex rx; /**< regular expression */ char *command; /**< filename, command or pattern to execute */ struct Pattern *pattern; /**< used for fcc,save,send-hook */ - struct Hook *next; + TAILQ_ENTRY(Hook) entries; }; -static struct Hook *Hooks = NULL; +static struct HookHead Hooks = TAILQ_HEAD_INITIALIZER(Hooks); static int current_hook_type = 0; @@ -175,7 +176,7 @@ int mutt_parse_hook(struct Buffer *buf, struct Buffer *s, unsigned long data, } /* check to make sure that a matching hook doesn't already exist */ - for (ptr = Hooks; ptr; ptr = ptr->next) + TAILQ_FOREACH(ptr, &Hooks, entries) { if (data & MUTT_GLOBALHOOK) { @@ -216,8 +217,6 @@ int mutt_parse_hook(struct Buffer *buf, struct Buffer *s, unsigned long data, return 0; } } - if (!ptr->next) - break; } if (data & (MUTT_SENDHOOK | MUTT_SEND2HOOK | MUTT_SAVEHOOK | MUTT_FCCHOOK | @@ -246,19 +245,14 @@ int mutt_parse_hook(struct Buffer *buf, struct Buffer *s, unsigned long data, } } - if (ptr) - { - ptr->next = safe_calloc(1, sizeof(struct Hook)); - ptr = ptr->next; - } - else - Hooks = ptr = safe_calloc(1, sizeof(struct Hook)); + ptr = safe_calloc(1, sizeof(struct Hook)); ptr->type = data; ptr->command = command.data; ptr->pattern = pat; ptr->rx.pattern = pattern.data; ptr->rx.rx = rx; ptr->rx.not = not; + TAILQ_INSERT_TAIL(&Hooks, ptr, entries); return 0; error: @@ -289,26 +283,15 @@ static void delete_hook(struct Hook *h) static void delete_hooks(int type) { struct Hook *h = NULL; - struct Hook *prev = NULL; + struct Hook *tmp = NULL; - while (h = Hooks, h && (type == 0 || type == h->type)) + TAILQ_FOREACH_SAFE(h, &Hooks, entries, tmp) { - Hooks = h->next; - delete_hook(h); - } - - prev = h; /* Unused assignment to avoid compiler warnings */ - - while (h) - { - if (type == h->type) + if (type == 0 || type == h->type) { - prev->next = h->next; + TAILQ_REMOVE(&Hooks, h, entries); delete_hook(h); } - else - prev = h; - h = prev->next; } } @@ -351,7 +334,7 @@ int mutt_parse_unhook(struct Buffer *buf, struct Buffer *s, unsigned long data, void mutt_folder_hook(char *path) { - struct Hook *tmp = Hooks; + struct Hook *tmp = NULL; struct Buffer err, token; current_hook_type = MUTT_FOLDERHOOK; @@ -360,7 +343,7 @@ void mutt_folder_hook(char *path) err.dsize = STRING; err.data = safe_malloc(err.dsize); mutt_buffer_init(&token); - for (; tmp; tmp = tmp->next) + TAILQ_FOREACH(tmp, &Hooks, entries) { if (!tmp->command) continue; @@ -390,14 +373,16 @@ void mutt_folder_hook(char *path) char *mutt_find_hook(int type, const char *pat) { - struct Hook *tmp = Hooks; + struct Hook *tmp = NULL; - for (; tmp; tmp = tmp->next) + TAILQ_FOREACH(tmp, &Hooks, entries) + { if (tmp->type & type) { if (regexec(tmp->rx.rx, pat, 0, NULL, 0) == 0) return tmp->command; } + } return NULL; } @@ -414,7 +399,7 @@ void mutt_message_hook(struct Context *ctx, struct Header *hdr, int type) err.data = safe_malloc(err.dsize); mutt_buffer_init(&token); memset(&cache, 0, sizeof(cache)); - for (hook = Hooks; hook; hook = hook->next) + TAILQ_FOREACH(hook, &Hooks, entries) { if (!hook->command) continue; @@ -451,7 +436,7 @@ static int addr_hook(char *path, size_t pathlen, int type, struct Context *ctx, memset(&cache, 0, sizeof(cache)); /* determine if a matching hook exists */ - for (hook = Hooks; hook; hook = hook->next) + TAILQ_FOREACH(hook, &Hooks, entries) { if (!hook->command) continue; @@ -519,9 +504,9 @@ void mutt_select_fcc(char *path, size_t pathlen, struct Header *hdr) static char *_mutt_string_hook(const char *match, int hook) { - struct Hook *tmp = Hooks; + struct Hook *tmp = NULL; - for (; tmp; tmp = tmp->next) + TAILQ_FOREACH(tmp, &Hooks, entries) { if ((tmp->type & hook) && ((match && regexec(tmp->rx.rx, match, 0, NULL, 0) == 0) ^ tmp->rx.not)) @@ -532,9 +517,9 @@ static char *_mutt_string_hook(const char *match, int hook) static void _mutt_list_hook(struct STailQHead *matches, const char *match, int hook) { - struct Hook *tmp = Hooks; + struct Hook *tmp = NULL; - for (; tmp; tmp = tmp->next) + TAILQ_FOREACH(tmp, &Hooks, entries) { if ((tmp->type & hook) && ((match && regexec(tmp->rx.rx, match, 0, NULL, 0) == 0) ^ tmp->rx.not)) @@ -577,7 +562,7 @@ void mutt_account_hook(const char *url) err.data = safe_malloc(err.dsize); mutt_buffer_init(&token); - for (hook = Hooks; hook; hook = hook->next) + TAILQ_FOREACH(hook, &Hooks, entries) { if (!(hook->command && (hook->type & MUTT_ACCOUNTHOOK))) continue; @@ -617,7 +602,7 @@ void mutt_timeout_hook(void) err.dsize = sizeof(buf); mutt_buffer_init(&token); - for (hook = Hooks; hook; hook = hook->next) + TAILQ_FOREACH(hook, &Hooks, entries) { if (!(hook->command && (hook->type & MUTT_TIMEOUTHOOK))) continue; @@ -652,7 +637,7 @@ void mutt_startup_shutdown_hook(int type) err.dsize = sizeof(buf); mutt_buffer_init(&token); - for (hook = Hooks; hook; hook = hook->next) + TAILQ_FOREACH(hook, &Hooks, entries) { if (!(hook->command && (hook->type & type))) continue; -- 2.40.0