xref: /openbmc/linux/scripts/get_abi.pl (revision 7d7ae873b5e0f46d19e5dc818d1a7809e4b7cc81)
1c25ce589SFinn Behrens#!/usr/bin/env perl
2ecb351f1SMauro Carvalho Chehab# SPDX-License-Identifier: GPL-2.0
3bbc249f2SMauro Carvalho Chehab
442f09848SMauro Carvalho ChehabBEGIN { $Pod::Usage::Formatter = 'Pod::Text::Termcap'; }
542f09848SMauro Carvalho Chehab
6bbc249f2SMauro Carvalho Chehabuse strict;
7234948bfSMauro Carvalho Chehabuse warnings;
855e5414fSMauro Carvalho Chehabuse utf8;
942f09848SMauro Carvalho Chehabuse Pod::Usage qw(pod2usage);
10bbc249f2SMauro Carvalho Chehabuse Getopt::Long;
11bbc249f2SMauro Carvalho Chehabuse File::Find;
1228331a01SMauro Carvalho Chehabuse IO::Handle;
13bbc249f2SMauro Carvalho Chehabuse Fcntl ':mode';
14ab02c515SMauro Carvalho Chehabuse Cwd 'abs_path';
1546f661fdSMauro Carvalho Chehabuse Data::Dumper;
16bbc249f2SMauro Carvalho Chehab
17234948bfSMauro Carvalho Chehabmy $help = 0;
18ab02c515SMauro Carvalho Chehabmy $hint = 0;
19234948bfSMauro Carvalho Chehabmy $man = 0;
20234948bfSMauro Carvalho Chehabmy $debug = 0;
21234948bfSMauro Carvalho Chehabmy $enable_lineno = 0;
22f090db43SMauro Carvalho Chehabmy $show_warnings = 1;
2333e3e991SMauro Carvalho Chehabmy $prefix="Documentation/ABI";
24f090db43SMauro Carvalho Chehabmy $sysfs_prefix="/sys";
2514c94257SMauro Carvalho Chehabmy $search_string;
26bbc249f2SMauro Carvalho Chehab
2746f661fdSMauro Carvalho Chehab# Debug options
2846f661fdSMauro Carvalho Chehabmy $dbg_what_parsing = 1;
2946f661fdSMauro Carvalho Chehabmy $dbg_what_open = 2;
3046f661fdSMauro Carvalho Chehabmy $dbg_dump_abi_structs = 4;
31f34f6729SMauro Carvalho Chehabmy $dbg_undefined = 8;
3246f661fdSMauro Carvalho Chehab
333a1cc06cSMauro Carvalho Chehab$Data::Dumper::Indent = 1;
343a1cc06cSMauro Carvalho Chehab$Data::Dumper::Terse = 1;
353a1cc06cSMauro Carvalho Chehab
3611ce90a4SMauro Carvalho Chehab#
3711ce90a4SMauro Carvalho Chehab# If true, assumes that the description is formatted with ReST
3811ce90a4SMauro Carvalho Chehab#
392fcce37aSMauro Carvalho Chehabmy $description_is_rst = 1;
4011ce90a4SMauro Carvalho Chehab
41bbc249f2SMauro Carvalho ChehabGetOptions(
4246f661fdSMauro Carvalho Chehab	"debug=i" => \$debug,
4361439c4aSMauro Carvalho Chehab	"enable-lineno" => \$enable_lineno,
4411ce90a4SMauro Carvalho Chehab	"rst-source!" => \$description_is_rst,
4533e3e991SMauro Carvalho Chehab	"dir=s" => \$prefix,
46bbc249f2SMauro Carvalho Chehab	'help|?' => \$help,
47ab02c515SMauro Carvalho Chehab	"show-hints" => \$hint,
4814c94257SMauro Carvalho Chehab	"search-string=s" => \$search_string,
49bbc249f2SMauro Carvalho Chehab	man => \$man
50bbc249f2SMauro Carvalho Chehab) or pod2usage(2);
51bbc249f2SMauro Carvalho Chehab
52bbc249f2SMauro Carvalho Chehabpod2usage(1) if $help;
5342f09848SMauro Carvalho Chehabpod2usage(-exitstatus => 0, -noperldoc, -verbose => 2) if $man;
54bbc249f2SMauro Carvalho Chehab
5533e3e991SMauro Carvalho Chehabpod2usage(2) if (scalar @ARGV < 1 || @ARGV > 2);
56bbc249f2SMauro Carvalho Chehab
5733e3e991SMauro Carvalho Chehabmy ($cmd, $arg) = @ARGV;
5833e3e991SMauro Carvalho Chehab
59f090db43SMauro Carvalho Chehabpod2usage(2) if ($cmd ne "search" && $cmd ne "rest" && $cmd ne "validate" && $cmd ne "undefined");
6033e3e991SMauro Carvalho Chehabpod2usage(2) if ($cmd eq "search" && !$arg);
61bbc249f2SMauro Carvalho Chehab
6246f661fdSMauro Carvalho Chehabrequire Data::Dumper if ($debug & $dbg_dump_abi_structs);
63bbc249f2SMauro Carvalho Chehab
64bbc249f2SMauro Carvalho Chehabmy %data;
65234948bfSMauro Carvalho Chehabmy %symbols;
66bbc249f2SMauro Carvalho Chehab
67bbc249f2SMauro Carvalho Chehab#
68bbc249f2SMauro Carvalho Chehab# Displays an error message, printing file name and line
69bbc249f2SMauro Carvalho Chehab#
70bbc249f2SMauro Carvalho Chehabsub parse_error($$$$) {
71bbc249f2SMauro Carvalho Chehab	my ($file, $ln, $msg, $data) = @_;
72bbc249f2SMauro Carvalho Chehab
73f090db43SMauro Carvalho Chehab	return if (!$show_warnings);
74f090db43SMauro Carvalho Chehab
7575442fb0SMauro Carvalho Chehab	$data =~ s/\s+$/\n/;
7675442fb0SMauro Carvalho Chehab
7775442fb0SMauro Carvalho Chehab	print STDERR "Warning: file $file#$ln:\n\t$msg";
7875442fb0SMauro Carvalho Chehab
7975442fb0SMauro Carvalho Chehab	if ($data ne "") {
8075442fb0SMauro Carvalho Chehab		print STDERR ". Line\n\t\t$data";
8175442fb0SMauro Carvalho Chehab	} else {
8275442fb0SMauro Carvalho Chehab	    print STDERR "\n";
8375442fb0SMauro Carvalho Chehab	}
84bbc249f2SMauro Carvalho Chehab}
85bbc249f2SMauro Carvalho Chehab
86bbc249f2SMauro Carvalho Chehab#
87bbc249f2SMauro Carvalho Chehab# Parse an ABI file, storing its contents at %data
88bbc249f2SMauro Carvalho Chehab#
89bbc249f2SMauro Carvalho Chehabsub parse_abi {
90bbc249f2SMauro Carvalho Chehab	my $file = $File::Find::name;
91bbc249f2SMauro Carvalho Chehab
92bbc249f2SMauro Carvalho Chehab	my $mode = (stat($file))[2];
93bbc249f2SMauro Carvalho Chehab	return if ($mode & S_IFDIR);
94bbc249f2SMauro Carvalho Chehab	return if ($file =~ m,/README,);
95aa21a1bfSJonathan Neuschäfer	return if ($file =~ m,/\.,);
96bbc249f2SMauro Carvalho Chehab
97bbc249f2SMauro Carvalho Chehab	my $name = $file;
98bbc249f2SMauro Carvalho Chehab	$name =~ s,.*/,,;
99bbc249f2SMauro Carvalho Chehab
100a4ea67bcSMauro Carvalho Chehab	my $fn = $file;
101*7af40dfdSVegard Nossum	$fn =~ s,.*Documentation/ABI/,,;
102a4ea67bcSMauro Carvalho Chehab
103a4ea67bcSMauro Carvalho Chehab	my $nametag = "File $fn";
104d0ebaf51SMauro Carvalho Chehab	$data{$nametag}->{what} = "File $name";
105d0ebaf51SMauro Carvalho Chehab	$data{$nametag}->{type} = "File";
106d0ebaf51SMauro Carvalho Chehab	$data{$nametag}->{file} = $name;
10733e3e991SMauro Carvalho Chehab	$data{$nametag}->{filepath} = $file;
108d0ebaf51SMauro Carvalho Chehab	$data{$nametag}->{is_file} = 1;
10961439c4aSMauro Carvalho Chehab	$data{$nametag}->{line_no} = 1;
110d0ebaf51SMauro Carvalho Chehab
111bbc249f2SMauro Carvalho Chehab	my $type = $file;
112bbc249f2SMauro Carvalho Chehab	$type =~ s,.*/(.*)/.*,$1,;
113bbc249f2SMauro Carvalho Chehab
114bbc249f2SMauro Carvalho Chehab	my $what;
115bbc249f2SMauro Carvalho Chehab	my $new_what;
116234948bfSMauro Carvalho Chehab	my $tag = "";
117bbc249f2SMauro Carvalho Chehab	my $ln;
1186619c661SMauro Carvalho Chehab	my $xrefs;
1194e6a6234SMauro Carvalho Chehab	my $space;
120d0ebaf51SMauro Carvalho Chehab	my @labels;
121234948bfSMauro Carvalho Chehab	my $label = "";
122bbc249f2SMauro Carvalho Chehab
12346f661fdSMauro Carvalho Chehab	print STDERR "Opening $file\n" if ($debug & $dbg_what_open);
124bbc249f2SMauro Carvalho Chehab	open IN, $file;
125bbc249f2SMauro Carvalho Chehab	while(<IN>) {
126bbc249f2SMauro Carvalho Chehab		$ln++;
1274e6a6234SMauro Carvalho Chehab		if (m/^(\S+)(:\s*)(.*)/i) {
128bbc249f2SMauro Carvalho Chehab			my $new_tag = lc($1);
1294e6a6234SMauro Carvalho Chehab			my $sep = $2;
1304e6a6234SMauro Carvalho Chehab			my $content = $3;
131bbc249f2SMauro Carvalho Chehab
1327ce7b89bSMauro Carvalho Chehab			if (!($new_tag =~ m/(what|where|date|kernelversion|contact|description|users)/)) {
133bbc249f2SMauro Carvalho Chehab				if ($tag eq "description") {
1344e6a6234SMauro Carvalho Chehab					# New "tag" is actually part of
1354e6a6234SMauro Carvalho Chehab					# description. Don't consider it a tag
1364e6a6234SMauro Carvalho Chehab					$new_tag = "";
1377d7ea8d2SMauro Carvalho Chehab				} elsif ($tag ne "") {
138bbc249f2SMauro Carvalho Chehab					parse_error($file, $ln, "tag '$tag' is invalid", $_);
139bbc249f2SMauro Carvalho Chehab				}
140bbc249f2SMauro Carvalho Chehab			}
141bbc249f2SMauro Carvalho Chehab
1422c0700e7SMauro Carvalho Chehab			# Invalid, but it is a common mistake
1432c0700e7SMauro Carvalho Chehab			if ($new_tag eq "where") {
14475442fb0SMauro Carvalho Chehab				parse_error($file, $ln, "tag 'Where' is invalid. Should be 'What:' instead", "");
1452c0700e7SMauro Carvalho Chehab				$new_tag = "what";
1462c0700e7SMauro Carvalho Chehab			}
1472c0700e7SMauro Carvalho Chehab
148bbc249f2SMauro Carvalho Chehab			if ($new_tag =~ m/what/) {
1494e6a6234SMauro Carvalho Chehab				$space = "";
150234948bfSMauro Carvalho Chehab				$content =~ s/[,.;]$//;
151234948bfSMauro Carvalho Chehab
152c7ba3334SMauro Carvalho Chehab				push @{$symbols{$content}->{file}}, " $file:" . ($ln - 1);
153c7ba3334SMauro Carvalho Chehab
154bbc249f2SMauro Carvalho Chehab				if ($tag =~ m/what/) {
155ab9c1480SMauro Carvalho Chehab					$what .= "\xac" . $content;
156bbc249f2SMauro Carvalho Chehab				} else {
157234948bfSMauro Carvalho Chehab					if ($what) {
158234948bfSMauro Carvalho Chehab						parse_error($file, $ln, "What '$what' doesn't have a description", "") if (!$data{$what}->{description});
159234948bfSMauro Carvalho Chehab
160ab9c1480SMauro Carvalho Chehab						foreach my $w(split /\xac/, $what) {
161c7ba3334SMauro Carvalho Chehab							$symbols{$w}->{xref} = $what;
162234948bfSMauro Carvalho Chehab						};
163234948bfSMauro Carvalho Chehab					}
1644e6a6234SMauro Carvalho Chehab
165bbc249f2SMauro Carvalho Chehab					$what = $content;
166d0ebaf51SMauro Carvalho Chehab					$label = $content;
167bbc249f2SMauro Carvalho Chehab					$new_what = 1;
168bbc249f2SMauro Carvalho Chehab				}
169d0ebaf51SMauro Carvalho Chehab				push @labels, [($content, $label)];
170bbc249f2SMauro Carvalho Chehab				$tag = $new_tag;
1716619c661SMauro Carvalho Chehab
172234948bfSMauro Carvalho Chehab				push @{$data{$nametag}->{symbols}}, $content if ($data{$nametag}->{what});
173bbc249f2SMauro Carvalho Chehab				next;
174bbc249f2SMauro Carvalho Chehab			}
175bbc249f2SMauro Carvalho Chehab
1767d7ea8d2SMauro Carvalho Chehab			if ($tag ne "" && $new_tag) {
177bbc249f2SMauro Carvalho Chehab				$tag = $new_tag;
178bbc249f2SMauro Carvalho Chehab
179bbc249f2SMauro Carvalho Chehab				if ($new_what) {
180234948bfSMauro Carvalho Chehab					@{$data{$what}->{label_list}} = @labels if ($data{$nametag}->{what});
181d0ebaf51SMauro Carvalho Chehab					@labels = ();
182d0ebaf51SMauro Carvalho Chehab					$label = "";
183bbc249f2SMauro Carvalho Chehab					$new_what = 0;
184bbc249f2SMauro Carvalho Chehab
185bbc249f2SMauro Carvalho Chehab					$data{$what}->{type} = $type;
186c7ba3334SMauro Carvalho Chehab					if (!defined($data{$what}->{file})) {
187bbc249f2SMauro Carvalho Chehab						$data{$what}->{file} = $name;
18833e3e991SMauro Carvalho Chehab						$data{$what}->{filepath} = $file;
189c7ba3334SMauro Carvalho Chehab					} else {
190ff3777d0SMauro Carvalho Chehab						$data{$what}->{description} .= "\n\n" if (defined($data{$what}->{description}));
191c7ba3334SMauro Carvalho Chehab						if ($name ne $data{$what}->{file}) {
192c7ba3334SMauro Carvalho Chehab							$data{$what}->{file} .= " " . $name;
193c7ba3334SMauro Carvalho Chehab							$data{$what}->{filepath} .= " " . $file;
194c7ba3334SMauro Carvalho Chehab						}
195c7ba3334SMauro Carvalho Chehab					}
19646f661fdSMauro Carvalho Chehab					print STDERR "\twhat: $what\n" if ($debug & $dbg_what_parsing);
197c7ba3334SMauro Carvalho Chehab					$data{$what}->{line_no} = $ln;
198c7ba3334SMauro Carvalho Chehab				} else {
199c7ba3334SMauro Carvalho Chehab					$data{$what}->{line_no} = $ln if (!defined($data{$what}->{line_no}));
200bbc249f2SMauro Carvalho Chehab				}
201bbc249f2SMauro Carvalho Chehab
202bbc249f2SMauro Carvalho Chehab				if (!$what) {
203bbc249f2SMauro Carvalho Chehab					parse_error($file, $ln, "'What:' should come first:", $_);
204bbc249f2SMauro Carvalho Chehab					next;
205bbc249f2SMauro Carvalho Chehab				}
206f82a8a74SMauro Carvalho Chehab				if ($new_tag eq "description") {
207f82a8a74SMauro Carvalho Chehab					$sep =~ s,:, ,;
20811ce90a4SMauro Carvalho Chehab					$content = ' ' x length($new_tag) . $sep . $content;
209f82a8a74SMauro Carvalho Chehab					while ($content =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}
210f82a8a74SMauro Carvalho Chehab					if ($content =~ m/^(\s*)(\S.*)$/) {
211f82a8a74SMauro Carvalho Chehab						# Preserve initial spaces for the first line
21211ce90a4SMauro Carvalho Chehab						$space = $1;
213f82a8a74SMauro Carvalho Chehab						$content = "$2\n";
214f82a8a74SMauro Carvalho Chehab						$data{$what}->{$tag} .= $content;
215f82a8a74SMauro Carvalho Chehab					} else {
216f82a8a74SMauro Carvalho Chehab						undef($space);
2174e6a6234SMauro Carvalho Chehab					}
218e9bca891SMauro Carvalho Chehab
2194e6a6234SMauro Carvalho Chehab				} else {
220bbc249f2SMauro Carvalho Chehab					$data{$what}->{$tag} = $content;
2214e6a6234SMauro Carvalho Chehab				}
222bbc249f2SMauro Carvalho Chehab				next;
223bbc249f2SMauro Carvalho Chehab			}
2244e6a6234SMauro Carvalho Chehab		}
225bbc249f2SMauro Carvalho Chehab
2264e6a6234SMauro Carvalho Chehab		# Store any contents before tags at the database
227d0ebaf51SMauro Carvalho Chehab		if (!$tag && $data{$nametag}->{what}) {
228d0ebaf51SMauro Carvalho Chehab			$data{$nametag}->{description} .= $_;
2296619c661SMauro Carvalho Chehab			next;
2306619c661SMauro Carvalho Chehab		}
231bbc249f2SMauro Carvalho Chehab
2324e6a6234SMauro Carvalho Chehab		if ($tag eq "description") {
2334e6a6234SMauro Carvalho Chehab			my $content = $_;
234e9bca891SMauro Carvalho Chehab			while ($content =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}
2354e6a6234SMauro Carvalho Chehab			if (m/^\s*\n/) {
236f82a8a74SMauro Carvalho Chehab				$data{$what}->{$tag} .= "\n";
2374e6a6234SMauro Carvalho Chehab				next;
2384e6a6234SMauro Carvalho Chehab			}
2394e6a6234SMauro Carvalho Chehab
240f82a8a74SMauro Carvalho Chehab			if (!defined($space)) {
241f82a8a74SMauro Carvalho Chehab				# Preserve initial spaces for the first line
242f82a8a74SMauro Carvalho Chehab				if ($content =~ m/^(\s*)(\S.*)$/) {
243f82a8a74SMauro Carvalho Chehab					$space = $1;
244f82a8a74SMauro Carvalho Chehab					$content = "$2\n";
2454e6a6234SMauro Carvalho Chehab				}
246f82a8a74SMauro Carvalho Chehab			} else {
247f82a8a74SMauro Carvalho Chehab				$space = "" if (!($content =~ s/^($space)//));
248f82a8a74SMauro Carvalho Chehab			}
249f82a8a74SMauro Carvalho Chehab			$data{$what}->{$tag} .= $content;
250f82a8a74SMauro Carvalho Chehab
2514e6a6234SMauro Carvalho Chehab			next;
2524e6a6234SMauro Carvalho Chehab		}
253bbc249f2SMauro Carvalho Chehab		if (m/^\s*(.*)/) {
254bbc249f2SMauro Carvalho Chehab			$data{$what}->{$tag} .= "\n$1";
255bbc249f2SMauro Carvalho Chehab			$data{$what}->{$tag} =~ s/\n+$//;
256bbc249f2SMauro Carvalho Chehab			next;
257bbc249f2SMauro Carvalho Chehab		}
258bbc249f2SMauro Carvalho Chehab
259bbc249f2SMauro Carvalho Chehab		# Everything else is error
26075442fb0SMauro Carvalho Chehab		parse_error($file, $ln, "Unexpected content", $_);
261bbc249f2SMauro Carvalho Chehab	}
262234948bfSMauro Carvalho Chehab	$data{$nametag}->{description} =~ s/^\n+// if ($data{$nametag}->{description});
263234948bfSMauro Carvalho Chehab	if ($what) {
264234948bfSMauro Carvalho Chehab		parse_error($file, $ln, "What '$what' doesn't have a description", "") if (!$data{$what}->{description});
265234948bfSMauro Carvalho Chehab
266ab9c1480SMauro Carvalho Chehab		foreach my $w(split /\xac/,$what) {
267c7ba3334SMauro Carvalho Chehab			$symbols{$w}->{xref} = $what;
268234948bfSMauro Carvalho Chehab		};
269234948bfSMauro Carvalho Chehab	}
270bbc249f2SMauro Carvalho Chehab	close IN;
271bbc249f2SMauro Carvalho Chehab}
272bbc249f2SMauro Carvalho Chehab
273234948bfSMauro Carvalho Chehabsub create_labels {
274234948bfSMauro Carvalho Chehab	my %labels;
275234948bfSMauro Carvalho Chehab
276234948bfSMauro Carvalho Chehab	foreach my $what (keys %data) {
277234948bfSMauro Carvalho Chehab		next if ($data{$what}->{file} eq "File");
278234948bfSMauro Carvalho Chehab
279234948bfSMauro Carvalho Chehab		foreach my $p (@{$data{$what}->{label_list}}) {
280234948bfSMauro Carvalho Chehab			my ($content, $label) = @{$p};
281234948bfSMauro Carvalho Chehab			$label = "abi_" . $label . " ";
282234948bfSMauro Carvalho Chehab			$label =~ tr/A-Z/a-z/;
283234948bfSMauro Carvalho Chehab
284234948bfSMauro Carvalho Chehab			# Convert special chars to "_"
285234948bfSMauro Carvalho Chehab			$label =~s/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xff])/_/g;
286234948bfSMauro Carvalho Chehab			$label =~ s,_+,_,g;
287234948bfSMauro Carvalho Chehab			$label =~ s,_$,,;
288234948bfSMauro Carvalho Chehab
289234948bfSMauro Carvalho Chehab			# Avoid duplicated labels
290234948bfSMauro Carvalho Chehab			while (defined($labels{$label})) {
291234948bfSMauro Carvalho Chehab			    my @chars = ("A".."Z", "a".."z");
292234948bfSMauro Carvalho Chehab			    $label .= $chars[rand @chars];
293234948bfSMauro Carvalho Chehab			}
294234948bfSMauro Carvalho Chehab			$labels{$label} = 1;
295234948bfSMauro Carvalho Chehab
296234948bfSMauro Carvalho Chehab			$data{$what}->{label} = $label;
297234948bfSMauro Carvalho Chehab
298234948bfSMauro Carvalho Chehab			# only one label is enough
299234948bfSMauro Carvalho Chehab			last;
300234948bfSMauro Carvalho Chehab		}
301234948bfSMauro Carvalho Chehab	}
302234948bfSMauro Carvalho Chehab}
303234948bfSMauro Carvalho Chehab
30433e3e991SMauro Carvalho Chehab#
30533e3e991SMauro Carvalho Chehab# Outputs the book on ReST format
30633e3e991SMauro Carvalho Chehab#
30745f96517SMauro Carvalho Chehab
30850ebf8f4SMauro Carvalho Chehab# \b doesn't work well with paths. So, we need to define something else:
30950ebf8f4SMauro Carvalho Chehab# Boundaries are punct characters, spaces and end-of-line
31050ebf8f4SMauro Carvalho Chehabmy $start = qr {(^|\s|\() }x;
31150ebf8f4SMauro Carvalho Chehabmy $bondary = qr { ([,.:;\)\s]|\z) }x;
31287ec9ea1SMauro Carvalho Chehabmy $xref_match = qr { $start(\/(sys|config|proc|dev|kvd)\/[^,.:;\)\s]+)$bondary }x;
313b0f9580aSMauro Carvalho Chehabmy $symbols = qr { ([\x01-\x08\x0e-\x1f\x21-\x2f\x3a-\x40\x7b-\xff]) }x;
31455e5414fSMauro Carvalho Chehab
315bbc249f2SMauro Carvalho Chehabsub output_rest {
316234948bfSMauro Carvalho Chehab	create_labels();
317234948bfSMauro Carvalho Chehab
3189d4fdda3SMauro Carvalho Chehab	my $part = "";
3199d4fdda3SMauro Carvalho Chehab
32045f96517SMauro Carvalho Chehab	foreach my $what (sort {
32145f96517SMauro Carvalho Chehab				($data{$a}->{type} eq "File") cmp ($data{$b}->{type} eq "File") ||
32245f96517SMauro Carvalho Chehab				$a cmp $b
32345f96517SMauro Carvalho Chehab			       } keys %data) {
324bbc249f2SMauro Carvalho Chehab		my $type = $data{$what}->{type};
325c7ba3334SMauro Carvalho Chehab
326c7ba3334SMauro Carvalho Chehab		my @file = split / /, $data{$what}->{file};
327c7ba3334SMauro Carvalho Chehab		my @filepath = split / /, $data{$what}->{filepath};
328bbc249f2SMauro Carvalho Chehab
32961439c4aSMauro Carvalho Chehab		if ($enable_lineno) {
33092b6de17SMauro Carvalho Chehab			printf ".. LINENO %s%s#%s\n\n",
331c7ba3334SMauro Carvalho Chehab			       $prefix, $file[0],
33261439c4aSMauro Carvalho Chehab			       $data{$what}->{line_no};
33361439c4aSMauro Carvalho Chehab		}
33461439c4aSMauro Carvalho Chehab
335bbc249f2SMauro Carvalho Chehab		my $w = $what;
336bbc249f2SMauro Carvalho Chehab
337c7ba3334SMauro Carvalho Chehab		if ($type ne "File") {
3389d4fdda3SMauro Carvalho Chehab			my $cur_part = $what;
3399d4fdda3SMauro Carvalho Chehab			if ($what =~ '/') {
3409d4fdda3SMauro Carvalho Chehab				if ($what =~ m#^(\/?(?:[\w\-]+\/?){1,2})#) {
3419d4fdda3SMauro Carvalho Chehab					$cur_part = "Symbols under $1";
3429d4fdda3SMauro Carvalho Chehab					$cur_part =~ s,/$,,;
3439d4fdda3SMauro Carvalho Chehab				}
3449d4fdda3SMauro Carvalho Chehab			}
3459d4fdda3SMauro Carvalho Chehab
3469d4fdda3SMauro Carvalho Chehab			if ($cur_part ne "" && $part ne $cur_part) {
3479d4fdda3SMauro Carvalho Chehab			    $part = $cur_part;
3489d4fdda3SMauro Carvalho Chehab			    my $bar = $part;
3499d4fdda3SMauro Carvalho Chehab			    $bar =~ s/./-/g;
3509d4fdda3SMauro Carvalho Chehab			    print "$part\n$bar\n\n";
3519d4fdda3SMauro Carvalho Chehab			}
3529d4fdda3SMauro Carvalho Chehab
353234948bfSMauro Carvalho Chehab			printf ".. _%s:\n\n", $data{$what}->{label};
35445f96517SMauro Carvalho Chehab
355ab9c1480SMauro Carvalho Chehab			my @names = split /\xac/,$w;
35645f96517SMauro Carvalho Chehab			my $len = 0;
35745f96517SMauro Carvalho Chehab
35845f96517SMauro Carvalho Chehab			foreach my $name (@names) {
359b0f9580aSMauro Carvalho Chehab				$name =~ s/$symbols/\\$1/g;
360c01d62d3SMauro Carvalho Chehab				$name = "**$name**";
36145f96517SMauro Carvalho Chehab				$len = length($name) if (length($name) > $len);
36245f96517SMauro Carvalho Chehab			}
36345f96517SMauro Carvalho Chehab
36445f96517SMauro Carvalho Chehab			print "+-" . "-" x $len . "-+\n";
36545f96517SMauro Carvalho Chehab			foreach my $name (@names) {
36645f96517SMauro Carvalho Chehab				printf "| %s", $name . " " x ($len - length($name)) . " |\n";
36745f96517SMauro Carvalho Chehab				print "+-" . "-" x $len . "-+\n";
36845f96517SMauro Carvalho Chehab			}
369234948bfSMauro Carvalho Chehab
370c7ba3334SMauro Carvalho Chehab			print "\n";
371c7ba3334SMauro Carvalho Chehab		}
372c7ba3334SMauro Carvalho Chehab
373c7ba3334SMauro Carvalho Chehab		for (my $i = 0; $i < scalar(@filepath); $i++) {
374c7ba3334SMauro Carvalho Chehab			my $path = $filepath[$i];
375c7ba3334SMauro Carvalho Chehab			my $f = $file[$i];
376c7ba3334SMauro Carvalho Chehab
377c7ba3334SMauro Carvalho Chehab			$path =~ s,.*/(.*/.*),$1,;;
378c7ba3334SMauro Carvalho Chehab			$path =~ s,[/\-],_,g;;
379c7ba3334SMauro Carvalho Chehab			my $fileref = "abi_file_".$path;
380c7ba3334SMauro Carvalho Chehab
381c7ba3334SMauro Carvalho Chehab			if ($type eq "File") {
382c7ba3334SMauro Carvalho Chehab				print ".. _$fileref:\n\n";
383c7ba3334SMauro Carvalho Chehab			} else {
384c7ba3334SMauro Carvalho Chehab				print "Defined on file :ref:`$f <$fileref>`\n\n";
385c7ba3334SMauro Carvalho Chehab			}
38645f96517SMauro Carvalho Chehab		}
38745f96517SMauro Carvalho Chehab
388a4ea67bcSMauro Carvalho Chehab		if ($type eq "File") {
389a4ea67bcSMauro Carvalho Chehab			my $bar = $w;
390a4ea67bcSMauro Carvalho Chehab			$bar =~ s/./-/g;
391a4ea67bcSMauro Carvalho Chehab			print "$w\n$bar\n\n";
392a4ea67bcSMauro Carvalho Chehab		}
393a4ea67bcSMauro Carvalho Chehab
394234948bfSMauro Carvalho Chehab		my $desc = "";
395234948bfSMauro Carvalho Chehab		$desc = $data{$what}->{description} if (defined($data{$what}->{description}));
396234948bfSMauro Carvalho Chehab		$desc =~ s/\s+$/\n/;
39711ce90a4SMauro Carvalho Chehab
39811ce90a4SMauro Carvalho Chehab		if (!($desc =~ /^\s*$/)) {
39911ce90a4SMauro Carvalho Chehab			if ($description_is_rst) {
400daaaf58aSMauro Carvalho Chehab				# Remove title markups from the description
401daaaf58aSMauro Carvalho Chehab				# Having titles inside ABI files will only work if extra
402daaaf58aSMauro Carvalho Chehab				# care would be taken in order to strictly follow the same
403daaaf58aSMauro Carvalho Chehab				# level order for each markup.
404daaaf58aSMauro Carvalho Chehab				$desc =~ s/\n[\-\*\=\^\~]+\n/\n\n/g;
405daaaf58aSMauro Carvalho Chehab
40655e5414fSMauro Carvalho Chehab				# Enrich text by creating cross-references
40755e5414fSMauro Carvalho Chehab
408c27c2e34SMauro Carvalho Chehab				my $new_desc = "";
4092ae7bb57SMauro Carvalho Chehab				my $init_indent = -1;
4102ae7bb57SMauro Carvalho Chehab				my $literal_indent = -1;
4112ae7bb57SMauro Carvalho Chehab
412c27c2e34SMauro Carvalho Chehab				open(my $fh, "+<", \$desc);
413c27c2e34SMauro Carvalho Chehab				while (my $d = <$fh>) {
4142ae7bb57SMauro Carvalho Chehab					my $indent = $d =~ m/^(\s+)/;
4152ae7bb57SMauro Carvalho Chehab					my $spaces = length($indent);
4162ae7bb57SMauro Carvalho Chehab					$init_indent = $indent if ($init_indent < 0);
4172ae7bb57SMauro Carvalho Chehab					if ($literal_indent >= 0) {
4182ae7bb57SMauro Carvalho Chehab						if ($spaces > $literal_indent) {
4192ae7bb57SMauro Carvalho Chehab							$new_desc .= $d;
4202ae7bb57SMauro Carvalho Chehab							next;
4212ae7bb57SMauro Carvalho Chehab						} else {
4222ae7bb57SMauro Carvalho Chehab							$literal_indent = -1;
4232ae7bb57SMauro Carvalho Chehab						}
4242ae7bb57SMauro Carvalho Chehab					} else {
4252ae7bb57SMauro Carvalho Chehab						if ($d =~ /()::$/ && !($d =~ /^\s*\.\./)) {
4262ae7bb57SMauro Carvalho Chehab							$literal_indent = $spaces;
4272ae7bb57SMauro Carvalho Chehab						}
4282ae7bb57SMauro Carvalho Chehab					}
4292ae7bb57SMauro Carvalho Chehab
430c27c2e34SMauro Carvalho Chehab					$d =~ s,Documentation/(?!devicetree)(\S+)\.rst,:doc:`/$1`,g;
43155e5414fSMauro Carvalho Chehab
432c27c2e34SMauro Carvalho Chehab					my @matches = $d =~ m,Documentation/ABI/([\w\/\-]+),g;
43355e5414fSMauro Carvalho Chehab					foreach my $f (@matches) {
43455e5414fSMauro Carvalho Chehab						my $xref = $f;
43555e5414fSMauro Carvalho Chehab						my $path = $f;
43655e5414fSMauro Carvalho Chehab						$path =~ s,.*/(.*/.*),$1,;;
43755e5414fSMauro Carvalho Chehab						$path =~ s,[/\-],_,g;;
43855e5414fSMauro Carvalho Chehab						$xref .= " <abi_file_" . $path . ">";
439c27c2e34SMauro Carvalho Chehab						$d =~ s,\bDocumentation/ABI/$f\b,:ref:`$xref`,g;
44055e5414fSMauro Carvalho Chehab					}
44155e5414fSMauro Carvalho Chehab
44250ebf8f4SMauro Carvalho Chehab					# Seek for cross reference symbols like /sys/...
443c27c2e34SMauro Carvalho Chehab					@matches = $d =~ m/$xref_match/g;
44455e5414fSMauro Carvalho Chehab
44555e5414fSMauro Carvalho Chehab					foreach my $s (@matches) {
44650ebf8f4SMauro Carvalho Chehab						next if (!($s =~ m,/,));
44755e5414fSMauro Carvalho Chehab						if (defined($data{$s}) && defined($data{$s}->{label})) {
44855e5414fSMauro Carvalho Chehab							my $xref = $s;
44955e5414fSMauro Carvalho Chehab
450b0f9580aSMauro Carvalho Chehab							$xref =~ s/$symbols/\\$1/g;
45155e5414fSMauro Carvalho Chehab							$xref = ":ref:`$xref <" . $data{$s}->{label} . ">`";
45255e5414fSMauro Carvalho Chehab
453c27c2e34SMauro Carvalho Chehab							$d =~ s,$start$s$bondary,$1$xref$2,g;
45455e5414fSMauro Carvalho Chehab						}
45555e5414fSMauro Carvalho Chehab					}
456c27c2e34SMauro Carvalho Chehab					$new_desc .= $d;
457c27c2e34SMauro Carvalho Chehab				}
458c27c2e34SMauro Carvalho Chehab				close $fh;
45955e5414fSMauro Carvalho Chehab
460c27c2e34SMauro Carvalho Chehab
461c27c2e34SMauro Carvalho Chehab				print "$new_desc\n\n";
46211ce90a4SMauro Carvalho Chehab			} else {
463bbc249f2SMauro Carvalho Chehab				$desc =~ s/^\s+//;
464bbc249f2SMauro Carvalho Chehab
465bbc249f2SMauro Carvalho Chehab				# Remove title markups from the description, as they won't work
46611ce90a4SMauro Carvalho Chehab				$desc =~ s/\n[\-\*\=\^\~]+\n/\n\n/g;
467bbc249f2SMauro Carvalho Chehab
4684e6a6234SMauro Carvalho Chehab				if ($desc =~ m/\:\n/ || $desc =~ m/\n[\t ]+/  || $desc =~ m/[\x00-\x08\x0b-\x1f\x7b-\xff]/) {
469bbc249f2SMauro Carvalho Chehab					# put everything inside a code block
470bbc249f2SMauro Carvalho Chehab					$desc =~ s/\n/\n /g;
471bbc249f2SMauro Carvalho Chehab
4724e6a6234SMauro Carvalho Chehab					print "::\n\n";
473bbc249f2SMauro Carvalho Chehab					print " $desc\n\n";
474bbc249f2SMauro Carvalho Chehab				} else {
4754e6a6234SMauro Carvalho Chehab					# Escape any special chars from description
4764e6a6234SMauro Carvalho Chehab					$desc =~s/([\x00-\x08\x0b-\x1f\x21-\x2a\x2d\x2f\x3c-\x40\x5c\x5e-\x60\x7b-\xff])/\\$1/g;
4774e6a6234SMauro Carvalho Chehab					print "$desc\n\n";
4784e6a6234SMauro Carvalho Chehab				}
47911ce90a4SMauro Carvalho Chehab			}
4804e6a6234SMauro Carvalho Chehab		} else {
481d0ebaf51SMauro Carvalho Chehab			print "DESCRIPTION MISSING for $what\n\n" if (!$data{$what}->{is_file});
482bbc249f2SMauro Carvalho Chehab		}
4836619c661SMauro Carvalho Chehab
484234948bfSMauro Carvalho Chehab		if ($data{$what}->{symbols}) {
485d0ebaf51SMauro Carvalho Chehab			printf "Has the following ABI:\n\n";
486d0ebaf51SMauro Carvalho Chehab
487234948bfSMauro Carvalho Chehab			foreach my $content(@{$data{$what}->{symbols}}) {
488c7ba3334SMauro Carvalho Chehab				my $label = $data{$symbols{$content}->{xref}}->{label};
489d0ebaf51SMauro Carvalho Chehab
490d0ebaf51SMauro Carvalho Chehab				# Escape special chars from content
491d0ebaf51SMauro Carvalho Chehab				$content =~s/([\x00-\x1f\x21-\x2f\x3a-\x40\x7b-\xff])/\\$1/g;
492d0ebaf51SMauro Carvalho Chehab
493d0ebaf51SMauro Carvalho Chehab				print "- :ref:`$content <$label>`\n\n";
494d0ebaf51SMauro Carvalho Chehab			}
495d0ebaf51SMauro Carvalho Chehab		}
496a16ab14eSMauro Carvalho Chehab
497a16ab14eSMauro Carvalho Chehab		if (defined($data{$what}->{users})) {
498a16ab14eSMauro Carvalho Chehab			my $users = $data{$what}->{users};
499a16ab14eSMauro Carvalho Chehab
500a16ab14eSMauro Carvalho Chehab			$users =~ s/\n/\n\t/g;
501a16ab14eSMauro Carvalho Chehab			printf "Users:\n\t%s\n\n", $users if ($users ne "");
502a16ab14eSMauro Carvalho Chehab		}
503a16ab14eSMauro Carvalho Chehab
504bbc249f2SMauro Carvalho Chehab	}
505bbc249f2SMauro Carvalho Chehab}
506bbc249f2SMauro Carvalho Chehab
507bbc249f2SMauro Carvalho Chehab#
50833e3e991SMauro Carvalho Chehab# Searches for ABI symbols
50933e3e991SMauro Carvalho Chehab#
51033e3e991SMauro Carvalho Chehabsub search_symbols {
51133e3e991SMauro Carvalho Chehab	foreach my $what (sort keys %data) {
51233e3e991SMauro Carvalho Chehab		next if (!($what =~ m/($arg)/));
51333e3e991SMauro Carvalho Chehab
51433e3e991SMauro Carvalho Chehab		my $type = $data{$what}->{type};
51533e3e991SMauro Carvalho Chehab		next if ($type eq "File");
51633e3e991SMauro Carvalho Chehab
51733e3e991SMauro Carvalho Chehab		my $file = $data{$what}->{filepath};
51833e3e991SMauro Carvalho Chehab
519e27c42a5SMauro Carvalho Chehab		$what =~ s/\xac/, /g;
52033e3e991SMauro Carvalho Chehab		my $bar = $what;
52133e3e991SMauro Carvalho Chehab		$bar =~ s/./-/g;
52233e3e991SMauro Carvalho Chehab
52333e3e991SMauro Carvalho Chehab		print "\n$what\n$bar\n\n";
52433e3e991SMauro Carvalho Chehab
525234948bfSMauro Carvalho Chehab		my $kernelversion = $data{$what}->{kernelversion} if (defined($data{$what}->{kernelversion}));
526234948bfSMauro Carvalho Chehab		my $contact = $data{$what}->{contact} if (defined($data{$what}->{contact}));
527234948bfSMauro Carvalho Chehab		my $users = $data{$what}->{users} if (defined($data{$what}->{users}));
528234948bfSMauro Carvalho Chehab		my $date = $data{$what}->{date} if (defined($data{$what}->{date}));
529234948bfSMauro Carvalho Chehab		my $desc = $data{$what}->{description} if (defined($data{$what}->{description}));
530234948bfSMauro Carvalho Chehab
531234948bfSMauro Carvalho Chehab		$kernelversion =~ s/^\s+// if ($kernelversion);
532234948bfSMauro Carvalho Chehab		$contact =~ s/^\s+// if ($contact);
533234948bfSMauro Carvalho Chehab		if ($users) {
53433e3e991SMauro Carvalho Chehab			$users =~ s/^\s+//;
53533e3e991SMauro Carvalho Chehab			$users =~ s/\n//g;
536234948bfSMauro Carvalho Chehab		}
537234948bfSMauro Carvalho Chehab		$date =~ s/^\s+// if ($date);
538234948bfSMauro Carvalho Chehab		$desc =~ s/^\s+// if ($desc);
53933e3e991SMauro Carvalho Chehab
54033e3e991SMauro Carvalho Chehab		printf "Kernel version:\t\t%s\n", $kernelversion if ($kernelversion);
54133e3e991SMauro Carvalho Chehab		printf "Date:\t\t\t%s\n", $date if ($date);
54233e3e991SMauro Carvalho Chehab		printf "Contact:\t\t%s\n", $contact if ($contact);
54333e3e991SMauro Carvalho Chehab		printf "Users:\t\t\t%s\n", $users if ($users);
544c7ba3334SMauro Carvalho Chehab		print "Defined on file(s):\t$file\n\n";
54533e3e991SMauro Carvalho Chehab		print "Description:\n\n$desc";
54633e3e991SMauro Carvalho Chehab	}
54733e3e991SMauro Carvalho Chehab}
54833e3e991SMauro Carvalho Chehab
549f090db43SMauro Carvalho Chehab# Exclude /sys/kernel/debug and /sys/kernel/tracing from the search path
550ab02c515SMauro Carvalho Chehabsub dont_parse_special_attributes {
551f090db43SMauro Carvalho Chehab	if (($File::Find::dir =~ m,^/sys/kernel,)) {
552f090db43SMauro Carvalho Chehab		return grep {!/(debug|tracing)/ } @_;
553f090db43SMauro Carvalho Chehab	}
554f090db43SMauro Carvalho Chehab
555f090db43SMauro Carvalho Chehab	if (($File::Find::dir =~ m,^/sys/fs,)) {
556f090db43SMauro Carvalho Chehab		return grep {!/(pstore|bpf|fuse)/ } @_;
557f090db43SMauro Carvalho Chehab	}
558f090db43SMauro Carvalho Chehab
559f090db43SMauro Carvalho Chehab	return @_
560f090db43SMauro Carvalho Chehab}
561f090db43SMauro Carvalho Chehab
562f090db43SMauro Carvalho Chehabmy %leaf;
563ab02c515SMauro Carvalho Chehabmy %aliases;
564ab02c515SMauro Carvalho Chehabmy @files;
565ca8e055cSMauro Carvalho Chehabmy %root;
566ca8e055cSMauro Carvalho Chehab
567ca8e055cSMauro Carvalho Chehabsub graph_add_file {
568ca8e055cSMauro Carvalho Chehab	my $file = shift;
569ca8e055cSMauro Carvalho Chehab	my $type = shift;
570ca8e055cSMauro Carvalho Chehab
571ca8e055cSMauro Carvalho Chehab	my $dir = $file;
572ca8e055cSMauro Carvalho Chehab	$dir =~ s,^(.*/).*,$1,;
573ca8e055cSMauro Carvalho Chehab	$file =~ s,.*/,,;
574ca8e055cSMauro Carvalho Chehab
575ca8e055cSMauro Carvalho Chehab	my $name;
576ca8e055cSMauro Carvalho Chehab	my $file_ref = \%root;
577ca8e055cSMauro Carvalho Chehab	foreach my $edge(split "/", $dir) {
578ca8e055cSMauro Carvalho Chehab		$name .= "$edge/";
579ca8e055cSMauro Carvalho Chehab		if (!defined ${$file_ref}{$edge}) {
580ca8e055cSMauro Carvalho Chehab			${$file_ref}{$edge} = { };
581ca8e055cSMauro Carvalho Chehab		}
582ca8e055cSMauro Carvalho Chehab		$file_ref = \%{$$file_ref{$edge}};
583ca8e055cSMauro Carvalho Chehab		${$file_ref}{"__name"} = [ $name ];
584ca8e055cSMauro Carvalho Chehab	}
585ca8e055cSMauro Carvalho Chehab	$name .= "$file";
586ca8e055cSMauro Carvalho Chehab	${$file_ref}{$file} = {
587ca8e055cSMauro Carvalho Chehab		"__name" => [ $name ]
588ca8e055cSMauro Carvalho Chehab	};
589ca8e055cSMauro Carvalho Chehab
590ca8e055cSMauro Carvalho Chehab	return \%{$$file_ref{$file}};
591ca8e055cSMauro Carvalho Chehab}
592ca8e055cSMauro Carvalho Chehab
593ca8e055cSMauro Carvalho Chehabsub graph_add_link {
594ca8e055cSMauro Carvalho Chehab	my $file = shift;
595ca8e055cSMauro Carvalho Chehab	my $link = shift;
596ca8e055cSMauro Carvalho Chehab
597ca8e055cSMauro Carvalho Chehab	# Traverse graph to find the reference
598ca8e055cSMauro Carvalho Chehab	my $file_ref = \%root;
599ca8e055cSMauro Carvalho Chehab	foreach my $edge(split "/", $file) {
600ca8e055cSMauro Carvalho Chehab		$file_ref = \%{$$file_ref{$edge}} || die "Missing node!";
601ca8e055cSMauro Carvalho Chehab	}
602ca8e055cSMauro Carvalho Chehab
603ca8e055cSMauro Carvalho Chehab	# do a BFS
604ca8e055cSMauro Carvalho Chehab
605ca8e055cSMauro Carvalho Chehab	my @queue;
606ca8e055cSMauro Carvalho Chehab	my %seen;
607ca8e055cSMauro Carvalho Chehab	my $st;
608ca8e055cSMauro Carvalho Chehab
609ca8e055cSMauro Carvalho Chehab	push @queue, $file_ref;
610ca8e055cSMauro Carvalho Chehab	$seen{$start}++;
611ca8e055cSMauro Carvalho Chehab
612ca8e055cSMauro Carvalho Chehab	while (@queue) {
613ca8e055cSMauro Carvalho Chehab		my $v = shift @queue;
614ca8e055cSMauro Carvalho Chehab		my @child = keys(%{$v});
615ca8e055cSMauro Carvalho Chehab
616ca8e055cSMauro Carvalho Chehab		foreach my $c(@child) {
617ca8e055cSMauro Carvalho Chehab			next if $seen{$$v{$c}};
618ca8e055cSMauro Carvalho Chehab			next if ($c eq "__name");
619ca8e055cSMauro Carvalho Chehab
6203a1cc06cSMauro Carvalho Chehab			if (!defined($$v{$c}{"__name"})) {
6213a1cc06cSMauro Carvalho Chehab				printf STDERR "Error: Couldn't find a non-empty name on a children of $file/.*: ";
6223a1cc06cSMauro Carvalho Chehab				print STDERR Dumper(%{$v});
6233a1cc06cSMauro Carvalho Chehab				exit;
6243a1cc06cSMauro Carvalho Chehab			}
6253a1cc06cSMauro Carvalho Chehab
626ca8e055cSMauro Carvalho Chehab			# Add new name
627ca8e055cSMauro Carvalho Chehab			my $name = @{$$v{$c}{"__name"}}[0];
628ca8e055cSMauro Carvalho Chehab			if ($name =~ s#^$file/#$link/#) {
629ca8e055cSMauro Carvalho Chehab				push @{$$v{$c}{"__name"}}, $name;
630ca8e055cSMauro Carvalho Chehab			}
631ca8e055cSMauro Carvalho Chehab			# Add child to the queue and mark as seen
632ca8e055cSMauro Carvalho Chehab			push @queue, $$v{$c};
633ca8e055cSMauro Carvalho Chehab			$seen{$c}++;
634ca8e055cSMauro Carvalho Chehab		}
635ca8e055cSMauro Carvalho Chehab	}
636ca8e055cSMauro Carvalho Chehab}
637f090db43SMauro Carvalho Chehab
638ab02c515SMauro Carvalho Chehabmy $escape_symbols = qr { ([\x01-\x08\x0e-\x1f\x21-\x29\x2b-\x2d\x3a-\x40\x7b-\xfe]) }x;
639f090db43SMauro Carvalho Chehabsub parse_existing_sysfs {
640f090db43SMauro Carvalho Chehab	my $file = $File::Find::name;
6410b87a1b8SMauro Carvalho Chehab
64287b58c6fSMauro Carvalho Chehab	my $mode = (lstat($file))[2];
64387b58c6fSMauro Carvalho Chehab	my $abs_file = abs_path($file);
6440b87a1b8SMauro Carvalho Chehab
64587b58c6fSMauro Carvalho Chehab	my @tmp;
64687b58c6fSMauro Carvalho Chehab	push @tmp, $file;
64787b58c6fSMauro Carvalho Chehab	push @tmp, $abs_file if ($abs_file ne $file);
64887b58c6fSMauro Carvalho Chehab
64987b58c6fSMauro Carvalho Chehab	foreach my $f(@tmp) {
65087b58c6fSMauro Carvalho Chehab		# Ignore cgroup, as this is big and has zero docs under ABI
65187b58c6fSMauro Carvalho Chehab		return if ($f =~ m#^/sys/fs/cgroup/#);
65287b58c6fSMauro Carvalho Chehab
65387b58c6fSMauro Carvalho Chehab		# Ignore firmware as it is documented elsewhere
65487b58c6fSMauro Carvalho Chehab		# Either ACPI or under Documentation/devicetree/bindings/
65587b58c6fSMauro Carvalho Chehab		return if ($f =~ m#^/sys/firmware/#);
65687b58c6fSMauro Carvalho Chehab
65787b58c6fSMauro Carvalho Chehab		# Ignore some sysfs nodes that aren't actually part of ABI
65887b58c6fSMauro Carvalho Chehab		return if ($f =~ m#/sections|notes/#);
6590cd9e25bSMauro Carvalho Chehab
6600cd9e25bSMauro Carvalho Chehab		# Would need to check at
6610cd9e25bSMauro Carvalho Chehab		# Documentation/admin-guide/kernel-parameters.txt, but this
6620cd9e25bSMauro Carvalho Chehab		# is not easily parseable.
66387b58c6fSMauro Carvalho Chehab		return if ($f =~ m#/parameters/#);
66487b58c6fSMauro Carvalho Chehab	}
665f090db43SMauro Carvalho Chehab
666ab02c515SMauro Carvalho Chehab	if (S_ISLNK($mode)) {
667ab02c515SMauro Carvalho Chehab		$aliases{$file} = $abs_file;
668ab02c515SMauro Carvalho Chehab		return;
669ab02c515SMauro Carvalho Chehab	}
670ab02c515SMauro Carvalho Chehab
671ab02c515SMauro Carvalho Chehab	return if (S_ISDIR($mode));
672ab02c515SMauro Carvalho Chehab
673ab02c515SMauro Carvalho Chehab	# Trivial: file is defined exactly the same way at ABI What:
674ab02c515SMauro Carvalho Chehab	return if (defined($data{$file}));
675ab02c515SMauro Carvalho Chehab	return if (defined($data{$abs_file}));
676ab02c515SMauro Carvalho Chehab
677ca8e055cSMauro Carvalho Chehab	push @files, graph_add_file($abs_file, "file");
678ca8e055cSMauro Carvalho Chehab}
679ca8e055cSMauro Carvalho Chehab
680ca8e055cSMauro Carvalho Chehabsub get_leave($)
681ca8e055cSMauro Carvalho Chehab{
682ca8e055cSMauro Carvalho Chehab	my $what = shift;
683ca8e055cSMauro Carvalho Chehab	my $leave;
684ca8e055cSMauro Carvalho Chehab
685ca8e055cSMauro Carvalho Chehab	my $l = $what;
686ca8e055cSMauro Carvalho Chehab	my $stop = 1;
687ca8e055cSMauro Carvalho Chehab
688ca8e055cSMauro Carvalho Chehab	$leave = $l;
689ca8e055cSMauro Carvalho Chehab	$leave =~ s,/$,,;
690ca8e055cSMauro Carvalho Chehab	$leave =~ s,.*/,,;
691ca8e055cSMauro Carvalho Chehab	$leave =~ s/[\(\)]//g;
692ca8e055cSMauro Carvalho Chehab
693ca8e055cSMauro Carvalho Chehab	# $leave is used to improve search performance at
694ca8e055cSMauro Carvalho Chehab	# check_undefined_symbols, as the algorithm there can seek
695ca8e055cSMauro Carvalho Chehab	# for a small number of "what". It also allows giving a
696ca8e055cSMauro Carvalho Chehab	# hint about a leave with the same name somewhere else.
697ca8e055cSMauro Carvalho Chehab	# However, there are a few occurences where the leave is
698ca8e055cSMauro Carvalho Chehab	# either a wildcard or a number. Just group such cases
699ca8e055cSMauro Carvalho Chehab	# altogether.
70092635894SMauro Carvalho Chehab	if ($leave =~ m/\.\*/ || $leave eq "" || $leave =~ /\\d/) {
701ca8e055cSMauro Carvalho Chehab		$leave = "others";
702ca8e055cSMauro Carvalho Chehab	}
703ca8e055cSMauro Carvalho Chehab
704ca8e055cSMauro Carvalho Chehab	return $leave;
705ab02c515SMauro Carvalho Chehab}
706ab02c515SMauro Carvalho Chehab
70728331a01SMauro Carvalho Chehabmy @not_found;
70828331a01SMauro Carvalho Chehab
70928331a01SMauro Carvalho Chehabsub check_file($$)
71028331a01SMauro Carvalho Chehab{
71128331a01SMauro Carvalho Chehab	my $file_ref = shift;
71228331a01SMauro Carvalho Chehab	my $names_ref = shift;
71328331a01SMauro Carvalho Chehab	my @names = @{$names_ref};
714ca8e055cSMauro Carvalho Chehab	my $file = $names[0];
715ab02c515SMauro Carvalho Chehab
71614c94257SMauro Carvalho Chehab	my $found_string;
717f090db43SMauro Carvalho Chehab
718ca8e055cSMauro Carvalho Chehab	my $leave = get_leave($file);
719ca8e055cSMauro Carvalho Chehab	if (!defined($leaf{$leave})) {
720ca8e055cSMauro Carvalho Chehab		$leave = "others";
721ca8e055cSMauro Carvalho Chehab	}
722f34f6729SMauro Carvalho Chehab	my @expr = @{$leaf{$leave}->{expr}};
72328331a01SMauro Carvalho Chehab	die ("\rmissing rules for $leave") if (!defined($leaf{$leave}));
724f090db43SMauro Carvalho Chehab
725ab02c515SMauro Carvalho Chehab	my $path = $file;
726ab02c515SMauro Carvalho Chehab	$path =~ s,(.*/).*,$1,;
727ab02c515SMauro Carvalho Chehab
72814c94257SMauro Carvalho Chehab	if ($search_string) {
72928331a01SMauro Carvalho Chehab		return if (!($file =~ m#$search_string#));
73014c94257SMauro Carvalho Chehab		$found_string = 1;
73114c94257SMauro Carvalho Chehab	}
73214c94257SMauro Carvalho Chehab
733f34f6729SMauro Carvalho Chehab	for (my $i = 0; $i < @names; $i++) {
734f34f6729SMauro Carvalho Chehab		if ($found_string && $hint) {
735f34f6729SMauro Carvalho Chehab			if (!$i) {
7362833e30aSMauro Carvalho Chehab				print STDERR "--> $names[$i]\n";
737f34f6729SMauro Carvalho Chehab			} else {
7382833e30aSMauro Carvalho Chehab				print STDERR "    $names[$i]\n";
739f34f6729SMauro Carvalho Chehab			}
740f34f6729SMauro Carvalho Chehab		}
741f34f6729SMauro Carvalho Chehab		foreach my $re (@expr) {
74228331a01SMauro Carvalho Chehab			print STDERR "$names[$i] =~ /^$re\$/\n" if ($debug && $dbg_undefined);
743f34f6729SMauro Carvalho Chehab			if ($names[$i] =~ $re) {
74428331a01SMauro Carvalho Chehab				return;
745ab02c515SMauro Carvalho Chehab			}
746ab02c515SMauro Carvalho Chehab		}
747f090db43SMauro Carvalho Chehab	}
748f090db43SMauro Carvalho Chehab
749d4771993SMauro Carvalho Chehab	if ($leave ne "others") {
7504dcce5b0SMauro Carvalho Chehab		my @expr = @{$leaf{"others"}->{expr}};
751d4771993SMauro Carvalho Chehab		for (my $i = 0; $i < @names; $i++) {
752d4771993SMauro Carvalho Chehab			foreach my $re (@expr) {
75328331a01SMauro Carvalho Chehab				print STDERR "$names[$i] =~ /^$re\$/\n" if ($debug && $dbg_undefined);
754d4771993SMauro Carvalho Chehab				if ($names[$i] =~ $re) {
75528331a01SMauro Carvalho Chehab					return;
756d4771993SMauro Carvalho Chehab				}
757d4771993SMauro Carvalho Chehab			}
758d4771993SMauro Carvalho Chehab		}
759d4771993SMauro Carvalho Chehab	}
760d4771993SMauro Carvalho Chehab
76128331a01SMauro Carvalho Chehab	push @not_found, $file if (!$search_string || $found_string);
7622833e30aSMauro Carvalho Chehab
763cb06b8ddSMauro Carvalho Chehab	if ($hint && (!$search_string || $found_string)) {
764f34f6729SMauro Carvalho Chehab		my $what = $leaf{$leave}->{what};
765ca8e055cSMauro Carvalho Chehab		$what =~ s/\xac/\n\t/g;
766ca8e055cSMauro Carvalho Chehab		if ($leave ne "others") {
76728331a01SMauro Carvalho Chehab			print STDERR "\r    more likely regexes:\n\t$what\n";
768ca8e055cSMauro Carvalho Chehab		} else {
76928331a01SMauro Carvalho Chehab			print STDERR "\r    tested regexes:\n\t$what\n";
770ab02c515SMauro Carvalho Chehab		}
771f090db43SMauro Carvalho Chehab	}
772ab02c515SMauro Carvalho Chehab}
773f090db43SMauro Carvalho Chehab
77428331a01SMauro Carvalho Chehabsub check_undefined_symbols {
77528331a01SMauro Carvalho Chehab	my $num_files = scalar @files;
77628331a01SMauro Carvalho Chehab	my $next_i = 0;
77728331a01SMauro Carvalho Chehab	my $start_time = times;
77828331a01SMauro Carvalho Chehab
779e5c044c8SMauro Carvalho Chehab	@files = sort @files;
780e5c044c8SMauro Carvalho Chehab
78128331a01SMauro Carvalho Chehab	my $last_time = $start_time;
78228331a01SMauro Carvalho Chehab
78328331a01SMauro Carvalho Chehab	# When either debug or hint is enabled, there's no sense showing
78428331a01SMauro Carvalho Chehab	# progress, as the progress will be overriden.
78528331a01SMauro Carvalho Chehab	if ($hint || ($debug && $dbg_undefined)) {
78628331a01SMauro Carvalho Chehab		$next_i = $num_files;
78728331a01SMauro Carvalho Chehab	}
78828331a01SMauro Carvalho Chehab
78928331a01SMauro Carvalho Chehab	my $is_console;
79028331a01SMauro Carvalho Chehab	$is_console = 1 if (-t STDERR);
79128331a01SMauro Carvalho Chehab
79228331a01SMauro Carvalho Chehab	for (my $i = 0; $i < $num_files; $i++) {
79328331a01SMauro Carvalho Chehab		my $file_ref = $files[$i];
79428331a01SMauro Carvalho Chehab		my @names = @{$$file_ref{"__name"}};
79528331a01SMauro Carvalho Chehab
79628331a01SMauro Carvalho Chehab		check_file($file_ref, \@names);
79728331a01SMauro Carvalho Chehab
79828331a01SMauro Carvalho Chehab		my $cur_time = times;
79928331a01SMauro Carvalho Chehab
80028331a01SMauro Carvalho Chehab		if ($i == $next_i || $cur_time > $last_time + 1) {
80128331a01SMauro Carvalho Chehab			my $percent = $i * 100 / $num_files;
80228331a01SMauro Carvalho Chehab
80328331a01SMauro Carvalho Chehab			my $tm = $cur_time - $start_time;
80428331a01SMauro Carvalho Chehab			my $time = sprintf "%d:%02d", int($tm), 60 * ($tm - int($tm));
80528331a01SMauro Carvalho Chehab
80628331a01SMauro Carvalho Chehab			printf STDERR "\33[2K\r", if ($is_console);
80728331a01SMauro Carvalho Chehab			printf STDERR "%s: processing sysfs files... %i%%: $names[0]", $time, $percent;
80828331a01SMauro Carvalho Chehab			printf STDERR "\n", if (!$is_console);
80928331a01SMauro Carvalho Chehab			STDERR->flush();
81028331a01SMauro Carvalho Chehab
81128331a01SMauro Carvalho Chehab			$next_i = int (($percent + 1) * $num_files / 100);
81228331a01SMauro Carvalho Chehab			$last_time = $cur_time;
81328331a01SMauro Carvalho Chehab		}
81428331a01SMauro Carvalho Chehab	}
81528331a01SMauro Carvalho Chehab
81628331a01SMauro Carvalho Chehab	my $cur_time = times;
81728331a01SMauro Carvalho Chehab	my $tm = $cur_time - $start_time;
81828331a01SMauro Carvalho Chehab	my $time = sprintf "%d:%02d", int($tm), 60 * ($tm - int($tm));
81928331a01SMauro Carvalho Chehab
82028331a01SMauro Carvalho Chehab	printf STDERR "\33[2K\r", if ($is_console);
82128331a01SMauro Carvalho Chehab	printf STDERR "%s: processing sysfs files... done\n", $time;
82228331a01SMauro Carvalho Chehab
82328331a01SMauro Carvalho Chehab	foreach my $file (@not_found) {
82428331a01SMauro Carvalho Chehab		print "$file not found.\n";
82528331a01SMauro Carvalho Chehab	}
82628331a01SMauro Carvalho Chehab}
82728331a01SMauro Carvalho Chehab
828f090db43SMauro Carvalho Chehabsub undefined_symbols {
82928331a01SMauro Carvalho Chehab	print STDERR "Reading $sysfs_prefix directory contents...";
830ab02c515SMauro Carvalho Chehab	find({
831ab02c515SMauro Carvalho Chehab		wanted =>\&parse_existing_sysfs,
832ab02c515SMauro Carvalho Chehab		preprocess =>\&dont_parse_special_attributes,
833ab02c515SMauro Carvalho Chehab		no_chdir => 1
834ab02c515SMauro Carvalho Chehab	     }, $sysfs_prefix);
83528331a01SMauro Carvalho Chehab	print STDERR "done.\n";
836ab02c515SMauro Carvalho Chehab
837f34f6729SMauro Carvalho Chehab	$leaf{"others"}->{what} = "";
838ca8e055cSMauro Carvalho Chehab
83928331a01SMauro Carvalho Chehab	print STDERR "Converting ABI What fields into regexes...";
840f090db43SMauro Carvalho Chehab	foreach my $w (sort keys %data) {
841f090db43SMauro Carvalho Chehab		foreach my $what (split /\xac/,$w) {
842ab02c515SMauro Carvalho Chehab			next if (!($what =~ m/^$sysfs_prefix/));
843ab02c515SMauro Carvalho Chehab
844ab02c515SMauro Carvalho Chehab			# Convert what into regular expressions
845ab02c515SMauro Carvalho Chehab
846df2205deSMauro Carvalho Chehab			# Escape dot characters
847df2205deSMauro Carvalho Chehab			$what =~ s/\./\xf6/g;
848ab02c515SMauro Carvalho Chehab
849ab02c515SMauro Carvalho Chehab			# Temporarily change [0-9]+ type of patterns
850ab02c515SMauro Carvalho Chehab			$what =~ s/\[0\-9\]\+/\xff/g;
851ab02c515SMauro Carvalho Chehab
852ab02c515SMauro Carvalho Chehab			# Temporarily change [\d+-\d+] type of patterns
853ab02c515SMauro Carvalho Chehab			$what =~ s/\[0\-\d+\]/\xff/g;
854ab02c515SMauro Carvalho Chehab			$what =~ s/\[(\d+)\]/\xf4$1\xf5/g;
855ab02c515SMauro Carvalho Chehab
856ab02c515SMauro Carvalho Chehab			# Temporarily change [0-9] type of patterns
857ab02c515SMauro Carvalho Chehab			$what =~ s/\[(\d)\-(\d)\]/\xf4$1-$2\xf5/g;
858ab02c515SMauro Carvalho Chehab
859ab02c515SMauro Carvalho Chehab			# Handle multiple option patterns
860ab02c515SMauro Carvalho Chehab			$what =~ s/[\{\<\[]([\w_]+)(?:[,|]+([\w_]+)){1,}[\}\>\]]/($1|$2)/g;
861ab02c515SMauro Carvalho Chehab
862ab02c515SMauro Carvalho Chehab			# Handle wildcards
863df2205deSMauro Carvalho Chehab			$what =~ s,\*,.*,g;
864df2205deSMauro Carvalho Chehab			$what =~ s,/\xf6..,/.*,g;
865ab02c515SMauro Carvalho Chehab			$what =~ s/\<[^\>]+\>/.*/g;
866ab02c515SMauro Carvalho Chehab			$what =~ s/\{[^\}]+\}/.*/g;
867ab02c515SMauro Carvalho Chehab			$what =~ s/\[[^\]]+\]/.*/g;
868ab02c515SMauro Carvalho Chehab
869ab02c515SMauro Carvalho Chehab			$what =~ s/[XYZ]/.*/g;
870ab02c515SMauro Carvalho Chehab
871ab02c515SMauro Carvalho Chehab			# Recover [0-9] type of patterns
872ab02c515SMauro Carvalho Chehab			$what =~ s/\xf4/[/g;
873ab02c515SMauro Carvalho Chehab			$what =~ s/\xf5/]/g;
874ab02c515SMauro Carvalho Chehab
875ab02c515SMauro Carvalho Chehab			# Remove duplicated spaces
876ab02c515SMauro Carvalho Chehab			$what =~ s/\s+/ /g;
877ab02c515SMauro Carvalho Chehab
878ab02c515SMauro Carvalho Chehab			# Special case: this ABI has a parenthesis on it
879ab02c515SMauro Carvalho Chehab			$what =~ s/sqrt\(x^2\+y^2\+z^2\)/sqrt\(x^2\+y^2\+z^2\)/;
880ab02c515SMauro Carvalho Chehab
881ab02c515SMauro Carvalho Chehab			# Special case: drop comparition as in:
882ab02c515SMauro Carvalho Chehab			#	What: foo = <something>
883ab02c515SMauro Carvalho Chehab			# (this happens on a few IIO definitions)
884ab02c515SMauro Carvalho Chehab			$what =~ s,\s*\=.*$,,;
885ab02c515SMauro Carvalho Chehab
886ab02c515SMauro Carvalho Chehab			# Escape all other symbols
887ab02c515SMauro Carvalho Chehab			$what =~ s/$escape_symbols/\\$1/g;
888ab02c515SMauro Carvalho Chehab			$what =~ s/\\\\/\\/g;
889ab02c515SMauro Carvalho Chehab			$what =~ s/\\([\[\]\(\)\|])/$1/g;
890ab02c515SMauro Carvalho Chehab			$what =~ s/(\d+)\\(-\d+)/$1$2/g;
891ab02c515SMauro Carvalho Chehab
89214c94257SMauro Carvalho Chehab			$what =~ s/\xff/\\d+/g;
89314c94257SMauro Carvalho Chehab
89414c94257SMauro Carvalho Chehab			# Special case: IIO ABI which a parenthesis.
89514c94257SMauro Carvalho Chehab			$what =~ s/sqrt(.*)/sqrt\(.*\)/;
89614c94257SMauro Carvalho Chehab
897df2205deSMauro Carvalho Chehab			# Simplify regexes with multiple .*
898df2205deSMauro Carvalho Chehab			$what =~ s#(?:\.\*){2,}##g;
899df2205deSMauro Carvalho Chehab#			$what =~ s#\.\*/\.\*#.*#g;
900df2205deSMauro Carvalho Chehab
901df2205deSMauro Carvalho Chehab			# Recover dot characters
902df2205deSMauro Carvalho Chehab			$what =~ s/\xf6/\./g;
903df2205deSMauro Carvalho Chehab
90445495db9SMauro Carvalho Chehab			my $leave = get_leave($what);
905f34f6729SMauro Carvalho Chehab
90614c94257SMauro Carvalho Chehab			my $added = 0;
907ab02c515SMauro Carvalho Chehab			foreach my $l (split /\|/, $leave) {
908ab02c515SMauro Carvalho Chehab				if (defined($leaf{$l})) {
909f34f6729SMauro Carvalho Chehab					next if ($leaf{$l}->{what} =~ m/\b$what\b/);
910f34f6729SMauro Carvalho Chehab					$leaf{$l}->{what} .= "\xac" . $what;
91114c94257SMauro Carvalho Chehab					$added = 1;
912ab02c515SMauro Carvalho Chehab				} else {
913f34f6729SMauro Carvalho Chehab					$leaf{$l}->{what} = $what;
91414c94257SMauro Carvalho Chehab					$added = 1;
915ab02c515SMauro Carvalho Chehab				}
916ab02c515SMauro Carvalho Chehab			}
91714c94257SMauro Carvalho Chehab			if ($search_string && $added) {
9182833e30aSMauro Carvalho Chehab				print STDERR "What: $what\n" if ($what =~ m#$search_string#);
91914c94257SMauro Carvalho Chehab			}
92014c94257SMauro Carvalho Chehab
921ab02c515SMauro Carvalho Chehab		}
922ab02c515SMauro Carvalho Chehab	}
923f34f6729SMauro Carvalho Chehab	# Compile regexes
924e5c044c8SMauro Carvalho Chehab	foreach my $l (sort keys %leaf) {
925f34f6729SMauro Carvalho Chehab		my @expr;
926e5c044c8SMauro Carvalho Chehab		foreach my $w(sort split /\xac/, $leaf{$l}->{what}) {
927f34f6729SMauro Carvalho Chehab			push @expr, qr /^$w$/;
928f34f6729SMauro Carvalho Chehab		}
929f34f6729SMauro Carvalho Chehab		$leaf{$l}->{expr} = \@expr;
930f34f6729SMauro Carvalho Chehab	}
931f34f6729SMauro Carvalho Chehab
932ca8e055cSMauro Carvalho Chehab	# Take links into account
933e5c044c8SMauro Carvalho Chehab	foreach my $link (sort keys %aliases) {
934ca8e055cSMauro Carvalho Chehab		my $abs_file = $aliases{$link};
935ca8e055cSMauro Carvalho Chehab		graph_add_link($abs_file, $link);
936ca8e055cSMauro Carvalho Chehab	}
93728331a01SMauro Carvalho Chehab	print STDERR "done.\n";
93828331a01SMauro Carvalho Chehab
939ab02c515SMauro Carvalho Chehab	check_undefined_symbols;
940f090db43SMauro Carvalho Chehab}
941f090db43SMauro Carvalho Chehab
94261439c4aSMauro Carvalho Chehab# Ensure that the prefix will always end with a slash
94361439c4aSMauro Carvalho Chehab# While this is not needed for find, it makes the patch nicer
94461439c4aSMauro Carvalho Chehab# with --enable-lineno
94561439c4aSMauro Carvalho Chehab$prefix =~ s,/?$,/,;
94633e3e991SMauro Carvalho Chehab
947f090db43SMauro Carvalho Chehabif ($cmd eq "undefined" || $cmd eq "search") {
948f090db43SMauro Carvalho Chehab	$show_warnings = 0;
949f090db43SMauro Carvalho Chehab}
95033e3e991SMauro Carvalho Chehab#
951bbc249f2SMauro Carvalho Chehab# Parses all ABI files located at $prefix dir
952bbc249f2SMauro Carvalho Chehab#
953bbc249f2SMauro Carvalho Chehabfind({wanted =>\&parse_abi, no_chdir => 1}, $prefix);
954bbc249f2SMauro Carvalho Chehab
95546f661fdSMauro Carvalho Chehabprint STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug & $dbg_dump_abi_structs);
956bbc249f2SMauro Carvalho Chehab
957bbc249f2SMauro Carvalho Chehab#
95833e3e991SMauro Carvalho Chehab# Handles the command
959bbc249f2SMauro Carvalho Chehab#
960f090db43SMauro Carvalho Chehabif ($cmd eq "undefined") {
961f090db43SMauro Carvalho Chehab	undefined_symbols;
962f090db43SMauro Carvalho Chehab} elsif ($cmd eq "search") {
963c7ba3334SMauro Carvalho Chehab	search_symbols;
964c7ba3334SMauro Carvalho Chehab} else {
96533e3e991SMauro Carvalho Chehab	if ($cmd eq "rest") {
96633e3e991SMauro Carvalho Chehab		output_rest;
96733e3e991SMauro Carvalho Chehab	}
968bbc249f2SMauro Carvalho Chehab
969c7ba3334SMauro Carvalho Chehab	# Warn about duplicated ABI entries
970c7ba3334SMauro Carvalho Chehab	foreach my $what(sort keys %symbols) {
971c7ba3334SMauro Carvalho Chehab		my @files = @{$symbols{$what}->{file}};
972c7ba3334SMauro Carvalho Chehab
973c7ba3334SMauro Carvalho Chehab		next if (scalar(@files) == 1);
974c7ba3334SMauro Carvalho Chehab
975c7ba3334SMauro Carvalho Chehab		printf STDERR "Warning: $what is defined %d times: @files\n",
976c7ba3334SMauro Carvalho Chehab		    scalar(@files);
977c7ba3334SMauro Carvalho Chehab	}
978c7ba3334SMauro Carvalho Chehab}
979bbc249f2SMauro Carvalho Chehab
980bbc249f2SMauro Carvalho Chehab__END__
981bbc249f2SMauro Carvalho Chehab
982bbc249f2SMauro Carvalho Chehab=head1 NAME
983bbc249f2SMauro Carvalho Chehab
9845b5bfecaSSeongJae Parkget_abi.pl - parse the Linux ABI files and produce a ReST book.
985bbc249f2SMauro Carvalho Chehab
986bbc249f2SMauro Carvalho Chehab=head1 SYNOPSIS
987bbc249f2SMauro Carvalho Chehab
9885b5bfecaSSeongJae ParkB<get_abi.pl> [--debug <level>] [--enable-lineno] [--man] [--help]
989ab02c515SMauro Carvalho Chehab	       [--(no-)rst-source] [--dir=<dir>] [--show-hints]
99014c94257SMauro Carvalho Chehab	       [--search-string <regex>]
9915bff9632SMichal Simek	       <COMMAND> [<ARGUMENT>]
99233e3e991SMauro Carvalho Chehab
99342f09848SMauro Carvalho ChehabWhere B<COMMAND> can be:
99433e3e991SMauro Carvalho Chehab
99533e3e991SMauro Carvalho Chehab=over 8
99633e3e991SMauro Carvalho Chehab
99742f09848SMauro Carvalho ChehabB<search> I<SEARCH_REGEX> - search for I<SEARCH_REGEX> inside ABI
99833e3e991SMauro Carvalho Chehab
99933e3e991SMauro Carvalho ChehabB<rest>                   - output the ABI in ReST markup language
100033e3e991SMauro Carvalho Chehab
10017ce7b89bSMauro Carvalho ChehabB<validate>               - validate the ABI contents
10027ce7b89bSMauro Carvalho Chehab
1003f090db43SMauro Carvalho ChehabB<undefined>              - existing symbols at the system that aren't
1004f090db43SMauro Carvalho Chehab                            defined at Documentation/ABI
1005f090db43SMauro Carvalho Chehab
100633e3e991SMauro Carvalho Chehab=back
1007bbc249f2SMauro Carvalho Chehab
1008bbc249f2SMauro Carvalho Chehab=head1 OPTIONS
1009bbc249f2SMauro Carvalho Chehab
1010bbc249f2SMauro Carvalho Chehab=over 8
1011bbc249f2SMauro Carvalho Chehab
101233e3e991SMauro Carvalho Chehab=item B<--dir>
101333e3e991SMauro Carvalho Chehab
101433e3e991SMauro Carvalho ChehabChanges the location of the ABI search. By default, it uses
101533e3e991SMauro Carvalho Chehabthe Documentation/ABI directory.
101633e3e991SMauro Carvalho Chehab
101711ce90a4SMauro Carvalho Chehab=item B<--rst-source> and B<--no-rst-source>
101811ce90a4SMauro Carvalho Chehab
101911ce90a4SMauro Carvalho ChehabThe input file may be using ReST syntax or not. Those two options allow
102042f09848SMauro Carvalho Chehabselecting between a rst-compliant source ABI (B<--rst-source>), or a
102111ce90a4SMauro Carvalho Chehabplain text that may be violating ReST spec, so it requres some escaping
102242f09848SMauro Carvalho Chehablogic (B<--no-rst-source>).
102311ce90a4SMauro Carvalho Chehab
102461439c4aSMauro Carvalho Chehab=item B<--enable-lineno>
102561439c4aSMauro Carvalho Chehab
102692b6de17SMauro Carvalho ChehabEnable output of .. LINENO lines.
102761439c4aSMauro Carvalho Chehab
102846f661fdSMauro Carvalho Chehab=item B<--debug> I<debug level>
1029bbc249f2SMauro Carvalho Chehab
103046f661fdSMauro Carvalho ChehabPrint debug information according with the level, which is given by the
103146f661fdSMauro Carvalho Chehabfollowing bitmask:
103246f661fdSMauro Carvalho Chehab
103346f661fdSMauro Carvalho Chehab    -  1: Debug parsing What entries from ABI files;
103446f661fdSMauro Carvalho Chehab    -  2: Shows what files are opened from ABI files;
103546f661fdSMauro Carvalho Chehab    -  4: Dump the structs used to store the contents of the ABI files.
1036bbc249f2SMauro Carvalho Chehab
1037ab02c515SMauro Carvalho Chehab=item B<--show-hints>
1038ab02c515SMauro Carvalho Chehab
1039ab02c515SMauro Carvalho ChehabShow hints about possible definitions for the missing ABI symbols.
1040ab02c515SMauro Carvalho ChehabUsed only when B<undefined>.
1041ab02c515SMauro Carvalho Chehab
104242f09848SMauro Carvalho Chehab=item B<--search-string> I<regex string>
104314c94257SMauro Carvalho Chehab
104414c94257SMauro Carvalho ChehabShow only occurences that match a search string.
104514c94257SMauro Carvalho ChehabUsed only when B<undefined>.
104614c94257SMauro Carvalho Chehab
1047bbc249f2SMauro Carvalho Chehab=item B<--help>
1048bbc249f2SMauro Carvalho Chehab
1049bbc249f2SMauro Carvalho ChehabPrints a brief help message and exits.
1050bbc249f2SMauro Carvalho Chehab
1051bbc249f2SMauro Carvalho Chehab=item B<--man>
1052bbc249f2SMauro Carvalho Chehab
1053bbc249f2SMauro Carvalho ChehabPrints the manual page and exits.
1054bbc249f2SMauro Carvalho Chehab
1055bbc249f2SMauro Carvalho Chehab=back
1056bbc249f2SMauro Carvalho Chehab
1057bbc249f2SMauro Carvalho Chehab=head1 DESCRIPTION
1058bbc249f2SMauro Carvalho Chehab
105933e3e991SMauro Carvalho ChehabParse the Linux ABI files from ABI DIR (usually located at Documentation/ABI),
106033e3e991SMauro Carvalho Chehaballowing to search for ABI symbols or to produce a ReST book containing
106133e3e991SMauro Carvalho Chehabthe Linux ABI documentation.
106233e3e991SMauro Carvalho Chehab
106333e3e991SMauro Carvalho Chehab=head1 EXAMPLES
106433e3e991SMauro Carvalho Chehab
106533e3e991SMauro Carvalho ChehabSearch for all stable symbols with the word "usb":
106633e3e991SMauro Carvalho Chehab
106733e3e991SMauro Carvalho Chehab=over 8
106833e3e991SMauro Carvalho Chehab
106933e3e991SMauro Carvalho Chehab$ scripts/get_abi.pl search usb --dir Documentation/ABI/stable
107033e3e991SMauro Carvalho Chehab
107133e3e991SMauro Carvalho Chehab=back
107233e3e991SMauro Carvalho Chehab
107333e3e991SMauro Carvalho ChehabSearch for all symbols that match the regex expression "usb.*cap":
107433e3e991SMauro Carvalho Chehab
107533e3e991SMauro Carvalho Chehab=over 8
107633e3e991SMauro Carvalho Chehab
107733e3e991SMauro Carvalho Chehab$ scripts/get_abi.pl search usb.*cap
107833e3e991SMauro Carvalho Chehab
107933e3e991SMauro Carvalho Chehab=back
108033e3e991SMauro Carvalho Chehab
108133e3e991SMauro Carvalho ChehabOutput all obsoleted symbols in ReST format
108233e3e991SMauro Carvalho Chehab
108333e3e991SMauro Carvalho Chehab=over 8
108433e3e991SMauro Carvalho Chehab
108533e3e991SMauro Carvalho Chehab$ scripts/get_abi.pl rest --dir Documentation/ABI/obsolete
108633e3e991SMauro Carvalho Chehab
108733e3e991SMauro Carvalho Chehab=back
1088bbc249f2SMauro Carvalho Chehab
1089bbc249f2SMauro Carvalho Chehab=head1 BUGS
1090bbc249f2SMauro Carvalho Chehab
109142f09848SMauro Carvalho ChehabReport bugs to Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
1092bbc249f2SMauro Carvalho Chehab
1093bbc249f2SMauro Carvalho Chehab=head1 COPYRIGHT
1094bbc249f2SMauro Carvalho Chehab
109542f09848SMauro Carvalho ChehabCopyright (c) 2016-2021 by Mauro Carvalho Chehab <mchehab+huawei@kernel.org>.
1096bbc249f2SMauro Carvalho Chehab
1097bbc249f2SMauro Carvalho ChehabLicense GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>.
1098bbc249f2SMauro Carvalho Chehab
1099bbc249f2SMauro Carvalho ChehabThis is free software: you are free to change and redistribute it.
1100bbc249f2SMauro Carvalho ChehabThere is NO WARRANTY, to the extent permitted by law.
1101bbc249f2SMauro Carvalho Chehab
1102bbc249f2SMauro Carvalho Chehab=cut
1103