Skip Menu |

This queue is for tickets about the Expect CPAN distribution.

Report information
The Basics
Id: 100342
Status: open
Priority: 0/
Queue: Expect

People
Owner: Nobody in particular
Requestors: abhihimself [...] gmail.com
heinz.knutzen [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Expect-1.32 matches differently than v1.21
Date: Fri, 14 Nov 2014 23:04:56 +0100
To: bug-Expect [...] rt.cpan.org
From: Heinz Knutzen <heinz.knutzen [...] gmail.com>
I use Expect.pm to parse the output of Linux "iptables-save" command. The output should be read up to the next prompt which matches "\n#". But inside the output there are other occurences of "\n#". Expect-1.21 only matched the backmost "\n#", but Expect-1.32 matches the first one, so I don't get the expected output in $e->before. This test succeeds with Expect-1.21, but fails with Expect-1.32: ============================================ use strict; use warnings; use Test::More; use Expect; my $e = Expect->new; $e->raw_pty(1); $e->log_stdout(0); $e->spawn($^X . q{ -e 'print "iptables-save\n# Generated by\n*filter\n#";' }); $e->send("iptables-save\n"); $e->expect(1, '-re', '\n#$'); is $e->before, "iptables-save\n# Generated by\n*filter"; is $e->after, ""; done_testing; ============================================
On 2014-11-14 17:05:19, heinz.knutzen@gmail.com wrote: Show quoted text
> I use Expect.pm to parse the output of Linux "iptables-save" command. > The output should be read up to the next prompt which matches "\n#". > But inside the output there are other occurences of "\n#". > > Expect-1.21 only matched the backmost "\n#", > but Expect-1.32 matches the first one, > so I don't get the expected output in $e->before. > > This test succeeds with Expect-1.21, but fails with Expect-1.32: > ============================================ > use strict; > use warnings; > > use Test::More; > use Expect; > > my $e = Expect->new; > $e->raw_pty(1); > $e->log_stdout(0); > $e->spawn($^X . q{ -e 'print "iptables-save\n# Generated > by\n*filter\n#";' }); > $e->send("iptables-save\n"); > $e->expect(1, '-re', '\n#$'); > is $e->before, "iptables-save\n# Generated by\n*filter"; > is $e->after, ""; > > done_testing; > ============================================
Confirmed (FreeBSD 9.2, various perl versions). The behavior change happens already with v1.29, maybe even earlier.
Subject: rt.cpan.org #100342
Date: Fri, 21 Nov 2014 16:55:37 +0530
To: bug-Expect [...] rt.cpan.org
From: abhishek kumar <abhihimself [...] gmail.com>
Hello All, The problem is there was two occurrences of '\n#' in the process. And expect was detecting the first occurrence. Earlier it used to find the last occurrence. Here is what i found There is a change in the code in which (Aug 13 commit) the use of $' and other special variables are eliminated. Now current(V1.32) code(Expect.pm Code Line 770) looks like this if ($Expect::Multiline_Matching) { @matchlist = ( ${*$exp}{exp_Accum} =~ m/($pattern->[2])/m); } else { @matchlist = ( ${*$exp}{exp_Accum} =~ m/($pattern->[2])/); } if (@matchlist) { # Matching regexp $match = shift @matchlist; my $start = index ${*$exp}{exp_Accum}, $match; die 'The match could not be found' if $start == -1; $before = substr ${*$exp}{exp_Accum}, 0, $start; $after = substr ${*$exp}{exp_Accum}, $start + length($match); ${*$exp}{exp_Before} = $before; ${*$exp}{exp_Match} = $match; ${*$exp}{exp_After} = $after; #pop @matchlist; # remove kludged empty bracket from end @{ ${*$exp}{exp_Matchlist} } = @matchlist; ${*$exp}{exp_Match_Number} = $pattern->[0]; $exp_matched = $exp; } Here we are using *index* which will search for first occurrence if *position* parameter is omitted. So behavior mentioned in bug is correct according to current implementation. If we want to change the behavior so that last occurrence is checked . We can do my $start = index ${*$exp}{exp_Accum}, $match; if ($start == -1) {die 'The match could not be found'} else { my $newp; do { $newp = index (${*$exp}{exp_Accum}, $match, $start+1); if($newp != -1) {$start=$newp} }until($newp == -1) } All the test cases with this implementation(Including the test script mentioned in bug) are working fine except one: *04-multiline.t (Taste case 12. Line 51*). This test case expects exactly opposite i.e. it expects that first occurrence of keyword should be matched. So we have to decide which implementation we want. I have made above mentioned changes in a forked repository. Pls have a look https://github.com/abhihimself/expect.pm