summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Adam <thomas@xteddy.org>2022-06-07 14:01:09 +0100
committerThomas Adam <thomas@xteddy.org>2022-06-07 14:01:09 +0100
commitbe2eb57d6295a72b870841bbb85e65d624c5d87c (patch)
tree3fde58f40fefb97cbf42a10fa961ebdaafe02769
parentafb3a5fe7180f73457346cf12d096497d93aa642 (diff)
parentc07d582e2476db075252998388305f11302a8b23 (diff)
Merge branch 'obsd-master'
-rw-r--r--arguments.c102
-rw-r--r--cmd-capture-pane.c6
-rw-r--r--cmd-join-pane.c36
-rw-r--r--cmd-send-keys.c3
-rw-r--r--cmd-split-window.c79
-rw-r--r--tmux.h6
6 files changed, 165 insertions, 67 deletions
diff --git a/arguments.c b/arguments.c
index d0dc2d4d..46777f7f 100644
--- a/arguments.c
+++ b/arguments.c
@@ -848,6 +848,41 @@ args_strtonum(struct args *args, u_char flag, long long minval,
return (ll);
}
+/* Convert an argument value to a number, and expand formats. */
+long long
+args_strtonum_and_expand(struct args *args, u_char flag, long long minval,
+ long long maxval, struct cmdq_item *item, char **cause)
+{
+ const char *errstr;
+ char *formatted;
+ long long ll;
+ struct args_entry *entry;
+ struct args_value *value;
+
+ if ((entry = args_find(args, flag)) == NULL) {
+ *cause = xstrdup("missing");
+ return (0);
+ }
+ value = TAILQ_LAST(&entry->values, args_values);
+ if (value == NULL ||
+ value->type != ARGS_STRING ||
+ value->string == NULL) {
+ *cause = xstrdup("missing");
+ return (0);
+ }
+
+ formatted = format_single_from_target(item, value->string);
+ ll = strtonum(formatted, minval, maxval, &errstr);
+ free(formatted);
+ if (errstr != NULL) {
+ *cause = xstrdup(errstr);
+ return (0);
+ }
+
+ *cause = NULL;
+ return (ll);
+}
+
/* Convert an argument to a number which may be a percentage. */
long long
args_percentage(struct args *args, u_char flag, long long minval,
@@ -904,3 +939,70 @@ args_string_percentage(const char *value, long long minval, long long maxval,
*cause = NULL;
return (ll);
}
+
+/*
+ * Convert an argument to a number which may be a percentage, and expand
+ * formats.
+ */
+long long
+args_percentage_and_expand(struct args *args, u_char flag, long long minval,
+ long long maxval, long long curval, struct cmdq_item *item, char **cause)
+{
+ const char *value;
+ struct args_entry *entry;
+
+ if ((entry = args_find(args, flag)) == NULL) {
+ *cause = xstrdup("missing");
+ return (0);
+ }
+ value = TAILQ_LAST(&entry->values, args_values)->string;
+ return (args_string_percentage_and_expand(value, minval, maxval, curval,
+ item, cause));
+}
+
+/*
+ * Convert a string to a number which may be a percentage, and expand formats.
+ */
+long long
+args_string_percentage_and_expand(const char *value, long long minval,
+ long long maxval, long long curval, struct cmdq_item *item, char **cause)
+{
+ const char *errstr;
+ long long ll;
+ size_t valuelen = strlen(value);
+ char *copy, *f;
+
+ if (value[valuelen - 1] == '%') {
+ copy = xstrdup(value);
+ copy[valuelen - 1] = '\0';
+
+ f = format_single_from_target(item, copy);
+ ll = strtonum(f, 0, 100, &errstr);
+ free(f);
+ free(copy);
+ if (errstr != NULL) {
+ *cause = xstrdup(errstr);
+ return (0);
+ }
+ ll = (curval * ll) / 100;
+ if (ll < minval) {
+ *cause = xstrdup("too small");
+ return (0);
+ }
+ if (ll > maxval) {
+ *cause = xstrdup("too large");
+ return (0);
+ }
+ } else {
+ f = format_single_from_target(item, value);
+ ll = strtonum(f, minval, maxval, &errstr);
+ free(f);
+ if (errstr != NULL) {
+ *cause = xstrdup(errstr);
+ return (0);
+ }
+ }
+
+ *cause = NULL;
+ return (ll);
+}
diff --git a/cmd-capture-pane.c b/cmd-capture-pane.c
index 964f831e..a3e84c46 100644
--- a/cmd-capture-pane.c
+++ b/cmd-capture-pane.c
@@ -133,7 +133,8 @@ cmd_capture_pane_history(struct args *args, struct cmdq_item *item,
if (Sflag != NULL && strcmp(Sflag, "-") == 0)
top = 0;
else {
- n = args_strtonum(args, 'S', INT_MIN, SHRT_MAX, &cause);
+ n = args_strtonum_and_expand(args, 'S', INT_MIN, SHRT_MAX,
+ item, &cause);
if (cause != NULL) {
top = gd->hsize;
free(cause);
@@ -149,7 +150,8 @@ cmd_capture_pane_history(struct args *args, struct cmdq_item *item,
if (Eflag != NULL && strcmp(Eflag, "-") == 0)
bottom = gd->hsize + gd->sy - 1;
else {
- n = args_strtonum(args, 'E', INT_MIN, SHRT_MAX, &cause);
+ n = args_strtonum_and_expand(args, 'E', INT_MIN, SHRT_MAX,
+ item, &cause);
if (cause != NULL) {
bottom = gd->hsize + gd->sy - 1;
free(cause);
diff --git a/cmd-join-pane.c b/cmd-join-pane.c
index cb3fb343..e82b4cde 100644
--- a/cmd-join-pane.c
+++ b/cmd-join-pane.c
@@ -71,10 +71,11 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
struct window *src_w, *dst_w;
struct window_pane *src_wp, *dst_wp;
char *cause = NULL;
- int size, percentage, dst_idx;
+ int size, dst_idx;
int flags;
enum layout_type type;
struct layout_cell *lc;
+ u_int curval = 0;
dst_s = target->s;
dst_wl = target->wl;
@@ -97,24 +98,31 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
if (args_has(args, 'h'))
type = LAYOUT_LEFTRIGHT;
- size = -1;
- if (args_has(args, 'l')) {
- if (type == LAYOUT_TOPBOTTOM) {
- size = args_percentage(args, 'l', 0, INT_MAX,
- dst_wp->sy, &cause);
+ /* If the 'p' flag is dropped then this bit can be moved into 'l'. */
+ if (args_has(args, 'l') || args_has(args, 'p')) {
+ if (args_has(args, 'f')) {
+ if (type == LAYOUT_TOPBOTTOM)
+ curval = dst_w->sy;
+ else
+ curval = dst_w->sx;
} else {
- size = args_percentage(args, 'l', 0, INT_MAX,
- dst_wp->sx, &cause);
- }
- } else if (args_has(args, 'p')) {
- percentage = args_strtonum(args, 'p', 0, 100, &cause);
- if (cause == NULL) {
if (type == LAYOUT_TOPBOTTOM)
- size = (dst_wp->sy * percentage) / 100;
+ curval = dst_wp->sy;
else
- size = (dst_wp->sx * percentage) / 100;
+ curval = dst_wp->sx;
}
}
+
+ size = -1;
+ if (args_has(args, 'l')) {
+ size = args_percentage_and_expand(args, 'l', 0, INT_MAX, curval,
+ item, &cause);
+ } else if (args_has(args, 'p')) {
+ size = args_strtonum_and_expand(args, 'l', 0, 100, item,
+ &cause);
+ if (cause == NULL)
+ size = curval * size / 100;
+ }
if (cause != NULL) {
cmdq_error(item, "size %s", cause);
free(cause);
diff --git a/cmd-send-keys.c b/cmd-send-keys.c
index d6a95434..e22d94a6 100644
--- a/cmd-send-keys.c
+++ b/cmd-send-keys.c
@@ -151,7 +151,8 @@ cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item)
char *cause = NULL;
if (args_has(args, 'N')) {
- np = args_strtonum(args, 'N', 1, UINT_MAX, &cause);
+ np = args_strtonum_and_expand(args, 'N', 1, UINT_MAX, item,
+ &cause);
if (cause != NULL) {
cmdq_error(item, "repeat count %s", cause);
free(cause);
diff --git a/cmd-split-window.c b/cmd-split-window.c
index 9947dfd3..637bad30 100644
--- a/cmd-split-window.c
+++ b/cmd-split-window.c
@@ -65,67 +65,46 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
enum layout_type type;
struct layout_cell *lc;
struct cmd_find_state fs;
- int size, percentage, flags, input;
- const char *template, *errstr, *p;
- char *cause, *cp, *copy;
- size_t plen;
+ int size, flags, input;
+ const char *template;
+ char *cause = NULL, *cp;
struct args_value *av;
- u_int count = args_count(args);
+ u_int count = args_count(args), curval = 0;
+ type = LAYOUT_TOPBOTTOM;
if (args_has(args, 'h'))
type = LAYOUT_LEFTRIGHT;
- else
- type = LAYOUT_TOPBOTTOM;
- if ((p = args_get(args, 'l')) != NULL) {
- plen = strlen(p);
- if (p[plen - 1] == '%') {
- copy = xstrdup(p);
- copy[plen - 1] = '\0';
- percentage = strtonum(copy, 0, INT_MAX, &errstr);
- free(copy);
- if (errstr != NULL) {
- cmdq_error(item, "percentage %s", errstr);
- return (CMD_RETURN_ERROR);
- }
- if (args_has(args, 'f')) {
- if (type == LAYOUT_TOPBOTTOM)
- size = (w->sy * percentage) / 100;
- else
- size = (w->sx * percentage) / 100;
- } else {
- if (type == LAYOUT_TOPBOTTOM)
- size = (wp->sy * percentage) / 100;
- else
- size = (wp->sx * percentage) / 100;
- }
- } else {
- size = args_strtonum(args, 'l', 0, INT_MAX, &cause);
- if (cause != NULL) {
- cmdq_error(item, "lines %s", cause);
- free(cause);
- return (CMD_RETURN_ERROR);
- }
- }
- } else if (args_has(args, 'p')) {
- percentage = args_strtonum(args, 'p', 0, INT_MAX, &cause);
- if (cause != NULL) {
- cmdq_error(item, "create pane failed: -p %s", cause);
- free(cause);
- return (CMD_RETURN_ERROR);
- }
+
+ /* If the 'p' flag is dropped then this bit can be moved into 'l'. */
+ if (args_has(args, 'l') || args_has(args, 'p')) {
if (args_has(args, 'f')) {
if (type == LAYOUT_TOPBOTTOM)
- size = (w->sy * percentage) / 100;
+ curval = w->sy;
else
- size = (w->sx * percentage) / 100;
+ curval = w->sx;
} else {
if (type == LAYOUT_TOPBOTTOM)
- size = (wp->sy * percentage) / 100;
+ curval = wp->sy;
else
- size = (wp->sx * percentage) / 100;
+ curval = wp->sx;
}
- } else
- size = -1;
+ }
+
+ size = -1;
+ if (args_has(args, 'l')) {
+ size = args_percentage_and_expand(args, 'l', 0, INT_MAX, curval,
+ item, &cause);
+ } else if (args_has(args, 'p')) {
+ size = args_strtonum_and_expand(args, 'l', 0, 100, item,
+ &cause);
+ if (cause == NULL)
+ size = curval * size / 100;
+ }
+ if (cause != NULL) {
+ cmdq_error(item, "size %s", cause);
+ free(cause);
+ return (CMD_RETURN_ERROR);
+ }
window_push_zoom(wp->window, 1, args_has(args, 'Z'));
input = (args_has(args, 'I') && count == 0);
diff --git a/tmux.h b/tmux.h
index 972b4624..6a4f98dd 100644
--- a/tmux.h
+++ b/tmux.h
@@ -2384,10 +2384,16 @@ struct args_value *args_first_value(struct args *, u_char);
struct args_value *args_next_value(struct args_value *);
long long args_strtonum(struct args *, u_char, long long, long long,
char **);
+long long args_strtonum_and_expand(struct args *, u_char, long long,
+ long long, struct cmdq_item *, char **);
long long args_percentage(struct args *, u_char, long long,
long long, long long, char **);
long long args_string_percentage(const char *, long long, long long,
long long, char **);
+long long args_percentage_and_expand(struct args *, u_char, long long,
+ long long, long long, struct cmdq_item *, char **);
+long long args_string_percentage_and_expand(const char *, long long,
+ long long, long long, struct cmdq_item *, char **);
/* cmd-find.c */
int cmd_find_target(struct cmd_find_state *, struct cmdq_item *,