xref: /linux/scripts/parse-maintainers.pl (revision ead5d1f4d877e92c051e1a1ade623d0d30e71619)
17683e9e5SLinus Torvalds#!/usr/bin/perl -w
2b2441318SGreg Kroah-Hartman# SPDX-License-Identifier: GPL-2.0
37683e9e5SLinus Torvalds
47683e9e5SLinus Torvaldsuse strict;
51e6270d0SJoe Perchesuse Getopt::Long qw(:config no_auto_abbrev);
61e6270d0SJoe Perches
71e6270d0SJoe Perchesmy $input_file = "MAINTAINERS";
81e6270d0SJoe Perchesmy $output_file = "MAINTAINERS.new";
91e6270d0SJoe Perchesmy $output_section = "SECTION.new";
101e6270d0SJoe Perchesmy $help = 0;
11*5cdbec10SJoe Perchesmy $order = 0;
12fe909030SJoe Perchesmy $P = $0;
137683e9e5SLinus Torvalds
141e6270d0SJoe Perchesif (!GetOptions(
151e6270d0SJoe Perches		'input=s' => \$input_file,
161e6270d0SJoe Perches		'output=s' => \$output_file,
171e6270d0SJoe Perches		'section=s' => \$output_section,
18*5cdbec10SJoe Perches		'order!' => \$order,
191e6270d0SJoe Perches		'h|help|usage' => \$help,
201e6270d0SJoe Perches	    )) {
211e6270d0SJoe Perches    die "$P: invalid argument - use --help if necessary\n";
221e6270d0SJoe Perches}
231e6270d0SJoe Perches
241e6270d0SJoe Perchesif ($help != 0) {
251e6270d0SJoe Perches    usage();
261e6270d0SJoe Perches    exit 0;
271e6270d0SJoe Perches}
281e6270d0SJoe Perches
291e6270d0SJoe Perchessub usage {
301e6270d0SJoe Perches    print <<EOT;
311e6270d0SJoe Perchesusage: $P [options] <pattern matching regexes>
321e6270d0SJoe Perches
331e6270d0SJoe Perches  --input => MAINTAINERS file to read (default: MAINTAINERS)
341e6270d0SJoe Perches  --output => sorted MAINTAINERS file to write (default: MAINTAINERS.new)
351e6270d0SJoe Perches  --section => new sorted MAINTAINERS file to write to (default: SECTION.new)
36*5cdbec10SJoe Perches  --order => Use the preferred section content output ordering (default: 0)
37*5cdbec10SJoe Perches    Preferred ordering of section output is:
38*5cdbec10SJoe Perches      M:  Person acting as a maintainer
39*5cdbec10SJoe Perches      R:  Person acting as a patch reviewer
40*5cdbec10SJoe Perches      L:  Mailing list where patches should be sent
41*5cdbec10SJoe Perches      S:  Maintenance status
42*5cdbec10SJoe Perches      W:  URI for general information
43*5cdbec10SJoe Perches      Q:  URI for patchwork tracking
44*5cdbec10SJoe Perches      B:  URI for bug tracking/submission
45*5cdbec10SJoe Perches      C:  URI for chat
46*5cdbec10SJoe Perches      P:  URI or file for subsystem specific coding styles
47*5cdbec10SJoe Perches      T:  SCM tree type and location
48*5cdbec10SJoe Perches      F:  File and directory pattern
49*5cdbec10SJoe Perches      X:  File and directory exclusion pattern
50*5cdbec10SJoe Perches      N:  File glob
51*5cdbec10SJoe Perches      K:  Keyword - patch content regex
521e6270d0SJoe Perches
531e6270d0SJoe PerchesIf <pattern match regexes> exist, then the sections that match the
541e6270d0SJoe Perchesregexes are not written to the output file but are written to the
551e6270d0SJoe Perchessection file.
561e6270d0SJoe Perches
571e6270d0SJoe PerchesEOT
581e6270d0SJoe Perches}
591e6270d0SJoe Perches
6061f74164SJoe Perches# sort comparison functions
617683e9e5SLinus Torvaldssub by_category($$) {
627683e9e5SLinus Torvalds    my ($a, $b) = @_;
637683e9e5SLinus Torvalds
647683e9e5SLinus Torvalds    $a = uc $a;
657683e9e5SLinus Torvalds    $b = uc $b;
667683e9e5SLinus Torvalds
677683e9e5SLinus Torvalds    # This always sorts last
687683e9e5SLinus Torvalds    $a =~ s/THE REST/ZZZZZZ/g;
697683e9e5SLinus Torvalds    $b =~ s/THE REST/ZZZZZZ/g;
707683e9e5SLinus Torvalds
7161f74164SJoe Perches    return $a cmp $b;
7261f74164SJoe Perches}
7361f74164SJoe Perches
7461f74164SJoe Perchessub by_pattern($$) {
7561f74164SJoe Perches    my ($a, $b) = @_;
76*5cdbec10SJoe Perches    my $preferred_order = 'MRLSWQBCPTFXNK';
7761f74164SJoe Perches
7861f74164SJoe Perches    my $a1 = uc(substr($a, 0, 1));
7961f74164SJoe Perches    my $b1 = uc(substr($b, 0, 1));
8061f74164SJoe Perches
8161f74164SJoe Perches    my $a_index = index($preferred_order, $a1);
8261f74164SJoe Perches    my $b_index = index($preferred_order, $b1);
8361f74164SJoe Perches
8461f74164SJoe Perches    $a_index = 1000 if ($a_index == -1);
8561f74164SJoe Perches    $b_index = 1000 if ($b_index == -1);
8661f74164SJoe Perches
8761f74164SJoe Perches    if (($a1 =~ /^F$/ && $b1 =~ /^F$/) ||
8861f74164SJoe Perches	($a1 =~ /^X$/ && $b1 =~ /^X$/)) {
8961f74164SJoe Perches	return $a cmp $b;
9061f74164SJoe Perches    }
9161f74164SJoe Perches
9261f74164SJoe Perches    if ($a_index < $b_index) {
9361f74164SJoe Perches	return -1;
9461f74164SJoe Perches    } elsif ($a_index == $b_index) {
9561f74164SJoe Perches	return 0;
9661f74164SJoe Perches    } else {
9761f74164SJoe Perches	return 1;
9861f74164SJoe Perches    }
997683e9e5SLinus Torvalds}
1007683e9e5SLinus Torvalds
1017683e9e5SLinus Torvaldssub trim {
1027683e9e5SLinus Torvalds    my $s = shift;
1037683e9e5SLinus Torvalds    $s =~ s/\s+$//;
1047683e9e5SLinus Torvalds    $s =~ s/^\s+//;
1057683e9e5SLinus Torvalds    return $s;
1067683e9e5SLinus Torvalds}
1077683e9e5SLinus Torvalds
108fe909030SJoe Perchessub alpha_output {
109fe909030SJoe Perches    my ($hashref, $filename) = (@_);
110fe909030SJoe Perches
1111e6270d0SJoe Perches    return if ! scalar(keys %$hashref);
1121e6270d0SJoe Perches
113fe909030SJoe Perches    open(my $file, '>', "$filename") or die "$P: $filename: open failed - $!\n";
1141e6270d0SJoe Perches    my $separator;
115fe909030SJoe Perches    foreach my $key (sort by_category keys %$hashref) {
116fe909030SJoe Perches	if ($key eq " ") {
117fe909030SJoe Perches	    print $file $$hashref{$key};
118fe909030SJoe Perches	} else {
1191e6270d0SJoe Perches	    if (! defined $separator) {
1201e6270d0SJoe Perches		$separator = "\n";
1211e6270d0SJoe Perches	    } else {
1221e6270d0SJoe Perches		print $file $separator;
1231e6270d0SJoe Perches	    }
1241e6270d0SJoe Perches	    print $file $key . "\n";
125*5cdbec10SJoe Perches	    if ($order) {
126fe909030SJoe Perches		foreach my $pattern (sort by_pattern split('\n', %$hashref{$key})) {
127fe909030SJoe Perches		    print $file ($pattern . "\n");
128fe909030SJoe Perches		}
129*5cdbec10SJoe Perches	    } else {
130*5cdbec10SJoe Perches		foreach my $pattern (split('\n', %$hashref{$key})) {
131*5cdbec10SJoe Perches		    print $file ($pattern . "\n");
132*5cdbec10SJoe Perches		}
133*5cdbec10SJoe Perches	    }
134fe909030SJoe Perches	}
135fe909030SJoe Perches    }
136fe909030SJoe Perches    close($file);
137fe909030SJoe Perches}
138fe909030SJoe Perches
1397683e9e5SLinus Torvaldssub file_input {
140fe909030SJoe Perches    my ($hashref, $filename) = (@_);
141fe909030SJoe Perches
1427683e9e5SLinus Torvalds    my $lastline = "";
1437683e9e5SLinus Torvalds    my $case = " ";
144fe909030SJoe Perches    $$hashref{$case} = "";
1457683e9e5SLinus Torvalds
146fe909030SJoe Perches    open(my $file, '<', "$filename") or die "$P: $filename: open failed - $!\n";
147fe909030SJoe Perches
148fe909030SJoe Perches    while (<$file>) {
1497683e9e5SLinus Torvalds        my $line = $_;
1507683e9e5SLinus Torvalds
1517683e9e5SLinus Torvalds        # Pattern line?
1527683e9e5SLinus Torvalds        if ($line =~ m/^([A-Z]):\s*(.*)/) {
1537683e9e5SLinus Torvalds            $line = $1 . ":\t" . trim($2) . "\n";
1547683e9e5SLinus Torvalds            if ($lastline eq "") {
155fe909030SJoe Perches                $$hashref{$case} = $$hashref{$case} . $line;
1567683e9e5SLinus Torvalds                next;
1577683e9e5SLinus Torvalds            }
1587683e9e5SLinus Torvalds            $case = trim($lastline);
159fe909030SJoe Perches            exists $$hashref{$case} and die "Header '$case' already exists";
160fe909030SJoe Perches            $$hashref{$case} = $line;
1617683e9e5SLinus Torvalds            $lastline = "";
1627683e9e5SLinus Torvalds            next;
1637683e9e5SLinus Torvalds        }
1647683e9e5SLinus Torvalds
1657683e9e5SLinus Torvalds        if ($case eq " ") {
166fe909030SJoe Perches            $$hashref{$case} = $$hashref{$case} . $lastline;
1677683e9e5SLinus Torvalds            $lastline = $line;
1687683e9e5SLinus Torvalds            next;
1697683e9e5SLinus Torvalds        }
1707683e9e5SLinus Torvalds        trim($lastline) eq "" or die ("Odd non-pattern line '$lastline' for '$case'");
1717683e9e5SLinus Torvalds        $lastline = $line;
1727683e9e5SLinus Torvalds    }
173fe909030SJoe Perches    $$hashref{$case} = $$hashref{$case} . $lastline;
174fe909030SJoe Perches    close($file);
1757683e9e5SLinus Torvalds}
1767683e9e5SLinus Torvalds
177fe909030SJoe Perchesmy %hash;
178b95c29a2SJoe Perchesmy %new_hash;
179fe909030SJoe Perches
1801e6270d0SJoe Perchesfile_input(\%hash, $input_file);
181b95c29a2SJoe Perches
182b95c29a2SJoe Perchesforeach my $type (@ARGV) {
183b95c29a2SJoe Perches    foreach my $key (keys %hash) {
184b95c29a2SJoe Perches	if ($key =~ /$type/ || $hash{$key} =~ /$type/) {
185b95c29a2SJoe Perches	    $new_hash{$key} = $hash{$key};
186b95c29a2SJoe Perches	    delete $hash{$key};
187b95c29a2SJoe Perches	}
188b95c29a2SJoe Perches    }
189b95c29a2SJoe Perches}
190b95c29a2SJoe Perches
1911e6270d0SJoe Perchesalpha_output(\%hash, $output_file);
1921e6270d0SJoe Perchesalpha_output(\%new_hash, $output_section);
19361f74164SJoe Perches
1947683e9e5SLinus Torvaldsexit(0);
195