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