imgtools/buildrom/tools/cdfparser.pm
author timothy.murphy@nokia.com
Sun, 28 Feb 2010 21:18:07 +0200
branchfix
changeset 279 733464eaac50
parent 0 044383f39525
child 590 360bd6b35136
permissions -rw-r--r--
fix: make sure host attribute is set rather than blank in logs on windows by using the env var 'COMPUTERNAME' instead of 'HOSTNAME'. Thus make it less difficult to order recipes in the log by time.

#
# 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;