imgtools/buildrom/tools/featuresutil.pm
changeset 0 044383f39525
child 590 360bd6b35136
equal deleted inserted replaced
-1:000000000000 0:044383f39525
       
     1 #
       
     2 # Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 # All rights reserved.
       
     4 # This component and the accompanying materials are made available
       
     5 # under the terms of the License "Eclipse Public License v1.0"
       
     6 # which accompanies this distribution, and is available
       
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 #
       
     9 # Initial Contributors:
       
    10 # Nokia Corporation - initial contribution.
       
    11 #
       
    12 # Contributors:
       
    13 #
       
    14 # Description: 
       
    15 #
       
    16 
       
    17 package featuresutil;
       
    18         
       
    19 
       
    20 require Exporter;
       
    21 @ISA = qw(Exporter);
       
    22 @EXPORT = qw(
       
    23 	parseXMLDatabase
       
    24 	createFeatureFile
       
    25 	convert_FeatRegToFeatMgr
       
    26 );
       
    27 
       
    28 use strict;
       
    29 use XML::Handler::XMLWriter;
       
    30 use IO;
       
    31 
       
    32 use featureparser;
       
    33 use featuremanager;
       
    34 use featureregistry;
       
    35 use featuresdat;
       
    36 use featurecfg;
       
    37 
       
    38 my $xmlDBHandle = undef; #Object of feature parser
       
    39 
       
    40 my @includeFeatureList;	#List of included features. The included feature in this list is a hash table giving the 
       
    41 			#Uid or the name. These features are collected from the iby/obey files.
       
    42 my @excludeFeatureList;	#List of excluded features.The excluded feature in this list is a hash table giving the 
       
    43 			#Uid or the name. These features are collected from the iby/obey files.
       
    44 
       
    45 my $verboseFlg = 0; # verbose mode flag
       
    46 my $strictFlg = 1; # strict mode flag
       
    47 
       
    48 # Subroutine to generate warning messages.
       
    49 sub WARN 
       
    50 {
       
    51 	print "WARNING: ".$_[0]."\n"; 
       
    52 }
       
    53 
       
    54 # Subroutine to generate error messages.
       
    55 sub ERROR 
       
    56 { 
       
    57 	print "ERROR: ".$_[0]."\n"; 
       
    58 }
       
    59 
       
    60 # Verbose mode output routine
       
    61 sub MSG 
       
    62 {
       
    63 	if($verboseFlg) {
       
    64 		print "**".$_[0]."...\n";
       
    65 	}
       
    66 }
       
    67 
       
    68 # Subroutine to parse feature list XML database file.
       
    69 # @param dbfileList					- List of XML database file names seperated by commas.
       
    70 # @param fmFlag						- Flag to generate features data file.
       
    71 # @param strictFlg					- Flag to enable strict mode (optional).
       
    72 # @param verboseFlg                 - Flag to enable verbose mode (optional).
       
    73 sub parseXMLDatabase
       
    74 {
       
    75 	my $dbfileList = shift;
       
    76 	my $fmFlag = shift;
       
    77 	$strictFlg = shift;
       
    78 	$verboseFlg = shift;
       
    79 	
       
    80 	# list of xml databases
       
    81 	my @filelist = split(/,/,$dbfileList);
       
    82 	
       
    83 	# return status
       
    84 	my $retStatus = 0;
       
    85 	
       
    86 	# default mode is strict
       
    87 	$strictFlg=0 if(!defined $strictFlg);
       
    88 	# default mode is nonverbose
       
    89 	$verboseFlg=0 if(!defined $verboseFlg);
       
    90 	
       
    91 	# multiple file support is not applicable for feature registry option
       
    92 	if( (@filelist > 1) && (!$fmFlag) ) {
       
    93 		&ERROR("Multiple XML database file support is not applicable for featureregistry option");
       
    94 		return 0;
       
    95 	}
       
    96 	
       
    97 	if($fmFlag) # Feature manager option handling
       
    98 	{
       
    99 		# create the object of feature manager class
       
   100 		$xmlDBHandle = new featuremanager;
       
   101 		
       
   102 		if($xmlDBHandle) {
       
   103 			foreach my $file (@filelist) 
       
   104 			{
       
   105 				my $status = 1;
       
   106 				if(-e $file) {
       
   107 					
       
   108 					&MSG("Parsing $file");
       
   109 					
       
   110 					# parse the feature manager xml file
       
   111 					$status = $xmlDBHandle->parseXMLFile($file);
       
   112 					if(! $status) {
       
   113 					
       
   114 						# create the object of feature registry class
       
   115 						my $registryObj = new featureregistry;
       
   116 						# parse the feature registry xml file
       
   117 						$status = $registryObj->parseXMLFile($file);
       
   118 						if($status < 0) {
       
   119 							if($strictFlg) {
       
   120 								&ERROR("Invalid features database $file");
       
   121 								$xmlDBHandle = undef;
       
   122 								return 0;
       
   123 							}
       
   124 							else {
       
   125 								&WARN("Invalid features database $file");
       
   126 							}
       
   127 						}
       
   128 						elsif(! $status) {
       
   129 							# if the xml file is not valid feature list xml file
       
   130 							if($strictFlg) {
       
   131 								&ERROR("Error in reading features database file \"$file\"");
       
   132 								$xmlDBHandle = undef;
       
   133 								return 0;
       
   134 							}
       
   135 							else {
       
   136 								&WARN("Error in reading features database file \"$file\"");
       
   137 							}
       
   138 						}
       
   139 						else {
       
   140 							MSG("Converting featureregistry database to featuremanager");
       
   141 							
       
   142 							# add the feature registry file object to the feature manager file object
       
   143 							if(! $xmlDBHandle->addFeatureRegistry($registryObj)) {
       
   144 								if($strictFlg) {
       
   145 									MSG("Error in reading features database file \"$file\"");
       
   146 									$xmlDBHandle = undef;
       
   147 									return 0;
       
   148 								}
       
   149 								else {
       
   150 									&WARN("Error in reading features database file \"$file\"");
       
   151 								}
       
   152 							}
       
   153 							else {
       
   154 								# parsing feature registry database success
       
   155 								$retStatus = 1;
       
   156 							}
       
   157 						}
       
   158 					}
       
   159 					elsif( $status < 0 ) {
       
   160 						if($strictFlg) {
       
   161 							&ERROR("Invalid features database $file");
       
   162 							$xmlDBHandle = undef;
       
   163 							return 0;
       
   164 						}
       
   165 						else {
       
   166 							&WARN("Invalid features database $file");
       
   167 						}
       
   168 					}
       
   169 					else {
       
   170 						# parsing feature manager database success
       
   171 						$retStatus = 1;
       
   172 					}
       
   173 				}
       
   174 				else {
       
   175 					if(!$strictFlg) {
       
   176 						&WARN($file." doesn\'t exist");
       
   177 						next;
       
   178 					}
       
   179 					else {
       
   180 						&ERROR($file." doesn\'t exist");
       
   181 						$xmlDBHandle = undef;
       
   182 						return 0;
       
   183 					}
       
   184 				}
       
   185 			}
       
   186 		}
       
   187 		else {
       
   188 			&ERROR("Couldn't create feature parser object");
       
   189 		}
       
   190 	}
       
   191 	else # Feature registry file handling
       
   192 	{
       
   193 		if(@filelist) {
       
   194 			my $file = $filelist[0];
       
   195 			$xmlDBHandle = new featureregistry;
       
   196 			
       
   197 			if($xmlDBHandle) {
       
   198 				if(-e $file) {
       
   199 				
       
   200 					MSG("Parsing $file");
       
   201 					
       
   202 					my $status = $xmlDBHandle->parseXMLFile($file);
       
   203 
       
   204 					if($status < 0) {
       
   205 						&ERROR($file." is invalid feature registry file");
       
   206 						$xmlDBHandle = undef;
       
   207 						return 0;
       
   208 					}
       
   209 					elsif(!$status) {
       
   210 						&ERROR("Error in reading feature registry file ".$file);
       
   211 						$xmlDBHandle = undef;
       
   212 					}
       
   213 					else {
       
   214 						# parsing feature registry database success
       
   215 						$retStatus = 1;
       
   216 					}
       
   217 				}
       
   218 				else {
       
   219 					if(!$strictFlg) {
       
   220 						&WARN($file." doesn\'t exist -- ");
       
   221 					}
       
   222 					else {
       
   223 						&ERROR($file." doesn\'t exist -- ");
       
   224 					}				
       
   225 					$xmlDBHandle = undef;
       
   226 				}
       
   227 			}
       
   228 			else {
       
   229 				&ERROR("Couldn't create feature parser object");
       
   230 			}
       
   231 		}
       
   232 	}
       
   233 	
       
   234 	if($retStatus) {
       
   235 		return $xmlDBHandle
       
   236 	}
       
   237 	else {
       
   238 		return $retStatus;
       
   239 	}
       
   240 }
       
   241 
       
   242 # Subroutine to generate feature manager database file from the given feature registry database
       
   243 # @param strictFlg - strict mode flag
       
   244 # @param verboseFlg - verbose mode flag
       
   245 # @param outpath - destination path for the converted database file(s)
       
   246 # @param dblist - list of xml file names
       
   247 sub convert_FeatRegToFeatMgr
       
   248 {
       
   249 	$strictFlg = shift;
       
   250 	$verboseFlg = shift;
       
   251 	my $outpath = shift;
       
   252 	my @dblist = @_;
       
   253 	
       
   254 	# default mode is strict
       
   255 	$strictFlg=0 if(!defined $strictFlg);
       
   256 	# default mode is nonverbose
       
   257 	$verboseFlg=0 if(!defined $verboseFlg);
       
   258 
       
   259 	foreach my $file (@dblist)
       
   260 	{
       
   261 		# Create the object of feature registry
       
   262 		my $fileHandle = new featureregistry;
       
   263 		
       
   264 		if(-e $file) {
       
   265 			# Parse the database
       
   266 			if($fileHandle->parseXMLFile($file) > 0) {
       
   267 				MSG("Converting Feature Registry database $file");
       
   268 				
       
   269 				# Create directory if it doesn't exists
       
   270 				if(!(-e $outpath)) {
       
   271 					if(!mkdir($outpath)) {
       
   272 						&ERROR("Failed to create $outpath folder");
       
   273 						return 0;
       
   274 					}
       
   275 				}
       
   276 				# Emit the contents of feature registry object into an feature manager database file
       
   277 				&generateXML($fileHandle, $outpath);
       
   278 			}
       
   279 		}
       
   280 		else {
       
   281 			if(!$strictFlg) {
       
   282 				&WARN($file." doesn\'t exist -- ");
       
   283 				next;
       
   284 			}
       
   285 			else {
       
   286 				&ERROR($file." doesn\'t exist -- ");
       
   287 				return 0;
       
   288 			}
       
   289 		}
       
   290 	}
       
   291 }
       
   292 
       
   293 # Subroutine to emit XML output for the given featureregistry object
       
   294 # @param frObject - object of feature registry database
       
   295 # @param outPath - destination path for the converted database file
       
   296 sub generateXML
       
   297 {
       
   298 	my ($frObject, $outPath) = @_;
       
   299 		
       
   300 	my $outputFile = $frObject->fileName();
       
   301 	
       
   302 	# Extract absolute file name
       
   303 	if( $outputFile =~ /[\\\/]/) {
       
   304 		$outputFile =~ /.*[\\\/](.+)\z/;
       
   305 		$outputFile = $1;
       
   306 	}
       
   307 	
       
   308 	# Add suffix _converted
       
   309 	$outputFile =~ s/(.*)([\.].+)\z/$1_converted$2/;
       
   310 	
       
   311 	my $fileHandle = new IO::File(">$outPath$outputFile");
       
   312 	
       
   313 	if($fileHandle) {
       
   314 		my $writer = XML::Handler::XMLWriter->new(Output => $fileHandle);
       
   315 		
       
   316 		# Header
       
   317 		$writer->start_document();
       
   318 		$writer->print("<!--Converted from the feature registry ".$frObject->fileName()."-->\n\n");
       
   319 		# DOCTYPE
       
   320 		$writer->print("<!DOCTYPE featuredatabase SYSTEM \"featuredatabase.dtd\">\n\n");
       
   321 		
       
   322 		# Root element begin
       
   323 		$writer->start_element({Name => 'featuredatabase', Attributes => {}});
       
   324 		
       
   325 		# FeatureSet element
       
   326 		$writer->print("\n\t");
       
   327 		$writer->start_element({Name => 'featureset', Attributes => {}});
       
   328 		my $nameuidmap = $frObject->featureNameUidMap();
       
   329 		foreach my $uid (sort(values %$nameuidmap)) {
       
   330 			my $featinfo = $frObject->getFeatureInfo($uid);
       
   331 			my %attributes = ();
       
   332 			
       
   333 			$attributes{uid} = sprintf("0x%08X",$uid);
       
   334 			$attributes{statusflags} = "0x00000001";
       
   335 			$attributes{name} = $featinfo->{name};
       
   336 			
       
   337 			$writer->print("\n\t\t");
       
   338 			$writer->start_element({Name => 'feature', Attributes => \%attributes});
       
   339 			$writer->end_element({Name => 'feature'});
       
   340 		}
       
   341 		$writer->print("\n\t");
       
   342 		$writer->end_element({Name => 'featureset'});
       
   343 		
       
   344 		# defaultfeaturerange element
       
   345 		my $rangeList = $frObject->defaultRangeList();
       
   346 		foreach my $range (@$rangeList) {
       
   347 			my %attributes = ();
       
   348 			
       
   349 			next if(lc($range->{support}) eq "exclude");
       
   350 			
       
   351 			$attributes{higheruid} = sprintf("0x%08X",$range->{max});
       
   352 			$attributes{loweruid} = sprintf("0x%08X",$range->{min});
       
   353 			
       
   354 			$writer->print("\n\t");
       
   355 			$writer->start_element({Name => 'defaultfeaturerange', Attributes => \%attributes});
       
   356 			$writer->end_element({Name => 'defaultfeaturerange'});
       
   357 		}
       
   358 		
       
   359 		# Root element close
       
   360 		$writer->print("\n");
       
   361 		$writer->end_element({Name => 'featuredatabase'});
       
   362 		
       
   363 		# Footer
       
   364 		$writer->end_document();
       
   365 	}
       
   366 	else {
       
   367 		&ERROR("Failed to create $outPath$outputFile file");
       
   368 	}
       
   369 }
       
   370 
       
   371 # Subroutine to create Feature Registry/Features Data file
       
   372 # @param romimage				 - Rom image number.
       
   373 # @param featurefile			 - Feature file number.
       
   374 # @param featurefilename		 - Name of the feature file to be generated.
       
   375 # @param featureslist			 - Reference to array of hashes containing features to included/excluded.
       
   376 # @param featuremanager			 - Flag to generate features data file.
       
   377 # @param singleDATfile           - Flag to generate single features.dat file.
       
   378 sub createFeatureFile
       
   379 {
       
   380 	if($xmlDBHandle == undef) 
       
   381 	{
       
   382 		ERROR("No XML Database opened");
       
   383 		return 0;
       
   384 	}	
       
   385 	my ($romimage,$featurefile,$featurefilename,$featureslist,$featuremanager,$singleDATfile) = @_;
       
   386 	
       
   387 	# Default setting for singleDATfile flag
       
   388 	$singleDATfile = 0 if(!defined $singleDATfile);
       
   389 	
       
   390 	# Clear the global include/exclude feature list.
       
   391 	@includeFeatureList = (); 
       
   392 	@excludeFeatureList = ();
       
   393 
       
   394 
       
   395 	for(my $k=0;$k<scalar @$featureslist;$k++)
       
   396 	{
       
   397 		if(($singleDATfile) || ($featureslist->[$k]{rom}==$romimage && $featureslist->[$k]{cfgfile} == $featurefile))
       
   398 		{			
       
   399 			AddToFeatureList($featureslist->[$k],$featuremanager);
       
   400 		}
       
   401 	}
       
   402 
       
   403 	my $features = &featureparser::getFeatures(\@includeFeatureList, \@excludeFeatureList);
       
   404 	if (!$features)
       
   405 	{
       
   406 		ERROR("No feature file generated for ROM_IMAGE[".$romimage."]");
       
   407 		return 0;
       
   408 	}
       
   409 	else
       
   410 	{
       
   411 		my $object;
       
   412 		if ($featuremanager) 
       
   413 		{
       
   414 			$object = new featuresdat($xmlDBHandle);
       
   415 		}
       
   416 		else
       
   417 		{
       
   418 			$object = new featurecfg($xmlDBHandle);
       
   419 		}		
       
   420 		return $object->createFile($featurefilename, $features , $featuremanager);
       
   421 	}	
       
   422 }
       
   423 
       
   424 # Subroutine to add the feature specified to the included/excluded feature list
       
   425 # @param featureData				 - Reference to hash containing feature information (i.e. name/uid,
       
   426 # 									   included/excluded,SF and UD).  
       
   427 # @param featuremanager				 - Flag to generate features data file.
       
   428 sub AddToFeatureList
       
   429 {
       
   430 	my ($featureData, $featuremanager) = @_; 	
       
   431 	
       
   432 	my %feat = ();
       
   433 	my $feature = $featureData->{feature};		
       
   434 	
       
   435 #	Check if the given value is a feature name.
       
   436 	my $value = $xmlDBHandle->getFeatureUID($feature);
       
   437 
       
   438 #	If not a feature, then may be uid value
       
   439 	if(!defined $value)
       
   440 	{
       
   441 		if (!featureparser::IsValidNum($feature)) 
       
   442 		{
       
   443 			ERROR("Feature \"".$feature."\" not found in feature list XML");
       
   444 			return;
       
   445 		}
       
   446 		if (&featureparser::ValidateUIDValue($feature))
       
   447 		{
       
   448 			my $featureUid = $feature;
       
   449 			$feature = &featureparser::ConvertHexToDecimal($feature);
       
   450 			my $featureInfo = $xmlDBHandle->getFeatureInfo($feature);
       
   451 			if (!$featureInfo)
       
   452 			{
       
   453 				ERROR("Feature \"".$featureUid."\" not found in feature list XML");
       
   454 				return;
       
   455 			}
       
   456 			else
       
   457 			{
       
   458 				$feat{uid} = $feature;
       
   459 				$feat{name} = $featureInfo->{name};				
       
   460 			}
       
   461 		}
       
   462 		else
       
   463 		{
       
   464 			return;
       
   465 		}
       
   466 	}
       
   467 	else
       
   468 	{
       
   469 		$feat{name} = $feature;
       
   470 		$feat{uid} = $value;		
       
   471 	}		
       
   472 
       
   473 	# Set the values of "SF" and "UD" for feature manager.
       
   474 	if ($featuremanager) 
       
   475 	{		
       
   476 		&setFeatureArguments(\%feat,$featureData->{SF},$featureData->{UD});
       
   477 	}	
       
   478 
       
   479 	if($featureData->{include} == 1)
       
   480 	{
       
   481 		$feat{include} = 1;
       
   482 		push @includeFeatureList, \%feat;
       
   483 	}
       
   484 	else
       
   485 	{
       
   486 		$feat{exclude} = 1;
       
   487 		push @excludeFeatureList, \%feat;
       
   488 	}
       
   489 }
       
   490 
       
   491 # Subroutine to set the values of "SF" and "UD" for the specified feature
       
   492 # @param feat						- Reference to hash containing information(i.e. name and uid) 
       
   493 #									  of the specified feature.
       
   494 # @param SF							- Value of "SF" provided in the iby/oby file. 
       
   495 # @param UD							- Value of "UD" provided in the iby/oby file.
       
   496 sub setFeatureArguments
       
   497 {
       
   498 	my($feat,$SF,$UD)= @_;
       
   499 	
       
   500 	my $featureInfo = $xmlDBHandle->getFeatureInfo($feat->{uid});
       
   501 	
       
   502 	# If the values of 'SF' and 'UD' are not provided in the iby/oby file, then take the values
       
   503 	# from Feature Database XML file.
       
   504 	if ($SF && featureparser::IsValidNum($SF))  
       
   505 	{
       
   506 		$feat->{SF} = &featureparser::ConvertHexToDecimal($SF);
       
   507 	}
       
   508 	else 
       
   509 	{
       
   510 		# Generate warning if the value of "SF" provided for the feature in iby/oby file
       
   511 		# is invalid.
       
   512 		if ($SF) 
       
   513 		{
       
   514 			WARN("Invalid SF value \"$SF\" provided for feature \"$feat->{name}\". Defaulting to value provided in XML file");
       
   515 		}
       
   516 		$feat->{SF} = &featureparser::ConvertHexToDecimal($featureInfo->{statusflags});			
       
   517 	}
       
   518 	if ($UD && featureparser::IsValidNum($UD))  					
       
   519 	{			
       
   520 		$feat->{UD} = &featureparser::ConvertHexToDecimal($UD);						
       
   521 	}
       
   522 	else 
       
   523 	{
       
   524 		# Generate warning if the value of "UD" provided for the feature in iby/oby file
       
   525 		# is invalid.
       
   526 		if ($UD) 
       
   527 		{
       
   528 			WARN("Invalid UD value \"$UD\" provided for feature \"$feat->{name}\". Defaulting to value provided in XML file");
       
   529 		}
       
   530 		$feat->{UD} = &featureparser::ConvertHexToDecimal($featureInfo->{userdata});				
       
   531 	}				
       
   532 }
       
   533 
       
   534 1;