View Javadoc

1   /*
2    * #%L
3    * Native ARchive plugin for Maven
4    * %%
5    * Copyright (C) 2002 - 2014 NAR Maven Plugin developers.
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   * 
11   * http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package com.github.maven_nar.cpptasks;
21  
22  import java.io.File;
23  import java.util.Map;
24  import java.util.Vector;
25  
26  import org.apache.tools.ant.BuildException;
27  
28  import com.github.maven_nar.cpptasks.compiler.LinkerConfiguration;
29  import com.github.maven_nar.cpptasks.compiler.ProcessorConfiguration;
30  
31  /**
32   * This class matches each visited file with an appropriate compiler
33   *
34   * @author Curt Arnold
35   */
36  public final class TargetMatcher implements FileVisitor {
37    private final LinkerConfiguration linker;
38    private final Vector<File> objectFiles;
39    private final File outputDir;
40    private final ProcessorConfiguration[] processors;
41    private final File sourceFiles[] = new File[1];
42    private final Map<String, TargetInfo> targets;
43    private final VersionInfo versionInfo;
44    private final CCTask task;
45  
46    public TargetMatcher(final CCTask task, final File outputDir, final ProcessorConfiguration[] processors,
47        final LinkerConfiguration linker, final Vector<File> objectFiles, final Map<String, TargetInfo> targets,
48        final VersionInfo versionInfo) {
49      this.task = task;
50      this.outputDir = outputDir;
51      this.processors = processors;
52      this.targets = targets;
53      this.linker = linker;
54      this.objectFiles = objectFiles;
55      this.versionInfo = versionInfo;
56    }
57  
58    @Override
59    public void visit(final File parentDir, final String filename) throws BuildException {
60      final File fullPath = new File(parentDir, filename);
61      //
62      // see if any processor wants to bid
63      // on this one
64      ProcessorConfiguration selectedCompiler = null;
65      int bid = 0;
66      if (this.processors != null) {
67        for (final ProcessorConfiguration processor : this.processors) {
68          final int newBid = processor.bid(fullPath.toString());
69          if (newBid > bid) {
70            bid = newBid;
71            selectedCompiler = processor;
72          }
73        }
74      }
75      //
76      // no processor interested in file
77      // log diagnostic message
78      if (bid <= 0) {
79        if (this.linker != null) {
80          final int linkerbid = this.linker.bid(filename);
81          if (linkerbid > 0) {
82            this.objectFiles.addElement(fullPath);
83            if (linkerbid == 1) {
84              this.task.log("Unrecognized file type " + fullPath.toString() + " will be passed to linker");
85            }
86          }
87        }
88      } else {
89        //
90        // get output file name
91        // requires full path as output name may be changed based on location
92        //
93        final String[] outputFileNames = selectedCompiler.getOutputFileNames(fullPath.getPath(), this.versionInfo);
94        this.sourceFiles[0] = fullPath;
95        //
96        // if there is some output for this task
97        // (that is a source file and not an header file)
98        //
99        for (final String outputFileName : outputFileNames) {
100         //
101         // see if the same output file has already been registered
102         //
103         final TargetInfo previousTarget = this.targets.get(outputFileName);
104         if (previousTarget == null) {
105           this.targets.put(outputFileName, new TargetInfo(selectedCompiler, this.sourceFiles, null, new File(
106               this.outputDir, outputFileName), selectedCompiler.getRebuild()));
107         } else {
108           if (!previousTarget.getSources()[0].equals(this.sourceFiles[0])) {
109             final String builder = "Output filename conflict: " + outputFileName +
110                 " would be produced from " +
111                 previousTarget.getSources()[0].toString() +
112                 " and " +
113                 filename;
114             throw new BuildException(builder);
115           }
116         }
117       }
118     }
119   }
120 }