How about this?

diff --git a/format.c b/format.c
index 0845df6..9a3ed07 100644
--- a/format.c
+++ b/format.c
@@ -191,7 +191,7 @@ int
 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, *ptr, *saved;
        const char      *value;
        size_t           valuelen;
 
@@ -223,10 +223,15 @@ format_replace(struct format_tree *ft,
                                goto fail;
                        value = ptr + 1;
                }
+               value = format_expand(ft, value);
+
+               saved = value;
        } else {
                value = format_find(ft, copy);
                if (value == NULL)
                        value = "";
+
+               saved = NULL;
        }
        valuelen = strlen(value);
 
@@ -238,6 +243,7 @@ format_replace(struct format_tree *ft,
        memcpy(*buf + *off, value, valuelen);
        *off += valuelen;
 
+       free(saved);
        free(copy);
        return (0);
 
@@ -253,7 +259,7 @@ format_expand(struct format_tree *ft, const char *fmt)
        char            *buf, *ptr;
        const char      *s;
        size_t           off, len, n;
-       int              ch;
+       int              ch, brackets;
 
        len = 64;
        buf = xmalloc(len);
@@ -271,11 +277,16 @@ format_expand(struct format_tree *ft, const char *fmt)
                fmt++;
 
                ch = (u_char) *fmt++;
-
                switch (ch) {
                case '{':
-                       ptr = strchr(fmt, '}');
-                       if (ptr == NULL)
+                       brackets = 1;
+                       for (ptr = fmt; *ptr != '\0'; ptr++) {
+                               if (*ptr == '{')
+                                       brackets++;
+                               if (*ptr == '}' && --brackets == 0)
+                                       break;
+                       }
+                       if (*ptr != '}' || brackets != 0)
                                break;
                        n = ptr - fmt;
 




On Wed, May 15, 2013 at 05:01:53PM +0100, Nicholas Marriott wrote:
> This still doesn't seem right.
> 
> If I have "#{?foo,bar,#{baz}} #{zoink}".
> 
> Then in format_expand it'll decide the first { is: "?foo,bar,#{baz}}
> #{zoink".
> 
> Then if foo is true I'll get bar (which is fine)
> 
> But if it's false I'll get "#{baz}} #{zoink" which is wrong.
> 
> You need to replace the strchr with a loop like:
> 
> depth = 1;
> ptr = fmt;
> while (*ptr != '\0') {
>       if (*ptr == '{')
>               depth++;
>       if (*ptr == '}') {
>               if (--depth == 0)
>                       break;
>       }
> }
> 
> Which means format_replace will be passed exactly "?foo,bar,#{baz}".
> 
> 
> On Sun, Apr 28, 2013 at 01:54:44PM +0100, Thomas Adam wrote:
> > Hi,
> > 
> > On Thu, Apr 25, 2013 at 10:55:56PM +0100, Nicholas Marriott wrote:
> > > Ok. I think you have the right idea about recursing through
> > > format_expand you are just going to need to pull out the affected format
> > > differently (ditch strchr and use a custom loop which counts {s and }s).
> > 
> > Yeah, that's one way.  But actually, strchr/strchrr would both be doing the
> > same thing as this manual loop you refer to, it's just that their use would
> > vary depending on whether we're expanding a terniary-form of a format
> > replacement or just a single element.
> > 
> > So I think something along the lines of the patch attached might be an idea.
> > It's certainly the path of least resistance (i.e., not much code changed)
> > but that doesn't mean I particularly like it.  ;P
> > 
> > -- Thomas Adam
> 
> > diff --git a/format.c b/format.c
> > index 7de819a..178f201 100644
> > --- a/format.c
> > +++ b/format.c
> > @@ -150,8 +150,8 @@ int
> >  format_replace(struct format_tree *ft,
> >      const char *key, size_t keylen, char **buf, size_t *len, size_t *off)
> >  {
> > -   char            *copy, *ptr;
> >     const char      *value;
> > +   char            *copy, *ptr;
> >     size_t           valuelen;
> >  
> >     /* Make a copy of the key. */
> > @@ -182,6 +182,7 @@ format_replace(struct format_tree *ft,
> >                             goto fail;
> >                     value = ptr + 1;
> >             }
> > +           value = format_expand(ft, value);
> >     } else {
> >             value = format_find(ft, copy);
> >             if (value == NULL)
> > @@ -232,7 +233,11 @@ format_expand(struct format_tree *ft, const char *fmt)
> >             ch = (u_char) *fmt++;
> >             switch (ch) {
> >             case '{':
> > -                   ptr = strchr(fmt, '}');
> > +                   if (*fmt++ == '?')
> > +                           ptr = strrchr(--fmt, '}');
> > +                   else
> > +                           ptr = strchr(--fmt, '}');
> 
> There is no need to do fmt++ if you then do --fmt in both branches of
> the if.
> 
> > +
> >                     if (ptr == NULL)
> >                             break;
> >                     n = ptr - fmt;
> > -- 
> > 1.7.11.4
> > 
> 

------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent 
caught up. So what steps can you take to put your SQL databases under 
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to