From nobody Wed Dec 17 03:19:47 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4712B1DED63; Mon, 10 Feb 2025 10:18:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739182705; cv=none; b=Pv8xxHX0uPFZ3haaN51QkuvdhlPy312lmlg/0t4wJkWMUo0MloOFz/cPs8zfFHn+uY0dWvq874ksjGuhDF835rNGA+AKPX1ISm0o6MHkwqV/T6VcyBhvITeWCMyUXljtklzKnwPJbjlEc4iaxQ0JZrkgh3cte/KOBpKDmhGymro= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739182705; c=relaxed/simple; bh=sCuTz3zxaa3V2tY51057fBvBcrlzP04scyPpCe0UiUk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HkjZOxJ1BYDP+jIVyqrSFyMEIYe8iUHXkMsMcEbQ7phHr8zW/C+FlkDGBeMXniMFVKxKbgkIX815vP0KTcetWZTu1wypUojIypCb23/ewUVBYekfcRa0idPsOqU/feGNAlbw5WDyhzzFTt/wKArx8maWROhZMNSoMEywInBy/wE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MLZjQNMj; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MLZjQNMj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6B3CBC2BCB2; Mon, 10 Feb 2025 10:18:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1739182704; bh=sCuTz3zxaa3V2tY51057fBvBcrlzP04scyPpCe0UiUk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MLZjQNMjHHzoyAfoDi7A1lOZldyuqNYOm+b5ILtFKI5JUanNLnJDHxoryBFzIjNLH hD9C6UMvzwr02jrHNjQbGcSpvI4ZSR6hTSg4p+D5rkiRhsV7IS833chcTYh4j5ozq/ NPXHbldKV3UfThHP3XuOtxWvbgwDXspI1gS8o2rQWD6ozfG3YvDn9df794g39Q5Miu DQLcDr3SDMGI9fvZQeKTKlTmoPYLlVN+mFlP7iQm/pWTRTDK/r8q5KvyhO2DR+uUj+ AtbtSnneRpl30+kgV8ANozSIWYuQHx63DWfHOpxod+5EveHbblwP42XwOFhylTPQhU chdF+UNqJeIqQ== Received: from mchehab by mail.kernel.org with local (Exim 4.98) (envelope-from ) id 1thQru-00000006Cjs-2P03; Mon, 10 Feb 2025 11:18:22 +0100 From: Mauro Carvalho Chehab To: Linux Doc Mailing List Cc: Mauro Carvalho Chehab , "Guilherme G. Piccoli" , "Jonathan Corbet" , "Mauro Carvalho Chehab" , Kees Cook , Tony Luck , bpf@vger.kernel.org, linux-hardening@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 27/27] scripts/get_abi.pl: drop now obsoleted script Date: Mon, 10 Feb 2025 11:18:16 +0100 Message-ID: <698ec258b36b63ccde5f7da1af9c97cf8df51050.1739182025.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.48.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Content-Type: text/plain; charset="utf-8" As all functionalities of it were migrated to get_abi.py, drop the now obsoleted script. Signed-off-by: Mauro Carvalho Chehab --- scripts/get_abi.pl | 1103 -------------------------------------------- 1 file changed, 1103 deletions(-) delete mode 100755 scripts/get_abi.pl diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl deleted file mode 100755 index de1c0354b50c..000000000000 --- a/scripts/get_abi.pl +++ /dev/null @@ -1,1103 +0,0 @@ -#!/usr/bin/env perl -# SPDX-License-Identifier: GPL-2.0 - -BEGIN { $Pod::Usage::Formatter =3D 'Pod::Text::Termcap'; } - -use strict; -use warnings; -use utf8; -use Pod::Usage qw(pod2usage); -use Getopt::Long; -use File::Find; -use IO::Handle; -use Fcntl ':mode'; -use Cwd 'abs_path'; -use Data::Dumper; - -my $help =3D 0; -my $hint =3D 0; -my $man =3D 0; -my $debug =3D 0; -my $enable_lineno =3D 0; -my $show_warnings =3D 1; -my $prefix=3D"Documentation/ABI"; -my $sysfs_prefix=3D"/sys"; -my $search_string; - -# Debug options -my $dbg_what_parsing =3D 1; -my $dbg_what_open =3D 2; -my $dbg_dump_abi_structs =3D 4; -my $dbg_undefined =3D 8; - -$Data::Dumper::Indent =3D 1; -$Data::Dumper::Terse =3D 1; - -# -# If true, assumes that the description is formatted with ReST -# -my $description_is_rst =3D 1; - -GetOptions( - "debug=3Di" =3D> \$debug, - "enable-lineno" =3D> \$enable_lineno, - "rst-source!" =3D> \$description_is_rst, - "dir=3Ds" =3D> \$prefix, - 'help|?' =3D> \$help, - "show-hints" =3D> \$hint, - "search-string=3Ds" =3D> \$search_string, - man =3D> \$man -) or pod2usage(2); - -pod2usage(1) if $help; -pod2usage(-exitstatus =3D> 0, -noperldoc, -verbose =3D> 2) if $man; - -pod2usage(2) if (scalar @ARGV < 1 || @ARGV > 2); - -my ($cmd, $arg) =3D @ARGV; - -pod2usage(2) if ($cmd ne "search" && $cmd ne "rest" && $cmd ne "validate" = && $cmd ne "undefined"); -pod2usage(2) if ($cmd eq "search" && !$arg); - -require Data::Dumper if ($debug & $dbg_dump_abi_structs); - -my %data; -my %symbols; - -# -# Displays an error message, printing file name and line -# -sub parse_error($$$$) { - my ($file, $ln, $msg, $data) =3D @_; - - return if (!$show_warnings); - - $data =3D~ s/\s+$/\n/; - - print STDERR "Warning: file $file#$ln:\n\t$msg"; - - if ($data ne "") { - print STDERR ". Line\n\t\t$data"; - } else { - print STDERR "\n"; - } -} - -# -# Parse an ABI file, storing its contents at %data -# -sub parse_abi { - my $file =3D $File::Find::name; - - my $mode =3D (stat($file))[2]; - return if ($mode & S_IFDIR); - return if ($file =3D~ m,/README,); - return if ($file =3D~ m,/\.,); - return if ($file =3D~ m,\.(rej|org|orig|bak)$,); - - my $name =3D $file; - $name =3D~ s,.*/,,; - - my $fn =3D $file; - $fn =3D~ s,.*Documentation/ABI/,,; - - my $nametag =3D "File $fn"; - $data{$nametag}->{what} =3D "File $name"; - $data{$nametag}->{type} =3D "File"; - $data{$nametag}->{file} =3D $name; - $data{$nametag}->{filepath} =3D $file; - $data{$nametag}->{is_file} =3D 1; - $data{$nametag}->{line_no} =3D 1; - - my $type =3D $file; - $type =3D~ s,.*/(.*)/.*,$1,; - - my $what; - my $new_what; - my $tag =3D ""; - my $ln; - my $xrefs; - my $space; - my @labels; - my $label =3D ""; - - print STDERR "Opening $file\n" if ($debug & $dbg_what_open); - open IN, $file; - while() { - $ln++; - if (m/^(\S+)(:\s*)(.*)/i) { - my $new_tag =3D lc($1); - my $sep =3D $2; - my $content =3D $3; - - if (!($new_tag =3D~ m/(what|where|date|kernelversion|contact|descriptio= n|users)/)) { - if ($tag eq "description") { - # New "tag" is actually part of - # description. Don't consider it a tag - $new_tag =3D ""; - } elsif ($tag ne "") { - parse_error($file, $ln, "tag '$tag' is invalid", $_); - } - } - - # Invalid, but it is a common mistake - if ($new_tag eq "where") { - parse_error($file, $ln, "tag 'Where' is invalid. Should be 'What:' ins= tead", ""); - $new_tag =3D "what"; - } - - if ($new_tag =3D~ m/what/) { - $space =3D ""; - $content =3D~ s/[,.;]$//; - - push @{$symbols{$content}->{file}}, " $file:" . ($ln - 1); - - if ($tag =3D~ m/what/) { - $what .=3D "\xac" . $content; - } else { - if ($what) { - parse_error($file, $ln, "What '$what' doesn't have a description", "= ") if (!$data{$what}->{description}); - - foreach my $w(split /\xac/, $what) { - $symbols{$w}->{xref} =3D $what; - }; - } - - $what =3D $content; - $label =3D $content; - $new_what =3D 1; - } - push @labels, [($content, $label)]; - $tag =3D $new_tag; - - push @{$data{$nametag}->{symbols}}, $content if ($data{$nametag}->{wha= t}); - next; - } - - if ($tag ne "" && $new_tag) { - $tag =3D $new_tag; - - if ($new_what) { - @{$data{$what}->{label_list}} =3D @labels if ($data{$nametag}->{what}= ); - @labels =3D (); - $label =3D ""; - $new_what =3D 0; - - $data{$what}->{type} =3D $type; - if (!defined($data{$what}->{file})) { - $data{$what}->{file} =3D $name; - $data{$what}->{filepath} =3D $file; - } else { - $data{$what}->{description} .=3D "\n\n" if (defined($data{$what}->{d= escription})); - if ($name ne $data{$what}->{file}) { - $data{$what}->{file} .=3D " " . $name; - $data{$what}->{filepath} .=3D " " . $file; - } - } - print STDERR "\twhat: $what\n" if ($debug & $dbg_what_parsing); - $data{$what}->{line_no} =3D $ln; - } else { - $data{$what}->{line_no} =3D $ln if (!defined($data{$what}->{line_no})= ); - } - - if (!$what) { - parse_error($file, $ln, "'What:' should come first:", $_); - next; - } - if ($new_tag eq "description") { - $sep =3D~ s,:, ,; - $content =3D ' ' x length($new_tag) . $sep . $content; - while ($content =3D~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e)= {} - if ($content =3D~ m/^(\s*)(\S.*)$/) { - # Preserve initial spaces for the first line - $space =3D $1; - $content =3D "$2\n"; - $data{$what}->{$tag} .=3D $content; - } else { - undef($space); - } - - } else { - $data{$what}->{$tag} =3D $content; - } - next; - } - } - - # Store any contents before tags at the database - if (!$tag && $data{$nametag}->{what}) { - $data{$nametag}->{description} .=3D $_; - next; - } - - if ($tag eq "description") { - my $content =3D $_; - while ($content =3D~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {} - if (m/^\s*\n/) { - $data{$what}->{$tag} .=3D "\n"; - next; - } - - if (!defined($space)) { - # Preserve initial spaces for the first line - if ($content =3D~ m/^(\s*)(\S.*)$/) { - $space =3D $1; - $content =3D "$2\n"; - } - } else { - $space =3D "" if (!($content =3D~ s/^($space)//)); - } - $data{$what}->{$tag} .=3D $content; - - next; - } - if (m/^\s*(.*)/) { - $data{$what}->{$tag} .=3D "\n$1"; - $data{$what}->{$tag} =3D~ s/\n+$//; - next; - } - - # Everything else is error - parse_error($file, $ln, "Unexpected content", $_); - } - $data{$nametag}->{description} =3D~ s/^\n+// if ($data{$nametag}->{descri= ption}); - if ($what) { - parse_error($file, $ln, "What '$what' doesn't have a description", "") i= f (!$data{$what}->{description}); - - foreach my $w(split /\xac/,$what) { - $symbols{$w}->{xref} =3D $what; - }; - } - close IN; -} - -sub create_labels { - my %labels; - - foreach my $what (keys %data) { - next if ($data{$what}->{file} eq "File"); - - foreach my $p (@{$data{$what}->{label_list}}) { - my ($content, $label) =3D @{$p}; - $label =3D "abi_" . $label . " "; - $label =3D~ tr/A-Z/a-z/; - - # Convert special chars to "_" - $label =3D~s/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xff])/_/g; - $label =3D~ s,_+,_,g; - $label =3D~ s,_$,,; - - # Avoid duplicated labels - while (defined($labels{$label})) { - my @chars =3D ("A".."Z", "a".."z"); - $label .=3D $chars[rand @chars]; - } - $labels{$label} =3D 1; - - $data{$what}->{label} =3D $label; - - # only one label is enough - last; - } - } -} - -# -# Outputs the book on ReST format -# - -# \b doesn't work well with paths. So, we need to define something else: -# Boundaries are punct characters, spaces and end-of-line -my $start =3D qr {(^|\s|\() }x; -my $bondary =3D qr { ([,.:;\)\s]|\z) }x; -my $xref_match =3D qr { $start(\/(sys|config|proc|dev|kvd)\/[^,.:;\)\s]+)$= bondary }x; -my $symbols =3D qr { ([\x01-\x08\x0e-\x1f\x21-\x2f\x3a-\x40\x7b-\xff]) }x; - -sub output_rest { - create_labels(); - - my $part =3D ""; - - foreach my $what (sort { - ($data{$a}->{type} eq "File") cmp ($data{$b}->{type} eq "File") || - $a cmp $b - } keys %data) { - my $type =3D $data{$what}->{type}; - - my @file =3D split / /, $data{$what}->{file}; - my @filepath =3D split / /, $data{$what}->{filepath}; - - if ($enable_lineno) { - printf ".. LINENO %s%s#%s\n\n", - $prefix, $file[0], - $data{$what}->{line_no}; - } - - my $w =3D $what; - - if ($type ne "File") { - my $cur_part =3D $what; - if ($what =3D~ '/') { - if ($what =3D~ m#^(\/?(?:[\w\-]+\/?){1,2})#) { - $cur_part =3D "Symbols under $1"; - $cur_part =3D~ s,/$,,; - } - } - - if ($cur_part ne "" && $part ne $cur_part) { - $part =3D $cur_part; - my $bar =3D $part; - $bar =3D~ s/./-/g; - print "$part\n$bar\n\n"; - } - - printf ".. _%s:\n\n", $data{$what}->{label}; - - my @names =3D split /\xac/,$w; - my $len =3D 0; - - foreach my $name (@names) { - $name =3D~ s/$symbols/\\$1/g; - $name =3D "**$name**"; - $len =3D length($name) if (length($name) > $len); - } - - print "+-" . "-" x $len . "-+\n"; - foreach my $name (@names) { - printf "| %s", $name . " " x ($len - length($name)) . " |\n"; - print "+-" . "-" x $len . "-+\n"; - } - - print "\n"; - } - - for (my $i =3D 0; $i < scalar(@filepath); $i++) { - my $path =3D $filepath[$i]; - my $f =3D $file[$i]; - - $path =3D~ s,.*/(.*/.*),$1,;; - $path =3D~ s,[/\-],_,g;; - my $fileref =3D "abi_file_".$path; - - if ($type eq "File") { - print ".. _$fileref:\n\n"; - } else { - print "Defined on file :ref:`$f <$fileref>`\n\n"; - } - } - - if ($type eq "File") { - my $bar =3D $w; - $bar =3D~ s/./-/g; - print "$w\n$bar\n\n"; - } - - my $desc =3D ""; - $desc =3D $data{$what}->{description} if (defined($data{$what}->{descrip= tion})); - $desc =3D~ s/\s+$/\n/; - - if (!($desc =3D~ /^\s*$/)) { - if ($description_is_rst) { - # 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 =3D~ s/\n[\-\*\=3D\^\~]+\n/\n\n/g; - - # Enrich text by creating cross-references - - my $new_desc =3D ""; - my $init_indent =3D -1; - my $literal_indent =3D -1; - - open(my $fh, "+<", \$desc); - while (my $d =3D <$fh>) { - my $indent =3D $d =3D~ m/^(\s+)/; - my $spaces =3D length($indent); - $init_indent =3D $indent if ($init_indent < 0); - if ($literal_indent >=3D 0) { - if ($spaces > $literal_indent) { - $new_desc .=3D $d; - next; - } else { - $literal_indent =3D -1; - } - } else { - if ($d =3D~ /()::$/ && !($d =3D~ /^\s*\.\./)) { - $literal_indent =3D $spaces; - } - } - - $d =3D~ s,Documentation/(?!devicetree)(\S+)\.rst,:doc:`/$1`,g; - - my @matches =3D $d =3D~ m,Documentation/ABI/([\w\/\-]+),g; - foreach my $f (@matches) { - my $xref =3D $f; - my $path =3D $f; - $path =3D~ s,.*/(.*/.*),$1,;; - $path =3D~ s,[/\-],_,g;; - $xref .=3D " "; - $d =3D~ s,\bDocumentation/ABI/$f\b,:ref:`$xref`,g; - } - - # Seek for cross reference symbols like /sys/... - @matches =3D $d =3D~ m/$xref_match/g; - - foreach my $s (@matches) { - next if (!($s =3D~ m,/,)); - if (defined($data{$s}) && defined($data{$s}->{label})) { - my $xref =3D $s; - - $xref =3D~ s/$symbols/\\$1/g; - $xref =3D ":ref:`$xref <" . $data{$s}->{label} . ">`"; - - $d =3D~ s,$start$s$bondary,$1$xref$2,g; - } - } - $new_desc .=3D $d; - } - close $fh; - - - print "$new_desc\n\n"; - } else { - $desc =3D~ s/^\s+//; - - # Remove title markups from the description, as they won't work - $desc =3D~ s/\n[\-\*\=3D\^\~]+\n/\n\n/g; - - if ($desc =3D~ m/\:\n/ || $desc =3D~ m/\n[\t ]+/ || $desc =3D~ m/[\x0= 0-\x08\x0b-\x1f\x7b-\xff]/) { - # put everything inside a code block - $desc =3D~ s/\n/\n /g; - - print "::\n\n"; - print " $desc\n\n"; - } else { - # Escape any special chars from description - $desc =3D~s/([\x00-\x08\x0b-\x1f\x21-\x2a\x2d\x2f\x3c-\x40\x5c\x5e-\x= 60\x7b-\xff])/\\$1/g; - print "$desc\n\n"; - } - } - } else { - print "DESCRIPTION MISSING for $what\n\n" if (!$data{$what}->{is_file}); - } - - if ($data{$what}->{symbols}) { - printf "Has the following ABI:\n\n"; - - foreach my $content(@{$data{$what}->{symbols}}) { - my $label =3D $data{$symbols{$content}->{xref}}->{label}; - - # Escape special chars from content - $content =3D~s/([\x00-\x1f\x21-\x2f\x3a-\x40\x7b-\xff])/\\$1/g; - - print "- :ref:`$content <$label>`\n\n"; - } - } - - if (defined($data{$what}->{users})) { - my $users =3D $data{$what}->{users}; - - $users =3D~ s/\n/\n\t/g; - printf "Users:\n\t%s\n\n", $users if ($users ne ""); - } - - } -} - -# -# Searches for ABI symbols -# -sub search_symbols { - foreach my $what (sort keys %data) { - next if (!($what =3D~ m/($arg)/)); - - my $type =3D $data{$what}->{type}; - next if ($type eq "File"); - - my $file =3D $data{$what}->{filepath}; - - $what =3D~ s/\xac/, /g; - my $bar =3D $what; - $bar =3D~ s/./-/g; - - print "\n$what\n$bar\n\n"; - - my $kernelversion =3D $data{$what}->{kernelversion} if (defined($data{$w= hat}->{kernelversion})); - my $contact =3D $data{$what}->{contact} if (defined($data{$what}->{conta= ct})); - my $users =3D $data{$what}->{users} if (defined($data{$what}->{users})); - my $date =3D $data{$what}->{date} if (defined($data{$what}->{date})); - my $desc =3D $data{$what}->{description} if (defined($data{$what}->{desc= ription})); - - $kernelversion =3D~ s/^\s+// if ($kernelversion); - $contact =3D~ s/^\s+// if ($contact); - if ($users) { - $users =3D~ s/^\s+//; - $users =3D~ s/\n//g; - } - $date =3D~ s/^\s+// if ($date); - $desc =3D~ s/^\s+// if ($desc); - - printf "Kernel version:\t\t%s\n", $kernelversion if ($kernelversion); - printf "Date:\t\t\t%s\n", $date if ($date); - printf "Contact:\t\t%s\n", $contact if ($contact); - printf "Users:\t\t\t%s\n", $users if ($users); - print "Defined on file(s):\t$file\n\n"; - print "Description:\n\n$desc"; - } -} - -# Exclude /sys/kernel/debug and /sys/kernel/tracing from the search path -sub dont_parse_special_attributes { - if (($File::Find::dir =3D~ m,^/sys/kernel,)) { - return grep {!/(debug|tracing)/ } @_; - } - - if (($File::Find::dir =3D~ m,^/sys/fs,)) { - return grep {!/(pstore|bpf|fuse)/ } @_; - } - - return @_ -} - -my %leaf; -my %aliases; -my @files; -my %root; - -sub graph_add_file { - my $file =3D shift; - my $type =3D shift; - - my $dir =3D $file; - $dir =3D~ s,^(.*/).*,$1,; - $file =3D~ s,.*/,,; - - my $name; - my $file_ref =3D \%root; - foreach my $edge(split "/", $dir) { - $name .=3D "$edge/"; - if (!defined ${$file_ref}{$edge}) { - ${$file_ref}{$edge} =3D { }; - } - $file_ref =3D \%{$$file_ref{$edge}}; - ${$file_ref}{"__name"} =3D [ $name ]; - } - $name .=3D "$file"; - ${$file_ref}{$file} =3D { - "__name" =3D> [ $name ] - }; - - return \%{$$file_ref{$file}}; -} - -sub graph_add_link { - my $file =3D shift; - my $link =3D shift; - - # Traverse graph to find the reference - my $file_ref =3D \%root; - foreach my $edge(split "/", $file) { - $file_ref =3D \%{$$file_ref{$edge}} || die "Missing node!"; - } - - # do a BFS - - my @queue; - my %seen; - my $st; - - push @queue, $file_ref; - $seen{$start}++; - - while (@queue) { - my $v =3D shift @queue; - my @child =3D keys(%{$v}); - - foreach my $c(@child) { - next if $seen{$$v{$c}}; - next if ($c eq "__name"); - - if (!defined($$v{$c}{"__name"})) { - printf STDERR "Error: Couldn't find a non-empty name on a children of = $file/.*: "; - print STDERR Dumper(%{$v}); - exit; - } - - # Add new name - my $name =3D @{$$v{$c}{"__name"}}[0]; - if ($name =3D~ s#^$file/#$link/#) { - push @{$$v{$c}{"__name"}}, $name; - } - # Add child to the queue and mark as seen - push @queue, $$v{$c}; - $seen{$c}++; - } - } -} - -my $escape_symbols =3D qr { ([\x01-\x08\x0e-\x1f\x21-\x29\x2b-\x2d\x3a-\x4= 0\x7b-\xfe]) }x; -sub parse_existing_sysfs { - my $file =3D $File::Find::name; - - my $mode =3D (lstat($file))[2]; - my $abs_file =3D abs_path($file); - - my @tmp; - push @tmp, $file; - push @tmp, $abs_file if ($abs_file ne $file); - - foreach my $f(@tmp) { - # Ignore cgroup, as this is big and has zero docs under ABI - return if ($f =3D~ m#^/sys/fs/cgroup/#); - - # Ignore firmware as it is documented elsewhere - # Either ACPI or under Documentation/devicetree/bindings/ - return if ($f =3D~ m#^/sys/firmware/#); - - # Ignore some sysfs nodes that aren't actually part of ABI - return if ($f =3D~ m#/sections|notes/#); - - # Would need to check at - # Documentation/admin-guide/kernel-parameters.txt, but this - # is not easily parseable. - return if ($f =3D~ m#/parameters/#); - } - - if (S_ISLNK($mode)) { - $aliases{$file} =3D $abs_file; - return; - } - - return if (S_ISDIR($mode)); - - # Trivial: file is defined exactly the same way at ABI What: - return if (defined($data{$file})); - return if (defined($data{$abs_file})); - - push @files, graph_add_file($abs_file, "file"); -} - -sub get_leave($) -{ - my $what =3D shift; - my $leave; - - my $l =3D $what; - my $stop =3D 1; - - $leave =3D $l; - $leave =3D~ s,/$,,; - $leave =3D~ s,.*/,,; - $leave =3D~ s/[\(\)]//g; - - # $leave is used to improve search performance at - # check_undefined_symbols, as the algorithm there can seek - # for a small number of "what". It also allows giving a - # hint about a leave with the same name somewhere else. - # However, there are a few occurences where the leave is - # either a wildcard or a number. Just group such cases - # altogether. - if ($leave =3D~ m/\.\*/ || $leave eq "" || $leave =3D~ /\\d/) { - $leave =3D "others"; - } - - return $leave; -} - -my @not_found; - -sub check_file($$) -{ - my $file_ref =3D shift; - my $names_ref =3D shift; - my @names =3D @{$names_ref}; - my $file =3D $names[0]; - - my $found_string; - - my $leave =3D get_leave($file); - if (!defined($leaf{$leave})) { - $leave =3D "others"; - } - my @expr =3D @{$leaf{$leave}->{expr}}; - die ("\rmissing rules for $leave") if (!defined($leaf{$leave})); - - my $path =3D $file; - $path =3D~ s,(.*/).*,$1,; - - if ($search_string) { - return if (!($file =3D~ m#$search_string#)); - $found_string =3D 1; - } - - for (my $i =3D 0; $i < @names; $i++) { - if ($found_string && $hint) { - if (!$i) { - print STDERR "--> $names[$i]\n"; - } else { - print STDERR " $names[$i]\n"; - } - } - foreach my $re (@expr) { - print STDERR "$names[$i] =3D~ /^$re\$/\n" if ($debug && $dbg_undefined); - if ($names[$i] =3D~ $re) { - return; - } - } - } - - if ($leave ne "others") { - my @expr =3D @{$leaf{"others"}->{expr}}; - for (my $i =3D 0; $i < @names; $i++) { - foreach my $re (@expr) { - print STDERR "$names[$i] =3D~ /^$re\$/\n" if ($debug && $dbg_undefined= ); - if ($names[$i] =3D~ $re) { - return; - } - } - } - } - - push @not_found, $file if (!$search_string || $found_string); - - if ($hint && (!$search_string || $found_string)) { - my $what =3D $leaf{$leave}->{what}; - $what =3D~ s/\xac/\n\t/g; - if ($leave ne "others") { - print STDERR "\r more likely regexes:\n\t$what\n"; - } else { - print STDERR "\r tested regexes:\n\t$what\n"; - } - } -} - -sub check_undefined_symbols { - my $num_files =3D scalar @files; - my $next_i =3D 0; - my $start_time =3D times; - - @files =3D sort @files; - - my $last_time =3D $start_time; - - # When either debug or hint is enabled, there's no sense showing - # progress, as the progress will be overriden. - if ($hint || ($debug && $dbg_undefined)) { - $next_i =3D $num_files; - } - - my $is_console; - $is_console =3D 1 if (-t STDERR); - - for (my $i =3D 0; $i < $num_files; $i++) { - my $file_ref =3D $files[$i]; - my @names =3D @{$$file_ref{"__name"}}; - - check_file($file_ref, \@names); - - my $cur_time =3D times; - - if ($i =3D=3D $next_i || $cur_time > $last_time + 1) { - my $percent =3D $i * 100 / $num_files; - - my $tm =3D $cur_time - $start_time; - my $time =3D sprintf "%d:%02d", int($tm), 60 * ($tm - int($tm)); - - printf STDERR "\33[2K\r", if ($is_console); - printf STDERR "%s: processing sysfs files... %i%%: $names[0]", $time, $= percent; - printf STDERR "\n", if (!$is_console); - STDERR->flush(); - - $next_i =3D int (($percent + 1) * $num_files / 100); - $last_time =3D $cur_time; - } - } - - my $cur_time =3D times; - my $tm =3D $cur_time - $start_time; - my $time =3D sprintf "%d:%02d", int($tm), 60 * ($tm - int($tm)); - - printf STDERR "\33[2K\r", if ($is_console); - printf STDERR "%s: processing sysfs files... done\n", $time; - - foreach my $file (@not_found) { - print "$file not found.\n"; - } -} - -sub undefined_symbols { - print STDERR "Reading $sysfs_prefix directory contents..."; - find({ - wanted =3D>\&parse_existing_sysfs, - preprocess =3D>\&dont_parse_special_attributes, - no_chdir =3D> 1 - }, $sysfs_prefix); - print STDERR "done.\n"; - - $leaf{"others"}->{what} =3D ""; - - print STDERR "Converting ABI What fields into regexes..."; - foreach my $w (sort keys %data) { - foreach my $what (split /\xac/,$w) { - next if (!($what =3D~ m/^$sysfs_prefix/)); - - # Convert what into regular expressions - - # Escape dot characters - $what =3D~ s/\./\xf6/g; - - # Temporarily change [0-9]+ type of patterns - $what =3D~ s/\[0\-9\]\+/\xff/g; - - # Temporarily change [\d+-\d+] type of patterns - $what =3D~ s/\[0\-\d+\]/\xff/g; - $what =3D~ s/\[(\d+)\]/\xf4$1\xf5/g; - - # Temporarily change [0-9] type of patterns - $what =3D~ s/\[(\d)\-(\d)\]/\xf4$1-$2\xf5/g; - - # Handle multiple option patterns - $what =3D~ s/[\{\<\[]([\w_]+)(?:[,|]+([\w_]+)){1,}[\}\>\]]/($1|$2)/g; - - # Handle wildcards - $what =3D~ s,\*,.*,g; - $what =3D~ s,/\xf6..,/.*,g; - $what =3D~ s/\<[^\>]+\>/.*/g; - $what =3D~ s/\{[^\}]+\}/.*/g; - $what =3D~ s/\[[^\]]+\]/.*/g; - - $what =3D~ s/[XYZ]/.*/g; - - # Recover [0-9] type of patterns - $what =3D~ s/\xf4/[/g; - $what =3D~ s/\xf5/]/g; - - # Remove duplicated spaces - $what =3D~ s/\s+/ /g; - - # Special case: this ABI has a parenthesis on it - $what =3D~ s/sqrt\(x^2\+y^2\+z^2\)/sqrt\(x^2\+y^2\+z^2\)/; - - # Special case: drop comparition as in: - # What: foo =3D - # (this happens on a few IIO definitions) - $what =3D~ s,\s*\=3D.*$,,; - - # Escape all other symbols - $what =3D~ s/$escape_symbols/\\$1/g; - $what =3D~ s/\\\\/\\/g; - $what =3D~ s/\\([\[\]\(\)\|])/$1/g; - $what =3D~ s/(\d+)\\(-\d+)/$1$2/g; - - $what =3D~ s/\xff/\\d+/g; - - # Special case: IIO ABI which a parenthesis. - $what =3D~ s/sqrt(.*)/sqrt\(.*\)/; - - # Simplify regexes with multiple .* - $what =3D~ s#(?:\.\*){2,}##g; -# $what =3D~ s#\.\*/\.\*#.*#g; - - # Recover dot characters - $what =3D~ s/\xf6/\./g; - - my $leave =3D get_leave($what); - - my $added =3D 0; - foreach my $l (split /\|/, $leave) { - if (defined($leaf{$l})) { - next if ($leaf{$l}->{what} =3D~ m/\b$what\b/); - $leaf{$l}->{what} .=3D "\xac" . $what; - $added =3D 1; - } else { - $leaf{$l}->{what} =3D $what; - $added =3D 1; - } - } - if ($search_string && $added) { - print STDERR "What: $what\n" if ($what =3D~ m#$search_string#); - } - - } - } - # Compile regexes - foreach my $l (sort keys %leaf) { - my @expr; - foreach my $w(sort split /\xac/, $leaf{$l}->{what}) { - push @expr, qr /^$w$/; - } - $leaf{$l}->{expr} =3D \@expr; - } - - # Take links into account - foreach my $link (sort keys %aliases) { - my $abs_file =3D $aliases{$link}; - graph_add_link($abs_file, $link); - } - print STDERR "done.\n"; - - check_undefined_symbols; -} - -# 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 =3D~ s,/?$,/,; - -if ($cmd eq "undefined" || $cmd eq "search") { - $show_warnings =3D 0; -} -# -# Parses all ABI files located at $prefix dir -# -find({wanted =3D>\&parse_abi, no_chdir =3D> 1}, $prefix); - -print STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug & $dbg_d= ump_abi_structs); - -# -# Handles the command -# -if ($cmd eq "undefined") { - undefined_symbols; -} elsif ($cmd eq "search") { - search_symbols; -} else { - if ($cmd eq "rest") { - output_rest; - } - - # Warn about duplicated ABI entries - foreach my $what(sort keys %symbols) { - my @files =3D @{$symbols{$what}->{file}}; - - next if (scalar(@files) =3D=3D 1); - - printf STDERR "Warning: $what is defined %d times: @files\n", - scalar(@files); - } -} - -__END__ - -=3Dhead1 NAME - -get_abi.pl - parse the Linux ABI files and produce a ReST book. - -=3Dhead1 SYNOPSIS - -B [--debug ] [--enable-lineno] [--man] [--help] - [--(no-)rst-source] [--dir=3D] [--show-hints] - [--search-string ] - [] - -Where B can be: - -=3Dover 8 - -B I - search for I inside ABI - -B - output the ABI in ReST markup language - -B - validate the ABI contents - -B - existing symbols at the system that aren't - defined at Documentation/ABI - -=3Dback - -=3Dhead1 OPTIONS - -=3Dover 8 - -=3Ditem B<--dir> - -Changes the location of the ABI search. By default, it uses -the Documentation/ABI directory. - -=3Ditem 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 (B<--rst-source>), or a -plain text that may be violating ReST spec, so it requres some escaping -logic (B<--no-rst-source>). - -=3Ditem B<--enable-lineno> - -Enable output of .. LINENO lines. - -=3Ditem B<--debug> I - -Print debug information according with the level, which is given by the -following bitmask: - - - 1: Debug parsing What entries from ABI files; - - 2: Shows what files are opened from ABI files; - - 4: Dump the structs used to store the contents of the ABI files. - -=3Ditem B<--show-hints> - -Show hints about possible definitions for the missing ABI symbols. -Used only when B. - -=3Ditem B<--search-string> I - -Show only occurences that match a search string. -Used only when B. - -=3Ditem B<--help> - -Prints a brief help message and exits. - -=3Ditem B<--man> - -Prints the manual page and exits. - -=3Dback - -=3Dhead1 DESCRIPTION - -Parse the Linux ABI files from ABI DIR (usually located at Documentation/A= BI), -allowing to search for ABI symbols or to produce a ReST book containing -the Linux ABI documentation. - -=3Dhead1 EXAMPLES - -Search for all stable symbols with the word "usb": - -=3Dover 8 - -$ scripts/get_abi.pl search usb --dir Documentation/ABI/stable - -=3Dback - -Search for all symbols that match the regex expression "usb.*cap": - -=3Dover 8 - -$ scripts/get_abi.pl search usb.*cap - -=3Dback - -Output all obsoleted symbols in ReST format - -=3Dover 8 - -$ scripts/get_abi.pl rest --dir Documentation/ABI/obsolete - -=3Dback - -=3Dhead1 BUGS - -Report bugs to Mauro Carvalho Chehab - -=3Dhead1 COPYRIGHT - -Copyright (c) 2016-2021 by Mauro Carvalho Chehab . - -License GPLv2: GNU GPL version 2 . - -This is free software: you are free to change and redistribute it. -There is NO WARRANTY, to the extent permitted by law. - -=3Dcut --=20 2.48.1