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