+++ /dev/null
-/*\r
- * \r
- * Copyright 2002-2004 The Ant-Contrib project\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package net.sf.antcontrib.cpptasks.compiler;\r
-import java.io.BufferedReader;\r
-import java.io.File;\r
-import java.io.FileReader;\r
-import java.io.IOException;\r
-import java.io.Reader;\r
-import java.util.Vector;\r
-import net.sf.antcontrib.cpptasks.CCTask;\r
-import net.sf.antcontrib.cpptasks.CUtil;\r
-import net.sf.antcontrib.cpptasks.CompilerDef;\r
-import net.sf.antcontrib.cpptasks.DependencyInfo;\r
-import net.sf.antcontrib.cpptasks.ProcessorDef;\r
-import net.sf.antcontrib.cpptasks.parser.Parser;\r
-import net.sf.antcontrib.cpptasks.TargetDef;\r
-\r
-/**\r
- * An abstract compiler implementation.\r
- * \r
- * @author Adam Murdoch\r
- * @author Curt Arnold\r
- */\r
-public abstract class AbstractCompiler extends AbstractProcessor\r
- implements\r
- Compiler {\r
- private static final String[] emptyIncludeArray = new String[0];\r
- private String outputSuffix;\r
- protected AbstractCompiler(String[] sourceExtensions,\r
- String[] headerExtensions, String outputSuffix) {\r
- super(sourceExtensions, headerExtensions);\r
- this.outputSuffix = outputSuffix;\r
- }\r
- /**\r
- * Checks file name to see if parse should be attempted\r
- * \r
- * Default implementation returns false for files with extensions '.dll',\r
- * 'tlb', '.res'\r
- * \r
- */\r
- protected boolean canParse(File sourceFile) {\r
- String sourceName = sourceFile.toString();\r
- int lastPeriod = sourceName.lastIndexOf('.');\r
- if (lastPeriod >= 0 && lastPeriod == sourceName.length() - 4) {\r
- String ext = sourceName.substring(lastPeriod).toUpperCase();\r
- if (ext.equals(".DLL") || ext.equals(".TLB") || ext.equals(".RES")) {\r
- return false;\r
- }\r
- }\r
- return true;\r
- }\r
- abstract protected CompilerConfiguration createConfiguration(CCTask task,\r
- LinkType linkType, ProcessorDef[] baseConfigs,\r
- CompilerDef specificConfig, TargetDef targetPlatform);\r
- public ProcessorConfiguration createConfiguration(CCTask task,\r
- LinkType linkType, ProcessorDef[] baseConfigs,\r
- ProcessorDef specificConfig, TargetDef targetPlatform) {\r
- if (specificConfig == null) {\r
- throw new NullPointerException("specificConfig");\r
- }\r
- return createConfiguration(task, linkType, baseConfigs,\r
- (CompilerDef) specificConfig, targetPlatform);\r
- }\r
- abstract protected Parser createParser(File sourceFile);\r
- protected String getBaseOutputName(String inputFile) {\r
- int lastSlash = inputFile.lastIndexOf('/');\r
- int lastReverse = inputFile.lastIndexOf('\\');\r
- int lastSep = inputFile.lastIndexOf(File.separatorChar);\r
- if (lastReverse > lastSlash) {\r
- lastSlash = lastReverse;\r
- }\r
- if (lastSep > lastSlash) {\r
- lastSlash = lastSep;\r
- }\r
- int lastPeriod = inputFile.lastIndexOf('.');\r
- if (lastPeriod < 0) {\r
- lastPeriod = inputFile.length();\r
- }\r
- return inputFile.substring(lastSlash + 1, lastPeriod);\r
- }\r
- public String getOutputFileName(String inputFile) {\r
- //\r
- // if a recognized input file\r
- //\r
- if (bid(inputFile) > 1) {\r
- String baseName = getBaseOutputName(inputFile);\r
- return baseName + outputSuffix;\r
- }\r
- return null;\r
- }\r
- /**\r
- * Returns dependency info for the specified source file\r
- * \r
- * @param task\r
- * task for any diagnostic output\r
- * @param source\r
- * file to be parsed\r
- * @param includePath\r
- * include path to be used to resolve included files\r
- * \r
- * @param sysIncludePath\r
- * sysinclude path from build file, files resolved using\r
- * sysInclude path will not participate in dependency analysis\r
- * \r
- * @param envIncludePath\r
- * include path from environment variable, files resolved with\r
- * envIncludePath will not participate in dependency analysis\r
- * \r
- * @param baseDir\r
- * used to produce relative paths in DependencyInfo\r
- * @param includePathIdentifier\r
- * used to distinguish DependencyInfo's from different include\r
- * path settings\r
- * \r
- * @author Curt Arnold\r
- */\r
- public final DependencyInfo parseIncludes(CCTask task, File source,\r
- File[] includePath, File[] sysIncludePath, File[] envIncludePath,\r
- File baseDir, String includePathIdentifier) {\r
- //\r
- // if any of the include files can not be identified\r
- // change the sourceLastModified to Long.MAX_VALUE to\r
- // force recompilation of anything that depends on it\r
- long sourceLastModified = source.lastModified();\r
- File[] sourcePath = new File[1];\r
- sourcePath[0] = new File(source.getParent());\r
- Vector onIncludePath = new Vector();\r
- Vector onSysIncludePath = new Vector();\r
- String baseDirPath;\r
- try {\r
- baseDirPath = baseDir.getCanonicalPath();\r
- } catch (IOException ex) {\r
- baseDirPath = baseDir.toString();\r
- }\r
- String relativeSource = CUtil.getRelativePath(baseDirPath, source);\r
- String[] includes = emptyIncludeArray;\r
- if (canParse(source)) {\r
- Parser parser = createParser(source);\r
- try {\r
- Reader reader = new BufferedReader(new FileReader(source));\r
- parser.parse(reader);\r
- includes = parser.getIncludes();\r
- } catch (IOException ex) {\r
- task.log("Error parsing " + source.toString() + ":"\r
- + ex.toString());\r
- includes = new String[0];\r
- }\r
- }\r
- for (int i = 0; i < includes.length; i++) {\r
- String includeName = includes[i];\r
- if (!resolveInclude(includeName, sourcePath, onIncludePath)) {\r
- if (!resolveInclude(includeName, includePath, onIncludePath)) {\r
- if (!resolveInclude(includeName, sysIncludePath,\r
- onSysIncludePath)) {\r
- if (!resolveInclude(includeName, envIncludePath,\r
- onSysIncludePath)) {\r
- //\r
- // this should be enough to require us to reparse\r
- // the file with the missing include for dependency\r
- // information without forcing a rebuild\r
- sourceLastModified++;\r
- }\r
- }\r
- }\r
- }\r
- }\r
- for (int i = 0; i < onIncludePath.size(); i++) {\r
- String relativeInclude = CUtil.getRelativePath(baseDirPath,\r
- (File) onIncludePath.elementAt(i));\r
- onIncludePath.setElementAt(relativeInclude, i);\r
- }\r
- for (int i = 0; i < onSysIncludePath.size(); i++) {\r
- String relativeInclude = CUtil.getRelativePath(baseDirPath,\r
- (File) onSysIncludePath.elementAt(i));\r
- onSysIncludePath.setElementAt(relativeInclude, i);\r
- }\r
- return new DependencyInfo(includePathIdentifier, relativeSource,\r
- sourceLastModified, onIncludePath, onSysIncludePath);\r
- }\r
- protected boolean resolveInclude(String includeName, File[] includePath,\r
- Vector onThisPath) {\r
- for (int i = 0; i < includePath.length; i++) {\r
- File includeFile = new File(includePath[i], includeName);\r
- if (includeFile.exists()) {\r
- onThisPath.addElement(includeFile);\r
- return true;\r
- }\r
- }\r
- return false;\r
- }\r
-}\r