sl@0: #
sl@0: # Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: # All rights reserved.
sl@0: # This component and the accompanying materials are made available
sl@0: # under the terms of the License "Eclipse Public License v1.0"
sl@0: # which accompanies this distribution, and is available
sl@0: # at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: #
sl@0: # Initial Contributors:
sl@0: # Nokia Corporation - initial contribution.
sl@0: #
sl@0: # Contributors:
sl@0: #
sl@0: # Description: 
sl@0: # Created by Relja Arandjelovic
sl@0: # relja.arandjelovic@symbian.com
sl@0: # Used to check for occurrences of "C: , EDriveC and [<index>]='C' and report warnings about it into HTML file
sl@0: # USAGE:
sl@0: # cdrive.pl -exclude=exclude.txt -excludedir=/common/generic/security/caf2/ -log=logfilename.htm path1 path2 ...
sl@0: # log is created in $ENV{EPOCROOT}epoc32\\winscw\\c\\
sl@0: # add -mytest option if the log should be stored in the execution directory
sl@0: # (for example, if you are not using the script during overnight builds)
sl@0: # exclude contains items formated as as follows (new line corresponds to new line in file):
sl@0: # filename
sl@0: # line content
sl@0: # comment about why the warning should be excluded (may be in several lines, but with no line with only whice characters)
sl@0: # line with only white characters
sl@0: # NB: paths in cdrive.pl argumetns and filename in exclude list should be absolute paths
sl@0: #
sl@0: 
sl@0: use strict;
sl@0: use Getopt::Std;
sl@0: use Getopt::Long;
sl@0: use File::Find;
sl@0: 
sl@0: my @ListOfFiles=();
sl@0: my @FileIsTest=();
sl@0: my $nTests=0;
sl@0: my %Exclude=();
sl@0: 
sl@0: my $exclude="";
sl@0: my $excludedir="_no_dir_";
sl@0: my $LogFileName="";
sl@0: 
sl@0: 
sl@0: 
sl@0: ################
sl@0: ########
sl@0: sub TypeOfWarning($$$$){
sl@0: 	my ($FileName,$FileIsTest,$linetext,$Warning)=@_;
sl@0: 	
sl@0: 	$linetext=~ s/^\s*//; $linetext=~ s/\s*$//;
sl@0: 
sl@0: 	$$Warning="warning";
sl@0: 	
sl@0: 	if ($FileIsTest==1){
sl@0: 		$$Warning="test";
sl@0: 	} else {
sl@0: 		# check if in include list
sl@0: 	
sl@0: 		my $ExcludeLine;
sl@0: 		foreach $ExcludeLine (@{$Exclude{$FileName}}){
sl@0: 			if ($linetext eq $ExcludeLine) {
sl@0: 				$$Warning="ignoredwarning";
sl@0: 				last;
sl@0: 			}
sl@0: 		}		
sl@0: 	}
sl@0: 	
sl@0: }
sl@0: 	
sl@0: 	
sl@0: 	
sl@0: ################
sl@0: ########
sl@0: 
sl@0: 
sl@0: my $FirstWarning=1;
sl@0: my $PrevFileName="_no_file_";
sl@0: 
sl@0: sub printHTML($$$$){
sl@0: 	my ($FileName,$linenumber,$linetext,$Warning)=@_;
sl@0: 
sl@0: 	
sl@0: 	$linetext=~ s/^\s*//; $linetext=~ s/\s*$//;
sl@0: 
sl@0: 	# convert special characters to HTML format
sl@0: 	$linetext=~ s/&/&amp;/sg;
sl@0: 	$linetext=~ s/</&lt;/sg;
sl@0: 	$linetext=~ s/>/&gt;/sg;
sl@0: 	
sl@0: 
sl@0: 	if ($FileName ne $PrevFileName){
sl@0: 		print HTML "
sl@0: <tr><td colspan=\"4\" height=\"20\">&nbsp;</td></tr>
sl@0: 	<tr><td width=\"20\"></td><td colspan=\"3\">
sl@0: 		$FileName
sl@0: 	</td></tr>	
sl@0: ";
sl@0: 	}
sl@0: 	
sl@0: 	print HTML "
sl@0: <tr><td colspan=\"4\" height=\"10\">&nbsp;</td></tr>
sl@0: 		<tr class=\"$Warning\"><td width=\"20\"></td><td width=\"60\"></td><td colspan=\"2\">
sl@0: 			Line number: $linenumber
sl@0: 		</td></tr>
sl@0: 			<tr class=\"$Warning\"><td width=\"20\"></td><td width=\"60\"></td><td width=\"80\"></td><td>
sl@0: $linetext
sl@0: 			</td></tr>
sl@0: ";
sl@0: 	
sl@0: 	$PrevFileName=$FileName;
sl@0: 	$FirstWarning=0;
sl@0: }
sl@0: 
sl@0: ################
sl@0: ########
sl@0: my $prevDir="_no_previous_dir_";
sl@0: my $isTest=0;
sl@0: 
sl@0: sub MakeList(){
sl@0: 	
sl@0: 
sl@0: 	if (lc($File::Find::dir) =~ /^$excludedir/) { return; }
sl@0: 	if (lc($File::Find::dir) =~ /test/i) { return; }
sl@0: 	if (lc($File::Find::dir) =~ /examples/i) { return; }
sl@0: 	if (lc($File::Find::dir) =~ /tpkcs10/i) { return; }
sl@0: 	if (lc($File::Find::dir) =~ /tocsp/i) { return; }
sl@0: 	if (lc($File::Find::dir) =~ /referencedrmagent/i) { return; }
sl@0: 	if (lc($File::Find::dir) =~ /dumpswicertstoretool/i) { return; }
sl@0: 	if (!(lc($File::Find::name) =~ /\.(cpp|cxx|c\+\+|c|h)$/)){ return; }
sl@0: 	
sl@0: 	# include in list of files to be searched only if not test code
sl@0: 	# ie distribution policy doesn't include Reference/Test
sl@0: 	if ($prevDir ne lc($File::Find::dir)){ # new dir => search for distribution.policy	
sl@0: 		$isTest=0;
sl@0: 		my $policy="".($File::Find::dir)."/distribution.policy";
sl@0: 		
sl@0: 		if (-e $policy){
sl@0: 			open (POLICY , "<$policy" );
sl@0: 			while (<POLICY>){
sl@0: 				if ($_ =~ /Reference\/Test/){
sl@0: 					$isTest=1;
sl@0: 					last;
sl@0: 				}
sl@0: 			}
sl@0: 			close (POLICY);
sl@0: 		}
sl@0: 	}
sl@0: 	
sl@0: 	push(@ListOfFiles,lc($File::Find::name));
sl@0: 	push(@FileIsTest,$isTest);	
sl@0: 	if ($isTest) { $nTests++; }
sl@0: 	
sl@0: 	$prevDir=lc($File::Find::dir);
sl@0: }
sl@0: 
sl@0: ################
sl@0: ########
sl@0: sub FindC($$$$){
sl@0: 	my ($FileName,$FileIsTest,$count,$countunique)=@_;
sl@0: 			
sl@0: 	open(SOURCE,"<$FileName") or die ("Could not open file: $FileName");
sl@0: 	
sl@0: 	my $prevCount=$$count;
sl@0: 	my $line; my $templine; my $linenumber=1;
sl@0: 	my $MultiLineComment=0;
sl@0: 	my $MadeChangeDueToComments;
sl@0: 	my $FirstLine=0;
sl@0: 	
sl@0: 	my $HTMLFirstWarning=1;
sl@0: 	
sl@0: 	while ($line=<SOURCE>){
sl@0: 	
sl@0: 		$templine=$line;
sl@0: 		$linenumber++;
sl@0: 		$FirstLine=0;
sl@0: 		
sl@0: 		# process comments
sl@0: 		do {
sl@0: 		
sl@0: 			$MadeChangeDueToComments=0;
sl@0: 		
sl@0: 			if ($MultiLineComment==0){
sl@0: 		
sl@0: 				# remove text in // coments 
sl@0: 				$templine=~ s/(.*?)\/\/.*$/$1/;
sl@0: 				# remove /* */ comments found in one line
sl@0: 				$templine=~ s/\/\*.*\*\///g;
sl@0: 			
sl@0: 				# if only /* then remove text after it and mark the start of comment
sl@0: 				if ($templine=~ /^(.*?)\/\*/){
sl@0: 					$templine=$1;
sl@0: 					$MultiLineComment=1;
sl@0: 					$MadeChangeDueToComments=1;
sl@0: 					$FirstLine=1;
sl@0: 				}
sl@0: 			
sl@0: 			} else {	# $MultiLineComment==1
sl@0: 		
sl@0: 				# if */ end comment
sl@0: 				if ($templine=~ /\*\/(.*)$/){
sl@0: 					$templine=$1;
sl@0: 					$MultiLineComment=0;
sl@0: 					$MadeChangeDueToComments=1;				
sl@0: 				}
sl@0: 			
sl@0: 			}
sl@0: 			
sl@0: 		} while ($MadeChangeDueToComments==1);
sl@0: 		# end of processing comments
sl@0: 		
sl@0: 		
sl@0: 		if ($MultiLineComment==1 && $FirstLine==0) { next; } # skip checking if in comment
sl@0: 	
sl@0: 	
sl@0: 		if (
sl@0: 			$templine=~ /["'][cC]:/	|| # '" # need comment for correct highlighting in codewarrior
sl@0: 			$templine=~ /EDriveC/		||
sl@0: 			$templine=~ /\[.+\]\s*=\s*'[cC]':/
sl@0: 			){
sl@0: 			
sl@0: 				my $Warning;
sl@0: 				TypeOfWarning($FileName,$FileIsTest,$line,\$Warning);
sl@0: 				printHTML($FileName,$linenumber,$line,$Warning);
sl@0: 				if ($Warning eq "warning") { $$count++; }
sl@0: 				
sl@0: 			}
sl@0: 		
sl@0: 	}
sl@0: 	
sl@0: 	close(SOURCE);
sl@0: 	
sl@0: 	if ($prevCount<$$count) { $$countunique++; }
sl@0: }
sl@0: 
sl@0: ################
sl@0: ########
sl@0: sub ReadExcludeList(){
sl@0: 
sl@0: 	#print "\n";
sl@0: 	
sl@0: 	
sl@0: 	if ($exclude eq ""){
sl@0: 		#print "Exclude list file not specified\nCarrying on without an exclude list\n";
sl@0: 		return;
sl@0: 	} elsif (!(-e $exclude)){
sl@0: 		#print "Exclude list file doesn't exist!\nCarrying on without an exclude list\n";
sl@0: 		return;
sl@0: 	}
sl@0: 	
sl@0: 	
sl@0: 	my $line; my $FileName; my $LineText; my $justification;
sl@0: 	
sl@0: 	open (EXCLUDE,"<$exclude");
sl@0: 	while (1){
sl@0: 	
sl@0: 		$line=<EXCLUDE> or last;
sl@0: 		$line=~ s/^(\s*)//g; $line=~ s/(\s*)$//g;
sl@0: 		$line=~ s/\\/\//g;
sl@0: 		$FileName=lc($line);
sl@0: 		
sl@0: 		$line=<EXCLUDE>; $line=~ s/^(\s*)//g; $line=~ s/(\s*)$//g;
sl@0: 		$LineText=$line;
sl@0: 		
sl@0: 		$justification=0;
sl@0: 		while($line=<EXCLUDE>){
sl@0: 			$line=~ s/^(\s*)//g; $line=~ s/(\s*)$//g;
sl@0: 			if ($line eq "") { last;}
sl@0: 			$justification=1;
sl@0: 		}
sl@0: 		
sl@0: 		if ($justification==0){
sl@0: 			#print "Not added to the excludion list since no justification found for:\n$FileName\n$LineText\n";
sl@0: 		} else {		
sl@0: 			push(@{$Exclude{$FileName}},$LineText);
sl@0: 		}
sl@0: 		
sl@0: 	}
sl@0: 	close(EXCLUDE);
sl@0: 	
sl@0: }
sl@0: 
sl@0: ################
sl@0: ######## Main
sl@0: 
sl@0: 	
sl@0: 	my $MyTest=0;
sl@0: 	
sl@0: 	GetOptions(
sl@0: 			"exclude=s" => \$exclude ,
sl@0: 			"excludedir=s" => \$excludedir, # one dir to be excluded from scaning (along wih its subdirs)
sl@0: 			"log=s" => \$LogFileName,
sl@0: 			"mytest" => \$MyTest # inteded for my personal testing (so that path is not the one for overnight testing)
sl@0: 				);
sl@0: 	
sl@0: 	$excludedir=~ s/\\/\//g; # convert \ into / so that it matches perl's path form
sl@0: 	
sl@0: 	ReadExcludeList();
sl@0: 
sl@0: 	
sl@0: 	if ($MyTest==0){ # overnight
sl@0: 		$LogFileName = "$ENV{EPOCROOT}epoc32\\winscw\\c\\".$LogFileName;
sl@0: 	}
sl@0: 
sl@0: 			
sl@0: 	my $iArgv;
sl@0: 	for ($iArgv=0;$iArgv<@ARGV;$iArgv++){
sl@0: 		$ARGV[$iArgv]=~ s/\\/\//g; # convert \ into / so that it matches perl's path form
sl@0: 		find(\&MakeList, ($ARGV[$iArgv]) );
sl@0: 	}
sl@0: 
sl@0: 	
sl@0: 	open(HTML,">$LogFileName");
sl@0: 	print HTML "
sl@0: <html>
sl@0: 
sl@0: <head>
sl@0: 	<title>CDrive warnings</title>
sl@0: 	
sl@0: 	<style type=\'text/css\'>
sl@0: .warning {
sl@0: 	background-color: #FFAAAA;
sl@0: }
sl@0: .ignoredwarning {
sl@0: 	background-color: #90ffff;
sl@0: }
sl@0: .test{
sl@0: 	background-color: #ffc060;
sl@0: }
sl@0: 	</style>
sl@0: </head>
sl@0: <body>	
sl@0: 	<table border=\"0\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">
sl@0: ";
sl@0: 	
sl@0: 
sl@0: 	my $count=0; my $countunique=0;
sl@0: 	my $iList; my $nList=@ListOfFiles;
sl@0: 	for ($iList=0;$iList<$nList;$iList++){
sl@0: 		FindC($ListOfFiles[$iList],$FileIsTest[$iList],\$count,\$countunique);
sl@0: 	}
sl@0: 
sl@0: 	
sl@0: 	print HTML "\n</table>\n";
sl@0: 
sl@0: 	my $total=$nList-$nTests;
sl@0: 	# workaround in order to be reported to the standardised system	
sl@0: 	print HTML "<br><center>$countunique tests failed out of $total\n</center>\n";	
sl@0: 	
sl@0: 	print HTML "
sl@0: </body>
sl@0: </html>	
sl@0: 	";
sl@0: 	
sl@0: 	#print "\n\tNumber of files:\t$nList\n";
sl@0: 	#print "\n\tNumber of warnings:\t$count\n";
sl@0: 	#print "\n\tNumber of unique warnings:\t$countunique\n";
sl@0: 	
sl@0: 	close(HTML);
sl@0: 
sl@0: ################
sl@0: ######## end-Main
sl@0: