Hi

This breaks quotes, for example try:

  neww -n "a;neww"

I know the existing code allows things like 'neww -n "a;" neww' but that
isn't as bad.

It would seem that it'd be better to do this in cmd_string_parse which
would fix both.

But the problem is that will stop it working with the argv given to main
which has already been split by the shell.

cmd_list_parse is only used for that argv though... maybe we just make
it so cmd_string_parse doesn't call cmd_list_parse and they both do the
same ; stuff in a different way.



On Sun, Jan 19, 2014 at 10:30:26PM -0600, J Raynor wrote:
> The tmux TODO list has this item regarding command sequences:
> 
> 
> * don't require space after ;
> 
> 
> I've attached a patch that does this.

> diff --git a/cmd-list.c b/cmd-list.c
> index 08e2067..22327cd 100644
> --- a/cmd-list.c
> +++ b/cmd-list.c
> @@ -29,55 +29,85 @@ cmd_list_parse(int argc, char **argv, const char* file, 
> u_int line,
>  {
>       struct cmd_list *cmdlist;
>       struct cmd      *cmd;
> -     int              i, lastsplit;
> -     size_t           arglen, new_argc;
> -     char           **copy_argv, **new_argv;
> +     int              i;
> +     size_t           c, x, y, arglen, new_argc;
> +     char           **new_argv, *argdup;
>  
> -     copy_argv = cmd_copy_argv(argc, argv);
> +     new_argv = xcalloc(argc, sizeof *new_argv);
>  
>       cmdlist = xcalloc(1, sizeof *cmdlist);
>       cmdlist->references = 1;
>       TAILQ_INIT(&cmdlist->list);
>  
> -     lastsplit = 0;
> +     new_argc = 0;
>       for (i = 0; i < argc; i++) {
> -             arglen = strlen(copy_argv[i]);
> -             if (arglen == 0 || copy_argv[i][arglen - 1] != ';')
> +             arglen = strlen(argv[i]);
> +             if (arglen == 0) {
> +                     new_argv[new_argc++] = xstrdup(argv[i]);
>                       continue;
> -             copy_argv[i][arglen - 1] = '\0';
> +             }
>  
> -             if (arglen > 1 && copy_argv[i][arglen - 2] == '\\') {
> -                     copy_argv[i][arglen - 2] = ';';
> -                     continue;
> +             argdup = xcalloc(1, arglen + 1);
> +             x = y = 0;
> +             while (x < arglen) {
> +                     switch (argv[i][x]) {
> +                     case ';':
> +                             argdup[y] = '\0';
> +                             y = 0;
> +                             if (strlen(argdup) > 0)
> +                                     new_argv[new_argc++] = xstrdup(argdup);
> +
> +                             cmd = cmd_parse(new_argc, new_argv, file,
> +                                     line, cause);
> +                             if (cmd == NULL) {
> +                                     free(argdup);
> +                                     goto bad;
> +                             }
> +                             TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
> +
> +                             for(c = 0; c < new_argc; c++)
> +                                     free(new_argv[c]);
> +
> +                             new_argc = 0;
> +                             break;
> +                     case '\\':
> +                             if (argv[i][x+1] == ';') {
> +                                     argdup[y++] = ';';
> +                                     x++;
> +                             } else {
> +                                     argdup[y++] = '\\';
> +                             }
> +                             break;
> +                     default:
> +                             argdup[y++] = argv[i][x];
> +                             break;
> +                     }
> +                     x++;
>               }
> +             argdup[y] = '\0';
> +             if (strlen(argdup) > 0)
> +                     new_argv[new_argc++] = xstrdup(argdup);
>  
> -             new_argc = i - lastsplit;
> -             new_argv = copy_argv + lastsplit;
> -             if (arglen != 1)
> -                     new_argc++;
> +             free(argdup);
> +     }
>  
> +     if (new_argc > 0) {
>               cmd = cmd_parse(new_argc, new_argv, file, line, cause);
>               if (cmd == NULL)
>                       goto bad;
> -             TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
>  
> -             lastsplit = i + 1;
> -     }
> -
> -     if (lastsplit != argc) {
> -             cmd = cmd_parse(argc - lastsplit, copy_argv + lastsplit,
> -                 file, line, cause);
> -             if (cmd == NULL)
> -                     goto bad;
>               TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
> +
> +             for(c = 0; c < new_argc; c++)
> +                     free(new_argv[c]);
>       }
>  
> -     cmd_free_argv(argc, copy_argv);
> +     free(new_argv);
>       return (cmdlist);
>  
>  bad:
>       cmd_list_free(cmdlist);
> -     cmd_free_argv(argc, copy_argv);
> +     free(new_argv);
>       return (NULL);
>  }
>  

> ------------------------------------------------------------------------------
> CenturyLink Cloud: The Leader in Enterprise Cloud Services.
> Learn Why More Businesses Are Choosing CenturyLink Cloud For
> Critical Workloads, Development Environments & Everything In Between.
> Get a Quote or Start a Free Trial Today. 
> http://pubads.g.doubleclick.net/gampad/clk?id=119420431&iu=/4140/ostg.clktrk

> _______________________________________________
> tmux-users mailing list
> tmux-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/tmux-users


------------------------------------------------------------------------------
WatchGuard Dimension instantly turns raw network data into actionable 
security intelligence. It gives you real-time visual feedback on key
security issues and trends.  Skip the complicated setup - simply import
a virtual appliance and go from zero to informed in seconds.
http://pubads.g.doubleclick.net/gampad/clk?id=123612991&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