version 1.42, 2010/12/30 23:16:18 |
version 1.43, 2011/01/01 16:51:21 |
|
|
|
|
int cmd_set_option_exec(struct cmd *, struct cmd_ctx *); |
int cmd_set_option_exec(struct cmd *, struct cmd_ctx *); |
|
|
const char *cmd_set_option_print( |
int cmd_set_option_unset(struct cmd *, struct cmd_ctx *, |
const struct set_option_entry *, struct options_entry *); |
const struct options_table_entry *, struct options *); |
void cmd_set_option_string(struct cmd_ctx *, |
int cmd_set_option_set(struct cmd *, struct cmd_ctx *, |
struct options *, const struct set_option_entry *, char *, int); |
const struct options_table_entry *, struct options *); |
void cmd_set_option_number(struct cmd_ctx *, |
|
struct options *, const struct set_option_entry *, char *); |
|
void cmd_set_option_keys(struct cmd_ctx *, |
|
struct options *, const struct set_option_entry *, char *); |
|
void cmd_set_option_colour(struct cmd_ctx *, |
|
struct options *, const struct set_option_entry *, char *); |
|
void cmd_set_option_attributes(struct cmd_ctx *, |
|
struct options *, const struct set_option_entry *, char *); |
|
void cmd_set_option_flag(struct cmd_ctx *, |
|
struct options *, const struct set_option_entry *, char *); |
|
void cmd_set_option_choice(struct cmd_ctx *, |
|
struct options *, const struct set_option_entry *, char *); |
|
|
|
|
struct options_entry *cmd_set_option_string(struct cmd *, struct cmd_ctx *, |
|
const struct options_table_entry *, struct options *); |
|
struct options_entry *cmd_set_option_number(struct cmd *, struct cmd_ctx *, |
|
const struct options_table_entry *, struct options *); |
|
struct options_entry *cmd_set_option_keys(struct cmd *, struct cmd_ctx *, |
|
const struct options_table_entry *, struct options *); |
|
struct options_entry *cmd_set_option_colour(struct cmd *, struct cmd_ctx *, |
|
const struct options_table_entry *, struct options *); |
|
struct options_entry *cmd_set_option_attributes(struct cmd *, struct cmd_ctx *, |
|
const struct options_table_entry *, struct options *); |
|
struct options_entry *cmd_set_option_flag(struct cmd *, struct cmd_ctx *, |
|
const struct options_table_entry *, struct options *); |
|
struct options_entry *cmd_set_option_choice(struct cmd *, struct cmd_ctx *, |
|
const struct options_table_entry *, struct options *); |
|
|
const struct cmd_entry cmd_set_option_entry = { |
const struct cmd_entry cmd_set_option_entry = { |
"set-option", "set", |
"set-option", "set", |
"[-agsuw] [-t target-session|target-window] option [value]", |
"[-agsuw] [-t target-session|target-window] option [value]", |
|
|
cmd_target_print |
cmd_target_print |
}; |
}; |
|
|
const char *set_option_mode_keys_list[] = { |
|
"emacs", "vi", NULL |
|
}; |
|
const char *set_option_clock_mode_style_list[] = { |
|
"12", "24", NULL |
|
}; |
|
const char *set_option_status_keys_list[] = { |
|
"emacs", "vi", NULL |
|
}; |
|
const char *set_option_status_justify_list[] = { |
|
"left", "centre", "right", NULL |
|
}; |
|
const char *set_option_bell_action_list[] = { |
|
"none", "any", "current", NULL |
|
}; |
|
|
|
const struct set_option_entry set_option_table[] = { |
|
{ "buffer-limit", SET_OPTION_NUMBER, 1, INT_MAX, NULL }, |
|
{ "escape-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, |
|
{ "exit-unattached", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "quiet", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ NULL, 0, 0, 0, NULL } |
|
}; |
|
|
|
const struct set_option_entry set_session_option_table[] = { |
|
{ "base-index", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, |
|
{ "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list }, |
|
{ "default-command", SET_OPTION_STRING, 0, 0, NULL }, |
|
{ "default-path", SET_OPTION_STRING, 0, 0, NULL }, |
|
{ "default-shell", SET_OPTION_STRING, 0, 0, NULL }, |
|
{ "default-terminal", SET_OPTION_STRING, 0, 0, NULL }, |
|
{ "destroy-unattached", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "detach-on-destroy", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "display-panes-active-colour", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "display-panes-colour", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "display-panes-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL }, |
|
{ "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL }, |
|
{ "history-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, |
|
{ "lock-after-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, |
|
{ "lock-command", SET_OPTION_STRING, 0, 0, NULL }, |
|
{ "lock-server", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "message-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, |
|
{ "message-bg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "message-fg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "message-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, |
|
{ "mouse-select-pane", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "pane-active-border-bg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "pane-active-border-fg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "pane-border-bg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "pane-border-fg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "prefix", SET_OPTION_KEYS, 0, 0, NULL }, |
|
{ "repeat-time", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL }, |
|
{ "set-remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "set-titles", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "set-titles-string", SET_OPTION_STRING, 0, 0, NULL }, |
|
{ "status", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, |
|
{ "status-bg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "status-fg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "status-interval", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, |
|
{ "status-justify", |
|
SET_OPTION_CHOICE, 0, 0, set_option_status_justify_list }, |
|
{ "status-keys", SET_OPTION_CHOICE, 0, 0, set_option_status_keys_list }, |
|
{ "status-left", SET_OPTION_STRING, 0, 0, NULL }, |
|
{ "status-left-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, |
|
{ "status-left-bg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "status-left-fg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "status-left-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL }, |
|
{ "status-right", SET_OPTION_STRING, 0, 0, NULL }, |
|
{ "status-right-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, |
|
{ "status-right-bg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "status-right-fg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "status-right-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL }, |
|
{ "status-utf8", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "terminal-overrides", SET_OPTION_STRING, 0, 0, NULL }, |
|
{ "update-environment", SET_OPTION_STRING, 0, 0, NULL }, |
|
{ "visual-activity", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "visual-bell", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "visual-content", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "visual-silence", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ NULL, 0, 0, 0, NULL } |
|
}; |
|
|
|
const struct set_option_entry set_window_option_table[] = { |
|
{ "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "alternate-screen", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "automatic-rename", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "clock-mode-colour", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "clock-mode-style", |
|
SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list }, |
|
{ "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, |
|
{ "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, |
|
{ "main-pane-height", SET_OPTION_NUMBER, 1, INT_MAX, NULL }, |
|
{ "main-pane-width", SET_OPTION_NUMBER, 1, INT_MAX, NULL }, |
|
{ "mode-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, |
|
{ "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list }, |
|
{ "mode-mouse", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "monitor-content", SET_OPTION_STRING, 0, 0, NULL }, |
|
{ "monitor-silence",SET_OPTION_NUMBER, 0, INT_MAX, NULL}, |
|
{ "other-pane-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, |
|
{ "other-pane-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, |
|
{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "synchronize-panes", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "utf8", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ "window-status-alert-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, |
|
{ "window-status-alert-bg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "window-status-alert-fg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, |
|
{ "window-status-bg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "window-status-current-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, |
|
{ "window-status-current-bg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "window-status-current-fg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "window-status-current-format", SET_OPTION_STRING, 0, 0, NULL }, |
|
{ "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL }, |
|
{ "window-status-format", SET_OPTION_STRING, 0, 0, NULL }, |
|
{ "word-separators", SET_OPTION_STRING, 0, 0, NULL }, |
|
{ "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL }, |
|
{ NULL, 0, 0, 0, NULL } |
|
}; |
|
|
|
int |
int |
cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx) |
cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx) |
{ |
{ |
struct cmd_target_data *data = self->data; |
struct cmd_target_data *data = self->data; |
const struct set_option_entry *table; |
const struct options_table_entry *table, *oe, *oe_loop; |
struct session *s; |
struct session *s; |
struct winlink *wl; |
struct winlink *wl; |
struct client *c; |
struct client *c; |
struct options *oo; |
struct options *oo; |
const struct set_option_entry *entry, *opt; |
struct jobs *jobs; |
struct jobs *jobs; |
struct job *job, *nextjob; |
struct job *job, *nextjob; |
u_int i; |
u_int i; |
int try_again; |
int try_again; |
|
|
|
|
/* Work out the options tree and table to use. */ |
if (cmd_check_flag(data->chflags, 's')) { |
if (cmd_check_flag(data->chflags, 's')) { |
oo = &global_options; |
oo = &global_options; |
table = set_option_table; |
table = server_options_table; |
} else if (cmd_check_flag(data->chflags, 'w')) { |
} else if (cmd_check_flag(data->chflags, 'w')) { |
table = set_window_option_table; |
table = window_options_table; |
if (cmd_check_flag(data->chflags, 'g')) |
if (cmd_check_flag(data->chflags, 'g')) |
oo = &global_w_options; |
oo = &global_w_options; |
else { |
else { |
|
|
oo = &wl->window->options; |
oo = &wl->window->options; |
} |
} |
} else { |
} else { |
table = set_session_option_table; |
table = session_options_table; |
if (cmd_check_flag(data->chflags, 'g')) |
if (cmd_check_flag(data->chflags, 'g')) |
oo = &global_s_options; |
oo = &global_s_options; |
else { |
else { |
|
|
} |
} |
} |
} |
|
|
if (*data->arg == '\0') { |
/* Find the option table entry. */ |
ctx->error(ctx, "invalid option"); |
oe = NULL; |
return (-1); |
for (oe_loop = table; oe_loop->name != NULL; oe_loop++) { |
} |
if (strncmp(oe_loop->name, data->arg, strlen(data->arg)) != 0) |
|
|
entry = NULL; |
|
for (opt = table; opt->name != NULL; opt++) { |
|
if (strncmp(opt->name, data->arg, strlen(data->arg)) != 0) |
|
continue; |
continue; |
if (entry != NULL) { |
if (oe != NULL) { |
ctx->error(ctx, "ambiguous option: %s", data->arg); |
ctx->error(ctx, "ambiguous option: %s", data->arg); |
return (-1); |
return (-1); |
} |
} |
entry = opt; |
oe = oe_loop; |
|
|
/* Bail now if an exact match. */ |
/* Bail now if an exact match. */ |
if (strcmp(entry->name, data->arg) == 0) |
if (strcmp(oe->name, data->arg) == 0) |
break; |
break; |
} |
} |
if (entry == NULL) { |
if (oe == NULL) { |
ctx->error(ctx, "unknown option: %s", data->arg); |
ctx->error(ctx, "unknown option: %s", data->arg); |
return (-1); |
return (-1); |
} |
} |
|
|
|
/* Unset or set the option. */ |
if (cmd_check_flag(data->chflags, 'u')) { |
if (cmd_check_flag(data->chflags, 'u')) { |
if (cmd_check_flag(data->chflags, 'g')) { |
if (cmd_set_option_unset(self, ctx, oe, oo) != 0) |
ctx->error(ctx, |
|
"can't unset global option: %s", entry->name); |
|
return (-1); |
return (-1); |
} |
|
if (data->arg2 != NULL) { |
|
ctx->error(ctx, |
|
"value passed to unset option: %s", entry->name); |
|
return (-1); |
|
} |
|
|
|
options_remove(oo, entry->name); |
|
ctx->info(ctx, "unset option: %s", entry->name); |
|
} else { |
} else { |
switch (entry->type) { |
if (cmd_set_option_set(self, ctx, oe, oo) != 0) |
case SET_OPTION_STRING: |
return (-1); |
cmd_set_option_string(ctx, oo, entry, |
|
data->arg2, cmd_check_flag(data->chflags, 'a')); |
|
break; |
|
case SET_OPTION_NUMBER: |
|
cmd_set_option_number(ctx, oo, entry, data->arg2); |
|
break; |
|
case SET_OPTION_KEYS: |
|
cmd_set_option_keys(ctx, oo, entry, data->arg2); |
|
break; |
|
case SET_OPTION_COLOUR: |
|
cmd_set_option_colour(ctx, oo, entry, data->arg2); |
|
break; |
|
case SET_OPTION_ATTRIBUTES: |
|
cmd_set_option_attributes(ctx, oo, entry, data->arg2); |
|
break; |
|
case SET_OPTION_FLAG: |
|
cmd_set_option_flag(ctx, oo, entry, data->arg2); |
|
break; |
|
case SET_OPTION_CHOICE: |
|
cmd_set_option_choice(ctx, oo, entry, data->arg2); |
|
break; |
|
} |
|
} |
} |
|
|
|
/* Update sizes and redraw. May not need it but meh. */ |
recalculate_sizes(); |
recalculate_sizes(); |
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { |
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { |
c = ARRAY_ITEM(&clients, i); |
c = ARRAY_ITEM(&clients, i); |
|
|
* or set-titles-string have changed. Persistent jobs are only used by |
* or set-titles-string have changed. Persistent jobs are only used by |
* the status line at the moment so this works XXX. |
* the status line at the moment so this works XXX. |
*/ |
*/ |
if (strcmp(entry->name, "status-left") == 0 || |
if (strcmp(oe->name, "status-left") == 0 || |
strcmp(entry->name, "status-right") == 0 || |
strcmp(oe->name, "status-right") == 0 || |
strcmp(entry->name, "status") == 0 || |
strcmp(oe->name, "status") == 0 || |
strcmp(entry->name, "set-titles-string") == 0 || |
strcmp(oe->name, "set-titles-string") == 0 || |
strcmp(entry->name, "window-status-format") == 0) { |
strcmp(oe->name, "window-status-format") == 0) { |
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { |
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { |
c = ARRAY_ITEM(&clients, i); |
c = ARRAY_ITEM(&clients, i); |
if (c == NULL || c->session == NULL) |
if (c == NULL || c->session == NULL) |
|
|
return (0); |
return (0); |
} |
} |
|
|
const char * |
/* Unset an option. */ |
cmd_set_option_print( |
int |
const struct set_option_entry *entry, struct options_entry *o) |
cmd_set_option_unset(struct cmd *self, struct cmd_ctx *ctx, |
|
const struct options_table_entry *oe, struct options *oo) |
{ |
{ |
static char out[BUFSIZ]; |
struct cmd_target_data *data = self->data; |
const char *s; |
|
struct keylist *keylist; |
|
u_int i; |
|
|
|
*out = '\0'; |
if (cmd_check_flag(data->chflags, 'g')) { |
switch (entry->type) { |
ctx->error(ctx, "can't unset global option: %s", oe->name); |
case SET_OPTION_STRING: |
return (-1); |
xsnprintf(out, sizeof out, "\"%s\"", o->str); |
|
break; |
|
case SET_OPTION_NUMBER: |
|
xsnprintf(out, sizeof out, "%lld", o->num); |
|
break; |
|
case SET_OPTION_KEYS: |
|
keylist = o->data; |
|
for (i = 0; i < ARRAY_LENGTH(keylist); i++) { |
|
strlcat(out, key_string_lookup_key( |
|
ARRAY_ITEM(keylist, i)), sizeof out); |
|
if (i != ARRAY_LENGTH(keylist) - 1) |
|
strlcat(out, ",", sizeof out); |
|
} |
|
break; |
|
case SET_OPTION_COLOUR: |
|
s = colour_tostring(o->num); |
|
xsnprintf(out, sizeof out, "%s", s); |
|
break; |
|
case SET_OPTION_ATTRIBUTES: |
|
s = attributes_tostring(o->num); |
|
xsnprintf(out, sizeof out, "%s", s); |
|
break; |
|
case SET_OPTION_FLAG: |
|
if (o->num) |
|
strlcpy(out, "on", sizeof out); |
|
else |
|
strlcpy(out, "off", sizeof out); |
|
break; |
|
case SET_OPTION_CHOICE: |
|
s = entry->choices[o->num]; |
|
xsnprintf(out, sizeof out, "%s", s); |
|
break; |
|
} |
} |
return (out); |
if (data->arg2 != NULL) { |
|
ctx->error(ctx, "value passed to unset option: %s", oe->name); |
|
return (-1); |
|
} |
|
|
|
options_remove(oo, oe->name); |
|
ctx->info(ctx, "unset option: %s", oe->name); |
|
return (0); |
} |
} |
|
|
void |
/* Set an option. */ |
cmd_set_option_string(struct cmd_ctx *ctx, struct options *oo, |
int |
const struct set_option_entry *entry, char *value, int append) |
cmd_set_option_set(struct cmd *self, struct cmd_ctx *ctx, |
|
const struct options_table_entry *oe, struct options *oo) |
{ |
{ |
|
struct cmd_target_data *data = self->data; |
struct options_entry *o; |
struct options_entry *o; |
char *oldvalue, *newvalue; |
const char *s; |
|
|
if (value == NULL) { |
if (oe->type != OPTIONS_TABLE_FLAG && data->arg2 == NULL) { |
ctx->error(ctx, "empty value"); |
ctx->error(ctx, "empty data->arg2"); |
return; |
return (-1); |
} |
} |
|
|
if (append) { |
o = NULL; |
oldvalue = options_get_string(oo, entry->name); |
switch (oe->type) { |
xasprintf(&newvalue, "%s%s", oldvalue, value); |
case OPTIONS_TABLE_STRING: |
|
o = cmd_set_option_string(self, ctx, oe, oo); |
|
break; |
|
case OPTIONS_TABLE_NUMBER: |
|
o = cmd_set_option_number(self, ctx, oe, oo); |
|
break; |
|
case OPTIONS_TABLE_KEYS: |
|
o = cmd_set_option_keys(self, ctx, oe, oo); |
|
break; |
|
case OPTIONS_TABLE_COLOUR: |
|
o = cmd_set_option_colour(self, ctx, oe, oo); |
|
break; |
|
case OPTIONS_TABLE_ATTRIBUTES: |
|
o = cmd_set_option_attributes(self, ctx, oe, oo); |
|
break; |
|
case OPTIONS_TABLE_FLAG: |
|
o = cmd_set_option_flag(self, ctx, oe, oo); |
|
break; |
|
case OPTIONS_TABLE_CHOICE: |
|
o = cmd_set_option_choice(self, ctx, oe, oo); |
|
break; |
|
} |
|
if (o == NULL) |
|
return (-1); |
|
|
|
s = options_table_print_entry(oe, o); |
|
ctx->info(ctx, "set option: %s -> %s", oe->name, s); |
|
return (0); |
|
} |
|
|
|
/* Set a string option. */ |
|
struct options_entry * |
|
cmd_set_option_string(struct cmd *self, unused struct cmd_ctx *ctx, |
|
const struct options_table_entry *oe, struct options *oo) |
|
{ |
|
struct cmd_target_data *data = self->data; |
|
struct options_entry *o; |
|
char *oldval, *newval; |
|
|
|
if (cmd_check_flag(data->chflags, 'a')) { |
|
oldval = options_get_string(oo, oe->name); |
|
xasprintf(&newval, "%s%s", oldval, data->arg2); |
} else |
} else |
newvalue = value; |
newval = data->arg2; |
|
|
o = options_set_string(oo, entry->name, "%s", newvalue); |
o = options_set_string(oo, oe->name, "%s", newval); |
ctx->info(ctx, |
|
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o)); |
|
|
|
if (newvalue != value) |
if (newval != data->arg2) |
xfree(newvalue); |
xfree(newval); |
|
return (o); |
} |
} |
|
|
void |
/* Set a number option. */ |
cmd_set_option_number(struct cmd_ctx *ctx, struct options *oo, |
struct options_entry * |
const struct set_option_entry *entry, char *value) |
cmd_set_option_number(struct cmd *self, struct cmd_ctx *ctx, |
|
const struct options_table_entry *oe, struct options *oo) |
{ |
{ |
struct options_entry *o; |
struct cmd_target_data *data = self->data; |
long long number; |
long long ll; |
const char *errstr; |
const char *errstr; |
|
|
if (value == NULL) { |
ll = strtonum(data->arg2, oe->minimum, oe->maximum, &errstr); |
ctx->error(ctx, "empty value"); |
|
return; |
|
} |
|
|
|
number = strtonum(value, entry->minimum, entry->maximum, &errstr); |
|
if (errstr != NULL) { |
if (errstr != NULL) { |
ctx->error(ctx, "value is %s: %s", errstr, value); |
ctx->error(ctx, "value is %s: %s", errstr, data->arg2); |
return; |
return (NULL); |
} |
} |
|
|
o = options_set_number(oo, entry->name, number); |
return (options_set_number(oo, oe->name, ll)); |
ctx->info(ctx, |
|
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o)); |
|
} |
} |
|
|
void |
/* Set a keys option. */ |
cmd_set_option_keys(struct cmd_ctx *ctx, struct options *oo, |
struct options_entry * |
const struct set_option_entry *entry, char *value) |
cmd_set_option_keys(struct cmd *self, struct cmd_ctx *ctx, |
|
const struct options_table_entry *oe, struct options *oo) |
{ |
{ |
struct options_entry *o; |
struct cmd_target_data *data = self->data; |
struct keylist *keylist; |
struct keylist *keylist; |
char *copyvalue, *ptr, *str; |
char *copy, *ptr, *s; |
int key; |
int key; |
|
|
if (value == NULL) { |
|
ctx->error(ctx, "empty value"); |
|
return; |
|
} |
|
|
|
keylist = xmalloc(sizeof *keylist); |
keylist = xmalloc(sizeof *keylist); |
ARRAY_INIT(keylist); |
ARRAY_INIT(keylist); |
|
|
ptr = copyvalue = xstrdup(value); |
ptr = copy = xstrdup(data->arg2); |
while ((str = strsep(&ptr, ",")) != NULL) { |
while ((s = strsep(&ptr, ",")) != NULL) { |
if ((key = key_string_lookup_string(str)) == KEYC_NONE) { |
if ((key = key_string_lookup_string(s)) == KEYC_NONE) { |
|
ctx->error(ctx, "unknown key: %s", s); |
|
xfree(copy); |
xfree(keylist); |
xfree(keylist); |
ctx->error(ctx, "unknown key: %s", str); |
return (NULL); |
xfree(copyvalue); |
|
return; |
|
} |
} |
ARRAY_ADD(keylist, key); |
ARRAY_ADD(keylist, key); |
} |
} |
xfree(copyvalue); |
xfree(copy); |
|
|
o = options_set_data(oo, entry->name, keylist, xfree); |
return (options_set_data(oo, oe->name, keylist, xfree)); |
ctx->info(ctx, |
|
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o)); |
|
} |
} |
|
|
void |
/* Set a colour option. */ |
cmd_set_option_colour(struct cmd_ctx *ctx, struct options *oo, |
struct options_entry * |
const struct set_option_entry *entry, char *value) |
cmd_set_option_colour(struct cmd *self, struct cmd_ctx *ctx, |
|
const struct options_table_entry *oe, struct options *oo) |
{ |
{ |
struct options_entry *o; |
struct cmd_target_data *data = self->data; |
int colour; |
int colour; |
|
|
if (value == NULL) { |
if ((colour = colour_fromstring(data->arg2)) == -1) { |
ctx->error(ctx, "empty value"); |
ctx->error(ctx, "bad colour: %s", data->arg2); |
return; |
return (NULL); |
} |
} |
|
|
if ((colour = colour_fromstring(value)) == -1) { |
return (options_set_number(oo, oe->name, colour)); |
ctx->error(ctx, "bad colour: %s", value); |
|
return; |
|
} |
|
|
|
o = options_set_number(oo, entry->name, colour); |
|
ctx->info(ctx, |
|
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o)); |
|
} |
} |
|
|
void |
/* Set an attributes option. */ |
cmd_set_option_attributes(struct cmd_ctx *ctx, struct options *oo, |
struct options_entry * |
const struct set_option_entry *entry, char *value) |
cmd_set_option_attributes(struct cmd *self, struct cmd_ctx *ctx, |
|
const struct options_table_entry *oe, struct options *oo) |
{ |
{ |
struct options_entry *o; |
struct cmd_target_data *data = self->data; |
int attr; |
int attr; |
|
|
if (value == NULL) { |
if ((attr = attributes_fromstring(data->arg2)) == -1) { |
ctx->error(ctx, "empty value"); |
ctx->error(ctx, "bad attributes: %s", data->arg2); |
return; |
return (NULL); |
} |
} |
|
|
if ((attr = attributes_fromstring(value)) == -1) { |
return (options_set_number(oo, oe->name, attr)); |
ctx->error(ctx, "bad attributes: %s", value); |
|
return; |
|
} |
|
|
|
o = options_set_number(oo, entry->name, attr); |
|
ctx->info(ctx, |
|
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o)); |
|
} |
} |
|
|
void |
/* Set a flag option. */ |
cmd_set_option_flag(struct cmd_ctx *ctx, struct options *oo, |
struct options_entry * |
const struct set_option_entry *entry, char *value) |
cmd_set_option_flag(struct cmd *self, struct cmd_ctx *ctx, |
|
const struct options_table_entry *oe, struct options *oo) |
{ |
{ |
struct options_entry *o; |
struct cmd_target_data *data = self->data; |
int flag; |
int flag; |
|
|
if (value == NULL || *value == '\0') |
if (data->arg2 == NULL || *data->arg2 == '\0') |
flag = !options_get_number(oo, entry->name); |
flag = !options_get_number(oo, oe->name); |
else { |
else { |
if ((value[0] == '1' && value[1] == '\0') || |
if ((data->arg2[0] == '1' && data->arg2[1] == '\0') || |
strcasecmp(value, "on") == 0 || |
strcasecmp(data->arg2, "on") == 0 || |
strcasecmp(value, "yes") == 0) |
strcasecmp(data->arg2, "yes") == 0) |
flag = 1; |
flag = 1; |
else if ((value[0] == '0' && value[1] == '\0') || |
else if ((data->arg2[0] == '0' && data->arg2[1] == '\0') || |
strcasecmp(value, "off") == 0 || |
strcasecmp(data->arg2, "off") == 0 || |
strcasecmp(value, "no") == 0) |
strcasecmp(data->arg2, "no") == 0) |
flag = 0; |
flag = 0; |
else { |
else { |
ctx->error(ctx, "bad value: %s", value); |
ctx->error(ctx, "bad value: %s", data->arg2); |
return; |
return (NULL); |
} |
} |
} |
} |
|
|
o = options_set_number(oo, entry->name, flag); |
return (options_set_number(oo, oe->name, flag)); |
ctx->info(ctx, |
|
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o)); |
|
} |
} |
|
|
void |
/* Set a choice option. */ |
cmd_set_option_choice(struct cmd_ctx *ctx, struct options *oo, |
struct options_entry * |
const struct set_option_entry *entry, char *value) |
cmd_set_option_choice(struct cmd *self, struct cmd_ctx *ctx, |
|
const struct options_table_entry *oe, struct options *oo) |
{ |
{ |
struct options_entry *o; |
struct cmd_target_data *data = self->data; |
const char **choicep; |
const char **choicep; |
int n, choice = -1; |
int n, choice = -1; |
|
|
if (value == NULL) { |
|
ctx->error(ctx, "empty value"); |
|
return; |
|
} |
|
|
|
n = 0; |
n = 0; |
for (choicep = entry->choices; *choicep != NULL; choicep++) { |
for (choicep = oe->choices; *choicep != NULL; choicep++) { |
n++; |
n++; |
if (strncmp(*choicep, value, strlen(value)) != 0) |
if (strncmp(*choicep, data->arg2, strlen(data->arg2)) != 0) |
continue; |
continue; |
|
|
if (choice != -1) { |
if (choice != -1) { |
ctx->error(ctx, "ambiguous option value: %s", value); |
ctx->error(ctx, "ambiguous value: %s", data->arg2); |
return; |
return (NULL); |
} |
} |
choice = n - 1; |
choice = n - 1; |
} |
} |
if (choice == -1) { |
if (choice == -1) { |
ctx->error(ctx, "unknown option value: %s", value); |
ctx->error(ctx, "unknown value: %s", data->arg2); |
return; |
return (NULL); |
} |
} |
|
|
o = options_set_number(oo, entry->name, choice); |
return (options_set_number(oo, oe->name, choice)); |
ctx->info(ctx, |
|
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o)); |
|
} |
} |