]>
Commit | Line | Data |
---|---|---|
ff21692c | 1 | #!/usr/bin/perl |
2 | # | |
3 | # Script used to sort kernel-*.config files. | |
4 | # Usage: | |
5 | # ./kernel-config-sort.pl ../BUILD/linux-2.6.*/ kernel-multiarch.config | |
6 | # | |
7 | # ./kernel-config-sort.pl ../BUILD/linux-2.6.*/ -a x86 kernel-x86_84.config | |
8 | # | |
9 | use strict; | |
10 | use warnings; | |
11 | ||
12 | my $dir = ( shift @ARGV ) || "."; | |
13 | my $arch; | |
14 | if ( $ARGV[0] eq "-a" ) { | |
15 | shift @ARGV; | |
16 | $arch = shift @ARGV; | |
17 | } | |
18 | my $old_dir = $ENV{PWD}; | |
19 | chdir $dir; | |
20 | ||
21 | my @Kconfig_list; | |
22 | my @Kconfig_arch; | |
23 | ||
24 | sub look_in | |
25 | { | |
26 | my $parent = shift; | |
27 | my @files = glob $parent."*"; | |
28 | foreach ( @files ) { | |
29 | if ( -d ) { | |
30 | if ( $_ eq "Documentation" or $_ eq "build-done" ) { | |
31 | warn "Skipping $_\n"; | |
32 | next; | |
33 | } | |
34 | look_in( $_ . '/' ); | |
35 | next; | |
36 | } | |
37 | if ( m#^.*/Kconfig# ) { | |
38 | if ( m#^arch/# ) { | |
39 | push @Kconfig_arch, $_; | |
40 | } else { | |
41 | push @Kconfig_list, $_; | |
42 | } | |
43 | } | |
44 | } | |
45 | } | |
46 | ||
47 | if ( $arch ) { | |
48 | push @Kconfig_list, "arch/$arch/Kconfig"; | |
49 | } else { | |
50 | look_in(""); | |
51 | push @Kconfig_list, @Kconfig_arch; | |
52 | } | |
53 | ||
54 | my %byFile; | |
55 | my %byName; | |
56 | ||
57 | sub add_Kconfig | |
58 | { | |
59 | my $file = shift; | |
60 | ||
61 | my @maybe_add_source; | |
62 | my @config_list; | |
63 | ||
64 | unless ( -r $file ) { | |
65 | warn "FILE $file does not exist\n"; | |
66 | return; | |
67 | } | |
68 | ||
69 | open my $f_in, '<', $file; | |
70 | while ( <$f_in> ) { | |
71 | if ( /^\s?(?:menu)?config\s+(.*?)`?\s*$/ ) { | |
72 | if ( $byName{ $1 } ) { | |
73 | warn "Warning: $file: $1 already defined in $byName{ $1 }\n"; | |
74 | next; | |
75 | } | |
76 | push @config_list, [ 'o', $1 ]; | |
77 | next; | |
78 | } | |
79 | if ( /^\s?comment\s+"(.*?)"\s*$/ ) { | |
80 | push @config_list, [ 'c', $1 ]; | |
81 | next; | |
82 | } | |
83 | if ( /^\s*source\s+"(\S+?)"\s*$/ or /^\s*source\s+(\S+?)\s*$/) { | |
84 | push @maybe_add_source, $1; | |
85 | push @config_list, [ 's', $1 ]; | |
86 | next; | |
87 | } | |
88 | } | |
89 | close $f_in; | |
90 | ||
91 | $byFile{ $file } = \@config_list; | |
92 | ||
93 | { | |
94 | my %add; | |
95 | @add{ @maybe_add_source } = (); | |
96 | foreach ( @Kconfig_list ) { | |
97 | delete $add{ $_ } if exists $add{ $_ }; | |
98 | } | |
99 | if ( keys %add ) { | |
100 | #warn "Adding more source files: " . ( join ", ", sort keys %add ) ."\n"; | |
101 | push @Kconfig_list, sort keys %add; | |
102 | } | |
103 | } | |
104 | } | |
105 | ||
106 | { | |
107 | my $i; | |
108 | for ( $i = 0; $i < scalar @Kconfig_list; $i++ ) { | |
109 | my $file = $Kconfig_list[ $i ]; | |
110 | add_Kconfig( $file ); | |
111 | } | |
112 | } | |
113 | ||
114 | my $arch_specific; | |
115 | unless ( $arch ) { | |
116 | my @arch_specific; | |
117 | ||
118 | foreach my $f ( sort keys %byFile ) { | |
119 | next unless $f =~ /^arch/; | |
120 | foreach my $line ( @{ $byFile{ $f } } ) { | |
121 | push @arch_specific, $line->[1] | |
122 | if $line->[0] eq 'o'; | |
123 | } | |
124 | delete $byFile{ $f }; | |
125 | } | |
126 | ||
127 | my @as = map { [ 'o', $_ ] } sort @arch_specific; | |
128 | $arch_specific = \@as; | |
129 | } | |
130 | ||
131 | chdir $old_dir; | |
132 | ||
133 | my $out_file = $ARGV[ $#ARGV ]; | |
134 | ||
135 | my %setOptions; | |
136 | ||
137 | my $allowed_name = qr/[A-Za-z0-9_]+/; | |
138 | my $comment = ""; | |
139 | while ( <> ) { | |
140 | if ( /^#\*/ ) { | |
141 | $comment .= $_; | |
142 | next; | |
143 | } | |
144 | my $opt; | |
145 | if ( /^# CONFIG_($allowed_name) is not set$/ ) { | |
146 | $opt = $1; | |
147 | } | |
148 | if ( /^(?:CONFIG_)?($allowed_name)[=\s]/ ) { | |
149 | $opt = $1; | |
150 | } | |
151 | unless ( $opt ) { | |
152 | if ( /\S/ and !/^#-/ ) { | |
153 | warn "Ignored line: $_"; | |
154 | } | |
155 | next; | |
156 | } | |
157 | ||
158 | if ( exists $setOptions{ $opt } ) { | |
159 | die "OPTION $opt REDEFINED"; | |
160 | } | |
161 | chomp; | |
162 | $setOptions{ $opt } = $comment . $_; | |
163 | $comment = ""; | |
164 | } | |
165 | ||
166 | sub file_out | |
167 | { | |
168 | my $file = shift; | |
169 | my $any_out = 0; | |
170 | my @out; | |
171 | push @out, "#-", "#- *** FILE: $file ***", "#-"; | |
172 | my $file_lines = $byFile{ $file }; | |
173 | ||
174 | foreach my $line ( @{$file_lines} ) { | |
175 | my ($type, $data) = @$line; | |
176 | if ( $type eq 'o' ) { | |
177 | if ( exists $setOptions{ $data } ) { | |
178 | push @out, $setOptions{ $data }; | |
179 | delete $setOptions{ $data }; | |
180 | $any_out = 1; | |
181 | } | |
182 | } elsif ( $type eq 'c' ) { | |
183 | push @out, "#- $data"; | |
184 | } elsif ( $type eq 's' ) { | |
185 | push @out, "#- file $data goes here"; | |
186 | } | |
187 | } | |
188 | if ( $any_out ) { | |
189 | return "\n" . ( join "\n", @out ) . "\n"; | |
190 | } | |
191 | return ""; | |
192 | } | |
193 | ||
194 | *FILE_OUT = \*STDOUT; | |
195 | if ( $out_file ) { | |
196 | open FILE_OUT, '>', $out_file; | |
197 | } | |
198 | unless ( $arch ) { | |
199 | my @out; | |
200 | foreach my $f ( sort keys %byFile ) { | |
201 | push @out, file_out( $f ); | |
202 | } | |
203 | ||
204 | my $as_name = "arch/* - ARCH SPECIFIC OPTIONS"; | |
205 | $byFile{ $as_name } = $arch_specific; | |
206 | unshift @out, file_out( $as_name ); | |
207 | ||
208 | print FILE_OUT @out; | |
209 | } else { | |
210 | foreach my $f ( sort keys %byFile ) { | |
211 | print FILE_OUT file_out( $f ); | |
212 | } | |
213 | } | |
214 | ||
215 | if ( keys %setOptions ) { | |
216 | print FILE_OUT "\n#-\n#- *** PROBABLY REMOVED OPTIONS ***\n#-\n"; | |
217 | foreach my $k ( sort keys %setOptions ) { | |
218 | print FILE_OUT $setOptions{ $k } . "\n"; | |
219 | } | |
220 | } |