Annotation of src/usr.bin/tmux/hooks.c, Revision 1.1
1.1 ! nicm 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_PROTOTYPE(hooks_tree, hook, entry, hooks_cmp);
! 33: RB_GENERATE(hooks_tree, hook, entry, hooks_cmp);
! 34:
! 35: struct hook *hooks_find1(struct hooks *, const char *);
! 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_create(struct hooks *parent)
! 45: {
! 46: struct hooks *hooks;
! 47:
! 48: hooks = xcalloc(1, sizeof *hooks);
! 49: RB_INIT(&hooks->tree);
! 50: hooks->parent = parent;
! 51: return (hooks);
! 52: }
! 53:
! 54: void
! 55: hooks_free(struct hooks *hooks)
! 56: {
! 57: struct hook *hook, *hook1;
! 58:
! 59: RB_FOREACH_SAFE(hook, hooks_tree, &hooks->tree, hook1)
! 60: hooks_remove(hooks, hook);
! 61: free(hooks);
! 62: }
! 63:
! 64: struct hook *
! 65: hooks_first(struct hooks *hooks)
! 66: {
! 67: return (RB_MIN(hooks_tree, &hooks->tree));
! 68: }
! 69:
! 70: struct hook *
! 71: hooks_next(struct hook *hook)
! 72: {
! 73: return (RB_NEXT(hooks_tree, &hooks->tree, hook));
! 74: }
! 75:
! 76: void
! 77: hooks_add(struct hooks *hooks, const char *name, struct cmd_list *cmdlist)
! 78: {
! 79: struct hook *hook;
! 80:
! 81: if ((hook = hooks_find1(hooks, name)) != NULL)
! 82: hooks_remove(hooks, hook);
! 83:
! 84: hook = xcalloc(1, sizeof *hook);
! 85: hook->name = xstrdup(name);
! 86: hook->cmdlist = cmdlist;
! 87: hook->cmdlist->references++;
! 88: RB_INSERT(hooks_tree, &hooks->tree, hook);
! 89: }
! 90:
! 91: void
! 92: hooks_remove(struct hooks *hooks, struct hook *hook)
! 93: {
! 94: RB_REMOVE(hooks_tree, &hooks->tree, hook);
! 95: cmd_list_free(hook->cmdlist);
! 96: free((char *) hook->name);
! 97: free(hook);
! 98: }
! 99:
! 100: struct hook *
! 101: hooks_find1(struct hooks *hooks, const char *name)
! 102: {
! 103: struct hook hook;
! 104:
! 105: hook.name = name;
! 106: return (RB_FIND(hooks_tree, &hooks->tree, &hook));
! 107: }
! 108:
! 109: struct hook *
! 110: hooks_find(struct hooks *hooks, const char *name)
! 111: {
! 112: struct hook hook0, *hook;
! 113:
! 114: hook0.name = name;
! 115: hook = RB_FIND(hooks_tree, &hooks->tree, &hook0);
! 116: while (hook == NULL) {
! 117: hooks = hooks->parent;
! 118: if (hooks == NULL)
! 119: break;
! 120: hook = RB_FIND(hooks_tree, &hooks->tree, &hook0);
! 121: }
! 122: return (hook);
! 123: }
! 124:
! 125: void
! 126: hooks_run(struct hooks *hooks, const char *name, struct client *c)
! 127: {
! 128: struct hook *hook;
! 129: struct cmd_q *cmdq;
! 130:
! 131: hook = hooks_find(hooks, name);
! 132: if (hook == NULL)
! 133: return;
! 134: log_debug("running hook %s", name);
! 135:
! 136: cmdq = cmdq_new(c);
! 137: cmdq_run(cmdq, hook->cmdlist, NULL);
! 138: cmdq_free(cmdq);
! 139: }