Blame view

scripts/get_abi.pl 14.3 KB
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
1
  #!/usr/bin/perl
ecb351f1c   Mauro Carvalho Chehab   doc: ABI scripts:...
2
  # SPDX-License-Identifier: GPL-2.0
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
3
4
  
  use strict;
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
5
  use warnings;
55e5414f2   Mauro Carvalho Chehab   scripts: get_abi....
6
  use utf8;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
7
8
9
10
  use Pod::Usage;
  use Getopt::Long;
  use File::Find;
  use Fcntl ':mode';
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
11
12
13
14
  my $help = 0;
  my $man = 0;
  my $debug = 0;
  my $enable_lineno = 0;
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
15
  my $prefix="Documentation/ABI";
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
16

11ce90a45   Mauro Carvalho Chehab   scripts: get_abi....
17
18
19
  #
  # If true, assumes that the description is formatted with ReST
  #
2fcce37a3   Mauro Carvalho Chehab   scripts: get_abi....
20
  my $description_is_rst = 1;
11ce90a45   Mauro Carvalho Chehab   scripts: get_abi....
21

bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
22
23
  GetOptions(
  	"debug|d+" => \$debug,
61439c4ad   Mauro Carvalho Chehab   scripts: get_abi....
24
  	"enable-lineno" => \$enable_lineno,
11ce90a45   Mauro Carvalho Chehab   scripts: get_abi....
25
  	"rst-source!" => \$description_is_rst,
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
26
  	"dir=s" => \$prefix,
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
27
28
29
30
31
32
  	'help|?' => \$help,
  	man => \$man
  ) or pod2usage(2);
  
  pod2usage(1) if $help;
  pod2usage(-exitstatus => 0, -verbose => 2) if $man;
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
33
  pod2usage(2) if (scalar @ARGV < 1 || @ARGV > 2);
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
34

33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
35
  my ($cmd, $arg) = @ARGV;
7ce7b89bf   Mauro Carvalho Chehab   scripts/get_abi.p...
36
  pod2usage(2) if ($cmd ne "search" && $cmd ne "rest" && $cmd ne "validate");
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
37
  pod2usage(2) if ($cmd eq "search" && !$arg);
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
38
39
40
41
  
  require Data::Dumper if ($debug);
  
  my %data;
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
42
  my %symbols;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
