]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Java/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AbstractCompiler.java
Restructuring for better separation of Tool packages.
[mirror_edk2.git] / Tools / Java / Source / Cpptasks / net / sf / antcontrib / cpptasks / compiler / AbstractCompiler.java
1 /*
2 *
3 * Copyright 2002-2004 The Ant-Contrib project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package net.sf.antcontrib.cpptasks.compiler;
18 import java.io.BufferedReader;
19 import java.io.File;
20 import java.io.FileReader;
21 import java.io.IOException;
22 import java.io.Reader;
23 import java.util.Vector;
24 import net.sf.antcontrib.cpptasks.CCTask;
25 import net.sf.antcontrib.cpptasks.CUtil;
26 import net.sf.antcontrib.cpptasks.CompilerDef;
27 import net.sf.antcontrib.cpptasks.DependencyInfo;
28 import net.sf.antcontrib.cpptasks.ProcessorDef;
29 import net.sf.antcontrib.cpptasks.parser.Parser;
30 import net.sf.antcontrib.cpptasks.TargetDef;
31
32 /**
33 * An abstract compiler implementation.
34 *
35 * @author Adam Murdoch
36 * @author Curt Arnold
37 */
38 public abstract class AbstractCompiler extends AbstractProcessor
39 implements
40 Compiler {
41 private static final String[] emptyIncludeArray = new String[0];
42 private String outputSuffix;
43 protected AbstractCompiler(String[] sourceExtensions,
44 String[] headerExtensions, String outputSuffix) {
45 super(sourceExtensions, headerExtensions);
46 this.outputSuffix = outputSuffix;
47 }
48 /**
49 * Checks file name to see if parse should be attempted
50 *
51 * Default implementation returns false for files with extensions '.dll',
52 * 'tlb', '.res'
53 *
54 */
55 protected boolean canParse(File sourceFile) {
56 String sourceName = sourceFile.toString();
57 int lastPeriod = sourceName.lastIndexOf('.');
58 if (lastPeriod >= 0 && lastPeriod == sourceName.length() - 4) {
59 String ext = sourceName.substring(lastPeriod).toUpperCase();
60 if (ext.equals(".DLL") || ext.equals(".TLB") || ext.equals(".RES")) {
61 return false;
62 }
63 }
64 return true;
65 }
66 abstract protected CompilerConfiguration createConfiguration(CCTask task,
67 LinkType linkType, ProcessorDef[] baseConfigs,
68 CompilerDef specificConfig, TargetDef targetPlatform);
69 public ProcessorConfiguration createConfiguration(CCTask task,
70 LinkType linkType, ProcessorDef[] baseConfigs,
71 ProcessorDef specificConfig, TargetDef targetPlatform) {
72 if (specificConfig == null) {
73 throw new NullPointerException("specificConfig");
74 }
75 return createConfiguration(task, linkType, baseConfigs,
76 (CompilerDef) specificConfig, targetPlatform);
77 }
78 abstract protected Parser createParser(File sourceFile);
79 protected String getBaseOutputName(String inputFile) {
80 int lastSlash = inputFile.lastIndexOf('/');
81 int lastReverse = inputFile.lastIndexOf('\\');
82 int lastSep = inputFile.lastIndexOf(File.separatorChar);
83 if (lastReverse > lastSlash) {
84 lastSlash = lastReverse;
85 }
86 if (lastSep > lastSlash) {
87 lastSlash = lastSep;
88 }
89 int lastPeriod = inputFile.lastIndexOf('.');
90 if (lastPeriod < 0) {
91 lastPeriod = inputFile.length();
92 }
93 return inputFile.substring(lastSlash + 1, lastPeriod);
94 }
95 public String getOutputFileName(String inputFile) {
96 //
97 // if a recognized input file
98 //
99 if (bid(inputFile) > 1) {
100 String baseName = getBaseOutputName(inputFile);
101 return baseName + outputSuffix;
102 }
103 return null;
104 }
105 /**
106 * Returns dependency info for the specified source file
107 *
108 * @param task
109 * task for any diagnostic output
110 * @param source
111 * file to be parsed
112 * @param includePath
113 * include path to be used to resolve included files
114 *
115 * @param sysIncludePath
116 * sysinclude path from build file, files resolved using
117 * sysInclude path will not participate in dependency analysis
118 *
119 * @param envIncludePath
120 * include path from environment variable, files resolved with
121 * envIncludePath will not participate in dependency analysis
122 *
123 * @param baseDir
124 * used to produce relative paths in DependencyInfo
125 * @param includePathIdentifier
126 * used to distinguish DependencyInfo's from different include
127 * path settings
128 *
129 * @author Curt Arnold
130 */
131 public final DependencyInfo parseIncludes(CCTask task, File source,
132 File[] includePath, File[] sysIncludePath, File[] envIncludePath,
133 File baseDir, String includePathIdentifier) {
134 //
135 // if any of the include files can not be identified
136 // change the sourceLastModified to Long.MAX_VALUE to
137 // force recompilation of anything that depends on it
138 long sourceLastModified = source.lastModified();
139 File[] sourcePath = new File[1];
140 sourcePath[0] = new File(source.getParent());
141 Vector onIncludePath = new Vector();
142 Vector onSysIncludePath = new Vector();
143 String baseDirPath;
144 try {
145 baseDirPath = baseDir.getCanonicalPath();
146 } catch (IOException ex) {
147 baseDirPath = baseDir.toString();
148 }
149 String relativeSource = CUtil.getRelativePath(baseDirPath, source);
150 String[] includes = emptyIncludeArray;
151 if (canParse(source)) {
152 Parser parser = createParser(source);
153 try {
154 Reader reader = new BufferedReader(new FileReader(source));
155 parser.parse(reader);
156 includes = parser.getIncludes();
157 } catch (IOException ex) {
158 task.log("Error parsing " + source.toString() + ":"
159 + ex.toString());
160 includes = new String[0];
161 }
162 }
163 for (int i = 0; i < includes.length; i++) {
164 String includeName = includes[i];
165 if (!resolveInclude(includeName, sourcePath, onIncludePath)) {
166 if (!resolveInclude(includeName, includePath, onIncludePath)) {
167 if (!resolveInclude(includeName, sysIncludePath,
168 onSysIncludePath)) {
169 if (!resolveInclude(includeName, envIncludePath,
170 onSysIncludePath)) {
171 //
172 // this should be enough to require us to reparse
173 // the file with the missing include for dependency
174 // information without forcing a rebuild
175 sourceLastModified++;
176 }
177 }
178 }
179 }
180 }
181 for (int i = 0; i < onIncludePath.size(); i++) {
182 String relativeInclude = CUtil.getRelativePath(baseDirPath,
183 (File) onIncludePath.elementAt(i));
184 onIncludePath.setElementAt(relativeInclude, i);
185 }
186 for (int i = 0; i < onSysIncludePath.size(); i++) {
187 String relativeInclude = CUtil.getRelativePath(baseDirPath,
188 (File) onSysIncludePath.elementAt(i));
189 onSysIncludePath.setElementAt(relativeInclude, i);
190 }
191 return new DependencyInfo(includePathIdentifier, relativeSource,
192 sourceLastModified, onIncludePath, onSysIncludePath);
193 }
194 protected boolean resolveInclude(String includeName, File[] includePath,
195 Vector onThisPath) {
196 for (int i = 0; i < includePath.length; i++) {
197 File includeFile = new File(includePath[i], includeName);
198 if (includeFile.exists()) {
199 onThisPath.addElement(includeFile);
200 return true;
201 }
202 }
203 return false;
204 }
205 }