in reply to Re: Parsing strings into @ARGV
in thread Parsing strings into @ARGV

Thanks. Indeed it should work, and it nearly does... but it fails on one of the tests (foo\ , with an extra space at the end of the name, which is mildly annoying as I do have files that end with spaces (before anybody mentions it: no I can't change that ;--). If I quote them it works OK though (.

It might be a bug in the module and worth fixing though.

Replies are listed 'Best First'.
Re: Parsing strings into @ARGV
by Abigail-II (Bishop) on Apr 23, 2004 at 16:12 UTC
    Yes, it's a bug. This is the offending part:
    sub shellwords { local(@lines) = @_; $lines[$#lines] =~ s/\s+$//; return(quotewords('\s+', 0, @lines)); }
    The bug is the unrestricted deletion of trailing whitespace - it shouldn't delete whitespace that's preceeded by the right number of backslashes. I'll see if I can come up with a patch later tonight.

    Note that that's not the only case where Text::ParseWords and my shell (bash) disagrees. Given the string "foo\'bar", my shell parses that as foo\'bar, while Text::ParseWords turns it into foo'bar.

    Abigail

      Yes, I saw that, here is my fix:

          $lines[$#lines] =~ s{(\\.)?\s*$}{defined $1 ? $1 : ''}e;

      I don't really like it but it passes my tests.:

      #!/usr/bin/perl -w use strict; use Test::More qw(no_plan); while( <DATA>) { my( $input, $expected)= m{^'(.*?)'\s*=>\s*'(.*?)'}; (my $trimmed= $input)=~ s{(\\.)?\s*$}{defined $1 ? $1 : ''}e; is( $trimmed, $expected, "'$input'"); } __DATA__ 't' =>'t' 't ' =>'t' 't\ ' =>'t\ ' 't\ ' =>'t\ ' 't\ \ '=>'t\ \ '
        Your solution fails on 't\\\ ', yielding 't\\\', but I expect 't\\\ '.

        $ echo t\\\ | cat -e t\ $

        Abigail

      bash, sh, csh and tcsh all give foo\'bar. This one looks more of a pain to fix.

      Are there tests for Text::ParseWords somewhere? The CPAN version has nothing, which makes it quite dangerous to work on it.

        There are some really old tests in bleadperl. I think they might date back to 5.6.0 or 5.6.1.