1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.github.maven_nar.cpptasks.compiler;
21
22 import java.io.BufferedReader;
23 import java.io.File;
24 import java.io.FileReader;
25 import java.io.IOException;
26 import java.io.Reader;
27 import java.util.Vector;
28
29 import org.apache.commons.io.FilenameUtils;
30
31 import com.github.maven_nar.cpptasks.CCTask;
32 import com.github.maven_nar.cpptasks.CUtil;
33 import com.github.maven_nar.cpptasks.CompilerDef;
34 import com.github.maven_nar.cpptasks.DependencyInfo;
35 import com.github.maven_nar.cpptasks.ProcessorDef;
36 import com.github.maven_nar.cpptasks.TargetDef;
37 import com.github.maven_nar.cpptasks.VersionInfo;
38 import com.github.maven_nar.cpptasks.parser.Parser;
39
40
41
42
43
44
45
46 public abstract class AbstractCompiler extends AbstractProcessor implements Compiler {
47 private static final String[] emptyIncludeArray = new String[0];
48 private final String outputSuffix;
49 protected File workDir;
50 protected File objDir;
51
52 protected AbstractCompiler(final String[] sourceExtensions, final String[] headerExtensions, final String outputSuffix) {
53 super(sourceExtensions, headerExtensions);
54 this.outputSuffix = outputSuffix;
55 }
56
57
58
59
60
61
62
63
64 protected boolean canParse(final File sourceFile) {
65 final String sourceName = sourceFile.toString();
66 final int lastPeriod = sourceName.lastIndexOf('.');
67 if (lastPeriod >= 0 && lastPeriod == sourceName.length() - 4) {
68 final String ext = sourceName.substring(lastPeriod).toUpperCase();
69 if (ext.equals(".DLL") || ext.equals(".TLB") || ext.equals(".RES")) {
70 return false;
71 }
72 }
73 return true;
74 }
75
76 abstract protected CompilerConfiguration createConfiguration(CCTask task, LinkType linkType,
77 ProcessorDef[] baseConfigs, CompilerDef specificConfig, TargetDef targetPlatform, VersionInfo versionInfo);
78
79 @Override
80 public ProcessorConfiguration createConfiguration(final CCTask task, final LinkType linkType,
81 final ProcessorDef[] baseConfigs, final ProcessorDef specificConfig, final TargetDef targetPlatform,
82 final VersionInfo versionInfo) {
83 if (specificConfig == null) {
84 throw new NullPointerException("specificConfig");
85 }
86 return createConfiguration(task, linkType, baseConfigs, (CompilerDef) specificConfig, targetPlatform, versionInfo);
87 }
88
89 abstract protected Parser createParser(File sourceFile);
90
91 protected String getBaseOutputName(final String inputFile) {
92 return FilenameUtils.getBaseName(inputFile);
93 }
94
95 @Override
96 public String[] getOutputFileNames(final String inputFile, final VersionInfo versionInfo) {
97
98
99
100 if (bid(inputFile) > 1) {
101 final String baseName = getBaseOutputName(inputFile);
102 return new String[] {
103 baseName + this.outputSuffix
104 };
105 }
106 return new String[0];
107 }
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134 public final DependencyInfo parseIncludes(final CCTask task, final File source, final File[] includePath,
135 final File[] sysIncludePath, final File[] envIncludePath, final File baseDir, final String includePathIdentifier) {
136
137
138
139
140 long sourceLastModified = source.lastModified();
141 final File[] sourcePath = new File[1];
142 sourcePath[0] = new File(source.getParent());
143 final Vector onIncludePath = new Vector();
144 final Vector onSysIncludePath = new Vector();
145 String baseDirPath;
146 try {
147 baseDirPath = baseDir.getCanonicalPath();
148 } catch (final IOException ex) {
149 baseDirPath = baseDir.toString();
150 }
151 final String relativeSource = CUtil.getRelativePath(baseDirPath, source);
152 String[] includes = emptyIncludeArray;
153 if (canParse(source)) {
154 final Parser parser = createParser(source);
155 try {
156 final Reader reader = new BufferedReader(new FileReader(source));
157 parser.parse(reader);
158 includes = parser.getIncludes();
159 } catch (final IOException ex) {
160 task.log("Error parsing " + source.toString() + ":" + ex.toString());
161 includes = new String[0];
162 }
163 }
164 for (final String include : includes) {
165 if (!resolveInclude(include, sourcePath, onIncludePath)) {
166 if (!resolveInclude(include, includePath, onIncludePath)) {
167 if (!resolveInclude(include, sysIncludePath, onSysIncludePath)) {
168 if (!resolveInclude(include, envIncludePath, onSysIncludePath)) {
169
170
171
172
173 sourceLastModified += 2 * CUtil.FILETIME_EPSILON;
174 }
175 }
176 }
177 }
178 }
179 for (int i = 0; i < onIncludePath.size(); i++) {
180 final String relativeInclude = CUtil.getRelativePath(baseDirPath, (File) onIncludePath.elementAt(i));
181 onIncludePath.setElementAt(relativeInclude, i);
182 }
183 for (int i = 0; i < onSysIncludePath.size(); i++) {
184 final String relativeInclude = CUtil.getRelativePath(baseDirPath, (File) onSysIncludePath.elementAt(i));
185 onSysIncludePath.setElementAt(relativeInclude, i);
186 }
187 return new DependencyInfo(includePathIdentifier, relativeSource, sourceLastModified, onIncludePath,
188 onSysIncludePath);
189 }
190
191 protected boolean resolveInclude(final String includeName, final File[] includePath, final Vector onThisPath) {
192 for (final File element : includePath) {
193 final File includeFile = new File(element, includeName);
194 if (includeFile.exists()) {
195 onThisPath.addElement(includeFile);
196 return true;
197 }
198 }
199 return false;
200 }
201
202 public final String getOutputSuffix() {
203 return this.outputSuffix;
204 }
205
206 public void setWorkDir(final File workDir) {
207 this.workDir = workDir;
208 }
209
210 public void setObjDir(final File objDir) {
211 this.objDir = objDir;
212 }
213 }