|
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; |