File: check_option_descriptions

package info (click to toggle)
cod-tools 2.3%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 114,852 kB
  • sloc: perl: 53,336; sh: 23,842; ansic: 6,318; xml: 1,982; yacc: 1,112; makefile: 716; python: 158; sql: 73
file content (125 lines) | stat: -rwxr-xr-x 3,973 bytes parent folder | download
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";
}