diff -r 820b22e13ff1 -r 39c28ec933dd imgtools/buildrom/tools/features.pm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imgtools/buildrom/tools/features.pm Mon May 10 19:54:49 2010 +0100 @@ -0,0 +1,538 @@ +# +# 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 create the feature header and iby files. +package features; + +require Exporter; +@ISA=qw(Exporter); +@EXPORT=qw( + open_Database + generate_Headerfile + generate_Obeyfile + generate_DATfile + set_DefaultPath + set_VerboseMode + set_StrictMode +); + +use strict; + +# Include the featureutil module to use API to read from XML file. +use featuresutil; + +# Object of featureparser +my $xmlDBHandle = undef; + +# Mask value for supported feature flag +use constant BIT_SUPPORTED=>0x00000001; + +# Feature dat file name +use constant DAT_FILE=>"features.dat"; + +# Feature manager support flag +use constant FM_FLG=>0x01; + +# Feature registry support flag +use constant FR_FLG=>0x02; + +# single dat file generation +use constant SINGLE_DATFILE=>1; + +# none value +use constant NONE=>-1; + +# verbose mode flag +my $verboseMode = 0; + +# strict mode flag +my $strictMode = 0; + +# +# Open and parse the given xml database +# @param - xml file name +# +sub open_Database +{ + my ($xmlDBFile) = join(',',@_); + + $xmlDBHandle = &featuresutil::parseXMLDatabase($xmlDBFile,FM_FLG,$strictMode,$verboseMode); + + return 0 if(!$xmlDBHandle); + return 1; +} + +# +# set the default path settings for header and iby files +# +sub set_DefaultPath +{ + my ($epocroot, $hdrpath, $ibypath, $datpath, $convpath) = @_; + + $$hdrpath = $epocroot."epoc32/include/"; + $$ibypath = $epocroot."epoc32/rom/include/"; + $$datpath = "./"; # current folder + $$convpath = "./"; # current folder +} + +# +# Generate the header file for each featureset +# @param - destination path for the header file(s) +# +sub generate_Headerfile +{ + my $featureList=(); + my $featureSetList = (); + my $hdrpath = shift; + my $aliasfeatureList = (); + + # Get the list of featuresets exists in the xml database + $featureSetList = $xmlDBHandle->getFeatureset(); + foreach my $featureSet (@$featureSetList) { + my @defPresent=(); + my @defNotPresent=(); + my @defPresentAlias = (); + my @defNotPresentAlias = (); + my $tab = "\t"; + + # if the headerfile name is not there then just return + if(!defined $featureSet->{hfilename}) { + MSG("No header file generated for the featureset $featureSet->{namespace}"); + next; + } + + # Get the filename + my $hfile = $featureSet->{hfilename}; + + # Create directory if it doesn't exists + return if(!createDirectory($hdrpath)); + + my $hfileHandle = openFile($hdrpath.$hfile); + if(!$hfileHandle) { + print "ERROR: Cannot open file $hdrpath$hfile\n"; + next; + } + + MSG("Creating headerfile $hdrpath$hfile"); + + # Get the name->uid map for the features given in the selected featureset + $featureList = $featureSet->{feature_list}; + # Create two sets of feature name list for the default present and notpresent + foreach my $name (keys %$featureList) + { + if(defaultPresent($featureList->{$name})){ + push @defPresent, $name; + } + else { + push @defNotPresent, $name; + } + } + #for alias + $aliasfeatureList = $featureSet->{alias_feature_list}; + foreach my $alias_name (keys %$aliasfeatureList) + { + if(defaultPresent($aliasfeatureList->{$alias_name})) + { + push @defPresentAlias, $alias_name; + } + else + { + push @defNotPresent, $alias_name; + } + } + + # sort them + @defPresent = sort(@defPresent); + @defNotPresent = sort(@defNotPresent); + + # insert the file header attribute value + my $comment = $featureSet->{hfileheader}; + if($comment) { + trimString(\$comment); + + # insert the interfacevisibility and interfacestatus attribute values + writeFile($hfileHandle, $comment."\n/**\n".$featureSet->{interfacevisibility}."\n". + $featureSet->{interfacestatus}."\n*/\n"); + } + + if(defined $featureSet->{namespace}) { + writeFile($hfileHandle, "namespace ".$featureSet->{namespace}." {\n"); + } + else { + $tab = ""; + } + + # for each feature list insert an entry in the current namespace + writeFile($hfileHandle,$tab."// default present\n") if(@defPresent); + foreach my $name (@defPresent) { + $comment = $featureSet->{feature}{$featureList->{$name}}{comment}; + if(defined $comment) { + trimString(\$comment); + $comment =~ s/\n/\n$tab/mg; + chop($comment) if($tab eq "\t"); + writeFile($hfileHandle, $tab.$comment); + } + + writeFile($hfileHandle,$tab."const TUid K", $featureSet->{feature}{$featureList->{$name}}{name}, + sprintf(" = {0x%X};\n", $featureList->{$name})); + writeFile($hfileHandle,"\n") if(defined $comment); + } + + foreach my $alias_name (@defPresentAlias) + { + $comment = $featureSet->{alias_feature}{$aliasfeatureList->{$alias_name}}{comment}; + if(defined $comment) + { + trimString(\$comment); + $comment =~ s/\n/\n$tab/mg; + chop($comment) if ($tab eq "\t"); + writeFile($hfileHandle, $tab.$comment); + } + writeFile($hfileHandle, $tab."const TUid K", $featureSet->{alias_feature}{$aliasfeatureList->{$alias_name}}{name}, sprintf(" = {0x%X};\n", $aliasfeatureList->{$alias_name})); + writeFile($hfileHandle, "\n") if(defined $comment); + } + + writeFile($hfileHandle, "\n".$tab."// default not present\n") if(@defNotPresent); + foreach my $name (@defNotPresent) { + $comment = $featureSet->{feature}{$featureList->{$name}}{comment}; + if(defined $comment) { + trimString(\$comment); + $comment =~ s/\n/\n$tab/mg; + chop($comment) if($tab eq "\t"); + writeFile($hfileHandle,$tab.$comment); + } + + writeFile($hfileHandle,$tab."const TUid K", $featureSet->{feature}{$featureList->{$name}}{name}, + sprintf(" = {0x%X};\n", $featureList->{$name})); + writeFile($hfileHandle,"\n") if(defined $comment); + } + foreach my $alias_name (@defNotPresentAlias) + { + $comment = $featureSet->{alias_feature}{$aliasfeatureList->{$alias_name}}{comment}; + if(defined $comment) + { + trimString(\$comment); + $comment =~ s/\n/\n$tab/mg; + chop($comment) if ($tab eq "\t"); + writeFile($hfileHandle, $tab.$comment); + } + writeFile($hfileHandle, $tab."const TUid K", $featureSet->{alias_feature}{$aliasfeatureList->{$alias_name}}{name}, sprintf(" = {0x%X};\n", $aliasfeatureList->{$alias_name})); + writeFile($hfileHandle, "\n") if(defined $comment); + } + + if(defined $featureSet->{namespace}) { + writeFile($hfileHandle,"}\n"); + } + + closeFile($hfileHandle); + } +} + +# +# Generate the obey file for each featureset +# @param - destination path for the iby file(s) +# +sub generate_Obeyfile +{ + my $featureSet=(); my $feature=(); my $featureList=(); my $featureSetList=(); + my $aliasfeatureList = (); + my $ibypath = shift; + + # Get the list of featuresets exists in the xml database + $featureSetList = $xmlDBHandle->getFeatureset(); + foreach my $featureSet (@$featureSetList) { + # if the obey file name is not there then just return + if(!defined $featureSet->{ibyname}) { + MSG("No IBY file generated for the featureset $featureSet->{namespace}"); + next; + } + + # Get the file name + my $ibyfile = $featureSet->{ibyname}; + + # Create the directory if it doesn't exists + return if(!createDirectory($ibypath)); + + my $ibyfilehandle = openFile($ibypath.$ibyfile); + if(!$ibyfilehandle) { + print "*ERROR: Cannot open file $ibypath$ibyfile\n"; + next; + } + + MSG("Creating IBY file $ibypath$ibyfile"); + + $ibyfile =~ s/\./\_/g; + $ibyfile = uc($ibyfile); + + # insert the file header + writeFile($ibyfilehandle, "#ifndef\t__",$ibyfile,"__\n#define\t__",$ibyfile,"__\n\n"); + + # get the name->uid map of features for the given featureset + $featureList = $featureSet->{feature_list}; + $aliasfeatureList = $featureSet->{alias_feature_list}; + my %combine_list = (%$featureList, %$aliasfeatureList); + foreach my $name (sort keys %combine_list) + { + my $defblock=(); my $flags=(); my $comment=(); + + my $uid = $xmlDBHandle->getFeatureUID($name,$featureSet->{namespace}); + + # get the featureset attributes + $feature = $xmlDBHandle->getFeatureInfo($uid,$featureSet->{namespace}); + + # check to see this feature to be included in iby file + next if(!$feature->{infeaturesetiby}); + # get the feature flags + $flags = "SF ".$feature->{statusflags} if(defined $feature->{statusflags}); + if(defined $feature->{userdata}) { + $flags .= " "."UD ".$feature->{userdata}; + } + else { + $flags .= " "."UD 0x00000000"; + } + + # get the comment value + if(defined $feature->{comment}) { + $comment = $feature->{comment}; + trimString(\$comment); + } + + if(defined $feature->{includemacro}) { # if the include macro is specified + $defblock = "\n#ifdef ".$feature->{includemacro}."\n"; + $defblock .= $comment; + $defblock .= "FEATURE ".$feature->{name}." ".$flags."\n"; + $defblock .= "#else\nEXCLUDE_FEATURE ".$feature->{name}." ".$flags."\n#endif\n" + } + elsif(defined $feature->{excludemacro}) { # if the exclude macro is specified + $defblock = "\n#ifdef ".$feature->{excludemacro}."\n"; + $defblock .= "EXCLUDE_FEATURE ".$feature->{name}." ".$flags."\n#else\n"; + $defblock .= $comment; + $defblock .= "FEATURE ".$feature->{name}." ".$flags."\n#endif\n" + } + else { # default case + # No system wide macro defined for this feature + next; + } + + # insert #ifdef block + writeFile($ibyfilehandle, $defblock); + } + + writeFile($ibyfilehandle, "\n\n#endif //__",$ibyfile,"__"); + closeFile($ibyfilehandle); + } +} + +# +# Generate the feature DAT file +# @param - destination path for the features.DAT file +# +sub generate_DATfile +{ + my $featureSet=(); my $feature=(); my $featureList=(); my $featureSetList=(); + my @featList=(); + my $aliasfeatureList = (); + my $aliasfeatlist = (); + my %uidtoaliasname = (); + my $datpath = shift; + + # Get the list of featuresets exists in the xml database + $featureSetList = $xmlDBHandle->getFeatureset(); + $aliasfeatlist = $xmlDBHandle->getAliasFeatureList(); + foreach my $aliasname (keys %$aliasfeatlist) + { + $uidtoaliasname{$aliasfeatlist->{$aliasname}} = $aliasname; + } + foreach my $featureSet (@$featureSetList) { + # get the name->uid map of features for the given featureset + $featureList = $featureSet->{feature_list}; + foreach my $name (keys %$featureList) + { + if (exists $uidtoaliasname{$featureList->{$name}}) + { + next; + } + my $statusflag = 0; + my %featinfo = (); + + $featinfo{feature} = $name; + $featinfo{SF} = $xmlDBHandle->getStatusFlag($name, $featureSet->{namespace}); + $featinfo{UD} = $xmlDBHandle->getUserData($name, $featureSet->{namespace}); + $statusflag = &featureparser::ConvertHexToDecimal($featinfo{SF}); + if($statusflag & BIT_SUPPORTED) { + $featinfo{include} = 1; + } + else { + $featinfo{include} = 0; + } + + push @featList, {%featinfo}; + } + $aliasfeatureList = $featureSet->{alias_feature_list}; + foreach my $alias_name (keys %$aliasfeatureList) + { + my $statusflag = 0; + my %featinfo = (); + + $featinfo{feature} = $alias_name; + $featinfo{SF} = $xmlDBHandle->getStatusFlag($alias_name, $featureSet->{namespace}); + $featinfo{UD} = $xmlDBHandle->getUserData($alias_name, $featureSet->{namespace}); + $statusflag = &featureparser::ConvertHexToDecimal($featinfo{SF}); + if($statusflag & BIT_SUPPORTED) { + $featinfo{include} = 1; + } + else { + $featinfo{include} = 0; + } + push @featList, {%featinfo}; + } + + + } + + if(@featList) { + # Create the directory if doesn't exists + return if(!createDirectory($datpath)); + + # Create features.dat file + &featuresutil::createFeatureFile(NONE,NONE,$datpath.DAT_FILE,\@featList,FM_FLG,SINGLE_DATFILE); + } +} + +# +# Converts the feature registry object to feature manager xml +# @param - destination path for the output file +# @param - input file list as an array +# +sub convert_FeatRegToFeatMgr +{ + &featuresutil::convert_FeatRegToFeatMgr($strictMode,$verboseMode,@_); +} + +# +# Enable verbose mode +# +sub set_VerboseMode +{ + $verboseMode = 1; +} + +# +# Enable strict mode +# +sub set_StrictMode +{ + $strictMode = 1; +} + +# --Utility Functions + +# +# Check whether the given feature uid is present in default include list +# @param - feature uid value +# +sub defaultPresent +{ + my ($uid) = shift; + + my $defaultRanges = $xmlDBHandle->defaultRangeList(); + + foreach my $range (@$defaultRanges) + { + if ( (lc($range->{"support"}) eq "include") and ($range->{"min"} <= $uid) and ($range->{"max"} >= $uid) ) { + return 1; + } + } + return 0; +} + +# +# Trim the given string for trailing whitespaces +# @param - string to be trimmed +# +sub trimString +{ + my $str = shift; + + $$str =~ s/^[ \t]+//mg; + $$str =~ s/^\n//mg; + + $$str .= "\n" if($$str !~ /\n$/m); +} + +# +# Verbose mode output routine +# @param - Message to be displayed +# +sub MSG +{ + print "**".$_[0]."...\n" if($verboseMode); +} + +# +# Open a text file in write mode +# @param - name of the file to open +# +sub openFile +{ + my $file = shift; + + open(FILEP,">$file") or (return 0); + + return *FILEP; +} + +# +# Writes string to the file stream +# @param filehandle - reference to the file handle +# @param data - array of string to be written +# +sub writeFile +{ + my ($filehandle, @data) = @_; + + printf $filehandle "%s",$_ foreach (@data); +} + +# +# Closes the file stream +# @param filehanlde - referece to the file handle +# +sub closeFile +{ + my $filehandle = shift; + + close $filehandle; +} + +# +# Check the existance of the directory and create one if it doesn't exist +# @param dir - directory name +# +sub createDirectory +{ + my $dir = shift; + + if(!(-e $dir)) { + if(!mkdir($dir)) { + print "ERROR: Failed to create $dir folder\n"; + return 0; + } + } + return 1; +} + +1;