3576578202f68cef37e63865d82a0d107cc37bf7
[mirror_edk2.git] / Tools / Source / MigrationTools / org / tianocore / migration / ModuleInfo.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.*;
18
19 /*
20 Class ModuleInfo is built for scanning the source files, it contains all the needed
21 information and all the temporary data.
22 */
23 public class ModuleInfo {
24 ModuleInfo(String modulepath, UI ui, Database db) throws Exception {
25 this.modulepath = modulepath;
26 this.ui = ui;
27 this.db = db;
28 moduleScan();
29 }
30
31 private String modulepath = null;
32 private Database db = null;
33 private UI ui = null;
34
35 public String modulename = null;
36 public String guidvalue = null;
37 public String moduletype = null;
38 public String entrypoint = null;
39
40 public Set<String> localmodulesources = new HashSet<String>(); //contains both .c and .h
41 public Set<String> localmoduleheaders = new HashSet<String>();
42 public Set<String> preprocessedccodes = new HashSet<String>();
43
44 public Set<String> hashfuncc = new HashSet<String>();
45 public Set<String> hashfuncd = new HashSet<String>();
46 public Set<String> hashnonlocalfunc = new HashSet<String>();
47 public Set<String> hashnonlocalmacro = new HashSet<String>();
48 public Set<String> hashEFIcall = new HashSet<String>();
49 public Set<String> hashr8only = new HashSet<String>();
50
51 public Set<String> hashrequiredr9libs = new HashSet<String>(); // hashrequiredr9libs is now all added in SourceFileReplacer
52 public Set<String> guid = new HashSet<String>();
53 public Set<String> protocol = new HashSet<String>();
54 public Set<String> ppi = new HashSet<String>();
55
56 private static String migrationcomment = "//%$//";
57
58 private void moduleScan() throws Exception {
59 String[] list = new File(modulepath).list();
60 boolean hasInf = false;
61 String infname = null;
62 boolean hasMsa = false;
63 String msaname = null;
64
65 for (int i = 0 ; i < list.length ; i++) {
66 if (new File(list[i]).isDirectory()) {
67 ;
68 } else {
69 if (list[i].contains(".c") || list[i].contains(".C")) {
70 localmodulesources.add(list[i]);
71 } else if (list[i].contains(".h") || list[i].contains(".H")) {
72 localmodulesources.add(list[i]);
73 localmoduleheaders.add(list[i]); //the case that several .inf or .msa found is not concerned
74 } else if (list[i].contains(".dxs")) {
75 localmodulesources.add(list[i]);
76 } else if (list[i].contains(".uni")) {
77 localmodulesources.add(list[i]);
78 } else if (list[i].contains(".inf")) {
79 if (ui.yesOrNo("Found .inf file : " + list[i] + "\nUse this file as this module's .inf ?")) {
80 hasInf = true;
81 infname = list[i];
82 } else {
83 continue;
84 }
85 } else if (list[i].contains(".msa")) {
86 if (ui.yesOrNo("Found .msa file : " + list[i] + "\nUse this file as this module's .msa ?")) {
87 hasMsa = true;
88 msaname = list[i];
89 } else {
90 continue;
91 }
92 }
93 }
94 }
95
96 ModuleReader mr = new ModuleReader(modulepath, this, db);
97 if (hasInf) { // this sequence shows using .inf as default
98 mr.readInf(infname);
99 } else if (hasMsa) {
100 mr.readMsa(msaname);
101 } else {
102 ui.println("No Inf Nor Msa Found");
103 }
104
105 CommentOutNonLocalHFile();
106 parsePreProcessedSourceCode();
107
108 new SourceFileReplacer(modulepath, this, db, ui).flush(); // some adding library actions are taken here,so it must be put before "MsaWriter"
109
110 // show result
111 if (ui.yesOrNo("Parse Module Information Complete . See details ?")) {
112 ui.println("\nModule Information : ");
113 ui.println("Entrypoint : " + entrypoint);
114 show(protocol, "Protocol : ");
115 show(ppi, "Ppi : ");
116 show(guid, "Guid : ");
117 show(hashfuncc, "call : ");
118 show(hashfuncd, "def : ");
119 show(hashEFIcall, "EFIcall : ");
120 show(hashnonlocalmacro, "macro : ");
121 show(hashnonlocalfunc, "nonlocal : ");
122 show(hashr8only, "hashr8only : ");
123 }
124
125 new MsaWriter(modulepath, this, db).flush();
126
127 // remove temp directory
128 //File tempdir = new File(modulepath + File.separator + "temp");
129 //System.out.println("Deleting Dir");
130 //if (tempdir.exists()) tempdir.d;
131
132 ui.println("Errors Left : " + db.error);
133 ui.println("Complete!");
134 ui.println("Your R9 module is placed at " + modulepath + File.separator + "result");
135 ui.println("Your logfile is placed at " + modulepath);
136 }
137
138 private void show(Set<String> hash, String show) {
139 ui.println(show + hash.size());
140 ui.println(hash);
141 }
142
143 // add '//' to all non-local include lines
144 private void CommentOutNonLocalHFile() throws IOException {
145 BufferedReader rd;
146 String line;
147 String curFile;
148 PrintWriter outfile;
149
150 Pattern ptninclude = Pattern.compile("[\"<](.*[.]h)[\">]");
151 Matcher mtcinclude;
152
153 File tempdir = new File(modulepath + File.separator + "temp" + File.separator);
154 if (!tempdir.exists()) tempdir.mkdir();
155
156 Iterator<String> ii = localmodulesources.iterator();
157 while ( ii.hasNext() ) {
158 curFile = ii.next();
159 rd = new BufferedReader(new FileReader(modulepath + File.separator + curFile));
160 outfile = new PrintWriter(new BufferedWriter(new FileWriter(modulepath + File.separator + "temp" + File.separator + curFile)));
161 while ((line = rd.readLine()) != null) {
162 if (line.contains("#include")) {
163 mtcinclude = ptninclude.matcher(line);
164 if (mtcinclude.find() && localmoduleheaders.contains(mtcinclude.group(1))) {
165 } else {
166 line = migrationcomment + line;
167 }
168 }
169 outfile.append(line + '\n');
170 }
171 outfile.flush();
172 outfile.close();
173 }
174 }
175 /*
176 private void search(String line, Pattern ptn, Method md) {
177 matmacro = Func.ptntmacro.matcher(line);
178 while (matmacro.find()) {
179 if ((temp = Func.registerMacro(matmacro, this, db)) != null) {
180 }
181 }
182 }
183 */
184 private void parsePreProcessedSourceCode() throws Exception {
185 //Cl cl = new Cl(modulepath);
186 //cl.execute("Fat.c");
187 //cl.generateAll(preprocessedccodes);
188 //
189 //System.out.println("Note!!!! The CL is not implemented now , pls do it manually!!! RUN :");
190 //System.out.println("cl " + modulepath + "\\temp\\*.c" + " -P");
191 //String[] list = new File(modulepath + File.separator + "temp").list(); // without CL , add
192 String[] list = new File(modulepath).list();
193 for (int i = 0 ; i < list.length ; i++) {
194 if (list[i].contains(".c")) { // without CL , change to .i
195 preprocessedccodes.add(list[i]);
196 }
197 }
198 //
199 Iterator<String> ii = preprocessedccodes.iterator();
200 BufferedReader rd = null;
201 String ifile = null;
202 String line = null;
203 String temp = null;
204 //StringBuffer result = new StringBuffer();
205
206 Pattern patefifuncc = Pattern.compile("g?(BS|RT)\\s*->\\s*([a-zA-Z_]\\w*)",Pattern.MULTILINE);
207 Pattern patentrypoint = Pattern.compile("EFI_([A-Z]*)_ENTRY_POINT\\s*\\(([^\\(\\)]*)\\)",Pattern.MULTILINE);
208 Matcher matguid;
209 Matcher matfuncc;
210 Matcher matfuncd;
211 Matcher matenclosereplace;
212 Matcher matefifuncc;
213 Matcher matentrypoint;
214 Matcher matmacro;
215
216 while (ii.hasNext()) {
217 StringBuffer wholefile = new StringBuffer();
218 ifile = ii.next();
219 rd = new BufferedReader(new FileReader(modulepath + File.separator + "temp" + File.separator + ifile));
220 while ((line = rd.readLine()) != null) {
221 wholefile.append(line + '\n');
222 }
223 line = wholefile.toString();
224
225 // if this is a Pei phase module , add these library class to .msa
226 matentrypoint = patentrypoint.matcher(line);
227 if (matentrypoint.find()) {
228 entrypoint = matentrypoint.group(2);
229 if (matentrypoint.group(1).matches("PEIM")) {
230 hashrequiredr9libs.add("PeimEntryPoint");
231 } else {
232 hashrequiredr9libs.add("UefiDriverEntryPoint");
233 }
234 }
235
236 // find guid
237 matguid = Guid.ptnguid.matcher(line); // several ways to implement this , which one is faster ? :
238 while (matguid.find()) { // 1.currently , find once , then call to identify which is it
239 if ((temp = Guid.register(matguid, this, db)) != null) { // 2.use 3 different matchers , search 3 times to find each
240 //matguid.appendReplacement(result, db.getR9Guidname(temp)); // search the database for all 3 kinds of guids , high cost
241 }
242 }
243 //matguid.appendTail(result);
244 //line = result.toString();
245
246 // find EFI call in form of '->' , many 'gUnicodeCollationInterface->' like things are not changed
247 // This item is not simply replaced , special operation is required.
248 matefifuncc = patefifuncc.matcher(line);
249 while (matefifuncc.find()) {
250 hashEFIcall.add(matefifuncc.group(2));
251 }
252
253 // find function call
254 matfuncc = Func.ptnfuncc.matcher(line);
255 while (matfuncc.find()) {
256 if ((temp = Func.register(matfuncc, this, db)) != null) {
257 //ui.println(ifile + " dofunc " + temp);
258 //matfuncc.appendReplacement(result, db.getR9Func(temp));
259 }
260 }
261 //matfuncc.appendTail(result);
262 //line = result.toString();
263
264 // find macro
265 matmacro = Macro.ptntmacro.matcher(line);
266 while (matmacro.find()) {
267 if ((temp = Macro.register(matmacro, this, db)) != null) {
268 }
269 }
270
271 // find function definition
272 // replace all {} to @
273 while ((matenclosereplace = Func.ptnbrace.matcher(line)).find()) {
274 line = matenclosereplace.replaceAll("@");
275 }
276
277 matfuncd = Func.ptnfuncd.matcher(line);
278 while (matfuncd.find()) {
279 if ((temp = Func.register(matfuncd, this, db)) != null) {
280 }
281 }
282 }
283
284 // op on hash
285 Iterator<String> funcci = hashfuncc.iterator();
286 while (funcci.hasNext()) {
287 if (!hashfuncd.contains(temp = funcci.next()) && !hashEFIcall.contains(temp)) {
288 hashnonlocalfunc.add(temp); // this set contains both changed and not changed items
289 }
290 }
291 }
292
293 public static void main(String[] args) throws Exception {
294 FirstPanel.init();
295 }
296 }