From nobody Tue Dec 2 02:41:52 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 AEC0D36921F; Tue, 18 Nov 2025 19:09:42 +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=1763492982; cv=none; b=oPI1cqM/s9zwnT3fVbpYDeY1dmVk2beZcyKBJNzNZVt9N3BqpQ5QXGUhmtUjs8UeKJ5znRr370gH9/3JQ/ryVfAE9XTBym20Oi/Ohk5wbWF32QPZYTsOLs1GlnuRoJY5OZA2uu4XYf3C9OfNYdXaTQOWCj8FyND8deJoOcE73Cs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763492982; c=relaxed/simple; bh=pXSkk7JQqoaPjJMx/lQckHYi4LcLVPHAn7LMXiLemvk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lV82me8Y9dW5GiOFOUNJbX46Al789c5UbqgCiNLVHgIQLfd90k91XqCICOfbDFMjYHI0UyYgJWodNz7CGtbqnqNwifjm4HStn3C3awBNuCJ8OpgqmHuFKFntgSpK9hz5r2qbbL/ezG7kpnoklPnORCuHHowM8nGrxA4H65Mjn8M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=blFJkGEr; 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="blFJkGEr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9E0D7C2BCB4; Tue, 18 Nov 2025 19:09:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763492982; bh=pXSkk7JQqoaPjJMx/lQckHYi4LcLVPHAn7LMXiLemvk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=blFJkGErJGBLtQ3KzI5a29EDJMwPtb1ej5iOMHM+UGYlgA+YdNEOzEMhDw430sxX7 wbFT2rAvhGCR3EETLSCYf4GHpgwKAGV/Ao46hb+5fnc/+GbU/IEGZyDPKFKVVlUq1a fl9MOwXr1pav1nZ7q3ONcRPkzJOLPKoA3abISy44AyrR63vDYGuamIyrXxtJ7mJQpX zn10jdSoFGB5ku0wCQP++b2F3pC7LD7++vrltmGEGRTS5jNKeKpoAN5vzE/T58rtUq zDNtV2jALEVoVoKZTw8lJHNMqCW+v+ZG88N+AUohGu0q7Bfu/NOw3byP5niqwcrqsr 8Qe+xcxO0xd4Q== Received: from mchehab by mail.kernel.org with local (Exim 4.99) (envelope-from ) id 1vLR58-000000042hY-1MMg; Tue, 18 Nov 2025 20:09:38 +0100 From: Mauro Carvalho Chehab To: "Jonathan Corbet" , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , "Mauro Carvalho Chehab" , linux-kernel@vger.kernel.org Subject: [PATCH v2 3/3] get_feat.pl: remove it, as it got replaced by get_feat.py Date: Tue, 18 Nov 2025 20:09:28 +0100 Message-ID: <1f53e0fa48616af189ce98b45a65cc0c245e7aaf.1763492868.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.51.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" Now that this was rewritten in Python, we can remove the old tool. Signed-off-by: Mauro Carvalho Chehab --- tools/docs/get_feat.pl | 641 ----------------------------------------- 1 file changed, 641 deletions(-) delete mode 100755 tools/docs/get_feat.pl diff --git a/tools/docs/get_feat.pl b/tools/docs/get_feat.pl deleted file mode 100755 index d75e7c85dc85..000000000000 --- a/tools/docs/get_feat.pl +++ /dev/null @@ -1,641 +0,0 @@ -#!/usr/bin/env perl -# SPDX-License-Identifier: GPL-2.0 - -use strict; -use Pod::Usage; -use Getopt::Long; -use File::Find; -use Fcntl ':mode'; -use Cwd 'abs_path'; - -my $help; -my $man; -my $debug; -my $arch; -my $feat; -my $enable_fname; - -my $basename =3D abs_path($0); -$basename =3D~ s,/[^/]+$,/,; - -my $prefix=3D$basename . "../../Documentation/features"; - -# Used only at for full features output. The script will auto-adjust -# such values for the minimal possible values -my $status_size =3D 1; -my $description_size =3D 1; - -GetOptions( - "debug|d+" =3D> \$debug, - "dir=3Ds" =3D> \$prefix, - 'help|?' =3D> \$help, - 'arch=3Ds' =3D> \$arch, - 'feat=3Ds' =3D> \$feat, - 'feature=3Ds' =3D> \$feat, - "enable-fname" =3D> \$enable_fname, - man =3D> \$man -) or pod2usage(2); - -pod2usage(1) if $help; -pod2usage(-exitstatus =3D> 0, -verbose =3D> 2) if $man; - -pod2usage(1) if (scalar @ARGV < 1 || @ARGV > 2); - -my ($cmd, $arg) =3D @ARGV; - -pod2usage(2) if ($cmd ne "current" && $cmd ne "rest" && $cmd ne "validate" - && $cmd ne "ls" && $cmd ne "list"); - -require Data::Dumper if ($debug); - -my %data; -my %archs; - -# -# Displays an error message, printing file name and line -# -sub parse_error($$$$) { - my ($file, $ln, $msg, $data) =3D @_; - - $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 a features file, storing its contents at %data -# - -my $h_name =3D "Feature"; -my $h_kconfig =3D "Kconfig"; -my $h_description =3D "Description"; -my $h_subsys =3D "Subsystem"; -my $h_status =3D "Status"; -my $h_arch =3D "Architecture"; - -my $max_size_name =3D length($h_name); -my $max_size_kconfig =3D length($h_kconfig); -my $max_size_description =3D length($h_description); -my $max_size_subsys =3D length($h_subsys); -my $max_size_status =3D length($h_status); - -my $max_size_arch =3D 0; -my $max_size_arch_with_header; -my $max_description_word =3D 0; - -sub parse_feat { - my $file =3D $File::Find::name; - - my $mode =3D (stat($file))[2]; - return if ($mode & S_IFDIR); - return if ($file =3D~ m,($prefix)/arch-support.txt,); - return if (!($file =3D~ m,arch-support.txt$,)); - - if ($enable_fname) { - printf ".. FILE %s\n", abs_path($file); - } - - my $subsys =3D ""; - $subsys =3D $2 if ( m,.*($prefix)/([^/]+).*,); - - if (length($subsys) > $max_size_subsys) { - $max_size_subsys =3D length($subsys); - } - - my $name; - my $kconfig; - my $description; - my $comments =3D ""; - my $last_status; - my $ln; - my %arch_table; - - print STDERR "Opening $file\n" if ($debug > 1); - open IN, $file; - - while() { - $ln++; - - if (m/^\#\s+Feature\s+name:\s*(.*\S)/) { - $name =3D $1; - if (length($name) > $max_size_name) { - $max_size_name =3D length($name); - } - next; - } - if (m/^\#\s+Kconfig:\s*(.*\S)/) { - $kconfig =3D $1; - if (length($kconfig) > $max_size_kconfig) { - $max_size_kconfig =3D length($kconfig); - } - next; - } - if (m/^\#\s+description:\s*(.*\S)/) { - $description =3D $1; - if (length($description) > $max_size_description) { - $max_size_description =3D length($description); - } - - foreach my $word (split /\s+/, $description) { - if (length($word) > $max_description_word) { - $max_description_word =3D length($word); - } - } - - next; - } - next if (m/^\\s*$/); - next if (m/^\s*\-+\s*$/); - next if (m/^\s*\|\s*arch\s*\|\s*status\s*\|\s*$/); - - if (m/^\#\s*(.*)/) { - $comments .=3D "$1\n"; - next; - } - if (m/^\s*\|\s*(\S+):\s*\|\s*(\S+)\s*\|\s*$/) { - my $a =3D $1; - my $status =3D $2; - - if (length($status) > $max_size_status) { - $max_size_status =3D length($status); - } - if (length($a) > $max_size_arch) { - $max_size_arch =3D length($a); - } - - $status =3D "---" if ($status =3D~ m/^\.\.$/); - - $archs{$a} =3D 1; - $arch_table{$a} =3D $status; - next; - } - - #Everything else is an error - parse_error($file, $ln, "line is invalid", $_); - } - close IN; - - if (!$name) { - parse_error($file, $ln, "Feature name not found", ""); - return; - } - - parse_error($file, $ln, "Subsystem not found", "") if (!$subsys); - parse_error($file, $ln, "Kconfig not found", "") if (!$kconfig); - parse_error($file, $ln, "Description not found", "") if (!$description); - - if (!%arch_table) { - parse_error($file, $ln, "Architecture table not found", ""); - return; - } - - $data{$name}->{where} =3D $file; - $data{$name}->{subsys} =3D $subsys; - $data{$name}->{kconfig} =3D $kconfig; - $data{$name}->{description} =3D $description; - $data{$name}->{comments} =3D $comments; - $data{$name}->{table} =3D \%arch_table; - - $max_size_arch_with_header =3D $max_size_arch + length($h_arch); -} - -# -# Output feature(s) for a given architecture -# -sub output_arch_table { - my $title =3D "Feature status on $arch architecture"; - - print "=3D" x length($title) . "\n"; - print "$title\n"; - print "=3D" x length($title) . "\n\n"; - - print "=3D" x $max_size_subsys; - print " "; - print "=3D" x $max_size_name; - print " "; - print "=3D" x $max_size_kconfig; - print " "; - print "=3D" x $max_size_status; - print " "; - print "=3D" x $max_size_description; - print "\n"; - printf "%-${max_size_subsys}s ", $h_subsys; - printf "%-${max_size_name}s ", $h_name; - printf "%-${max_size_kconfig}s ", $h_kconfig; - printf "%-${max_size_status}s ", $h_status; - printf "%-${max_size_description}s\n", $h_description; - print "=3D" x $max_size_subsys; - print " "; - print "=3D" x $max_size_name; - print " "; - print "=3D" x $max_size_kconfig; - print " "; - print "=3D" x $max_size_status; - print " "; - print "=3D" x $max_size_description; - print "\n"; - - foreach my $name (sort { - ($data{$a}->{subsys} cmp $data{$b}->{subsys}) || - ("\L$a" cmp "\L$b") - } keys %data) { - next if ($feat && $name ne $feat); - - my %arch_table =3D %{$data{$name}->{table}}; - printf "%-${max_size_subsys}s ", $data{$name}->{subsys}; - printf "%-${max_size_name}s ", $name; - printf "%-${max_size_kconfig}s ", $data{$name}->{kconfig}; - printf "%-${max_size_status}s ", $arch_table{$arch}; - printf "%-s\n", $data{$name}->{description}; - } - - print "=3D" x $max_size_subsys; - print " "; - print "=3D" x $max_size_name; - print " "; - print "=3D" x $max_size_kconfig; - print " "; - print "=3D" x $max_size_status; - print " "; - print "=3D" x $max_size_description; - print "\n"; -} - -# -# list feature(s) for a given architecture -# -sub list_arch_features { - print "#\n# Kernel feature support matrix of the '$arch' architecture:\n#= \n"; - - foreach my $name (sort { - ($data{$a}->{subsys} cmp $data{$b}->{subsys}) || - ("\L$a" cmp "\L$b") - } keys %data) { - next if ($feat && $name ne $feat); - - my %arch_table =3D %{$data{$name}->{table}}; - - my $status =3D $arch_table{$arch}; - $status =3D " " x ((4 - length($status)) / 2) . $status; - - printf " %${max_size_subsys}s/ ", $data{$name}->{subsys}; - printf "%-${max_size_name}s: ", $name; - printf "%-5s| ", $status; - printf "%${max_size_kconfig}s # ", $data{$name}->{kconfig}; - printf " %s\n", $data{$name}->{description}; - } -} - -# -# Output a feature on all architectures -# -sub output_feature { - my $title =3D "Feature $feat"; - - print "=3D" x length($title) . "\n"; - print "$title\n"; - print "=3D" x length($title) . "\n\n"; - - print ":Subsystem: $data{$feat}->{subsys} \n" if ($data{$feat}->{subsys}); - print ":Kconfig: $data{$feat}->{kconfig} \n" if ($data{$feat}->{kconfig}); - - my $desc =3D $data{$feat}->{description}; - $desc =3D~ s/^([a-z])/\U$1/; - $desc =3D~ s/\.?\s*//; - print "\n$desc.\n\n"; - - my $com =3D $data{$feat}->{comments}; - $com =3D~ s/^\s+//; - $com =3D~ s/\s+$//; - if ($com) { - print "Comments\n"; - print "--------\n\n"; - print "$com\n\n"; - } - - print "=3D" x $max_size_arch_with_header; - print " "; - print "=3D" x $max_size_status; - print "\n"; - - printf "%-${max_size_arch}s ", $h_arch; - printf "%-${max_size_status}s", $h_status . "\n"; - - print "=3D" x $max_size_arch_with_header; - print " "; - print "=3D" x $max_size_status; - print "\n"; - - my %arch_table =3D %{$data{$feat}->{table}}; - foreach my $arch (sort keys %arch_table) { - printf "%-${max_size_arch}s ", $arch; - printf "%-${max_size_status}s\n", $arch_table{$arch}; - } - - print "=3D" x $max_size_arch_with_header; - print " "; - print "=3D" x $max_size_status; - print "\n"; -} - -# -# Output all features for all architectures -# - -sub matrix_lines($$$) { - my $desc_size =3D shift; - my $status_size =3D shift; - my $header =3D shift; - my $fill; - my $ln_marker; - - if ($header) { - $ln_marker =3D "=3D"; - } else { - $ln_marker =3D "-"; - } - - $fill =3D $ln_marker; - - print "+"; - print $fill x $max_size_name; - print "+"; - print $fill x $desc_size; - print "+"; - print $ln_marker x $status_size; - print "+\n"; -} - -sub output_matrix { - my $title =3D "Feature status on all architectures"; - my $notcompat =3D "Not compatible"; - - print "=3D" x length($title) . "\n"; - print "$title\n"; - print "=3D" x length($title) . "\n\n"; - - my $desc_title =3D "$h_kconfig / $h_description"; - - my $desc_size =3D $max_size_kconfig + 4; - if (!$description_size) { - $desc_size =3D $max_size_description if ($max_size_description > $desc_s= ize); - } else { - $desc_size =3D $description_size if ($description_size > $desc_size); - } - $desc_size =3D $max_description_word if ($max_description_word > $desc_si= ze); - - $desc_size =3D length($desc_title) if (length($desc_title) > $desc_size); - - $max_size_status =3D length($notcompat) if (length($notcompat) > $max_siz= e_status); - - # Ensure that the status will fit - my $min_status_size =3D $max_size_status + $max_size_arch + 6; - $status_size =3D $min_status_size if ($status_size < $min_status_size); - - - my $cur_subsys =3D ""; - foreach my $name (sort { - ($data{$a}->{subsys} cmp $data{$b}->{subsys}) or - ("\L$a" cmp "\L$b") - } keys %data) { - - if ($cur_subsys ne $data{$name}->{subsys}) { - if ($cur_subsys ne "") { - printf "\n"; - } - - $cur_subsys =3D $data{$name}->{subsys}; - - my $title =3D "Subsystem: $cur_subsys"; - print "$title\n"; - print "=3D" x length($title) . "\n\n"; - - - matrix_lines($desc_size, $status_size, 0); - - printf "|%-${max_size_name}s", $h_name; - printf "|%-${desc_size}s", $desc_title; - - printf "|%-${status_size}s|\n", "Status per architecture"; - matrix_lines($desc_size, $status_size, 1); - } - - my %arch_table =3D %{$data{$name}->{table}}; - my $cur_status =3D ""; - - my (@lines, @descs); - my $line =3D ""; - foreach my $arch (sort { - ($arch_table{$b} cmp $arch_table{$a}) or - ("\L$a" cmp "\L$b") - } keys %arch_table) { - - my $status =3D $arch_table{$arch}; - - if ($status eq "---") { - $status =3D $notcompat; - } - - if ($status ne $cur_status) { - if ($line ne "") { - push @lines, $line; - $line =3D ""; - } - $line =3D "- **" . $status . "**: " . $arch; - } elsif (length($line) + length ($arch) + 2 < $status_size) { - $line .=3D ", " . $arch; - } else { - push @lines, $line; - $line =3D " " . $arch; - } - $cur_status =3D $status; - } - push @lines, $line if ($line ne ""); - - my $description =3D $data{$name}->{description}; - while (length($description) > $desc_size) { - my $d =3D substr $description, 0, $desc_size; - - # Ensure that it will end on a space - # if it can't, it means that the size is too small - # Instead of aborting it, let's print what we have - if (!($d =3D~ s/^(.*)\s+.*/$1/)) { - $d =3D substr $d, 0, -1; - push @descs, "$d\\"; - $description =3D~ s/^\Q$d\E//; - } else { - push @descs, $d; - $description =3D~ s/^\Q$d\E\s+//; - } - } - push @descs, $description; - - # Ensure that the full description will be printed - push @lines, "" while (scalar(@lines) < 2 + scalar(@descs)); - - my $ln =3D 0; - for my $line(@lines) { - if (!$ln) { - printf "|%-${max_size_name}s", $name; - printf "|%-${desc_size}s", "``" . $data{$name}->{kconfig} . "``"; - } elsif ($ln >=3D 2 && scalar(@descs)) { - printf "|%-${max_size_name}s", ""; - printf "|%-${desc_size}s", shift @descs; - } else { - printf "|%-${max_size_name}s", ""; - printf "|%-${desc_size}s", ""; - } - - printf "|%-${status_size}s|\n", $line; - - $ln++; - } - matrix_lines($desc_size, $status_size, 0); - } -} - - -# -# Parses all feature files located at $prefix dir -# -find({wanted =3D>\&parse_feat, no_chdir =3D> 1}, $prefix); - -print STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug); - -# -# Handles the command -# -if ($cmd eq "current") { - $arch =3D qx(uname -m | sed 's/x86_64/x86/' | sed 's/i386/x86/' | sed 's/= s390x/s390/'); - $arch =3D~s/\s+$//; -} - -if ($cmd eq "ls" or $cmd eq "list") { - if (!$arch) { - $arch =3D qx(uname -m | sed 's/x86_64/x86/' | sed 's/i386/x86/' | sed 's= /s390x/s390/'); - $arch =3D~s/\s+$//; - } - - list_arch_features; - - exit; -} - -if ($cmd ne "validate") { - if ($arch) { - output_arch_table; - } elsif ($feat) { - output_feature; - } else { - output_matrix; - } -} - -__END__ - -=3Dhead1 NAME - -get_feat.pl - parse the Linux Feature files and produce a ReST book. - -=3Dhead1 SYNOPSIS - -B [--debug] [--man] [--help] [--dir=3D] [--arch=3D] - [--feature=3D|--feat=3D] [] - -Where can be: - -=3Dover 8 - -B - output table in ReST compatible ASCII format - with features for this machine's architecture - -B - output table(s) in ReST compatible ASCII format - with features in ReST markup language. The output - is affected by --arch or --feat/--feature flags. - -B - validate the contents of the files under - Documentation/features. - -B or B - list features for this machine's architecture, - using an easier to parse format. - The output is affected by --arch flag. - -=3Dback - -=3Dhead1 OPTIONS - -=3Dover 8 - -=3Ditem B<--arch> - -Output features for an specific architecture, optionally filtering for -a single specific feature. - -=3Ditem B<--feat> or B<--feature> - -Output features for a single specific feature. - -=3Ditem B<--dir> - -Changes the location of the Feature files. By default, it uses -the Documentation/features directory. - -=3Ditem B<--enable-fname> - -Prints the file name of the feature files. This can be used in order to -track dependencies during documentation build. - -=3Ditem B<--debug> - -Put the script in verbose mode, useful for debugging. Can be called multip= le -times, to increase verbosity. - -=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 feature files from Documentation/features (by default), -optionally producing results at ReST format. - -It supports output data per architecture, per feature or a -feature x arch matrix. - -When used with B command, it will use either one of the tree formats: - -If neither B<--arch> or B<--feature> arguments are used, it will output a -matrix with features per architecture. - -If B<--arch> argument is used, it will output the features availability for -a given architecture. - -If B<--feat> argument is used, it will output the content of the feature -file using ReStructured Text markup. - -=3Dhead1 BUGS - -Report bugs to Mauro Carvalho Chehab - -=3Dhead1 COPYRIGHT - -Copyright (c) 2019 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.51.1