]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Java/Source/MigrationTools/org/tianocore/migration/SourceFileReplacer.java
Fix a bug in HobLib migration.
[mirror_edk2.git] / Tools / Java / Source / MigrationTools / org / tianocore / migration / SourceFileReplacer.java
1 /** @file
2
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
8
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.
11
12 **/
13 package org.tianocore.migration;
14
15 import java.io.*;
16 import java.util.*;
17 import java.util.regex.Matcher;
18 import java.util.regex.Pattern;
19
20 import org.tianocore.UsageTypes;
21
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>();
26
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>();
34
35 private static final String[] specialhoblibfunc = {
36 "BuildModuleHob",
37 "BuildResourceDescriptorHob",
38 "BuildFvHob",
39 "BuildCpuHob",
40 "BuildGuidDataHob",
41 "BuildStackHob",
42 "BuildBspStoreHob",
43 "BuildMemoryAllocationHob"
44 };
45 private static final String[] peiserviceslibfunc = {
46 "InstallPpi",
47 "ReInstallPpi",
48 "LocatePpi",
49 "NotifyPpi",
50 "GetBootMode",
51 "SetBootMode",
52 "GetHobList",
53 "CreateHob",
54 "FfsFindNextVolume",
55 "FfsFindNextFile",
56 "FfsFindSectionData",
57 "InstallPeiMemory",
58 "AllocatePages",
59 "AllocatePool",
60 "PeiResetSystem"
61 };
62 //---------------------------------------inner classes---------------------------------------//
63 private static class r8tor9 {
64 r8tor9(String r8, String r9) {
65 r8thing = r8;
66 r9thing = r9;
67 }
68 public String r8thing;
69 public String r9thing;
70 }
71
72 private class IdleLaplace extends Common.Laplace {
73 public String operation(String wholeline) {
74 return replaceLibrary (wholeline, mi.hashmacro);
75 }
76
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"));
81 }
82
83 public String namechange(String oldname) {
84 if (oldname.contains(".H")) {
85 return oldname.replaceFirst(".H", ".h");
86 } else {
87 return oldname;
88 }
89 }
90 }
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\\>");
96 } else {
97 return addincludefile(wholeline, "\\<DxeDepex.h\\>");
98 }
99 }
100
101 public boolean recognize(String filename) {
102 return filename.contains(".dxs");
103 }
104
105 public String namechange(String oldname) {
106 return oldname;
107 }
108 }
109
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");
121 }
122 if (Common.find (wholeline, "\\bg?RT\\b")) {
123 mi.hashrequiredr9libs.add ("UefiRuntimeServicesTableLib");
124 }
125 if (Common.find (wholeline, "\\bgDS\\b")) {
126 mi.hashrequiredr9libs.add ("DxeServicesTableLib");
127 }
128
129 wholeline = replaceLibrary (wholeline, mi.hashnonlocalfunc);
130 wholeline = replaceLibrary (wholeline, mi.hashmacro);
131 // Converting macro
132 wholeline = replaceMacro (wholeline, mi.hashnonlocalmacro);
133
134 // Converting guid
135 replaceGuid(wholeline, mi.guids, "guid", fileguid);
136 replaceGuid(wholeline, mi.ppis, "ppi", fileppi);
137 replaceGuid(wholeline, mi.protocols, "protocol", fileprotocol);
138
139 // Converting Pei
140 if (mi.getModuleType().matches("PEIM")) {
141 //
142 // Try to remove PeiServicesTablePointer;
143 //
144 wholeline = dropPeiServicesPointer (wholeline);
145 //
146 // Drop the possible return Status of Hob building function.
147 //
148 wholeline = drophobLibReturnStatus (wholeline);
149 }
150 //
151 // Expand obsolete R8 macro.
152 //
153 wholeline = replaceObsoleteMacro (wholeline);
154
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);
162 }
163
164 filefunc.clear();
165 filemacro.clear();
166 fileguid.clear();
167 fileppi.clear();
168 fileprotocol.clear();
169 filer8only.clear();
170
171 return wholeline;
172 }
173
174 public boolean recognize(String filename) {
175 return filename.contains(".c") || filename.contains(".C");
176 }
177
178 public String namechange(String oldname) {
179 if (oldname.contains(".C")) {
180 return oldname.replaceFirst(".C", ".c");
181 } else {
182 return oldname;
183 }
184 }
185 }
186 //---------------------------------------inner classes---------------------------------------//
187
188 //-------------------------------------process functions-------------------------------------//
189 private static final String addincludefile(String wholeline, String hfile) {
190 return wholeline.replaceFirst("(\\*/\\s)", "$1\n#include " + hfile + "\n");
191 }
192
193 private static final void show(Set<r8tor9> hash, String sh) {
194 Iterator<r8tor9> it = hash.iterator();
195 r8tor9 temp;
196 if (!hash.isEmpty()) {
197 MigrationTool.ui.print("Converting " + sh + " : ");
198 while (it.hasNext()) {
199 temp = it.next();
200 MigrationTool.ui.print("[" + temp.r8thing + "->" + temp.r9thing + "] ");
201 }
202 MigrationTool.ui.println("");
203 }
204 }
205
206 private static final void replaceGuid(String line, Set<String> hash, String kind, Set<r8tor9> filehash) {
207 Iterator<String> it;
208 String r8thing;
209 String r9thing;
210 it = hash.iterator();
211 while (it.hasNext()) {
212 r8thing = it.next();
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));
218 }
219 }
220 }
221 }
222 }
223
224 private final String dropPeiServicesPointer (String wholeline) {
225 String peiServicesTablePointer;
226 String peiServicesTableCaller;
227 String regPeiServices;
228 Pattern ptnPei;
229 Matcher mtrPei;
230
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);
237 if (mtrPei.find()) {
238 wholeline = mtrPei.replaceAll("PeiServices" + peiserviceslibfunc[i] + " (");
239 mi.hashrequiredr9libs.add("PeiServicesLib");
240 }
241 }
242 regPeiServices = peiServicesTableCaller + "(CopyMem|SetMem)" + "\\s*\\((\\t| )*";
243 ptnPei = Pattern.compile (regPeiServices);
244 mtrPei = ptnPei.matcher (wholeline);
245 if (mtrPei.find()) {
246 wholeline = mtrPei.replaceAll("$2 (");
247 mi.hashrequiredr9libs.add("BaseMemoryLib");
248 }
249
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");
254 }
255
256 return wholeline;
257 }
258
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 do {
265 ptnhobstatus = Pattern.compile("((?:\t| )*)(\\w(?:\\w|\\d)*)\\s*=\\s*" + specialhoblibfunc[i] + "(.*?;)", Pattern.DOTALL);
266 mtrhobstatus = ptnhobstatus.matcher(templine);
267 if (!mtrhobstatus.find()) {
268 break;
269 }
270 String captureIndent = mtrhobstatus.group(1);
271 String captureStatus = mtrhobstatus.group(2);
272 String replaceString = captureIndent + specialhoblibfunc[i] + mtrhobstatus.group(3) + "\n";
273 replaceString += captureIndent + MigrationTool.MIGRATIONCOMMENT + "R9 Hob-building library functions will assert if build failure.\n";
274 replaceString += captureIndent + captureStatus + " = EFI_SUCCESS;";
275 templine = mtrhobstatus.replaceFirst(replaceString);
276 } while (true);
277 }
278 return templine;
279 }
280
281 private final String replaceMacro (String wholeline, Set<String> symbolSet) {
282 String r8thing;
283 String r9thing;
284 Iterator<String> it;
285
286 it = symbolSet.iterator();
287 while (it.hasNext()) { //macros are all assumed MdePkg currently
288 r8thing = it.next();
289 //mi.hashrequiredr9libs.add(MigrationTool.db.getR9Lib(r8thing));
290 if ((r9thing = MigrationTool.db.getR9Macro(r8thing)) != null) {
291 if (wholeline.contains(r8thing)) {
292 String findString = "(?<!(?:\\d|\\w))" + r8thing + "(?!(?:\\d|\\w))";
293 wholeline = wholeline.replaceAll(findString, r9thing);
294 filemacro.add(new r8tor9(r8thing, r9thing));
295 }
296 }
297 }
298 return wholeline;
299 }
300
301 private final String replaceLibrary (String wholeline, Set<String> symbolSet) {
302 boolean addr8 = false;
303 // start replacing names
304 String r8thing;
305 String r9thing;
306 Iterator<String> it;
307 // Converting non-locla function
308 it = symbolSet.iterator();
309 while (it.hasNext()) {
310 r8thing = it.next();
311 mi.addLibraryClass(MigrationTool.db.getR9Lib(r8thing), UsageTypes.ALWAYS_CONSUMED);
312 //mi.hashrequiredr9libs.add(MigrationTool.db.getR9Lib(r8thing)); // add a library here
313
314 r8tor9 temp;
315 if ((r9thing = MigrationTool.db.getR9Func(r8thing)) != null) {
316 if (!r8thing.equals(r9thing)) {
317 if (wholeline.contains(r8thing)) {
318 wholeline = wholeline.replaceAll(r8thing, r9thing);
319 filefunc.add(new r8tor9(r8thing, r9thing));
320 Iterator<r8tor9> rt = filefunc.iterator();
321 while (rt.hasNext()) {
322 temp = rt.next();
323 if (MigrationTool.db.r8only.contains(temp.r8thing)) {
324 filer8only.add(r8thing);
325 mi.hashr8only.add(r8thing);
326 addr8 = true;
327 }
328 }
329 }
330 }
331 }
332 } //is any of the guids changed?
333 if (addr8 == true) {
334 wholeline = addincludefile(wholeline, "\"R8Lib.h\"");
335 }
336 return wholeline;
337 }
338
339 private final String replaceObsoleteMacro (String wholeline) {
340 Matcher mtrmac;
341 mtrmac = Pattern.compile("EFI_IDIV_ROUND\\((.*), (.*)\\)").matcher(wholeline);
342 if (mtrmac.find()) {
343 wholeline = mtrmac.replaceAll("\\($1 \\/ $2 \\+ \\(\\(\\(2 \\* \\($1 \\% $2\\)\\) \\< $2\\) \\? 0 \\: 1\\)\\)");
344 }
345 mtrmac = Pattern.compile("EFI_MIN\\((.*), (.*)\\)").matcher(wholeline);
346 if (mtrmac.find()) {
347 wholeline = mtrmac.replaceAll("\\(\\($1 \\< $2\\) \\? $1 \\: $2\\)");
348 }
349 mtrmac = Pattern.compile("EFI_MAX\\((.*), (.*)\\)").matcher(wholeline);
350 if (mtrmac.find()) {
351 wholeline = mtrmac.replaceAll("\\(\\($1 \\> $2\\) \\? $1 \\: $2\\)");
352 }
353 mtrmac = Pattern.compile("EFI_UINTN_ALIGNED\\((.*)\\)").matcher(wholeline);
354 if (mtrmac.find()) {
355 wholeline = mtrmac.replaceAll("\\(\\(\\(UINTN\\) $1\\) \\& \\(sizeof \\(UINTN\\) \\- 1\\)\\)");
356 }
357 if (wholeline.contains("EFI_UINTN_ALIGN_MASK")) {
358 wholeline = wholeline.replaceAll("EFI_UINTN_ALIGN_MASK", "(sizeof (UINTN) - 1)");
359 }
360 return wholeline;
361 }
362
363 private final void addr8only() throws Exception {
364 String paragraph = null;
365 String line = Common.file2string(MigrationTool.db.DatabasePath + File.separator + "R8Lib.c");
366 PrintWriter outfile1 = new PrintWriter(new BufferedWriter(new FileWriter(MigrationTool.ModuleInfoMap.get(mi) + File.separator + "Migration_" + mi.modulename + File.separator + "R8Lib.c")));
367 PrintWriter outfile2 = new PrintWriter(new BufferedWriter(new FileWriter(MigrationTool.ModuleInfoMap.get(mi) + File.separator + "Migration_" + mi.modulename + File.separator + "R8Lib.h")));
368 Pattern ptnr8only = Pattern.compile("////#?(\\w*)?(.*?R8_(\\w*).*?)////~", Pattern.DOTALL);
369 Matcher mtrr8only = ptnr8only.matcher(line);
370 Matcher mtrr8onlyhead;
371
372 //add head comment
373 Matcher mtrr8onlyheadcomment = Critic.PTN_NEW_HEAD_COMMENT.matcher(line);
374 if (mtrr8onlyheadcomment.find()) {
375 outfile1.append(mtrr8onlyheadcomment.group() + "\n\n");
376 outfile2.append(mtrr8onlyheadcomment.group() + "\n\n");
377 }
378
379 //add functions body
380 while (mtrr8only.find()) {
381 if (mi.hashr8only.contains(mtrr8only.group(3))) {
382 paragraph = mtrr8only.group(2);
383 outfile1.append(paragraph + "\n\n");
384 if (mtrr8only.group(1).length() != 0) {
385 mi.hashrequiredr9libs.add(mtrr8only.group(1));
386 }
387 //generate R8lib.h
388 while ((mtrr8onlyhead = Func.ptnbrace.matcher(paragraph)).find()) {
389 paragraph = mtrr8onlyhead.replaceAll(";");
390 }
391 outfile2.append(paragraph + "\n\n");
392 }
393 }
394 outfile1.flush();
395 outfile1.close();
396 outfile2.flush();
397 outfile2.close();
398
399 mi.localmodulesources.add("R8Lib.h");
400 mi.localmodulesources.add("R8Lib.c");
401 }
402 //-------------------------------------process functions-------------------------------------//
403
404 //-----------------------------------ForDoAll-----------------------------------//
405 public void run(String filepath) throws Exception {
406 String inname = filepath.replace(mi.temppath + File.separator, "");
407 String tempinpath = mi.temppath + File.separator;
408 String tempoutpath = MigrationTool.ModuleInfoMap.get(mi) + File.separator + "Migration_" + mi.modulename + File.separator;
409
410 Iterator<Common.Laplace> itLaplace = Laplaces.iterator();
411 while (itLaplace.hasNext()) {
412 Common.Laplace lap = itLaplace.next();
413 if (lap.recognize(inname)) {
414 MigrationTool.ui.println("\nHandling file: " + inname);
415 lap.transform(tempinpath + inname, tempoutpath + lap.namechange(inname));
416 }
417 }
418 }
419
420 public boolean filter(File dir) {
421 return true;
422 }
423 //-----------------------------------ForDoAll-----------------------------------//
424
425 private final void setModuleInfo(ModuleInfo moduleinfo) {
426 mi = moduleinfo;
427 }
428
429 private final void start() throws Exception {
430 Laplaces.add(new DxsLaplace());
431 Laplaces.add(new CLaplace());
432 Laplaces.add(new IdleLaplace());
433
434 Common.toDoAll(mi.temppath, this, Common.FILE);
435
436 if (!mi.hashr8only.isEmpty()) {
437 addr8only();
438 }
439
440 Laplaces.clear();
441 }
442
443 public static final void fireAt(ModuleInfo moduleinfo) throws Exception {
444 SFReplacer.setModuleInfo(moduleinfo);
445 SFReplacer.start();
446 }
447 }