From 804beb9266f9f731329d90b56842a863598f25ff Mon Sep 17 00:00:00 2001 From: Tiago Cunha Date: Sun, 1 Feb 2009 18:14:49 +0000 Subject: [PATCH] Support commands with right parenthesis. From nicm and me. --- CHANGES | 6 +++++- FAQ | 15 +++++++++++++++ status.c | 39 ++++++++++++++++++++++++++++++--------- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/CHANGES b/CHANGES index 7a095b18..b512af76 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +01 February 2009 + +* The character pair #(command) may now contain (escaped) right parenthesis. + 30 January 2009 * . now bound to "command-prompt 'move-window %%'" by default, from joshe. @@ -1070,7 +1074,7 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.245 2009-01-30 21:10:10 nicm Exp $ +$Id: CHANGES,v 1.246 2009-02-01 18:14:49 tcunha Exp $ LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms diff --git a/FAQ b/FAQ index f7d02b99..8bdc0ed3 100644 --- a/FAQ +++ b/FAQ @@ -164,3 +164,18 @@ exit (elinks, for some strange reason, sets it to the value of TERM): STY= `which elinks` $* echo -ne \\033]0\;\\007; } + +* What's the proper way to escape characters with #(command)? + +When using the character pair #(command), the command will be parsed twice. +First when it's read by the configuration file, or the command-prompt parser, +and another right before the command is passed to the shell by popen(3). As an +example, to echo the string (test) to the status line, one could use single, +or double-quotes (the meaning is the same as if in the shell): + + set -g status-right "#(echo \\\\(test\\\\))" + set -g status-right '#(echo \\\(test\\\))' + +With the double-quotes, the string when is first parsed will be set to +#(echo \\(test\\)), and then again parsed as echo \(test\) before passing the +command to sh -c. diff --git a/status.c b/status.c index 7850cfd6..47299388 100644 --- a/status.c +++ b/status.c @@ -1,4 +1,4 @@ -/* $Id: status.c,v 1.70 2009-01-30 00:24:49 nicm Exp $ */ +/* $Id: status.c,v 1.71 2009-02-01 18:14:49 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -376,16 +376,37 @@ char * status_replace_popen(char **iptr) { FILE *f; - char *buf = NULL; - char cmd[BUFSIZ]; - char *ptr = NULL; + char *buf, *cmd, *ptr; + int lastesc; size_t len; - if (**iptr == '\0' || strchr(*iptr, ')') == NULL) + if (**iptr == '\0') return (NULL); + if (**iptr == ')') { /* no command given */ + (*iptr)++; + return (NULL); + } - strlcpy(cmd, *iptr, sizeof cmd); - cmd[strcspn(cmd, ")")] = '\0'; + buf = NULL; + + cmd = xmalloc(strlen(*iptr) + 1); + len = 0; + + lastesc = 0; + for (; **iptr != '\0'; (*iptr)++) { + if (!lastesc && **iptr == ')') + break; /* unescaped ) is the end */ + if (!lastesc && **iptr == '\\') { + lastesc = 1; + continue; /* skip \ if not escaped */ + } + lastesc = 0; + cmd[len++] = **iptr; + } + if (**iptr == '\0') /* no terminating ) */ + goto out; + (*iptr)++; /* skip final ) */ + cmd[len] = '\0'; if ((f = popen(cmd, "r")) == NULL) goto out; @@ -398,7 +419,7 @@ status_replace_popen(char **iptr) buf[len - 1] = '\0'; buf = xstrdup(buf); } else { - ptr = xrealloc(ptr, 1, len + 1); + ptr = xmalloc(len + 1); memcpy(ptr, buf, len); ptr[len] = '\0'; buf = ptr; @@ -406,7 +427,7 @@ status_replace_popen(char **iptr) pclose(f); out: - *iptr = (strchr(*iptr, ')') + 1); + xfree(cmd); return (buf); }