xref: /openbmc/linux/scripts/get_feat.pl (revision 4fa32f87)
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