Allow attach-session -t to accept a window and pane to select them on
[tmux-openbsd.git] / cfg.c
blob35192dc0b43dc0f530ec4d62ec7db7b9a2b1760f
1 /* $OpenBSD$ */
3 /*
4 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
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.
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.
19 #include <sys/types.h>
20 #include <sys/stat.h>
22 #include <ctype.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
28 #include "tmux.h"
30 struct cmd_q *cfg_cmd_q;
31 int cfg_finished;
32 int cfg_references;
33 struct causelist cfg_causes;
34 struct client *cfg_client;
36 int
37 load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
39 FILE *f;
40 u_int n, found;
41 char *buf, *copy, *line, *cause1, *msg;
42 size_t len, oldlen;
43 struct cmd_list *cmdlist;
45 log_debug("loading %s", path);
46 if ((f = fopen(path, "rb")) == NULL) {
47 xasprintf(cause, "%s: %s", path, strerror(errno));
48 return (-1);
51 n = found = 0;
52 line = NULL;
53 while ((buf = fgetln(f, &len))) {
54 /* Trim \n. */
55 if (buf[len - 1] == '\n')
56 len--;
57 log_debug("%s: %.*s", path, (int)len, buf);
59 /* Current line is the continuation of the previous one. */
60 if (line != NULL) {
61 oldlen = strlen(line);
62 line = xrealloc(line, 1, oldlen + len + 1);
63 } else {
64 oldlen = 0;
65 line = xmalloc(len + 1);
68 /* Append current line to the previous. */
69 memcpy(line + oldlen, buf, len);
70 line[oldlen + len] = '\0';
71 n++;
73 /* Continuation: get next line? */
74 len = strlen(line);
75 if (len > 0 && line[len - 1] == '\\') {
76 line[len - 1] = '\0';
78 /* Ignore escaped backslash at EOL. */
79 if (len > 1 && line[len - 2] != '\\')
80 continue;
82 copy = line;
83 line = NULL;
85 /* Skip empty lines. */
86 buf = copy;
87 while (isspace((u_char)*buf))
88 buf++;
89 if (*buf == '\0') {
90 free(copy);
91 continue;
94 /* Parse and run the command. */
95 if (cmd_string_parse(buf, &cmdlist, path, n, &cause1) != 0) {
96 free(copy);
97 if (cause1 == NULL)
98 continue;
99 xasprintf(&msg, "%s:%u: %s", path, n, cause1);
100 ARRAY_ADD(&cfg_causes, msg);
101 free(cause1);
102 continue;
104 free(copy);
106 if (cmdlist == NULL)
107 continue;
108 cmdq_append(cmdq, cmdlist);
109 cmd_list_free(cmdlist);
110 found++;
112 if (line != NULL)
113 free(line);
114 fclose(f);
116 return (found);
119 void
120 cfg_default_done(unused struct cmd_q *cmdq)
122 if (--cfg_references != 0)
123 return;
124 cfg_finished = 1;
126 if (!RB_EMPTY(&sessions))
127 cfg_show_causes(RB_MIN(sessions, &sessions));
129 cmdq_free(cfg_cmd_q);
130 cfg_cmd_q = NULL;
132 if (cfg_client != NULL) {
134 * The client command queue starts with client_exit set to 1 so
135 * only continue if not empty (that is, we have been delayed
136 * during configuration parsing for long enough that the
137 * MSG_COMMAND has arrived), else the client will exit before
138 * the MSG_COMMAND which might tell it not to.
140 if (!TAILQ_EMPTY(&cfg_client->cmdq->queue))
141 cmdq_continue(cfg_client->cmdq);
142 cfg_client->references--;
143 cfg_client = NULL;
147 void
148 cfg_show_causes(struct session *s)
150 struct window_pane *wp;
151 char *cause;
152 u_int i;
154 if (s == NULL || ARRAY_EMPTY(&cfg_causes))
155 return;
156 wp = s->curw->window->active;
158 window_pane_set_mode(wp, &window_copy_mode);
159 window_copy_init_for_output(wp);
160 for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
161 cause = ARRAY_ITEM(&cfg_causes, i);
162 window_copy_add(wp, "%s", cause);
163 free(cause);
165 ARRAY_FREE(&cfg_causes);