^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) #!/usr/bin/env perl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) # SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) use strict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) use warnings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) use utf8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) use Pod::Usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) use Getopt::Long;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) use File::Find;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) use Fcntl ':mode';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) my $help = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) my $man = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) my $debug = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) my $enable_lineno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) my $prefix="Documentation/ABI";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) # If true, assumes that the description is formatted with ReST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) my $description_is_rst = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) GetOptions(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) "debug|d+" => \$debug,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) "enable-lineno" => \$enable_lineno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) "rst-source!" => \$description_is_rst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) "dir=s" => \$prefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) 'help|?' => \$help,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) man => \$man
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) ) or pod2usage(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) pod2usage(1) if $help;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) pod2usage(-exitstatus => 0, -verbose => 2) if $man;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) pod2usage(2) if (scalar @ARGV < 1 || @ARGV > 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) my ($cmd, $arg) = @ARGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) pod2usage(2) if ($cmd ne "search" && $cmd ne "rest" && $cmd ne "validate");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) pod2usage(2) if ($cmd eq "search" && !$arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) require Data::Dumper if ($debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) my %data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) my %symbols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) # Displays an error message, printing file name and line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) sub parse_error($$$$) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) my ($file, $ln, $msg, $data) = @_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) $data =~ s/\s+$/\n/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) print STDERR "Warning: file $file#$ln:\n\t$msg";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if ($data ne "") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) print STDERR ". Line\n\t\t$data";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) print STDERR "\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) # Parse an ABI file, storing its contents at %data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) sub parse_abi {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) my $file = $File::Find::name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) my $mode = (stat($file))[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return if ($mode & S_IFDIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return if ($file =~ m,/README,);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) my $name = $file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) $name =~ s,.*/,,;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) my $fn = $file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) $fn =~ s,Documentation/ABI/,,;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) my $nametag = "File $fn";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) $data{$nametag}->{what} = "File $name";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) $data{$nametag}->{type} = "File";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) $data{$nametag}->{file} = $name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) $data{$nametag}->{filepath} = $file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) $data{$nametag}->{is_file} = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) $data{$nametag}->{line_no} = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) my $type = $file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) $type =~ s,.*/(.*)/.*,$1,;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) my $what;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) my $new_what;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) my $tag = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) my $ln;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) my $xrefs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) my $space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) my @labels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) my $label = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) print STDERR "Opening $file\n" if ($debug > 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) open IN, $file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) while(<IN>) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) $ln++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (m/^(\S+)(:\s*)(.*)/i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) my $new_tag = lc($1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) my $sep = $2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) my $content = $3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!($new_tag =~ m/(what|where|date|kernelversion|contact|description|users)/)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if ($tag eq "description") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) # New "tag" is actually part of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) # description. Don't consider it a tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) $new_tag = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) } elsif ($tag ne "") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) parse_error($file, $ln, "tag '$tag' is invalid", $_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) # Invalid, but it is a common mistake
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if ($new_tag eq "where") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) parse_error($file, $ln, "tag 'Where' is invalid. Should be 'What:' instead", "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) $new_tag = "what";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if ($new_tag =~ m/what/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) $space = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) $content =~ s/[,.;]$//;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) push @{$symbols{$content}->{file}}, " $file:" . ($ln - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if ($tag =~ m/what/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) $what .= ", " . $content;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if ($what) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) parse_error($file, $ln, "What '$what' doesn't have a description", "") if (!$data{$what}->{description});
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) foreach my $w(split /, /, $what) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) $symbols{$w}->{xref} = $what;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) $what = $content;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) $label = $content;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) $new_what = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) push @labels, [($content, $label)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) $tag = $new_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) push @{$data{$nametag}->{symbols}}, $content if ($data{$nametag}->{what});
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if ($tag ne "" && $new_tag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) $tag = $new_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if ($new_what) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) @{$data{$what}->{label_list}} = @labels if ($data{$nametag}->{what});
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) @labels = ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) $label = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) $new_what = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) $data{$what}->{type} = $type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (!defined($data{$what}->{file})) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) $data{$what}->{file} = $name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) $data{$what}->{filepath} = $file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if ($name ne $data{$what}->{file}) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) $data{$what}->{file} .= " " . $name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) $data{$what}->{filepath} .= " " . $file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) print STDERR "\twhat: $what\n" if ($debug > 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) $data{$what}->{line_no} = $ln;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) $data{$what}->{line_no} = $ln if (!defined($data{$what}->{line_no}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (!$what) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) parse_error($file, $ln, "'What:' should come first:", $_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if ($new_tag eq "description") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) $sep =~ s,:, ,;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) $content = ' ' x length($new_tag) . $sep . $content;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) while ($content =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if ($content =~ m/^(\s*)(\S.*)$/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) # Preserve initial spaces for the first line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) $space = $1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) $content = "$2\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) $data{$what}->{$tag} .= $content;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) undef($space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) $data{$what}->{$tag} = $content;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) # Store any contents before tags at the database
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (!$tag && $data{$nametag}->{what}) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) $data{$nametag}->{description} .= $_;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if ($tag eq "description") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) my $content = $_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) while ($content =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (m/^\s*\n/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) $data{$what}->{$tag} .= "\n";
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (!defined($space)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) # Preserve initial spaces for the first line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if ($content =~ m/^(\s*)(\S.*)$/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) $space = $1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) $content = "$2\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) $space = "" if (!($content =~ s/^($space)//));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) $data{$what}->{$tag} .= $content;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (m/^\s*(.*)/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) $data{$what}->{$tag} .= "\n$1";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) $data{$what}->{$tag} =~ s/\n+$//;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) # Everything else is error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) parse_error($file, $ln, "Unexpected content", $_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) $data{$nametag}->{description} =~ s/^\n+// if ($data{$nametag}->{description});
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if ($what) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) parse_error($file, $ln, "What '$what' doesn't have a description", "") if (!$data{$what}->{description});
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) foreach my $w(split /, /,$what) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) $symbols{$w}->{xref} = $what;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) close IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) sub create_labels {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) my %labels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) foreach my $what (keys %data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) next if ($data{$what}->{file} eq "File");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) foreach my $p (@{$data{$what}->{label_list}}) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) my ($content, $label) = @{$p};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) $label = "abi_" . $label . " ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) $label =~ tr/A-Z/a-z/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) # Convert special chars to "_"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) $label =~s/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xff])/_/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) $label =~ s,_+,_,g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) $label =~ s,_$,,;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) # Avoid duplicated labels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) while (defined($labels{$label})) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) my @chars = ("A".."Z", "a".."z");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) $label .= $chars[rand @chars];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) $labels{$label} = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) $data{$what}->{label} = $label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) # only one label is enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^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) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) # Outputs the book on ReST format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) # \b doesn't work well with paths. So, we need to define something else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) my $bondary = qr { (?<![\w\/\`\{])(?=[\w\/\`\{])|(?<=[\w\/\`\{])(?![\w\/\`\{]) }x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) sub output_rest {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) create_labels();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) my $part = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) foreach my $what (sort {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ($data{$a}->{type} eq "File") cmp ($data{$b}->{type} eq "File") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) $a cmp $b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) } keys %data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) my $type = $data{$what}->{type};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) my @file = split / /, $data{$what}->{file};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) my @filepath = split / /, $data{$what}->{filepath};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if ($enable_lineno) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) printf "#define LINENO %s%s#%s\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) $prefix, $file[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) $data{$what}->{line_no};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) my $w = $what;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) $w =~ s/([\(\)\_\-\*\=\^\~\\])/\\$1/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if ($type ne "File") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) my $cur_part = $what;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if ($what =~ '/') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if ($what =~ m#^(\/?(?:[\w\-]+\/?){1,2})#) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) $cur_part = "Symbols under $1";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) $cur_part =~ s,/$,,;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^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) if ($cur_part ne "" && $part ne $cur_part) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) $part = $cur_part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) my $bar = $part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) $bar =~ s/./-/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) print "$part\n$bar\n\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) printf ".. _%s:\n\n", $data{$what}->{label};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) my @names = split /, /,$w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) my $len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) foreach my $name (@names) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) $name = "**$name**";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) $len = length($name) if (length($name) > $len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) print "+-" . "-" x $len . "-+\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) foreach my $name (@names) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) printf "| %s", $name . " " x ($len - length($name)) . " |\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) print "+-" . "-" x $len . "-+\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) print "\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) for (my $i = 0; $i < scalar(@filepath); $i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) my $path = $filepath[$i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) my $f = $file[$i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) $path =~ s,.*/(.*/.*),$1,;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) $path =~ s,[/\-],_,g;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) my $fileref = "abi_file_".$path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if ($type eq "File") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) print ".. _$fileref:\n\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) print "Defined on file :ref:`$f <$fileref>`\n\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if ($type eq "File") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) my $bar = $w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) $bar =~ s/./-/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) print "$w\n$bar\n\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) my $desc = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) $desc = $data{$what}->{description} if (defined($data{$what}->{description}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) $desc =~ s/\s+$/\n/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (!($desc =~ /^\s*$/)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if ($description_is_rst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) # Remove title markups from the description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) # Having titles inside ABI files will only work if extra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) # care would be taken in order to strictly follow the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) # level order for each markup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) $desc =~ s/\n[\-\*\=\^\~]+\n/\n\n/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) # Enrich text by creating cross-references
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) $desc =~ s,Documentation/(?!devicetree)(\S+)\.rst,:doc:`/$1`,g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) my @matches = $desc =~ m,Documentation/ABI/([\w\/\-]+),;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) foreach my $f (@matches) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) my $xref = $f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) my $path = $f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) $path =~ s,.*/(.*/.*),$1,;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) $path =~ s,[/\-],_,g;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) $xref .= " <abi_file_" . $path . ">";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) $desc =~ s,\bDocumentation/ABI/$f\b,:ref:`$xref`,g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) @matches = $desc =~ m,$bondary(/sys/[^\s\.\,\;\:\*\s\`\'\(\)]+)$bondary,;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) foreach my $s (@matches) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (defined($data{$s}) && defined($data{$s}->{label})) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) my $xref = $s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) $xref =~ s/([\x00-\x1f\x21-\x2f\x3a-\x40\x7b-\xff])/\\$1/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) $xref = ":ref:`$xref <" . $data{$s}->{label} . ">`";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) $desc =~ s,$bondary$s$bondary,$xref,g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) print "$desc\n\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) $desc =~ s/^\s+//;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) # Remove title markups from the description, as they won't work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) $desc =~ s/\n[\-\*\=\^\~]+\n/\n\n/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if ($desc =~ m/\:\n/ || $desc =~ m/\n[\t ]+/ || $desc =~ m/[\x00-\x08\x0b-\x1f\x7b-\xff]/) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) # put everything inside a code block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) $desc =~ s/\n/\n /g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) print "::\n\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) print " $desc\n\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) # Escape any special chars from description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) $desc =~s/([\x00-\x08\x0b-\x1f\x21-\x2a\x2d\x2f\x3c-\x40\x5c\x5e-\x60\x7b-\xff])/\\$1/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) print "$desc\n\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) print "DESCRIPTION MISSING for $what\n\n" if (!$data{$what}->{is_file});
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if ($data{$what}->{symbols}) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) printf "Has the following ABI:\n\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) foreach my $content(@{$data{$what}->{symbols}}) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) my $label = $data{$symbols{$content}->{xref}}->{label};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) # Escape special chars from content
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) $content =~s/([\x00-\x1f\x21-\x2f\x3a-\x40\x7b-\xff])/\\$1/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) print "- :ref:`$content <$label>`\n\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (defined($data{$what}->{users})) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) my $users = $data{$what}->{users};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) $users =~ s/\n/\n\t/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) printf "Users:\n\t%s\n\n", $users if ($users ne "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) # Searches for ABI symbols
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) sub search_symbols {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) foreach my $what (sort keys %data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) next if (!($what =~ m/($arg)/));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) my $type = $data{$what}->{type};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) next if ($type eq "File");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) my $file = $data{$what}->{filepath};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) my $bar = $what;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) $bar =~ s/./-/g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) print "\n$what\n$bar\n\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) my $kernelversion = $data{$what}->{kernelversion} if (defined($data{$what}->{kernelversion}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) my $contact = $data{$what}->{contact} if (defined($data{$what}->{contact}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) my $users = $data{$what}->{users} if (defined($data{$what}->{users}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) my $date = $data{$what}->{date} if (defined($data{$what}->{date}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) my $desc = $data{$what}->{description} if (defined($data{$what}->{description}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) $kernelversion =~ s/^\s+// if ($kernelversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) $contact =~ s/^\s+// if ($contact);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if ($users) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) $users =~ s/^\s+//;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) $users =~ s/\n//g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) $date =~ s/^\s+// if ($date);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) $desc =~ s/^\s+// if ($desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) printf "Kernel version:\t\t%s\n", $kernelversion if ($kernelversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) printf "Date:\t\t\t%s\n", $date if ($date);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) printf "Contact:\t\t%s\n", $contact if ($contact);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) printf "Users:\t\t\t%s\n", $users if ($users);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) print "Defined on file(s):\t$file\n\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) print "Description:\n\n$desc";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) # Ensure that the prefix will always end with a slash
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) # While this is not needed for find, it makes the patch nicer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) # with --enable-lineno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) $prefix =~ s,/?$,/,;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) # Parses all ABI files located at $prefix dir
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) find({wanted =>\&parse_abi, no_chdir => 1}, $prefix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) print STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) # Handles the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if ($cmd eq "search") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) search_symbols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if ($cmd eq "rest") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) output_rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) # Warn about duplicated ABI entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) foreach my $what(sort keys %symbols) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) my @files = @{$symbols{$what}->{file}};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) next if (scalar(@files) == 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) printf STDERR "Warning: $what is defined %d times: @files\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) scalar(@files);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) __END__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) =head1 NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) abi_book.pl - parse the Linux ABI files and produce a ReST book.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) =head1 SYNOPSIS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) B<abi_book.pl> [--debug] [--enable-lineno] [--man] [--help]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) [--(no-)rst-source] [--dir=<dir>] <COMAND> [<ARGUMENT>]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) Where <COMMAND> can be:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) =over 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) B<search> [SEARCH_REGEX] - search for [SEARCH_REGEX] inside ABI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) B<rest> - output the ABI in ReST markup language
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) B<validate> - validate the ABI contents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) =back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) =head1 OPTIONS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) =over 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) =item B<--dir>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) Changes the location of the ABI search. By default, it uses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) the Documentation/ABI directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) =item B<--rst-source> and B<--no-rst-source>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) The input file may be using ReST syntax or not. Those two options allow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) selecting between a rst-compliant source ABI (--rst-source), or a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) plain text that may be violating ReST spec, so it requres some escaping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) logic (--no-rst-source).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) =item B<--enable-lineno>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) Enable output of #define LINENO lines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) =item B<--debug>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) Put the script in verbose mode, useful for debugging. Can be called multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) times, to increase verbosity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) =item B<--help>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) Prints a brief help message and exits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) =item B<--man>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) Prints the manual page and exits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) =back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) =head1 DESCRIPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) Parse the Linux ABI files from ABI DIR (usually located at Documentation/ABI),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) allowing to search for ABI symbols or to produce a ReST book containing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) the Linux ABI documentation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) =head1 EXAMPLES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) Search for all stable symbols with the word "usb":
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) =over 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) $ scripts/get_abi.pl search usb --dir Documentation/ABI/stable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) =back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) Search for all symbols that match the regex expression "usb.*cap":
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) =over 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) $ scripts/get_abi.pl search usb.*cap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) =back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) Output all obsoleted symbols in ReST format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) =over 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) $ scripts/get_abi.pl rest --dir Documentation/ABI/obsolete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) =back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) =head1 BUGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) Report bugs to Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) =head1 COPYRIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) Copyright (c) 2016-2019 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) License GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) This is free software: you are free to change and redistribute it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) There is NO WARRANTY, to the extent permitted by law.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) =cut