imgtools/imaker/buildrom_plugins/obyparse.pm
changeset 596 9f25be3da657
parent 584 56dd7656a965
equal deleted inserted replaced
595:997c19261166 596:9f25be3da657
    31     $VERSION = 1.00;
    31     $VERSION = 1.00;
    32     @ISA     = qw(Exporter);
    32     @ISA     = qw(Exporter);
    33     @EXPORT  = qw(&obyparse_info &obyparse_init &obyparse_process);
    33     @EXPORT  = qw(&obyparse_info &obyparse_init &obyparse_process);
    34 }
    34 }
    35 
    35 
    36 my $conf = "";
    36 my $conf;
    37 
    37 
    38 sub obyparse_info()
    38 sub obyparse_info()
    39 {
    39 {
    40     return({
    40     return({
    41         name       => "obyparse",
    41         name       => "obyparse",
    42         invocation => "InvocationPoint2",
    42         invocation => "InvocationPoint2",  # tmp6.oby
    43         initialize => "obyparse::obyparse_init",
    43         initialize => "obyparse::obyparse_init",
    44         single     => "obyparse::obyparse_process"});
    44         single     => "obyparse::obyparse_process"});
    45 }
    45 }
    46 
    46 
    47 sub obyparse_init($)
    47 sub obyparse_init($)
    48 {
    48 {
    49     plugin_init("obyparse.pm", $conf = shift());
    49     plugin_init(&obyparse_info, $conf = shift(), 0);
    50 }
    50 }
    51 
    51 
    52 sub obyparse_readconffile($$$$$);
    52 sub obyparse_readconffile($$$$$);
    53 
    53 sub obyparse_findincfiles();
       
    54 sub obyparse_findspifiles();
    54 
    55 
    55 sub obyparse_process($)
    56 sub obyparse_process($)
    56 {
    57 {
    57     plugin_start("obyparse.pm", $conf);
    58     plugin_start(&obyparse_info, $conf);
    58 
    59 
    59     my $obydata = shift();
    60     my ($obydata, $romfiles, $rofs1files, $udebfiles, $urelfiles, $fname) = (shift(), undef, undef, "", "", "");
    60     my %targets = ();
    61     my %targets = my %patchdata = ();
    61     my %patchdata = ();
    62 
    62     my ($romfiles, $rofs1files, $udebfiles, $urelfiles) = (undef, undef, "", "");
    63     obyparse_findincfiles();
    63     my $fname = "";
    64     obyparse_findspifiles();
       
    65     plugin_reset();
    64 
    66 
    65     foreach (@$obydata)
    67     foreach (@$obydata)
    66     {
    68     {
    67         next if (my $parse = parse_obyline($_)) < 0;
    69         next if !(my $parse = parse_obyline($_));
    68 
    70 
    69         if (($parse == 1) && ($gKeyword =~ FILEBITMAPSPECKEYWORD)) {
    71         if (($parse == 2) && ($gKeyword =~ FILEBITMAPSPECKEYWORD)) {
    70             ($fname = lc($gTarget)) =~ /^(?:.*\\)?(.+?)$/;
    72             $targets{$gTgtCmp} = $targets{File::Basename::basename($gTgtCmp)} = [$gLnum - 1,
    71             my $tname = $1;
    73                 !$gRomid && ($gKeyword =~ ROFSBITMAPFILESPECKEYWORD) && ($gAttrib !~ /paging_unmovable/i)]
    72             $targets{$fname} = $targets{$tname} = [$gLnum - 1, !$gRomid && ($gKeyword =~ ROFSBITMAPFILESPECKEYWORD)];
    74                     if ($gImgid == $gRomidCmp);
       
    75             dprint(2, "Removed attribute paging_unmovable: `$_'")
       
    76                 if ($gAttrib =~ /paging_unmovable/i) && (s/\s+paging_unmovable\s*(?=\s|^)//i);
    73             next;
    77             next;
    74         }
    78         }
    75 
    79 
    76         next if !/^\s*OBYPARSE_(ROM|ROFS1|UDEB|UREL)\s+(.+?)\s*$/i;
    80         next if !/^\s*OBYPARSE_(ROM|ROFS1|UDEB|UREL)\s+(.+?)\s*$/i;
    77 
    81 
    78         (my $rule, $fname) = (uc($1), $2);
    82         (my $rule, $fname) = (uc($1), $2);
       
    83         $_ = "$gHandlestr $_";
       
    84         next if $gRomid && ($gImgid != $gRomidCmp);
       
    85 
       
    86         dprint(2, "#$gLnum: `$gLine'");
    79         my $files = ($rule eq "ROM" ? \$romfiles : ($rule eq "ROFS1" ? \$rofs1files :
    87         my $files = ($rule eq "ROM" ? \$romfiles : ($rule eq "ROFS1" ? \$rofs1files :
    80             ($rule eq "UDEB" ? \$udebfiles : \$urelfiles)));
    88             ($rule eq "UDEB" ? \$udebfiles : \$urelfiles)));
    81         $$files = "" if !defined($$files);
    89         $$files = "" if !defined($$files);
    82         dprint(2, "#$gLnum: `$gLine'");
       
    83 
    90 
    84         if ($fname ne "*") {
    91         if ($fname ne "*") {
    85             my $basedir = "";
    92             my $basedir = "";
    86             ($basedir, $fname) = ($1, $2) if $fname =~ /^(.*[\/\\])(.+?)$/;
    93             ($basedir, $fname) = ($1, $2) if $fname =~ /^(.*[\/\\])(.+?)$/;
    87             dprint(3, "Found " . obyparse_readconffile($basedir, $fname, $rule, $files, 0) . " entries");
    94             dprint(3, "Found " . obyparse_readconffile($basedir, $fname, $rule, $files, 0) . " entries");
    88         }
    95         } else {
    89         else {
    96             dprint(3, "Move/change all possible components to $rule");
    90             $$files = ".*";
    97             $$files = ".*";
    91             dprint(3, "Move/change all possible components to $rule");
    98         }
    92         }
       
    93         $_ = "$gHandlestr $_";
       
    94     }
    99     }
    95 
   100 
    96     $romfiles   = qr/^($romfiles)$/i   if defined($romfiles);
   101     $romfiles   = qr/^($romfiles)$/i   if defined($romfiles);
    97     $rofs1files = qr/^($rofs1files)$/i if defined($rofs1files);
   102     $rofs1files = qr/^($rofs1files)$/i if defined($rofs1files);
    98     ($udebfiles, $urelfiles) = (qr/^($udebfiles)$/i, qr/^($urelfiles)$/i);
   103     ($udebfiles, $urelfiles) = (qr/^($udebfiles)$/i, qr/^($urelfiles)$/i);
    99 
   104 
   100     ($gLnum, $gRomid) = (0, 0);
   105     my ($rofs1ofs, $udebcnt, $urelcnt, @torofs1) = (0, 0, 0, ());
   101     my ($rofs1cnt, $udebcnt, $urelcnt, $offset, @torofs1) = (0, 0, 0, 0, ());
   106     plugin_reset();
   102 
   107 
   103     foreach (@$obydata)
   108     foreach (@$obydata)
   104     {
   109     {
   105         my $parse = parse_obyline($_);
   110         my $parse = parse_obyline($_);
   106         $offset++ if $gRomid < 2;
   111         $rofs1ofs++ if ($gRomid < 2);
   107         next if $parse != 1;
   112         next if ($parse != 2) || ($gImgid != $gRomidCmp);
   108 
   113 
   109         if ($gKeyword =~ /^patchdata$/i) {
   114         if ($gKeyword =~ /^patchdata$/i) {
   110             $gSource =~ /^(.+?)(?:@.+)?$/;
   115             $gSrcCmp =~ /^(.+?)(?:@.+)?$/;
   111             $fname = lc($1);
   116             next if !exists($targets{$fname = $1});
   112             $patchdata{$fname} = $targets{$fname}[0] if !exists($patchdata{$fname});
   117             $patchdata{$fname} = $targets{$fname}[0] if !exists($patchdata{$fname});
   113         }
   118             next if !$targets{$fname}[1];
   114         else {
   119         }
   115             $gTarget =~ /^(?:.*\\)?(.+?)$/;
   120         elsif ($gKeyword =~ FILEBITMAPSPECKEYWORD) {
   116             $fname = $1;
   121             $fname = File::Basename::basename($gTgtCmp);
   117             if ($fname =~ $urelfiles && s/(?<=[\/\\])udeb(?=[\/\\])/urel/i) {
   122             if ($fname =~ $urelfiles && s/(?<=[\/\\])udeb(?=[\/\\])/urel/i) {
   118                 $urelcnt++;
   123                 $urelcnt++;
   119                 dprint(2, "Changed to UREL: `$_'");
   124                 dprint(2, "Changed to UREL: `$_'");
   120             }
   125             }
   121             elsif ($fname =~ $udebfiles && s/(?<=[\/\\])urel(?=[\/\\])/udeb/i) {
   126             elsif ($fname =~ $udebfiles && s/(?<=[\/\\])urel(?=[\/\\])/udeb/i) {
   122                 $udebcnt++;
   127                 $udebcnt++;
   123                 dprint(2, "Changed to UDEB: `$_'");
   128                 dprint(2, "Changed to UDEB: `$_'");
   124             }
   129             }
   125         }
   130             next if !$targets{$gTgtCmp}[1];
   126 
   131         }
   127         next if $gRomid || !defined($romfiles) && !defined($rofs1files);
   132         elsif ($gKeyword =~ DIRECTORYKEYWORD) {
   128 
   133             $fname = File::Basename::basename($gTgtCmp);
   129         if (($gKeyword =~ ROFSBITMAPFILESPECKEYWORD) ||
   134             next if !(exists($targets{$gTgtCmp}) && $targets{$gTgtCmp}[1]) &&
   130             ($gKeyword =~ /^patchdata$/i) && exists($targets{$fname}) && $targets{$fname}[1]) {
   135                 !(exists($targets{$fname}) && $targets{$fname}[1]);
   131         }
   136         }
   132         elsif ($gKeyword =~ /^(?:alias|rename)/i && exists($targets{lc($gSource)}) && $targets{lc($gSource)}[1]) {
   137         else { next }
   133             $gSource =~ /^(?:.*\\)?(.+?)$/;
   138 
   134             $fname = $1;
   139         if (!$gRomid && (defined($rofs1files) && ($fname =~ $rofs1files) || defined($romfiles) && ($fname !~ $romfiles))) {
   135         }
       
   136         else {
       
   137             next;
       
   138         }
       
   139         if (defined($rofs1files) && ($fname =~ $rofs1files) || defined($romfiles) && ($fname !~ $romfiles)) {
       
   140             $rofs1cnt++;
       
   141             push(@torofs1, $_);
   140             push(@torofs1, $_);
   142             $_ = "$gHandlestr =>ROFS1 $_";
   141             $_ = "$gHandlestr $_";
   143         }
   142         }
   144     }
   143     }
   145 
   144 
   146     dprint(3, "Moved $rofs1cnt entries to ROFS1")    if $rofs1cnt;
   145     dprint(3, "Moved " . scalar(@torofs1) . " entries to ROFS1") if @torofs1;
   147     dprint(3, "Changed $udebcnt components to UDEB") if $udebcnt;
   146     dprint(3, "Changed $udebcnt components to UDEB") if $udebcnt;
   148     dprint(3, "Changed $urelcnt components to UREL") if $urelcnt;
   147     dprint(3, "Changed $urelcnt components to UREL") if $urelcnt;
   149 
   148 
   150     dprint(2, "Found " . keys(%patchdata) . " ROM-patched components:") if %patchdata;
   149     dprint(3, "Finding ROM-patched components");
   151     foreach (sort({$a <=> $b} values(%patchdata))) {
   150     foreach (sort({$a <=> $b} values(%patchdata))) {
   152         ${$obydata}[$_] =~ /^(?:$gHandlestr =>ROFS1 )?(.+)$/;
   151         ${$obydata}[$_] =~ /^(?:$gHandlestr )?(.+)$/;
   153         parse_keyline($1);
   152         parse_keyline($1);
   154         dprint(2, "`$gSource'");
   153         dprint(2, "`$gSource'");
   155     }
   154     }
   156 
   155     dprint(3, "Found " . keys(%patchdata) . " ROM-patched components");
   157     splice(@$obydata, $offset, 0, @torofs1) if @torofs1;
   156 
       
   157     splice(@$obydata, $rofs1ofs, 0, @torofs1) if @torofs1;
   158 
   158 
   159     plugin_end();
   159     plugin_end();
   160 }
   160 }
   161 
   161 
       
   162 sub obyparse_findincfiles()
       
   163 {
       
   164     my ($drive, $indent, $prev, $tmpoby, %files) =
       
   165         (Cwd::cwd() =~ /^([a-z]:)/i ? $1 : "", -2, "", "$gWorkdir/tmp1.oby", ());
       
   166 
       
   167     dprint(3, "Finding include hierarchy from `$tmpoby'");
       
   168     open(FILE, $tmpoby) or dprint(-3, "$gPluginname can't open `$tmpoby'"), return;
       
   169 
       
   170     while (my $line = <FILE>) {
       
   171         next if ($line !~ /^#\s+\d+\s+"(.+?)"(?:\s+(\d))?$/);
       
   172         my ($file, $flag) = ($1, defined($2) ? $2 : 0);
       
   173         next if ($file =~ /^<.*>$/);
       
   174         $indent -= 2, $prev = $file, next if ($flag == 2);
       
   175         next if (!$flag && $file eq $prev || $flag > 1);
       
   176         $indent += 2 if $flag;
       
   177         ($prev = $file) =~ /^(.*[\/\\])?(.+?)$/;
       
   178         (my $dir, $file) = ("", $2);
       
   179         $dir = abspath(defined($1) ? $1 : ".");
       
   180         dprint(2, ("." x $indent) . "`$prev' !!!"), next if ($dir eq "");
       
   181         $dir =~ s/^$drive|\/$//gi;
       
   182         $files{lc($file = "$dir/$file")} = 1;
       
   183         dprint(2, ("." x $indent) . "`$file'");
       
   184     }
       
   185     close(FILE);
       
   186     dprint(3, "Found " . keys(%files) . " different include files");
       
   187 }
       
   188 
       
   189 sub obyparse_findspifiles()
       
   190 {
       
   191     my ($spicnt, $tmpoby) = (0, "$gWorkdir/tmp5.oby");
       
   192 
       
   193     dprint(3, "Finding SPI input files from `$tmpoby'");
       
   194     open(FILE, $tmpoby) or dprint(-3, "$gPluginname can't open `$tmpoby'"), return;
       
   195 
       
   196     while (my $line = <FILE>) {
       
   197         next if (parse_obyline($line) != 2) || ($gKeyword !~ /^spidata/i);
       
   198         $spicnt++;
       
   199         dprint(2, "`$gSource'" . ($gKeyword =~ /^spidata$/i ? "" : " ($gKeyword)"));
       
   200     }
       
   201     close(FILE);
       
   202     dprint(3, "Found $spicnt SPI input files");
       
   203 }
   162 
   204 
   163 sub obyparse_readconffile($$$$$)
   205 sub obyparse_readconffile($$$$$)
   164 {
   206 {
   165     my ($basedir, $file, $type, $files, $indent) = @_;
   207     my ($basedir, $file, $type, $files, $indent) = @_;
   166     $file = $basedir . $file;
   208     $file = "$basedir$file";
   167     my $filecnt = 0;
   209     my $filecnt = 0;
   168 
   210 
   169     dprint(3, "Reading $type files") if $type;
   211     dprint(3, "Reading $type files from $file") if $type;
   170     dprint(3, ("." x $indent) . "`$file'");
   212     dprint(2, ("." x $indent) . "`$file'");
   171 
   213 
   172     open(FILE, $file) or die("ERROR: Can't open `$file'\n");
   214     open(FILE, $file) or dprint(3, "Error: $gPluginname can't open $file", 1), die("\n");
   173 
   215     my @files = <FILE>;
   174     foreach my $line (<FILE>) {
   216     close(FILE);
   175         if ($line =~ /^\s*#include\s+(.+?)\s*$/i) {
   217 
       
   218     foreach (@files) {
       
   219         if (/^\s*#include\s+(.+?)\s*$/i) {
   176             $filecnt += obyparse_readconffile($basedir, $1, "", $files, $indent + 2);
   220             $filecnt += obyparse_readconffile($basedir, $1, "", $files, $indent + 2);
   177             next;
   221             next;
   178         }
   222         }
   179         next if ($line =~ /^\s*$/) || ($line =~ /^\s*(?:#|\/\/|REM\s)/i);
   223         next if (/^\s*$/) || (/^\s*(?:#|\/\/|REM\s)/i);
   180         $filecnt++;
   224         $filecnt++;
   181         (my $fname = $line) =~ s/^\s+|\s+$//g;
   225         (my $fname = $_) =~ s/^\s+|\s+$//g;
   182         $fname =~ s/(.)/{'*' => '.*', '?' => '.', '[' => '[', ']' => ']'}->{$1} || "\Q$1\E"/ge;
   226         $fname =~ s/(.)/{"*" => ".*", "?" => "."}->{$1} || "\Q$1\E"/eg;
   183         $$files .= ($$files eq "" ? "" : "|") . $fname;
   227         $$files .= ($$files eq "" ? "" : "|") . $fname;
   184     }
   228     }
   185     close(FILE);
       
   186     return($filecnt);
   229     return($filecnt);
   187 }
   230 }
   188 
   231 
   189 1;
   232 1;
   190 
   233