3204 from Anindya Mukherjee.
-/* $OpenBSD: arguments.c,v 1.54 2022/05/30 13:04:24 nicm Exp $ */
+/* $OpenBSD: arguments.c,v 1.55 2022/06/07 10:02:19 nicm Exp $ */
/*
* Copyright (c) 2010 Nicholas Marriott <nicholas.marriott@gmail.com>
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,
*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);
+}
-/* $OpenBSD: cmd-capture-pane.c,v 1.55 2021/08/21 10:22:38 nicm Exp $ */
+/* $OpenBSD: cmd-capture-pane.c,v 1.56 2022/06/07 10:02:19 nicm Exp $ */
/*
* Copyright (c) 2009 Jonathan Alvarado <radobobo@users.sourceforge.net>
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);
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);
-/* $OpenBSD: cmd-join-pane.c,v 1.49 2021/08/21 10:22:39 nicm Exp $ */
+/* $OpenBSD: cmd-join-pane.c,v 1.50 2022/06/07 10:02:19 nicm Exp $ */
/*
* Copyright (c) 2011 George Nachman <tmux@georgester.com>
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;
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);
-/* $OpenBSD: cmd-send-keys.c,v 1.71 2021/10/19 12:51:43 nicm Exp $ */
+/* $OpenBSD: cmd-send-keys.c,v 1.72 2022/06/07 10:02:19 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
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);
-/* $OpenBSD: cmd-split-window.c,v 1.112 2022/03/08 22:14:25 nicm Exp $ */
+/* $OpenBSD: cmd-split-window.c,v 1.113 2022/06/07 10:02:19 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
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);
-/* $OpenBSD: tmux.h,v 1.1171 2022/06/04 07:42:07 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.1172 2022/06/07 10:02:19 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
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 *,