4a4d71cd79418f6b0f83bd570ed0f7ba0581c77e
[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 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;");
269 }
270 }
271 return templine;
272 }
273
274 private final String replaceMacro (String wholeline, Set<String> symbolSet) {
275 String r8thing;
276 String r9thing;
277 Iterator<String> it;
278
279 it = symbolSet.iterator();
280 while (it.hasNext()) { //macros are all assumed MdePkg currently
281 r8thing = it.next();
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));
288 }
289 }
290 }
291 return wholeline;
292 }
293
294 private final String replaceLibrary (String wholeline, Set<String> symbolSet) {
295 boolean addr8 = false;
296 // start replacing names
297 String r8thing;
298 String r9thing;
299 Iterator<String> it;
300 // Converting non-locla function
301 it = symbolSet.iterator();
302 while (it.hasNext()) {
303 r8thing = it.next();
304 mi.addLibraryClass(MigrationTool.db.getR9Lib(r8thing), UsageTypes.ALWAYS_CONSUMED);
305 //mi.hashrequiredr9libs.add(MigrationTool.db.getR9Lib(r8thing)); // add a library here
306
307 r8tor9 temp;
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()) {
315 temp = rt.next();
316 if (MigrationTool.db.r8only.contains(temp.r8thing)) {
317 filer8only.add(r8thing);
318 mi.hashr8only.add(r8thing);
319 addr8 = true;
320 }
321 }
322 }
323 }
324 }
325 } //is any of the guids changed?
326 if (addr8 == true) {
327 wholeline = addincludefile(wholeline, "\"R8Lib.h\"");
328 }
329 return wholeline;
330 }
331
332 private final String replaceObsoleteMacro (String wholeline) {
333 Matcher mtrmac;
334 mtrmac = Pattern.compile("EFI_IDIV_ROUND\\((.*), (.*)\\)").matcher(wholeline);
335 if (mtrmac.find()) {
336 wholeline = mtrmac.replaceAll("\\($1 \\/ $2 \\+ \\(\\(\\(2 \\* \\($1 \\% $2\\)\\) \\< $2\\) \\? 0 \\: 1\\)\\)");
337 }
338 mtrmac = Pattern.compile("EFI_MIN\\((.*), (.*)\\)").matcher(wholeline);
339 if (mtrmac.find()) {
340 wholeline = mtrmac.replaceAll("\\(\\($1 \\< $2\\) \\? $1 \\: $2\\)");
341 }
342 mtrmac = Pattern.compile("EFI_MAX\\((.*), (.*)\\)").matcher(wholeline);
343 if (mtrmac.find()) {
344 wholeline = mtrmac.replaceAll("\\(\\($1 \\> $2\\) \\? $1 \\: $2\\)");
345 }
346 mtrmac = Pattern.compile("EFI_UINTN_ALIGNED\\((.*)\\)").matcher(wholeline);
347 if (mtrmac.find()) {
348 wholeline = mtrmac.replaceAll("\\(\\(\\(UINTN\\) $1\\) \\& \\(sizeof \\(UINTN\\) \\- 1\\)\\)");
349 }
350 if (wholeline.contains("EFI_UINTN_ALIGN_MASK")) {
351 wholeline = wholeline.replaceAll("EFI_UINTN_ALIGN_MASK", "(sizeof (UINTN) - 1)");
352 }
353 return wholeline;
354 }
355
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;
364
365 //add head comment
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");
370 }
371
372 //add functions body
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));
379 }
380 //generate R8lib.h
381 while ((mtrr8onlyhead = Func.ptnbrace.matcher(paragraph)).find()) {
382 paragraph = mtrr8onlyhead.replaceAll(";");
383 }
384 outfile2.append(paragraph + "\n\n");
385 }
386 }
387 outfile1.flush();
388 outfile1.close();
389 outfile2.flush();
390 outfile2.close();
391
392 mi.localmodulesources.add("R8Lib.h");
393 mi.localmodulesources.add("R8Lib.c");
394 }
395 //-------------------------------------process functions-------------------------------------//
396
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;
402
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));
409 }
410 }
411 }
412
413 public boolean filter(File dir) {
414 return true;
415 }
416 //-----------------------------------ForDoAll-----------------------------------//
417
418 private final void setModuleInfo(ModuleInfo moduleinfo) {
419 mi = moduleinfo;
420 }
421
422 private final void start() throws Exception {
423 Laplaces.add(new DxsLaplace());
424 Laplaces.add(new CLaplace());
425 Laplaces.add(new IdleLaplace());
426
427 Common.toDoAll(mi.temppath, this, Common.FILE);
428
429 if (!mi.hashr8only.isEmpty()) {
430 addr8only();
431 }
432
433 Laplaces.clear();
434 }
435
436 public static final void fireAt(ModuleInfo moduleinfo) throws Exception {
437 SFReplacer.setModuleInfo(moduleinfo);
438 SFReplacer.start();
439 }
440 }