68 $VERSION = 1.00; |
69 $VERSION = 1.00; |
69 @ISA = qw(Exporter); |
70 @ISA = qw(Exporter); |
70 @EXPORT = qw(&override_info &override_init &override_process); |
71 @EXPORT = qw(&override_info &override_init &override_process); |
71 } |
72 } |
72 |
73 |
73 my $conf = ""; |
74 my $conf; |
74 |
75 |
75 sub override_info |
76 sub override_info |
76 { |
77 { |
77 return({ |
78 return({ |
78 name => "override", |
79 name => "override", |
79 invocation => "InvocationPoint2", |
80 invocation => "InvocationPoint2", # tmp6.oby |
80 initialize => "override::override_init", |
81 initialize => "override::override_init", |
81 single => "override::override_process"}); |
82 single => "override::override_process"}); |
82 } |
83 } |
83 |
84 |
84 sub override_init |
85 sub override_init |
85 { |
86 { |
86 plugin_init("override.pm", $conf = shift()); |
87 plugin_init(&override_info, $conf = shift(), 0); |
87 } |
88 } |
88 |
89 |
89 sub override_process |
90 sub override_process |
90 { |
91 { |
91 plugin_start("override.pm", $conf); |
92 plugin_start(&override_info, $conf); |
92 |
93 |
93 my $obydata = shift(); |
94 my $obydata = shift(); |
94 my %targets = (); |
95 my %targets = (); |
95 my @overrides = (); |
96 my @overrides = (); |
96 my @oconfstack = (REPLACE_WARN); |
97 my @oconfstack = (REPLACE_WARN); |
97 my @romelemcnt = (0, 0, 0, 0, 0, 0, 0, 0); |
|
98 |
98 |
99 # Go through all the tmp6.oby (InvocationPoint2) lines and store |
99 # Go through all the tmp6.oby (InvocationPoint2) lines and store |
100 # normal targets' data to %targets and override targets' data to @overrides |
100 # normal targets' data to %targets and override targets' data to @overrides |
101 |
101 |
102 dprint(2, "Finding overrides..."); |
102 dprint(2, "Finding overrides..."); |
103 |
103 |
104 foreach (@{$obydata}) |
104 foreach (@{$obydata}) |
105 { |
105 { |
106 my $parse = parse_obyline($_); |
106 next if !(my $parse = parse_obyline($_)); |
107 |
107 |
108 if ($parse == 2) { |
108 if (($parse == 2) && ($gKeyword =~ /-?override$/i)) { |
109 # REM ROM_IMAGE[id] |
109 # Override entry |
|
110 $_ = "$gHandlestr $_", next if ($gImgid != $gRomidCmp); |
110 dprint(2, "#$gLnum: `$gLine'"); |
111 dprint(2, "#$gLnum: `$gLine'"); |
|
112 push(@overrides, [$gLnum - 1, $oconfstack[$#oconfstack]]); |
|
113 next; |
111 } |
114 } |
112 elsif (/^\s*OVERRIDE_(?:(END)|(REPLACE\/ADD)|(REPLACE\/SKIP)|(REPLACE\/WARN)|SKIP\/ADD)\s*$/i) { |
115 if (($parse == 2) && ($gKeyword =~ FILEBITMAPSPECKEYWORD)) { |
113 # Override configuration keyword |
116 # Normal file specification entry |
114 if (defined($1)) { |
117 $targets{$gTgtCmp} = $targets{File::Basename::basename($gTgtCmp)} = $gLnum - 1 |
115 # OVERRIDE_END |
118 if ($gImgid == $gRomidCmp); |
116 pop(@oconfstack); |
119 next; |
117 } else { |
|
118 # OVERRIDE_REPLACE/ADD|REPLACE/SKIP|REPLACE/WARN|SKIP/ADD |
|
119 push(@oconfstack, defined($2) ? REPLACE_ADD : (defined($3) ? REPLACE_SKIP : (defined($4) ? REPLACE_WARN : SKIP_ADD))); |
|
120 } |
|
121 dprint(2, "#$gLnum: `$gLine'"); |
|
122 $_ = "$gHandlestr $gLine"; |
|
123 } |
120 } |
124 elsif ($parse == 1 && $gKeyword =~ /-override/i) { |
121 |
125 # Override entry |
122 next if !/^\s*OVERRIDE_(?:(END)|(REPLACE\/ADD)|(REPLACE\/SKIP)|(REPLACE\/WARN)|SKIP\/ADD)\s*$/i; |
126 dprint(2, "#$gLnum: `$gLine'"); |
123 |
127 push(@overrides, [$gLnum - 1, $gRomid, $oconfstack[$#oconfstack]]); |
124 # Override configuration keyword |
|
125 $_ = "$gHandlestr $_"; |
|
126 next if $gRomid && ($gImgid != $gRomidCmp); |
|
127 if (defined($1)) { |
|
128 # OVERRIDE_END |
|
129 pop(@oconfstack); |
|
130 } else { |
|
131 # OVERRIDE_REPLACE/ADD|REPLACE/SKIP|REPLACE/WARN|SKIP/ADD |
|
132 push(@oconfstack, defined($2) ? REPLACE_ADD : (defined($3) ? REPLACE_SKIP : (defined($4) ? REPLACE_WARN : SKIP_ADD))); |
128 } |
133 } |
129 elsif ($parse == 1 && $gKeyword =~ FILESPECKEYWORD) { |
134 dprint(2, "#$gLnum: `$gLine'"); |
130 # Normal file specification entry |
|
131 $targets{lc("$gTarget/$gRomid")} = $gLnum - 1; |
|
132 $romelemcnt[$gRomid]++; |
|
133 } |
|
134 } |
135 } |
135 |
136 |
136 # Loop through all overrides and handle them |
137 # Loop through all overrides and handle them |
137 dprint(3, @overrides ? "Handling overrides..." : "No override entries found"); |
138 dprint(3, @overrides ? "Handling overrides..." : "No override entries found"); |
138 |
139 |
139 foreach (@overrides) |
140 foreach (@overrides) |
140 { |
141 { |
141 my ($lnum, $romid, $type) = @{$_}; |
142 my ($tlnum, $olnum, $type) = (0, @$_); |
142 parse_keyline(${$obydata}[$lnum], 1); |
143 parse_keyline(${$obydata}[$olnum]); |
143 dprint(2, "Handling : `$gLine' ($romid, " . ("REPLACE/ADD", "REPLACE/SKIP", "REPLACE/WARN", "SKIP/ADD")[$type] . ")"); |
144 dprint(2, "Handling : `$gLine' (" . ("REPLACE/ADD", "REPLACE/SKIP", "REPLACE/WARN", "SKIP/ADD")[$type] . ")"); |
144 ${$obydata}[$lnum] = "$gHandlestr $gLine"; |
145 ${$obydata}[$olnum] = "$gHandlestr ${$obydata}[$olnum]"; |
145 (my $target = $gTarget) =~ s/^"(.*)"$/$1/; |
|
146 |
146 |
147 if (exists($targets{lc("$target/$romid")})) { |
147 if (defined($tlnum = $targets{$gTgtCmp}) || defined($tlnum = $targets{File::Basename::basename($gTgtCmp)})) { |
148 # Override target found |
148 # Override target found |
149 |
|
150 my ($line, $keyword, $source, $attrib) = ($gLine, $gKeyword, $gSource, $gAttrib); |
149 my ($line, $keyword, $source, $attrib) = ($gLine, $gKeyword, $gSource, $gAttrib); |
151 parse_keyline(${$obydata}[$lnum = $targets{lc("$target/$romid")}], 1); |
150 parse_keyline(${$obydata}[$tlnum]); |
152 dprint(2, "Target : `$gLine' ($romid, #" . ($lnum + 1) . ")"); |
151 dprint(2, "Target : `$gLine' (#" . ($tlnum + 1) . ")"); |
153 |
152 |
154 if ($type == SKIP_ADD) { |
153 if ($type == SKIP_ADD) { |
155 dprint(2, "Do nothing : Target found and override type SKIP"); |
154 dprint(2, "Do nothing : Target found and override type SKIP"); |
156 } |
155 } |
157 elsif ($source =~ /^"?empty"?$/i) { |
156 elsif ($source =~ /^empty$/i) { |
158 # Empty keyword -> comment line out |
157 # Empty keyword -> comment line out |
159 ${$obydata}[$lnum] = "$gHandlestr $gLine"; |
158 ${$obydata}[$tlnum] = "$gHandlestr ${$obydata}[$tlnum]"; |
160 dprint(1, "Remove ROM_IMAGE[$romid] `$gLine' due to `$line'"); |
159 dprint(1, "Remove `$gLine' due to `$line'"); |
161 dprint(2, "Replace with: `${$obydata}[$lnum]' (Override source EMPTY)"); |
160 dprint(2, "Replace with: `${$obydata}[$tlnum]' (Override source EMPTY)"); |
162 } |
161 } |
163 else { |
162 else { |
164 # Replace existing line with new line |
163 # Replace existing line with new line |
165 $keyword =~ s/-override//i; |
164 $keyword =~ s/-?override$//i; |
166 $attrib = ($attrib eq "" ? $gAttrib : ($attrib =~ /^\s*empty$/i ? "" : $attrib)); |
165 $attrib = ($attrib eq "" ? $gAttrib : ($attrib =~ /^\s*empty$/i ? "" : $attrib)); |
167 $line = ${$obydata}[$lnum] = "$keyword=$source $gTarget$attrib\n"; |
166 $line = ${$obydata}[$tlnum] = ($keyword ne "" ? $keyword : $gKeyword) . |
168 dprint(1, "Replace ROM_IMAGE[$romid] `$gLine' with `$line'"); |
167 ($source =~ /\s/ ? "=\"$source\"" : "=$source") . " " . |
|
168 ($gTarget =~ /\s/ ? "\"$gTarget\"" : $gTarget) . "$attrib\n"; |
|
169 dprint(1, "Replace `$gLine' with `$line'"); |
169 dprint(2, "Replace with: `$line'"); |
170 dprint(2, "Replace with: `$line'"); |
170 } |
171 } |
171 } |
172 } |
172 else { |
173 else { # Override target not found |
173 # Override target not found |
|
174 |
|
175 if (!$romelemcnt[$romid] && $type != REPLACE_ADD && $type != SKIP_ADD) { |
|
176 # Ignore override non-XXX/ADD targets on empty ROM_IMAGE sections |
|
177 dprint(2, "Do nothing : Target not found, override target's ROM_IMAGE[$romid] section is empty"); |
|
178 next; |
|
179 } |
|
180 # Check if override target exists in different ROM section |
|
181 my $warn = ""; |
|
182 foreach my $tromid (0 .. 7) { |
|
183 $warn = "Override target `$target' found from ROM_IMAGE[$tromid] while override is for ROM_IMAGE[$romid]", last |
|
184 if exists($targets{lc("$target/$tromid")}); |
|
185 } |
|
186 if ($type == REPLACE_SKIP) { |
174 if ($type == REPLACE_SKIP) { |
187 dprint(2, "Do nothing : Target not found " . ($warn ? "from ROM_IMAGE[$romid] " : "") . "and override type SKIP"); |
175 dprint(2, "Do nothing : Target not found and override type SKIP"); |
188 } |
176 } |
189 elsif ($type == REPLACE_WARN) { |
177 elsif ($type == REPLACE_WARN) { |
190 dprint(-3, $warn ? "$warn, ignoring `$target'" : "Ignoring override target `$target', target not found"); |
178 dprint(-3, "Ignoring override target `$gTarget', target not found"); |
191 dprint(2, "Do nothing : Target not found and override type WARN"); |
179 dprint(2, "Do nothing : Target not found and override type WARN"); |
192 } |
180 } |
193 else { |
181 else { |
194 # OVERRIDE_XXX/ADD |
182 # OVERRIDE_XXX/ADD |
195 (my $line = $gLine) =~ s/^(\S+?)-override/$1/i; |
183 (my $line = $gLine) =~ s/^(\S*?)-?override/$1/i; |
196 ${$obydata}[$lnum] = $line; |
184 $line = ${$obydata}[$olnum] = ($1 ne "" ? "" : "data") . $line; |
197 dprint(-3, $warn) if $warn; |
185 dprint(1, "Add `$line' from `$gLine'"); |
198 dprint(1, "Add ROM_IMAGE[$romid] `$line' from `$gLine'"); |
|
199 dprint(2, "Add new : `$line' (Target not found, override type ADD)"); |
186 dprint(2, "Add new : `$line' (Target not found, override type ADD)"); |
200 } |
187 } |
201 } |
188 } |
202 } |
189 } |
203 plugin_end(); |
190 plugin_end(); |