From 84c22d053b5ec1cd25e1694fa3889922b9cbe11b Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 3 Aug 2013 21:06:38 +0100 Subject: [PATCH] Add length limit operator for formats. --- format.c | 40 ++++++++++++++++++++++++++++++++++------ options-table.c | 2 +- tmux.1 | 6 ++++++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/format.c b/format.c index 0845df6d..ee3339dc 100644 --- a/format.c +++ b/format.c @@ -18,6 +18,8 @@ #include +#include +#include #include #include #include @@ -188,18 +190,40 @@ format_find(struct format_tree *ft, const char *key) * #{?blah,a,b} is replace with a if blah exists and is nonzero else b. */ int -format_replace(struct format_tree *ft, - const char *key, size_t keylen, char **buf, size_t *len, size_t *off) +format_replace(struct format_tree *ft, const char *key, size_t keylen, + char **buf, size_t *len, size_t *off) { - char *copy, *ptr; + char *copy, *copy0, *endptr, *ptr; const char *value; size_t valuelen; + u_long limit = ULONG_MAX; /* Make a copy of the key. */ - copy = xmalloc(keylen + 1); + copy0 = copy = xmalloc(keylen + 1); memcpy(copy, key, keylen); copy[keylen] = '\0'; + /* Is there a length limit or whatnot? */ + if (!islower((u_char) *copy) && *copy != '?') { + while (*copy != ':' && *copy != '\0') { + switch (*copy) { + case '=': + errno = 0; + limit = strtoul(copy + 1, &endptr, 10); + if (errno == ERANGE && limit == ULONG_MAX) + goto fail; + copy = endptr; + break; + default: + copy++; + break; + } + } + if (*copy != ':') + goto fail; + copy++; + } + /* * Is this a conditional? If so, check it exists and extract either the * first or second element. If not, look up the key directly. @@ -230,6 +254,10 @@ format_replace(struct format_tree *ft, } valuelen = strlen(value); + /* Truncate the value if needed. */ + if (valuelen > limit) + valuelen = limit; + /* Expand the buffer and copy in the value. */ while (*len - *off < valuelen + 1) { *buf = xrealloc(*buf, 2, *len); @@ -238,11 +266,11 @@ format_replace(struct format_tree *ft, memcpy(*buf + *off, value, valuelen); *off += valuelen; - free(copy); + free(copy0); return (0); fail: - free(copy); + free(copy0); return (-1); } diff --git a/options-table.c b/options-table.c index 2281d652..0b86ef7c 100644 --- a/options-table.c +++ b/options-table.c @@ -386,7 +386,7 @@ const struct options_table_entry session_options_table[] = { { .name = "status-right", .type = OPTIONS_TABLE_STRING, - .default_str = "\"#22T\" %H:%M %d-%b-%y" + .default_str = "\"#{=22:pane_title}\" %H:%M %d-%b-%y" }, { .name = "status-right-attr", diff --git a/tmux.1 b/tmux.1 index 340109b6..19ae4a9b 100644 --- a/tmux.1 +++ b/tmux.1 @@ -3026,6 +3026,12 @@ will include the string if the session is attached and the string .Ql not attached if it is unattached. +A limit may be placed on the length of the resultant string by prefixing it +by an +.Ql = , +a number and a colon, so +.Ql #{=10:pane_title} +will include at most the first 10 characters of the pane title. .Pp The following variables are available, where appropriate: .Bl -column "XXXXXXXXXXXXXXXXXXX" "XXXXX"