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