diff options
author | Nicholas Marriott <nicm@openbsd.org> | 2009-07-13 23:11:35 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@openbsd.org> | 2009-07-13 23:11:35 +0000 |
commit | 5f108d9df6bada119def52518152a487f8695702 (patch) | |
tree | 2ae6420cfdea4f68ce031e9a1ed62c2756c2c588 | |
parent | 5d91555c7c8d88577892e0a2e2bde2cde60a2882 (diff) |
Having fixed flags for single-character getopt options is a bit hard to
maintain and is only going to get worse as more are used. So instead, add a new
uint64_t member to cmd_entry which is a bitmask of upper and lowercase options
accepted by the command.
This means new single character options can be used without the need to add it
explicitly to the list.
73 files changed, 191 insertions, 229 deletions
diff --git a/cmd-attach-session.c b/cmd-attach-session.c index 1f0bb517..196d5d13 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -29,7 +29,7 @@ int cmd_attach_session_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_attach_session_entry = { "attach-session", "attach", "[-d] " CMD_TARGET_SESSION_USAGE, - CMD_DFLAG|CMD_CANTNEST|CMD_STARTSERVER, + CMD_CANTNEST|CMD_STARTSERVER, CMD_CHFLAG('d'), cmd_target_init, cmd_target_parse, cmd_attach_session_exec, @@ -67,7 +67,7 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx) return (-1); } - if (data->flags & CMD_DFLAG) + if (data->chflags & CMD_CHFLAG('d')) server_write_session(s, MSG_DETACH, NULL, 0); ctx->cmdclient->session = s; diff --git a/cmd-bind-key.c b/cmd-bind-key.c index f0988899..14a93831 100644 --- a/cmd-bind-key.c +++ b/cmd-bind-key.c @@ -40,7 +40,7 @@ struct cmd_bind_key_data { const struct cmd_entry cmd_bind_key_entry = { "bind-key", "bind", "[-r] key command [arguments]", - 0, + 0, 0, NULL, cmd_bind_key_parse, cmd_bind_key_exec, diff --git a/cmd-break-pane.c b/cmd-break-pane.c index f2b51edf..74e052d5 100644 --- a/cmd-break-pane.c +++ b/cmd-break-pane.c @@ -31,7 +31,7 @@ int cmd_break_pane_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_break_pane_entry = { "break-pane", "breakp", CMD_PANE_WINDOW_USAGE " [-d]", - CMD_DFLAG, + 0, CMD_CHFLAG('d'), cmd_pane_init, cmd_pane_parse, cmd_break_pane_exec, @@ -82,7 +82,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx) w->name = default_window_name(w); wl = session_attach(s, w, -1, &cause); /* can't fail */ - if (!(data->flags & CMD_DFLAG)) + if (!(data->chflags & CMD_CHFLAG('d'))) session_select(s, wl->idx); layout_refresh(w, 0); diff --git a/cmd-choose-session.c b/cmd-choose-session.c index d1f6ba23..22f7d04b 100644 --- a/cmd-choose-session.c +++ b/cmd-choose-session.c @@ -31,7 +31,7 @@ void cmd_choose_session_callback(void *, int); const struct cmd_entry cmd_choose_session_entry = { "choose-session", NULL, CMD_TARGET_WINDOW_USAGE, - 0, + 0, 0, cmd_target_init, cmd_target_parse, cmd_choose_session_exec, diff --git a/cmd-choose-window.c b/cmd-choose-window.c index 64eab882..baa55eb2 100644 --- a/cmd-choose-window.c +++ b/cmd-choose-window.c @@ -31,7 +31,7 @@ void cmd_choose_window_callback(void *, int); const struct cmd_entry cmd_choose_window_entry = { "choose-window", NULL, CMD_TARGET_WINDOW_USAGE, - 0, + 0, 0, cmd_target_init, cmd_target_parse, cmd_choose_window_exec, diff --git a/cmd-clear-history.c b/cmd-clear-history.c index 4399c6c2..de24ac57 100644 --- a/cmd-clear-history.c +++ b/cmd-clear-history.c @@ -29,7 +29,7 @@ int cmd_clear_history_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_clear_history_entry = { "clear-history", "clearhist", CMD_PANE_WINDOW_USAGE, - 0, + 0, 0, cmd_pane_init, cmd_pane_parse, cmd_clear_history_exec, diff --git a/cmd-clock-mode.c b/cmd-clock-mode.c index 7f3f0d07..4399b7ba 100644 --- a/cmd-clock-mode.c +++ b/cmd-clock-mode.c @@ -29,7 +29,7 @@ int cmd_clock_mode_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_clock_mode_entry = { "clock-mode", NULL, CMD_TARGET_WINDOW_USAGE, - 0, + 0, 0, cmd_target_init, cmd_target_parse, cmd_clock_mode_exec, diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c index cf914648..841dfd78 100644 --- a/cmd-command-prompt.c +++ b/cmd-command-prompt.c @@ -35,7 +35,7 @@ int cmd_command_prompt_callback(void *, const char *); const struct cmd_entry cmd_command_prompt_entry = { "command-prompt", NULL, CMD_TARGET_CLIENT_USAGE " [template]", - CMD_ARG01, + CMD_ARG01, 0, cmd_command_prompt_init, cmd_target_parse, cmd_command_prompt_exec, diff --git a/cmd-confirm-before.c b/cmd-confirm-before.c index f544d810..0819e3e9 100644 --- a/cmd-confirm-before.c +++ b/cmd-confirm-before.c @@ -38,7 +38,7 @@ struct cmd_confirm_before_data { const struct cmd_entry cmd_confirm_before_entry = { "confirm-before", "confirm", CMD_TARGET_CLIENT_USAGE " command", - CMD_ARG1, + CMD_ARG1, 0, cmd_confirm_before_init, cmd_target_parse, cmd_confirm_before_exec, diff --git a/cmd-copy-buffer.c b/cmd-copy-buffer.c index ab6fe14b..544cf1c6 100644 --- a/cmd-copy-buffer.c +++ b/cmd-copy-buffer.c @@ -42,7 +42,7 @@ struct cmd_copy_buffer_data { const struct cmd_entry cmd_copy_buffer_entry = { "copy-buffer", "copyb", "[-a src-index] [-b dst-index] [-s src-session] [-t dst-session]", - 0, + 0, 0, cmd_copy_buffer_init, cmd_copy_buffer_parse, cmd_copy_buffer_exec, diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c index 0600d116..e9891179 100644 --- a/cmd-copy-mode.c +++ b/cmd-copy-mode.c @@ -29,7 +29,7 @@ int cmd_copy_mode_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_copy_mode_entry = { "copy-mode", NULL, "[-u] " CMD_TARGET_WINDOW_USAGE, - CMD_UFLAG, + 0, CMD_CHFLAG('u'), cmd_target_init, cmd_target_parse, cmd_copy_mode_exec, @@ -51,7 +51,7 @@ cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx) wp = wl->window->active; window_pane_set_mode(wp, &window_copy_mode); - if (wp->mode == &window_copy_mode && data->flags & CMD_UFLAG) + if (wp->mode == &window_copy_mode && data->chflags & CMD_CHFLAG('u')) window_copy_pageup(wp); return (0); diff --git a/cmd-delete-buffer.c b/cmd-delete-buffer.c index 7351cf2c..81b69417 100644 --- a/cmd-delete-buffer.c +++ b/cmd-delete-buffer.c @@ -31,7 +31,7 @@ int cmd_delete_buffer_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_delete_buffer_entry = { "delete-buffer", "deleteb", CMD_BUFFER_SESSION_USAGE, - 0, + 0, 0, cmd_buffer_init, cmd_buffer_parse, cmd_delete_buffer_exec, diff --git a/cmd-detach-client.c b/cmd-detach-client.c index b900d84a..0a28cdc7 100644 --- a/cmd-detach-client.c +++ b/cmd-detach-client.c @@ -29,7 +29,7 @@ int cmd_detach_client_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_detach_client_entry = { "detach-client", "detach", CMD_TARGET_CLIENT_USAGE, - 0, + 0, 0, cmd_target_init, cmd_target_parse, cmd_detach_client_exec, diff --git a/cmd-down-pane.c b/cmd-down-pane.c index ddfe412a..9b1dfe1e 100644 --- a/cmd-down-pane.c +++ b/cmd-down-pane.c @@ -29,7 +29,7 @@ int cmd_down_pane_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_down_pane_entry = { "down-pane", "downp", CMD_TARGET_WINDOW_USAGE, - 0, + 0, 0, cmd_target_init, cmd_target_parse, cmd_down_pane_exec, diff --git a/cmd-find-window.c b/cmd-find-window.c index 9458fa8b..21461cdc 100644 --- a/cmd-find-window.c +++ b/cmd-find-window.c @@ -34,7 +34,7 @@ void cmd_find_window_callback(void *, int); const struct cmd_entry cmd_find_window_entry = { "find-window", "findw", CMD_TARGET_WINDOW_USAGE " match-string", - CMD_ARG1, + CMD_ARG1, 0, cmd_target_init, cmd_target_parse, cmd_find_window_exec, diff --git a/cmd-generic.c b/cmd-generic.c index 1b2e17a9..ea0d4d16 100644 --- a/cmd-generic.c +++ b/cmd-generic.c @@ -23,12 +23,9 @@ #include "tmux.h" -#define CMD_FLAGS "adDgkruU" -#define CMD_FLAGMASK (CMD_AFLAG|CMD_DFLAG|CMD_BIGDFLAG|CMD_GFLAG|CMD_KFLAG| \ - CMD_RFLAG|CMD_UFLAG|CMD_BIGUFLAG) - -int cmd_do_flags(int, int, int *); -size_t cmd_print_flags(char *, size_t, size_t, int); +int cmd_getopt(int, char **, const char *, uint64_t); +int cmd_flags(int, uint64_t, uint64_t *); +size_t cmd_print_flags(char *, size_t, size_t, uint64_t); int cmd_fill_argument(int, char **, int, char **); size_t @@ -39,86 +36,70 @@ cmd_prarg(char *buf, size_t len, const char *prefix, char *arg) return (xsnprintf(buf, len, "%s%s", prefix, arg)); } +/* Prepend flags from chflags onto flagstr and call getopt. */ int -cmd_do_flags(int opt, int iflags, int *oflags) +cmd_getopt(int argc, char **argv, const char *flagstr, uint64_t chflags) { - switch (opt) { - case 'a': - if (iflags & CMD_AFLAG) { - (*oflags) |= CMD_AFLAG; - return (0); - } - return (-1); - case 'd': - if (iflags & CMD_DFLAG) { - (*oflags) |= CMD_DFLAG; - return (0); - } - return (-1); - case 'D': - if (iflags & CMD_BIGDFLAG) { - (*oflags) |= CMD_BIGDFLAG; - return (0); - } - return (-1); - case 'g': - if (iflags & CMD_GFLAG) { - (*oflags) |= CMD_GFLAG; - return (0); - } - return (-1); - case 'k': - if (iflags & CMD_KFLAG) { - (*oflags) |= CMD_KFLAG; - return (0); - } - return (-1); - case 'r': - if (iflags & CMD_RFLAG) { - (*oflags) |= CMD_RFLAG; - return (0); - } - return (-1); - case 'u': - if (iflags & CMD_UFLAG) { - (*oflags) |= CMD_UFLAG; + u_char ch; + char buf[128]; + size_t len, off; + + *buf = '\0'; + + len = sizeof buf; + off = 0; + + for (ch = 0; ch < 26; ch++) { + if (chflags & CMD_CHFLAG('a' + ch)) + off += xsnprintf(buf + off, len - off, "%c", 'a' + ch); + if (chflags & CMD_CHFLAG('A' + ch)) + off += xsnprintf(buf + off, len - off, "%c", 'A' + ch); + } + + strlcat(buf, flagstr, sizeof buf); + + return (getopt(argc, argv, buf)); +} + +/* + * If this option is expected (in ichflags), set it in ochflags, otherwise + * return -1. + */ +int +cmd_flags(int opt, uint64_t ichflags, uint64_t *ochflags) +{ + u_char ch; + + for (ch = 0; ch < 26; ch++) { + if (opt == 'a' + ch && ichflags & CMD_CHFLAG(opt)) { + (*ochflags) |= CMD_CHFLAG(opt); return (0); } - return (-1); - case 'U': - if (iflags & CMD_BIGUFLAG) { - (*oflags) |= CMD_BIGUFLAG; + if (opt == 'A' + ch && ichflags & CMD_CHFLAG(opt)) { + (*ochflags) |= CMD_CHFLAG(opt); return (0); } - return (-1); } - return (1); + return (-1); } +/* Print the flags supported in chflags. */ size_t -cmd_print_flags(char *buf, size_t len, size_t off, int flags) +cmd_print_flags(char *buf, size_t len, size_t off, uint64_t chflags) { + u_char ch; size_t boff = off; - if ((flags & CMD_FLAGMASK) == 0) + if (chflags == 0) return (0); off += xsnprintf(buf + off, len - off, " -"); - if (off < len && flags & CMD_AFLAG) - off += xsnprintf(buf + off, len - off, "a"); - if (off < len && flags & CMD_BIGDFLAG) - off += xsnprintf(buf + off, len - off, "D"); - if (off < len && flags & CMD_DFLAG) - off += xsnprintf(buf + off, len - off, "d"); - if (off < len && flags & CMD_GFLAG) - off += xsnprintf(buf + off, len - off, "g"); - if (off < len && flags & CMD_KFLAG) - off += xsnprintf(buf + off, len - off, "k"); - if (off < len && flags & CMD_RFLAG) - off += xsnprintf(buf + off, len - off, "r"); - if (off < len && flags & CMD_UFLAG) - off += xsnprintf(buf + off, len - off, "u"); - if (off < len && flags & CMD_BIGUFLAG) - off += xsnprintf(buf + off, len - off, "U"); + + for (ch = 0; ch < 26; ch++) { + if (chflags & CMD_CHFLAG('a' + ch)) + off += xsnprintf(buf + off, len - off, "%c", 'a' + ch); + if (chflags & CMD_CHFLAG('A' + ch)) + off += xsnprintf(buf + off, len - off, "%c", 'A' + ch); + } return (off - boff); } @@ -153,7 +134,7 @@ cmd_target_init(struct cmd *self, unused int key) struct cmd_target_data *data; self->data = data = xmalloc(sizeof *data); - data->flags = 0; + data->chflags = 0; data->target = NULL; data->arg = NULL; } @@ -162,19 +143,16 @@ int cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause) { struct cmd_target_data *data; + const struct cmd_entry *entry = self->entry; int opt; /* Don't use the entry version since it may be dependent on key. */ cmd_target_init(self, 0); data = self->data; - while ((opt = getopt(argc, argv, CMD_FLAGS "t:")) != -1) { - switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) { - case -1: - goto usage; - case 0: + while ((opt = cmd_getopt(argc, argv, "t:", entry->chflags)) != -1) { + if (cmd_flags(opt, entry->chflags, &data->chflags) == 0) continue; - } switch (opt) { case 't': if (data->target == NULL) @@ -240,7 +218,7 @@ cmd_target_print(struct cmd *self, char *buf, size_t len) off += xsnprintf(buf, len, "%s", self->entry->name); if (data == NULL) return (off); - off += cmd_print_flags(buf, len, off, data->flags); + off += cmd_print_flags(buf, len, off, data->chflags); if (off < len && data->target != NULL) off += cmd_prarg(buf + off, len - off, " -t ", data->target); if (off < len && data->arg != NULL) @@ -254,7 +232,7 @@ cmd_srcdst_init(struct cmd *self, unused int key) struct cmd_srcdst_data *data; self->data = data = xmalloc(sizeof *data); - data->flags = 0; + data->chflags = 0; data->src = NULL; data->dst = NULL; data->arg = NULL; @@ -264,18 +242,15 @@ int cmd_srcdst_parse(struct cmd *self, int argc, char **argv, char **cause) { struct cmd_srcdst_data *data; + const struct cmd_entry *entry = self->entry; int opt; cmd_srcdst_init(self, 0); data = self->data; - while ((opt = getopt(argc, argv, CMD_FLAGS "s:t:")) != -1) { - switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) { - case -1: - goto usage; - case 0: + while ((opt = cmd_getopt(argc, argv, "s:t:", entry->chflags)) != -1) { + if (cmd_flags(opt, entry->chflags, &data->chflags) == 0) continue; - } switch (opt) { case 's': if (data->src == NULL) @@ -349,7 +324,7 @@ cmd_srcdst_print(struct cmd *self, char *buf, size_t len) off += xsnprintf(buf, len, "%s", self->entry->name); if (data == NULL) return (off); - off += cmd_print_flags(buf, len, off, data->flags); + off += cmd_print_flags(buf, len, off, data->chflags); if (off < len && data->src != NULL) off += xsnprintf(buf + off, len - off, " -s %s", data->src); if (off < len && data->dst != NULL) @@ -365,7 +340,7 @@ cmd_buffer_init(struct cmd *self, unused int key) struct cmd_buffer_data *data; self->data = data = xmalloc(sizeof *data); - data->flags = 0; + data->chflags = 0; data->target = NULL; data->buffer = -1; data->arg = NULL; @@ -375,19 +350,16 @@ int cmd_buffer_parse(struct cmd *self, int argc, char **argv, char **cause) { struct cmd_buffer_data *data; + const struct cmd_entry *entry = self->entry; int opt, n; const char *errstr; cmd_buffer_init(self, 0); data = self->data; - while ((opt = getopt(argc, argv, CMD_FLAGS "b:t:")) != -1) { - switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) { - case -1: - goto usage; - case 0: + while ((opt = cmd_getopt(argc, argv, "b:t:", entry->chflags)) != -1) { + if (cmd_flags(opt, entry->chflags, &data->chflags) == 0) continue; - } switch (opt) { case 'b': if (data->buffer == -1) { @@ -464,7 +436,7 @@ cmd_buffer_print(struct cmd *self, char *buf, size_t len) off += xsnprintf(buf, len, "%s", self->entry->name); if (data == NULL) return (off); - off += cmd_print_flags(buf, len, off, data->flags); + off += cmd_print_flags(buf, len, off, data->chflags); if (off < len && data->buffer != -1) off += xsnprintf(buf + off, len - off, " -b %d", data->buffer); if (off < len && data->target != NULL) @@ -480,7 +452,7 @@ cmd_option_init(struct cmd *self, unused int key) struct cmd_option_data *data; self->data = data = xmalloc(sizeof *data); - data->flags = 0; + data->chflags = 0; data->target = NULL; data->option = NULL; data->value = NULL; @@ -490,19 +462,16 @@ int cmd_option_parse(struct cmd *self, int argc, char **argv, char **cause) { struct cmd_option_data *data; + const struct cmd_entry *entry = self->entry; int opt; /* Don't use the entry version since it may be dependent on key. */ cmd_option_init(self, 0); data = self->data; - while ((opt = getopt(argc, argv, CMD_FLAGS "t:")) != -1) { - switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) { - case -1: - goto usage; - case 0: + while ((opt = cmd_getopt(argc, argv, "t:", entry->chflags)) != -1) { + if (cmd_flags(opt, entry->chflags, &da |