Annotation of embedaddon/tmux/hooks.c, revision 1.1.1.1
1.1 misho 1: /* $OpenBSD$ */
2:
3: /*
4: * Copyright (c) 2012 Thomas Adam <thomas@xteddy.org>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include <sys/types.h>
20:
21: #include <stdlib.h>
22: #include <string.h>
23:
24: #include "tmux.h"
25:
26: struct hooks {
27: RB_HEAD(hooks_tree, hook) tree;
28: struct hooks *parent;
29: };
30:
31: static int hooks_cmp(struct hook *, struct hook *);
32: RB_GENERATE_STATIC(hooks_tree, hook, entry, hooks_cmp);
33:
34: static struct hook *hooks_find1(struct hooks *, const char *);
35: static void hooks_free1(struct hooks *, struct hook *);
36:
37: static int
38: hooks_cmp(struct hook *hook1, struct hook *hook2)
39: {
40: return (strcmp(hook1->name, hook2->name));
41: }
42:
43: struct hooks *
44: hooks_get(struct session *s)
45: {
46: if (s != NULL)
47: return (s->hooks);
48: return (global_hooks);
49: }
50:
51: struct hooks *
52: hooks_create(struct hooks *parent)
53: {
54: struct hooks *hooks;
55:
56: hooks = xcalloc(1, sizeof *hooks);
57: RB_INIT(&hooks->tree);
58: hooks->parent = parent;
59: return (hooks);
60: }
61:
62: static void
63: hooks_free1(struct hooks *hooks, struct hook *hook)
64: {
65: RB_REMOVE(hooks_tree, &hooks->tree, hook);
66: cmd_list_free(hook->cmdlist);
67: free((char *)hook->name);
68: free(hook);
69: }
70:
71: void
72: hooks_free(struct hooks *hooks)
73: {
74: struct hook *hook, *hook1;
75:
76: RB_FOREACH_SAFE(hook, hooks_tree, &hooks->tree, hook1)
77: hooks_free1(hooks, hook);
78: free(hooks);
79: }
80:
81: struct hook *
82: hooks_first(struct hooks *hooks)
83: {
84: return (RB_MIN(hooks_tree, &hooks->tree));
85: }
86:
87: struct hook *
88: hooks_next(struct hook *hook)
89: {
90: return (RB_NEXT(hooks_tree, &hooks->tree, hook));
91: }
92:
93: void
94: hooks_add(struct hooks *hooks, const char *name, struct cmd_list *cmdlist)
95: {
96: struct hook *hook;
97:
98: if ((hook = hooks_find1(hooks, name)) != NULL)
99: hooks_free1(hooks, hook);
100:
101: hook = xcalloc(1, sizeof *hook);
102: hook->name = xstrdup(name);
103: hook->cmdlist = cmdlist;
104: hook->cmdlist->references++;
105: RB_INSERT(hooks_tree, &hooks->tree, hook);
106: }
107:
108: void
109: hooks_remove(struct hooks *hooks, const char *name)
110: {
111: struct hook *hook;
112:
113: if ((hook = hooks_find1(hooks, name)) != NULL)
114: hooks_free1(hooks, hook);
115: }
116:
117: static struct hook *
118: hooks_find1(struct hooks *hooks, const char *name)
119: {
120: struct hook hook;
121:
122: hook.name = name;
123: return (RB_FIND(hooks_tree, &hooks->tree, &hook));
124: }
125:
126: struct hook *
127: hooks_find(struct hooks *hooks, const char *name)
128: {
129: struct hook hook0, *hook;
130:
131: hook0.name = name;
132: hook = RB_FIND(hooks_tree, &hooks->tree, &hook0);
133: while (hook == NULL) {
134: hooks = hooks->parent;
135: if (hooks == NULL)
136: break;
137: hook = RB_FIND(hooks_tree, &hooks->tree, &hook0);
138: }
139: return (hook);
140: }
141:
142: void
143: hooks_run(struct hooks *hooks, struct client *c, struct cmd_find_state *fs,
144: const char *fmt, ...)
145: {
146: struct hook *hook;
147: va_list ap;
148: char *name;
149: struct cmdq_item *new_item;
150:
151: va_start(ap, fmt);
152: xvasprintf(&name, fmt, ap);
153: va_end(ap);
154:
155: hook = hooks_find(hooks, name);
156: if (hook == NULL) {
157: free(name);
158: return;
159: }
160: log_debug("running hook %s", name);
161:
162: new_item = cmdq_get_command(hook->cmdlist, fs, NULL, CMDQ_NOHOOKS);
163: cmdq_format(new_item, "hook", "%s", name);
164: cmdq_append(c, new_item);
165:
166: free(name);
167: }
168:
169: void
170: hooks_insert(struct hooks *hooks, struct cmdq_item *item,
171: struct cmd_find_state *fs, const char *fmt, ...)
172: {
173: struct hook *hook;
174: va_list ap;
175: char *name;
176: struct cmdq_item *new_item;
177:
178: if (item->flags & CMDQ_NOHOOKS)
179: return;
180:
181: va_start(ap, fmt);
182: xvasprintf(&name, fmt, ap);
183: va_end(ap);
184:
185: hook = hooks_find(hooks, name);
186: if (hook == NULL) {
187: free(name);
188: return;
189: }
190: log_debug("running hook %s (parent %p)", name, item);
191:
192: new_item = cmdq_get_command(hook->cmdlist, fs, NULL, CMDQ_NOHOOKS);
193: cmdq_format(new_item, "hook", "%s", name);
194: if (item != NULL)
195: cmdq_insert_after(item, new_item);
196: else
197: cmdq_append(NULL, new_item);
198:
199: free(name);
200: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>