2014-04-07 19:34:55 +04:00
|
|
|
#!/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(
|
2014-08-16 20:01:32 +04:00
|
|
|
"help|h" => \$HELP,
|
|
|
|
"verbose|v" => \$VERBOSE,
|
2014-04-07 19:34:55 +04:00
|
|
|
) or die "unable to parse options, aborted";
|
|
|
|
|
|
|
|
if ($HELP) {
|
|
|
|
print <<EOF;
|
|
|
|
%0 [options]
|
|
|
|
|
2014-08-16 20:01:32 +04:00
|
|
|
--help | h This help message
|
|
|
|
--verbose | v Be verbose in output
|
2014-04-07 19:34:55 +04:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-08-16 20:01:32 +04:00
|
|
|
sub isTopDir {
|
|
|
|
my ($d) = @_;
|
|
|
|
|
|
|
|
# trunk
|
|
|
|
if (-f "$d/Makefile.ompi-rules") {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
# v1.8
|
|
|
|
if (-f "$d/Makefile.man-page-rules") {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-04-07 19:34:55 +04:00
|
|
|
###########################################################################
|
|
|
|
|
|
|
|
# Find the top-level OMPI source tree dir
|
|
|
|
my $start = cwd();
|
|
|
|
my $top = $start;
|
2014-08-16 20:01:32 +04:00
|
|
|
while (!isTopDir($top)) {
|
2014-04-07 19:34:55 +04:00
|
|
|
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";
|
2014-08-16 15:56:21 +04:00
|
|
|
my $startrel = $start;
|
|
|
|
if ($top ne $start) {
|
|
|
|
$startrel =~ s/^$top//;
|
|
|
|
$startrel =~ s/^\///;
|
|
|
|
}
|
2014-04-07 19:34:55 +04:00
|
|
|
find(\&match_files, ".");
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
|
|
|
|
# Index all help files
|
|
|
|
my $help_topics;
|
|
|
|
my $help_file_refs;
|
|
|
|
|
2014-08-16 15:56:21 +04:00
|
|
|
print "Indexing help files (from entire source tree)...\n";
|
2014-04-07 19:34:55 +04:00
|
|
|
|
|
|
|
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");
|
2014-08-08 17:32:56 +04:00
|
|
|
$help_topics->{$info->{short}}->{topic}->{$topic} = 0;
|
|
|
|
$help_topics->{$info->{short}}->{full} = $info->{full};
|
2014-04-07 19:34:55 +04:00
|
|
|
++$num_topics;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close(FH);
|
|
|
|
|
|
|
|
if (0 == $num_topics) {
|
|
|
|
print "*** WARNING: Empty help file (no topics)
|
2014-08-08 17:32:56 +04:00
|
|
|
Help file: $info->{full}\n";
|
2014-04-07 19:34:55 +04:00
|
|
|
++$num_warnings;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
|
|
|
|
# Search source files for calls to opal_show_help and (o)rte_show_help
|
|
|
|
|
2014-08-16 15:56:21 +04:00
|
|
|
if ($start eq $top) {
|
|
|
|
print "Searching source files (from entire source tree)...\n";
|
|
|
|
} else {
|
|
|
|
print "Searching source files (under $startrel)...\n";
|
|
|
|
}
|
2014-04-07 19:34:55 +04:00
|
|
|
|
|
|
|
# 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?
|
2014-08-08 17:32:56 +04:00
|
|
|
elsif (!exists($help_topics->{$file}->{topic}->{$topic})) {
|
2014-04-07 19:34:55 +04:00
|
|
|
print "*** ERROR: Source-referenced help topic does not exist
|
|
|
|
Source file: $info->{relative}
|
|
|
|
Help file referenced: $file
|
2014-08-08 17:32:56 +04:00
|
|
|
which is: $help_topics->{$file}->{full}
|
2014-04-07 19:34:55 +04:00
|
|
|
Help topic referenced: $topic\n";
|
|
|
|
++$num_errors;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Yes, we do have a topic in that help file for this.
|
|
|
|
# Increase its ref count.
|
|
|
|
else {
|
2014-08-08 17:32:56 +04:00
|
|
|
++$help_topics->{$file}->{topic}->{$topic};
|
2014-04-07 19:34:55 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# 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");
|
|
|
|
|
2014-08-16 15:56:21 +04:00
|
|
|
# If this source file is not in the target area, then skip it
|
|
|
|
next
|
|
|
|
if ($info->{relative} != /^$startrel/);
|
|
|
|
|
2014-04-07 19:34:55 +04:00
|
|
|
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;
|
2014-08-08 17:32:56 +04:00
|
|
|
foreach my $topic (sort(keys(%{$help_topics->{$file}->{topic}}))) {
|
|
|
|
if (0 == $help_topics->{$file}->{topic}->{$topic}) {
|
2014-04-07 19:34:55 +04:00
|
|
|
print "*** WARNING: Possibly unused help topic
|
2014-08-08 17:32:56 +04:00
|
|
|
Help file: $help_topics->{$file}->{full}
|
2014-04-07 19:34:55 +04:00
|
|
|
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)
|
2014-08-08 17:32:56 +04:00
|
|
|
Help file: $help_topics->{$file}->{full}\n";
|
2014-04-07 19:34:55 +04:00
|
|
|
++$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);
|
|
|
|
}
|