43
44
45
46
47
48
  
  #
  # Displays an error message, printing file name and line
  #
  sub parse_error($$$$) {
  	my ($file, $ln, $msg, $data) = @_;
75442fb0c   Mauro Carvalho Chehab   docs: Kconfig/Mak...
49
50
51
52
53
54
55
56
57
58
59
60
61
  	$data =~ s/\s+$/
  /;
  
  	print STDERR "Warning: file $file#$ln:
  \t$msg";
  
  	if ($data ne "") {
  		print STDERR ". Line
  \t\t$data";
  	} else {
  	    print STDERR "
  ";
  	}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
62
63
64
65
66
67
68
69
70
71
72
73
74
75
  }
  
  #
  # Parse an ABI file, storing its contents at %data
  #
  sub parse_abi {
  	my $file = $File::Find::name;
  
  	my $mode = (stat($file))[2];
  	return if ($mode & S_IFDIR);
  	return if ($file =~ m,/README,);
  
  	my $name = $file;
  	$name =~ s,.*/,,;
a4ea67bc6   Mauro Carvalho Chehab   scripts: get_abi....
76
77
78
79
  	my $fn = $file;
  	$fn =~ s,Documentation/ABI/,,;
  
  	my $nametag = "File $fn";
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
80
81
82
  	$data{$nametag}->{what} = "File $name";
  	$data{$nametag}->{type} = "File";
  	$data{$nametag}->{file} = $name;
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
83
  	$data{$nametag}->{filepath} = $file;
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
84
  	$data{$nametag}->{is_file} = 1;
61439c4ad   Mauro Carvalho Chehab   scripts: get_abi....
85
  	$data{$nametag}->{line_no} = 1;
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
86

bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
87
88
89
90
91
  	my $type = $file;
  	$type =~ s,.*/(.*)/.*,$1,;
  
  	my $what;
  	my $new_what;
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
92
  	my $tag = "";
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
93
  	my $ln;
6619c6617   Mauro Carvalho Chehab   scripts/get_abi.p...
94
  	my $xrefs;
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
95
  	my $space;
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
96
  	my @labels;
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
97
  	my $label = "";
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
98
99
100
101
102
103
  
  	print STDERR "Opening $file
  " if ($debug > 1);
  	open IN, $file;
  	while(<IN>) {
  		$ln++;
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
104
  		if (m/^(\S+)(:\s*)(.*)/i) {
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
105
  			my $new_tag = lc($1);
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
106
107
  			my $sep = $2;
  			my $content = $3;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
108

7ce7b89bf   Mauro Carvalho Chehab   scripts/get_abi.p...
109
  			if (!($new_tag =~ m/(what|where|date|kernelversion|contact|description|users)/)) {
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
110
  				if ($tag eq "description") {
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
111
112
113
  					# New "tag" is actually part of
  					# description. Don't consider it a tag
  					$new_tag = "";
7d7ea8d24   Mauro Carvalho Chehab   scripts/get_abi.p...
114
  				} elsif ($tag ne "") {
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
115
116
117
  					parse_error($file, $ln, "tag '$tag' is invalid", $_);
  				}
  			}
2c0700e7a   Mauro Carvalho Chehab   scripts/get_abi.p...
118
119
  			# Invalid, but it is a common mistake
  			if ($new_tag eq "where") {
75442fb0c   Mauro Carvalho Chehab   docs: Kconfig/Mak...
120
  				parse_error($file, $ln, "tag 'Where' is invalid. Should be 'What:' instead", "");
2c0700e7a   Mauro Carvalho Chehab   scripts/get_abi.p...
121
122
  				$new_tag = "what";
  			}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
123
  			if ($new_tag =~ m/what/) {
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
124
  				$space = "";
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
125
  				$content =~ s/[,.;]$//;
c7ba33342   Mauro Carvalho Chehab   scripts: get_abi....
126
  				push @{$symbols{$content}->{file}}, " $file:" . ($ln - 1);
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
127
128
129
  				if ($tag =~ m/what/) {
  					$what .= ", " . $content;
  				} else {
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
130
131
132
133
  					if ($what) {
  						parse_error($file, $ln, "What '$what' doesn't have a description", "") if (!$data{$what}->{description});
  
  						foreach my $w(split /, /, $what) {
c7ba33342   Mauro Carvalho Chehab   scripts: get_abi....
134
  							$symbols{$w}->{xref} = $what;
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
135
136
  						};
  					}
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
137

bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
138
  					$what = $content;
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
139
  					$label = $content;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
140
141
  					$new_what = 1;
  				}
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
142
  				push @labels, [($content, $label)];
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
143
  				$tag = $new_tag;
6619c6617   Mauro Carvalho Chehab   scripts/get_abi.p...
144

234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
145
  				push @{$data{$nametag}->{symbols}}, $content if ($data{$nametag}->{what});
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
146
147
  				next;
  			}
7d7ea8d24   Mauro Carvalho Chehab   scripts/get_abi.p...
148
  			if ($tag ne "" && $new_tag) {
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
149
  				$tag = $new_tag;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
150

4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
151
  				if ($new_what) {
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
152
  					@{$data{$what}->{label_list}} = @labels if ($data{$nametag}->{what});
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
153
154
  					@labels = ();
  					$label = "";
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
155
  					$new_what = 0;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
156

4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
157
  					$data{$what}->{type} = $type;
c7ba33342   Mauro Carvalho Chehab   scripts: get_abi....
158
159
160
161
162
163
164
165
166
  					if (!defined($data{$what}->{file})) {
  						$data{$what}->{file} = $name;
  						$data{$what}->{filepath} = $file;
  					} else {
  						if ($name ne $data{$what}->{file}) {
  							$data{$what}->{file} .= " " . $name;
  							$data{$what}->{filepath} .= " " . $file;
  						}
  					}
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
167
168
  					print STDERR "\twhat: $what
  " if ($debug > 1);
c7ba33342   Mauro Carvalho Chehab   scripts: get_abi....
169
170
171
  					$data{$what}->{line_no} = $ln;
  				} else {
  					$data{$what}->{line_no} = $ln if (!defined($data{$what}->{line_no}));
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
172
  				}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
173

4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
174
175
176
177
  				if (!$what) {
  					parse_error($file, $ln, "'What:' should come first:", $_);
  					next;
  				}
f82a8a74e   Mauro Carvalho Chehab   scripts: get_abi....
178
179
  				if ($new_tag eq "description") {
  					$sep =~ s,:, ,;
11ce90a45   Mauro Carvalho Chehab   scripts: get_abi....
180
  					$content = ' ' x length($new_tag) . $sep . $content;
f82a8a74e   Mauro Carvalho Chehab   scripts: get_abi....
181
182
183
  					while ($content =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}
  					if ($content =~ m/^(\s*)(\S.*)$/) {
  						# Preserve initial spaces for the first line
11ce90a45   Mauro Carvalho Chehab   scripts: get_abi....
184
  						$space = $1;
f82a8a74e   Mauro Carvalho Chehab   scripts: get_abi....
185
186
187
188
189
  						$content = "$2
  ";
  						$data{$what}->{$tag} .= $content;
  					} else {
  						undef($space);
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
190
  					}
e9bca8918   Mauro Carvalho Chehab   scripts: get_abi....
191

4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
192
193
194
  				} else {
  					$data{$what}->{$tag} = $content;
  				}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
195
196
  				next;
  			}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
197
  		}
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
198
  		# Store any contents before tags at the database
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
199
200
  		if (!$tag && $data{$nametag}->{what}) {
  			$data{$nametag}->{description} .= $_;
6619c6617   Mauro Carvalho Chehab   scripts/get_abi.p...
201
202
  			next;
  		}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
203

4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
204
  		if ($tag eq "description") {
e9bca8918   Mauro Carvalho Chehab   scripts: get_abi....
205
206
  			my $content = $_;
  			while ($content =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}
f82a8a74e   Mauro Carvalho Chehab   scripts: get_abi....
207
208
209
210
211
212
213
214
  			if (m/^\s*
  /) {
  				$data{$what}->{$tag} .= "
  ";
  				next;
  			}
  
  			if (!defined($space)) {
e9bca8918   Mauro Carvalho Chehab   scripts: get_abi....
215
  				# Preserve initial spaces for the first line
f82a8a74e   Mauro Carvalho Chehab   scripts: get_abi....
216
  				if ($content =~ m/^(\s*)(\S.*)$/) {
e9bca8918   Mauro Carvalho Chehab   scripts: get_abi....
217
  					$space = $1;
f82a8a74e   Mauro Carvalho Chehab   scripts: get_abi....
218
219
  					$content = "$2
  ";
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
220
221
  				}
  			} else {
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
222
  				$space = "" if (!($content =~ s/^($space)//));
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
223
  			}
f82a8a74e   Mauro Carvalho Chehab   scripts: get_abi....
224
  			$data{$what}->{$tag} .= $content;
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
225
226
  			next;
  		}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
227
228
229
230
231
232
233
234
235
  		if (m/^\s*(.*)/) {
  			$data{$what}->{$tag} .= "
  $1";
  			$data{$what}->{$tag} =~ s/
  +$//;
  			next;
  		}
  
  		# Everything else is error
75442fb0c   Mauro Carvalho Chehab   docs: Kconfig/Mak...
236
  		parse_error($file, $ln, "Unexpected content", $_);
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
237
  	}
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
238
239
240
241
242
243
  	$data{$nametag}->{description} =~ s/^
  +// if ($data{$nametag}->{description});
  	if ($what) {
  		parse_error($file, $ln, "What '$what' doesn't have a description", "") if (!$data{$what}->{description});
  
  		foreach my $w(split /, /,$what) {
c7ba33342   Mauro Carvalho Chehab   scripts: get_abi....
244
  			$symbols{$w}->{xref} = $what;
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
245
246
  		};
  	}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
247
248
  	close IN;
  }
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
249
250
  sub create_labels {
  	my %labels;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
251

234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
252
253
  	foreach my $what (keys %data) {
  		next if ($data{$what}->{file} eq "File");
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
254

234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
255
  		foreach my $p (@{$data{$what}->{label_list}}) {
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
256
257
258
259
260
261
262
263
  			my ($content, $label) = @{$p};
  			$label = "abi_" . $label . " ";
  			$label =~ tr/A-Z/a-z/;
  
  			# Convert special chars to "_"
  			$label =~s/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xff])/_/g;
  			$label =~ s,_+,_,g;
  			$label =~ s,_$,,;
2e7ce0559   Mauro Carvalho Chehab   scripts/get_abi.p...
264
265
266
267
268
269
  			# Avoid duplicated labels
  			while (defined($labels{$label})) {
  			    my @chars = ("A".."Z", "a".."z");
  			    $label .= $chars[rand @chars];
  			}
  			$labels{$label} = 1;
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
270
  			$data{$what}->{label} = $label;
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
271
272
273
  
  			# only one label is enough
  			last;
6619c6617   Mauro Carvalho Chehab   scripts/get_abi.p...
274
  		}
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
275
276
277
278
279
280
  	}
  }
  
  #
  # Outputs the book on ReST format
  #
