3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 package org
.tianocore
.migration
;
17 import java
.util
.regex
.Matcher
;
18 import java
.util
.regex
.Pattern
;
20 import org
.tianocore
.UsageTypes
;
22 public final class SourceFileReplacer
implements Common
.ForDoAll
{
23 private static final SourceFileReplacer SFReplacer
= new SourceFileReplacer();
24 private ModuleInfo mi
;
25 private static final Set
<Common
.Laplace
> Laplaces
= new HashSet
<Common
.Laplace
>();
27 // these sets are used only for printing log of the changes in current file
28 private static final Set
<r8tor9
> filefunc
= new HashSet
<r8tor9
>();
29 private static final Set
<r8tor9
> filemacro
= new HashSet
<r8tor9
>();
30 private static final Set
<r8tor9
> fileguid
= new HashSet
<r8tor9
>();
31 private static final Set
<r8tor9
> fileppi
= new HashSet
<r8tor9
>();
32 private static final Set
<r8tor9
> fileprotocol
= new HashSet
<r8tor9
>();
33 private static final Set
<String
> filer8only
= new HashSet
<String
>();
35 private static final String
[] specialhoblibfunc
= {
37 "BuildResourceDescriptorHob",
43 "BuildMemoryAllocationHob"
45 private static final String
[] peiserviceslibfunc
= {
62 //---------------------------------------inner classes---------------------------------------//
63 private static class r8tor9
{
64 r8tor9(String r8
, String r9
) {
68 public String r8thing
;
69 public String r9thing
;
72 private class IdleLaplace
extends Common
.Laplace
{
73 public String
operation(String wholeline
) {
74 return replaceLibrary (wholeline
, mi
.hashmacro
);
77 public boolean recognize(String filename
) {
78 return filename
.contains(".h") || filename
.contains(".H") || filename
.contains(".uni") ||
79 filename
.contains(".s") || filename
.contains(".S") || filename
.contains(".asm") ||
80 (!filename
.contains(".inf") && filename
.contains(".i"));
83 public String
namechange(String oldname
) {
84 if (oldname
.contains(".H")) {
85 return oldname
.replaceFirst(".H", ".h");
91 private class DxsLaplace
extends Common
.Laplace
{
92 public String
operation(String wholeline
) {
93 wholeline
= replaceMacro(wholeline
, mi
.hashnonlocalmacro
);
94 if (mi
.getModuleType().equals("PEIM")) {
95 return addincludefile(wholeline
, "\\<PeimDepex.h\\>");
97 return addincludefile(wholeline
, "\\<DxeDepex.h\\>");
101 public boolean recognize(String filename
) {
102 return filename
.contains(".dxs");
105 public String
namechange(String oldname
) {
110 private class CLaplace
extends Common
.Laplace
{
111 public String
operation(String wholeline
) {
112 // remove EFI_DRIVER_ENTRY_POINT
113 wholeline
= wholeline
.replaceAll("(EFI_[A-Z]+_ENTRY_POINT\\s*\\(\\s*\\w(\\w|\\d)*\\s*\\))", MigrationTool
.MIGRATIONCOMMENT
+ " $1");
114 // redefine module entry point for some self-relocated modules
115 wholeline
= wholeline
.replaceAll (mi
.entrypoint
+ "([^{]*?})", "_ModuleEntryPoint" + "$1");
116 // remove R8 library contractor
117 wholeline
= wholeline
.replaceAll ("(\\b(?:Efi|Dxe)InitializeDriverLib\\b)", MigrationTool
.MIGRATIONCOMMENT
+ " $1");
118 // Add Library Class for potential reference of gBS, gRT & gDS.
119 if (Common
.find (wholeline
, "\\bg?BS\\b")) {
120 mi
.hashrequiredr9libs
.add("UefiBootServicesTableLib");
122 if (Common
.find (wholeline
, "\\bg?RT\\b")) {
123 mi
.hashrequiredr9libs
.add ("UefiRuntimeServicesTableLib");
125 if (Common
.find (wholeline
, "\\bgDS\\b")) {
126 mi
.hashrequiredr9libs
.add ("DxeServicesTableLib");
129 wholeline
= replaceLibrary (wholeline
, mi
.hashnonlocalfunc
);
130 wholeline
= replaceLibrary (wholeline
, mi
.hashmacro
);
132 wholeline
= replaceMacro (wholeline
, mi
.hashnonlocalmacro
);
135 replaceGuid(wholeline
, mi
.guids
, "guid", fileguid
);
136 replaceGuid(wholeline
, mi
.ppis
, "ppi", fileppi
);
137 replaceGuid(wholeline
, mi
.protocols
, "protocol", fileprotocol
);
140 if (mi
.getModuleType().matches("PEIM")) {
142 // Try to remove PeiServicesTablePointer;
144 wholeline
= dropPeiServicesPointer (wholeline
);
146 // Drop the possible return Status of Hob building function.
148 wholeline
= drophobLibReturnStatus (wholeline
);
151 // Expand obsolete R8 macro.
153 wholeline
= replaceObsoleteMacro (wholeline
);
155 show(filefunc
, "function");
156 show(filemacro
, "macro");
157 show(fileguid
, "guid");
158 show(fileppi
, "ppi");
159 show(fileprotocol
, "protocol");
160 if (!filer8only
.isEmpty()) {
161 MigrationTool
.ui
.println("Converting r8only : " + filer8only
);
168 fileprotocol
.clear();
174 public boolean recognize(String filename
) {
175 return filename
.contains(".c") || filename
.contains(".C");
178 public String
namechange(String oldname
) {
179 if (oldname
.contains(".C")) {
180 return oldname
.replaceFirst(".C", ".c");
186 //---------------------------------------inner classes---------------------------------------//
188 //-------------------------------------process functions-------------------------------------//
189 private static final String
addincludefile(String wholeline
, String hfile
) {
190 return wholeline
.replaceFirst("(\\*/\\s)", "$1\n#include " + hfile
+ "\n");
193 private static final void show(Set
<r8tor9
> hash
, String sh
) {
194 Iterator
<r8tor9
> it
= hash
.iterator();
196 if (!hash
.isEmpty()) {
197 MigrationTool
.ui
.print("Converting " + sh
+ " : ");
198 while (it
.hasNext()) {
200 MigrationTool
.ui
.print("[" + temp
.r8thing
+ "->" + temp
.r9thing
+ "] ");
202 MigrationTool
.ui
.println("");
206 private static final void replaceGuid(String line
, Set
<String
> hash
, String kind
, Set
<r8tor9
> filehash
) {
210 it
= hash
.iterator();
211 while (it
.hasNext()) {
213 if ((r9thing
= MigrationTool
.db
.getR9Guidname(r8thing
)) != null) {
214 if (!r8thing
.equals(r9thing
)) {
215 if (line
.contains(r8thing
)) {
216 line
= line
.replaceAll(r8thing
, r9thing
);
217 filehash
.add(new r8tor9(r8thing
, r9thing
));
224 private final String
dropPeiServicesPointer (String wholeline
) {
225 String peiServicesTablePointer
;
226 String peiServicesTableCaller
;
227 String regPeiServices
;
231 peiServicesTablePointer
= "\\w(?:\\w|[0-9]|->)*";
232 peiServicesTableCaller
= "\\(\\*\\*?\\s*(" + peiServicesTablePointer
+ ")\\s*\\)[.-]>?\\s*";
233 for (int i
= 0; i
< peiserviceslibfunc
.length
; i
++) {
234 regPeiServices
= peiServicesTableCaller
+ peiserviceslibfunc
[i
] + "\\s*\\(\\s*\\1\\s*,(\\t| )*";
235 ptnPei
= Pattern
.compile (regPeiServices
);
236 mtrPei
= ptnPei
.matcher (wholeline
);
238 wholeline
= mtrPei
.replaceAll("PeiServices" + peiserviceslibfunc
[i
] + " (");
239 mi
.hashrequiredr9libs
.add("PeiServicesLib");
242 regPeiServices
= peiServicesTableCaller
+ "(CopyMem|SetMem)" + "\\s*\\((\\t| )*";
243 ptnPei
= Pattern
.compile (regPeiServices
);
244 mtrPei
= ptnPei
.matcher (wholeline
);
246 wholeline
= mtrPei
.replaceAll("$2 (");
247 mi
.hashrequiredr9libs
.add("BaseMemoryLib");
250 ptnPei
= Pattern
.compile("#%+(\\s*\\(+\\s*)" + peiServicesTablePointer
+ "\\s*,\\s*", Pattern
.MULTILINE
);
251 mtrPei
= ptnPei
.matcher(wholeline
);
252 while (mtrPei
.find()) {
253 wholeline
= mtrPei
.replaceAll("$1");
259 private final String
drophobLibReturnStatus (String wholeline
) { // or use regex to find pattern "Status = ..."
260 Pattern ptnhobstatus
;
261 Matcher mtrhobstatus
;
262 String templine
= wholeline
;
263 for (int i
= 0; i
< specialhoblibfunc
.length
; i
++) {
264 ptnhobstatus
= Pattern
.compile("(Status\\s*=\\s*)?" + specialhoblibfunc
[i
] + "(.*?\\)\\s*;)", Pattern
.DOTALL
);
265 mtrhobstatus
= ptnhobstatus
.matcher(templine
);
266 if (mtrhobstatus
.find()) {
267 templine
= mtrhobstatus
.replaceAll(specialhoblibfunc
[i
] + mtrhobstatus
.group(2) + "\n " +
268 MigrationTool
.MIGRATIONCOMMENT
+ "R9 Hob-building library functions will assert if build failure.\n Status = EFI_SUCCESS;");
274 private final String
replaceMacro (String wholeline
, Set
<String
> symbolSet
) {
279 it
= symbolSet
.iterator();
280 while (it
.hasNext()) { //macros are all assumed MdePkg currently
282 //mi.hashrequiredr9libs.add(MigrationTool.db.getR9Lib(r8thing));
283 if ((r9thing
= MigrationTool
.db
.getR9Macro(r8thing
)) != null) {
284 if (wholeline
.contains(r8thing
)) {
285 String findString
= "(?<!(?:\\d|\\w))" + r8thing
+ "(?!(?:\\d|\\w))";
286 wholeline
= wholeline
.replaceAll(findString
, r9thing
);
287 filemacro
.add(new r8tor9(r8thing
, r9thing
));
294 private final String
replaceLibrary (String wholeline
, Set
<String
> symbolSet
) {
295 boolean addr8
= false;
296 // start replacing names
300 // Converting non-locla function
301 it
= symbolSet
.iterator();
302 while (it
.hasNext()) {
304 mi
.addLibraryClass(MigrationTool
.db
.getR9Lib(r8thing
), UsageTypes
.ALWAYS_CONSUMED
);
305 //mi.hashrequiredr9libs.add(MigrationTool.db.getR9Lib(r8thing)); // add a library here
308 if ((r9thing
= MigrationTool
.db
.getR9Func(r8thing
)) != null) {
309 if (!r8thing
.equals(r9thing
)) {
310 if (wholeline
.contains(r8thing
)) {
311 wholeline
= wholeline
.replaceAll(r8thing
, r9thing
);
312 filefunc
.add(new r8tor9(r8thing
, r9thing
));
313 Iterator
<r8tor9
> rt
= filefunc
.iterator();
314 while (rt
.hasNext()) {
316 if (MigrationTool
.db
.r8only
.contains(temp
.r8thing
)) {
317 filer8only
.add(r8thing
);
318 mi
.hashr8only
.add(r8thing
);
325 } //is any of the guids changed?
327 wholeline
= addincludefile(wholeline
, "\"R8Lib.h\"");
332 private final String
replaceObsoleteMacro (String wholeline
) {
334 mtrmac
= Pattern
.compile("EFI_IDIV_ROUND\\((.*), (.*)\\)").matcher(wholeline
);
336 wholeline
= mtrmac
.replaceAll("\\($1 \\/ $2 \\+ \\(\\(\\(2 \\* \\($1 \\% $2\\)\\) \\< $2\\) \\? 0 \\: 1\\)\\)");
338 mtrmac
= Pattern
.compile("EFI_MIN\\((.*), (.*)\\)").matcher(wholeline
);
340 wholeline
= mtrmac
.replaceAll("\\(\\($1 \\< $2\\) \\? $1 \\: $2\\)");
342 mtrmac
= Pattern
.compile("EFI_MAX\\((.*), (.*)\\)").matcher(wholeline
);
344 wholeline
= mtrmac
.replaceAll("\\(\\($1 \\> $2\\) \\? $1 \\: $2\\)");
346 mtrmac
= Pattern
.compile("EFI_UINTN_ALIGNED\\((.*)\\)").matcher(wholeline
);
348 wholeline
= mtrmac
.replaceAll("\\(\\(\\(UINTN\\) $1\\) \\& \\(sizeof \\(UINTN\\) \\- 1\\)\\)");
350 if (wholeline
.contains("EFI_UINTN_ALIGN_MASK")) {
351 wholeline
= wholeline
.replaceAll("EFI_UINTN_ALIGN_MASK", "(sizeof (UINTN) - 1)");
356 private final void addr8only() throws Exception
{
357 String paragraph
= null;
358 String line
= Common
.file2string(MigrationTool
.db
.DatabasePath
+ File
.separator
+ "R8Lib.c");
359 PrintWriter outfile1
= new PrintWriter(new BufferedWriter(new FileWriter(MigrationTool
.ModuleInfoMap
.get(mi
) + File
.separator
+ "Migration_" + mi
.modulename
+ File
.separator
+ "R8Lib.c")));
360 PrintWriter outfile2
= new PrintWriter(new BufferedWriter(new FileWriter(MigrationTool
.ModuleInfoMap
.get(mi
) + File
.separator
+ "Migration_" + mi
.modulename
+ File
.separator
+ "R8Lib.h")));
361 Pattern ptnr8only
= Pattern
.compile("////#?(\\w*)?(.*?R8_(\\w*).*?)////~", Pattern
.DOTALL
);
362 Matcher mtrr8only
= ptnr8only
.matcher(line
);
363 Matcher mtrr8onlyhead
;
366 Matcher mtrr8onlyheadcomment
= Critic
.PTN_NEW_HEAD_COMMENT
.matcher(line
);
367 if (mtrr8onlyheadcomment
.find()) {
368 outfile1
.append(mtrr8onlyheadcomment
.group() + "\n\n");
369 outfile2
.append(mtrr8onlyheadcomment
.group() + "\n\n");
373 while (mtrr8only
.find()) {
374 if (mi
.hashr8only
.contains(mtrr8only
.group(3))) {
375 paragraph
= mtrr8only
.group(2);
376 outfile1
.append(paragraph
+ "\n\n");
377 if (mtrr8only
.group(1).length() != 0) {
378 mi
.hashrequiredr9libs
.add(mtrr8only
.group(1));
381 while ((mtrr8onlyhead
= Func
.ptnbrace
.matcher(paragraph
)).find()) {
382 paragraph
= mtrr8onlyhead
.replaceAll(";");
384 outfile2
.append(paragraph
+ "\n\n");
392 mi
.localmodulesources
.add("R8Lib.h");
393 mi
.localmodulesources
.add("R8Lib.c");
395 //-------------------------------------process functions-------------------------------------//
397 //-----------------------------------ForDoAll-----------------------------------//
398 public void run(String filepath
) throws Exception
{
399 String inname
= filepath
.replace(mi
.temppath
+ File
.separator
, "");
400 String tempinpath
= mi
.temppath
+ File
.separator
;
401 String tempoutpath
= MigrationTool
.ModuleInfoMap
.get(mi
) + File
.separator
+ "Migration_" + mi
.modulename
+ File
.separator
;
403 Iterator
<Common
.Laplace
> itLaplace
= Laplaces
.iterator();
404 while (itLaplace
.hasNext()) {
405 Common
.Laplace lap
= itLaplace
.next();
406 if (lap
.recognize(inname
)) {
407 MigrationTool
.ui
.println("\nHandling file: " + inname
);
408 lap
.transform(tempinpath
+ inname
, tempoutpath
+ lap
.namechange(inname
));
413 public boolean filter(File dir
) {
416 //-----------------------------------ForDoAll-----------------------------------//
418 private final void setModuleInfo(ModuleInfo moduleinfo
) {
422 private final void start() throws Exception
{
423 Laplaces
.add(new DxsLaplace());
424 Laplaces
.add(new CLaplace());
425 Laplaces
.add(new IdleLaplace());
427 Common
.toDoAll(mi
.temppath
, this, Common
.FILE
);
429 if (!mi
.hashr8only
.isEmpty()) {
436 public static final void fireAt(ModuleInfo moduleinfo
) throws Exception
{
437 SFReplacer
.setModuleInfo(moduleinfo
);