imgtools/buildrom/tools/features.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 # This package contains routines to create the feature header and iby files.
       
    18 package features;
       
    19 
       
    20 require Exporter;
       
    21 @ISA=qw(Exporter);
       
    22 @EXPORT=qw(
       
    23 	open_Database
       
    24 	generate_Headerfile
       
    25 	generate_Obeyfile
       
    26 	generate_DATfile
       
    27 	set_DefaultPath
       
    28 	set_VerboseMode
       
    29 	set_StrictMode
       
    30 );
       
    31 
       
    32 use strict;
       
    33 
       
    34 # Include the featureutil module to use API to read from XML file.
       
    35 use featuresutil;
       
    36 
       
    37 # Object of featureparser
       
    38 my $xmlDBHandle = undef;
       
    39 
       
    40 # Mask value for supported feature flag
       
    41 use constant BIT_SUPPORTED=>0x00000001;
       
    42 
       
    43 # Feature dat file name
       
    44 use constant DAT_FILE=>"features.dat";
       
    45 
       
    46 # Feature manager support flag
       
    47 use constant FM_FLG=>0x01;
       
    48 
       
    49 # Feature registry support flag
       
    50 use constant FR_FLG=>0x02;
       
    51 
       
    52 # single dat file generation
       
    53 use constant SINGLE_DATFILE=>1;
       
    54 
       
    55 # none value
       
    56 use constant NONE=>-1;
       
    57 
       
    58 # verbose mode flag
       
    59 my $verboseMode = 0;
       
    60 
       
    61 # strict mode flag
       
    62 my $strictMode = 0;
       
    63 
       
    64 #
       
    65 # Open and parse the given xml database
       
    66 # @param - xml file name
       
    67 #
       
    68 sub open_Database
       
    69 {
       
    70 	my ($xmlDBFile) = join(',',@_);
       
    71 	
       
    72 	$xmlDBHandle = &featuresutil::parseXMLDatabase($xmlDBFile,FM_FLG,$strictMode,$verboseMode);
       
    73 	
       
    74 	return 0 if(!$xmlDBHandle);
       
    75 	return 1;
       
    76 }
       
    77 
       
    78 #
       
    79 # set the default path settings for header and iby files
       
    80 #
       
    81 sub set_DefaultPath
       
    82 {
       
    83 	my ($epocroot, $hdrpath, $ibypath, $datpath, $convpath) = @_;
       
    84 	
       
    85 	$$hdrpath = $epocroot."epoc32/include/";
       
    86 	$$ibypath = $epocroot."epoc32/rom/include/";
       
    87 	$$datpath = "./"; # current folder
       
    88 	$$convpath = "./"; # current folder
       
    89 }
       
    90 
       
    91 #
       
    92 # Generate the header file for each featureset
       
    93 # @param - destination path for the header file(s)
       
    94 #
       
    95 sub generate_Headerfile
       
    96 {
       
    97 	my $featureList=(); 
       
    98 	my $featureSetList = ();
       
    99 	my $hdrpath = shift;
       
   100 	my $aliasfeatureList = ();
       
   101 	
       
   102 	# Get the list of featuresets exists in the xml database
       
   103 	$featureSetList = $xmlDBHandle->getFeatureset();
       
   104 	foreach my $featureSet (@$featureSetList) {
       
   105 		my @defPresent=();
       
   106 		my @defNotPresent=();
       
   107 		my @defPresentAlias = ();
       
   108 		my @defNotPresentAlias = ();
       
   109 		my $tab = "\t";
       
   110 		
       
   111 		# if the headerfile name is not there then just return
       
   112 		if(!defined $featureSet->{hfilename}) {
       
   113 			MSG("No header file generated for the featureset $featureSet->{namespace}");
       
   114 			next;
       
   115 		}
       
   116 		
       
   117 		# Get the filename
       
   118 		my $hfile = $featureSet->{hfilename};
       
   119 		
       
   120 		# Create directory if it doesn't exists
       
   121 		return if(!createDirectory($hdrpath));
       
   122 		
       
   123 		my $hfileHandle = openFile($hdrpath.$hfile);
       
   124 		if(!$hfileHandle) {
       
   125 			print "ERROR: Cannot open file $hdrpath$hfile\n";
       
   126 			next;
       
   127 		}
       
   128 		
       
   129 		MSG("Creating headerfile $hdrpath$hfile");
       
   130 		
       
   131 		# Get the name->uid map for the features given in the selected featureset
       
   132 		$featureList = $featureSet->{feature_list};
       
   133 		# Create two sets of feature name list for the default present and notpresent
       
   134 		foreach my $name (keys %$featureList)
       
   135 		{
       
   136 			if(defaultPresent($featureList->{$name})){
       
   137 				push @defPresent, $name;
       
   138 			}
       
   139 			else {
       
   140 				push @defNotPresent, $name;
       
   141 			}
       
   142 		}
       
   143 		#for alias
       
   144 		$aliasfeatureList = $featureSet->{alias_feature_list};
       
   145 		foreach my $alias_name (keys %$aliasfeatureList)
       
   146 		{
       
   147 			if(defaultPresent($aliasfeatureList->{$alias_name}))
       
   148 			{
       
   149 				push @defPresentAlias, $alias_name;
       
   150 			}
       
   151 			else
       
   152 			{
       
   153 				push @defNotPresent, $alias_name;
       
   154 			}
       
   155 		}
       
   156 
       
   157 		# sort them
       
   158 		@defPresent = sort(@defPresent);
       
   159 		@defNotPresent = sort(@defNotPresent);
       
   160 		
       
   161 		# insert the file header attribute value
       
   162 		my $comment = $featureSet->{hfileheader};
       
   163 		if($comment) {
       
   164 			trimString(\$comment);
       
   165 			
       
   166 			# insert the interfacevisibility and interfacestatus attribute values
       
   167 			writeFile($hfileHandle, $comment."\n/**\n".$featureSet->{interfacevisibility}."\n".
       
   168 						 $featureSet->{interfacestatus}."\n*/\n");
       
   169 		}
       
   170 					 
       
   171 		if(defined $featureSet->{namespace}) {
       
   172 			writeFile($hfileHandle, "namespace ".$featureSet->{namespace}." {\n");
       
   173 		}
       
   174 		else {
       
   175 			$tab = "";
       
   176 		}
       
   177 		
       
   178 		# for each feature list insert an entry in the current namespace
       
   179 		writeFile($hfileHandle,$tab."// default present\n") if(@defPresent);
       
   180 		foreach my $name (@defPresent) {
       
   181 			$comment = $featureSet->{feature}{$featureList->{$name}}{comment};
       
   182 			if(defined $comment) {
       
   183 				trimString(\$comment);
       
   184 				$comment =~ s/\n/\n$tab/mg;
       
   185 				chop($comment) if($tab eq "\t");
       
   186 				writeFile($hfileHandle, $tab.$comment);
       
   187 			}
       
   188 			
       
   189 			writeFile($hfileHandle,$tab."const TUid K", $featureSet->{feature}{$featureList->{$name}}{name},
       
   190 						 sprintf(" = {0x%X};\n", $featureList->{$name}));
       
   191 			writeFile($hfileHandle,"\n") if(defined $comment);
       
   192 		}
       
   193 
       
   194 		foreach my $alias_name (@defPresentAlias)
       
   195 		{
       
   196 			$comment = $featureSet->{alias_feature}{$aliasfeatureList->{$alias_name}}{comment};
       
   197 			if(defined $comment)
       
   198 			{
       
   199 				trimString(\$comment);
       
   200 				$comment =~ s/\n/\n$tab/mg;
       
   201 				chop($comment) if ($tab eq "\t");
       
   202 				writeFile($hfileHandle, $tab.$comment);
       
   203 			}
       
   204 			writeFile($hfileHandle, $tab."const TUid K", $featureSet->{alias_feature}{$aliasfeatureList->{$alias_name}}{name}, sprintf(" = {0x%X};\n", $aliasfeatureList->{$alias_name}));
       
   205 			writeFile($hfileHandle, "\n") if(defined $comment);
       
   206 		}
       
   207 
       
   208 		writeFile($hfileHandle, "\n".$tab."// default not present\n") if(@defNotPresent);
       
   209 		foreach my $name (@defNotPresent) {
       
   210 			$comment = $featureSet->{feature}{$featureList->{$name}}{comment};
       
   211 			if(defined $comment) {
       
   212 				trimString(\$comment);
       
   213 				$comment =~ s/\n/\n$tab/mg;
       
   214 				chop($comment) if($tab eq "\t");
       
   215 				writeFile($hfileHandle,$tab.$comment);
       
   216 			}
       
   217 			
       
   218 			writeFile($hfileHandle,$tab."const TUid K", $featureSet->{feature}{$featureList->{$name}}{name},
       
   219 						 sprintf(" = {0x%X};\n", $featureList->{$name}));
       
   220 			writeFile($hfileHandle,"\n") if(defined $comment);
       
   221 		}
       
   222 		foreach my $alias_name (@defNotPresentAlias)
       
   223 		{
       
   224 			$comment = $featureSet->{alias_feature}{$aliasfeatureList->{$alias_name}}{comment};
       
   225 			if(defined $comment)
       
   226 			{
       
   227 				trimString(\$comment);
       
   228 				$comment =~ s/\n/\n$tab/mg;
       
   229 				chop($comment) if ($tab eq "\t");
       
   230 				writeFile($hfileHandle, $tab.$comment);
       
   231 			}
       
   232 			writeFile($hfileHandle, $tab."const TUid K", $featureSet->{alias_feature}{$aliasfeatureList->{$alias_name}}{name}, sprintf(" = {0x%X};\n", $aliasfeatureList->{$alias_name}));
       
   233 			writeFile($hfileHandle, "\n") if(defined $comment);
       
   234 		}
       
   235 		
       
   236 		if(defined $featureSet->{namespace}) {
       
   237 			writeFile($hfileHandle,"}\n");
       
   238 		}
       
   239 		
       
   240 		closeFile($hfileHandle);
       
   241 	}
       
   242 }
       
   243 
       
   244 #
       
   245 # Generate the obey file for each featureset
       
   246 # @param - destination path for the iby file(s)
       
   247 #
       
   248 sub generate_Obeyfile
       
   249 {
       
   250 	my $featureSet=(); my $feature=(); my $featureList=(); my $featureSetList=();
       
   251 	my $aliasfeatureList = ();
       
   252 	my $ibypath = shift;
       
   253 	
       
   254 	# Get the list of featuresets exists in the xml database
       
   255 	$featureSetList = $xmlDBHandle->getFeatureset();
       
   256 	foreach my $featureSet (@$featureSetList) {
       
   257 		# if the obey file name is not there then just return
       
   258 		if(!defined $featureSet->{ibyname}) {
       
   259 			MSG("No IBY file generated for the featureset $featureSet->{namespace}");
       
   260 			next;
       
   261 		}
       
   262 		
       
   263 		# Get the file name
       
   264 		my $ibyfile = $featureSet->{ibyname};
       
   265 		
       
   266 		# Create the directory if it doesn't exists
       
   267 		return if(!createDirectory($ibypath));
       
   268 		
       
   269 		my $ibyfilehandle = openFile($ibypath.$ibyfile);
       
   270 		if(!$ibyfilehandle) {
       
   271 			print "*ERROR: Cannot open file $ibypath$ibyfile\n";
       
   272 			next;
       
   273 		}
       
   274 		
       
   275 		MSG("Creating IBY file $ibypath$ibyfile");
       
   276 		
       
   277 		$ibyfile =~ s/\./\_/g;
       
   278 		$ibyfile = uc($ibyfile);
       
   279 		
       
   280 		# insert the file header
       
   281 		writeFile($ibyfilehandle, "#ifndef\t__",$ibyfile,"__\n#define\t__",$ibyfile,"__\n\n");
       
   282 
       
   283 		# get the name->uid map of features for the given featureset
       
   284 		$featureList = $featureSet->{feature_list};
       
   285 		$aliasfeatureList = $featureSet->{alias_feature_list};
       
   286 		my %combine_list = (%$featureList, %$aliasfeatureList);
       
   287 		foreach my $name (sort keys %combine_list)
       
   288 		{
       
   289 			my $defblock=(); my $flags=(); my $comment=();
       
   290 			
       
   291 			my $uid = $xmlDBHandle->getFeatureUID($name,$featureSet->{namespace});
       
   292 			
       
   293 			# get the featureset attributes
       
   294 			$feature = $xmlDBHandle->getFeatureInfo($uid,$featureSet->{namespace});
       
   295 			
       
   296 			# check to see this feature to be included in iby file
       
   297 			next if(!$feature->{infeaturesetiby});
       
   298 			# get the feature flags
       
   299 			$flags = "SF ".$feature->{statusflags} if(defined $feature->{statusflags});
       
   300 			if(defined $feature->{userdata}) {
       
   301 				$flags .= " "."UD ".$feature->{userdata};
       
   302 			}
       
   303 			else {
       
   304 				$flags .= " "."UD 0x00000000";
       
   305 			}
       
   306 
       
   307 			# get the comment value
       
   308 			if(defined $feature->{comment}) {
       
   309 				$comment = $feature->{comment};
       
   310 				trimString(\$comment);
       
   311 			}
       
   312 			
       
   313 			if(defined $feature->{includemacro}) { # if the include macro is specified
       
   314 				$defblock = "\n#ifdef ".$feature->{includemacro}."\n";
       
   315 				$defblock .= $comment;
       
   316 				$defblock .= "FEATURE ".$feature->{name}." ".$flags."\n";
       
   317 				$defblock .= "#else\nEXCLUDE_FEATURE ".$feature->{name}." ".$flags."\n#endif\n"
       
   318 			}
       
   319 			elsif(defined $feature->{excludemacro}) { # if the exclude macro is specified
       
   320 				$defblock = "\n#ifdef ".$feature->{excludemacro}."\n";
       
   321 				$defblock .= "EXCLUDE_FEATURE ".$feature->{name}." ".$flags."\n#else\n";
       
   322 				$defblock .= $comment;
       
   323 				$defblock .= "FEATURE ".$feature->{name}." ".$flags."\n#endif\n"
       
   324 			}
       
   325 			else {  # default case
       
   326 				# No system wide macro defined for this feature
       
   327 				next;
       
   328 			}
       
   329 			
       
   330 			# insert #ifdef block
       
   331 			writeFile($ibyfilehandle, $defblock);
       
   332 		}
       
   333 		
       
   334 		writeFile($ibyfilehandle, "\n\n#endif //__",$ibyfile,"__");
       
   335 		closeFile($ibyfilehandle);
       
   336 	}
       
   337 }
       
   338 
       
   339 #
       
   340 # Generate the feature DAT file
       
   341 # @param - destination path for the features.DAT file
       
   342 #
       
   343 sub generate_DATfile
       
   344 {
       
   345 	my $featureSet=(); my $feature=(); my $featureList=(); my $featureSetList=();
       
   346 	my @featList=();
       
   347 	my $aliasfeatureList = ();
       
   348 	my $aliasfeatlist = ();
       
   349 	my %uidtoaliasname = ();
       
   350 	my $datpath = shift;
       
   351 	
       
   352 	# Get the list of featuresets exists in the xml database
       
   353 	$featureSetList = $xmlDBHandle->getFeatureset();
       
   354 	$aliasfeatlist = $xmlDBHandle->getAliasFeatureList();
       
   355 	foreach my $aliasname (keys %$aliasfeatlist)
       
   356 	{
       
   357 		$uidtoaliasname{$aliasfeatlist->{$aliasname}} = $aliasname;
       
   358 	}
       
   359 	foreach my $featureSet (@$featureSetList) {
       
   360 		# get the name->uid map of features for the given featureset
       
   361 		$featureList = $featureSet->{feature_list};
       
   362 		foreach my $name (keys %$featureList)
       
   363 		{
       
   364 			if (exists $uidtoaliasname{$featureList->{$name}})
       
   365 			{
       
   366 				next;
       
   367 			}
       
   368 			my $statusflag = 0;
       
   369 			my %featinfo = ();
       
   370 			
       
   371 			$featinfo{feature} = $name;
       
   372 			$featinfo{SF} = $xmlDBHandle->getStatusFlag($name, $featureSet->{namespace});
       
   373 			$featinfo{UD} = $xmlDBHandle->getUserData($name, $featureSet->{namespace});
       
   374 			$statusflag = &featureparser::ConvertHexToDecimal($featinfo{SF});
       
   375 			if($statusflag & BIT_SUPPORTED) {
       
   376 				$featinfo{include} = 1;
       
   377 			}
       
   378 			else {
       
   379 				$featinfo{include} = 0;
       
   380 			}
       
   381 			
       
   382 			push @featList, {%featinfo};
       
   383 		}
       
   384 		$aliasfeatureList = $featureSet->{alias_feature_list};
       
   385 		foreach my $alias_name (keys %$aliasfeatureList)
       
   386 		{
       
   387 			my $statusflag = 0;
       
   388 			my %featinfo = ();
       
   389 			
       
   390 			$featinfo{feature} = $alias_name;
       
   391 			$featinfo{SF} = $xmlDBHandle->getStatusFlag($alias_name, $featureSet->{namespace});
       
   392 			$featinfo{UD} = $xmlDBHandle->getUserData($alias_name, $featureSet->{namespace});
       
   393 			$statusflag = &featureparser::ConvertHexToDecimal($featinfo{SF});
       
   394 			if($statusflag & BIT_SUPPORTED) {
       
   395 				$featinfo{include} = 1;
       
   396 			}
       
   397 			else {
       
   398 				$featinfo{include} = 0;
       
   399 			}
       
   400 			push @featList, {%featinfo};
       
   401 		}
       
   402 
       
   403 
       
   404 	}
       
   405 	
       
   406 	if(@featList) {
       
   407 		# Create the directory if doesn't exists
       
   408 		return if(!createDirectory($datpath));
       
   409 		
       
   410 		# Create features.dat file
       
   411 		&featuresutil::createFeatureFile(NONE,NONE,$datpath.DAT_FILE,\@featList,FM_FLG,SINGLE_DATFILE);
       
   412 	}
       
   413 }
       
   414 
       
   415 #
       
   416 # Converts the feature registry object to feature manager xml
       
   417 # @param - destination path for the output file
       
   418 # @param - input file list as an array
       
   419 #
       
   420 sub convert_FeatRegToFeatMgr
       
   421 {
       
   422 	&featuresutil::convert_FeatRegToFeatMgr($strictMode,$verboseMode,@_);
       
   423 }
       
   424 
       
   425 #
       
   426 # Enable verbose mode
       
   427 # 
       
   428 sub set_VerboseMode
       
   429 {
       
   430 	$verboseMode = 1;
       
   431 }
       
   432 
       
   433 #
       
   434 # Enable strict mode
       
   435 # 
       
   436 sub set_StrictMode
       
   437 {
       
   438 	$strictMode = 1;
       
   439 }
       
   440 
       
   441 # --Utility Functions
       
   442 
       
   443 #
       
   444 # Check whether the given feature uid is present in default include list
       
   445 # @param - feature uid value
       
   446 #
       
   447 sub defaultPresent
       
   448 {
       
   449 	my ($uid) = shift;
       
   450 	
       
   451 	my $defaultRanges = $xmlDBHandle->defaultRangeList();
       
   452 	
       
   453 	foreach my $range (@$defaultRanges)
       
   454 	{
       
   455 		if ( (lc($range->{"support"}) eq "include") and ($range->{"min"} <= $uid) and ($range->{"max"} >= $uid) ) {
       
   456 			return 1;
       
   457 		}
       
   458 	}
       
   459 	return 0;
       
   460 }
       
   461 
       
   462 #
       
   463 # Trim the given string for trailing whitespaces
       
   464 # @param - string to be trimmed
       
   465 #
       
   466 sub trimString
       
   467 {
       
   468 	my $str = shift;
       
   469 	
       
   470 	$$str =~ s/^[ \t]+//mg;
       
   471 	$$str =~ s/^\n//mg;
       
   472 	
       
   473 	$$str .= "\n" if($$str !~ /\n$/m);
       
   474 }
       
   475 
       
   476 #
       
   477 # Verbose mode output routine
       
   478 # @param - Message to be displayed
       
   479 #
       
   480 sub MSG 
       
   481 {
       
   482 	print "**".$_[0]."...\n" if($verboseMode);
       
   483 }
       
   484 
       
   485 #
       
   486 # Open a text file in write mode
       
   487 # @param - name of the file to open
       
   488 #
       
   489 sub openFile
       
   490 {
       
   491 	my $file = shift;
       
   492 	
       
   493 	open(FILEP,">$file") or (return 0);
       
   494 	
       
   495 	return *FILEP;
       
   496 }
       
   497 
       
   498 #
       
   499 # Writes string to the file stream
       
   500 # @param filehandle - reference to the file handle
       
   501 # @param data - array of string to be written
       
   502 #
       
   503 sub writeFile
       
   504 {
       
   505 	my ($filehandle, @data) = @_;
       
   506 	
       
   507 	printf $filehandle "%s",$_ foreach (@data);
       
   508 }
       
   509 
       
   510 #
       
   511 # Closes the file stream
       
   512 # @param filehanlde - referece to the file handle
       
   513 #
       
   514 sub closeFile
       
   515 {
       
   516 	my $filehandle = shift;
       
   517 	
       
   518 	close $filehandle;
       
   519 }
       
   520 
       
   521 #
       
   522 # Check the existance of the directory and create one if it doesn't exist
       
   523 # @param dir - directory name
       
   524 #
       
   525 sub createDirectory
       
   526 {
       
   527 	my $dir = shift;
       
   528 	
       
   529 	if(!(-e $dir)) {
       
   530 		if(!mkdir($dir)) {
       
   531 			print "ERROR: Failed to create $dir folder\n";
       
   532 			return 0;
       
   533 		}
       
   534 	}
       
   535 	return 1;
       
   536 }
       
   537 
       
   538 1;