Explorar o código

Allow changelog parser to abort early

Dpkg::Changelog->_abort_early() tests whether the parser
can abort.
Dpkg::Changelog::Debian->parse() checks this after each
finished entry.
parsechangelog/debian sets count explicetly to 1 if no
other range options are given so that the parser
aborts early in this case.
Frank Lichtenheld %!s(int64=18) %!d(string=hai) anos
pai
achega
0287c4c511
Modificáronse 3 ficheiros con 59 adicións e 9 borrados
  1. 45 0
      scripts/Dpkg/Changelog.pm
  2. 1 0
      scripts/Dpkg/Changelog/Debian.pm
  3. 13 9
      scripts/changelog/debian.pl

+ 45 - 0
scripts/Dpkg/Changelog.pm

@@ -303,6 +303,51 @@ sub _data_range {
     return \@result;
 }
 
+sub _abort_early {
+    my ($self) = @_;
+
+    my $data = $self->data or return;
+    my $config = $self->{config} or return;
+
+#    use Data::Dumper;
+#    warn "Abort early? (\$# = $#$data)\n".Dumper($config);
+
+    return if $config->{all};
+
+    my $since = $config->{since} || '';
+    my $until = $config->{until} || '';
+    my $from = $config->{from} || '';
+    my $to = $config->{to} || '';
+    my $count = $config->{count} || 0;
+    my $offset = $config->{offset} || 0;
+
+    return if $offset and not $count;
+    return if $offset < 0 or $count < 0;
+    if ($offset > 0) {
+	$offset -= ($count < 0);
+    }
+    my $start = my $end = $offset;
+    $end += $count-1 if $count > 0;
+
+    unless ($from or $to or $since or $until or $start or $end) {
+	return if not $count;
+	return 1 if @$data;
+    }
+
+    return 1 if ($start or $end)
+	and $start < @$data and $end < @$data;
+
+    return unless $since or $from;
+    foreach (@$data) {
+	my $v = $_->{Version};
+
+	return 1 if $v eq $since;
+	return 1 if $v eq $from;
+    }
+
+    return;
+}
+
 =pod
 
 =head3 dpkg

+ 1 - 0
scripts/Dpkg/Changelog/Debian.pm

@@ -144,6 +144,7 @@ sub parse {
 #		    print STDERR, Dumper($entry);
 		push @{$self->{data}}, $entry;
 		$entry = Dpkg::Changelog::Entry->init();
+		last if $self->_abort_early;
 	    }
 	    {
 		$entry->{'Source'} = "$1";

+ 13 - 9
scripts/changelog/debian.pl

@@ -99,21 +99,25 @@ if (@ARGV) {
 my $changes = Dpkg::Changelog::Debian->init();
 
 $file ||= $default_file;
+unless ($since or $until or $from or $to or
+	$offset or $count or $all) {
+    $count = 1;
+}
+my @all = $all ? ( all => $all ) : ();
+my $opts = { since => $since, until => $until,
+	     from => $from, to => $to,
+	     count => $count, offset => $offset,
+	     @all };
+
 if ($file eq '-') {
     my @input = <STDIN>;
-    $changes->parse({ instring => join('', @input) })
+    $changes->parse({ instring => join('', @input), %$opts })
 	or failure(_g('fatal error occured while parsing input'));
 } else {
-    $changes->parse({ infile => $file })
+    $changes->parse({ infile => $file, %$opts })
 	or failure(_g('fatal error occured while parsing %s'),
 		   $file );
 }
 
 
-my @all = $all ? ( all => $all ) : ();
-
-eval("print \$changes->${format}_str(
-      { since => \$since, until => \$until,
-	from => \$from, to => \$to,
-	count => \$count, offset => \$offset,
-	\@all })");
+eval("print \$changes->${format}_str(\$opts)");