| @@ -1,15 +1,15 @@ | | | @@ -1,15 +1,15 @@ |
1 | #! @PERL@ | | 1 | #! @PERL@ |
2 | # $NetBSD: pkglint.pl,v 1.884 2015/10/11 18:16:50 rillig Exp $ | | 2 | # $NetBSD: pkglint.pl,v 1.885 2015/10/11 18:34:23 rillig Exp $ |
3 | # | | 3 | # |
4 | | | 4 | |
5 | # pkglint - static analyzer and checker for pkgsrc packages | | 5 | # pkglint - static analyzer and checker for pkgsrc packages |
6 | # | | 6 | # |
7 | # Written by: | | 7 | # Written by: |
8 | # Roland Illig <rillig@NetBSD.org> | | 8 | # Roland Illig <rillig@NetBSD.org> |
9 | # | | 9 | # |
10 | # Based on work by: | | 10 | # Based on work by: |
11 | # Hubert Feyrer <hubertf@NetBSD.org> | | 11 | # Hubert Feyrer <hubertf@NetBSD.org> |
12 | # Thorsten Frueauf <frueauf@NetBSD.org> | | 12 | # Thorsten Frueauf <frueauf@NetBSD.org> |
13 | # Thomas Klausner <wiz@NetBSD.org> | | 13 | # Thomas Klausner <wiz@NetBSD.org> |
14 | # and others. | | 14 | # and others. |
15 | # | | 15 | # |
| @@ -5453,28 +5453,26 @@ sub checklines_buildlink3_inclusion($) { | | | @@ -5453,28 +5453,26 @@ sub checklines_buildlink3_inclusion($) { |
5453 | sub checkfile_ALTERNATIVES($) { | | 5453 | sub checkfile_ALTERNATIVES($) { |
5454 | my ($fname) = @_; | | 5454 | my ($fname) = @_; |
5455 | my ($lines); | | 5455 | my ($lines); |
5456 | | | 5456 | |
5457 | $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_ALTERNATIVES()"); | | 5457 | $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_ALTERNATIVES()"); |
5458 | | | 5458 | |
5459 | checkperms($fname); | | 5459 | checkperms($fname); |
5460 | if (!($lines = load_file($fname))) { | | 5460 | if (!($lines = load_file($fname))) { |
5461 | log_error($fname, NO_LINE_NUMBER, "Cannot be read."); | | 5461 | log_error($fname, NO_LINE_NUMBER, "Cannot be read."); |
5462 | return; | | 5462 | return; |
5463 | } | | 5463 | } |
5464 | } | | 5464 | } |
5465 | | | 5465 | |
5466 | sub checklines_buildlink3_mk_2009($$$); | | | |
5467 | sub checklines_buildlink3_mk_pre2009($$); | | | |
5468 | sub checkfile_buildlink3_mk($) { | | 5466 | sub checkfile_buildlink3_mk($) { |
5469 | my ($fname) = @_; | | 5467 | my ($fname) = @_; |
5470 | my ($lines, $lineno, $m); | | 5468 | my ($lines, $lineno, $m); |
5471 | | | 5469 | |
5472 | $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_buildlink3_mk()"); | | 5470 | $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_buildlink3_mk()"); |
5473 | | | 5471 | |
5474 | checkperms($fname); | | 5472 | checkperms($fname); |
5475 | if (!($lines = load_lines($fname, true))) { | | 5473 | if (!($lines = load_lines($fname, true))) { |
5476 | log_error($fname, NO_LINE_NUMBER, "Cannot be read."); | | 5474 | log_error($fname, NO_LINE_NUMBER, "Cannot be read."); |
5477 | return; | | 5475 | return; |
5478 | } | | 5476 | } |
5479 | if (@{$lines} == 0) { | | 5477 | if (@{$lines} == 0) { |
5480 | log_error($fname, NO_LINES, "Must not be empty."); | | 5478 | log_error($fname, NO_LINES, "Must not be empty."); |
| @@ -5485,263 +5483,54 @@ sub checkfile_buildlink3_mk($) { | | | @@ -5485,263 +5483,54 @@ sub checkfile_buildlink3_mk($) { |
5485 | checklines_mk($lines); | | 5483 | checklines_mk($lines); |
5486 | | | 5484 | |
5487 | $lineno = 0; | | 5485 | $lineno = 0; |
5488 | | | 5486 | |
5489 | # Header comments | | 5487 | # Header comments |
5490 | while ($lineno <= $#{$lines} && (my $text = $lines->[$lineno]->text) =~ m"^#") { | | 5488 | while ($lineno <= $#{$lines} && (my $text = $lines->[$lineno]->text) =~ m"^#") { |
5491 | if ($text =~ m"^# XXX") { | | 5489 | if ($text =~ m"^# XXX") { |
5492 | $lines->[$lineno]->log_note("Please read this comment and remove it if appropriate."); | | 5490 | $lines->[$lineno]->log_note("Please read this comment and remove it if appropriate."); |
5493 | } | | 5491 | } |
5494 | $lineno++; | | 5492 | $lineno++; |
5495 | } | | 5493 | } |
5496 | expect_empty_line($lines, \$lineno); | | 5494 | expect_empty_line($lines, \$lineno); |
5497 | | | 5495 | |
5498 | # This line does not belong here, but appears often. | | | |
5499 | if (expect($lines, \$lineno, qr"^BUILDLINK_DEPMETHOD\.(\S+)\?=.*$")) { | | 5496 | if (expect($lines, \$lineno, qr"^BUILDLINK_DEPMETHOD\.(\S+)\?=.*$")) { |
5500 | $lines->[$lineno - 1]->log_warning("This line belongs inside the .ifdef block."); | | 5497 | $lines->[$lineno - 1]->log_warning("This line belongs inside the .ifdef block."); |
5501 | while ($lines->[$lineno]->text eq "") { | | 5498 | while ($lines->[$lineno]->text eq "") { |
5502 | $lineno++; | | 5499 | $lineno++; |
5503 | } | | 5500 | } |
5504 | } | | 5501 | } |
5505 | | | 5502 | |
5506 | if (($m = expect($lines, \$lineno, qr"^BUILDLINK_TREE\+=\s*(\S+)$"))) { | | 5503 | if (!($m = expect($lines, \$lineno, qr"^BUILDLINK_TREE\+=\s*(\S+)$"))) { |
5507 | checklines_buildlink3_mk_2009($lines, $lineno, $m->text(1)); | | 5504 | $lines->[$lineno]->log_warning("Expected a BUILDLINK_TREE line."); |
5508 | } else { | | | |
5509 | checklines_buildlink3_mk_pre2009($lines, $lineno); | | | |
5510 | } | | | |
5511 | } | | | |
5512 | | | | |
5513 | sub checklines_buildlink3_mk_pre2009($$) { | | | |
5514 | my ($lines, $lineno) = @_; | | | |
5515 | my ($m); | | | |
5516 | my ($bl_PKGBASE_line, $bl_PKGBASE); | | | |
5517 | my ($bl_pkgbase_line, $bl_pkgbase); | | | |
5518 | my ($abi_line, $abi_pkg, $abi_version); | | | |
5519 | my ($api_line, $api_pkg, $api_version); | | | |
5520 | | | | |
5521 | # First paragraph: Reference counters. | | | |
5522 | if (!expect($lines, \$lineno, qr"^BUILDLINK_DEPTH:=\t+\$\{BUILDLINK_DEPTH\}\+$")) { | | | |
5523 | # When none of the formats has been found, prefer the 2009 format. | | | |
5524 | lines_log_warning($lines, $lineno, "Expected BUILDLINK_TREE line."); | | | |
5525 | return; | | | |
5526 | } | | | |
5527 | $lines->[$lineno - 1]->log_warning("Please switch to the new buildlink3.mk format."); | | | |
5528 | $lines->[$lineno - 1]->explain_warning( | | | |
5529 | "The format for buildlink3.mk files has changed in 2009Q1. You can", | | | |
5530 | "generate a new-style buildlink3.mk file with the createbuildlink>=3.14", | | | |
5531 | "package and then adjust the variable's values manually."); | | | |
5532 | | | | |
5533 | if (($m = expect($lines, \$lineno, qr"^(.*)_BUILDLINK3_MK:=\t*\$\{\1_BUILDLINK3_MK\}\+$"))) { | | | |
5534 | $bl_PKGBASE_line = $lines->[$lineno - 1]; | | | |
5535 | $bl_PKGBASE = $m->text(1); | | | |
5536 | $opt_debug_misc and $bl_PKGBASE_line->log_debug("bl_PKGBASE=${bl_PKGBASE}"); | | | |
5537 | } else { | | | |
5538 | lines_log_warning($lines, $lineno, "Expected {PKGNAME}_BUILDLINK3_MK:= \${{PKGNAME}_BUILDLINK3_MK}+."); | | | |
5539 | return; | | | |
5540 | } | | | |
5541 | expect_empty_line($lines, \$lineno); | | | |
5542 | | | | |
5543 | # Second paragraph: Adding the dependency. | | | |
5544 | if (!expect($lines, \$lineno, qr"^\.if !empty\(BUILDLINK_DEPTH:M\+\)$")) { | | | |
5545 | if (!expect_text($lines, \$lineno, ".if \${BUILDLINK_DEPTH} == \"+\"")) { | | | |
5546 | return; | | | |
5547 | } | | | |
5548 | } | | | |
5549 | if (($m = expect($lines, \$lineno, qr"^BUILDLINK_DEPENDS\+=\t+(\S+)$"))) { | | | |
5550 | $bl_pkgbase_line = $lines->[$lineno - 1]; | | | |
5551 | $bl_pkgbase = $m->text(1); | | | |
5552 | $opt_debug_misc and $bl_pkgbase_line->log_debug("bl_pkgbase=${bl_pkgbase}"); | | | |
5553 | } else { | | | |
5554 | lines_log_warning($lines, $lineno, "BUILDLINK_DEPENDS line expected."); | | | |
5555 | return; | | | |
5556 | } | | | |
5557 | | | | |
5558 | my $norm_bl_pkgbase = $bl_pkgbase; | | | |
5559 | $norm_bl_pkgbase =~ s/-/_/g; | | | |
5560 | $norm_bl_pkgbase = uc($norm_bl_pkgbase); | | | |
5561 | if ($norm_bl_pkgbase ne $bl_PKGBASE) { | | | |
5562 | $bl_PKGBASE_line->log_error("Package name mismatch between ${bl_PKGBASE} ..."); | | | |
5563 | $bl_pkgbase_line->log_error("... and ${bl_pkgbase}."); | | | |
5564 | } | | | |
5565 | if (defined($effective_pkgbase) && $effective_pkgbase ne $bl_pkgbase) { | | | |
5566 | $bl_pkgbase_line->log_error("Package name mismatch between ${bl_pkgbase} ..."); | | | |
5567 | $effective_pkgname_line->log_error("... and ${effective_pkgbase}."); | | | |
5568 | } | | | |
5569 | | | | |
5570 | if (!expect_text($lines, \$lineno, ".endif")) { | | | |
5571 | return; | | | |
5572 | } | | | |
5573 | expect_empty_line($lines, \$lineno); | | | |
5574 | | | | |
5575 | # Third paragraph: Duplicate elimination. | | | |
5576 | if (expect($lines, \$lineno, qr"^BUILDLINK_PACKAGES:=\t+\$\{BUILDLINK_PACKAGES:N\Q${bl_pkgbase}\E\}\s+\Q${bl_pkgbase}\E$")) { | | | |
5577 | # The compressed form of duplicate elimination. | | | |
5578 | | | | |
5579 | } else { | | | |
5580 | if (!expect($lines, \$lineno, qr"^BUILDLINK_PACKAGES:=\t+\$\{BUILDLINK_PACKAGES:N\Q${bl_pkgbase}\E\}$")) { | | | |
5581 | lines_log_warning($lines, $lineno, "Expected BUILDLINK_PACKAGES:= \${BUILDLINK_PACKAGES:N${bl_pkgbase}} line."); | | | |
5582 | return; | | | |
5583 | } | | | |
5584 | if (!expect($lines, \$lineno, qr"^BUILDLINK_PACKAGES\+=\t+\Q${bl_pkgbase}\E$")) { | | | |
5585 | lines_log_warning($lines, $lineno, "Expected BUILDLINK_PACKAGES+= ${bl_pkgbase} line."); | | | |
5586 | return; | | | |
5587 | } | | | |
5588 | } | | 5505 | } |
5589 | expect_text($lines, \$lineno, "BUILDLINK_ORDER:=\t\${BUILDLINK_ORDER} \${BUILDLINK_DEPTH}${bl_pkgbase}"); | | | |
5590 | expect_empty_line($lines, \$lineno); | | | |
5591 | | | 5506 | |
5592 | # Fourth paragraph: Package information. | | 5507 | checklines_buildlink3_mk($lines, $lineno, $m->text(1)); |
5593 | if (!expect($lines, \$lineno, qr"^\.if !empty\(\Q${bl_PKGBASE}\E_BUILDLINK3_MK:M\+\)$")) { | | | |
5594 | if (!expect_text($lines, \$lineno, ".if \${${bl_PKGBASE}_BUILDLINK3_MK} == \"+\"")) { | | | |
5595 | return; | | | |
5596 | } | | | |
5597 | } | | | |
5598 | while (!expect($lines, \$lineno, qr"^\.endif.*$")) { | | | |
5599 | | | | |
5600 | if ($lineno > $#{$lines}) { | | | |
5601 | lines_log_warning($lines, $lineno, "Expected .endif"); | | | |
5602 | return; | | | |
5603 | } | | | |
5604 | | | | |
5605 | my $line = $lines->[$lineno]; | | | |
5606 | | | | |
5607 | if (($m = expect($lines, \$lineno, regex_varassign))) { | | | |
5608 | my ($varname, $value) = ($m->text(1), $m->text(3)); | | | |
5609 | my $do_check = false; | | | |
5610 | | | | |
5611 | if ($varname eq "BUILDLINK_ABI_DEPENDS.${bl_pkgbase}") { | | | |
5612 | $abi_line = $line; | | | |
5613 | if ($value =~ regex_dependency_lge) { | | | |
5614 | ($abi_pkg, $abi_version) = ($1, $2); | | | |
5615 | } elsif ($value =~ regex_dependency_wildcard) { | | | |
5616 | ($abi_pkg) = ($1); | | | |
5617 | } else { | | | |
5618 | $opt_debug_unchecked and $line->log_debug("Unchecked dependency pattern \"${value}\"."); | | | |
5619 | } | | | |
5620 | $do_check = true; | | | |
5621 | } | | | |
5622 | if ($varname eq "BUILDLINK_API_DEPENDS.${bl_pkgbase}") { | | | |
5623 | $api_line = $line; | | | |
5624 | if ($value =~ regex_dependency_lge) { | | | |
5625 | ($api_pkg, $api_version) = ($1, $2); | | | |
5626 | } elsif ($value =~ regex_dependency_wildcard) { | | | |
5627 | ($api_pkg) = ($1); | | | |
5628 | } else { | | | |
5629 | $opt_debug_unchecked and $line->log_debug("Unchecked dependency pattern \"${value}\"."); | | | |
5630 | } | | | |
5631 | $do_check = true; | | | |
5632 | } | | | |
5633 | if ($do_check && defined($abi_pkg) && defined($api_pkg)) { | | | |
5634 | if ($abi_pkg ne $api_pkg) { | | | |
5635 | $abi_line->log_warning("Package name mismatch between ${abi_pkg} ..."); | | | |
5636 | $api_line->log_warning("... and ${api_pkg}."); | | | |
5637 | } | | | |
5638 | } | | | |
5639 | if ($do_check && defined($abi_version) && defined($api_version)) { | | | |
5640 | if (!dewey_cmp($abi_version, ">=", $api_version)) { | | | |
5641 | $abi_line->log_warning("ABI version (${abi_version}) should be at least ..."); | | | |
5642 | $api_line->log_warning("... API version (${api_version})."); | | | |
5643 | } | | | |
5644 | } | | | |
5645 | | | | |
5646 | if ($varname =~ m"^BUILDLINK_[\w_]+\.(.*)$") { | | | |
5647 | my ($varparam) = ($1); | | | |
5648 | | | | |
5649 | if ($varparam ne $bl_pkgbase) { | | | |
5650 | $line->log_warning("Only buildlink variables for ${bl_pkgbase}, not ${varparam} may be set in this file."); | | | |
5651 | } | | | |
5652 | } | | | |
5653 | | | | |
5654 | # TODO: More checks. | | | |
5655 | | | | |
5656 | } elsif (expect($lines, \$lineno, qr"^(?:#.*)?$")) { | | | |
5657 | # Comments and empty lines are fine here. | | | |
5658 | | | | |
5659 | } else { | | | |
5660 | $opt_debug_unchecked and lines_log_warning($lines, $lineno, "Unchecked line in fourth paragraph."); | | | |
5661 | $lineno++; | | | |
5662 | } | | | |
5663 | } | | | |
5664 | if (!defined($api_line)) { | | | |
5665 | $lines->[$lineno - 1]->log_warning("Definition of BUILDLINK_API_DEPENDS is missing."); | | | |
5666 | } | | | |
5667 | expect_empty_line($lines, \$lineno); | | | |
5668 | | | | |
5669 | # Before the fifth paragraph, it may be necessary to resolve the build | | | |
5670 | # options of other packages. | | | |
5671 | if (expect($lines, \$lineno, qr"^pkgbase\s*:=\s*(\S+)$")) { | | | |
5672 | do { | | | |
5673 | expect_text($lines, \$lineno, ".include \"../../mk/pkg-build-options.mk\""); | | | |
5674 | } while (expect($lines, \$lineno, qr"^pkgbase\s*:=\s*(\S+)$")); | | | |
5675 | expect_empty_line($lines, \$lineno); | | | |
5676 | } | | | |
5677 | | | | |
5678 | # Fifth paragraph (optional): Dependencies. | | | |
5679 | my $have_dependencies = false; | | | |
5680 | my $need_empty_line = false; | | | |
5681 | while (true) { | | | |
5682 | if (expect($lines, \$lineno, qr"^\.\s*include \"\.\./\.\./([^/]+/[^/]+)/buildlink3\.mk\"$") | | | |
5683 | || expect($lines, \$lineno, qr"^\.\s*include \"\.\./\.\./mk/(\S+)\.buildlink3\.mk\"$") | | | |
5684 | || expect($lines, \$lineno, qr"^\.if !empty\(PKG_BUILD_OPTIONS\.\Q${bl_pkgbase}\E:M\S+\)$") | | | |
5685 | || expect($lines, \$lineno, qr"^\.endif$")) { | | | |
5686 | $have_dependencies = true; | | | |
5687 | $need_empty_line = true; | | | |
5688 | } elsif ($have_dependencies && expect($lines, \$lineno, qr"^$")) { | | | |
5689 | $need_empty_line = false; | | | |
5690 | } else { | | | |
5691 | last; | | | |
5692 | } | | | |
5693 | } | | | |
5694 | if ($need_empty_line) { | | | |
5695 | expect_empty_line($lines, \$lineno); | | | |
5696 | } | | | |
5697 | | | | |
5698 | # Sixth paragraph: Reference counter. | | | |
5699 | if (!expect($lines, \$lineno, qr"^BUILDLINK_DEPTH:=\t+\$\{BUILDLINK_DEPTH:S/\+\$//\}$")) { | | | |
5700 | lines_log_warning($lines, $lineno, "Expected BUILDLINK_DEPTH:= \${BUILDLINK_DEPTH:S/+\$//}."); | | | |
5701 | explain_warning($lines, $lineno, | | | |
5702 | "Everything besides the .include lines for the buildlink3.mk files of", | | | |
5703 | "dependencies should go between the .if !empty({PKGNAME}_BUILDLINK3_MK)", | | | |
5704 | "and the corresponding .endif."); | | | |
5705 | return; | | | |
5706 | } | | | |
5707 | | | | |
5708 | if ($lineno <= $#{$lines}) { | | | |
5709 | $lines->[$lineno]->log_warning("The file should end here."); | | | |
5710 | } | | | |
5711 | | | | |
5712 | checklines_buildlink3_inclusion($lines); | | | |
5713 | } | | 5508 | } |
5714 | | | 5509 | |
5715 | # This code is copy-pasted from checklines_buildlink3_mk_pre2009, which | | 5510 | sub checklines_buildlink3_mk($$$) { |
5716 | # will disappear after branching 2010Q1. | | | |
5717 | # | | | |
5718 | # In 2009, the format of the buildlink3.mk files has been revised to | | | |
5719 | # improve the speed of pkgsrc. As a result, the file format has improved | | | |
5720 | # in legibility and size. | | | |
5721 | sub checklines_buildlink3_mk_2009($$$) { | | | |
5722 | my ($lines, $lineno, $pkgid) = @_; | | 5511 | my ($lines, $lineno, $pkgid) = @_; |
5723 | my ($m); | | 5512 | my ($m); |
5724 | my ($bl_PKGBASE_line, $bl_PKGBASE); | | 5513 | my ($bl_PKGBASE_line, $bl_PKGBASE); |
5725 | my ($bl_pkgbase_line, $bl_pkgbase); | | 5514 | my ($bl_pkgbase_line, $bl_pkgbase); |
5726 | my ($abi_line, $abi_pkg, $abi_version); | | 5515 | my ($abi_line, $abi_pkg, $abi_version); |
5727 | my ($api_line, $api_pkg, $api_version); | | 5516 | my ($api_line, $api_pkg, $api_version); |
5728 | | | 5517 | |
5729 | # First paragraph: Introduction of the package identifier | | 5518 | # First paragraph: Introduction of the package identifier |
5730 | $bl_pkgbase_line = $lines->[$lineno - 1]; | | 5519 | $bl_pkgbase_line = $lines->[$lineno - 1]; |
5731 | $bl_pkgbase = $pkgid; | | 5520 | $bl_pkgbase = $pkgid; |
5732 | $opt_debug_misc and $bl_pkgbase_line->log_debug("bl_pkgbase=${bl_pkgbase}"); | | 5521 | $opt_debug_misc and $bl_pkgbase_line->log_debug("bl_pkgbase=${bl_pkgbase}"); |
5733 | expect_empty_line($lines, \$lineno); | | 5522 | expect_empty_line($lines, \$lineno); |
5734 | | | 5523 | |
5735 | # Second paragraph: multiple inclusion protection and introduction | | 5524 | # Second paragraph: multiple inclusion protection and introduction |
5736 | # of the uppercase package identifier. | | 5525 | # of the uppercase package identifier. |
5737 | return unless ($m = expect_re($lines, \$lineno, qr"^\.if !defined\((\S+)_BUILDLINK3_MK\)$")); | | 5526 | return unless ($m = expect_re($lines, \$lineno, qr"^\.if !defined\((\S+)_BUILDLINK3_MK\)$")); |
5738 | $bl_PKGBASE_line = $lines->[$lineno - 1]; | | 5527 | $bl_PKGBASE_line = $lines->[$lineno - 1]; |
5739 | $bl_PKGBASE = $m->text(1); | | 5528 | $bl_PKGBASE = $m->text(1); |
5740 | $opt_debug_misc and $bl_PKGBASE_line->log_debug("bl_PKGBASE=${bl_PKGBASE}"); | | 5529 | $opt_debug_misc and $bl_PKGBASE_line->log_debug("bl_PKGBASE=${bl_PKGBASE}"); |
5741 | expect_re($lines, \$lineno, qr"^\Q$bl_PKGBASE\E_BUILDLINK3_MK:=$"); | | 5530 | expect_re($lines, \$lineno, qr"^\Q$bl_PKGBASE\E_BUILDLINK3_MK:=$"); |
5742 | expect_empty_line($lines, \$lineno); | | 5531 | expect_empty_line($lines, \$lineno); |
5743 | | | 5532 | |
5744 | my $norm_bl_pkgbase = $bl_pkgbase; | | 5533 | my $norm_bl_pkgbase = $bl_pkgbase; |
5745 | $norm_bl_pkgbase =~ s/-/_/g; | | 5534 | $norm_bl_pkgbase =~ s/-/_/g; |
5746 | $norm_bl_pkgbase = uc($norm_bl_pkgbase); | | 5535 | $norm_bl_pkgbase = uc($norm_bl_pkgbase); |
5747 | if ($norm_bl_pkgbase ne $bl_PKGBASE) { | | 5536 | if ($norm_bl_pkgbase ne $bl_PKGBASE) { |