+\r
+ //\r
+ // get dependent files list by parsing "#include" directive\r
+ // \r
+ private synchronized Set<String> getDependencies(String[] sourceFiles) {\r
+ Set<String> dependencies = new LinkedHashSet<String>();\r
+ String[] searchPathList = includePathList.toArray();\r
+\r
+ Stack<String> pendingFiles = new Stack<String>();\r
+ for (int i = 0; i < sourceFiles.length; ++i) {\r
+ File srcFile = new File(sourceFiles[i]);\r
+ if (srcFile.exists()) {\r
+ //\r
+ // a file must depend itself\r
+ // \r
+ dependencies.add(srcFile.getAbsolutePath());\r
+ pendingFiles.push(sourceFiles[i]);\r
+ }\r
+ }\r
+\r
+ while (!pendingFiles.empty()) {\r
+ String src = pendingFiles.pop();\r
+ File srcFile = new File(src);\r
+ if (!srcFile.exists()) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // try cache first\r
+ // \r
+ Set<String> incFiles = includesCache.get(src);\r
+ if (incFiles == null) {\r
+ incFiles = new HashSet<String>();\r
+ FileReader fileReader = null;\r
+ BufferedReader bufReader = null;\r
+ String fileContent = "";\r
+ int fileLength = (int)srcFile.length();\r
+\r
+ try {\r
+ fileReader = new FileReader(srcFile);\r
+ bufReader = new BufferedReader(fileReader);\r
+ char[] buf = new char[fileLength];\r
+\r
+ bufReader.read(buf, 0, fileLength);\r
+ fileContent = new String(buf);\r
+ } catch (IOException e) {\r
+ throw new BuildException(e.getMessage());\r
+ } finally {\r
+ try {\r
+ if (bufReader != null) {\r
+ bufReader.close();\r
+ }\r
+ if (fileReader != null) {\r
+ fileReader.close();\r
+ }\r
+ } catch (Exception e) {\r
+ throw new BuildException(e.getMessage());\r
+ }\r
+ }\r
+\r
+ //\r
+ // find out all "#include" lines\r
+ // \r
+ Matcher matcher = incPattern.matcher(fileContent);\r
+ while (matcher.find()) {\r
+ String incFilePath = fileContent.substring(matcher.start(1), matcher.end(1));\r
+ incFiles.add(incFilePath);\r
+ }\r
+\r
+ //\r
+ // put the includes in cache to avoid re-parsing\r
+ // \r
+ includesCache.put(src, incFiles);\r
+ }\r
+\r
+ //\r
+ // try each include search path to see if the include file exists or not\r
+ // \r
+ for (Iterator<String> it = incFiles.iterator(); it.hasNext();) {\r
+ String depFilePath = it.next();\r
+\r
+ for (int i = 0; i < searchPathList.length; ++i) {\r
+ File depFile = new File(searchPathList[i] + File.separator + depFilePath);\r
+ String filePath = depFile.getAbsolutePath();\r
+ //\r
+ // following check is a must. it can prevent dead loop if two\r
+ // files include each other\r
+ // \r
+ if (depFile.exists() && !dependencies.contains(filePath)) {\r
+ dependencies.add(filePath);\r
+ pendingFiles.push(filePath);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return dependencies;\r
+ }\r