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.os390;
21
22 import java.io.File;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.util.Vector;
26
27 import org.apache.tools.ant.BuildException;
28
29 import com.github.maven_nar.cpptasks.CCTask;
30 import com.github.maven_nar.cpptasks.CUtil;
31 import com.github.maven_nar.cpptasks.VersionInfo;
32 import com.github.maven_nar.cpptasks.compiler.CommandLineLinker;
33 import com.github.maven_nar.cpptasks.compiler.CommandLineLinkerConfiguration;
34 import com.github.maven_nar.cpptasks.compiler.LinkType;
35 import com.github.maven_nar.cpptasks.compiler.Linker;
36 import com.github.maven_nar.cpptasks.types.LibrarySet;
37 import com.github.maven_nar.cpptasks.types.LibraryTypeEnum;
38
39
40
41
42
43
44 public final class OS390Linker extends CommandLineLinker {
45 private static final OS390Linker datasetLinker = new OS390Linker();
46 private static final OS390Linker dllLinker = new OS390Linker("", ".dll");
47 private static final OS390Linker instance = new OS390Linker("", "");
48
49 private static int addLibraryPatterns(final String[] libnames, final StringBuffer buf, final String prefix,
50 final String extension, final String[] patterns, final int offset) {
51 for (int i = 0; i < libnames.length; i++) {
52 buf.setLength(0);
53 buf.append(prefix);
54 buf.append(libnames[i]);
55 buf.append(extension);
56 patterns[offset + i] = buf.toString();
57 }
58 return offset + libnames.length;
59 }
60
61 public static OS390Linker getDataSetInstance() {
62 return datasetLinker;
63 }
64
65 public static OS390Linker getInstance() {
66 return instance;
67 }
68
69 private final boolean isADatasetLinker;
70 File outputFile;
71 private final String outputPrefix;
72 CCTask task;
73
74 private OS390Linker() {
75 super("cxx", "/bogus", new String[] {
76 ".o", ".a", ".lib", ".xds"
77 }, new String[] {
78 ".dll", ".x"
79 }, ".xds", false, null);
80 this.outputPrefix = "";
81 this.isADatasetLinker = true;
82 }
83
84 private OS390Linker(final String outputPrefix, final String outputSuffix) {
85 super("cxx", "/bogus", new String[] {
86 ".o", ".a", ".lib", ".x"
87 }, new String[] {
88 ".dll"
89 }, outputSuffix, false, null);
90 this.outputPrefix = outputPrefix;
91 this.isADatasetLinker = false;
92 }
93
94 protected void addBase(final long base, final Vector<String> args) {
95 }
96
97 protected void addEntry(final String entry, final Vector<String> args) {
98 }
99
100 protected void addFixed(final Boolean fixed, final Vector<String> args) {
101 }
102
103 protected void addImpliedArgs(final boolean debug, final LinkType linkType, final Vector<String> args) {
104 if (linkType.isSharedLibrary()) {
105 args.addElement("-W");
106 args.addElement("l,DLL");
107 }
108 }
109
110 protected void addIncremental(final boolean incremental, final Vector<String> args) {
111 }
112
113 @Override
114 protected String[] addLibrarySets(final CCTask task, final LibrarySet[] libsets, final Vector<String> preargs,
115 final Vector<String> midargs, final Vector<String> endargs) {
116
117
118
119
120
121
122
123
124 if (libsets != null) {
125 for (final LibrarySet libset : libsets) {
126 final String libs[] = libset.getLibs();
127 for (final String lib : libs) {
128 if (lib.startsWith("//")) {
129 endargs.addElement("-l");
130 endargs.addElement(lib);
131 } else if (libset.getDataset() != null) {
132 final String ds = libset.getDataset();
133 endargs.addElement("//'" + ds + "(" + lib + ")'");
134 }
135 }
136 }
137 }
138 return super.addLibrarySets(task, libsets, preargs, midargs, endargs);
139 }
140
141 protected void addMap(final boolean map, final Vector<String> args) {
142 }
143
144 protected void addStack(final int stack, final Vector<String> args) {
145 }
146
147 @Override
148 public String getCommandFileSwitch(final String commandFile) {
149 return "@" + commandFile;
150 }
151
152 @Override
153 public File[] getLibraryPath() {
154 return CUtil.getPathFromEnvironment("LIB", ";");
155 }
156
157 @Override
158 public String[] getLibraryPatterns(final String[] libnames, final LibraryTypeEnum libType) {
159 final StringBuffer buf = new StringBuffer();
160 final String[] patterns = new String[libnames.length * 3];
161 int offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0);
162 offset = addLibraryPatterns(libnames, buf, "", ".x", patterns, offset);
163 offset = addLibraryPatterns(libnames, buf, "", ".o", patterns, offset);
164 return patterns;
165 }
166
167 @Override
168 public Linker getLinker(final LinkType linkType) {
169 if (this == datasetLinker) {
170 return datasetLinker;
171 }
172 if (linkType.isSharedLibrary()) {
173 return dllLinker;
174 }
175 return instance;
176 }
177
178 @Override
179 public int getMaximumCommandLength() {
180 return Integer.MAX_VALUE;
181 }
182
183 @Override
184 public String[] getOutputFileNames(final String baseName, final VersionInfo versionInfo) {
185 final String[] baseNames = super.getOutputFileNames(baseName, versionInfo);
186 if (this.outputPrefix.length() > 0) {
187 for (int i = 0; i < baseNames.length; i++) {
188 baseNames[i] = this.outputPrefix + baseNames[i];
189 }
190 }
191 return baseNames;
192 }
193
194 @Override
195 protected String[] getOutputFileSwitch(final CCTask task, String outputFile) {
196 if (this.isADatasetLinker && task.getDataset() != null) {
197 final String ds = task.getDataset();
198 outputFile = "//'" + ds + "(" + outputFile + ")'";
199 }
200 return getOutputFileSwitch(outputFile);
201 }
202
203 @Override
204 public String[] getOutputFileSwitch(final String outputFile) {
205 return new String[] {
206 "-o", outputFile
207 };
208 }
209
210 @Override
211 public boolean isCaseSensitive() {
212 return OS390Processor.isCaseSensitive();
213 }
214
215 @Override
216 public void link(final CCTask task, File outputFile, final String[] sourceFiles,
217 final CommandLineLinkerConfiguration config) throws BuildException {
218 this.task = task;
219 this.outputFile = outputFile;
220 if (this.isADatasetLinker) {
221 final int p = outputFile.getName().indexOf(".");
222 if (p >= 0) {
223 final String newname = outputFile.getName().substring(0, p);
224 outputFile = new File(outputFile.getParent(), newname);
225 }
226 }
227 super.link(task, outputFile, sourceFiles, config);
228 }
229
230 @Override
231 protected int runCommand(final CCTask task, final File workingDir, final String[] cmdline) throws BuildException {
232 final int rc = super.runCommand(task, workingDir, cmdline);
233
234 if (rc == 0) {
235 try {
236 this.outputFile.delete();
237 new FileOutputStream(this.outputFile).close();
238 } catch (final IOException e) {
239 throw new BuildException(e.getMessage());
240 }
241 }
242 return rc;
243 }
244 }