/* * * Copyright 2002-2004 The Ant-Contrib project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.sf.antcontrib.cpptasks.os390; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Vector; import net.sf.antcontrib.cpptasks.CCTask; import net.sf.antcontrib.cpptasks.CUtil; import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; import net.sf.antcontrib.cpptasks.compiler.LinkType; import net.sf.antcontrib.cpptasks.compiler.Linker; import net.sf.antcontrib.cpptasks.types.LibrarySet; import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; import net.sf.antcontrib.cpptasks.VersionInfo; import org.apache.tools.ant.BuildException; /** * Adapter for the IBM (R) OS/390 (tm) Linker * * @author Hiram Chirino (cojonudo14@hotmail.com) */ public final class OS390Linker extends CommandLineLinker { private static final OS390Linker datasetLinker = new OS390Linker(); private static final OS390Linker dllLinker = new OS390Linker("", ".dll"); private static final OS390Linker instance = new OS390Linker("", ""); public static OS390Linker getDataSetInstance() { return datasetLinker; } public static OS390Linker getInstance() { return instance; } private boolean isADatasetLinker; File outputFile; private String outputPrefix; CCTask task; private OS390Linker() { super("cxx", "/bogus", new String[]{".o", ".a", ".lib", ".xds"}, new String[]{".dll", ".x"}, ".xds", false, null); this.outputPrefix = ""; this.isADatasetLinker = true; } private OS390Linker(String outputPrefix, String outputSuffix) { super("cxx", "/bogus", new String[]{".o", ".a", ".lib", ".x"}, new String[]{".dll"}, outputSuffix, false, null); this.outputPrefix = outputPrefix; this.isADatasetLinker = false; } protected void addBase(long base, Vector args) { } protected void addFixed(Boolean fixed, Vector args) { } protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { if (linkType.isSharedLibrary()) { args.addElement("-W"); args.addElement("l,DLL"); } } protected void addIncremental(boolean incremental, Vector args) { } /* * @see CommandLineLinker#addLibrarySets(LibrarySet[], Vector, Vector, * Vector) */ protected String[] addLibrarySets(CCTask task, LibrarySet[] libsets, Vector preargs, Vector midargs, Vector endargs) { // If yo want to link against a library sitting in a dataset and // not in the HFS, you can just use the //'dataset' notation // to specify it. e.g: // <libset dir="." libs="//'MQM.V5R2M0.SCSQLOAD'"/> // // We have to have special handling here because the file is not // on the normal filesystem so the task will not noramly include it // as part of the link command. if (libsets != null) { for (int i = 0; i < libsets.length; i++) { String libs[] = libsets[i].getLibs(); for (int j = 0; j < libs.length; j++) { if (libs[j].startsWith("//")) { endargs.addElement("-l"); endargs.addElement(libs[j]); } else if (libsets[i].getDataset() != null) { String ds = libsets[i].getDataset(); endargs.addElement("//'" + ds + "(" + libs[j] + ")'"); } } } } return super.addLibrarySets(task, libsets, preargs, midargs, endargs); } protected void addMap(boolean map, Vector args) { } protected void addStack(int stack, Vector args) { } protected void addEntry(String entry, Vector args) { } public String getCommandFileSwitch(String commandFile) { return "@" + commandFile; } public File[] getLibraryPath() { return CUtil.getPathFromEnvironment("LIB", ";"); } public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { StringBuffer buf = new StringBuffer(); String[] patterns = new String[libnames.length * 3]; int offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0); offset = addLibraryPatterns(libnames, buf, "", ".x", patterns, offset); offset = addLibraryPatterns(libnames, buf, "", ".o", patterns, offset); return patterns; } private static int addLibraryPatterns(String[] libnames, StringBuffer buf, String prefix, String extension, String[] patterns, int offset) { for (int i = 0; i < libnames.length; i++) { buf.setLength(0); buf.append(prefix); buf.append(libnames[i]); buf.append(extension); patterns[offset + i] = buf.toString(); } return offset + libnames.length; } public Linker getLinker(LinkType linkType) { if (this == datasetLinker) return datasetLinker; if (linkType.isSharedLibrary()) return dllLinker; return instance; } public int getMaximumCommandLength() { return Integer.MAX_VALUE; } public String[] getOutputFileNames(String baseName, VersionInfo versionInfo) { String[] baseNames = super.getOutputFileNames(baseName, versionInfo); if (outputPrefix.length() > 0) { for(int i = 0; i < baseNames.length; i++) { baseNames[i] = outputPrefix + baseNames[i]; } } return baseNames; } protected String[] getOutputFileSwitch(CCTask task, String outputFile) { if (isADatasetLinker && task.getDataset() != null) { String ds = task.getDataset(); outputFile = "//'" + ds + "(" + outputFile + ")'"; } return getOutputFileSwitch(outputFile); } public String[] getOutputFileSwitch(String outputFile) { return new String[]{"-o", outputFile}; } public boolean isCaseSensitive() { return OS390Processor.isCaseSensitive(); } /* * @see CommandLineLinker#link(Task, File, String[], * CommandLineLinkerConfiguration) */ public void link(CCTask task, File outputFile, String[] sourceFiles, CommandLineLinkerConfiguration config) throws BuildException { this.task = task; this.outputFile = outputFile; if (isADatasetLinker) { int p = outputFile.getName().indexOf("."); if (p >= 0) { String newname = outputFile.getName().substring(0, p); outputFile = new File(outputFile.getParent(), newname); } } super.link(task, outputFile, sourceFiles, config); } /* * @see CommandLineLinker#runCommand(Task, File, String[]) */ protected int runCommand(CCTask task, File workingDir, String[] cmdline) throws BuildException { int rc = super.runCommand(task, workingDir, cmdline); // create the .xds file if everything was ok. if (rc == 0) { try { outputFile.delete(); new FileOutputStream(outputFile).close(); } catch (IOException e) { throw new BuildException(e.getMessage()); } } return rc; } }