contrib: simple script to check for stale show_help messages / usage
This script can be run from any sub-tree in the OMPI code base. It does several things: * Find all help-*txt files and index all the topics found in the sub-tree. * Find all C/C++ source files (.c, .cc, .h) in the sub-tree, and look for various flavors of the opal_show_help() function (e.g., including orte_show_help()) and search for hard-coded filenames and topics. * Also look for special tokens (in comments) in the source code for help topics that are not necessarily hard-coded (e.g., topics that are snprintf'ed). * For each filename/topic found, output a warning if a) the file does not exist, or b) that the topic does not exist in that file. * Output a warning for any topic that is not referenced in the source code (i.e., orphaned/now-unused help messages). * Output a warning for any help file that appears to be empty. * Output a warning for any help file that appears to be unused (i.e., no topics in the help file are referenced in code). This commit was SVN r31311.
Этот коммит содержится в:
родитель
95a4f219ea
Коммит
7a3adcf050
292
contrib/check-help-strings.pl
Обычный файл
292
contrib/check-help-strings.pl
Обычный файл
@ -0,0 +1,292 @@
|
||||
#!/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} = 0;
|
||||
++$num_topics;
|
||||
}
|
||||
}
|
||||
close(FH);
|
||||
|
||||
if (0 == $num_topics) {
|
||||
print "*** WARNING: Empty help file (no topics)
|
||||
Help file: $info->{short}\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})) {
|
||||
print "*** ERROR: Source-referenced help topic does not exist
|
||||
Source file: $info->{relative}
|
||||
Help file referenced: $file
|
||||
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};
|
||||
}
|
||||
}
|
||||
|
||||
# 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}}))) {
|
||||
if (0 == $help_topics->{$file}->{$topic}) {
|
||||
print "*** WARNING: Possibly unused help topic
|
||||
Help file: $file
|
||||
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: $file\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);
|
||||
}
|
Загрузка…
x
Ссылка в новой задаче
Block a user