55e5414f2   Mauro Carvalho Chehab   scripts: get_abi....
281
282
  # \b doesn't work well with paths. So, we need to define something else
  my $bondary = qr { (?<![\w\/\`\{])(?=[\w\/\`\{])|(?<=[\w\/\`\{])(?![\w\/\`\{]) }x;
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
283
284
  sub output_rest {
  	create_labels();
9d4fdda33   Mauro Carvalho Chehab   scripts: get_api....
285
  	my $part = "";
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
286
287
288
289
290
  	foreach my $what (sort {
  				($data{$a}->{type} eq "File") cmp ($data{$b}->{type} eq "File") ||
  				$a cmp $b
  			       } keys %data) {
  		my $type = $data{$what}->{type};
c7ba33342   Mauro Carvalho Chehab   scripts: get_abi....
291
292
293
  
  		my @file = split / /, $data{$what}->{file};
  		my @filepath = split / /, $data{$what}->{filepath};
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
294
295
296
297
298
  
  		if ($enable_lineno) {
  			printf "#define LINENO %s%s#%s
  
  ",
c7ba33342   Mauro Carvalho Chehab   scripts: get_abi....
299
  			       $prefix, $file[0],
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
300
301
  			       $data{$what}->{line_no};
  		}
6619c6617   Mauro Carvalho Chehab   scripts/get_abi.p...
302

234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
303
304
  		my $w = $what;
  		$w =~ s/([\(\)\_\-\*\=\^\~\\])/\\$1/g;
6619c6617   Mauro Carvalho Chehab   scripts/get_abi.p...
305

c7ba33342   Mauro Carvalho Chehab   scripts: get_abi....
306
  		if ($type ne "File") {
9d4fdda33   Mauro Carvalho Chehab   scripts: get_api....
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
  			my $cur_part = $what;
  			if ($what =~ '/') {
  				if ($what =~ m#^(\/?(?:[\w\-]+\/?){1,2})#) {
  					$cur_part = "Symbols under $1";
  					$cur_part =~ s,/$,,;
  				}
  			}
  
  			if ($cur_part ne "" && $part ne $cur_part) {
  			    $part = $cur_part;
  			    my $bar = $part;
  			    $bar =~ s/./-/g;
  			    print "$part
  $bar
  
  ";
  			}
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
324
325
326
  			printf ".. _%s:
  
  ", $data{$what}->{label};
45f965179   Mauro Carvalho Chehab   scripts/get_abi.p...
327

234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
328
  			my @names = split /, /,$w;
45f965179   Mauro Carvalho Chehab   scripts/get_abi.p...
329
330
331
  			my $len = 0;
  
  			foreach my $name (@names) {
c01d62d3f   Mauro Carvalho Chehab   scripts: get_abi....
332
  				$name = "**$name**";
45f965179   Mauro Carvalho Chehab   scripts/get_abi.p...
333
334
  				$len = length($name) if (length($name) > $len);
  			}
45f965179   Mauro Carvalho Chehab   scripts/get_abi.p...
335
336
337
338
339
340
341
342
  			print "+-" . "-" x $len . "-+
  ";
  			foreach my $name (@names) {
  				printf "| %s", $name . " " x ($len - length($name)) . " |
  ";
  				print "+-" . "-" x $len . "-+
  ";
  			}
45f965179   Mauro Carvalho Chehab   scripts/get_abi.p...
343

c7ba33342   Mauro Carvalho Chehab   scripts: get_abi....
344
345
346
347
348
349
350
351
352
353
354
355
356
  			print "
  ";
  		}
  
  		for (my $i = 0; $i < scalar(@filepath); $i++) {
  			my $path = $filepath[$i];
  			my $f = $file[$i];
  
  			$path =~ s,.*/(.*/.*),$1,;;
  			$path =~ s,[/\-],_,g;;
  			my $fileref = "abi_file_".$path;
  
  			if ($type eq "File") {
c7ba33342   Mauro Carvalho Chehab   scripts: get_abi....
357
358
359
  				print ".. _$fileref:
  
  ";
c7ba33342   Mauro Carvalho Chehab   scripts: get_abi....
360
361
362
363
364
  			} else {
  				print "Defined on file :ref:`$f <$fileref>`
  
  ";
  			}
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
365
  		}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
366

a4ea67bc6   Mauro Carvalho Chehab   scripts: get_abi....
367
368
369
370
371
372
373
374
  		if ($type eq "File") {
  			my $bar = $w;
  			$bar =~ s/./-/g;
  			print "$w
  $bar
  
  ";
  		}
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
375
376
377
378
  		my $desc = "";
  		$desc = $data{$what}->{description} if (defined($data{$what}->{description}));
  		$desc =~ s/\s+$/
  /;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
379

4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
380
  		if (!($desc =~ /^\s*$/)) {
11ce90a45   Mauro Carvalho Chehab   scripts: get_abi....
381
  			if ($description_is_rst) {
daaaf58a2   Mauro Carvalho Chehab   scripts: get_abi....
382
383
384
385
386
387
388
389
390
  				# Remove title markups from the description
  				# Having titles inside ABI files will only work if extra
  				# care would be taken in order to strictly follow the same
  				# level order for each markup.
  				$desc =~ s/
  [\-\*\=\^\~]+
  /
  
  /g;
55e5414f2   Mauro Carvalho Chehab   scripts: get_abi....
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
  				# Enrich text by creating cross-references
  
  				$desc =~ s,Documentation/(?!devicetree)(\S+)\.rst,:doc:`/$1`,g;
  
  				my @matches = $desc =~ m,Documentation/ABI/([\w\/\-]+),;
  				foreach my $f (@matches) {
  					my $xref = $f;
  					my $path = $f;
  					$path =~ s,.*/(.*/.*),$1,;;
  					$path =~ s,[/\-],_,g;;
  					$xref .= " <abi_file_" . $path . ">";
  					$desc =~ s,\bDocumentation/ABI/$f\b,:ref:`$xref`,g;
  				}
  
  				@matches = $desc =~ m,$bondary(/sys/[^\s\.\,\;\:\*\s\`\'\(\)]+)$bondary,;
  
  				foreach my $s (@matches) {
  					if (defined($data{$s}) && defined($data{$s}->{label})) {
  						my $xref = $s;
  
  						$xref =~ s/([\x00-\x1f\x21-\x2f\x3a-\x40\x7b-\xff])/\\$1/g;
  						$xref = ":ref:`$xref <" . $data{$s}->{label} . ">`";
  
  						$desc =~ s,$bondary$s$bondary,$xref,g;
  					}
  				}
11ce90a45   Mauro Carvalho Chehab   scripts: get_abi....
417
418
419
  				print "$desc
  
  ";
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
420
  			} else {
11ce90a45   Mauro Carvalho Chehab   scripts: get_abi....
421
  				$desc =~ s/^\s+//;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
422

11ce90a45   Mauro Carvalho Chehab   scripts: get_abi....
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
  				# Remove title markups from the description, as they won't work
  				$desc =~ s/
  [\-\*\=\^\~]+
  /
  
  /g;
  
  				if ($desc =~ m/\:
  / || $desc =~ m/
  [\t ]+/  || $desc =~ m/[\x00-\x08\x0b-\x1f\x7b-\xff]/) {
  					# put everything inside a code block
  					$desc =~ s/
  /
   /g;
  
  					print "::
  
  ";
  					print " $desc
  
  ";
  				} else {
  					# Escape any special chars from description
  					$desc =~s/([\x00-\x08\x0b-\x1f\x21-\x2a\x2d\x2f\x3c-\x40\x5c\x5e-\x60\x7b-\xff])/\\$1/g;
  					print "$desc
  
  ";
  				}
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
451
  			}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
452
  		} else {
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
453
454
455
  			print "DESCRIPTION MISSING for $what
  
  " if (!$data{$what}->{is_file});
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
456
  		}
6619c6617   Mauro Carvalho Chehab   scripts/get_abi.p...
457

234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
458
  		if ($data{$what}->{symbols}) {
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
459
460
461
  			printf "Has the following ABI:
  
  ";
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
462
  			foreach my $content(@{$data{$what}->{symbols}}) {
c7ba33342   Mauro Carvalho Chehab   scripts: get_abi....
463
  				my $label = $data{$symbols{$content}->{xref}}->{label};
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
464
465
466
467
468
469
470
471
472
  
  				# Escape special chars from content
  				$content =~s/([\x00-\x1f\x21-\x2f\x3a-\x40\x7b-\xff])/\\$1/g;
  
  				print "- :ref:`$content <$label>`
  
  ";
  			}
  		}
a16ab14eb   Mauro Carvalho Chehab   scripts: get_abi....
473
474
475
476
477
478
479
480
481
482
483
484
  
  		if (defined($data{$what}->{users})) {
  			my $users = $data{$what}->{users};
  
  			$users =~ s/
  /
  \t/g;
  			printf "Users:
  \t%s
  
  ", $users if ($users ne "");
  		}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
485
486
487
488
  	}
  }
  
  #
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
  # Searches for ABI symbols
  #
  sub search_symbols {
  	foreach my $what (sort keys %data) {
  		next if (!($what =~ m/($arg)/));
  
  		my $type = $data{$what}->{type};
  		next if ($type eq "File");
  
  		my $file = $data{$what}->{filepath};
  
  		my $bar = $what;
  		$bar =~ s/./-/g;
  
  		print "
  $what
  $bar
  
  ";
234948bf3   Mauro Carvalho Chehab   scripts: get_abi....
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
  		my $kernelversion = $data{$what}->{kernelversion} if (defined($data{$what}->{kernelversion}));
  		my $contact = $data{$what}->{contact} if (defined($data{$what}->{contact}));
  		my $users = $data{$what}->{users} if (defined($data{$what}->{users}));
  		my $date = $data{$what}->{date} if (defined($data{$what}->{date}));
  		my $desc = $data{$what}->{description} if (defined($data{$what}->{description}));
  
  		$kernelversion =~ s/^\s+// if ($kernelversion);
  		$contact =~ s/^\s+// if ($contact);
  		if ($users) {
  			$users =~ s/^\s+//;
  			$users =~ s/
  //g;
  		}
  		$date =~ s/^\s+// if ($date);
  		$desc =~ s/^\s+// if ($desc);
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
523
524
525
526
527
528
529
530
531
  
  		printf "Kernel version:\t\t%s
  ", $kernelversion if ($kernelversion);
  		printf "Date:\t\t\t%s
  ", $date if ($date);
  		printf "Contact:\t\t%s
  ", $contact if ($contact);
  		printf "Users:\t\t\t%s
  ", $users if ($users);
c7ba33342   Mauro Carvalho Chehab   scripts: get_abi....
532
533
534
  		print "Defined on file(s):\t$file
  
  ";
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
535
536
537
538
539
  		print "Description:
  
  $desc";
  	}
  }
61439c4ad   Mauro Carvalho Chehab   scripts: get_abi....
540
541
542
543
  # Ensure that the prefix will always end with a slash
  # While this is not needed for find, it makes the patch nicer
  # with --enable-lineno
  $prefix =~ s,/?$,/,;
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
544
545
  
  #
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
546
547
548
549
550
551
552
  # Parses all ABI files located at $prefix dir
  #
  find({wanted =>\&parse_abi, no_chdir => 1}, $prefix);
  
  print STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug);
  
  #
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
553
  # Handles the command
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
554
  #
c7ba33342   Mauro Carvalho Chehab   scripts: get_abi....
555
  if ($cmd eq "search") {
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
556
  	search_symbols;
c7ba33342   Mauro Carvalho Chehab   scripts: get_abi....
557
558
559
560
561
562
563
564
565
566
  } else {
  	if ($cmd eq "rest") {
  		output_rest;
  	}
  
  	# Warn about duplicated ABI entries
  	foreach my $what(sort keys %symbols) {
  		my @files = @{$symbols{$what}->{file}};
  
  		next if (scalar(@files) == 1);
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
567

c7ba33342   Mauro Carvalho Chehab   scripts: get_abi....
568
569
570
571
572
  		printf STDERR "Warning: $what is defined %d times: @files
  ",
  		    scalar(@files);
  	}
  }
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
573
574
575
576
577
578
579
580
  
  __END__
  
  =head1 NAME
  
  abi_book.pl - parse the Linux ABI files and produce a ReST book.
  
  =head1 SYNOPSIS
61439c4ad   Mauro Carvalho Chehab   scripts: get_abi....
581
582
  B<abi_book.pl> [--debug] [--enable-lineno] [--man] [--help]
  	       [--(no-)rst-source] [--dir=<dir>] <COMAND> [<ARGUMENT>]
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
583
584
585
586
587
588
  
  Where <COMMAND> can be:
  
  =over 8
  
  B<search> [SEARCH_REGEX] - search for [SEARCH_REGEX] inside ABI
7ce7b89bf   Mauro Carvalho Chehab   scripts/get_abi.p...
589
590
591
  B<rest>                  - output the ABI in ReST markup language
  
  B<validate>              - validate the ABI contents
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
592
593
  
  =back
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
594
595
596
597
  
  =head1 OPTIONS
  
  =over 8
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
598
599
600
601
  =item B<--dir>
  
  Changes the location of the ABI search. By default, it uses
  the Documentation/ABI directory.
11ce90a45   Mauro Carvalho Chehab   scripts: get_abi....
602
603
604
605
606
607
  =item B<--rst-source> and B<--no-rst-source>
  
  The input file may be using ReST syntax or not. Those two options allow
  selecting between a rst-compliant source ABI (--rst-source), or a
  plain text that may be violating ReST spec, so it requres some escaping
  logic (--no-rst-source).
61439c4ad   Mauro Carvalho Chehab   scripts: get_abi....
608
609
610
  =item B<--enable-lineno>
  
  Enable output of #define LINENO lines.
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
  =item B<--debug>
  
  Put the script in verbose mode, useful for debugging. Can be called multiple
  times, to increase verbosity.
  
  =item B<--help>
  
  Prints a brief help message and exits.
  
  =item B<--man>
  
  Prints the manual page and exits.
  
  =back
  
  =head1 DESCRIPTION
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
  Parse the Linux ABI files from ABI DIR (usually located at Documentation/ABI),
  allowing to search for ABI symbols or to produce a ReST book containing
  the Linux ABI documentation.
  
  =head1 EXAMPLES
  
  Search for all stable symbols with the word "usb":
  
  =over 8
  
  $ scripts/get_abi.pl search usb --dir Documentation/ABI/stable
  
  =back
  
  Search for all symbols that match the regex expression "usb.*cap":
  
  =over 8
  
  $ scripts/get_abi.pl search usb.*cap
  
  =back
  
  Output all obsoleted symbols in ReST format
  
  =over 8
  
  $ scripts/get_abi.pl rest --dir Documentation/ABI/obsolete
  
  =back
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
656
657
  
  =head1 BUGS
7ce7b89bf   Mauro Carvalho Chehab   scripts/get_abi.p...
658
  Report bugs to Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
659
660
  
  =head1 COPYRIGHT
7ce7b89bf   Mauro Carvalho Chehab   scripts/get_abi.p...
661
  Copyright (c) 2016-2019 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>.
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
662
663
664
665
666
667
668
  
  License GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>.
  
  This is free software: you are free to change and redistribute it.
  There is NO WARRANTY, to the extent permitted by law.
  
  =cut