Blame view

scripts/get_abi.pl 10.1 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
5
6
7
8
9
10
11
12
  
  use strict;
  use Pod::Usage;
  use Getopt::Long;
  use File::Find;
  use Fcntl ':mode';
  
  my $help;
  my $man;
  my $debug;
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
13
  my $prefix="Documentation/ABI";
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
14
15
16
  
  GetOptions(
  	"debug|d+" => \$debug,
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
17
  	"dir=s" => \$prefix,
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
18
19
20
21
22
23
  	'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...
24
  pod2usage(2) if (scalar @ARGV < 1 || @ARGV > 2);
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
25

33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
26
  my ($cmd, $arg) = @ARGV;
7ce7b89bf   Mauro Carvalho Chehab   scripts/get_abi.p...
27
  pod2usage(2) if ($cmd ne "search" && $cmd ne "rest" && $cmd ne "validate");
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
28
  pod2usage(2) if ($cmd eq "search" && !$arg);
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  
  require Data::Dumper if ($debug);
  
  my %data;
  
  #
  # Displays an error message, printing file name and line
  #
  sub parse_error($$$$) {
  	my ($file, $ln, $msg, $data) = @_;
  
  	print STDERR "file $file#$ln: $msg at
  \t$data";
  }
  
  #
  # 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,.*/,,;
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
56
57
58
59
  	my $nametag = "File $name";
  	$data{$nametag}->{what} = "File $name";
  	$data{$nametag}->{type} = "File";
  	$data{$nametag}->{file} = $name;
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
60
  	$data{$nametag}->{filepath} = $file;
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
61
  	$data{$nametag}->{is_file} = 1;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
62
63
64
65
66
67
68
  	my $type = $file;
  	$type =~ s,.*/(.*)/.*,$1,;
  
  	my $what;
  	my $new_what;
  	my $tag;
  	my $ln;
6619c6617   Mauro Carvalho Chehab   scripts/get_abi.p...
69
  	my $xrefs;
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
70
  	my $space;
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
71
72
  	my @labels;
  	my $label;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
73
74
75
76
77
78
  
  	print STDERR "Opening $file
  " if ($debug > 1);
  	open IN, $file;
  	while(<IN>) {
  		$ln++;
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
79
  		if (m/^(\S+)(:\s*)(.*)/i) {
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
80
  			my $new_tag = lc($1);
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
81
82
  			my $sep = $2;
  			my $content = $3;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
83

7ce7b89bf   Mauro Carvalho Chehab   scripts/get_abi.p...
84
  			if (!($new_tag =~ m/(what|where|date|kernelversion|contact|description|users)/)) {
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
85
  				if ($tag eq "description") {
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
86
87
88
  					# New "tag" is actually part of
  					# description. Don't consider it a tag
  					$new_tag = "";
7d7ea8d24   Mauro Carvalho Chehab   scripts/get_abi.p...
89
  				} elsif ($tag ne "") {
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
90
91
92
  					parse_error($file, $ln, "tag '$tag' is invalid", $_);
  				}
  			}
2c0700e7a   Mauro Carvalho Chehab   scripts/get_abi.p...
93
94
95
96
97
  			# Invalid, but it is a common mistake
  			if ($new_tag eq "where") {
  				parse_error($file, $ln, "tag 'Where' is invalid. Should be 'What:' instead", $_);
  				$new_tag = "what";
  			}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
98
  			if ($new_tag =~ m/what/) {
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
99
  				$space = "";
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
100
101
102
  				if ($tag =~ m/what/) {
  					$what .= ", " . $content;
  				} else {
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
103
  					parse_error($file, $ln, "What '$what' doesn't have a description", "") if ($what && !$data{$what}->{description});
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
104
  					$what = $content;
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
105
  					$label = $content;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
106
107
  					$new_what = 1;
  				}
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
108
  				push @labels, [($content, $label)];
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
109
  				$tag = $new_tag;
6619c6617   Mauro Carvalho Chehab   scripts/get_abi.p...
110

d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
111
  				push @{$data{$nametag}->{xrefs}}, [($content, $label)] if ($data{$nametag}->{what});
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
112
113
  				next;
  			}
7d7ea8d24   Mauro Carvalho Chehab   scripts/get_abi.p...
114
  			if ($tag ne "" && $new_tag) {
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
115
  				$tag = $new_tag;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
116

4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
117
  				if ($new_what) {
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
118
119
120
  					@{$data{$what}->{label}} = @labels if ($data{$nametag}->{what});
  					@labels = ();
  					$label = "";
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
121
  					$new_what = 0;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
122

4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
123
124
  					$data{$what}->{type} = $type;
  					$data{$what}->{file} = $name;
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
125
  					$data{$what}->{filepath} = $file;
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
126
127
128
  					print STDERR "\twhat: $what
  " if ($debug > 1);
  				}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
129

4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
  				if (!$what) {
  					parse_error($file, $ln, "'What:' should come first:", $_);
  					next;
  				}
  				if ($tag eq "description") {
  					next if ($content =~ m/^\s*$/);
  					if ($content =~ m/^(\s*)(.*)/) {
  						my $new_content = $2;
  						$space = $new_tag . $sep . $1;
  						while ($space =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}
  						$space =~ s/./ /g;
  						$data{$what}->{$tag} .= "$new_content
  ";
  					}
  				} else {
  					$data{$what}->{$tag} = $content;
  				}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
147
148
  				next;
  			}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
149
  		}
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
150
  		# Store any contents before tags at the database
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
151
152
  		if (!$tag && $data{$nametag}->{what}) {
  			$data{$nametag}->{description} .= $_;
6619c6617   Mauro Carvalho Chehab   scripts/get_abi.p...
153
154
  			next;
  		}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
155

4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
  		if ($tag eq "description") {
  			if (!$data{$what}->{description}) {
  				next if (m/^\s*
  /);
  				if (m/^(\s*)(.*)/) {
  					$space = $1;
  					while ($space =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}
  					$data{$what}->{$tag} .= "$2
  ";
  				}
  			} else {
  				my $content = $_;
  				if (m/^\s*
  /) {
  					$data{$what}->{$tag} .= $content;
  					next;
  				}
  
  				while ($content =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}
  				$space = "" if (!($content =~ s/^($space)//));
  
  				# Compress spaces with tabs
  				$content =~ s<^ {8}> <\t>;
  				$content =~ s<^ {1,7}\t> <\t>;
  				$content =~ s< {1,7}\t> <\t>;
  				$data{$what}->{$tag} .= $content;
  			}
  			next;
  		}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
185
186
187
188
189
190
191
192
193
194
195
  		if (m/^\s*(.*)/) {
  			$data{$what}->{$tag} .= "
  $1";
  			$data{$what}->{$tag} =~ s/
  +$//;
  			next;
  		}
  
  		# Everything else is error
  		parse_error($file, $ln, "Unexpected line:", $_);
  	}
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
196
197
  	$data{$nametag}->{description} =~ s/^
  +//;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
198
199
  	close IN;
  }
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
200
201
202
  #
  # Outputs the book on ReST format
  #
45f965179   Mauro Carvalho Chehab   scripts/get_abi.p...
203

2e7ce0559   Mauro Carvalho Chehab   scripts/get_abi.p...
204
  my %labels;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
205
  sub output_rest {
45f965179   Mauro Carvalho Chehab   scripts/get_abi.p...
206
207
208
209
  	foreach my $what (sort {
  				($data{$a}->{type} eq "File") cmp ($data{$b}->{type} eq "File") ||
  				$a cmp $b
  			       } keys %data) {
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
210
211
  		my $type = $data{$what}->{type};
  		my $file = $data{$what}->{file};
45f965179   Mauro Carvalho Chehab   scripts/get_abi.p...
212
  		my $filepath = $data{$what}->{filepath};
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
213
214
215
  
  		my $w = $what;
  		$w =~ s/([\(\)\_\-\*\=\^\~\\])/\\$1/g;
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
216

d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
217
218
219
220
221
222
223
224
225
  		foreach my $p (@{$data{$what}->{label}}) {
  			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...
226
227
228
229
230
231
  			# Avoid duplicated labels
  			while (defined($labels{$label})) {
  			    my @chars = ("A".."Z", "a".."z");
  			    $label .= $chars[rand @chars];
  			}
  			$labels{$label} = 1;
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
232
233
234
235
236
237
238
239
  			$data{$what}->{label} .= $label;
  
  			printf ".. _%s:
  
  ", $label;
  
  			# only one label is enough
  			last;
6619c6617   Mauro Carvalho Chehab   scripts/get_abi.p...
240
  		}
6619c6617   Mauro Carvalho Chehab   scripts/get_abi.p...
241

45f965179   Mauro Carvalho Chehab   scripts/get_abi.p...
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
  		$filepath =~ s,.*/(.*/.*),\1,;;
  		$filepath =~ s,[/\-],_,g;;
  		my $fileref = "abi_file_".$filepath;
  
  		if ($type eq "File") {
  			my $bar = $w;
  			$bar =~ s/./-/g;
  
  			print ".. _$fileref:
  
  ";
  			print "$w
  $bar
  
  ";
  		} else {
  			my @names = split /\s*,\s*/,$w;
  
  			my $len = 0;
  
  			foreach my $name (@names) {
  				$len = length($name) if (length($name) > $len);
  			}
  
  			print "What:
  
  ";
  
  			print "+-" . "-" x $len . "-+
  ";
  			foreach my $name (@names) {
  				printf "| %s", $name . " " x ($len - length($name)) . " |
  ";
  				print "+-" . "-" x $len . "-+
  ";
  			}
  			print "
  ";
  		}
  
  		print "Defined on file :ref:`$file <$fileref>`
  
  " if ($type ne "File");
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
285
286
287
288
289
290
291
292
293
  
  		my $desc = $data{$what}->{description};
  		$desc =~ s/^\s+//;
  
  		# Remove title markups from the description, as they won't work
  		$desc =~ s/
  [\-\*\=\^\~]+
  /
  /g;
4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
294
295
296
297
298
299
300
301
  		if (!($desc =~ /^\s*$/)) {
  			if ($desc =~ m/\:
  / || $desc =~ m/
  [\t ]+/  || $desc =~ m/[\x00-\x08\x0b-\x1f\x7b-\xff]/) {
  				# put everything inside a code block
  				$desc =~ s/
  /
   /g;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
302

4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
303
304
305
306
307
308
309
310
311
  				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;
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
312

4e6a6234d   Mauro Carvalho Chehab   scripts/get_abi.p...
313
314
315
316
  				print "$desc
  
  ";
  			}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
317
  		} else {
d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
318
319
320
  			print "DESCRIPTION MISSING for $what
  
  " if (!$data{$what}->{is_file});
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
321
  		}
6619c6617   Mauro Carvalho Chehab   scripts/get_abi.p...
322

d0ebaf51d   Mauro Carvalho Chehab   scripts/get_abi.p...
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
  		if ($data{$what}->{xrefs}) {
  			printf "Has the following ABI:
  
  ";
  
  			foreach my $p(@{$data{$what}->{xrefs}}) {
  				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,_$,,;
  
  				# Escape special chars from content
  				$content =~s/([\x00-\x1f\x21-\x2f\x3a-\x40\x7b-\xff])/\\$1/g;
  
  				print "- :ref:`$content <$label>`
  
  ";
  			}
  		}
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
346
347
348
349
  	}
  }
  
  #
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
  # 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
  
  ";
  
  		my $kernelversion = $data{$what}->{kernelversion};
  		my $contact = $data{$what}->{contact};
  		my $users = $data{$what}->{users};
  		my $date = $data{$what}->{date};
  		my $desc = $data{$what}->{description};
  		$kernelversion =~ s/^\s+//;
  		$contact =~ s/^\s+//;
  		$users =~ s/^\s+//;
  		$users =~ s/
  //g;
  		$date =~ s/^\s+//;
  		$desc =~ s/^\s+//;
  
  		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);
  		print "Defined on file:\t$file
  
  ";
  		print "Description:
  
  $desc";
  	}
  }
  
  
  #
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
402
403
404
405
406
407
408
  # 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...
