|
1 @rem |
|
2 @rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 @rem All rights reserved. |
|
4 @rem This component and the accompanying materials are made available |
|
5 @rem under the terms of "Eclipse Public License v1.0" |
|
6 @rem which accompanies this distribution, and is available |
|
7 @rem at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 @rem |
|
9 @rem Initial Contributors: |
|
10 @rem Nokia Corporation - initial contribution. |
|
11 @rem |
|
12 @rem Contributors: |
|
13 @rem |
|
14 @rem Description: |
|
15 @rem |
|
16 @rem = '--*-Perl-*-- |
|
17 @echo off |
|
18 if "%OS%" == "Windows_NT" goto WinNT |
|
19 perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9 |
|
20 goto endofperl |
|
21 :WinNT |
|
22 perl -x -S "%0" %* |
|
23 if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endofperl |
|
24 if %errorlevel% == 9009 echo You do not have Perl in your PATH. |
|
25 goto endofperl |
|
26 @rem '; |
|
27 #!perl |
|
28 #line 14 |
|
29 |
|
30 |
|
31 use Getopt::Long; |
|
32 use File::Spec; |
|
33 use File::Copy; |
|
34 use File::Path; |
|
35 use File::Basename; |
|
36 |
|
37 my $toolVersion = "2.1"; |
|
38 |
|
39 # Example warnings: |
|
40 # |
|
41 # Incorrect slash |
|
42 # \src\common\generic\comms-infras\commsfw\group\bld.inf:10: Incorrect slash in PRJ_EXPORTS - '..\inc\commschan.h'. |
|
43 # \src\cedar\generic\base\f32\group\ecomp.mmp:14: Incorrect slash in SYSTEMINCLUDE - '..\inc'. |
|
44 # \src\common\generic\syncml\framework\TransportProvision\HttpWsp\SmlHttpBase.cpp:13: Incorrect slash in #include - 'http\rhttpheaders.h'. |
|
45 # |
|
46 # Incorrect case for epoc32 tree |
|
47 # \src\common\generic\syslibs\pwrcli\group\bld.inf:23: Incorrect case for epoc32 tree in PRJ_EXPORTS - '\epoc32\rom\include\PwrCli.IBY'. |
|
48 # \src\common\generic\security\crypto\group\hash.mmp:8: Incorrect case for epoc32 tree in TARGET - 'hash.DLL'. |
|
49 # \src\common\generic\syslibs\ecom\ongoing\Framework\frame\Discoverer.cpp:20: Incorrect case for epoc32 tree in #include - 'BaSPI.h'. |
|
50 # |
|
51 # Incorrect case versus filesystem |
|
52 # \src\common\generic\comms-infras\commdb\commdbshim\group\BLD.INF:20: Incorrect case versus filesystem in PRJ_EXPORTS - '..\inc\cdblen.h' vs. \src\common\generic\comms-infras\commdb\commdbshim\INC\CDBLEN.H. |
|
53 # \src\common\generic\syslibs\ecom\ongoing\Framework\MMPFiles\EComServer.mmp:45: Incorrect case versus filesystem in USERINCLUDE - '..\..\framework\inc' vs. \src\common\generic\syslibs\ecom\ongoing\Framework\inc. |
|
54 # \src\common\generic\comms-infras\commdb\commdbshim\INC\CDBOVER.H:16: Incorrect case versus filesystem in #include - 'cdbpreftable.h' vs. \src\common\generic\comms-infras\commdb\commdbshim\INC\CDBPREFTABLE.H. |
|
55 # |
|
56 # Incorrect case for epoc32 tree from default export (i.e. source export case will replicated under \epoc32) |
|
57 # \src\common\generic\application-protocols\http\group\bld.inf:22: Incorrect case for epoc32 tree from default export in PRJ_EXPORTS - '..\inc\HTTPSocketConstants.h'. |
|
58 # \src\common\generic\messaging\email\smtpservermtm\group\bld.inf:11: Incorrect case for epoc32 tree from default export in PRJ_EXPORTS - '..\inc\smts.h' vs. \src\common\generic\messaging\email\smtpservermtm\inc\SMTS.H. |
|
59 # |
|
60 # Incorrect case versus exclusion list |
|
61 # \src\common\generic\Multimedia\openmax\group\bld.inf:14: Incorrect case versus exclusion list in PRJ_EXPORTS - '\epoc32\include\openmax\il\OMX_Types.h' vs. OMX_TYPES.H. |
|
62 # \src\common\generic\Multimedia\openmax\inc\openmax\il\OMX_Audio.h:41: Incorrect case versus exclusion list in #include - 'OMX_Types.h' vs. OMX_TYPES.H. |
|
63 # |
|
64 # Can't find physical file match for |
|
65 # \src\common\generic\app-framework\conarc\group\BLD.INF:48: Can't find physical file match for PRJ_TESTMMPFILES MMP - '..\tsrc\tcon3_V2.mpp' on filesystem. |
|
66 # |
|
67 |
|
68 |
|
69 # 1. Check arguments, output help etc. |
|
70 |
|
71 my $analyse = 0; |
|
72 my $list = 0; |
|
73 my $update = 0; |
|
74 my $warnings = ""; |
|
75 my $verbose = 0; |
|
76 my $debug = 0; |
|
77 my $debugUpdate = 0; |
|
78 GetOptions ('analyse|a' => \$analyse, 'list|l' => \$list, 'update|u' => \$update, 'warnings|w=s' => \$warnings, |
|
79 'verbose|v' => \$verbose, 'debug|d' => \$debug, 'debugupdate|du' => \$debugUpdate); |
|
80 |
|
81 if (@ARGV == 0) |
|
82 { |
|
83 print (STDERR "\nFIXSOURCE.BAT - Version $toolVersion\n"); |
|
84 |
|
85 print STDERR << 'END_OF_HELP'; |
|
86 |
|
87 Usage: fixsource.bat -analyse|-list|-update|-warnings buildlog_1.log [buildlog_n.log] |
|
88 |
|
89 Parses the output from the specified build logs to locate warnings produced via |
|
90 "abld -checksource". Provides the option to update source automatically to comply |
|
91 with Symbian's Filename Policy. |
|
92 |
|
93 -analyse | -a List and describe all warnings that cannot be addressed |
|
94 by this tool. |
|
95 -list | -l List all source files that can be updated by this tool |
|
96 using "-update". |
|
97 -update | -u Update source files, as output by "-list", to comply with |
|
98 Symbian's Filename Policy. |
|
99 -warnings| -w [all|fixable] Output all unique "-checksource" warnings present in the |
|
100 specified logs: |
|
101 all - every warning, regardless of whether this |
|
102 tool can fix them. |
|
103 fixable - only warnings that this tool can fix. |
|
104 -verbose | -v Additional verbose output for the "-update" option. |
|
105 |
|
106 NOTES: |
|
107 * The tool assumes that the original build source and layout is present on the drive |
|
108 where it is being executed. |
|
109 * With the exception of the "-warnings all" output, any warnings for files under the |
|
110 known release and build locations of %EPOCROOT%epoc32\include and |
|
111 %EPOCROOT%epoc32\build are discarded by default. |
|
112 |
|
113 END_OF_HELP |
|
114 |
|
115 } |
|
116 |
|
117 |
|
118 # 2. Parse the logs storing all GNU format warnings and errors |
|
119 |
|
120 |
|
121 my %ActionableFilenamePolicyWarnings; # Hash Key (filename) |
|
122 # Hash Key (line number) |
|
123 # Hash Key (problematic text) |
|
124 # Hash Key ORIGINAL_WARNINGS |
|
125 # Hash Key (original warning) |
|
126 # 1 |
|
127 # Hash Key ITEM |
|
128 # item type that has generated the warning |
|
129 # Hash Key SEARCH_TEXT |
|
130 # quotemeta version of problematic text |
|
131 # Hash Key UNIX_SLASH |
|
132 # 1 |
|
133 # Hash Key LOWERCASE |
|
134 # 1 |
|
135 # Hash Key PHYSICAL |
|
136 # 1 |
|
137 # Hash Key EXCLUSION |
|
138 # 1 |
|
139 # Hash Key PHYSICAL_REALITY |
|
140 # Hash Key (physical reality) |
|
141 # 1 |
|
142 # fully pathed filesystem reality used in physical checking |
|
143 # Hash Key EXCLUSION_LISTING |
|
144 # required format of reference as dictated from an exclusion list |
|
145 # Hash Key ACTUAL_TEST |
|
146 # test used for check when this differed from that in actual source |
|
147 # Hash Key DEFAULT_EXPORT |
|
148 # special case - a PRJ_EXPORTS line without a destination will break |
|
149 # the filename policy if the source line is not lowercase |
|
150 my %NonActionableFilenamePolicyWarnings; |
|
151 my %AllFilenamePolicyWarnings; |
|
152 my %OtherWarningsAndErrors; |
|
153 |
|
154 foreach my $BUILD_LOG (@ARGV) |
|
155 { |
|
156 open BUILD_LOG, "< $BUILD_LOG" or die "\nCannot read \"$BUILD_LOG\"!\n\n"; |
|
157 |
|
158 while (<BUILD_LOG>) |
|
159 { |
|
160 chomp; |
|
161 |
|
162 if (/^\\\S+:.*: .+$/) |
|
163 { |
|
164 if (!/:\d+: (Incorrect case|Incorrect slash|Can\'t find) /) |
|
165 { |
|
166 $OtherWarningsAndErrors{$_} = 1 if (!/(unresolved api-item|unknown base class|unresolved xref|no image file|xm-replace_text)/); # Ignore the noise of doc stuff... |
|
167 next; |
|
168 } |
|
169 |
|
170 $AllFilenamePolicyWarnings{$_} = 1; |
|
171 |
|
172 if (/: Can\'t find /) |
|
173 { |
|
174 $NonActionableFilenamePolicyWarnings{$_} = 1; |
|
175 next; |
|
176 } |
|
177 |
|
178 my $originalWarning = $_; |
|
179 |
|
180 /(^.*):(\d+): Incorrect (case for epoc32 tree|case versus filesystem|case versus exclusion list|slash|case for epoc32 tree from default export) in (.+) - \'(.+?)\'/; |
|
181 |
|
182 my $filename = $1; |
|
183 my $lineNumber = $2; |
|
184 my $type = $3; |
|
185 my $item = $4; |
|
186 my $problematicText = $5; |
|
187 |
|
188 $type =~ s/case for epoc32 tree from default export/defaultexport/; |
|
189 $type =~ s/case for epoc32 tree/lowercase/; |
|
190 $type =~ s/case versus filesystem/physical/; |
|
191 $type =~ s/case versus exclusion list/exclusion/; |
|
192 |
|
193 my $actualTest = ""; |
|
194 my $physicalReality = ""; |
|
195 my $exclusionListing = ""; |
|
196 $actualTest = $1 if (/\(actual test \'(.*)\'\)/); |
|
197 |
|
198 if (/ vs\. (.*)\./) |
|
199 { |
|
200 $physicalReality = $1 if ($type eq "physical"); |
|
201 $exclusionListing = $1 if ($type eq "exclusion"); |
|
202 } |
|
203 |
|
204 if ($debug) |
|
205 { |
|
206 print ("ORIGINAL WARNING : $originalWarning\n"); |
|
207 print ("FILENAME : $filename\n"); |
|
208 print ("LINENUMBER : $lineNumber\n"); |
|
209 print ("TYPE : $type\n"); |
|
210 print ("ITEM : $item\n"); |
|
211 print ("PROBLEMATIC TEXT : $problematicText\n"); |
|
212 print ("ACTUAL TEST : $actualTest\n") if ($actualTest); |
|
213 print ("PHYSICAL REALITY : $physicalReality\n") if ($physicalReality); |
|
214 print ("EXCLUSION LISTING : $exclusionListing\n") if ($exclusionListing); |
|
215 print ("\n"); |
|
216 } |
|
217 |
|
218 next if ($warnings =~ /all/i); |
|
219 |
|
220 # Line Number |
|
221 |
|
222 my $lineNumberHashRef; |
|
223 if ($ActionableFilenamePolicyWarnings{$filename}) |
|
224 { |
|
225 $lineNumberHashRef = $ActionableFilenamePolicyWarnings{$filename}; |
|
226 } |
|
227 else |
|
228 { |
|
229 my %newHash; |
|
230 $lineNumberHashRef = \%newHash; |
|
231 $ActionableFilenamePolicyWarnings{$filename} = $lineNumberHashRef; |
|
232 } |
|
233 |
|
234 # Problematic Text |
|
235 |
|
236 my $problematicTextHashRef; |
|
237 if ($lineNumberHashRef->{$lineNumber}) |
|
238 { |
|
239 $problematicTextHashRef = $lineNumberHashRef->{$lineNumber}; |
|
240 } |
|
241 else |
|
242 { |
|
243 my %newHash; |
|
244 $problematicTextHashRef = \%newHash; |
|
245 $lineNumberHashRef->{$lineNumber} = $problematicTextHashRef; |
|
246 } |
|
247 |
|
248 # Attributes |
|
249 |
|
250 my $attributesHashRef; |
|
251 if ($problematicTextHashRef->{$problematicText}) |
|
252 { |
|
253 $attributesHashRef = $problematicTextHashRef->{$problematicText}; |
|
254 } |
|
255 else |
|
256 { |
|
257 my %newHash; |
|
258 $attributesHashRef = \%newHash; |
|
259 $problematicTextHashRef->{$problematicText} = $attributesHashRef; |
|
260 } |
|
261 |
|
262 # Attributes : Original Warnings |
|
263 |
|
264 my $originalWarningsHashRef; |
|
265 if ($attributesHashRef->{ORIGINAL_WARNINGS}) |
|
266 { |
|
267 $originalWarningsHashRef = $attributesHashRef->{ORIGINAL_WARNINGS}; |
|
268 } |
|
269 else |
|
270 { |
|
271 my %newHash; |
|
272 $originalWarningsHashRef = \%newHash; |
|
273 $attributesHashRef->{ORIGINAL_WARNINGS} = $originalWarningsHashRef; |
|
274 } |
|
275 $originalWarningsHashRef->{$originalWarning} = 1; |
|
276 |
|
277 # Attributes : Item |
|
278 |
|
279 $attributesHashRef->{ITEM} = $item; |
|
280 |
|
281 # Attributes : Search Text |
|
282 |
|
283 $attributesHashRef->{SEARCH_TEXT} = quotemeta ($problematicText); |
|
284 |
|
285 # Attributes : Unix Slash |
|
286 |
|
287 $attributesHashRef->{UNIX_SLASH} = 1 if ($type eq "slash"); |
|
288 |
|
289 # Attributes : Lowercase |
|
290 |
|
291 $attributesHashRef->{LOWERCASE} = 1 if ($type eq "lowercase"); |
|
292 |
|
293 # Attributes : Physical |
|
294 |
|
295 $attributesHashRef->{PHYSICAL} = 1 if ($type eq "physical"); |
|
296 |
|
297 # Attributes : Exclusion |
|
298 |
|
299 $attributesHashRef->{EXCLUSION} = 1 if ($type eq "exclusion"); |
|
300 |
|
301 # Attributes : Physical Reality |
|
302 |
|
303 my $physicalRealityHashRef; |
|
304 if ($physicalReality) |
|
305 { |
|
306 if ($attributesHashRef->{PHYSICAL_REALITY}) |
|
307 { |
|
308 $physicalRealityHashRef = $attributesHashRef->{PHYSICAL_REALITY}; |
|
309 } |
|
310 else |
|
311 { |
|
312 my %newHash; |
|
313 $physicalRealityHashRef = \%newHash; |
|
314 $attributesHashRef->{PHYSICAL_REALITY} = $physicalRealityHashRef; |
|
315 } |
|
316 $physicalRealityHashRef->{$physicalReality} = 1; |
|
317 } |
|
318 |
|
319 # Attributes : Actual Test |
|
320 |
|
321 $attributesHashRef->{ACTUAL_TEST} = $actualTest if ($actualTest); |
|
322 |
|
323 # Attributes : Exclusion Listing |
|
324 |
|
325 $attributesHashRef->{EXCLUSION_LISTING} = $exclusionListing if ($exclusionListing); |
|
326 |
|
327 # Attributes : Default Export |
|
328 |
|
329 $attributesHashRef->{DEFAULT_EXPORT} = 1 if ($type eq "defaultexport"); |
|
330 } |
|
331 } |
|
332 |
|
333 close BUILD_LOG; |
|
334 } |
|
335 |
|
336 |
|
337 # 3. Examine source and warnings and compile lists of files and warnings that we can/can't do anything about |
|
338 |
|
339 my %WarningsNotMatchingSource; |
|
340 my %WarningsWithMissingFiles; |
|
341 my %WarningsForBothLowercaseAndPhysicalOnSameReference; |
|
342 my %WarningsForMultiplePhysicalUpdates; |
|
343 |
|
344 |
|
345 if ($analyse || $list || $update || $debugUpdate || $warnings =~ /^fixable$/i) |
|
346 { |
|
347 |
|
348 foreach my $SOURCE_FILE (sort keys %ActionableFilenamePolicyWarnings) |
|
349 { |
|
350 |
|
351 # Discard anything in known release locations |
|
352 |
|
353 if ($SOURCE_FILE =~ /\\epoc32\\(include|build)\\/i) |
|
354 { |
|
355 delete ($ActionableFilenamePolicyWarnings{$SOURCE_FILE}); |
|
356 next; |
|
357 } |
|
358 |
|
359 my $lineNumbersHashRef = $ActionableFilenamePolicyWarnings{$SOURCE_FILE}; |
|
360 |
|
361 # Discard warnings where source files cannot be found |
|
362 |
|
363 if (!(open SOURCE_FILE, "< $SOURCE_FILE")) |
|
364 { |
|
365 foreach my $lineNumber (sort keys (%$lineNumbersHashRef)) |
|
366 { |
|
367 my $problematicTextHashRef = $lineNumbersHashRef->{$lineNumber}; |
|
368 |
|
369 foreach my $problematicText (sort keys (%$problematicTextHashRef)) |
|
370 { |
|
371 my $attributesHashRef = $problematicTextHashRef->{$problematicText}; |
|
372 my $originalWarningsHashRef = $attributesHashRef->{ORIGINAL_WARNINGS}; |
|
373 |
|
374 foreach my $originalWarning (keys (%$originalWarningsHashRef)) |
|
375 { |
|
376 $WarningsWithMissingFiles{$originalWarning} = 1; |
|
377 } |
|
378 } |
|
379 } |
|
380 delete ($ActionableFilenamePolicyWarnings{$SOURCE_FILE}); |
|
381 next; |
|
382 } |
|
383 |
|
384 |
|
385 # Identify and discard warnings where, for the same reference: |
|
386 # (a) both lowercase and physical warnings are flagged and |
|
387 # (b) multiple, different, filesystem matches have been found |
|
388 # These will need to be resolved manually |
|
389 |
|
390 foreach my $lineNumber (sort keys (%$lineNumbersHashRef)) |
|
391 { |
|
392 my $problematicTextHashRef = $lineNumbersHashRef->{$lineNumber}; |
|
393 |
|
394 foreach my $problematicText (sort keys (%$problematicTextHashRef)) |
|
395 { |
|
396 my $attributesHashRef = $problematicTextHashRef->{$problematicText}; |
|
397 my $originalWarningsHashRef = $attributesHashRef->{ORIGINAL_WARNINGS}; |
|
398 |
|
399 my $skipPhysicalUpdate = 0; |
|
400 my $skipLowercaseUpdate = 0; |
|
401 |
|
402 if ($attributesHashRef->{LOWERCASE} && $attributesHashRef->{PHYSICAL}) |
|
403 { |
|
404 $skipPhysicalUpdate = 1; |
|
405 $skipLowercaseUpdate = 1; |
|
406 |
|
407 foreach my $originalWarning (keys %{$originalWarningsHashRef}) |
|
408 { |
|
409 next if ($originalWarning !~ /Incorrect case/); |
|
410 |
|
411 $originalWarning =~ /\:(.*$)/; |
|
412 |
|
413 my $lowercaseAndPhysicalWarningsHashRef; |
|
414 if ($WarningsForBothLowercaseAndPhysicalOnSameReference{$SOURCE_FILE}) |
|
415 { |
|
416 $lowercaseAndPhysicalWarningsHashRef = $WarningsForBothLowercaseAndPhysicalOnSameReference{$SOURCE_FILE}; |
|
417 } |
|
418 else |
|
419 { |
|
420 my %newHash; |
|
421 $lowercaseAndPhysicalWarningsHashRef = \%newHash; |
|
422 $WarningsForBothLowercaseAndPhysicalOnSameReference{$SOURCE_FILE} = $lowercaseAndPhysicalWarningsHashRef; |
|
423 } |
|
424 $lowercaseAndPhysicalWarningsHashRef->{$1} = 1; |
|
425 } |
|
426 } |
|
427 |
|
428 my $physicalRealityHashRef = $attributesHashRef->{PHYSICAL_REALITY}; |
|
429 |
|
430 if ($physicalRealityHashRef && ((keys %{$physicalRealityHashRef}) > 1)) |
|
431 { |
|
432 my $physicalMatchCheck; |
|
433 if ($attributesHashRef->{ACTUAL_TEST}) |
|
434 { |
|
435 $physicalMatchCheck = $attributesHashRef->{ACTUAL_TEST}; |
|
436 } |
|
437 else |
|
438 { |
|
439 $physicalMatchCheck = $problematicText; |
|
440 $physicalMatchCheck =~ s/\.\.[\\|\/]//g; |
|
441 $physicalMatchCheck =~ s/\.[\\|\/]//g; |
|
442 } |
|
443 |
|
444 $physicalMatchCheck =~ s/\\\\/\\/g; |
|
445 $physicalMatchCheck =~ s/\/\//\//g; |
|
446 $physicalMatchCheck =~ s/\//\\/g; |
|
447 $physicalMatchCheck = quotemeta($physicalMatchCheck); |
|
448 $physicalMatchCheck =~ s/\\\*/\\w\+/g; # * -> \w+ |
|
449 $physicalMatchCheck =~ s/\\\?/\\w\{1\}/g; # ? -> \w{1} |
|
450 |
|
451 my %normalisedPhysicalReferences; |
|
452 |
|
453 foreach my $physicalReality (keys %{$physicalRealityHashRef}) |
|
454 { |
|
455 $physicalReality =~ /($physicalMatchCheck)$/i; |
|
456 $normalisedPhysicalReferences{$1} = 1; |
|
457 } |
|
458 |
|
459 if ((keys (%normalisedPhysicalReferences)) > 1) |
|
460 { |
|
461 foreach my $originalWarning (keys %{$originalWarningsHashRef}) |
|
462 { |
|
463 next if ($originalWarning !~ /Incorrect case versus/); |
|
464 |
|
465 $originalWarning =~ /\:(.*$)/; |
|
466 |
|
467 my $multiplePhysicalWarningsHashRef; |
|
468 if ($WarningsForMultiplePhysicalUpdates{$SOURCE_FILE}) |
|
469 { |
|
470 $multiplePhysicalWarningsHashRef = $WarningsForMultiplePhysicalUpdates{$SOURCE_FILE}; |
|
471 } |
|
472 else |
|
473 { |
|
474 my %newHash; |
|
475 $multiplePhysicalWarningsHashRef = \%newHash; |
|
476 $WarningsForMultiplePhysicalUpdates{$SOURCE_FILE} = $multiplePhysicalWarningsHashRef; |
|
477 } |
|
478 $multiplePhysicalWarningsHashRef->{$1} = 1; |
|
479 } |
|
480 $skipPhysicalUpdate = 1; |
|
481 } |
|
482 } |
|
483 |
|
484 $attributesHashRef->{LOWERCASE} = 0 if ($skipLowercaseUpdate); |
|
485 $attributesHashRef->{PHYSICAL} = 0 if ($skipPhysicalUpdate); |
|
486 |
|
487 if (!$attributesHashRef->{LOWERCASE} && !$attributesHashRef->{PHYSICAL} && |
|
488 !$attributesHashRef->{UNIX_SLASH} && !$attributesHashRef->{DEFAULT_EXPORT} && |
|
489 !$attributesHashRef->{EXCLUSION}) |
|
490 { |
|
491 delete ($problematicTextHashRef->{$problematicText}); |
|
492 } |
|
493 } |
|
494 |
|
495 delete ($lineNumbersHashRef->{$lineNumber}) if (!scalar (keys %{$problematicTextHashRef})); |
|
496 } |
|
497 |
|
498 my $lineNumber = 0; |
|
499 |
|
500 while (my $line = <SOURCE_FILE>) |
|
501 { |
|
502 $lineNumber++; |
|
503 |
|
504 next if (!($lineNumbersHashRef->{$lineNumber})); |
|
505 |
|
506 my $problematicTextHashRef = $lineNumbersHashRef->{$lineNumber}; |
|
507 |
|
508 foreach my $text (keys %{$problematicTextHashRef}) |
|
509 { |
|
510 my $attributesHashRef = $problematicTextHashRef->{$text}; |
|
511 |
|
512 chomp ($line); |
|
513 |
|
514 if ($line !~ /(\"|\<|^|\s){1}$attributesHashRef->{SEARCH_TEXT}/) |
|
515 { |
|
516 # Put warning(s) onto the failed list, as we can't find the required text |
|
517 # in the source present on the machine |
|
518 |
|
519 my $originalWarningsHashRef = $attributesHashRef->{ORIGINAL_WARNINGS}; |
|
520 foreach my $originalWarning (keys %{$originalWarningsHashRef}) |
|
521 { |
|
522 $WarningsNotMatchingSource{$originalWarning} = $line; |
|
523 } |
|
524 |
|
525 delete ($problematicTextHashRef->{$text}); |
|
526 } |
|
527 } |
|
528 |
|
529 delete ($lineNumbersHashRef->{$lineNumber}) if (!scalar (keys %{$problematicTextHashRef})); |
|
530 } |
|
531 |
|
532 delete ($ActionableFilenamePolicyWarnings{$SOURCE_FILE}) if (!scalar (keys %{$lineNumbersHashRef})); |
|
533 close SOURCE_FILE; |
|
534 } |
|
535 } |
|
536 |
|
537 |
|
538 # 4. Provide -warnings [all|fixable] output |
|
539 |
|
540 if ($warnings =~ /^all$/i) |
|
541 { |
|
542 foreach my $warning (sort keys %AllFilenamePolicyWarnings) |
|
543 { |
|
544 print ("$warning\n"); |
|
545 } |
|
546 } |
|
547 elsif ($warnings =~ /^fixable$/i) |
|
548 { |
|
549 my %fixableWarnings; |
|
550 |
|
551 foreach my $sourceFile (keys %ActionableFilenamePolicyWarnings) |
|
552 { |
|
553 my $lineNumbersHashRef = $ActionableFilenamePolicyWarnings{$sourceFile}; |
|
554 |
|
555 foreach my $lineNumber (keys (%$lineNumbersHashRef)) |
|
556 { |
|
557 my $problematicTextHashRef = $lineNumbersHashRef->{$lineNumber}; |
|
558 |
|
559 foreach my $text (keys %{$problematicTextHashRef}) |
|
560 { |
|
561 my $attributesHashRef = $problematicTextHashRef->{$text}; |
|
562 my $originalWarningsHashRef = $attributesHashRef->{ORIGINAL_WARNINGS}; |
|
563 |
|
564 foreach my $originalWarning (keys %{$originalWarningsHashRef}) |
|
565 { |
|
566 $fixableWarnings{$originalWarning} = 1; |
|
567 } |
|
568 } |
|
569 } |
|
570 } |
|
571 |
|
572 foreach my $fixableWarning (sort keys %fixableWarnings) |
|
573 { |
|
574 print ("$fixableWarning\n"); |
|
575 } |
|
576 } |
|
577 |
|
578 |
|
579 # 5. Provide -list output |
|
580 |
|
581 if ($list) |
|
582 { |
|
583 foreach my $sourceFile (sort keys %ActionableFilenamePolicyWarnings) |
|
584 { |
|
585 print ("$sourceFile\n"); |
|
586 } |
|
587 } |
|
588 |
|
589 |
|
590 # 6. Provide -analyse output |
|
591 |
|
592 if ($analyse) |
|
593 { |
|
594 print ("\nFilename policy warnings with missing files\n". |
|
595 "-------------------------------------------\n\n"); |
|
596 foreach my $warningWithMissingFile (sort keys %WarningsWithMissingFiles) |
|
597 { |
|
598 print ("$warningWithMissingFile\n"); |
|
599 } |
|
600 print ("NONE\n") if (!scalar (keys %WarningsWithMissingFiles)); |
|
601 |
|
602 |
|
603 print ("\n\nFilename policy warnings that don't match source\n". |
|
604 "------------------------------------------------\n\n"); |
|
605 foreach my $warningNotMatchingSource (sort keys %WarningsNotMatchingSource) |
|
606 { |
|
607 print ("$warningNotMatchingSource\n"); |
|
608 print ("\tACTUAL LINE : \'$WarningsNotMatchingSource{$warningNotMatchingSource}\'\n"); |
|
609 } |
|
610 print ("NONE\n") if (!scalar (keys %WarningsNotMatchingSource)); |
|
611 |
|
612 print ("\n\nFilename policy warnings with both lowercase and physical warnings for the same reference\n". |
|
613 "-----------------------------------------------------------------------------------------\n\n"); |
|
614 foreach my $sourceFile (sort keys %WarningsForBothLowercaseAndPhysicalOnSameReference) |
|
615 { |
|
616 print ("$sourceFile\n"); |
|
617 foreach my $warning (sort keys %{$WarningsForBothLowercaseAndPhysicalOnSameReference{$sourceFile}}) |
|
618 { |
|
619 print ("\t$warning\n"); |
|
620 } |
|
621 } |
|
622 print ("NONE\n") if (!scalar (keys %WarningsForBothLowercaseAndPhysicalOnSameReference)); |
|
623 |
|
624 print ("\n\nMultiple differing physical filename policy warnings for the same reference\n". |
|
625 "---------------------------------------------------------------------------\n\n"); |
|
626 foreach my $sourceFile (sort keys %WarningsForMultiplePhysicalUpdates) |
|
627 { |
|
628 print ("$sourceFile\n"); |
|
629 foreach my $warning (sort keys %{$WarningsForMultiplePhysicalUpdates{$sourceFile}}) |
|
630 { |
|
631 print ("\t$warning\n"); |
|
632 } |
|
633 } |
|
634 print ("NONE\n") if (!scalar (keys %WarningsForMultiplePhysicalUpdates)); |
|
635 |
|
636 print ("\n\nNon-actionable filename policy warnings\n". |
|
637 "---------------------------------------\n\n"); |
|
638 foreach my $nonActionableWarning (sort keys %NonActionableFilenamePolicyWarnings) |
|
639 { |
|
640 print ("$nonActionableWarning\n"); |
|
641 } |
|
642 print ("NONE\n") if (!scalar (keys %NonActionableFilenamePolicyWarnings)); |
|
643 |
|
644 |
|
645 print ("\n\nOther detected warnings unrelated to filename policy\n". |
|
646 "----------------------------------------------------\n\n"); |
|
647 foreach my $otherWarningOrError (sort keys %OtherWarningsAndErrors) |
|
648 { |
|
649 print ("$otherWarningOrError\n"); |
|
650 } |
|
651 print ("NONE\n") if (!scalar (keys %OtherWarningsAndErrors)); |
|
652 |
|
653 print ("\n\n"); |
|
654 } |
|
655 |
|
656 |
|
657 # 7. Perform -update function |
|
658 |
|
659 if ($update || $debugUpdate) |
|
660 { |
|
661 foreach my $SOURCE_FILE (sort keys %ActionableFilenamePolicyWarnings) |
|
662 { |
|
663 if (!(open SOURCE_FILE, "< $SOURCE_FILE")) |
|
664 { |
|
665 print ("ERROR: Could not open $SOURCE_FILE to read.\n"); |
|
666 next; |
|
667 } |
|
668 |
|
669 print ("Updating \'$SOURCE_FILE\'...\n") unless ($debugUpdate); |
|
670 |
|
671 my $lineNumbersHashRef = $ActionableFilenamePolicyWarnings{$SOURCE_FILE}; |
|
672 my $lineNumber = 0; |
|
673 my @newSourceFile; |
|
674 |
|
675 while (my $line = <SOURCE_FILE>) |
|
676 { |
|
677 $lineNumber++; |
|
678 |
|
679 if ($lineNumbersHashRef->{$lineNumber}) |
|
680 { |
|
681 print ("\tOriginal : $line") if ($verbose); |
|
682 |
|
683 my $problematicTextHashRef = $lineNumbersHashRef->{$lineNumber}; |
|
684 |
|
685 # We need to order the updates on a per-line basis so that, for example, |
|
686 # a search and update for 'nkern\arm\' occurs after one for 'include\nkern\arm\nk_plat.h' |
|
687 # We can do this by length, making sure the longest updates are performed first |
|
688 my @problematicTextOrderedHashKeys = sort {length $b <=> length $a} (keys %{$problematicTextHashRef}); |
|
689 |
|
690 foreach my $problematicText (@problematicTextOrderedHashKeys) |
|
691 { |
|
692 my $attributesHashRef = $problematicTextHashRef->{$problematicText}; |
|
693 my $revisedText = $problematicText; |
|
694 |
|
695 # Physical |
|
696 |
|
697 if ($attributesHashRef->{PHYSICAL}) |
|
698 { |
|
699 my $physicalRealityHashRef = $attributesHashRef->{PHYSICAL_REALITY}; |
|
700 |
|
701 my $physicalReality = (keys %{$physicalRealityHashRef})[0]; |
|
702 my $physicalRealityUnixSlash = $physicalReality; |
|
703 $physicalRealityUnixSlash =~ s/\\/\//g; |
|
704 |
|
705 if ($physicalReality =~ /($attributesHashRef->{SEARCH_TEXT})$/i || |
|
706 $physicalRealityUnixSlash =~ /($attributesHashRef->{SEARCH_TEXT})$/i) |
|
707 { |
|
708 # Simple case - direct match with just case and slash differences |
|
709 my $replacement = $1; |
|
710 $replacement =~ s/\\/\//g; |
|
711 $revisedText =~ s/$attributesHashRef->{SEARCH_TEXT}/$replacement/; |
|
712 } |
|
713 else |
|
714 { |
|
715 # What we're looking at in the source file doesn't map directly |
|
716 # to what's physically on the file system. |
|
717 |
|
718 my $modifiedSearchText = $problematicText; |
|
719 $modifiedSearchText =~ s/\.\.[\\|\/]//g; |
|
720 $modifiedSearchText =~ s/\.[\\|\/]//g; |
|
721 |
|
722 my $physicalMatchCheck; |
|
723 if ($attributesHashRef->{ACTUAL_TEST}) |
|
724 { |
|
725 $physicalMatchCheck = $attributesHashRef->{ACTUAL_TEST}; |
|
726 } |
|
727 else |
|
728 { |
|
729 $physicalMatchCheck = $modifiedSearchText; |
|
730 } |
|
731 |
|
732 # The physical match check needs to remove double-slashing... |
|
733 $physicalMatchCheck =~ s/\\\\/\\/g; |
|
734 $physicalMatchCheck =~ s/\/\//\//g; |
|
735 |
|
736 $modifiedSearchText = quotemeta($modifiedSearchText); |
|
737 $physicalMatchCheck = quotemeta($physicalMatchCheck); |
|
738 |
|
739 $physicalMatchCheck =~ s/\\\*/\\w\+/g; # * -> \w+ |
|
740 $physicalMatchCheck =~ s/\\\?/\\w\{1\}/g; # ? -> \w{1} |
|
741 |
|
742 if ($physicalReality =~ /($physicalMatchCheck)$/i || |
|
743 $physicalRealityUnixSlash =~ /($physicalMatchCheck)$/i ) |
|
744 { |
|
745 my $replacement = $1; |
|
746 $replacement =~ s/\\/\//g; |
|
747 |
|
748 if ($attributesHashRef->{ACTUAL_TEST} && |
|
749 ($attributesHashRef->{ITEM} =~ /MMP$/ || $attributesHashRef->{ITEM} =~ /DEFFILE/)) |
|
750 { |
|
751 # Both DEFFILE and PRJ_[TEST]MMPFILE entries may be specifed without extension |
|
752 $replacement =~ s/\.\w+$// if ($problematicText !~ /\.\w+$/); |
|
753 |
|
754 # DEFFILE entries may have eabi\bwins in the physical match and had a "u" inserted or appended |
|
755 if ($attributesHashRef->{ITEM} =~ /DEFFILE/ && $replacement !~ /$modifiedSearchText$/i) |
|
756 { |
|
757 $replacement =~ s/(eabi|bwins)\//~\//i if ($problematicText =~ /~[\\|\/]/); |
|
758 $replacement =~ s/u(\.\w+)?$/$1/i if ($attributesHashRef->{ITEM} !~ /NOSTRICTDEF/); |
|
759 } |
|
760 } |
|
761 |
|
762 $revisedText =~ s/$modifiedSearchText/$replacement/; |
|
763 } |
|
764 else |
|
765 { |
|
766 print ("ERROR: Can\'t perform physical consistency updates for:"); |
|
767 |
|
768 my $originalWarningsHashRef = $attributesHashRef->{ORIGINAL_WARNINGS}; |
|
769 foreach my $originalWarning (keys %{$originalWarningsHashRef}) |
|
770 { |
|
771 print ("\t$originalWarning") if ($originalWarning =~ /case versus/); |
|
772 } |
|
773 |
|
774 print ("\n"); |
|
775 } |
|
776 } |
|
777 } |
|
778 |
|
779 # Exclusion |
|
780 |
|
781 if ($attributesHashRef->{EXCLUSION}) |
|
782 { |
|
783 my $exclusionListingSearch = quotemeta($attributesHashRef->{EXCLUSION_LISTING}); |
|
784 $revisedText =~ s/$exclusionListingSearch/$attributesHashRef->{EXCLUSION_LISTING}/i; |
|
785 } |
|
786 |
|
787 # Slash |
|
788 if ($attributesHashRef->{UNIX_SLASH}) |
|
789 { |
|
790 $revisedText =~ s/\\/\//g; |
|
791 $revisedText =~ s/\/\//\//g; # Don't allow replacements that lead to "//" in paths |
|
792 } |
|
793 |
|
794 # Lowercase |
|
795 |
|
796 if ($attributesHashRef->{LOWERCASE}) |
|
797 { |
|
798 $revisedText = lc ($revisedText); |
|
799 } |
|
800 |
|
801 # Default Export |
|
802 |
|
803 if ($attributesHashRef->{DEFAULT_EXPORT}) |
|
804 { |
|
805 my $exportedFilename = lc (basename ($problematicText)); |
|
806 $revisedText .= " \/epoc32\/include\/".$exportedFilename; |
|
807 } |
|
808 |
|
809 $line =~ s/(\"|\<|^|\s){1}$attributesHashRef->{SEARCH_TEXT}/$1$revisedText/; |
|
810 } |
|
811 |
|
812 print ("\tUpdated : $line") if ($verbose); |
|
813 } |
|
814 |
|
815 push @newSourceFile, $line; |
|
816 } |
|
817 |
|
818 close SOURCE_FILE; |
|
819 |
|
820 if ($debugUpdate) |
|
821 { |
|
822 # Don't touch the original source, but create two trees for easy comparison |
|
823 |
|
824 my $baseDir = dirname ($SOURCE_FILE); |
|
825 mkpath ("\\compare\\orig".$baseDir); |
|
826 mkpath ("\\compare\\updated".$baseDir); |
|
827 print ("Copying \'\\compare\\orig".$SOURCE_FILE."\'...\n"); |
|
828 copy ($SOURCE_FILE, "\\compare\\orig".$SOURCE_FILE); |
|
829 $SOURCE_FILE = "\\compare\\updated".$SOURCE_FILE; |
|
830 print ("Updating \'$SOURCE_FILE\'...\n"); |
|
831 } |
|
832 |
|
833 if (!(open SOURCE_FILE, "> $SOURCE_FILE")) |
|
834 { |
|
835 print ("ERROR: Could not open $SOURCE_FILE to write.\n"); |
|
836 next; |
|
837 } |
|
838 |
|
839 foreach my $line (@newSourceFile) |
|
840 { |
|
841 print (SOURCE_FILE $line); |
|
842 } |
|
843 |
|
844 close SOURCE_FILE; |
|
845 } |
|
846 |
|
847 print ("\n") if ($verbose); |
|
848 } |
|
849 |
|
850 __END__ |
|
851 |
|
852 :endofperl |