|
1 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 # This component and the accompanying materials are made available |
|
3 # under the terms of the License "Eclipse Public License v1.0" |
|
4 # which accompanies this distribution, and is available |
|
5 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
6 # |
|
7 # Initial Contributors: |
|
8 # Nokia Corporation - initial contribution |
|
9 # |
|
10 # Contributors |
|
11 # |
|
12 # Description: Replace S60 header with Symbian Foundation license header. |
|
13 # Output file (results) is compatibe for SFMakeLxrLinks.pl as input. |
|
14 # |
|
15 use strict; |
|
16 use File::Find; |
|
17 use File::Basename; |
|
18 use Getopt::Long; |
|
19 use IO::Handle; |
|
20 use FindBin qw($Bin); |
|
21 use FileHandle; |
|
22 |
|
23 #################### |
|
24 # Constants |
|
25 #################### |
|
26 |
|
27 # Tool version |
|
28 use constant VERSION => '2.1'; |
|
29 # Version history: 0.8 Added copyright year pick-up |
|
30 # Version history: 0.9- Bug fixesg |
|
31 # Version history: 0.95- EPL header support added |
|
32 # Version history: 0.96 Minor script adjustments |
|
33 # Version history: 0.97 Assembly files (.s, .cia, .asm) checked as well |
|
34 # Version history: 0.98 Support for -oem added. Also @file tag removed from template |
|
35 # Version history: 0.99 Testing -oem option |
|
36 # Version history: 1.0 Comment column added for PostProcess script |
|
37 # Version history: 1.01 Modify option bug fixed |
|
38 # Version history: 1.1 Description bug fixed |
|
39 # Version history: 1.2 Digia copyrights moved to SF as well. Also R/O attribute removed only for files modified |
|
40 # Version history: 1.3 Distribution policy files handled as well. With -create also created |
|
41 # Version history: 1.31 Fixes to distribution file handling (only non-empty directories acknowledged) |
|
42 # Version history: 1.32 .pm files checked as well |
|
43 # Version history: 1.4 Bug fixes and "ignorefile" agrument added |
|
44 # Version history: 1.41 Bug fix in Description pick-up |
|
45 # Version history: 1.42 Bug fix in -ignore option (also missing .s60 file creation need to be ignored). Default value set to ignore option |
|
46 # Version history: 1.43 Description statistics fixed, .hpp added, description pick-up improved |
|
47 # Version history: 1.5 -verify option implemented, ignorefile default value extended, statistics go to log |
|
48 # Version history: 1.51 Copyright year pick-up bug fixed, ignorefilepattern comparison case-insensitive |
|
49 # Version history: 1.52 current s60 dumped to result |
|
50 # Version history: 1.53 abld.bat added ti ignorefile default |
|
51 # Version history: 1.54 -verify statistics improved |
|
52 # Version history: 1.55 -eula option added |
|
53 # Version history: 1.56 .mmh files added, extra Non-Nokia check added for "No Copyright" case for weired headers |
|
54 # Version history: 1.57 Changes to -verify |
|
55 # Version history: 1.58 @echo on ... @echo off added to .cmd and .bat headers |
|
56 # Version history: 1.59 EPL warning log entry --> info |
|
57 # Version history: 1.60 and 1.61 -ignorelist option added |
|
58 # Version history: 1.62 Uppercase REM text allowed |
|
59 # Version history: 1.63 Internal directory check added to -verify |
|
60 # Version history: 1.64 Symbian --> Symbian.*Ltd in $ExternalToNokiaCopyrPattern |
|
61 # Version history: 1.65 Bug fixed in normalizeCppComment |
|
62 # Version history: 1.70 Changes to better cope with ex-Symbian sources, |
|
63 # Pasi's better "@rem" taken into use for .bat and .cmd files |
|
64 # Version history: 1.71 Config file support added (option -config) for non 3/7 IDs |
|
65 # Version history: 1.72 handleVerify checks improved to include also file start |
|
66 # Version history: 1.73 \b added to Copyright word to reduce if "wrong" alarms |
|
67 # Version history: 1.74 incomplete copyright check added to -verify |
|
68 # Version history: 1.75 Support for ignoring generated headers (@sfGeneratedPatternArray) added |
|
69 # Version history: 1.76 .script extension added (using Cpp comments e.g. // Text) |
|
70 # Version history: 1.77 Reporting and logging improvements for wk19 checks (need to check / patch single files) |
|
71 # Version history: 1.80 Few Qt specific file extensions added, -lgpl option added, |
|
72 # C++ comment fix in handleOem |
|
73 # Version history: 1.90 checkNoMultipleLicenses function added, and call to handleVerify* added |
|
74 # Version history: 2.0 handleDistributionValue() changes IDs 0-->3/7 and 3-->7, |
|
75 # isGeneratedHeader() checks for file content added. |
|
76 # Version history: 2.01 checkPortionsCopyright implemented and applied |
|
77 # Version history: 2.02 Extra license word taken out from EPL header |
|
78 # Version history: 2.1 -verify -epl support added and switchLicense() tried first for SFL --> EPL switching |
|
79 |
|
80 my $IGNORE_MAN ='Ignore-manually'; |
|
81 my $IGNORE ='Ignore'; |
|
82 my $INTERNAL = 'internal'; |
|
83 use constant KEEP_SYMBIAN => 0; |
|
84 use constant REMOVE_SYMBIAN => 1; |
|
85 |
|
86 |
|
87 #file extention list that headers should be replace |
|
88 my @extlist = ('.cpp', '.c', '.h', '.mmp', '.mmpi', '.rss', '.hrh', '.inl', '.inf', '.iby', '.oby', |
|
89 '.loc', '.rh', '.ra', '.java', '.mk', '.bat', '.cmd', '.pkg', '.rls', '.rssi', '.pan', '.py', '.pl', '.s', '.asm', '.cia', |
|
90 '.s60', '.pm', '.hpp', '.mmh', '.script', |
|
91 '.pro', '.pri'); # Qt specific |
|
92 |
|
93 # Various header comment styles |
|
94 my @header_regexps = |
|
95 ( |
|
96 '^\s*(\#.*?\n)*', # Perl, Python |
|
97 '^\s*(\@echo\s*off\s*\n)?\n*(@?(?i)rem.*?\n)*(\@echo\s*on\s*)?', # Windows command script |
|
98 '^\s*(\;.*?\n)*', # SIS package file |
|
99 '\s*\/\*[\n\s\*-=].*?\*\/', # C comment block |
|
100 '(\s*\/\/.*\n)+', # C++ comment block (do not use /s in regexp evaluation !!!) |
|
101 '^\s*((\/\/|\#).*?\n)*' # Script file comment |
|
102 ); |
|
103 |
|
104 # Comment regular expression (Indeces within @header_regexps) |
|
105 use constant COMMENT_PERL => 0; |
|
106 use constant COMMENT_CMD => 1; |
|
107 use constant COMMENT_SIS_ASM => 2; |
|
108 use constant COMMENT_C => 3; |
|
109 use constant COMMENT_CPP => 4; |
|
110 use constant COMMENT_SCRIPT => 5; |
|
111 |
|
112 my $descrTemplateOnly = '\?Description'; |
|
113 my $linenumtext = "1"; # Use this linenumer in LXR links |
|
114 |
|
115 # Copyright patterns |
|
116 my $copyrYearPattern = 'Copyright\b.*\d{4}\s*([,-]\s*\d{4})*'; |
|
117 my $copyrYearPattern2 = '\d{4}(\s*[,-]\s*\d{4})*'; |
|
118 use constant DEFCOPYRIGHTYEAR => "2009"; # For error cases |
|
119 |
|
120 my $NokiaCopyrPattern = '\bCopyright\b.*Nokia.*(All Rights)?'; |
|
121 my $NonNokiaCopyrPattern = '\bCopyright\b.*(?!Nokia).*(All Rights)?'; |
|
122 my $CopyrPattern = '\bCopyright\b'; |
|
123 my $RemoveS60TextBlockPattern = 'This material.*Nokia'; |
|
124 my $CC = 'CCHAR'; |
|
125 my $BeginLicenseBlockPattern = 'BEGIN LICENSE BLOCK'; |
|
126 my $OldNokiaPattern = 'Nokia\s*Corporation[\.\s]*\n'; |
|
127 my $NewNokiaText = "Nokia Corporation and/or its subsidiary(-ies).\n"; # Used in substitu to text |
|
128 my $NewNokiaPattern = "Nokia Corporation and/or its subsidiary"; |
|
129 my $OldNokiaPattern2 = "This material.*including documentation and any related.*protected by copyright controlled.*Nokia"; |
|
130 my $PortionsNokiaCopyrPattern = 'Portions.*Copyright\b.*Nokia.*(All Rights)?'; |
|
131 my $NewPortionsNokiaCopyrPattern = 'Portions\s*Copyright\b.*' . $NewNokiaPattern; |
|
132 |
|
133 # Move these copyrights to Nokia !!! |
|
134 my $ExternalToNokiaCopyrPattern = 'Copyright\b.*(Symbian\sLtd|Symbian\s*Software\s*Ltd|Digia|SysopenDigia).*(All\s+Rights|All\s+rights)?'; |
|
135 my $PortionsSymbianCopyrPattern = 'Portions\s*Copyright\b.*(Symbian\sLtd|Symbian\s*Software\s*Ltd).*(All\s+Rights|All\s+rights)?'; |
|
136 |
|
137 ############### |
|
138 # SFL headers |
|
139 ############### |
|
140 # SFL C/C++ style |
|
141 # |
|
142 my $SFLicenseHeader = |
|
143 '/* |
|
144 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
145 * All rights reserved. |
|
146 * This component and the accompanying materials are made available |
|
147 * under the terms of the License "Symbi'.'an Foundation License v1.0" |
|
148 * which accompanies this distribution, and is available |
|
149 * at the URL "http://www.symbi'.'anfoundation.org/legal/sf'.'l-v10.html". |
|
150 * |
|
151 * Initial Contributors: |
|
152 * Nokia Corporation - initial contribution. |
|
153 * |
|
154 * Contributors: |
|
155 * |
|
156 * Description: |
|
157 * |
|
158 */'. "\n"; |
|
159 |
|
160 # Test string to test header have been changed |
|
161 my $SFLHeaderTest = 'Symbian\s*Foundation\s*License.*www\.symbianfoundation\.org\/legal\/sfl'; |
|
162 |
|
163 # Partial SFL header template (# will be replaced by actual comment syntax char) |
|
164 # Prepare for cases where someone adds spaces to string. |
|
165 my $SFLicenseHeaderPartial_template = |
|
166 $CC . '\s*This\s*component\s*and\s*the\s*accompanying\s*materials\s*are\s*made\s*available\s*\n' . |
|
167 $CC . '\s*under\s*the\s*terms\s*of\s*the\s*License\s*\"Symbian\s*Foundation\s*License\s*v1\.0\"\s*\n' . |
|
168 $CC . '\s*which\s*accompanies\s*this\s*distribution\,\s*and\s*is\s*available\s*\n' . |
|
169 $CC . '\s*at\s*the\s*URL\s*\"http\:\/\/www\.symbianfoundation\.org\/legal\/sfl\-v10\.html\"\s*\.'; |
|
170 |
|
171 # SFL other comment styles (replace # with actual comment starter) |
|
172 # |
|
173 my $SFLicenseHeader_other_template = |
|
174 '# |
|
175 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
176 # All rights reserved. |
|
177 # This component and the accompanying materials are made available |
|
178 # under the terms of the License "Symbi'.'an Foundation License v1.0" |
|
179 # which accompanies this distribution, and is available |
|
180 # at the URL "http://www.symbi','anfoundation.org/legal/sf'.'l-v10.html". |
|
181 # |
|
182 # Initial Contributors: |
|
183 # Nokia Corporation - initial contribution. |
|
184 # |
|
185 # Contributors: |
|
186 # |
|
187 # Description: |
|
188 # |
|
189 '; |
|
190 |
|
191 |
|
192 |
|
193 ############### |
|
194 # EPL headers |
|
195 ############### |
|
196 # C/C++ style |
|
197 my $EPLLicenseHeader = |
|
198 '/* |
|
199 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
200 * All rights reserved. |
|
201 * This component and the accompanying materials are made available |
|
202 * under the terms of "Eclipse Public License v1.0" |
|
203 * which accompanies this distribution, and is available |
|
204 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
205 * |
|
206 * Initial Contributors: |
|
207 * Nokia Corporation - initial contribution. |
|
208 * |
|
209 * Contributors: |
|
210 * |
|
211 * Description: |
|
212 * |
|
213 */' . "\n"; |
|
214 |
|
215 # Test string to test header have been changed |
|
216 my $EPLHeaderTest = 'Eclipse\s*Public\s*License.*www\.eclipse\.org\/legal\/epl'; |
|
217 |
|
218 # Partial EPL header (replace # with actual comment starter) |
|
219 # Prepare for cases where someone adds spaces to string. |
|
220 my $EPLLicenseHeaderPartial_template = |
|
221 $CC . '\s*This\s*component\s*and\s*the\s*accompanying\s*materials\s*are\s*made\s*available\s*\n' . |
|
222 $CC . '\s*under\s*the\s*terms\s*of\s*\"Eclipse\s*Public\s*License\s*v1\.0\"\s*\n' . |
|
223 $CC . '\s*which\s*accompanies\s*this\s*distribution,\s*and\s*is\s*available\s*\n' . |
|
224 $CC . '\s*at\s*the\s*URL\s*\"http\:\/\/www\.eclipse\.org\/legal\/epl\-v10\.html\"\s*\.'; |
|
225 |
|
226 |
|
227 # EPL other comment styles (replace # with comment starter) |
|
228 # |
|
229 my $EPLLicenseHeader_other_template = |
|
230 '# |
|
231 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
232 # All rights reserved. |
|
233 # This component and the accompanying materials are made available |
|
234 # under the terms of "Eclipse Public License v1.0" |
|
235 # which accompanies this distribution, and is available |
|
236 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
237 # |
|
238 # Initial Contributors: |
|
239 # Nokia Corporation - initial contribution. |
|
240 # |
|
241 # Contributors: |
|
242 # |
|
243 # Description: |
|
244 # |
|
245 '; |
|
246 |
|
247 ############## |
|
248 # LGPL headers |
|
249 ############## |
|
250 my $LGPLLicenseHeader = |
|
251 '/* |
|
252 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
253 * All rights reserved. |
|
254 * |
|
255 * This program is free software: you can redistribute it and/or modify |
|
256 * it under the terms of the GNU Lesser General Public License as published by |
|
257 * the Free Software Foundation, version 2.1 of the License. |
|
258 * |
|
259 * This program is distributed in the hope that it will be useful, |
|
260 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
261 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
262 * GNU Lesser General Public License for more details. |
|
263 * |
|
264 * You should have received a copy of the GNU Lesser General Public License |
|
265 * along with this program. If not, |
|
266 * see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/". |
|
267 * |
|
268 * Description: |
|
269 * |
|
270 */'; |
|
271 |
|
272 # Test string to test header have been changed |
|
273 my $LGPLHeaderTest = 'GNU\s*Lesser\s*General\s*Public\s*License.*www\.gnu\.org\/licenses/old-licenses\/lgpl-2\.1\.html'; |
|
274 |
|
275 # Partial LGPL header (replace $CC with actual comment starter) |
|
276 my $LGPLLicenseHeaderPartial_template = |
|
277 $CC . '\s*This\s*program\s*is\s*free\s*software\:\s*you\s*can\s*redistribute\s*it\s*and\/or\s*modify\n' . |
|
278 $CC . '\s*it\s*under\s*the\s*terms\s*of\s*the\s*GNU\s*Lesser\s*General\s*Public\s*License\s*as\s*published\s*by\n' . |
|
279 $CC . '\s*the\s*Free\s*Software\s*Foundation\,\s*version\s*2\.1\s*of\s*the\s*License\n'; |
|
280 |
|
281 |
|
282 # LGPL other comment styles (replace # with comment starter) |
|
283 # |
|
284 my $LGPLLicenseHeader_other_template = |
|
285 '# |
|
286 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
287 # All rights reserved. |
|
288 # |
|
289 # This program is free software: you can redistribute it and/or modify |
|
290 # it under the terms of the GNU Lesser General Public License as published by |
|
291 # the Free Software Foundation, version 2.1 of the License. |
|
292 # |
|
293 # This program is distributed in the hope that it will be useful, |
|
294 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
295 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
296 # GNU Lesser General Public License for more details. |
|
297 # |
|
298 # You should have received a copy of the GNU Lesser General Public License |
|
299 # along with this program. If not, |
|
300 # see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/". |
|
301 # |
|
302 # Description: |
|
303 # |
|
304 '; |
|
305 |
|
306 |
|
307 ############### |
|
308 # S60 headers |
|
309 ############### |
|
310 # C/C++ style |
|
311 my $S60HeaderPartial_template = |
|
312 $CC . " This material, including documentation and any related computer\n" . |
|
313 $CC . " programs, is protected by copyright controlled by Nokia. All\n" . |
|
314 $CC . " rights are reserved. Copying, including reproducing, storing\n" . |
|
315 $CC . " adapting or translating, any or all of this material requires the\n" . |
|
316 $CC . " prior written consent of Nokia. This material also contains\n" . |
|
317 $CC . " confidential information which may not be disclosed to others\n" . |
|
318 $CC . " without the prior written consent of Nokia."; |
|
319 |
|
320 # Test string to test header have been changed |
|
321 my $S60HeaderTest = 'is\s*protected\s*by\s*copyright\s*controlled\s*by\s*Nokia'; |
|
322 |
|
323 |
|
324 my @SflHeaders = (\$SFLicenseHeader, \$SFLicenseHeader_other_template, \$SFLicenseHeaderPartial_template, \$SFLHeaderTest); # contains refs |
|
325 my @EplHeaders = (\$EPLLicenseHeader, \$EPLLicenseHeader_other_template, \$EPLLicenseHeaderPartial_template, \$EPLHeaderTest); # contains refs |
|
326 my @S60Headers = (undef,undef,\$S60HeaderPartial_template, \$S60HeaderTest); # contains refs |
|
327 my @LgplHeaders = (\$LGPLLicenseHeader, \$LGPLLicenseHeader_other_template, \$LGPLLicenseHeaderPartial_template, \$LGPLHeaderTest); # contains refs |
|
328 |
|
329 # Header styles (indeces within @SflHeaders and @EplHeaders) |
|
330 use constant CPP_HEADER => 0; |
|
331 use constant OTHER_HEADER => 1; |
|
332 |
|
333 # switchLicense related values |
|
334 use constant SFL_LICENSE => 3; |
|
335 use constant EPL_LICENSE => 7; |
|
336 use constant S60_LICENSE => 0; |
|
337 use constant LGPL_LICENSE => 4; |
|
338 use constant LICENSE_CHANGED => 1; |
|
339 use constant LICENSE_NONE => 0; |
|
340 use constant LICENSE_ERROR => -1; |
|
341 use constant LICENSE_NOT_SUPPORTED => -2; |
|
342 |
|
343 # Distribution policy file values |
|
344 use constant INTERNAL_DISTRIBUTION_VALUE => "1"; |
|
345 use constant ZERO_DISTRIBUTION_VALUE => "0"; |
|
346 use constant SFL_DISTRIBUTION_VALUE => "3"; |
|
347 use constant EPL_DISTRIBUTION_VALUE => "7"; # option -epl |
|
348 use constant TSRC_DISTRIBUTION_VALUE => "950"; # |
|
349 use constant NONSF_DISTRIBUTION_VALUE => "Other"; # |
|
350 use constant DISTRIBUTION_FILENAME => "distribution.policy.s60"; |
|
351 |
|
352 my $usage = 'SFUpdateLicenHeader.pl tool, version: ' . VERSION . |
|
353 ' |
|
354 Usages: |
|
355 perl SFUpdateLicenceHeader.pl [-modify] [-epl] [-oem] [-create] [-ignorefile pattern] |
|
356 [-output csv-file] [-log logfile] [-verbose level] [-verify] [-append] |
|
357 [-oldoutput old-csv-file] DIRECTORY|FILE |
|
358 |
|
359 Check switch to SFL header in a directory (and subdirectories under that): |
|
360 perl SFUpdateLicenceHeader.pl -output csv-file -log logfile DIRECTORY |
|
361 Switch to SFL header and modify .policy.s60 files in a directory (and subdirectories under that): |
|
362 perl SFUpdateLicenceHeader.pl -modify -output csv-file -log logfile DIRECTORY |
|
363 Switch to SFL header and modify .policy.s60 files in a single file: |
|
364 perl SFUpdateLicenceHeader.pl -modify -output csv-file -log logfile FILE |
|
365 Switch to EPL header and modify .policy.s60 files: |
|
366 perl SFUpdateLicenceHeader.pl -modify -epl -output csv-file -log logfile DIRECTORY |
|
367 Switch to SFL header and modify/create missing .policy.s60 files: |
|
368 perl SFUpdateLicenceHeader.pl -modify -create -output csv-file -log logfile DIRECTORY |
|
369 Switch to SFL header and ignore files matching CCM file pattern: |
|
370 perl SFUpdateLicenceHeader.pl -modify -ignore "_ccmwaid.inf" -output csv-file -log logfile DIRECTORY |
|
371 Switch to SFL header and ignore files matching CCM or SVN file patterns: |
|
372 perl SFUpdateLicenceHeader.pl -modify -ignore "(_ccm|.svn)" -output csv-file -log logfile DIRECTORY |
|
373 Switch back to Nokia header (for OEM delivery team): |
|
374 perl SFUpdateLicenceHeader.pl -modify -oem -output csv-file -log logfile DIRECTORY |
|
375 Verify file header changes |
|
376 perl SFUpdateLicenceHeader.pl -verify -output csv-file -log logfile DIRECTORY |
|
377 Verify and append logs and results to single file |
|
378 perl SFUpdateLicenceHeader.pl -verify -append -output AllResults.csv -log AllLogs.log DIRECTORY |
|
379 Verify file header changes and use old result file as add-on configuation (used by -verbose only) |
|
380 perl SFUpdateLicenceHeader.pl -verify -oldoutput old-csv-file -output csv-file -log logfile DIRECTORY |
|
381 |
|
382 For more info, see http://s60wiki.nokia.com/S60Wiki/SFDG-File-Header#SFUpdateLicenceHeader.pl |
|
383 '; |
|
384 |
|
385 # Logging constants |
|
386 use constant LOG_ALWAYS => 0; |
|
387 use constant LOG_INFO => 3; |
|
388 use constant LOG_ERROR => 1; |
|
389 use constant LOG_WARNING => 2; |
|
390 use constant LOG_DEBUG => 4; |
|
391 my @LOGTEXTS = ("", "ERROR: ", "Warning: ", "Info: ", "DEBUG: "); |
|
392 my $sep = ","; |
|
393 my $logFile = ""; |
|
394 |
|
395 # Issue categories in result CSV formatted file |
|
396 use constant HEADER_CONTEXT => 'header-issue'; |
|
397 use constant DISTRIBUTION_CONTEXT => 'distribution-issue'; |
|
398 |
|
399 |
|
400 #################### |
|
401 # Global variables |
|
402 #################### |
|
403 |
|
404 # Command line options |
|
405 my $help = 0; |
|
406 my $outputfile; |
|
407 my $ignorefilepattern; # File patterns to ignore |
|
408 # my $optSfl = 1; # By default sfl is on |
|
409 my $optEpl = 0; # Use EPL headers |
|
410 my $optLgpl = 0; # Use LGPL v2.1 headers |
|
411 my $optLogLevel = LOG_INFO; |
|
412 my $optModify = 0; # (default mode is check) |
|
413 my $optCreate = 0; # (create missing files) |
|
414 my $optOem = 0; # OEM delivery to S60 license |
|
415 my $optAppend = 0; # Append results |
|
416 my $optVerify = 0; # Verify option |
|
417 my $oldOutputFile; # Version 1.60 old output file in CSV format |
|
418 my %manualIgnoreFileHash; # Hash of files ignored |
|
419 my $optDescription = 0; # Output also missing description |
|
420 my $optOutputOK = 0; # Output also OK issues for -verify |
|
421 |
|
422 # The last distribution ID |
|
423 my $lastDistributionValue = ""; |
|
424 |
|
425 # Config file specific gllobals |
|
426 my $configFile; |
|
427 my $configVersion = ""; |
|
428 my @sfDistributionIdArray = (); # Distribution ID array |
|
429 my @sfGeneratedPatternArray = (); # Distribution ID array |
|
430 |
|
431 # |
|
432 # Statistics variables |
|
433 # |
|
434 my $fileCount = 0; |
|
435 my $modifiedFileCount = 0; |
|
436 my $willModifiedFileCount = 0; |
|
437 my $noDescrcount = 0; |
|
438 my $otherCopyrCount=0; |
|
439 my $ExternalToNokiaCopyrCount=0; |
|
440 my $NokiaCopyrCount=0; |
|
441 my $NoCopyrCount=0; |
|
442 my $UnclearCopyrCount=0; |
|
443 my $SflToS60Changes = 0; |
|
444 my $EplToS60Changes = 0; |
|
445 my $SflToEplChanges = 0; |
|
446 my $EplToSflChanges = 0; |
|
447 my $LicenseChangeErrors = 0; |
|
448 my $ignoreCount = 0; |
|
449 my $unrecogCount = 0; |
|
450 my $createCount = 0; |
|
451 my @verifyFailedCount = (0,0,0,0,0,0,0,0,0,0,0); |
|
452 my @verifyFailedCountMsgs = ("Distribution file missing", # Index 0 |
|
453 "SFL or EPL distribution ID missing", #1 |
|
454 "SFL or EPL header missing", #2 |
|
455 "Proper copyright missing", #3 |
|
456 "Header vs. distribution ID mismatch", #4 |
|
457 "Internal directory going to SF", #5 |
|
458 "Old Nokia file header used", #6 |
|
459 "Unclear Non-Nokia copyright", #7 |
|
460 "Incomplete copyright", #8 |
|
461 "OK", #9 |
|
462 "OK (Non-Nokia)", #10 |
|
463 "Multiple license" #11 |
|
464 ); |
|
465 use constant VERI_MISSING_FILE => 0; |
|
466 use constant VERI_MISSING_ID => 1; |
|
467 use constant VERI_MISSING_HEADER => 2; |
|
468 use constant VERI_PROPER_COPYRIGHT => 3; |
|
469 use constant VERI_ID_HEADER_MISMATCH => 4; |
|
470 use constant VERI_INTERNAL_TO_SF => 5; |
|
471 use constant VERI_OLD_NOKIA_HEADER => 6; |
|
472 use constant VERI_UNCLEAR_COPYR => 7; |
|
473 use constant VERI_INCOMPLETE_COPYR => 8; |
|
474 use constant VERI_OK => 9; |
|
475 use constant VERI_OK_NON_NOKIA => 10; |
|
476 use constant VERI_MULTIPLE_LICENSES => 11; |
|
477 |
|
478 |
|
479 ################################## |
|
480 # Callback for the find function |
|
481 # (wanted) |
|
482 # Note ! "no_chdir" not used |
|
483 ################################## |
|
484 sub process_file |
|
485 { |
|
486 |
|
487 my $full_filename = $File::Find::name; # Full name needed for result and logs ! |
|
488 $full_filename =~ s/\\/\//g; # Standardize name |
|
489 my $filename = $_; # This in filename in the current working directory ! |
|
490 |
|
491 #Skip all directory entries |
|
492 return if -d; |
|
493 |
|
494 if ($ignorefilepattern && $full_filename =~ m/$ignorefilepattern/i) |
|
495 { |
|
496 printLog(LOG_DEBUG, "File ignored by pattern: ". $full_filename . "\n"); |
|
497 $ignoreCount++; |
|
498 return; |
|
499 } |
|
500 |
|
501 # Set initial value from options, turn off later if needed |
|
502 my $modify = $optModify; |
|
503 my $willmodify = 1; # For statistics only |
|
504 |
|
505 #skip non-source code files |
|
506 my ($name, $path, $suffix)=fileparse($_, qr/\.[^.]*/); |
|
507 |
|
508 my $match = grep {$_ eq lc($suffix)} @extlist; |
|
509 if (!$match) |
|
510 { |
|
511 printLog(LOG_DEBUG, "File ignored: ". $full_filename . "\n"); |
|
512 $ignoreCount++; |
|
513 return; |
|
514 } |
|
515 |
|
516 # As there have been cased where e.g. .pkg file has been saved as Unicode format |
|
517 # Check that we can really modify file (e.g. Unicode files not supported) |
|
518 if (! (-T $filename)) # Text file only ! |
|
519 { |
|
520 printLog(LOG_WARNING, "File not in text format: $full_filename\n"); |
|
521 return; |
|
522 } |
|
523 |
|
524 |
|
525 printLog(LOG_DEBUG, "Handling ". $full_filename . "\n"); |
|
526 |
|
527 local($/, *FH); |
|
528 |
|
529 # Open file for reading here, re-open later if modified |
|
530 open(FH, "<$filename") or return printLog(LOG_ERROR, "Failed to open file for reading: $full_filename\n"); |
|
531 |
|
532 my $filecontent = <FH>; # read whole content into buffer |
|
533 # Standardize the new-line handling in files by replacing \r with \n |
|
534 # Some files may be using only \r and it causes problems |
|
535 $filecontent =~ s/\r/\n/g; |
|
536 |
|
537 my $modifiedFilecontent; |
|
538 my $description = ""; |
|
539 my $contributors = ""; |
|
540 |
|
541 #comment mark |
|
542 my $cm = '\*'; |
|
543 my $cm2 = '*'; |
|
544 my $newheader = ""; |
|
545 my $oldheader = ""; |
|
546 my $oldheader2; |
|
547 my $header_regexp = ""; |
|
548 my $header_regexp2; |
|
549 my $isCcomment = 0; |
|
550 my $isCPPcomment = 0; |
|
551 my $oldCopyrightYear; |
|
552 my $matchPos1; |
|
553 my $matchPos2; |
|
554 my $unrecog=0; |
|
555 |
|
556 |
|
557 # For statisctics.... |
|
558 $fileCount++; |
|
559 |
|
560 ################### |
|
561 # Prepare regular expressions |
|
562 # based on file extensions |
|
563 ################### |
|
564 |
|
565 if (lc($suffix) eq ".s60") |
|
566 { |
|
567 # |
|
568 # Alter exisring distribution policy file |
|
569 # |
|
570 my $stat = LICENSE_NONE; |
|
571 $stat = &handleDistributionValue(\$filecontent, $full_filename); |
|
572 if ($stat eq LICENSE_CHANGED) |
|
573 { |
|
574 $willModifiedFileCount++; |
|
575 if ($modify) |
|
576 { |
|
577 close(FH); # Close null |
|
578 writeFile(\$filecontent, $filename, $full_filename); |
|
579 } |
|
580 } |
|
581 return; # All done |
|
582 } |
|
583 |
|
584 elsif ( (lc($suffix) eq ".mk" ) or |
|
585 (lc($suffix) eq ".pl") or (lc($suffix) eq ".py") or (lc($suffix) eq ".pm") or # script |
|
586 (lc($suffix) eq ".pro") or (lc($suffix) eq ".pri") ) # Qt specific |
|
587 { |
|
588 # Makefile, Perl or Python script (# comment) |
|
589 $cm = '#'; |
|
590 $cm2 = '#'; |
|
591 $newheader = &headerOf(OTHER_HEADER()); |
|
592 $header_regexp = $header_regexps[COMMENT_PERL]; |
|
593 } |
|
594 elsif ((lc($suffix) eq ".bat" ) or (lc($suffix) eq ".cmd" )) |
|
595 { |
|
596 # Windows command script (@rem comment) |
|
597 $cm = '@rem'; |
|
598 $cm2 = '@rem'; |
|
599 $newheader = &headerOf(OTHER_HEADER()); |
|
600 $newheader =~ s/\#/\@rem/g; # use rem as comment start, not # |
|
601 #$newheader = "\@echo off\n" . $newheader; # Disable std output, otherwise rem statements are shown |
|
602 #$newheader = $newheader . "\@echo on\n"; # Enable std output |
|
603 $header_regexp = $header_regexps[COMMENT_CMD]; |
|
604 } |
|
605 elsif (lc($suffix) eq ".pkg" or lc($suffix) eq ".asm") |
|
606 { |
|
607 # SIS package file or Assembly file (; comment) |
|
608 $cm = ';'; |
|
609 $cm2 = ';'; |
|
610 $newheader = &headerOf(OTHER_HEADER()); |
|
611 $newheader =~ s/\#/\;/g; # use ; as comment start |
|
612 $header_regexp = $header_regexps[COMMENT_SIS_ASM]; |
|
613 } |
|
614 elsif (lc($suffix) eq ".s") |
|
615 { |
|
616 # Not all .s files are assemby files !!! |
|
617 # |
|
618 if ($filecontent =~ m/\#include\s*\"armasmdef\.h\"/s) |
|
619 { |
|
620 # ARM assembly file (C comment) |
|
621 $newheader = &headerOf(CPP_HEADER()); |
|
622 # Match both C and C++ comment syntaxes |
|
623 $isCcomment = 1; |
|
624 $header_regexp = $header_regexps[COMMENT_C]; |
|
625 $header_regexp2 = $header_regexps[COMMENT_CPP]; # Use without /s in regexp eval ! |
|
626 } |
|
627 elsif ($filecontent =~ m/[\s\t]+AREA[\s\t]+/s) # AREA statement |
|
628 { |
|
629 # RVCT assembly file (; comment) |
|
630 $cm = ';'; |
|
631 $cm2 = ';'; |
|
632 $newheader = &headerOf(OTHER_HEADER()); |
|
633 $newheader =~ s/\#/\;/g; # use ; as comment start |
|
634 $header_regexp = $header_regexps[COMMENT_SIS_ASM]; |
|
635 } |
|
636 else |
|
637 { |
|
638 # Not recognized |
|
639 $unrecog = 1; |
|
640 printLog(LOG_WARNING, "Assembly file content not recognized, ignored ". $full_filename . "\n"); |
|
641 } |
|
642 } |
|
643 elsif (lc($suffix) eq ".script" ) |
|
644 { |
|
645 # Test scipt (// comment) |
|
646 $cm = '//'; |
|
647 $cm2 = '//'; |
|
648 $newheader = &headerOf(OTHER_HEADER()); |
|
649 $newheader =~ s/\#/\/\//g; # use // as comment start |
|
650 $header_regexp = $header_regexps[COMMENT_SCRIPT]; |
|
651 } |
|
652 else |
|
653 { |
|
654 # C/C++ syntaxed file |
|
655 $newheader = &headerOf(CPP_HEADER()); |
|
656 # Match both C and C++ comment syntaxes |
|
657 $isCcomment = 1; |
|
658 $header_regexp = $header_regexps[COMMENT_C]; |
|
659 $header_regexp2 = $header_regexps[COMMENT_CPP]; # Use without /s in regexp eval ! |
|
660 } |
|
661 |
|
662 if ($unrecog) |
|
663 { |
|
664 close(FH); |
|
665 $unrecogCount++; |
|
666 return; |
|
667 } |
|
668 |
|
669 ################### |
|
670 # Pick up old header in the very first comment block. |
|
671 # If the actual license text is in the later comment block, it may generate |
|
672 # UNCLEAR COPYRIGHT CASE (See Consistency checks) |
|
673 ################### |
|
674 # |
|
675 if ($header_regexp2) |
|
676 { |
|
677 if ($filecontent =~ m/$header_regexp2/) # Note /s not used by purpose ! |
|
678 { |
|
679 $oldheader = $&; |
|
680 $oldheader2 = $&; |
|
681 $matchPos2 = $-[0]; |
|
682 $isCPPcomment = 1; |
|
683 printLog(LOG_DEBUG, "Orig C++ header:$matchPos2=($oldheader)\n"); |
|
684 } |
|
685 } |
|
686 |
|
687 if ($filecontent =~ m/$header_regexp/s) |
|
688 { |
|
689 $oldheader = $&; |
|
690 $matchPos1 = $-[0]; |
|
691 $isCPPcomment = 0; |
|
692 if ($oldheader2 && ($matchPos2 < $matchPos1)) |
|
693 { |
|
694 $oldheader = $oldheader2; # C++ header was earlier |
|
695 $isCPPcomment = 1; # revert back |
|
696 } |
|
697 else |
|
698 { |
|
699 printLog(LOG_DEBUG, "Orig C or other header:$header_regexp,$matchPos1\n"); |
|
700 printLog(LOG_DEBUG, "Orig C or other header:($oldheader)\n"); |
|
701 } |
|
702 } |
|
703 |
|
704 # |
|
705 ################### |
|
706 # Process old header |
|
707 ################### |
|
708 |
|
709 # Handle -verify option |
|
710 if ($optVerify) |
|
711 { |
|
712 if ($optLgpl) |
|
713 { |
|
714 &handleVerifyLgpl(\$filecontent, \$oldheader, $cm, $full_filename, $File::Find::dir); |
|
715 } |
|
716 elsif ($optEpl) |
|
717 { |
|
718 &handleVerifyEpl(\$filecontent, \$oldheader, $cm, $full_filename, $File::Find::dir); |
|
719 } |
|
720 else |
|
721 { |
|
722 &handleVerify(\$filecontent, \$oldheader, $cm, $full_filename, $File::Find::dir); |
|
723 } |
|
724 |
|
725 close(FH); |
|
726 return; # All done |
|
727 } |
|
728 |
|
729 # |
|
730 # Try switch license from SFL to EPL / S60-OEM release |
|
731 # |
|
732 my $switchStat = LICENSE_NONE; |
|
733 $switchStat = &switchLicense(\$filecontent, \$oldheader, $cm, $full_filename, $isCPPcomment); |
|
734 if ($switchStat eq LICENSE_CHANGED) |
|
735 { |
|
736 # OK the switch was sucessful |
|
737 $willModifiedFileCount++; |
|
738 if ($modify) |
|
739 { |
|
740 close(FH); |
|
741 writeFile(\$filecontent, $filename, $full_filename); |
|
742 } |
|
743 close(FH); |
|
744 return; # All done |
|
745 } |
|
746 elsif ($switchStat eq LICENSE_NOT_SUPPORTED) |
|
747 { |
|
748 close(FH); |
|
749 return; # No worth continue |
|
750 } |
|
751 |
|
752 |
|
753 # Otherwise (error or no license) continue to create new header |
|
754 |
|
755 ################### |
|
756 # Consistency checks |
|
757 ################### |
|
758 if ( (!($oldheader =~ m/$CopyrPattern/is)) && ($filecontent =~ m/$BeginLicenseBlockPattern/s)) |
|
759 { |
|
760 # Looks like header is something weired going on. First comment block contains no copyright, |
|
761 # and still there is "BEGIN LICENSE" block in the file |
|
762 $UnclearCopyrCount++; |
|
763 printLog(LOG_INFO, "Non-Nokia copyright (#1) ". $full_filename . "\n"); |
|
764 printResult(HEADER_CONTEXT() . "$sep"."Non-Nokia copyright $sep$sep"."BEGIN LICENSE BLOCK$sep$full_filename$sep$linenumtext\n"); |
|
765 close(FH); |
|
766 return; |
|
767 } |
|
768 |
|
769 # |
|
770 # Switch license from S60 to SFL/EPL according to options |
|
771 # |
|
772 |
|
773 my $otherCopyr = 0; |
|
774 my $noCopyr = 0; |
|
775 my $ExternalToNokiaCopyr = 0; |
|
776 my $s60header = 0; |
|
777 |
|
778 # First remove all "Nokia copyright" texts + weired "Copyright known-words" from header |
|
779 # This because, the header can contain both Nokia and other company copyright statements |
|
780 my $testheader = makeTestHeader(\$oldheader, 0, REMOVE_SYMBIAN); |
|
781 printLog(LOG_DEBUG, "Cleaned header=($testheader)\n"); |
|
782 |
|
783 # Now test whether it contain non-Nokia (=Nokia+Symbian) copyright statements |
|
784 # The rule is: If this hits, do not touch the header |
|
785 |
|
786 if ($testheader =~ m/$NonNokiaCopyrPattern/is) |
|
787 { |
|
788 # Some other than Nokia & Symbian copyright exist in header |
|
789 $otherCopyr = 1; |
|
790 $modify = 0; # !!! Do not modify file !!! |
|
791 $willmodify = 0; |
|
792 $otherCopyrCount++; |
|
793 my $failReason = ""; |
|
794 if (!checkPortionsCopyright(\$oldheader, 0, \$failReason)) |
|
795 { |
|
796 printLog(LOG_WARNING, "Non-Nokia copyright (#2) ". $full_filename . "\n"); |
|
797 printResult(HEADER_CONTEXT() . "$sep"."Non-Nokia copyright$sep$sep$sep$full_filename$sep$linenumtext\n"); |
|
798 } |
|
799 else |
|
800 { |
|
801 printResult(HEADER_CONTEXT() . "$sep"."Non-Nokia (portions Nokia) copyright$sep$sep$sep$full_filename$sep$linenumtext\n"); |
|
802 printLog(LOG_INFO, "Non-Nokia (portions Nokia) copyright ". $full_filename . "\n"); |
|
803 } |
|
804 |
|
805 close(FH); |
|
806 return; # Quit |
|
807 } |
|
808 |
|
809 # Test header has Nokia or Symbian copyright statement or it could be some other comment |
|
810 # Check the rest of file |
|
811 my $wholefile = makeTestHeader(\$filecontent, 1, REMOVE_SYMBIAN); # Check the rest of file |
|
812 if ($wholefile =~ m/$NonNokiaCopyrPattern/is) |
|
813 { |
|
814 # The header might be empty due to weired file header style. |
|
815 # Check the whole file content, it could be non-nokia file? |
|
816 $modify = 0; # !!! Do not modify file !!! |
|
817 $willmodify = 0; |
|
818 my $failReason = ""; |
|
819 if (!checkPortionsCopyright(\$filecontent, 1, \$failReason)) |
|
820 { |
|
821 $UnclearCopyrCount++; |
|
822 printLog(LOG_INFO, "Non-Nokia copyright (#2) ". $full_filename . "\n"); |
|
823 printResult(HEADER_CONTEXT() . "$sep"."Non-Nokia copyright$failReason$sep$sep$sep$full_filename$sep$linenumtext\n"); |
|
824 } |
|
825 else |
|
826 { |
|
827 printResult(HEADER_CONTEXT() . "$sep"."Non-Nokia (portions Nokia) copyright$sep$sep$sep$full_filename$sep$linenumtext\n"); |
|
828 printLog(LOG_INFO, "Non-Nokia (portions Nokia) copyright ". $full_filename . "\n"); |
|
829 } |
|
830 close(FH); |
|
831 return; # Quit |
|
832 } |
|
833 |
|
834 # Check if header is already OK. |
|
835 # This is needed to keep Ex-Symbian C++ comment syntaxes. |
|
836 # Also, this avoid unncessary changes in headers. |
|
837 # NOTE ! If header need to be converted to a new format the check must return FALSE !!! |
|
838 my $license = licenceIdForOption(); |
|
839 if (checkHeader(\$filecontent, \$oldheader, $cm, $full_filename, $File::Find::dir, \$license)) |
|
840 { |
|
841 if (!checkNoMultipleLicenses(\$filecontent, \$oldheader, $cm, $full_filename, $File::Find::dir)) |
|
842 { |
|
843 printResult(HEADER_CONTEXT() . "$sep"."Multiple licenses$sep$sep$sep$full_filename$sep" ."1\n"); |
|
844 printLog(LOG_ERROR, "Multiple licenses:". $full_filename . "\n"); |
|
845 close(FH); |
|
846 return; # Failed |
|
847 } |
|
848 else |
|
849 { |
|
850 # Quit here, header OK |
|
851 printLog(LOG_INFO, "Header already OK ($license): $full_filename\n"); |
|
852 close(FH); |
|
853 return; # Quit |
|
854 } |
|
855 } |
|
856 |
|
857 # Check if Ex-Symbian file |
|
858 my $testheader = makeTestHeader(\$oldheader, 0, KEEP_SYMBIAN); |
|
859 if ($testheader =~ m/$ExternalToNokiaCopyrPattern/is) |
|
860 { |
|
861 # External copyright moved to Nokia |
|
862 my $txt = $1; |
|
863 $txt =~ s/,//; |
|
864 $ExternalToNokiaCopyr = 1; |
|
865 $ExternalToNokiaCopyrCount++; |
|
866 if ($isCPPcomment) |
|
867 { |
|
868 # Normalize the C++ header syntax back to C comment |
|
869 $modifiedFilecontent = &normalizeCppComment($header_regexp2,$filecontent, \$oldheader); |
|
870 printLog(LOG_DEBUG, "Normalized External header=($oldheader)\n"); |
|
871 } |
|
872 if ($testheader =~ /$copyrYearPattern/) |
|
873 { |
|
874 if ($& =~ /$copyrYearPattern2/) |
|
875 { |
|
876 $oldCopyrightYear = $&; |
|
877 } |
|
878 printLog(LOG_DEBUG, "Old copyright=($oldCopyrightYear)\n"); |
|
879 } |
|
880 printLog(LOG_INFO, "Copyright will be converted to Nokia: $full_filename\n"); |
|
881 printResult(HEADER_CONTEXT() . "$sep"."Converted copyright$sep$sep$sep$full_filename$sep$linenumtext\n"); |
|
882 } |
|
883 |
|
884 elsif ($oldheader =~ m/$NokiaCopyrPattern/is) |
|
885 { |
|
886 # Consider it to be Nokia copyright |
|
887 $s60header = 1; |
|
888 $NokiaCopyrCount++; |
|
889 printLog(LOG_DEBUG, "Nokia header=($full_filename)\n"); |
|
890 if ($isCPPcomment) |
|
891 { |
|
892 # Normalize the C++ header syntax back to C comment |
|
893 $modifiedFilecontent = &normalizeCppComment($header_regexp2, $filecontent, \$oldheader); |
|
894 printLog(LOG_DEBUG, "Normalized Nokia header=($oldheader)\n"); |
|
895 } |
|
896 if ($oldheader =~ /$copyrYearPattern/) |
|
897 { |
|
898 if ($& =~ /$copyrYearPattern2/) |
|
899 { |
|
900 $oldCopyrightYear = $&; |
|
901 } |
|
902 printLog(LOG_DEBUG, "Old copyright2=($oldCopyrightYear)\n"); |
|
903 } |
|
904 } |
|
905 elsif (! ($testheader =~ m/$CopyrPattern/is) ) |
|
906 { |
|
907 # No copyright in the header. |
|
908 $NoCopyrCount++; |
|
909 $noCopyr = 1; |
|
910 # printResult(HEADER_CONTEXT() . "$sep"."No Copyright$sep$sep$sep$full_filename$sep$linenumtext\n"); |
|
911 } |
|
912 else |
|
913 { |
|
914 $UnclearCopyrCount++; |
|
915 $modify = 0; # !!! Do not modify file !!! |
|
916 $willmodify = 0; |
|
917 printLog(LOG_ERROR, "UNCLEAR copyright ". $full_filename . "\n"); |
|
918 printResult(HEADER_CONTEXT() . "$sep"."UNCLEAR COPYRIGHT CASE$sep$sep$sep$full_filename$sep$linenumtext\n"); |
|
919 } |
|
920 |
|
921 |
|
922 # Get description from current header |
|
923 if ($oldheader =~ m/$cm\s*Description\s*\:(.*?)$cm\s*(Version)/s) |
|
924 { |
|
925 # Description followed by Version |
|
926 $description = $1; |
|
927 printLog(LOG_DEBUG, "Old description followed by version ($description)\n"); |
|
928 } else |
|
929 { |
|
930 # Description without Version |
|
931 # ORIG if ($oldheader =~ m/$cm?\s*Description\s*\:(.*?)$cm\s*(\n)/s) |
|
932 if ($oldheader =~ m/$cm?\s*Description\s*\:(.*?)($cm|$cm\/|\n)\s*\n/s) |
|
933 { |
|
934 $description = $1; |
|
935 printLog(LOG_DEBUG, "Old description not followed by version ($description)\n"); |
|
936 } |
|
937 } |
|
938 |
|
939 if ($isCcomment) |
|
940 { |
|
941 $description =~ s/\/\*.*//; # Remove possible /* |
|
942 $description =~ s/\*\/.*//; # Remove possible */ |
|
943 $description =~ s/\=//g; # Remove possible =/ |
|
944 } |
|
945 |
|
946 # Get contributors from old header |
|
947 if ( $oldheader =~ m/$cm\s*Contributors\s*\:(.*?)$cm\s*Description\s*\:/s) |
|
948 { |
|
949 $contributors = $1; |
|
950 printLog(LOG_DEBUG, "Old contributors ($contributors)\n"); |
|
951 } |
|
952 |
|
953 # Keep description text |
|
954 if($description) |
|
955 { |
|
956 $newheader =~ s/Description:[ \t]*\n/Description: $description/s; |
|
957 } |
|
958 |
|
959 |
|
960 #Keep contributor list |
|
961 if ($contributors) |
|
962 { |
|
963 $newheader =~ s/$cm[ \t]*Contributors:[ \t]*\n$cm[ \t]*\n/$cm2 Contributors:$contributors/s; |
|
964 } |
|
965 |
|
966 |
|
967 ################### |
|
968 # Modify the header |
|
969 ################### |
|
970 if($oldheader) |
|
971 { |
|
972 { |
|
973 # Update the old header to new one |
|
974 # Old header may be just a description comment, e.g. in script |
|
975 # |
|
976 |
|
977 if ($otherCopyr) |
|
978 { |
|
979 # Other copyright statement, do not touch ! |
|
980 printLog(LOG_DEBUG, "Non-Nokia file not modified: $full_filename\n"); |
|
981 } |
|
982 elsif ($noCopyr) |
|
983 { |
|
984 |
|
985 # No copyright statement |
|
986 if (!isGeneratedHeader(\$oldheader)) |
|
987 { |
|
988 # Just add new header |
|
989 $filecontent = $newheader . $filecontent; |
|
990 printLog(LOG_INFO, "New header will be added: $full_filename\n"); |
|
991 } |
|
992 else |
|
993 { |
|
994 printLog(LOG_INFO, "Generated file ignored: $full_filename\n"); |
|
995 } |
|
996 } |
|
997 else |
|
998 { |
|
999 # Replace the old external / S60 header |
|
1000 my $newHeaderCopyrYear; |
|
1001 if ($newheader =~ /$copyrYearPattern2/) |
|
1002 { |
|
1003 # This is picked up from newheader template in this script, so should work always ! |
|
1004 $newHeaderCopyrYear = $&; # Pick up year from new header |
|
1005 printLog(LOG_DEBUG, "Template header copyright=($newHeaderCopyrYear)\n"); |
|
1006 } |
|
1007 if (!$newHeaderCopyrYear) |
|
1008 { |
|
1009 # Anyway, some weired error happended |
|
1010 $newHeaderCopyrYear = DEFCOPYRIGHTYEAR; |
|
1011 } |
|
1012 |
|
1013 # Create new copyright years |
|
1014 if ($oldCopyrightYear && !($oldCopyrightYear =~ /$newHeaderCopyrYear/)) |
|
1015 { |
|
1016 # Keep the old copyright !!! |
|
1017 # !!! If adding new copyright year to old header, uncomment the next line !!! |
|
1018 # $oldCopyrightYear .= ",$newHeaderCopyrYear"; |
|
1019 } |
|
1020 if (!$oldCopyrightYear) |
|
1021 { |
|
1022 # Nothing found |
|
1023 $oldCopyrightYear = $newHeaderCopyrYear; |
|
1024 } |
|
1025 printLog(LOG_DEBUG, "New header copyright:$oldCopyrightYear\n"); |
|
1026 $newheader =~ s/$newHeaderCopyrYear/$oldCopyrightYear/; |
|
1027 printLog(LOG_DEBUG, "New header:$full_filename,($newheader)\n"); |
|
1028 if ($modifiedFilecontent) |
|
1029 { |
|
1030 $filecontent = $modifiedFilecontent; # Use the already modified content as basis |
|
1031 } |
|
1032 |
|
1033 # |
|
1034 # SET THE NEW HEADER |
|
1035 # |
|
1036 if (!($filecontent =~ s/$header_regexp/$newheader/s)) |
|
1037 { |
|
1038 printLog(LOG_ERROR, "FAILED to change file header: ". $full_filename . "\n"); |
|
1039 $LicenseChangeErrors++; |
|
1040 $modify = 0; # Can not modify on failure |
|
1041 $willmodify = 0; |
|
1042 } |
|
1043 else |
|
1044 { |
|
1045 printLog(LOG_INFO, "File header will be changed: $full_filename\n"); |
|
1046 } |
|
1047 } |
|
1048 } |
|
1049 } |
|
1050 else |
|
1051 { |
|
1052 if (!isGeneratedHeader(\$filecontent)) # Ensure file is not generated |
|
1053 { |
|
1054 # Missing old header, add new header as such |
|
1055 printLog(LOG_INFO, "Missing header will be added: $full_filename\n"); |
|
1056 $filecontent = $newheader."\n".$filecontent; |
|
1057 } |
|
1058 else |
|
1059 { |
|
1060 printLog(LOG_INFO, "Generated file ignored: $full_filename\n"); |
|
1061 } |
|
1062 } |
|
1063 |
|
1064 if ($description =~ m/^\s*$/g || $description =~ m/$descrTemplateOnly/) |
|
1065 { |
|
1066 $noDescrcount++; |
|
1067 if ($optDescription) |
|
1068 { |
|
1069 printResult(HEADER_CONTEXT() . "$sep"."Description missing$sep$sep$sep$full_filename$sep$linenumtext\n"); |
|
1070 } |
|
1071 } |
|
1072 |
|
1073 close(FH); |
|
1074 |
|
1075 if ($modify) |
|
1076 { |
|
1077 # Re-open the file for modifications |
|
1078 chmod 0777, $filename if !-w; # remove first R/O |
|
1079 open(FH, "+<$filename") or return printLog(LOG_ERROR, "Failed to open file for modifying: $full_filename\n"); |
|
1080 print FH $filecontent or printLog(LOG_ERROR, "Failed to modify file: $full_filename\n"); |
|
1081 truncate(FH, tell(FH)); |
|
1082 $modifiedFileCount++; |
|
1083 close(FH); |
|
1084 } |
|
1085 |
|
1086 if ($willmodify) |
|
1087 { |
|
1088 # Only for statistics |
|
1089 $willModifiedFileCount++; |
|
1090 } |
|
1091 |
|
1092 } |
|
1093 |
|
1094 |
|
1095 |
|
1096 ################################## |
|
1097 # Callback for the find function |
|
1098 # (postprocess) |
|
1099 # Note ! "no_chdir" not used |
|
1100 ################################## |
|
1101 sub postprocess |
|
1102 { |
|
1103 my $dir = $File::Find::dir; |
|
1104 printLog(LOG_DEBUG, "postprocess $dir\n"); |
|
1105 |
|
1106 return if (-e DISTRIBUTION_FILENAME); # Already exists ? |
|
1107 |
|
1108 my $full_filename = $dir . "/" . DISTRIBUTION_FILENAME; # Full name needed for results and log |
|
1109 my $filename = DISTRIBUTION_FILENAME; |
|
1110 |
|
1111 if ($ignorefilepattern && $full_filename =~ m/$ignorefilepattern/i) |
|
1112 { |
|
1113 printLog(LOG_DEBUG, "Missing file ignored by pattern: ". $full_filename . "\n"); |
|
1114 $ignoreCount++; |
|
1115 return; |
|
1116 } |
|
1117 |
|
1118 my $filecontent = ""; |
|
1119 my $stat = LICENSE_NONE; |
|
1120 $stat = &handleDistributionValue(\$filecontent, $full_filename); |
|
1121 if ($stat eq LICENSE_CHANGED && $optCreate && isDirectoryNonEmpty('.')) |
|
1122 { |
|
1123 # Create new distribution file to non-empty directory |
|
1124 printResult(DISTRIBUTION_CONTEXT() . "$sep"."New file$sep$sep$sep$full_filename$sep$linenumtext\n"); |
|
1125 if ($optModify) |
|
1126 { |
|
1127 # Without -modify it is possible to see what new files will created |
|
1128 createAndWriteFile(\$filecontent, $filename, $full_filename); |
|
1129 } |
|
1130 $createCount++; # For statistics |
|
1131 } |
|
1132 |
|
1133 |
|
1134 } |
|
1135 |
|
1136 |
|
1137 ################################## |
|
1138 # Callback for the find function |
|
1139 # (preprocess). Used by option -verify |
|
1140 # Note ! "no_chdir" not used |
|
1141 ################################## |
|
1142 sub preprocess |
|
1143 { |
|
1144 my $dir = $File::Find::dir; |
|
1145 printLog(LOG_DEBUG, "preprocess $dir\n"); |
|
1146 $lastDistributionValue = ""; # Empty first |
|
1147 |
|
1148 if (!isDirectoryNonEmpty('.')) |
|
1149 { |
|
1150 # Ignore empty dirs |
|
1151 return @_; # Return input args |
|
1152 } |
|
1153 if (!$optVerify) |
|
1154 { |
|
1155 return @_; # Return input args |
|
1156 } |
|
1157 |
|
1158 # |
|
1159 # Currently option -verify required !!! |
|
1160 # |
|
1161 |
|
1162 my $full_filename = $dir . "/" . DISTRIBUTION_FILENAME; # Full name needed for results and log |
|
1163 $full_filename =~ s/\\/\//g; # Standardize name |
|
1164 |
|
1165 my $filename = DISTRIBUTION_FILENAME; |
|
1166 if ($ignorefilepattern && $full_filename =~ m/$ignorefilepattern/i) |
|
1167 { |
|
1168 if (! ($dir =~ m/$INTERNAL/i) ) |
|
1169 { |
|
1170 return @_; |
|
1171 } |
|
1172 } |
|
1173 |
|
1174 # Check existency of the file |
|
1175 if (!open(FH, "<$filename")) |
|
1176 { |
|
1177 printResult(DISTRIBUTION_CONTEXT() . "$sep"."Distribution policy file missing$sep$sep$sep$full_filename$sep$linenumtext\n"); |
|
1178 $verifyFailedCount[VERI_MISSING_FILE]++; |
|
1179 return @_; # Return input args |
|
1180 } |
|
1181 |
|
1182 my $content = <FH>; # IF CONTENT CHECKS |
|
1183 close FH; |
|
1184 |
|
1185 $content =~ s/\n//g; # Remove all new-lines |
|
1186 $content =~ s/^\s+//g; # trim left |
|
1187 $content =~ s/\s+$//g; # trim right |
|
1188 $lastDistributionValue = $content; # Save to global variable for the sub handleVerify |
|
1189 |
|
1190 printLog(LOG_DEBUG, "$full_filename content=$content\n"); |
|
1191 |
|
1192 if ($dir =~ m/$INTERNAL/i) |
|
1193 { |
|
1194 if ( ($content eq SFL_DISTRIBUTION_VALUE) || ($content eq EPL_DISTRIBUTION_VALUE) ) |
|
1195 { |
|
1196 # Internal directory has SFL or EPL distribution value, something is wrong ! |
|
1197 my $comment = ""; # Leave it just empty |
|
1198 printResult(DISTRIBUTION_CONTEXT() . "$sep"."Internal directory going to SF (current value $content)$sep$comment$sep$sep$full_filename$sep$linenumtext\n"); |
|
1199 $verifyFailedCount[VERI_INTERNAL_TO_SF]++; |
|
1200 } |
|
1201 } |
|
1202 elsif (! (($content eq SFL_DISTRIBUTION_VALUE) || ($content eq EPL_DISTRIBUTION_VALUE))) |
|
1203 { |
|
1204 # Neither SFL nor EPL value |
|
1205 my $comment = getCommentText($content,0,"0,3,7,950", $full_filename); |
|
1206 my $isSFId = &isSFDistribution($content); |
|
1207 if (!$isSFId) |
|
1208 { |
|
1209 printResult(DISTRIBUTION_CONTEXT() . "$sep"."SFL or EPL value missing (current value $content)$sep$comment$sep$sep$full_filename$sep$linenumtext\n"); |
|
1210 $verifyFailedCount[VERI_MISSING_ID]++; |
|
1211 } |
|
1212 } |
|
1213 |
|
1214 return @_; # Return input args |
|
1215 |
|
1216 } |
|
1217 |
|
1218 ################################################## |
|
1219 # Read distribution file from given directory |
|
1220 ################################################## |
|
1221 sub readDistributionValue |
|
1222 { |
|
1223 |
|
1224 my $dir = shift; |
|
1225 |
|
1226 my $filename = DISTRIBUTION_FILENAME; |
|
1227 my $content = ""; |
|
1228 |
|
1229 if (open(FH, "<$filename")) |
|
1230 { |
|
1231 $content = <FH>; |
|
1232 close FH; |
|
1233 } |
|
1234 |
|
1235 $content =~ s/\n//g; # Remove all new-lines |
|
1236 $content =~ s/^\s+//g; # trim left |
|
1237 $content =~ s/\s+$//g; # trim right |
|
1238 |
|
1239 return $content; |
|
1240 } |
|
1241 |
|
1242 |
|
1243 ################################################## |
|
1244 # Make test header from given input text |
|
1245 ################################################## |
|
1246 sub makeTestHeader |
|
1247 { |
|
1248 my $ref = shift; # Input text reference |
|
1249 my $isWholeFile = shift; # $ref is the file content |
|
1250 my $removeExternalToNokia = shift; # Remove to Nokia transferreable copyright texts |
|
1251 |
|
1252 my $tstheader = ""; |
|
1253 |
|
1254 if (!$isWholeFile) |
|
1255 { |
|
1256 $tstheader = $$ref; |
|
1257 } |
|
1258 else |
|
1259 { |
|
1260 # To optimize, whole file == 10k !!! |
|
1261 # The proper header should be included in that amount of data. |
|
1262 $tstheader = substr($$ref, 0, 10*1024); |
|
1263 } |
|
1264 $tstheader =~ s/$NokiaCopyrPattern//gi; |
|
1265 $tstheader =~ s/$PortionsNokiaCopyrPattern//gi; |
|
1266 $tstheader =~ s/$RemoveS60TextBlockPattern//si; |
|
1267 if ($removeExternalToNokia) |
|
1268 { |
|
1269 $tstheader =~ s/$ExternalToNokiaCopyrPattern//gi; |
|
1270 $tstheader =~ s/$PortionsSymbianCopyrPattern//gi; |
|
1271 } |
|
1272 |
|
1273 # Take out special texts containing copyright word |
|
1274 $tstheader =~ s/Copyright\s*\(c\)\s*\.//gi; |
|
1275 $tstheader =~ s/COPYRIGHT[\s\n\*\#+;]*(HOLDER|OWNER|notice)//gi; |
|
1276 |
|
1277 return $tstheader; |
|
1278 } |
|
1279 |
|
1280 |
|
1281 ################################################## |
|
1282 # Check whether portions copyright is OK |
|
1283 # Call this for non Nokia cases only ! |
|
1284 ################################################## |
|
1285 sub checkPortionsCopyright |
|
1286 { |
|
1287 my $ref = shift; # Input text reference |
|
1288 my $isWholeFile = shift; # $ref is the file content |
|
1289 my $failReason_ref = shift; # check failure reason (OUT) |
|
1290 |
|
1291 my $tstheader = ""; |
|
1292 |
|
1293 if (!$isWholeFile) |
|
1294 { |
|
1295 $tstheader = $$ref; |
|
1296 } |
|
1297 else |
|
1298 { |
|
1299 # The portions info should be included within first 10 Kb of file |
|
1300 $tstheader = substr($$ref, 0, 10*1024); |
|
1301 } |
|
1302 |
|
1303 if ($tstheader =~ m/$PortionsSymbianCopyrPattern/is) |
|
1304 { |
|
1305 # Symbian portions copyright should be converted to Nokia one |
|
1306 if (!($tstheader =~ m/$PortionsNokiaCopyrPattern/is)) |
|
1307 { |
|
1308 $$failReason_ref = "(portions Symbian copyright)"; |
|
1309 } |
|
1310 else |
|
1311 { |
|
1312 $$failReason_ref = "(portions Nokia+Symbian copyright)"; |
|
1313 } |
|
1314 return 0; |
|
1315 } |
|
1316 |
|
1317 if (!($tstheader =~ m/$NewPortionsNokiaCopyrPattern/is)) |
|
1318 { |
|
1319 # No portions copyright present |
|
1320 $$failReason_ref = ""; |
|
1321 return 0; |
|
1322 } |
|
1323 |
|
1324 return 1; # Should be OK |
|
1325 } |
|
1326 |
|
1327 |
|
1328 ################################################## |
|
1329 # Get comment text by ID or filename |
|
1330 # Returns currently empty or value of the $IGNORE |
|
1331 ################################################## |
|
1332 sub getCommentText |
|
1333 { |
|
1334 my $distributionValue = shift; |
|
1335 my $contains = shift; |
|
1336 my $pattern = shift; |
|
1337 my $fullfilename = shift; |
|
1338 |
|
1339 if ($contains) |
|
1340 { |
|
1341 if ($pattern =~ m/$distributionValue/) |
|
1342 { |
|
1343 return $IGNORE; |
|
1344 } |
|
1345 } |
|
1346 else |
|
1347 { |
|
1348 # Not contains |
|
1349 if (!($pattern =~ m/$distributionValue/)) |
|
1350 { |
|
1351 return $IGNORE; |
|
1352 } |
|
1353 } |
|
1354 |
|
1355 my $ignoreThis = $manualIgnoreFileHash{lc($fullfilename)}; |
|
1356 if (defined $ignoreThis) |
|
1357 { |
|
1358 printLog(LOG_DEBUG, "$IGNORE_MAN 2: $fullfilename\n"); |
|
1359 return $IGNORE_MAN; |
|
1360 } |
|
1361 |
|
1362 return ""; |
|
1363 } |
|
1364 |
|
1365 |
|
1366 ################################################## |
|
1367 # Write content to file |
|
1368 ################################################## |
|
1369 sub writeFile |
|
1370 { |
|
1371 my $filecontent_ref = shift; |
|
1372 my $filename = shift; |
|
1373 my $full_filename = shift; |
|
1374 |
|
1375 my $fh; |
|
1376 |
|
1377 chmod 0777, $filename if !-w; # remove first R/O |
|
1378 open($fh, "+<$filename") or return printLog(LOG_ERROR, "Failed to open file for modifying: $full_filename\n"); |
|
1379 print $fh $$filecontent_ref or printLog(LOG_ERROR, "Failed to modify file: $full_filename\n"); |
|
1380 truncate($fh, tell($fh)); |
|
1381 close($fh); |
|
1382 |
|
1383 $modifiedFileCount++; |
|
1384 } |
|
1385 |
|
1386 ################################################## |
|
1387 # Create file and write content to file |
|
1388 ################################################## |
|
1389 sub createAndWriteFile |
|
1390 { |
|
1391 my $filecontent_ref = shift; |
|
1392 my $filename = shift; |
|
1393 my $full_filename = shift; |
|
1394 |
|
1395 my $fh; |
|
1396 |
|
1397 open($fh, ">$filename") or return printLog(LOG_ERROR, "Failed to create file: $full_filename\n"); |
|
1398 print $fh $$filecontent_ref or printLog(LOG_ERROR, "Failed to write file: $full_filename\n"); |
|
1399 close($fh); |
|
1400 } |
|
1401 |
|
1402 ################################## |
|
1403 # Check if current directory is empty |
|
1404 ################################## |
|
1405 sub isDirectoryNonEmpty |
|
1406 { |
|
1407 my ($dir) = @_; |
|
1408 opendir (DIR,$dir) or printLog(LOG_ERROR, "Can't opendir $dir\n"); |
|
1409 for(readdir DIR) |
|
1410 { |
|
1411 if (-f $_) |
|
1412 { |
|
1413 closedir DIR; |
|
1414 return 1; |
|
1415 }; |
|
1416 } |
|
1417 closedir DIR; |
|
1418 return 0; |
|
1419 } |
|
1420 |
|
1421 |
|
1422 ################################################## |
|
1423 # Change SFL back to S60, or |
|
1424 # Change SFl to EPL |
|
1425 # Returns LICENSE_CHANGED if function switched the license succesfully |
|
1426 ################################################## |
|
1427 # Switch only license text and URL |
|
1428 my $sflText = '"Symbian Foundation License v1.0"'; |
|
1429 my $sflTextPattern = '(the\s*License\s*)?\"Symbian\s*Foundation\s*License\s*v1\.0\"'; |
|
1430 my $sflUrlPattern = 'http\:\/\/www\.symbianfoundation\.org\/legal\/sfl\-v10\.html'; |
|
1431 my $sflUrl = 'http://www.symbianfoundation.org/legal/sf'.'l-v10.html'; |
|
1432 my $eplText = '"Eclipse Public License v1.0"'; |
|
1433 my $eplUrl = 'http://www.eclipse.org/legal/epl-v10.html'; |
|
1434 my $eplUrlPattern = 'http\:\/\/www\.eclipse\.org\/legal\/epl\-v10\.html'; |
|
1435 my $eplTextPattern = '"Eclipse\s*Public\s*License\s*v1\.0"'; |
|
1436 my $oldEplTextPattern = 'the\s*License\s*"Eclipse\s*Public\s*License\s*v1\.0'; # "the License" is unncessary |
|
1437 |
|
1438 sub switchLicense |
|
1439 { |
|
1440 my $filecontent_ref = shift; |
|
1441 my $header_ref = shift; |
|
1442 my $commentChar = shift; |
|
1443 my $fullfilename = shift; |
|
1444 my $isCPPcomment = shift; |
|
1445 |
|
1446 my $testValueSfl = ""; |
|
1447 my $testValueEpl = ""; |
|
1448 my $testValueS60 = ""; |
|
1449 |
|
1450 if ($isCPPcomment) |
|
1451 { |
|
1452 # xSymbian files use this style |
|
1453 $commentChar = '//'; |
|
1454 # in xSymbian files there are comments like, /// some text |
|
1455 $$filecontent_ref =~ s/(\/){3,}/\/\//g; # replace ///+ back to // |
|
1456 } |
|
1457 |
|
1458 |
|
1459 # In from value \* need to be escaped. |
|
1460 my $FromSFLText = &partialHeaderOf(SFL_LICENSE,$commentChar, \$testValueSfl); |
|
1461 my $FromEPLText = &partialHeaderOf(EPL_LICENSE,$commentChar, \$testValueEpl); |
|
1462 |
|
1463 $commentChar =~ s/\\//; # Remove \ from possible \* |
|
1464 my $ToS60Text = &partialHeaderOf(S60_LICENSE,$commentChar, \$testValueS60); |
|
1465 |
|
1466 # Note that partial headers are manually quoted in the declaration |
|
1467 # Otherwise \Q$SFLText\E and \Q$EPLText\E would be needed around those ones |
|
1468 # because plain text contains special chars, like . |
|
1469 |
|
1470 printLog(LOG_DEBUG, "switchLicense: $fullfilename, $testValueEpl\n"); |
|
1471 |
|
1472 if ($$filecontent_ref =~ m/$testValueSfl/s) |
|
1473 { |
|
1474 # SFL license |
|
1475 |
|
1476 if ($optOem) |
|
1477 { |
|
1478 # Switch from SFL to S60 |
|
1479 if (!($$filecontent_ref =~ s/$FromSFLText/$ToS60Text/s)) |
|
1480 { |
|
1481 printLog(LOG_ERROR, "FAILED to change SFL license to S60: ". $fullfilename . "\n"); |
|
1482 $LicenseChangeErrors++; |
|
1483 return LICENSE_ERROR; |
|
1484 } |
|
1485 printLog(LOG_WARNING, "License will be swicthed from SFL to S60: ". $fullfilename . "\n"); |
|
1486 $SflToS60Changes++; |
|
1487 return LICENSE_CHANGED; |
|
1488 } |
|
1489 elsif ($optEpl) |
|
1490 { |
|
1491 # Switch from SFL to EPL |
|
1492 if (! ( ($$filecontent_ref =~ s/$sflTextPattern/$eplText/s) && ($$filecontent_ref =~ s/$sflUrlPattern/$eplUrl/s) ) ) |
|
1493 { |
|
1494 printLog(LOG_ERROR, "FAILED to change SFL to EPL: ". $fullfilename . "\n"); |
|
1495 $LicenseChangeErrors++; |
|
1496 return LICENSE_ERROR; |
|
1497 } |
|
1498 else |
|
1499 { |
|
1500 printLog(LOG_INFO, "License will be switched from SFL to EPL: ". $fullfilename . "\n"); |
|
1501 } |
|
1502 $SflToEplChanges++; |
|
1503 return LICENSE_CHANGED; |
|
1504 } |
|
1505 } |
|
1506 |
|
1507 if ($$filecontent_ref =~ m/$testValueEpl/s) |
|
1508 { |
|
1509 if ($optOem) |
|
1510 { |
|
1511 printLog(LOG_ERROR, "Not supported to change EPL to S60: ". $fullfilename . "\n"); |
|
1512 return LICENSE_NOT_SUPPORTED; |
|
1513 } |
|
1514 elsif (!$optEpl) |
|
1515 { |
|
1516 # Switch from EPL to SFL |
|
1517 if (! ( ($$filecontent_ref =~ s/$eplTextPattern/$sflText/s) && ($$filecontent_ref =~ s/$eplUrlPattern/$sflUrl/s) ) ) |
|
1518 { |
|
1519 printLog(LOG_ERROR, "FAILED to change EPL to SFL: ". $fullfilename . "\n"); |
|
1520 $LicenseChangeErrors++; |
|
1521 return LICENSE_ERROR; |
|
1522 } |
|
1523 else |
|
1524 { |
|
1525 printLog(LOG_WARNING, "License will be switched from EPL to SFL: ". $fullfilename . "\n"); |
|
1526 } |
|
1527 $EplToSflChanges++; |
|
1528 return LICENSE_CHANGED; |
|
1529 } |
|
1530 |
|
1531 # EPL text cleanup (remove unncessary "the License") |
|
1532 if ($$filecontent_ref =~ m/$oldEplTextPattern/s) |
|
1533 { |
|
1534 # EPL header contains extra words, get rid of them (allow script replace old header) |
|
1535 if ($$filecontent_ref =~ s/$oldEplTextPattern/$eplText/s) |
|
1536 { |
|
1537 # Not error if fails |
|
1538 printLog(LOG_INFO, "Unnecessary \"the License\" will be removed: $fullfilename\n"); |
|
1539 return LICENSE_CHANGED; |
|
1540 } |
|
1541 } |
|
1542 |
|
1543 } |
|
1544 else |
|
1545 { |
|
1546 return LICENSE_NONE; # Allow caller decide |
|
1547 } |
|
1548 |
|
1549 } |
|
1550 |
|
1551 ################################################## |
|
1552 # Verify changes |
|
1553 ################################################## |
|
1554 sub handleVerify |
|
1555 { |
|
1556 my $filecontent_ref = shift; |
|
1557 my $header_ref = shift; |
|
1558 my $commentChar = shift; |
|
1559 my $fullfilename = shift; |
|
1560 my $directory = shift; |
|
1561 |
|
1562 my $testValueSfl = ""; |
|
1563 my $testValueEpl = ""; |
|
1564 my $FromSFLText = &partialHeaderOf(SFL_LICENSE,$commentChar, \$testValueSfl); |
|
1565 my $FromEPLText = &partialHeaderOf(EPL_LICENSE,$commentChar, \$testValueEpl); |
|
1566 |
|
1567 if ($lastDistributionValue eq "") |
|
1568 { |
|
1569 # Distribution file may be empty if giving single file as input |
|
1570 # Read it |
|
1571 $lastDistributionValue = readDistributionValue($directory); |
|
1572 } |
|
1573 |
|
1574 printLog(LOG_DEBUG, "handleVerify $fullfilename, $$header_ref\n"); |
|
1575 |
|
1576 # First check Non-Nokia copyright files |
|
1577 my $testheader = makeTestHeader($header_ref, 0, REMOVE_SYMBIAN); |
|
1578 if (($testheader =~ m/$NonNokiaCopyrPattern/is)) |
|
1579 { |
|
1580 printLog(LOG_DEBUG, "DEBUG:Extra check1 $&\n"); |
|
1581 if (!($testheader =~ m/$ExternalToNokiaCopyrPattern/si)) |
|
1582 { |
|
1583 # Non-nokia file |
|
1584 if ($testheader =~ m/$copyrYearPattern/si) |
|
1585 { |
|
1586 # Looks like copyright statement |
|
1587 printResult(HEADER_CONTEXT() . "$sep"."Non-Nokia copyright$sep" . "$IGNORE$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1588 $otherCopyrCount++; |
|
1589 $verifyFailedCount[VERI_OK_NON_NOKIA]++; |
|
1590 return 1; # OK |
|
1591 } |
|
1592 else |
|
1593 { |
|
1594 # Incomplete copyright ? |
|
1595 printResult(HEADER_CONTEXT() . "$sep"."Non-Nokia incomplete copyright$sep" . "$IGNORE?$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1596 $verifyFailedCount[VERI_OK]++; |
|
1597 return 0; |
|
1598 } |
|
1599 } |
|
1600 } |
|
1601 |
|
1602 # The header might be empty due to weired file header style. |
|
1603 # Check the whole file content, it could be non-nokia file? |
|
1604 my $filestart = makeTestHeader($filecontent_ref, 1, REMOVE_SYMBIAN); |
|
1605 |
|
1606 if ($filestart =~ m/$NonNokiaCopyrPattern/is) |
|
1607 { |
|
1608 # There is Non-Nokia copyright statement in the file |
|
1609 if (($filestart =~ m/$testValueSfl/is) || ($filestart =~ m/$testValueEpl/is)) |
|
1610 { |
|
1611 # Non-Nokia file, but still SFL or EPL header |
|
1612 printResult(HEADER_CONTEXT() . "$sep"."UNCLEAR Non-Nokia copyright with SFL/EPL$sep" . "$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1613 $verifyFailedCount[VERI_UNCLEAR_COPYR]++; |
|
1614 return 0; |
|
1615 } |
|
1616 elsif ($$filecontent_ref =~ m/$OldNokiaPattern2/is) |
|
1617 { |
|
1618 printResult(HEADER_CONTEXT() . "$sep"."UNCLEAR Old Nokia copyright$sep" . "$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1619 $verifyFailedCount[VERI_OLD_NOKIA_HEADER]++; |
|
1620 return 0; |
|
1621 } |
|
1622 else |
|
1623 { |
|
1624 # Non-Nokia file |
|
1625 my $failReason = ""; |
|
1626 if (!checkPortionsCopyright($filecontent_ref, 1, \$failReason)) |
|
1627 { |
|
1628 printResult(HEADER_CONTEXT() . "$sep"."UNCLEAR Non-Nokia copyright$failReason$sep" . "$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1629 $verifyFailedCount[VERI_UNCLEAR_COPYR]++; |
|
1630 return 0; |
|
1631 } |
|
1632 else |
|
1633 { |
|
1634 # Contains portions copyright |
|
1635 printResult(HEADER_CONTEXT() . "$sep"."Non-Nokia (portions Nokia) copyright$sep" . "$IGNORE$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1636 return 1; |
|
1637 } |
|
1638 } |
|
1639 } |
|
1640 |
|
1641 # |
|
1642 # OK, it should be Nokia copyrighted file |
|
1643 # |
|
1644 |
|
1645 # Note that partial headers are manually quoted in the declaration |
|
1646 # Otherwise \Q$SFLText\E and \Q$EPLText\E would be needed around those ones |
|
1647 # because plain text contains special chars, like . |
|
1648 printLog(LOG_DEBUG, "handleVerify testheaders: $testValueSfl,$testValueEpl,$$header_ref\n"); |
|
1649 |
|
1650 if ( !( ($$header_ref =~ m/$testValueSfl/s) || ($$header_ref =~ m/$testValueEpl/s) || |
|
1651 ($$filecontent_ref =~ m/$testValueSfl/s) || ($$filecontent_ref =~ m/$testValueEpl/s) |
|
1652 ) ) |
|
1653 { |
|
1654 # Header not found from header or whole file |
|
1655 if (isGeneratedHeader($header_ref) || isGeneratedHeader($filecontent_ref)) |
|
1656 { |
|
1657 # OK, it is generated header |
|
1658 if ($optOutputOK) |
|
1659 { |
|
1660 printResult(HEADER_CONTEXT() . "$sep"."OK$sep" . "Generated header$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1661 } |
|
1662 $verifyFailedCount[VERI_OK]++; |
|
1663 return 1; # OK |
|
1664 } |
|
1665 |
|
1666 my $comment = getCommentText($lastDistributionValue, 0, "0,3,7", $fullfilename); |
|
1667 if (($$header_ref =~ m/$OldNokiaPattern2/is) || ($$filecontent_ref =~ m/$OldNokiaPattern2/is)) |
|
1668 { |
|
1669 printResult(HEADER_CONTEXT() . "$sep"."SFL or EPL header missing (old Nokia copyright)$sep$comment$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1670 } |
|
1671 else |
|
1672 { |
|
1673 printResult(HEADER_CONTEXT() . "$sep"."SFL or EPL header missing$sep$comment$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1674 } |
|
1675 $verifyFailedCount[VERI_MISSING_HEADER]++; |
|
1676 return 0; |
|
1677 } |
|
1678 |
|
1679 # Cross header versus distribution ID |
|
1680 if ($lastDistributionValue ne "") |
|
1681 { |
|
1682 # Also other than 3 or 7 may be OK based on the config file |
|
1683 my $isSFId = &isSFDistribution($lastDistributionValue); |
|
1684 printLog(LOG_DEBUG, "DEBUG:handleVerify:Other ID OK=$isSFId\n"); |
|
1685 if ( (($$header_ref =~ m/$testValueSfl/s) || ($$filecontent_ref =~ m/$testValueSfl/s)) && !$isSFId) |
|
1686 { |
|
1687 my $comment = getCommentText($lastDistributionValue, 0, "0,3,7", $fullfilename); |
|
1688 printResult(HEADER_CONTEXT() . "$sep"."SFL header vs. distribution id ($lastDistributionValue) mismatch$sep$comment$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1689 $verifyFailedCount[VERI_ID_HEADER_MISMATCH]++; |
|
1690 return 0; |
|
1691 } |
|
1692 if ( (($$header_ref =~ m/$testValueEpl/s) || ($$filecontent_ref =~ m/$testValueEpl/s)) && !$isSFId ) |
|
1693 { |
|
1694 my $comment = getCommentText($lastDistributionValue, 0, "0,3,7", $fullfilename); |
|
1695 printResult(HEADER_CONTEXT() . "$sep"."EPL header vs. distribution id ($lastDistributionValue) mismatch$sep$comment$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1696 $verifyFailedCount[VERI_ID_HEADER_MISMATCH]++; |
|
1697 return 0; |
|
1698 } |
|
1699 } |
|
1700 |
|
1701 if (!checkNoMultipleLicenses($filecontent_ref, $header_ref, $commentChar, $fullfilename, $directory)) |
|
1702 { |
|
1703 printResult(HEADER_CONTEXT() . "$sep"."Multiple licenses$sep$sep$sep$fullfilename$sep" ."1\n"); |
|
1704 printLog(LOG_ERROR, "Multiple licenses:". $fullfilename . "\n"); |
|
1705 $verifyFailedCount[VERI_MULTIPLE_LICENSES]++; |
|
1706 return 0; # Failed |
|
1707 } |
|
1708 |
|
1709 |
|
1710 # We should have proper header in place |
|
1711 |
|
1712 printLog(LOG_DEBUG, "handleVerify: $$filecontent_ref\n"); |
|
1713 # Check New Nokia copyright pattern (added one sentence to the old one) |
|
1714 if (! (($$header_ref =~ m/$NewNokiaPattern/s) || ($$filecontent_ref =~ m/$NewNokiaPattern/s)) ) |
|
1715 { |
|
1716 my $comment = getCommentText($lastDistributionValue, 0, "0,3,7,950", $fullfilename); |
|
1717 printResult(HEADER_CONTEXT() . "$sep"."Proper Nokia copyright statement missing$sep$comment$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1718 $verifyFailedCount[VERI_PROPER_COPYRIGHT]++; |
|
1719 return 0; # Failed |
|
1720 } |
|
1721 |
|
1722 if ($optOutputOK) |
|
1723 { |
|
1724 printResult(HEADER_CONTEXT() . "$sep"."OK$sep" . "OK$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1725 } |
|
1726 $verifyFailedCount[VERI_OK]++; |
|
1727 |
|
1728 return 1; |
|
1729 |
|
1730 } |
|
1731 |
|
1732 |
|
1733 ################################################## |
|
1734 # Verify changes |
|
1735 ################################################## |
|
1736 sub handleVerifyEpl |
|
1737 { |
|
1738 my $filecontent_ref = shift; |
|
1739 my $header_ref = shift; |
|
1740 my $commentChar = shift; |
|
1741 my $fullfilename = shift; |
|
1742 my $directory = shift; |
|
1743 |
|
1744 my $testValueSfl = ""; |
|
1745 my $testValueEpl = ""; |
|
1746 my $FromSFLText = &partialHeaderOf(SFL_LICENSE,$commentChar, \$testValueSfl); |
|
1747 my $FromEPLText = &partialHeaderOf(EPL_LICENSE,$commentChar, \$testValueEpl); |
|
1748 |
|
1749 if ($lastDistributionValue eq "") |
|
1750 { |
|
1751 # Distribution file may be empty if giving single file as input |
|
1752 # Read it |
|
1753 $lastDistributionValue = readDistributionValue($directory); |
|
1754 } |
|
1755 |
|
1756 printLog(LOG_DEBUG, "handleVerifyEpl $fullfilename, $$header_ref\n"); |
|
1757 |
|
1758 # First check Non-Nokia copyright files |
|
1759 my $testheader = makeTestHeader($header_ref, 0, REMOVE_SYMBIAN); |
|
1760 if (($testheader =~ m/$NonNokiaCopyrPattern/is)) |
|
1761 { |
|
1762 printLog(LOG_DEBUG, "DEBUG:Extra check1 $&\n"); |
|
1763 if (!($testheader =~ m/$ExternalToNokiaCopyrPattern/si)) |
|
1764 { |
|
1765 # Non-nokia file |
|
1766 if ($testheader =~ m/$copyrYearPattern/si) |
|
1767 { |
|
1768 # Looks like copyright statement |
|
1769 printResult(HEADER_CONTEXT() . "$sep"."Non-Nokia copyright$sep" . "$IGNORE$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1770 $otherCopyrCount++; |
|
1771 $verifyFailedCount[VERI_OK_NON_NOKIA]++; |
|
1772 return 1; # OK |
|
1773 } |
|
1774 else |
|
1775 { |
|
1776 # Incomplete copyright ? |
|
1777 printResult(HEADER_CONTEXT() . "$sep"."Non-Nokia incomplete copyright$sep" . "$IGNORE?$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1778 $verifyFailedCount[VERI_OK]++; |
|
1779 return 0; |
|
1780 } |
|
1781 } |
|
1782 } |
|
1783 |
|
1784 # The header might be empty due to weired file header style. |
|
1785 # Check the whole file content, it could be non-nokia file? |
|
1786 my $filestart = makeTestHeader($filecontent_ref, 1, REMOVE_SYMBIAN); |
|
1787 |
|
1788 if ($filestart =~ m/$NonNokiaCopyrPattern/is) |
|
1789 { |
|
1790 # There is Non-Nokia copyright statement in the file |
|
1791 if ($filestart =~ m/$testValueEpl/is) |
|
1792 { |
|
1793 # Non-Nokia file, but still EPL header |
|
1794 printResult(HEADER_CONTEXT() . "$sep"."UNCLEAR Non-Nokia copyright with EPL$sep" . "$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1795 $verifyFailedCount[VERI_UNCLEAR_COPYR]++; |
|
1796 return 0; |
|
1797 } |
|
1798 elsif ($$filecontent_ref =~ m/$OldNokiaPattern2/is) |
|
1799 { |
|
1800 printResult(HEADER_CONTEXT() . "$sep"."UNCLEAR Old Nokia copyright$sep" . "$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1801 $verifyFailedCount[VERI_OLD_NOKIA_HEADER]++; |
|
1802 return 0; |
|
1803 } |
|
1804 else |
|
1805 { |
|
1806 # Non-Nokia file |
|
1807 my $failReason = ""; |
|
1808 if (!checkPortionsCopyright($filecontent_ref, 1, \$failReason)) |
|
1809 { |
|
1810 printResult(HEADER_CONTEXT() . "$sep"."UNCLEAR Non-Nokia copyright$failReason$sep" . "$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1811 $verifyFailedCount[VERI_UNCLEAR_COPYR]++; |
|
1812 return 0; |
|
1813 } |
|
1814 else |
|
1815 { |
|
1816 # Contains portions copyright |
|
1817 printResult(HEADER_CONTEXT() . "$sep"."Non-Nokia (portions Nokia) copyright$sep" . "$IGNORE$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1818 return 1; |
|
1819 } |
|
1820 } |
|
1821 } |
|
1822 |
|
1823 # |
|
1824 # OK, it should be Nokia copyrighted file |
|
1825 # |
|
1826 |
|
1827 # Note that partial headers are manually quoted in the declaration |
|
1828 # Otherwise \Q$EPLText\E would be needed around those ones |
|
1829 # because plain text contains special chars, like . |
|
1830 printLog(LOG_DEBUG, "handleVerify testheaders: $testValueEpl,$$header_ref\n"); |
|
1831 |
|
1832 if ( !( ($$header_ref =~ m/$testValueEpl/s) || ($$filecontent_ref =~ m/$testValueEpl/s) ) ) |
|
1833 { |
|
1834 # Header not found from header or whole file |
|
1835 if (isGeneratedHeader($header_ref) || isGeneratedHeader($filecontent_ref)) |
|
1836 { |
|
1837 # OK, it is generated header |
|
1838 if ($optOutputOK) |
|
1839 { |
|
1840 printResult(HEADER_CONTEXT() . "$sep"."OK$sep" . "Generated header$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1841 } |
|
1842 $verifyFailedCount[VERI_OK]++; |
|
1843 return 1; # OK |
|
1844 } |
|
1845 |
|
1846 if (($$header_ref =~ m/$testValueSfl/s) || ($$filecontent_ref =~ m/$testValueSfl/s)) |
|
1847 { |
|
1848 # Still SFL header in place |
|
1849 printResult(HEADER_CONTEXT() . "$sep"."EPL header missing (SFL header used)$sep$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1850 } |
|
1851 elsif (($$header_ref =~ m/$OldNokiaPattern2/is) || ($$filecontent_ref =~ m/$OldNokiaPattern2/is)) |
|
1852 { |
|
1853 printResult(HEADER_CONTEXT() . "$sep"."EPL header missing (old Nokia copyright)$sep$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1854 } |
|
1855 else |
|
1856 { |
|
1857 printResult(HEADER_CONTEXT() . "$sep"."EPL header missing$sep$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1858 } |
|
1859 $verifyFailedCount[VERI_MISSING_HEADER]++; |
|
1860 return 0; |
|
1861 } |
|
1862 |
|
1863 # Cross header versus distribution ID |
|
1864 if ($lastDistributionValue ne "") |
|
1865 { |
|
1866 # Also other than 7 may be OK based on the config file |
|
1867 my $isSFId = &isSFDistribution($lastDistributionValue); |
|
1868 printLog(LOG_DEBUG, "DEBUG:handleVerify:Other ID OK=$isSFId\n"); |
|
1869 if ( ($$filecontent_ref =~ m/$testValueEpl/s) && ($lastDistributionValue ne EPL_DISTRIBUTION_VALUE) ) |
|
1870 { |
|
1871 printResult(HEADER_CONTEXT() . "$sep"."EPL header vs. distribution id ($lastDistributionValue) mismatch$sep$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1872 $verifyFailedCount[VERI_ID_HEADER_MISMATCH]++; |
|
1873 return 0; |
|
1874 } |
|
1875 } |
|
1876 |
|
1877 if (!checkNoMultipleLicenses($filecontent_ref, $header_ref, $commentChar, $fullfilename, $directory)) |
|
1878 { |
|
1879 printResult(HEADER_CONTEXT() . "$sep"."Multiple licenses$sep$sep$sep$fullfilename$sep" ."1\n"); |
|
1880 printLog(LOG_ERROR, "Multiple licenses:". $fullfilename . "\n"); |
|
1881 $verifyFailedCount[VERI_MULTIPLE_LICENSES]++; |
|
1882 return 0; # Failed |
|
1883 } |
|
1884 |
|
1885 |
|
1886 # We should have proper header in place |
|
1887 |
|
1888 printLog(LOG_DEBUG, "handleVerify: $$filecontent_ref\n"); |
|
1889 # Check New Nokia copyright pattern (added one sentence to the old one) |
|
1890 if (! (($$header_ref =~ m/$NewNokiaPattern/s) || ($$filecontent_ref =~ m/$NewNokiaPattern/s)) ) |
|
1891 { |
|
1892 printResult(HEADER_CONTEXT() . "$sep"."Proper Nokia copyright statement missing$sep$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1893 $verifyFailedCount[VERI_PROPER_COPYRIGHT]++; |
|
1894 return 0; # Failed |
|
1895 } |
|
1896 |
|
1897 if ($optOutputOK) |
|
1898 { |
|
1899 printResult(HEADER_CONTEXT() . "$sep"."OK$sep" . "OK$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1900 } |
|
1901 $verifyFailedCount[VERI_OK]++; |
|
1902 |
|
1903 return 1; |
|
1904 |
|
1905 } |
|
1906 |
|
1907 |
|
1908 |
|
1909 ################################################## |
|
1910 # Verify changes for LGPL headers |
|
1911 ################################################## |
|
1912 sub handleVerifyLgpl |
|
1913 { |
|
1914 my $filecontent_ref = shift; |
|
1915 my $header_ref = shift; |
|
1916 my $commentChar = shift; |
|
1917 my $fullfilename = shift; |
|
1918 my $directory = shift; |
|
1919 |
|
1920 my $testValueLgpl = ""; |
|
1921 my $FromLgplText = &partialHeaderOf(LGPL_LICENSE,$commentChar, \$testValueLgpl); |
|
1922 |
|
1923 if ($lastDistributionValue eq "") |
|
1924 { |
|
1925 # Distribution file may be empty if giving single file as input |
|
1926 # Read it |
|
1927 $lastDistributionValue = readDistributionValue($directory); |
|
1928 } |
|
1929 |
|
1930 printLog(LOG_DEBUG, "handleVerifyLgpl $fullfilename, $$header_ref\n"); |
|
1931 |
|
1932 # Note that partial headers are manually quoted in the declaration |
|
1933 # Otherwise \Q$SFLText\E and \Q$EPLText\E would be needed around those ones |
|
1934 # because plain text contains special chars, like . |
|
1935 printLog(LOG_DEBUG, "handleVerifyLgpl testheaders: $testValueLgpl,$$header_ref\n"); |
|
1936 |
|
1937 if ( !( ($$header_ref =~ m/$testValueLgpl/s) || ($$filecontent_ref =~ m/$testValueLgpl/s) ) ) |
|
1938 { |
|
1939 # Header not found from header or whole file |
|
1940 if (isGeneratedHeader($header_ref) || isGeneratedHeader($filecontent_ref)) |
|
1941 { |
|
1942 # OK, it is generated header |
|
1943 if ($optOutputOK) |
|
1944 { |
|
1945 printResult(HEADER_CONTEXT() . "$sep"."OK$sep" . "Generated header$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1946 } |
|
1947 $verifyFailedCount[VERI_OK]++; |
|
1948 return 1; # OK |
|
1949 } |
|
1950 |
|
1951 my $comment = getCommentText($lastDistributionValue, 0, "0,3,7", $fullfilename); |
|
1952 if (($$header_ref =~ m/$OldNokiaPattern2/is) || ($$filecontent_ref =~ m/$OldNokiaPattern2/is)) |
|
1953 { |
|
1954 printResult(HEADER_CONTEXT() . "$sep"."LGPL header missing (old Nokia copyright)$sep$comment$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1955 } |
|
1956 else |
|
1957 { |
|
1958 printResult(HEADER_CONTEXT() . "$sep"."LGPL header missing$sep$comment$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1959 } |
|
1960 $verifyFailedCount[VERI_MISSING_HEADER]++; |
|
1961 return 0; |
|
1962 } |
|
1963 |
|
1964 if (!checkNoMultipleLicenses($filecontent_ref, $header_ref, $commentChar, $fullfilename, $directory)) |
|
1965 { |
|
1966 printResult(HEADER_CONTEXT() . "$sep"."Multiple licenses$sep$sep$sep$fullfilename$sep" ."1\n"); |
|
1967 printLog(LOG_ERROR, "Multiple licenses:". $fullfilename . "\n"); |
|
1968 $verifyFailedCount[VERI_MULTIPLE_LICENSES]++; |
|
1969 return 0; # Failed |
|
1970 } |
|
1971 |
|
1972 |
|
1973 if ($optOutputOK) |
|
1974 { |
|
1975 printResult(HEADER_CONTEXT() . "$sep"."OK$sep" . "OK$sep$lastDistributionValue$sep$fullfilename$sep$linenumtext\n"); |
|
1976 } |
|
1977 |
|
1978 $verifyFailedCount[VERI_OK]++; |
|
1979 |
|
1980 return 1; |
|
1981 |
|
1982 } |
|
1983 |
|
1984 |
|
1985 ################################################## |
|
1986 # Test if header is already OK |
|
1987 # NOTE ! If header need to be converted to a new format, the |
|
1988 # check must return FALSE !!! |
|
1989 ################################################## |
|
1990 sub checkHeader |
|
1991 { |
|
1992 my $filecontent_ref = shift; |
|
1993 my $header_ref = shift; |
|
1994 my $commentChar = shift; |
|
1995 my $fullfilename = shift; |
|
1996 my $directory = shift; |
|
1997 my $req_license_ref = shift; # in/out !!! |
|
1998 |
|
1999 my $testValueSfl = ""; |
|
2000 my $testValueEpl = ""; |
|
2001 my $testValueLgpl = ""; |
|
2002 |
|
2003 my $FromSFLText = &partialHeaderOf(SFL_LICENSE,$commentChar, \$testValueSfl); |
|
2004 my $FromEPLText = &partialHeaderOf(EPL_LICENSE,$commentChar, \$testValueEpl); |
|
2005 my $FromLGPLText = &partialHeaderOf(LGPL_LICENSE,$commentChar, \$testValueLgpl); |
|
2006 |
|
2007 # Note that partial headers are manually quoted in the declaration |
|
2008 # Otherwise \Q$SFLText\E and \Q$EPLText\E would be needed around those ones |
|
2009 # because plain text contains special chars, like . |
|
2010 |
|
2011 my $retLicense = SFL_LICENSE; # default |
|
2012 my $testValue = $testValueSfl; |
|
2013 |
|
2014 if ($$req_license_ref == EPL_LICENSE) |
|
2015 { |
|
2016 $testValue = $testValueEpl; |
|
2017 $retLicense = EPL_LICENSE; |
|
2018 } |
|
2019 elsif ($$req_license_ref == LGPL_LICENSE) |
|
2020 { |
|
2021 $testValue = $testValueLgpl; |
|
2022 $retLicense = LGPL_LICENSE; |
|
2023 } |
|
2024 |
|
2025 my $ret = 0; |
|
2026 $ret = ($$header_ref =~ m/$testValue/s); |
|
2027 if (!$ret) |
|
2028 { |
|
2029 # Check the rest of file |
|
2030 $ret = ($$filecontent_ref =~ m/$testValue/s); |
|
2031 } |
|
2032 |
|
2033 printLog(LOG_DEBUG, "checkHeader return=$ret\n"); |
|
2034 |
|
2035 if ($ret) |
|
2036 { |
|
2037 $$req_license_ref = $retLicense; |
|
2038 } |
|
2039 |
|
2040 return $ret; |
|
2041 } |
|
2042 |
|
2043 |
|
2044 ################################################## |
|
2045 # Test if file does not contain multiple licenses |
|
2046 # Returns 0 if test failed |
|
2047 ################################################## |
|
2048 sub checkNoMultipleLicenses |
|
2049 { |
|
2050 my $filecontent_ref = shift; |
|
2051 my $header_ref = shift; |
|
2052 my $commentChar = shift; |
|
2053 my $fullfilename = shift; |
|
2054 my $directory = shift; |
|
2055 |
|
2056 my $usedLicense = SFL_LICENSE; |
|
2057 my $licenseCnt = 0; |
|
2058 if (checkHeader($filecontent_ref, $header_ref, $commentChar, $fullfilename, $directory, \$usedLicense)) |
|
2059 { |
|
2060 printLog(LOG_DEBUG, "checkNoMultipleLicenses SFL: $fullfilename\n"); |
|
2061 $licenseCnt++; |
|
2062 } |
|
2063 |
|
2064 $usedLicense = EPL_LICENSE; |
|
2065 if (checkHeader($filecontent_ref, $header_ref, $commentChar, $fullfilename, $directory, \$usedLicense)) |
|
2066 { |
|
2067 printLog(LOG_DEBUG, "checkNoMultipleLicenses EPL: $fullfilename\n"); |
|
2068 $licenseCnt++; |
|
2069 } |
|
2070 |
|
2071 $usedLicense = LGPL_LICENSE; |
|
2072 if (checkHeader($filecontent_ref, $header_ref, $commentChar, $fullfilename, $directory, \$usedLicense)) |
|
2073 { |
|
2074 printLog(LOG_DEBUG, "checkNoMultipleLicenses LGPL: $fullfilename\n"); |
|
2075 $licenseCnt++; |
|
2076 } |
|
2077 |
|
2078 if ($licenseCnt > 1) |
|
2079 { |
|
2080 return 0; # check failed |
|
2081 } |
|
2082 return 1; |
|
2083 } |
|
2084 |
|
2085 ################################################## |
|
2086 # Change distribution value |
|
2087 # Can also be called with empty file content |
|
2088 ################################################## |
|
2089 sub handleDistributionValue |
|
2090 { |
|
2091 my $filecontent_ref = shift; |
|
2092 my $filename = shift; |
|
2093 my $content = $$filecontent_ref; |
|
2094 |
|
2095 if ($optVerify) |
|
2096 { |
|
2097 # Ignored |
|
2098 return LICENSE_NONE; |
|
2099 } |
|
2100 |
|
2101 $content =~ s/\n//g; # Remove all new-lines |
|
2102 $content =~ s/^\s+//g; # trim left |
|
2103 $content =~ s/\s+$//g; # trim right |
|
2104 |
|
2105 if ($content ne "" && $content ne ZERO_DISTRIBUTION_VALUE) |
|
2106 { |
|
2107 if ($optEpl && ($content eq SFL_DISTRIBUTION_VALUE )) |
|
2108 { |
|
2109 # Allow switching SFL to EPL |
|
2110 $$filecontent_ref = EPL_DISTRIBUTION_VALUE; |
|
2111 printLog(LOG_INFO, "Distribution value changed from $content to $$filecontent_ref: $filename\n"); |
|
2112 return LICENSE_CHANGED; |
|
2113 } |
|
2114 else |
|
2115 { |
|
2116 # Otheriwise do not touch non-zero files ! (agreed with build team) |
|
2117 $ignoreCount++; |
|
2118 return LICENSE_NONE; |
|
2119 } |
|
2120 } |
|
2121 |
|
2122 if ($optOem) |
|
2123 { |
|
2124 # Leave existing (or missing) value as it was |
|
2125 return LICENSE_NONE; |
|
2126 } |
|
2127 elsif ($optEpl) |
|
2128 { |
|
2129 $$filecontent_ref = EPL_DISTRIBUTION_VALUE; |
|
2130 printLog(LOG_INFO, "Distribution value changed from $content to $$filecontent_ref: $filename\n"); |
|
2131 return LICENSE_CHANGED; |
|
2132 } |
|
2133 else # SFL |
|
2134 { |
|
2135 $$filecontent_ref = SFL_DISTRIBUTION_VALUE; |
|
2136 printLog(LOG_INFO, "Distribution value changed from $content to $$filecontent_ref: $filename\n"); |
|
2137 return LICENSE_CHANGED; |
|
2138 } |
|
2139 |
|
2140 return LICENSE_NONE; |
|
2141 |
|
2142 } |
|
2143 |
|
2144 ################################################## |
|
2145 # Select proper |
|
2146 ################################################## |
|
2147 sub licenceIdForOption |
|
2148 { |
|
2149 if ($optEpl) |
|
2150 { |
|
2151 return EPL_LICENSE; |
|
2152 } |
|
2153 elsif ($optLgpl) |
|
2154 { |
|
2155 return LGPL_LICENSE; |
|
2156 } |
|
2157 else # Must be |
|
2158 { |
|
2159 return SFL_LICENSE; |
|
2160 } |
|
2161 } |
|
2162 |
|
2163 |
|
2164 ################################################## |
|
2165 # Select proper header |
|
2166 ################################################## |
|
2167 sub headerOf |
|
2168 { |
|
2169 my $style = shift; |
|
2170 |
|
2171 if ($style < 0 || $style > 1) |
|
2172 { |
|
2173 printLog(LOG_ALWAYS, "INTERNAL ERROR: Header index out of bounds:$style. Exiting.\n"); |
|
2174 exit 1; |
|
2175 } |
|
2176 |
|
2177 my $ref; |
|
2178 if ($optEpl) |
|
2179 { |
|
2180 $ref = $EplHeaders[$style]; |
|
2181 } |
|
2182 elsif ($optLgpl) |
|
2183 { |
|
2184 $ref = $LgplHeaders[$style]; |
|
2185 } |
|
2186 else # SFL |
|
2187 { |
|
2188 $ref = $SflHeaders[$style]; |
|
2189 } |
|
2190 |
|
2191 # Return the actual value |
|
2192 return $$ref; |
|
2193 } |
|
2194 |
|
2195 ################################################## |
|
2196 # Select proper partial header |
|
2197 ################################################## |
|
2198 sub partialHeaderOf |
|
2199 { |
|
2200 my $license = shift; |
|
2201 my $commentChar = shift; |
|
2202 my $testValue_ref = shift; |
|
2203 |
|
2204 my $ref; |
|
2205 my $ref2; |
|
2206 if ($license eq EPL_LICENSE) |
|
2207 { |
|
2208 $ref = $EplHeaders[2]; |
|
2209 $ref2 = $EplHeaders[3]; |
|
2210 } |
|
2211 elsif ($license eq S60_LICENSE) |
|
2212 { |
|
2213 $ref = $S60Headers[2]; |
|
2214 $ref2 = $S60Headers[3]; |
|
2215 } |
|
2216 elsif ($license eq LGPL_LICENSE) |
|
2217 { |
|
2218 $ref = $LgplHeaders[2]; |
|
2219 $ref2 = $LgplHeaders[3]; |
|
2220 } |
|
2221 elsif ($license eq SFL_LICENSE) |
|
2222 { |
|
2223 # SFL License |
|
2224 $ref = $SflHeaders[2]; |
|
2225 $ref2 = $SflHeaders[3]; # return value |
|
2226 } |
|
2227 else |
|
2228 { |
|
2229 printLog(LOG_ALWAYS, "INTERNAL ERROR: Invalid license parameter :$license. Exiting.\n"); |
|
2230 exit 1; |
|
2231 } |
|
2232 |
|
2233 # Switch to proper comment char |
|
2234 my $ret = $$ref; |
|
2235 $ret =~ s/$CC/$commentChar/g; # Replace the proper comment starter character |
|
2236 |
|
2237 # Return values |
|
2238 $$testValue_ref = $$ref2; |
|
2239 return $ret; |
|
2240 } |
|
2241 |
|
2242 |
|
2243 ################################################## |
|
2244 # Print result line |
|
2245 ################################################## |
|
2246 sub normalizeCppComment |
|
2247 { |
|
2248 my $header_regexp2 = shift; |
|
2249 my $filecontent = shift; |
|
2250 my $oldheader_ref = shift; # in/out |
|
2251 |
|
2252 |
|
2253 # Normalize the C++ header syntax back to C++ in the file content |
|
2254 # in order to standardize stuff later on |
|
2255 $$oldheader_ref =~ s/(\/){3,}/\/\//g; # replace ///+ back to // |
|
2256 $$oldheader_ref =~ s/\/\//*/g; # Replace now // with * |
|
2257 $$oldheader_ref = "/*\n" . $$oldheader_ref . "*/\n"; # Add /* and */ markers |
|
2258 |
|
2259 # Created saved modified file content into memory |
|
2260 # This is the best way to do this. |
|
2261 my $ret = $filecontent; |
|
2262 $ret =~ s/$header_regexp2/$$oldheader_ref/; # Note /s not used by purpose ! |
|
2263 return $ret; |
|
2264 } |
|
2265 |
|
2266 |
|
2267 |
|
2268 ################################################## |
|
2269 # Print result line |
|
2270 ################################################## |
|
2271 sub printResult |
|
2272 { |
|
2273 my $text = shift; |
|
2274 |
|
2275 if ($outputfile) |
|
2276 { |
|
2277 print OUTPUT $text; |
|
2278 } |
|
2279 else |
|
2280 { |
|
2281 print $text; |
|
2282 } |
|
2283 |
|
2284 printLog(LOG_DEBUG(), $text); |
|
2285 |
|
2286 } |
|
2287 |
|
2288 ################################################## |
|
2289 # Print log line |
|
2290 ################################################## |
|
2291 sub printLog |
|
2292 { |
|
2293 my $loglevel = shift; |
|
2294 my $text = shift; |
|
2295 |
|
2296 if ($loglevel > $optLogLevel) |
|
2297 { |
|
2298 return; # No logging |
|
2299 } |
|
2300 if ($logFile) |
|
2301 { |
|
2302 print LOG $LOGTEXTS[$loglevel] . $text; |
|
2303 } |
|
2304 |
|
2305 return 0; |
|
2306 } |
|
2307 |
|
2308 |
|
2309 ################################################## |
|
2310 # Print log line |
|
2311 ################################################## |
|
2312 sub printLogStatisticNumber |
|
2313 { |
|
2314 my $number = shift; |
|
2315 my $loglevel = shift; |
|
2316 my $text = shift; # Should contains %d where to put the number |
|
2317 |
|
2318 if ($number == 0) |
|
2319 { |
|
2320 return; # No logging |
|
2321 } |
|
2322 |
|
2323 if ($text =~ m/\%d/) |
|
2324 { |
|
2325 $text =~ s/\%d/$number/; |
|
2326 } |
|
2327 else |
|
2328 { |
|
2329 # Add number to the beginning of text |
|
2330 $text = $number . " " . $text; |
|
2331 } |
|
2332 |
|
2333 if ($loglevel > $optLogLevel) |
|
2334 { |
|
2335 return; # No logging |
|
2336 } |
|
2337 if ($logFile) |
|
2338 { |
|
2339 print LOG $LOGTEXTS[$loglevel] . $text; |
|
2340 } |
|
2341 |
|
2342 return 0; |
|
2343 } |
|
2344 |
|
2345 |
|
2346 ################################################## |
|
2347 # Read the content of old output |
|
2348 ################################################## |
|
2349 sub readOldOutput |
|
2350 { |
|
2351 my($filename) = shift; |
|
2352 my $fh = new FileHandle "<$filename"; |
|
2353 if (!defined($fh)) |
|
2354 { |
|
2355 printLog(LOG_ERROR, "Could not open file $filename for read\n"); |
|
2356 return; |
|
2357 } |
|
2358 |
|
2359 my @lines = <$fh>; |
|
2360 my $line; |
|
2361 foreach $line (@lines) |
|
2362 { |
|
2363 my (@parts) = split(/\,/,$line); # Split line with "," separator |
|
2364 if ($parts[2] =~ m/$IGNORE_MAN/i) |
|
2365 { |
|
2366 my $fullfilename = lc($parts[4]); |
|
2367 $fullfilename =~ s/\\/\//g; # Standardize name |
|
2368 $manualIgnoreFileHash{$fullfilename} = "1" ; # Just some value |
|
2369 printLog(LOG_DEBUG, "Manually ignoring file:$fullfilename\n"); |
|
2370 } |
|
2371 } |
|
2372 |
|
2373 close ($fh); |
|
2374 } |
|
2375 |
|
2376 ################################################## |
|
2377 # Read configuation file which has the format: |
|
2378 # sf-update-licence-header-config-1.0 |
|
2379 ################################################## |
|
2380 sub readConfig |
|
2381 { |
|
2382 my ($fname) = @_; |
|
2383 |
|
2384 open(IN,$fname) || die "Unable to open file: \"$fname\" for reading."; |
|
2385 LINE: |
|
2386 while(<IN>) |
|
2387 { |
|
2388 chomp; |
|
2389 # tr/A-Z/a-z/; # Do not lowercase pattern |
|
2390 my $line = $_; |
|
2391 $line =~ s/^\s+//; # trim left |
|
2392 $line =~ s/\s+$//; # trim right |
|
2393 |
|
2394 next LINE if length($line) == 0; # # Skip empty lines |
|
2395 next LINE if ($line =~ /^\#.*/); # Skip comments; |
|
2396 |
|
2397 if ($line =~ /^sf-update-licence-header-config.*/i) |
|
2398 { |
|
2399 my ($tmp1, $tmp2) = split(/sf-update-licence-header-config-/,$line); # Get version |
|
2400 $configVersion = $tmp2; |
|
2401 } |
|
2402 elsif ($line =~ /^sf-distribution-id/i) |
|
2403 { |
|
2404 my ($tmp, @parts) = split(/[\s\t]+/,$line); # space as separator |
|
2405 my $cnt = @parts; |
|
2406 push(@sfDistributionIdArray, @parts); |
|
2407 my $cnt = @sfDistributionIdArray; |
|
2408 printLog(LOG_DEBUG, "readConfig:sfDistributionIdArray count:$cnt\n"); |
|
2409 } |
|
2410 elsif ($line =~ /^sf-generated-header/i) |
|
2411 { |
|
2412 my ($tmp, @parts) = split(/[\s\t]+/,$line); # space as separator |
|
2413 my $cnt = @parts; |
|
2414 push(@sfGeneratedPatternArray, @parts); |
|
2415 my $cnt = @sfGeneratedPatternArray; |
|
2416 printLog(LOG_DEBUG, "readConfig:sfGeneratedPatternArray count:$cnt\n"); |
|
2417 } |
|
2418 } |
|
2419 |
|
2420 # Pre-compile here the source line pattern |
|
2421 close (IN); |
|
2422 } |
|
2423 |
|
2424 |
|
2425 ################################################## |
|
2426 # Test ID is under SF distribution |
|
2427 ################################################## |
|
2428 sub isSFDistribution |
|
2429 { |
|
2430 my $id = shift; |
|
2431 |
|
2432 if (($id == SFL_DISTRIBUTION_VALUE) || ($id == EPL_DISTRIBUTION_VALUE)) |
|
2433 { |
|
2434 # Implicit case |
|
2435 return 1; |
|
2436 } |
|
2437 |
|
2438 my $otherOkId = grep { $_ eq $id } @sfDistributionIdArray; # Use exact match |
|
2439 return $otherOkId; |
|
2440 } |
|
2441 |
|
2442 ################################################## |
|
2443 # Test header contains generated file pattern |
|
2444 ################################################## |
|
2445 sub isGeneratedHeader |
|
2446 { |
|
2447 my $header_ref = shift; |
|
2448 |
|
2449 my $count = grep { $$header_ref =~ m/$_/is } @sfGeneratedPatternArray; |
|
2450 return $count; |
|
2451 } |
|
2452 |
|
2453 |
|
2454 ################################################## |
|
2455 # MAIN |
|
2456 ################################################## |
|
2457 |
|
2458 GetOptions( |
|
2459 'h|help' => \$help, #print help message |
|
2460 'm|modify' => \$optModify, #Allow modifications |
|
2461 'c|create' => \$optCreate, #Create missing file |
|
2462 'output:s' => \$outputfile, #Output (result) file |
|
2463 'ignorefile:s' => \$ignorefilepattern, #Ignore file pattern |
|
2464 'oldoutput:s' => \$oldOutputFile, #Old output file |
|
2465 'log:s' => \$logFile, # Log file |
|
2466 'verbose:i' => \$optLogLevel, # Logging level |
|
2467 'epl' => \$optEpl, # Switch file header to EPL one |
|
2468 'lgpl' => \$optLgpl, # Switch file header LGPL v2.1 |
|
2469 'oem' => \$optOem, # Switch back S60 header for OEM release. |
|
2470 'eula' => \$optOem, # Switch back S60 header for EULA (End-User License Agreement) release. Same as OEM |
|
2471 'append' => \$optAppend, # Append result files |
|
2472 'verify' => \$optVerify, # Verifies files has correct header |
|
2473 'configfile:s' => \$configFile, |
|
2474 'description!' => \$optDescription, # output missing description |
|
2475 'okoutput!' => \$optOutputOK # output also OK entries |
|
2476 ); |
|
2477 |
|
2478 die $usage if $#ARGV<0; |
|
2479 die $usage if $help; |
|
2480 |
|
2481 if ($logFile) |
|
2482 { |
|
2483 my $openmode = ">" . ($optAppend ? ">" : ""); |
|
2484 open (LOG, "$openmode$logFile") || die "Couldn't open $openmode$logFile\n"; # Can not call printLog |
|
2485 LOG->autoflush(1); # Force flush |
|
2486 } |
|
2487 |
|
2488 printLog(LOG_INFO, "========================\n"); |
|
2489 |
|
2490 if ($oldOutputFile && $optVerify) |
|
2491 { |
|
2492 readOldOutput($oldOutputFile); |
|
2493 } |
|
2494 |
|
2495 if (!$configFile) |
|
2496 { |
|
2497 $configFile = "$Bin/SFUpdateLicenceHeader.cfg"; |
|
2498 } |
|
2499 |
|
2500 if ($configFile && -e $configFile) |
|
2501 { |
|
2502 &readConfig($configFile); |
|
2503 } |
|
2504 |
|
2505 if (!$ignorefilepattern) |
|
2506 { |
|
2507 # Set decent default value |
|
2508 if ($optOem) |
|
2509 { |
|
2510 # Scan through internal stuff all source dirs just in case |
|
2511 $ignorefilepattern = "(_ccmwaid\.inf|\.svn)"; |
|
2512 } |
|
2513 else |
|
2514 { |
|
2515 $ignorefilepattern = "(abld\.bat|_ccmwaid\.inf|\.svn|/docs/|/internal/|/doc/)"; |
|
2516 } |
|
2517 } |
|
2518 |
|
2519 if ($optEpl) |
|
2520 { |
|
2521 printLog(LOG_INFO, "Option -epl used\n"); |
|
2522 } |
|
2523 if ($optLgpl) |
|
2524 { |
|
2525 printLog(LOG_INFO, "Option -lgpl used\n"); |
|
2526 } |
|
2527 if ($optOem) |
|
2528 { |
|
2529 printLog(LOG_INFO, "Option -oem used\n"); |
|
2530 # Modify ignore to contain also internal dirs just in case |
|
2531 } |
|
2532 if ($optModify) |
|
2533 { |
|
2534 printLog(LOG_INFO, "Option -modify used\n"); |
|
2535 } |
|
2536 if ($optVerify) |
|
2537 { |
|
2538 printLog(LOG_INFO, "Option -verify used\n"); |
|
2539 } |
|
2540 if ($optCreate) |
|
2541 { |
|
2542 printLog(LOG_INFO, "Option -create used\n"); |
|
2543 } |
|
2544 |
|
2545 if ($ignorefilepattern) |
|
2546 { |
|
2547 printLog(LOG_INFO, "Option -ignorefile has value: $ignorefilepattern\n"); |
|
2548 } |
|
2549 |
|
2550 my $startTime = time; |
|
2551 |
|
2552 if ($outputfile) |
|
2553 { |
|
2554 my $openmode = ">" . ($optAppend ? ">" : ""); |
|
2555 open (OUTPUT, "$openmode$outputfile") || die "Couldn't open $outputfile\n"; |
|
2556 OUTPUT->autoflush(1); # Force flush |
|
2557 } |
|
2558 |
|
2559 if (! -e $ARGV[0] ) |
|
2560 { |
|
2561 printLog(LOG_ERROR, "$ARGV[0] not found\n"); |
|
2562 if ($logFile) |
|
2563 { |
|
2564 close LOG; |
|
2565 } |
|
2566 exit(1); |
|
2567 } |
|
2568 |
|
2569 printLog(LOG_INFO,"SFUpdateLicenceHeader.pl version " . VERSION . " statistics:\n"); |
|
2570 printLog(LOG_INFO, "Directory/file=@ARGV\n"); |
|
2571 |
|
2572 # |
|
2573 # Process files in the given directory recursively |
|
2574 # |
|
2575 # NOTE : "no_chdir" option not used --> find changes the current working directory |
|
2576 find({ wanted => \&process_file, postprocess => \&postprocess, preprocess => \&preprocess }, @ARGV); |
|
2577 |
|
2578 if ($outputfile) |
|
2579 { |
|
2580 close OUTPUT; |
|
2581 } |
|
2582 |
|
2583 my $elapsedTime = time - $startTime; |
|
2584 |
|
2585 printLogStatisticNumber($fileCount, LOG_INFO, "%d files checked\n") ; |
|
2586 if ($optModify) |
|
2587 { |
|
2588 printLogStatisticNumber($modifiedFileCount, LOG_INFO, "%d files modified \n") ; |
|
2589 } |
|
2590 else |
|
2591 { |
|
2592 printLogStatisticNumber($willModifiedFileCount, LOG_INFO, "%d will be modified \n") ; |
|
2593 } |
|
2594 printLogStatisticNumber($ignoreCount, LOG_INFO, "%d files ignored.\n") ; |
|
2595 printLogStatisticNumber($unrecogCount, LOG_INFO, "%d files not recognized.\n") ; |
|
2596 if ($optVerify) |
|
2597 { |
|
2598 for (my $i=0; $i < @verifyFailedCountMsgs; $i++) |
|
2599 { |
|
2600 printLogStatisticNumber($verifyFailedCount[$i], LOG_INFO, "Verify statistics:$verifyFailedCountMsgs[$i]=%d.\n") ; |
|
2601 } |
|
2602 } |
|
2603 elsif (!$optOem) |
|
2604 { |
|
2605 printLogStatisticNumber($noDescrcount, LOG_INFO, "%d files has no Description.\n") ; |
|
2606 printLogStatisticNumber($NokiaCopyrCount, LOG_INFO, "%d files has Nokia copyright.\n") ; |
|
2607 printLogStatisticNumber($ExternalToNokiaCopyrCount, LOG_INFO, "%d files moved also to Nokia.\n") ; |
|
2608 printLogStatisticNumber($otherCopyrCount, LOG_INFO, "%d files has non-nokia copyright.\n") ; |
|
2609 printLogStatisticNumber($NoCopyrCount, LOG_INFO, "%d files has no copyright.\n") ; |
|
2610 printLogStatisticNumber($UnclearCopyrCount, LOG_INFO, "%d files has UNCLEAR copyright.\n") ; |
|
2611 printLogStatisticNumber($createCount, LOG_INFO, "%d new files.\n") ; |
|
2612 if ($optEpl) |
|
2613 { |
|
2614 printLogStatisticNumber($SflToEplChanges, LOG_INFO, "%d files changes from SFL to EPL license.\n") ; |
|
2615 } |
|
2616 else |
|
2617 { |
|
2618 printLogStatisticNumber($EplToSflChanges, LOG_INFO, "%d files changes from SFL to EPL license.\n") ; |
|
2619 } |
|
2620 } |
|
2621 else |
|
2622 { |
|
2623 printLogStatisticNumber($SflToS60Changes, LOG_INFO, "%d files changes from SFL to S60 license.\n") ; |
|
2624 # printLog($EplToS60Changes, LOG_INFO, "%d files changes from EPL to S60 license.\n") ; |
|
2625 printLogStatisticNumber($LicenseChangeErrors, LOG_INFO, "%d errors upon license change.\n") ; |
|
2626 } |
|
2627 |
|
2628 printLog(LOG_INFO,"Time elapsed $elapsedTime.\n") ; |
|
2629 |
|
2630 if ($logFile) |
|
2631 { |
|
2632 close LOG; |
|
2633 } |
|
2634 |