Annotation of embedaddon/tmux/cfg.c, revision 1.1
1.1 ! misho 1: /* $OpenBSD$ */
! 2:
! 3: /*
! 4: * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
! 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 <ctype.h>
! 22: #include <errno.h>
! 23: #include <stdio.h>
! 24: #include <stdlib.h>
! 25: #include <string.h>
! 26: #include <unistd.h>
! 27:
! 28: #include "tmux.h"
! 29:
! 30: static char *cfg_file;
! 31: int cfg_finished;
! 32: static char **cfg_causes;
! 33: static u_int cfg_ncauses;
! 34: struct client *cfg_client;
! 35:
! 36: static enum cmd_retval
! 37: cfg_done(__unused struct cmdq_item *item, __unused void *data)
! 38: {
! 39: if (cfg_finished)
! 40: return (CMD_RETURN_NORMAL);
! 41: cfg_finished = 1;
! 42:
! 43: if (!RB_EMPTY(&sessions))
! 44: cfg_show_causes(RB_MIN(sessions, &sessions));
! 45:
! 46: if (cfg_client != NULL)
! 47: server_client_unref(cfg_client);
! 48: return (CMD_RETURN_NORMAL);
! 49: }
! 50:
! 51: void
! 52: set_cfg_file(const char *path)
! 53: {
! 54: free(cfg_file);
! 55: cfg_file = xstrdup(path);
! 56: }
! 57:
! 58: void
! 59: start_cfg(void)
! 60: {
! 61: const char *home;
! 62: int quiet = 0;
! 63:
! 64: cfg_client = TAILQ_FIRST(&clients);
! 65: if (cfg_client != NULL)
! 66: cfg_client->references++;
! 67:
! 68: load_cfg(TMUX_CONF, cfg_client, NULL, 1);
! 69:
! 70: if (cfg_file == NULL && (home = find_home()) != NULL) {
! 71: xasprintf(&cfg_file, "%s/.tmux.conf", home);
! 72: quiet = 1;
! 73: }
! 74: if (cfg_file != NULL)
! 75: load_cfg(cfg_file, cfg_client, NULL, quiet);
! 76:
! 77: cmdq_append(cfg_client, cmdq_get_callback(cfg_done, NULL));
! 78: }
! 79:
! 80: int
! 81: load_cfg(const char *path, struct client *c, struct cmdq_item *item, int quiet)
! 82: {
! 83: FILE *f;
! 84: const char delim[3] = { '\\', '\\', '\0' };
! 85: u_int found = 0;
! 86: size_t line = 0;
! 87: char *buf, *cause1, *p, *q, *s;
! 88: struct cmd_list *cmdlist;
! 89: struct cmdq_item *new_item;
! 90: int condition = 0;
! 91: struct format_tree *ft;
! 92:
! 93: log_debug("loading %s", path);
! 94: if ((f = fopen(path, "rb")) == NULL) {
! 95: if (errno == ENOENT && quiet)
! 96: return (0);
! 97: cfg_add_cause("%s: %s", path, strerror(errno));
! 98: return (-1);
! 99: }
! 100:
! 101: while ((buf = fparseln(f, NULL, &line, delim, 0)) != NULL) {
! 102: log_debug("%s: %s", path, buf);
! 103:
! 104: p = buf;
! 105: while (isspace((u_char)*p))
! 106: p++;
! 107: if (*p == '\0') {
! 108: free(buf);
! 109: continue;
! 110: }
! 111: q = p + strlen(p) - 1;
! 112: while (q != p && isspace((u_char)*q))
! 113: *q-- = '\0';
! 114:
! 115: if (condition != 0 && strcmp(p, "%endif") == 0) {
! 116: condition = 0;
! 117: continue;
! 118: }
! 119: if (strncmp(p, "%if ", 4) == 0) {
! 120: if (condition != 0) {
! 121: cfg_add_cause("%s:%zu: nested %%if", path,
! 122: line);
! 123: continue;
! 124: }
! 125: ft = format_create(NULL, FORMAT_NONE, FORMAT_NOJOBS);
! 126:
! 127: s = p + 3;
! 128: while (isspace((u_char)*s))
! 129: s++;
! 130: s = format_expand(ft, s);
! 131: if (*s != '\0' && (s[0] != '0' || s[1] != '\0'))
! 132: condition = 1;
! 133: else
! 134: condition = -1;
! 135: free(s);
! 136:
! 137: format_free(ft);
! 138: continue;
! 139: }
! 140: if (condition == -1)
! 141: continue;
! 142:
! 143: cmdlist = cmd_string_parse(p, path, line, &cause1);
! 144: if (cmdlist == NULL) {
! 145: free(buf);
! 146: if (cause1 == NULL)
! 147: continue;
! 148: cfg_add_cause("%s:%zu: %s", path, line, cause1);
! 149: free(cause1);
! 150: continue;
! 151: }
! 152: free(buf);
! 153:
! 154: if (cmdlist == NULL)
! 155: continue;
! 156: new_item = cmdq_get_command(cmdlist, NULL, NULL, 0);
! 157: if (item != NULL)
! 158: cmdq_insert_after(item, new_item);
! 159: else
! 160: cmdq_append(c, new_item);
! 161: cmd_list_free(cmdlist);
! 162:
! 163: found++;
! 164: }
! 165: fclose(f);
! 166:
! 167: return (found);
! 168: }
! 169:
! 170: void
! 171: cfg_add_cause(const char *fmt, ...)
! 172: {
! 173: va_list ap;
! 174: char *msg;
! 175:
! 176: va_start(ap, fmt);
! 177: xvasprintf(&msg, fmt, ap);
! 178: va_end(ap);
! 179:
! 180: cfg_ncauses++;
! 181: cfg_causes = xreallocarray(cfg_causes, cfg_ncauses, sizeof *cfg_causes);
! 182: cfg_causes[cfg_ncauses - 1] = msg;
! 183: }
! 184:
! 185: void
! 186: cfg_print_causes(struct cmdq_item *item)
! 187: {
! 188: u_int i;
! 189:
! 190: for (i = 0; i < cfg_ncauses; i++) {
! 191: cmdq_print(item, "%s", cfg_causes[i]);
! 192: free(cfg_causes[i]);
! 193: }
! 194:
! 195: free(cfg_causes);
! 196: cfg_causes = NULL;
! 197: cfg_ncauses = 0;
! 198: }
! 199:
! 200: void
! 201: cfg_show_causes(struct session *s)
! 202: {
! 203: struct window_pane *wp;
! 204: u_int i;
! 205:
! 206: if (s == NULL || cfg_ncauses == 0)
! 207: return;
! 208: wp = s->curw->window->active;
! 209:
! 210: window_pane_set_mode(wp, &window_copy_mode);
! 211: window_copy_init_for_output(wp);
! 212: for (i = 0; i < cfg_ncauses; i++) {
! 213: window_copy_add(wp, "%s", cfg_causes[i]);
! 214: free(cfg_causes[i]);
! 215: }
! 216:
! 217: free(cfg_causes);
! 218: cfg_causes = NULL;
! 219: cfg_ncauses = 0;
! 220: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>