18c2ecf20Sopenharmony_ci#!/usr/bin/perl -w 28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ciuse strict; 58c2ecf20Sopenharmony_ciuse Getopt::Long qw(:config no_auto_abbrev); 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_cimy $input_file = "MAINTAINERS"; 88c2ecf20Sopenharmony_cimy $output_file = "MAINTAINERS.new"; 98c2ecf20Sopenharmony_cimy $output_section = "SECTION.new"; 108c2ecf20Sopenharmony_cimy $help = 0; 118c2ecf20Sopenharmony_cimy $order = 0; 128c2ecf20Sopenharmony_cimy $P = $0; 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ciif (!GetOptions( 158c2ecf20Sopenharmony_ci 'input=s' => \$input_file, 168c2ecf20Sopenharmony_ci 'output=s' => \$output_file, 178c2ecf20Sopenharmony_ci 'section=s' => \$output_section, 188c2ecf20Sopenharmony_ci 'order!' => \$order, 198c2ecf20Sopenharmony_ci 'h|help|usage' => \$help, 208c2ecf20Sopenharmony_ci )) { 218c2ecf20Sopenharmony_ci die "$P: invalid argument - use --help if necessary\n"; 228c2ecf20Sopenharmony_ci} 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ciif ($help != 0) { 258c2ecf20Sopenharmony_ci usage(); 268c2ecf20Sopenharmony_ci exit 0; 278c2ecf20Sopenharmony_ci} 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cisub usage { 308c2ecf20Sopenharmony_ci print <<EOT; 318c2ecf20Sopenharmony_ciusage: $P [options] <pattern matching regexes> 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci --input => MAINTAINERS file to read (default: MAINTAINERS) 348c2ecf20Sopenharmony_ci --output => sorted MAINTAINERS file to write (default: MAINTAINERS.new) 358c2ecf20Sopenharmony_ci --section => new sorted MAINTAINERS file to write to (default: SECTION.new) 368c2ecf20Sopenharmony_ci --order => Use the preferred section content output ordering (default: 0) 378c2ecf20Sopenharmony_ci Preferred ordering of section output is: 388c2ecf20Sopenharmony_ci M: Person acting as a maintainer 398c2ecf20Sopenharmony_ci R: Person acting as a patch reviewer 408c2ecf20Sopenharmony_ci L: Mailing list where patches should be sent 418c2ecf20Sopenharmony_ci S: Maintenance status 428c2ecf20Sopenharmony_ci W: URI for general information 438c2ecf20Sopenharmony_ci Q: URI for patchwork tracking 448c2ecf20Sopenharmony_ci B: URI for bug tracking/submission 458c2ecf20Sopenharmony_ci C: URI for chat 468c2ecf20Sopenharmony_ci P: URI or file for subsystem specific coding styles 478c2ecf20Sopenharmony_ci T: SCM tree type and location 488c2ecf20Sopenharmony_ci F: File and directory pattern 498c2ecf20Sopenharmony_ci X: File and directory exclusion pattern 508c2ecf20Sopenharmony_ci N: File glob 518c2ecf20Sopenharmony_ci K: Keyword - patch content regex 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ciIf <pattern match regexes> exist, then the sections that match the 548c2ecf20Sopenharmony_ciregexes are not written to the output file but are written to the 558c2ecf20Sopenharmony_cisection file. 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ciEOT 588c2ecf20Sopenharmony_ci} 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci# sort comparison functions 618c2ecf20Sopenharmony_cisub by_category($$) { 628c2ecf20Sopenharmony_ci my ($a, $b) = @_; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci $a = uc $a; 658c2ecf20Sopenharmony_ci $b = uc $b; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci # This always sorts last 688c2ecf20Sopenharmony_ci $a =~ s/THE REST/ZZZZZZ/g; 698c2ecf20Sopenharmony_ci $b =~ s/THE REST/ZZZZZZ/g; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci return $a cmp $b; 728c2ecf20Sopenharmony_ci} 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cisub by_pattern($$) { 758c2ecf20Sopenharmony_ci my ($a, $b) = @_; 768c2ecf20Sopenharmony_ci my $preferred_order = 'MRLSWQBCPTFXNK'; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci my $a1 = uc(substr($a, 0, 1)); 798c2ecf20Sopenharmony_ci my $b1 = uc(substr($b, 0, 1)); 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci my $a_index = index($preferred_order, $a1); 828c2ecf20Sopenharmony_ci my $b_index = index($preferred_order, $b1); 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci $a_index = 1000 if ($a_index == -1); 858c2ecf20Sopenharmony_ci $b_index = 1000 if ($b_index == -1); 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci if (($a1 =~ /^F$/ && $b1 =~ /^F$/) || 888c2ecf20Sopenharmony_ci ($a1 =~ /^X$/ && $b1 =~ /^X$/)) { 898c2ecf20Sopenharmony_ci return $a cmp $b; 908c2ecf20Sopenharmony_ci } 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci if ($a_index < $b_index) { 938c2ecf20Sopenharmony_ci return -1; 948c2ecf20Sopenharmony_ci } elsif ($a_index == $b_index) { 958c2ecf20Sopenharmony_ci return 0; 968c2ecf20Sopenharmony_ci } else { 978c2ecf20Sopenharmony_ci return 1; 988c2ecf20Sopenharmony_ci } 998c2ecf20Sopenharmony_ci} 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_cisub trim { 1028c2ecf20Sopenharmony_ci my $s = shift; 1038c2ecf20Sopenharmony_ci $s =~ s/\s+$//; 1048c2ecf20Sopenharmony_ci $s =~ s/^\s+//; 1058c2ecf20Sopenharmony_ci return $s; 1068c2ecf20Sopenharmony_ci} 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cisub alpha_output { 1098c2ecf20Sopenharmony_ci my ($hashref, $filename) = (@_); 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci return if ! scalar(keys %$hashref); 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci open(my $file, '>', "$filename") or die "$P: $filename: open failed - $!\n"; 1148c2ecf20Sopenharmony_ci my $separator; 1158c2ecf20Sopenharmony_ci foreach my $key (sort by_category keys %$hashref) { 1168c2ecf20Sopenharmony_ci if ($key eq " ") { 1178c2ecf20Sopenharmony_ci print $file $$hashref{$key}; 1188c2ecf20Sopenharmony_ci } else { 1198c2ecf20Sopenharmony_ci if (! defined $separator) { 1208c2ecf20Sopenharmony_ci $separator = "\n"; 1218c2ecf20Sopenharmony_ci } else { 1228c2ecf20Sopenharmony_ci print $file $separator; 1238c2ecf20Sopenharmony_ci } 1248c2ecf20Sopenharmony_ci print $file $key . "\n"; 1258c2ecf20Sopenharmony_ci if ($order) { 1268c2ecf20Sopenharmony_ci foreach my $pattern (sort by_pattern split('\n', %$hashref{$key})) { 1278c2ecf20Sopenharmony_ci print $file ($pattern . "\n"); 1288c2ecf20Sopenharmony_ci } 1298c2ecf20Sopenharmony_ci } else { 1308c2ecf20Sopenharmony_ci foreach my $pattern (split('\n', %$hashref{$key})) { 1318c2ecf20Sopenharmony_ci print $file ($pattern . "\n"); 1328c2ecf20Sopenharmony_ci } 1338c2ecf20Sopenharmony_ci } 1348c2ecf20Sopenharmony_ci } 1358c2ecf20Sopenharmony_ci } 1368c2ecf20Sopenharmony_ci close($file); 1378c2ecf20Sopenharmony_ci} 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_cisub file_input { 1408c2ecf20Sopenharmony_ci my ($hashref, $filename) = (@_); 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci my $lastline = ""; 1438c2ecf20Sopenharmony_ci my $case = " "; 1448c2ecf20Sopenharmony_ci $$hashref{$case} = ""; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci open(my $file, '<', "$filename") or die "$P: $filename: open failed - $!\n"; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci while (<$file>) { 1498c2ecf20Sopenharmony_ci my $line = $_; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci # Pattern line? 1528c2ecf20Sopenharmony_ci if ($line =~ m/^([A-Z]):\s*(.*)/) { 1538c2ecf20Sopenharmony_ci $line = $1 . ":\t" . trim($2) . "\n"; 1548c2ecf20Sopenharmony_ci if ($lastline eq "") { 1558c2ecf20Sopenharmony_ci $$hashref{$case} = $$hashref{$case} . $line; 1568c2ecf20Sopenharmony_ci next; 1578c2ecf20Sopenharmony_ci } 1588c2ecf20Sopenharmony_ci $case = trim($lastline); 1598c2ecf20Sopenharmony_ci exists $$hashref{$case} and die "Header '$case' already exists"; 1608c2ecf20Sopenharmony_ci $$hashref{$case} = $line; 1618c2ecf20Sopenharmony_ci $lastline = ""; 1628c2ecf20Sopenharmony_ci next; 1638c2ecf20Sopenharmony_ci } 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci if ($case eq " ") { 1668c2ecf20Sopenharmony_ci $$hashref{$case} = $$hashref{$case} . $lastline; 1678c2ecf20Sopenharmony_ci $lastline = $line; 1688c2ecf20Sopenharmony_ci next; 1698c2ecf20Sopenharmony_ci } 1708c2ecf20Sopenharmony_ci trim($lastline) eq "" or die ("Odd non-pattern line '$lastline' for '$case'"); 1718c2ecf20Sopenharmony_ci $lastline = $line; 1728c2ecf20Sopenharmony_ci } 1738c2ecf20Sopenharmony_ci $$hashref{$case} = $$hashref{$case} . $lastline; 1748c2ecf20Sopenharmony_ci close($file); 1758c2ecf20Sopenharmony_ci} 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_cimy %hash; 1788c2ecf20Sopenharmony_cimy %new_hash; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_cifile_input(\%hash, $input_file); 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ciforeach my $type (@ARGV) { 1838c2ecf20Sopenharmony_ci foreach my $key (keys %hash) { 1848c2ecf20Sopenharmony_ci if ($key =~ /$type/ || $hash{$key} =~ /$type/) { 1858c2ecf20Sopenharmony_ci $new_hash{$key} = $hash{$key}; 1868c2ecf20Sopenharmony_ci delete $hash{$key}; 1878c2ecf20Sopenharmony_ci } 1888c2ecf20Sopenharmony_ci } 1898c2ecf20Sopenharmony_ci} 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_cialpha_output(\%hash, $output_file); 1928c2ecf20Sopenharmony_cialpha_output(\%new_hash, $output_section); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ciexit(0); 195