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 2252a4be3fSMauro Carvalho ChehabGetOptions( 2352a4be3fSMauro Carvalho Chehab "debug|d+" => \$debug, 2452a4be3fSMauro Carvalho Chehab "dir=s" => \$prefix, 2552a4be3fSMauro Carvalho Chehab 'help|?' => \$help, 2652a4be3fSMauro Carvalho Chehab 'arch=s' => \$arch, 2752a4be3fSMauro Carvalho Chehab 'feat=s' => \$feat, 28ca908577SMauro Carvalho Chehab 'feature=s' => \$feat, 2952a4be3fSMauro Carvalho Chehab man => \$man 3052a4be3fSMauro Carvalho Chehab) or pod2usage(2); 3152a4be3fSMauro Carvalho Chehab 3252a4be3fSMauro Carvalho Chehabpod2usage(1) if $help; 3352a4be3fSMauro Carvalho Chehabpod2usage(-exitstatus => 0, -verbose => 2) if $man; 3452a4be3fSMauro Carvalho Chehab 35ca908577SMauro Carvalho Chehabpod2usage(1) if (scalar @ARGV < 1 || @ARGV > 2); 3652a4be3fSMauro Carvalho Chehab 3752a4be3fSMauro Carvalho Chehabmy ($cmd, $arg) = @ARGV; 3852a4be3fSMauro Carvalho Chehab 39ca908577SMauro Carvalho Chehabpod2usage(2) if ($cmd ne "current" && $cmd ne "rest" && $cmd ne "validate" 40ca908577SMauro Carvalho Chehab && $cmd ne "ls" && $cmd ne "list"); 4152a4be3fSMauro Carvalho Chehab 4252a4be3fSMauro Carvalho Chehabrequire Data::Dumper if ($debug); 4352a4be3fSMauro Carvalho Chehab 4452a4be3fSMauro Carvalho Chehabmy %data; 4552a4be3fSMauro Carvalho Chehabmy %archs; 4652a4be3fSMauro Carvalho Chehab 4752a4be3fSMauro Carvalho Chehab# 4852a4be3fSMauro Carvalho Chehab# Displays an error message, printing file name and line 4952a4be3fSMauro Carvalho Chehab# 5052a4be3fSMauro Carvalho Chehabsub parse_error($$$$) { 5152a4be3fSMauro Carvalho Chehab my ($file, $ln, $msg, $data) = @_; 5252a4be3fSMauro Carvalho Chehab 5352a4be3fSMauro Carvalho Chehab $data =~ s/\s+$/\n/; 5452a4be3fSMauro Carvalho Chehab 5552a4be3fSMauro Carvalho Chehab print STDERR "Warning: file $file#$ln:\n\t$msg"; 5652a4be3fSMauro Carvalho Chehab 5752a4be3fSMauro Carvalho Chehab if ($data ne "") { 5852a4be3fSMauro Carvalho Chehab print STDERR ". Line\n\t\t$data"; 5952a4be3fSMauro Carvalho Chehab } else { 6052a4be3fSMauro Carvalho Chehab print STDERR "\n"; 6152a4be3fSMauro Carvalho Chehab } 6252a4be3fSMauro Carvalho Chehab} 6352a4be3fSMauro Carvalho Chehab 6452a4be3fSMauro Carvalho Chehab# 6552a4be3fSMauro Carvalho Chehab# Parse a features file, storing its contents at %data 6652a4be3fSMauro Carvalho Chehab# 6752a4be3fSMauro Carvalho Chehab 6852a4be3fSMauro Carvalho Chehabmy $h_name = "Feature"; 6952a4be3fSMauro Carvalho Chehabmy $h_kconfig = "Kconfig"; 7052a4be3fSMauro Carvalho Chehabmy $h_description = "Description"; 7152a4be3fSMauro Carvalho Chehabmy $h_subsys = "Subsystem"; 7252a4be3fSMauro Carvalho Chehabmy $h_status = "Status"; 7352a4be3fSMauro Carvalho Chehabmy $h_arch = "Architecture"; 7452a4be3fSMauro Carvalho Chehab 7552a4be3fSMauro Carvalho Chehabmy $max_size_name = length($h_name); 7652a4be3fSMauro Carvalho Chehabmy $max_size_kconfig = length($h_kconfig); 7752a4be3fSMauro Carvalho Chehabmy $max_size_description = length($h_description); 7852a4be3fSMauro Carvalho Chehabmy $max_size_subsys = length($h_subsys); 7952a4be3fSMauro Carvalho Chehabmy $max_size_status = length($h_status); 8052a4be3fSMauro Carvalho Chehabmy $max_size_arch = length($h_arch); 8152a4be3fSMauro Carvalho Chehab 8252a4be3fSMauro Carvalho Chehabsub parse_feat { 8352a4be3fSMauro Carvalho Chehab my $file = $File::Find::name; 8452a4be3fSMauro Carvalho Chehab 8552a4be3fSMauro Carvalho Chehab my $mode = (stat($file))[2]; 8652a4be3fSMauro Carvalho Chehab return if ($mode & S_IFDIR); 8752a4be3fSMauro Carvalho Chehab return if ($file =~ m,($prefix)/arch-support.txt,); 8852a4be3fSMauro Carvalho Chehab return if (!($file =~ m,arch-support.txt$,)); 8952a4be3fSMauro Carvalho Chehab 9052a4be3fSMauro Carvalho Chehab my $subsys = ""; 9152a4be3fSMauro Carvalho Chehab $subsys = $2 if ( m,.*($prefix)/([^/]+).*,); 9252a4be3fSMauro Carvalho Chehab 9352a4be3fSMauro Carvalho Chehab if (length($subsys) > $max_size_subsys) { 9452a4be3fSMauro Carvalho Chehab $max_size_subsys = length($subsys); 9552a4be3fSMauro Carvalho Chehab } 9652a4be3fSMauro Carvalho Chehab 9752a4be3fSMauro Carvalho Chehab my $name; 9852a4be3fSMauro Carvalho Chehab my $kconfig; 9952a4be3fSMauro Carvalho Chehab my $description; 10052a4be3fSMauro Carvalho Chehab my $comments = ""; 10152a4be3fSMauro Carvalho Chehab my $last_status; 10252a4be3fSMauro Carvalho Chehab my $ln; 10352a4be3fSMauro Carvalho Chehab my %arch_table; 10452a4be3fSMauro Carvalho Chehab 10552a4be3fSMauro Carvalho Chehab print STDERR "Opening $file\n" if ($debug > 1); 10652a4be3fSMauro Carvalho Chehab open IN, $file; 10752a4be3fSMauro Carvalho Chehab 10852a4be3fSMauro Carvalho Chehab while(<IN>) { 10952a4be3fSMauro Carvalho Chehab $ln++; 11052a4be3fSMauro Carvalho Chehab 11152a4be3fSMauro Carvalho Chehab if (m/^\#\s+Feature\s+name:\s*(.*\S)/) { 11252a4be3fSMauro Carvalho Chehab $name = $1; 11352a4be3fSMauro Carvalho Chehab if (length($name) > $max_size_name) { 11452a4be3fSMauro Carvalho Chehab $max_size_name = length($name); 11552a4be3fSMauro Carvalho Chehab } 11652a4be3fSMauro Carvalho Chehab next; 11752a4be3fSMauro Carvalho Chehab } 11852a4be3fSMauro Carvalho Chehab if (m/^\#\s+Kconfig:\s*(.*\S)/) { 11952a4be3fSMauro Carvalho Chehab $kconfig = $1; 12052a4be3fSMauro Carvalho Chehab if (length($kconfig) > $max_size_kconfig) { 12152a4be3fSMauro Carvalho Chehab $max_size_kconfig = length($kconfig); 12252a4be3fSMauro Carvalho Chehab } 12352a4be3fSMauro Carvalho Chehab next; 12452a4be3fSMauro Carvalho Chehab } 12552a4be3fSMauro Carvalho Chehab if (m/^\#\s+description:\s*(.*\S)/) { 12652a4be3fSMauro Carvalho Chehab $description = $1; 12752a4be3fSMauro Carvalho Chehab if (length($description) > $max_size_description) { 12852a4be3fSMauro Carvalho Chehab $max_size_description = length($description); 12952a4be3fSMauro Carvalho Chehab } 13052a4be3fSMauro Carvalho Chehab next; 13152a4be3fSMauro Carvalho Chehab } 13252a4be3fSMauro Carvalho Chehab next if (m/^\\s*$/); 13352a4be3fSMauro Carvalho Chehab next if (m/^\s*\-+\s*$/); 13452a4be3fSMauro Carvalho Chehab next if (m/^\s*\|\s*arch\s*\|\s*status\s*\|\s*$/); 13552a4be3fSMauro Carvalho Chehab 13652a4be3fSMauro Carvalho Chehab if (m/^\#\s*(.*)/) { 13752a4be3fSMauro Carvalho Chehab $comments .= "$1\n"; 13852a4be3fSMauro Carvalho Chehab next; 13952a4be3fSMauro Carvalho Chehab } 14052a4be3fSMauro Carvalho Chehab if (m/^\s*\|\s*(\S+):\s*\|\s*(\S+)\s*\|\s*$/) { 14152a4be3fSMauro Carvalho Chehab my $a = $1; 14252a4be3fSMauro Carvalho Chehab my $status = $2; 14352a4be3fSMauro Carvalho Chehab 14452a4be3fSMauro Carvalho Chehab if (length($status) > $max_size_status) { 14552a4be3fSMauro Carvalho Chehab $max_size_status = length($status); 14652a4be3fSMauro Carvalho Chehab } 14752a4be3fSMauro Carvalho Chehab if (length($a) > $max_size_arch) { 14852a4be3fSMauro Carvalho Chehab $max_size_arch = length($a); 14952a4be3fSMauro Carvalho Chehab } 15052a4be3fSMauro Carvalho Chehab 15152a4be3fSMauro Carvalho Chehab $status = "---" if ($status =~ m/^\.\.$/); 15252a4be3fSMauro Carvalho Chehab 15352a4be3fSMauro Carvalho Chehab $archs{$a} = 1; 15452a4be3fSMauro Carvalho Chehab $arch_table{$a} = $status; 15552a4be3fSMauro Carvalho Chehab next; 15652a4be3fSMauro Carvalho Chehab } 15752a4be3fSMauro Carvalho Chehab 15852a4be3fSMauro Carvalho Chehab #Everything else is an error 15952a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "line is invalid", $_); 16052a4be3fSMauro Carvalho Chehab } 16152a4be3fSMauro Carvalho Chehab close IN; 16252a4be3fSMauro Carvalho Chehab 16352a4be3fSMauro Carvalho Chehab if (!$name) { 16452a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "Feature name not found", ""); 16552a4be3fSMauro Carvalho Chehab return; 16652a4be3fSMauro Carvalho Chehab } 16752a4be3fSMauro Carvalho Chehab 16852a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "Subsystem not found", "") if (!$subsys); 16952a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "Kconfig not found", "") if (!$kconfig); 17052a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "Description not found", "") if (!$description); 17152a4be3fSMauro Carvalho Chehab 17252a4be3fSMauro Carvalho Chehab if (!%arch_table) { 17352a4be3fSMauro Carvalho Chehab parse_error($file, $ln, "Architecture table not found", ""); 17452a4be3fSMauro Carvalho Chehab return; 17552a4be3fSMauro Carvalho Chehab } 17652a4be3fSMauro Carvalho Chehab 17752a4be3fSMauro Carvalho Chehab $data{$name}->{where} = $file; 17852a4be3fSMauro Carvalho Chehab $data{$name}->{subsys} = $subsys; 17952a4be3fSMauro Carvalho Chehab $data{$name}->{kconfig} = $kconfig; 18052a4be3fSMauro Carvalho Chehab $data{$name}->{description} = $description; 18152a4be3fSMauro Carvalho Chehab $data{$name}->{comments} = $comments; 18252a4be3fSMauro Carvalho Chehab $data{$name}->{table} = \%arch_table; 18352a4be3fSMauro Carvalho Chehab} 18452a4be3fSMauro Carvalho Chehab 18552a4be3fSMauro Carvalho Chehab# 18652a4be3fSMauro Carvalho Chehab# Output feature(s) for a given architecture 18752a4be3fSMauro Carvalho Chehab# 18852a4be3fSMauro Carvalho Chehabsub output_arch_table { 18952a4be3fSMauro Carvalho Chehab my $title = "Feature status on $arch architecture"; 19052a4be3fSMauro Carvalho Chehab 19152a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n"; 19252a4be3fSMauro Carvalho Chehab print "$title\n"; 19352a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n\n"; 19452a4be3fSMauro Carvalho Chehab 19552a4be3fSMauro Carvalho Chehab print "=" x $max_size_subsys; 19652a4be3fSMauro Carvalho Chehab print " "; 19752a4be3fSMauro Carvalho Chehab print "=" x $max_size_name; 19852a4be3fSMauro Carvalho Chehab print " "; 19952a4be3fSMauro Carvalho Chehab print "=" x $max_size_kconfig; 20052a4be3fSMauro Carvalho Chehab print " "; 20152a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 20252a4be3fSMauro Carvalho Chehab print " "; 20352a4be3fSMauro Carvalho Chehab print "=" x $max_size_description; 20452a4be3fSMauro Carvalho Chehab print "\n"; 20552a4be3fSMauro Carvalho Chehab printf "%-${max_size_subsys}s ", $h_subsys; 20652a4be3fSMauro Carvalho Chehab printf "%-${max_size_name}s ", $h_name; 20752a4be3fSMauro Carvalho Chehab printf "%-${max_size_kconfig}s ", $h_kconfig; 20852a4be3fSMauro Carvalho Chehab printf "%-${max_size_status}s ", $h_status; 20952a4be3fSMauro Carvalho Chehab printf "%-${max_size_description}s\n", $h_description; 21052a4be3fSMauro Carvalho Chehab print "=" x $max_size_subsys; 21152a4be3fSMauro Carvalho Chehab print " "; 21252a4be3fSMauro Carvalho Chehab print "=" x $max_size_name; 21352a4be3fSMauro Carvalho Chehab print " "; 21452a4be3fSMauro Carvalho Chehab print "=" x $max_size_kconfig; 21552a4be3fSMauro Carvalho Chehab print " "; 21652a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 21752a4be3fSMauro Carvalho Chehab print " "; 21852a4be3fSMauro Carvalho Chehab print "=" x $max_size_description; 21952a4be3fSMauro Carvalho Chehab print "\n"; 22052a4be3fSMauro Carvalho Chehab 22152a4be3fSMauro Carvalho Chehab foreach my $name (sort { 22252a4be3fSMauro Carvalho Chehab ($data{$a}->{subsys} cmp $data{$b}->{subsys}) || 223ca908577SMauro Carvalho Chehab ("\L$a" cmp "\L$b") 22452a4be3fSMauro Carvalho Chehab } keys %data) { 22552a4be3fSMauro Carvalho Chehab next if ($feat && $name ne $feat); 22652a4be3fSMauro Carvalho Chehab 22752a4be3fSMauro Carvalho Chehab my %arch_table = %{$data{$name}->{table}}; 22852a4be3fSMauro Carvalho Chehab printf "%-${max_size_subsys}s ", $data{$name}->{subsys}; 22952a4be3fSMauro Carvalho Chehab printf "%-${max_size_name}s ", $name; 23052a4be3fSMauro Carvalho Chehab printf "%-${max_size_kconfig}s ", $data{$name}->{kconfig}; 23152a4be3fSMauro Carvalho Chehab printf "%-${max_size_status}s ", $arch_table{$arch}; 232ca908577SMauro Carvalho Chehab printf "%-s\n", $data{$name}->{description}; 23352a4be3fSMauro Carvalho Chehab } 23452a4be3fSMauro Carvalho Chehab 23552a4be3fSMauro Carvalho Chehab print "=" x $max_size_subsys; 23652a4be3fSMauro Carvalho Chehab print " "; 23752a4be3fSMauro Carvalho Chehab print "=" x $max_size_name; 23852a4be3fSMauro Carvalho Chehab print " "; 23952a4be3fSMauro Carvalho Chehab print "=" x $max_size_kconfig; 24052a4be3fSMauro Carvalho Chehab print " "; 24152a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 24252a4be3fSMauro Carvalho Chehab print " "; 24352a4be3fSMauro Carvalho Chehab print "=" x $max_size_description; 24452a4be3fSMauro Carvalho Chehab print "\n"; 24552a4be3fSMauro Carvalho Chehab} 24652a4be3fSMauro Carvalho Chehab 24752a4be3fSMauro Carvalho Chehab# 248ca908577SMauro Carvalho Chehab# list feature(s) for a given architecture 249ca908577SMauro Carvalho Chehab# 250ca908577SMauro Carvalho Chehabsub list_arch_features { 251ca908577SMauro Carvalho Chehab print "#\n# Kernel feature support matrix of the '$arch' architecture:\n#\n"; 252ca908577SMauro Carvalho Chehab 253ca908577SMauro Carvalho Chehab foreach my $name (sort { 254ca908577SMauro Carvalho Chehab ($data{$a}->{subsys} cmp $data{$b}->{subsys}) || 255ca908577SMauro Carvalho Chehab ("\L$a" cmp "\L$b") 256ca908577SMauro Carvalho Chehab } keys %data) { 257ca908577SMauro Carvalho Chehab next if ($feat && $name ne $feat); 258ca908577SMauro Carvalho Chehab 259ca908577SMauro Carvalho Chehab my %arch_table = %{$data{$name}->{table}}; 260ca908577SMauro Carvalho Chehab 261ca908577SMauro Carvalho Chehab my $status = $arch_table{$arch}; 262ca908577SMauro Carvalho Chehab $status = " " x ((4 - length($status)) / 2) . $status; 263ca908577SMauro Carvalho Chehab 264ca908577SMauro Carvalho Chehab printf " %${max_size_subsys}s/ ", $data{$name}->{subsys}; 265ca908577SMauro Carvalho Chehab printf "%-${max_size_name}s: ", $name; 266ca908577SMauro Carvalho Chehab printf "%-5s| ", $status; 267ca908577SMauro Carvalho Chehab printf "%${max_size_kconfig}s # ", $data{$name}->{kconfig}; 268ca908577SMauro Carvalho Chehab printf " %s\n", $data{$name}->{description}; 269ca908577SMauro Carvalho Chehab } 270ca908577SMauro Carvalho Chehab} 271ca908577SMauro Carvalho Chehab 272ca908577SMauro Carvalho Chehab# 27352a4be3fSMauro Carvalho Chehab# Output a feature on all architectures 27452a4be3fSMauro Carvalho Chehab# 27552a4be3fSMauro Carvalho Chehabsub output_feature { 27652a4be3fSMauro Carvalho Chehab my $title = "Feature $feat"; 27752a4be3fSMauro Carvalho Chehab 27852a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n"; 27952a4be3fSMauro Carvalho Chehab print "$title\n"; 28052a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n\n"; 28152a4be3fSMauro Carvalho Chehab 28252a4be3fSMauro Carvalho Chehab print ":Subsystem: $data{$feat}->{subsys} \n" if ($data{$feat}->{subsys}); 28352a4be3fSMauro Carvalho Chehab print ":Kconfig: $data{$feat}->{kconfig} \n" if ($data{$feat}->{kconfig}); 28452a4be3fSMauro Carvalho Chehab 28552a4be3fSMauro Carvalho Chehab my $desc = $data{$feat}->{description}; 28652a4be3fSMauro Carvalho Chehab $desc =~ s/^([a-z])/\U$1/; 28752a4be3fSMauro Carvalho Chehab $desc =~ s/\.?\s*//; 28852a4be3fSMauro Carvalho Chehab print "\n$desc.\n\n"; 28952a4be3fSMauro Carvalho Chehab 29052a4be3fSMauro Carvalho Chehab my $com = $data{$feat}->{comments}; 29152a4be3fSMauro Carvalho Chehab $com =~ s/^\s+//; 29252a4be3fSMauro Carvalho Chehab $com =~ s/\s+$//; 29352a4be3fSMauro Carvalho Chehab if ($com) { 29452a4be3fSMauro Carvalho Chehab print "Comments\n"; 29552a4be3fSMauro Carvalho Chehab print "--------\n\n"; 29652a4be3fSMauro Carvalho Chehab print "$com\n\n"; 29752a4be3fSMauro Carvalho Chehab } 29852a4be3fSMauro Carvalho Chehab 29952a4be3fSMauro Carvalho Chehab print "=" x $max_size_arch; 30052a4be3fSMauro Carvalho Chehab print " "; 30152a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 30252a4be3fSMauro Carvalho Chehab print "\n"; 30352a4be3fSMauro Carvalho Chehab 30452a4be3fSMauro Carvalho Chehab printf "%-${max_size_arch}s ", $h_arch; 30552a4be3fSMauro Carvalho Chehab printf "%-${max_size_status}s", $h_status . "\n"; 30652a4be3fSMauro Carvalho Chehab 30752a4be3fSMauro Carvalho Chehab print "=" x $max_size_arch; 30852a4be3fSMauro Carvalho Chehab print " "; 30952a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 31052a4be3fSMauro Carvalho Chehab print "\n"; 31152a4be3fSMauro Carvalho Chehab 31252a4be3fSMauro Carvalho Chehab my %arch_table = %{$data{$feat}->{table}}; 31352a4be3fSMauro Carvalho Chehab foreach my $arch (sort keys %arch_table) { 31452a4be3fSMauro Carvalho Chehab printf "%-${max_size_arch}s ", $arch; 31552a4be3fSMauro Carvalho Chehab printf "%-${max_size_status}s\n", $arch_table{$arch}; 31652a4be3fSMauro Carvalho Chehab } 31752a4be3fSMauro Carvalho Chehab 31852a4be3fSMauro Carvalho Chehab print "=" x $max_size_arch; 31952a4be3fSMauro Carvalho Chehab print " "; 32052a4be3fSMauro Carvalho Chehab print "=" x $max_size_status; 32152a4be3fSMauro Carvalho Chehab print "\n"; 32252a4be3fSMauro Carvalho Chehab} 32352a4be3fSMauro Carvalho Chehab 32452a4be3fSMauro Carvalho Chehab# 32552a4be3fSMauro Carvalho Chehab# Output all features for all architectures 32652a4be3fSMauro Carvalho Chehab# 32752a4be3fSMauro Carvalho Chehab 328dbb90902SMauro Carvalho Chehabsub matrix_lines($$$) { 329dbb90902SMauro Carvalho Chehab my $desc_size = shift; 330dbb90902SMauro Carvalho Chehab my $status_size = shift; 331ba813f7cSMauro Carvalho Chehab my $header = shift; 332ba813f7cSMauro Carvalho Chehab my $fill; 333ba813f7cSMauro Carvalho Chehab my $ln_marker; 33452a4be3fSMauro Carvalho Chehab 335ba813f7cSMauro Carvalho Chehab if ($header) { 336ba813f7cSMauro Carvalho Chehab $ln_marker = "="; 337ba813f7cSMauro Carvalho Chehab } else { 338ba813f7cSMauro Carvalho Chehab $ln_marker = "-"; 33952a4be3fSMauro Carvalho Chehab } 340ba813f7cSMauro Carvalho Chehab 341ba813f7cSMauro Carvalho Chehab $fill = $ln_marker; 342ba813f7cSMauro Carvalho Chehab 343dbb90902SMauro Carvalho Chehab print "+"; 344ba813f7cSMauro Carvalho Chehab print $fill x $max_size_name; 345ba813f7cSMauro Carvalho Chehab print "+"; 346dbb90902SMauro Carvalho Chehab print $fill x $desc_size; 347ba813f7cSMauro Carvalho Chehab print "+"; 348dbb90902SMauro Carvalho Chehab print $ln_marker x $status_size; 349ba813f7cSMauro Carvalho Chehab print "+\n"; 35052a4be3fSMauro Carvalho Chehab} 35152a4be3fSMauro Carvalho Chehab 35252a4be3fSMauro Carvalho Chehabsub output_matrix { 353ba813f7cSMauro Carvalho Chehab my $title = "Feature status on all architectures"; 35452a4be3fSMauro Carvalho Chehab 35552a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n"; 35652a4be3fSMauro Carvalho Chehab print "$title\n"; 35752a4be3fSMauro Carvalho Chehab print "=" x length($title) . "\n\n"; 35852a4be3fSMauro Carvalho Chehab 359dbb90902SMauro Carvalho Chehab my $desc_title = "$h_kconfig / $h_description"; 360dbb90902SMauro Carvalho Chehab 361dbb90902SMauro Carvalho Chehab my $desc_size = $max_size_kconfig + 4; 362dbb90902SMauro Carvalho Chehab $desc_size = $max_size_description if ($max_size_description > $desc_size); 363dbb90902SMauro Carvalho Chehab $desc_size = length($desc_title) if (length($desc_title) > $desc_size); 364dbb90902SMauro Carvalho Chehab 365dbb90902SMauro Carvalho Chehab my $status_size = 60; 366dbb90902SMauro Carvalho Chehab 367ba813f7cSMauro Carvalho Chehab my $cur_subsys = ""; 36852a4be3fSMauro Carvalho Chehab foreach my $name (sort { 369ba813f7cSMauro Carvalho Chehab ($data{$a}->{subsys} cmp $data{$b}->{subsys}) or 370ca908577SMauro Carvalho Chehab ("\L$a" cmp "\L$b") 37152a4be3fSMauro Carvalho Chehab } keys %data) { 372ba813f7cSMauro Carvalho Chehab 373ba813f7cSMauro Carvalho Chehab if ($cur_subsys ne $data{$name}->{subsys}) { 374ba813f7cSMauro Carvalho Chehab if ($cur_subsys ne "") { 375ba813f7cSMauro Carvalho Chehab printf "\n"; 376ba813f7cSMauro Carvalho Chehab } 377ba813f7cSMauro Carvalho Chehab 378ba813f7cSMauro Carvalho Chehab $cur_subsys = $data{$name}->{subsys}; 379ba813f7cSMauro Carvalho Chehab 380ba813f7cSMauro Carvalho Chehab my $title = "Subsystem: $cur_subsys"; 381ba813f7cSMauro Carvalho Chehab print "$title\n"; 382ba813f7cSMauro Carvalho Chehab print "=" x length($title) . "\n\n"; 383ba813f7cSMauro Carvalho Chehab 384dbb90902SMauro Carvalho Chehab 385dbb90902SMauro Carvalho Chehab matrix_lines($desc_size, $status_size, 0); 386dbb90902SMauro Carvalho Chehab 387ba813f7cSMauro Carvalho Chehab printf "|%-${max_size_name}s", $h_name; 388dbb90902SMauro Carvalho Chehab printf "|%-${desc_size}s", $desc_title; 389ba813f7cSMauro Carvalho Chehab 390dbb90902SMauro Carvalho Chehab printf "|%-${status_size}s|\n", "Status per architecture"; 391dbb90902SMauro Carvalho Chehab matrix_lines($desc_size, $status_size, 1); 392ba813f7cSMauro Carvalho Chehab } 39352a4be3fSMauro Carvalho Chehab 39452a4be3fSMauro Carvalho Chehab my %arch_table = %{$data{$name}->{table}}; 395dbb90902SMauro Carvalho Chehab my $cur_status = ""; 39652a4be3fSMauro Carvalho Chehab 397dbb90902SMauro Carvalho Chehab my @lines; 398dbb90902SMauro Carvalho Chehab my $line = ""; 399dbb90902SMauro Carvalho Chehab foreach my $arch (sort { 400*4fa32f87SMauro Carvalho Chehab ($arch_table{$b} cmp $arch_table{$a}) or 401dbb90902SMauro Carvalho Chehab ("\L$a" cmp "\L$b") 402dbb90902SMauro Carvalho Chehab } keys %arch_table) { 403dbb90902SMauro Carvalho Chehab 404dbb90902SMauro Carvalho Chehab my $status = $arch_table{$arch}; 405dbb90902SMauro Carvalho Chehab 406dbb90902SMauro Carvalho Chehab if ($status eq "---") { 407dbb90902SMauro Carvalho Chehab $status = "Not compatible"; 408dbb90902SMauro Carvalho Chehab } 409dbb90902SMauro Carvalho Chehab 410dbb90902SMauro Carvalho Chehab if ($status ne $cur_status) { 411dbb90902SMauro Carvalho Chehab if ($line ne "") { 412dbb90902SMauro Carvalho Chehab push @lines, $line; 413dbb90902SMauro Carvalho Chehab $line = ""; 414dbb90902SMauro Carvalho Chehab } 415dbb90902SMauro Carvalho Chehab $line = "- **" . $status . "**: " . $arch; 416dbb90902SMauro Carvalho Chehab } elsif (length($line) + length ($arch) + 2 < $status_size) { 417dbb90902SMauro Carvalho Chehab $line .= ", " . $arch; 418dbb90902SMauro Carvalho Chehab } else { 419dbb90902SMauro Carvalho Chehab push @lines, $line; 420dbb90902SMauro Carvalho Chehab $line = " " . $arch; 421dbb90902SMauro Carvalho Chehab } 422dbb90902SMauro Carvalho Chehab $cur_status = $status; 423dbb90902SMauro Carvalho Chehab } 424dbb90902SMauro Carvalho Chehab push @lines, $line if ($line ne ""); 425dbb90902SMauro Carvalho Chehab 426dbb90902SMauro Carvalho Chehab # Ensure that description will be printed 427dbb90902SMauro Carvalho Chehab push @lines, "" while (scalar(@lines) < 2); 428dbb90902SMauro Carvalho Chehab 429dbb90902SMauro Carvalho Chehab my $ln = 0; 430dbb90902SMauro Carvalho Chehab for my $line(@lines) { 431dbb90902SMauro Carvalho Chehab if (!$ln) { 432dbb90902SMauro Carvalho Chehab printf "|%-${max_size_name}s", $name; 433dbb90902SMauro Carvalho Chehab printf "|%-${desc_size}s", "``" . $data{$name}->{kconfig} . "``"; 434dbb90902SMauro Carvalho Chehab } elsif ($ln == 2) { 435ba813f7cSMauro Carvalho Chehab printf "|%-${max_size_name}s", ""; 436dbb90902SMauro Carvalho Chehab printf "|%-${desc_size}s", $data{$name}->{description}; 437dbb90902SMauro Carvalho Chehab } else { 438dbb90902SMauro Carvalho Chehab printf "|%-${max_size_name}s", ""; 439dbb90902SMauro Carvalho Chehab printf "|%-${desc_size}s", ""; 44052a4be3fSMauro Carvalho Chehab } 441dbb90902SMauro Carvalho Chehab 442dbb90902SMauro Carvalho Chehab printf "|%-${status_size}s|\n", $line; 443dbb90902SMauro Carvalho Chehab 444dbb90902SMauro Carvalho Chehab $ln++; 44552a4be3fSMauro Carvalho Chehab } 446dbb90902SMauro Carvalho Chehab matrix_lines($desc_size, $status_size, 0); 447ba813f7cSMauro Carvalho Chehab } 44852a4be3fSMauro Carvalho Chehab} 44952a4be3fSMauro Carvalho Chehab 45052a4be3fSMauro Carvalho Chehab 45152a4be3fSMauro Carvalho Chehab# 45252a4be3fSMauro Carvalho Chehab# Parses all feature files located at $prefix dir 45352a4be3fSMauro Carvalho Chehab# 45452a4be3fSMauro Carvalho Chehabfind({wanted =>\&parse_feat, no_chdir => 1}, $prefix); 45552a4be3fSMauro Carvalho Chehab 45652a4be3fSMauro Carvalho Chehabprint STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug); 45752a4be3fSMauro Carvalho Chehab 45852a4be3fSMauro Carvalho Chehab# 45952a4be3fSMauro Carvalho Chehab# Handles the command 46052a4be3fSMauro Carvalho Chehab# 46152a4be3fSMauro Carvalho Chehabif ($cmd eq "current") { 46252a4be3fSMauro Carvalho Chehab $arch = qx(uname -m | sed 's/x86_64/x86/' | sed 's/i386/x86/'); 46352a4be3fSMauro Carvalho Chehab $arch =~s/\s+$//; 46452a4be3fSMauro Carvalho Chehab} 46552a4be3fSMauro Carvalho Chehab 466ca908577SMauro Carvalho Chehabif ($cmd eq "ls" or $cmd eq "list") { 467ca908577SMauro Carvalho Chehab if (!$arch) { 468ca908577SMauro Carvalho Chehab $arch = qx(uname -m | sed 's/x86_64/x86/' | sed 's/i386/x86/'); 469ca908577SMauro Carvalho Chehab $arch =~s/\s+$//; 470ca908577SMauro Carvalho Chehab } 471ca908577SMauro Carvalho Chehab 472ca908577SMauro Carvalho Chehab list_arch_features; 473ca908577SMauro Carvalho Chehab 474ca908577SMauro Carvalho Chehab exit; 475ca908577SMauro Carvalho Chehab} 476ca908577SMauro Carvalho Chehab 47752a4be3fSMauro Carvalho Chehabif ($cmd ne "validate") { 47852a4be3fSMauro Carvalho Chehab if ($arch) { 47952a4be3fSMauro Carvalho Chehab output_arch_table; 48052a4be3fSMauro Carvalho Chehab } elsif ($feat) { 48152a4be3fSMauro Carvalho Chehab output_feature; 48252a4be3fSMauro Carvalho Chehab } else { 48352a4be3fSMauro Carvalho Chehab output_matrix; 48452a4be3fSMauro Carvalho Chehab } 48552a4be3fSMauro Carvalho Chehab} 48652a4be3fSMauro Carvalho Chehab 48752a4be3fSMauro Carvalho Chehab__END__ 48852a4be3fSMauro Carvalho Chehab 48952a4be3fSMauro Carvalho Chehab=head1 NAME 49052a4be3fSMauro Carvalho Chehab 49152a4be3fSMauro Carvalho Chehabget_feat.pl - parse the Linux Feature files and produce a ReST book. 49252a4be3fSMauro Carvalho Chehab 49352a4be3fSMauro Carvalho Chehab=head1 SYNOPSIS 49452a4be3fSMauro Carvalho Chehab 495ca908577SMauro Carvalho ChehabB<get_feat.pl> [--debug] [--man] [--help] [--dir=<dir>] [--arch=<arch>] 496ca908577SMauro Carvalho Chehab [--feature=<feature>|--feat=<feature>] <COMAND> [<ARGUMENT>] 49752a4be3fSMauro Carvalho Chehab 49852a4be3fSMauro Carvalho ChehabWhere <COMMAND> can be: 49952a4be3fSMauro Carvalho Chehab 50052a4be3fSMauro Carvalho Chehab=over 8 50152a4be3fSMauro Carvalho Chehab 502ca908577SMauro Carvalho ChehabB<current> - output table in ReST compatible ASCII format 503ca908577SMauro Carvalho Chehab with features for this machine's architecture 50452a4be3fSMauro Carvalho Chehab 505ca908577SMauro Carvalho ChehabB<rest> - output table(s) in ReST compatible ASCII format 506ca908577SMauro Carvalho Chehab with features in ReST markup language. The output 507ca908577SMauro Carvalho Chehab is affected by --arch or --feat/--feature flags. 50852a4be3fSMauro Carvalho Chehab 509ca908577SMauro Carvalho ChehabB<validate> - validate the contents of the files under 510ca908577SMauro Carvalho Chehab Documentation/features. 511ca908577SMauro Carvalho Chehab 512ca908577SMauro Carvalho ChehabB<ls> or B<list> - list features for this machine's architecture, 513ca908577SMauro Carvalho Chehab using an easier to parse format. 514ca908577SMauro Carvalho Chehab The output is affected by --arch flag. 51552a4be3fSMauro Carvalho Chehab 51652a4be3fSMauro Carvalho Chehab=back 51752a4be3fSMauro Carvalho Chehab 51852a4be3fSMauro Carvalho Chehab=head1 OPTIONS 51952a4be3fSMauro Carvalho Chehab 52052a4be3fSMauro Carvalho Chehab=over 8 52152a4be3fSMauro Carvalho Chehab 52252a4be3fSMauro Carvalho Chehab=item B<--arch> 52352a4be3fSMauro Carvalho Chehab 52452a4be3fSMauro Carvalho ChehabOutput features for an specific architecture, optionally filtering for 52552a4be3fSMauro Carvalho Chehaba single specific feature. 52652a4be3fSMauro Carvalho Chehab 527ca908577SMauro Carvalho Chehab=item B<--feat> or B<--feature> 52852a4be3fSMauro Carvalho Chehab 529ca908577SMauro Carvalho ChehabOutput features for a single specific feature. 53052a4be3fSMauro Carvalho Chehab 53152a4be3fSMauro Carvalho Chehab=item B<--dir> 53252a4be3fSMauro Carvalho Chehab 53352a4be3fSMauro Carvalho ChehabChanges the location of the Feature files. By default, it uses 53452a4be3fSMauro Carvalho Chehabthe Documentation/features directory. 53552a4be3fSMauro Carvalho Chehab 53652a4be3fSMauro Carvalho Chehab=item B<--debug> 53752a4be3fSMauro Carvalho Chehab 53852a4be3fSMauro Carvalho ChehabPut the script in verbose mode, useful for debugging. Can be called multiple 53952a4be3fSMauro Carvalho Chehabtimes, to increase verbosity. 54052a4be3fSMauro Carvalho Chehab 54152a4be3fSMauro Carvalho Chehab=item B<--help> 54252a4be3fSMauro Carvalho Chehab 54352a4be3fSMauro Carvalho ChehabPrints a brief help message and exits. 54452a4be3fSMauro Carvalho Chehab 54552a4be3fSMauro Carvalho Chehab=item B<--man> 54652a4be3fSMauro Carvalho Chehab 54752a4be3fSMauro Carvalho ChehabPrints the manual page and exits. 54852a4be3fSMauro Carvalho Chehab 54952a4be3fSMauro Carvalho Chehab=back 55052a4be3fSMauro Carvalho Chehab 55152a4be3fSMauro Carvalho Chehab=head1 DESCRIPTION 55252a4be3fSMauro Carvalho Chehab 55352a4be3fSMauro Carvalho ChehabParse the Linux feature files from Documentation/features (by default), 55452a4be3fSMauro Carvalho Chehaboptionally producing results at ReST format. 55552a4be3fSMauro Carvalho Chehab 55652a4be3fSMauro Carvalho ChehabIt supports output data per architecture, per feature or a 55752a4be3fSMauro Carvalho Chehabfeature x arch matrix. 55852a4be3fSMauro Carvalho Chehab 55952a4be3fSMauro Carvalho ChehabWhen used with B<rest> command, it will use either one of the tree formats: 56052a4be3fSMauro Carvalho Chehab 56152a4be3fSMauro Carvalho ChehabIf neither B<--arch> or B<--feature> arguments are used, it will output a 56252a4be3fSMauro Carvalho Chehabmatrix with features per architecture. 56352a4be3fSMauro Carvalho Chehab 56452a4be3fSMauro Carvalho ChehabIf B<--arch> argument is used, it will output the features availability for 56552a4be3fSMauro Carvalho Chehaba given architecture. 56652a4be3fSMauro Carvalho Chehab 56752a4be3fSMauro Carvalho ChehabIf B<--feat> argument is used, it will output the content of the feature 56852a4be3fSMauro Carvalho Chehabfile using ReStructured Text markup. 56952a4be3fSMauro Carvalho Chehab 57052a4be3fSMauro Carvalho Chehab=head1 BUGS 57152a4be3fSMauro Carvalho Chehab 57252a4be3fSMauro Carvalho ChehabReport bugs to Mauro Carvalho Chehab <mchehab+samsung@kernel.org> 57352a4be3fSMauro Carvalho Chehab 57452a4be3fSMauro Carvalho Chehab=head1 COPYRIGHT 57552a4be3fSMauro Carvalho Chehab 57652a4be3fSMauro Carvalho ChehabCopyright (c) 2019 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>. 57752a4be3fSMauro Carvalho Chehab 57852a4be3fSMauro Carvalho ChehabLicense GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>. 57952a4be3fSMauro Carvalho Chehab 58052a4be3fSMauro Carvalho ChehabThis is free software: you are free to change and redistribute it. 58152a4be3fSMauro Carvalho ChehabThere is NO WARRANTY, to the extent permitted by law. 58252a4be3fSMauro Carvalho Chehab 58352a4be3fSMauro Carvalho Chehab=cut 584