1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
#!/bin/sh
#!perl -w # --*- Perl -*--
eval 'exec perl -x $0 ${1+"$@"}'
if 0;
#------------------------------------------------------------------------------
#$Author: antanas $
#$Date: 2016-01-19 00:30:36 +0200 (An, 19 saus. 2016) $
#$Revision: 4539 $
#$URL: svn://www.crystallography.net/cod-tools/tags/v2.3/tools/check_option_descriptions $
#------------------------------------------------------------------------------
#*
# Parse the command line options from the provided script and its help in
# order to locate non-described and non-existing command line options.
#**
use strict;
use warnings;
my $script = shift @ARGV;
my $interpreter = shift @ARGV;
my @file_options;
my @help_options;
while( <> ) {
if( /^\s*((?:-[a-zA-Z\-_\d]+,\s*)*)(-[a-zA-Z\-_\d]+)/ ) {
# skip built-in help options in Python scripts
if ( $interpreter eq "python" &&
$2 =~ /^((-h)|(--help))$/ ) {
next;
};
push( @help_options, $2 );
push( @help_options, split( /,\s*/, $1 ) ) if $1;
}
}
open( my $help, $script );
my $getoptions_seen = 0;
if ( $interpreter eq "perl" ) {
while( <$help> ) {
if( $getoptions_seen ) {
# ignore the "--options" option
next if /--options/;
last if /^\);$/;
if( /^\s*(["'])(-[^\1]+?)\1/ ) {
push( @file_options, split( /,\s*/, $2 ) );
}
} else {
$getoptions_seen = 1 if /@ARGV\s+=\s+getOptions/;
}
}
} elsif ( $interpreter eq "sh" || $interpreter eq "bash" ) {
my @substr;
while( <$help> ) {
if( $getoptions_seen ) {
last if /^done$/;
if( /^\s*(-.*)[\\)]/ ) {
push @substr, split ( qw(\|), $1 );
}
} else {
$getoptions_seen = 1 if /while\s+[\s+\$#\s+-gt\s+0\s+]/;
}
}
@substr = sort { length $a <=> length $b } @substr;
for ( my $i = 0; $i < scalar(@substr); $i++ ) {
# ignore the safeguard catch-all option
next if $substr[$i] =~ /-\*/;
next if $substr[$i] =~ /-\?\*/;
# ignore the '--options' option
next if $substr[$i] =~ /--options/;
my $is_prefix = 0;
for ( my $j = ($i+1); $j < scalar(@substr); $j++ ) {
# assume short form options will not be prefixes
last if $substr[$i] =~ /^-[^-](-)?$/;
if ( $substr[$j] =~ /^$substr[$i]/ ) {
$is_prefix = 1;
last;
}
}
push( @file_options, $substr[$i] ) if !$is_prefix;
}
} elsif ( $interpreter eq "python" ) {
# This section could potentially be removed due to the way
# argparse.ArgumentParser handles option descriptions (if
# the option is defined then it will automatically be printed
# in the help message)
while( <$help> ) {
if( $getoptions_seen ) {
last if /parse_args\(args=sys.argv\[1:\]\)/;
if( /parser.add_argument\("(--[^"]+)/ ) {
push( @file_options, $1 );
}
} else {
$getoptions_seen = 1 if /argparse.ArgumentParser/;
}
}
}
# print join( "\n", sort @help_options ) . "\n--------\n";
# print join( "\n", sort @file_options ) . "\n--------\n";
my %help_options = map { $_ => 1 } @help_options;
my %file_options = map { $_ => 1 } @file_options;
my @not_described;
for my $key (@file_options) {
push( @not_described, $key ) if !exists $help_options{$key};
}
if( @not_described ) {
print "$script: options "
. join( ", ", map { "\"$_\"" } @not_described )
. " are not described in help.\n";
}
my @not_existing;
for my $key (@help_options) {
push( @not_existing, $key ) if !exists $file_options{$key};
}
if( @not_existing ) {
print "$script: options "
. join( ", ", map { "\"$_\"" } @not_existing )
. " are described in help, but no longer exist.\n";
}
|