xref: /OK3568_Linux_fs/kernel/scripts/parse-maintainers.pl (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/usr/bin/perl -w
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0
3*4882a593Smuzhiyun
4*4882a593Smuzhiyunuse strict;
5*4882a593Smuzhiyunuse Getopt::Long qw(:config no_auto_abbrev);
6*4882a593Smuzhiyun
7*4882a593Smuzhiyunmy $input_file = "MAINTAINERS";
8*4882a593Smuzhiyunmy $output_file = "MAINTAINERS.new";
9*4882a593Smuzhiyunmy $output_section = "SECTION.new";
10*4882a593Smuzhiyunmy $help = 0;
11*4882a593Smuzhiyunmy $order = 0;
12*4882a593Smuzhiyunmy $P = $0;
13*4882a593Smuzhiyun
14*4882a593Smuzhiyunif (!GetOptions(
15*4882a593Smuzhiyun		'input=s' => \$input_file,
16*4882a593Smuzhiyun		'output=s' => \$output_file,
17*4882a593Smuzhiyun		'section=s' => \$output_section,
18*4882a593Smuzhiyun		'order!' => \$order,
19*4882a593Smuzhiyun		'h|help|usage' => \$help,
20*4882a593Smuzhiyun	    )) {
21*4882a593Smuzhiyun    die "$P: invalid argument - use --help if necessary\n";
22*4882a593Smuzhiyun}
23*4882a593Smuzhiyun
24*4882a593Smuzhiyunif ($help != 0) {
25*4882a593Smuzhiyun    usage();
26*4882a593Smuzhiyun    exit 0;
27*4882a593Smuzhiyun}
28*4882a593Smuzhiyun
29*4882a593Smuzhiyunsub usage {
30*4882a593Smuzhiyun    print <<EOT;
31*4882a593Smuzhiyunusage: $P [options] <pattern matching regexes>
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun  --input => MAINTAINERS file to read (default: MAINTAINERS)
34*4882a593Smuzhiyun  --output => sorted MAINTAINERS file to write (default: MAINTAINERS.new)
35*4882a593Smuzhiyun  --section => new sorted MAINTAINERS file to write to (default: SECTION.new)
36*4882a593Smuzhiyun  --order => Use the preferred section content output ordering (default: 0)
37*4882a593Smuzhiyun    Preferred ordering of section output is:
38*4882a593Smuzhiyun      M:  Person acting as a maintainer
39*4882a593Smuzhiyun      R:  Person acting as a patch reviewer
40*4882a593Smuzhiyun      L:  Mailing list where patches should be sent
41*4882a593Smuzhiyun      S:  Maintenance status
42*4882a593Smuzhiyun      W:  URI for general information
43*4882a593Smuzhiyun      Q:  URI for patchwork tracking
44*4882a593Smuzhiyun      B:  URI for bug tracking/submission
45*4882a593Smuzhiyun      C:  URI for chat
46*4882a593Smuzhiyun      P:  URI or file for subsystem specific coding styles
47*4882a593Smuzhiyun      T:  SCM tree type and location
48*4882a593Smuzhiyun      F:  File and directory pattern
49*4882a593Smuzhiyun      X:  File and directory exclusion pattern
50*4882a593Smuzhiyun      N:  File glob
51*4882a593Smuzhiyun      K:  Keyword - patch content regex
52*4882a593Smuzhiyun
53*4882a593SmuzhiyunIf <pattern match regexes> exist, then the sections that match the
54*4882a593Smuzhiyunregexes are not written to the output file but are written to the
55*4882a593Smuzhiyunsection file.
56*4882a593Smuzhiyun
57*4882a593SmuzhiyunEOT
58*4882a593Smuzhiyun}
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun# sort comparison functions
61*4882a593Smuzhiyunsub by_category($$) {
62*4882a593Smuzhiyun    my ($a, $b) = @_;
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun    $a = uc $a;
65*4882a593Smuzhiyun    $b = uc $b;
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun    # This always sorts last
68*4882a593Smuzhiyun    $a =~ s/THE REST/ZZZZZZ/g;
69*4882a593Smuzhiyun    $b =~ s/THE REST/ZZZZZZ/g;
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun    return $a cmp $b;
72*4882a593Smuzhiyun}
73*4882a593Smuzhiyun
74*4882a593Smuzhiyunsub by_pattern($$) {
75*4882a593Smuzhiyun    my ($a, $b) = @_;
76*4882a593Smuzhiyun    my $preferred_order = 'MRLSWQBCPTFXNK';
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun    my $a1 = uc(substr($a, 0, 1));
79*4882a593Smuzhiyun    my $b1 = uc(substr($b, 0, 1));
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun    my $a_index = index($preferred_order, $a1);
82*4882a593Smuzhiyun    my $b_index = index($preferred_order, $b1);
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun    $a_index = 1000 if ($a_index == -1);
85*4882a593Smuzhiyun    $b_index = 1000 if ($b_index == -1);
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun    if (($a1 =~ /^F$/ && $b1 =~ /^F$/) ||
88*4882a593Smuzhiyun	($a1 =~ /^X$/ && $b1 =~ /^X$/)) {
89*4882a593Smuzhiyun	return $a cmp $b;
90*4882a593Smuzhiyun    }
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun    if ($a_index < $b_index) {
93*4882a593Smuzhiyun	return -1;
94*4882a593Smuzhiyun    } elsif ($a_index == $b_index) {
95*4882a593Smuzhiyun	return 0;
96*4882a593Smuzhiyun    } else {
97*4882a593Smuzhiyun	return 1;
98*4882a593Smuzhiyun    }
99*4882a593Smuzhiyun}
100*4882a593Smuzhiyun
101*4882a593Smuzhiyunsub trim {
102*4882a593Smuzhiyun    my $s = shift;
103*4882a593Smuzhiyun    $s =~ s/\s+$//;
104*4882a593Smuzhiyun    $s =~ s/^\s+//;
105*4882a593Smuzhiyun    return $s;
106*4882a593Smuzhiyun}
107*4882a593Smuzhiyun
108*4882a593Smuzhiyunsub alpha_output {
109*4882a593Smuzhiyun    my ($hashref, $filename) = (@_);
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun    return if ! scalar(keys %$hashref);
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun    open(my $file, '>', "$filename") or die "$P: $filename: open failed - $!\n";
114*4882a593Smuzhiyun    my $separator;
115*4882a593Smuzhiyun    foreach my $key (sort by_category keys %$hashref) {
116*4882a593Smuzhiyun	if ($key eq " ") {
117*4882a593Smuzhiyun	    print $file $$hashref{$key};
118*4882a593Smuzhiyun	} else {
119*4882a593Smuzhiyun	    if (! defined $separator) {
120*4882a593Smuzhiyun		$separator = "\n";
121*4882a593Smuzhiyun	    } else {
122*4882a593Smuzhiyun		print $file $separator;
123*4882a593Smuzhiyun	    }
124*4882a593Smuzhiyun	    print $file $key . "\n";
125*4882a593Smuzhiyun	    if ($order) {
126*4882a593Smuzhiyun		foreach my $pattern (sort by_pattern split('\n', %$hashref{$key})) {
127*4882a593Smuzhiyun		    print $file ($pattern . "\n");
128*4882a593Smuzhiyun		}
129*4882a593Smuzhiyun	    } else {
130*4882a593Smuzhiyun		foreach my $pattern (split('\n', %$hashref{$key})) {
131*4882a593Smuzhiyun		    print $file ($pattern . "\n");
132*4882a593Smuzhiyun		}
133*4882a593Smuzhiyun	    }
134*4882a593Smuzhiyun	}
135*4882a593Smuzhiyun    }
136*4882a593Smuzhiyun    close($file);
137*4882a593Smuzhiyun}
138*4882a593Smuzhiyun
139*4882a593Smuzhiyunsub file_input {
140*4882a593Smuzhiyun    my ($hashref, $filename) = (@_);
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun    my $lastline = "";
143*4882a593Smuzhiyun    my $case = " ";
144*4882a593Smuzhiyun    $$hashref{$case} = "";
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun    open(my $file, '<', "$filename") or die "$P: $filename: open failed - $!\n";
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun    while (<$file>) {
149*4882a593Smuzhiyun        my $line = $_;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun        # Pattern line?
152*4882a593Smuzhiyun        if ($line =~ m/^([A-Z]):\s*(.*)/) {
153*4882a593Smuzhiyun            $line = $1 . ":\t" . trim($2) . "\n";
154*4882a593Smuzhiyun            if ($lastline eq "") {
155*4882a593Smuzhiyun                $$hashref{$case} = $$hashref{$case} . $line;
156*4882a593Smuzhiyun                next;
157*4882a593Smuzhiyun            }
158*4882a593Smuzhiyun            $case = trim($lastline);
159*4882a593Smuzhiyun            exists $$hashref{$case} and die "Header '$case' already exists";
160*4882a593Smuzhiyun            $$hashref{$case} = $line;
161*4882a593Smuzhiyun            $lastline = "";
162*4882a593Smuzhiyun            next;
163*4882a593Smuzhiyun        }
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun        if ($case eq " ") {
166*4882a593Smuzhiyun            $$hashref{$case} = $$hashref{$case} . $lastline;
167*4882a593Smuzhiyun            $lastline = $line;
168*4882a593Smuzhiyun            next;
169*4882a593Smuzhiyun        }
170*4882a593Smuzhiyun        trim($lastline) eq "" or die ("Odd non-pattern line '$lastline' for '$case'");
171*4882a593Smuzhiyun        $lastline = $line;
172*4882a593Smuzhiyun    }
173*4882a593Smuzhiyun    $$hashref{$case} = $$hashref{$case} . $lastline;
174*4882a593Smuzhiyun    close($file);
175*4882a593Smuzhiyun}
176*4882a593Smuzhiyun
177*4882a593Smuzhiyunmy %hash;
178*4882a593Smuzhiyunmy %new_hash;
179*4882a593Smuzhiyun
180*4882a593Smuzhiyunfile_input(\%hash, $input_file);
181*4882a593Smuzhiyun
182*4882a593Smuzhiyunforeach my $type (@ARGV) {
183*4882a593Smuzhiyun    foreach my $key (keys %hash) {
184*4882a593Smuzhiyun	if ($key =~ /$type/ || $hash{$key} =~ /$type/) {
185*4882a593Smuzhiyun	    $new_hash{$key} = $hash{$key};
186*4882a593Smuzhiyun	    delete $hash{$key};
187*4882a593Smuzhiyun	}
188*4882a593Smuzhiyun    }
189*4882a593Smuzhiyun}
190*4882a593Smuzhiyun
191*4882a593Smuzhiyunalpha_output(\%hash, $output_file);
192*4882a593Smuzhiyunalpha_output(\%new_hash, $output_section);
193*4882a593Smuzhiyun
194*4882a593Smuzhiyunexit(0);
195