fix: stop using "magic" numbers in string operations for the copyannofile2log feature
fix: When using the copylogfromannofile workaround, extract the build ID and build duration and add to the log as these are useful for analysis. The log should now be identical to the stdout file.
fix: Remove extra blank lines from output in copylogfromannofile mode.
#
# 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 List XML file.
package featureparser; # Base class implementation of feature list xml parser
# Include the genericparser to use API to read from XML file.
use genericparser;
use strict;
#
# Class constructor
#
sub new {
my $class = shift;
my $object = {};
# Class members
$object->{_DEFAULT_RANGE} = []; # Array of default ranges
$object->{_DEFAULT_INCLUDE_COUNT} = 0; # Default include range count
$object->{_DEFAULT_EXCLUDE_COUNT} = 0; # Default exclude range count
$object->{_FILENAME} = undef; # Current xml file parsing
$object->{_ROOT_ELEMENT} = undef; # Root element pointer of current xml file
bless($object, $class);
return $object;
}
#
# Public methods
#
# Get/Set the _DEFAULT_RANGE member value of this class
# @param : array of default ranges (optional for GET)
#
sub defaultRangeList
{
my $object = shift;
return 0 if(!&ISREF($object,qw(defaultRangeList)));
if (@_)
{
$object->{_DEFAULT_RANGE} = shift;
}
return $object->{_DEFAULT_RANGE};
}
# Get/Set the _DEFAULT_INCLUDE_COUNT member value of this class
# @param : default include feature count (optional for GET)
#
sub defaultIncludeCount
{
my $object = shift;
return 0 if(!&ISREF($object,qw(defaultIncludeCount)));
if (@_)
{
$object->{_DEFAULT_INCLUDE_COUNT} = shift;
}
return $object->{_DEFAULT_INCLUDE_COUNT};
}
# Get/Set the _DEFAULT_EXCLUDE_COUNT member value of this class
# @param : default exclude feature count (optional for GET)
#
sub defaultExcludeCount
{
my $object = shift;
return 0 if(!&ISREF($object,qw(defaultExcludeCount)));
if (@_)
{
$object->{_DEFAULT_EXCLUDE_COUNT} = shift;
}
return $object->{_DEFAULT_EXCLUDE_COUNT};
}
# Get/Set the _FILENAME member value of this class
# @param : xml file name (optional for GET)
#
sub fileName
{
my $object = shift;
return 0 if(!&ISREF($object,qw(fileName)));
if (@_)
{
$object->{_FILENAME} = shift;
}
return $object->{_FILENAME};
}
# Get/Set the _ROOT_ELEMENT member value of this class
# @param : root element document pointer (optional for GET)
#
sub rootElement
{
my $object = shift;
return 0 if(!&ISREF($object,qw(rootElement)));
if (@_)
{
$object->{_ROOT_ELEMENT} = shift;
}
return $object->{_ROOT_ELEMENT};
}
# Parse the feature xml file
# @param : xml file name to parse
#
sub parseXMLFile
{
my $object = shift;
return 0 if(!&ISREF($object,qw(parseXMLFile)));
my $file = shift; # Get the featuredatabase XML filename
$object->fileName($file);
# Check for the existence of xml file
if(!(-e $file))
{
ERROR($file." doesn\'t exist");
return 0;
}
#Parse the file and Get root Element
my $root = &genericparser::getRootElement($file);
$object->rootElement($root);
if($root)
{
#Read the <featureset>/<feature> elements
if( !($object->createFeatureMap()) )
{
return 0;
}
#Read the <defaultfeaturerange> elements
if( !($object->createDefaultRangeMap()) )
{
return 0;
}
return 1;
}
return -1;
}
# Read the <defaultfeaturerange> elements
# @param - input range attribute set
#
sub createDefaultRangeMap
{
my ($object, @attrSet) = @_;
return 0 if(!&ISREF($object,"createDefaultRangeMap"));
# Get the reference to the default feature range list from the object
my $rangeList = $object->defaultRangeList();
foreach my $currNode (@attrSet)
{
my ($min, $max);
my %attrHashMap = ();
# Get the range attributes
$object->readRangeAttributes($currNode, \%attrHashMap);
#Get the lower and higher uids
$min = $attrHashMap{min};
$max = $attrHashMap{max};
#Validate it
if((!&IsValidNum($min)) or (!&IsValidNum($max))) {
&ERROR("Valid hexadecimal or decimal value expected in default range");
return 0;
}
#Convert it to decimal
$attrHashMap{min} = &ConvertHexToDecimal($min);
$attrHashMap{max} = &ConvertHexToDecimal($max);
if( $attrHashMap{min} > $attrHashMap{max} ) {
&ERROR("Mininum/Lower UID value ".$min." is greater than Maximum/Higher UID value ".$max);
return 0;
}
#Add it to the existing range list
my $include = 1;
foreach my $node (@$rangeList) { #Check the range already exists
if(($node->{min} == $attrHashMap{min}) && ($node->{max} == $attrHashMap{max})
&& ($node->{support} eq $attrHashMap{support})) {
$include = 0;
}
}
if($include) { # If it is a new range attribute then add it to the list
push @$rangeList, \%attrHashMap;
$object->defaultIncludeCount($object->defaultIncludeCount()+1) if(lc($attrHashMap{support}) eq "include");
$object->defaultExcludeCount($object->defaultExcludeCount()+1) if(lc($attrHashMap{support}) eq "exclude");
}
}
return 1;
}
# Get the default include ranges of min and max values in 2dimensional array
#
sub getDefaultIncludeInfo()
{
my $object = shift;
return 0 if(!&ISREF($object,qw(getDefaultIncludeInfo)));
my @result;
my %tempHash=();
my $rangeList = $object->defaultRangeList();
foreach my $range (@$rangeList)
{
if(lc($range->{"support"}) eq "include" )
{
my $min_value=$range->{"min"};
my $max_value=$range->{"max"};
$tempHash{$min_value} = $max_value;
}
}
my $index = 0;
my @sortedHash = sort keys %tempHash;
foreach my $key (@sortedHash)
{
push @{$result[$index]},$key;
push @{$result[$index]},$tempHash{$key};
$index++;
}
return @result;
}
# Get the default exclude ranges of min and max values in 2dimensional array
#
sub getDefaultExcludeInfo()
{
my $object = shift;
return 0 if(!&ISREF($object,qw(getDefaultExcludeInfo)));
my @result;
my %tempHash=();
my $rangeList = $object->defaultRangeList();
foreach my $range (@$rangeList)
{
if(lc($range->{"support"}) eq "exclude" )
{
my $min_value=$range->{"min"};
my $max_value=$range->{"max"};
$tempHash{$min_value} = $max_value;
}
}
my $index = 0;
my @sortedHash = sort {$a <=> $b}(keys %tempHash);
foreach my $key (@sortedHash){
push @{$result[$index]},$key;
push @{$result[$index]},$tempHash{$key};
$index++;
}
return @result;
}
# Get the count of total number of ranges that are either included or excluded on the device as default
#
sub getDefaultTotalCount()
{
my $object = shift;
return 0 if(!&ISREF($object,qw(getDefaultTotalCount)));
return ($object->defaultIncludeCount() + $object->defaultExcludeCount());
}
# For a given uid value, this function checks if the given uid is within the default=present range.
# @param : UID to check
#
sub getRangeEntry
{
my $object = shift;
return 0 if(!&ISREF($object,qw(getRangeEntry)));
my $aUid = shift;
my $length = $object->getDefaultTotalCount();
my $pos = 0;
my $rangeRef;
my $rangeList = $object->defaultRangeList();
foreach my $range (@$rangeList)
{
if ( (lc($range->{"support"}) eq "include") and ($range->{"min"} <= $aUid) and ($range->{"max"} >= $aUid) )
{
return $range;
}
}
return undef;
}
# Get the list of features
#
sub getFeatures($$)
{
my ($includeFeatureRef, $excludeFeatureRef) = @_;
my %FeatureMap = ();
my @FeatList = ();
my $featRef;
my $uid;
foreach my $feat (@$excludeFeatureRef)
{
$uid = $feat->{uid};
$featRef = $FeatureMap{$uid};
if( $featRef->{include} == 1 )
{
&ERROR("The feature $feat->{name} was added into the exclude as well as include list");
return 0;
}
elsif($featRef->{exclude} == 1)
{
# Already added to the final feature list
next;
}
else
{
$FeatureMap{$uid} = $feat;
push @FeatList, $feat;
}
}
foreach my $feat (@$includeFeatureRef)
{
$uid = $feat->{uid};
$featRef = $FeatureMap{$uid};
if( $featRef->{exclude} == 1 )
{
&ERROR("The feature $feat->{name} was added into the exclude as well as include list");
return 0;
}
elsif($featRef->{include} == 1)
{
# Already added to the final feature list
next;
}
else
{
$FeatureMap{$uid} = $feat;
push @FeatList, $feat;
}
}
return \@FeatList;
}
# ========================================================================
# Wrappers for generic xml parser
# ========================================================================
sub featureparser::getnodefromTree
{
&genericparser::getNodeFromTree(@_);
}
sub getattrValue
{
&genericparser::getAttrValue(@_);
}
sub getelementValue
{
&genericparser::getElementValue(@_);
}
# ========================================================================
# Utility sub routines
# ========================================================================
# Check whether the object is reference type
# @param : the object reference
#
sub ISREF
{
my ($object, $method) = @_;
if(!ref($object))
{
&ERROR("**Object is not reference-type for the method($method)");
return 0;
}
return 1;
}
# Parser debugging routines
#
sub WARN
{
print "WARNING: ".$_[0]."\n";
}
sub ERROR
{
print "ERROR: ".$_[0]."\n";
}
# Return Decimal value for the given Hexadecimal number.
# @param : HexaDecimal Value
#
sub ConvertHexToDecimal
{
my $val = shift;
if(grep /^0x/i, $val)
{
# Input is Hexadecimal value, convert to Decimal
return hex($val);
}
else
{
# Decimal value
return $val;
}
}
# Validate if the given value is a valid number
#
sub IsValidNum
{
my $num = shift;
return 1 if($num =~ /^\d+$|^0[x][\da-f]+/i);
return 0;
}
# Validate if the given UID value is a valid number (either decimal or hexadecimal number)
#
sub ValidateUIDValue
{
my $fuid = shift;
# check to ensure that uid value contains only valid digits (decimal/hexadecimal)
if(IsValidNum $fuid)
{
return 1;
}
else
{
&ERROR("Invalid UID value".$fuid."\n");
return 0;
}
}
1;