Enhance buildrom.pm to enable final OBY file to be converted into acceptable input for buildrom (Bug 3862)
#
# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
# All rights reserved.
# This component and the accompanying materials are made available
# under the terms of the License "Eclipse Public License v1.0"
# which accompanies this distribution, and is available
# at the URL "http://www.eclipse.org/legal/epl-v10.html".
#
# Initial Contributors:
# Nokia Corporation - initial contribution.
#
# Contributors:
#
# Description:
# Split core image components to ROM/ROFS1.
# Make UREL <-> UDEB conversions.
#
package obyparse;
use strict;
use warnings;
use plugincommon;
BEGIN
{
use Exporter();
our($VERSION, @ISA, @EXPORT);
$VERSION = 1.00;
@ISA = qw(Exporter);
@EXPORT = qw(&obyparse_info &obyparse_init &obyparse_process);
}
my $conf;
sub obyparse_info()
{
return({
name => "obyparse",
invocation => "InvocationPoint2", # tmp6.oby
initialize => "obyparse::obyparse_init",
single => "obyparse::obyparse_process"});
}
sub obyparse_init($)
{
plugin_init(&obyparse_info, $conf = shift(), 0);
}
sub obyparse_readconffile($$$$$);
sub obyparse_findincfiles();
sub obyparse_findspifiles();
sub obyparse_process($)
{
plugin_start(&obyparse_info, $conf);
my ($obydata, $romfiles, $rofs1files, $udebfiles, $urelfiles, $fname) = (shift(), undef, undef, "", "", "");
my %targets = my %patchdata = ();
obyparse_findincfiles();
obyparse_findspifiles();
plugin_reset();
foreach (@$obydata)
{
next if !(my $parse = parse_obyline($_));
if (($parse == 2) && ($gKeyword =~ FILEBITMAPSPECKEYWORD)) {
$targets{$gTgtCmp} = $targets{File::Basename::basename($gTgtCmp)} = [$gLnum - 1,
!$gRomid && ($gKeyword =~ ROFSBITMAPFILESPECKEYWORD) && ($gAttrib !~ /paging_unmovable/i)]
if ($gImgid == $gRomidCmp);
dprint(2, "Removed attribute paging_unmovable: `$_'")
if ($gAttrib =~ /paging_unmovable/i) && (s/\s+paging_unmovable\s*(?=\s|^)//i);
next;
}
next if !/^\s*OBYPARSE_(ROM|ROFS1|UDEB|UREL)\s+(.+?)\s*$/i;
(my $rule, $fname) = (uc($1), $2);
$_ = "$gHandlestr $_";
next if $gRomid && ($gImgid != $gRomidCmp);
dprint(2, "#$gLnum: `$gLine'");
my $files = ($rule eq "ROM" ? \$romfiles : ($rule eq "ROFS1" ? \$rofs1files :
($rule eq "UDEB" ? \$udebfiles : \$urelfiles)));
$$files = "" if !defined($$files);
if ($fname ne "*") {
my $basedir = "";
($basedir, $fname) = ($1, $2) if $fname =~ /^(.*[\/\\])(.+?)$/;
dprint(3, "Found " . obyparse_readconffile($basedir, $fname, $rule, $files, 0) . " entries");
} else {
dprint(3, "Move/change all possible components to $rule");
$$files = ".*";
}
}
$romfiles = qr/^($romfiles)$/i if defined($romfiles);
$rofs1files = qr/^($rofs1files)$/i if defined($rofs1files);
($udebfiles, $urelfiles) = (qr/^($udebfiles)$/i, qr/^($urelfiles)$/i);
my ($rofs1ofs, $udebcnt, $urelcnt, @torofs1) = (0, 0, 0, ());
plugin_reset();
foreach (@$obydata)
{
my $parse = parse_obyline($_);
$rofs1ofs++ if ($gRomid < 2);
next if ($parse != 2) || ($gImgid != $gRomidCmp);
if ($gKeyword =~ /^patchdata$/i) {
$gSrcCmp =~ /^(.+?)(?:@.+)?$/;
next if !exists($targets{$fname = $1});
$patchdata{$fname} = $targets{$fname}[0] if !exists($patchdata{$fname});
next if !$targets{$fname}[1];
}
elsif ($gKeyword =~ FILEBITMAPSPECKEYWORD) {
$fname = File::Basename::basename($gTgtCmp);
if ($fname =~ $urelfiles && s/(?<=[\/\\])udeb(?=[\/\\])/urel/i) {
$urelcnt++;
dprint(2, "Changed to UREL: `$_'");
}
elsif ($fname =~ $udebfiles && s/(?<=[\/\\])urel(?=[\/\\])/udeb/i) {
$udebcnt++;
dprint(2, "Changed to UDEB: `$_'");
}
next if !$targets{$gTgtCmp}[1];
}
elsif ($gKeyword =~ DIRECTORYKEYWORD) {
$fname = File::Basename::basename($gTgtCmp);
next if !(exists($targets{$gTgtCmp}) && $targets{$gTgtCmp}[1]) &&
!(exists($targets{$fname}) && $targets{$fname}[1]);
}
else { next }
if (!$gRomid && (defined($rofs1files) && ($fname =~ $rofs1files) || defined($romfiles) && ($fname !~ $romfiles))) {
push(@torofs1, $_);
$_ = "$gHandlestr $_";
}
}
dprint(3, "Moved " . scalar(@torofs1) . " entries to ROFS1") if @torofs1;
dprint(3, "Changed $udebcnt components to UDEB") if $udebcnt;
dprint(3, "Changed $urelcnt components to UREL") if $urelcnt;
dprint(3, "Finding ROM-patched components");
foreach (sort({$a <=> $b} values(%patchdata))) {
${$obydata}[$_] =~ /^(?:$gHandlestr )?(.+)$/;
parse_keyline($1);
dprint(2, "`$gSource'");
}
dprint(3, "Found " . keys(%patchdata) . " ROM-patched components");
splice(@$obydata, $rofs1ofs, 0, @torofs1) if @torofs1;
plugin_end();
}
sub obyparse_findincfiles()
{
my ($drive, $indent, $prev, $tmpoby, %files) =
(Cwd::cwd() =~ /^([a-z]:)/i ? $1 : "", -2, "", "$gWorkdir/tmp1.oby", ());
dprint(3, "Finding include hierarchy from `$tmpoby'");
open(FILE, $tmpoby) or dprint(-3, "$gPluginname can't open `$tmpoby'"), return;
while (my $line = <FILE>) {
next if ($line !~ /^#\s+\d+\s+"(.+?)"(?:\s+(\d))?$/);
my ($file, $flag) = ($1, defined($2) ? $2 : 0);
next if ($file =~ /^<.*>$/);
$indent -= 2, $prev = $file, next if ($flag == 2);
next if (!$flag && $file eq $prev || $flag > 1);
$indent += 2 if $flag;
($prev = $file) =~ /^(.*[\/\\])?(.+?)$/;
(my $dir, $file) = ("", $2);
$dir = abspath(defined($1) ? $1 : ".");
dprint(2, ("." x $indent) . "`$prev' !!!"), next if ($dir eq "");
$dir =~ s/^$drive|\/$//gi;
$files{lc($file = "$dir/$file")} = 1;
dprint(2, ("." x $indent) . "`$file'");
}
close(FILE);
dprint(3, "Found " . keys(%files) . " different include files");
}
sub obyparse_findspifiles()
{
my ($spicnt, $tmpoby) = (0, "$gWorkdir/tmp5.oby");
dprint(3, "Finding SPI input files from `$tmpoby'");
open(FILE, $tmpoby) or dprint(-3, "$gPluginname can't open `$tmpoby'"), return;
while (my $line = <FILE>) {
next if (parse_obyline($line) != 2) || ($gKeyword !~ /^spidata/i);
$spicnt++;
dprint(2, "`$gSource'" . ($gKeyword =~ /^spidata$/i ? "" : " ($gKeyword)"));
}
close(FILE);
dprint(3, "Found $spicnt SPI input files");
}
sub obyparse_readconffile($$$$$)
{
my ($basedir, $file, $type, $files, $indent) = @_;
$file = "$basedir$file";
my $filecnt = 0;
dprint(3, "Reading $type files from $file") if $type;
dprint(2, ("." x $indent) . "`$file'");
open(FILE, $file) or dprint(3, "Error: $gPluginname can't open $file", 1), die("\n");
my @files = <FILE>;
close(FILE);
foreach (@files) {
if (/^\s*#include\s+(.+?)\s*$/i) {
$filecnt += obyparse_readconffile($basedir, $1, "", $files, $indent + 2);
next;
}
next if (/^\s*$/) || (/^\s*(?:#|\/\/|REM\s)/i);
$filecnt++;
(my $fname = $_) =~ s/^\s+|\s+$//g;
$fname =~ s/(.)/{"*" => ".*", "?" => "."}->{$1} || "\Q$1\E"/eg;
$$files .= ($$files eq "" ? "" : "|") . $fname;
}
return($filecnt);
}
1;
__END__ # OF OBYPARSE.PM