package org.tianocore.framework.tasks;\r
\r
import java.io.File;\r
+import java.io.FileReader;\r
+import java.io.BufferedReader;\r
+\r
+import java.util.List;\r
+import java.util.ArrayList;\r
+import java.util.regex.Pattern;\r
+import java.util.regex.Matcher;\r
+\r
import org.apache.tools.ant.Task;\r
import org.apache.tools.ant.Project;\r
import org.apache.tools.ant.BuildException;\r
//\r
// tool name\r
//\r
- private final String toolName = "FlashMap";\r
+ private static final String toolName = "FlashMap";\r
\r
+ //\r
+ // \r
+ // \r
+ private static Pattern fileBlock = Pattern.compile("\\s*File\\s*\\{([^\\{\\}]+)\\}");\r
+ private static Pattern fileNameDef = Pattern.compile("\\bName\\s*=\\s*\"([^\"]+)\"");\r
+ \r
//\r
// Flash definition file\r
//\r
@throws BuidException\r
**/\r
public void execute() throws BuildException {\r
- /*\r
if (isUptodate()) {\r
EdkLog.log(this, EdkLog.EDK_VERBOSE, headerFile.toFileList()\r
+ imageOutFile.toFileList()\r
+ dscFile.toFileList()\r
+ asmIncFile.toFileList()\r
+ outStrFile\r
- + " is/are up-to-date!");\r
+ + " is up-to-date!");\r
return;\r
}\r
- */\r
\r
Project project = this.getOwningTarget().getProject();\r
//\r
EdkLog.log(this, EdkLog.EDK_VERBOSE, srcName + " has been changed since last build!");\r
return false;\r
}\r
+\r
+ //\r
+ // we need to check the time stamp of each FV file specified in fdf file\r
+ // \r
+ if (!isFdUptodate(dstName, getFvFiles(flashDefFile.getValue()))) {\r
+ return false;\r
+ }\r
}\r
\r
if (!mcoFile.isEmpty()) {\r
\r
return true;\r
}\r
+\r
+ //\r
+ // Parse the flash definition file and find out the FV file names\r
+ // \r
+ private List<String> getFvFiles(String fdfFileName) {\r
+ File fdfFile = new File(fdfFileName);\r
+ int fileLength = (int)fdfFile.length();\r
+ char[] fdfContent = new char[fileLength];\r
+ List<String> fileList = new ArrayList<String>();\r
+\r
+ try {\r
+ FileReader reader = new FileReader(fdfFile);\r
+ BufferedReader in = new BufferedReader(reader);\r
+\r
+ in.read(fdfContent, 0, fileLength);\r
+ String str = new String(fdfContent);\r
+\r
+ //\r
+ // match the \r
+ // File {\r
+ // ...\r
+ // }\r
+ // block\r
+ // \r
+ Matcher matcher = fileBlock.matcher(str);\r
+ while (matcher.find()) {\r
+ String fileBlockContent = str.substring(matcher.start(1), matcher.end(1));\r
+ //\r
+ // match the definition like\r
+ // Name = "..."\r
+ // \r
+ Matcher nameMatcher = fileNameDef.matcher(fileBlockContent);\r
+ if (nameMatcher.find()) {\r
+ fileList.add(fileBlockContent.substring(nameMatcher.start(1), nameMatcher.end(1)));\r
+ }\r
+ }\r
+\r
+ in.close();\r
+ reader.close();\r
+ } catch (Exception ex) {\r
+ throw new BuildException(ex.getMessage());\r
+ }\r
+\r
+ return fileList;\r
+ }\r
+\r
+ private boolean isFdUptodate(String fdFile, List<String> fvFileList) {\r
+ String fvDir = ".";\r
+ File fd = new File(fdFile);\r
+\r
+ if (outputDir.equals(".")) {\r
+ if (!fd.isAbsolute()) {\r
+ //\r
+ // If we cannot get the absolute path of fd file, we caanot\r
+ // get its time stamp. Re-generate it always in such situation.\r
+ // \r
+ EdkLog.log(this, EdkLog.EDK_VERBOSE, "Cannot retrieve the time stamp of " + fdFile);\r
+ return false;\r
+ }\r
+ fvDir = fd.getParent();\r
+ } else {\r
+ fvDir = outputDir;\r
+ if (!fd.isAbsolute()) {\r
+ fd = new File(fvDir + File.separator + fdFile);\r
+ }\r
+ }\r
+\r
+ long fdTimeStamp = fd.lastModified();\r
+ for (int i = 0; i < fvFileList.size(); ++i) {\r
+ File fv = new File(fvDir + File.separator + fvFileList.get(i));\r
+ if (fv.lastModified() > fdTimeStamp) {\r
+ EdkLog.log(this, EdkLog.EDK_VERBOSE, fv.getPath() + " has been changed since last build!");\r
+ return false;\r
+ }\r
+ }\r
+\r
+ return true;\r
+ }\r
}\r