mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	We cannot do hooks_find and then hooks_remove because it might have come
from the parent (global) tree, instead make it remove by name like options. While here, also tidy up a few bits of options and hooks handling (use RB_FOREACH_SAFE, and a helper function for the free).
This commit is contained in:
		| @@ -93,8 +93,7 @@ cmd_set_hook_exec(struct cmd *self, struct cmd_q *cmdq) | |||||||
| 			    name); | 			    name); | ||||||
| 			return (CMD_RETURN_ERROR); | 			return (CMD_RETURN_ERROR); | ||||||
| 		} | 		} | ||||||
| 		if ((hook = hooks_find(hooks, name)) != NULL) | 		hooks_remove(hooks, name); | ||||||
| 			hooks_remove(hooks, hook); |  | ||||||
| 		return (CMD_RETURN_NORMAL); | 		return (CMD_RETURN_NORMAL); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										28
									
								
								hooks.c
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								hooks.c
									
									
									
									
									
								
							| @@ -32,7 +32,8 @@ static int	hooks_cmp(struct hook *, struct hook *); | |||||||
| RB_PROTOTYPE(hooks_tree, hook, entry, hooks_cmp); | RB_PROTOTYPE(hooks_tree, hook, entry, hooks_cmp); | ||||||
| RB_GENERATE(hooks_tree, hook, entry, hooks_cmp); | RB_GENERATE(hooks_tree, hook, entry, hooks_cmp); | ||||||
|  |  | ||||||
| struct hook	*hooks_find1(struct hooks *, const char *); | static struct hook	*hooks_find1(struct hooks *, const char *); | ||||||
|  | static void		 hooks_free1(struct hooks *, struct hook *); | ||||||
|  |  | ||||||
| static int | static int | ||||||
| hooks_cmp(struct hook *hook1, struct hook *hook2) | hooks_cmp(struct hook *hook1, struct hook *hook2) | ||||||
| @@ -51,13 +52,22 @@ hooks_create(struct hooks *parent) | |||||||
| 	return (hooks); | 	return (hooks); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | hooks_free1(struct hooks *hooks, struct hook *hook) | ||||||
|  | { | ||||||
|  | 	RB_REMOVE(hooks_tree, &hooks->tree, hook); | ||||||
|  | 	cmd_list_free(hook->cmdlist); | ||||||
|  | 	free((char *)hook->name); | ||||||
|  | 	free(hook); | ||||||
|  | } | ||||||
|  |  | ||||||
| void | void | ||||||
| hooks_free(struct hooks *hooks) | hooks_free(struct hooks *hooks) | ||||||
| { | { | ||||||
| 	struct hook	*hook, *hook1; | 	struct hook	*hook, *hook1; | ||||||
|  |  | ||||||
| 	RB_FOREACH_SAFE(hook, hooks_tree, &hooks->tree, hook1) | 	RB_FOREACH_SAFE(hook, hooks_tree, &hooks->tree, hook1) | ||||||
| 		hooks_remove(hooks, hook); | 		hooks_free1(hooks, hook); | ||||||
| 	free(hooks); | 	free(hooks); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -79,7 +89,7 @@ hooks_add(struct hooks *hooks, const char *name, struct cmd_list *cmdlist) | |||||||
| 	struct hook	*hook; | 	struct hook	*hook; | ||||||
|  |  | ||||||
| 	if ((hook = hooks_find1(hooks, name)) != NULL) | 	if ((hook = hooks_find1(hooks, name)) != NULL) | ||||||
| 		hooks_remove(hooks, hook); | 		hooks_free1(hooks, hook); | ||||||
|  |  | ||||||
| 	hook = xcalloc(1, sizeof *hook); | 	hook = xcalloc(1, sizeof *hook); | ||||||
| 	hook->name = xstrdup(name); | 	hook->name = xstrdup(name); | ||||||
| @@ -89,15 +99,15 @@ hooks_add(struct hooks *hooks, const char *name, struct cmd_list *cmdlist) | |||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| hooks_remove(struct hooks *hooks, struct hook *hook) | hooks_remove(struct hooks *hooks, const char *name) | ||||||
| { | { | ||||||
| 	RB_REMOVE(hooks_tree, &hooks->tree, hook); | 	struct hook	*hook; | ||||||
| 	cmd_list_free(hook->cmdlist); |  | ||||||
| 	free((char *) hook->name); | 	if ((hook = hooks_find1(hooks, name)) != NULL) | ||||||
| 	free(hook); | 		hooks_free1(hooks, hook); | ||||||
| } | } | ||||||
|  |  | ||||||
| struct hook * | static struct hook * | ||||||
| hooks_find1(struct hooks *hooks, const char *name) | hooks_find1(struct hooks *hooks, const char *name) | ||||||
| { | { | ||||||
| 	struct hook	hook; | 	struct hook	hook; | ||||||
|   | |||||||
							
								
								
									
										42
									
								
								options.c
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								options.c
									
									
									
									
									
								
							| @@ -34,11 +34,13 @@ struct options { | |||||||
| 	struct options	*parent; | 	struct options	*parent; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| int	options_cmp(struct options_entry *, struct options_entry *); | static int	options_cmp(struct options_entry *, struct options_entry *); | ||||||
| RB_PROTOTYPE(options_tree, options_entry, entry, options_cmp); | RB_PROTOTYPE(options_tree, options_entry, entry, options_cmp); | ||||||
| RB_GENERATE(options_tree, options_entry, entry, options_cmp); | RB_GENERATE(options_tree, options_entry, entry, options_cmp); | ||||||
|  |  | ||||||
| int | static void	options_free1(struct options *, struct options_entry *); | ||||||
|  |  | ||||||
|  | static int | ||||||
| options_cmp(struct options_entry *o1, struct options_entry *o2) | options_cmp(struct options_entry *o1, struct options_entry *o2) | ||||||
| { | { | ||||||
| 	return (strcmp(o1->name, o2->name)); | 	return (strcmp(o1->name, o2->name)); | ||||||
| @@ -55,19 +57,23 @@ options_create(struct options *parent) | |||||||
| 	return (oo); | 	return (oo); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | options_free1(struct options *oo, struct options_entry *o) | ||||||
|  | { | ||||||
|  | 	RB_REMOVE(options_tree, &oo->tree, o); | ||||||
|  | 	free((char *)o->name); | ||||||
|  | 	if (o->type == OPTIONS_STRING) | ||||||
|  | 		free(o->str); | ||||||
|  | 	free(o); | ||||||
|  | } | ||||||
|  |  | ||||||
| void | void | ||||||
| options_free(struct options *oo) | options_free(struct options *oo) | ||||||
| { | { | ||||||
| 	struct options_entry	*o; | 	struct options_entry	*o, *o1; | ||||||
|  |  | ||||||
| 	while (!RB_EMPTY(&oo->tree)) { | 	RB_FOREACH_SAFE (o, options_tree, &oo->tree, o1) | ||||||
| 		o = RB_ROOT(&oo->tree); | 		options_free1(oo, o); | ||||||
| 		RB_REMOVE(options_tree, &oo->tree, o); |  | ||||||
| 		free(o->name); |  | ||||||
| 		if (o->type == OPTIONS_STRING) |  | ||||||
| 			free(o->str); |  | ||||||
| 		free(o); |  | ||||||
| 	} |  | ||||||
| 	free(oo); | 	free(oo); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -88,7 +94,7 @@ options_find1(struct options *oo, const char *name) | |||||||
| { | { | ||||||
| 	struct options_entry	p; | 	struct options_entry	p; | ||||||
|  |  | ||||||
| 	p.name = (char *) name; | 	p.name = (char *)name; | ||||||
| 	return (RB_FIND(options_tree, &oo->tree, &p)); | 	return (RB_FIND(options_tree, &oo->tree, &p)); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -97,7 +103,7 @@ options_find(struct options *oo, const char *name) | |||||||
| { | { | ||||||
| 	struct options_entry	*o, p; | 	struct options_entry	*o, p; | ||||||
|  |  | ||||||
| 	p.name = (char *) name; | 	p.name = (char *)name; | ||||||
| 	o = RB_FIND(options_tree, &oo->tree, &p); | 	o = RB_FIND(options_tree, &oo->tree, &p); | ||||||
| 	while (o == NULL) { | 	while (o == NULL) { | ||||||
| 		oo = oo->parent; | 		oo = oo->parent; | ||||||
| @@ -113,14 +119,8 @@ options_remove(struct options *oo, const char *name) | |||||||
| { | { | ||||||
| 	struct options_entry	*o; | 	struct options_entry	*o; | ||||||
|  |  | ||||||
| 	if ((o = options_find1(oo, name)) == NULL) | 	if ((o = options_find1(oo, name)) != NULL) | ||||||
| 		return; | 		options_free1(oo, o); | ||||||
|  |  | ||||||
| 	RB_REMOVE(options_tree, &oo->tree, o); |  | ||||||
| 	free(o->name); |  | ||||||
| 	if (o->type == OPTIONS_STRING) |  | ||||||
| 		free(o->str); |  | ||||||
| 	free(o); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| struct options_entry * | struct options_entry * | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -703,7 +703,7 @@ struct hook { | |||||||
|  |  | ||||||
| /* Option data structures. */ | /* Option data structures. */ | ||||||
| struct options_entry { | struct options_entry { | ||||||
| 	char		*name; | 	const char		*name; | ||||||
|  |  | ||||||
| 	enum { | 	enum { | ||||||
| 		OPTIONS_STRING, | 		OPTIONS_STRING, | ||||||
| @@ -1514,7 +1514,7 @@ struct hook	*hooks_first(struct hooks *); | |||||||
| struct hook	*hooks_next(struct hook *); | struct hook	*hooks_next(struct hook *); | ||||||
| void		 hooks_add(struct hooks *, const char *, struct cmd_list *); | void		 hooks_add(struct hooks *, const char *, struct cmd_list *); | ||||||
| void		 hooks_copy(struct hooks *, struct hooks *); | void		 hooks_copy(struct hooks *, struct hooks *); | ||||||
| void		 hooks_remove(struct hooks *, struct hook *); | void		 hooks_remove(struct hooks *, const char *); | ||||||
| struct hook	*hooks_find(struct hooks *, const char *); | struct hook	*hooks_find(struct hooks *, const char *); | ||||||
| void		 hooks_run(struct hooks *, const char *, struct client *); | void		 hooks_run(struct hooks *, const char *, struct client *); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 nicm
					nicm