#
# Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
# All rights reserved.
# This component and the accompanying materials are made available
# under the terms of the License "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:
#
# This package contains routines to read the information from the Component Description Files.
package cdfparser;
# Include Module package to use APIs to parse an XML file.
use genericparser;
require Exporter;
@ISA=qw(Exporter);
@EXPORT=qw(
CreateCDFFileBinaryMapFromDir
GetBinaries
GetCDFFileName
LoadCDF
GetDynamicDependencies
GetBinaryInfo
GetIncludedFeatureList
GetExcludedFeatureList
);
use strict;
# Map between the CDF File Name and the corresponding list of binaries
# This is required so that one can fetch the list of binaries for a particular CDF file.
my %binaryCDFFileMap=();
# Include Feature List
# The list of features to be included for a given binary.
my @includeFeatureList;
# Exclude Feature List
# The list of features to be excluded for a given binary.
my @excludeFeatureList;
# List that contains the complete information of each binary
my %binaryInfo=();
my $warning_level = 0;
# Absolute path that contains the CDF Files
my @cdfDirectories;
# To extract the cdf files from the directory specified as input. The default directory is chosen if no
# input is specified.
sub CreateCDFFileBinaryMapFromDir
{
my @acdfDirList = @_;
# To store the list of cdf file names specified under the directory
my @cdfFileList;
if ((scalar @acdfDirList) != 0)
{
foreach my $acdfDir (@acdfDirList)
{
opendir DIR, "$acdfDir";
if(not grep /$acdfDir/i, @cdfDirectories)
{
push @cdfDirectories, $acdfDir;
}
push (@cdfFileList, (grep /\.cdf/i, readdir DIR));
foreach my $filename (@cdfFileList)
{
&CreateCDFFileBinaryMap(lc($filename), $acdfDir);
$binaryCDFFileMap{$filename}{path} = $acdfDir;
}
}
}
}
# To create a mapping between the CDF file name and the corresponding list of binaries
sub CreateCDFFileBinaryMap
{
my ($cdffilename, $aCdfDir) = @_;
if( defined $binaryCDFFileMap{$cdffilename} )
{
return;
}
my $path;
if( defined $aCdfDir)
{
$path = "$aCdfDir\\$cdffilename";
}
else
{
$path = $cdffilename;
}
my $rootNode = &genericparser::getRootElement($path);
$binaryCDFFileMap{$cdffilename}{root} = $rootNode;
my @binaryList = &genericparser::getChildElements($rootNode);
my $binaryInfoRef;
foreach my $binary (@binaryList)
{
my $filename = &genericparser::getAttrValue($binary, "id");
push @{$binaryCDFFileMap{$cdffilename}{binaries}}, $filename;
# This is required so that one can fetch the CDF file name in which the binary is present
$binaryInfoRef = \%{$binaryInfo{$filename}};
$binaryInfoRef->{"filename"} = $cdffilename;
}
}
# To get the complete list of binaries present in a given CDF file
# Input Parameter : CDF filename
# Returns the complete list of binaries
sub GetBinaries
{
my $cdffilename = shift;
if (exists $binaryCDFFileMap{$cdffilename})
{
return @{$binaryCDFFileMap{$cdffilename}{binaries}};
}
else
{
return undef;
}
}
# To get the name of the CDF file that contains the input binary
# Input Parameter : Binary Name
# Returns the CDF file name
sub GetCDFFileName
{
my $aBinary = lc(shift);
if (exists $binaryInfo{$aBinary})
{
my $binInfo = \%{$binaryInfo{$aBinary}};
return $binInfo->{filename};
}
else
{
return undef;
}
}
#Loads all the specified CDF files.
sub LoadCDF
{
my @cdfFileList = @_;
foreach my $afile (@cdfFileList)
{
CreateCDFFileBinaryMap($afile);
my $rootNode = $binaryCDFFileMap{$afile}{root};
# Get the total list of files present in the cdf file.
my @binaryList = &genericparser::getChildElements($rootNode);
# Hash Reference to the hash map binaryInfo
my $binaryInfoHashRef;
foreach my $binaryNode (@binaryList)
{
my $fileId = &genericparser::getAttrValue($binaryNode, "id");
$binaryInfoHashRef = \%{$binaryInfo{$fileId}};
&setBinaryInfo($binaryInfoHashRef, $binaryNode);
}
}
}
#Sets the information of the CDF file to a hash map
sub setBinaryInfo
{
my ($aBinaryInfoRef, $aBinaryNode) = @_;
# Set the File attributes
$aBinaryInfoRef->{"id"} = &genericparser::getAttrValue($aBinaryNode, "id");
$aBinaryInfoRef->{"customisable"} = &genericparser::getAttrValue($aBinaryNode, "customisable");
$aBinaryInfoRef->{"addressable"} = &genericparser::getAttrValue($aBinaryNode, "addressable");
$aBinaryInfoRef->{"compress"} = &genericparser::getAttrValue($aBinaryNode, "compress");
$aBinaryInfoRef->{"type"} = &genericparser::getAttrValue($aBinaryNode, "type");
$aBinaryInfoRef->{"plugin_name"} = &genericparser::getAttrValue($aBinaryNode, "plugin_name");
# Check for the plugin, setting the plugin type as ECOM_PLUGIN
if (defined $aBinaryInfoRef->{"plugin_name"})
{
$aBinaryInfoRef->{"IsFoundInCDF"} = 1;
$aBinaryInfoRef->{"source"} = "ABI_DIR\\BUILD_DIR\\$aBinaryInfoRef->{id}";
$aBinaryInfoRef->{"plugin_name"} =~ s/$aBinaryInfoRef->{plugin_name}/ECOM/;
}
else {
# Get all the nodes of element 'file'
my @children = &genericparser::getChildElements($aBinaryNode);
foreach my $childNode (@children)
{
$aBinaryInfoRef->{"IsFoundInCDF"} = 1;
if (&genericparser::getElementName($childNode) eq "source")
{
$aBinaryInfoRef->{"source"} = &genericparser::getElementValue($childNode);
}
if (&genericparser::getElementName($childNode) eq "destination")
{
$aBinaryInfoRef->{"destination"} = &genericparser::getElementValue($childNode);
}
if (&genericparser::getElementName($childNode) eq "features")
{
# The children nodes will specify the list of features
my @aFeatureNodes = &genericparser::getChildElements($childNode);
foreach my $aFeatureChildNode (@aFeatureNodes)
{
# A list of features can be listed out either for supported case or for the prevented case.
if (&genericparser::getElementName($aFeatureChildNode) eq "supports")
{
my @aSupportedFeatureNodes = &genericparser::getChildElements($aFeatureChildNode);
foreach my $aSuppChildNode (@aSupportedFeatureNodes)
{
my %feat = ();
my $featureName = &genericparser::getAttrValue($aSuppChildNode, "name");
my $featureUID = &genericparser::getAttrValue($aSuppChildNode, "uid");
if (defined ($featureName) and ($featureName ne ""))
{
$feat{name} = $featureName ;
$feat{uid} = undef;
}
elsif(defined ($featureUID) and ($featureUID ne ""))
{
if(&featureparser::ValidateUIDValue($featureUID))
{
$featureUID = &featureparser::ConvertHexToDecimal($featureUID);
$feat{uid} = $featureUID;
$feat{name} = undef;
}
else
{
print "The uid value $featureUID specified for the Include feature list for the Binary, $aBinaryInfoRef->{id}, is not a valid number\n";
}
}
else
{
print ("Warning: Feature $featureName has both name and Uid mentioned\n") if ($warning_level < 2);
next;
}
$feat{include} = 1;
push @includeFeatureList, \%feat;
}
}
if (&genericparser::getElementName($aFeatureChildNode) eq "prevents")
{
my @aPreventedFeatureNodes = &genericparser::getChildElements($aFeatureChildNode);
foreach my $aPreventedChildNode (@aPreventedFeatureNodes)
{
my %feat = ();
my $featureName = &genericparser::getAttrValue($aPreventedChildNode, "name");
my $featureUID = &genericparser::getAttrValue($aPreventedChildNode, "uid");
if (defined ($featureName) and ($featureName ne ""))
{
$feat{name} = $featureName ;
$feat{uid} = undef;
}
elsif(defined ($featureUID) and ($featureUID ne ""))
{
if(&featureparser::ValidateUIDValue($featureUID))
{
$featureUID = &featureparser::ConvertHexToDecimal($featureUID);
$feat{uid} = $featureUID;
$feat{name} = undef;
}
else
{
print "The uid value $featureUID specified for the Exclude feature list for the Binary, $aBinaryInfoRef->{id}, is not a valid number\n";
}
}
else
{
print "Warning: Feature $featureName has both name and Uid mentioned\n" if ($warning_level < 2);
next;
}
$feat{exclude} = 1;
push @excludeFeatureList, \%feat;
}
push @{$aBinaryInfoRef->{"prevents"}}, (&genericparser::getElementValue($aFeatureChildNode));
}
}
}
if (&genericparser::getElementName($childNode) eq "dynamicdependencies")
{
# The children nodes will contain the file name.
my @aDynDependNodes = &genericparser::getChildElements($childNode);
foreach my $aDynDependChildNode (@aDynDependNodes)
{
# There can be a list of binaries for dynamic dependencies
if (&genericparser::getElementName($aDynDependChildNode) eq "depend")
{
push @{$aBinaryInfoRef->{"depend"}}, (&genericparser::getElementValue($aDynDependChildNode));
}
}
}
if (&genericparser::getElementName($childNode) eq "localisation")
{
# The children nodes will contain the language code
my @aLocalisationNodes = &genericparser::getChildElements($childNode);
foreach my $aLocalisationChildNode (@aLocalisationNodes)
{
# There can be a list of binaries for dynamic dependencies
if (&genericparser::getElementName($aLocalisationChildNode) eq "default")
{
$aBinaryInfoRef->{"default"} = &genericparser::getElementValue($aLocalisationChildNode);
}
if (&genericparser::getElementName($aLocalisationChildNode) eq "language")
{
push @{$aBinaryInfoRef->{"language"}}, (&genericparser::getElementValue($aLocalisationChildNode));
}
}
}
if (&genericparser::getElementName($childNode) eq "options")
{
# The children nodes will contain the option details
my @aOptionNodes = &genericparser::getChildElements($childNode);
foreach my $aOptionChildNode (@aOptionNodes)
{
if (&genericparser::getElementName($aOptionChildNode) eq "multilinguify")
{
$aBinaryInfoRef->{"multilinguify"} = &genericparser::getElementValue($aOptionChildNode);
}
if (&genericparser::getElementName($aOptionChildNode) eq "stack")
{
$aBinaryInfoRef->{"stack"} = &genericparser::getElementValue($aOptionChildNode);
}
if (&genericparser::getElementName($aOptionChildNode) eq "heapmin")
{
$aBinaryInfoRef->{"heapmin"} = &genericparser::getElementValue($aOptionChildNode);
}
if (&genericparser::getElementName($aOptionChildNode) eq "heapmax")
{
$aBinaryInfoRef->{"heapmax"} = &genericparser::getElementValue($aOptionChildNode);
}
if (&genericparser::getElementName($aOptionChildNode) eq "fixed")
{
$aBinaryInfoRef->{"fixed"} = &genericparser::getElementValue($aOptionChildNode);
}
if (&genericparser::getElementName($aOptionChildNode) eq "priority")
{
$aBinaryInfoRef->{"priority"} = &genericparser::getElementValue($aOptionChildNode);
}
if (&genericparser::getElementName($aOptionChildNode) eq "uid1")
{
$aBinaryInfoRef->{"uid1"} = &genericparser::getElementValue($aOptionChildNode);
}
if (&genericparser::getElementName($aOptionChildNode) eq "uid2")
{
$aBinaryInfoRef->{"uid2"} = &genericparser::getElementValue($aOptionChildNode);
}
if (&genericparser::getElementName($aOptionChildNode) eq "uid3")
{
$aBinaryInfoRef->{"uid3"} = &genericparser::getElementValue($aOptionChildNode);
}
if (&genericparser::getElementName($aOptionChildNode) eq "dll")
{
$aBinaryInfoRef->{"dll"} = &genericparser::getElementValue($aOptionChildNode);
}
if (&genericparser::getElementName($aOptionChildNode) eq "dlldatatop")
{
$aBinaryInfoRef->{"dlldatatop"} = &genericparser::getElementValue($aOptionChildNode);
}
}
}
}
}
}
# To get the complete list of information for a given binary
# Input Parameter : Binary
# Returns the detailed information for each binary
sub GetBinaryInfo
{
my $aBinary = shift;
my $aBinaryInfoHash = \%{$binaryInfo{$aBinary}};
if ($aBinaryInfoHash->{IsFoundInCDF})
{
return $aBinaryInfoHash;
}
return undef;
}
# To get the complete list of dynamic dependencies for a given binary
# Input Parameter : Binary
# Returns the complete list of dynamic dependencies
sub GetDynamicDependencies
{
my $aBinary = shift;
my $bin = \%{$binaryInfo{$aBinary}};
return \@{$bin->{"depend"}};
}
#Returns the included feature list
sub GetIncludedFeatureList
{
return \@includeFeatureList;
}
#Returns the excluded feature list
sub GetExcludedFeatureList
{
return \@excludeFeatureList;
}
1;