^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) #!/usr/bin/env perl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) use strict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) use Text::Tabs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) use Getopt::Long;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) use Pod::Usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) my $debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) my $help;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) my $man;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) GetOptions(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) "debug" => \$debug,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) 'usage|?' => \$help,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) 'help' => \$man
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) ) or pod2usage(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) pod2usage(1) if $help;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) pod2usage(-exitstatus => 0, -verbose => 2) if $man;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) pod2usage(2) if (scalar @ARGV < 2 || scalar @ARGV > 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) my ($file_in, $file_out, $file_exceptions) = @ARGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) my $data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) my %ioctls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) my %defines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) my %typedefs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) my %enums;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) my %enum_symbols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) my %structs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) require Data::Dumper if ($debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) # read the file and get identifiers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) my $is_enum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) my $is_comment = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) open IN, $file_in or die "Can't open $file_in";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) while (<IN>) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) $data .= $_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) my $ln = $_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (!$is_comment) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) $ln =~ s,/\*.*(\*/),,g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) $is_comment = 1 if ($ln =~ s,/\*.*,,);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if ($ln =~ s,^(.*\*/),,) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) $is_comment = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if ($is_enum && $ln =~ m/^\s*([_\w][\w\d_]+)\s*[\,=]?/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) my $s = $1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) my $n = $1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) $n =~ tr/A-Z/a-z/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) $n =~ tr/_/-/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) $enum_symbols{$s} = "\\ :ref:`$s <$n>`\\ ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) $is_enum = 0 if ($is_enum && m/\}/);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) $is_enum = 0 if ($is_enum && m/\}/);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+_IO/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) my $s = $1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) my $n = $1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) $n =~ tr/A-Z/a-z/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) $ioctls{$s} = "\\ :ref:`$s <$n>`\\ ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) my $s = $1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) my $n = $1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) $n =~ tr/A-Z/a-z/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) $n =~ tr/_/-/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) $defines{$s} = "\\ :ref:`$s <$n>`\\ ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if ($ln =~ m/^\s*typedef\s+([_\w][\w\d_]+)\s+(.*)\s+([_\w][\w\d_]+);/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) my $s = $2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) my $n = $3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) $typedefs{$n} = "\\ :c:type:`$n <$s>`\\ ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if ($ln =~ m/^\s*enum\s+([_\w][\w\d_]+)\s+\{/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) || $ln =~ m/^\s*enum\s+([_\w][\w\d_]+)$/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) || $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)\s+\{/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) || $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)$/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) my $s = $1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) $enums{$s} = "enum :c:type:`$s`\\ ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) $is_enum = $1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if ($ln =~ m/^\s*struct\s+([_\w][\w\d_]+)\s+\{/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) || $ln =~ m/^\s*struct\s+([[_\w][\w\d_]+)$/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) || $ln =~ m/^\s*typedef\s*struct\s+([_\w][\w\d_]+)\s+\{/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) || $ln =~ m/^\s*typedef\s*struct\s+([[_\w][\w\d_]+)$/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) my $s = $1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) $structs{$s} = "struct $s\\ ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) close IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) # Handle multi-line typedefs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) my @matches = ($data =~ m/typedef\s+struct\s+\S+?\s*\{[^\}]+\}\s*(\S+)\s*\;/g,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) $data =~ m/typedef\s+enum\s+\S+?\s*\{[^\}]+\}\s*(\S+)\s*\;/g,);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) foreach my $m (@matches) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) my $s = $m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) $typedefs{$s} = "\\ :c:type:`$s`\\ ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) # Handle exceptions, if any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) my %def_reftype = (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) "ioctl" => ":ref",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) "define" => ":ref",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) "symbol" => ":ref",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) "typedef" => ":c:type",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) "enum" => ":c:type",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) "struct" => ":c:type",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if ($file_exceptions) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) open IN, $file_exceptions or die "Can't read $file_exceptions";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) while (<IN>) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) next if (m/^\s*$/ || m/^\s*#/);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) # Parsers to ignore a symbol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (m/^ignore\s+ioctl\s+(\S+)/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) delete $ioctls{$1} if (exists($ioctls{$1}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (m/^ignore\s+define\s+(\S+)/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) delete $defines{$1} if (exists($defines{$1}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (m/^ignore\s+typedef\s+(\S+)/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) delete $typedefs{$1} if (exists($typedefs{$1}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (m/^ignore\s+enum\s+(\S+)/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) delete $enums{$1} if (exists($enums{$1}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (m/^ignore\s+struct\s+(\S+)/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) delete $structs{$1} if (exists($structs{$1}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (m/^ignore\s+symbol\s+(\S+)/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) delete $enum_symbols{$1} if (exists($enum_symbols{$1}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) # Parsers to replace a symbol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) my ($type, $old, $new, $reftype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (m/^replace\s+(\S+)\s+(\S+)\s+(\S+)/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) $type = $1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) $old = $2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) $new = $3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) die "Can't parse $file_exceptions: $_";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if ($new =~ m/^\:c\:(data|func|macro|type)\:\`(.+)\`/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) $reftype = ":c:$1";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) $new = $2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) } elsif ($new =~ m/\:ref\:\`(.+)\`/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) $reftype = ":ref";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) $new = $1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) $reftype = $def_reftype{$type};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) $new = "$reftype:`$old <$new>`";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if ($type eq "ioctl") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) $ioctls{$old} = $new if (exists($ioctls{$old}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if ($type eq "define") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) $defines{$old} = $new if (exists($defines{$old}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if ($type eq "symbol") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) $enum_symbols{$old} = $new if (exists($enum_symbols{$old}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if ($type eq "typedef") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) $typedefs{$old} = $new if (exists($typedefs{$old}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if ($type eq "enum") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) $enums{$old} = $new if (exists($enums{$old}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if ($type eq "struct") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) $structs{$old} = $new if (exists($structs{$old}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) die "Can't parse $file_exceptions: $_";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if ($debug) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) print Data::Dumper->Dump([\%ioctls], [qw(*ioctls)]) if (%ioctls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) print Data::Dumper->Dump([\%typedefs], [qw(*typedefs)]) if (%typedefs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) print Data::Dumper->Dump([\%enums], [qw(*enums)]) if (%enums);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) print Data::Dumper->Dump([\%structs], [qw(*structs)]) if (%structs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) print Data::Dumper->Dump([\%defines], [qw(*defines)]) if (%defines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) print Data::Dumper->Dump([\%enum_symbols], [qw(*enum_symbols)]) if (%enum_symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) # Align block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) $data = expand($data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) $data = " " . $data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) $data =~ s/\n/\n /g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) $data =~ s/\n\s+$/\n/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) $data =~ s/\n\s+\n/\n\n/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) # Add escape codes for special characters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) $data =~ s,([\_\`\*\<\>\&\\\\:\/\|\%\$\#\{\}\~\^]),\\$1,g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) $data =~ s,DEPRECATED,**DEPRECATED**,g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) # Add references
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) my $start_delim = "[ \n\t\(\=\*\@]";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) my $end_delim = "(\\s|,|\\\\=|\\\\:|\\;|\\\)|\\}|\\{)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) foreach my $r (keys %ioctls) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) my $s = $ioctls{$r};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) print "$r -> $s\n" if ($debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) foreach my $r (keys %defines) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) my $s = $defines{$r};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) print "$r -> $s\n" if ($debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) foreach my $r (keys %enum_symbols) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) my $s = $enum_symbols{$r};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) print "$r -> $s\n" if ($debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) foreach my $r (keys %enums) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) my $s = $enums{$r};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) print "$r -> $s\n" if ($debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) $data =~ s/enum\s+($r)$end_delim/$s$2/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) foreach my $r (keys %structs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) my $s = $structs{$r};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) print "$r -> $s\n" if ($debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) $data =~ s/struct\s+($r)$end_delim/$s$2/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) foreach my $r (keys %typedefs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) my $s = $typedefs{$r};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) print "$r -> $s\n" if ($debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) $data =~ s/\\ ([\n\s])/\1/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) # Generate output file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) my $title = $file_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) $title =~ s,.*/,,;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) open OUT, "> $file_out" or die "Can't open $file_out";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) print OUT ".. -*- coding: utf-8; mode: rst -*-\n\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) print OUT "$title\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) print OUT "=" x length($title);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) print OUT "\n\n.. parsed-literal::\n\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) print OUT $data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) close OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) __END__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) =head1 NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) parse_headers.pl - parse a C file, in order to identify functions, structs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) enums and defines and create cross-references to a Sphinx book.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) =head1 SYNOPSIS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) B<parse_headers.pl> [<options>] <C_FILE> <OUT_FILE> [<EXCEPTIONS_FILE>]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) Where <options> can be: --debug, --help or --usage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) =head1 OPTIONS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) =over 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) =item B<--debug>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) Put the script in verbose mode, useful for debugging.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) =item B<--usage>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) Prints a brief help message and exits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) =item B<--help>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) Prints a more detailed help message and exits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) =back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) =head1 DESCRIPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) Convert a C header or source file (C_FILE), into a ReStructured Text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) included via ..parsed-literal block with cross-references for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) documentation files that describe the API. It accepts an optional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) EXCEPTIONS_FILE with describes what elements will be either ignored or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) be pointed to a non-default reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) The output is written at the (OUT_FILE).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) It is capable of identifying defines, functions, structs, typedefs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) enums and enum symbols and create cross-references for all of them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) It is also capable of distinguish #define used for specifying a Linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) ioctl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) The EXCEPTIONS_FILE contain two rules to allow ignoring a symbol or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) to replace the default references by a custom one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) Please read Documentation/doc-guide/parse-headers.rst at the Kernel's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) tree for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) =head1 BUGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) Report bugs to Mauro Carvalho Chehab <mchehab@kernel.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) =head1 COPYRIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) License GPLv2: GNU GPL version 2 <https://gnu.org/licenses/gpl.html>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) This is free software: you are free to change and redistribute it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) There is NO WARRANTY, to the extent permitted by law.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) =cut