10 File::Spec->catfile($Bin, '..', 'src', 'main.c'),
11 qr/static \s+? struct \s+? cmdline_option \s+? option_data\[\] \s+? = \s+? \{ (.*?) \}\;/sx,
12 [ qw(long_name short_name type data argtype) ],
14 File::Spec->catfile($Bin, '..', 'src', 'init.c'),
15 qr/commands\[\] \s+? = \s+? \{ (.*?) \}\;/sx,
16 [ qw(name place action) ],
20 my (@lines, @opts, $source);
21 foreach my $arg (@args) {
22 my ($file, $regex, $names) = @$arg;
23 $source = read_file($file);
24 @lines = extract_opts_chunk($source, $regex);
25 push @opts, extract_opts(\@lines, $names);
33 open(my $fh, '<', $file) or die "Cannot open $file: $!";
34 return do { local $/; <$fh> };
37 sub extract_opts_chunk
39 my ($source, $regex) = @_;
40 my ($opts) = $source =~ $regex;
41 return map { /\S/ && !/^\#/ ? $_ : () } split /(?<=\})/, $opts;
46 my ($lines, $names) = @_;
47 my ($is_deprecated, @opts);
48 foreach my $line (@$lines) {
49 my ($args) = $line =~ /\{ \s+? (.*?) \s+? \}/sx;
50 next unless defined $args;
51 my @args = map { tr/'"//d; $_ }
52 map { /\((.*?)\)/ ? $1 : $_ }
54 my $opt = { map { $_ => shift @args } @$names };
55 ($opt->{line}) = $line =~ /.*? (\{.*)/;
56 $opts[-1]->{is_deprecated} = 1 if $line =~ /deprecated/i;
64 emit_no_corresponding_cmds(@_);
66 emit_no_matching_long_cmds(@_);
68 emit_no_corresponding_opts(@_);
70 emit_deprecated_opts(@_);
72 emit_deprecated_cmds(@_);
76 sub emit_no_corresponding_cmds
80 No corresponding commands
81 =========================
83 foreach my $opt (@$opts) {
84 unless ($opt->{type} =~ /^(?:OPT_BOOLEAN|OPT_VALUE)$/
85 && $opt->{argtype} == -1)
87 print $opt->{line}, "\n";
92 sub emit_no_matching_long_cmds
99 foreach my $opt (@$opts) {
100 my $long_name = $opt->{long_name};
101 $long_name =~ tr/-//d;
102 unless ($long_name eq $opt->{data}) {
103 print $opt->{line}, "\n";
108 sub emit_no_corresponding_opts
110 my ($opts, $cmds) = @_;
112 No corresponding options
113 ========================
115 foreach my $cmd (@$cmds) {
117 foreach my $opt (@$opts) {
118 my $long_name = $opt->{long_name};
119 $long_name =~ tr/-//d;
120 if ($cmd->{name} eq $opt->{data}
121 || $cmd->{name} eq $long_name) {
127 print $cmd->{line}, "\n";
132 sub emit_deprecated_opts
139 foreach my $opt (@$opts) {
140 if ($opt->{is_deprecated}) {
141 print $opt->{line}, "\n";
146 sub emit_deprecated_cmds
148 my ($opts, $cmds) = @_;
153 foreach my $cmd (@$cmds) {
154 if ($cmd->{is_deprecated}) {
155 print $cmd->{line}, "\n";