--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sbsv1/abld/e32util/checksource.pm Fri Jun 25 17:29:25 2010 +0800
@@ -0,0 +1,471 @@
+# Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# Routines involved in checking that source matches various filename policy constraints
+#
+#
+
+
+package CheckSource;
+
+require Exporter;
+@ISA=qw(Exporter);
+
+# Exported for clarity in calling scripts and modules
+our $CheckSource_PhysicalCheck = 1;
+our $CheckSource_NoUserSystemDistinction = 1;
+
+@EXPORT=qw(
+ CheckSource_MetaData
+ CheckSource_Includes
+ CheckSource_ExportedIncludes
+ CheckSource_MakefileOutput
+ CheckSource_UnixSlash
+ CheckSource_Lowercase
+ CheckSource_Physical
+ $CheckSource_PhysicalCheck
+ $CheckSource_NoUserSystemDistinction
+);
+
+use Cwd;
+use Pathutl;
+use Win32;
+
+my $exclusionsFile = $ENV{EPOCROOT}."epoc32\\tools\\filenamepolicyexclusions.txt";
+
+my $makefileWarningPrefix = "\@echo ";
+my $checksourcePrefix = "\@perl -S checksource.pl";
+my $releaseLocationRoot = quotemeta ($ENV{EPOCROOT}."epoc32");
+
+
+sub CheckSource_MetaData (\%$$$$;$;$)
+ {
+ my ($actionHash, $sourceFile, $item, $reference, $lineNumber, $physical, $offset) = @_;
+
+ return if ($reference =~ /^(\.|\.\.)$/);
+
+ my $checksourceCall = "$checksourcePrefix --metadata \"$sourceFile\" \"$item\" \"$reference\" $lineNumber";
+ $checksourceCall .= " $physical" if ($physical);
+ $checksourceCall .= " \"$offset\"" if ($offset);
+ $$actionHash{$checksourceCall} = 1;
+ }
+
+
+sub CheckSource_UnixSlash (\%$$$$;$)
+ {
+ my ($actionHash, $sourceFile, $item, $reference, $lineNumber, $verbose) = @_;
+
+ $sourceFile =~ s/^[a-zA-Z]{1}://;
+ $item =~ s/PRJ_EXPORTS \(NO DESTINATION\)/PRJ_EXPORTS/;
+
+ print "Checking - Unix slash : $sourceFile ($lineNumber) - $item:$reference\n" if ($verbose);
+
+ if ($reference =~/\\/)
+ {
+ $$actionHash{constructWarning ($sourceFile, $lineNumber, $item, "Incorrect slash in", $reference)} = 1;
+ }
+ }
+
+
+sub CheckSource_Lowercase (\%$$$;$;$)
+ {
+ my ($actionHash, $sourceFile, $item, $reference, $lineNumber, $verbose) = @_;
+
+ return if ($reference =~ /^[\/|\\]epoc32[\/|\\]tools[\/|\\].*$/);
+
+ $sourceFile =~ s/^[a-zA-Z]{1}://;
+
+ print "Checking - lowercase : $sourceFile ($lineNumber) - $item:$reference\n" if ($verbose);
+
+ my $exclusion = lowercaseExclusionCheck ($reference);
+
+ if ($exclusion eq "UNLISTED")
+ {
+ if ($reference =~ /[A-Z]/)
+ {
+ $$actionHash{constructWarning ($sourceFile, $lineNumber, $item, "Incorrect case for epoc32 tree in", $reference)} = 1;
+ }
+ }
+ elsif ($exclusion !~ /(OK|ERROR)/)
+ {
+ $$actionHash{constructWarning($sourceFile, $lineNumber, $item, "Incorrect case versus exclusion list in", $reference, " vs. $exclusion")} = 1;
+ }
+ }
+
+
+sub CheckSource_Physical (\%$$$$;$;$)
+ {
+ my ($actionHash, $sourceFile, $item, $reference, $lineNumber, $path, $verbose) = @_;
+
+ print "Checking - physical : $sourceFile ($lineNumber) - $item:$reference:$path\n" if ($verbose);
+
+ my $physicalCheck;
+ my $searchText;
+
+ my $examineDefaultExportDestination = ($item =~ s/PRJ_EXPORTS \(NO DESTINATION\)/PRJ_EXPORTS/) ? 1 : 0;
+
+ if ($item eq "#include")
+ {
+ # In the case of #includes, the path passed in is already the fully pathed physical file
+ # that needs to be checked (as obtained from the parsed output of CPP)
+ $searchText = $reference;
+ $physicalCheck = $path;
+ }
+ else
+ {
+ my $physicalReference;
+ if (($item =~ /^PRJ_(TEST)?MMPFILES MMP/) && ($reference !~ /\.\w+$/i))
+ {
+ $physicalReference = $reference."\.mmp";
+ $searchText = $reference."\.*";
+ }
+ elsif ($item =~ /^DEFFILE/)
+ {
+ # The full path for DEFFILE entries is always passed in, so we just
+ # need to concentrate on sorting out the oddities for the search
+ # text and then just take the final file bit as the physical
+ # reference
+
+ $searchText = $reference;
+ $searchText .= "?\.*" if ($reference !~ /(\.def|[\\|\/])$/i);
+ $searchText =~ s/(\.def)/\?$1/i if ($item !~ /NOSTRICTDEF/);
+ $searchText =~ s/\~/\*/;
+ $physicalReference = $searchText;
+ $physicalReference =~ s/\//\\/g;
+ $physicalReference =~ s/\?/u/;
+ $physicalReference =~ s/\.\w+$/\.def/;
+ $physicalReference = &Path_Split ('File', $physicalReference);
+ }
+ else
+ {
+ $searchText = $reference;
+ $physicalReference = $searchText;
+ }
+
+ my $physicalLocation;
+ if ($path)
+ {
+ $physicalLocation = $path;
+ }
+ elsif ($reference =~ /^(\\|\/)/)
+ {
+ $physicalLocation = $ENV{EPOCROOT};
+ }
+ elsif ($reference =~ /^\+/)
+ {
+ $physicalLocation = $ENV{EPOCROOT}."epoc32\\";
+ }
+ elsif ($item =~ /EXTENSIONS/)
+ {
+ $physicalLocation = $ENV{EPOCROOT}."epoc32\\tools\\makefile_templates\\";
+ }
+ else
+ {
+ $physicalLocation = &Path_Split ('Path', $sourceFile);
+ }
+ $physicalReference =~ s/^[\\|\/]//;
+ $physicalCheck = $physicalLocation.$physicalReference;
+ }
+
+ $physicalCheck =~ s/\//\\/g;
+ $physicalCheck = &Path_Strip ($physicalCheck);
+
+ # If a file reference is actually under \epoc32, we just need to confirm that it's lowercase
+ if ($physicalCheck =~ /^$releaseLocationRoot/i)
+ {
+ CheckSource_Lowercase (%$actionHash, $sourceFile, $item, $reference, $lineNumber, $verbose);
+ return;
+ }
+
+ # Massage search text to provide something we can compare with a physical check on the filesystem
+ $searchText =~ s/\//\\/g;
+ $searchText =~ s/\.\.\\//g;
+ $searchText =~ s/\.\\//g;
+ $searchText =~ s/\\\\/\\/g;
+
+ my $warningSearchText = $searchText; # Record a more intelligible version of the search text for warning purposes
+
+ $searchText = quotemeta ($searchText);
+ $searchText =~ s/\\\*/\\w\+/g; # * -> \w+
+ $searchText =~ s/\\\?/\\w\{1\}/g; # ? -> \w{1}
+
+ my $physicalReality = getPhysical ($physicalCheck);
+
+ my $warningSuffix = "";
+
+ if (!$physicalReality)
+ {
+ $$actionHash{constructWarning($sourceFile, $lineNumber, $item, "Can\'t find physical file match for", $reference, " on filesystem")} = 1;
+ }
+ elsif ($physicalReality !~ /^.*$searchText$/)
+ {
+ if ($physicalReality !~ /^.*$searchText$/i)
+ {
+ # Doesn't just differ in case...something's gone wrong
+ $$actionHash{constructWarning($sourceFile, $lineNumber, $item, "Can\'t find physical file match for", $reference, " - match was attempted against $physicalReality")} = 1;
+ }
+ else
+ {
+ if (($item =~ /^DEFFILE/ || $item =~ /^PRJ_(TEST)?MMPFILES MMP/) && ($reference !~ /$searchText$/))
+ {
+ $warningSuffix .= " (actual test \'$warningSearchText\')"
+ }
+
+ $warningSuffix .= " vs. $physicalReality";
+ $$actionHash{constructWarning($sourceFile, $lineNumber, $item, "Incorrect case versus filesystem in", $reference, $warningSuffix)} = 1;
+ }
+ }
+
+ # Special case - PRJ_EXPORTS source lines with no destination must be normalised via a new destination compliant
+ # with the filename policy. FIXSOURCE will do this, but it needs a warning to work on
+
+ if ($examineDefaultExportDestination)
+ {
+ $physicalReality =~ /^.*($searchText)$/i;
+ my $defaultExportReference = $1;
+
+ my $exclusion = lowercaseExclusionCheck ($defaultExportReference);
+
+ if ($defaultExportReference =~ /[A-Z]/)
+ {
+ $$actionHash{constructWarning ($sourceFile, $lineNumber, $item, "Incorrect case for epoc32 tree from default export in", $reference, $warningSuffix)} = 1;
+ }
+ }
+
+ }
+
+
+sub CheckSource_Includes ($\%$\@;\@;\@;$)
+ {
+ # References are used for array arguments only so that they can be distinguished within the subroutine
+ my ($sourceFile, $actionHash, $preInclude, $macros, $userIncludesRef, $systemIncludesRef, $noUserSystemDistinction) = @_;
+ my (@userIncludes, @systemIncludes);
+
+ @userIncludes = @$userIncludesRef if ($userIncludesRef);
+ @systemIncludes = @$systemIncludesRef if ($systemIncludesRef);
+
+ my $call = "$checksourcePrefix --preprocess -- ";
+
+ if (($sourceFile !~ /\.inf$/i) && ($sourceFile !~ /\.mmp/i))
+ {
+ push @$macros, "__SUPPORT_CPP_EXCEPTIONS__";
+ }
+
+ my $platformPreInclude = "";
+
+ foreach my $macro (@$macros)
+ {
+ $call .= "-D$macro ";
+
+ if ($macro =~ /__ARMCC_2_2__/)
+ {
+ $platformPreInclude = $ENV{EPOCROOT}."epoc32\\include\\rvct2_2\\rvct2_2.h";
+
+ if (($sourceFile =~ /BASE\\E32\\compsupp\\/i) && $ENV{RVCT22INC})
+ {
+ # Need some way to deal with ARMINC from the front-end...
+ my $rvctIncDir = $ENV{RVCT22INC};
+ push @systemIncludes, $rvctIncDir;
+ }
+ }
+ elsif ($macro =~ /__GCCE__/)
+ {
+ $platformPreInclude = $ENV{EPOCROOT}."epoc32\\include\\GCCE\\GCCE.h";
+
+ my $GCCEinstall = Cl_bpabi::getConfigVariable('COMPILER_INSTALL_PATH');
+
+ push @systemIncludes, "\"\\\"$GCCEinstall\\..\\lib\\gcc\\arm-none-symbianelf\\3.4.3\\include\\\"\"";
+ }
+ }
+
+ if ($preInclude ne "")
+ {
+ $call .= "-include ".getDrive().$preInclude." ";
+ push @systemIncludes, &Path_Split ('Path', getDrive().$preInclude);
+ }
+
+ if ($platformPreInclude ne "")
+ {
+ $call .= "-include ".getDrive().$platformPreInclude." ";
+ push @systemIncludes, &Path_Split ('Path', getDrive().$platformPreInclude);
+ }
+
+ # Enforce user and system includes in checksource processing.
+
+ foreach my $include (@userIncludes)
+ {
+ $include =~ s/\\$//;
+ $include = getDrive().$include if (($include !~ /^[a-zA-Z]:/) && ($include !~ /^[\"|\.]/));
+ $call .= "-I $include ";
+ }
+
+ $call .= "-I- " unless $noUserSystemDistinction;
+
+ foreach my $include (@systemIncludes)
+ {
+ $include =~ s/\\$//;
+ $include = getDrive().$include if (($include !~ /^[a-zA-Z]:/) && ($include !~ /^[\"|\.]/));
+ $call .= "-I $include ";
+ }
+
+ $sourceFile =~ s/\//\\/g;
+ $sourceFile = &Path_Strip ($sourceFile);
+ $sourceFile = getDrive().$sourceFile;
+
+ $call .= $sourceFile;
+
+ $$actionHash{$call} = 1;
+
+ return $call;
+ }
+
+
+sub CheckSource_ExportedIncludes ($$\%)
+ {
+ my ($sourceFile, $destinationFile, $actionHash) = @_;
+
+ # Exclude exported files as appropriate
+ if ($destinationFile)
+ {
+ my $epoc32Include = quotemeta ($ENV{EPOCROOT})."epoc32\\\\include";
+ return if ($destinationFile !~ /^$epoc32Include/i);
+ return if ($destinationFile =~ /\.def$/i);
+ }
+
+ $$actionHash{"$checksourcePrefix --parsefile -- $sourceFile"} = 1;
+ }
+
+
+sub CheckSource_MakefileOutput(%)
+ {
+ my (%actionHash) = @_;
+
+ return "\t\@rem\n" if !(keys (%actionHash));
+
+ my $output = "";
+
+ foreach (keys (%actionHash))
+ {
+ $output .= "\t$_\n";
+ }
+
+ return $output;
+ }
+
+
+sub getDrive
+ {
+ if(cwd =~ /^([a-zA-Z]:)/)
+ {
+ return $1;
+ }
+
+ return "";
+ }
+
+
+sub getPhysical ($)
+ {
+ my ($physicalReference) = @_;
+
+ my $physicalReality = Win32::GetLongPathName($physicalReference);
+
+ if ($physicalReality)
+ {
+ $physicalReality =~ s/^.*://;
+ $physicalReality = &Path_Strip ($physicalReality);
+ }
+
+ return $physicalReality;
+ }
+
+
+sub constructWarning ($$$$$;$)
+ {
+ my ($sourceFile, $lineNumber, $item, $warningText, $reference, $suffix) = @_;
+
+ $sourceFile =~ s/\//\\/g;
+ $sourceFile = Win32::GetLongPathName($sourceFile);
+ $sourceFile =~ s/^[a-zA-Z]{1}://;
+ $sourceFile = &Path_Strip ($sourceFile);
+
+ my $warning = "";
+ $warning .= $sourceFile.":".$lineNumber.": ".$warningText." $item - \'".$reference."\'";
+ $warning .= $suffix if ($suffix);
+ $warning .= ".";
+
+ return $warning;
+ }
+
+
+sub lowercaseExclusionCheck ($)
+ {
+ my ($reference) = @_;
+
+ # An exclusions file isn't mandatory
+ return "UNLISTED" if (! -e $exclusionsFile);
+
+ my $EXCLUSIONS;
+
+ if (!(open EXCLUSIONS, "< $exclusionsFile"))
+ {
+ print ("ERROR: Can't open $exclusionsFile in checksource processing.\n");
+ return "ERROR";
+ }
+
+ my $referenceDOSSlash = $reference;
+ $referenceDOSSlash =~ s/\//\\/g;
+
+ my $exclusionCheck = "UNLISTED";
+
+ while (my $exclusion = <EXCLUSIONS>)
+ {
+ next if ($exclusion =~ /^\s*$/);
+
+ $exclusion =~ s/^\s+//;
+ $exclusion =~ s/\s+$//;
+ $exclusion =~ s/\//\\/g;
+ my $quotemetaExclusion = quotemeta ($exclusion);
+
+ if ($referenceDOSSlash =~ /^$quotemetaExclusion$/i)
+ {
+ if ($referenceDOSSlash !~ /^$quotemetaExclusion$/)
+ {
+ $exclusionCheck = $exclusion;
+ }
+ else
+ {
+ $exclusionCheck = "OK";
+ }
+ last;
+ }
+ elsif($referenceDOSSlash =~ /\\$quotemetaExclusion$/i)
+ {
+ if ($referenceDOSSlash !~ /\\$quotemetaExclusion$/)
+ {
+ $exclusionCheck = $exclusion;
+ }
+ else
+ {
+ $exclusionCheck = "OK";
+ }
+ last;
+ }
+ }
+
+ close EXCLUSIONS;
+
+ return $exclusionCheck;
+ }
+
+1;