0001
0002
0003
0004 use strict;
0005 use Getopt::Long ;
0006
0007 my $input_file = "MAINTAINERS";
0008 my $output_file = "MAINTAINERS.new";
0009 my $output_section = "SECTION.new";
0010 my $help = 0;
0011 my $order = 0;
0012 my $P = $0;
0013
0014 if (!GetOptions(
0015 'input=s' => \$input_file,
0016 'output=s' => \$output_file,
0017 'section=s' => \$output_section,
0018 'order!' => \$order,
0019 'h|help|usage' => \$help,
0020 )) {
0021 die "$P: invalid argument - use --help if necessary\n";
0022 }
0023
0024 if ($help != 0) {
0025 usage();
0026 exit 0;
0027 }
0028
0029 sub usage {
0030 print <<EOT;
0031 usage: $P [options] <pattern matching regexes>
0032
0033 --input => MAINTAINERS file to read (default: MAINTAINERS)
0034 --output => sorted MAINTAINERS file to write (default: MAINTAINERS.new)
0035 --section => new sorted MAINTAINERS file to write to (default: SECTION.new)
0036 --order => Use the preferred section content output ordering (default: 0)
0037 Preferred ordering of section output is:
0038 M: Person acting as a maintainer
0039 R: Person acting as a patch reviewer
0040 L: Mailing list where patches should be sent
0041 S: Maintenance status
0042 W: URI for general information
0043 Q: URI for patchwork tracking
0044 B: URI for bug tracking/submission
0045 C: URI for chat
0046 P: URI or file for subsystem specific coding styles
0047 T: SCM tree type and location
0048 F: File and directory pattern
0049 X: File and directory exclusion pattern
0050 N: File glob
0051 K: Keyword - patch content regex
0052
0053 If <pattern match regexes> exist, then the sections that match the
0054 regexes are not written to the output file but are written to the
0055 section file.
0056
0057 EOT
0058 }
0059
0060
0061 sub by_category($$) {
0062 my ($a, $b) = @_;
0063
0064 $a = uc $a;
0065 $b = uc $b;
0066
0067
0068 $a =~ s/THE REST/ZZZZZZ/g;
0069 $b =~ s/THE REST/ZZZZZZ/g;
0070
0071 return $a cmp $b;
0072 }
0073
0074 sub by_pattern($$) {
0075 my ($a, $b) = @_;
0076 my $preferred_order = 'MRLSWQBCPTFXNK';
0077
0078 my $a1 = uc(substr($a, 0, 1));
0079 my $b1 = uc(substr($b, 0, 1));
0080
0081 my $a_index = index($preferred_order, $a1);
0082 my $b_index = index($preferred_order, $b1);
0083
0084 $a_index = 1000 if ($a_index == -1);
0085 $b_index = 1000 if ($b_index == -1);
0086
0087 if (($a1 =~ /^F$/ && $b1 =~ /^F$/) ||
0088 ($a1 =~ /^X$/ && $b1 =~ /^X$/)) {
0089 return $a cmp $b;
0090 }
0091
0092 if ($a_index < $b_index) {
0093 return -1;
0094 } elsif ($a_index == $b_index) {
0095 return 0;
0096 } else {
0097 return 1;
0098 }
0099 }
0100
0101 sub trim {
0102 my $s = shift;
0103 $s =~ s/\s+$//;
0104 $s =~ s/^\s+//;
0105 return $s;
0106 }
0107
0108 sub alpha_output {
0109 my ($hashref, $filename) = (@_);
0110
0111 return if ! scalar(keys %$hashref);
0112
0113 open(my $file, '>', "$filename") or die "$P: $filename: open failed - $!\n";
0114 my $separator;
0115 foreach my $key (sort by_category keys %$hashref) {
0116 if ($key eq " ") {
0117 print $file $$hashref{$key};
0118 } else {
0119 if (! defined $separator) {
0120 $separator = "\n";
0121 } else {
0122 print $file $separator;
0123 }
0124 print $file $key . "\n";
0125 if ($order) {
0126 foreach my $pattern (sort by_pattern split('\n', %$hashref{$key})) {
0127 print $file ($pattern . "\n");
0128 }
0129 } else {
0130 foreach my $pattern (split('\n', %$hashref{$key})) {
0131 print $file ($pattern . "\n");
0132 }
0133 }
0134 }
0135 }
0136 close($file);
0137 }
0138
0139 sub file_input {
0140 my ($hashref, $filename) = (@_);
0141
0142 my $lastline = "";
0143 my $case = " ";
0144 $$hashref{$case} = "";
0145
0146 open(my $file, '<', "$filename") or die "$P: $filename: open failed - $!\n";
0147
0148 while (<$file>) {
0149 my $line = $_;
0150
0151
0152 if ($line =~ ) {
0153 $line = $1 . ":\t" . trim($2) . "\n";
0154 if ($lastline eq "") {
0155 $$hashref{$case} = $$hashref{$case} . $line;
0156 next;
0157 }
0158 $case = trim($lastline);
0159 exists $$hashref{$case} and die "Header '$case' already exists";
0160 $$hashref{$case} = $line;
0161 $lastline = "";
0162 next;
0163 }
0164
0165 if ($case eq " ") {
0166 $$hashref{$case} = $$hashref{$case} . $lastline;
0167 $lastline = $line;
0168 next;
0169 }
0170 trim($lastline) eq "" or die ("Odd non-pattern line '$lastline' for '$case'");
0171 $lastline = $line;
0172 }
0173 $$hashref{$case} = $$hashref{$case} . $lastline;
0174 close($file);
0175 }
0176
0177 my %hash;
0178 my %new_hash;
0179
0180 file_input(\%hash, $input_file);
0181
0182 foreach my $type (@ARGV) {
0183 foreach my $key (keys %hash) {
0184 if ($key =~ /$type/ || $hash{$key} =~ /$type/) {
0185 $new_hash{$key} = $hash{$key};
0186 delete $hash{$key};
0187 }
0188 }
0189 }
0190
0191 alpha_output(\%hash, $output_file);
0192 alpha_output(\%new_hash, $output_section);
0193
0194 exit(0);