Annotation of embedaddon/tmux/hooks.c, revision 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>