@@ -294,6 +294,7 @@ our $FILTER_MISSING_FILE;
294
294
our $FILTER_EXCEPTION_BRANCH ;
295
295
# remove lone branch in block - it can't be an actual conditional
296
296
our $FILTER_ORPHAN_BRANCH ;
297
+ our $FILTER_OMIT_PATTERNS ; # special/somewhat faked filter
297
298
298
299
our %COVERAGE_FILTERS = (" branch" => \$FILTER_BRANCH_NO_COND ,
299
300
' brace' => \$FILTER_LINE_CLOSE_BRACE ,
@@ -2297,7 +2298,7 @@ sub parse_cov_filters(@)
2297
2298
{
2298
2299
my @filters = split ($split_char , join ($split_char , @_ ));
2299
2300
2300
- return if (!@filters );
2301
+ goto final if (!@filters );
2301
2302
2302
2303
foreach my $item (@filters ) {
2303
2304
die (" unknown argument for --filter: '$item '\n " )
@@ -2324,6 +2325,13 @@ sub parse_cov_filters(@)
2324
2325
$cov_filter [$FILTER_EXCEPTION_BRANCH ] = [' exception' , 0, 0];
2325
2326
$cov_filter [$FILTER_ORPHAN_BRANCH ] = [' orphan' , 0, 0];
2326
2327
}
2328
+ final:
2329
+ if (@lcovutil::omit_line_patterns ) {
2330
+ $lcovutil::FILTER_OMIT_PATTERNS = scalar (@lcovutil::cov_filter );
2331
+ push (@lcovutil::cov_filter , [' omit_lines' , 0, 0]);
2332
+ $lcovutil::COVERAGE_FILTERS {' omit_lines' } =
2333
+ $lcovutil::FILTER_OMIT_PATTERNS ;
2334
+ }
2327
2335
}
2328
2336
2329
2337
sub summarize_cov_filters
@@ -5350,6 +5358,12 @@ use constant {
5350
5358
PATH => 1,
5351
5359
SOURCE => 2,
5352
5360
EXCLUDE => 3,
5361
+
5362
+ # reasons: (bitfield)
5363
+ EXCLUDE_REGION => 0x10,
5364
+ EXCLUDE_BRANCH_REGION => 0x20,
5365
+ EXCLUDE_DIRECTIVE => 0x40,
5366
+ OMIT_LINE => 0x80,
5353
5367
};
5354
5368
5355
5369
sub new
@@ -5439,27 +5453,47 @@ sub parseLines
5439
5453
my ($self , $filename , $sourceLines ) = @_ ;
5440
5454
5441
5455
my @excluded ;
5442
- my $exclude_region = 0 ;
5443
- my $exclude_br_region = 0 ;
5444
- my $exclude_exception_region = 0 ;
5445
- my $line = 0;
5446
- my $excl_start = qr ($lcovutil::EXCL_START ) ;
5447
- my $excl_stop = qr ($lcovutil::EXCL_STOP ) ;
5448
- my $excl_line = qr ($lcovutil::EXCL_LINE ) ;
5449
- my $excl_br_start = qr ($lcovutil::EXCL_BR_START ) ;
5450
- my $excl_br_stop = qr ($lcovutil::EXCL_BR_STOP ) ;
5451
- my $excl_br_line = qr ($lcovutil::EXCL_BR_LINE ) ;
5452
- my $excl_ex_start = qr ($lcovutil::EXCL_EXCEPTION_BR_START ) ;
5453
- my $excl_ex_stop = qr ($lcovutil::EXCL_EXCEPTION_BR_STOP ) ;
5454
- my $excl_ex_line = qr ($lcovutil::EXCL_EXCEPTION_LINE ) ;
5456
+ my $exclude_region ;
5457
+ my $exclude_br_region ;
5458
+ my $exclude_exception_region ;
5459
+ my $line = 0;
5460
+ my $excl_start = qr ($lcovutil::EXCL_START ) ;
5461
+ my $excl_stop = qr ($lcovutil::EXCL_STOP ) ;
5462
+ my $excl_line = qr ($lcovutil::EXCL_LINE ) ;
5463
+ my $excl_br_start = qr ($lcovutil::EXCL_BR_START ) ;
5464
+ my $excl_br_stop = qr ($lcovutil::EXCL_BR_STOP ) ;
5465
+ my $excl_br_line = qr ($lcovutil::EXCL_BR_LINE ) ;
5466
+ my $excl_ex_start = qr ($lcovutil::EXCL_EXCEPTION_BR_START ) ;
5467
+ my $excl_ex_stop = qr ($lcovutil::EXCL_EXCEPTION_BR_STOP ) ;
5468
+ my $excl_ex_line = qr ($lcovutil::EXCL_EXCEPTION_LINE ) ;
5455
5469
# @todo: if we had annotated data here, then we could whine at the
5456
5470
# author of the unmatched start, extra end, etc.
5457
5471
5458
5472
my $exclude_directives =
5459
- qr / ^\s *#\s *((else|endif)|((ifdef|if|elif|include|define|undef)\s +))/
5473
+ qr / ^\s *#\s *((else|endif)|((ifdef|ifndef| if|elif|include|define|undef)\s +))/
5460
5474
if (TraceFile::is_language(' c' , $filename ) &&
5461
5475
defined ($lcovutil::cov_filter [$lcovutil::FILTER_DIRECTIVE ]));
5462
5476
5477
+ my @excludes ;
5478
+ if (defined ($lcovutil::cov_filter [$lcovutil::FILTER_EXCLUDE_REGION ])) {
5479
+ push (@excludes ,
5480
+ [$excl_start , $excl_stop , \$exclude_region , 3 | EXCLUDE_REGION]);
5481
+ } else {
5482
+ $excl_line = undef ;
5483
+ }
5484
+
5485
+ if (defined ($lcovutil::cov_filter [$lcovutil::FILTER_EXCLUDE_BRANCH ])) {
5486
+ push (@excludes ,
5487
+ [$excl_ex_start , $excl_ex_stop ,
5488
+ \$exclude_exception_region , 4 | EXCLUDE_BRANCH_REGION
5489
+ ],
5490
+ [$excl_br_start , $excl_br_stop ,
5491
+ \$exclude_br_region , 2 | EXCLUDE_BRANCH_REGION
5492
+ ]);
5493
+ } else {
5494
+ $excl_br_line = undef ;
5495
+ $excl_ex_line = undef ;
5496
+ }
5463
5497
LINES: foreach (@$sourceLines ) {
5464
5498
$line += 1;
5465
5499
my $exclude_branch_line = 0;
@@ -5469,66 +5503,69 @@ sub parseLines
5469
5503
s /\r // ; # remove carriage return
5470
5504
if (defined ($exclude_directives ) &&
5471
5505
$_ =~ $exclude_directives ) {
5472
- ++$lcovutil::cov_filter [$lcovutil::FILTER_DIRECTIVE ]-> [-2];
5473
- ++$lcovutil::cov_filter [$lcovutil::FILTER_DIRECTIVE ]-> [-1];
5474
- push (@excluded , 3); # everything excluded
5475
- lcovutil::info(2, " exclude '#$1 ' directive on $filename :$line \n " );
5506
+ push (@excluded , 3 | EXCLUDE_DIRECTIVE); # everything excluded
5507
+ lcovutil::info(2, " directive '#$1 ' on $filename :$line \n " );
5476
5508
next ;
5477
5509
}
5478
5510
5479
- foreach my $d ([$excl_start , $excl_stop , \$exclude_region ],
5480
- [$excl_br_start , $excl_br_stop , \$exclude_br_region ],
5481
- [$excl_ex_start , $excl_ex_stop ,
5482
- \$exclude_exception_region
5483
- ]
5484
- ) {
5485
- my ($start , $stop , $ref ) = @$d ;
5511
+ foreach my $d (@excludes ) {
5512
+ my ($start , $stop , $ref , $reason ) = @$d ;
5486
5513
if ($_ =~ $start ) {
5487
5514
lcovutil::ignorable_error($lcovutil::ERROR_MISMATCH ,
5488
5515
" $filename : overlapping exclude directives. Found $start at line $line - but no matching $stop for $start at line "
5489
- . $$ ref )
5516
+ . $ref -> [0] )
5490
5517
if $$ref ;
5491
- $$ref = $line ;
5518
+ $$ref = [ $line , $reason ] ;
5492
5519
last ;
5493
5520
} elsif ($_ =~ $stop ) {
5494
5521
lcovutil::ignorable_error($lcovutil::ERROR_MISMATCH ,
5495
5522
" $filename : found $stop directive at line $line without matching $start directive"
5496
5523
) unless $$ref ;
5497
- $$ref = 0 ;
5524
+ $$ref = undef ;
5498
5525
last ;
5499
5526
}
5500
5527
}
5501
- if ($_ =~ $excl_line ) {
5502
- push (@excluded , 3); # everything excluded
5528
+ if (defined ($excl_line ) &&
5529
+ $_ =~ $excl_line ) {
5530
+ push (@excluded , 3 | EXCLUDE_REGION); # everything excluded
5503
5531
next ;
5504
- } elsif ($_ =~ $excl_br_line ) {
5505
- $exclude_branch_line = 2;
5506
- } elsif ($_ =~ $excl_ex_line ) {
5507
- $exclude_branch_line = 4;
5532
+ } elsif (defined ($excl_br_line ) &&
5533
+ $_ =~ $excl_br_line ) {
5534
+ $exclude_branch_line = 2 | EXCLUDE_BRANCH_REGION;
5535
+ } elsif (defined ($excl_ex_line ) &&
5536
+ $_ =~ $excl_ex_line ) {
5537
+ $exclude_branch_line = 4 | EXCLUDE_BRANCH_REGION;
5508
5538
} elsif (0 != scalar (@lcovutil::omit_line_patterns )) {
5509
5539
foreach my $p (@lcovutil::omit_line_patterns ) {
5510
5540
my $pat = $p -> [0];
5511
5541
if ($_ =~ $pat ) {
5512
- push (@excluded , 3); # everything excluded
5542
+ push (@excluded , 3 | OMIT_LINE ); # everything excluded
5513
5543
# lcovutil::info("'" . $p->[-2] . "' matched \"$_\", line \"$filename\":"$line\n");
5514
5544
++$p -> [-1];
5515
5545
next LINES;
5516
5546
}
5517
5547
}
5518
5548
}
5519
5549
push (@excluded ,
5520
- ($exclude_region ? 1 : 0) | ($exclude_br_region ? 2 : 0) |
5521
- ($exclude_exception_region ? 4 : 0) | $exclude_branch_line |
5522
- $exclude_exception_branch_line );
5550
+ ($exclude_region ? $exclude_region -> [1] : 0) |
5551
+ ($exclude_br_region ? $exclude_br_region -> [1] : 0) | (
5552
+ $exclude_exception_region ? $exclude_exception_region -> [1] : 0
5553
+ ) | $exclude_branch_line | $exclude_exception_branch_line );
5523
5554
}
5524
5555
lcovutil::ignorable_error($lcovutil::ERROR_MISMATCH ,
5525
- " $filename : unmatched $lcovutil::EXCL_START at line $exclude_region - saw EOF while looking for matching $lcovutil::EXCL_STOP "
5556
+ " $filename : unmatched $lcovutil::EXCL_START at line " .
5557
+ $exclude_region -> [0] .
5558
+ " - saw EOF while looking for matching $lcovutil::EXCL_STOP "
5526
5559
) if $exclude_region ;
5527
5560
lcovutil::ignorable_error($lcovutil::ERROR_MISMATCH ,
5528
- " $filename : unmatched $lcovutil::EXCL_BR_START at line $exclude_br_region - saw EOF while looking for matching $lcovutil::EXCL_BR_STOP "
5561
+ " $filename : unmatched $lcovutil::EXCL_BR_START at line " .
5562
+ $exclude_br_region -> [0] .
5563
+ " - saw EOF while looking for matching $lcovutil::EXCL_BR_STOP "
5529
5564
) if $exclude_br_region ;
5530
5565
lcovutil::ignorable_error($lcovutil::ERROR_MISMATCH ,
5531
- " $filename : unmatched $lcovutil::EXCL_EXCEPTION_BR_START at line $exclude_exception_region - saw EOF while looking for matching $lcovutil::EXCL_EXCEPTION_BR_STOP "
5566
+ " $filename : unmatched $lcovutil::EXCL_EXCEPTION_BR_START at line " .
5567
+ $exclude_exception_region -> [0] .
5568
+ " - saw EOF while looking for matching $lcovutil::EXCL_EXCEPTION_BR_STOP "
5532
5569
) if $exclude_exception_region ;
5533
5570
5534
5571
my $data = $self -> [0];
@@ -5621,6 +5658,16 @@ sub isOutOfRange
5621
5658
return 0;
5622
5659
}
5623
5660
5661
+ sub excludeReason
5662
+ {
5663
+ my ($self , $lineNo ) = @_ ;
5664
+ my $data = $self -> [0];
5665
+ die (" missing data at $lineNo " )
5666
+ unless (defined ($data -> [EXCLUDE]) &&
5667
+ scalar (@{$data -> [EXCLUDE]}) >= $lineNo );
5668
+ return $data -> [EXCLUDE]-> [$lineNo - 1] & 0xFF0;
5669
+ }
5670
+
5624
5671
sub isExcluded
5625
5672
{
5626
5673
my ($self , $lineNo , $branch ) = @_ ;
@@ -6489,6 +6536,9 @@ sub _filterFile
6489
6536
my $trivial_histogram = $cov_filter [$FILTER_TRIVIAL_FUNCTION ];
6490
6537
my $filter_initializer_list = $cov_filter [$FILTER_INITIALIZER_LIST ]
6491
6538
if (is_language(' c' , $source_file ));
6539
+ my $directive = $cov_filter [$FILTER_DIRECTIVE ];
6540
+ my $omit = $cov_filter [$FILTER_OMIT_PATTERNS ]
6541
+ if defined ($FILTER_OMIT_PATTERNS );
6492
6542
6493
6543
my $context = MessageContext-> new(" filtering $source_file " );
6494
6544
if (lcovutil::is_filter_enabled()) {
@@ -6580,9 +6630,16 @@ sub _filterFile
6580
6630
" filter FN " . $data -> name() .
6581
6631
' ' . $data -> file() . " :$line \n " );
6582
6632
++$range -> [-2]; # one location where this applied
6583
- } elsif ($region && $ srcReader-> isExcluded($line )) {
6633
+ } elsif ($srcReader -> isExcluded($line )) {
6584
6634
$remove = 1;
6585
- $region -> [-2] += scalar (keys %{$data -> aliases()});
6635
+ my $reason = $srcReader -> excludeReason($line );
6636
+ foreach my $f ([ReadCurrentSource::EXCLUDE_REGION, $region ],
6637
+ [ReadCurrentSource::OMIT_LINE, $omit ]) {
6638
+ if ($reason & $f -> [0]) {
6639
+ $f -> [1]-> [-2] += scalar (keys %{$data -> aliases()});
6640
+ last ;
6641
+ }
6642
+ }
6586
6643
}
6587
6644
if ($remove ) {
6588
6645
# remove this function from everywhere
@@ -6603,10 +6660,11 @@ sub _filterFile
6603
6660
if ($lcovutil::br_coverage &&
6604
6661
defined ($testbrcount ) &&
6605
6662
($branch_histogram ||
6606
- $region ||
6607
- $branch_region ||
6608
- $range ||
6609
- $filterExceptionBranches )
6663
+ $region ||
6664
+ $branch_region ||
6665
+ $range ||
6666
+ $filterExceptionBranches ||
6667
+ $omit )
6610
6668
) {
6611
6669
foreach my $line ($testbrcount -> keylist()) {
6612
6670
# for counting: keep track filter which triggered exclusion -
@@ -6616,11 +6674,24 @@ sub _filterFile
6616
6674
# only counting line coverpoints that got excluded
6617
6675
die (" inconsistent state" ) unless $range ;
6618
6676
$remove = $range ;
6619
- } elsif (($region || $branch_region ) &&
6620
- $srcReader -> isExcluded($line , 2)) {
6677
+ } elsif ($srcReader -> isExcluded($line , 2)) {
6621
6678
# all branches here
6622
- $remove = $region ? $region : $branch_region ;
6623
- die (" inconsistent" ) unless $remove ;
6679
+ my $reason = $srcReader -> excludeReason($line );
6680
+ foreach my $f ([ReadCurrentSource::EXCLUDE_REGION, $region ],
6681
+ [ReadCurrentSource::OMIT_LINE, $omit ],
6682
+ [ReadCurrentSource::EXCLUDE_DIRECTIVE,
6683
+ $directive
6684
+ ],
6685
+ [ReadCurrentSource::EXCLUDE_BRANCH_REGION,
6686
+ $branch_region
6687
+ ]
6688
+ ) {
6689
+ if ($reason & $f -> [0]) {
6690
+ $remove = $f -> [1];
6691
+ last ;
6692
+ }
6693
+ }
6694
+ die (" inconsistent reason $reason " ) unless $remove ;
6624
6695
} elsif ($branch_histogram &&
6625
6696
!$srcReader -> containsConditional($line )) {
6626
6697
$remove = $branch_histogram ;
@@ -6659,6 +6730,8 @@ sub _filterFile
6659
6730
$range ||
6660
6731
$brace_histogram ||
6661
6732
$branch_histogram ||
6733
+ $directive ||
6734
+ $omit ||
6662
6735
$filter_initializer_list ;
6663
6736
6664
6737
my %initializerListRange ;
@@ -6697,9 +6770,20 @@ sub _filterFile
6697
6770
$outOfRange ;
6698
6771
my $excluded = $srcReader -> isExcluded($line )
6699
6772
unless $is_filtered ;
6700
- $is_filtered =
6701
- $lcovutil::cov_filter [$lcovutil::FILTER_EXCLUDE_REGION ]
6702
- if !defined ($is_filtered ) && defined ($excluded ) && $excluded ;
6773
+ if (defined ($excluded ) && $excluded ) {
6774
+ my $reason = $srcReader -> excludeReason($line );
6775
+ foreach my $f ([ReadCurrentSource::EXCLUDE_REGION, $region ],
6776
+ [ReadCurrentSource::OMIT_LINE, $omit ],
6777
+ [ReadCurrentSource::EXCLUDE_DIRECTIVE,
6778
+ $directive
6779
+ ]
6780
+ ) {
6781
+ if ($reason & $f -> [0]) {
6782
+ $is_filtered = $f -> [1];
6783
+ last ;
6784
+ }
6785
+ }
6786
+ }
6703
6787
my $l_hit = $testcount -> value($line );
6704
6788
my $isCloseBrace =
6705
6789
($brace_histogram &&
@@ -6728,8 +6812,7 @@ sub _filterFile
6728
6812
" " ) .
6729
6813
" $source_file :$line \n " );
6730
6814
6731
- unless ((defined ($outOfRange ) && $outOfRange ) ||
6732
- (defined ($excluded ) && $excluded )) {
6815
+ unless (defined ($outOfRange ) && $outOfRange ) {
6733
6816
# some filters already counted...
6734
6817
++$is_filtered -> [-2]; # one location where this applied
6735
6818
++$is_filtered -> [-1]; # one coverpoint suppressed
0 commit comments