409
  # Handles the command
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
410
  #
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
411
412
  if ($cmd eq "rest") {
  	output_rest;
7ce7b89bf   Mauro Carvalho Chehab   scripts/get_abi.p...
413
  } elsif ($cmd eq "search") {
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
414
415
  	search_symbols;
  }
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
416
417
418
419
420
421
422
423
424
  
  
  __END__
  
  =head1 NAME
  
  abi_book.pl - parse the Linux ABI files and produce a ReST book.
  
  =head1 SYNOPSIS
7ce7b89bf   Mauro Carvalho Chehab   scripts/get_abi.p...
425
  B<abi_book.pl> [--debug] [--man] [--help] [--dir=<dir>] <COMAND> [<ARGUMENT>]
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
426
427
428
429
430
431
  
  Where <COMMAND> can be:
  
  =over 8
  
  B<search> [SEARCH_REGEX] - search for [SEARCH_REGEX] inside ABI
7ce7b89bf   Mauro Carvalho Chehab   scripts/get_abi.p...
432
433
434
  B<rest>                  - output the ABI in ReST markup language
  
  B<validate>              - validate the ABI contents
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
435
436
  
  =back
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
437
438
439
440
  
  =head1 OPTIONS
  
  =over 8
33e3e9913   Mauro Carvalho Chehab   scripts/get_abi.p...
441
442
443
444
  =item B<--dir>
  
  Changes the location of the ABI search. By default, it uses
  the Documentation/ABI directory.
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
  =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...
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
  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...
490
491
  
  =head1 BUGS
7ce7b89bf   Mauro Carvalho Chehab   scripts/get_abi.p...
492
  Report bugs to Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
493
494
  
  =head1 COPYRIGHT
7ce7b89bf   Mauro Carvalho Chehab   scripts/get_abi.p...
495
  Copyright (c) 2016-2019 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>.
bbc249f2b   Mauro Carvalho Chehab   scripts: add an s...
496
497
498
499
500
501
502
  
  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