File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / tmux / hooks.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 14 12:22:44 2017 UTC (7 years ago) by misho
Branches: tmux, MAIN
CVS tags: v2_4p0, v2_4, HEAD
tmux 2.4

    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>