Remove building with NOCRYPTO option
[minix.git] / external / bsd / tmux / dist / cmd-set-option.c
blob271b37597f36c03455620c7df32cabcefebdf962
1 /* Id */
3 /*
4 * Copyright (c) 2007 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>
21 #include <stdlib.h>
22 #include <string.h>
24 #include "tmux.h"
27 * Set an option.
30 enum cmd_retval cmd_set_option_exec(struct cmd *, struct cmd_q *);
32 enum cmd_retval cmd_set_option_user(struct cmd *, struct cmd_q *,
33 const char *, const char *);
35 int cmd_set_option_unset(struct cmd *, struct cmd_q *,
36 const struct options_table_entry *, struct options *,
37 const char *);
38 int cmd_set_option_set(struct cmd *, struct cmd_q *,
39 const struct options_table_entry *, struct options *,
40 const char *);
42 struct options_entry *cmd_set_option_string(struct cmd *, struct cmd_q *,
43 const struct options_table_entry *, struct options *,
44 const char *);
45 struct options_entry *cmd_set_option_number(struct cmd *, struct cmd_q *,
46 const struct options_table_entry *, struct options *,
47 const char *);
48 struct options_entry *cmd_set_option_key(struct cmd *, struct cmd_q *,
49 const struct options_table_entry *, struct options *,
50 const char *);
51 struct options_entry *cmd_set_option_colour(struct cmd *, struct cmd_q *,
52 const struct options_table_entry *, struct options *,
53 const char *);
54 struct options_entry *cmd_set_option_attributes(struct cmd *, struct cmd_q *,
55 const struct options_table_entry *, struct options *,
56 const char *);
57 struct options_entry *cmd_set_option_flag(struct cmd *, struct cmd_q *,
58 const struct options_table_entry *, struct options *,
59 const char *);
60 struct options_entry *cmd_set_option_choice(struct cmd *, struct cmd_q *,
61 const struct options_table_entry *, struct options *,
62 const char *);
63 struct options_entry *cmd_set_option_style(struct cmd *, struct cmd_q *,
64 const struct options_table_entry *, struct options *,
65 const char *);
67 const struct cmd_entry cmd_set_option_entry = {
68 "set-option", "set",
69 "agoqst:uw", 1, 2,
70 "[-agosquw] [-t target-session|target-window] option [value]",
72 NULL,
73 cmd_set_option_exec
76 const struct cmd_entry cmd_set_window_option_entry = {
77 "set-window-option", "setw",
78 "agoqt:u", 1, 2,
79 "[-agoqu] " CMD_TARGET_WINDOW_USAGE " option [value]",
81 NULL,
82 cmd_set_option_exec
85 enum cmd_retval
86 cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
88 struct args *args = self->args;
89 const struct options_table_entry *table, *oe;
90 struct session *s;
91 struct winlink *wl;
92 struct client *c;
93 struct options *oo;
94 struct window *w;
95 const char *optstr, *valstr;
96 u_int i;
98 /* Get the option name and value. */
99 optstr = args->argv[0];
100 if (*optstr == '\0') {
101 cmdq_error(cmdq, "invalid option");
102 return (CMD_RETURN_ERROR);
104 if (args->argc < 2)
105 valstr = NULL;
106 else
107 valstr = args->argv[1];
109 /* Is this a user option? */
110 if (*optstr == '@')
111 return (cmd_set_option_user(self, cmdq, optstr, valstr));
113 /* Find the option entry, try each table. */
114 table = oe = NULL;
115 if (options_table_find(optstr, &table, &oe) != 0) {
116 cmdq_error(cmdq, "ambiguous option: %s", optstr);
117 return (CMD_RETURN_ERROR);
119 if (oe == NULL) {
120 cmdq_error(cmdq, "unknown option: %s", optstr);
121 return (CMD_RETURN_ERROR);
124 /* Work out the tree from the table. */
125 if (table == server_options_table)
126 oo = &global_options;
127 else if (table == window_options_table) {
128 if (args_has(self->args, 'g'))
129 oo = &global_w_options;
130 else {
131 wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
132 if (wl == NULL) {
133 cmdq_error(cmdq,
134 "couldn't set '%s'%s", optstr,
135 (!args_has(args, 't') && !args_has(args,
136 'g')) ? " need target window or -g" : "");
137 return (CMD_RETURN_ERROR);
139 oo = &wl->window->options;
141 } else if (table == session_options_table) {
142 if (args_has(self->args, 'g'))
143 oo = &global_s_options;
144 else {
145 s = cmd_find_session(cmdq, args_get(args, 't'), 0);
146 if (s == NULL) {
147 cmdq_error(cmdq,
148 "couldn't set '%s'%s", optstr,
149 (!args_has(args, 't') && !args_has(args,
150 'g')) ? " need target session or -g" : "");
151 return (CMD_RETURN_ERROR);
153 oo = &s->options;
155 } else {
156 cmdq_error(cmdq, "unknown table");
157 return (CMD_RETURN_ERROR);
160 /* Unset or set the option. */
161 if (args_has(args, 'u')) {
162 if (cmd_set_option_unset(self, cmdq, oe, oo, valstr) != 0)
163 return (CMD_RETURN_ERROR);
164 } else {
165 if (args_has(args, 'o') && options_find1(oo, optstr) != NULL) {
166 if (!args_has(args, 'q'))
167 cmdq_print(cmdq, "already set: %s", optstr);
168 return (CMD_RETURN_NORMAL);
170 if (cmd_set_option_set(self, cmdq, oe, oo, valstr) != 0)
171 return (CMD_RETURN_ERROR);
174 /* Start or stop timers when automatic-rename changed. */
175 if (strcmp(oe->name, "automatic-rename") == 0) {
176 for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
177 if ((w = ARRAY_ITEM(&windows, i)) == NULL)
178 continue;
179 if (options_get_number(&w->options, "automatic-rename"))
180 queue_window_name(w);
181 else if (event_initialized(&w->name_timer))
182 evtimer_del(&w->name_timer);
186 /* Update sizes and redraw. May not need it but meh. */
187 recalculate_sizes();
188 for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
189 c = ARRAY_ITEM(&clients, i);
190 if (c != NULL && c->session != NULL)
191 server_redraw_client(c);
194 return (CMD_RETURN_NORMAL);
197 /* Set user option. */
198 enum cmd_retval
199 cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr,
200 const char *valstr)
202 struct args *args = self->args;
203 struct session *s;
204 struct winlink *wl;
205 struct options *oo;
207 if (args_has(args, 's'))
208 oo = &global_options;
209 else if (args_has(self->args, 'w') ||
210 self->entry == &cmd_set_window_option_entry) {
211 if (args_has(self->args, 'g'))
212 oo = &global_w_options;
213 else {
214 wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
215 if (wl == NULL)
216 return (CMD_RETURN_ERROR);
217 oo = &wl->window->options;
219 } else {
220 if (args_has(self->args, 'g'))
221 oo = &global_s_options;
222 else {
223 s = cmd_find_session(cmdq, args_get(args, 't'), 0);
224 if (s == NULL)
225 return (CMD_RETURN_ERROR);
226 oo = &s->options;
230 if (args_has(args, 'u')) {
231 if (options_find1(oo, optstr) == NULL) {
232 cmdq_error(cmdq, "unknown option: %s", optstr);
233 return (CMD_RETURN_ERROR);
235 if (valstr != NULL) {
236 cmdq_error(cmdq, "value passed to unset option: %s",
237 optstr);
238 return (CMD_RETURN_ERROR);
240 options_remove(oo, optstr);
241 } else {
242 if (valstr == NULL) {
243 cmdq_error(cmdq, "empty value");
244 return (CMD_RETURN_ERROR);
246 if (args_has(args, 'o') && options_find1(oo, optstr) != NULL) {
247 if (!args_has(args, 'q'))
248 cmdq_print(cmdq, "already set: %s", optstr);
249 return (CMD_RETURN_NORMAL);
251 options_set_string(oo, optstr, "%s", valstr);
252 if (!args_has(args, 'q')) {
253 cmdq_info(cmdq, "set option: %s -> %s", optstr,
254 valstr);
257 return (CMD_RETURN_NORMAL);
261 /* Unset an option. */
263 cmd_set_option_unset(struct cmd *self, struct cmd_q *cmdq,
264 const struct options_table_entry *oe, struct options *oo, const char *value)
266 struct args *args = self->args;
268 if (args_has(args, 'g')) {
269 cmdq_error(cmdq, "can't unset global option: %s", oe->name);
270 return (-1);
272 if (value != NULL) {
273 cmdq_error(cmdq, "value passed to unset option: %s", oe->name);
274 return (-1);
277 options_remove(oo, oe->name);
278 if (!args_has(args, 'q'))
279 cmdq_info(cmdq, "unset option: %s", oe->name);
280 return (0);
283 /* Set an option. */
285 cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
286 const struct options_table_entry *oe, struct options *oo, const char *value)
288 struct args *args = self->args;
289 struct options_entry *o;
290 const char *s;
292 if (oe->type != OPTIONS_TABLE_FLAG && value == NULL) {
293 cmdq_error(cmdq, "empty value");
294 return (-1);
297 o = NULL;
298 switch (oe->type) {
299 case OPTIONS_TABLE_STRING:
300 o = cmd_set_option_string(self, cmdq, oe, oo, value);
301 break;
302 case OPTIONS_TABLE_NUMBER:
303 o = cmd_set_option_number(self, cmdq, oe, oo, value);
304 break;
305 case OPTIONS_TABLE_KEY:
306 o = cmd_set_option_key(self, cmdq, oe, oo, value);
307 break;
308 case OPTIONS_TABLE_COLOUR:
309 o = cmd_set_option_colour(self, cmdq, oe, oo, value);
310 if (o != NULL)
311 style_update_new(oo, o->name, oe->style);
312 break;
313 case OPTIONS_TABLE_ATTRIBUTES:
314 o = cmd_set_option_attributes(self, cmdq, oe, oo, value);
315 if (o != NULL)
316 style_update_new(oo, o->name, oe->style);
317 break;
318 case OPTIONS_TABLE_FLAG:
319 o = cmd_set_option_flag(self, cmdq, oe, oo, value);
320 break;
321 case OPTIONS_TABLE_CHOICE:
322 o = cmd_set_option_choice(self, cmdq, oe, oo, value);
323 break;
324 case OPTIONS_TABLE_STYLE:
325 o = cmd_set_option_style(self, cmdq, oe, oo, value);
326 break;
328 if (o == NULL)
329 return (-1);
331 s = options_table_print_entry(oe, o, 0);
332 if (!args_has(args, 'q'))
333 cmdq_info(cmdq, "set option: %s -> %s", oe->name, s);
334 return (0);
337 /* Set a string option. */
338 struct options_entry *
339 cmd_set_option_string(struct cmd *self, unused struct cmd_q *cmdq,
340 const struct options_table_entry *oe, struct options *oo, const char *value)
342 struct args *args = self->args;
343 struct options_entry *o;
344 char *oldval, *newval;
346 if (args_has(args, 'a')) {
347 oldval = options_get_string(oo, oe->name);
348 xasprintf(&newval, "%s%s", oldval, value);
349 } else
350 newval = xstrdup(value);
352 o = options_set_string(oo, oe->name, "%s", newval);
354 free(newval);
355 return (o);
358 /* Set a number option. */
359 struct options_entry *
360 cmd_set_option_number(unused struct cmd *self, struct cmd_q *cmdq,
361 const struct options_table_entry *oe, struct options *oo, const char *value)
363 long long ll;
364 const char *errstr;
366 ll = strtonum(value, oe->minimum, oe->maximum, &errstr);
367 if (errstr != NULL) {
368 cmdq_error(cmdq, "value is %s: %s", errstr, value);
369 return (NULL);
372 return (options_set_number(oo, oe->name, ll));
375 /* Set a key option. */
376 struct options_entry *
377 cmd_set_option_key(unused struct cmd *self, struct cmd_q *cmdq,
378 const struct options_table_entry *oe, struct options *oo, const char *value)
380 int key;
382 if ((key = key_string_lookup_string(value)) == KEYC_NONE) {
383 cmdq_error(cmdq, "bad key: %s", value);
384 return (NULL);
387 return (options_set_number(oo, oe->name, key));
390 /* Set a colour option. */
391 struct options_entry *
392 cmd_set_option_colour(unused struct cmd *self, struct cmd_q *cmdq,
393 const struct options_table_entry *oe, struct options *oo, const char *value)
395 int colour;
397 if ((colour = colour_fromstring(value)) == -1) {
398 cmdq_error(cmdq, "bad colour: %s", value);
399 return (NULL);
402 return (options_set_number(oo, oe->name, colour));
405 /* Set an attributes option. */
406 struct options_entry *
407 cmd_set_option_attributes(unused struct cmd *self, struct cmd_q *cmdq,
408 const struct options_table_entry *oe, struct options *oo, const char *value)
410 int attr;
412 if ((attr = attributes_fromstring(value)) == -1) {
413 cmdq_error(cmdq, "bad attributes: %s", value);
414 return (NULL);
417 return (options_set_number(oo, oe->name, attr));
420 /* Set a flag option. */
421 struct options_entry *
422 cmd_set_option_flag(unused struct cmd *self, struct cmd_q *cmdq,
423 const struct options_table_entry *oe, struct options *oo, const char *value)
425 int flag;
427 if (value == NULL || *value == '\0')
428 flag = !options_get_number(oo, oe->name);
429 else {
430 if ((value[0] == '1' && value[1] == '\0') ||
431 strcasecmp(value, "on") == 0 ||
432 strcasecmp(value, "yes") == 0)
433 flag = 1;
434 else if ((value[0] == '0' && value[1] == '\0') ||
435 strcasecmp(value, "off") == 0 ||
436 strcasecmp(value, "no") == 0)
437 flag = 0;
438 else {
439 cmdq_error(cmdq, "bad value: %s", value);
440 return (NULL);
444 return (options_set_number(oo, oe->name, flag));
447 /* Set a choice option. */
448 struct options_entry *
449 cmd_set_option_choice(unused struct cmd *self, struct cmd_q *cmdq,
450 const struct options_table_entry *oe, struct options *oo,
451 const char *value)
453 const char **choicep;
454 int n, choice = -1;
456 n = 0;
457 for (choicep = oe->choices; *choicep != NULL; choicep++) {
458 n++;
459 if (strncmp(*choicep, value, strlen(value)) != 0)
460 continue;
462 if (choice != -1) {
463 cmdq_error(cmdq, "ambiguous value: %s", value);
464 return (NULL);
466 choice = n - 1;
468 if (choice == -1) {
469 cmdq_error(cmdq, "unknown value: %s", value);
470 return (NULL);
473 return (options_set_number(oo, oe->name, choice));
476 /* Set a style option. */
477 struct options_entry *
478 cmd_set_option_style(struct cmd *self, struct cmd_q *cmdq,
479 const struct options_table_entry *oe, struct options *oo,
480 const char *value)
482 struct args *args = self->args;
483 struct options_entry *o;
484 int append;
486 append = args_has(args, 'a');
487 if ((o = options_set_style(oo, oe->name, value, append)) == NULL) {
488 cmdq_error(cmdq, "bad style: %s", value);
489 return (NULL);
492 style_update_old(oo, oe->name, &o->style);
493 return (o);