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