blob: 64b40e986cef673aa1085763ca66afb38399ae05 [file] [log] [blame]
Richard S. Hall6fe36b42009-07-13 13:25:46 +00001#!/usr/bin/env perl
2
3# Licensed to the Apache Software Foundation (ASF) under one
4# or more contributor license agreements. See the NOTICE file
5# distributed with this work for additional information
6# regarding copyright ownership. The ASF licenses this file
7# to you under the Apache License, Version 2.0 (the
8# "License"); you may not use this file except in compliance
9# with the License. You may obtain a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing,
14# software distributed under the License is distributed on an
15# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16# KIND, either express or implied. See the License for the
17# specific language governing permissions and limitations
18# under the License.
19
20use FileHandle;
21
22my $dryrun = 0;
23my $quiet = 0;
24
25#
26# Usage: notice.pl [-n] [-q] files...
27#
28
29my $NOTICE = <<'EOT';
30Licensed to the Apache Software Foundation (ASF) under one
31or more contributor license agreements. See the NOTICE file
32distributed with this work for additional information
33regarding copyright ownership. The ASF licenses this file
34to you under the Apache License, Version 2.0 (the
35"License"); you may not use this file except in compliance
36with the License. You may obtain a copy of the License at
37
38 http://www.apache.org/licenses/LICENSE-2.0
39
40Unless required by applicable law or agreed to in writing,
41software distributed under the License is distributed on an
42"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
43KIND, either express or implied. See the License for the
44specific language governing permissions and limitations
45under the License.
46EOT
47
48# Note: source code notices must not be changed by code formatter
49
50my $NOTICE_java = $NOTICE;
51$NOTICE_java =~ s/^/ * /gm;
52$NOTICE_java = "/*\n" . $NOTICE_java . " */\n\n";
53
54my $NOTICE_xml = $NOTICE;
55$NOTICE_xml =~ s/^/ /gm;
56$NOTICE_xml = "<!--\n" . $NOTICE_xml . "-->\n";
57
58my $NOTICE_sh = $NOTICE;
59$NOTICE_sh =~ s/^/# /gm;
60
61my $NOTICE_bat = $NOTICE;
62$NOTICE_bat =~ s/^/:: /gm;
63
64sub addNotice {
65 my ($fh, $file, $notice) = @_;
66 print "$file\n";
67
68 return if ($dryrun);
69
70 my $tmp = "$file.tmp";
71 my $fh2 = new FileHandle(">$tmp");
72
73 print $fh2 $notice;
74 while (<$fh>) {
75 print $fh2 $_;
76 }
77
78 unlink($file);
79 rename($tmp, $file);
80}
81
82#
83# locate existing copyright & license
84# starts at top of file
85# ends at "package" statement
86#
87sub notice_java {
88 my $file = shift;
89 my $fh = new FileHandle($file);
90 my $header;
91 my $package = undef;
92
93 while (<$fh>) {
94 if (/^package\s+[\w.]+\s*;/) {
95 $package = $_;
96 last;
97 }
98 last if ($. > 200);
99 $header .= $_;
100 }
101
102 if (! $package) {
103 print STDERR "$file: ERROR: no package statement.\n";
104 return;
105 }
106
107 return if ($header eq $NOTICE_java);
108
109 # completely replace all before package statement
110 # so DON'T change below, without changing above
111 # to stop at end-of-first-comment.
112 $header = '';
113 #$header = '' if ($header =~ /copyright/im);
114 #$header = "\n" . $header unless ($header =~ /^\n/);
115
116 addNotice($fh, $file, $NOTICE_java . $header . $package);
117}
118
119sub notice_xml {
120 my $file = shift;
121 my $fh = new FileHandle($file);
122 my $header = undef;
123 my $decl = qq(<?xml version="1.0"?>\n);
124 my $end = 0;
125 my $start = 0;
126
127 while (<$fh>) {
128 if ($. == 1 && /^\<\?/) {
129 $decl = $_;
130 next;
131 }
132
133 $header .= $_;
134
135 if (!$start) {
136 last unless (/^<!--/);
137 $start = 1;
138 }
139
140 if (/-->/) {
141 $end = 1;
142 last;
143 }
144 }
145
146 return if ($header eq $NOTICE_xml);
147
148 $header = '' if ($header =~ /copyright/im);
149
150 if ($start && !$end) {
151 print STDERR "$file: ERROR: initial comment not terminated.\n";
152 return;
153 }
154
155 addNotice($fh, $file, $decl . $NOTICE_xml . $header);
156}
157
158sub notice_sh {
159 my $file = shift;
160 my $fh = new FileHandle($file);
161 my $header = undef;
162 my $hashbang = undef;
163 my $end = '';
164 my $start = '';
165
166 while (<$fh>) {
167 if ($. == 1 && /^#!/) {
168 $hashbang = $_;
169 next;
170 }
171
172 if (!$start) {
173 unless (/^(#|\s*$)/) {
174 $header = $_;
175 last;
176 }
177 $start = 1;
178 next if (/^\s*$/);
179 }
180
181 if (!/^#/) {
182 $end = $_;
183 last;
184 }
185
186 $header .= $_;
187 }
188
189 return if ($header eq $NOTICE_sh);
190
191 $hashbang .= "\n" if ($hashbang);
192
193 $header = '' if ($header =~ /copyright/im);
194 $header .= $end;
195 $header = "\n" . $header unless ($header =~ /^\n/);
196
197 if ($start && !$end) {
198 print STDERR "$file: ERROR: initial comment not terminated.\n";
199 return;
200 }
201
202 addNotice($fh, $file, $hashbang . $NOTICE_sh . $header);
203}
204
205sub notice_bat {
206 my $file = shift;
207 my $fh = new FileHandle($file);
208 my $header = undef;
209 my $atecho = undef;
210 my $end = '';
211 my $start = '';
212
213 while (<$fh>) {
214 s/\r\n$/\n/;
215 if ($. == 1 && /^\@echo/) {
216 $atecho = $_;
217 next;
218 }
219
220 if (!$start) {
221 unless (/^(::|\s*$)/) {
222 $header = $_;
223 last;
224 }
225 $start = 1;
226 next if (/^\s*$/);
227 }
228
229 if (!/^::/) {
230 $end = $_;
231 last;
232 }
233
234 $header .= $_;
235 }
236
237 return if ($header eq $NOTICE_bat);
238
239 $atecho .= "\n" if ($atecho);
240
241 $header = '' if ($header =~ /copyright/im);
242 $header .= $end;
243 $header = "\n" . $header unless ($header =~ /^\n/);
244
245 if ($start && !$end) {
246 print STDERR "$file: ERROR: initial comment not terminated.\n";
247 return;
248 }
249
250 $header = $atecho . $NOTICE_bat . $header;
251 $header =~ s/\n/\r\n/mg;
252 addNotice($fh, $file, $header);
253}
254
255sub notice_unknown {
256 my $file = shift;
257 my $fh = new FileHandle($file);
258
259 my $line = <$fh>;
260
261 if ($line =~ /^#!/) {
262 notice_sh($file);
263 }
264 elsif ($line =~ /^\<\?xml/) {
265 notice_xml($file);
266 }
267 elsif (! $quiet) {
268 print STDERR "$file: unknown file type.\n";
269 }
270}
271
272foreach my $f (@ARGV) {
273 if ($f eq '-n') {
274 $dryrun++;
275 }
276 elsif ($f eq '-q') {
277 $quiet++;
278 }
279 elsif ($f =~ /\.java$/) {
280 notice_java($f);
281 }
282 elsif ($f =~ /\.(xml|xsd|system|composite)$/) {
283 notice_xml($f);
284 }
285 elsif ($f =~ /\.(sh|app|ini|xargs)$/) {
286 notice_sh($f);
287 }
288 elsif ($f =~ /\.(bat)$/) {
289 notice_bat($f);
290 }
291 else {
292 notice_unknown($f);
293 }
294}
295