--- /dev/null
+/*\r
+ * \r
+ * Copyright 2001-2004 The Ant-Contrib project\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package net.sf.antcontrib.cpptasks.types;\r
+import java.io.File;\r
+\r
+import net.sf.antcontrib.cpptasks.CUtil;\r
+import net.sf.antcontrib.cpptasks.FileVisitor;\r
+import net.sf.antcontrib.cpptasks.compiler.Linker;\r
+\r
+import org.apache.tools.ant.BuildException;\r
+import org.apache.tools.ant.DirectoryScanner;\r
+import org.apache.tools.ant.Project;\r
+import org.apache.tools.ant.ProjectComponent;\r
+import org.apache.tools.ant.types.FileSet;\r
+import org.apache.tools.ant.types.PatternSet;\r
+/**\r
+ * A set of library names. Libraries can also be added to a link by specifying\r
+ * them in a fileset.\r
+ * \r
+ * For most Unix-like compilers, libset will result in a series of -l and -L\r
+ * linker arguments. For Windows compilers, the library names will be used to\r
+ * locate the appropriate library files which will be added to the linkers\r
+ * input file list as if they had been specified in a fileset.\r
+ * \r
+ * @author Mark A Russell <a\r
+ * href="mailto:mark_russell@csgsystems.com">mark_russell@csg_systems.com\r
+ * </a>\r
+ * @author Adam Murdoch\r
+ * @author Curt Arnold\r
+ */\r
+public class LibrarySet extends ProjectComponent {\r
+ private String dataset;\r
+ private boolean explicitCaseSensitive;\r
+ private String ifCond;\r
+ private String[] libnames;\r
+ private final FileSet set = new FileSet();\r
+ private String unlessCond;\r
+ private LibraryTypeEnum libraryType;\r
+ public LibrarySet() {\r
+ libnames = new String[0];\r
+ }\r
+ public void execute() throws org.apache.tools.ant.BuildException {\r
+ throw new org.apache.tools.ant.BuildException(\r
+ "Not an actual task, but looks like one for documentation purposes");\r
+ }\r
+ /**\r
+ * Gets the dataset. Used on OS390 if the libs are in a dataset.\r
+ * \r
+ * @return Returns a String\r
+ */\r
+ public String getDataset() {\r
+ return dataset;\r
+ }\r
+ public File getDir(Project project) {\r
+ return set.getDir(project);\r
+ }\r
+ protected FileSet getFileSet() {\r
+ return set;\r
+ }\r
+ public String[] getLibs() {\r
+ String[] retval = (String[]) libnames.clone();\r
+ return retval;\r
+ }\r
+ \r
+ /**\r
+ * Gets preferred library type\r
+ * \r
+ * @return library type, may be null.\r
+ */\r
+ public LibraryTypeEnum getType() {\r
+ return libraryType;\r
+ }\r
+ /**\r
+ * Returns true if the define's if and unless conditions (if any) are\r
+ * satisfied.\r
+ */\r
+ public boolean isActive(org.apache.tools.ant.Project p) {\r
+ if (p == null) {\r
+ throw new NullPointerException("p");\r
+ }\r
+ if (ifCond != null) {\r
+ String ifValue = p.getProperty(ifCond);\r
+ if (ifValue != null) {\r
+ if (ifValue.equals("no") || ifValue.equals("false")) {\r
+ throw new BuildException(\r
+ "property "\r
+ + ifCond\r
+ + " used as if condition has value "\r
+ + ifValue\r
+ + " which suggests a misunderstanding of if attributes");\r
+ }\r
+ } else {\r
+ return false;\r
+ }\r
+ }\r
+ if (unlessCond != null) {\r
+ String unlessValue = p.getProperty(unlessCond);\r
+ if (unlessValue != null) {\r
+ if (unlessValue.equals("no") || unlessValue.equals("false")) {\r
+ throw new BuildException(\r
+ "property "\r
+ + unlessCond\r
+ + " used as unless condition has value "\r
+ + unlessValue\r
+ + " which suggests a misunderstanding of unless attributes");\r
+ }\r
+ return false;\r
+ }\r
+ }\r
+ if (libnames.length == 0) {\r
+ p.log("libnames not specified or empty.", Project.MSG_WARN);\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+ /**\r
+ * Sets case sensitivity of the file system. If not set, will default to\r
+ * the linker's case sensitivity.\r
+ * \r
+ * @param isCaseSensitive\r
+ * "true"|"on"|"yes" if file system is case sensitive,\r
+ * "false"|"off"|"no" when not.\r
+ */\r
+ public void setCaseSensitive(boolean isCaseSensitive) {\r
+ explicitCaseSensitive = true;\r
+ set.setCaseSensitive(isCaseSensitive);\r
+ }\r
+ /**\r
+ * Sets the dataset. Used on OS390 if the libs are in a dataset.\r
+ * \r
+ * @param dataset\r
+ * The dataset to set\r
+ */\r
+ public void setDataset(String dataset) {\r
+ this.dataset = dataset;\r
+ }\r
+ /**\r
+ * Library directory.\r
+ * \r
+ * @param dir\r
+ * library directory\r
+ * \r
+ */\r
+ public void setDir(File dir) throws BuildException {\r
+ set.setDir(dir);\r
+ }\r
+ /**\r
+ * Sets the property name for the 'if' condition.\r
+ * \r
+ * The library set will be ignored unless the property is defined.\r
+ * \r
+ * The value of the property is insignificant, but values that would imply\r
+ * misinterpretation ("false", "no") will throw an exception when\r
+ * evaluated.\r
+ * \r
+ * @param propName\r
+ * property name\r
+ */\r
+ public void setIf(String propName) {\r
+ ifCond = propName;\r
+ }\r
+ /**\r
+ * Comma-separated list of library names without leading prefixes, such as\r
+ * "lib", or extensions, such as ".so" or ".a".\r
+ * \r
+ */\r
+ public void setLibs(CUtil.StringArrayBuilder libs) throws BuildException {\r
+ libnames = libs.getValue();\r
+ // If this is not active.. then it's ok if the lib names are invalid.\r
+ // so we can do a: <libset if="x.lib" dir="." libs="${x.lib}"/>\r
+ if (!isActive(getProject()))\r
+ return;\r
+ for (int i = 0; i < libnames.length; i++) {\r
+ int lastDot = libnames[i].lastIndexOf('.');\r
+ if (lastDot >= 0) {\r
+ String extension = libnames[i].substring(lastDot);\r
+ if (extension.equalsIgnoreCase(".lib")\r
+ || extension.equalsIgnoreCase(".so")\r
+ || extension.equalsIgnoreCase(".a")) {\r
+ getProject().log(\r
+ "Suspicious library name ending with \""\r
+ + extension + "\": " + libnames[i], Project.MSG_DEBUG );\r
+ }\r
+ }\r
+ if (libnames[i].length() >= 3\r
+ && libnames[i].substring(0, 3).equalsIgnoreCase("lib")) {\r
+ getProject().log(\r
+ "Suspicious library name starting with \"lib\": "\r
+ + libnames[i], Project.MSG_DEBUG);\r
+ }\r
+ }\r
+ }\r
+ public void setProject(Project project) {\r
+ set.setProject(project);\r
+ super.setProject(project);\r
+ }\r
+ /**\r
+ * Set the property name for the 'unless' condition.\r
+ * \r
+ * If named property is set, the library set will be ignored.\r
+ * \r
+ * The value of the property is insignificant, but values that would imply\r
+ * misinterpretation ("false", "no") of the behavior will throw an\r
+ * exception when evaluated.\r
+ * \r
+ * @param propName\r
+ * name of property\r
+ */\r
+ public void setUnless(String propName) {\r
+ unlessCond = propName;\r
+ }\r
+ \r
+ /**\r
+ * Sets the preferred library type. Supported values "shared", "static", and\r
+ * "framework". "framework" is equivalent to "shared" on non-Darwin platforms. \r
+ */\r
+ public void setType(LibraryTypeEnum type) {\r
+ this.libraryType = type;\r
+ }\r
+ \r
+ public void visitLibraries(Project project, Linker linker, File[] libpath,\r
+ FileVisitor visitor) throws BuildException {\r
+ FileSet localSet = (FileSet) set.clone();\r
+ //\r
+ // unless explicitly set\r
+ // will default to the linker case sensitivity\r
+ //\r
+ if (!explicitCaseSensitive) {\r
+ boolean linkerCaseSensitive = linker.isCaseSensitive();\r
+ localSet.setCaseSensitive(linkerCaseSensitive);\r
+ }\r
+ //\r
+ // if there was a libs attribute then\r
+ // add the corresponding patterns to the FileSet\r
+ //\r
+ if (libnames != null && libnames.length > 0) {\r
+ String[] patterns = linker.getLibraryPatterns(libnames, libraryType);\r
+ //\r
+ // if no patterns, then linker does not support libraries\r
+ //\r
+ if (patterns.length > 0) {\r
+ for (int i = 0; i < patterns.length; i++) {\r
+ PatternSet.NameEntry entry = localSet.createInclude();\r
+ entry.setName(patterns[i]);\r
+ }\r
+ //\r
+ // if there was no specified directory then\r
+ // run through the libpath backwards\r
+ //\r
+ if (localSet.getDir(project) == null) {\r
+ //\r
+ // scan libpath in reverse order\r
+ // to give earlier entries priority\r
+ //\r
+ for (int j = libpath.length - 1; j >= 0; j--) {\r
+ FileSet clone = (FileSet) localSet.clone();\r
+ clone.setDir(libpath[j]);\r
+ DirectoryScanner scanner = clone.getDirectoryScanner(project);\r
+ File basedir = scanner.getBasedir();\r
+ String[] files = scanner.getIncludedFiles();\r
+ for (int k = 0; k < files.length; k++) {\r
+ visitor.visit(basedir, files[k]);\r
+ }\r
+ }\r
+ } else {\r
+ DirectoryScanner scanner = localSet.getDirectoryScanner(project);\r
+ File basedir = scanner.getBasedir();\r
+ String[] files = scanner.getIncludedFiles();\r
+ for (int k = 0; k < files.length; k++) {\r
+ visitor.visit(basedir, files[k]);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r