diff -r c7c26511138f -r 360bd6b35136 imgtools/buildrom/tools/featuremanager.pm --- a/imgtools/buildrom/tools/featuremanager.pm Wed Jun 16 16:51:40 2010 +0300 +++ b/imgtools/buildrom/tools/featuremanager.pm Wed Jun 23 16:56:47 2010 +0800 @@ -1,852 +1,850 @@ -# -# 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: -# - -# This package contains routines to read the information from the Feature manager XML file. -package featuremanager; # Derived class for the feature manager xml parser - -BEGIN { - @ISA = qw(featureparser); # Derived from featuerParser - require featureparser; -}; - -use constant STRICTCASE=>1; # To suppress the case conversion in genericparser routine - -# Parse the featuredatabase XML file and generate the maps and counts -# -#featureset: -# {namespace} - optional -# {ibyname} - optional -# {hfilename} - optional -# {hfileheader} - optional -# {interfacestatus} -optional -# {interfacevisibility} - optional -# {feature_list} -# {feature} {}{statusflags} -# {name} -# {userdata} - optional -# {includemacro} -# {excludemacro} -# {infeaturesetiby} - optional -# {comment} - optional -# {}{statusflags} -# {name} -# {userdata} - optional -# {includemacro} -# {excludemacro} -# {infeaturesetiby} - optional -# {comment} -# - -# -# Class constructor -# -sub new -{ - my $class = shift; - my $object = $class->SUPER::new(); - - # Class members - $object->{_OBJNAME} = "FeatureManager"; # Name of the object - $object->{_FEAT_SET_LIST} = []; # Array of hash maps - $object->{_FEAT_LIST} = {}; # Hash map of all feature name with uid - $object->{_ALIAS_FEAT_LIST} = {}; # Hash map of all alias feature name with uid - return $object; -} - -# -# Private methods -# - -# Private method to Get/Set the _FEAT_SET_LIST member value of this class -# @param : reference to the array of hash maps (optional for GET) -# -my $featuresetList = sub -{ - my $object = shift; - return 0 if(!&featureparser::ISREF($object,"featuresetList")); - - if (@_) - { - $object->{_FEAT_SET_LIST} = shift; - } - return $object->{_FEAT_SET_LIST}; -}; - -# Private method to Get/Set the _FEAT_LIST member value of this class -# @param : reference to the fash map of feature name with uid (optional for GET) -# -my $featureList = sub -{ - my $object = shift; - return 0 if(!&featureparser::ISREF($object,"featureList")); - - if (@_) - { - $object->{_FEAT_LIST} = shift; - } - return $object->{_FEAT_LIST}; -}; -# Private method ot Get/Set the _ALIAS_FEAT_LIST member value of this class -# @param: reference to the hash map of alias feature name with uid -my $aliasfeatureList = sub -{ - my $object = shift; - return 0 if(!&featureparser::ISREF($object, "aliasfeatureList")); - - if(@_) - { - $object->{_ALIAS_FEAT_LIST} = shift; - } - return $object->{_ALIAS_FEAT_LIST}; -}; - -# Read the attributes of element -# @param : reference to the featureset -# @param : reference to the attributemap -# -my $fillFeatureSetAttributes = sub -{ - my $node = shift; - my $map = shift; - $map->{ibyname} = &featureparser::getattrValue($node, "ibyname", STRICTCASE); - $map->{hfilename} = &featureparser::getattrValue($node, "hfilename", STRICTCASE); - $map->{namespace} = &featureparser::getattrValue($node, "namespace", STRICTCASE); -}; - -# Read the attributes of element -# @param : reference to the featureset -# @param : reference to the attributemap -# -my $fillFileHeaderAttributes = sub -{ - my $node = shift; - my $map = shift; - my @attribSet = &featureparser::getnodefromTree($node, "hfileheader"); - - foreach my $att_node (@attribSet) - { - $map->{interfacestatus} = &featureparser::getattrValue($att_node, "interfacestatus",STRICTCASE); - $map->{interfacevisibility} = &featureparser::getattrValue($att_node, "interfacevisibility",STRICTCASE); - $map->{hfileheader} = &featureparser::getelementValue($att_node,STRICTCASE); - } -}; - -# Read the attributes of element -# @param : reference to the featureset -# @param : reference to the attributemap -# -my $fillFeatureAttributes = sub -{ - my $node = shift; my $map = shift; - - my @attribSet = &featureparser::getnodefromTree($node, "feature"); - - my %nameUidMap = (); - foreach my $att_node (@attribSet) - { - my ($uid_value, $feat_name, $attval); - my (@macroSet, @commentSet); - my %featureHash = (); - - #Read the feature name and its other attributes - $feat_name = &featureparser::getattrValue($att_node, "name",STRICTCASE); - - # Validate Name - if(!$feat_name) { - &featureparser::ERROR("Feature name attribute is empty"); - return 0; - } - if(exists $nameUidMap{lc($feat_name)}) { - &featureparser::ERROR("Feature entry \"".$feat_name."\" already exists"); - return 0; - } - - #Read the uid value - $uid_value = &featureparser::getattrValue($att_node, "uid"); - if(!&featureparser::IsValidNum($uid_value)) { - &featureparser::ERROR("Valid hexadecimal or decimal value expected in UID entry for \"$feat_name\""); - return 0; - } - $uid_value = &featureparser::ConvertHexToDecimal($uid_value); - if((defined $map->{feature}) && (exists $map->{feature}{$uid_value})) { - &featureparser::ERROR("UID entry for \"".$feat_name."\" already exists"); - return 0; - } - - $attval = &featureparser::getattrValue($att_node, "statusflags"); - if(!&featureparser::IsValidNum($attval)) { - &featureparser::ERROR("Valid hexadecimal or decimal value expected in STATUS_FLAGS entry for \"$feat_name\""); - return 0; - } - $featureHash{statusflags} = $attval; - - $attval = &featureparser::getattrValue($att_node, "userdata"); - if(defined $attval) { - if(!&featureparser::IsValidNum($attval)) { - &featureparser::ERROR("Valid hexadecimal or decimal value expected in USER_DATA entry for \"$feat_name\""); - return 0; - } - } - $featureHash{name} = $feat_name; - $featureHash{userdata} = $attval; - - #Read the attributes of element - @macroSet = &featureparser::getnodefromTree($att_node, "hrhmacro"); - foreach my $nodeMac (@macroSet) { - $featureHash{includemacro} = &featureparser::getattrValue($nodeMac,"include",STRICTCASE); - $featureHash{excludemacro} = &featureparser::getattrValue($nodeMac,"exclude",STRICTCASE); - - #Read the attribute infeaturesetiby - $attval = &featureparser::getattrValue($nodeMac,"infeaturesetiby"); - if(($attval eq undef) or (lc($attval) eq "yes")) { - $featureHash{infeaturesetiby} = 1; - } - elsif(lc($attval) eq "no") { - $featureHash{infeaturesetiby} = 0; - } - else { - &featureparser::ERROR("(yes|no) value expected in infeaturesetiby attribute for \"$feat_name\""); - return 0; - } - } - - #Read the element value - @commentSet = &featureparser::getnodefromTree($att_node, "comment"); - foreach my $nodeCmt (@commentSet) { - $featureHash{comment} = &featureparser::getelementValue($nodeCmt,STRICTCASE); - } - - #Add an entry to name->uid map for this feature - $nameUidMap{lc($feat_name)} = $uid_value; - #Add an entry to the global hash map with all the attributes of this feature - $map->{feature}{$uid_value} = \%featureHash; - } - - $map->{feature_list} = \%nameUidMap; - - return 1; -}; -my $fillAliasAttributes = sub -{ - my $node = shift; - my $map = shift; - my %aliasnameUidMap = (); - my $featureList = $map->{feature_list}; - my @attribSet = &featureparser::getnodefromTree($node, "featureoverride"); - foreach my $att_node (@attribSet) - { - my ($uid_value, $alias_name, $feat_name, $attval); - my (@macroSet, @commentSet); - my %featureHash = (); - #read the alias name - $alias_name = &featureparser::getattrValue($att_node, "name", STRICTCASE); - if(!$alias_name) - { - &featureparser::ERROR("Featureoverride name attribute is empty"); - return 0; - } - if(exists $featureList->{lc($alias_name)}) - { - &featureparser::ERROR("Can't override \"".sprintf("0x%08x", $featureList->{lc($alias_name)})."\" in the same "); - return 0; - } - if(exists $aliasnameUidMap{lc($alias_name)}) - { - &featureparser::ERROR("Can't override \"".sprintf("0x%08x", $aliasnameUidMap{lc($alias_name)})."\" in the same "); - return 0; - } - $uid_value = &featureparser::getattrValue($att_node, "uid"); - if(!&featureparser::IsValidNum($uid_value)) - { - &featureparser::ERROR("Valid hexadecimal or decimal value expected in UID entry for \"$alias_name\""); - return 0; - } - $uid_value = &featureparser::ConvertHexToDecimal($uid_value); - if((defined $map->{alias_feature}) && (exists $map->{alias_feature}{$uid_value})) - { - &featureparser::ERROR("Can't override \"".sprintf("0x%08x", $uid_value)."\" in the same "); - return 0; - } - if((defined $map->{feature}) && (exists $map->{feature}{$uid_value})) - { - &featureparser::ERROR("Can't override \"".sprintf("0x%08x", $uid_value)."\" in the same "); - return 0; - } - $attval = &featureparser::getattrValue($att_node, "statusflags"); - if(defined $attval) - { - if(!&featureparser::IsValidNum($attval)) - { - &featureparser::ERROR("Valid hexadecimal or decimal value expected in STATUS_FLAGS entry for \"$alias_name\""); - return 0; - } - } - $featureHash{statusflags} = $attval; - - $attval = &featureparser::getattrValue($att_node, "userdata"); - if(defined $attval) - { - if(!&featureparser::IsValidNum($attval)) - { - &featureparser::ERROR("Valid hexadecimal or decimal value expected in USER_DATA entry for \"$alias_name\""); - return 0; - } - } - - $featureHash{uid} = $uid_value; - $featureHash{name} = $alias_name; - $featureHash{userdata} = $attval; - #read the attributes of element - @macroSet = &featureparser::getnodefromTree($att_node,"hrhmacro"); - foreach my $nodeMac (@macroSet) - { - $featureHash{includemacro} = &featureparser::getattrValue($nodeMac, "include", STRICTCASE); - $featureHash{excludemacro} = &featureparser::getattrValue($nodeMac, "exclude", STRICTCASE); - #read the attribute infeaturesetiby - $attval = &featureparser::getattrValue($nodeMac, "infeaturesetiby"); - if(($attval eq undef) or (lc($attval) eq "yes")) - { - $featureHash{infeaturesetiby} = 1; - } - elsif(lc($attval) eq "no") - { - $featureHash{infeaturesetiby} = 0; - } - else - { - &featureparser::ERROR("(yes|no) value expected in infeaturesetiby attribute for \"$feat_name\""); - return 0; - } - } - #read the element value - @commentSet = &featureparser::getnodefromTree($att_node, "comment"); - foreach my $nodeCmt (@commentSet) - { - $featureHash{comment} = &featureparser::getelementValue($nodeCmt, STRICTCASE); - } - #add an entry to alias->uid map for this feature - $aliasnameUidMap{lc($alias_name)} = $uid_value; - #add an entry to the global hash map with all the attributes of this alias feature - $map->{alias_feature}{$uid_value} = \%featureHash; - } - $map->{alias_feature_list} = \%aliasnameUidMap; - - return 1; -}; - -# -# Public methods -# - -sub getAliasFeatureList -{ - my $object = shift; - return 0 if(!&featureparser::ISREF($object,"getAliasFeatureList")); - - my $aliasfeatlist = $object->$aliasfeatureList(); - return $aliasfeatlist; -} -# To get the status flag attribute value of the given feature -# @param : feature name -# -sub getStatusFlag -{ - my $object = shift; - return 0 if(!&featureparser::ISREF($object,"getStausFlag")); - - my $name = shift; - my $namespace = shift; - my $uid = $object->getFeatureUID($name, $namespace); - if($uid) - { - my $feature = $object->getFeatureInfo($uid, $namespace); - - return ($feature->{statusflags}) if(exists $feature->{statusflags}); - } - - return undef; -} - -# To get the user data attribute value of the given feature -# @param : feature name -# -sub getUserData -{ - my $object = shift; - return 0 if(!&featureparser::ISREF($object,"getUserData")); - - my $name = shift; - my $namespace = shift; - my $uid = $object->getFeatureUID($name, $namespace); - if($uid) - { - my $feature = $object->getFeatureInfo($uid, $namespace); - - return ($feature->{userdata}) if(exists $feature->{userdata}); - } - - return undef; -} - -# To get the include macro attribute value of the given feature -# @param : feature name -# -sub getIncludeMacro -{ - my $object = shift; - return 0 if(!&featureparser::ISREF($object,"getIncludeMacro")); - - my $name = shift; - my $uid = $object->getfeatureUID($name); - if($uid) - { - my $feature = $object->getfeatureInfo($uid); - return $feature->{includemacro}; - } - - return undef; -} - -# To get the exclude macro attribute value of the given feature -# @param : feature name -# -sub getExcludeMacro -{ - my $object = shift; - return 0 if(!&featureparser::ISREF($object,"getExcludeMacro")); - - my $name = shift; - my $uid = $object->getfeatureUID($name); - if($uid) - { - my $feature = $object->getfeatureInfo($uid); - return $feature->{excludemacro}; - } - - return undef; -} - -# Return the feature uid for the given feature name. -# @param : Feature Name -# @param : namespace of the featureset (optional) -# -sub getFeatureUID -{ - my $object = shift; - return 0 if(!&featureparser::ISREF($object,"getFeatureUID")); - - my $feature = shift; - my $namespace = shift; - my $featuresetList = $object->$featuresetList; - - $feature = lc($feature); - if($namespace eq undef) { - if(exists $$featuresetList[0]->{feature_list}{$feature}) { - return $$featuresetList[0]->{feature_list}{$feature}; - } - if(exists $$featuresetList[0]->{alias_feature_list}{$feature}) { - return $$featuresetList[0]->{alias_feature_list}{$feature}; - } - } - else { - foreach my $node (@$featuresetList) - { - if((lc($node->{namespace}) eq lc($namespace)) && ((exists $node->{feature_list}{$feature})||(exists $node->{alias_feature_list}{$feature}))) { - return $node->{feature_list}{$feature} if (exists $node->{feature_list}{$feature}); - return $node->{alias_feature_list}{$feature} if (exists $node->{alias_feature_list}{$feature}); - } - } - } - foreach my $node (@$featuresetList) { - return $node->{feature_list}{$feature} if(exists $node->{feature_list}{$feature}); - return $node->{alias_feature_list}{$feature} if(exists $node->{alias_feature_list}{$feature}); - } - return undef; -} - -# Get the details of feature with given featureuid and other parameters -# This function only consider the feature UID only and that UID should be in decimal -# @param : Feature UID -# @param : namespace of the featureset (optional) -# -sub getFeatureInfo -{ - my $object = shift; - return 0 if(!&featureparser::ISREF($object,"getFeatureInfo")); - - my $uid = shift; - my $namespace = shift; - my $featuresetList = $object->$featuresetList; - - if($namespace eq undef) { - foreach my $node (@$featuresetList) { - return $node->{alias_feature}{$uid} if(exists $node->{alias_feature}{$uid}); - } - if(exists $$featuresetList[0]->{feature}{$uid}) { - return $$featuresetList[0]->{feature}{$uid}; - } - if(exists $$featuresetList[0]->{alias_feature}{$uid}) { - return $$featuresetList[0]->{alias_feature}{$uid}; - } - } - else { - foreach my $node (@$featuresetList) - { - if((lc($node->{namespace}) eq lc($namespace)) && ((exists $node->{feature}{$uid})||(exists $node->{alias_feature}{$uid}))) { - return $node->{feature}{$uid} if (exists $node->{feature}{$uid}); - return $node->{alias_feature}{$uid} if (exists $node->{alias_feature}{$uid}); - } - } - } - foreach my $node (@$featuresetList) { - return $node->{feature}{$uid} if(exists $node->{feature}{$uid}); - } - return undef; -} - - -# Get the Feature set info as a hash -# @param: namespace of the featureset -# -sub getFeaturesetInfo -{ - my $object = shift; - return 0 if(!&featureparser::ISREF($object,"getFeaturesetInfo")); - - my $namespace = shift; - - my $featuresetList = $object->$featuresetList; - if($namespace eq undef) { - if(exists $$featuresetList[0]) { - return $$featuresetList[0]; - } - } - else { - foreach my $node (@$featuresetList) - { - if((lc($node->{namespace}) eq lc($namespace))) { - return $node; - } - } - } - return undef; -} - -# Get the Featureset namespaces as an array -# -sub getFeatureset -{ - my $object = shift; - return 0 if(!&featureparser::ISREF($object,"getFeatureset")); - - my @featureSet=(); - - my $featuresetList = $object->$featuresetList; - foreach my $node (@$featuresetList) { - push @featureSet, $node; - } - return \@featureSet; -} - -# Add feature registry object contents to feature manager object -# @param : feature registry object -# -sub addFeatureRegistry -{ - my $object = shift; - return 0 if(!&featureparser::ISREF($object,"addFeatureRegistry")); - - my $registryobj = shift; - my %attribHash = (); - my $nameuidmap; - my $newRangeList; - my $rangeList; - - # Adding default range list - $newRangeList = $registryobj->defaultRangeList(); - $rangeList = $object->defaultRangeList(); - - foreach my $newnode (@$newRangeList) { - my $include = 1; - foreach my $node (@$rangeList) { #Check if the range is already exists - if(($node->{min} == $newnode->{min}) && ($node->{max} == $newnode->{max}) - && ($node->{support} eq $newnode->{support})) { - $include = 0; - } - } - - if($include) { # Add it if it is new range - push @$rangeList, $newnode; - $object->defaultIncludeCount($object->defaultIncludeCount()+1) if(lc($newnode->{support}) eq "include"); - $object->defaultExcludeCount($object->defaultExcludeCount()+1) if(lc($newnode->{support}) eq "exclude"); - } - } - - # Adding feature list - $nameuidmap = $registryobj->featureNameUidMap(); - $attribHash{namespace} = undef; - $attribHash{feature_list} = $nameuidmap; - - foreach my $name (keys %$nameuidmap) { - my $uid = $nameuidmap->{$name}; - my %featureinfo = (); - - $featureinfo{name} = $name; - # Default values for statusflags and userdata - $featureinfo{statusflags} = "0x00000001"; - $featureinfo{userdata} = "0x00000000"; - - $attribHash{feature}{$uid} = \%featureinfo; - } - - # add the featureset into the feature manager object - return 0 if(! &addFeatureSet($object, \%attribHash)); - - return 1; -} - -# -# Utility functions -# -# Add the featureset into the hash map -# @param : reference to the atrribute hash map of featureset -# -sub addFeatureSet -{ - my $object = shift; - return 0 if(!&featureparser::ISREF($object,"addFeatureSet")); - - my $newSet = shift; - my $featSetList = $object->$featuresetList(); - my $newfeatList = $newSet->{feature_list}; - my $newaliasfeatList = $newSet->{alias_feature_list}; - - # Check for the duplicate featue names in the existing list - foreach my $name (keys %$newfeatList) - { - if(exists $object->$featureList()->{$name}) - { - &featureparser::ERROR("\(".$object->fileName()."\) Feature \"".uc($name)."\" already exists"); - return 0; - } - else - { - my $uid = $newfeatList->{$name}; - $object->$featureList()->{$name} = $uid; #Add it to global featue name list - } - } - - # Check for the duplicate UIDs in the existing list - if(@$featSetList) - { - foreach my $set (@$featSetList) - { - foreach my $name (keys %$newfeatList) - { - my $uid = $newfeatList->{$name}; - if(exists $set->{feature}{$uid}) - { - &featureparser::ERROR("\(".$object->fileName()."\) UID \"".sprintf("0x%08x",$uid)."\" for the feature \"".uc($name)."\" already exists"); - return 0; - } - } - } - } - #check for the duplicate alias feature names in the existing list - foreach my $alias_name (keys %$newaliasfeatList) - { - if(exists $object->$featureList()->{$alias_name}) - { - &featureparser::ERROR("\(".$object->fileName."\) Can't override \"".sprintf("0x%08x", $newaliasfeatList->{$alias_name})."\" with the same feature name ".$alias_name); - return 0; - - } - if(exists $object->$aliasfeatureList()->{$alias_name}) - { - &featureparser::ERROR("\(".$object->fileName."\) Can't override \"".sprintf("0x%08x", $newaliasfeatList->{$alias_name})."\" with the same feature name ".$alias_name); - return 0; - } - else - { - my $uid = $newaliasfeatList->{$alias_name}; - # add it to global alias feature name list - $object->$aliasfeatureList()->{$alias_name} = $uid; - } - } - #check if the original feature has existed in other feature set. - foreach my $alias_name (keys %$newaliasfeatList) - { - my $featHash; - my $uid = $newaliasfeatList->{$alias_name}; - foreach my $set (@$featSetList) - { - if(exists $set->{feature}{$uid}) - { - $featHash = $set->{feature}{$uid}; - last; - } - if(exists $set->{alias_feature}{$uid}) - { - $featHash = $set->{alias_feature}{$uid}; - last; - } - } - if(!$featHash) - { - &featureparser::ERROR("original feature definition does not exist."); - return 0; - } - - my $aliasfeatHash = $newSet->{alias_feature}{$uid}; - - if(($aliasfeatHash->{includemacro}) || ($aliasfeatHash->{excludemacro})) - { - if(($featHash->{includemacro}) || ($featHash->{excludemacro})) - { - &featureparser::WARN("the value of attribute hrhmacro has been overrided in ogrinal feature ".sprintf("0x%08x", $uid)); - undef $featHash->{includemacro}; - undef $featHash->{excludemacro}; - } - } - elsif($featHash->{includemacro} || $featHash->{excludemacro}) - { - &featureparser::WARN("the original value of attribute hrhmacro will be used for featureoverride ".sprintf("0x%08x", $uid)); - $aliasfeatHash->{includemacro} = $featHash->{includemacro}; - $aliasfeatHash->{excludemacro} = $featHash->{excludemacro}; - } - if($aliasfeatHash->{statusflags}) - { - if(($featHash->{statusflags}) && !($aliasfeatHash->{statusflags} eq $featHash->{statusflags})) - { - &featureparser::WARN("the value of attribute statusflags has been overrided in ogrinal feature ".sprintf("0x%08x", $uid)); - } - } - elsif($featHash->{statusflags}) - { - $aliasfeatHash->{statusflags} = $featHash->{statusflags}; - &featureparser::WARN("the original value of attribute statusflags will be used for featureoverride ".sprintf("0x%08x", $uid)); - } - if($aliasfeatHash->{userdata}) - { - if(($featHash->{userdata}) && !($aliasfeatHash->{userdata} eq $featHash->{userdata})) - { - &featureparser::WARN("the value of attribute userdata has been overrided in ogrinal feature ".sprintf("0x%08x", $uid)); - } - } - elsif($featHash->{userdata}) - { - $aliasfeatHash->{userdata} = $featHash->{userdata}; - &featureparser::WARN("the original value of attribute userdata will be used for featureoverride ".sprintf("0x%08x", $uid)); - } - if($aliasfeatHash->{infeaturesetiby}) - { - if(($featHash->{infeaturesetiby}) && ($aliasfeatHash->{infeaturesetiby} != $featHash->{infeaturesetiby})) - { - &featureparser::WARN("the value of attribute infeautresetiby has been overrided in ogrinal feature ".sprintf("0x%08x", $uid)); - } - } - elsif(defined($featHash->{infeaturesetiby})) - { - $aliasfeatHash->{infeaturesetiby} = $featHash->{infeaturesetiby}; - &featureparser::WARN("the original value of attribute infewaturesetiby will be used for featureoverride ".sprintf("0x%08x", $uid)); - } - } - # Add the unique featureset into the list - push @$featSetList, $newSet; - return 1; -} - -# Read the element -# -sub createFeatureMap -{ - my $object = shift; - return 0 if(!&featureparser::ISREF($object,"createFeatureMap")); - - # Return error if the rootelement reference is NULL - return 0 if($object->rootElement() < 0); - - # Get all the elements - my @attrSet = &featureparser::getnodefromTree($object->rootElement(), "featureset"); - - if(@attrSet) - { - foreach my $currNode (@attrSet) - { - my %attrHashMap = (); - - # Get the attributes - $fillFeatureSetAttributes->($currNode,\%attrHashMap); - # Get the attributes - $fillFileHeaderAttributes->($currNode,\%attrHashMap); - - # Get the attributes - return 0 if( !($fillFeatureAttributes->($currNode,\%attrHashMap)) ); - # Get the attributes - return 0 if( !($fillAliasAttributes->($currNode, \%attrHashMap)) ); - - # Add the featureset into the object - if(! &addFeatureSet($object,\%attrHashMap)) - { - return 0; - } - } - return 1; - } - return 0; -} - -# Read the element -# -sub createDefaultRangeMap -{ - my $object = shift; - return 0 if(!&featureparser::ISREF($object,"createDefaultRangeMap")); - - # Return error if the rootelement reference is NULL - return 0 if($object->rootElement() < 0); - - # Get all the elements - my @attrSet = &featureparser::getnodefromTree($object->rootElement(), "defaultfeaturerange"); - - # Add the defaultfeaturerange elements into the object - return &featureparser::createDefaultRangeMap($object,@attrSet); -} - -# Read the attributes of the element -# @param - node reference -# @param - reference to the range attributes -# -sub readRangeAttributes -{ - my ($object, $currNode, $range) = @_; - my @commentSet; - return 0 if(!&featureparser::ISREF($object,"readRangeAttributes")); - - #Get the lower and higher uids - $range->{min} = &featureparser::getattrValue($currNode, "loweruid"); - $range->{max} = &featureparser::getattrValue($currNode, "higheruid"); - - #Always supported/included for FM. Keep this value for compatible with FR - $range->{support} = "include"; - #Read the element - @commentSet = &featureparser::getnodefromTree($currNode, "comment"); - foreach my $node (@commentSet) { - $range->{comment} = &featureparser::getelementValue($node,STRICTCASE); - } -} - -1; +# +# 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: +# + +# This package contains routines to read the information from the Feature manager XML file. +package featuremanager; # Derived class for the feature manager xml parser + +BEGIN { + @ISA = qw(featureparser); # Derived from featuerParser + require featureparser; +}; + +use constant STRICTCASE=>1; # To suppress the case conversion in genericparser routine + +# Parse the featuredatabase XML file and generate the maps and counts +# +#featureset: +# {namespace} - optional +# {ibyname} - optional +# {hfilename} - optional +# {hfileheader} - optional +# {interfacestatus} -optional +# {interfacevisibility} - optional +# {feature_list} +# {feature} {}{statusflags} +# {name} +# {userdata} - optional +# {includemacro} +# {excludemacro} +# {infeaturesetiby} - optional +# {comment} - optional +# {}{statusflags} +# {name} +# {userdata} - optional +# {includemacro} +# {excludemacro} +# {infeaturesetiby} - optional +# {comment} +# + +# +# Class constructor +# +sub new +{ + my $class = shift; + my $object = $class->SUPER::new(); + + # Class members + $object->{_OBJNAME} = "FeatureManager"; # Name of the object + $object->{_FEAT_SET_LIST} = []; # Array of hash maps + $object->{_FEAT_LIST} = {}; # Hash map of all feature name with uid + $object->{_ALIAS_FEAT_LIST} = {}; # Hash map of all alias feature name with uid + return $object; +} + +# +# Private methods +# + +# Private method to Get/Set the _FEAT_SET_LIST member value of this class +# @param : reference to the array of hash maps (optional for GET) +# +my $featuresetList = sub +{ + my $object = shift; + return 0 if(!&featureparser::ISREF($object,"featuresetList")); + + if (@_) + { + $object->{_FEAT_SET_LIST} = shift; + } + return $object->{_FEAT_SET_LIST}; +}; + +# Private method to Get/Set the _FEAT_LIST member value of this class +# @param : reference to the fash map of feature name with uid (optional for GET) +# +my $featureList = sub +{ + my $object = shift; + return 0 if(!&featureparser::ISREF($object,"featureList")); + + if (@_) + { + $object->{_FEAT_LIST} = shift; + } + return $object->{_FEAT_LIST}; +}; +# Private method ot Get/Set the _ALIAS_FEAT_LIST member value of this class +# @param: reference to the hash map of alias feature name with uid +my $aliasfeatureList = sub +{ + my $object = shift; + return 0 if(!&featureparser::ISREF($object, "aliasfeatureList")); + + if(@_) + { + $object->{_ALIAS_FEAT_LIST} = shift; + } + return $object->{_ALIAS_FEAT_LIST}; +}; + +# Read the attributes of element +# @param : reference to the featureset +# @param : reference to the attributemap +# +my $fillFeatureSetAttributes = sub +{ + my $node = shift; + my $map = shift; + $map->{ibyname} = &featureparser::getattrValue($node, "ibyname", STRICTCASE); + $map->{hfilename} = &featureparser::getattrValue($node, "hfilename", STRICTCASE); + $map->{namespace} = &featureparser::getattrValue($node, "namespace", STRICTCASE); +}; + +# Read the attributes of element +# @param : reference to the featureset +# @param : reference to the attributemap +# +my $fillFileHeaderAttributes = sub +{ + my $node = shift; + my $map = shift; + my @attribSet = &featureparser::getnodefromTree($node, "hfileheader"); + + foreach my $att_node (@attribSet) + { + $map->{interfacestatus} = &featureparser::getattrValue($att_node, "interfacestatus",STRICTCASE); + $map->{interfacevisibility} = &featureparser::getattrValue($att_node, "interfacevisibility",STRICTCASE); + $map->{hfileheader} = &featureparser::getelementValue($att_node,STRICTCASE); + } +}; + +# Read the attributes of element +# @param : reference to the featureset +# @param : reference to the attributemap +# +my $fillFeatureAttributes = sub +{ + my $node = shift; my $map = shift; + + my @attribSet = &featureparser::getnodefromTree($node, "feature"); + + my %nameUidMap = (); + foreach my $att_node (@attribSet) + { + my ($uid_value, $feat_name, $attval); + my (@macroSet, @commentSet); + my %featureHash = (); + + #Read the feature name and its other attributes + $feat_name = &featureparser::getattrValue($att_node, "name",STRICTCASE); + + # Validate Name + if(!$feat_name) { + &featureparser::ERROR("Feature name attribute is empty"); + return 0; + } + if(exists $nameUidMap{lc($feat_name)}) { + &featureparser::ERROR("Feature entry \"".$feat_name."\" already exists"); + return 0; + } + + #Read the uid value + $uid_value = &featureparser::getattrValue($att_node, "uid"); + if(!&featureparser::IsValidNum($uid_value)) { + &featureparser::ERROR("Valid hexadecimal or decimal value expected in UID entry for \"$feat_name\""); + return 0; + } + $uid_value = &featureparser::ConvertHexToDecimal($uid_value); + if((defined $map->{feature}) && (exists $map->{feature}{$uid_value})) { + &featureparser::ERROR("UID entry for \"".$feat_name."\" already exists"); + return 0; + } + + $attval = &featureparser::getattrValue($att_node, "statusflags"); + if(!&featureparser::IsValidNum($attval)) { + &featureparser::ERROR("Valid hexadecimal or decimal value expected in STATUS_FLAGS entry for \"$feat_name\""); + return 0; + } + $featureHash{statusflags} = $attval; + + $attval = &featureparser::getattrValue($att_node, "userdata"); + if(defined $attval) { + if(!&featureparser::IsValidNum($attval)) { + &featureparser::ERROR("Valid hexadecimal or decimal value expected in USER_DATA entry for \"$feat_name\""); + return 0; + } + } + $featureHash{name} = $feat_name; + $featureHash{userdata} = $attval; + + #Read the attributes of element + @macroSet = &featureparser::getnodefromTree($att_node, "hrhmacro"); + foreach my $nodeMac (@macroSet) { + $featureHash{includemacro} = &featureparser::getattrValue($nodeMac,"include",STRICTCASE); + $featureHash{excludemacro} = &featureparser::getattrValue($nodeMac,"exclude",STRICTCASE); + + #Read the attribute infeaturesetiby + $attval = &featureparser::getattrValue($nodeMac,"infeaturesetiby"); + if(!defined($attval) or (lc($attval) eq "yes")) { + $featureHash{infeaturesetiby} = 1; + } + elsif(lc($attval) eq "no") { + $featureHash{infeaturesetiby} = 0; + } + else { + &featureparser::ERROR("(yes|no) value expected in infeaturesetiby attribute for \"$feat_name\""); + return 0; + } + } + + #Read the element value + @commentSet = &featureparser::getnodefromTree($att_node, "comment"); + foreach my $nodeCmt (@commentSet) { + $featureHash{comment} = &featureparser::getelementValue($nodeCmt,STRICTCASE); + } + + #Add an entry to name->uid map for this feature + $nameUidMap{lc($feat_name)} = $uid_value; + #Add an entry to the global hash map with all the attributes of this feature + $map->{feature}{$uid_value} = \%featureHash; + } + + $map->{feature_list} = \%nameUidMap; + + return 1; +}; +my $fillAliasAttributes = sub +{ + my $node = shift; + my $map = shift; + my %aliasnameUidMap = (); + my $featureList = $map->{feature_list}; + my @attribSet = &featureparser::getnodefromTree($node, "featureoverride"); + foreach my $att_node (@attribSet) + { + my ($uid_value, $alias_name, $feat_name, $attval); + my (@macroSet, @commentSet); + my %featureHash = (); + #read the alias name + $alias_name = &featureparser::getattrValue($att_node, "name", STRICTCASE); + if(!$alias_name) + { + &featureparser::ERROR("Featureoverride name attribute is empty"); + return 0; + } + if(exists $featureList->{lc($alias_name)}) + { + &featureparser::ERROR("Can't override \"".sprintf("0x%08x", $featureList->{lc($alias_name)})."\" in the same "); + return 0; + } + if(exists $aliasnameUidMap{lc($alias_name)}) + { + &featureparser::ERROR("Can't override \"".sprintf("0x%08x", $aliasnameUidMap{lc($alias_name)})."\" in the same "); + return 0; + } + $uid_value = &featureparser::getattrValue($att_node, "uid"); + if(!&featureparser::IsValidNum($uid_value)) + { + &featureparser::ERROR("Valid hexadecimal or decimal value expected in UID entry for \"$alias_name\""); + return 0; + } + $uid_value = &featureparser::ConvertHexToDecimal($uid_value); + if((defined $map->{alias_feature}) && (exists $map->{alias_feature}{$uid_value})) + { + &featureparser::ERROR("Can't override \"".sprintf("0x%08x", $uid_value)."\" in the same "); + return 0; + } + if((defined $map->{feature}) && (exists $map->{feature}{$uid_value})) + { + &featureparser::ERROR("Can't override \"".sprintf("0x%08x", $uid_value)."\" in the same "); + return 0; + } + $attval = &featureparser::getattrValue($att_node, "statusflags"); + if(defined $attval) + { + if(!&featureparser::IsValidNum($attval)) + { + &featureparser::ERROR("Valid hexadecimal or decimal value expected in STATUS_FLAGS entry for \"$alias_name\""); + return 0; + } + } + $featureHash{statusflags} = $attval; + + $attval = &featureparser::getattrValue($att_node, "userdata"); + if(defined $attval) + { + if(!&featureparser::IsValidNum($attval)) + { + &featureparser::ERROR("Valid hexadecimal or decimal value expected in USER_DATA entry for \"$alias_name\""); + return 0; + } + } + + $featureHash{uid} = $uid_value; + $featureHash{name} = $alias_name; + $featureHash{userdata} = $attval; + #read the attributes of element + @macroSet = &featureparser::getnodefromTree($att_node,"hrhmacro"); + foreach my $nodeMac (@macroSet) + { + $featureHash{includemacro} = &featureparser::getattrValue($nodeMac, "include", STRICTCASE); + $featureHash{excludemacro} = &featureparser::getattrValue($nodeMac, "exclude", STRICTCASE); + #read the attribute infeaturesetiby + $attval = &featureparser::getattrValue($nodeMac, "infeaturesetiby"); + if(!defined($attval) or (lc($attval) eq "yes")) + { + $featureHash{infeaturesetiby} = 1; + } + elsif(lc($attval) eq "no") + { + $featureHash{infeaturesetiby} = 0; + } + else + { + &featureparser::ERROR("(yes|no) value expected in infeaturesetiby attribute for \"$feat_name\""); + return 0; + } + } + #read the element value + @commentSet = &featureparser::getnodefromTree($att_node, "comment"); + foreach my $nodeCmt (@commentSet) + { + $featureHash{comment} = &featureparser::getelementValue($nodeCmt, STRICTCASE); + } + #add an entry to alias->uid map for this feature + $aliasnameUidMap{lc($alias_name)} = $uid_value; + #add an entry to the global hash map with all the attributes of this alias feature + $map->{alias_feature}{$uid_value} = \%featureHash; + } + $map->{alias_feature_list} = \%aliasnameUidMap; + + return 1; +}; + +# +# Public methods +# + +sub getAliasFeatureList +{ + my $object = shift; + return 0 if(!&featureparser::ISREF($object,"getAliasFeatureList")); + + my $aliasfeatlist = $object->$aliasfeatureList(); + return $aliasfeatlist; +} +# To get the status flag attribute value of the given feature +# @param : feature name +# +sub getStatusFlag +{ + my $object = shift; + return 0 if(!&featureparser::ISREF($object,"getStausFlag")); + + my $name = shift; + my $namespace = shift; + my $uid = $object->getFeatureUID($name, $namespace); + if($uid) + { + my $feature = $object->getFeatureInfo($uid, $namespace); + + return ($feature->{statusflags}) if(exists $feature->{statusflags}); + } + + return undef; +} + +# To get the user data attribute value of the given feature +# @param : feature name +# +sub getUserData +{ + my $object = shift; + return 0 if(!&featureparser::ISREF($object,"getUserData")); + + my $name = shift; + my $namespace = shift; + my $uid = $object->getFeatureUID($name, $namespace); + if($uid) + { + my $feature = $object->getFeatureInfo($uid, $namespace); + + return ($feature->{userdata}) if(exists $feature->{userdata}); + } + + return undef; +} + +# To get the include macro attribute value of the given feature +# @param : feature name +# +sub getIncludeMacro +{ + my $object = shift; + return 0 if(!&featureparser::ISREF($object,"getIncludeMacro")); + + my $name = shift; + my $uid = $object->getfeatureUID($name); + if($uid) + { + my $feature = $object->getfeatureInfo($uid); + return $feature->{includemacro}; + } + + return undef; +} + +# To get the exclude macro attribute value of the given feature +# @param : feature name +# +sub getExcludeMacro +{ + my $object = shift; + return 0 if(!&featureparser::ISREF($object,"getExcludeMacro")); + + my $name = shift; + my $uid = $object->getfeatureUID($name); + if($uid) + { + my $feature = $object->getfeatureInfo($uid); + return $feature->{excludemacro}; + } + + return undef; +} + +# Return the feature uid for the given feature name. +# @param : Feature Name +# @param : namespace of the featureset (optional) +# +sub getFeatureUID +{ + my $object = shift; + return 0 if(!&featureparser::ISREF($object,"getFeatureUID")); + + my $feature = shift; + my $namespace = shift; + my $featuresetList = $object->$featuresetList; + + $feature = lc($feature); + if(!defined ($namespace)) { + if(exists $$featuresetList[0]->{feature_list}{$feature}) { + return $$featuresetList[0]->{feature_list}{$feature}; + } + if(exists $$featuresetList[0]->{alias_feature_list}{$feature}) { + return $$featuresetList[0]->{alias_feature_list}{$feature}; + } + } + else { + foreach my $node (@$featuresetList) + { + if((lc($node->{namespace}) eq lc($namespace)) && ((exists $node->{feature_list}{$feature})||(exists $node->{alias_feature_list}{$feature}))) { + return $node->{feature_list}{$feature} if (exists $node->{feature_list}{$feature}); + return $node->{alias_feature_list}{$feature} if (exists $node->{alias_feature_list}{$feature}); + } + } + } + foreach my $node (@$featuresetList) { + return $node->{feature_list}{$feature} if(exists $node->{feature_list}{$feature}); + return $node->{alias_feature_list}{$feature} if(exists $node->{alias_feature_list}{$feature}); + } + return undef; +} + +# Get the details of feature with given featureuid and other parameters +# This function only consider the feature UID only and that UID should be in decimal +# @param : Feature UID +# @param : namespace of the featureset (optional) +# +sub getFeatureInfo +{ + my $object = shift; + return 0 if(!&featureparser::ISREF($object,"getFeatureInfo")); + + my $uid = shift; + my $namespace = shift; + my $featuresetList = $object->$featuresetList; + + if(!defined($namespace)) { + foreach my $node (@$featuresetList) { + return $node->{alias_feature}{$uid} if(exists $node->{alias_feature}{$uid}); + } + if(exists $$featuresetList[0]->{feature}{$uid}) { + return $$featuresetList[0]->{feature}{$uid}; + } + if(exists $$featuresetList[0]->{alias_feature}{$uid}) { + return $$featuresetList[0]->{alias_feature}{$uid}; + } + } + else { + foreach my $node (@$featuresetList) + { + if((lc($node->{namespace}) eq lc($namespace)) && ((exists $node->{feature}{$uid})||(exists $node->{alias_feature}{$uid}))) { + return $node->{feature}{$uid} if (exists $node->{feature}{$uid}); + return $node->{alias_feature}{$uid} if (exists $node->{alias_feature}{$uid}); + } + } + } + foreach my $node (@$featuresetList) { + return $node->{feature}{$uid} if(exists $node->{feature}{$uid}); + } + return undef; +} + + +# Get the Feature set info as a hash +# @param: namespace of the featureset +# +sub getFeaturesetInfo +{ + my $object = shift; + return 0 if(!&featureparser::ISREF($object,"getFeaturesetInfo")); + + my $namespace = shift; + + my $featuresetList = $object->$featuresetList; + if(!defined ($namespace)) { + if(exists $$featuresetList[0]) { + return $$featuresetList[0]; + } + } + else { + foreach my $node (@$featuresetList) + { + if((lc($node->{namespace}) eq lc($namespace))) { + return $node; + } + } + } + return undef; +} + +# Get the Featureset namespaces as an array +# +sub getFeatureset +{ + my $object = shift; + return 0 if(!&featureparser::ISREF($object,"getFeatureset")); + + my @featureSet=(); + + my $featuresetList = $object->$featuresetList; + foreach my $node (@$featuresetList) { + push @featureSet, $node; + } + return \@featureSet; +} + +# Add feature registry object contents to feature manager object +# @param : feature registry object +# +sub addFeatureRegistry +{ + my $object = shift; + return 0 if(!&featureparser::ISREF($object,"addFeatureRegistry")); + + my $registryobj = shift; + my %attribHash = (); + my $nameuidmap; + my $newRangeList; + my $rangeList; + + # Adding default range list + $newRangeList = $registryobj->defaultRangeList(); + $rangeList = $object->defaultRangeList(); + + foreach my $newnode (@$newRangeList) { + my $include = 1; + foreach my $node (@$rangeList) { #Check if the range is already exists + if(($node->{min} == $newnode->{min}) && ($node->{max} == $newnode->{max}) + && ($node->{support} eq $newnode->{support})) { + $include = 0; + } + } + + if($include) { # Add it if it is new range + push @$rangeList, $newnode; + $object->defaultIncludeCount($object->defaultIncludeCount()+1) if(lc($newnode->{support}) eq "include"); + $object->defaultExcludeCount($object->defaultExcludeCount()+1) if(lc($newnode->{support}) eq "exclude"); + } + } + + # Adding feature list + $nameuidmap = $registryobj->featureNameUidMap(); + $attribHash{namespace} = undef; + $attribHash{feature_list} = $nameuidmap; + + foreach my $name (keys %$nameuidmap) { + my $uid = $nameuidmap->{$name}; + my %featureinfo = (); + + $featureinfo{name} = $name; + # Default values for statusflags and userdata + $featureinfo{statusflags} = "0x00000001"; + $featureinfo{userdata} = "0x00000000"; + + $attribHash{feature}{$uid} = \%featureinfo; + } + + # add the featureset into the feature manager object + return 0 if(! &addFeatureSet($object, \%attribHash)); + + return 1; +} + +# +# Utility functions +# +# Add the featureset into the hash map +# @param : reference to the atrribute hash map of featureset +# +sub addFeatureSet +{ + my $object = shift; + return 0 if(!&featureparser::ISREF($object,"addFeatureSet")); + + my $newSet = shift; + my $featSetList = $object->$featuresetList(); + my $newfeatList = $newSet->{feature_list}; + my $newaliasfeatList = $newSet->{alias_feature_list}; + + # Check for the duplicate featue names in the existing list + foreach my $name (keys %$newfeatList) + { + if(exists $object->$featureList()->{$name}) + { + &featureparser::ERROR("\(".$object->fileName()."\) Feature \"".uc($name)."\" already exists"); + return 0; + } + else + { + my $uid = $newfeatList->{$name}; + $object->$featureList()->{$name} = $uid; #Add it to global featue name list + } + } + + # Check for the duplicate UIDs in the existing list + if(@$featSetList) + { + foreach my $set (@$featSetList) + { + foreach my $name (keys %$newfeatList) + { + my $uid = $newfeatList->{$name}; + if(exists $set->{feature}{$uid}) + { + &featureparser::ERROR("\(".$object->fileName()."\) UID \"".sprintf("0x%08x",$uid)."\" for the feature \"".uc($name)."\" already exists"); + return 0; + } + } + } + } + #check for the duplicate alias feature names in the existing list + foreach my $alias_name (keys %$newaliasfeatList) + { + if(exists $object->$featureList()->{$alias_name}) + { + &featureparser::ERROR("\(".$object->fileName."\) Can't override \"".sprintf("0x%08x", $newaliasfeatList->{$alias_name})."\" with the same feature name ".$alias_name); + return 0; + + } + if(exists $object->$aliasfeatureList()->{$alias_name}) + { + &featureparser::ERROR("\(".$object->fileName."\) Can't override \"".sprintf("0x%08x", $newaliasfeatList->{$alias_name})."\" with the same feature name ".$alias_name); + return 0; + } + else + { + my $uid = $newaliasfeatList->{$alias_name}; + # add it to global alias feature name list + $object->$aliasfeatureList()->{$alias_name} = $uid; + } + } + #check if the original feature has existed in other feature set. + foreach my $alias_name (keys %$newaliasfeatList) + { + my $featHash; + my $uid = $newaliasfeatList->{$alias_name}; + foreach my $set (@$featSetList) + { + if(exists $set->{feature}{$uid}) + { + $featHash = $set->{feature}{$uid}; + last; + } + if(exists $set->{alias_feature}{$uid}) + { + $featHash = $set->{alias_feature}{$uid}; + last; + } + } + if(!$featHash) + { + &featureparser::ERROR("Original feature definition does not exist for feature ".sprintf("0x%08x", $uid)); + return 0; + } + + my $aliasfeatHash = $newSet->{alias_feature}{$uid}; + + if(($aliasfeatHash->{includemacro}) || ($aliasfeatHash->{excludemacro})) + { + if (($featHash->{includemacro} || $featHash->{excludemacro}) && (!(($featHash->{includemacro} && ($featHash->{includemacro} eq $aliasfeatHash->{includemacro})) || ($featHash->{excludemacro} && ($featHash->{excludemacro} eq $aliasfeatHash->{excludemacro}))))) + { + &featureparser::WARN("the value of attribute hrhmacro has been overridden in original feature ".sprintf("0x%08x", $uid)); + } + undef $featHash->{includemacro}; + undef $featHash->{excludemacro}; + } + elsif($featHash->{includemacro} || $featHash->{excludemacro}) + { + $aliasfeatHash->{includemacro} = $featHash->{includemacro}; + $aliasfeatHash->{excludemacro} = $featHash->{excludemacro}; + undef $featHash->{includemacro}; + undef $featHash->{excludemacro}; + } + if($aliasfeatHash->{statusflags}) + { + if(($featHash->{statusflags}) && !($aliasfeatHash->{statusflags} eq $featHash->{statusflags})) + { + &featureparser::WARN("the value of attribute statusflags has been overridden in original feature ".sprintf("0x%08x", $uid)); + } + } + elsif($featHash->{statusflags}) + { + $aliasfeatHash->{statusflags} = $featHash->{statusflags}; + } + if($aliasfeatHash->{userdata}) + { + if(($featHash->{userdata}) && !($aliasfeatHash->{userdata} eq $featHash->{userdata})) + { + &featureparser::WARN("the value of attribute userdata has been overridden in original feature ".sprintf("0x%08x", $uid)); + } + } + elsif($featHash->{userdata}) + { + $aliasfeatHash->{userdata} = $featHash->{userdata}; + } + if($aliasfeatHash->{infeaturesetiby}) + { + if(($featHash->{infeaturesetiby}) && ($aliasfeatHash->{infeaturesetiby} != $featHash->{infeaturesetiby})) + { + &featureparser::WARN("the value of attribute infeautresetiby has been overridden in original feature ".sprintf("0x%08x", $uid)); + } + } + elsif(defined($featHash->{infeaturesetiby})) + { + $aliasfeatHash->{infeaturesetiby} = $featHash->{infeaturesetiby}; + } + } + # Add the unique featureset into the list + push @$featSetList, $newSet; + return 1; +} + +# Read the element +# +sub createFeatureMap +{ + my $object = shift; + return 0 if(!&featureparser::ISREF($object,"createFeatureMap")); + + # Return error if the rootelement reference is NULL + return 0 if($object->rootElement() < 0); + + # Get all the elements + my @attrSet = &featureparser::getnodefromTree($object->rootElement(), "featureset"); + + if(@attrSet) + { + foreach my $currNode (@attrSet) + { + my %attrHashMap = (); + + # Get the attributes + $fillFeatureSetAttributes->($currNode,\%attrHashMap); + # Get the attributes + $fillFileHeaderAttributes->($currNode,\%attrHashMap); + + # Get the attributes + return 0 if( !($fillFeatureAttributes->($currNode,\%attrHashMap)) ); + # Get the attributes + return 0 if( !($fillAliasAttributes->($currNode, \%attrHashMap)) ); + + # Add the featureset into the object + if(! &addFeatureSet($object,\%attrHashMap)) + { + return 0; + } + } + return 1; + } + return 0; +} + +# Read the element +# +sub createDefaultRangeMap +{ + my $object = shift; + return 0 if(!&featureparser::ISREF($object,"createDefaultRangeMap")); + + # Return error if the rootelement reference is NULL + return 0 if($object->rootElement() < 0); + + # Get all the elements + my @attrSet = &featureparser::getnodefromTree($object->rootElement(), "defaultfeaturerange"); + + # Add the defaultfeaturerange elements into the object + return &featureparser::createDefaultRangeMap($object,@attrSet); +} + +# Read the attributes of the element +# @param - node reference +# @param - reference to the range attributes +# +sub readRangeAttributes +{ + my ($object, $currNode, $range) = @_; + my @commentSet; + return 0 if(!&featureparser::ISREF($object,"readRangeAttributes")); + + #Get the lower and higher uids + $range->{min} = &featureparser::getattrValue($currNode, "loweruid"); + $range->{max} = &featureparser::getattrValue($currNode, "higheruid"); + + #Always supported/included for FM. Keep this value for compatible with FR + $range->{support} = "include"; + #Read the element + @commentSet = &featureparser::getnodefromTree($currNode, "comment"); + foreach my $node (@commentSet) { + $range->{comment} = &featureparser::getelementValue($node,STRICTCASE); + } +} + +1;