152a4be3fSMauro Carvalho Chehab#!/usr/bin/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; 16ca908577SMauro Carvalho Chehab 17ca908577SMauro Carvalho Chehabmy $basename = abs_path($0); 18ca908577SMauro Carvalho Chehab$basename =~ s,/[^/]+$,/,; 19ca908577SMauro Carvalho Chehab 20ca908577SMauro Carvalho Chehabmy $prefix=$basename . "../Documentation/features"; 2152a4be3fSMauro Carvalho Chehab 22*f5889e70SMauro Carvalho Chehab# Used only at for full features output. The script will auto-adjust 23*f5889e70SMauro Carvalho Chehab# such values for the minimal possible values 24*f5889e70SMauro Carvalho Chehabmy $status_size = 1; 25*f5889e70SMauro Carvalho Chehabmy $description_size = 1; 26*f5889e70SMauro Carvalho Chehab 2752a4be3fSMauro Carvalho ChehabGetOptions( 2852a4be3fSMauro Carvalho Chehab "debug|d+" => \$debug, 2952a4be3fSMauro Carvalho Chehab "dir=s" => \$prefix, 3052a4be3fSMauro Carvalho Chehab 'help|?' => \$help, 3152a4be3fSMauro Carvalho Chehab 'arch=s' => \$arch, 3252a4be3fSMauro Carvalho Chehab 'feat=s' => \$feat, 33ca908577SMauro Carvalho Chehab 'feature=s' => \$feat, 3452a4be3fSMauro Carvalho Chehab man => \$man 3552a4be3fSMauro Carvalho Chehab) or pod2usage(2); 3652a4be3fSMauro Carvalho Chehab 3752a4be3fSMauro Carvalho Chehabpod2usage(1) if $help; 3852a4be3fSMauro Carvalho Chehabpod2usage(-exitstatus => 0, -verbose => 2) if $man; 3952a4be3fSMauro Carvalho Chehab 40ca908577SMauro Carvalho Chehabpod2usage(1) if (scalar @ARGV < 1 || @ARGV > 2); 4152a4be3fSMauro Carvalho Chehab 4252a4be3fSMauro Carvalho Chehabmy ($cmd, $arg) = @ARGV; 4352a4be3fSMauro Carvalho Chehab 44ca908577SMauro Carvalho Chehabpod2usage(2) if ($cmd ne "current" && $cmd ne "rest" && $cmd ne "validate" 45ca908577SMauro Carvalho Chehab && $cmd ne "ls" && $cmd ne "list"); 4652a4be3fSMauro Carvalho Chehab 4752a4be3fSMauro Carvalho Chehabrequire Data::Dumper if ($debug); 4852a4be3fSMauro Carvalho Chehab 4952a4be3fSMauro Carvalho Chehabmy %data; 5052a4be3fSMauro Carvalho Chehabmy %archs; 5152a4be3fSMauro Carvalho Chehab 5252a4be3fSMauro Carvalho Chehab# 5352a4be3fSMauro Carvalho Chehab# Displays an error message, printing file name and line 5452a4be3fSMauro Carvalho Chehab# 5552a4be3fSMauro Carvalho Chehabsub parse_error($$$$) { 5652a4be3fSMauro Carvalho Chehab my ($file, $ln, $msg, $data) = @_; 5752a4be3fSMauro Carvalho Chehab 5852a4be3fSMauro Carvalho Chehab $data =~ s/\s+$/\n/; 5952a4be3fSMauro Carvalho Chehab 6052a4be3fSMauro Carvalho Chehab print STDERR "Warning: file $file#$ln:\n\t$msg"; 6152a4be3fSMauro Carvalho Chehab 6252a4be3fSMauro Carvalho Chehab if ($data ne "") { 6352a4be3fSMauro Carvalho Chehab print STDERR ". Line\n\t\t$data"; 6452a4be3fSMauro Carvalho Chehab } else { 6552a4be3fSMauro Carvalho Chehab print STDERR "\n"; 6652a4be3fSMauro Carvalho Chehab } 6752a4be3fSMauro Carvalho Chehab} 6852a4be3fSMauro Carvalho Chehab 6952a4be3fSMauro Carvalho Chehab# 7052a4be3fSMauro Carvalho Chehab# Parse a features file, storing its contents at %data 7152a4be3fSMauro Carvalho Chehab# 7252a4be3fSMauro Carvalho Chehab 7352a4be3fSMauro Carvalho Chehabmy $h_name = "Feature"; 7452a4be3fSMauro Carvalho Chehabmy $h_kconfig = "Kconfig"; 7552a4be3fSMauro Carvalho Chehabmy $h_description = "Description"; 7652a4be3fSMauro Carvalho Chehabmy $h_subsys = "Subsystem"; 7752a4be3fSMauro Carvalho Chehabmy $h_status = "Status"; 7852a4be3fSMauro Carvalho Chehabmy $h_arch = "Architecture"; 7952a4be3fSMauro Carvalho Chehab 8052a4be3fSMauro Carvalho Chehabmy $max_size_name = length($h_name); 8152a4be3fSMauro Carvalho Chehabmy $max_size_kconfig = length($h_kconfig); 8252a4be3fSMauro Carvalho Chehabmy $max_size_description = length($h_description); 8352a4be3fSMauro Carvalho Chehabmy $max_size_subsys = length($h_subsys); 8452a4be3fSMauro Carvalho Chehabmy $max_size_status = length($h_status); 85*f5889e70SMauro Carvalho Chehab 86*f5889e70SMauro Carvalho Chehabmy $max_size_arch = 0; 87*f5889e70SMauro Carvalho Chehabmy $max_size_arch_with_header; 88*f5889e70SMauro Carvalho Chehabmy $max_description_word = 0; 8952a4be3fSMauro Carvalho Chehab 9052a4be3fSMauro Carvalho Chehabsub parse_feat { 9152a4be3fSMauro Carvalho Chehab my $file = $File::Find::name; 9252a4be3fSMauro Carvalho Chehab 9352a4be3fSMauro Carvalho Chehab my $mode = (stat($file))[2]; 9452a4be3fSMauro Carvalho Chehab return if ($mode & S_IFDIR); 9552a4be3fSMauro Carvalho Chehab return if ($file =~ m,($prefix)/arch-support.txt,); 9652a4be3fSMauro Carvalho Chehab return if (!($file =~ m,arch-support.txt$,)); 9752a4be3fSMauro Carvalho Chehab 9852a4be3fSMauro Carvalho Chehab my $subsys = ""; 9952a4be3fSMauro Carvalho Chehab $subsys = $2 if ( m,.*($prefix)/([^/]+).*,); 10052a4be3fSMauro Carvalho Chehab 10152a4be3fSMauro Carvalho Chehab if (length($subsys) > $max_size_subsys) { 10252a4be3fSMauro Carvalho Chehab $max_size_subsys = length($subsys); 10352a4be3fSMauro Carvalho Chehab } 10452a4be3fSMauro Carvalho Chehab 10552a4be3fSMauro Carvalho Chehab my $name; 10652a4be3fSMauro Carvalho Chehab my $kconfig; 10752a4be3fSMauro Carvalho Chehab my $description; 10852a4be3fSMauro Carvalho Chehab my $comments = ""; 10952a4be3fSMauro Carvalho Chehab my $last_status; 11052a4be3fSMauro Carvalho Chehab my $ln; 11152a4be3fSMauro Carvalho Chehab my %arch_table; 11252a4be3fSMauro Carvalho Chehab 11352a4be3fSMauro Carvalho Chehab print STDERR "Opening $file\n" if ($debug > 1); 11452a4be3fSMauro Carvalho Chehab open IN, $file; 11552a4be3fSMauro Carvalho Chehab 11652a4be3fSMauro Carvalho Chehab while(<IN>) { 11752a4be3fSMauro Carvalho Chehab $ln++; 11852a4be3fSMauro Carvalho Chehab 11952a4be3fSMauro Carvalho Chehab if (m/^\#\s+Feature\s+name:\s*(.*\S)/) { 12052a4be3fSMauro Carvalho Chehab $name = $1; 12152a4be3fSMauro Carvalho Chehab if (length($name) > $max_size_name) { 12252a4be3fSMauro Carvalho Chehab $max_size_name = length($name); 12352a4be3fSMauro Carvalho Chehab } 12452a4be3fSMauro Carvalho Chehab next; 12552a4be3fSMauro Carvalho Chehab } 12652a4be3fSMauro Carvalho Chehab if (m/^\#\s+Kconfig:\s*(.*\S)/) { 12752a4be3fSMauro Carvalho Chehab $kconfig = $1; 12852a4be3fSMauro Carvalho Chehab if (length($kconfig) > $max_size_kconfig) { 12952a4be3fSMauro Carvalho Chehab $max_size_kconfig = length($kconfig); 13052a4be3fSMauro Carvalho Chehab } 13152a4be3fSMauro Carvalho Chehab next; 13252a4be3fSMauro Carvalho Chehab } 13352a4be3fSMauro Carvalho Chehab if (m/^\#\s+description:\s*(.*\S)/) { 13452a4be3fSMauro Carvalho Chehab $description = $1; 13552a4be3fSMauro Carvalho Chehab if (length($description) > $max_size_description) { 13652a4be3fSMauro Carvalho Chehab $max_size_description = length($description); 13752a4be3fSMauro Carvalho Chehab } 138*f5889e70SMauro Carvalho Chehab 139*f5889e70SMauro Carvalho Chehab foreach my $word (split /\s+/, $description) { 140*f5889e70SMauro Carvalho Chehab if (length($word) > $max_description_word) { 141*f5889e70SMauro Carvalho Chehab $max_description_word = length($word); 142*f5889e70SMauro Carvalho Chehab } 143*f5889e70SMauro Carvalho Chehab } 144*f5889e70SMauro Carvalho Chehab 14552a4be3fSMauro Carvalho Chehab next; 14652a4be3fSMauro Carvalho Chehab } 14752a4be3fSMauro Carvalho Chehab next if (m/^\\s*$/); 14852a4be3fSMauro Carvalho Chehab next if (m/^\s*\-+\s*$/); 14952a4be3fSMauro Carvalho Chehab next if (m/^\s*\|\s*arch\s*\|\s*status\s*\|\s*$/); 15052a4be3fSMauro Carvalho Chehab 15152a4be3fSMauro Carvalho Chehab if (m/^\#\s*(.*)/) { 15252a4be3fSMauro Carvalho Chehab $comments .= "$1\n"; 15352a4be3fSMauro Carvalho Chehab next; 15452a4be3fSMauro Carvalho Chehab } 15552a4be3fSMauro Carvalho Chehab if (m/^\s*\|\s*(\S+):\s*\|\s*(\S+)\s*\|\s*$/) { 15652a4be3fSMauro Carvalho Chehab my $a = $1; 15752a4be3fSMauro Carvalho Chehab my $status = $2; 15852a4be3fSMauro Carvalho Chehab 15952a4be3fSMauro Carvalho Chehab if (length($status) > $max_size_status) { 16052a4be3fSMauro Carvalho Chehab $max_size_status = length($status); 16152a4be3fSMauro Carvalho Chehab } 16252a4be3fSMauro Carvalho Chehab if (length($a) > $max_size_arch) { 16352a4be3fSMauro Carvalho Chehab $max_size_arch = length($a); 16452a4be3fSMauro Carvalho Chehab } 16552a4be3fSMauro Carvalho Chehab 16652a4be3fSMauro Carvalho Chehab $status = "---" if ($status =~ m/^\.\.$/); 16752a4be3fSMauro Carvalho Chehab 16852a4be3fSMauro Carvalho Chehab $archs{$a} = 1; 16952a4be3fSMauro Carvalho Chehab $arch_table{$a} = $status; 17052a4be3fSMauro Carvalho Chehab next; 17152a4be3fSMauro Carvalho Chehab } 17252a4be3fSMauro Carvalho Chehab 17352a4be3fSMauro Carvalho Chehab #Everything else is an error 17452a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "line is invalid", $_); 17552a4be3fSMauro Carvalho Chehab } 17652a4be3fSMauro Carvalho Chehab close IN; 17752a4be3fSMauro Carvalho Chehab 17852a4be3fSMauro Carvalho Chehab if (!$name) { 17952a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "Feature name not found", ""); 18052a4be3fSMauro Carvalho Chehab return; 18152a4be3fSMauro Carvalho Chehab } 18252a4be3fSMauro Carvalho Chehab 18352a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "Subsystem not found", "") if (!$subsys); 18452a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "Kconfig not found", "") if (!$kconfig); 18552a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "Description not found", "") if (!$description); 18652a4be3fSMauro Carvalho Chehab 18752a4be3fSMauro Carvalho Chehab if (!%arch_table) { 18852a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "Architecture table not found", ""); 18952a4be3fSMauro Carvalho Chehab return; 19052a4be3fSMauro Carvalho Chehab } 19152a4be3fSMauro Carvalho Chehab 19252a4be3fSMauro Carvalho Chehab $data{$name}->{where} = $file; 19352a4be3fSMauro Carvalho Chehab $data{$name}->{subsys} = $subsys; 19452a4be3fSMauro Carvalho Chehab $data{$name}->{kconfig} = $kconfig; 19552a4be3fSMauro Carvalho Chehab $data{$name}->{description} = $description; 19652a4be3fSMauro Carvalho Chehab $data{$name}->{comments} = $comments; 19752a4be3fSMauro Carvalho Chehab $data{$name}->{table} = \%arch_table; 198*f5889e70SMauro Carvalho Chehab 199*f5889e70SMauro Carvalho Chehab $max_size_arch_with_header = $max_size_arch + length($h_arch); 20052a4be3fSMauro Carvalho Chehab} 20152a4be3fSMauro Carvalho Chehab 20252a4be3fSMauro Carvalho Chehab# 20352a4be3fSMauro Carvalho Chehab# Output feature(s) for a given architecture 20452a4be3fSMauro Carvalho Chehab# 20552a4be3fSMauro Carvalho Chehabsub output_arch_table { 20652a4be3fSMauro Carvalho Chehab my $title = "Feature status on $arch architecture"; 20752a4be3fSMauro Carvalho Chehab 20852a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n"; 20952a4be3fSMauro Carvalho Chehab print "$title\n"; 21052a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n\n"; 21152a4be3fSMauro Carvalho Chehab 21252a4be3fSMauro Carvalho Chehab print "=" x $max_size_subsys; 21352a4be3fSMauro Carvalho Chehab print " "; 21452a4be3fSMauro Carvalho Chehab print "=" x $max_size_name; 21552a4be3fSMauro Carvalho Chehab print " "; 21652a4be3fSMauro Carvalho Chehab print "=" x $max_size_kconfig; 21752a4be3fSMauro Carvalho Chehab print " "; 21852a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 21952a4be3fSMauro Carvalho Chehab print " "; 22052a4be3fSMauro Carvalho Chehab print "=" x $max_size_description; 22152a4be3fSMauro Carvalho Chehab print "\n"; 22252a4be3fSMauro Carvalho Chehab printf "%-${max_size_subsys}s ", $h_subsys; 22352a4be3fSMauro Carvalho Chehab printf "%-${max_size_name}s ", $h_name; 22452a4be3fSMauro Carvalho Chehab printf "%-${max_size_kconfig}s ", $h_kconfig; 22552a4be3fSMauro Carvalho Chehab printf "%-${max_size_status}s ", $h_status; 22652a4be3fSMauro Carvalho Chehab printf "%-${max_size_description}s\n", $h_description; 22752a4be3fSMauro Carvalho Chehab print "=" x $max_size_subsys; 22852a4be3fSMauro Carvalho Chehab print " "; 22952a4be3fSMauro Carvalho Chehab print "=" x $max_size_name; 23052a4be3fSMauro Carvalho Chehab print " "; 23152a4be3fSMauro Carvalho Chehab print "=" x $max_size_kconfig; 23252a4be3fSMauro Carvalho Chehab print " "; 23352a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 23452a4be3fSMauro Carvalho Chehab print " "; 23552a4be3fSMauro Carvalho Chehab print "=" x $max_size_description; 23652a4be3fSMauro Carvalho Chehab print "\n"; 23752a4be3fSMauro Carvalho Chehab 23852a4be3fSMauro Carvalho Chehab foreach my $name (sort { 23952a4be3fSMauro Carvalho Chehab ($data{$a}->{subsys} cmp $data{$b}->{subsys}) || 240ca908577SMauro Carvalho Chehab ("\L$a" cmp "\L$b") 24152a4be3fSMauro Carvalho Chehab } keys %data) { 24252a4be3fSMauro Carvalho Chehab next if ($feat && $name ne $feat); 24352a4be3fSMauro Carvalho Chehab 24452a4be3fSMauro Carvalho Chehab my %arch_table = %{$data{$name}->{table}}; 24552a4be3fSMauro Carvalho Chehab printf "%-${max_size_subsys}s ", $data{$name}->{subsys}; 24652a4be3fSMauro Carvalho Chehab printf "%-${max_size_name}s ", $name; 24752a4be3fSMauro Carvalho Chehab printf "%-${max_size_kconfig}s ", $data{$name}->{kconfig}; 24852a4be3fSMauro Carvalho Chehab printf "%-${max_size_status}s ", $arch_table{$arch}; 249ca908577SMauro Carvalho Chehab printf "%-s\n", $data{$name}->{description}; 25052a4be3fSMauro Carvalho Chehab } 25152a4be3fSMauro Carvalho Chehab 25252a4be3fSMauro Carvalho Chehab print "=" x $max_size_subsys; 25352a4be3fSMauro Carvalho Chehab print " "; 25452a4be3fSMauro Carvalho Chehab print "=" x $max_size_name; 25552a4be3fSMauro Carvalho Chehab print " "; 25652a4be3fSMauro Carvalho Chehab print "=" x $max_size_kconfig; 25752a4be3fSMauro Carvalho Chehab print " "; 25852a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 25952a4be3fSMauro Carvalho Chehab print " "; 26052a4be3fSMauro Carvalho Chehab print "=" x $max_size_description; 26152a4be3fSMauro Carvalho Chehab print "\n"; 26252a4be3fSMauro Carvalho Chehab} 26352a4be3fSMauro Carvalho Chehab 26452a4be3fSMauro Carvalho Chehab# 265ca908577SMauro Carvalho Chehab# list feature(s) for a given architecture 266ca908577SMauro Carvalho Chehab# 267ca908577SMauro Carvalho Chehabsub list_arch_features { 268ca908577SMauro Carvalho Chehab print "#\n# Kernel feature support matrix of the '$arch' architecture:\n#\n"; 269ca908577SMauro Carvalho Chehab 270ca908577SMauro Carvalho Chehab foreach my $name (sort { 271ca908577SMauro Carvalho Chehab ($data{$a}->{subsys} cmp $data{$b}->{subsys}) || 272ca908577SMauro Carvalho Chehab ("\L$a" cmp "\L$b") 273ca908577SMauro Carvalho Chehab } keys %data) { 274ca908577SMauro Carvalho Chehab next if ($feat && $name ne $feat); 275ca908577SMauro Carvalho Chehab 276ca908577SMauro Carvalho Chehab my %arch_table = %{$data{$name}->{table}}; 277ca908577SMauro Carvalho Chehab 278ca908577SMauro Carvalho Chehab my $status = $arch_table{$arch}; 279ca908577SMauro Carvalho Chehab $status = " " x ((4 - length($status)) / 2) . $status; 280ca908577SMauro Carvalho Chehab 281ca908577SMauro Carvalho Chehab printf " %${max_size_subsys}s/ ", $data{$name}->{subsys}; 282ca908577SMauro Carvalho Chehab printf "%-${max_size_name}s: ", $name; 283ca908577SMauro Carvalho Chehab printf "%-5s| ", $status; 284ca908577SMauro Carvalho Chehab printf "%${max_size_kconfig}s # ", $data{$name}->{kconfig}; 285ca908577SMauro Carvalho Chehab printf " %s\n", $data{$name}->{description}; 286ca908577SMauro Carvalho Chehab } 287ca908577SMauro Carvalho Chehab} 288ca908577SMauro Carvalho Chehab 289ca908577SMauro Carvalho Chehab# 29052a4be3fSMauro Carvalho Chehab# Output a feature on all architectures 29152a4be3fSMauro Carvalho Chehab# 29252a4be3fSMauro Carvalho Chehabsub output_feature { 29352a4be3fSMauro Carvalho Chehab my $title = "Feature $feat"; 29452a4be3fSMauro Carvalho Chehab 29552a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n"; 29652a4be3fSMauro Carvalho Chehab print "$title\n"; 29752a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n\n"; 29852a4be3fSMauro Carvalho Chehab 29952a4be3fSMauro Carvalho Chehab print ":Subsystem: $data{$feat}->{subsys} \n" if ($data{$feat}->{subsys}); 30052a4be3fSMauro Carvalho Chehab print ":Kconfig: $data{$feat}->{kconfig} \n" if ($data{$feat}->{kconfig}); 30152a4be3fSMauro Carvalho Chehab 30252a4be3fSMauro Carvalho Chehab my $desc = $data{$feat}->{description}; 30352a4be3fSMauro Carvalho Chehab $desc =~ s/^([a-z])/\U$1/; 30452a4be3fSMauro Carvalho Chehab $desc =~ s/\.?\s*//; 30552a4be3fSMauro Carvalho Chehab print "\n$desc.\n\n"; 30652a4be3fSMauro Carvalho Chehab 30752a4be3fSMauro Carvalho Chehab my $com = $data{$feat}->{comments}; 30852a4be3fSMauro Carvalho Chehab $com =~ s/^\s+//; 30952a4be3fSMauro Carvalho Chehab $com =~ s/\s+$//; 31052a4be3fSMauro Carvalho Chehab if ($com) { 31152a4be3fSMauro Carvalho Chehab print "Comments\n"; 31252a4be3fSMauro Carvalho Chehab print "--------\n\n"; 31352a4be3fSMauro Carvalho Chehab print "$com\n\n"; 31452a4be3fSMauro Carvalho Chehab } 31552a4be3fSMauro Carvalho Chehab 316*f5889e70SMauro Carvalho Chehab print "=" x $max_size_arch_with_header; 31752a4be3fSMauro Carvalho Chehab print " "; 31852a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 31952a4be3fSMauro Carvalho Chehab print "\n"; 32052a4be3fSMauro Carvalho Chehab 32152a4be3fSMauro Carvalho Chehab printf "%-${max_size_arch}s ", $h_arch; 32252a4be3fSMauro Carvalho Chehab printf "%-${max_size_status}s", $h_status . "\n"; 32352a4be3fSMauro Carvalho Chehab 324*f5889e70SMauro Carvalho Chehab print "=" x $max_size_arch_with_header; 32552a4be3fSMauro Carvalho Chehab print " "; 32652a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 32752a4be3fSMauro Carvalho Chehab print "\n"; 32852a4be3fSMauro Carvalho Chehab 32952a4be3fSMauro Carvalho Chehab my %arch_table = %{$data{$feat}->{table}}; 33052a4be3fSMauro Carvalho Chehab foreach my $arch (sort keys %arch_table) { 33152a4be3fSMauro Carvalho Chehab printf "%-${max_size_arch}s ", $arch; 33252a4be3fSMauro Carvalho Chehab printf "%-${max_size_status}s\n", $arch_table{$arch}; 33352a4be3fSMauro Carvalho Chehab } 33452a4be3fSMauro Carvalho Chehab 335*f5889e70SMauro Carvalho Chehab print "=" x $max_size_arch_with_header; 33652a4be3fSMauro Carvalho Chehab print " "; 33752a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 33852a4be3fSMauro Carvalho Chehab print "\n"; 33952a4be3fSMauro Carvalho Chehab} 34052a4be3fSMauro Carvalho Chehab 34152a4be3fSMauro Carvalho Chehab# 34252a4be3fSMauro Carvalho Chehab# Output all features for all architectures 34352a4be3fSMauro Carvalho Chehab# 34452a4be3fSMauro Carvalho Chehab 345dbb90902SMauro Carvalho Chehabsub matrix_lines($$$) { 346dbb90902SMauro Carvalho Chehab my $desc_size = shift; 347dbb90902SMauro Carvalho Chehab my $status_size = shift; 348ba813f7cSMauro Carvalho Chehab my $header = shift; 349ba813f7cSMauro Carvalho Chehab my $fill; 350ba813f7cSMauro Carvalho Chehab my $ln_marker; 35152a4be3fSMauro Carvalho Chehab 352ba813f7cSMauro Carvalho Chehab if ($header) { 353ba813f7cSMauro Carvalho Chehab $ln_marker = "="; 354ba813f7cSMauro Carvalho Chehab } else { 355ba813f7cSMauro Carvalho Chehab $ln_marker = "-"; 35652a4be3fSMauro Carvalho Chehab } 357ba813f7cSMauro Carvalho Chehab 358ba813f7cSMauro Carvalho Chehab $fill = $ln_marker; 359ba813f7cSMauro Carvalho Chehab 360dbb90902SMauro Carvalho Chehab print "+"; 361ba813f7cSMauro Carvalho Chehab print $fill x $max_size_name; 362ba813f7cSMauro Carvalho Chehab print "+"; 363dbb90902SMauro Carvalho Chehab print $fill x $desc_size; 364ba813f7cSMauro Carvalho Chehab print "+"; 365dbb90902SMauro Carvalho Chehab print $ln_marker x $status_size; 366ba813f7cSMauro Carvalho Chehab print "+\n"; 36752a4be3fSMauro Carvalho Chehab} 36852a4be3fSMauro Carvalho Chehab 36952a4be3fSMauro Carvalho Chehabsub output_matrix { 370ba813f7cSMauro Carvalho Chehab my $title = "Feature status on all architectures"; 371*f5889e70SMauro Carvalho Chehab my $notcompat = "Not compatible"; 37252a4be3fSMauro Carvalho Chehab 37352a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n"; 37452a4be3fSMauro Carvalho Chehab print "$title\n"; 37552a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n\n"; 37652a4be3fSMauro Carvalho Chehab 377dbb90902SMauro Carvalho Chehab my $desc_title = "$h_kconfig / $h_description"; 378dbb90902SMauro Carvalho Chehab 379dbb90902SMauro Carvalho Chehab my $desc_size = $max_size_kconfig + 4; 380*f5889e70SMauro Carvalho Chehab if (!$description_size) { 381dbb90902SMauro Carvalho Chehab $desc_size = $max_size_description if ($max_size_description > $desc_size); 382*f5889e70SMauro Carvalho Chehab } else { 383*f5889e70SMauro Carvalho Chehab $desc_size = $description_size if ($description_size > $desc_size); 384*f5889e70SMauro Carvalho Chehab } 385*f5889e70SMauro Carvalho Chehab $desc_size = $max_description_word if ($max_description_word > $desc_size); 386*f5889e70SMauro Carvalho Chehab 387dbb90902SMauro Carvalho Chehab $desc_size = length($desc_title) if (length($desc_title) > $desc_size); 388dbb90902SMauro Carvalho Chehab 389*f5889e70SMauro Carvalho Chehab $max_size_status = length($notcompat) if (length($notcompat) > $max_size_status); 390*f5889e70SMauro Carvalho Chehab 391*f5889e70SMauro Carvalho Chehab # Ensure that the status will fit 392*f5889e70SMauro Carvalho Chehab my $min_status_size = $max_size_status + $max_size_arch + 6; 393*f5889e70SMauro Carvalho Chehab $status_size = $min_status_size if ($status_size < $min_status_size); 394*f5889e70SMauro Carvalho Chehab 395dbb90902SMauro Carvalho Chehab 396ba813f7cSMauro Carvalho Chehab my $cur_subsys = ""; 39752a4be3fSMauro Carvalho Chehab foreach my $name (sort { 398ba813f7cSMauro Carvalho Chehab ($data{$a}->{subsys} cmp $data{$b}->{subsys}) or 399ca908577SMauro Carvalho Chehab ("\L$a" cmp "\L$b") 40052a4be3fSMauro Carvalho Chehab } keys %data) { 401ba813f7cSMauro Carvalho Chehab 402ba813f7cSMauro Carvalho Chehab if ($cur_subsys ne $data{$name}->{subsys}) { 403ba813f7cSMauro Carvalho Chehab if ($cur_subsys ne "") { 404ba813f7cSMauro Carvalho Chehab printf "\n"; 405ba813f7cSMauro Carvalho Chehab } 406ba813f7cSMauro Carvalho Chehab 407ba813f7cSMauro Carvalho Chehab $cur_subsys = $data{$name}->{subsys}; 408ba813f7cSMauro Carvalho Chehab 409ba813f7cSMauro Carvalho Chehab my $title = "Subsystem: $cur_subsys"; 410ba813f7cSMauro Carvalho Chehab print "$title\n"; 411ba813f7cSMauro Carvalho Chehab print "=" x length($title) . "\n\n"; 412ba813f7cSMauro Carvalho Chehab 413dbb90902SMauro Carvalho Chehab 414dbb90902SMauro Carvalho Chehab matrix_lines($desc_size, $status_size, 0); 415dbb90902SMauro Carvalho Chehab 416ba813f7cSMauro Carvalho Chehab printf "|%-${max_size_name}s", $h_name; 417dbb90902SMauro Carvalho Chehab printf "|%-${desc_size}s", $desc_title; 418ba813f7cSMauro Carvalho Chehab 419dbb90902SMauro Carvalho Chehab printf "|%-${status_size}s|\n", "Status per architecture"; 420dbb90902SMauro Carvalho Chehab matrix_lines($desc_size, $status_size, 1); 421ba813f7cSMauro Carvalho Chehab } 42252a4be3fSMauro Carvalho Chehab 42352a4be3fSMauro Carvalho Chehab my %arch_table = %{$data{$name}->{table}}; 424dbb90902SMauro Carvalho Chehab my $cur_status = ""; 42552a4be3fSMauro Carvalho Chehab 426*f5889e70SMauro Carvalho Chehab my (@lines, @descs); 427dbb90902SMauro Carvalho Chehab my $line = ""; 428dbb90902SMauro Carvalho Chehab foreach my $arch (sort { 4294fa32f87SMauro Carvalho Chehab ($arch_table{$b} cmp $arch_table{$a}) or 430dbb90902SMauro Carvalho Chehab ("\L$a" cmp "\L$b") 431dbb90902SMauro Carvalho Chehab } keys %arch_table) { 432dbb90902SMauro Carvalho Chehab 433dbb90902SMauro Carvalho Chehab my $status = $arch_table{$arch}; 434dbb90902SMauro Carvalho Chehab 435dbb90902SMauro Carvalho Chehab if ($status eq "---") { 436*f5889e70SMauro Carvalho Chehab $status = $notcompat; 437dbb90902SMauro Carvalho Chehab } 438dbb90902SMauro Carvalho Chehab 439dbb90902SMauro Carvalho Chehab if ($status ne $cur_status) { 440dbb90902SMauro Carvalho Chehab if ($line ne "") { 441dbb90902SMauro Carvalho Chehab push @lines, $line; 442dbb90902SMauro Carvalho Chehab $line = ""; 443dbb90902SMauro Carvalho Chehab } 444dbb90902SMauro Carvalho Chehab $line = "- **" . $status . "**: " . $arch; 445dbb90902SMauro Carvalho Chehab } elsif (length($line) + length ($arch) + 2 < $status_size) { 446dbb90902SMauro Carvalho Chehab $line .= ", " . $arch; 447dbb90902SMauro Carvalho Chehab } else { 448dbb90902SMauro Carvalho Chehab push @lines, $line; 449dbb90902SMauro Carvalho Chehab $line = " " . $arch; 450dbb90902SMauro Carvalho Chehab } 451dbb90902SMauro Carvalho Chehab $cur_status = $status; 452dbb90902SMauro Carvalho Chehab } 453dbb90902SMauro Carvalho Chehab push @lines, $line if ($line ne ""); 454dbb90902SMauro Carvalho Chehab 455*f5889e70SMauro Carvalho Chehab my $description = $data{$name}->{description}; 456*f5889e70SMauro Carvalho Chehab while (length($description) > $desc_size) { 457*f5889e70SMauro Carvalho Chehab my $d = substr $description, 0, $desc_size; 458*f5889e70SMauro Carvalho Chehab 459*f5889e70SMauro Carvalho Chehab # Ensure that it will end on a space 460*f5889e70SMauro Carvalho Chehab # if it can't, it means that the size is too small 461*f5889e70SMauro Carvalho Chehab # Instead of aborting it, let's print what we have 462*f5889e70SMauro Carvalho Chehab if (!($d =~ s/^(.*)\s+.*/$1/)) { 463*f5889e70SMauro Carvalho Chehab $d = substr $d, 0, -1; 464*f5889e70SMauro Carvalho Chehab push @descs, "$d\\"; 465*f5889e70SMauro Carvalho Chehab $description =~ s/^\Q$d\E//; 466*f5889e70SMauro Carvalho Chehab } else { 467*f5889e70SMauro Carvalho Chehab push @descs, $d; 468*f5889e70SMauro Carvalho Chehab $description =~ s/^\Q$d\E\s+//; 469*f5889e70SMauro Carvalho Chehab } 470*f5889e70SMauro Carvalho Chehab } 471*f5889e70SMauro Carvalho Chehab push @descs, $description; 472*f5889e70SMauro Carvalho Chehab 473*f5889e70SMauro Carvalho Chehab # Ensure that the full description will be printed 474*f5889e70SMauro Carvalho Chehab push @lines, "" while (scalar(@lines) < 2 + scalar(@descs)); 475dbb90902SMauro Carvalho Chehab 476dbb90902SMauro Carvalho Chehab my $ln = 0; 477dbb90902SMauro Carvalho Chehab for my $line(@lines) { 478dbb90902SMauro Carvalho Chehab if (!$ln) { 479dbb90902SMauro Carvalho Chehab printf "|%-${max_size_name}s", $name; 480dbb90902SMauro Carvalho Chehab printf "|%-${desc_size}s", "``" . $data{$name}->{kconfig} . "``"; 481*f5889e70SMauro Carvalho Chehab } elsif ($ln >= 2 && scalar(@descs)) { 482ba813f7cSMauro Carvalho Chehab printf "|%-${max_size_name}s", ""; 483*f5889e70SMauro Carvalho Chehab printf "|%-${desc_size}s", shift @descs; 484dbb90902SMauro Carvalho Chehab } else { 485dbb90902SMauro Carvalho Chehab printf "|%-${max_size_name}s", ""; 486dbb90902SMauro Carvalho Chehab printf "|%-${desc_size}s", ""; 48752a4be3fSMauro Carvalho Chehab } 488dbb90902SMauro Carvalho Chehab 489dbb90902SMauro Carvalho Chehab printf "|%-${status_size}s|\n", $line; 490dbb90902SMauro Carvalho Chehab 491dbb90902SMauro Carvalho Chehab $ln++; 49252a4be3fSMauro Carvalho Chehab } 493dbb90902SMauro Carvalho Chehab matrix_lines($desc_size, $status_size, 0); 494ba813f7cSMauro Carvalho Chehab } 49552a4be3fSMauro Carvalho Chehab} 49652a4be3fSMauro Carvalho Chehab 49752a4be3fSMauro Carvalho Chehab 49852a4be3fSMauro Carvalho Chehab# 49952a4be3fSMauro Carvalho Chehab# Parses all feature files located at $prefix dir 50052a4be3fSMauro Carvalho Chehab# 50152a4be3fSMauro Carvalho Chehabfind({wanted =>\&parse_feat, no_chdir => 1}, $prefix); 50252a4be3fSMauro Carvalho Chehab 50352a4be3fSMauro Carvalho Chehabprint STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug); 50452a4be3fSMauro Carvalho Chehab 50552a4be3fSMauro Carvalho Chehab# 50652a4be3fSMauro Carvalho Chehab# Handles the command 50752a4be3fSMauro Carvalho Chehab# 50852a4be3fSMauro Carvalho Chehabif ($cmd eq "current") { 50952a4be3fSMauro Carvalho Chehab $arch = qx(uname -m | sed 's/x86_64/x86/' | sed 's/i386/x86/'); 51052a4be3fSMauro Carvalho Chehab $arch =~s/\s+$//; 51152a4be3fSMauro Carvalho Chehab} 51252a4be3fSMauro Carvalho Chehab 513ca908577SMauro Carvalho Chehabif ($cmd eq "ls" or $cmd eq "list") { 514ca908577SMauro Carvalho Chehab if (!$arch) { 515ca908577SMauro Carvalho Chehab $arch = qx(uname -m | sed 's/x86_64/x86/' | sed 's/i386/x86/'); 516ca908577SMauro Carvalho Chehab $arch =~s/\s+$//; 517ca908577SMauro Carvalho Chehab } 518ca908577SMauro Carvalho Chehab 519ca908577SMauro Carvalho Chehab list_arch_features; 520ca908577SMauro Carvalho Chehab 521ca908577SMauro Carvalho Chehab exit; 522ca908577SMauro Carvalho Chehab} 523ca908577SMauro Carvalho Chehab 52452a4be3fSMauro Carvalho Chehabif ($cmd ne "validate") { 52552a4be3fSMauro Carvalho Chehab if ($arch) { 52652a4be3fSMauro Carvalho Chehab output_arch_table; 52752a4be3fSMauro Carvalho Chehab } elsif ($feat) { 52852a4be3fSMauro Carvalho Chehab output_feature; 52952a4be3fSMauro Carvalho Chehab } else { 53052a4be3fSMauro Carvalho Chehab output_matrix; 53152a4be3fSMauro Carvalho Chehab } 53252a4be3fSMauro Carvalho Chehab} 53352a4be3fSMauro Carvalho Chehab 53452a4be3fSMauro Carvalho Chehab__END__ 53552a4be3fSMauro Carvalho Chehab 53652a4be3fSMauro Carvalho Chehab=head1 NAME 53752a4be3fSMauro Carvalho Chehab 53852a4be3fSMauro Carvalho Chehabget_feat.pl - parse the Linux Feature files and produce a ReST book. 53952a4be3fSMauro Carvalho Chehab 54052a4be3fSMauro Carvalho Chehab=head1 SYNOPSIS 54152a4be3fSMauro Carvalho Chehab 542ca908577SMauro Carvalho ChehabB<get_feat.pl> [--debug] [--man] [--help] [--dir=<dir>] [--arch=<arch>] 543ca908577SMauro Carvalho Chehab [--feature=<feature>|--feat=<feature>] <COMAND> [<ARGUMENT>] 54452a4be3fSMauro Carvalho Chehab 54552a4be3fSMauro Carvalho ChehabWhere <COMMAND> can be: 54652a4be3fSMauro Carvalho Chehab 54752a4be3fSMauro Carvalho Chehab=over 8 54852a4be3fSMauro Carvalho Chehab 549ca908577SMauro Carvalho ChehabB<current> - output table in ReST compatible ASCII format 550ca908577SMauro Carvalho Chehab with features for this machine's architecture 55152a4be3fSMauro Carvalho Chehab 552ca908577SMauro Carvalho ChehabB<rest> - output table(s) in ReST compatible ASCII format 553ca908577SMauro Carvalho Chehab with features in ReST markup language. The output 554ca908577SMauro Carvalho Chehab is affected by --arch or --feat/--feature flags. 55552a4be3fSMauro Carvalho Chehab 556ca908577SMauro Carvalho ChehabB<validate> - validate the contents of the files under 557ca908577SMauro Carvalho Chehab Documentation/features. 558ca908577SMauro Carvalho Chehab 559ca908577SMauro Carvalho ChehabB<ls> or B<list> - list features for this machine's architecture, 560ca908577SMauro Carvalho Chehab using an easier to parse format. 561ca908577SMauro Carvalho Chehab The output is affected by --arch flag. 56252a4be3fSMauro Carvalho Chehab 56352a4be3fSMauro Carvalho Chehab=back 56452a4be3fSMauro Carvalho Chehab 56552a4be3fSMauro Carvalho Chehab=head1 OPTIONS 56652a4be3fSMauro Carvalho Chehab 56752a4be3fSMauro Carvalho Chehab=over 8 56852a4be3fSMauro Carvalho Chehab 56952a4be3fSMauro Carvalho Chehab=item B<--arch> 57052a4be3fSMauro Carvalho Chehab 57152a4be3fSMauro Carvalho ChehabOutput features for an specific architecture, optionally filtering for 57252a4be3fSMauro Carvalho Chehaba single specific feature. 57352a4be3fSMauro Carvalho Chehab 574ca908577SMauro Carvalho Chehab=item B<--feat> or B<--feature> 57552a4be3fSMauro Carvalho Chehab 576ca908577SMauro Carvalho ChehabOutput features for a single specific feature. 57752a4be3fSMauro Carvalho Chehab 57852a4be3fSMauro Carvalho Chehab=item B<--dir> 57952a4be3fSMauro Carvalho Chehab 58052a4be3fSMauro Carvalho ChehabChanges the location of the Feature files. By default, it uses 58152a4be3fSMauro Carvalho Chehabthe Documentation/features directory. 58252a4be3fSMauro Carvalho Chehab 58352a4be3fSMauro Carvalho Chehab=item B<--debug> 58452a4be3fSMauro Carvalho Chehab 58552a4be3fSMauro Carvalho ChehabPut the script in verbose mode, useful for debugging. Can be called multiple 58652a4be3fSMauro Carvalho Chehabtimes, to increase verbosity. 58752a4be3fSMauro Carvalho Chehab 58852a4be3fSMauro Carvalho Chehab=item B<--help> 58952a4be3fSMauro Carvalho Chehab 59052a4be3fSMauro Carvalho ChehabPrints a brief help message and exits. 59152a4be3fSMauro Carvalho Chehab 59252a4be3fSMauro Carvalho Chehab=item B<--man> 59352a4be3fSMauro Carvalho Chehab 59452a4be3fSMauro Carvalho ChehabPrints the manual page and exits. 59552a4be3fSMauro Carvalho Chehab 59652a4be3fSMauro Carvalho Chehab=back 59752a4be3fSMauro Carvalho Chehab 59852a4be3fSMauro Carvalho Chehab=head1 DESCRIPTION 59952a4be3fSMauro Carvalho Chehab 60052a4be3fSMauro Carvalho ChehabParse the Linux feature files from Documentation/features (by default), 60152a4be3fSMauro Carvalho Chehaboptionally producing results at ReST format. 60252a4be3fSMauro Carvalho Chehab 60352a4be3fSMauro Carvalho ChehabIt supports output data per architecture, per feature or a 60452a4be3fSMauro Carvalho Chehabfeature x arch matrix. 60552a4be3fSMauro Carvalho Chehab 60652a4be3fSMauro Carvalho ChehabWhen used with B<rest> command, it will use either one of the tree formats: 60752a4be3fSMauro Carvalho Chehab 60852a4be3fSMauro Carvalho ChehabIf neither B<--arch> or B<--feature> arguments are used, it will output a 60952a4be3fSMauro Carvalho Chehabmatrix with features per architecture. 61052a4be3fSMauro Carvalho Chehab 61152a4be3fSMauro Carvalho ChehabIf B<--arch> argument is used, it will output the features availability for 61252a4be3fSMauro Carvalho Chehaba given architecture. 61352a4be3fSMauro Carvalho Chehab 61452a4be3fSMauro Carvalho ChehabIf B<--feat> argument is used, it will output the content of the feature 61552a4be3fSMauro Carvalho Chehabfile using ReStructured Text markup. 61652a4be3fSMauro Carvalho Chehab 61752a4be3fSMauro Carvalho Chehab=head1 BUGS 61852a4be3fSMauro Carvalho Chehab 61952a4be3fSMauro Carvalho ChehabReport bugs to Mauro Carvalho Chehab <mchehab+samsung@kernel.org> 62052a4be3fSMauro Carvalho Chehab 62152a4be3fSMauro Carvalho Chehab=head1 COPYRIGHT 62252a4be3fSMauro Carvalho Chehab 62352a4be3fSMauro Carvalho ChehabCopyright (c) 2019 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>. 62452a4be3fSMauro Carvalho Chehab 62552a4be3fSMauro Carvalho ChehabLicense GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>. 62652a4be3fSMauro Carvalho Chehab 62752a4be3fSMauro Carvalho ChehabThis is free software: you are free to change and redistribute it. 62852a4be3fSMauro Carvalho ChehabThere is NO WARRANTY, to the extent permitted by law. 62952a4be3fSMauro Carvalho Chehab 63052a4be3fSMauro Carvalho Chehab=cut 631