mirror of
https://github.com/verilator/verilator.git
synced 2025-01-05 22:27:35 +00:00
120 lines
3.6 KiB
Perl
Executable File
120 lines
3.6 KiB
Perl
Executable File
#!/usr/bin/env perl
|
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
|
# DESCRIPTION: Verilator: Primitive C++ style checker
|
|
#
|
|
# Copyright 2022 by Wilson Snyder. This program is free software; you
|
|
# can redistribute it and/or modify it under the terms of either the GNU
|
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
|
# Version 2.0.
|
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
|
|
|
scenarios(dist => 1);
|
|
|
|
my $root = "..";
|
|
|
|
my @Waivers =
|
|
(
|
|
'+verilator+prof+threads+file+', # Deprecated
|
|
'+verilator+prof+threads+start+', # Deprecated
|
|
'+verilator+prof+threads+window+', # Deprecated
|
|
'-fno-', # Documented differently
|
|
'-no-lineno', # Deprecated
|
|
'-no-order-clock-delay', # Deprecated
|
|
'-prof-threads', # Deprecated
|
|
);
|
|
|
|
my %sums = %{get_summary_opts($root)};
|
|
my %docs = %{get_docs_opts($root)};
|
|
|
|
my %both = (%sums, %docs);
|
|
my %waiver = map { $_ => 1; } @Waivers;
|
|
foreach my $opt (sort keys %both) {
|
|
next if $waiver{$opt};
|
|
my $sum_ok = 0;
|
|
my $docs_ok = 0;
|
|
for my $alt (alt_names($opt)) {
|
|
$sum_ok = 1 if $sums{$alt};
|
|
print "$sum_ok SAC '$opt' -> '$alt'\n" if $Self->{verbose};
|
|
}
|
|
$sum_ok = 1 if $opt =~ /-fno-/; # Minimal-documented optimization option
|
|
for my $alt (alt_names($opt)) {
|
|
$docs_ok = 1 if $docs{$alt};
|
|
print "$sum_ok DAC '$opt' -> '$alt'\n" if $Self->{verbose};
|
|
}
|
|
if (!$sum_ok) {
|
|
error($docs{$opt}.": Option documented in docs/guide '$opt'"
|
|
." not found in bin/* ARGUMENT SUMMARY documentation");
|
|
} elsif (!$docs_ok) {
|
|
error($sums{$opt}.": Option documented in bin/ ARGUMENT SUMMARY '$opt'"
|
|
." not found in docs/guide documentation");
|
|
} else {
|
|
print($docs{$opt}.": ok '$opt'\n") if $Self->{verbose};
|
|
}
|
|
}
|
|
|
|
ok(1);
|
|
1;
|
|
|
|
sub get_summary_opts {
|
|
my $root = shift;
|
|
my %args = ();
|
|
foreach my $file (glob "$root/bin/*") {
|
|
my $fc = file_contents($file);
|
|
my $on = 0;
|
|
my $lineno = 0;
|
|
foreach my $line (split(/\n/, $fc)) {
|
|
++$lineno;
|
|
if ($line =~ /ARGUMENT SUMMARY/) {
|
|
$on = 1;
|
|
} elsif ($line =~ /=head1/) {
|
|
$on = 0;
|
|
} elsif ($on && $line =~ /^\s+([---+]+[^ ]+)/) {
|
|
my $opt = opt_clean($1);
|
|
print "S '$opt' $line\n" if $Self->{verbose};
|
|
$args{$opt} = "$file:$lineno";
|
|
} elsif ($line =~ /parser.add_argument\('([---+][^']+)'/) {
|
|
my $opt = opt_clean($1);
|
|
print "S '$opt' $line\n" if $Self->{verbose};
|
|
$args{$opt} = "$file:$lineno";
|
|
}
|
|
}
|
|
}
|
|
return \%args;
|
|
}
|
|
|
|
sub get_docs_opts {
|
|
my $root = shift;
|
|
my %args = ();
|
|
foreach my $file (glob "$root/docs/guide/*.rst") {
|
|
my $fc = file_contents($file);
|
|
my $lineno = 0;
|
|
foreach my $line (split(/\n/, $fc)) {
|
|
++$lineno;
|
|
if ($line =~ /option:: ([---+]+[^ `]+)/
|
|
|| $line =~ /:vlopt:`[^`]+ <([^>]+)>/
|
|
|| $line =~ /:vlopt:`([---+]+[^ `]+)/) {
|
|
my $opt = opt_clean($1);
|
|
print "D '$opt' $line\n" if $Self->{verbose};
|
|
$args{$opt} = "$file:$lineno";
|
|
}
|
|
}
|
|
}
|
|
return \%args;
|
|
}
|
|
|
|
sub opt_clean {
|
|
my $opt = shift;
|
|
$opt =~ s/--/-/;
|
|
$opt =~ s/<.*//;
|
|
$opt =~ s/\\//;
|
|
return $opt;
|
|
}
|
|
|
|
sub alt_names {
|
|
my $opt = shift;
|
|
my @opts = ($opt);
|
|
push @opts, "-no".$opt if $opt =~ /^-/;
|
|
push @opts, $1 if $opt =~ /^-no(-.*)/;
|
|
return @opts;
|
|
}
|