1*2bc64308SDavid Reaver#!/usr/bin/env perl 252a4be3fSMauro Carvalho Chehab# SPDX-License-Identifier: GPL-2.0 352a4be3fSMauro Carvalho Chehab 452a4be3fSMauro Carvalho Chehabuse strict; 552a4be3fSMauro Carvalho Chehabuse Pod::Usage; 652a4be3fSMauro Carvalho Chehabuse Getopt::Long; 752a4be3fSMauro Carvalho Chehabuse File::Find; 852a4be3fSMauro Carvalho Chehabuse Fcntl ':mode'; 9ca908577SMauro Carvalho Chehabuse Cwd 'abs_path'; 1052a4be3fSMauro Carvalho Chehab 1152a4be3fSMauro Carvalho Chehabmy $help; 1252a4be3fSMauro Carvalho Chehabmy $man; 1352a4be3fSMauro Carvalho Chehabmy $debug; 1452a4be3fSMauro Carvalho Chehabmy $arch; 1552a4be3fSMauro Carvalho Chehabmy $feat; 1601096e5cSMauro Carvalho Chehabmy $enable_fname; 17ca908577SMauro Carvalho Chehab 18ca908577SMauro Carvalho Chehabmy $basename = abs_path($0); 19ca908577SMauro Carvalho Chehab$basename =~ s,/[^/]+$,/,; 20ca908577SMauro Carvalho Chehab 21ca908577SMauro Carvalho Chehabmy $prefix=$basename . "../Documentation/features"; 2252a4be3fSMauro Carvalho Chehab 23f5889e70SMauro Carvalho Chehab# Used only at for full features output. The script will auto-adjust 24f5889e70SMauro Carvalho Chehab# such values for the minimal possible values 25f5889e70SMauro Carvalho Chehabmy $status_size = 1; 26f5889e70SMauro Carvalho Chehabmy $description_size = 1; 27f5889e70SMauro Carvalho Chehab 2852a4be3fSMauro Carvalho ChehabGetOptions( 2952a4be3fSMauro Carvalho Chehab "debug|d+" => \$debug, 3052a4be3fSMauro Carvalho Chehab "dir=s" => \$prefix, 3152a4be3fSMauro Carvalho Chehab 'help|?' => \$help, 3252a4be3fSMauro Carvalho Chehab 'arch=s' => \$arch, 3352a4be3fSMauro Carvalho Chehab 'feat=s' => \$feat, 34ca908577SMauro Carvalho Chehab 'feature=s' => \$feat, 3501096e5cSMauro Carvalho Chehab "enable-fname" => \$enable_fname, 3652a4be3fSMauro Carvalho Chehab man => \$man 3752a4be3fSMauro Carvalho Chehab) or pod2usage(2); 3852a4be3fSMauro Carvalho Chehab 3952a4be3fSMauro Carvalho Chehabpod2usage(1) if $help; 4052a4be3fSMauro Carvalho Chehabpod2usage(-exitstatus => 0, -verbose => 2) if $man; 4152a4be3fSMauro Carvalho Chehab 42ca908577SMauro Carvalho Chehabpod2usage(1) if (scalar @ARGV < 1 || @ARGV > 2); 4352a4be3fSMauro Carvalho Chehab 4452a4be3fSMauro Carvalho Chehabmy ($cmd, $arg) = @ARGV; 4552a4be3fSMauro Carvalho Chehab 46ca908577SMauro Carvalho Chehabpod2usage(2) if ($cmd ne "current" && $cmd ne "rest" && $cmd ne "validate" 47ca908577SMauro Carvalho Chehab && $cmd ne "ls" && $cmd ne "list"); 4852a4be3fSMauro Carvalho Chehab 4952a4be3fSMauro Carvalho Chehabrequire Data::Dumper if ($debug); 5052a4be3fSMauro Carvalho Chehab 5152a4be3fSMauro Carvalho Chehabmy %data; 5252a4be3fSMauro Carvalho Chehabmy %archs; 5352a4be3fSMauro Carvalho Chehab 5452a4be3fSMauro Carvalho Chehab# 5552a4be3fSMauro Carvalho Chehab# Displays an error message, printing file name and line 5652a4be3fSMauro Carvalho Chehab# 5752a4be3fSMauro Carvalho Chehabsub parse_error($$$$) { 5852a4be3fSMauro Carvalho Chehab my ($file, $ln, $msg, $data) = @_; 5952a4be3fSMauro Carvalho Chehab 6052a4be3fSMauro Carvalho Chehab $data =~ s/\s+$/\n/; 6152a4be3fSMauro Carvalho Chehab 6252a4be3fSMauro Carvalho Chehab print STDERR "Warning: file $file#$ln:\n\t$msg"; 6352a4be3fSMauro Carvalho Chehab 6452a4be3fSMauro Carvalho Chehab if ($data ne "") { 6552a4be3fSMauro Carvalho Chehab print STDERR ". Line\n\t\t$data"; 6652a4be3fSMauro Carvalho Chehab } else { 6752a4be3fSMauro Carvalho Chehab print STDERR "\n"; 6852a4be3fSMauro Carvalho Chehab } 6952a4be3fSMauro Carvalho Chehab} 7052a4be3fSMauro Carvalho Chehab 7152a4be3fSMauro Carvalho Chehab# 7252a4be3fSMauro Carvalho Chehab# Parse a features file, storing its contents at %data 7352a4be3fSMauro Carvalho Chehab# 7452a4be3fSMauro Carvalho Chehab 7552a4be3fSMauro Carvalho Chehabmy $h_name = "Feature"; 7652a4be3fSMauro Carvalho Chehabmy $h_kconfig = "Kconfig"; 7752a4be3fSMauro Carvalho Chehabmy $h_description = "Description"; 7852a4be3fSMauro Carvalho Chehabmy $h_subsys = "Subsystem"; 7952a4be3fSMauro Carvalho Chehabmy $h_status = "Status"; 8052a4be3fSMauro Carvalho Chehabmy $h_arch = "Architecture"; 8152a4be3fSMauro Carvalho Chehab 8252a4be3fSMauro Carvalho Chehabmy $max_size_name = length($h_name); 8352a4be3fSMauro Carvalho Chehabmy $max_size_kconfig = length($h_kconfig); 8452a4be3fSMauro Carvalho Chehabmy $max_size_description = length($h_description); 8552a4be3fSMauro Carvalho Chehabmy $max_size_subsys = length($h_subsys); 8652a4be3fSMauro Carvalho Chehabmy $max_size_status = length($h_status); 87f5889e70SMauro Carvalho Chehab 88f5889e70SMauro Carvalho Chehabmy $max_size_arch = 0; 89f5889e70SMauro Carvalho Chehabmy $max_size_arch_with_header; 90f5889e70SMauro Carvalho Chehabmy $max_description_word = 0; 9152a4be3fSMauro Carvalho Chehab 9252a4be3fSMauro Carvalho Chehabsub parse_feat { 9352a4be3fSMauro Carvalho Chehab my $file = $File::Find::name; 9452a4be3fSMauro Carvalho Chehab 9552a4be3fSMauro Carvalho Chehab my $mode = (stat($file))[2]; 9652a4be3fSMauro Carvalho Chehab return if ($mode & S_IFDIR); 9752a4be3fSMauro Carvalho Chehab return if ($file =~ m,($prefix)/arch-support.txt,); 9852a4be3fSMauro Carvalho Chehab return if (!($file =~ m,arch-support.txt$,)); 9952a4be3fSMauro Carvalho Chehab 10001096e5cSMauro Carvalho Chehab if ($enable_fname) { 10101096e5cSMauro Carvalho Chehab printf ".. FILE %s\n", abs_path($file); 10201096e5cSMauro Carvalho Chehab } 10301096e5cSMauro Carvalho Chehab 10452a4be3fSMauro Carvalho Chehab my $subsys = ""; 10552a4be3fSMauro Carvalho Chehab $subsys = $2 if ( m,.*($prefix)/([^/]+).*,); 10652a4be3fSMauro Carvalho Chehab 10752a4be3fSMauro Carvalho Chehab if (length($subsys) > $max_size_subsys) { 10852a4be3fSMauro Carvalho Chehab $max_size_subsys = length($subsys); 10952a4be3fSMauro Carvalho Chehab } 11052a4be3fSMauro Carvalho Chehab 11152a4be3fSMauro Carvalho Chehab my $name; 11252a4be3fSMauro Carvalho Chehab my $kconfig; 11352a4be3fSMauro Carvalho Chehab my $description; 11452a4be3fSMauro Carvalho Chehab my $comments = ""; 11552a4be3fSMauro Carvalho Chehab my $last_status; 11652a4be3fSMauro Carvalho Chehab my $ln; 11752a4be3fSMauro Carvalho Chehab my %arch_table; 11852a4be3fSMauro Carvalho Chehab 11952a4be3fSMauro Carvalho Chehab print STDERR "Opening $file\n" if ($debug > 1); 12052a4be3fSMauro Carvalho Chehab open IN, $file; 12152a4be3fSMauro Carvalho Chehab 12252a4be3fSMauro Carvalho Chehab while(<IN>) { 12352a4be3fSMauro Carvalho Chehab $ln++; 12452a4be3fSMauro Carvalho Chehab 12552a4be3fSMauro Carvalho Chehab if (m/^\#\s+Feature\s+name:\s*(.*\S)/) { 12652a4be3fSMauro Carvalho Chehab $name = $1; 12752a4be3fSMauro Carvalho Chehab if (length($name) > $max_size_name) { 12852a4be3fSMauro Carvalho Chehab $max_size_name = length($name); 12952a4be3fSMauro Carvalho Chehab } 13052a4be3fSMauro Carvalho Chehab next; 13152a4be3fSMauro Carvalho Chehab } 13252a4be3fSMauro Carvalho Chehab if (m/^\#\s+Kconfig:\s*(.*\S)/) { 13352a4be3fSMauro Carvalho Chehab $kconfig = $1; 13452a4be3fSMauro Carvalho Chehab if (length($kconfig) > $max_size_kconfig) { 13552a4be3fSMauro Carvalho Chehab $max_size_kconfig = length($kconfig); 13652a4be3fSMauro Carvalho Chehab } 13752a4be3fSMauro Carvalho Chehab next; 13852a4be3fSMauro Carvalho Chehab } 13952a4be3fSMauro Carvalho Chehab if (m/^\#\s+description:\s*(.*\S)/) { 14052a4be3fSMauro Carvalho Chehab $description = $1; 14152a4be3fSMauro Carvalho Chehab if (length($description) > $max_size_description) { 14252a4be3fSMauro Carvalho Chehab $max_size_description = length($description); 14352a4be3fSMauro Carvalho Chehab } 144f5889e70SMauro Carvalho Chehab 145f5889e70SMauro Carvalho Chehab foreach my $word (split /\s+/, $description) { 146f5889e70SMauro Carvalho Chehab if (length($word) > $max_description_word) { 147f5889e70SMauro Carvalho Chehab $max_description_word = length($word); 148f5889e70SMauro Carvalho Chehab } 149f5889e70SMauro Carvalho Chehab } 150f5889e70SMauro Carvalho Chehab 15152a4be3fSMauro Carvalho Chehab next; 15252a4be3fSMauro Carvalho Chehab } 15352a4be3fSMauro Carvalho Chehab next if (m/^\\s*$/); 15452a4be3fSMauro Carvalho Chehab next if (m/^\s*\-+\s*$/); 15552a4be3fSMauro Carvalho Chehab next if (m/^\s*\|\s*arch\s*\|\s*status\s*\|\s*$/); 15652a4be3fSMauro Carvalho Chehab 15752a4be3fSMauro Carvalho Chehab if (m/^\#\s*(.*)/) { 15852a4be3fSMauro Carvalho Chehab $comments .= "$1\n"; 15952a4be3fSMauro Carvalho Chehab next; 16052a4be3fSMauro Carvalho Chehab } 16152a4be3fSMauro Carvalho Chehab if (m/^\s*\|\s*(\S+):\s*\|\s*(\S+)\s*\|\s*$/) { 16252a4be3fSMauro Carvalho Chehab my $a = $1; 16352a4be3fSMauro Carvalho Chehab my $status = $2; 16452a4be3fSMauro Carvalho Chehab 16552a4be3fSMauro Carvalho Chehab if (length($status) > $max_size_status) { 16652a4be3fSMauro Carvalho Chehab $max_size_status = length($status); 16752a4be3fSMauro Carvalho Chehab } 16852a4be3fSMauro Carvalho Chehab if (length($a) > $max_size_arch) { 16952a4be3fSMauro Carvalho Chehab $max_size_arch = length($a); 17052a4be3fSMauro Carvalho Chehab } 17152a4be3fSMauro Carvalho Chehab 17252a4be3fSMauro Carvalho Chehab $status = "---" if ($status =~ m/^\.\.$/); 17352a4be3fSMauro Carvalho Chehab 17452a4be3fSMauro Carvalho Chehab $archs{$a} = 1; 17552a4be3fSMauro Carvalho Chehab $arch_table{$a} = $status; 17652a4be3fSMauro Carvalho Chehab next; 17752a4be3fSMauro Carvalho Chehab } 17852a4be3fSMauro Carvalho Chehab 17952a4be3fSMauro Carvalho Chehab #Everything else is an error 18052a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "line is invalid", $_); 18152a4be3fSMauro Carvalho Chehab } 18252a4be3fSMauro Carvalho Chehab close IN; 18352a4be3fSMauro Carvalho Chehab 18452a4be3fSMauro Carvalho Chehab if (!$name) { 18552a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "Feature name not found", ""); 18652a4be3fSMauro Carvalho Chehab return; 18752a4be3fSMauro Carvalho Chehab } 18852a4be3fSMauro Carvalho Chehab 18952a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "Subsystem not found", "") if (!$subsys); 19052a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "Kconfig not found", "") if (!$kconfig); 19152a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "Description not found", "") if (!$description); 19252a4be3fSMauro Carvalho Chehab 19352a4be3fSMauro Carvalho Chehab if (!%arch_table) { 19452a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "Architecture table not found", ""); 19552a4be3fSMauro Carvalho Chehab return; 19652a4be3fSMauro Carvalho Chehab } 19752a4be3fSMauro Carvalho Chehab 19852a4be3fSMauro Carvalho Chehab $data{$name}->{where} = $file; 19952a4be3fSMauro Carvalho Chehab $data{$name}->{subsys} = $subsys; 20052a4be3fSMauro Carvalho Chehab $data{$name}->{kconfig} = $kconfig; 20152a4be3fSMauro Carvalho Chehab $data{$name}->{description} = $description; 20252a4be3fSMauro Carvalho Chehab $data{$name}->{comments} = $comments; 20352a4be3fSMauro Carvalho Chehab $data{$name}->{table} = \%arch_table; 204f5889e70SMauro Carvalho Chehab 205f5889e70SMauro Carvalho Chehab $max_size_arch_with_header = $max_size_arch + length($h_arch); 20652a4be3fSMauro Carvalho Chehab} 20752a4be3fSMauro Carvalho Chehab 20852a4be3fSMauro Carvalho Chehab# 20952a4be3fSMauro Carvalho Chehab# Output feature(s) for a given architecture 21052a4be3fSMauro Carvalho Chehab# 21152a4be3fSMauro Carvalho Chehabsub output_arch_table { 21252a4be3fSMauro Carvalho Chehab my $title = "Feature status on $arch architecture"; 21352a4be3fSMauro Carvalho Chehab 21452a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n"; 21552a4be3fSMauro Carvalho Chehab print "$title\n"; 21652a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n\n"; 21752a4be3fSMauro Carvalho Chehab 21852a4be3fSMauro Carvalho Chehab print "=" x $max_size_subsys; 21952a4be3fSMauro Carvalho Chehab print " "; 22052a4be3fSMauro Carvalho Chehab print "=" x $max_size_name; 22152a4be3fSMauro Carvalho Chehab print " "; 22252a4be3fSMauro Carvalho Chehab print "=" x $max_size_kconfig; 22352a4be3fSMauro Carvalho Chehab print " "; 22452a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 22552a4be3fSMauro Carvalho Chehab print " "; 22652a4be3fSMauro Carvalho Chehab print "=" x $max_size_description; 22752a4be3fSMauro Carvalho Chehab print "\n"; 22852a4be3fSMauro Carvalho Chehab printf "%-${max_size_subsys}s ", $h_subsys; 22952a4be3fSMauro Carvalho Chehab printf "%-${max_size_name}s ", $h_name; 23052a4be3fSMauro Carvalho Chehab printf "%-${max_size_kconfig}s ", $h_kconfig; 23152a4be3fSMauro Carvalho Chehab printf "%-${max_size_status}s ", $h_status; 23252a4be3fSMauro Carvalho Chehab printf "%-${max_size_description}s\n", $h_description; 23352a4be3fSMauro Carvalho Chehab print "=" x $max_size_subsys; 23452a4be3fSMauro Carvalho Chehab print " "; 23552a4be3fSMauro Carvalho Chehab print "=" x $max_size_name; 23652a4be3fSMauro Carvalho Chehab print " "; 23752a4be3fSMauro Carvalho Chehab print "=" x $max_size_kconfig; 23852a4be3fSMauro Carvalho Chehab print " "; 23952a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 24052a4be3fSMauro Carvalho Chehab print " "; 24152a4be3fSMauro Carvalho Chehab print "=" x $max_size_description; 24252a4be3fSMauro Carvalho Chehab print "\n"; 24352a4be3fSMauro Carvalho Chehab 24452a4be3fSMauro Carvalho Chehab foreach my $name (sort { 24552a4be3fSMauro Carvalho Chehab ($data{$a}->{subsys} cmp $data{$b}->{subsys}) || 246ca908577SMauro Carvalho Chehab ("\L$a" cmp "\L$b") 24752a4be3fSMauro Carvalho Chehab } keys %data) { 24852a4be3fSMauro Carvalho Chehab next if ($feat && $name ne $feat); 24952a4be3fSMauro Carvalho Chehab 25052a4be3fSMauro Carvalho Chehab my %arch_table = %{$data{$name}->{table}}; 25152a4be3fSMauro Carvalho Chehab printf "%-${max_size_subsys}s ", $data{$name}->{subsys}; 25252a4be3fSMauro Carvalho Chehab printf "%-${max_size_name}s ", $name; 25352a4be3fSMauro Carvalho Chehab printf "%-${max_size_kconfig}s ", $data{$name}->{kconfig}; 25452a4be3fSMauro Carvalho Chehab printf "%-${max_size_status}s ", $arch_table{$arch}; 255ca908577SMauro Carvalho Chehab printf "%-s\n", $data{$name}->{description}; 25652a4be3fSMauro Carvalho Chehab } 25752a4be3fSMauro Carvalho Chehab 25852a4be3fSMauro Carvalho Chehab print "=" x $max_size_subsys; 25952a4be3fSMauro Carvalho Chehab print " "; 26052a4be3fSMauro Carvalho Chehab print "=" x $max_size_name; 26152a4be3fSMauro Carvalho Chehab print " "; 26252a4be3fSMauro Carvalho Chehab print "=" x $max_size_kconfig; 26352a4be3fSMauro Carvalho Chehab print " "; 26452a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 26552a4be3fSMauro Carvalho Chehab print " "; 26652a4be3fSMauro Carvalho Chehab print "=" x $max_size_description; 26752a4be3fSMauro Carvalho Chehab print "\n"; 26852a4be3fSMauro Carvalho Chehab} 26952a4be3fSMauro Carvalho Chehab 27052a4be3fSMauro Carvalho Chehab# 271ca908577SMauro Carvalho Chehab# list feature(s) for a given architecture 272ca908577SMauro Carvalho Chehab# 273ca908577SMauro Carvalho Chehabsub list_arch_features { 274ca908577SMauro Carvalho Chehab print "#\n# Kernel feature support matrix of the '$arch' architecture:\n#\n"; 275ca908577SMauro Carvalho Chehab 276ca908577SMauro Carvalho Chehab foreach my $name (sort { 277ca908577SMauro Carvalho Chehab ($data{$a}->{subsys} cmp $data{$b}->{subsys}) || 278ca908577SMauro Carvalho Chehab ("\L$a" cmp "\L$b") 279ca908577SMauro Carvalho Chehab } keys %data) { 280ca908577SMauro Carvalho Chehab next if ($feat && $name ne $feat); 281ca908577SMauro Carvalho Chehab 282ca908577SMauro Carvalho Chehab my %arch_table = %{$data{$name}->{table}}; 283ca908577SMauro Carvalho Chehab 284ca908577SMauro Carvalho Chehab my $status = $arch_table{$arch}; 285ca908577SMauro Carvalho Chehab $status = " " x ((4 - length($status)) / 2) . $status; 286ca908577SMauro Carvalho Chehab 287ca908577SMauro Carvalho Chehab printf " %${max_size_subsys}s/ ", $data{$name}->{subsys}; 288ca908577SMauro Carvalho Chehab printf "%-${max_size_name}s: ", $name; 289ca908577SMauro Carvalho Chehab printf "%-5s| ", $status; 290ca908577SMauro Carvalho Chehab printf "%${max_size_kconfig}s # ", $data{$name}->{kconfig}; 291ca908577SMauro Carvalho Chehab printf " %s\n", $data{$name}->{description}; 292ca908577SMauro Carvalho Chehab } 293ca908577SMauro Carvalho Chehab} 294ca908577SMauro Carvalho Chehab 295ca908577SMauro Carvalho Chehab# 29652a4be3fSMauro Carvalho Chehab# Output a feature on all architectures 29752a4be3fSMauro Carvalho Chehab# 29852a4be3fSMauro Carvalho Chehabsub output_feature { 29952a4be3fSMauro Carvalho Chehab my $title = "Feature $feat"; 30052a4be3fSMauro Carvalho Chehab 30152a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n"; 30252a4be3fSMauro Carvalho Chehab print "$title\n"; 30352a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n\n"; 30452a4be3fSMauro Carvalho Chehab 30552a4be3fSMauro Carvalho Chehab print ":Subsystem: $data{$feat}->{subsys} \n" if ($data{$feat}->{subsys}); 30652a4be3fSMauro Carvalho Chehab print ":Kconfig: $data{$feat}->{kconfig} \n" if ($data{$feat}->{kconfig}); 30752a4be3fSMauro Carvalho Chehab 30852a4be3fSMauro Carvalho Chehab my $desc = $data{$feat}->{description}; 30952a4be3fSMauro Carvalho Chehab $desc =~ s/^([a-z])/\U$1/; 31052a4be3fSMauro Carvalho Chehab $desc =~ s/\.?\s*//; 31152a4be3fSMauro Carvalho Chehab print "\n$desc.\n\n"; 31252a4be3fSMauro Carvalho Chehab 31352a4be3fSMauro Carvalho Chehab my $com = $data{$feat}->{comments}; 31452a4be3fSMauro Carvalho Chehab $com =~ s/^\s+//; 31552a4be3fSMauro Carvalho Chehab $com =~ s/\s+$//; 31652a4be3fSMauro Carvalho Chehab if ($com) { 31752a4be3fSMauro Carvalho Chehab print "Comments\n"; 31852a4be3fSMauro Carvalho Chehab print "--------\n\n"; 31952a4be3fSMauro Carvalho Chehab print "$com\n\n"; 32052a4be3fSMauro Carvalho Chehab } 32152a4be3fSMauro Carvalho Chehab 322f5889e70SMauro Carvalho Chehab print "=" x $max_size_arch_with_header; 32352a4be3fSMauro Carvalho Chehab print " "; 32452a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 32552a4be3fSMauro Carvalho Chehab print "\n"; 32652a4be3fSMauro Carvalho Chehab 32752a4be3fSMauro Carvalho Chehab printf "%-${max_size_arch}s ", $h_arch; 32852a4be3fSMauro Carvalho Chehab printf "%-${max_size_status}s", $h_status . "\n"; 32952a4be3fSMauro Carvalho Chehab 330f5889e70SMauro Carvalho Chehab print "=" x $max_size_arch_with_header; 33152a4be3fSMauro Carvalho Chehab print " "; 33252a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 33352a4be3fSMauro Carvalho Chehab print "\n"; 33452a4be3fSMauro Carvalho Chehab 33552a4be3fSMauro Carvalho Chehab my %arch_table = %{$data{$feat}->{table}}; 33652a4be3fSMauro Carvalho Chehab foreach my $arch (sort keys %arch_table) { 33752a4be3fSMauro Carvalho Chehab printf "%-${max_size_arch}s ", $arch; 33852a4be3fSMauro Carvalho Chehab printf "%-${max_size_status}s\n", $arch_table{$arch}; 33952a4be3fSMauro Carvalho Chehab } 34052a4be3fSMauro Carvalho Chehab 341f5889e70SMauro Carvalho Chehab print "=" x $max_size_arch_with_header; 34252a4be3fSMauro Carvalho Chehab print " "; 34352a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 34452a4be3fSMauro Carvalho Chehab print "\n"; 34552a4be3fSMauro Carvalho Chehab} 34652a4be3fSMauro Carvalho Chehab 34752a4be3fSMauro Carvalho Chehab# 34852a4be3fSMauro Carvalho Chehab# Output all features for all architectures 34952a4be3fSMauro Carvalho Chehab# 35052a4be3fSMauro Carvalho Chehab 351dbb90902SMauro Carvalho Chehabsub matrix_lines($$$) { 352dbb90902SMauro Carvalho Chehab my $desc_size = shift; 353dbb90902SMauro Carvalho Chehab my $status_size = shift; 354ba813f7cSMauro Carvalho Chehab my $header = shift; 355ba813f7cSMauro Carvalho Chehab my $fill; 356ba813f7cSMauro Carvalho Chehab my $ln_marker; 35752a4be3fSMauro Carvalho Chehab 358ba813f7cSMauro Carvalho Chehab if ($header) { 359ba813f7cSMauro Carvalho Chehab $ln_marker = "="; 360ba813f7cSMauro Carvalho Chehab } else { 361ba813f7cSMauro Carvalho Chehab $ln_marker = "-"; 36252a4be3fSMauro Carvalho Chehab } 363ba813f7cSMauro Carvalho Chehab 364ba813f7cSMauro Carvalho Chehab $fill = $ln_marker; 365ba813f7cSMauro Carvalho Chehab 366dbb90902SMauro Carvalho Chehab print "+"; 367ba813f7cSMauro Carvalho Chehab print $fill x $max_size_name; 368ba813f7cSMauro Carvalho Chehab print "+"; 369dbb90902SMauro Carvalho Chehab print $fill x $desc_size; 370ba813f7cSMauro Carvalho Chehab print "+"; 371dbb90902SMauro Carvalho Chehab print $ln_marker x $status_size; 372ba813f7cSMauro Carvalho Chehab print "+\n"; 37352a4be3fSMauro Carvalho Chehab} 37452a4be3fSMauro Carvalho Chehab 37552a4be3fSMauro Carvalho Chehabsub output_matrix { 376ba813f7cSMauro Carvalho Chehab my $title = "Feature status on all architectures"; 377f5889e70SMauro Carvalho Chehab my $notcompat = "Not compatible"; 37852a4be3fSMauro Carvalho Chehab 37952a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n"; 38052a4be3fSMauro Carvalho Chehab print "$title\n"; 38152a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n\n"; 38252a4be3fSMauro Carvalho Chehab 383dbb90902SMauro Carvalho Chehab my $desc_title = "$h_kconfig / $h_description"; 384dbb90902SMauro Carvalho Chehab 385dbb90902SMauro Carvalho Chehab my $desc_size = $max_size_kconfig + 4; 386f5889e70SMauro Carvalho Chehab if (!$description_size) { 387dbb90902SMauro Carvalho Chehab $desc_size = $max_size_description if ($max_size_description > $desc_size); 388f5889e70SMauro Carvalho Chehab } else { 389f5889e70SMauro Carvalho Chehab $desc_size = $description_size if ($description_size > $desc_size); 390f5889e70SMauro Carvalho Chehab } 391f5889e70SMauro Carvalho Chehab $desc_size = $max_description_word if ($max_description_word > $desc_size); 392f5889e70SMauro Carvalho Chehab 393dbb90902SMauro Carvalho Chehab $desc_size = length($desc_title) if (length($desc_title) > $desc_size); 394dbb90902SMauro Carvalho Chehab 395f5889e70SMauro Carvalho Chehab $max_size_status = length($notcompat) if (length($notcompat) > $max_size_status); 396f5889e70SMauro Carvalho Chehab 397f5889e70SMauro Carvalho Chehab # Ensure that the status will fit 398f5889e70SMauro Carvalho Chehab my $min_status_size = $max_size_status + $max_size_arch + 6; 399f5889e70SMauro Carvalho Chehab $status_size = $min_status_size if ($status_size < $min_status_size); 400f5889e70SMauro Carvalho Chehab 401dbb90902SMauro Carvalho Chehab 402ba813f7cSMauro Carvalho Chehab my $cur_subsys = ""; 40352a4be3fSMauro Carvalho Chehab foreach my $name (sort { 404ba813f7cSMauro Carvalho Chehab ($data{$a}->{subsys} cmp $data{$b}->{subsys}) or 405ca908577SMauro Carvalho Chehab ("\L$a" cmp "\L$b") 40652a4be3fSMauro Carvalho Chehab } keys %data) { 407ba813f7cSMauro Carvalho Chehab 408ba813f7cSMauro Carvalho Chehab if ($cur_subsys ne $data{$name}->{subsys}) { 409ba813f7cSMauro Carvalho Chehab if ($cur_subsys ne "") { 410ba813f7cSMauro Carvalho Chehab printf "\n"; 411ba813f7cSMauro Carvalho Chehab } 412ba813f7cSMauro Carvalho Chehab 413ba813f7cSMauro Carvalho Chehab $cur_subsys = $data{$name}->{subsys}; 414ba813f7cSMauro Carvalho Chehab 415ba813f7cSMauro Carvalho Chehab my $title = "Subsystem: $cur_subsys"; 416ba813f7cSMauro Carvalho Chehab print "$title\n"; 417ba813f7cSMauro Carvalho Chehab print "=" x length($title) . "\n\n"; 418ba813f7cSMauro Carvalho Chehab 419dbb90902SMauro Carvalho Chehab 420dbb90902SMauro Carvalho Chehab matrix_lines($desc_size, $status_size, 0); 421dbb90902SMauro Carvalho Chehab 422ba813f7cSMauro Carvalho Chehab printf "|%-${max_size_name}s", $h_name; 423dbb90902SMauro Carvalho Chehab printf "|%-${desc_size}s", $desc_title; 424ba813f7cSMauro Carvalho Chehab 425dbb90902SMauro Carvalho Chehab printf "|%-${status_size}s|\n", "Status per architecture"; 426dbb90902SMauro Carvalho Chehab matrix_lines($desc_size, $status_size, 1); 427ba813f7cSMauro Carvalho Chehab } 42852a4be3fSMauro Carvalho Chehab 42952a4be3fSMauro Carvalho Chehab my %arch_table = %{$data{$name}->{table}}; 430dbb90902SMauro Carvalho Chehab my $cur_status = ""; 43152a4be3fSMauro Carvalho Chehab 432f5889e70SMauro Carvalho Chehab my (@lines, @descs); 433dbb90902SMauro Carvalho Chehab my $line = ""; 434dbb90902SMauro Carvalho Chehab foreach my $arch (sort { 4354fa32f87SMauro Carvalho Chehab ($arch_table{$b} cmp $arch_table{$a}) or 436dbb90902SMauro Carvalho Chehab ("\L$a" cmp "\L$b") 437dbb90902SMauro Carvalho Chehab } keys %arch_table) { 438dbb90902SMauro Carvalho Chehab 439dbb90902SMauro Carvalho Chehab my $status = $arch_table{$arch}; 440dbb90902SMauro Carvalho Chehab 441dbb90902SMauro Carvalho Chehab if ($status eq "---") { 442f5889e70SMauro Carvalho Chehab $status = $notcompat; 443dbb90902SMauro Carvalho Chehab } 444dbb90902SMauro Carvalho Chehab 445dbb90902SMauro Carvalho Chehab if ($status ne $cur_status) { 446dbb90902SMauro Carvalho Chehab if ($line ne "") { 447dbb90902SMauro Carvalho Chehab push @lines, $line; 448dbb90902SMauro Carvalho Chehab $line = ""; 449dbb90902SMauro Carvalho Chehab } 450dbb90902SMauro Carvalho Chehab $line = "- **" . $status . "**: " . $arch; 451dbb90902SMauro Carvalho Chehab } elsif (length($line) + length ($arch) + 2 < $status_size) { 452dbb90902SMauro Carvalho Chehab $line .= ", " . $arch; 453dbb90902SMauro Carvalho Chehab } else { 454dbb90902SMauro Carvalho Chehab push @lines, $line; 455dbb90902SMauro Carvalho Chehab $line = " " . $arch; 456dbb90902SMauro Carvalho Chehab } 457dbb90902SMauro Carvalho Chehab $cur_status = $status; 458dbb90902SMauro Carvalho Chehab } 459dbb90902SMauro Carvalho Chehab push @lines, $line if ($line ne ""); 460dbb90902SMauro Carvalho Chehab 461f5889e70SMauro Carvalho Chehab my $description = $data{$name}->{description}; 462f5889e70SMauro Carvalho Chehab while (length($description) > $desc_size) { 463f5889e70SMauro Carvalho Chehab my $d = substr $description, 0, $desc_size; 464f5889e70SMauro Carvalho Chehab 465f5889e70SMauro Carvalho Chehab # Ensure that it will end on a space 466f5889e70SMauro Carvalho Chehab # if it can't, it means that the size is too small 467f5889e70SMauro Carvalho Chehab # Instead of aborting it, let's print what we have 468f5889e70SMauro Carvalho Chehab if (!($d =~ s/^(.*)\s+.*/$1/)) { 469f5889e70SMauro Carvalho Chehab $d = substr $d, 0, -1; 470f5889e70SMauro Carvalho Chehab push @descs, "$d\\"; 471f5889e70SMauro Carvalho Chehab $description =~ s/^\Q$d\E//; 472f5889e70SMauro Carvalho Chehab } else { 473f5889e70SMauro Carvalho Chehab push @descs, $d; 474f5889e70SMauro Carvalho Chehab $description =~ s/^\Q$d\E\s+//; 475f5889e70SMauro Carvalho Chehab } 476f5889e70SMauro Carvalho Chehab } 477f5889e70SMauro Carvalho Chehab push @descs, $description; 478f5889e70SMauro Carvalho Chehab 479f5889e70SMauro Carvalho Chehab # Ensure that the full description will be printed 480f5889e70SMauro Carvalho Chehab push @lines, "" while (scalar(@lines) < 2 + scalar(@descs)); 481dbb90902SMauro Carvalho Chehab 482dbb90902SMauro Carvalho Chehab my $ln = 0; 483dbb90902SMauro Carvalho Chehab for my $line(@lines) { 484dbb90902SMauro Carvalho Chehab if (!$ln) { 485dbb90902SMauro Carvalho Chehab printf "|%-${max_size_name}s", $name; 486dbb90902SMauro Carvalho Chehab printf "|%-${desc_size}s", "``" . $data{$name}->{kconfig} . "``"; 487f5889e70SMauro Carvalho Chehab } elsif ($ln >= 2 && scalar(@descs)) { 488ba813f7cSMauro Carvalho Chehab printf "|%-${max_size_name}s", ""; 489f5889e70SMauro Carvalho Chehab printf "|%-${desc_size}s", shift @descs; 490dbb90902SMauro Carvalho Chehab } else { 491dbb90902SMauro Carvalho Chehab printf "|%-${max_size_name}s", ""; 492dbb90902SMauro Carvalho Chehab printf "|%-${desc_size}s", ""; 49352a4be3fSMauro Carvalho Chehab } 494dbb90902SMauro Carvalho Chehab 495dbb90902SMauro Carvalho Chehab printf "|%-${status_size}s|\n", $line; 496dbb90902SMauro Carvalho Chehab 497dbb90902SMauro Carvalho Chehab $ln++; 49852a4be3fSMauro Carvalho Chehab } 499dbb90902SMauro Carvalho Chehab matrix_lines($desc_size, $status_size, 0); 500ba813f7cSMauro Carvalho Chehab } 50152a4be3fSMauro Carvalho Chehab} 50252a4be3fSMauro Carvalho Chehab 50352a4be3fSMauro Carvalho Chehab 50452a4be3fSMauro Carvalho Chehab# 50552a4be3fSMauro Carvalho Chehab# Parses all feature files located at $prefix dir 50652a4be3fSMauro Carvalho Chehab# 50752a4be3fSMauro Carvalho Chehabfind({wanted =>\&parse_feat, no_chdir => 1}, $prefix); 50852a4be3fSMauro Carvalho Chehab 50952a4be3fSMauro Carvalho Chehabprint STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug); 51052a4be3fSMauro Carvalho Chehab 51152a4be3fSMauro Carvalho Chehab# 51252a4be3fSMauro Carvalho Chehab# Handles the command 51352a4be3fSMauro Carvalho Chehab# 51452a4be3fSMauro Carvalho Chehabif ($cmd eq "current") { 51552a4be3fSMauro Carvalho Chehab $arch = qx(uname -m | sed 's/x86_64/x86/' | sed 's/i386/x86/'); 51652a4be3fSMauro Carvalho Chehab $arch =~s/\s+$//; 51752a4be3fSMauro Carvalho Chehab} 51852a4be3fSMauro Carvalho Chehab 519ca908577SMauro Carvalho Chehabif ($cmd eq "ls" or $cmd eq "list") { 520ca908577SMauro Carvalho Chehab if (!$arch) { 521ca908577SMauro Carvalho Chehab $arch = qx(uname -m | sed 's/x86_64/x86/' | sed 's/i386/x86/'); 522ca908577SMauro Carvalho Chehab $arch =~s/\s+$//; 523ca908577SMauro Carvalho Chehab } 524ca908577SMauro Carvalho Chehab 525ca908577SMauro Carvalho Chehab list_arch_features; 526ca908577SMauro Carvalho Chehab 527ca908577SMauro Carvalho Chehab exit; 528ca908577SMauro Carvalho Chehab} 529ca908577SMauro Carvalho Chehab 53052a4be3fSMauro Carvalho Chehabif ($cmd ne "validate") { 53152a4be3fSMauro Carvalho Chehab if ($arch) { 53252a4be3fSMauro Carvalho Chehab output_arch_table; 53352a4be3fSMauro Carvalho Chehab } elsif ($feat) { 53452a4be3fSMauro Carvalho Chehab output_feature; 53552a4be3fSMauro Carvalho Chehab } else { 53652a4be3fSMauro Carvalho Chehab output_matrix; 53752a4be3fSMauro Carvalho Chehab } 53852a4be3fSMauro Carvalho Chehab} 53952a4be3fSMauro Carvalho Chehab 54052a4be3fSMauro Carvalho Chehab__END__ 54152a4be3fSMauro Carvalho Chehab 54252a4be3fSMauro Carvalho Chehab=head1 NAME 54352a4be3fSMauro Carvalho Chehab 54452a4be3fSMauro Carvalho Chehabget_feat.pl - parse the Linux Feature files and produce a ReST book. 54552a4be3fSMauro Carvalho Chehab 54652a4be3fSMauro Carvalho Chehab=head1 SYNOPSIS 54752a4be3fSMauro Carvalho Chehab 548ca908577SMauro Carvalho ChehabB<get_feat.pl> [--debug] [--man] [--help] [--dir=<dir>] [--arch=<arch>] 549ca908577SMauro Carvalho Chehab [--feature=<feature>|--feat=<feature>] <COMAND> [<ARGUMENT>] 55052a4be3fSMauro Carvalho Chehab 55152a4be3fSMauro Carvalho ChehabWhere <COMMAND> can be: 55252a4be3fSMauro Carvalho Chehab 55352a4be3fSMauro Carvalho Chehab=over 8 55452a4be3fSMauro Carvalho Chehab 555ca908577SMauro Carvalho ChehabB<current> - output table in ReST compatible ASCII format 556ca908577SMauro Carvalho Chehab with features for this machine's architecture 55752a4be3fSMauro Carvalho Chehab 558ca908577SMauro Carvalho ChehabB<rest> - output table(s) in ReST compatible ASCII format 559ca908577SMauro Carvalho Chehab with features in ReST markup language. The output 560ca908577SMauro Carvalho Chehab is affected by --arch or --feat/--feature flags. 56152a4be3fSMauro Carvalho Chehab 562ca908577SMauro Carvalho ChehabB<validate> - validate the contents of the files under 563ca908577SMauro Carvalho Chehab Documentation/features. 564ca908577SMauro Carvalho Chehab 565ca908577SMauro Carvalho ChehabB<ls> or B<list> - list features for this machine's architecture, 566ca908577SMauro Carvalho Chehab using an easier to parse format. 567ca908577SMauro Carvalho Chehab The output is affected by --arch flag. 56852a4be3fSMauro Carvalho Chehab 56952a4be3fSMauro Carvalho Chehab=back 57052a4be3fSMauro Carvalho Chehab 57152a4be3fSMauro Carvalho Chehab=head1 OPTIONS 57252a4be3fSMauro Carvalho Chehab 57352a4be3fSMauro Carvalho Chehab=over 8 57452a4be3fSMauro Carvalho Chehab 57552a4be3fSMauro Carvalho Chehab=item B<--arch> 57652a4be3fSMauro Carvalho Chehab 57752a4be3fSMauro Carvalho ChehabOutput features for an specific architecture, optionally filtering for 57852a4be3fSMauro Carvalho Chehaba single specific feature. 57952a4be3fSMauro Carvalho Chehab 580ca908577SMauro Carvalho Chehab=item B<--feat> or B<--feature> 58152a4be3fSMauro Carvalho Chehab 582ca908577SMauro Carvalho ChehabOutput features for a single specific feature. 58352a4be3fSMauro Carvalho Chehab 58452a4be3fSMauro Carvalho Chehab=item B<--dir> 58552a4be3fSMauro Carvalho Chehab 58652a4be3fSMauro Carvalho ChehabChanges the location of the Feature files. By default, it uses 58752a4be3fSMauro Carvalho Chehabthe Documentation/features directory. 58852a4be3fSMauro Carvalho Chehab 58901096e5cSMauro Carvalho Chehab=item B<--enable-fname> 59001096e5cSMauro Carvalho Chehab 59101096e5cSMauro Carvalho ChehabPrints the file name of the feature files. This can be used in order to 59201096e5cSMauro Carvalho Chehabtrack dependencies during documentation build. 59301096e5cSMauro Carvalho Chehab 59452a4be3fSMauro Carvalho Chehab=item B<--debug> 59552a4be3fSMauro Carvalho Chehab 59652a4be3fSMauro Carvalho ChehabPut the script in verbose mode, useful for debugging. Can be called multiple 59752a4be3fSMauro Carvalho Chehabtimes, to increase verbosity. 59852a4be3fSMauro Carvalho Chehab 59952a4be3fSMauro Carvalho Chehab=item B<--help> 60052a4be3fSMauro Carvalho Chehab 60152a4be3fSMauro Carvalho ChehabPrints a brief help message and exits. 60252a4be3fSMauro Carvalho Chehab 60352a4be3fSMauro Carvalho Chehab=item B<--man> 60452a4be3fSMauro Carvalho Chehab 60552a4be3fSMauro Carvalho ChehabPrints the manual page and exits. 60652a4be3fSMauro Carvalho Chehab 60752a4be3fSMauro Carvalho Chehab=back 60852a4be3fSMauro Carvalho Chehab 60952a4be3fSMauro Carvalho Chehab=head1 DESCRIPTION 61052a4be3fSMauro Carvalho Chehab 61152a4be3fSMauro Carvalho ChehabParse the Linux feature files from Documentation/features (by default), 61252a4be3fSMauro Carvalho Chehaboptionally producing results at ReST format. 61352a4be3fSMauro Carvalho Chehab 61452a4be3fSMauro Carvalho ChehabIt supports output data per architecture, per feature or a 61552a4be3fSMauro Carvalho Chehabfeature x arch matrix. 61652a4be3fSMauro Carvalho Chehab 61752a4be3fSMauro Carvalho ChehabWhen used with B<rest> command, it will use either one of the tree formats: 61852a4be3fSMauro Carvalho Chehab 61952a4be3fSMauro Carvalho ChehabIf neither B<--arch> or B<--feature> arguments are used, it will output a 62052a4be3fSMauro Carvalho Chehabmatrix with features per architecture. 62152a4be3fSMauro Carvalho Chehab 62252a4be3fSMauro Carvalho ChehabIf B<--arch> argument is used, it will output the features availability for 62352a4be3fSMauro Carvalho Chehaba given architecture. 62452a4be3fSMauro Carvalho Chehab 62552a4be3fSMauro Carvalho ChehabIf B<--feat> argument is used, it will output the content of the feature 62652a4be3fSMauro Carvalho Chehabfile using ReStructured Text markup. 62752a4be3fSMauro Carvalho Chehab 62852a4be3fSMauro Carvalho Chehab=head1 BUGS 62952a4be3fSMauro Carvalho Chehab 63052a4be3fSMauro Carvalho ChehabReport bugs to Mauro Carvalho Chehab <mchehab+samsung@kernel.org> 63152a4be3fSMauro Carvalho Chehab 63252a4be3fSMauro Carvalho Chehab=head1 COPYRIGHT 63352a4be3fSMauro Carvalho Chehab 63452a4be3fSMauro Carvalho ChehabCopyright (c) 2019 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>. 63552a4be3fSMauro Carvalho Chehab 63652a4be3fSMauro Carvalho ChehabLicense GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>. 63752a4be3fSMauro Carvalho Chehab 63852a4be3fSMauro Carvalho ChehabThis is free software: you are free to change and redistribute it. 63952a4be3fSMauro Carvalho ChehabThere is NO WARRANTY, to the extent permitted by law. 64052a4be3fSMauro Carvalho Chehab 64152a4be3fSMauro Carvalho Chehab=cut 642