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