82b49c2b9f
Include the full path to the helpfile in the output message, when relevant. This commit was SVN r32451.
295 строки
7.6 KiB
Perl
Исполняемый файл
295 строки
7.6 KiB
Perl
Исполняемый файл
#!/usr/bin/env perl
|
|
#
|
|
# Copyright (c) 2014 Cisco Systems, Inc. All rights reserved.
|
|
# $COPYRIGHT$
|
|
#
|
|
# Simple script to check all the opal_show_help (and orte_show_help)
|
|
# strings against what is found in help files.
|
|
#
|
|
|
|
use strict;
|
|
|
|
use Cwd;
|
|
use File::Find;
|
|
use Getopt::Long;
|
|
use Data::Dumper;
|
|
|
|
my $num_warnings = 0;
|
|
my $num_errors = 0;
|
|
|
|
###########################################################################
|
|
|
|
my $VERBOSE = 0;
|
|
my $HELP = 0;
|
|
|
|
GetOptions(
|
|
"help" => \$HELP,
|
|
"verbose" => \$VERBOSE,
|
|
) or die "unable to parse options, aborted";
|
|
|
|
if ($HELP) {
|
|
print <<EOF;
|
|
%0 [options]
|
|
|
|
--help | -h This help message
|
|
--verbose | -v Be verbose in output
|
|
EOF
|
|
exit(0);
|
|
}
|
|
|
|
###########################################################################
|
|
|
|
sub verbose {
|
|
print @_
|
|
if ($VERBOSE);
|
|
}
|
|
|
|
sub DebugDump {
|
|
my $d = new Data::Dumper([@_]);
|
|
$d->Purity(1)->Indent(1);
|
|
my $s = $d->Dump;
|
|
print $s;
|
|
}
|
|
|
|
###########################################################################
|
|
|
|
# Find the top-level OMPI source tree dir
|
|
my $start = cwd();
|
|
my $top = $start;
|
|
while (! -f "$top/Makefile.ompi-rules") {
|
|
chdir("..");
|
|
$top = cwd();
|
|
die "Can't find top-level Open MPI directory"
|
|
if ($top eq "/");
|
|
}
|
|
chdir($start);
|
|
|
|
###########################################################################
|
|
|
|
my @source_files;
|
|
my @help_files;
|
|
|
|
# Helper: Search for all source and help files
|
|
sub match_files {
|
|
# Don't process sym links
|
|
return
|
|
if (-l $_);
|
|
|
|
# Don't recurse down "special" directories
|
|
if (-d $_ &&
|
|
((/^\.deps$/) || (/^\.libs$/) ||
|
|
(/^\.svn$/) || (/^\.hg$/) || (/^\.git$/))) {
|
|
$File::Find::prune = 1;
|
|
return;
|
|
}
|
|
|
|
# $File::Find::name is the path relative to the starting point.
|
|
# $_ contains the file's basename. The code automatically changes
|
|
# to the processed directory, so we want to open / close $_.
|
|
|
|
verbose("--> $File::Find::name\n");
|
|
|
|
my $relative = $File::Find::name;
|
|
$relative =~ s/^$top//;
|
|
$relative =~ s/^\///;
|
|
|
|
my $short = $_;
|
|
if ($short =~ /^help-.*\.txt$/) {
|
|
push(@help_files, {
|
|
full => $File::Find::name,
|
|
short => $short,
|
|
relative => $relative,
|
|
});
|
|
verbose(" Found help file: $short\n");
|
|
}
|
|
|
|
if ($short =~ /\.c$/ ||
|
|
$short =~ /\.h$/ ||
|
|
$short =~ /\.cc$/) {
|
|
push(@source_files, {
|
|
full => $File::Find::name,
|
|
short => $short,
|
|
relative => $relative,
|
|
});
|
|
verbose(" Found source file: $short\n");
|
|
}
|
|
}
|
|
|
|
# Find all source and help files
|
|
print "Searching for source and help files...\n";
|
|
print "Starting in: $start\n";
|
|
find(\&match_files, ".");
|
|
|
|
###########################################################################
|
|
|
|
# Index all help files
|
|
my $help_topics;
|
|
my $help_file_refs;
|
|
|
|
print "Indexing help files...\n";
|
|
|
|
foreach my $info (@help_files) {
|
|
verbose("Indexing help: $info->{full}\n");
|
|
|
|
# Check for short name collision
|
|
if (exists($help_topics->{$info->{short}})) {
|
|
|
|
# Found a collision! Find the original's full name.
|
|
my $collide_relative = "unknown";
|
|
foreach my $i (@help_files) {
|
|
if ($i->{short} eq $info->{short}) {
|
|
$collide_relative = $i->{relative};
|
|
last;
|
|
}
|
|
}
|
|
|
|
# Print error message
|
|
print "*** ERROR: Help file name collision:
|
|
File 1: $info->{relative}
|
|
File 2: $collide_relative\n";
|
|
++$num_errors;
|
|
}
|
|
|
|
# Read in file, find all of its topics
|
|
my $num_topics = 0;
|
|
open(FH, $info->{full}) || die "Can't open $info->{full}";
|
|
while (<FH>) {
|
|
if (m/^\s*\[(.+?)\]\s*$/) {
|
|
my $topic = $1;
|
|
verbose(" Topic: $topic\n");
|
|
$help_topics->{$info->{short}}->{topic}->{$topic} = 0;
|
|
$help_topics->{$info->{short}}->{full} = $info->{full};
|
|
++$num_topics;
|
|
}
|
|
}
|
|
close(FH);
|
|
|
|
if (0 == $num_topics) {
|
|
print "*** WARNING: Empty help file (no topics)
|
|
Help file: $info->{full}\n";
|
|
++$num_warnings;
|
|
}
|
|
}
|
|
|
|
###########################################################################
|
|
|
|
# Search source files for calls to opal_show_help and (o)rte_show_help
|
|
|
|
print "Searching source files...\n";
|
|
|
|
# Helper: for a given filename/topic, see if it exists
|
|
sub check_file_topic {
|
|
my $info = shift;
|
|
my $file = shift;
|
|
my $topic = shift;
|
|
|
|
verbose("Found $info->{short}: $file / $topic\n");
|
|
|
|
# Do we have a help file for this?
|
|
if (!exists($help_topics->{$file})) {
|
|
print "*** ERROR: Source-referenced help file does not exist
|
|
Source file: $info->{relative}
|
|
Help file referenced: $file\n";
|
|
++$num_errors;
|
|
}
|
|
|
|
# Do we have a topic in that help file for this?
|
|
elsif (!exists($help_topics->{$file}->{topic}->{$topic})) {
|
|
print "*** ERROR: Source-referenced help topic does not exist
|
|
Source file: $info->{relative}
|
|
Help file referenced: $file
|
|
which is: $help_topics->{$file}->{full}
|
|
Help topic referenced: $topic\n";
|
|
++$num_errors;
|
|
}
|
|
|
|
# Yes, we do have a topic in that help file for this.
|
|
# Increase its ref count.
|
|
else {
|
|
++$help_topics->{$file}->{topic}->{$topic};
|
|
}
|
|
}
|
|
|
|
# Helper: search source file for a regexps matching a help filename
|
|
# and topic.
|
|
sub check_name {
|
|
my $info = shift,
|
|
my $name = shift;
|
|
my $sep = shift;
|
|
my $src = shift;
|
|
|
|
while ($src =~ m/$name\s*$sep\s*"(.+?)"\s*,\s*"(.+?)"/) {
|
|
my $file = $1;
|
|
my $topic = $2;
|
|
check_file_topic($info, $file, $topic);
|
|
|
|
# Don't find this one again
|
|
$src =~ s/$name\s*$sep\s*"(.+?)"\s*,\s*"(.+?)"/SHOW_HELP_REPLACED/;
|
|
}
|
|
|
|
return $src;
|
|
}
|
|
|
|
|
|
# Check to ensure helpfile/topic combos exist
|
|
foreach my $info (@source_files) {
|
|
verbose("Searching source: $info->{full}\n");
|
|
|
|
my $src;
|
|
open(FH, $info->{full}) || die "Can't open $info->{full}";
|
|
while (<FH>) {
|
|
# Eliminate newlines, just for regexp simplicity later
|
|
chomp;
|
|
$src .= $_;
|
|
}
|
|
close(FH);
|
|
|
|
# Find calls to opal_show_help()
|
|
$src = check_name($info, "opal_show_help", "\\(", $src);
|
|
# Find calls to opal_show_help_string()
|
|
$src = check_name($info, "opal_show_help_string", "\\(", $src);
|
|
# Find calls to rte_show_help() (and also orte_show_help())
|
|
$src = check_name($info, "rte_show_help", "\\(", $src);
|
|
# Find special tokens from comments
|
|
$src = check_name($info, "SHOW_HELP", ":", $src);
|
|
}
|
|
|
|
###########################################################################
|
|
|
|
# Check that all indexed help strings were referenced
|
|
|
|
print "Checking for stale help messages / files...\n";
|
|
|
|
foreach my $file (sort(keys(%{$help_topics}))) {
|
|
my $num_used = 0;
|
|
foreach my $topic (sort(keys(%{$help_topics->{$file}->{topic}}))) {
|
|
if (0 == $help_topics->{$file}->{topic}->{$topic}) {
|
|
print "*** WARNING: Possibly unused help topic
|
|
Help file: $help_topics->{$file}->{full}
|
|
Help topic: $topic\n";
|
|
++$num_warnings;
|
|
} else {
|
|
++$num_used;
|
|
}
|
|
}
|
|
|
|
# Were no topics used in this file at all?
|
|
if (0 == $num_used) {
|
|
print "*** WARNING: Possibly unused help file (no topics used from this file)
|
|
Help file: $help_topics->{$file}->{full}\n";
|
|
++$num_warnings;
|
|
}
|
|
}
|
|
|
|
###########################################################################
|
|
|
|
# All done
|
|
if (0 == $num_errors && 0 == $num_warnings) {
|
|
print "+++ All seems good!\n";
|
|
exit(0);
|
|
} else {
|
|
print "Total number of warnings: $num_warnings
|
|
Total number of errors: $num_errors\n";
|
|
exit(1);
|
|
}
|