xref: /openbsd-src/usr.bin/tmux/cmd-show-options.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /* $OpenBSD: cmd-show-options.c,v 1.31 2016/03/03 14:15:22 nicm Exp $ */
2 
3 /*
4  * Copyright (c) 2007 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 <stdlib.h>
22 #include <string.h>
23 
24 #include "tmux.h"
25 
26 /*
27  * Show options.
28  */
29 
30 enum cmd_retval	 cmd_show_options_exec(struct cmd *, struct cmd_q *);
31 
32 enum cmd_retval	cmd_show_options_one(struct cmd *, struct cmd_q *,
33 		    struct options *, int);
34 enum cmd_retval cmd_show_options_all(struct cmd *, struct cmd_q *,
35 	    	    struct options *, enum options_table_scope);
36 
37 const struct cmd_entry cmd_show_options_entry = {
38 	.name = "show-options",
39 	.alias = "show",
40 
41 	.args = { "gqst:vw", 0, 1 },
42 	.usage = "[-gqsvw] [-t target-session|target-window] [option]",
43 
44 	.tflag = CMD_WINDOW_CANFAIL,
45 
46 	.flags = 0,
47 	.exec = cmd_show_options_exec
48 };
49 
50 const struct cmd_entry cmd_show_window_options_entry = {
51 	.name = "show-window-options",
52 	.alias = "showw",
53 
54 	.args = { "gvt:", 0, 1 },
55 	.usage = "[-gv] " CMD_TARGET_WINDOW_USAGE " [option]",
56 
57 	.tflag = CMD_WINDOW_CANFAIL,
58 
59 	.flags = 0,
60 	.exec = cmd_show_options_exec
61 };
62 
63 enum cmd_retval
64 cmd_show_options_exec(struct cmd *self, struct cmd_q *cmdq)
65 {
66 	struct args			*args = self->args;
67 	struct session			*s = cmdq->state.tflag.s;
68 	struct winlink			*wl = cmdq->state.tflag.wl;
69 	struct options			*oo;
70 	enum options_table_scope	 scope;
71 	int				 quiet;
72 	const char			*target;
73 
74 	if (args_has(self->args, 's')) {
75 		oo = global_options;
76 		scope = OPTIONS_TABLE_SERVER;
77 	} else if (args_has(self->args, 'w') ||
78 	    self->entry == &cmd_show_window_options_entry) {
79 		scope = OPTIONS_TABLE_WINDOW;
80 		if (args_has(self->args, 'g'))
81 			oo = global_w_options;
82 		else if (wl == NULL) {
83 			target = args_get(args, 't');
84 			if (target != NULL) {
85 				cmdq_error(cmdq, "no such window: %s", target);
86 			} else
87 				cmdq_error(cmdq, "no current window");
88 			return (CMD_RETURN_ERROR);
89 		} else
90 			oo = wl->window->options;
91 	} else {
92 		scope = OPTIONS_TABLE_SESSION;
93 		if (args_has(self->args, 'g'))
94 			oo = global_s_options;
95 		else if (s == NULL) {
96 			target = args_get(args, 't');
97 			if (target != NULL) {
98 				cmdq_error(cmdq, "no such session: %s", target);
99 			} else
100 				cmdq_error(cmdq, "no current session");
101 			return (CMD_RETURN_ERROR);
102 		} else
103 			oo = s->options;
104 	}
105 
106 	quiet = args_has(self->args, 'q');
107 	if (args->argc == 0)
108 		return (cmd_show_options_all(self, cmdq, oo, scope));
109 	else
110 		return (cmd_show_options_one(self, cmdq, oo, quiet));
111 }
112 
113 enum cmd_retval
114 cmd_show_options_one(struct cmd *self, struct cmd_q *cmdq,
115     struct options *oo, int quiet)
116 {
117 	struct args				*args = self->args;
118 	const char				*name = args->argv[0];
119 	const struct options_table_entry	*oe;
120 	struct options_entry			*o;
121 	const char				*optval;
122 
123 retry:
124 	if (*name == '@') {
125 		if ((o = options_find1(oo, name)) == NULL) {
126 			if (quiet)
127 				return (CMD_RETURN_NORMAL);
128 			cmdq_error(cmdq, "unknown option: %s", name);
129 			return (CMD_RETURN_ERROR);
130 		}
131 		if (args_has(self->args, 'v'))
132 			cmdq_print(cmdq, "%s", o->str);
133 		else
134 			cmdq_print(cmdq, "%s \"%s\"", o->name, o->str);
135 		return (CMD_RETURN_NORMAL);
136 	}
137 
138 	oe = NULL;
139 	if (options_table_find(name, &oe) != 0) {
140 		cmdq_error(cmdq, "ambiguous option: %s", name);
141 		return (CMD_RETURN_ERROR);
142 	}
143 	if (oe == NULL) {
144 		if (quiet)
145 			return (CMD_RETURN_NORMAL);
146 		cmdq_error(cmdq, "unknown option: %s", name);
147 		return (CMD_RETURN_ERROR);
148 	}
149 	if (oe->style != NULL) {
150 		name = oe->style;
151 		goto retry;
152 	}
153 	if ((o = options_find1(oo, oe->name)) == NULL)
154 		return (CMD_RETURN_NORMAL);
155 	optval = options_table_print_entry(oe, o, args_has(self->args, 'v'));
156 	if (args_has(self->args, 'v'))
157 		cmdq_print(cmdq, "%s", optval);
158 	else
159 		cmdq_print(cmdq, "%s %s", oe->name, optval);
160 	return (CMD_RETURN_NORMAL);
161 }
162 
163 enum cmd_retval
164 cmd_show_options_all(struct cmd *self, struct cmd_q *cmdq, struct options *oo,
165     enum options_table_scope scope)
166 {
167 	const struct options_table_entry	*oe;
168 	struct options_entry			*o;
169 	const char				*optval;
170 	int					 vflag;
171 
172 	o = options_first(oo);
173 	while (o != NULL) {
174 		if (*o->name == '@') {
175 			if (args_has(self->args, 'v'))
176 				cmdq_print(cmdq, "%s", o->str);
177 			else
178 				cmdq_print(cmdq, "%s \"%s\"", o->name, o->str);
179 		}
180 		o = options_next(o);
181 	}
182 
183 	vflag = args_has(self->args, 'v');
184 	for (oe = options_table; oe->name != NULL; oe++) {
185 		if (oe->style != NULL || oe->scope != scope)
186 			continue;
187 		if ((o = options_find1(oo, oe->name)) == NULL)
188 			continue;
189 		optval = options_table_print_entry(oe, o, vflag);
190 		if (vflag)
191 			cmdq_print(cmdq, "%s", optval);
192 		else
193 			cmdq_print(cmdq, "%s %s", oe->name, optval);
194 	}
195 
196 	return (CMD_RETURN_NORMAL);
197 }
198