The branch, master has been updated
       via  399d7380a5babec8179d6e3334a5cabfa8e2fade (commit)
       via  c231381aa3a22340e787baaf78781d9b8ecd6a2c (commit)
       via  c30d60f7ae7631a4c2edc241739b5c6eff110a24 (commit)
       via  9fb9f78e43337833825ae464a1c39ed6d78a2fdb (commit)
       via  a0cf65db77343cf60a72c59596ccfcaebe91c663 (commit)
      from  2ee9c4df12429d4f6fb8f06a373fdd5c0347049c (commit)

- Log -----------------------------------------------------------------
commit 399d7380a5babec8179d6e3334a5cabfa8e2fade
Merge: 2ee9c4d c231381
Author: Thomas Adam <[email protected]>
Commit: Thomas Adam <[email protected]>

    Merge branch 'obsd-master'

 arguments.c     |  119 ++++++++++++++++++++++++-------------
 cmd-send-keys.c |    2 +-
 format.c        |   74 +++++++++++++++++------
 status.c        |   61 +++----------------
 tmux.1          |  179 ++++++++++++++++++++++++++-----------------------------
 tmux.h          |   19 ++++--
 6 files changed, 240 insertions(+), 214 deletions(-)



commit c231381aa3a22340e787baaf78781d9b8ecd6a2c
Author: Nicholas Marriott <[email protected]>
Commit: Nicholas Marriott <[email protected]>

    Demote the old single-character replacement variables (#S and friends)
    to aliases of formats. From Tiago Cunha.
---
 status.c |   61 +++------------------
 tmux.1   |  180 +++++++++++++++++++++++++++++---------------------------------
 2 files changed, 93 insertions(+), 148 deletions(-)

diff --git a/status.c b/status.c
index 6ce0b87..ecfd7e5 100644
--- a/status.c
+++ b/status.c
@@ -38,8 +38,7 @@ void  status_job_free(void *);
 void   status_job_callback(struct job *);
 char   *status_print(
            struct client *, struct winlink *, time_t, struct grid_cell *);
-void   status_replace1(struct client *, struct session *, struct winlink *,
-           struct window_pane *, char **, char **, char *, size_t, int);
+void   status_replace1(struct client *, char **, char **, char *, size_t, int);
 void   status_message_callback(int, short, void *);
 
 const char *status_prompt_up_history(u_int *);
@@ -384,14 +383,12 @@ out:
 
 /* Replace a single special sequence (prefixed by #). */
 void
-status_replace1(struct client *c, struct session *s, struct winlink *wl,
-    struct window_pane *wp, char **iptr, char **optr, char *out,
+status_replace1(struct client *c, char **iptr, char **optr, char *out,
     size_t outsize, int jobsflag)
 {
-       char    ch, tmp[256], *ptr, *endptr, *freeptr;
+       char    ch, tmp[256], *ptr, *endptr;
        size_t  ptrlen;
        long    limit;
-       u_int   idx;
 
        errno = 0;
        limit = strtol(*iptr, &endptr, 10);
@@ -403,8 +400,6 @@ status_replace1(struct client *c, struct session *s, struct 
winlink *wl,
        if (limit <= 0)
                limit = LONG_MAX;
 
-       freeptr = NULL;
-
        switch (*(*iptr)++) {
        case '(':
                if (!jobsflag) {
@@ -414,45 +409,6 @@ status_replace1(struct client *c, struct session *s, 
struct winlink *wl,
                if ((ptr = status_find_job(c, iptr)) == NULL)
                        return;
                goto do_replace;
-       case 'D':
-               xsnprintf(tmp, sizeof tmp, "%%%u", wp->id);
-               ptr = tmp;
-               goto do_replace;
-       case 'H':
-               if (gethostname(tmp, sizeof tmp) != 0)
-                       fatal("gethostname failed");
-               ptr = tmp;
-               goto do_replace;
-       case 'h':
-               if (gethostname(tmp, sizeof tmp) != 0)
-                       fatal("gethostname failed");
-               if ((ptr = strchr(tmp, '.')) != NULL)
-                       *ptr = '\0';
-               ptr = tmp;
-               goto do_replace;
-       case 'I':
-               xsnprintf(tmp, sizeof tmp, "%d", wl->idx);
-               ptr = tmp;
-               goto do_replace;
-       case 'P':
-               if (window_pane_index(wp, &idx) != 0)
-                       fatalx("index not found");
-               xsnprintf(tmp, sizeof tmp, "%u", idx);
-               ptr = tmp;
-               goto do_replace;
-       case 'S':
-               ptr = s->name;
-               goto do_replace;
-       case 'T':
-               ptr = wp->base.title;
-               goto do_replace;
-       case 'W':
-               ptr = wl->window->name;
-               goto do_replace;
-       case 'F':
-               ptr = window_printable_flags(s, wl);
-               freeptr = ptr;
-               goto do_replace;
        case '[':
                /*
                 * Embedded style, handled at display time. Leave present and
@@ -466,6 +422,10 @@ status_replace1(struct client *c, struct session *s, 
struct winlink *wl,
        case '#':
                *(*optr)++ = '#';
                break;
+       default:
+               xsnprintf(tmp, sizeof tmp, "#%c", *(*iptr - 1));
+               ptr = tmp;
+               goto do_replace;
        }
 
        return;
@@ -476,14 +436,12 @@ do_replace:
                ptrlen = limit;
 
        if (*optr + ptrlen >= out + outsize - 1)
-               goto out;
+               return;
        while (ptrlen > 0 && *ptr != '\0') {
                *(*optr)++ = *ptr++;
                ptrlen--;
        }
 
-out:
-       free(freeptr);
        return;
 
 skip_to:
@@ -532,8 +490,7 @@ status_replace(struct client *c, struct session *s, struct 
winlink *wl,
                        *optr++ = ch;
                        continue;
                }
-               status_replace1(
-                   c, s, wl, wp, &iptr, &optr, out, sizeof out, jobsflag);
+               status_replace1(c, &iptr, &optr, out, sizeof out, jobsflag);
        }
        *optr = '\0';
 
diff --git a/tmux.1 b/tmux.1
index 1ce94a1..40b0ef7 100644
--- a/tmux.1
+++ b/tmux.1
@@ -2438,27 +2438,18 @@ environment variables are set and contain the string
 .It Ic status-left Ar string
 Display
 .Ar string
-to the left of the status bar.
+(by default the session name) to the left of the status bar.
 .Ar string
 will be passed through
 .Xr strftime 3
-before being used.
-By default, the session name is shown.
-.Ar string
-may contain any of the following special character sequences:
+and formats (see
+.Sx FORMATS Ns )
+will be expanded.
+It may also contain any of the following special character sequences:
 .Bl -column "Character pair" "Replaced with" -offset indent
 .It Sy "Character pair" Ta Sy "Replaced with"
 .It Li "#(shell-command)" Ta "First line of the command's output"
 .It Li "#[attributes]" Ta "Colour or attribute change"
-.It Li "#H" Ta "Hostname of local host"
-.It Li "#h" Ta "Hostname of local host without the domain name"
-.It Li "#F" Ta "Current window flag"
-.It Li "#I" Ta "Current window index"
-.It Li "#D" Ta "Current pane unique identifier"
-.It Li "#P" Ta "Current pane index"
-.It Li "#S" Ta "Session name"
-.It Li "#T" Ta "Current pane title"
-.It Li "#W" Ta "Current window name"
 .It Li "##" Ta "A literal" Ql #
 .El
 .Pp
@@ -3003,16 +2994,13 @@ flag with a
 .Ar format
 argument.
 This is a string which controls the output format of the command.
-Special character sequences are replaced as documented under the
-.Ic status-left
-option and an additional long form is accepted.
 Replacement variables are enclosed in
 .Ql #{
 and
 .Ql } ,
 for example
-.Ql #{session_name}
-is equivalent to
+.Ql #{session_name} .
+Some variables also have an shorter alias such as
 .Ql #S .
 Conditionals are also accepted by prefixing with
 .Ql \&?
@@ -3028,83 +3016,83 @@ if the session is attached and the string
 if it is unattached.
 .Pp
 The following variables are available, where appropriate:
-.Bl -column "session_created_string" "Replaced with" -offset indent
-.It Sy "Variable name" Ta Sy "Replaced with"
-.It Li "alternate_on" Ta "If pane is in alternate screen"
-.It Li "alternate_saved_x" Ta "Saved cursor X in alternate screen"
-.It Li "alternate_saved_y" Ta "Saved cursor Y in alternate screen"
-.It Li "buffer_sample" Ta "First 50 characters from the specified buffer"
-.It Li "buffer_size" Ta "Size of the specified buffer in bytes"
-.It Li "client_activity" Ta "Integer time client last had activity"
-.It Li "client_activity_string" Ta "String time client last had activity"
-.It Li "client_created" Ta "Integer time client created"
-.It Li "client_created_string" Ta "String time client created"
-.It Li "client_cwd" Ta "Working directory of client"
-.It Li "client_height" Ta "Height of client"
-.It Li "client_last_session" Ta "Name of the client's last session"
-.It Li "client_prefix" Ta "1 if prefix key has been pressed"
-.It Li "client_readonly" Ta "1 if client is readonly"
-.It Li "client_session" Ta "Name of the client's session"
-.It Li "client_termname" Ta "Terminal name of client"
-.It Li "client_tty" Ta "Pseudo terminal of client"
-.It Li "client_utf8" Ta "1 if client supports utf8"
-.It Li "client_width" Ta "Width of client"
-.It Li "cursor_flag" Ta "Pane cursor flag"
-.It Li "cursor_x" Ta "Cursor X position in pane"
-.It Li "cursor_y" Ta "Cursor Y position in pane"
-.It Li "history_bytes" Ta "Number of bytes in window history"
-.It Li "history_limit" Ta "Maximum window history lines"
-.It Li "history_size" Ta "Size of history in bytes"
-.It Li "host" Ta "Hostname of local host"
-.It Li "host_short" Ta "Hostname of local host (no domain name)"
-.It Li "insert_flag" Ta "Pane insert flag"
-.It Li "keypad_cursor_flag" Ta "Pane keypad cursor flag"
-.It Li "keypad_flag" Ta "Pane keypad flag"
-.It Li "line" Ta "Line number in the list"
-.It Li "mouse_any_flag" Ta "Pane mouse any flag"
-.It Li "mouse_button_flag" Ta "Pane mouse button flag"
-.It Li "mouse_standard_flag" Ta "Pane mouse standard flag"
-.It Li "mouse_utf8_flag" Ta "Pane mouse UTF-8 flag"
-.It Li "pane_active" Ta "1 if active pane"
-.It Li "pane_current_command" Ta "Current command if available"
-.It Li "pane_current_path" Ta "Current path if available"
-.It Li "pane_dead" Ta "1 if pane is dead"
-.It Li "pane_height" Ta "Height of pane"
-.It Li "pane_id" Ta "Unique pane ID"
-.It Li "pane_in_mode" Ta "If pane is in a mode"
-.It Li "pane_index" Ta "Index of pane"
-.It Li "pane_pid" Ta "PID of first process in pane"
-.It Li "pane_start_command" Ta "Command pane started with"
-.It Li "pane_start_path" Ta "Path pane started with"
-.It Li "pane_tabs" Ta "Pane tab positions"
-.It Li "pane_title" Ta "Title of pane"
-.It Li "pane_tty" Ta "Pseudo terminal of pane"
-.It Li "pane_width" Ta "Width of pane"
-.It Li "saved_cursor_x" Ta "Saved cursor X in pane"
-.It Li "saved_cursor_y" Ta "Saved cursor Y in pane"
-.It Li "scroll_region_lower" Ta "Bottom of scroll region in pane"
-.It Li "scroll_region_upper" Ta "Top of scroll region in pane"
-.It Li "session_attached" Ta "1 if session attached"
-.It Li "session_created" Ta "Integer time session created"
-.It Li "session_created_string" Ta "String time session created"
-.It Li "session_group" Ta "Number of session group"
-.It Li "session_grouped" Ta "1 if session in a group"
-.It Li "session_height" Ta "Height of session"
-.It Li "session_id" Ta "Unique session ID"
-.It Li "session_name" Ta "Name of session"
-.It Li "session_width" Ta "Width of session"
-.It Li "session_windows" Ta "Number of windows in session"
-.It Li "window_active" Ta "1 if window active"
-.It Li "window_find_matches" Ta "Matched data from the find-window command if 
available"
-.It Li "window_flags" Ta "Window flags"
-.It Li "window_height" Ta "Height of window"
-.It Li "window_id" Ta "Unique window ID"
-.It Li "window_index" Ta "Index of window"
-.It Li "window_layout" Ta "Window layout description"
-.It Li "window_name" Ta "Name of window"
-.It Li "window_panes" Ta "Number of panes in window"
-.It Li "window_width" Ta "Width of window"
-.It Li "wrap_flag" Ta "Pane wrap flag"
+.Bl -column "XXXXXXXXXXXXXXXXXXX" "XXXXX"
+.It Sy "Variable name" Ta Sy "Alias" Ta Sy "Replaced with"
+.It Li "alternate_on" Ta "" Ta "If pane is in alternate screen"
+.It Li "alternate_saved_x" Ta "" Ta "Saved cursor X in alternate screen"
+.It Li "alternate_saved_y" Ta "" Ta "Saved cursor Y in alternate screen"
+.It Li "buffer_sample" Ta "" Ta "First 50 characters from buffer"
+.It Li "buffer_size" Ta "" Ta "Size of the specified buffer in bytes"
+.It Li "client_activity" Ta "" Ta "Integer time client last had activity"
+.It Li "client_activity_string" Ta "" Ta "String time client last had activity"
+.It Li "client_created" Ta "" Ta "Integer time client created"
+.It Li "client_created_string" Ta "" Ta "String time client created"
+.It Li "client_cwd" Ta "" Ta "Working directory of client"
+.It Li "client_height" Ta "" Ta "Height of client"
+.It Li "client_last_session" Ta "" Ta "Name of the client's last session"
+.It Li "client_prefix" Ta "" Ta "1 if prefix key has been pressed"
+.It Li "client_readonly" Ta "" Ta "1 if client is readonly"
+.It Li "client_session" Ta "" Ta "Name of the client's session"
+.It Li "client_termname" Ta "" Ta "Terminal name of client"
+.It Li "client_tty" Ta "" Ta "Pseudo terminal of client"
+.It Li "client_utf8" Ta "" Ta "1 if client supports utf8"
+.It Li "client_width" Ta "" Ta "Width of client"
+.It Li "cursor_flag" Ta "" Ta "Pane cursor flag"
+.It Li "cursor_x" Ta "" Ta "Cursor X position in pane"
+.It Li "cursor_y" Ta "" Ta "Cursor Y position in pane"
+.It Li "history_bytes" Ta "" Ta "Number of bytes in window history"
+.It Li "history_limit" Ta "" Ta "Maximum window history lines"
+.It Li "history_size" Ta "" Ta "Size of history in bytes"
+.It Li "host" Ta "#H" Ta "Hostname of local host"
+.It Li "host_short" Ta "#h" Ta "Hostname of local host (no domain name)"
+.It Li "insert_flag" Ta "" Ta "Pane insert flag"
+.It Li "keypad_cursor_flag" Ta "" Ta "Pane keypad cursor flag"
+.It Li "keypad_flag" Ta "" Ta "Pane keypad flag"
+.It Li "line" Ta "" Ta "Line number in the list"
+.It Li "mouse_any_flag" Ta "" Ta "Pane mouse any flag"
+.It Li "mouse_button_flag" Ta "" Ta "Pane mouse button flag"
+.It Li "mouse_standard_flag" Ta "" Ta "Pane mouse standard flag"
+.It Li "mouse_utf8_flag" Ta "" Ta "Pane mouse UTF-8 flag"
+.It Li "pane_active" Ta "" Ta "1 if active pane"
+.It Li "pane_current_command" Ta "" Ta "Current command if available"
+.It Li "pane_current_path" Ta "" Ta "Current path if available"
+.It Li "pane_dead" Ta "" Ta "1 if pane is dead"
+.It Li "pane_height" Ta "" Ta "Height of pane"
+.It Li "pane_id" Ta "#D" Ta "Unique pane ID"
+.It Li "pane_in_mode" Ta "" Ta "If pane is in a mode"
+.It Li "pane_index" Ta "#P" Ta "Index of pane"
+.It Li "pane_pid" Ta "" Ta "PID of first process in pane"
+.It Li "pane_start_command" Ta "" Ta "Command pane started with"
+.It Li "pane_start_path" Ta "" Ta "Path pane started with"
+.It Li "pane_tabs" Ta "" Ta "Pane tab positions"
+.It Li "pane_title" Ta "#T" Ta "Title of pane"
+.It Li "pane_tty" Ta "" Ta "Pseudo terminal of pane"
+.It Li "pane_width" Ta "" Ta "Width of pane"
+.It Li "saved_cursor_x" Ta "" Ta "Saved cursor X in pane"
+.It Li "saved_cursor_y" Ta "" Ta "Saved cursor Y in pane"
+.It Li "scroll_region_lower" Ta "" Ta "Bottom of scroll region in pane"
+.It Li "scroll_region_upper" Ta "" Ta "Top of scroll region in pane"
+.It Li "session_attached" Ta "" Ta "1 if session attached"
+.It Li "session_created" Ta "" Ta "Integer time session created"
+.It Li "session_created_string" Ta "" Ta "String time session created"
+.It Li "session_group" Ta "" Ta "Number of session group"
+.It Li "session_grouped" Ta "" Ta "1 if session in a group"
+.It Li "session_height" Ta "" Ta "Height of session"
+.It Li "session_id" Ta "" Ta "Unique session ID"
+.It Li "session_name" Ta "#S" Ta "Name of session"
+.It Li "session_width" Ta "" Ta "Width of session"
+.It Li "session_windows" Ta "" Ta "Number of windows in session"
+.It Li "window_active" Ta "" Ta "1 if window active"
+.It Li "window_find_matches" Ta "" Ta "Matched data from the find-window"
+.It Li "window_flags" Ta "#F" Ta "Window flags"
+.It Li "window_height" Ta "" Ta "Height of window"
+.It Li "window_id" Ta "" Ta "Unique window ID"
+.It Li "window_index" Ta "#I" Ta "Index of window"
+.It Li "window_layout" Ta "" Ta "Window layout description"
+.It Li "window_name" Ta "#W" Ta "Name of window"
+.It Li "window_panes" Ta "" Ta "Number of panes in window"
+.It Li "window_width" Ta "" Ta "Width of window"
+.It Li "wrap_flag" Ta "" Ta "Pane wrap flag"
 .El
 .Sh NAMES AND TITLES
 .Nm


commit c30d60f7ae7631a4c2edc241739b5c6eff110a24
Author: Nicholas Marriott <[email protected]>
Commit: Nicholas Marriott <[email protected]>

    Add host_short format, from Tiago Cunha.
---
 format.c |   74 ++++++++++++++++++++++++++++++++++++++++++++++----------------
 tmux.1   |    1 +
 2 files changed, 56 insertions(+), 19 deletions(-)

diff --git a/format.c b/format.c
index 9918cfe..8ed1c1b 100644
--- a/format.c
+++ b/format.c
@@ -46,8 +46,8 @@ format_cmp(struct format_entry *fe1, struct format_entry *fe2)
        return (strcmp(fe1->key, fe2->key));
 }
 
-/* Single-character aliases. */
-const char *format_aliases[26] = {
+/* Single-character uppercase aliases. */
+const char *format_upper[] = {
        NULL,           /* A */
        NULL,           /* B */
        NULL,           /* C */
@@ -76,18 +76,52 @@ const char *format_aliases[26] = {
        NULL            /* Z */
 };
 
+/* Single-character lowercase aliases. */
+const char *format_lower[] = {
+       NULL,           /* a */
+       NULL,           /* b */
+       NULL,           /* c */
+       NULL,           /* d */
+       NULL,           /* e */
+       NULL,           /* f */
+       NULL,           /* g */
+       "host_short",   /* h */
+       NULL,           /* i */
+       NULL,           /* j */
+       NULL,           /* k */
+       NULL,           /* l */
+       NULL,           /* m */
+       NULL,           /* n */
+       NULL,           /* o */
+       NULL,           /* p */
+       NULL,           /* q */
+       NULL,           /* r */
+       NULL,           /* s */
+       NULL,           /* t */
+       NULL,           /* u */
+       NULL,           /* v */
+       NULL,           /* w */
+       NULL,           /* x */
+       NULL,           /* y */
+       NULL            /* z */
+};
+
 /* Create a new tree. */
 struct format_tree *
 format_create(void)
 {
        struct format_tree      *ft;
-       char                     host[MAXHOSTNAMELEN];
+       char                     host[MAXHOSTNAMELEN], *ptr;
 
        ft = xmalloc(sizeof *ft);
        RB_INIT(ft);
 
-       if (gethostname(host, sizeof host) == 0)
+       if (gethostname(host, sizeof host) == 0) {
                format_add(ft, "host", "%s", host);
+               if ((ptr = strrchr(host, '.')) != NULL)
+                       *ptr = '\0';
+               format_add(ft, "host_short", "%s", host);
+       }
 
        return (ft);
 }
@@ -109,7 +143,7 @@ format_free(struct format_tree *ft)
                free(fe);
        }
 
-       free (ft);
+       free(ft);
 }
 
 /* Add a key-value pair. */
@@ -230,6 +264,7 @@ format_expand(struct format_tree *ft, const char *fmt)
                fmt++;
 
                ch = (u_char) *fmt++;
+
                switch (ch) {
                case '{':
                        ptr = strchr(fmt, '}');
@@ -242,22 +277,23 @@ format_expand(struct format_tree *ft, const char *fmt)
                        fmt += n + 1;
                        continue;
                default:
-                       if (ch >= 'A' && ch <= 'Z') {
-                               s = format_aliases[ch - 'A'];
-                               if (s != NULL) {
-                                       n = strlen(s);
-                                       if (format_replace (
-                                           ft, s, n, &buf, &len, &off) != 0)
-                                               break;
-                                       continue;
+                       s = NULL;
+                       if (ch >= 'A' && ch <= 'Z')
+                               s = format_upper[ch - 'A'];
+                       else if (ch >= 'a' && ch <= 'z')
+                               s = format_lower[ch - 'a'];
+                       if (s == NULL) {
+                               while (len - off < 3) {
+                                       buf = xrealloc(buf, 2, len);
+                                       len *= 2;
                                }
+                               buf[off++] = '#';
+                               buf[off++] = ch;
+                               continue;
                        }
-                       while (len - off < 3) {
-                               buf = xrealloc(buf, 2, len);
-                               len *= 2;
-                       }
-                       buf[off++] = '#';
-                       buf[off++] = ch;
+                       n = strlen(s);
+                       if (format_replace(ft, s, n, &buf, &len, &off) != 0)
+                               break;
                        continue;
                }
 
diff --git a/tmux.1 b/tmux.1
index 9b874f7..1ce94a1 100644
--- a/tmux.1
+++ b/tmux.1
@@ -3056,6 +3056,7 @@ The following variables are available, where appropriate:
 .It Li "history_limit" Ta "Maximum window history lines"
 .It Li "history_size" Ta "Size of history in bytes"
 .It Li "host" Ta "Hostname of local host"
+.It Li "host_short" Ta "Hostname of local host (no domain name)"
 .It Li "insert_flag" Ta "Pane insert flag"
 .It Li "keypad_cursor_flag" Ta "Pane keypad cursor flag"
 .It Li "keypad_flag" Ta "Pane keypad flag"


commit 9fb9f78e43337833825ae464a1c39ed6d78a2fdb
Author: Nicholas Marriott <[email protected]>
Commit: Nicholas Marriott <[email protected]>

    Use u_char for the send-keys string to avoid mangling top-bit-set
    characters when they are promoted to int and passed to
    window_pane_key. Reported by Jacob Bang.
---
 cmd-send-keys.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/cmd-send-keys.c b/cmd-send-keys.c
index 3ee3dbe..dcd5f28 100644
--- a/cmd-send-keys.c
+++ b/cmd-send-keys.c
@@ -56,7 +56,7 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
        struct window_pane      *wp;
        struct session          *s;
        struct input_ctx        *ictx;
-       const char              *str;
+       const u_char            *str;
        int                      i, key;
 
        if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)


commit a0cf65db77343cf60a72c59596ccfcaebe91c663
Author: Nicholas Marriott <[email protected]>
Commit: Nicholas Marriott <[email protected]>

    Instead of eating 1024 bytes or so for the arguments of each command,
    save memory by using an RB tree. From Tiago Cunha.
---
 arguments.c |  120 ++++++++++++++++++++++++++++++++++++++--------------------
 tmux.h      |   19 ++++++---
 2 files changed, 91 insertions(+), 48 deletions(-)

diff --git a/arguments.c b/arguments.c
index c15832a..ca828f0 100644
--- a/arguments.c
+++ b/arguments.c
@@ -18,12 +18,26 @@
 
 #include <sys/types.h>
 
-#include <bitstring.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "tmux.h"
 
+/*
+ * Manipulate command arguments.
+ */
+
+struct args_entry      *args_find(struct args *, u_char);
+
+RB_GENERATE(args_tree, args_entry, entry, args_cmp);
+
+/* Arguments tree comparison function. */
+int
+args_cmp(struct args_entry *a1, struct args_entry *a2)
+{
+       return (a1->flag - a2->flag);
+}
+
 /* Create an arguments set with no flags. */
 struct args *
 args_create(int argc, ...)
@@ -33,8 +47,6 @@ args_create(int argc, ...)
        int              i;
 
        args = xcalloc(1, sizeof *args);
-       if ((args->flags = bit_alloc(SCHAR_MAX)) == NULL)
-               fatal("bit_alloc failed");
 
        args->argc = argc;
        if (argc == 0)
@@ -50,6 +62,16 @@ args_create(int argc, ...)
        return (args);
 }
 
+/* Find a flag in the arguments tree. */
+struct args_entry *
+args_find(struct args *args, u_char ch)
+{
+       struct args_entry       entry;
+
+       entry.flag = ch;
+       return (RB_FIND(args_tree, &args->tree, &entry));
+}
+
 /* Parse an argv and argc into a new argument set. */
 struct args *
 args_parse(const char *template, int argc, char **argv)
@@ -59,26 +81,18 @@ args_parse(const char *template, int argc, char **argv)
        int              opt;
 
        args = xcalloc(1, sizeof *args);
-       if ((args->flags = bit_alloc(SCHAR_MAX)) == NULL)
-               fatal("bit_alloc failed");
 
        optreset = 1;
        optind = 1;
 
        while ((opt = getopt(argc, argv, template)) != -1) {
-               if (opt < 0 || opt >= SCHAR_MAX)
+               if (opt < 0)
                        continue;
                if (opt == '?' || (ptr = strchr(template, opt)) == NULL) {
-                       free(args->flags);
-                       free(args);
+                       args_free(args);
                        return (NULL);
                }
-
-               bit_set(args->flags, opt);
-               if (ptr[1] == ':') {
-                       free(args->values[opt]);
-                       args->values[opt] = xstrdup(optarg);
-               }
+               args_set(args, opt, optarg);
        }
        argc -= optind;
        argv += optind;
@@ -93,14 +107,17 @@ args_parse(const char *template, int argc, char **argv)
 void
 args_free(struct args *args)
 {
-       u_int   i;
+       struct args_entry       *entry;
+       struct args_entry       *entry1;
 
        cmd_free_argv(args->argc, args->argv);
 
-       for (i = 0; i < SCHAR_MAX; i++)
-               free(args->values[i]);
+       RB_FOREACH_SAFE(entry, args_tree, &args->tree, entry1) {
+               RB_REMOVE(args_tree, &args->tree, entry);
+               free(entry->value);
+               free(entry);
+       }
 
-       free(args->flags);
        free(args);
 }
 
@@ -108,9 +125,10 @@ args_free(struct args *args)
 size_t
 args_print(struct args *args, char *buf, size_t len)
 {
-       size_t           off;
-       int              i;
-       const char      *quotes;
+       size_t                   off;
+       int                      i;
+       const char              *quotes;
+       struct args_entry       *entry;
 
        /* There must be at least one byte at the start. */
        if (len == 0)
@@ -119,23 +137,23 @@ args_print(struct args *args, char *buf, size_t len)
 
        /* Process the flags first. */
        buf[off++] = '-';
-       for (i = 0; i < SCHAR_MAX; i++) {
-               if (!bit_test(args->flags, i) || args->values[i] != NULL)
+       RB_FOREACH(entry, args_tree, &args->tree) {
+               if (entry->value != NULL)
                        continue;
 
                if (off == len - 1) {
                        buf[off] = '\0';
                        return (len);
                }
-               buf[off++] = i;
+               buf[off++] = entry->flag;
                buf[off] = '\0';
        }
        if (off == 1)
                buf[--off] = '\0';
 
        /* Then the flags with arguments. */
-       for (i = 0; i < SCHAR_MAX; i++) {
-               if (!bit_test(args->flags, i) || args->values[i] == NULL)
+       RB_FOREACH(entry, args_tree, &args->tree) {
+               if (entry->value == NULL)
                        continue;
 
                if (off >= len) {
@@ -143,12 +161,13 @@ args_print(struct args *args, char *buf, size_t len)
                        return (len);
                }
 
-               if (strchr(args->values[i], ' ') != NULL)
+               if (strchr(entry->value, ' ') != NULL)
                        quotes = "\"";
                else
                        quotes = "";
                off += xsnprintf(buf + off, len - off, "%s-%c %s%s%s",
-                   off != 0 ? " " : "", i, quotes, args->values[i], quotes);
+                   off != 0 ? " " : "", entry->flag, quotes, entry->value,
+                   quotes);
        }
 
        /* And finally the argument vector. */
@@ -173,42 +192,59 @@ args_print(struct args *args, char *buf, size_t len)
 int
 args_has(struct args *args, u_char ch)
 {
-       return (bit_test(args->flags, ch));
+       return (args_find(args, ch) == NULL ? 0 : 1);
 }
 
-/* Set argument value. */
+/* Set argument value in the arguments tree. */
 void
 args_set(struct args *args, u_char ch, const char *value)
 {
-       free(args->values[ch]);
+       struct args_entry       *entry;
+
+       /* Replace existing argument. */
+       if ((entry = args_find(args, ch)) != NULL) {
+               free(entry->value);
+               if (value != NULL)
+                       entry->value = xstrdup(value);
+               else
+                       entry->value = NULL;
+               return;
+       }
+
+       entry = xcalloc(1, sizeof *entry);
+       entry->flag = ch;
        if (value != NULL)
-               args->values[ch] = xstrdup(value);
-       else
-               args->values[ch] = NULL;
-       bit_set(args->flags, ch);
+               entry->value = xstrdup(value);
+
+       RB_INSERT(args_tree, &args->tree, entry);
 }
 
 /* Get argument value. Will be NULL if it isn't present. */
 const char *
 args_get(struct args *args, u_char ch)
 {
-       return (args->values[ch]);
+       struct args_entry       *entry;
+
+       if ((entry = args_find(args, ch)) == NULL)
+               return (NULL);
+       return (entry->value);
 }
 
 /* Convert an argument value to a number. */
 long long
-args_strtonum(struct args *args,
-    u_char ch, long long minval, long long maxval, char **cause)
+args_strtonum(struct args *args, u_char ch, long long minval, long long maxval,
+    char **cause)
 {
-       const char      *errstr;
-       long long        ll;
+       const char              *errstr;
+       long long                ll;
+       struct args_entry       *entry;
 
-       if (!args_has(args, ch)) {
+       if ((entry = args_find(args, ch)) == NULL) {
                *cause = xstrdup("missing");
                return (0);
        }
 
-       ll = strtonum(args->values[ch], minval, maxval, &errstr);
+       ll = strtonum(entry->value, minval, maxval, &errstr);
        if (errstr != NULL) {
                *cause = xstrdup(errstr);
                return (0);
diff --git a/tmux.h b/tmux.h
index 7404b27..7c577b4 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1361,13 +1361,18 @@ struct client {
 };
 ARRAY_DECL(clients, struct client *);
 
-/* Parsed arguments. */
-struct args {
-       bitstr_t        *flags;
-       char            *values[SCHAR_MAX]; /* XXX This is awfully big. */
+/* Parsed arguments structures. */
+struct args_entry {
+       u_char                   flag;
+       char                    *value;
+       RB_ENTRY(args_entry)     entry;
+};
+RB_HEAD(args_tree, args_entry);
 
-       int              argc;
-       char           **argv;
+struct args {
+       struct args_tree          tree;
+       int                       argc;
+       char                    **argv;
 };
 
 /* Command and list of commands. */
@@ -1724,6 +1729,8 @@ extern const char clock_table[14][5][5];
 void            clock_draw(struct screen_write_ctx *, int, int);
 
 /* arguments.c */
+int             args_cmp(struct args_entry *, struct args_entry *);
+RB_PROTOTYPE(args_tree, args_entry, entry, args_cmp);
 struct args    *args_create(int, ...);
 struct args    *args_parse(const char *, int, char **);
 void            args_free(struct args *);


-----------------------------------------------------------------------

Summary of changes:
 arguments.c     |  119 ++++++++++++++++++++++++-------------
 cmd-send-keys.c |    2 +-
 format.c        |   74 +++++++++++++++++------
 status.c        |   61 +++----------------
 tmux.1          |  179 ++++++++++++++++++++++++++-----------------------------
 tmux.h          |   19 ++++--
 6 files changed, 240 insertions(+), 214 deletions(-)


hooks/post-receive
-- 
tmux

------------------------------------------------------------------------------
Get 100% visibility into Java/.NET code with AppDynamics Lite
It's a free troubleshooting tool designed for production
Get down to code-level detail for bottlenecks, with <2% overhead.
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap2
_______________________________________________
tmux-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-cvs

Reply via email to