/** @file Copyright (c) 2006, Intel Corporation All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ package org.tianocore.migration; import java.io.*; import java.util.*; import java.util.regex.*; import org.tianocore.*; public final class ModuleReader implements Common.ForDoAll { private static final ModuleReader modulereader = new ModuleReader(); private ModuleInfo mi; private final CommentLaplace commentlaplace = new CommentLaplace(); private static final Pattern ptninfequation = Pattern.compile("([^\\s]*)\\s*=\\s*([^\\s]*)"); private static final Pattern ptnsection = Pattern.compile("\\[([^\\[\\]]*)\\]([^\\[\\]]*)\\n", Pattern.MULTILINE); private static final Pattern ptnfilename = Pattern.compile("[^\\s]+"); public final void ModuleScan() throws Exception { Common.toDoAll(mi.modulepath, ModuleInfo.class.getMethod("enroll", String.class), mi, null, Common.FILE); // inf&msa String filename = null; if (mi.msaorinf.isEmpty()) { MigrationTool.ui.println("No INF nor MSA file found!"); System.exit(0); } else { if (mi.msaorinf.size() == 1) { filename = (String)mi.msaorinf.toArray()[0]; } else { filename = MigrationTool.ui.choose("Found .inf or .msa file for module\n" + mi.modulepath + "\nChoose one Please", mi.msaorinf.toArray()); } } if (filename.contains(".inf")) { readInf(filename); } else if (filename.contains(".msa")) { readMsa(filename); } // inf&msa preProcessModule(); } private final void readMsa(String name) throws Exception { ModuleSurfaceAreaDocument msadoc = ModuleSurfaceAreaDocument.Factory.parse(new File(mi.modulepath + File.separator + name)); ModuleSurfaceAreaDocument.ModuleSurfaceArea msa = msadoc.getModuleSurfaceArea(); MsaHeaderDocument.MsaHeader msaheader = msa.getMsaHeader(); mi.modulename = msaheader.getModuleName(); mi.guidvalue = msaheader.getGuidValue(); mi.moduletype = msaheader.getModuleType().toString(); // ??? SourceFilesDocument.SourceFiles sourcefiles = msa.getSourceFiles(); String temp; Iterator li = sourcefiles.getFilenameList().iterator(); while (li.hasNext()) { if (!mi.localmodulesources.contains(temp = li.next().toString())) { System.out.println("Source File Missing! : " + temp); } } } private final void readInf(String name) throws Exception { System.out.println("\nParsing INF file: " + name); String wholeline; Matcher mtrinfequation; Matcher mtrsection; Matcher mtrfilename; wholeline = Common.file2string(mi.modulepath + File.separator + name); mtrsection = ptnsection.matcher(wholeline); while (mtrsection.find()) { if (mtrsection.group(1).matches("defines")) { mtrinfequation = ptninfequation.matcher(mtrsection.group(2)); while (mtrinfequation.find()) { if (mtrinfequation.group(1).matches("BASE_NAME")) { mi.modulename = mtrinfequation.group(2); } if (mtrinfequation.group(1).matches("FILE_GUID")) { mi.guidvalue = mtrinfequation.group(2); } if (mtrinfequation.group(1).matches("COMPONENT_TYPE")) { mi.moduletype = mtrinfequation.group(2); } } } if (mtrsection.group(1).contains("nmake.")) { mtrinfequation = ptninfequation.matcher(mtrsection.group(2)); while (mtrinfequation.find()) { if (mtrinfequation.group(1).matches("IMAGE_ENTRY_POINT")) { mi.entrypoint = mtrinfequation.group(2); } if (mtrinfequation.group(1).matches("DPX_SOURCE")) { if (!mi.localmodulesources.contains(mtrinfequation.group(2))) { MigrationTool.ui.println("DPX File Missing! : " + mtrinfequation.group(2)); } } } } if (mtrsection.group(1).contains("sources.")) { mtrfilename = ptnfilename.matcher(mtrsection.group(2)); while (mtrfilename.find()) { mi.infsources.add(mtrfilename.group()); if (!mi.localmodulesources.contains(mtrfilename.group())) { MigrationTool.ui.println("Warn: Source File Missing! : " + mtrfilename.group()); } } } if (mtrsection.group(1).matches("includes.")) { mtrfilename = ptnfilename.matcher(mtrsection.group(2)); while (mtrfilename.find()) { mi.infincludes.add(mtrfilename.group()); } } } } private final void preProcessModule() throws Exception { // according to .inf file, add extraordinary includes and sourcefiles Common.dirCopy(mi.modulepath, mi.temppath); // collect all Laplace.namechange to here??? if (!mi.infincludes.isEmpty()) { Iterator it = mi.infincludes.iterator(); String tempincludename = null; while (it.hasNext()) { tempincludename = it.next(); if (tempincludename.contains("..")) { Matcher mtr = Common.PTNSEPARATER.matcher(tempincludename); if (mtr.find() && !mtr.group(2).matches(".")) { Common.oneLevelDirCopy(mi.modulepath.replaceAll(Common.STRSEPARATER, "$1") + File.separator + mtr.group(2), mi.temppath, ".h"); } else { Common.oneLevelDirCopy(mi.modulepath.replaceAll(Common.STRSEPARATER, "$1"), mi.temppath, ".h"); } } } } if (!mi.infsources.isEmpty()) { Iterator it = mi.infsources.iterator(); String tempsourcename = null; while (it.hasNext()) { tempsourcename = it.next(); if (tempsourcename.contains("..")) { Common.ensureDir(mi.temppath + File.separator + "MT_Parent_Sources"); Matcher mtr = Common.PTNSEPARATER.matcher(tempsourcename); if (mtr.find()) { Common.fileCopy(mi.modulepath.replaceAll(Common.STRSEPARATER, "$1") + File.separator + mtr.group(2), mi.temppath + File.separator + "MT_Parent_Sources" + File.separator + mtr.group(2)); } } } } //CommentOutNonLocalHFile(); Common.toDoAll(mi.temppath, this, Common.FILE); parsePreProcessedSourceCode(); } private final void parsePreProcessedSourceCode() throws Exception { //Cl cl = new Cl(modulepath); //cl.execute("Fat.c"); //cl.generateAll(preprocessedccodes); // //System.out.println("Note!!!! The CL is not implemented now , pls do it manually!!! RUN :"); //System.out.println("cl " + modulepath + "\\temp\\*.c" + " -P"); //String[] list = new File(modulepath + File.separator + "temp").list(); // without CL , add BufferedReader rd = null; String ifile = null; String line = null; String temp = null; Iterator ii = mi.localmodulesources.iterator(); while (ii.hasNext()) { temp = ii.next(); if (temp.contains(".c")) { mi.preprocessedccodes.add(temp); } } ii = mi.preprocessedccodes.iterator(); Pattern patefifuncc = Pattern.compile("g?(BS|RT)\\s*->\\s*([a-zA-Z_]\\w*)",Pattern.MULTILINE); Matcher matguid; Matcher matfuncc; Matcher matfuncd; Matcher matenclosereplace; Matcher matefifuncc; Matcher matmacro; while (ii.hasNext()) { StringBuffer wholefile = new StringBuffer(); ifile = ii.next(); rd = new BufferedReader(new FileReader(mi.temppath + File.separator + ifile)); while ((line = rd.readLine()) != null) { wholefile.append(line + '\n'); } line = wholefile.toString(); // find guid matguid = Guid.ptnguid.matcher(line); // several ways to implement this , which one is faster ? : while (matguid.find()) { // 1.currently , find once , then call to identify which is it if ((temp = Guid.register(matguid, mi, MigrationTool.db)) != null) { // 2.use 3 different matchers , search 3 times to find each //matguid.appendReplacement(result, MigrationTool.db.getR9Guidname(temp)); // search the database for all 3 kinds of guids , high cost } } //matguid.appendTail(result); //line = result.toString(); // find EFI call in form of '->' , many 'gUnicodeCollationInterface->' like things are not changed // This item is not simply replaced , special operation is required. matefifuncc = patefifuncc.matcher(line); while (matefifuncc.find()) { mi.hashEFIcall.add(matefifuncc.group(2)); } // find function call matfuncc = Func.ptnfuncc.matcher(line); while (matfuncc.find()) { if ((temp = Func.register(matfuncc, mi, MigrationTool.db)) != null) { //MigrationTool.ui.println(ifile + " dofunc " + temp); //matfuncc.appendReplacement(result, MigrationTool.db.getR9Func(temp)); } } //matfuncc.appendTail(result); //line = result.toString(); // find macro matmacro = Macro.ptntmacro.matcher(line); while (matmacro.find()) { if ((temp = Macro.register(matmacro, mi, MigrationTool.db)) != null) { } } // find function definition // replace all {} to @ while ((matenclosereplace = Func.ptnbrace.matcher(line)).find()) { line = matenclosereplace.replaceAll("@"); } matfuncd = Func.ptnfuncd.matcher(line); while (matfuncd.find()) { if ((temp = Func.register(matfuncd, mi, MigrationTool.db)) != null) { } } } // op on hash Iterator funcci = mi.hashfuncc.iterator(); while (funcci.hasNext()) { if (!mi.hashfuncd.contains(temp = funcci.next()) && !mi.hashEFIcall.contains(temp)) { mi.hashnonlocalfunc.add(temp); // this set contains both changed and not changed items } } } public class CommentLaplace extends Common.Laplace { public String operation(String wholeline) { StringBuffer wholebuffer = new StringBuffer(); String templine = null; Pattern ptnincludefile = Pattern.compile("[\"<](.*[.]h)[\">]"); Pattern ptninclude = Pattern.compile("#include\\s*(.*)"); Matcher mtrinclude = ptninclude.matcher(wholeline); Matcher mtrincludefile = null; while (mtrinclude.find()) { mtrincludefile = ptnincludefile.matcher(mtrinclude.group(1)); if (mtrincludefile.find() && mi.localmodulesources.contains(mtrincludefile.group(1))) { templine = mtrinclude.group(); } else { templine = MigrationTool.MIGRATIONCOMMENT + mtrinclude.group(); } mtrinclude.appendReplacement(wholebuffer, templine); } mtrinclude.appendTail(wholebuffer); return wholebuffer.toString(); } public boolean recognize(String filename) { return filename.contains(".c") || filename.contains(".h"); } public String namechange(String oldname) { return oldname; } } //-----------------------------------ForDoAll-----------------------------------// public void run(String filepath) throws Exception { String name = mi.temppath + File.separator + filepath.replace(mi.temppath + File.separator, ""); commentlaplace.transform(name, name); } public boolean filter(File dir) { return true; } //-----------------------------------ForDoAll-----------------------------------// public final void setModuleInfo(ModuleInfo m) { mi = m; } public static final void aimAt(ModuleInfo mi) throws Exception { modulereader.setModuleInfo(mi); modulereader.ModuleScan(); } }