~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/get_abi.pl

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /scripts/get_abi.pl (Version linux-6.11.5) and /scripts/get_abi.pl (Version linux-5.14.21)


  1 #!/usr/bin/env perl                                 1 #!/usr/bin/env perl
  2 # SPDX-License-Identifier: GPL-2.0                  2 # SPDX-License-Identifier: GPL-2.0
  3                                                     3 
  4 BEGIN { $Pod::Usage::Formatter = 'Pod::Text::T << 
  5                                                << 
  6 use strict;                                         4 use strict;
  7 use warnings;                                       5 use warnings;
  8 use utf8;                                           6 use utf8;
  9 use Pod::Usage qw(pod2usage);                  !!   7 use Pod::Usage;
 10 use Getopt::Long;                                   8 use Getopt::Long;
 11 use File::Find;                                     9 use File::Find;
 12 use IO::Handle;                                << 
 13 use Fcntl ':mode';                                 10 use Fcntl ':mode';
 14 use Cwd 'abs_path';                            << 
 15 use Data::Dumper;                              << 
 16                                                    11 
 17 my $help = 0;                                      12 my $help = 0;
 18 my $hint = 0;                                  << 
 19 my $man = 0;                                       13 my $man = 0;
 20 my $debug = 0;                                     14 my $debug = 0;
 21 my $enable_lineno = 0;                             15 my $enable_lineno = 0;
 22 my $show_warnings = 1;                         << 
 23 my $prefix="Documentation/ABI";                    16 my $prefix="Documentation/ABI";
 24 my $sysfs_prefix="/sys";                       << 
 25 my $search_string;                             << 
 26                                                << 
 27 # Debug options                                << 
 28 my $dbg_what_parsing = 1;                      << 
 29 my $dbg_what_open = 2;                         << 
 30 my $dbg_dump_abi_structs = 4;                  << 
 31 my $dbg_undefined = 8;                         << 
 32                                                << 
 33 $Data::Dumper::Indent = 1;                     << 
 34 $Data::Dumper::Terse = 1;                      << 
 35                                                    17 
 36 #                                                  18 #
 37 # If true, assumes that the description is for     19 # If true, assumes that the description is formatted with ReST
 38 #                                                  20 #
 39 my $description_is_rst = 1;                        21 my $description_is_rst = 1;
 40                                                    22 
 41 GetOptions(                                        23 GetOptions(
 42         "debug=i" => \$debug,                  !!  24         "debug|d+" => \$debug,
 43         "enable-lineno" => \$enable_lineno,        25         "enable-lineno" => \$enable_lineno,
 44         "rst-source!" => \$description_is_rst,     26         "rst-source!" => \$description_is_rst,
 45         "dir=s" => \$prefix,                       27         "dir=s" => \$prefix,
 46         'help|?' => \$help,                        28         'help|?' => \$help,
 47         "show-hints" => \$hint,                << 
 48         "search-string=s" => \$search_string,  << 
 49         man => \$man                               29         man => \$man
 50 ) or pod2usage(2);                                 30 ) or pod2usage(2);
 51                                                    31 
 52 pod2usage(1) if $help;                             32 pod2usage(1) if $help;
 53 pod2usage(-exitstatus => 0, -noperldoc, -verbo !!  33 pod2usage(-exitstatus => 0, -verbose => 2) if $man;
 54                                                    34 
 55 pod2usage(2) if (scalar @ARGV < 1 || @ARGV > 2)     35 pod2usage(2) if (scalar @ARGV < 1 || @ARGV > 2);
 56                                                    36 
 57 my ($cmd, $arg) = @ARGV;                           37 my ($cmd, $arg) = @ARGV;
 58                                                    38 
 59 pod2usage(2) if ($cmd ne "search" && $cmd ne " !!  39 pod2usage(2) if ($cmd ne "search" && $cmd ne "rest" && $cmd ne "validate");
 60 pod2usage(2) if ($cmd eq "search" && !$arg);       40 pod2usage(2) if ($cmd eq "search" && !$arg);
 61                                                    41 
 62 require Data::Dumper if ($debug & $dbg_dump_ab !!  42 require Data::Dumper if ($debug);
 63                                                    43 
 64 my %data;                                          44 my %data;
 65 my %symbols;                                       45 my %symbols;
 66                                                    46 
 67 #                                                  47 #
 68 # Displays an error message, printing file nam     48 # Displays an error message, printing file name and line
 69 #                                                  49 #
 70 sub parse_error($$$$) {                            50 sub parse_error($$$$) {
 71         my ($file, $ln, $msg, $data) = @_;         51         my ($file, $ln, $msg, $data) = @_;
 72                                                    52 
 73         return if (!$show_warnings);           << 
 74                                                << 
 75         $data =~ s/\s+$/\n/;                       53         $data =~ s/\s+$/\n/;
 76                                                    54 
 77         print STDERR "Warning: file $file#$ln:     55         print STDERR "Warning: file $file#$ln:\n\t$msg";
 78                                                    56 
 79         if ($data ne "") {                         57         if ($data ne "") {
 80                 print STDERR ". Line\n\t\t$dat     58                 print STDERR ". Line\n\t\t$data";
 81         } else {                                   59         } else {
 82             print STDERR "\n";                     60             print STDERR "\n";
 83         }                                          61         }
 84 }                                                  62 }
 85                                                    63 
 86 #                                                  64 #
 87 # Parse an ABI file, storing its contents at %     65 # Parse an ABI file, storing its contents at %data
 88 #                                                  66 #
 89 sub parse_abi {                                    67 sub parse_abi {
 90         my $file = $File::Find::name;              68         my $file = $File::Find::name;
 91                                                    69 
 92         my $mode = (stat($file))[2];               70         my $mode = (stat($file))[2];
 93         return if ($mode & S_IFDIR);               71         return if ($mode & S_IFDIR);
 94         return if ($file =~ m,/README,);           72         return if ($file =~ m,/README,);
 95         return if ($file =~ m,/\.,);           << 
 96         return if ($file =~ m,\.(rej|org|orig| << 
 97                                                    73 
 98         my $name = $file;                          74         my $name = $file;
 99         $name =~ s,.*/,,;                          75         $name =~ s,.*/,,;
100                                                    76 
101         my $fn = $file;                            77         my $fn = $file;
102         $fn =~ s,.*Documentation/ABI/,,;       !!  78         $fn =~ s,Documentation/ABI/,,;
103                                                    79 
104         my $nametag = "File $fn";                  80         my $nametag = "File $fn";
105         $data{$nametag}->{what} = "File $name"     81         $data{$nametag}->{what} = "File $name";
106         $data{$nametag}->{type} = "File";          82         $data{$nametag}->{type} = "File";
107         $data{$nametag}->{file} = $name;           83         $data{$nametag}->{file} = $name;
108         $data{$nametag}->{filepath} = $file;       84         $data{$nametag}->{filepath} = $file;
109         $data{$nametag}->{is_file} = 1;            85         $data{$nametag}->{is_file} = 1;
110         $data{$nametag}->{line_no} = 1;            86         $data{$nametag}->{line_no} = 1;
111                                                    87 
112         my $type = $file;                          88         my $type = $file;
113         $type =~ s,.*/(.*)/.*,$1,;                 89         $type =~ s,.*/(.*)/.*,$1,;
114                                                    90 
115         my $what;                                  91         my $what;
116         my $new_what;                              92         my $new_what;
117         my $tag = "";                              93         my $tag = "";
118         my $ln;                                    94         my $ln;
119         my $xrefs;                                 95         my $xrefs;
120         my $space;                                 96         my $space;
121         my @labels;                                97         my @labels;
122         my $label = "";                            98         my $label = "";
123                                                    99 
124         print STDERR "Opening $file\n" if ($de !! 100         print STDERR "Opening $file\n" if ($debug > 1);
125         open IN, $file;                           101         open IN, $file;
126         while(<IN>) {                             102         while(<IN>) {
127                 $ln++;                            103                 $ln++;
128                 if (m/^(\S+)(:\s*)(.*)/i) {       104                 if (m/^(\S+)(:\s*)(.*)/i) {
129                         my $new_tag = lc($1);     105                         my $new_tag = lc($1);
130                         my $sep = $2;             106                         my $sep = $2;
131                         my $content = $3;         107                         my $content = $3;
132                                                   108 
133                         if (!($new_tag =~ m/(w    109                         if (!($new_tag =~ m/(what|where|date|kernelversion|contact|description|users)/)) {
134                                 if ($tag eq "d    110                                 if ($tag eq "description") {
135                                         # New     111                                         # New "tag" is actually part of
136                                         # desc    112                                         # description. Don't consider it a tag
137                                         $new_t    113                                         $new_tag = "";
138                                 } elsif ($tag     114                                 } elsif ($tag ne "") {
139                                         parse_    115                                         parse_error($file, $ln, "tag '$tag' is invalid", $_);
140                                 }                 116                                 }
141                         }                         117                         }
142                                                   118 
143                         # Invalid, but it is a    119                         # Invalid, but it is a common mistake
144                         if ($new_tag eq "where    120                         if ($new_tag eq "where") {
145                                 parse_error($f    121                                 parse_error($file, $ln, "tag 'Where' is invalid. Should be 'What:' instead", "");
146                                 $new_tag = "wh    122                                 $new_tag = "what";
147                         }                         123                         }
148                                                   124 
149                         if ($new_tag =~ m/what    125                         if ($new_tag =~ m/what/) {
150                                 $space = "";      126                                 $space = "";
151                                 $content =~ s/    127                                 $content =~ s/[,.;]$//;
152                                                   128 
153                                 push @{$symbol    129                                 push @{$symbols{$content}->{file}}, " $file:" . ($ln - 1);
154                                                   130 
155                                 if ($tag =~ m/    131                                 if ($tag =~ m/what/) {
156                                         $what  !! 132                                         $what .= ", " . $content;
157                                 } else {          133                                 } else {
158                                         if ($w    134                                         if ($what) {
159                                                   135                                                 parse_error($file, $ln, "What '$what' doesn't have a description", "") if (!$data{$what}->{description});
160                                                   136 
161                                                !! 137                                                 foreach my $w(split /, /, $what) {
162                                                   138                                                         $symbols{$w}->{xref} = $what;
163                                                   139                                                 };
164                                         }         140                                         }
165                                                   141 
166                                         $what     142                                         $what = $content;
167                                         $label    143                                         $label = $content;
168                                         $new_w    144                                         $new_what = 1;
169                                 }                 145                                 }
170                                 push @labels,     146                                 push @labels, [($content, $label)];
171                                 $tag = $new_ta    147                                 $tag = $new_tag;
172                                                   148 
173                                 push @{$data{$    149                                 push @{$data{$nametag}->{symbols}}, $content if ($data{$nametag}->{what});
174                                 next;             150                                 next;
175                         }                         151                         }
176                                                   152 
177                         if ($tag ne "" && $new    153                         if ($tag ne "" && $new_tag) {
178                                 $tag = $new_ta    154                                 $tag = $new_tag;
179                                                   155 
180                                 if ($new_what)    156                                 if ($new_what) {
181                                         @{$dat    157                                         @{$data{$what}->{label_list}} = @labels if ($data{$nametag}->{what});
182                                         @label    158                                         @labels = ();
183                                         $label    159                                         $label = "";
184                                         $new_w    160                                         $new_what = 0;
185                                                   161 
186                                         $data{    162                                         $data{$what}->{type} = $type;
187                                         if (!d    163                                         if (!defined($data{$what}->{file})) {
188                                                   164                                                 $data{$what}->{file} = $name;
189                                                   165                                                 $data{$what}->{filepath} = $file;
190                                         } else    166                                         } else {
191                                                << 
192                                                   167                                                 if ($name ne $data{$what}->{file}) {
193                                                   168                                                         $data{$what}->{file} .= " " . $name;
194                                                   169                                                         $data{$what}->{filepath} .= " " . $file;
195                                                   170                                                 }
196                                         }         171                                         }
197                                         print  !! 172                                         print STDERR "\twhat: $what\n" if ($debug > 1);
198                                         $data{    173                                         $data{$what}->{line_no} = $ln;
199                                 } else {          174                                 } else {
200                                         $data{    175                                         $data{$what}->{line_no} = $ln if (!defined($data{$what}->{line_no}));
201                                 }                 176                                 }
202                                                   177 
203                                 if (!$what) {     178                                 if (!$what) {
204                                         parse_    179                                         parse_error($file, $ln, "'What:' should come first:", $_);
205                                         next;     180                                         next;
206                                 }                 181                                 }
207                                 if ($new_tag e    182                                 if ($new_tag eq "description") {
208                                         $sep =    183                                         $sep =~ s,:, ,;
209                                         $conte    184                                         $content = ' ' x length($new_tag) . $sep . $content;
210                                         while     185                                         while ($content =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}
211                                         if ($c    186                                         if ($content =~ m/^(\s*)(\S.*)$/) {
212                                                   187                                                 # Preserve initial spaces for the first line
213                                                   188                                                 $space = $1;
214                                                   189                                                 $content = "$2\n";
215                                                   190                                                 $data{$what}->{$tag} .= $content;
216                                         } else    191                                         } else {
217                                                   192                                                 undef($space);
218                                         }         193                                         }
219                                                   194 
220                                 } else {          195                                 } else {
221                                         $data{    196                                         $data{$what}->{$tag} = $content;
222                                 }                 197                                 }
223                                 next;             198                                 next;
224                         }                         199                         }
225                 }                                 200                 }
226                                                   201 
227                 # Store any contents before ta    202                 # Store any contents before tags at the database
228                 if (!$tag && $data{$nametag}->    203                 if (!$tag && $data{$nametag}->{what}) {
229                         $data{$nametag}->{desc    204                         $data{$nametag}->{description} .= $_;
230                         next;                     205                         next;
231                 }                                 206                 }
232                                                   207 
233                 if ($tag eq "description") {      208                 if ($tag eq "description") {
234                         my $content = $_;         209                         my $content = $_;
235                         while ($content =~ s/\    210                         while ($content =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}
236                         if (m/^\s*\n/) {          211                         if (m/^\s*\n/) {
237                                 $data{$what}->    212                                 $data{$what}->{$tag} .= "\n";
238                                 next;             213                                 next;
239                         }                         214                         }
240                                                   215 
241                         if (!defined($space))     216                         if (!defined($space)) {
242                                 # Preserve ini    217                                 # Preserve initial spaces for the first line
243                                 if ($content =    218                                 if ($content =~ m/^(\s*)(\S.*)$/) {
244                                         $space    219                                         $space = $1;
245                                         $conte    220                                         $content = "$2\n";
246                                 }                 221                                 }
247                         } else {                  222                         } else {
248                                 $space = "" if    223                                 $space = "" if (!($content =~ s/^($space)//));
249                         }                         224                         }
250                         $data{$what}->{$tag} .    225                         $data{$what}->{$tag} .= $content;
251                                                   226 
252                         next;                     227                         next;
253                 }                                 228                 }
254                 if (m/^\s*(.*)/) {                229                 if (m/^\s*(.*)/) {
255                         $data{$what}->{$tag} .    230                         $data{$what}->{$tag} .= "\n$1";
256                         $data{$what}->{$tag} =    231                         $data{$what}->{$tag} =~ s/\n+$//;
257                         next;                     232                         next;
258                 }                                 233                 }
259                                                   234 
260                 # Everything else is error        235                 # Everything else is error
261                 parse_error($file, $ln, "Unexp    236                 parse_error($file, $ln, "Unexpected content", $_);
262         }                                         237         }
263         $data{$nametag}->{description} =~ s/^\    238         $data{$nametag}->{description} =~ s/^\n+// if ($data{$nametag}->{description});
264         if ($what) {                              239         if ($what) {
265                 parse_error($file, $ln, "What     240                 parse_error($file, $ln, "What '$what' doesn't have a description", "") if (!$data{$what}->{description});
266                                                   241 
267                 foreach my $w(split /\xac/,$wh !! 242                 foreach my $w(split /, /,$what) {
268                         $symbols{$w}->{xref} =    243                         $symbols{$w}->{xref} = $what;
269                 };                                244                 };
270         }                                         245         }
271         close IN;                                 246         close IN;
272 }                                                 247 }
273                                                   248 
274 sub create_labels {                               249 sub create_labels {
275         my %labels;                               250         my %labels;
276                                                   251 
277         foreach my $what (keys %data) {           252         foreach my $what (keys %data) {
278                 next if ($data{$what}->{file}     253                 next if ($data{$what}->{file} eq "File");
279                                                   254 
280                 foreach my $p (@{$data{$what}-    255                 foreach my $p (@{$data{$what}->{label_list}}) {
281                         my ($content, $label)     256                         my ($content, $label) = @{$p};
282                         $label = "abi_" . $lab    257                         $label = "abi_" . $label . " ";
283                         $label =~ tr/A-Z/a-z/;    258                         $label =~ tr/A-Z/a-z/;
284                                                   259 
285                         # Convert special char    260                         # Convert special chars to "_"
286                         $label =~s/([\x00-\x2f    261                         $label =~s/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xff])/_/g;
287                         $label =~ s,_+,_,g;       262                         $label =~ s,_+,_,g;
288                         $label =~ s,_$,,;         263                         $label =~ s,_$,,;
289                                                   264 
290                         # Avoid duplicated lab    265                         # Avoid duplicated labels
291                         while (defined($labels    266                         while (defined($labels{$label})) {
292                             my @chars = ("A"..    267                             my @chars = ("A".."Z", "a".."z");
293                             $label .= $chars[r    268                             $label .= $chars[rand @chars];
294                         }                         269                         }
295                         $labels{$label} = 1;      270                         $labels{$label} = 1;
296                                                   271 
297                         $data{$what}->{label}     272                         $data{$what}->{label} = $label;
298                                                   273 
299                         # only one label is en    274                         # only one label is enough
300                         last;                     275                         last;
301                 }                                 276                 }
302         }                                         277         }
303 }                                                 278 }
304                                                   279 
305 #                                                 280 #
306 # Outputs the book on ReST format                 281 # Outputs the book on ReST format
307 #                                                 282 #
308                                                   283 
309 # \b doesn't work well with paths. So, we need    284 # \b doesn't work well with paths. So, we need to define something else:
310 # Boundaries are punct characters, spaces and     285 # Boundaries are punct characters, spaces and end-of-line
311 my $start = qr {(^|\s|\() }x;                     286 my $start = qr {(^|\s|\() }x;
312 my $bondary = qr { ([,.:;\)\s]|\z) }x;            287 my $bondary = qr { ([,.:;\)\s]|\z) }x;
313 my $xref_match = qr { $start(\/(sys|config|pro    288 my $xref_match = qr { $start(\/(sys|config|proc|dev|kvd)\/[^,.:;\)\s]+)$bondary }x;
314 my $symbols = qr { ([\x01-\x08\x0e-\x1f\x21-\x    289 my $symbols = qr { ([\x01-\x08\x0e-\x1f\x21-\x2f\x3a-\x40\x7b-\xff]) }x;
315                                                   290 
316 sub output_rest {                                 291 sub output_rest {
317         create_labels();                          292         create_labels();
318                                                   293 
319         my $part = "";                            294         my $part = "";
320                                                   295 
321         foreach my $what (sort {                  296         foreach my $what (sort {
322                                 ($data{$a}->{t    297                                 ($data{$a}->{type} eq "File") cmp ($data{$b}->{type} eq "File") ||
323                                 $a cmp $b         298                                 $a cmp $b
324                                } keys %data) {    299                                } keys %data) {
325                 my $type = $data{$what}->{type    300                 my $type = $data{$what}->{type};
326                                                   301 
327                 my @file = split / /, $data{$w    302                 my @file = split / /, $data{$what}->{file};
328                 my @filepath = split / /, $dat    303                 my @filepath = split / /, $data{$what}->{filepath};
329                                                   304 
330                 if ($enable_lineno) {             305                 if ($enable_lineno) {
331                         printf ".. LINENO %s%s !! 306                         printf "#define LINENO %s%s#%s\n\n",
332                                $prefix, $file[    307                                $prefix, $file[0],
333                                $data{$what}->{    308                                $data{$what}->{line_no};
334                 }                                 309                 }
335                                                   310 
336                 my $w = $what;                    311                 my $w = $what;
337                                                   312 
338                 if ($type ne "File") {            313                 if ($type ne "File") {
339                         my $cur_part = $what;     314                         my $cur_part = $what;
340                         if ($what =~ '/') {       315                         if ($what =~ '/') {
341                                 if ($what =~ m    316                                 if ($what =~ m#^(\/?(?:[\w\-]+\/?){1,2})#) {
342                                         $cur_p    317                                         $cur_part = "Symbols under $1";
343                                         $cur_p    318                                         $cur_part =~ s,/$,,;
344                                 }                 319                                 }
345                         }                         320                         }
346                                                   321 
347                         if ($cur_part ne "" &&    322                         if ($cur_part ne "" && $part ne $cur_part) {
348                             $part = $cur_part;    323                             $part = $cur_part;
349                             my $bar = $part;      324                             my $bar = $part;
350                             $bar =~ s/./-/g;      325                             $bar =~ s/./-/g;
351                             print "$part\n$bar    326                             print "$part\n$bar\n\n";
352                         }                         327                         }
353                                                   328 
354                         printf ".. _%s:\n\n",     329                         printf ".. _%s:\n\n", $data{$what}->{label};
355                                                   330 
356                         my @names = split /\xa !! 331                         my @names = split /, /,$w;
357                         my $len = 0;              332                         my $len = 0;
358                                                   333 
359                         foreach my $name (@nam    334                         foreach my $name (@names) {
360                                 $name =~ s/$sy    335                                 $name =~ s/$symbols/\\$1/g;
361                                 $name = "**$na    336                                 $name = "**$name**";
362                                 $len = length(    337                                 $len = length($name) if (length($name) > $len);
363                         }                         338                         }
364                                                   339 
365                         print "+-" . "-" x $le    340                         print "+-" . "-" x $len . "-+\n";
366                         foreach my $name (@nam    341                         foreach my $name (@names) {
367                                 printf "| %s",    342                                 printf "| %s", $name . " " x ($len - length($name)) . " |\n";
368                                 print "+-" . "    343                                 print "+-" . "-" x $len . "-+\n";
369                         }                         344                         }
370                                                   345 
371                         print "\n";               346                         print "\n";
372                 }                                 347                 }
373                                                   348 
374                 for (my $i = 0; $i < scalar(@f    349                 for (my $i = 0; $i < scalar(@filepath); $i++) {
375                         my $path = $filepath[$    350                         my $path = $filepath[$i];
376                         my $f = $file[$i];        351                         my $f = $file[$i];
377                                                   352 
378                         $path =~ s,.*/(.*/.*),    353                         $path =~ s,.*/(.*/.*),$1,;;
379                         $path =~ s,[/\-],_,g;;    354                         $path =~ s,[/\-],_,g;;
380                         my $fileref = "abi_fil    355                         my $fileref = "abi_file_".$path;
381                                                   356 
382                         if ($type eq "File") {    357                         if ($type eq "File") {
383                                 print ".. _$fi    358                                 print ".. _$fileref:\n\n";
384                         } else {                  359                         } else {
385                                 print "Defined    360                                 print "Defined on file :ref:`$f <$fileref>`\n\n";
386                         }                         361                         }
387                 }                                 362                 }
388                                                   363 
389                 if ($type eq "File") {            364                 if ($type eq "File") {
390                         my $bar = $w;             365                         my $bar = $w;
391                         $bar =~ s/./-/g;          366                         $bar =~ s/./-/g;
392                         print "$w\n$bar\n\n";     367                         print "$w\n$bar\n\n";
393                 }                                 368                 }
394                                                   369 
395                 my $desc = "";                    370                 my $desc = "";
396                 $desc = $data{$what}->{descrip    371                 $desc = $data{$what}->{description} if (defined($data{$what}->{description}));
397                 $desc =~ s/\s+$/\n/;              372                 $desc =~ s/\s+$/\n/;
398                                                   373 
399                 if (!($desc =~ /^\s*$/)) {        374                 if (!($desc =~ /^\s*$/)) {
400                         if ($description_is_rs    375                         if ($description_is_rst) {
401                                 # Remove title    376                                 # Remove title markups from the description
402                                 # Having title    377                                 # Having titles inside ABI files will only work if extra
403                                 # care would b    378                                 # care would be taken in order to strictly follow the same
404                                 # level order     379                                 # level order for each markup.
405                                 $desc =~ s/\n[    380                                 $desc =~ s/\n[\-\*\=\^\~]+\n/\n\n/g;
406                                                   381 
407                                 # Enrich text     382                                 # Enrich text by creating cross-references
408                                                   383 
409                                 my $new_desc =    384                                 my $new_desc = "";
410                                 my $init_inden    385                                 my $init_indent = -1;
411                                 my $literal_in    386                                 my $literal_indent = -1;
412                                                   387 
413                                 open(my $fh, "    388                                 open(my $fh, "+<", \$desc);
414                                 while (my $d =    389                                 while (my $d = <$fh>) {
415                                         my $in    390                                         my $indent = $d =~ m/^(\s+)/;
416                                         my $sp    391                                         my $spaces = length($indent);
417                                         $init_    392                                         $init_indent = $indent if ($init_indent < 0);
418                                         if ($l    393                                         if ($literal_indent >= 0) {
419                                                   394                                                 if ($spaces > $literal_indent) {
420                                                   395                                                         $new_desc .= $d;
421                                                   396                                                         next;
422                                                   397                                                 } else {
423                                                   398                                                         $literal_indent = -1;
424                                                   399                                                 }
425                                         } else    400                                         } else {
426                                                   401                                                 if ($d =~ /()::$/ && !($d =~ /^\s*\.\./)) {
427                                                   402                                                         $literal_indent = $spaces;
428                                                   403                                                 }
429                                         }         404                                         }
430                                                   405 
431                                         $d =~     406                                         $d =~ s,Documentation/(?!devicetree)(\S+)\.rst,:doc:`/$1`,g;
432                                                   407 
433                                         my @ma    408                                         my @matches = $d =~ m,Documentation/ABI/([\w\/\-]+),g;
434                                         foreac    409                                         foreach my $f (@matches) {
435                                                   410                                                 my $xref = $f;
436                                                   411                                                 my $path = $f;
437                                                   412                                                 $path =~ s,.*/(.*/.*),$1,;;
438                                                   413                                                 $path =~ s,[/\-],_,g;;
439                                                   414                                                 $xref .= " <abi_file_" . $path . ">";
440                                                   415                                                 $d =~ s,\bDocumentation/ABI/$f\b,:ref:`$xref`,g;
441                                         }         416                                         }
442                                                   417 
443                                         # Seek    418                                         # Seek for cross reference symbols like /sys/...
444                                         @match    419                                         @matches = $d =~ m/$xref_match/g;
445                                                   420 
446                                         foreac    421                                         foreach my $s (@matches) {
447                                                   422                                                 next if (!($s =~ m,/,));
448                                                   423                                                 if (defined($data{$s}) && defined($data{$s}->{label})) {
449                                                   424                                                         my $xref = $s;
450                                                   425 
451                                                   426                                                         $xref =~ s/$symbols/\\$1/g;
452                                                   427                                                         $xref = ":ref:`$xref <" . $data{$s}->{label} . ">`";
453                                                   428 
454                                                   429                                                         $d =~ s,$start$s$bondary,$1$xref$2,g;
455                                                   430                                                 }
456                                         }         431                                         }
457                                         $new_d    432                                         $new_desc .= $d;
458                                 }                 433                                 }
459                                 close $fh;        434                                 close $fh;
460                                                   435 
461                                                   436 
462                                 print "$new_de    437                                 print "$new_desc\n\n";
463                         } else {                  438                         } else {
464                                 $desc =~ s/^\s    439                                 $desc =~ s/^\s+//;
465                                                   440 
466                                 # Remove title    441                                 # Remove title markups from the description, as they won't work
467                                 $desc =~ s/\n[    442                                 $desc =~ s/\n[\-\*\=\^\~]+\n/\n\n/g;
468                                                   443 
469                                 if ($desc =~ m    444                                 if ($desc =~ m/\:\n/ || $desc =~ m/\n[\t ]+/  || $desc =~ m/[\x00-\x08\x0b-\x1f\x7b-\xff]/) {
470                                         # put     445                                         # put everything inside a code block
471                                         $desc     446                                         $desc =~ s/\n/\n /g;
472                                                   447 
473                                         print     448                                         print "::\n\n";
474                                         print     449                                         print " $desc\n\n";
475                                 } else {          450                                 } else {
476                                         # Esca    451                                         # Escape any special chars from description
477                                         $desc     452                                         $desc =~s/([\x00-\x08\x0b-\x1f\x21-\x2a\x2d\x2f\x3c-\x40\x5c\x5e-\x60\x7b-\xff])/\\$1/g;
478                                         print     453                                         print "$desc\n\n";
479                                 }                 454                                 }
480                         }                         455                         }
481                 } else {                          456                 } else {
482                         print "DESCRIPTION MIS    457                         print "DESCRIPTION MISSING for $what\n\n" if (!$data{$what}->{is_file});
483                 }                                 458                 }
484                                                   459 
485                 if ($data{$what}->{symbols}) {    460                 if ($data{$what}->{symbols}) {
486                         printf "Has the follow    461                         printf "Has the following ABI:\n\n";
487                                                   462 
488                         foreach my $content(@{    463                         foreach my $content(@{$data{$what}->{symbols}}) {
489                                 my $label = $d    464                                 my $label = $data{$symbols{$content}->{xref}}->{label};
490                                                   465 
491                                 # Escape speci    466                                 # Escape special chars from content
492                                 $content =~s/(    467                                 $content =~s/([\x00-\x1f\x21-\x2f\x3a-\x40\x7b-\xff])/\\$1/g;
493                                                   468 
494                                 print "- :ref:    469                                 print "- :ref:`$content <$label>`\n\n";
495                         }                         470                         }
496                 }                                 471                 }
497                                                   472 
498                 if (defined($data{$what}->{use    473                 if (defined($data{$what}->{users})) {
499                         my $users = $data{$wha    474                         my $users = $data{$what}->{users};
500                                                   475 
501                         $users =~ s/\n/\n\t/g;    476                         $users =~ s/\n/\n\t/g;
502                         printf "Users:\n\t%s\n    477                         printf "Users:\n\t%s\n\n", $users if ($users ne "");
503                 }                                 478                 }
504                                                   479 
505         }                                         480         }
506 }                                                 481 }
507                                                   482 
508 #                                                 483 #
509 # Searches for ABI symbols                        484 # Searches for ABI symbols
510 #                                                 485 #
511 sub search_symbols {                              486 sub search_symbols {
512         foreach my $what (sort keys %data) {      487         foreach my $what (sort keys %data) {
513                 next if (!($what =~ m/($arg)/)    488                 next if (!($what =~ m/($arg)/));
514                                                   489 
515                 my $type = $data{$what}->{type    490                 my $type = $data{$what}->{type};
516                 next if ($type eq "File");        491                 next if ($type eq "File");
517                                                   492 
518                 my $file = $data{$what}->{file    493                 my $file = $data{$what}->{filepath};
519                                                   494 
520                 $what =~ s/\xac/, /g;          << 
521                 my $bar = $what;                  495                 my $bar = $what;
522                 $bar =~ s/./-/g;                  496                 $bar =~ s/./-/g;
523                                                   497 
524                 print "\n$what\n$bar\n\n";        498                 print "\n$what\n$bar\n\n";
525                                                   499 
526                 my $kernelversion = $data{$wha    500                 my $kernelversion = $data{$what}->{kernelversion} if (defined($data{$what}->{kernelversion}));
527                 my $contact = $data{$what}->{c    501                 my $contact = $data{$what}->{contact} if (defined($data{$what}->{contact}));
528                 my $users = $data{$what}->{use    502                 my $users = $data{$what}->{users} if (defined($data{$what}->{users}));
529                 my $date = $data{$what}->{date    503                 my $date = $data{$what}->{date} if (defined($data{$what}->{date}));
530                 my $desc = $data{$what}->{desc    504                 my $desc = $data{$what}->{description} if (defined($data{$what}->{description}));
531                                                   505 
532                 $kernelversion =~ s/^\s+// if     506                 $kernelversion =~ s/^\s+// if ($kernelversion);
533                 $contact =~ s/^\s+// if ($cont    507                 $contact =~ s/^\s+// if ($contact);
534                 if ($users) {                     508                 if ($users) {
535                         $users =~ s/^\s+//;       509                         $users =~ s/^\s+//;
536                         $users =~ s/\n//g;        510                         $users =~ s/\n//g;
537                 }                                 511                 }
538                 $date =~ s/^\s+// if ($date);     512                 $date =~ s/^\s+// if ($date);
539                 $desc =~ s/^\s+// if ($desc);     513                 $desc =~ s/^\s+// if ($desc);
540                                                   514 
541                 printf "Kernel version:\t\t%s\    515                 printf "Kernel version:\t\t%s\n", $kernelversion if ($kernelversion);
542                 printf "Date:\t\t\t%s\n", $dat    516                 printf "Date:\t\t\t%s\n", $date if ($date);
543                 printf "Contact:\t\t%s\n", $co    517                 printf "Contact:\t\t%s\n", $contact if ($contact);
544                 printf "Users:\t\t\t%s\n", $us    518                 printf "Users:\t\t\t%s\n", $users if ($users);
545                 print "Defined on file(s):\t$f    519                 print "Defined on file(s):\t$file\n\n";
546                 print "Description:\n\n$desc";    520                 print "Description:\n\n$desc";
547         }                                         521         }
548 }                                                 522 }
549                                                   523 
550 # Exclude /sys/kernel/debug and /sys/kernel/tr << 
551 sub dont_parse_special_attributes {            << 
552         if (($File::Find::dir =~ m,^/sys/kerne << 
553                 return grep {!/(debug|tracing) << 
554         }                                      << 
555                                                << 
556         if (($File::Find::dir =~ m,^/sys/fs,)) << 
557                 return grep {!/(pstore|bpf|fus << 
558         }                                      << 
559                                                << 
560         return @_                              << 
561 }                                              << 
562                                                << 
563 my %leaf;                                      << 
564 my %aliases;                                   << 
565 my @files;                                     << 
566 my %root;                                      << 
567                                                << 
568 sub graph_add_file {                           << 
569         my $file = shift;                      << 
570         my $type = shift;                      << 
571                                                << 
572         my $dir = $file;                       << 
573         $dir =~ s,^(.*/).*,$1,;                << 
574         $file =~ s,.*/,,;                      << 
575                                                << 
576         my $name;                              << 
577         my $file_ref = \%root;                 << 
578         foreach my $edge(split "/", $dir) {    << 
579                 $name .= "$edge/";             << 
580                 if (!defined ${$file_ref}{$edg << 
581                         ${$file_ref}{$edge} =  << 
582                 }                              << 
583                 $file_ref = \%{$$file_ref{$edg << 
584                 ${$file_ref}{"__name"} = [ $na << 
585         }                                      << 
586         $name .= "$file";                      << 
587         ${$file_ref}{$file} = {                << 
588                 "__name" => [ $name ]          << 
589         };                                     << 
590                                                << 
591         return \%{$$file_ref{$file}};          << 
592 }                                              << 
593                                                << 
594 sub graph_add_link {                           << 
595         my $file = shift;                      << 
596         my $link = shift;                      << 
597                                                << 
598         # Traverse graph to find the reference << 
599         my $file_ref = \%root;                 << 
600         foreach my $edge(split "/", $file) {   << 
601                 $file_ref = \%{$$file_ref{$edg << 
602         }                                      << 
603                                                << 
604         # do a BFS                             << 
605                                                << 
606         my @queue;                             << 
607         my %seen;                              << 
608         my $st;                                << 
609                                                << 
610         push @queue, $file_ref;                << 
611         $seen{$start}++;                       << 
612                                                << 
613         while (@queue) {                       << 
614                 my $v = shift @queue;          << 
615                 my @child = keys(%{$v});       << 
616                                                << 
617                 foreach my $c(@child) {        << 
618                         next if $seen{$$v{$c}} << 
619                         next if ($c eq "__name << 
620                                                << 
621                         if (!defined($$v{$c}{" << 
622                                 printf STDERR  << 
623                                 print STDERR D << 
624                                 exit;          << 
625                         }                      << 
626                                                << 
627                         # Add new name         << 
628                         my $name = @{$$v{$c}{" << 
629                         if ($name =~ s#^$file/ << 
630                                 push @{$$v{$c} << 
631                         }                      << 
632                         # Add child to the que << 
633                         push @queue, $$v{$c};  << 
634                         $seen{$c}++;           << 
635                 }                              << 
636         }                                      << 
637 }                                              << 
638                                                << 
639 my $escape_symbols = qr { ([\x01-\x08\x0e-\x1f << 
640 sub parse_existing_sysfs {                     << 
641         my $file = $File::Find::name;          << 
642                                                << 
643         my $mode = (lstat($file))[2];          << 
644         my $abs_file = abs_path($file);        << 
645                                                << 
646         my @tmp;                               << 
647         push @tmp, $file;                      << 
648         push @tmp, $abs_file if ($abs_file ne  << 
649                                                << 
650         foreach my $f(@tmp) {                  << 
651                 # Ignore cgroup, as this is bi << 
652                 return if ($f =~ m#^/sys/fs/cg << 
653                                                << 
654                 # Ignore firmware as it is doc << 
655                 # Either ACPI or under Documen << 
656                 return if ($f =~ m#^/sys/firmw << 
657                                                << 
658                 # Ignore some sysfs nodes that << 
659                 return if ($f =~ m#/sections|n << 
660                                                << 
661                 # Would need to check at       << 
662                 # Documentation/admin-guide/ke << 
663                 # is not easily parseable.     << 
664                 return if ($f =~ m#/parameters << 
665         }                                      << 
666                                                << 
667         if (S_ISLNK($mode)) {                  << 
668                 $aliases{$file} = $abs_file;   << 
669                 return;                        << 
670         }                                      << 
671                                                << 
672         return if (S_ISDIR($mode));            << 
673                                                << 
674         # Trivial: file is defined exactly the << 
675         return if (defined($data{$file}));     << 
676         return if (defined($data{$abs_file})); << 
677                                                << 
678         push @files, graph_add_file($abs_file, << 
679 }                                              << 
680                                                << 
681 sub get_leave($)                               << 
682 {                                              << 
683         my $what = shift;                      << 
684         my $leave;                             << 
685                                                << 
686         my $l = $what;                         << 
687         my $stop = 1;                          << 
688                                                << 
689         $leave = $l;                           << 
690         $leave =~ s,/$,,;                      << 
691         $leave =~ s,.*/,,;                     << 
692         $leave =~ s/[\(\)]//g;                 << 
693                                                << 
694         # $leave is used to improve search per << 
695         # check_undefined_symbols, as the algo << 
696         # for a small number of "what". It als << 
697         # hint about a leave with the same nam << 
698         # However, there are a few occurences  << 
699         # either a wildcard or a number. Just  << 
700         # altogether.                          << 
701         if ($leave =~ m/\.\*/ || $leave eq ""  << 
702                 $leave = "others";             << 
703         }                                      << 
704                                                << 
705         return $leave;                         << 
706 }                                              << 
707                                                << 
708 my @not_found;                                 << 
709                                                << 
710 sub check_file($$)                             << 
711 {                                              << 
712         my $file_ref = shift;                  << 
713         my $names_ref = shift;                 << 
714         my @names = @{$names_ref};             << 
715         my $file = $names[0];                  << 
716                                                << 
717         my $found_string;                      << 
718                                                << 
719         my $leave = get_leave($file);          << 
720         if (!defined($leaf{$leave})) {         << 
721                 $leave = "others";             << 
722         }                                      << 
723         my @expr = @{$leaf{$leave}->{expr}};   << 
724         die ("\rmissing rules for $leave") if  << 
725                                                << 
726         my $path = $file;                      << 
727         $path =~ s,(.*/).*,$1,;                << 
728                                                << 
729         if ($search_string) {                  << 
730                 return if (!($file =~ m#$searc << 
731                 $found_string = 1;             << 
732         }                                      << 
733                                                << 
734         for (my $i = 0; $i < @names; $i++) {   << 
735                 if ($found_string && $hint) {  << 
736                         if (!$i) {             << 
737                                 print STDERR " << 
738                         } else {               << 
739                                 print STDERR " << 
740                         }                      << 
741                 }                              << 
742                 foreach my $re (@expr) {       << 
743                         print STDERR "$names[$ << 
744                         if ($names[$i] =~ $re) << 
745                                 return;        << 
746                         }                      << 
747                 }                              << 
748         }                                      << 
749                                                << 
750         if ($leave ne "others") {              << 
751                 my @expr = @{$leaf{"others"}-> << 
752                 for (my $i = 0; $i < @names; $ << 
753                         foreach my $re (@expr) << 
754                                 print STDERR " << 
755                                 if ($names[$i] << 
756                                         return << 
757                                 }              << 
758                         }                      << 
759                 }                              << 
760         }                                      << 
761                                                << 
762         push @not_found, $file if (!$search_st << 
763                                                << 
764         if ($hint && (!$search_string || $foun << 
765                 my $what = $leaf{$leave}->{wha << 
766                 $what =~ s/\xac/\n\t/g;        << 
767                 if ($leave ne "others") {      << 
768                         print STDERR "\r    mo << 
769                 } else {                       << 
770                         print STDERR "\r    te << 
771                 }                              << 
772         }                                      << 
773 }                                              << 
774                                                << 
775 sub check_undefined_symbols {                  << 
776         my $num_files = scalar @files;         << 
777         my $next_i = 0;                        << 
778         my $start_time = times;                << 
779                                                << 
780         @files = sort @files;                  << 
781                                                << 
782         my $last_time = $start_time;           << 
783                                                << 
784         # When either debug or hint is enabled << 
785         # progress, as the progress will be ov << 
786         if ($hint || ($debug && $dbg_undefined << 
787                 $next_i = $num_files;          << 
788         }                                      << 
789                                                << 
790         my $is_console;                        << 
791         $is_console = 1 if (-t STDERR);        << 
792                                                << 
793         for (my $i = 0; $i < $num_files; $i++) << 
794                 my $file_ref = $files[$i];     << 
795                 my @names = @{$$file_ref{"__na << 
796                                                << 
797                 check_file($file_ref, \@names) << 
798                                                << 
799                 my $cur_time = times;          << 
800                                                << 
801                 if ($i == $next_i || $cur_time << 
802                         my $percent = $i * 100 << 
803                                                << 
804                         my $tm = $cur_time - $ << 
805                         my $time = sprintf "%d << 
806                                                << 
807                         printf STDERR "\33[2K\ << 
808                         printf STDERR "%s: pro << 
809                         printf STDERR "\n", if << 
810                         STDERR->flush();       << 
811                                                << 
812                         $next_i = int (($perce << 
813                         $last_time = $cur_time << 
814                 }                              << 
815         }                                      << 
816                                                << 
817         my $cur_time = times;                  << 
818         my $tm = $cur_time - $start_time;      << 
819         my $time = sprintf "%d:%02d", int($tm) << 
820                                                << 
821         printf STDERR "\33[2K\r", if ($is_cons << 
822         printf STDERR "%s: processing sysfs fi << 
823                                                << 
824         foreach my $file (@not_found) {        << 
825                 print "$file not found.\n";    << 
826         }                                      << 
827 }                                              << 
828                                                << 
829 sub undefined_symbols {                        << 
830         print STDERR "Reading $sysfs_prefix di << 
831         find({                                 << 
832                 wanted =>\&parse_existing_sysf << 
833                 preprocess =>\&dont_parse_spec << 
834                 no_chdir => 1                  << 
835              }, $sysfs_prefix);                << 
836         print STDERR "done.\n";                << 
837                                                << 
838         $leaf{"others"}->{what} = "";          << 
839                                                << 
840         print STDERR "Converting ABI What fiel << 
841         foreach my $w (sort keys %data) {      << 
842                 foreach my $what (split /\xac/ << 
843                         next if (!($what =~ m/ << 
844                                                << 
845                         # Convert what into re << 
846                                                << 
847                         # Escape dot character << 
848                         $what =~ s/\./\xf6/g;  << 
849                                                << 
850                         # Temporarily change [ << 
851                         $what =~ s/\[0\-9\]\+/ << 
852                                                << 
853                         # Temporarily change [ << 
854                         $what =~ s/\[0\-\d+\]/ << 
855                         $what =~ s/\[(\d+)\]/\ << 
856                                                << 
857                         # Temporarily change [ << 
858                         $what =~ s/\[(\d)\-(\d << 
859                                                << 
860                         # Handle multiple opti << 
861                         $what =~ s/[\{\<\[]([\ << 
862                                                << 
863                         # Handle wildcards     << 
864                         $what =~ s,\*,.*,g;    << 
865                         $what =~ s,/\xf6..,/.* << 
866                         $what =~ s/\<[^\>]+\>/ << 
867                         $what =~ s/\{[^\}]+\}/ << 
868                         $what =~ s/\[[^\]]+\]/ << 
869                                                << 
870                         $what =~ s/[XYZ]/.*/g; << 
871                                                << 
872                         # Recover [0-9] type o << 
873                         $what =~ s/\xf4/[/g;   << 
874                         $what =~ s/\xf5/]/g;   << 
875                                                << 
876                         # Remove duplicated sp << 
877                         $what =~ s/\s+/ /g;    << 
878                                                << 
879                         # Special case: this A << 
880                         $what =~ s/sqrt\(x^2\+ << 
881                                                << 
882                         # Special case: drop c << 
883                         #       What: foo = <s << 
884                         # (this happens on a f << 
885                         $what =~ s,\s*\=.*$,,; << 
886                                                << 
887                         # Escape all other sym << 
888                         $what =~ s/$escape_sym << 
889                         $what =~ s/\\\\/\\/g;  << 
890                         $what =~ s/\\([\[\]\(\ << 
891                         $what =~ s/(\d+)\\(-\d << 
892                                                << 
893                         $what =~ s/\xff/\\d+/g << 
894                                                << 
895                         # Special case: IIO AB << 
896                         $what =~ s/sqrt(.*)/sq << 
897                                                << 
898                         # Simplify regexes wit << 
899                         $what =~ s#(?:\.\*){2, << 
900 #                       $what =~ s#\.\*/\.\*#. << 
901                                                << 
902                         # Recover dot characte << 
903                         $what =~ s/\xf6/\./g;  << 
904                                                << 
905                         my $leave = get_leave( << 
906                                                << 
907                         my $added = 0;         << 
908                         foreach my $l (split / << 
909                                 if (defined($l << 
910                                         next i << 
911                                         $leaf{ << 
912                                         $added << 
913                                 } else {       << 
914                                         $leaf{ << 
915                                         $added << 
916                                 }              << 
917                         }                      << 
918                         if ($search_string &&  << 
919                                 print STDERR " << 
920                         }                      << 
921                                                << 
922                 }                              << 
923         }                                      << 
924         # Compile regexes                      << 
925         foreach my $l (sort keys %leaf) {      << 
926                 my @expr;                      << 
927                 foreach my $w(sort split /\xac << 
928                         push @expr, qr /^$w$/; << 
929                 }                              << 
930                 $leaf{$l}->{expr} = \@expr;    << 
931         }                                      << 
932                                                << 
933         # Take links into account              << 
934         foreach my $link (sort keys %aliases)  << 
935                 my $abs_file = $aliases{$link} << 
936                 graph_add_link($abs_file, $lin << 
937         }                                      << 
938         print STDERR "done.\n";                << 
939                                                << 
940         check_undefined_symbols;               << 
941 }                                              << 
942                                                << 
943 # Ensure that the prefix will always end with     524 # Ensure that the prefix will always end with a slash
944 # While this is not needed for find, it makes     525 # While this is not needed for find, it makes the patch nicer
945 # with --enable-lineno                            526 # with --enable-lineno
946 $prefix =~ s,/?$,/,;                              527 $prefix =~ s,/?$,/,;
947                                                   528 
948 if ($cmd eq "undefined" || $cmd eq "search") { << 
949         $show_warnings = 0;                    << 
950 }                                              << 
951 #                                                 529 #
952 # Parses all ABI files located at $prefix dir     530 # Parses all ABI files located at $prefix dir
953 #                                                 531 #
954 find({wanted =>\&parse_abi, no_chdir => 1}, $p    532 find({wanted =>\&parse_abi, no_chdir => 1}, $prefix);
955                                                   533 
956 print STDERR Data::Dumper->Dump([\%data], [qw( !! 534 print STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug);
957                                                   535 
958 #                                                 536 #
959 # Handles the command                             537 # Handles the command
960 #                                                 538 #
961 if ($cmd eq "undefined") {                     !! 539 if ($cmd eq "search") {
962         undefined_symbols;                     << 
963 } elsif ($cmd eq "search") {                   << 
964         search_symbols;                           540         search_symbols;
965 } else {                                          541 } else {
966         if ($cmd eq "rest") {                     542         if ($cmd eq "rest") {
967                 output_rest;                      543                 output_rest;
968         }                                         544         }
969                                                   545 
970         # Warn about duplicated ABI entries       546         # Warn about duplicated ABI entries
971         foreach my $what(sort keys %symbols) {    547         foreach my $what(sort keys %symbols) {
972                 my @files = @{$symbols{$what}-    548                 my @files = @{$symbols{$what}->{file}};
973                                                   549 
974                 next if (scalar(@files) == 1);    550                 next if (scalar(@files) == 1);
975                                                   551 
976                 printf STDERR "Warning: $what     552                 printf STDERR "Warning: $what is defined %d times: @files\n",
977                     scalar(@files);               553                     scalar(@files);
978         }                                         554         }
979 }                                                 555 }
980                                                   556 
981 __END__                                           557 __END__
982                                                   558 
983 =head1 NAME                                       559 =head1 NAME
984                                                   560 
985 get_abi.pl - parse the Linux ABI files and pro !! 561 abi_book.pl - parse the Linux ABI files and produce a ReST book.
986                                                   562 
987 =head1 SYNOPSIS                                   563 =head1 SYNOPSIS
988                                                   564 
989 B<get_abi.pl> [--debug <level>] [--enable-line !! 565 B<abi_book.pl> [--debug] [--enable-lineno] [--man] [--help]
990                [--(no-)rst-source] [--dir=<dir !! 566                [--(no-)rst-source] [--dir=<dir>] <COMAND> [<ARGUMENT>]
991                [--search-string <regex>]       << 
992                <COMMAND> [<ARGUMENT>]          << 
993                                                   567 
994 Where B<COMMAND> can be:                       !! 568 Where <COMMAND> can be:
995                                                   569 
996 =over 8                                           570 =over 8
997                                                   571 
998 B<search> I<SEARCH_REGEX> - search for I<SEARC !! 572 B<search> [SEARCH_REGEX] - search for [SEARCH_REGEX] inside ABI
999                                                   573 
1000 B<rest>                   - output the ABI in !! 574 B<rest>                  - output the ABI in ReST markup language
1001                                                  575 
1002 B<validate>               - validate the ABI  !! 576 B<validate>              - validate the ABI contents
1003                                               << 
1004 B<undefined>              - existing symbols  << 
1005                             defined at Docume << 
1006                                                  577 
1007 =back                                            578 =back
1008                                                  579 
1009 =head1 OPTIONS                                   580 =head1 OPTIONS
1010                                                  581 
1011 =over 8                                          582 =over 8
1012                                                  583 
1013 =item B<--dir>                                   584 =item B<--dir>
1014                                                  585 
1015 Changes the location of the ABI search. By de    586 Changes the location of the ABI search. By default, it uses
1016 the Documentation/ABI directory.                 587 the Documentation/ABI directory.
1017                                                  588 
1018 =item B<--rst-source> and B<--no-rst-source>     589 =item B<--rst-source> and B<--no-rst-source>
1019                                                  590 
1020 The input file may be using ReST syntax or no    591 The input file may be using ReST syntax or not. Those two options allow
1021 selecting between a rst-compliant source ABI  !! 592 selecting between a rst-compliant source ABI (--rst-source), or a
1022 plain text that may be violating ReST spec, s    593 plain text that may be violating ReST spec, so it requres some escaping
1023 logic (B<--no-rst-source>).                   !! 594 logic (--no-rst-source).
1024                                                  595 
1025 =item B<--enable-lineno>                         596 =item B<--enable-lineno>
1026                                                  597 
1027 Enable output of .. LINENO lines.             !! 598 Enable output of #define LINENO lines.
1028                                               << 
1029 =item B<--debug> I<debug level>               << 
1030                                               << 
1031 Print debug information according with the le << 
1032 following bitmask:                            << 
1033                                               << 
1034     -  1: Debug parsing What entries from ABI << 
1035     -  2: Shows what files are opened from AB << 
1036     -  4: Dump the structs used to store the  << 
1037                                               << 
1038 =item B<--show-hints>                         << 
1039                                               << 
1040 Show hints about possible definitions for the << 
1041 Used only when B<undefined>.                  << 
1042                                                  599 
1043 =item B<--search-string> I<regex string>      !! 600 =item B<--debug>
1044                                                  601 
1045 Show only occurences that match a search stri !! 602 Put the script in verbose mode, useful for debugging. Can be called multiple
1046 Used only when B<undefined>.                  !! 603 times, to increase verbosity.
1047                                                  604 
1048 =item B<--help>                                  605 =item B<--help>
1049                                                  606 
1050 Prints a brief help message and exits.           607 Prints a brief help message and exits.
1051                                                  608 
1052 =item B<--man>                                   609 =item B<--man>
1053                                                  610 
1054 Prints the manual page and exits.                611 Prints the manual page and exits.
1055                                                  612 
1056 =back                                            613 =back
1057                                                  614 
1058 =head1 DESCRIPTION                               615 =head1 DESCRIPTION
1059                                                  616 
1060 Parse the Linux ABI files from ABI DIR (usual    617 Parse the Linux ABI files from ABI DIR (usually located at Documentation/ABI),
1061 allowing to search for ABI symbols or to prod    618 allowing to search for ABI symbols or to produce a ReST book containing
1062 the Linux ABI documentation.                     619 the Linux ABI documentation.
1063                                                  620 
1064 =head1 EXAMPLES                                  621 =head1 EXAMPLES
1065                                                  622 
1066 Search for all stable symbols with the word "    623 Search for all stable symbols with the word "usb":
1067                                                  624 
1068 =over 8                                          625 =over 8
1069                                                  626 
1070 $ scripts/get_abi.pl search usb --dir Documen    627 $ scripts/get_abi.pl search usb --dir Documentation/ABI/stable
1071                                                  628 
1072 =back                                            629 =back
1073                                                  630 
1074 Search for all symbols that match the regex e    631 Search for all symbols that match the regex expression "usb.*cap":
1075                                                  632 
1076 =over 8                                          633 =over 8
1077                                                  634 
1078 $ scripts/get_abi.pl search usb.*cap             635 $ scripts/get_abi.pl search usb.*cap
1079                                                  636 
1080 =back                                            637 =back
1081                                                  638 
1082 Output all obsoleted symbols in ReST format      639 Output all obsoleted symbols in ReST format
1083                                                  640 
1084 =over 8                                          641 =over 8
1085                                                  642 
1086 $ scripts/get_abi.pl rest --dir Documentation    643 $ scripts/get_abi.pl rest --dir Documentation/ABI/obsolete
1087                                                  644 
1088 =back                                            645 =back
1089                                                  646 
1090 =head1 BUGS                                      647 =head1 BUGS
1091                                                  648 
1092 Report bugs to Mauro Carvalho Chehab <mchehab+ !! 649 Report bugs to Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
1093                                                  650 
1094 =head1 COPYRIGHT                                 651 =head1 COPYRIGHT
1095                                                  652 
1096 Copyright (c) 2016-2021 by Mauro Carvalho Che< !! 653 Copyright (c) 2016-2019 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>.
1097                                                  654 
1098 License GPLv2: GNU GPL version 2 <http://gnu.    655 License GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>.
1099                                                  656 
1100 This is free software: you are free to change    657 This is free software: you are free to change and redistribute it.
1101 There is NO WARRANTY, to the extent permitted    658 There is NO WARRANTY, to the extent permitted by law.
1102                                                  659 
1103 =cut                                             660 =cut
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php