Update contrib.
1 # Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
3 # This component and the accompanying materials are made available
4 # under the terms of the License "Eclipse Public License v1.0"
5 # which accompanies this distribution, and is available
6 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 # Initial Contributors:
9 # Nokia Corporation - initial contribution.
15 # Check arguments and open files
19 my $nargs=scalar(@ARGV);
24 elsif ($nargs!=3 and $nargs!=4) {
25 die "Invalid number of arguments. Run with no arguments for help on usage.\n";
30 if ($ARGV[$arg] eq '-x') {
32 } elsif ($ARGV[$arg] eq '-s') {
34 } elsif ($ARGV[$arg] eq '-h') {
38 die "Invalid 1st argument $ARGV[0]\n";
42 my $headerFileName=$ARGV[$arg++];
43 my @hdr = &read_file_strip_comments($headerFileName);
45 my $inputFileName=$ARGV[$arg++];
46 my @input = &read_file_strip_comments($inputFileName);
48 my $outputFileName=$ARGV[$arg++];
51 # Parse the header file
62 next if (/^\s*\#/); # ignore preprocessor directives
63 next if (/^\s*\/\//); # ignore comments starting with //
64 next if (/^\s*$/); # ignore blank lines
66 if (/^\s*class\s+HALData\s*$/) {
69 if (/^\s*class\s+HALData\s*{/) {
85 if (/^\s*enum\s+(\w+)(.*)/) {
96 if (/^\s*bitmask\s+(\w+)(.*)/) {
116 if (/^\s*(\w+)(.*)/) {
120 # print "$tag\n$rest\n";
121 if ($rest=~/^\s*,/) {
123 } elsif ($rest=~/^\s*\=\s*(\d\w*)\s*\,/) {
125 unless ($val=~/^\d*$/) {
126 if ($val=~/^0x(\w+)$/i) {
132 } elsif ($rest=~/^\s*$/) { # ignore last one
137 unless (defined $val) {
138 die "Syntax error at line $line in file $headerFileName\n";
141 $enumValues{$tag}=$val;
142 # print "$tag=$val\n";
146 $enumValues{'__bitmask__'}=-1;
148 my %temp=%enumValues;
149 $enumList{$enumName}=\%temp;
155 die "Unexpected end of file in $headerFileName\n";
159 # my @keys=keys %enumList;
161 # print "enum $_\n\t{\n";
162 # my $ref=$enumList{$_};
163 # my @tags=keys(%$ref);
165 # my $value=$$ref{$_};
166 # print "\t$_=$value\n";
172 # Build a list of properties for each attribute
174 my $attribref=$enumList{'TAttribute'};
175 unless ($attribref) {
176 die "No TAttribute enum defined\n";
178 my @attribs=keys %$attribref;
182 $properties{'name'}=$_;
183 $properties{'ordinal'}=$$attribref{$_};
185 $enum=~s/^E/T/; # change initial E to T
186 if (defined $enumList{$enum}) {
187 my $enumRef=$enumList{$enum};
188 $properties{'enum'}=$enumRef;
189 if (defined $$enumRef{'__bitmask__'}) {
190 $properties{'bitmask'}=1;
193 $attribList{$_}=\%properties;
196 my $attpropref=$enumList{'TAttributeProperty'};
199 unless ($attpropref) {
200 die "No TAttributeProperty enum defined\n";
203 my @attprops=keys(%$attpropref);
204 foreach (@attprops) {
207 $PropTable{$propname}='HAL::'.$_;
209 die "Invalid attribute property $_\n";
213 my @PropTableKeys=keys %PropTable;
217 # Parse the input file
222 next if (/^\s*\/\//); # ignore comments starting with //
223 next if (/^\s*$/); # ignore blank lines
224 if (/^\s*(\w+)\s*(.*)/) {
227 my $propRef=$attribList{$attrib};
228 unless (defined $propRef) {
229 die "Unrecognised attribute at line $line in file $inputFileName\n";
232 if ($rest=~/^\:\s*(.*)/) { # attribute properties follow
234 die "Line $line: Properties not permitted without -x option\n";
238 while ($rest=~/^(\w+)\s*(.*)/) {
242 my $error=matchabbrev(\$prop, \@PropTableKeys);
244 die "$error property $prop at line $line in file $inputFileName\n";
247 if ($rest=~/^,\s*(.*)/) {
249 } elsif ($rest=~/^=\s*(.*)/) {
253 die "Syntax error at line $line in file $inputFileName\n";
256 } elsif ($rest=~/^=\s*(.*)/) {
257 $rest=$1 # attribute value follows
259 die "Invalid attribute specification at line $line in file $inputFileName\n";
264 if ($rest=~/^((\w|:)+)/) {
265 $$propRef{'value'}=$1;
267 die "Invalid function name $rest at line $line in file $inputFileName\n";
269 } elsif (defined $$propRef{'bitmask'}) { # bitmask value
270 my $enumRef=$$propRef{'enum'};
271 my @keys=keys %$enumRef;
273 while ($rest=~/^(\w+)\s*(.*)/) {
276 if ($bitmaskKey eq '0' or lc($bitmaskKey) eq 'none') {
278 die "Inconsistent bit mask values at line $line in file $inputFileName\n";
280 my $error=matchabbrev(\$bitmaskKey,\@keys);
282 die "$error bit value $bitmaskKey at line $line in file $inputFileName\n";
284 $val |= $$enumRef{$bitmaskKey};
285 if ($rest=~/^\+\s*(.*)/) {
287 } elsif ($rest=~/^\s*$/) {
290 die "Syntax error at line $line in file $inputFileName\n";
293 $$propRef{'value'}=$val;
294 } elsif (defined $$propRef{'enum'} and $rest!~/^\d/) { # enum value
295 my $enumRef=$$propRef{'enum'};
296 my @keys=keys %$enumRef;
297 if ($rest=~/^(\w+)\s*$/) {
299 my $error=matchabbrev(\$enumKey,\@keys);
301 die "$error enumeration value $enumKey at line $line in file $inputFileName\n";
303 $$propRef{'value'}=$$enumRef{$enumKey};
305 die "Invalid enum value $rest at line $line in file $inputFileName\n";
307 } elsif ($rest=~/^(\-?\d\w*)\s*$/) { # numeric value (decimal or hex) with optional -ve sign
309 unless ($val=~/^(\-?\d)\d*$/) { # First character should be an optional -ve sign followed by only digits
310 if ($val=~/^(\-?)0x(\w+)$/i) { # First character should be an optional -ve sign followed by only alphanumerics
320 unless (defined $val) {
321 die "Invalid attribute value $1 at line $line in file $inputFileName\n";
323 $$propRef{'value'}=$val;
325 die "Invalid attribute value at line $line in file $inputFileName\n";
328 die "Unrecognised attribute at line $line in file $inputFileName\n";
332 # foreach (@attribs) {
333 # my $propRef=$attribList{$_};
334 # if (defined $$propRef{'value'}) {
335 # print "Attribute $_:\n";
336 # my @keys=keys %$propRef;
338 # print "\t$_=$$propRef{$_}\n";
344 # Sort attributes by ordinal
346 my @AttribsByOrdinal;
348 my $propRef=$attribList{$_};
349 my $ordinal=$$propRef{'ordinal'};
350 $AttribsByOrdinal[$ordinal]=$propRef;
352 my $nAttribs=scalar(@AttribsByOrdinal);
355 # Generate the output file
358 open OUT, ">$outputFileName" or die "Cannot open output file $outputFileName\n";
362 # while ($i<$nAttribs) {
363 # my $value=0x80000000;
364 # my $propRef=$AttribsByOrdinal[$i];
365 # if (defined $$propRef{'value'}) {
366 # $value=$$propRef{'value'};
369 # my $b3=($value>>24)&0xff;
370 # my $b2=($value>>16)&0xff;
371 # my $b1=($value>>8)&0xff;
372 # my $b0=$value&0xff;
377 # my $writeres=syswrite OUT, $b0123, 4;
378 # if ($writeres != 4) {
379 # die "Error writing output file $outputFileName\n";
384 my @splitName=split /(:|\\)/, $outputFileName;
385 my $rootName=pop @splitName;
386 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
387 #print "\n$hour:$min:$sec $mday-$mon-$year wday=$wday, yday=$yday, isdst=$isdst\n\n";
390 print OUT "// $rootName\n";
392 print OUT "// Copyright (c) 1999-$year Nokia Corporation and/or its subsidiary(-ies).";
393 print OUT "// All rights reserved.\n";
396 print OUT "// GENERATED FILE - DO NOT EDIT\n";
400 print OUT "#include <kernel/hal_int.h>\n";
404 // CodeWarrior requires EXPORT_C on the definiton here, as well as the declaration (in hal_int.h)
405 EXPORT_C const TInt HalInternal::InitialValue[]=
407 EXPORT_D const TInt HalInternal::InitialValue[]=
413 while ($i<$nAttribs) {
414 my $propRef=$AttribsByOrdinal[$i];
416 my $separator=($i<$nAttribs)?',':'';
417 my $name=$$propRef{'name'};
419 if (defined $$propRef{'value'}) {
420 $value=$$propRef{'value'};
422 print OUT "\t$value$separator\t\t// $name\n";
425 } elsif ($xmode==1) {
428 while ($i<$nAttribs) {
429 my $propRef=$AttribsByOrdinal[$i];
431 my $name=$$propRef{'name'};
432 my $imp=$$propRef{'value'};
433 if ($imp=~/^\s*0\s*$/) {
437 print OUT "GLREF_C TInt $imp(TInt, TInt, TBool, TAny*);\t// $name\n";
441 print OUT "const TUint8 HalInternal::Properties[]=\n";
444 while ($i<$nAttribs) {
445 my $propRef=$AttribsByOrdinal[$i];
447 my $separator=($i<$nAttribs)?',':'';
449 my $name=$$propRef{'name'};
450 if (defined $$propRef{'value'}) {
451 $properties=$PropTable{'valid'};
452 my @keys=keys(%$propRef);
454 my $pConst=$PropTable{$_};
455 if (defined $pConst) {
456 $properties.="|$pConst";
460 if ($properties=~/^\s*$/) {
463 print OUT "\t$properties$separator\t\t// $name\n";
466 print OUT "\n#if 0\n";
467 print OUT "const TInt HalInternal::Offset[]=\n";
471 while ($i<$nAttribs) {
472 my $propRef=$AttribsByOrdinal[$i];
474 my $separator=($i<$nAttribs)?',':'';
475 my $name=$$propRef{'name'};
476 my $imp=$$propRef{'value'};
477 if ($imp=~/^\s*0\s*$/) {
478 print OUT "\t$memOffset$separator\t\t// $name\n";
481 print OUT "\t-1$separator\t\t// $name\n";
485 print OUT "\n#endif\n";
486 print OUT "const TInt HalInternal::HalDataSize=$memOffset;\n";
488 print OUT "const THalImplementation HalInternal::Implementation[]=\n";
491 while ($i<$nAttribs) {
492 my $propRef=$AttribsByOrdinal[$i];
494 my $separator=($i<$nAttribs)?',':'';
495 my $name=$$propRef{'name'};
496 my $imp=$$propRef{'value'};
497 if (!defined $imp or $imp=~/^\s*0\s*$/) {
500 print OUT "\t$imp$separator\t\t// $name\n";
503 } elsif ($xmode==2) {
506 while ($i<$nAttribs) {
507 my $propRef=$AttribsByOrdinal[$i];
509 my $name=$$propRef{'name'};
510 my $imp=$$propRef{'value'};
511 if ($imp=~/^\s*0\s*$/) {
514 my $setarg=' /*aSet*/';
515 if (defined $$propRef{'settable'}) {
519 print OUT "// $name\n";
520 print OUT "TInt $imp(TInt /*aDeviceNumber*/, TInt /*aAttrib*/, TBool$setarg, TAny* aInOut)\n";
522 print OUT "\treturn KErrNone;\n";
528 } elsif ($xmode==3) {
529 my $hdrprot='__'.uc $rootName.'__';
532 print OUT "#ifndef $hdrprot\n";
533 print OUT "#define $hdrprot\n";
535 while ($i<$nAttribs) {
536 my $propRef=$AttribsByOrdinal[$i];
538 my $name=$$propRef{'name'};
539 my $imp=$$propRef{'value'};
540 if ($imp=~/^\s*0\s*$/) {
544 print OUT "GLREF_C TInt $imp(TInt, TInt, TBool, TAny*);\t// $name\n";
548 print OUT "#endif\n";
557 sub matchabbrev($$) {
558 my ($inref, $lref)=@_;
559 my @matches=grep(/$$inref/i,@$lref);
560 my $nmatches=scalar(@matches);
563 } elsif ($nmatches>1) {
564 my @xmatches=grep(/^$$inref$/i,@matches);
565 if (scalar(@xmatches)!=1) {
568 $$inref=$xmatches[0];
577 sub read_file_strip_comments($) {
579 open IN, $filename or die "Cannot read file $filename\n";
587 $in =~ s/\/\*(.*?)\*\//\n/gms;
588 $in =~ s/\/\/(.*?)\n/\n/gms;
590 return split(/(\n)/, $in);
596 "halcfg.pl is a perl script that is used by the build system to generate the\n",
597 "C++ source files from the Config and Values files.\n",
599 "There are four modes in which the Perl script halcfg.pl can be used.\n",
601 "\"perl halcfg.pl hal_data.h values.hda values.cpp\"\n",
603 "takes the values.hda text file and generates a table of initial values for\n",
604 "items stored by the HAL.\n",
606 "\"perl halcfg.pl -x hal_data.h config.hcf config.cpp\"\n",
608 "generates three tables:\n",
610 " - the properties, i.e. whether valid and/or writable, for each item\n",
612 " - the offset of each item within the DllGlobal block\n",
614 " - the function implementing each item, for derived attributes. ie. those\n",
615 " attributes that are not simply stored by the HAL.\n",
617 "\"perl halcfg.pl -s hal_data.h config.hcf source.cpp\"\n",
619 "generates a source file containing skeleton code for the implementation of the\n",
620 "accessor function for each derived attribute\n",
622 "\"perl halcfg.pl -h hal_data.h config.hcf header.h\"\n",
624 "generates a header file containing prototypes for the accessor functions for\n",
625 "each derived attribute\n",
627 "Note that the header file hal_data.h containing the attributes and values used\n",
628 "by the HAL is passed on all calls to the perl script.\n";