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