imgtools/buildrom/tools/featuresutil.pm
changeset 0 044383f39525
child 590 360bd6b35136
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/buildrom/tools/featuresutil.pm	Tue Oct 27 16:36:35 2009 +0000
@@ -0,0 +1,534 @@
+#
+# Copyright (c) 2007-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: 
+#
+
+package featuresutil;
+        
+
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT = qw(
+	parseXMLDatabase
+	createFeatureFile
+	convert_FeatRegToFeatMgr
+);
+
+use strict;
+use XML::Handler::XMLWriter;
+use IO;
+
+use featureparser;
+use featuremanager;
+use featureregistry;
+use featuresdat;
+use featurecfg;
+
+my $xmlDBHandle = undef; #Object of feature parser
+
+my @includeFeatureList;	#List of included features. The included feature in this list is a hash table giving the 
+			#Uid or the name. These features are collected from the iby/obey files.
+my @excludeFeatureList;	#List of excluded features.The excluded feature in this list is a hash table giving the 
+			#Uid or the name. These features are collected from the iby/obey files.
+
+my $verboseFlg = 0; # verbose mode flag
+my $strictFlg = 1; # strict mode flag
+
+# Subroutine to generate warning messages.
+sub WARN 
+{
+	print "WARNING: ".$_[0]."\n"; 
+}
+
+# Subroutine to generate error messages.
+sub ERROR 
+{ 
+	print "ERROR: ".$_[0]."\n"; 
+}
+
+# Verbose mode output routine
+sub MSG 
+{
+	if($verboseFlg) {
+		print "**".$_[0]."...\n";
+	}
+}
+
+# Subroutine to parse feature list XML database file.
+# @param dbfileList					- List of XML database file names seperated by commas.
+# @param fmFlag						- Flag to generate features data file.
+# @param strictFlg					- Flag to enable strict mode (optional).
+# @param verboseFlg                 - Flag to enable verbose mode (optional).
+sub parseXMLDatabase
+{
+	my $dbfileList = shift;
+	my $fmFlag = shift;
+	$strictFlg = shift;
+	$verboseFlg = shift;
+	
+	# list of xml databases
+	my @filelist = split(/,/,$dbfileList);
+	
+	# return status
+	my $retStatus = 0;
+	
+	# default mode is strict
+	$strictFlg=0 if(!defined $strictFlg);
+	# default mode is nonverbose
+	$verboseFlg=0 if(!defined $verboseFlg);
+	
+	# multiple file support is not applicable for feature registry option
+	if( (@filelist > 1) && (!$fmFlag) ) {
+		&ERROR("Multiple XML database file support is not applicable for featureregistry option");
+		return 0;
+	}
+	
+	if($fmFlag) # Feature manager option handling
+	{
+		# create the object of feature manager class
+		$xmlDBHandle = new featuremanager;
+		
+		if($xmlDBHandle) {
+			foreach my $file (@filelist) 
+			{
+				my $status = 1;
+				if(-e $file) {
+					
+					&MSG("Parsing $file");
+					
+					# parse the feature manager xml file
+					$status = $xmlDBHandle->parseXMLFile($file);
+					if(! $status) {
+					
+						# create the object of feature registry class
+						my $registryObj = new featureregistry;
+						# parse the feature registry xml file
+						$status = $registryObj->parseXMLFile($file);
+						if($status < 0) {
+							if($strictFlg) {
+								&ERROR("Invalid features database $file");
+								$xmlDBHandle = undef;
+								return 0;
+							}
+							else {
+								&WARN("Invalid features database $file");
+							}
+						}
+						elsif(! $status) {
+							# if the xml file is not valid feature list xml file
+							if($strictFlg) {
+								&ERROR("Error in reading features database file \"$file\"");
+								$xmlDBHandle = undef;
+								return 0;
+							}
+							else {
+								&WARN("Error in reading features database file \"$file\"");
+							}
+						}
+						else {
+							MSG("Converting featureregistry database to featuremanager");
+							
+							# add the feature registry file object to the feature manager file object
+							if(! $xmlDBHandle->addFeatureRegistry($registryObj)) {
+								if($strictFlg) {
+									MSG("Error in reading features database file \"$file\"");
+									$xmlDBHandle = undef;
+									return 0;
+								}
+								else {
+									&WARN("Error in reading features database file \"$file\"");
+								}
+							}
+							else {
+								# parsing feature registry database success
+								$retStatus = 1;
+							}
+						}
+					}
+					elsif( $status < 0 ) {
+						if($strictFlg) {
+							&ERROR("Invalid features database $file");
+							$xmlDBHandle = undef;
+							return 0;
+						}
+						else {
+							&WARN("Invalid features database $file");
+						}
+					}
+					else {
+						# parsing feature manager database success
+						$retStatus = 1;
+					}
+				}
+				else {
+					if(!$strictFlg) {
+						&WARN($file." doesn\'t exist");
+						next;
+					}
+					else {
+						&ERROR($file." doesn\'t exist");
+						$xmlDBHandle = undef;
+						return 0;
+					}
+				}
+			}
+		}
+		else {
+			&ERROR("Couldn't create feature parser object");
+		}
+	}
+	else # Feature registry file handling
+	{
+		if(@filelist) {
+			my $file = $filelist[0];
+			$xmlDBHandle = new featureregistry;
+			
+			if($xmlDBHandle) {
+				if(-e $file) {
+				
+					MSG("Parsing $file");
+					
+					my $status = $xmlDBHandle->parseXMLFile($file);
+
+					if($status < 0) {
+						&ERROR($file." is invalid feature registry file");
+						$xmlDBHandle = undef;
+						return 0;
+					}
+					elsif(!$status) {
+						&ERROR("Error in reading feature registry file ".$file);
+						$xmlDBHandle = undef;
+					}
+					else {
+						# parsing feature registry database success
+						$retStatus = 1;
+					}
+				}
+				else {
+					if(!$strictFlg) {
+						&WARN($file." doesn\'t exist -- ");
+					}
+					else {
+						&ERROR($file." doesn\'t exist -- ");
+					}				
+					$xmlDBHandle = undef;
+				}
+			}
+			else {
+				&ERROR("Couldn't create feature parser object");
+			}
+		}
+	}
+	
+	if($retStatus) {
+		return $xmlDBHandle
+	}
+	else {
+		return $retStatus;
+	}
+}
+
+# Subroutine to generate feature manager database file from the given feature registry database
+# @param strictFlg - strict mode flag
+# @param verboseFlg - verbose mode flag
+# @param outpath - destination path for the converted database file(s)
+# @param dblist - list of xml file names
+sub convert_FeatRegToFeatMgr
+{
+	$strictFlg = shift;
+	$verboseFlg = shift;
+	my $outpath = shift;
+	my @dblist = @_;
+	
+	# default mode is strict
+	$strictFlg=0 if(!defined $strictFlg);
+	# default mode is nonverbose
+	$verboseFlg=0 if(!defined $verboseFlg);
+
+	foreach my $file (@dblist)
+	{
+		# Create the object of feature registry
+		my $fileHandle = new featureregistry;
+		
+		if(-e $file) {
+			# Parse the database
+			if($fileHandle->parseXMLFile($file) > 0) {
+				MSG("Converting Feature Registry database $file");
+				
+				# Create directory if it doesn't exists
+				if(!(-e $outpath)) {
+					if(!mkdir($outpath)) {
+						&ERROR("Failed to create $outpath folder");
+						return 0;
+					}
+				}
+				# Emit the contents of feature registry object into an feature manager database file
+				&generateXML($fileHandle, $outpath);
+			}
+		}
+		else {
+			if(!$strictFlg) {
+				&WARN($file." doesn\'t exist -- ");
+				next;
+			}
+			else {
+				&ERROR($file." doesn\'t exist -- ");
+				return 0;
+			}
+		}
+	}
+}
+
+# Subroutine to emit XML output for the given featureregistry object
+# @param frObject - object of feature registry database
+# @param outPath - destination path for the converted database file
+sub generateXML
+{
+	my ($frObject, $outPath) = @_;
+		
+	my $outputFile = $frObject->fileName();
+	
+	# Extract absolute file name
+	if( $outputFile =~ /[\\\/]/) {
+		$outputFile =~ /.*[\\\/](.+)\z/;
+		$outputFile = $1;
+	}
+	
+	# Add suffix _converted
+	$outputFile =~ s/(.*)([\.].+)\z/$1_converted$2/;
+	
+	my $fileHandle = new IO::File(">$outPath$outputFile");
+	
+	if($fileHandle) {
+		my $writer = XML::Handler::XMLWriter->new(Output => $fileHandle);
+		
+		# Header
+		$writer->start_document();
+		$writer->print("<!--Converted from the feature registry ".$frObject->fileName()."-->\n\n");
+		# DOCTYPE
+		$writer->print("<!DOCTYPE featuredatabase SYSTEM \"featuredatabase.dtd\">\n\n");
+		
+		# Root element begin
+		$writer->start_element({Name => 'featuredatabase', Attributes => {}});
+		
+		# FeatureSet element
+		$writer->print("\n\t");
+		$writer->start_element({Name => 'featureset', Attributes => {}});
+		my $nameuidmap = $frObject->featureNameUidMap();
+		foreach my $uid (sort(values %$nameuidmap)) {
+			my $featinfo = $frObject->getFeatureInfo($uid);
+			my %attributes = ();
+			
+			$attributes{uid} = sprintf("0x%08X",$uid);
+			$attributes{statusflags} = "0x00000001";
+			$attributes{name} = $featinfo->{name};
+			
+			$writer->print("\n\t\t");
+			$writer->start_element({Name => 'feature', Attributes => \%attributes});
+			$writer->end_element({Name => 'feature'});
+		}
+		$writer->print("\n\t");
+		$writer->end_element({Name => 'featureset'});
+		
+		# defaultfeaturerange element
+		my $rangeList = $frObject->defaultRangeList();
+		foreach my $range (@$rangeList) {
+			my %attributes = ();
+			
+			next if(lc($range->{support}) eq "exclude");
+			
+			$attributes{higheruid} = sprintf("0x%08X",$range->{max});
+			$attributes{loweruid} = sprintf("0x%08X",$range->{min});
+			
+			$writer->print("\n\t");
+			$writer->start_element({Name => 'defaultfeaturerange', Attributes => \%attributes});
+			$writer->end_element({Name => 'defaultfeaturerange'});
+		}
+		
+		# Root element close
+		$writer->print("\n");
+		$writer->end_element({Name => 'featuredatabase'});
+		
+		# Footer
+		$writer->end_document();
+	}
+	else {
+		&ERROR("Failed to create $outPath$outputFile file");
+	}
+}
+
+# Subroutine to create Feature Registry/Features Data file
+# @param romimage				 - Rom image number.
+# @param featurefile			 - Feature file number.
+# @param featurefilename		 - Name of the feature file to be generated.
+# @param featureslist			 - Reference to array of hashes containing features to included/excluded.
+# @param featuremanager			 - Flag to generate features data file.
+# @param singleDATfile           - Flag to generate single features.dat file.
+sub createFeatureFile
+{
+	if($xmlDBHandle == undef) 
+	{
+		ERROR("No XML Database opened");
+		return 0;
+	}	
+	my ($romimage,$featurefile,$featurefilename,$featureslist,$featuremanager,$singleDATfile) = @_;
+	
+	# Default setting for singleDATfile flag
+	$singleDATfile = 0 if(!defined $singleDATfile);
+	
+	# Clear the global include/exclude feature list.
+	@includeFeatureList = (); 
+	@excludeFeatureList = ();
+
+
+	for(my $k=0;$k<scalar @$featureslist;$k++)
+	{
+		if(($singleDATfile) || ($featureslist->[$k]{rom}==$romimage && $featureslist->[$k]{cfgfile} == $featurefile))
+		{			
+			AddToFeatureList($featureslist->[$k],$featuremanager);
+		}
+	}
+
+	my $features = &featureparser::getFeatures(\@includeFeatureList, \@excludeFeatureList);
+	if (!$features)
+	{
+		ERROR("No feature file generated for ROM_IMAGE[".$romimage."]");
+		return 0;
+	}
+	else
+	{
+		my $object;
+		if ($featuremanager) 
+		{
+			$object = new featuresdat($xmlDBHandle);
+		}
+		else
+		{
+			$object = new featurecfg($xmlDBHandle);
+		}		
+		return $object->createFile($featurefilename, $features , $featuremanager);
+	}	
+}
+
+# Subroutine to add the feature specified to the included/excluded feature list
+# @param featureData				 - Reference to hash containing feature information (i.e. name/uid,
+# 									   included/excluded,SF and UD).  
+# @param featuremanager				 - Flag to generate features data file.
+sub AddToFeatureList
+{
+	my ($featureData, $featuremanager) = @_; 	
+	
+	my %feat = ();
+	my $feature = $featureData->{feature};		
+	
+#	Check if the given value is a feature name.
+	my $value = $xmlDBHandle->getFeatureUID($feature);
+
+#	If not a feature, then may be uid value
+	if(!defined $value)
+	{
+		if (!featureparser::IsValidNum($feature)) 
+		{
+			ERROR("Feature \"".$feature."\" not found in feature list XML");
+			return;
+		}
+		if (&featureparser::ValidateUIDValue($feature))
+		{
+			my $featureUid = $feature;
+			$feature = &featureparser::ConvertHexToDecimal($feature);
+			my $featureInfo = $xmlDBHandle->getFeatureInfo($feature);
+			if (!$featureInfo)
+			{
+				ERROR("Feature \"".$featureUid."\" not found in feature list XML");
+				return;
+			}
+			else
+			{
+				$feat{uid} = $feature;
+				$feat{name} = $featureInfo->{name};				
+			}
+		}
+		else
+		{
+			return;
+		}
+	}
+	else
+	{
+		$feat{name} = $feature;
+		$feat{uid} = $value;		
+	}		
+
+	# Set the values of "SF" and "UD" for feature manager.
+	if ($featuremanager) 
+	{		
+		&setFeatureArguments(\%feat,$featureData->{SF},$featureData->{UD});
+	}	
+
+	if($featureData->{include} == 1)
+	{
+		$feat{include} = 1;
+		push @includeFeatureList, \%feat;
+	}
+	else
+	{
+		$feat{exclude} = 1;
+		push @excludeFeatureList, \%feat;
+	}
+}
+
+# Subroutine to set the values of "SF" and "UD" for the specified feature
+# @param feat						- Reference to hash containing information(i.e. name and uid) 
+#									  of the specified feature.
+# @param SF							- Value of "SF" provided in the iby/oby file. 
+# @param UD							- Value of "UD" provided in the iby/oby file.
+sub setFeatureArguments
+{
+	my($feat,$SF,$UD)= @_;
+	
+	my $featureInfo = $xmlDBHandle->getFeatureInfo($feat->{uid});
+	
+	# If the values of 'SF' and 'UD' are not provided in the iby/oby file, then take the values
+	# from Feature Database XML file.
+	if ($SF && featureparser::IsValidNum($SF))  
+	{
+		$feat->{SF} = &featureparser::ConvertHexToDecimal($SF);
+	}
+	else 
+	{
+		# Generate warning if the value of "SF" provided for the feature in iby/oby file
+		# is invalid.
+		if ($SF) 
+		{
+			WARN("Invalid SF value \"$SF\" provided for feature \"$feat->{name}\". Defaulting to value provided in XML file");
+		}
+		$feat->{SF} = &featureparser::ConvertHexToDecimal($featureInfo->{statusflags});			
+	}
+	if ($UD && featureparser::IsValidNum($UD))  					
+	{			
+		$feat->{UD} = &featureparser::ConvertHexToDecimal($UD);						
+	}
+	else 
+	{
+		# Generate warning if the value of "UD" provided for the feature in iby/oby file
+		# is invalid.
+		if ($UD) 
+		{
+			WARN("Invalid UD value \"$UD\" provided for feature \"$feat->{name}\". Defaulting to value provided in XML file");
+		}
+		$feat->{UD} = &featureparser::ConvertHexToDecimal($featureInfo->{userdata});				
+	}				
+}
+
+1;