3 * Copyright 2002-2004 The Ant-Contrib project
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package net
.sf
.antcontrib
.cpptasks
.os390
;
19 import java
.io
.FileOutputStream
;
20 import java
.io
.IOException
;
21 import java
.util
.Vector
;
23 import net
.sf
.antcontrib
.cpptasks
.CCTask
;
24 import net
.sf
.antcontrib
.cpptasks
.CUtil
;
25 import net
.sf
.antcontrib
.cpptasks
.compiler
.CommandLineLinker
;
26 import net
.sf
.antcontrib
.cpptasks
.compiler
.CommandLineLinkerConfiguration
;
27 import net
.sf
.antcontrib
.cpptasks
.compiler
.LinkType
;
28 import net
.sf
.antcontrib
.cpptasks
.compiler
.Linker
;
29 import net
.sf
.antcontrib
.cpptasks
.types
.LibrarySet
;
30 import net
.sf
.antcontrib
.cpptasks
.types
.LibraryTypeEnum
;
32 import org
.apache
.tools
.ant
.BuildException
;
34 * Adapter for the IBM (R) OS/390 (tm) Linker
36 * @author Hiram Chirino (cojonudo14@hotmail.com)
38 public final class OS390Linker
extends CommandLineLinker
{
39 private static final OS390Linker datasetLinker
= new OS390Linker();
40 private static final OS390Linker dllLinker
= new OS390Linker("", ".dll");
41 private static final OS390Linker instance
= new OS390Linker("", "");
42 public static OS390Linker
getDataSetInstance() {
45 public static OS390Linker
getInstance() {
48 private boolean isADatasetLinker
;
50 private String outputPrefix
;
52 private OS390Linker() {
53 super("cxx", "/bogus", new String
[]{".o", ".a", ".lib", ".xds"},
54 new String
[]{".dll", ".x"}, ".xds", false, null);
55 this.outputPrefix
= "";
56 this.isADatasetLinker
= true;
58 private OS390Linker(String outputPrefix
, String outputSuffix
) {
59 super("cxx", "/bogus", new String
[]{".o", ".a", ".lib", ".x"},
60 new String
[]{".dll"}, outputSuffix
, false, null);
61 this.outputPrefix
= outputPrefix
;
62 this.isADatasetLinker
= false;
64 protected void addBase(long base
, Vector args
) {
66 protected void addFixed(Boolean fixed
, Vector args
) {
68 protected void addImpliedArgs(boolean debug
, LinkType linkType
, Vector args
, Boolean defaultflag
) {
69 if (linkType
.isSharedLibrary()) {
70 args
.addElement("-W");
71 args
.addElement("l,DLL");
74 protected void addIncremental(boolean incremental
, Vector args
) {
77 * @see CommandLineLinker#addLibrarySets(LibrarySet[], Vector, Vector,
80 protected String
[] addLibrarySets(CCTask task
, LibrarySet
[] libsets
,
81 Vector preargs
, Vector midargs
, Vector endargs
) {
82 // If yo want to link against a library sitting in a dataset and
83 // not in the HFS, you can just use the //'dataset' notation
84 // to specify it. e.g:
85 // <libset dir="." libs="//'MQM.V5R2M0.SCSQLOAD'"/>
87 // We have to have special handling here because the file is not
88 // on the normal filesystem so the task will not noramly include it
89 // as part of the link command.
90 if (libsets
!= null) {
91 for (int i
= 0; i
< libsets
.length
; i
++) {
92 String libs
[] = libsets
[i
].getLibs();
93 for (int j
= 0; j
< libs
.length
; j
++) {
94 if (libs
[j
].startsWith("//")) {
95 endargs
.addElement("-l");
96 endargs
.addElement(libs
[j
]);
97 } else if (libsets
[i
].getDataset() != null) {
98 String ds
= libsets
[i
].getDataset();
99 endargs
.addElement("//'" + ds
+ "(" + libs
[j
] + ")'");
104 return super.addLibrarySets(task
, libsets
, preargs
, midargs
, endargs
);
106 protected void addMap(boolean map
, Vector args
) {
108 protected void addStack(int stack
, Vector args
) {
110 protected void addEntry(String entry
, Vector args
) {
113 public String
getCommandFileSwitch(String commandFile
) {
114 return "@" + commandFile
;
116 public File
[] getLibraryPath() {
117 return CUtil
.getPathFromEnvironment("LIB", ";");
120 public String
[] getLibraryPatterns(String
[] libnames
, LibraryTypeEnum libType
) {
121 StringBuffer buf
= new StringBuffer();
122 String
[] patterns
= new String
[libnames
.length
* 3];
123 int offset
= addLibraryPatterns(libnames
, buf
, "lib", ".a", patterns
, 0);
124 offset
= addLibraryPatterns(libnames
, buf
, "", ".x", patterns
, offset
);
125 offset
= addLibraryPatterns(libnames
, buf
, "", ".o", patterns
, offset
);
129 private static int addLibraryPatterns(String
[] libnames
, StringBuffer buf
,
130 String prefix
, String extension
, String
[] patterns
, int offset
) {
131 for (int i
= 0; i
< libnames
.length
; i
++) {
134 buf
.append(libnames
[i
]);
135 buf
.append(extension
);
136 patterns
[offset
+ i
] = buf
.toString();
138 return offset
+ libnames
.length
;
141 public Linker
getLinker(LinkType linkType
) {
142 if (this == datasetLinker
)
143 return datasetLinker
;
144 if (linkType
.isSharedLibrary())
148 public int getMaximumCommandLength() {
149 return Integer
.MAX_VALUE
;
151 public String
getOutputFileName(String baseName
) {
152 return outputPrefix
+ super.getOutputFileName(baseName
);
154 protected String
[] getOutputFileSwitch(CCTask task
, String outputFile
) {
155 if (isADatasetLinker
&& task
.getDataset() != null) {
156 String ds
= task
.getDataset();
157 outputFile
= "//'" + ds
+ "(" + outputFile
+ ")'";
159 return getOutputFileSwitch(outputFile
);
161 public String
[] getOutputFileSwitch(String outputFile
) {
162 return new String
[]{"-o", outputFile
};
164 public boolean isCaseSensitive() {
165 return OS390Processor
.isCaseSensitive();
168 * @see CommandLineLinker#link(Task, File, String[],
169 * CommandLineLinkerConfiguration)
171 public void link(CCTask task
, File outputFile
, String
[] sourceFiles
,
172 CommandLineLinkerConfiguration config
) throws BuildException
{
174 this.outputFile
= outputFile
;
175 if (isADatasetLinker
) {
176 int p
= outputFile
.getName().indexOf(".");
178 String newname
= outputFile
.getName().substring(0, p
);
179 outputFile
= new File(outputFile
.getParent(), newname
);
182 super.link(task
, outputFile
, sourceFiles
, config
);
185 * @see CommandLineLinker#runCommand(Task, File, String[])
187 protected int runCommand(CCTask task
, File workingDir
, String
[] cmdline
)
188 throws BuildException
{
189 int rc
= super.runCommand(task
, workingDir
, cmdline
);
190 // create the .xds file if everything was ok.
194 new FileOutputStream(outputFile
).close();
195 } catch (IOException e
) {
196 throw new BuildException(e
.getMessage());