summaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/AboutCCTask.java49
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ArchEnum.java72
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/CCTask.java1440
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/CCTaskProgressMonitor.java58
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/CPUEnum.java71
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/CUtil.java523
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/CompilerDef.java502
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/CompilerEnum.java262
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/CompilerParam.java33
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/DependencyInfo.java86
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/DependencyTable.java610
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/DistributerDef.java243
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/DistributerMap.java218
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/DistributerProtocolEnum.java50
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/FileVisitor.java27
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/LinkerDef.java509
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/LinkerEnum.java112
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/LinkerParam.java33
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/OSFamilyEnum.java59
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ObjectFileCollector.java42
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/OptimizationEnum.java82
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/OutputTypeEnum.java48
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/PrecompileDef.java212
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/PrecompileExceptDef.java80
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ProcessorDef.java679
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ProcessorEnumValue.java47
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ProcessorParam.java100
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/RuntimeType.java26
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/SourceHistory.java51
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/SubsystemEnum.java34
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/TargetDef.java228
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/TargetHistory.java58
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/TargetHistoryTable.java430
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/TargetInfo.java127
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/TargetMatcher.java120
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/VersionInfo.java671
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/WarningLevelEnum.java40
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/apple/PropertyListSerialization.java235
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/apple/XcodeProjectWriter.java1016
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/apple/package.html27
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/arm/ADSCCompiler.java210
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/arm/ADSLibrarian.java159
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/arm/ADSLinker.java166
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandCCompiler.java134
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandCfgParser.java70
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLibrarian.java219
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java293
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandProcessor.java219
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandResourceCompiler.java129
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/borland/CBuilderXProjectWriter.java542
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/borland/CfgFilenameState.java46
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/borland/ConsumeToSpaceOrNewLine.java30
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/borland/QuoteBranchState.java35
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/borland/package.html27
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranCompiler.java137
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLibrarian.java82
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLinker.java77
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractCompiler.java207
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractLinker.java122
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractProcessor.java129
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/CaptureStreamHandler.java122
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCCompiler.java42
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCompiler.java437
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCompilerConfiguration.java226
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineFortranCompiler.java42
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker.java407
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinkerConfiguration.java128
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/Compiler.java24
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/CompilerConfiguration.java64
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkType.java150
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/Linker.java80
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkerConfiguration.java33
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCCompiler.java43
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCompiler.java104
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCompiler.java49
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/Processor.java75
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/ProcessorConfiguration.java54
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/ProgressMonitor.java31
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudio2005CCompiler.java62
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCCompiler.java50
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleCCompiler.java136
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLibrarian.java80
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLinker.java148
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioLibrarian.java36
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioLinker.java44
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioMIDLCompiler.java112
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioProcessor.java90
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioProjectWriter.java710
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioResourceCompiler.java119
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/devstudio/VisualStudioNETProjectWriter.java866
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/devstudio/package.html27
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/AbstractArLibrarian.java107
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java339
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/GccCCompiler.java242
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/GccCompatibleCCompiler.java146
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/GccLibrarian.java41
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/GccLinker.java210
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java299
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/GppLinker.java203
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/LdLinker.java57
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/WindresResourceCompiler.java121
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccCCompiler.java272
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccLibrarian.java69
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccLinker.java234
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccProcessor.java288
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GppLinker.java228
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/LdLinker.java83
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccCCompiler.java244
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLibrarian.java43
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLinker.java215
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccProcessor.java305
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GppLinker.java210
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/LdLinker.java60
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/hp/aCCCompiler.java116
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/hp/aCCLinker.java100
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ibm/VisualAgeCCompiler.java118
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ibm/VisualAgeLinker.java83
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ide/CommentDef.java47
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ide/DebugDef.java127
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ide/DependencyDef.java77
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectDef.java372
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectWriter.java53
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectWriterEnum.java105
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ide/package.html27
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux32CCompiler.java58
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux32Linker.java55
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux64CCompiler.java58
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux64Linker.java55
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/intel/IntelProcessor.java51
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32CCompiler.java52
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32Librarian.java38
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32Linker.java46
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin64CCompiler.java53
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/mozilla/XpidlCompiler.java365
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/mozilla/package.html27
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCCompiler.java84
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCLinker.java69
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCompiler.java169
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomFortranCompiler.java86
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomFortranLinker.java69
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomLibrarian.java254
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomLinker.java205
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomProcessor.java169
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/openwatcom/package.html27
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/os390/OS390CCompiler.java156
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/os390/OS390Linker.java208
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/os390/OS390Processor.java71
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/os400/IccCompiler.java123
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/os400/IccLinker.java209
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/os400/IccProcessor.java71
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/package.html27
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/parser/AbstractParser.java67
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/parser/AbstractParserState.java41
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/parser/BranchState.java46
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/parser/CParser.java78
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/parser/CaseInsensitiveLetterState.java87
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/parser/FilenameState.java41
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/parser/FortranParser.java106
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/parser/LetterState.java80
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/parser/Parser.java28
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/parser/PostE.java41
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/parser/WhitespaceOrCaseInsensitiveLetterState.java83
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/parser/WhitespaceOrLetterState.java75
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/parser/package.html28
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/platforms/WindowsPlatform.java364
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/platforms/package.html27
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/sun/C89CCompiler.java108
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/sun/C89Linker.java132
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/sun/C89Processor.java116
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/sun/ForteCCCompiler.java130
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/sun/ForteCCLinker.java100
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxCCompiler.java191
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxLibrarian.java162
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxLinker.java181
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/trolltech/MetaObjectCompiler.java280
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/trolltech/MetaObjectParser.java148
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/trolltech/UserInterfaceCompiler.java347
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/trolltech/UserInterfaceParser.java67
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/trolltech/package.html27
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/types/CommandLineArgument.java104
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/types/CompilerArgument.java28
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/types/ConditionalFileSet.java84
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/types/ConditionalPath.java75
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/types/DefineArgument.java38
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/types/DefineSet.java199
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/types/FlexLong.java59
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/types/IncludePath.java38
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/types/LibrarySet.java347
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/types/LibraryTypeEnum.java48
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/types/LinkerArgument.java28
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/types/SystemIncludePath.java45
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/types/SystemLibrarySet.java37
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/types/UndefineArgument.java153
193 files changed, 29494 insertions, 0 deletions
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/AboutCCTask.java b/src/main/java/net/sf/antcontrib/cpptasks/AboutCCTask.java
new file mode 100644
index 0000000..4f17111
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/AboutCCTask.java
@@ -0,0 +1,49 @@
+/*
+ *
+ * Copyright 2001-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;
+
+/**
+ * The equivalent of a Help About
+ * run "java -jar cpptasks.jar" to read
+ *
+ * @author Curt Arnold
+ */
+public class AboutCCTask {
+ /**
+ * display identification message and exit
+ *
+ * @param args ignored
+ */
+ public static void main(String args[]) {
+ System.out.println("CCTask: Compile and link task for Apache Ant 1.5 or later\n");
+ System.out.println("Copyright (c) 2002-2004, The Ant-Contrib project.\n");
+ System.out.println("http://sf.net/projects/ant-contrib\n");
+ System.out.println("Licensed under the Apache Software License 2.0");
+ System.out.println("available at http://www.apache.org/licenses/LICENSE-2.0\n");
+ System.out.println("This software is not a product of the");
+ System.out.println("of the Apache Software Foundation and no");
+ System.out.println("endorsement or promotion is implied.\n");
+ System.out.println("THIS SOFTWARE IS PROVIDED 'AS-IS', See");
+ System.out.println("http://www.apache.org/LICENSE for additional");
+ System.out.println("disclaimers.\n");
+ System.out.println("To use:");
+ System.out.println("\tPlace cpptasks.jar into lib directory of Ant 1.5 or later.");
+ System.out.println("\tAdd <taskdef resource=\"cpptasks.tasks\"/> and");
+ System.out.println("\t\t<typedef resource=\"cpptasks.types\"/> to build.xml");
+ System.out.println("Add <cc/>, <compiler/>; and <linker/> elements.");
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ArchEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/ArchEnum.java
new file mode 100644
index 0000000..0f36405
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ArchEnum.java
@@ -0,0 +1,72 @@
+/*
+ *
+ * Copyright 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;
+
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+/**
+ * Enumeration of cpu architecture types.
+ *
+ * @author Curt Arnold
+ *
+ */
+public final class ArchEnum
+ extends EnumeratedAttribute {
+ /**
+ * Constructor.
+ *
+ * Set by default to "pentium3"
+ *
+ * @see java.lang.Object#Object()
+ */
+ public ArchEnum() {
+ setValue("pentium3");
+ }
+
+ /**
+ * Gets list of acceptable values.
+ *
+ * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues()
+ */
+ public String[] getValues() {
+ /**
+ * Class initializer.
+ */
+ return new String[] {
+ "i386",
+ "i486",
+ "i586",
+ "i686",
+ "pentium",
+ "pentium-mmx",
+ "pentiumpro",
+ "pentium2",
+ "pentium3",
+ "pentium4",
+ "k6",
+ "k6-2",
+ "k6-3",
+ "athlon",
+ "athlon-tbird",
+ "athlon-4",
+ "athlon-xp",
+ "athlon-mp",
+ "winchip-c6",
+ "winchip2",
+ "c3"};
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/CCTask.java b/src/main/java/net/sf/antcontrib/cpptasks/CCTask.java
new file mode 100644
index 0000000..2e6adab
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/CCTask.java
@@ -0,0 +1,1440 @@
+/*
+ *
+ * Copyright 2001-2008 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;
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.*;
+
+import net.sf.antcontrib.cpptasks.compiler.CompilerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.LinkerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;
+import net.sf.antcontrib.cpptasks.ide.ProjectDef;
+import net.sf.antcontrib.cpptasks.types.CompilerArgument;
+import net.sf.antcontrib.cpptasks.types.ConditionalFileSet;
+import net.sf.antcontrib.cpptasks.types.DefineSet;
+import net.sf.antcontrib.cpptasks.types.IncludePath;
+import net.sf.antcontrib.cpptasks.types.LibrarySet;
+import net.sf.antcontrib.cpptasks.types.LinkerArgument;
+import net.sf.antcontrib.cpptasks.types.SystemIncludePath;
+import net.sf.antcontrib.cpptasks.types.SystemLibrarySet;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Environment;
+/**
+ * Compile and link task.
+ *
+ * <p>
+ * This task can compile various source languages and produce executables,
+ * shared libraries (aka DLL's) and static libraries. Compiler adaptors are
+ * currently available for several C/C++ compilers, FORTRAN, MIDL and Windows
+ * Resource files.
+ * </p>
+ *
+ * <p>
+ * Copyright (c) 2001-2008, The Ant-Contrib project.
+ * </p>
+ *
+ * <p>
+ * Licensed under the Apache Software License 2.0,
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ * </p>
+ *
+ * <p>
+ * For use with Apache Ant 1.5 or later. This software is not a product of the
+ * of the Apache Software Foundation and no endorsement is implied.
+ * </p>
+ *
+ * <p>
+ * THIS SOFTWARE IS PROVIDED 'AS-IS', See
+ * http://www.apache.org/licenses/LICENSE-2.0 for additional disclaimers.
+ * </p>
+ *
+ * To use:
+ * <ol>
+ * <li>
+ * Place cpptasks.jar into Ant's classpath by placing it in Ant's lib
+ * directory, adding it to the CLASSPATH environment variable or by using the
+ * -lib command line option.
+ * </li>
+ * <li>
+ * Add type and task definitions to the build file:
+ * <ul>
+ * <li>
+ * Ant 1.6 or later:
+ * <ul>
+ * <li>Add xmlns:cpptasks="antlib:net.sf.antcontrib.cpptasks" to
+ * &lt;project&gt; element.
+ * </li>
+ * <li>
+ * Add &lt;cpptasks:cc/&gt;, &lt;cpptasks:compiler/&gt; and
+ * &lt;cpptasks:linker/&gt; elements to the project.
+ * </li>
+ * </ul>
+ * </li>
+ * <li>
+ * Ant 1.5 or later:
+ * <ul>
+ * <li>Add &lt;taskdef resource="cpptasks.tasks"/&gt; and
+ * &lt;typedef resource="cpptasks.types"/&gt; to body of &lt;project&gt;
+ * element.
+ * </li>
+ * <li>
+ * Add &lt;cc/&gt;, &lt;compiler/&gt; and &lt;linker/&gt; elements to the
+ * project.
+ * </li>
+ * </ul>
+ * </li>
+ * </ul>
+ * </li>
+ * <li>
+ * Set the path and environment variables to be able to run compiler from
+ * command line.
+ * </li>
+ * <li>
+ * Build the project.
+ * </li>
+ * </ol>
+ *
+ * @author Adam Murdoch
+ * @author Curt Arnold
+ */
+public class CCTask extends Task {
+ private static class SystemLibraryCollector implements FileVisitor {
+ private Hashtable libraries;
+ private Linker linker;
+ public SystemLibraryCollector(Linker linker, Hashtable libraries) {
+ this.linker = linker;
+ this.libraries = libraries;
+ }
+ public void visit(File basedir, String filename) {
+ if (linker.bid(filename) > 0) {
+ File libfile = new File(basedir, filename);
+ String key = linker.getLibraryKey(libfile);
+ libraries.put(key, libfile);
+ }
+ }
+ }
+
+ private static class ProjectFileCollector implements FileVisitor {
+ private final List files;
+ /**
+ * Creates a new ProjectFileCollector.
+ * @param files vector for collected files.
+ */
+ public ProjectFileCollector(List files) {
+ this.files = files;
+ }
+ /**
+ * Called for each file to be considered for collection.
+ * @param parentDir parent directory
+ * @param filename filename within directory
+ */
+ public void visit(File parentDir, String filename) {
+ files.add(new File(parentDir, filename));
+ }
+ }
+
+ private static final ProcessorConfiguration[] EMPTY_CONFIG_ARRAY = new ProcessorConfiguration[0];
+ /**
+ * Builds a Hashtable to targets needing to be rebuilt keyed by compiler
+ * configuration
+ */
+ public static Hashtable getTargetsToBuildByConfiguration(Hashtable targets) {
+ Hashtable targetsByConfig = new Hashtable();
+ Enumeration targetEnum = targets.elements();
+ while (targetEnum.hasMoreElements()) {
+ TargetInfo target = (TargetInfo) targetEnum.nextElement();
+ if (target.getRebuild()) {
+ Vector targetsForSameConfig = (Vector) targetsByConfig
+ .get(target.getConfiguration());
+ if (targetsForSameConfig != null) {
+ targetsForSameConfig.addElement(target);
+ } else {
+ targetsForSameConfig = new Vector();
+ targetsForSameConfig.addElement(target);
+ targetsByConfig.put(target.getConfiguration(),
+ targetsForSameConfig);
+ }
+ }
+ }
+ return targetsByConfig;
+ }
+ /** The compiler definitions. */
+ private Vector _compilers = new Vector();
+ /** The output file type. */
+ // private LinkType _linkType = LinkType.EXECUTABLE;
+ /** The library sets. */
+ private Vector _libsets = new Vector();
+ /** The linker definitions. */
+ private Vector _linkers = new Vector();
+ /** The object directory. */
+ private File _objDir;
+ /** The output file. */
+ private File _outfile;
+ /** The linker definitions. */
+ private final Vector targetPlatforms = new Vector();
+ /** The distributer definitions. */
+ private Vector distributers = new Vector();
+ private final Vector versionInfos = new Vector();
+ private final Vector projects = new Vector();
+ private boolean projectsOnly = false;
+
+
+ /**
+ * If true, stop build on compile failure.
+ */
+ protected boolean failOnError = true;
+
+ /**
+ * Content that appears in <cc>and also in <compiler>are maintained by a
+ * captive CompilerDef instance
+ */
+ private final CompilerDef compilerDef = new CompilerDef();
+ /** The OS390 dataset to build to object to */
+ private String dataset;
+ /**
+ *
+ * Depth of dependency checking
+ *
+ * Values < 0 indicate full dependency checking Values >= 0 indicate
+ * partial dependency checking and for superficial compilation checks. Will
+ * throw BuildException before attempting link
+ */
+ private int dependencyDepth = -1;
+ /**
+ * Content that appears in <cc>and also in <linker>are maintained by a
+ * captive CompilerDef instance
+ */
+ private final LinkerDef linkerDef = new LinkerDef();
+ /**
+ * contains the subsystem, output type and
+ *
+ */
+ private final LinkType linkType = new LinkType();
+ /**
+ * The property name which will be set with the physical filename of the
+ * file that is generated by the linker
+ */
+ private String outputFileProperty;
+ /**
+ * if relentless = true, compilations should attempt to compile as many
+ * files as possible before throwing a BuildException
+ */
+ private boolean relentless;
+ public CCTask() {
+ }
+ /**
+ * Adds a compiler definition or reference.
+ *
+ * @param compiler
+ * compiler
+ * @throws NullPointerException
+ * if compiler is null
+ */
+ public void addConfiguredCompiler(CompilerDef compiler) {
+ if (compiler == null) {
+ throw new NullPointerException("compiler");
+ }
+ compiler.setProject(getProject());
+ _compilers.addElement(compiler);
+ }
+ /**
+ * Adds a compiler command-line arg. Argument will be inherited by all
+ * nested compiler elements that do not have inherit="false".
+ *
+ */
+ public void addConfiguredCompilerArg(CompilerArgument arg) {
+ compilerDef.addConfiguredCompilerArg(arg);
+ }
+ /**
+ * Adds a defineset. Will be inherited by all compiler elements that do not
+ * have inherit="false".
+ *
+ * @param defs
+ * Define set
+ */
+ public void addConfiguredDefineset(DefineSet defs) {
+ compilerDef.addConfiguredDefineset(defs);
+ }
+ /**
+ * Adds a linker definition. The first linker that is not disqualified by
+ * its "if" and "unless" attributes will perform the link. If no child
+ * linker element is active, the linker implied by the cc elements name or
+ * classname attribute will be used.
+ *
+ * @param linker
+ * linker
+ * @throws NullPointerException
+ * if linker is null
+ */
+ public void addConfiguredLinker(LinkerDef linker) {
+ if (linker == null) {
+ throw new NullPointerException("linker");
+ }
+ linker.setProject(getProject());
+ _linkers.addElement(linker);
+ }
+ /**
+ * Adds a linker command-line arg. Argument will be inherited by all nested
+ * linker elements that do not have inherit="false".
+ */
+ public void addConfiguredLinkerArg(LinkerArgument arg) {
+ linkerDef.addConfiguredLinkerArg(arg);
+ }
+ /**
+ * Add an environment variable to the launched process.
+ */
+ public void addEnv(Environment.Variable var) {
+ compilerDef.addEnv(var);
+ linkerDef.addEnv(var);
+ }
+ /**
+ * Adds a source file set.
+ *
+ * Files in these filesets will be auctioned to the available compiler
+ * configurations, with the default compiler implied by the cc element
+ * bidding last. If no compiler is interested in the file, it will be
+ * passed to the linker.
+ *
+ * To have a file be processed by a particular compiler configuration, add
+ * a fileset to the corresponding compiler element.
+ */
+ public void addFileset(ConditionalFileSet srcSet) {
+ compilerDef.addFileset(srcSet);
+ }
+ /**
+ * Adds a library set.
+ *
+ * Library sets will be inherited by all linker elements that do not have
+ * inherit="false".
+ *
+ * @param libset
+ * library set
+ * @throws NullPointerException
+ * if libset is null.
+ */
+ public void addLibset(LibrarySet libset) {
+ if (libset == null) {
+ throw new NullPointerException("libset");
+ }
+ linkerDef.addLibset(libset);
+ }
+ /**
+ * Adds a system library set. Timestamps and locations of system library
+ * sets are not used in dependency analysis.
+ *
+ * Essential libraries (such as C Runtime libraries) should not be
+ * specified since the task will attempt to identify the correct libraries
+ * based on the multithread, debug and runtime attributes.
+ *
+ * System library sets will be inherited by all linker elements that do not
+ * have inherit="false".
+ *
+ * @param libset
+ * library set
+ * @throws NullPointerException
+ * if libset is null.
+ */
+ public void addSyslibset(SystemLibrarySet libset) {
+ if (libset == null) {
+ throw new NullPointerException("libset");
+ }
+ linkerDef.addSyslibset(libset);
+ }
+ /**
+ * Specifies the generation of IDE project file. Experimental.
+ * @param projectDef project file generation specification
+ */
+ public void addProject(final ProjectDef projectDef) {
+ if (projectDef == null) {
+ throw new NullPointerException("projectDef");
+ }
+ projects.addElement(projectDef);
+ }
+ public void setProjectsOnly(final boolean value) {
+ projectsOnly = value;
+ }
+ /**
+ * Checks all targets that are not forced to be rebuilt or are missing
+ * object files to be checked for modified include files
+ *
+ * @return total number of targets to be rebuilt
+ *
+ */
+ protected int checkForChangedIncludeFiles(Hashtable targets) {
+ int potentialTargets = 0;
+ int definiteTargets = 0;
+ Enumeration targetEnum = targets.elements();
+ while (targetEnum.hasMoreElements()) {
+ TargetInfo target = (TargetInfo) targetEnum.nextElement();
+ if (!target.getRebuild()) {
+ potentialTargets++;
+ } else {
+ definiteTargets++;
+ }
+ }
+ //
+ // If there were remaining targets that
+ // might be out of date
+ //
+ if (potentialTargets > 0) {
+ log("Starting dependency analysis for "
+ + Integer.toString(potentialTargets) + " files.");
+ DependencyTable dependencyTable = new DependencyTable(_objDir);
+ try {
+ dependencyTable.load();
+ } catch (Exception ex) {
+ log("Problem reading dependencies.xml: " + ex.toString());
+ }
+ targetEnum = targets.elements();
+ while (targetEnum.hasMoreElements()) {
+ TargetInfo target = (TargetInfo) targetEnum.nextElement();
+ if (!target.getRebuild()) {
+ if (dependencyTable.needsRebuild(this, target,
+ dependencyDepth)) {
+ target.mustRebuild();
+ }
+ }
+ }
+ dependencyTable.commit(this);
+ }
+ //
+ // count files being rebuilt now
+ //
+ int currentTargets = 0;
+ targetEnum = targets.elements();
+ while (targetEnum.hasMoreElements()) {
+ TargetInfo target = (TargetInfo) targetEnum.nextElement();
+ if (target.getRebuild()) {
+ currentTargets++;
+ }
+ }
+ if (potentialTargets > 0) {
+ log(Integer.toString(potentialTargets - currentTargets
+ + definiteTargets)
+ + " files are up to date.");
+ log(Integer.toString(currentTargets - definiteTargets)
+ + " files to be recompiled from dependency analysis.");
+ }
+ log(Integer.toString(currentTargets) + " total files to be compiled.");
+ return currentTargets;
+ }
+ protected LinkerConfiguration collectExplicitObjectFiles(
+ Vector objectFiles, Vector sysObjectFiles, VersionInfo versionInfo) {
+ //
+ // find the first eligible linker
+ //
+ //
+ ProcessorConfiguration linkerConfig = null;
+ LinkerDef selectedLinkerDef = null;
+ Linker selectedLinker = null;
+ Hashtable sysLibraries = new Hashtable();
+ TargetDef targetPlatform = getTargetPlatform();
+ FileVisitor objCollector = null;
+ FileVisitor sysLibraryCollector = null;
+ for (int i = 0; i < _linkers.size(); i++) {
+ LinkerDef currentLinkerDef = (LinkerDef) _linkers.elementAt(i);
+ if (currentLinkerDef.isActive()) {
+ selectedLinkerDef = currentLinkerDef;
+ selectedLinker = currentLinkerDef.getProcessor().getLinker(
+ linkType);
+ //
+ // skip the linker if it doesn't know how to
+ // produce the specified link type
+ if (selectedLinker != null) {
+ linkerConfig = currentLinkerDef.createConfiguration(this,
+ linkType, linkerDef, targetPlatform, versionInfo);
+ if (linkerConfig != null) {
+ //
+ // create collectors for object files
+ // and system libraries
+ objCollector = new ObjectFileCollector(selectedLinker,
+ objectFiles);
+ sysLibraryCollector = new SystemLibraryCollector(
+ selectedLinker, sysLibraries);
+ //
+ // if the <linker> has embedded <fileset>'s
+ // (such as linker specific libraries)
+ // add them as object files.
+ //
+ if (currentLinkerDef.hasFileSets()) {
+ currentLinkerDef.visitFiles(objCollector);
+ }
+ //
+ // user libraries are just a specialized form
+ // of an object fileset
+ selectedLinkerDef.visitUserLibraries(selectedLinker,
+ objCollector);
+ }
+ break;
+ }
+ }
+ }
+ if (linkerConfig == null) {
+ linkerConfig = linkerDef.createConfiguration(this, linkType, null, targetPlatform, versionInfo);
+ selectedLinker = (Linker) linkerDef.getProcessor().getLinker(
+ linkType);
+ objCollector = new ObjectFileCollector(selectedLinker, objectFiles);
+ sysLibraryCollector = new SystemLibraryCollector(selectedLinker,
+ sysLibraries);
+ }
+ //
+ // unless there was a <linker> element that
+ // explicitly did not inherit files from
+ // containing <cc> element
+ if (selectedLinkerDef == null || selectedLinkerDef.getInherit()) {
+ linkerDef.visitUserLibraries(selectedLinker, objCollector);
+ linkerDef.visitSystemLibraries(selectedLinker, sysLibraryCollector);
+ }
+ //
+ // if there was a <syslibset> in a nested <linker>
+ // evaluate it last so it takes priority over
+ // identically named libs from <cc> element
+ //
+ if (selectedLinkerDef != null) {
+ //
+ // add any system libraries to the hashtable
+ // done in reverse order so the earliest
+ // on the classpath takes priority
+ selectedLinkerDef.visitSystemLibraries(selectedLinker,
+ sysLibraryCollector);
+ }
+ //
+ // copy over any system libraries to the
+ // object files vector
+ //
+ Enumeration sysLibEnum = sysLibraries.elements();
+ while (sysLibEnum.hasMoreElements()) {
+ sysObjectFiles.addElement(sysLibEnum.nextElement());
+ }
+ return (LinkerConfiguration) linkerConfig;
+ }
+ /**
+ * Adds an include path.
+ *
+ * Include paths will be inherited by nested compiler elements that do not
+ * have inherit="false".
+ */
+ public IncludePath createIncludePath() {
+ return compilerDef.createIncludePath();
+ }
+ /**
+ * Specifies precompilation prototype file and exclusions. Inherited by all
+ * compilers that do not have inherit="false".
+ *
+ */
+ public PrecompileDef createPrecompile() throws BuildException {
+ return compilerDef.createPrecompile();
+ }
+ /**
+ * Adds a system include path. Locations and timestamps of files located
+ * using the system include paths are not used in dependency analysis.
+ *
+ *
+ * Standard include locations should not be specified. The compiler
+ * adapters should recognized the settings from the appropriate environment
+ * variables or configuration files.
+ *
+ * System include paths will be inherited by nested compiler elements that
+ * do not have inherit="false".
+ */
+ public SystemIncludePath createSysIncludePath() {
+ return compilerDef.createSysIncludePath();
+ }
+ /**
+ * Executes the task. Compiles the given files.
+ *
+ * @throws BuildException
+ * if someting goes wrong with the build
+ */
+ public void execute() throws BuildException {
+ //
+ // if link type allowed objdir to be defaulted
+ // provide it from outfile
+ if (_objDir == null) {
+ if(_outfile != null) {
+ _objDir = new File(_outfile.getParent());
+ } else {
+ _objDir = new File(".");
+ }
+ }
+
+ //
+ // if the object directory does not exist
+ //
+ if (!_objDir.exists()) {
+ throw new BuildException("Object directory does not exist");
+ }
+ TargetHistoryTable objHistory = new TargetHistoryTable(this, _objDir);
+
+ //
+ // get the first active version info
+ //
+ VersionInfo versionInfo = null;
+ Enumeration versionEnum = versionInfos.elements();
+ while (versionEnum.hasMoreElements()) {
+ versionInfo = (VersionInfo) versionEnum.nextElement();
+ versionInfo = versionInfo.merge();
+ if (versionInfo.isActive()) {
+ break;
+ } else {
+ versionInfo = null;
+ }
+ }
+
+
+ //
+ // determine the eventual linker configuration
+ // (may be null) and collect any explicit
+ // object files or libraries
+ Vector objectFiles = new Vector();
+ Vector sysObjectFiles = new Vector();
+ LinkerConfiguration linkerConfig = collectExplicitObjectFiles(
+ objectFiles, sysObjectFiles, versionInfo);
+
+
+ //
+ // Assemble hashtable of all files
+ // that we know how to compile (keyed by output file name)
+ //
+ Hashtable targets = getTargets(linkerConfig, objectFiles, versionInfo, _outfile);
+ TargetInfo linkTarget = null;
+ //
+ // if output file is not specified,
+ // then skip link step
+ //
+ if (_outfile != null) {
+ linkTarget = getLinkTarget(linkerConfig, objectFiles,
+ sysObjectFiles, targets, versionInfo);
+ }
+
+ if (projects.size() > 0) {
+ ArrayList files = new ArrayList();
+ ProjectFileCollector matcher = new ProjectFileCollector(files);
+ for (int i = 0; i < _compilers.size(); i++) {
+ CompilerDef currentCompilerDef = (CompilerDef) _compilers
+ .elementAt(i);
+ if (currentCompilerDef.isActive()) {
+ if (currentCompilerDef.hasFileSets()) {
+ currentCompilerDef.visitFiles(matcher);
+ }
+ }
+ }
+ compilerDef.visitFiles(matcher);
+
+
+ Enumeration iter = projects.elements();
+ while (iter.hasMoreElements()) {
+ ProjectDef projectDef = (ProjectDef) iter.nextElement();
+ if (projectDef.isActive()) {
+ projectDef.execute(this, files, targets, linkTarget);
+ }
+ }
+ }
+ if (projectsOnly) return;
+
+
+
+ //
+ // mark targets that don't have a history record or
+ // whose source last modification time is not
+ // the same as the history to be rebuilt
+ //
+ objHistory.markForRebuild(targets);
+ CCTaskProgressMonitor monitor = new CCTaskProgressMonitor(objHistory, versionInfo);
+ //
+ // check for changed include files
+ //
+ int rebuildCount = checkForChangedIncludeFiles(targets);
+ if (rebuildCount > 0) {
+ BuildException compileException = null;
+ //
+ // compile all targets with getRebuild() == true
+ //
+ Hashtable targetsByConfig = getTargetsToBuildByConfiguration(targets);
+ //
+ // build array containing Vectors with precompiled generation
+ // steps going first
+ //
+ Vector[] targetVectors = new Vector[targetsByConfig.size()];
+ int index = 0;
+ Enumeration targetVectorEnum = targetsByConfig.elements();
+ while (targetVectorEnum.hasMoreElements()) {
+ Vector targetsForConfig = (Vector) targetVectorEnum
+ .nextElement();
+ //
+ // get the configuration from the first entry
+ //
+ CompilerConfiguration config = (CompilerConfiguration) ((TargetInfo) targetsForConfig
+ .elementAt(0)).getConfiguration();
+ if (config.isPrecompileGeneration()) {
+ targetVectors[index++] = targetsForConfig;
+ }
+ }
+ targetVectorEnum = targetsByConfig.elements();
+ while (targetVectorEnum.hasMoreElements()) {
+ Vector targetsForConfig = (Vector) targetVectorEnum
+ .nextElement();
+ for (int i = 0; i < targetVectors.length; i++) {
+ if (targetVectors[i] == targetsForConfig) {
+ break;
+ }
+ if (targetVectors[i] == null) {
+ targetVectors[i] = targetsForConfig;
+ break;
+ }
+ }
+ }
+ for (int i = 0; i < targetVectors.length; i++) {
+ //
+ // get the targets for this configuration
+ //
+ Vector targetsForConfig = targetVectors[i];
+ //
+ // get the configuration from the first entry
+ //
+ CompilerConfiguration config = (CompilerConfiguration) ((TargetInfo) targetsForConfig
+ .elementAt(0)).getConfiguration();
+ //
+ // prepare the list of source files
+ //
+ String[] sourceFiles = new String[targetsForConfig.size()];
+ Enumeration targetsEnum = targetsForConfig.elements();
+ index = 0;
+ while (targetsEnum.hasMoreElements()) {
+ TargetInfo targetInfo = ((TargetInfo) targetsEnum
+ .nextElement());
+ sourceFiles[index++] = targetInfo.getSources()[0]
+ .toString();
+ }
+ try {
+ config.compile(this, _objDir, sourceFiles, relentless,
+ monitor);
+ } catch (BuildException ex) {
+ if (compileException == null) {
+ compileException = ex;
+ }
+ if (!relentless)
+ break;
+ }
+ }
+ //
+ // save the details of the object file compilation
+ // settings to disk for dependency analysis
+ //
+ try {
+ objHistory.commit();
+ } catch (IOException ex) {
+ this.log("Error writing history.xml: " + ex.toString());
+ }
+ //
+ // if we threw a compile exception and
+ // didn't throw it at the time because
+ // we were relentless then
+ // save the history and
+ // throw the exception
+ //
+ if (compileException != null) {
+ if (failOnError) {
+ throw compileException;
+ } else {
+ log(compileException.getMessage(), Project.MSG_ERR);
+ return;
+ }
+ }
+ }
+ //
+ // if the dependency tree was not fully
+ // evaluated, then throw an exception
+ // since we really didn't do what we
+ // should have done
+ //
+ //
+ if (dependencyDepth >= 0) {
+ throw new BuildException(
+ "All files at depth "
+ + Integer.toString(dependencyDepth)
+ + " from changes successfully compiled.\n"
+ + "Remove or change dependencyDepth to -1 to perform full compilation.");
+ }
+ //
+ // if no link target then
+ // commit the history for the object files
+ // and leave the task
+ if (linkTarget != null) {
+ //
+ // get the history for the link target (may be the same
+ // as the object history)
+ TargetHistoryTable linkHistory = getLinkHistory(objHistory);
+ //
+ // see if it needs to be rebuilt
+ //
+ linkHistory.markForRebuild(linkTarget);
+ //
+ // if it needs to be rebuilt, rebuild it
+ //
+ File output = linkTarget.getOutput();
+ if (linkTarget.getRebuild()) {
+ log("Starting link");
+ LinkerConfiguration linkConfig = (LinkerConfiguration) linkTarget
+ .getConfiguration();
+ if (failOnError) {
+ linkConfig.link(this, linkTarget);
+ } else {
+ try {
+ linkConfig.link(this, linkTarget);
+ } catch(BuildException ex) {
+ log(ex.getMessage(), Project.MSG_ERR);
+ return;
+ }
+ }
+ if (outputFileProperty != null)
+ getProject().setProperty(outputFileProperty,
+ output.getAbsolutePath());
+ linkHistory.update(linkTarget);
+ try {
+ linkHistory.commit();
+ } catch (IOException ex) {
+ log("Error writing link history.xml: " + ex.toString());
+ }
+ } else {
+ if (outputFileProperty != null)
+ getProject().setProperty(outputFileProperty,
+ output.getAbsolutePath());
+ }
+ }
+ }
+ /**
+ * Gets the dataset.
+ *
+ * @return Returns a String
+ */
+ public String getDataset() {
+ return dataset;
+ }
+ protected TargetHistoryTable getLinkHistory(TargetHistoryTable objHistory) {
+ File outputFileDir = new File(_outfile.getParent());
+ //
+ // if the output file is being produced in the link
+ // directory, then we can use the same history file
+ //
+ if (_objDir.equals(outputFileDir)) {
+ return objHistory;
+ }
+ return new TargetHistoryTable(this, outputFileDir);
+ }
+ protected TargetInfo getLinkTarget(LinkerConfiguration linkerConfig,
+ Vector objectFiles, Vector sysObjectFiles,
+ Hashtable compileTargets, VersionInfo versionInfo) {
+ //
+ // walk the compile phase targets and
+ // add those sources that have already been
+ // assigned to the linker or
+ // our output files the linker knows how to consume
+ // files the linker knows how to consume
+ //
+ Enumeration compileTargetsEnum = compileTargets.elements();
+ while (compileTargetsEnum.hasMoreElements()) {
+ TargetInfo compileTarget = (TargetInfo) compileTargetsEnum
+ .nextElement();
+ //
+ // output of compile tasks
+ //
+ int bid = linkerConfig.bid(compileTarget.getOutput().toString());
+ if (bid > 0) {
+ objectFiles.addElement(compileTarget.getOutput());
+ }
+ }
+ File[] objectFileArray = new File[objectFiles.size()];
+ objectFiles.copyInto(objectFileArray);
+ File[] sysObjectFileArray = new File[sysObjectFiles.size()];
+ sysObjectFiles.copyInto(sysObjectFileArray);
+ String baseName = _outfile.getName();
+ String[] fullNames = linkerConfig.getOutputFileNames(baseName, versionInfo);
+ File outputFile = new File(_outfile.getParent(), fullNames[0]);
+ return new TargetInfo(linkerConfig, objectFileArray,
+ sysObjectFileArray, outputFile, linkerConfig.getRebuild());
+ }
+ public File getObjdir() {
+ return _objDir;
+ }
+ public File getOutfile() {
+ return _outfile;
+ }
+
+ public TargetDef getTargetPlatform() {
+ return null;
+ }
+ /**
+ * This method collects a Hashtable, keyed by output file name, of
+ * TargetInfo's for every source file that is specified in the filesets of
+ * the <cc>and nested <compiler>elements. The TargetInfo's contain the
+ * appropriate compiler configurations for their possible compilation
+ *
+ */
+ private Hashtable getTargets(LinkerConfiguration linkerConfig,
+ Vector objectFiles, VersionInfo versionInfo, File outputFile) {
+ Hashtable targets = new Hashtable(1000);
+ TargetDef targetPlatform = getTargetPlatform();
+ //
+ // find active (specialized) compilers
+ //
+ Vector biddingProcessors = new Vector(_compilers.size());
+ for (int i = 0; i < _compilers.size(); i++) {
+ CompilerDef currentCompilerDef = (CompilerDef) _compilers
+ .elementAt(i);
+ if (currentCompilerDef.isActive()) {
+ ProcessorConfiguration config = currentCompilerDef
+ .createConfiguration(this, linkType, compilerDef,
+ targetPlatform, versionInfo);
+ //
+ // see if this processor had a precompile child element
+ //
+ PrecompileDef precompileDef = currentCompilerDef
+ .getActivePrecompile(compilerDef);
+ ProcessorConfiguration[] localConfigs = new ProcessorConfiguration[]{config};
+ //
+ // if it does then
+ //
+ if (precompileDef != null) {
+ File prototype = precompileDef.getPrototype();
+ //
+ // will throw exceptions if prototype doesn't exist, etc
+ //
+ if (!prototype.exists()) {
+ throw new BuildException("prototype ("
+ + prototype.toString() + ") does not exist.");
+ }
+ if (prototype.isDirectory()) {
+ throw new BuildException("prototype ("
+ + prototype.toString() + ") is a directory.");
+ }
+ String[] exceptFiles = precompileDef.getExceptFiles();
+ //
+ // create a precompile building and precompile using
+ // variants of the configuration
+ // or return null if compiler doesn't support
+ // precompilation
+ CompilerConfiguration[] configs = ((CompilerConfiguration) config)
+ .createPrecompileConfigurations(prototype,
+ exceptFiles);
+ if (configs != null && configs.length == 2) {
+ //
+ // visit the precompiled file to add it into the
+ // targets list (just like any other file if
+ // compiler doesn't support precompilation)
+ TargetMatcher matcher = new TargetMatcher(this,
+ _objDir,
+ new ProcessorConfiguration[]{configs[0]},
+ linkerConfig, objectFiles, targets, versionInfo);
+
+ matcher.visit(new File(prototype.getParent()),
+ prototype.getName());
+ //
+ // only the configuration that uses the
+ // precompiled header gets added to the bidding list
+ biddingProcessors.addElement(configs[1]);
+ localConfigs = new ProcessorConfiguration[2];
+ localConfigs[0] = configs[1];
+ localConfigs[1] = config;
+ }
+ }
+ //
+ // if the compiler has a fileset
+ // then allow it to add its files
+ // to the set of potential targets
+ if (currentCompilerDef.hasFileSets()) {
+ TargetMatcher matcher = new TargetMatcher(this, _objDir,
+ localConfigs, linkerConfig, objectFiles, targets,
+ versionInfo);
+ currentCompilerDef.visitFiles(matcher);
+ }
+ biddingProcessors.addElement(config);
+ }
+ }
+ //
+ // add fallback compiler at the end
+ //
+ ProcessorConfiguration config = compilerDef.createConfiguration(this,
+ linkType, null, targetPlatform, versionInfo);
+ biddingProcessors.addElement(config);
+ ProcessorConfiguration[] bidders = new ProcessorConfiguration[biddingProcessors
+ .size()];
+ biddingProcessors.copyInto(bidders);
+ //
+ // bid out the <fileset>'s in the cctask
+ //
+ TargetMatcher matcher = new TargetMatcher(this, _objDir, bidders,
+ linkerConfig, objectFiles, targets, versionInfo);
+ compilerDef.visitFiles(matcher);
+
+ if (outputFile != null && versionInfo != null) {
+ boolean isDebug = linkerConfig.isDebug();
+ try {
+ linkerConfig.getLinker().addVersionFiles(versionInfo, linkType,
+ outputFile,
+ isDebug,
+ _objDir, matcher);
+ } catch(IOException ex) {
+ throw new BuildException(ex);
+ }
+ }
+ return targets;
+ }
+ /**
+ * Sets the default compiler adapter. Use the "name" attribute when the
+ * compiler is a supported compiler.
+ *
+ * @param classname
+ * fully qualified classname which implements CompilerAdapter
+ */
+ public void setClassname(String classname) {
+ compilerDef.setClassname(classname);
+ linkerDef.setClassname(classname);
+ }
+ /**
+ * Sets the dataset for OS/390 builds.
+ *
+ * @param dataset
+ * The dataset to set
+ */
+ public void setDataset(String dataset) {
+ this.dataset = dataset;
+ }
+ /**
+ * Enables or disables generation of debug info.
+ */
+ public void setDebug(boolean debug) {
+ compilerDef.setDebug(debug);
+ linkerDef.setDebug(debug);
+ }
+
+ /**
+ * Gets debug state.
+ * @return true if building for debugging
+ */
+ public boolean getDebug() {
+ return compilerDef.getDebug(null, 0);
+ }
+
+ /**
+ * Deprecated.
+ *
+ * Controls the depth of the dependency evaluation. Used to do a quick
+ * check of changes before a full build.
+ *
+ * Any negative value which will perform full dependency checking. Positive
+ * values will truncate dependency checking. A value of 0 will cause only
+ * those files that changed to be recompiled, a value of 1 which cause
+ * files that changed or that explicitly include a file that changed to be
+ * recompiled.
+ *
+ * Any non-negative value will cause a BuildException to be thrown before
+ * attempting a link or completing the task.
+ *
+ */
+ public void setDependencyDepth(int depth) {
+ dependencyDepth = depth;
+ }
+ /**
+ * Enables generation of exception handling code
+ */
+ public void setExceptions(boolean exceptions) {
+ compilerDef.setExceptions(exceptions);
+ }
+ /**
+ * Enables run-time type information.
+ */
+ public void setRtti(boolean rtti) {
+ compilerDef.setRtti(rtti);
+ }
+ // public LinkType getLinkType() {
+ // return linkType;
+ // }
+ /**
+ * Enables or disables incremental linking.
+ *
+ * @param incremental
+ * new state
+ */
+ public void setIncremental(boolean incremental) {
+ linkerDef.setIncremental(incremental);
+ }
+ /**
+ * Set use of libtool.
+ *
+ * If set to true, the "libtool " will be prepended to the command line for
+ * compatible processors
+ *
+ * @param libtool
+ * If true, use libtool.
+ */
+ public void setLibtool(boolean libtool) {
+ compilerDef.setLibtool(libtool);
+ linkerDef.setLibtool(libtool);
+ }
+ /**
+ * Sets the output file type. Supported values "executable", "shared", and
+ * "static". Deprecated, specify outtype instead.
+ *
+ * @deprecated
+ */
+ public void setLink(OutputTypeEnum outputType) {
+ linkType.setOutputType(outputType);
+ }
+ /**
+ * Enables or disables generation of multithreaded code
+ *
+ * @param multi
+ * If true, generated code may be multithreaded.
+ */
+ public void setMultithreaded(boolean multi) {
+ compilerDef.setMultithreaded(multi);
+ }
+ //
+ // keep near duplicate comment at CompilerDef.setName in sync
+ //
+ /**
+ * Sets type of the default compiler and linker.
+ *
+ * <table width="100%" border="1"> <thead>Supported compilers </thead>
+ * <tr>
+ * <td>gcc (default)</td>
+ * <td>GCC C++ compiler</td>
+ * </tr>
+ * <tr>
+ * <td>g++</td>
+ * <td>GCC C++ compiler</td>
+ * </tr>
+ * <tr>
+ * <td>c++</td>
+ * <td>GCC C++ compiler</td>
+ * </tr>
+ * <tr>
+ * <td>g77</td>
+ * <td>GNU FORTRAN compiler</td>
+ * </tr>
+ * <tr>
+ * <td>msvc</td>
+ * <td>Microsoft Visual C++</td>
+ * </tr>
+ * <tr>
+ * <td>bcc</td>
+ * <td>Borland C++ Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>msrc</td>
+ * <td>Microsoft Resource Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>brc</td>
+ * <td>Borland Resource Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>df</td>
+ * <td>Compaq Visual Fortran Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>midl</td>
+ * <td>Microsoft MIDL Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>icl</td>
+ * <td>Intel C++ compiler for Windows (IA-32)</td>
+ * </tr>
+ * <tr>
+ * <td>ecl</td>
+ * <td>Intel C++ compiler for Windows (IA-64)</td>
+ * </tr>
+ * <tr>
+ * <td>icc</td>
+ * <td>Intel C++ compiler for Linux (IA-32)</td>
+ * </tr>
+ * <tr>
+ * <td>ecc</td>
+ * <td>Intel C++ compiler for Linux (IA-64)</td>
+ * </tr>
+ * <tr>
+ * <td>CC</td>
+ * <td>Sun ONE C++ compiler</td>
+ * </tr>
+ * <tr>
+ * <td>aCC</td>
+ * <td>HP aC++ C++ Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>os390</td>
+ * <td>OS390 C Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>os400</td>
+ * <td>Icc Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>sunc89</td>
+ * <td>Sun C89 C Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>xlC</td>
+ * <td>VisualAge C Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>uic</td>
+ * <td>Qt user interface compiler (creates .h, .cpp and moc_*.cpp files).</td>
+ * </tr>
+ * <tr>
+ * <td>moc</td>
+ * <td>Qt meta-object compiler</td>
+ * </tr>
+ * <tr>
+ * <td>xpidl</td>
+ * <td>Mozilla xpidl compiler (creates .h and .xpt files).</td>
+ * </tr>
+ * <tr>
+ * <td>wcl</td>
+ * <td>OpenWatcom C/C++ compiler</td>
+ * </tr>
+ * <tr>
+ * <td>wfl</td>
+ * <td>OpenWatcom FORTRAN compiler</td>
+ * </tr>
+ * </table>
+ *
+ */
+ public void setName(CompilerEnum name) {
+ compilerDef.setName(name);
+ Processor compiler = compilerDef.getProcessor();
+ Linker linker = compiler.getLinker(linkType);
+ linkerDef.setProcessor(linker);
+ }
+ /**
+ * Do not propagate old environment when new environment variables are
+ * specified.
+ */
+ public void setNewenvironment(boolean newenv) {
+ compilerDef.setNewenvironment(newenv);
+ linkerDef.setNewenvironment(newenv);
+ }
+ /**
+ * Sets the destination directory for object files.
+ *
+ * Generally this should be a property expression that evaluates to
+ * distinct debug and release object file directories.
+ *
+ * @param dir
+ * object directory
+ */
+ public void setObjdir(File dir) {
+ if (dir == null) {
+ throw new NullPointerException("dir");
+ }
+ _objDir = dir;
+ }
+ /**
+ * Sets the output file name. If not specified, the task will only compile
+ * files and not attempt to link. If an extension is not specified, the
+ * task may use a system appropriate extension and prefix, for example,
+ * outfile="example" may result in "libexample.so" being created.
+ *
+ * @param outfile
+ * output file name
+ */
+ public void setOutfile(File outfile) {
+ //
+ // if file name was empty, skip link step
+ //
+ if (outfile == null || outfile.toString().length() > 0) {
+ _outfile = outfile;
+ }
+ }
+ /**
+ * Specifies the name of a property to set with the physical filename that
+ * is produced by the linker
+ */
+ public void setOutputFileProperty(String outputFileProperty) {
+ this.outputFileProperty = outputFileProperty;
+ }
+ /**
+ * Sets the output file type. Supported values "executable", "shared", and
+ * "static".
+ */
+ public void setOuttype(OutputTypeEnum outputType) {
+ linkType.setOutputType(outputType);
+ }
+
+ /**
+ * Gets output type.
+ * @return output type
+ */
+ public String getOuttype() {
+ return linkType.getOutputType();
+ }
+
+ /**
+ * Sets the project.
+ */
+ public void setProject(Project project) {
+ super.setProject(project);
+ compilerDef.setProject(project);
+ linkerDef.setProject(project);
+ }
+ /**
+ * If set to true, all files will be rebuilt.
+ *
+ * @param rebuildAll If true, all files will be rebuilt. If false, up to
+ * date files will not be rebuilt.
+ */
+ public void setRebuild(boolean rebuildAll) {
+ compilerDef.setRebuild(rebuildAll);
+ linkerDef.setRebuild(rebuildAll);
+ }
+ /**
+ * If set to true, compilation errors will not stop the task until all
+ * files have been attempted.
+ *
+ * @param relentless
+ * If true, don't stop on the first compilation error
+ *
+ */
+ public void setRelentless(boolean relentless) {
+ this.relentless = relentless;
+ }
+ /**
+ * Sets the type of runtime library, possible values "dynamic", "static".
+ */
+ public void setRuntime(RuntimeType rtlType) {
+ linkType.setStaticRuntime((rtlType.getIndex() == 1));
+ }
+ /**
+ * Sets the nature of the subsystem under which that the program will
+ * execute.
+ *
+ * <table width="100%" border="1"> <thead>Supported subsystems </thead>
+ * <tr>
+ * <td>gui</td>
+ * <td>Graphical User Interface</td>
+ * </tr>
+ * <tr>
+ * <td>console</td>
+ * <td>Command Line Console</td>
+ * </tr>
+ * <tr>
+ * <td>other</td>
+ * <td>Other</td>
+ * </tr>
+ * </table>
+ *
+ * @param subsystem
+ * subsystem
+ * @throws NullPointerException
+ * if subsystem is null
+ */
+ public void setSubsystem(SubsystemEnum subsystem) {
+ if (subsystem == null) {
+ throw new NullPointerException("subsystem");
+ }
+ linkType.setSubsystem(subsystem);
+ }
+
+ /**
+ * Gets subsystem name.
+ * @return Subsystem name
+ */
+ public String getSubsystem() {
+ return linkType.getSubsystem();
+ }
+
+ /**
+ * Enumerated attribute with the values "none", "severe", "default",
+ * "production", "diagnostic", and "aserror".
+ */
+ public void setWarnings(WarningLevelEnum level) {
+ compilerDef.setWarnings(level);
+ }
+
+ /**
+ * Indicates whether the build will continue
+ * even if there are compilation errors; defaults to true.
+ * @param fail if true halt the build on failure
+ */
+ public void setFailonerror(boolean fail) {
+ failOnError = fail;
+ }
+
+ /**
+ * Gets the failonerror flag.
+ * @return the failonerror flag
+ */
+ public boolean getFailonerror() {
+ return failOnError;
+ }
+ /**
+ * Adds a target definition or reference (Non-functional prototype).
+ *
+ * @param target
+ * target
+ * @throws NullPointerException
+ * if compiler is null
+ */
+ public void addConfiguredTarget(TargetDef target) {
+ if (target == null) {
+ throw new NullPointerException("target");
+ }
+ target.setProject(getProject());
+ targetPlatforms.addElement(target);
+ }
+ /**
+ * Adds a distributer definition or reference (Non-functional prototype).
+ *
+ * @param distributer
+ * distributer
+ * @throws NullPointerException
+ * if compiler is null
+ */
+ public void addConfiguredDistributer(DistributerDef distributer) {
+ if (distributer == null) {
+ throw new NullPointerException("distributer");
+ }
+ distributer.setProject(getProject());
+ distributers.addElement(distributer);
+ }
+ /**
+ * Sets optimization.
+ * @param optimization
+ */
+ public void setOptimize(OptimizationEnum optimization) {
+ compilerDef.setOptimize(optimization);
+ }
+
+ /**
+ * Adds desriptive version information to be included in the
+ * generated file. The first active version info block will
+ * be used.
+ */
+ public void addConfiguredVersioninfo(VersionInfo newVersionInfo) {
+ newVersionInfo.setProject(this.getProject());
+ versionInfos.addElement(newVersionInfo);
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/CCTaskProgressMonitor.java b/src/main/java/net/sf/antcontrib/cpptasks/CCTaskProgressMonitor.java
new file mode 100644
index 0000000..317d6c3
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/CCTaskProgressMonitor.java
@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright 2001-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;
+import java.io.IOException;
+
+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.ProgressMonitor;
+public class CCTaskProgressMonitor implements ProgressMonitor {
+ private ProcessorConfiguration config;
+ private TargetHistoryTable history;
+ private VersionInfo versionInfo;
+ private long lastCommit = -1;
+ public CCTaskProgressMonitor(TargetHistoryTable history, VersionInfo versionInfo) {
+ this.history = history;
+ this.versionInfo = versionInfo;
+ }
+ public void finish(ProcessorConfiguration config, boolean normal) {
+ long current = System.currentTimeMillis();
+ if ((current - lastCommit) > 120000) {
+ try {
+ history.commit();
+ lastCommit = System.currentTimeMillis();
+ } catch (IOException ex) {
+ }
+ }
+ }
+ public void progress(String[] sources) {
+ history.update(config, sources, versionInfo);
+ long current = System.currentTimeMillis();
+ if ((current - lastCommit) > 120000) {
+ try {
+ history.commit();
+ lastCommit = current;
+ } catch (IOException ex) {
+ }
+ }
+ }
+ public void start(ProcessorConfiguration config) {
+ if (lastCommit < 0) {
+ lastCommit = System.currentTimeMillis();
+ }
+ this.config = config;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/CPUEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/CPUEnum.java
new file mode 100644
index 0000000..512ef37
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/CPUEnum.java
@@ -0,0 +1,71 @@
+/*
+ *
+ * Copyright 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;
+
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+/**
+ * Enumeration of cpu types.
+ *
+ * @author Curt Arnold
+ *
+ */
+public final class CPUEnum
+ extends EnumeratedAttribute {
+
+ /**
+ * Constructor.
+ *
+ * Set by default to "pentium3"
+ *
+ * @see java.lang.Object#Object()
+ */
+ public CPUEnum() {
+ setValue("pentium3");
+ }
+
+ /**
+ * Gets list of acceptable values.
+ *
+ * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues()
+ */
+ public String[] getValues() {
+ return new String[] {
+ "i386",
+ "i486",
+ "i586",
+ "i686",
+ "pentium",
+ "pentium-mmx",
+ "pentiumpro",
+ "pentium2",
+ "pentium3",
+ "pentium4",
+ "k6",
+ "k6-2",
+ "k6-3",
+ "athlon",
+ "athlon-tbird",
+ "athlon-4",
+ "athlon-xp",
+ "athlon-mp",
+ "winchip-c6",
+ "winchip2",
+ "c3" };
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/CUtil.java b/src/main/java/net/sf/antcontrib/cpptasks/CUtil.java
new file mode 100644
index 0000000..482593e
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/CUtil.java
@@ -0,0 +1,523 @@
+/*
+ *
+ * Copyright 2001-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;
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.LogStreamHandler;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Environment;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Some utilities used by the CC and Link tasks.
+ *
+ * @author Adam Murdoch
+ * @author Curt Arnold
+ */
+public class CUtil {
+ /**
+ * A class that splits a white-space, comma-separated list into a String
+ * array. Used for task attributes.
+ */
+ public static final class StringArrayBuilder {
+ private String[] _value;
+ public StringArrayBuilder(String value) {
+ // Split the defines up
+ StringTokenizer tokens = new StringTokenizer(value, ", ");
+ Vector vallist = new Vector();
+ while (tokens.hasMoreTokens()) {
+ String val = tokens.nextToken().trim();
+ if (val.length() == 0) {
+ continue;
+ }
+ vallist.addElement(val);
+ }
+ _value = new String[vallist.size()];
+ vallist.copyInto(_value);
+ }
+ public String[] getValue() {
+ return _value;
+ }
+ }
+ /**
+ * Adds the elements of the array to the given vector
+ */
+ public static void addAll(Vector dest, Object[] src) {
+ if (src == null) {
+ return;
+ }
+ for (int i = 0; i < src.length; i++) {
+ dest.addElement(src[i]);
+ }
+ }
+ /**
+ * Checks a array of names for non existent or non directory entries and
+ * nulls them out.
+ *
+ * @return Count of non-null elements
+ */
+ public static int checkDirectoryArray(String[] names) {
+ int count = 0;
+ for (int i = 0; i < names.length; i++) {
+ if (names[i] != null) {
+ File dir = new File(names[i]);
+ if (dir.exists() && dir.isDirectory()) {
+ count++;
+ } else {
+ names[i] = null;
+ }
+ }
+ }
+ return count;
+ }
+ /**
+ * Extracts the basename of a file, removing the extension, if present
+ */
+ public static String getBasename(File file) {
+ String path = file.getPath();
+ // Remove the extension
+ String basename = file.getName();
+ int pos = basename.lastIndexOf('.');
+ if (pos != -1) {
+ basename = basename.substring(0, pos);
+ }
+ return basename;
+ }
+ /**
+ * Gets the parent directory for the executable file name using the current
+ * directory and system executable path
+ *
+ * @param exeName
+ * Name of executable such as "cl.exe"
+ * @return parent directory or null if not located
+ */
+ public static File getExecutableLocation(String exeName) {
+ //
+ // must add current working directory to the
+ // from of the path from the "path" environment variable
+ File currentDir = new File(System.getProperty("user.dir"));
+ if (new File(currentDir, exeName).exists()) {
+ return currentDir;
+ }
+ File[] envPath = CUtil.getPathFromEnvironment("PATH",
+ File.pathSeparator);
+ for (int i = 0; i < envPath.length; i++) {
+ if (new File(envPath[i], exeName).exists()) {
+ return envPath[i];
+ }
+ }
+ return null;
+ }
+ /**
+ * Extracts the parent of a file
+ */
+ public static String getParentPath(String path) {
+ int pos = path.lastIndexOf(File.separator);
+ if (pos <= 0) {
+ return null;
+ }
+ return path.substring(0, pos);
+ }
+ /**
+ * Returns an array of File for each existing directory in the specified
+ * environment variable
+ *
+ * @param envVariable
+ * environment variable name such as "LIB" or "INCLUDE"
+ * @param delim
+ * delimitor used to separate parts of the path, typically ";"
+ * or ":"
+ * @return array of File's for each part that is an existing directory
+ */
+ public static File[] getPathFromEnvironment(String envVariable, String delim) {
+ // OS/4000 does not support the env command.
+ if (System.getProperty("os.name").equals("OS/400"))
+ return new File[]{};
+ Vector osEnv = Execute.getProcEnvironment();
+ String match = envVariable.concat("=");
+ for (Enumeration e = osEnv.elements(); e.hasMoreElements();) {
+ String entry = ((String) e.nextElement()).trim();
+ if (entry.length() > match.length()) {
+ String entryFrag = entry.substring(0, match.length());
+ if (entryFrag.equalsIgnoreCase(match)) {
+ String path = entry.substring(match.length());
+ return parsePath(path, delim);
+ }
+ }
+ }
+ File[] noPath = new File[0];
+ return noPath;
+ }
+ /**
+ * Returns a relative path for the targetFile relative to the base
+ * directory.
+ *
+ * @param base
+ * base directory as returned by File.getCanonicalPath()
+ * @param targetFile
+ * target file
+ * @return relative path of target file. Returns targetFile if there were
+ * no commonalities between the base and the target
+ *
+ */
+ public static String getRelativePath(final String base, final File targetFile) {
+ try {
+ //
+ // remove trailing file separator
+ //
+ String canonicalBase = base;
+ if (base.charAt(base.length() - 1) != File.separatorChar) {
+ canonicalBase = base + File.separatorChar;
+ }
+ //
+ // get canonical name of target
+ //
+ String canonicalTarget;
+ if (System.getProperty("os.name").equals("OS/400"))
+ canonicalTarget = targetFile.getPath();
+ else
+ canonicalTarget = targetFile.getCanonicalPath();
+ if (canonicalBase.startsWith(canonicalTarget + File.separatorChar)) {
+ canonicalTarget = canonicalTarget + File.separator;
+ }
+ if (canonicalTarget.equals(canonicalBase)) {
+ return ".";
+ }
+ //
+ // see if the prefixes are the same
+ //
+ if (canonicalBase.substring(0, 2).equals("\\\\")) {
+ //
+ // UNC file name, if target file doesn't also start with same
+ // server name, don't go there
+ int endPrefix = canonicalBase.indexOf('\\', 2);
+ String prefix1 = canonicalBase.substring(0, endPrefix);
+ String prefix2 = canonicalTarget.substring(0, endPrefix);
+ if (!prefix1.equals(prefix2)) {
+ return canonicalTarget;
+ }
+ } else {
+ if (canonicalBase.substring(1, 3).equals(":\\")) {
+ int endPrefix = 2;
+ String prefix1 = canonicalBase.substring(0, endPrefix);
+ String prefix2 = canonicalTarget.substring(0, endPrefix);
+ if (!prefix1.equals(prefix2)) {
+ return canonicalTarget;
+ }
+ } else {
+ if (canonicalBase.charAt(0) == '/') {
+ if (canonicalTarget.charAt(0) != '/') {
+ return canonicalTarget;
+ }
+ }
+ }
+ }
+ char separator = File.separatorChar;
+ int lastCommonSeparator = -1;
+ int minLength = canonicalBase.length();
+ if (canonicalTarget.length() < minLength) {
+ minLength = canonicalTarget.length();
+ }
+ //
+ // walk to the shorter of the two paths
+ // finding the last separator they have in common
+ for (int i = 0; i < minLength; i++) {
+ if (canonicalTarget.charAt(i) == canonicalBase.charAt(i)) {
+ if (canonicalTarget.charAt(i) == separator) {
+ lastCommonSeparator = i;
+ }
+ } else {
+ break;
+ }
+ }
+ StringBuffer relativePath = new StringBuffer(50);
+ //
+ // walk from the first difference to the end of the base
+ // adding "../" for each separator encountered
+ //
+ for (int i = lastCommonSeparator + 1; i < canonicalBase.length(); i++) {
+ if (canonicalBase.charAt(i) == separator) {
+ if (relativePath.length() > 0) {
+ relativePath.append(separator);
+ }
+ relativePath.append("..");
+ }
+ }
+ if (canonicalTarget.length() > lastCommonSeparator + 1) {
+ if (relativePath.length() > 0) {
+ relativePath.append(separator);
+ }
+ relativePath.append(canonicalTarget.substring(lastCommonSeparator + 1));
+ }
+ return relativePath.toString();
+ } catch (IOException ex) {
+ }
+ return targetFile.toString();
+ }
+ public static boolean isActive(Project p, String ifCond, String unlessCond)
+ throws BuildException {
+ if (ifCond != null) {
+ String ifValue = p.getProperty(ifCond);
+ if (ifValue == null) {
+ return false;
+ } else {
+ if (ifValue.equals("false") || ifValue.equals("no")) {
+ throw new BuildException("if condition \"" + ifCond
+ + "\" has suspicious value \"" + ifValue);
+ }
+ }
+ }
+ if (unlessCond != null) {
+ String unlessValue = p.getProperty(unlessCond);
+ if (unlessValue != null) {
+ if (unlessValue.equals("false") || unlessValue.equals("no")) {
+ throw new BuildException("unless condition \"" + unlessCond
+ + "\" has suspicious value \"" + unlessValue);
+ }
+ return false;
+ }
+ }
+ return true;
+ }
+ /**
+ * Parse a string containing directories into an File[]
+ *
+ * @param path
+ * path string, for example ".;c:\something\include"
+ * @param delim
+ * delimiter, typically ; or :
+ */
+ public static File[] parsePath(String path, String delim) {
+ Vector libpaths = new Vector();
+ int delimPos = 0;
+ for (int startPos = 0; startPos < path.length(); startPos = delimPos
+ + delim.length()) {
+ delimPos = path.indexOf(delim, startPos);
+ if (delimPos < 0) {
+ delimPos = path.length();
+ }
+ //
+ // don't add an entry for zero-length paths
+ //
+ if (delimPos > startPos) {
+ String dirName = path.substring(startPos, delimPos);
+ File dir = new File(dirName);
+ if (dir.exists() && dir.isDirectory()) {
+ libpaths.addElement(dir);
+ }
+ }
+ }
+ File[] paths = new File[libpaths.size()];
+ libpaths.copyInto(paths);
+ return paths;
+ }
+ /**
+ * This method is exposed so test classes can overload and test the
+ * arguments without actually spawning the compiler
+ */
+ public static int runCommand(CCTask task, File workingDir,
+ String[] cmdline, boolean newEnvironment, Environment env)
+ throws BuildException {
+ try {
+ task.log(Commandline.toString(cmdline), Project.MSG_VERBOSE);
+ Execute exe = new Execute(new LogStreamHandler(task,
+ Project.MSG_INFO, Project.MSG_ERR));
+ if (System.getProperty("os.name").equals("OS/390"))
+ exe.setVMLauncher(false);
+ exe.setAntRun(task.getProject());
+ exe.setCommandline(cmdline);
+ exe.setWorkingDirectory(workingDir);
+ if (env != null) {
+ String[] environment = env.getVariables();
+ if (environment != null) {
+ for (int i = 0; i < environment.length; i++) {
+ task.log("Setting environment variable: "
+ + environment[i], Project.MSG_VERBOSE);
+ }
+ }
+ exe.setEnvironment(environment);
+ }
+ exe.setNewenvironment(newEnvironment);
+ return exe.execute();
+ } catch (java.io.IOException exc) {
+ throw new BuildException("Could not launch " + cmdline[0] + ": "
+ + exc, task.getLocation());
+ }
+ }
+ /**
+ * Compares the contents of 2 arrays for equaliy.
+ */
+ public static boolean sameList(Object[] a, Object[] b) {
+ if (a == null || b == null || a.length != b.length) {
+ return false;
+ }
+ for (int i = 0; i < a.length; i++) {
+ if (!a[i].equals(b[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+ /**
+ * Compares the contents of an array and a Vector for equality.
+ */
+ public static boolean sameList(Vector v, Object[] a) {
+ if (v == null || a == null || v.size() != a.length) {
+ return false;
+ }
+ for (int i = 0; i < a.length; i++) {
+ Object o = a[i];
+ if (!o.equals(v.elementAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+ /**
+ * Compares the contents of an array and a Vector for set equality. Assumes
+ * input array and vector are sets (i.e. no duplicate entries)
+ */
+ public static boolean sameSet(Object[] a, Vector b) {
+ if (a == null || b == null || a.length != b.size()) {
+ return false;
+ }
+ if (a.length == 0) {
+ return true;
+ }
+ // Convert the array into a set
+ Hashtable t = new Hashtable();
+ for (int i = 0; i < a.length; i++) {
+ t.put(a[i], a[i]);
+ }
+ for (int i = 0; i < b.size(); i++) {
+ Object o = b.elementAt(i);
+ if (t.remove(o) == null) {
+ return false;
+ }
+ }
+ return (t.size() == 0);
+ }
+ /**
+ * Converts a vector to a string array.
+ */
+ public static String[] toArray(Vector src) {
+ String[] retval = new String[src.size()];
+ src.copyInto(retval);
+ return retval;
+ }
+ /**
+ * Replaces any embedded quotes in the string so that the value can be
+ * placed in an attribute in an XML file
+ *
+ * @param attrValue
+ * value to be expressed
+ * @return equivalent attribute literal
+ *
+ */
+ public static String xmlAttribEncode(String attrValue) {
+ StringBuffer buf = new StringBuffer (attrValue);
+ int quotePos;
+
+ for (quotePos = -1; (quotePos = buf.indexOf("\"", quotePos + 1)) >= 0;) {
+ buf.deleteCharAt(quotePos);
+ buf.insert (quotePos, "&quot;");
+ quotePos += 5;
+ }
+
+ for (quotePos = -1; (quotePos = buf.indexOf("<", quotePos + 1)) >= 0;) {
+ buf.deleteCharAt(quotePos);
+ buf.insert (quotePos, "&lt;");
+ quotePos += 3;
+ }
+
+ for (quotePos = -1; (quotePos = buf.indexOf(">", quotePos + 1)) >= 0;) {
+ buf.deleteCharAt(quotePos);
+ buf.insert (quotePos, "&gt;");
+ quotePos += 3;
+ }
+
+ return buf.toString();
+ }
+
+ public final static int FILETIME_EPSILON = 500;
+ /**
+ * Determines whether time1 is earlier than time2
+ * to a degree that file system time truncation is not significant.
+ *
+ * @param time1 long first time value
+ * @param time2 long second time value
+ * @return boolean if first time value is earlier than second time value.
+ * If the values are within the rounding error of the file system return false.
+ */
+ public static boolean isSignificantlyBefore(long time1, long time2) {
+ return (time1 + FILETIME_EPSILON) < time2;
+ }
+ /**
+ * Determines whether time1 is later than time2
+ * to a degree that file system time truncation is not significant.
+ *
+ * @param time1 long first time value
+ * @param time2 long second time value
+ * @return boolean if first time value is later than second time value.
+ * If the values are within the rounding error of the file system return false.
+ */
+ public static boolean isSignificantlyAfter(long time1, long time2) {
+ return time1 > (time2 + FILETIME_EPSILON);
+ }
+
+
+ public static String toWindowsPath(final String path) {
+ if (File.separatorChar != '\\' && path.indexOf(File.separatorChar) != -1) {
+ return StringUtils.replace(path, File.separator, "\\");
+ }
+ return path;
+ }
+
+ public static String toUnixPath(final String path) {
+ if (File.separatorChar != '/' && path.indexOf(File.separatorChar) != -1) {
+ return StringUtils.replace(path, File.separator, "/");
+ }
+ return path;
+ }
+
+ /**
+ * Determines if source file has a system path,
+ * that is part of the compiler or platform.
+ * @param source source, may not be null.
+ * @return true is source file appears to be system library
+ * and its path should be discarded.
+ */
+ public static boolean isSystemPath(final File source) {
+ String lcPath = source.getAbsolutePath().toLowerCase(java.util.Locale.US);
+ return lcPath.indexOf("platformsdk") != -1
+ || lcPath.indexOf("microsoft") != -1 ||
+ lcPath == "/usr/include" ||
+ lcPath == "/usr/lib" ||
+ lcPath == "/usr/local/include" ||
+ lcPath == "/usr/local/lib";
+ }
+
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/CompilerDef.java b/src/main/java/net/sf/antcontrib/cpptasks/CompilerDef.java
new file mode 100644
index 0000000..313d3ac
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/CompilerDef.java
@@ -0,0 +1,502 @@
+/*
+ *
+ * Copyright 2001-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;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler;
+import net.sf.antcontrib.cpptasks.compiler.Compiler;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.gcc.GccCCompiler;
+import net.sf.antcontrib.cpptasks.types.CompilerArgument;
+import net.sf.antcontrib.cpptasks.types.ConditionalPath;
+import net.sf.antcontrib.cpptasks.types.DefineSet;
+import net.sf.antcontrib.cpptasks.types.IncludePath;
+import net.sf.antcontrib.cpptasks.types.SystemIncludePath;
+import net.sf.antcontrib.cpptasks.types.UndefineArgument;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+/**
+ * A compiler definition. compiler elements may be placed either as children of
+ * a cc element or the project element. A compiler element with an id attribute
+ * may be referenced from compiler elements with refid or extends attributes.
+ *
+ * @author Adam Murdoch
+ */
+public final class CompilerDef extends ProcessorDef {
+ /** The source file sets. */
+ private final Vector defineSets = new Vector();
+ private Boolean exceptions;
+ private Boolean rtti;
+ private final Vector includePaths = new Vector();
+ private Boolean multithreaded;
+ private final Vector precompileDefs = new Vector();
+ private final Vector sysIncludePaths = new Vector();
+ private OptimizationEnum optimization;
+ private int warnings = -1;
+ public CompilerDef() {
+ }
+ /**
+ * Adds a compiler command-line arg.
+ */
+ public void addConfiguredCompilerArg(CompilerArgument arg) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ addConfiguredProcessorArg(arg);
+ }
+ /**
+ * Adds a compiler command-line arg.
+ */
+ public void addConfiguredCompilerParam(CompilerParam param) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ addConfiguredProcessorParam(param);
+ }
+ /**
+ * Adds a defineset.
+ */
+ public void addConfiguredDefineset(DefineSet defs) {
+ if (defs == null) {
+ throw new NullPointerException("defs");
+ }
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ defineSets.addElement(defs);
+ }
+ /**
+ * Creates an include path.
+ */
+ public IncludePath createIncludePath() {
+ Project p = getProject();
+ if (p == null) {
+ throw new java.lang.IllegalStateException("project must be set");
+ }
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ IncludePath path = new IncludePath(p);
+ includePaths.addElement(path);
+ return path;
+ }
+ /**
+ * Specifies precompilation prototype file and exclusions.
+ *
+ */
+ public PrecompileDef createPrecompile() throws BuildException {
+ Project p = getProject();
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ PrecompileDef precomp = new PrecompileDef();
+ precomp.setProject(p);
+ precompileDefs.addElement(precomp);
+ return precomp;
+ }
+ /**
+ * Creates a system include path. Locations and timestamps of files located
+ * using the system include paths are not used in dependency analysis.
+ *
+ *
+ * Standard include locations should not be specified. The compiler
+ * adapters should recognized the settings from the appropriate environment
+ * variables or configuration files.
+ */
+ public SystemIncludePath createSysIncludePath() {
+ Project p = getProject();
+ if (p == null) {
+ throw new java.lang.IllegalStateException("project must be set");
+ }
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ SystemIncludePath path = new SystemIncludePath(p);
+ sysIncludePaths.addElement(path);
+ return path;
+ }
+ public void execute() throws org.apache.tools.ant.BuildException {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+ public UndefineArgument[] getActiveDefines() {
+ Project p = getProject();
+ if (p == null) {
+ throw new java.lang.IllegalStateException(
+ "project must be set before this call");
+ }
+ if (isReference()) {
+ return ((CompilerDef) getCheckedRef(CompilerDef.class,
+ "CompilerDef")).getActiveDefines();
+ }
+ Vector actives = new Vector();
+ for (int i = 0; i < defineSets.size(); i++) {
+ DefineSet currentSet = (DefineSet) defineSets.elementAt(i);
+ UndefineArgument[] defines = currentSet.getDefines();
+ for (int j = 0; j < defines.length; j++) {
+ if (defines[j].isActive(p)) {
+ actives.addElement(defines[j]);
+ }
+ }
+ }
+ UndefineArgument[] retval = new UndefineArgument[actives.size()];
+ actives.copyInto(retval);
+ return retval;
+ }
+ /**
+ * Returns the compiler-specific include path.
+ */
+ public String[] getActiveIncludePaths() {
+ if (isReference()) {
+ return ((CompilerDef) getCheckedRef(CompilerDef.class,
+ "CompilerDef")).getActiveIncludePaths();
+ }
+ return getActivePaths(includePaths);
+ }
+ private String[] getActivePaths(Vector paths) {
+ Project p = getProject();
+ if (p == null) {
+ throw new java.lang.IllegalStateException("project not set");
+ }
+ Vector activePaths = new Vector(paths.size());
+ for (int i = 0; i < paths.size(); i++) {
+ ConditionalPath path = (ConditionalPath) paths.elementAt(i);
+ if (path.isActive(p)) {
+ String[] pathEntries = path.list();
+ for (int j = 0; j < pathEntries.length; j++) {
+ activePaths.addElement(pathEntries[j]);
+ }
+ }
+ }
+ String[] pathNames = new String[activePaths.size()];
+ activePaths.copyInto(pathNames);
+ return pathNames;
+ }
+ public PrecompileDef getActivePrecompile(CompilerDef ccElement) {
+ if (isReference()) {
+ return ((CompilerDef) getCheckedRef(CompilerDef.class,
+ "CompilerDef")).getActivePrecompile(ccElement);
+ }
+ PrecompileDef current = null;
+ Enumeration iter = precompileDefs.elements();
+ while (iter.hasMoreElements()) {
+ current = (PrecompileDef) iter.nextElement();
+ if (current.isActive()) {
+ return current;
+ }
+ }
+ CompilerDef extendedDef = (CompilerDef) getExtends();
+ if (extendedDef != null) {
+ current = extendedDef.getActivePrecompile(null);
+ if (current != null) {
+ return current;
+ }
+ }
+ if (ccElement != null && getInherit()) {
+ return ccElement.getActivePrecompile(null);
+ }
+ return null;
+ }
+ public String[] getActiveSysIncludePaths() {
+ if (isReference()) {
+ return ((CompilerDef) getCheckedRef(CompilerDef.class,
+ "CompilerDef")).getActiveSysIncludePaths();
+ }
+ return getActivePaths(sysIncludePaths);
+ }
+ public final boolean getExceptions(CompilerDef[] defaultProviders, int index) {
+ if (isReference()) {
+ return ((CompilerDef) getCheckedRef(CompilerDef.class,
+ "CompilerDef")).getExceptions(defaultProviders, index);
+ }
+ if (exceptions != null) {
+ return exceptions.booleanValue();
+ } else {
+ if (defaultProviders != null && index < defaultProviders.length) {
+ return defaultProviders[index].getExceptions(defaultProviders,
+ index + 1);
+ }
+ }
+ return false;
+ }
+ public final Boolean getRtti(CompilerDef[] defaultProviders, int index) {
+ if (isReference()) {
+ return ((CompilerDef) getCheckedRef(CompilerDef.class,
+ "CompilerDef")).getRtti(defaultProviders, index);
+ }
+ if (rtti != null) {
+ return rtti;
+ } else {
+ if (defaultProviders != null && index < defaultProviders.length) {
+ return defaultProviders[index].getRtti(defaultProviders,
+ index + 1);
+ }
+ }
+ return null;
+ }
+ public final OptimizationEnum getOptimization(CompilerDef[] defaultProviders, int index) {
+ if (isReference()) {
+ return ((CompilerDef) getCheckedRef(CompilerDef.class,
+ "CompilerDef")).getOptimization(defaultProviders, index);
+ }
+ if (optimization != null) {
+ return optimization;
+ } else {
+ if (defaultProviders != null && index < defaultProviders.length) {
+ return defaultProviders[index].getOptimization(defaultProviders,
+ index + 1);
+ }
+ }
+ return null;
+ }
+
+ public boolean getMultithreaded(CompilerDef[] defaultProviders, int index) {
+ if (isReference()) {
+ return ((CompilerDef) getCheckedRef(CompilerDef.class,
+ "CompilerDef")).getMultithreaded(defaultProviders, index);
+ }
+ if (multithreaded != null) {
+ return multithreaded.booleanValue();
+ } else {
+ if (defaultProviders != null && index < defaultProviders.length) {
+ return defaultProviders[index].getMultithreaded(
+ defaultProviders, index + 1);
+ }
+ }
+ return true;
+ }
+ public Processor getProcessor() {
+ Processor processor = super.getProcessor();
+ if (processor == null) {
+ processor = GccCCompiler.getInstance();
+ }
+ if (getLibtool() && processor instanceof CommandLineCompiler) {
+ CommandLineCompiler compiler = (CommandLineCompiler) processor;
+ processor = compiler.getLibtoolCompiler();
+ }
+ return processor;
+ }
+ public int getWarnings(CompilerDef[] defaultProviders, int index) {
+ if (isReference()) {
+ return ((CompilerDef) getCheckedRef(CompilerDef.class,
+ "CompilerDef")).getWarnings(defaultProviders, index);
+ }
+ if (warnings == -1) {
+ if (defaultProviders != null && index < defaultProviders.length) {
+ return defaultProviders[index].getWarnings(defaultProviders,
+ index + 1);
+ }
+ }
+ return warnings;
+ }
+ /**
+ * Sets the default compiler adapter. Use the "name" attribute when the
+ * compiler is a supported compiler.
+ *
+ * @param classname
+ * fully qualified classname which implements CompilerAdapter
+ */
+ public void setClassname(String classname) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ super.setClassname(classname);
+ Processor proc = getProcessor();
+ if (!(proc instanceof Compiler)) {
+ throw new BuildException(classname + " does not implement Compiler");
+ }
+ }
+ /**
+ * Enables or disables exception support.
+ *
+ * @param exceptions
+ * if true, exceptions are supported.
+ *
+ */
+ public void setExceptions(boolean exceptions) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.exceptions = booleanValueOf(exceptions);
+ }
+
+ /**
+ * Enables or disables run-time type information.
+ *
+ * @param rtti
+ * if true, run-time type information is supported.
+ *
+ */
+ public void setRtti(boolean rtti) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.rtti = booleanValueOf(rtti);
+ }
+
+ /**
+ * Enables or disables generation of multithreaded code. Unless specified,
+ * multithreaded code generation is enabled.
+ *
+ * @param multithreaded
+ * If true, generated code may be multithreaded.
+ */
+ public void setMultithreaded(boolean multithreaded) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.multithreaded = booleanValueOf(multithreaded);
+ }
+ /**
+ * Sets compiler type.
+ *
+ *
+ * <table width="100%" border="1"> <thead>Supported compilers </thead>
+ * <tr>
+ * <td>gcc (default)</td>
+ * <td>GCC C++ compiler</td>
+ * </tr>
+ * <tr>
+ * <td>g++</td>
+ * <td>GCC C++ compiler</td>
+ * </tr>
+ * <tr>
+ * <td>c++</td>
+ * <td>GCC C++ compiler</td>
+ * </tr>
+ * <tr>
+ * <td>g77</td>
+ * <td>GNU Fortran compiler</td>
+ * </tr>
+ * <tr>
+ * <td>msvc</td>
+ * <td>Microsoft Visual C++</td>
+ * </tr>
+ * <tr>
+ * <td>bcc</td>
+ * <td>Borland C++ Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>msrc</td>
+ * <td>Microsoft Resource Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>brc</td>
+ * <td>Borland Resource Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>df</td>
+ * <td>Compaq Visual Fortran Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>midl</td>
+ * <td>Microsoft MIDL Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>icl</td>
+ * <td>Intel C++ compiler for Windows (IA-32)</td>
+ * </tr>
+ * <tr>
+ * <td>ecl</td>
+ * <td>Intel C++ compiler for Windows (IA-64)</td>
+ * </tr>
+ * <tr>
+ * <td>icc</td>
+ * <td>Intel C++ compiler for Linux (IA-32)</td>
+ * </tr>
+ * <tr>
+ * <td>ecc</td>
+ * <td>Intel C++ compiler for Linux (IA-64)</td>
+ * </tr>
+ * <tr>
+ * <td>CC</td>
+ * <td>Sun ONE C++ compiler</td>
+ * </tr>
+ * <tr>
+ * <td>aCC</td>
+ * <td>HP aC++ C++ Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>os390</td>
+ * <td>OS390 C Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>os400</td>
+ * <td>Icc Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>sunc89</td>
+ * <td>Sun C89 C Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>xlC</td>
+ * <td>VisualAge C Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>uic</td>
+ * <td>Qt user interface compiler</td>
+ * </tr>
+ * <tr>
+ * <td>moc</td>
+ * <td>Qt meta-object compiler</td>
+ * </tr>
+ * <tr>
+ * <td>wcl</td>
+ * <td>OpenWatcom C/C++ compiler</td>
+ * </tr>
+ * <tr>
+ * <td>wfl</td>
+ * <td>OpenWatcom FORTRAN compiler</td>
+ * </tr>
+ * </table>
+ *
+ */
+ public void setName(CompilerEnum name) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ Compiler compiler = name.getCompiler();
+ setProcessor(compiler);
+ }
+ protected void setProcessor(Processor proc) throws BuildException {
+ try {
+ super.setProcessor((Compiler) proc);
+ } catch (ClassCastException ex) {
+ throw new BuildException(ex);
+ }
+ }
+ /**
+ * Enumerated attribute with the values "none", "severe", "default",
+ * "production", "diagnostic", and "aserror".
+ */
+ public void setWarnings(WarningLevelEnum level) {
+ warnings = level.getIndex();
+ }
+ /**
+ * Sets optimization level.
+ *
+ * @param value optimization level
+ */
+ public void setOptimize(OptimizationEnum value) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.optimization = value;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/CompilerEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/CompilerEnum.java
new file mode 100644
index 0000000..0233050
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/CompilerEnum.java
@@ -0,0 +1,262 @@
+/*
+ *
+ * Copyright 2002-2008 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;
+import net.sf.antcontrib.cpptasks.arm.ADSCCompiler;
+import net.sf.antcontrib.cpptasks.borland.BorlandCCompiler;
+import net.sf.antcontrib.cpptasks.borland.BorlandResourceCompiler;
+import net.sf.antcontrib.cpptasks.compaq.CompaqVisualFortranCompiler;
+import net.sf.antcontrib.cpptasks.compiler.Compiler;
+import net.sf.antcontrib.cpptasks.devstudio.DevStudioCCompiler;
+import net.sf.antcontrib.cpptasks.devstudio.DevStudio2005CCompiler;
+import net.sf.antcontrib.cpptasks.devstudio.DevStudioMIDLCompiler;
+import net.sf.antcontrib.cpptasks.devstudio.DevStudioResourceCompiler;
+import net.sf.antcontrib.cpptasks.gcc.GccCCompiler;
+import net.sf.antcontrib.cpptasks.gcc.WindresResourceCompiler;
+import net.sf.antcontrib.cpptasks.hp.aCCCompiler;
+import net.sf.antcontrib.cpptasks.ibm.VisualAgeCCompiler;
+import net.sf.antcontrib.cpptasks.intel.IntelLinux32CCompiler;
+import net.sf.antcontrib.cpptasks.intel.IntelLinux64CCompiler;
+import net.sf.antcontrib.cpptasks.intel.IntelWin32CCompiler;
+import net.sf.antcontrib.cpptasks.intel.IntelWin64CCompiler;
+import net.sf.antcontrib.cpptasks.mozilla.XpidlCompiler;
+import net.sf.antcontrib.cpptasks.os390.OS390CCompiler;
+import net.sf.antcontrib.cpptasks.os400.IccCompiler;
+import net.sf.antcontrib.cpptasks.sun.C89CCompiler;
+import net.sf.antcontrib.cpptasks.sun.ForteCCCompiler;
+import net.sf.antcontrib.cpptasks.ti.ClxxCCompiler;
+import net.sf.antcontrib.cpptasks.trolltech.MetaObjectCompiler;
+import net.sf.antcontrib.cpptasks.trolltech.UserInterfaceCompiler;
+import net.sf.antcontrib.cpptasks.openwatcom.OpenWatcomCCompiler;
+import net.sf.antcontrib.cpptasks.openwatcom.OpenWatcomFortranCompiler;
+
+import org.apache.tools.ant.types.EnumeratedAttribute;
+/**
+ * Enumeration of supported compilers
+ *
+ * <table width="100%" border="1"> <thead>Supported compilers </thead>
+ * <tr>
+ * <td>gcc (default)</td>
+ * <td>GCC C++ compiler</td>
+ * </tr>
+ * <tr>
+ * <td>g++</td>
+ * <td>GCC C++ compiler</td>
+ * </tr>
+ * <tr>
+ * <td>c++</td>
+ * <td>GCC C++ compiler</td>
+ * </tr>
+ * <tr>
+ * <td>g77</td>
+ * <td>GNU FORTRAN compiler</td>
+ * </tr>
+ * <tr>
+ * <td>msvc</td>
+ * <td>Microsoft Visual C++</td>
+ * </tr>
+ * <tr>
+ * <td>msvc8</td>
+ * <td>Microsoft Visual C++ 8</td>
+ * </tr>
+ * <tr>
+ * <td>bcc</td>
+ * <td>Borland C++ Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>msrc</td>
+ * <td>Microsoft Resource Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>brc</td>
+ * <td>Borland Resource Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>df</td>
+ * <td>Compaq Visual Fortran Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>midl</td>
+ * <td>Microsoft MIDL Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>icl</td>
+ * <td>Intel C++ compiler for Windows (IA-32)</td>
+ * </tr>
+ * <tr>
+ * <td>ecl</td>
+ * <td>Intel C++ compiler for Windows (IA-64)</td>
+ * </tr>
+ * <tr>
+ * <td>icc</td>
+ * <td>Intel C++ compiler for Linux (IA-32)</td>
+ * </tr>
+ * <tr>
+ * <td>ecc</td>
+ * <td>Intel C++ compiler for Linux (IA-64)</td>
+ * </tr>
+ * <tr>
+ * <td>CC</td>
+ * <td>Sun ONE C++ compiler</td>
+ * </tr>
+ * <tr>
+ * <td>aCC</td>
+ * <td>HP aC++ C++ Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>os390</td>
+ * <td>OS390 C Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>os400</td>
+ * <td>Icc Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>sunc89</td>
+ * <td>Sun C89 C Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>xlC</td>
+ * <td>VisualAge C Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>cl6x</td>
+ * <td>TI TMS320C6000 Optimizing Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>cl55</td>
+ * <td>TI TMS320C55x Optimizing C/C++ Compiler</td>
+ * </tr>
+ * <tr>
+ * <td>armcpp</td>
+ * <td>ARM 32-bit C++ compiler</td>
+ * </tr>
+ * <tr>
+ * <td>armcc</td>
+ * <td>ARM 32-bit C compiler</td>
+ * </tr>
+ * <tr>
+ * <td>tcpp</td>
+ * <td>ARM 16-bit C++ compiler</td>
+ * </tr>
+ * <tr>
+ * <td>tcc</td>
+ * <td>ARM 16-bit C compiler</td>
+ * </tr>
+ * * <tr>
+ * <td>uic</td>
+ * <td>Qt user interface compiler</td>
+ * </tr>
+ * <tr>
+ * <td>moc</td>
+ * <td>Qt meta-object compiler</td>
+ * </tr>
+ * <tr>
+ * <td>xpidl</td>
+ * <td>Mozilla xpidl compiler (creates .h and .xpt files).</td>
+ * </tr>
+ * <tr>
+ * <td>wcl</td>
+ * <td>OpenWatcom C/C++ compiler (experimental)</td>
+ * </tr>
+ * <tr>
+ * <td>wfl</td>
+ * <td>OpenWatcom FORTRAN compiler (experimental)</td>
+ * </tr>
+ * <tr>
+ * <td>windres</td>
+ * <td>GNU windres resource compiler</td>
+ * </tr>
+ * </table>
+ *
+ * @author Curt Arnold
+ *
+ */
+public class CompilerEnum extends EnumeratedAttribute {
+ private final static ProcessorEnumValue[] compilers = new ProcessorEnumValue[]{
+ new ProcessorEnumValue("gcc", GccCCompiler.getInstance()),
+ new ProcessorEnumValue("g++", GccCCompiler.getGppInstance()),
+ new ProcessorEnumValue("c++", GccCCompiler.getCppInstance()),
+ new ProcessorEnumValue("g77", GccCCompiler.getG77Instance()),
+ new ProcessorEnumValue("msvc", DevStudioCCompiler.getInstance()),
+ new ProcessorEnumValue("msvc8", DevStudio2005CCompiler.getInstance()),
+ new ProcessorEnumValue("bcc", BorlandCCompiler.getInstance()),
+ new ProcessorEnumValue("msrc", DevStudioResourceCompiler
+ .getInstance()),
+ new ProcessorEnumValue("brc", BorlandResourceCompiler.getInstance()),
+ new ProcessorEnumValue("df", CompaqVisualFortranCompiler
+ .getInstance()),
+ new ProcessorEnumValue("midl", DevStudioMIDLCompiler.getInstance()),
+ new ProcessorEnumValue("icl", IntelWin32CCompiler.getInstance()),
+ new ProcessorEnumValue("ecl", IntelWin64CCompiler.getInstance()),
+ new ProcessorEnumValue("icc", IntelLinux32CCompiler.getInstance()),
+ new ProcessorEnumValue("ecc", IntelLinux64CCompiler.getInstance()),
+ new ProcessorEnumValue("CC", ForteCCCompiler.getInstance()),
+ new ProcessorEnumValue("aCC", aCCCompiler.getInstance()),
+ new ProcessorEnumValue("os390", OS390CCompiler.getInstance()),
+ new ProcessorEnumValue("os400", IccCompiler.getInstance()),
+ new ProcessorEnumValue("sunc89", C89CCompiler.getInstance()),
+ new ProcessorEnumValue("xlC", VisualAgeCCompiler.getInstance()),
+ new ProcessorEnumValue("cl6x", ClxxCCompiler.getCl6xInstance()),
+ new ProcessorEnumValue("cl55", ClxxCCompiler.getCl55Instance()),
+ new ProcessorEnumValue("armcc", ADSCCompiler.getArmCC()),
+ new ProcessorEnumValue("armcpp", ADSCCompiler.getArmCpp()),
+ new ProcessorEnumValue("tcc", ADSCCompiler.getThumbCC()),
+ new ProcessorEnumValue("tcpp", ADSCCompiler.getThumbCpp()),
+ // GCC Cross Compilers
+ new ProcessorEnumValue(
+ "sparc-sun-solaris2-gcc",
+ net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccCCompiler
+ .getInstance()),
+ new ProcessorEnumValue(
+ "sparc-sun-solaris2-g++",
+ net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccCCompiler
+ .getGppInstance()),
+ new ProcessorEnumValue(
+ "sparc-sun-solaris2-c++",
+ net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccCCompiler
+ .getCppInstance()),
+ new ProcessorEnumValue(
+ "sparc-sun-solaris2-g77",
+ net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccCCompiler
+ .getG77Instance()),
+ // GCC Cross Compilers
+ new ProcessorEnumValue("gcc-cross",
+ net.sf.antcontrib.cpptasks.gcc.cross.GccCCompiler
+ .getInstance()),
+ new ProcessorEnumValue("g++-cross",
+ net.sf.antcontrib.cpptasks.gcc.cross.GccCCompiler
+ .getGppInstance()),
+ new ProcessorEnumValue("c++-cross",
+ net.sf.antcontrib.cpptasks.gcc.cross.GccCCompiler
+ .getCppInstance()),
+ new ProcessorEnumValue("g77-cross",
+ net.sf.antcontrib.cpptasks.gcc.cross.GccCCompiler
+ .getG77Instance()),
+ new ProcessorEnumValue("uic", UserInterfaceCompiler.getInstance()),
+ new ProcessorEnumValue("moc", MetaObjectCompiler.getInstance()),
+ new ProcessorEnumValue("xpidl", XpidlCompiler.getInstance()),
+ new ProcessorEnumValue("wcl", OpenWatcomCCompiler.getInstance()),
+ new ProcessorEnumValue("wfl", OpenWatcomFortranCompiler.getInstance()),
+ new ProcessorEnumValue("windres", WindresResourceCompiler.getInstance())
+ };
+ public Compiler getCompiler() {
+ return (Compiler) compilers[getIndex()].getProcessor();
+ }
+ public String[] getValues() {
+ return ProcessorEnumValue.getValues(compilers);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/CompilerParam.java b/src/main/java/net/sf/antcontrib/cpptasks/CompilerParam.java
new file mode 100644
index 0000000..8a15a77
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/CompilerParam.java
@@ -0,0 +1,33 @@
+/*
+ *
+ * Copyright 2001-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;
+/*******************************************************************************
+ * Place class description here.
+ *
+ * @author inger
+ * @author <additional author>
+ *
+ * @since
+ ******************************************************************************/
+public class CompilerParam extends ProcessorParam {
+ public CompilerParam() {
+ }
+ public void execute() throws org.apache.tools.ant.BuildException {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/DependencyInfo.java b/src/main/java/net/sf/antcontrib/cpptasks/DependencyInfo.java
new file mode 100644
index 0000000..a04105f
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/DependencyInfo.java
@@ -0,0 +1,86 @@
+/*
+ *
+ * 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;
+import java.util.Vector;
+/**
+ * @author Curt Arnold
+ */
+public final class DependencyInfo {
+ /**
+ * Last modified time of this file or anything that it depends on.
+ *
+ * Not persisted since almost any change could invalidate it. Initialized
+ * to long.MIN_VALUE on construction.
+ */
+ private long compositeLastModified;
+ private/* final */String includePathIdentifier;
+ private/* final */String[] includes;
+ private/* final */String source;
+ private/* final */long sourceLastModified;
+ private/* final */String[] sysIncludes;
+ public DependencyInfo(String includePathIdentifier, String source,
+ long sourceLastModified, Vector includes, Vector sysIncludes) {
+ if (source == null) {
+ throw new NullPointerException("source");
+ }
+ if (includePathIdentifier == null) {
+ throw new NullPointerException("includePathIdentifier");
+ }
+ this.source = source;
+ this.sourceLastModified = sourceLastModified;
+ this.includePathIdentifier = includePathIdentifier;
+ this.includes = new String[includes.size()];
+ if (includes.size() == 0) {
+ compositeLastModified = sourceLastModified;
+ } else {
+ includes.copyInto(this.includes);
+ compositeLastModified = Long.MIN_VALUE;
+ }
+ this.sysIncludes = new String[sysIncludes.size()];
+ sysIncludes.copyInto(this.sysIncludes);
+ }
+ /**
+ * Returns the latest modification date of the source or anything that it
+ * depends on.
+ *
+ * @return the composite lastModified time, returns Long.MIN_VALUE if not
+ * set
+ */
+ public long getCompositeLastModified() {
+ return compositeLastModified;
+ }
+ public String getIncludePathIdentifier() {
+ return includePathIdentifier;
+ }
+ public String[] getIncludes() {
+ String[] includesClone = (String[]) includes.clone();
+ return includesClone;
+ }
+ public String getSource() {
+ return source;
+ }
+ public long getSourceLastModified() {
+ return sourceLastModified;
+ }
+ public String[] getSysIncludes() {
+ String[] sysIncludesClone = (String[]) sysIncludes.clone();
+ return sysIncludesClone;
+ }
+ public void setCompositeLastModified(long lastMod) {
+ compositeLastModified = lastMod;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/DependencyTable.java b/src/main/java/net/sf/antcontrib/cpptasks/DependencyTable.java
new file mode 100644
index 0000000..48a7278
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/DependencyTable.java
@@ -0,0 +1,610 @@
+/*
+ *
+ * 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;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import net.sf.antcontrib.cpptasks.compiler.CompilerConfiguration;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+/**
+ * @author Curt Arnold
+ */
+public final class DependencyTable {
+ /**
+ * This class handles populates the TargetHistory hashtable in response to
+ * SAX parse events
+ */
+ private class DependencyTableHandler extends DefaultHandler {
+ private File baseDir;
+ private final DependencyTable dependencyTable;
+ private String includePath;
+ private Vector includes;
+ private String source;
+ private long sourceLastModified;
+ private Vector sysIncludes;
+ /**
+ * Constructor
+ *
+ * @param history
+ * hashtable of TargetHistory keyed by output name
+ * @param outputFiles
+ * existing files in output directory
+ */
+ private DependencyTableHandler(DependencyTable dependencyTable,
+ File baseDir) {
+ this.dependencyTable = dependencyTable;
+ this.baseDir = baseDir;
+ includes = new Vector();
+ sysIncludes = new Vector();
+ source = null;
+ }
+ public void endElement(String namespaceURI, String localName,
+ String qName) throws SAXException {
+ //
+ // if </source> then
+ // create Dependency object and add to hashtable
+ // if corresponding source file exists and
+ // has the same timestamp
+ //
+ if (qName.equals("source")) {
+ if (source != null && includePath != null) {
+ File existingFile = new File(baseDir, source);
+ //
+ // if the file exists and the time stamp is right
+ // preserve the dependency info
+ if (existingFile.exists()) {
+ //
+ // would have expected exact matches
+ // but was seeing some unexpected difference by
+ // a few tens of milliseconds, as long
+ // as the times are within a second
+ long existingLastModified = existingFile.lastModified();
+ if (!CUtil.isSignificantlyAfter(existingLastModified, sourceLastModified) &&
+ !CUtil.isSignificantlyBefore(existingLastModified, sourceLastModified)) {
+ DependencyInfo dependInfo = new DependencyInfo(
+ includePath, source, sourceLastModified,
+ includes, sysIncludes);
+ dependencyTable.putDependencyInfo(source,
+ dependInfo);
+ }
+ }
+ source = null;
+ includes.setSize(0);
+ }
+ } else {
+ //
+ // this causes any <source> elements outside the
+ // scope of an <includePath> to be discarded
+ //
+ if (qName.equals("includePath")) {
+ includePath = null;
+ }
+ }
+ }
+ /**
+ * startElement handler
+ */
+ public void startElement(String namespaceURI, String localName,
+ String qName, Attributes atts) throws SAXException {
+ //
+ // if includes, then add relative file name to vector
+ //
+ if (qName.equals("include")) {
+ includes.addElement(atts.getValue("file"));
+ } else {
+ if (qName.equals("sysinclude")) {
+ sysIncludes.addElement(atts.getValue("file"));
+ } else {
+ //
+ // if source then
+ // capture source file name,
+ // modification time and reset includes vector
+ //
+ if (qName.equals("source")) {
+ source = atts.getValue("file");
+ sourceLastModified = Long.parseLong(atts
+ .getValue("lastModified"), 16);
+ includes.setSize(0);
+ sysIncludes.setSize(0);
+ } else {
+ if (qName.equals("includePath")) {
+ includePath = atts.getValue("signature");
+ }
+ }
+ }
+ }
+ }
+ }
+ public abstract class DependencyVisitor {
+ /**
+ * Previews all the children of this source file.
+ *
+ * May be called multiple times as DependencyInfo's for children are
+ * filled in.
+ *
+ * @return true to continue towards recursion into included files
+ */
+ public abstract boolean preview(DependencyInfo parent,
+ DependencyInfo[] children);
+ /**
+ * Called if the dependency depth exhausted the stack.
+ */
+ public abstract void stackExhausted();
+ /**
+ * Visits the dependency info.
+ *
+ * @return true to continue towards recursion into included files
+ */
+ public abstract boolean visit(DependencyInfo dependInfo);
+ }
+ public class TimestampChecker extends DependencyVisitor {
+ private boolean noNeedToRebuild;
+ private long outputLastModified;
+ private boolean rebuildOnStackExhaustion;
+ public TimestampChecker(final long outputLastModified,
+ boolean rebuildOnStackExhaustion) {
+ this.outputLastModified = outputLastModified;
+ noNeedToRebuild = true;
+ this.rebuildOnStackExhaustion = rebuildOnStackExhaustion;
+ }
+ public boolean getMustRebuild() {
+ return !noNeedToRebuild;
+ }
+ public boolean preview(DependencyInfo parent, DependencyInfo[] children) {
+ int withCompositeTimes = 0;
+ long parentCompositeLastModified = parent.getSourceLastModified();
+ for (int i = 0; i < children.length; i++) {
+ if (children[i] != null) {
+ //
+ // expedient way to determine if a child forces us to
+ // rebuild
+ //
+ visit(children[i]);
+ long childCompositeLastModified = children[i]
+ .getCompositeLastModified();
+ if (childCompositeLastModified != Long.MIN_VALUE) {
+ withCompositeTimes++;
+ if (childCompositeLastModified > parentCompositeLastModified) {
+ parentCompositeLastModified = childCompositeLastModified;
+ }
+ }
+ }
+ }
+ if (withCompositeTimes == children.length) {
+ parent.setCompositeLastModified(parentCompositeLastModified);
+ }
+ //
+ // may have been changed by an earlier call to visit()
+ //
+ return noNeedToRebuild;
+ }
+ public void stackExhausted() {
+ if (rebuildOnStackExhaustion) {
+ noNeedToRebuild = false;
+ }
+ }
+ public boolean visit(DependencyInfo dependInfo) {
+ if (noNeedToRebuild) {
+ if (CUtil.isSignificantlyAfter(dependInfo.getSourceLastModified(), outputLastModified)
+ || CUtil.isSignificantlyAfter(dependInfo.getCompositeLastModified(), outputLastModified)) {
+ noNeedToRebuild = false;
+ }
+ }
+ //
+ // only need to process the children if
+ // it has not yet been determined whether
+ // we need to rebuild and the composite modified time
+ // has not been determined for this file
+ return noNeedToRebuild
+ && dependInfo.getCompositeLastModified() == Long.MIN_VALUE;
+ }
+ }
+ private/* final */File baseDir;
+ private String baseDirPath;
+ /**
+ * a hashtable of DependencyInfo[] keyed by output file name
+ */
+ private final Hashtable dependencies = new Hashtable();
+ /** The file the cache was loaded from. */
+ private/* final */File dependenciesFile;
+ /** Flag indicating whether the cache should be written back to file. */
+ private boolean dirty;
+ /**
+ * Creates a target history table from dependencies.xml in the prject
+ * directory, if it exists. Otherwise, initializes the dependencies empty.
+ *
+ * @param baseDir
+ * output directory for task
+ */
+ public DependencyTable(File baseDir) {
+ if (baseDir == null) {
+ throw new NullPointerException("baseDir");
+ }
+ this.baseDir = baseDir;
+ try {
+ baseDirPath = baseDir.getCanonicalPath();
+ } catch (IOException ex) {
+ baseDirPath = baseDir.toString();
+ }
+ dirty = false;
+ //
+ // load any existing dependencies from file
+ dependenciesFile = new File(baseDir, "dependencies.xml");
+ }
+ public void commit(CCTask task) {
+ //
+ // if not dirty, no need to update file
+ //
+ if (dirty) {
+ //
+ // walk through dependencies to get vector of include paths
+ // identifiers
+ //
+ Vector includePaths = getIncludePaths();
+ //
+ //
+ // write dependency file
+ //
+ try {
+ FileOutputStream outStream = new FileOutputStream(
+ dependenciesFile);
+ OutputStreamWriter streamWriter;
+ //
+ // Early VM's may not have UTF-8 support
+ // fallback to default code page which
+ // "should" be okay unless there are
+ // non ASCII file names
+ String encodingName = "UTF-8";
+ try {
+ streamWriter = new OutputStreamWriter(outStream, "UTF-8");
+ } catch (UnsupportedEncodingException ex) {
+ streamWriter = new OutputStreamWriter(outStream);
+ encodingName = streamWriter.getEncoding();
+ }
+ BufferedWriter writer = new BufferedWriter(streamWriter);
+ writer.write("<?xml version='1.0' encoding='");
+ writer.write(encodingName);
+ writer.write("'?>\n");
+ writer.write("<dependencies>\n");
+ StringBuffer buf = new StringBuffer();
+ Enumeration includePathEnum = includePaths.elements();
+ while (includePathEnum.hasMoreElements()) {
+ writeIncludePathDependencies((String) includePathEnum
+ .nextElement(), writer, buf);
+ }
+ writer.write("</dependencies>\n");
+ writer.close();
+ dirty = false;
+ } catch (IOException ex) {
+ task.log("Error writing " + dependenciesFile.toString() + ":"
+ + ex.toString());
+ }
+ }
+ }
+ /**
+ * Returns an enumerator of DependencyInfo's
+ */
+ public Enumeration elements() {
+ return dependencies.elements();
+ }
+ /**
+ * This method returns a DependencyInfo for the specific source file and
+ * include path identifier
+ *
+ */
+ public DependencyInfo getDependencyInfo(String sourceRelativeName,
+ String includePathIdentifier) {
+ DependencyInfo dependInfo = null;
+ DependencyInfo[] dependInfos = (DependencyInfo[]) dependencies
+ .get(sourceRelativeName);
+ if (dependInfos != null) {
+ for (int i = 0; i < dependInfos.length; i++) {
+ dependInfo = dependInfos[i];
+ if (dependInfo.getIncludePathIdentifier().equals(
+ includePathIdentifier)) {
+ return dependInfo;
+ }
+ }
+ }
+ return null;
+ }
+ private Vector getIncludePaths() {
+ Vector includePaths = new Vector();
+ DependencyInfo[] dependInfos;
+ Enumeration dependenciesEnum = dependencies.elements();
+ while (dependenciesEnum.hasMoreElements()) {
+ dependInfos = (DependencyInfo[]) dependenciesEnum.nextElement();
+ for (int i = 0; i < dependInfos.length; i++) {
+ DependencyInfo dependInfo = dependInfos[i];
+ boolean matchesExisting = false;
+ final String dependIncludePath = dependInfo
+ .getIncludePathIdentifier();
+ Enumeration includePathEnum = includePaths.elements();
+ while (includePathEnum.hasMoreElements()) {
+ if (dependIncludePath.equals(includePathEnum.nextElement())) {
+ matchesExisting = true;
+ break;
+ }
+ }
+ if (!matchesExisting) {
+ includePaths.addElement(dependIncludePath);
+ }
+ }
+ }
+ return includePaths;
+ }
+ public void load() throws IOException, ParserConfigurationException,
+ SAXException {
+ dependencies.clear();
+ if (dependenciesFile.exists()) {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setValidating(false);
+ SAXParser parser = factory.newSAXParser();
+ parser.parse(dependenciesFile, new DependencyTableHandler(this,
+ baseDir));
+ dirty = false;
+ }
+ }
+ /**
+ * Determines if the specified target needs to be rebuilt.
+ *
+ * This task may result in substantial IO as files are parsed to determine
+ * their dependencies
+ */
+ public boolean needsRebuild(CCTask task, TargetInfo target,
+ int dependencyDepth) {
+ // look at any files where the compositeLastModified
+ // is not known, but the includes are known
+ //
+ boolean mustRebuild = false;
+ CompilerConfiguration compiler = (CompilerConfiguration) target
+ .getConfiguration();
+ String includePathIdentifier = compiler.getIncludePathIdentifier();
+ File[] sources = target.getSources();
+ DependencyInfo[] dependInfos = new DependencyInfo[sources.length];
+ long outputLastModified = target.getOutput().lastModified();
+ //
+ // try to solve problem using existing dependency info
+ // (not parsing any new files)
+ //
+ DependencyInfo[] stack = new DependencyInfo[50];
+ boolean rebuildOnStackExhaustion = true;
+ if (dependencyDepth >= 0) {
+ if (dependencyDepth < 50) {
+ stack = new DependencyInfo[dependencyDepth];
+ }
+ rebuildOnStackExhaustion = false;
+ }
+ TimestampChecker checker = new TimestampChecker(outputLastModified,
+ rebuildOnStackExhaustion);
+ for (int i = 0; i < sources.length && !mustRebuild; i++) {
+ File source = sources[i];
+ String relative = CUtil.getRelativePath(baseDirPath, source);
+ DependencyInfo dependInfo = getDependencyInfo(relative,
+ includePathIdentifier);
+ if (dependInfo == null) {
+ task.log("Parsing " + relative, Project.MSG_VERBOSE);
+ dependInfo = parseIncludes(task, compiler, source);
+ }
+ walkDependencies(task, dependInfo, compiler, stack, checker);
+ mustRebuild = checker.getMustRebuild();
+ }
+ return mustRebuild;
+ }
+ public DependencyInfo parseIncludes(CCTask task,
+ CompilerConfiguration compiler, File source) {
+ DependencyInfo dependInfo = compiler.parseIncludes(task, baseDir,
+ source);
+ String relativeSource = CUtil.getRelativePath(baseDirPath, source);
+ putDependencyInfo(relativeSource, dependInfo);
+ return dependInfo;
+ }
+ private void putDependencyInfo(String key, DependencyInfo dependInfo) {
+ //
+ // optimistic, add new value
+ //
+ DependencyInfo[] old = (DependencyInfo[]) dependencies.put(key,
+ new DependencyInfo[]{dependInfo});
+ dirty = true;
+ //
+ // something was already there
+ //
+ if (old != null) {
+ //
+ // see if the include path matches a previous entry
+ // if so replace it
+ String includePathIdentifier = dependInfo
+ .getIncludePathIdentifier();
+ for (int i = 0; i < old.length; i++) {
+ DependencyInfo oldDepend = old[i];
+ if (oldDepend.getIncludePathIdentifier().equals(
+ includePathIdentifier)) {
+ old[i] = dependInfo;
+ dependencies.put(key, old);
+ return;
+ }
+ }
+ //
+ // no match prepend the new entry to the array
+ // of dependencies for the file
+ DependencyInfo[] combined = new DependencyInfo[old.length + 1];
+ combined[0] = dependInfo;
+ for (int i = 0; i < old.length; i++) {
+ combined[i + 1] = old[i];
+ }
+ dependencies.put(key, combined);
+ }
+ return;
+ }
+ public void walkDependencies(CCTask task, DependencyInfo dependInfo,
+ CompilerConfiguration compiler, DependencyInfo[] stack,
+ DependencyVisitor visitor) throws BuildException {
+ //
+ // visit this node
+ // if visit returns true then
+ // visit the referenced include and sysInclude dependencies
+ //
+ if (visitor.visit(dependInfo)) {
+ //
+ // find first null entry on stack
+ //
+ int stackPosition = -1;
+ for (int i = 0; i < stack.length; i++) {
+ if (stack[i] == null) {
+ stackPosition = i;
+ stack[i] = dependInfo;
+ break;
+ } else {
+ //
+ // if we have appeared early in the calling history
+ // then we didn't exceed the criteria
+ if (stack[i] == dependInfo) {
+ return;
+ }
+ }
+ }
+ if (stackPosition == -1) {
+ visitor.stackExhausted();
+ return;
+ }
+ //
+ // locate dependency infos
+ //
+ String[] includes = dependInfo.getIncludes();
+ String includePathIdentifier = compiler.getIncludePathIdentifier();
+ DependencyInfo[] includeInfos = new DependencyInfo[includes.length];
+ for (int i = 0; i < includes.length; i++) {
+ DependencyInfo includeInfo = getDependencyInfo(includes[i],
+ includePathIdentifier);
+ includeInfos[i] = includeInfo;
+ }
+ //
+ // preview with only the already available dependency infos
+ //
+ if (visitor.preview(dependInfo, includeInfos)) {
+ //
+ // now need to fill in the missing DependencyInfos
+ //
+ int missingCount = 0;
+ for (int i = 0; i < includes.length; i++) {
+ if (includeInfos[i] == null) {
+ missingCount++;
+ task.log("Parsing " + includes[i], Project.MSG_VERBOSE);
+ //
+ // If the include filepath is relative
+ // then anchor it the base directory
+ File src = new File(includes[i]);
+ if (!src.isAbsolute()) {
+ src = new File(baseDir, includes[i]);
+ }
+ DependencyInfo includeInfo = parseIncludes(task,
+ compiler, src);
+ includeInfos[i] = includeInfo;
+ }
+ }
+ //
+ // if it passes a review the second time
+ // then recurse into all the children
+ if (missingCount == 0
+ || visitor.preview(dependInfo, includeInfos)) {
+ //
+ // recurse into
+ //
+ for (int i = 0; i < includeInfos.length; i++) {
+ DependencyInfo includeInfo = includeInfos[i];
+ walkDependencies(task, includeInfo, compiler, stack,
+ visitor);
+ }
+ }
+ }
+ stack[stackPosition] = null;
+ }
+ }
+ private void writeDependencyInfo(BufferedWriter writer, StringBuffer buf,
+ DependencyInfo dependInfo) throws IOException {
+ String[] includes = dependInfo.getIncludes();
+ String[] sysIncludes = dependInfo.getSysIncludes();
+ //
+ // if the includes have not been evaluted then
+ // it is not worth our time saving it
+ // and trying to distiguish between files with
+ // no dependencies and those with undetermined dependencies
+ buf.setLength(0);
+ buf.append(" <source file=\"");
+ buf.append(CUtil.xmlAttribEncode(dependInfo.getSource()));
+ buf.append("\" lastModified=\"");
+ buf.append(Long.toHexString(dependInfo.getSourceLastModified()));
+ buf.append("\">\n");
+ writer.write(buf.toString());
+ for (int i = 0; i < includes.length; i++) {
+ buf.setLength(0);
+ buf.append(" <include file=\"");
+ buf.append(CUtil.xmlAttribEncode(includes[i]));
+ buf.append("\"/>\n");
+ writer.write(buf.toString());
+ }
+ for (int i = 0; i < sysIncludes.length; i++) {
+ buf.setLength(0);
+ buf.append(" <sysinclude file=\"");
+ buf.append(CUtil.xmlAttribEncode(sysIncludes[i]));
+ buf.append("\"/>\n");
+ writer.write(buf.toString());
+ }
+ writer.write(" </source>\n");
+ return;
+ }
+ private void writeIncludePathDependencies(String includePathIdentifier,
+ BufferedWriter writer, StringBuffer buf) throws IOException {
+ //
+ // include path element
+ //
+ buf.setLength(0);
+ buf.append(" <includePath signature=\"");
+ buf.append(CUtil.xmlAttribEncode(includePathIdentifier));
+ buf.append("\">\n");
+ writer.write(buf.toString());
+ Enumeration dependenciesEnum = dependencies.elements();
+ while (dependenciesEnum.hasMoreElements()) {
+ DependencyInfo[] dependInfos = (DependencyInfo[]) dependenciesEnum
+ .nextElement();
+ for (int i = 0; i < dependInfos.length; i++) {
+ DependencyInfo dependInfo = dependInfos[i];
+ //
+ // if this is for the same include path
+ // then output the info
+ if (dependInfo.getIncludePathIdentifier().equals(
+ includePathIdentifier)) {
+ writeDependencyInfo(writer, buf, dependInfo);
+ }
+ }
+ }
+ writer.write(" </includePath>\n");
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/DistributerDef.java b/src/main/java/net/sf/antcontrib/cpptasks/DistributerDef.java
new file mode 100644
index 0000000..f40ac8e
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/DistributerDef.java
@@ -0,0 +1,243 @@
+/*
+ *
+ * Copyright 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;
+
+
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Reference;
+import java.util.Vector;
+
+/**
+ * Distributed build information (Non-functional prototype).
+ *
+ */
+public final class DistributerDef
+ extends DataType {
+ /**
+ * if property.
+ */
+ private String ifCond;
+
+ /**
+ * unless property.
+ */
+ private String unlessCond;
+
+ /**
+ * hosts.
+ *
+ */
+ private String hosts;
+
+ /**
+ * Protocol.
+ *
+ */
+ private DistributerProtocolEnum protocol;
+
+ /**
+ * Not sure what this is.
+ */
+ private int tcpCork;
+
+ /**
+ * user name.
+ */
+ private String user;
+
+ /**
+ * local to remote file name maps.
+ */
+ private final Vector maps = new Vector();
+
+ /**
+ * Constructor.
+ *
+ */
+ public DistributerDef() {
+ }
+
+ /**
+ * Required by documentation generator.
+ */
+ public void execute() {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+
+ /**
+ * Returns true if the if and unless conditions (if any) are
+ * satisfied.
+ * @return true if definition is active.
+ */
+ public boolean isActive() {
+ return CUtil.isActive(getProject(), ifCond, unlessCond);
+ }
+
+ /**
+ * Sets an id that can be used to reference this element.
+ *
+ * @param id
+ * id
+ */
+ public void setId(final String id) {
+ //
+ // this is actually accomplished by a different
+ // mechanism, but we can document it
+ //
+ }
+
+ /**
+ * Sets the property name for the 'if' condition.
+ *
+ * The define will be ignored unless the property is defined.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") will throw an exception when
+ * evaluated.
+ *
+ * @param propName
+ * property name
+ */
+ public void setIf(final String propName) {
+ ifCond = propName;
+ }
+
+ /**
+ * Specifies that this element should behave as if the content of the
+ * element with the matching id attribute was inserted at this location. If
+ * specified, no other attributes should be specified.
+ * @param r reference name
+ */
+ public void setRefid(final Reference r) {
+ super.setRefid(r);
+ }
+
+ /**
+ * Set the property name for the 'unless' condition.
+ *
+ * If named property is set, the define will be ignored.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") of the behavior will throw an
+ * exception when evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public void setUnless(final String propName) {
+ unlessCond = propName;
+ }
+
+ /**
+ * Gets hosts.
+ * @return hosts, may be null.
+ *
+ */
+ public String getHosts() {
+ if (isReference()) {
+ DistributerDef refDistributer = (DistributerDef)
+ getCheckedRef(DistributerDef.class,
+ "DistributerDef");
+ return refDistributer.getHosts();
+ }
+ return hosts;
+ }
+
+ /**
+ * Gets tcp cork.
+ * @return TCP_CORK value.
+ *
+ */
+ public int getTcpcork() {
+ if (isReference()) {
+ DistributerDef refDistributer = (DistributerDef)
+ getCheckedRef(DistributerDef.class,
+ "DistributerDef");
+ return refDistributer.getTcpcork();
+ }
+ return tcpCork;
+ }
+
+ /**
+ * Gets protocol.
+ * @return protocol, may be null.
+ *
+ */
+ public DistributerProtocolEnum getProtocol() {
+ if (isReference()) {
+ DistributerDef refDistributer = (DistributerDef)
+ getCheckedRef(DistributerDef.class,
+ "DistributerDef");
+ return refDistributer.getProtocol();
+ }
+ return protocol;
+ }
+
+ /**
+ * Sets hosts.
+ * @param value new value
+ */
+ public void setHosts(final String value) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ hosts = value;
+ }
+
+ /**
+ * Sets TCP_CORK value.
+ * @param value new value
+ */
+ public void setTcpcork(final int value) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ tcpCork = value;
+ }
+
+ /**
+ * Sets protocol.
+ * @param value new value
+ */
+ public void setProtocol(final DistributerProtocolEnum value) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ protocol = value;
+ }
+
+ /**
+ * Local to remote filename maps.
+ * @return new map
+ */
+ public DistributerMap createMap() {
+ DistributerMap map = new DistributerMap();
+ map.setProject(getProject());
+ maps.addElement(map);
+ return map;
+ }
+
+ /**
+ * Sets remote user name.
+ * @param value user name
+ */
+ public void setUser(final String value) {
+ user = value;
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/DistributerMap.java b/src/main/java/net/sf/antcontrib/cpptasks/DistributerMap.java
new file mode 100644
index 0000000..ec0f4a4
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/DistributerMap.java
@@ -0,0 +1,218 @@
+/*
+ *
+ * Copyright 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;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.DataType;
+
+/**
+ * Local to remote filename mapping (Experimental).
+ *
+ */
+public final class DistributerMap
+ extends DataType {
+ /**
+ * if property.
+ */
+ private String ifCond;
+
+ /**
+ * unless property.
+ */
+ private String unlessCond;
+
+ /**
+ * local directory name.
+ *
+ */
+ private File localName;
+
+ /**
+ * Canonical local file name.
+ */
+ private String canonicalPath;
+
+ /**
+ * remote name.
+ *
+ */
+ private String remoteName;
+
+ /**
+ * Separator (/ or \) character on remote system.
+ */
+ private char remoteSeparator = File.separatorChar;
+
+ /**
+ * hosts that for which this map is valid.
+ *
+ */
+ private String hosts;
+
+ /**
+ * Constructor.
+ *
+ */
+ public DistributerMap() {
+ }
+
+ /**
+ * Required by documentation generator.
+ */
+ public void execute() {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+
+ /**
+ * Returns true if the if and unless conditions (if any) are
+ * satisfied.
+ *
+ * @return true if this object is active.
+ */
+ public boolean isActive() {
+ return CUtil.isActive(getProject(), ifCond, unlessCond);
+ }
+
+ /**
+ * Sets the property name for the 'if' condition.
+ *
+ * This object will be ignored unless the property is defined.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") will throw an exception when
+ * evaluated.
+ *
+ * @param propName
+ * property name
+ */
+ public void setIf(final String propName) {
+ ifCond = propName;
+ }
+
+ /**
+ * Set the property name for the 'unless' condition.
+ *
+ * If named property is set, the define will be ignored.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") of the behavior will throw an
+ * exception when evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public void setUnless(final String propName) {
+ unlessCond = propName;
+ }
+
+ /**
+ * Gets local directory.
+ * @return local directory, may be null.
+ *
+ */
+ public File getLocal() {
+ return localName;
+ }
+
+ /**
+ * Gets remote name for directory.
+ * @return remote name, may be null.
+ *
+ */
+ public String getRemote() {
+ return remoteName;
+ }
+
+ /**
+ * Converts the local file name to the remote name for the same file.
+ *
+ * @param host host
+ * @param localFile local file
+ * @return remote name for local file, null if unknown.
+ */
+ public String toRemote(final String host, final File localFile) {
+ if (remoteName != null
+ && (hosts == null || hosts.indexOf(host) >= 0)) {
+ try {
+ String canonical = localFile.getCanonicalPath();
+ if (canonical.startsWith(canonicalPath)) {
+ if (isActive()) {
+ return remoteName
+ + canonical.substring(canonicalPath.length()).replace(File.
+ separatorChar, remoteSeparator);
+ }
+ }
+ } catch (IOException ex) {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Sets local directory for base of mapping.
+ *
+ * @param value value
+ */
+ public void setLocal(final File value) {
+ if (value == null) {
+ throw new NullPointerException("value");
+ }
+ if (value.exists() && !value.isDirectory()) {
+ throw new BuildException("local should be a directory");
+ }
+ localName = value;
+ try {
+ canonicalPath = localName.getCanonicalPath();
+ } catch (IOException ex) {
+ throw new BuildException(ex);
+ }
+ }
+
+ /**
+ * Sets remote name for directory.
+ * @param value remote name for directory
+ */
+ public void setRemote(final String value) {
+ remoteName = value;
+ }
+
+ /**
+ * Sets the separator character (/ or \) for the remote system.
+ * @param value separator character
+ */
+ public void setRemoteSeparator(final String value) {
+ if (value != null && value.length() != 1) {
+ throw new BuildException("remote separator must be a single character");
+ }
+ remoteSeparator = value.charAt(0);
+ }
+
+ /**
+ * Sets hosts for which this mapping is valid.
+ *
+ * @param value hosts
+ */
+ public void setHosts(final String value) {
+ hosts = value;
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/DistributerProtocolEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/DistributerProtocolEnum.java
new file mode 100644
index 0000000..7d3734d
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/DistributerProtocolEnum.java
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright 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;
+
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+/**
+ * Distributer prococol names (experimental).
+ *
+ * @author Curt Arnold
+ *
+ */
+public final class DistributerProtocolEnum
+ extends EnumeratedAttribute {
+ /**
+ * Constructor.
+ *
+ * Set by default to "distcc"
+ *
+ * @see java.lang.Object#Object()
+ */
+ public DistributerProtocolEnum() {
+ setValue("distcc");
+ }
+
+ /**
+ * Gets list of acceptable values.
+ *
+ * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues()
+ */
+ public String[] getValues() {
+ return new String[] {
+ "distcc",
+ "ssh"};
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/FileVisitor.java b/src/main/java/net/sf/antcontrib/cpptasks/FileVisitor.java
new file mode 100644
index 0000000..c59f04f
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/FileVisitor.java
@@ -0,0 +1,27 @@
+/*
+ *
+ * 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;
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+/**
+ * An abstract class implemented to walk over the fileset members of a
+ * ProcessorDef
+ */
+public interface FileVisitor {
+ abstract void visit(File parentDir, String filename) throws BuildException;
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/LinkerDef.java b/src/main/java/net/sf/antcontrib/cpptasks/LinkerDef.java
new file mode 100644
index 0000000..cde8837
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/LinkerDef.java
@@ -0,0 +1,509 @@
+/*
+ *
+ * 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;
+import java.io.File;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;
+import net.sf.antcontrib.cpptasks.gcc.GccLinker;
+import net.sf.antcontrib.cpptasks.types.FlexLong;
+import net.sf.antcontrib.cpptasks.types.LibrarySet;
+import net.sf.antcontrib.cpptasks.types.LinkerArgument;
+import net.sf.antcontrib.cpptasks.types.SystemLibrarySet;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.FlexInteger;
+/**
+ * A linker definition. linker elements may be placed either as children of a
+ * cc element or the project element. A linker element with an id attribute may
+ * be referenced by linker elements with refid or extends attributes.
+ *
+ * @author Adam Murdoch
+ * @author Curt Arnold
+ */
+public class LinkerDef extends ProcessorDef {
+ private long base;
+ private String entry;
+ private Boolean fixed;
+ private Boolean incremental;
+ private final Vector librarySets = new Vector();
+ private Boolean map;
+ private int stack;
+ private final Vector sysLibrarySets = new Vector();
+ /**
+ * Default constructor
+ *
+ * @see java.lang.Object#Object()
+ */
+ public LinkerDef() {
+ base = -1;
+ stack = -1;
+ }
+ private void addActiveLibrarySet(Project project, Vector libsets,
+ Vector srcSets) {
+ Enumeration srcenum = srcSets.elements();
+ while (srcenum.hasMoreElements()) {
+ LibrarySet set = (LibrarySet) srcenum.nextElement();
+ if (set.isActive(project)) {
+ libsets.addElement(set);
+ }
+ }
+ }
+ private void addActiveSystemLibrarySets(Project project, Vector libsets) {
+ addActiveLibrarySet(project, libsets, sysLibrarySets);
+ }
+ private void addActiveUserLibrarySets(Project project, Vector libsets) {
+ addActiveLibrarySet(project, libsets, librarySets);
+ }
+ /**
+ * Adds a linker command-line arg.
+ */
+ public void addConfiguredLinkerArg(LinkerArgument arg) {
+ addConfiguredProcessorArg(arg);
+ }
+ /**
+ * Adds a compiler command-line arg.
+ */
+ public void addConfiguredLinkerParam(LinkerParam param) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ addConfiguredProcessorParam(param);
+ }
+ /**
+ * Adds a system library set.
+ */
+ public void addLibset(LibrarySet libset) {
+ if (isReference()) {
+ throw super.noChildrenAllowed();
+ }
+ if (libset == null) {
+ throw new NullPointerException("libset");
+ }
+ librarySets.addElement(libset);
+ }
+ /**
+ * Adds a system library set.
+ */
+ public void addSyslibset(SystemLibrarySet libset) {
+ if (isReference()) {
+ throw super.noChildrenAllowed();
+ }
+ if (libset == null) {
+ throw new NullPointerException("libset");
+ }
+ sysLibrarySets.addElement(libset);
+ }
+
+ public void execute() throws org.apache.tools.ant.BuildException {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+ /**
+ * Returns an array of active library sets for this linker definition.
+ */
+ public LibrarySet[] getActiveLibrarySets(LinkerDef[] defaultProviders,
+ int index) {
+ if (isReference()) {
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))
+ .getActiveUserLibrarySets(defaultProviders, index);
+ }
+ Project p = getProject();
+ Vector libsets = new Vector();
+ for (int i = index; i < defaultProviders.length; i++) {
+ defaultProviders[i].addActiveUserLibrarySets(p, libsets);
+ }
+ addActiveUserLibrarySets(p, libsets);
+ for (int i = index; i < defaultProviders.length; i++) {
+ defaultProviders[i].addActiveSystemLibrarySets(p, libsets);
+ }
+ addActiveSystemLibrarySets(p, libsets);
+ LibrarySet[] sets = new LibrarySet[libsets.size()];
+ libsets.copyInto(sets);
+ return sets;
+ }
+ /**
+ * Returns an array of active library sets for this linker definition.
+ */
+ public LibrarySet[] getActiveSystemLibrarySets(
+ LinkerDef[] defaultProviders, int index) {
+ if (isReference()) {
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))
+ .getActiveUserLibrarySets(defaultProviders, index);
+ }
+ Project p = getProject();
+ Vector libsets = new Vector();
+ for (int i = index; i < defaultProviders.length; i++) {
+ defaultProviders[i].addActiveSystemLibrarySets(p, libsets);
+ }
+ addActiveSystemLibrarySets(p, libsets);
+ LibrarySet[] sets = new LibrarySet[libsets.size()];
+ libsets.copyInto(sets);
+ return sets;
+ }
+ /**
+ * Returns an array of active library sets for this linker definition.
+ */
+ public LibrarySet[] getActiveUserLibrarySets(LinkerDef[] defaultProviders,
+ int index) {
+ if (isReference()) {
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))
+ .getActiveUserLibrarySets(defaultProviders, index);
+ }
+ Project p = getProject();
+ Vector libsets = new Vector();
+ for (int i = index; i < defaultProviders.length; i++) {
+ defaultProviders[i].addActiveUserLibrarySets(p, libsets);
+ }
+ addActiveUserLibrarySets(p, libsets);
+ LibrarySet[] sets = new LibrarySet[libsets.size()];
+ libsets.copyInto(sets);
+ return sets;
+ }
+ public long getBase(LinkerDef[] defaultProviders, int index) {
+ if (isReference()) {
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))
+ .getBase(defaultProviders, index);
+ }
+ if (base <= 0) {
+ if (defaultProviders != null && index < defaultProviders.length) {
+ return defaultProviders[index].getBase(defaultProviders,
+ index + 1);
+ }
+ }
+ return base;
+ }
+ public Boolean getFixed(LinkerDef[] defaultProviders, int index) {
+ if (isReference()) {
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))
+ .getFixed(defaultProviders, index);
+ }
+ if (fixed == null) {
+ if (defaultProviders != null && index < defaultProviders.length) {
+ return defaultProviders[index].getFixed(defaultProviders,
+ index + 1);
+ }
+ }
+ return fixed;
+ }
+ public boolean getIncremental(LinkerDef[] defaultProviders, int index) {
+ if (isReference()) {
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))
+ .getIncremental(defaultProviders, index);
+ }
+ if (incremental != null) {
+ return incremental.booleanValue();
+ }
+ if (defaultProviders != null && index < defaultProviders.length) {
+ return defaultProviders[index].getIncremental(defaultProviders, index + 1);
+ }
+ return false;
+ }
+ public boolean getMap(LinkerDef[] defaultProviders, int index) {
+ if (isReference()) {
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))
+ .getMap(defaultProviders, index);
+ }
+ if (map != null) {
+ return map.booleanValue();
+ }
+ if (defaultProviders != null && index < defaultProviders.length) {
+ return defaultProviders[index].getMap(defaultProviders, index + 1);
+ }
+ return false;
+ }
+ public String getEntry(LinkerDef[] defaultProviders, int index) {
+ if (isReference()) {
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))
+ .getEntry(defaultProviders, index);
+ }
+ if (entry != null) {
+ return entry;
+ }
+ if (defaultProviders != null && index < defaultProviders.length) {
+ return defaultProviders[index].getEntry(defaultProviders, index + 1);
+ }
+ return null;
+ }
+
+ public Processor getProcessor() {
+ Linker linker = (Linker) super.getProcessor();
+ if (linker == null) {
+ linker = GccLinker.getInstance();
+ }
+ if (getLibtool() && linker instanceof CommandLineLinker) {
+ CommandLineLinker cmdLineLinker = (CommandLineLinker) linker;
+ linker = cmdLineLinker.getLibtoolLinker();
+ }
+ return linker;
+ }
+
+ public Processor getProcessor(LinkType linkType) {
+ Processor proc = getProcessor();
+ return proc.getLinker(linkType);
+ }
+
+ public int getStack(LinkerDef[] defaultProviders, int index) {
+ if (isReference()) {
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))
+ .getStack(defaultProviders, index);
+ }
+ if (stack < 0) {
+ if (defaultProviders != null && index < defaultProviders.length) {
+ return defaultProviders[index].getStack(defaultProviders,
+ index + 1);
+ }
+ }
+ return stack;
+ }
+ /**
+ * Sets the base address. May be specified in either decimal or hex.
+ *
+ * @param base
+ * base address
+ *
+ */
+ public void setBase(FlexLong base) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.base = base.longValue();
+ }
+ /**
+ * Sets the starting address.
+ *
+ * @param entry
+ * function name
+ */
+ public void setEntry(String entry) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.entry = entry;
+ }
+ /**
+ * If true, marks the file to be loaded only at its preferred address.
+ */
+ public void setFixed(boolean fixed) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.fixed = booleanValueOf(fixed);
+ }
+ /**
+ * If true, allows incremental linking.
+ *
+ */
+ public void setIncremental(boolean incremental) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.incremental = booleanValueOf(incremental);
+ }
+ /**
+ * If set to true, a map file will be produced.
+ */
+ public void setMap(boolean map) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.map = booleanValueOf(map);
+ }
+ /**
+ * Sets linker type.
+ *
+ *
+ * <table width="100%" border="1"> <thead>Supported linkers </thead>
+ * <tr>
+ * <td>gcc</td>
+ * <td>Gcc Linker</td>
+ * </tr>
+ * <tr>
+ * <td>g++</td>
+ * <td>G++ Linker</td>
+ * </tr>
+ * <tr>
+ * <td>ld</td>
+ * <td>Ld Linker</td>
+ * </tr>
+ * <tr>
+ * <td>ar</td>
+ * <td>Gcc Librarian</td>
+ * </tr>
+ * <tr>
+ * <td>msvc</td>
+ * <td>Microsoft Linker</td>
+ * </tr>
+ * <tr>
+ * <td>bcc</td>
+ * <td>Borland Linker</td>
+ * </tr>
+ * <tr>
+ * <td>df</td>
+ * <td>Compaq Visual Fortran Linker</td>
+ * </tr>
+ * <tr>
+ * <td>icl</td>
+ * <td>Intel Linker for Windows (IA-32)</td>
+ * </tr>
+ * <tr>
+ * <td>ecl</td>
+ * <td>Intel Linker for Windows (IA-64)</td>
+ * </tr>
+ * <tr>
+ * <td>icc</td>
+ * <td>Intel Linker for Linux (IA-32)</td>
+ * </tr>
+ * <tr>
+ * <td>ecc</td>
+ * <td>Intel Linker for Linux (IA-64)</td>
+ * </tr>
+ * <tr>
+ * <td>CC</td>
+ * <td>Sun ONE Linker</td>
+ * </tr>
+ * <tr>
+ * <td>aCC</td>
+ * <td>HP aC++ Linker</td>
+ * </tr>
+ * <tr>
+ * <td>os390</td>
+ * <td>OS390 Linker</td>
+ * </tr>
+ * <tr>
+ * <td>os390batch</td>
+ * <td>OS390 Linker</td>
+ * </tr>
+ * <tr>
+ * <td>os400</td>
+ * <td>IccLinker</td>
+ * </tr>
+ * <tr>
+ * <td>sunc89</td>
+ * <td>C89 Linker</td>
+ * </tr>
+ * <tr>
+ * <td>xlC</td>
+ * <td>VisualAge Linker</td>
+ * </tr>
+ * <tr>
+ * <td>wcl</td>
+ * <td>OpenWatcom C/C++ linker</td>
+ * </tr>
+ * <tr>
+ * <td>wfl</td>
+ * <td>OpenWatcom FORTRAN linker</td>
+ * </tr>
+ * </table>
+ *
+ */
+ public void setName(LinkerEnum name) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ Linker linker = name.getLinker();
+ super.setProcessor(linker);
+ }
+ protected void setProcessor(Processor proc) throws BuildException {
+ Linker linker = null;
+ if (proc instanceof Linker) {
+ linker = (Linker) proc;
+ } else {
+ LinkType linkType = new LinkType();
+ linker = proc.getLinker(linkType);
+ }
+ super.setProcessor(linker);
+ }
+ /**
+ * Sets stack size in bytes.
+ */
+ public void setStack(FlexInteger stack) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.stack = stack.intValue();
+ }
+ public void visitSystemLibraries(Linker linker, FileVisitor libraryVisitor) {
+ Project p = getProject();
+ if (p == null) {
+ throw new java.lang.IllegalStateException("project must be set");
+ }
+ if (isReference()) {
+ LinkerDef master = ((LinkerDef) getCheckedRef(LinkerDef.class,
+ "Linker"));
+ master.visitSystemLibraries(linker, libraryVisitor);
+ } else {
+ //
+ // if this linker extends another,
+ // visit its libraries first
+ //
+ LinkerDef extendsDef = (LinkerDef) getExtends();
+ if (extendsDef != null) {
+ extendsDef.visitSystemLibraries(linker, libraryVisitor);
+ }
+ if (sysLibrarySets.size() > 0) {
+ File[] libpath = linker.getLibraryPath();
+ for (int i = 0; i < sysLibrarySets.size(); i++) {
+ LibrarySet set = (LibrarySet) sysLibrarySets.elementAt(i);
+ if (set.isActive(p)) {
+ set.visitLibraries(p, linker, libpath,
+ libraryVisitor);
+ }
+ }
+ }
+ }
+ }
+ public void visitUserLibraries(Linker linker, FileVisitor libraryVisitor) {
+ Project p = getProject();
+ if (p == null) {
+ throw new java.lang.IllegalStateException("project must be set");
+ }
+ if (isReference()) {
+ LinkerDef master = ((LinkerDef) getCheckedRef(LinkerDef.class,
+ "Linker"));
+ master.visitUserLibraries(linker, libraryVisitor);
+ } else {
+ //
+ // if this linker extends another,
+ // visit its libraries first
+ //
+ LinkerDef extendsDef = (LinkerDef) getExtends();
+ if (extendsDef != null) {
+ extendsDef.visitUserLibraries(linker, libraryVisitor);
+ }
+ //
+ // visit the user libraries
+ //
+ if (librarySets.size() > 0) {
+ File[] libpath = linker.getLibraryPath();
+ for (int i = 0; i < librarySets.size(); i++) {
+ LibrarySet set = (LibrarySet) librarySets.elementAt(i);
+ if (set.isActive(p)) {
+ set.visitLibraries(p, linker, libpath,
+ libraryVisitor);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/LinkerEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/LinkerEnum.java
new file mode 100644
index 0000000..df96723
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/LinkerEnum.java
@@ -0,0 +1,112 @@
+/*
+ *
+ * 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;
+import net.sf.antcontrib.cpptasks.arm.ADSLinker;
+import net.sf.antcontrib.cpptasks.borland.BorlandLinker;
+import net.sf.antcontrib.cpptasks.compaq.CompaqVisualFortranLinker;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.devstudio.DevStudioLinker;
+import net.sf.antcontrib.cpptasks.gcc.GccLibrarian;
+import net.sf.antcontrib.cpptasks.gcc.GccLinker;
+import net.sf.antcontrib.cpptasks.gcc.GppLinker;
+import net.sf.antcontrib.cpptasks.gcc.LdLinker;
+import net.sf.antcontrib.cpptasks.hp.aCCLinker;
+import net.sf.antcontrib.cpptasks.ibm.VisualAgeLinker;
+import net.sf.antcontrib.cpptasks.intel.IntelLinux32Linker;
+import net.sf.antcontrib.cpptasks.intel.IntelLinux64Linker;
+import net.sf.antcontrib.cpptasks.intel.IntelWin32Linker;
+import net.sf.antcontrib.cpptasks.os390.OS390Linker;
+import net.sf.antcontrib.cpptasks.os400.IccLinker;
+import net.sf.antcontrib.cpptasks.sun.C89Linker;
+import net.sf.antcontrib.cpptasks.sun.ForteCCLinker;
+import net.sf.antcontrib.cpptasks.ti.ClxxLinker;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import net.sf.antcontrib.cpptasks.openwatcom.OpenWatcomCLinker;
+import net.sf.antcontrib.cpptasks.openwatcom.OpenWatcomFortranLinker;
+
+/**
+ * Enumeration of supported linkers
+ *
+ * @author Curt Arnold
+ *
+ */
+public class LinkerEnum extends EnumeratedAttribute {
+ private final static ProcessorEnumValue[] linkers = new ProcessorEnumValue[]{
+ new ProcessorEnumValue("gcc", GccLinker.getInstance()),
+ new ProcessorEnumValue("g++", GppLinker.getInstance()),
+ new ProcessorEnumValue("ld", LdLinker.getInstance()),
+ new ProcessorEnumValue("ar", GccLibrarian.getInstance()),
+ new ProcessorEnumValue("msvc", DevStudioLinker.getInstance()),
+ new ProcessorEnumValue("bcc", BorlandLinker.getInstance()),
+ new ProcessorEnumValue("df", CompaqVisualFortranLinker
+ .getInstance()),
+ new ProcessorEnumValue("icl", IntelWin32Linker.getInstance()),
+ new ProcessorEnumValue("ecl", IntelWin32Linker.getInstance()),
+ new ProcessorEnumValue("icc", IntelLinux32Linker.getInstance()),
+ new ProcessorEnumValue("ecc", IntelLinux64Linker.getInstance()),
+ new ProcessorEnumValue("CC", ForteCCLinker.getInstance()),
+ new ProcessorEnumValue("aCC", aCCLinker.getInstance()),
+ new ProcessorEnumValue("os390", OS390Linker.getInstance()),
+ new ProcessorEnumValue("os390batch", OS390Linker
+ .getDataSetInstance()),
+ new ProcessorEnumValue("os400", IccLinker.getInstance()),
+ new ProcessorEnumValue("sunc89", C89Linker.getInstance()),
+ new ProcessorEnumValue("xlC", VisualAgeLinker.getInstance()),
+ new ProcessorEnumValue("cl6x", ClxxLinker.getCl6xInstance()),
+ new ProcessorEnumValue("cl55", ClxxLinker.getCl55Instance()),
+ new ProcessorEnumValue("armcc", ADSLinker.getInstance()),
+ new ProcessorEnumValue("armcpp", ADSLinker.getInstance()),
+ new ProcessorEnumValue("tcc", ADSLinker.getInstance()),
+ new ProcessorEnumValue("tcpp", ADSLinker.getInstance()),
+ // gcc cross compilers
+ new ProcessorEnumValue(
+ "sparc-sun-solaris2-gcc",
+ net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccLinker
+ .getInstance()),
+ new ProcessorEnumValue(
+ "sparc-sun-solaris2-g++",
+ net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GppLinker
+ .getInstance()),
+ new ProcessorEnumValue(
+ "sparc-sun-solaris2-ld",
+ net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.LdLinker
+ .getInstance()),
+ new ProcessorEnumValue(
+ "sparc-sun-solaris2-ar",
+ net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccLibrarian
+ .getInstance()),
+ new ProcessorEnumValue("gcc-cross",
+ net.sf.antcontrib.cpptasks.gcc.cross.GccLinker
+ .getInstance()),
+ new ProcessorEnumValue("g++-cross",
+ net.sf.antcontrib.cpptasks.gcc.cross.GppLinker
+ .getInstance()),
+ new ProcessorEnumValue("ld-cross",
+ net.sf.antcontrib.cpptasks.gcc.cross.LdLinker.getInstance()),
+ new ProcessorEnumValue("ar-cross",
+ net.sf.antcontrib.cpptasks.gcc.cross.GccLibrarian
+ .getInstance()),
+ new ProcessorEnumValue("wcl", OpenWatcomCLinker.getInstance()),
+ new ProcessorEnumValue("wfl", OpenWatcomFortranLinker.getInstance()),
+ };
+ public Linker getLinker() {
+ return (Linker) linkers[getIndex()].getProcessor();
+ }
+ public String[] getValues() {
+ return ProcessorEnumValue.getValues(linkers);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/LinkerParam.java b/src/main/java/net/sf/antcontrib/cpptasks/LinkerParam.java
new file mode 100644
index 0000000..3dae933
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/LinkerParam.java
@@ -0,0 +1,33 @@
+/*
+ *
+ * Copyright 2001-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;
+/*******************************************************************************
+ * Place class description here.
+ *
+ * @author inger
+ * @author <additional author>
+ *
+ * @since
+ ******************************************************************************/
+public class LinkerParam extends ProcessorParam {
+ public LinkerParam() {
+ }
+ public void execute() throws org.apache.tools.ant.BuildException {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/OSFamilyEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/OSFamilyEnum.java
new file mode 100644
index 0000000..68ebd82
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/OSFamilyEnum.java
@@ -0,0 +1,59 @@
+/*
+ *
+ * Copyright 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;
+
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+/**
+ * Enumeration of cpu types.
+ *
+ * @author Curt Arnold
+ *
+ */
+public final class OSFamilyEnum
+ extends EnumeratedAttribute {
+ /**
+ * Constructor.
+ *
+ * Set by default to "pentium3"
+ *
+ * @see java.lang.Object#Object()
+ */
+ public OSFamilyEnum() {
+ setValue("windows");
+ }
+
+ /**
+ * Gets list of acceptable values.
+ *
+ * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues()
+ */
+ public String[] getValues() {
+ return new String[] {
+ "windows",
+ "dos",
+ "mac",
+ "unix",
+ "netware",
+ "os/2",
+ "tandem",
+ "win9x",
+ "z/os",
+ "os/400",
+ "openvms"};
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ObjectFileCollector.java b/src/main/java/net/sf/antcontrib/cpptasks/ObjectFileCollector.java
new file mode 100644
index 0000000..fd4cda5
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ObjectFileCollector.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright 2001-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;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+
+import org.apache.tools.ant.BuildException;
+/**
+ * Collects object files for the link step.
+ *
+ *
+ */
+public final class ObjectFileCollector implements FileVisitor {
+ private final Vector files;
+ private final Linker linker;
+ public ObjectFileCollector(Linker linker, Vector files) {
+ this.linker = linker;
+ this.files = files;
+ }
+ public void visit(File parentDir, String filename) throws BuildException {
+ int bid = linker.bid(filename);
+ if (bid >= 1) {
+ files.addElement(new File(parentDir, filename));
+ }
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/OptimizationEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/OptimizationEnum.java
new file mode 100644
index 0000000..042822e
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/OptimizationEnum.java
@@ -0,0 +1,82 @@
+/*
+ *
+ * Copyright 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;
+
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+/**
+ * Enumeration of optimization levels (experimental).
+ *
+ * @author Curt Arnold
+ *
+ */
+public final class OptimizationEnum
+ extends EnumeratedAttribute {
+ /**
+ * Constructor.
+ *
+ * Set by default to "speed"
+ *
+ * @see java.lang.Object#Object()
+ */
+ public OptimizationEnum() {
+ setValue("speed");
+ }
+
+ /**
+ * Gets list of acceptable values.
+ *
+ * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues()
+ */
+ public String[] getValues() {
+ return new String[] {
+ "none",
+ "size",
+ "minimal",
+ "speed",
+ "full",
+ "aggressive",
+ "extreme",
+ "unsafe"
+ };
+ }
+
+ /**
+ * Is size optimized.
+ * @return boolean true if size is optimized.
+ */
+ public boolean isSize() {
+ return "size".equals(getValue());
+ }
+
+ /**
+ * Is speed optimized.
+ * @return boolean true if speed is optimized.
+ */
+ public boolean isSpeed() {
+ return !isSize() && !isNoOptimization();
+ }
+
+ /**
+ * Is no optimization performed.
+ * @return boolean true if no optimization is performed.
+ */
+ public boolean isNoOptimization() {
+ return "none".equals(getValue());
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/OutputTypeEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/OutputTypeEnum.java
new file mode 100644
index 0000000..873a99c
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/OutputTypeEnum.java
@@ -0,0 +1,48 @@
+/*
+ *
+ * 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;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+/**
+ * Enumeration of supported subsystems
+ *
+ * @author Curt Arnold
+ *
+ */
+public class OutputTypeEnum extends EnumeratedAttribute {
+ /**
+ * Constructor
+ *
+ * Set by default to "executable"
+ *
+ * @see java.lang.Object#Object()
+ */
+ public OutputTypeEnum() {
+ setValue("executable");
+ }
+ /**
+ * Gets list of acceptable values
+ *
+ * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues()
+ */
+ public String[] getValues() {
+ return new String[]{"executable", // executable program
+ "plugin", // plugin module
+ "shared", // dynamically linkable module
+ "static" // convenience library
+ };
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/PrecompileDef.java b/src/main/java/net/sf/antcontrib/cpptasks/PrecompileDef.java
new file mode 100644
index 0000000..b642197
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/PrecompileDef.java
@@ -0,0 +1,212 @@
+/*
+ *
+ * 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;
+import java.io.File;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.types.ConditionalFileSet;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.types.DataType;
+/**
+ * An element that specifies a prototype file and rules for source files that
+ * should not use precompiled headers
+ *
+ * @author Curt Arnold
+ */
+public final class PrecompileDef extends DataType {
+ private final Vector exceptSets = new Vector();
+ private String ifCond;
+ /**
+ * Directory of prototype file
+ */
+ private File prototype = new File("stdafx.cpp");
+ private String unlessCond;
+ /**
+ * Constructor
+ *
+ */
+ public PrecompileDef() {
+ }
+ /**
+ * Method used by PrecompileExceptDef to add exception set to
+ * PrecompileDef.
+ */
+ public void appendExceptFileSet(ConditionalFileSet exceptSet) {
+ exceptSet.setProject(getProject());
+ exceptSets.addElement(exceptSet);
+ }
+ /**
+ * Adds filesets that specify files that should not be processed with
+ * precompiled headers enabled.
+ *
+ */
+ public PrecompileExceptDef createExcept() {
+ return new PrecompileExceptDef(this);
+ }
+ public void execute() throws org.apache.tools.ant.BuildException {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+ public String[] getExceptFiles() {
+ PrecompileDef ref = getRef();
+ if (ref != null) {
+ return ref.getExceptFiles();
+ }
+ if (exceptSets.size() == 0) {
+ return new String[0];
+ }
+ Project p = getProject();
+ String[] exceptFiles = null;
+ Enumeration setEnum = exceptSets.elements();
+ while (setEnum.hasMoreElements()) {
+ ConditionalFileSet exceptSet = (ConditionalFileSet) setEnum
+ .nextElement();
+ if (exceptSet.isActive()) {
+ DirectoryScanner scanner = exceptSet
+ .getDirectoryScanner(p);
+ String[] scannerFiles = scanner.getIncludedFiles();
+ if (exceptFiles == null) {
+ exceptFiles = scannerFiles;
+ } else {
+ if (scannerFiles.length > 0) {
+ String[] newFiles = new String[exceptFiles.length
+ + scannerFiles.length];
+ for (int i = 0; i < exceptFiles.length; i++) {
+ newFiles[i] = exceptFiles[i];
+ }
+ int index = exceptFiles.length;
+ for (int i = 0; i < scannerFiles.length; i++) {
+ newFiles[index++] = scannerFiles[i];
+ }
+ exceptFiles = newFiles;
+ }
+ }
+ }
+ }
+ if (exceptFiles == null) {
+ exceptFiles = new String[0];
+ }
+ return exceptFiles;
+ }
+ /**
+ * Gets prototype source file
+ *
+ */
+ public File getPrototype() {
+ PrecompileDef ref = getRef();
+ if (ref != null) {
+ return ref.getPrototype();
+ }
+ return prototype;
+ }
+ private PrecompileDef getRef() {
+ if (isReference()) {
+ return ((PrecompileDef) getCheckedRef(PrecompileDef.class,
+ "PrecompileDef"));
+ }
+ return null;
+ }
+ public boolean isActive() {
+ boolean isActive = CUtil.isActive(getProject(), ifCond, unlessCond);
+ if (!isActive) {
+ PrecompileDef ref = getRef();
+ if (ref != null) {
+ return ref.isActive();
+ }
+ }
+ return isActive;
+ }
+ /**
+ * Sets a description of the current data type.
+ */
+ public void setDescription(String desc) {
+ super.setDescription(desc);
+ }
+ /**
+ * Sets an id that can be used to reference this element.
+ *
+ * @param id
+ * id
+ */
+ public void setId(String id) {
+ //
+ // this is actually accomplished by a different
+ // mechanism, but we can document it
+ //
+ }
+ /**
+ * Set the 'if' condition.
+ *
+ * The processor will be ignored unless the property is defined.
+ *
+ * The value of property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") will throw an exception when
+ * isActive() is evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public void setIf(String propName) {
+ ifCond = propName;
+ }
+ /**
+ * Sets file to precompile.
+ *
+ * Should be a source file that includes only one unguarded header file.
+ * Default value is "stdafx.cpp".
+ *
+ * @param prototype
+ * file path for prototype source file
+ */
+ public void setPrototype(File prototype) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (prototype == null) {
+ throw new NullPointerException("prototype");
+ }
+ this.prototype = prototype;
+ }
+ /**
+ * Specifies that this element should behave as if the content of the
+ * element with the matching id attribute was inserted at this location.
+ *
+ * @param ref
+ * Reference to other element
+ *
+ */
+ public void setRefid(org.apache.tools.ant.types.Reference ref) {
+ super.setRefid(ref);
+ }
+ /**
+ * Set the 'unless' condition. If named property exists at execution time,
+ * the processor will be ignored.
+ *
+ * Value of property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") of the behavior will throw an
+ * exception when isActive is called.
+ *
+ * @param propName
+ * name of property
+ */
+ public void setUnless(String propName) {
+ unlessCond = propName;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/PrecompileExceptDef.java b/src/main/java/net/sf/antcontrib/cpptasks/PrecompileExceptDef.java
new file mode 100644
index 0000000..c6c7da7
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/PrecompileExceptDef.java
@@ -0,0 +1,80 @@
+/*
+ *
+ * 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;
+import java.io.File;
+
+import net.sf.antcontrib.cpptasks.types.ConditionalFileSet;
+
+import org.apache.tools.ant.BuildException;
+/**
+ * Specifies files that should not be compiled using precompiled headers.
+ *
+ * @author Curt Arnold
+ */
+public final class PrecompileExceptDef {
+ private ConditionalFileSet localSet = null;
+ /**
+ * Collection of <fileset>contained by definition
+ */
+ private PrecompileDef owner;
+ /**
+ * Constructor
+ *
+ */
+ public PrecompileExceptDef(PrecompileDef owner) {
+ this.owner = owner;
+ }
+ /**
+ * Adds filesets that specify files that should not be processed using
+ * precompiled headers.
+ *
+ * @param exceptSet
+ * FileSet specify files that should not be processed with
+ * precompiled headers enabled.
+ */
+ public void addFileset(ConditionalFileSet exceptSet) {
+ owner.appendExceptFileSet(exceptSet);
+ }
+ public void execute() throws org.apache.tools.ant.BuildException {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+ /**
+ * Sets the base-directory
+ */
+ public void setDir(File dir) throws BuildException {
+ if (localSet == null) {
+ localSet = new ConditionalFileSet();
+ owner.appendExceptFileSet(localSet);
+ }
+ localSet.setDir(dir);
+ }
+ /**
+ * Comma or space separated list of file patterns that should not be
+ * compiled using precompiled headers.
+ *
+ * @param includes
+ * the string containing the include patterns
+ */
+ public void setIncludes(String includes) {
+ if (localSet == null) {
+ localSet = new ConditionalFileSet();
+ owner.appendExceptFileSet(localSet);
+ }
+ localSet.setIncludes(includes);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ProcessorDef.java b/src/main/java/net/sf/antcontrib/cpptasks/ProcessorDef.java
new file mode 100644
index 0000000..54a3406
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ProcessorDef.java
@@ -0,0 +1,679 @@
+/*
+ *
+ * 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;
+import java.io.File;
+import java.lang.reflect.Method;
+import java.util.Vector;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;
+import net.sf.antcontrib.cpptasks.types.CommandLineArgument;
+import net.sf.antcontrib.cpptasks.types.ConditionalFileSet;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Environment;
+import org.apache.tools.ant.types.Reference;
+/**
+ * An abstract compiler/linker definition.
+ *
+ * @author Curt Arnold
+ */
+public abstract class ProcessorDef extends DataType {
+ /**
+ * Returns the equivalent Boolean object for the specified value
+ *
+ * Equivalent to Boolean.valueOf in JDK 1.4
+ *
+ * @param val
+ * boolean value
+ * @return Boolean.TRUE or Boolean.FALSE
+ */
+ protected static Boolean booleanValueOf(boolean val) {
+ if (val) {
+ return Boolean.TRUE;
+ }
+ return Boolean.FALSE;
+ }
+ /**
+ * if true, targets will be built for debugging
+ */
+ private Boolean debug;
+ private Environment env = null;
+ /**
+ * Reference for "extends" processor definition
+ */
+ private Reference extendsRef = null;
+ /**
+ * Name of property that must be present or definition will be ignored. May
+ * be null.
+ */
+ private String ifProp;
+ /**
+ * if true, processor definition inherits values from containing cc
+ * element
+ */
+ private boolean inherit;
+ private Boolean libtool = null;
+ protected boolean newEnvironment = false;
+ /**
+ * Processor.
+ */
+ private Processor processor;
+ /**
+ * Collection of <compilerarg>or <linkerarg>contained by definition
+ */
+ private final Vector processorArgs = new Vector();
+ /**
+ * Collection of <compilerparam>or <linkerparam>contained by definition
+ */
+ private final Vector processorParams = new Vector();
+ /**
+ * if true, all targets will be unconditionally rebuilt
+ */
+ private Boolean rebuild;
+ /**
+ * Collection of <fileset>contained by definition
+ */
+ private final Vector srcSets = new Vector();
+ /**
+ * Name of property that if present will cause definition to be ignored.
+ * May be null.
+ */
+ private String unlessProp;
+ /**
+ * Constructor
+ *
+ */
+ protected ProcessorDef() throws NullPointerException {
+ inherit = true;
+ }
+ /**
+ * Adds a <compilerarg>or <linkerarg>
+ *
+ * @param arg
+ * command line argument, must not be null
+ * @throws NullPointerException
+ * if arg is null
+ * @throws BuildException
+ * if this definition is a reference
+ */
+ protected void addConfiguredProcessorArg(CommandLineArgument arg)
+ throws NullPointerException, BuildException {
+ if (arg == null) {
+ throw new NullPointerException("arg");
+ }
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ processorArgs.addElement(arg);
+ }
+ /**
+ * Adds a <compilerarg>or <linkerarg>
+ *
+ * @param param
+ * command line argument, must not be null
+ * @throws NullPointerException
+ * if arg is null
+ * @throws BuildException
+ * if this definition is a reference
+ */
+ protected void addConfiguredProcessorParam(ProcessorParam param)
+ throws NullPointerException, BuildException {
+ if (param == null) {
+ throw new NullPointerException("param");
+ }
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ processorParams.addElement(param);
+ }
+ /**
+ * Add an environment variable to the launched process.
+ */
+ public void addEnv(Environment.Variable var) {
+ if (env == null) {
+ env = new Environment();
+ }
+ env.addVariable(var);
+ }
+ /**
+ * Adds a source file set.
+ *
+ * Files in these set will be processed by this configuration and will not
+ * participate in the auction.
+ *
+ * @param srcSet
+ * Fileset identifying files that should be processed by this
+ * processor
+ * @throws BuildException
+ * if processor definition is a reference
+ */
+ public void addFileset(ConditionalFileSet srcSet) throws BuildException {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ srcSet.setProject(getProject());
+ srcSets.addElement(srcSet);
+ }
+ /**
+ * Creates a configuration
+ *
+ * @param baseDef
+ * reference to def from containing cc element, may be null
+ * @return configuration
+ *
+ */
+ public ProcessorConfiguration createConfiguration(CCTask task,
+ LinkType linkType, ProcessorDef baseDef,
+ TargetDef targetPlatform, VersionInfo versionInfo) {
+ if (isReference()) {
+ return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).createConfiguration(task, linkType,
+ baseDef, targetPlatform, versionInfo);
+ }
+ ProcessorDef[] defaultProviders = getDefaultProviders(baseDef);
+ Processor proc = getProcessor(linkType);
+ return proc.createConfiguration(task, linkType, defaultProviders, this, targetPlatform, versionInfo);
+ }
+ /**
+ * Prepares list of processor arguments ( compilerarg, linkerarg ) that
+ * are active for the current project settings.
+ *
+ * @return active compiler arguments
+ */
+ public CommandLineArgument[] getActiveProcessorArgs() {
+ Project p = getProject();
+ if (p == null) {
+ throw new java.lang.IllegalStateException("project must be set");
+ }
+ if (isReference()) {
+ return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).getActiveProcessorArgs();
+ }
+ Vector activeArgs = new Vector(processorArgs.size());
+ for (int i = 0; i < processorArgs.size(); i++) {
+ CommandLineArgument arg = (CommandLineArgument) processorArgs
+ .elementAt(i);
+ if (arg.isActive(p)) {
+ activeArgs.addElement(arg);
+ }
+ }
+ CommandLineArgument[] array = new CommandLineArgument[activeArgs.size()];
+ activeArgs.copyInto(array);
+ return array;
+ }
+ /**
+ * Prepares list of processor arguments ( compilerarg, linkerarg) that
+ * are active for the current project settings.
+ *
+ * @return active compiler arguments
+ */
+ public ProcessorParam[] getActiveProcessorParams() {
+ Project p = getProject();
+ if (p == null) {
+ throw new java.lang.IllegalStateException("project must be set");
+ }
+ if (isReference()) {
+ return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).getActiveProcessorParams();
+ }
+ Vector activeParams = new Vector(processorParams.size());
+ for (int i = 0; i < processorParams.size(); i++) {
+ ProcessorParam param = (ProcessorParam) processorParams
+ .elementAt(i);
+ if (param.isActive(p)) {
+ activeParams.addElement(param);
+ }
+ }
+ ProcessorParam[] array = new ProcessorParam[activeParams.size()];
+ activeParams.copyInto(array);
+ return array;
+ }
+ /**
+ * Gets boolean indicating debug build
+ *
+ * @param defaultProviders
+ * array of ProcessorDef's in descending priority
+ * @param index
+ * index to first element in array that should be considered
+ * @return if true, built targets for debugging
+ */
+ public boolean getDebug(ProcessorDef[] defaultProviders, int index) {
+ if (isReference()) {
+ return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).getDebug(defaultProviders, index);
+ }
+ if (debug != null) {
+ return debug.booleanValue();
+ } else {
+ if (defaultProviders != null && index < defaultProviders.length) {
+ return defaultProviders[index].getDebug(defaultProviders,
+ index + 1);
+ }
+ }
+ return false;
+ }
+ /**
+ * Creates an chain of objects which provide default values in descending
+ * order of significance.
+ *
+ * @param baseDef
+ * corresponding ProcessorDef from CCTask, will be last element
+ * in array unless inherit = false
+ * @return default provider array
+ *
+ */
+ protected final ProcessorDef[] getDefaultProviders(ProcessorDef baseDef) {
+ ProcessorDef extendsDef = getExtends();
+ Vector chain = new Vector();
+ while (extendsDef != null && !chain.contains(extendsDef)) {
+ chain.addElement(extendsDef);
+ extendsDef = extendsDef.getExtends();
+ }
+ if (baseDef != null && getInherit()) {
+ chain.addElement(baseDef);
+ }
+ ProcessorDef[] defaultProviders = new ProcessorDef[chain.size()];
+ chain.copyInto(defaultProviders);
+ return defaultProviders;
+ }
+ /**
+ * Gets the ProcessorDef specified by the extends attribute
+ *
+ * @return Base ProcessorDef, null if extends is not specified
+ * @throws BuildException
+ * if reference is not same type object
+ */
+ public ProcessorDef getExtends() throws BuildException {
+ if (extendsRef != null) {
+ Object obj = extendsRef.getReferencedObject(getProject());
+ if (!getClass().isInstance(obj)) {
+ throw new BuildException("Referenced object "
+ + extendsRef.getRefId() + " not correct type, is "
+ + obj.getClass().getName() + " should be "
+ + getClass().getName());
+ }
+ return (ProcessorDef) obj;
+ }
+ return null;
+ }
+ /**
+ * Gets the inherit attribute. If the inherit value is true, this processor
+ * definition will inherit default values from the containing cc element.
+ *
+ * @return if true then properties from the containing <cc>element are
+ * used.
+ */
+ public final boolean getInherit() {
+ return inherit;
+ }
+ public boolean getLibtool() {
+ if (libtool != null) {
+ return libtool.booleanValue();
+ }
+ if (isReference()) {
+ return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).getLibtool();
+ }
+ ProcessorDef extendsDef = getExtends();
+ if (extendsDef != null) {
+ return extendsDef.getLibtool();
+ }
+ return false;
+ }
+ /**
+ * Obtains the appropriate processor (compiler, linker)
+ *
+ * @return processor
+ */
+ protected Processor getProcessor() {
+ if (isReference()) {
+ return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).getProcessor();
+ }
+ //
+ // if a processor has not been explicitly set
+ // then may be set by an extended definition
+ if (processor == null) {
+ ProcessorDef extendsDef = getExtends();
+ if (extendsDef != null) {
+ return extendsDef.getProcessor();
+ }
+ }
+ return processor;
+ }
+
+ /**
+ * Obtains the appropriate processor (compiler, linker) based on the
+ * LinkType.
+ *
+ * @return processor
+ */
+ protected Processor getProcessor(LinkType linkType) {
+ // by default ignore the linkType.
+ return getProcessor();
+ }
+ /**
+ * Gets a boolean value indicating whether all targets must be rebuilt
+ * regardless of dependency analysis.
+ *
+ * @param defaultProviders
+ * array of ProcessorDef's in descending priority
+ * @param index
+ * index to first element in array that should be considered
+ * @return true if all targets should be rebuilt.
+ */
+ public boolean getRebuild(ProcessorDef[] defaultProviders, int index) {
+ if (isReference()) {
+ return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).getRebuild(defaultProviders, index);
+ }
+ if (rebuild != null) {
+ return rebuild.booleanValue();
+ } else {
+ if (defaultProviders != null && index < defaultProviders.length) {
+ return defaultProviders[index].getRebuild(defaultProviders,
+ index + 1);
+ }
+ }
+ return false;
+ }
+ /**
+ * Returns true if the processor definition contains embedded file set
+ * definitions
+ *
+ * @return true if processor definition contains embedded filesets
+ */
+ public boolean hasFileSets() {
+ if (isReference()) {
+ return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).hasFileSets();
+ }
+ return srcSets.size() > 0;
+ }
+ /**
+ * Determine if this def should be used.
+ *
+ * Definition will be active if the "if" variable (if specified) is set and
+ * the "unless" variable (if specified) is not set and that all reference
+ * or extended definitions are active
+ *
+ * @return true if processor is active
+ * @throws IllegalStateException
+ * if not properly initialized
+ * @throws BuildException
+ * if "if" or "unless" variable contains suspicious values
+ * "false" or "no" which indicates possible confusion
+ */
+ public boolean isActive() throws BuildException, IllegalStateException {
+ Project project = getProject();
+ if (!CUtil.isActive(project, ifProp, unlessProp)) {
+ return false;
+ }
+ if (isReference()) {
+ if (!((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).isActive()) {
+ return false;
+ }
+ }
+ //
+ // walk through any extended definitions
+ //
+ ProcessorDef[] defaultProviders = getDefaultProviders(null);
+ for (int i = 0; i < defaultProviders.length; i++) {
+ if (!defaultProviders[i].isActive()) {
+ return false;
+ }
+ }
+ return true;
+ }
+ /**
+ * Sets the class name for the adapter. Use the "name" attribute when the
+ * tool is supported.
+ *
+ * @param className
+ * full class name
+ *
+ */
+ public void setClassname(String className) throws BuildException {
+ Object proc = null;
+ try {
+ Class implClass = ProcessorDef.class.getClassLoader().loadClass(
+ className);
+ try {
+ Method getInstance = implClass.getMethod("getInstance",
+ new Class[0]);
+ proc = getInstance.invoke(null, new Object[0]);
+ } catch (Exception ex) {
+ proc = implClass.newInstance();
+ }
+ } catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ setProcessor((Processor) proc);
+ }
+ /**
+ * If set true, all targets will be built for debugging.
+ *
+ * @param debug
+ * true if targets should be built for debugging
+ * @throws BuildException
+ * if processor definition is a reference
+ */
+ public void setDebug(boolean debug) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.debug = booleanValueOf(debug);
+ }
+ /**
+ * Sets a description of the current data type.
+ */
+ public void setDescription(String desc) {
+ super.setDescription(desc);
+ }
+ /**
+ * Specifies that this element extends the element with id attribute with a
+ * matching value. The configuration will be constructed from the settings
+ * of this element, element referenced by extends, and the containing cc
+ * element.
+ *
+ * @param extendsRef
+ * Reference to the extended processor definition.
+ * @throws BuildException
+ * if this processor definition is a reference
+ */
+ public void setExtends(Reference extendsRef) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.extendsRef = extendsRef;
+ }
+ /**
+ * Sets an id that can be used to reference this element.
+ *
+ * @param id
+ * id
+ */
+ public void setId(String id) {
+ //
+ // this is actually accomplished by a different
+ // mechanism, but we can document it
+ //
+ }
+ /**
+ * Sets the property name for the 'if' condition.
+ *
+ * The configuration will be ignored unless the property is defined.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") will throw an exception when
+ * evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public void setIf(String propName) {
+ ifProp = propName;
+ }
+ /**
+ * If inherit has the default value of true, defines, includes and other
+ * settings from the containing cc element will be inherited.
+ *
+ * @param inherit
+ * new value
+ * @throws BuildException
+ * if processor definition is a reference
+ */
+ public void setInherit(boolean inherit) throws BuildException {
+ if (isReference()) {
+ throw super.tooManyAttributes();
+ }
+ this.inherit = inherit;
+ }
+ /**
+ * Set use of libtool.
+ *
+ * If set to true, the "libtool " will be prepended to the command line
+ *
+ * @param libtool
+ * If true, use libtool.
+ */
+ public void setLibtool(boolean libtool) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.libtool = booleanValueOf(libtool);
+ }
+ /**
+ * Do not propagate old environment when new environment variables are
+ * specified.
+ */
+ public void setNewenvironment(boolean newenv) {
+ newEnvironment = newenv;
+ }
+ /**
+ * Sets the processor
+ *
+ * @param processor
+ * processor, may not be null.
+ * @throws BuildException
+ * if ProcessorDef is a reference
+ * @throws NullPointerException
+ * if processor is null
+ */
+ protected void setProcessor(Processor processor) throws BuildException,
+ NullPointerException {
+ if (processor == null) {
+ throw new NullPointerException("processor");
+ }
+ if (isReference()) {
+ throw super.tooManyAttributes();
+ }
+ if (env == null && !newEnvironment) {
+ this.processor = processor;
+ } else {
+ this.processor = processor.changeEnvironment(newEnvironment, env);
+ }
+ }
+ /**
+ * If set true, all targets will be unconditionally rebuilt.
+ *
+ * @param rebuild
+ * if true, rebuild all targets.
+ * @throws BuildException
+ * if processor definition is a reference
+ */
+ public void setRebuild(boolean rebuild) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.rebuild = booleanValueOf(rebuild);
+ }
+ /**
+ * Specifies that this element should behave as if the content of the
+ * element with the matching id attribute was inserted at this location. If
+ * specified, no other attributes or child content should be specified,
+ * other than "if", "unless" and "description".
+ *
+ * @param ref
+ * Reference to other element
+ *
+ */
+ public void setRefid(org.apache.tools.ant.types.Reference ref) {
+ super.setRefid(ref);
+ }
+ /**
+ * Set the property name for the 'unless' condition.
+ *
+ * If named property is set, the configuration will be ignored.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") of the behavior will throw an
+ * exception when evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public void setUnless(String propName) {
+ unlessProp = propName;
+ }
+ /**
+ * This method calls the FileVistor's visit function for every file in the
+ * processors definition
+ *
+ * @param visitor
+ * object whose visit method is called for every file
+ */
+ public void visitFiles(FileVisitor visitor) {
+ Project p = getProject();
+ if (p == null) {
+ throw new java.lang.IllegalStateException(
+ "project must be set before this call");
+ }
+ if (isReference()) {
+ ((ProcessorDef) getCheckedRef(ProcessorDef.class, "ProcessorDef"))
+ .visitFiles(visitor);
+ }
+ //
+ // if this processor extends another,
+ // visit its files first
+ //
+ ProcessorDef extendsDef = getExtends();
+ if (extendsDef != null) {
+ extendsDef.visitFiles(visitor);
+ }
+
+ for (int i = 0; i < srcSets.size(); i++) {
+ ConditionalFileSet srcSet = (ConditionalFileSet) srcSets
+ .elementAt(i);
+ if (srcSet.isActive()) {
+ // Find matching source files
+ DirectoryScanner scanner = srcSet.getDirectoryScanner(p);
+ // Check each source file - see if it needs compilation
+ String[] fileNames = scanner.getIncludedFiles();
+ File parentDir = scanner.getBasedir();
+ for (int j = 0; j < fileNames.length; j++) {
+ String currentFile = fileNames[j];
+ visitor.visit(parentDir, currentFile);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ProcessorEnumValue.java b/src/main/java/net/sf/antcontrib/cpptasks/ProcessorEnumValue.java
new file mode 100644
index 0000000..9096183
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ProcessorEnumValue.java
@@ -0,0 +1,47 @@
+/*
+ *
+ * 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;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+/**
+ * One entry in the arrays used by the CompilerEnum and LinkerEnum classes.
+ *
+ * @author Curt Arnold
+ * @see CompilerEnum
+ * @see LinkerEnum
+ *
+ */
+public class ProcessorEnumValue {
+ public static String[] getValues(ProcessorEnumValue[] processors) {
+ String[] values = new String[processors.length];
+ for (int i = 0; i < processors.length; i++) {
+ values[i] = processors[i].getName();
+ }
+ return values;
+ }
+ private String name;
+ private Processor processor;
+ public ProcessorEnumValue(String name, Processor processor) {
+ this.name = name;
+ this.processor = processor;
+ }
+ public String getName() {
+ return name;
+ }
+ public Processor getProcessor() {
+ return processor;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ProcessorParam.java b/src/main/java/net/sf/antcontrib/cpptasks/ProcessorParam.java
new file mode 100644
index 0000000..1b0c613
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ProcessorParam.java
@@ -0,0 +1,100 @@
+/*
+ *
+ * Copyright 2001-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;
+/*******************************************************************************
+ * Place class description here.
+ *
+ * @author inger
+ * @author <additional author>
+ *
+ * @since
+ ******************************************************************************/
+public class ProcessorParam {
+ private String ifCond;
+ private String name;
+ private String unlessCond;
+ private String value;
+ public ProcessorParam() {
+ }
+ public String getName() {
+ return name;
+ }
+ public String getValue() {
+ return value;
+ }
+ /**
+ * Returns true if the define's if and unless conditions (if any) are
+ * satisfied.
+ */
+ public boolean isActive(org.apache.tools.ant.Project p) {
+ if (value == null) {
+ return false;
+ }
+ if (ifCond != null && p.getProperty(ifCond) == null) {
+ return false;
+ } else if (unlessCond != null && p.getProperty(unlessCond) != null) {
+ return false;
+ }
+ return true;
+ }
+ /**
+ * Sets the property name for the 'if' condition.
+ *
+ * The argument will be ignored unless the property is defined.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") will throw an exception when
+ * evaluated.
+ */
+ public void setIf(String propName) {
+ ifCond = propName;
+ }
+ /**
+ * Specifies relative location of argument on command line. "start" will
+ * place argument at start of command line, "mid" will place argument after
+ * all "start" arguments but before filenames, "end" will place argument
+ * after filenames.
+ *
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+ /**
+ * Set the property name for the 'unless' condition.
+ *
+ * If named property is set, the argument will be ignored.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") of the behavior will throw an
+ * exception when evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public void setUnless(String propName) {
+ unlessCond = propName;
+ }
+ /**
+ * Specifies the string that should appear on the command line. The
+ * argument will be quoted if it contains embedded blanks. Use multiple
+ * arguments to avoid quoting.
+ *
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/RuntimeType.java b/src/main/java/net/sf/antcontrib/cpptasks/RuntimeType.java
new file mode 100644
index 0000000..6590098
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/RuntimeType.java
@@ -0,0 +1,26 @@
+/*
+ *
+ * Copyright 2001-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;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+/**
+ * Enumerated attribute with the values "dynamic" and "static",
+ */
+public class RuntimeType extends EnumeratedAttribute {
+ public String[] getValues() {
+ return new String[]{"dynamic", "static"};
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/SourceHistory.java b/src/main/java/net/sf/antcontrib/cpptasks/SourceHistory.java
new file mode 100644
index 0000000..4ffd38f
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/SourceHistory.java
@@ -0,0 +1,51 @@
+/*
+ *
+ * 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;
+import java.io.File;
+import java.io.IOException;
+/**
+ * The history of a source file used to build a target
+ *
+ * @author Curt Arnold
+ */
+public final class SourceHistory {
+ private/* final */long lastModified;
+ private/* final */String relativePath;
+ /**
+ * Constructor
+ */
+ public SourceHistory(String relativePath, long lastModified) {
+ if (relativePath == null) {
+ throw new NullPointerException("relativePath");
+ }
+ this.relativePath = relativePath;
+ this.lastModified = lastModified;
+ }
+ public String getAbsolutePath(File baseDir) {
+ try {
+ return new File(baseDir, relativePath).getCanonicalPath();
+ } catch (IOException ex) {
+ }
+ return relativePath;
+ }
+ public long getLastModified() {
+ return lastModified;
+ }
+ public String getRelativePath() {
+ return relativePath;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/SubsystemEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/SubsystemEnum.java
new file mode 100644
index 0000000..19dd207
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/SubsystemEnum.java
@@ -0,0 +1,34 @@
+/*
+ *
+ * Copyright 2001-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;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+/**
+ * Enumeration of supported subsystems
+ *
+ * @author Curt Arnold
+ *
+ */
+public final class SubsystemEnum extends EnumeratedAttribute {
+ private final static String[] values = new String[]{"gui", "console",
+ "other"};
+ public SubsystemEnum() {
+ setValue("gui");
+ }
+ public String[] getValues() {
+ return (String[]) values.clone();
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/TargetDef.java b/src/main/java/net/sf/antcontrib/cpptasks/TargetDef.java
new file mode 100644
index 0000000..70263ad
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/TargetDef.java
@@ -0,0 +1,228 @@
+/*
+ *
+ * Copyright 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;
+
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Reference;
+
+/**
+ * Information on the execution platforms for the generated code.
+ * (Non-functional prototype)
+ *
+ */
+public final class TargetDef
+ extends DataType {
+ /**
+ * if property.
+ */
+ private String ifCond;
+
+ /**
+ * unless property.
+ */
+ private String unlessCond;
+
+ /**
+ * cpu.
+ *
+ */
+ private CPUEnum cpu;
+
+ /**
+ * architecture.
+ *
+ */
+ private ArchEnum arch;
+
+ /**
+ * OS Family.
+ *
+ */
+ private OSFamilyEnum osFamily;
+
+ /**
+ * Constructor.
+ *
+ */
+ public TargetDef() {
+ }
+
+ /**
+ * Bogus method required for documentation generation.
+ */
+ public void execute() {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+
+ /**
+ * Returns true if the define's if and unless conditions (if any) are
+ * satisfied.
+ * @return true if active
+ */
+ public boolean isActive() {
+ return CUtil.isActive(getProject(), ifCond, unlessCond);
+ }
+
+ /**
+ * Sets a description of the current data type.
+ * @param desc description
+ */
+ public void setDescription(final String desc) {
+ super.setDescription(desc);
+ }
+
+ /**
+ * Sets an id that can be used to reference this element.
+ *
+ * @param id
+ * id
+ */
+ public void setId(final String id) {
+ //
+ // this is actually accomplished by a different
+ // mechanism, but we can document it
+ //
+ }
+
+ /**
+ * Sets the property name for the 'if' condition.
+ *
+ * The define will be ignored unless the property is defined.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") will throw an exception when
+ * evaluated.
+ *
+ * @param propName
+ * property name
+ */
+ public void setIf(final String propName) {
+ ifCond = propName;
+ }
+
+ /**
+ * Specifies that this element should behave as if the content of the
+ * element with the matching id attribute was inserted at this location. If
+ * specified, no other attributes should be specified.
+ * @param r id of referenced target
+ */
+ public void setRefid(final Reference r) {
+ super.setRefid(r);
+ }
+
+ /**
+ * Set the property name for the 'unless' condition.
+ *
+ * If named property is set, the define will be ignored.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") of the behavior will throw an
+ * exception when evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public void setUnless(final String propName) {
+ unlessCond = propName;
+ }
+
+ /**
+ * Gets cpu.
+ * @return cpu, may be null.
+ *
+ */
+ public CPUEnum getCpu() {
+ if (isReference()) {
+ TargetDef refPlatform = (TargetDef)
+ getCheckedRef(TargetDef.class,
+ "TargetDef");
+ return refPlatform.getCpu();
+ }
+ return cpu;
+ }
+
+ /**
+ * Gets arch.
+ * @return arch, may be null.
+ *
+ */
+ public ArchEnum getArch() {
+ if (isReference()) {
+ TargetDef refPlatform = (TargetDef)
+ getCheckedRef(TargetDef.class,
+ "TargetDef");
+ return refPlatform.getArch();
+ }
+ return arch;
+ }
+
+ /**
+ * Gets operating system family.
+ * @return os family, may be null.
+ *
+ */
+ public OSFamilyEnum getOsfamily() {
+ if (isReference()) {
+ TargetDef refPlatform = (TargetDef)
+ getCheckedRef(TargetDef.class,
+ "TargetDef");
+ return refPlatform.getOsfamily();
+ }
+ return osFamily;
+ }
+
+ /**
+ * Sets preferred cpu, but does not use cpu specific instructions.
+ * @param value new value
+ */
+ public void setCpu(final CPUEnum value) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ cpu = value;
+ }
+
+ /**
+ * Sets cpu architecture, compiler may use cpu specific instructions.
+ * @param value new value
+ */
+ public void setArch(final ArchEnum value) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (cpu != null) {
+ throw tooManyAttributes();
+ }
+ arch = value;
+ }
+
+ /**
+ * Sets operating system family.
+ * @param value new value
+ */
+ public void setOsfamily(final OSFamilyEnum value) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (cpu != null) {
+ throw tooManyAttributes();
+ }
+ osFamily = value;
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/TargetHistory.java b/src/main/java/net/sf/antcontrib/cpptasks/TargetHistory.java
new file mode 100644
index 0000000..b797170
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/TargetHistory.java
@@ -0,0 +1,58 @@
+/*
+ *
+ * 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;
+/**
+ * A description of a file built or to be built
+ */
+public final class TargetHistory {
+ private/* final */String config;
+ private/* final */String output;
+ private/* final */long outputLastModified;
+ private/* final */SourceHistory[] sources;
+ /**
+ * Constructor from build step
+ */
+ public TargetHistory(String config, String output, long outputLastModified,
+ SourceHistory[] sources) {
+ if (config == null) {
+ throw new NullPointerException("config");
+ }
+ if (sources == null) {
+ throw new NullPointerException("source");
+ }
+ if (output == null) {
+ throw new NullPointerException("output");
+ }
+ this.config = config;
+ this.output = output;
+ this.outputLastModified = outputLastModified;
+ this.sources = (SourceHistory[]) sources.clone();
+ }
+ public String getOutput() {
+ return output;
+ }
+ public long getOutputLastModified() {
+ return outputLastModified;
+ }
+ public String getProcessorConfiguration() {
+ return config;
+ }
+ public SourceHistory[] getSources() {
+ SourceHistory[] clone = (SourceHistory[]) sources.clone();
+ return clone;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/TargetHistoryTable.java b/src/main/java/net/sf/antcontrib/cpptasks/TargetHistoryTable.java
new file mode 100644
index 0000000..bdab94c
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/TargetHistoryTable.java
@@ -0,0 +1,430 @@
+/*
+ *
+ * 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;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;
+
+import org.apache.tools.ant.BuildException;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+/**
+ * A history of the compiler and linker settings used to build the files in the
+ * same directory as the history.
+ *
+ * @author Curt Arnold
+ */
+public final class TargetHistoryTable {
+ /**
+ * This class handles populates the TargetHistory hashtable in response to
+ * SAX parse events
+ */
+ private class TargetHistoryTableHandler extends DefaultHandler {
+ private final File baseDir;
+ private String config;
+ private final Hashtable history;
+ private String output;
+ private long outputLastModified;
+ private final Vector sources = new Vector();
+ /**
+ * Constructor
+ *
+ * @param history
+ * hashtable of TargetHistory keyed by output name
+ * @param outputFiles
+ * existing files in output directory
+ */
+ private TargetHistoryTableHandler(Hashtable history, File baseDir) {
+ this.history = history;
+ config = null;
+ output = null;
+ this.baseDir = baseDir;
+ }
+ public void endElement(String namespaceURI, String localName,
+ String qName) throws SAXException {
+ //
+ // if </target> then
+ // create TargetHistory object and add to hashtable
+ // if corresponding output file exists and
+ // has the same timestamp
+ //
+ if (qName.equals("target")) {
+ if (config != null && output != null) {
+ File existingFile = new File(baseDir, output);
+ //
+ // if the corresponding files doesn't exist or has a
+ // different
+ // modification time, then discard this record
+ if (existingFile.exists()) {
+ //
+ // would have expected exact time stamps
+ // but have observed slight differences
+ // in return value for multiple evaluations of
+ // lastModified(). Check if times are within
+ // a second
+ long existingLastModified = existingFile.lastModified();
+ if (!CUtil.isSignificantlyBefore(existingLastModified, outputLastModified)
+ && !CUtil.isSignificantlyAfter(existingLastModified, outputLastModified)) {
+ SourceHistory[] sourcesArray = new SourceHistory[sources
+ .size()];
+ sources.copyInto(sourcesArray);
+ TargetHistory targetHistory = new TargetHistory(
+ config, output, outputLastModified,
+ sourcesArray);
+ history.put(output, targetHistory);
+ }
+ }
+ }
+ output = null;
+ sources.setSize(0);
+ } else {
+ //
+ // reset config so targets not within a processor element
+ // don't pick up a previous processors signature
+ //
+ if (qName.equals("processor")) {
+ config = null;
+ }
+ }
+ }
+ /**
+ * startElement handler
+ */
+ public void startElement(String namespaceURI, String localName,
+ String qName, Attributes atts) throws SAXException {
+ //
+ // if sourceElement
+ //
+ if (qName.equals("source")) {
+ String sourceFile = atts.getValue("file");
+ long sourceLastModified = Long.parseLong(atts
+ .getValue("lastModified"), 16);
+ sources.addElement(new SourceHistory(sourceFile,
+ sourceLastModified));
+ } else {
+ //
+ // if <target> element,
+ // grab file name and lastModified values
+ // TargetHistory object will be created in endElement
+ //
+ if (qName.equals("target")) {
+ sources.setSize(0);
+ output = atts.getValue("file");
+ outputLastModified = Long.parseLong(atts
+ .getValue("lastModified"), 16);
+ } else {
+ //
+ // if <processor> element,
+ // grab signature attribute
+ //
+ if (qName.equals("processor")) {
+ config = atts.getValue("signature");
+ }
+ }
+ }
+ }
+ }
+ /** Flag indicating whether the cache should be written back to file. */
+ private boolean dirty;
+ /**
+ * a hashtable of TargetHistory's keyed by output file name
+ */
+ private final Hashtable history = new Hashtable();
+ /** The file the cache was loaded from. */
+ private/* final */File historyFile;
+ private/* final */File outputDir;
+ private String outputDirPath;
+ /**
+ * Creates a target history table from history.xml in the output directory,
+ * if it exists. Otherwise, initializes the history table empty.
+ *
+ * @param task
+ * task used for logging history load errors
+ * @param outputDir
+ * output directory for task
+ */
+ public TargetHistoryTable(CCTask task, File outputDir)
+ throws BuildException {
+ if (outputDir == null) {
+ throw new NullPointerException("outputDir");
+ }
+ if (!outputDir.isDirectory()) {
+ throw new BuildException("Output directory is not a directory");
+ }
+ if (!outputDir.exists()) {
+ throw new BuildException("Output directory does not exist");
+ }
+ this.outputDir = outputDir;
+ try {
+ outputDirPath = outputDir.getCanonicalPath();
+ } catch (IOException ex) {
+ outputDirPath = outputDir.toString();
+ }
+ //
+ // load any existing history from file
+ // suppressing any records whose corresponding
+ // file does not exist, is zero-length or
+ // last modified dates differ
+ historyFile = new File(outputDir, "history.xml");
+ if (historyFile.exists()) {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setValidating(false);
+ try {
+ SAXParser parser = factory.newSAXParser();
+ parser.parse(historyFile, new TargetHistoryTableHandler(
+ history, outputDir));
+ } catch (Exception ex) {
+ //
+ // a failure on loading this history is not critical
+ // but should be logged
+ task.log("Error reading history.xml: " + ex.toString());
+ }
+ } else {
+ //
+ // create empty history file for identifying new files by last
+ // modified
+ // timestamp comperation (to compare with
+ // System.currentTimeMillis() don't work on Unix, because it
+ // maesure timestamps only in seconds).
+ //
+ try {
+ FileOutputStream outputStream = new FileOutputStream(
+ historyFile);
+ byte[] historyElement = new byte[]{0x3C, 0x68, 0x69, 0x73,
+ 0x74, 0x6F, 0x72, 0x79, 0x2F, 0x3E};
+ outputStream.write(historyElement);
+ outputStream.close();
+ } catch (IOException ex) {
+ throw new BuildException("Can't create history file", ex);
+ }
+ }
+ }
+ public void commit() throws IOException {
+ //
+ // if not dirty, no need to update file
+ //
+ if (dirty) {
+ //
+ // build (small) hashtable of config id's in history
+ //
+ Hashtable configs = new Hashtable(20);
+ Enumeration elements = history.elements();
+ while (elements.hasMoreElements()) {
+ TargetHistory targetHistory = (TargetHistory) elements
+ .nextElement();
+ String configId = targetHistory.getProcessorConfiguration();
+ if (configs.get(configId) == null) {
+ configs.put(configId, configId);
+ }
+ }
+ FileOutputStream outStream = new FileOutputStream(historyFile);
+ OutputStreamWriter outWriter;
+ //
+ // early VM's don't support UTF-8 encoding
+ // try and fallback to the default encoding
+ // otherwise
+ String encodingName = "UTF-8";
+ try {
+ outWriter = new OutputStreamWriter(outStream, "UTF-8");
+ } catch (UnsupportedEncodingException ex) {
+ outWriter = new OutputStreamWriter(outStream);
+ encodingName = outWriter.getEncoding();
+ }
+ BufferedWriter writer = new BufferedWriter(outWriter);
+ writer.write("<?xml version='1.0' encoding='");
+ writer.write(encodingName);
+ writer.write("'?>\n");
+ writer.write("<history>\n");
+ StringBuffer buf = new StringBuffer(200);
+ Enumeration configEnum = configs.elements();
+ while (configEnum.hasMoreElements()) {
+ String configId = (String) configEnum.nextElement();
+ buf.setLength(0);
+ buf.append(" <processor signature=\"");
+ buf.append(CUtil.xmlAttribEncode(configId));
+ buf.append("\">\n");
+ writer.write(buf.toString());
+ elements = history.elements();
+ while (elements.hasMoreElements()) {
+ TargetHistory targetHistory = (TargetHistory) elements
+ .nextElement();
+ if (targetHistory.getProcessorConfiguration().equals(
+ configId)) {
+ buf.setLength(0);
+ buf.append(" <target file=\"");
+ buf.append(CUtil.xmlAttribEncode(targetHistory
+ .getOutput()));
+ buf.append("\" lastModified=\"");
+ buf.append(Long.toHexString(targetHistory
+ .getOutputLastModified()));
+ buf.append("\">\n");
+ writer.write(buf.toString());
+ SourceHistory[] sourceHistories = targetHistory
+ .getSources();
+ for (int i = 0; i < sourceHistories.length; i++) {
+ buf.setLength(0);
+ buf.append(" <source file=\"");
+ buf.append(CUtil.xmlAttribEncode(sourceHistories[i]
+ .getRelativePath()));
+ buf.append("\" lastModified=\"");
+ buf.append(Long.toHexString(sourceHistories[i]
+ .getLastModified()));
+ buf.append("\"/>\n");
+ writer.write(buf.toString());
+ }
+ writer.write(" </target>\n");
+ }
+ }
+ writer.write(" </processor>\n");
+ }
+ writer.write("</history>\n");
+ writer.close();
+ dirty = false;
+ }
+ }
+ public TargetHistory get(String configId, String outputName) {
+ TargetHistory targetHistory = (TargetHistory) history.get(outputName);
+ if (targetHistory != null) {
+ if (!targetHistory.getProcessorConfiguration().equals(configId)) {
+ targetHistory = null;
+ }
+ }
+ return targetHistory;
+ }
+ public void markForRebuild(Hashtable targetInfos) {
+ Enumeration targetInfoEnum = targetInfos.elements();
+ while (targetInfoEnum.hasMoreElements()) {
+ markForRebuild((TargetInfo) targetInfoEnum.nextElement());
+ }
+ }
+ public void markForRebuild(TargetInfo targetInfo) {
+ //
+ // if it must already be rebuilt, no need to check further
+ //
+ if (!targetInfo.getRebuild()) {
+ TargetHistory history = get(targetInfo.getConfiguration()
+ .toString(), targetInfo.getOutput().getName());
+ if (history == null) {
+ targetInfo.mustRebuild();
+ } else {
+ SourceHistory[] sourceHistories = history.getSources();
+ File[] sources = targetInfo.getSources();
+ if (sourceHistories.length != sources.length) {
+ targetInfo.mustRebuild();
+ } else {
+ Hashtable sourceMap = new Hashtable(sources.length);
+ for (int i = 0; i < sources.length; i++) {
+ try {
+ sourceMap.put(sources[i].getCanonicalPath(), sources[i]);
+ } catch(IOException ex) {
+ sourceMap.put(sources[i].getAbsolutePath(), sources[i]);
+ }
+ }
+ for (int i = 0; i < sourceHistories.length; i++) {
+ //
+ // relative file name, must absolutize it on output
+ // directory
+ //
+ String absPath = sourceHistories[i].getAbsolutePath(outputDir);
+ File match = (File) sourceMap.get(absPath);
+ if (match != null) {
+ try {
+ match = (File) sourceMap.get(new File(absPath).getCanonicalPath());
+ } catch(IOException ex) {
+ targetInfo.mustRebuild();
+ break;
+ }
+ }
+ if (match == null || match.lastModified() != sourceHistories[i].getLastModified()) {
+ targetInfo.mustRebuild();
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ public void update(ProcessorConfiguration config, String[] sources, VersionInfo versionInfo) {
+ String configId = config.getIdentifier();
+ String[] onesource = new String[1];
+ String[] outputNames;
+ for (int i = 0; i < sources.length; i++) {
+ onesource[0] = sources[i];
+ outputNames = config.getOutputFileNames(sources[i], versionInfo);
+ for (int j = 0; j < outputNames.length; j++) {
+ update(configId, outputNames[j], onesource);
+ }
+ }
+ }
+ private void update(String configId, String outputName, String[] sources) {
+ File outputFile = new File(outputDir, outputName);
+ //
+ // if output file doesn't exist or predates the start of the
+ // compile step (most likely a compilation error) then
+ // do not write add a history entry
+ //
+ if (outputFile.exists() &&
+ !CUtil.isSignificantlyBefore(outputFile.lastModified(), historyFile.lastModified())) {
+ dirty = true;
+ history.remove(outputName);
+ SourceHistory[] sourceHistories = new SourceHistory[sources.length];
+ for (int i = 0; i < sources.length; i++) {
+ File sourceFile = new File(sources[i]);
+ long lastModified = sourceFile.lastModified();
+ String relativePath = CUtil.getRelativePath(outputDirPath,
+ sourceFile);
+ sourceHistories[i] = new SourceHistory(relativePath,
+ lastModified);
+ }
+ TargetHistory newHistory = new TargetHistory(configId, outputName,
+ outputFile.lastModified(), sourceHistories);
+ history.put(outputName, newHistory);
+ }
+ }
+ public void update(TargetInfo linkTarget) {
+ File outputFile = linkTarget.getOutput();
+ String outputName = outputFile.getName();
+ //
+ // if output file doesn't exist or predates the start of the
+ // compile or link step (most likely a compilation error) then
+ // do not write add a history entry
+ //
+ if (outputFile.exists()
+ && !CUtil.isSignificantlyBefore(outputFile.lastModified(),historyFile.lastModified())) {
+ dirty = true;
+ history.remove(outputName);
+ SourceHistory[] sourceHistories = linkTarget
+ .getSourceHistories(outputDirPath);
+ TargetHistory newHistory = new TargetHistory(linkTarget
+ .getConfiguration().getIdentifier(), outputName, outputFile
+ .lastModified(), sourceHistories);
+ history.put(outputName, newHistory);
+ }
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/TargetInfo.java b/src/main/java/net/sf/antcontrib/cpptasks/TargetInfo.java
new file mode 100644
index 0000000..8fd5bb4
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/TargetInfo.java
@@ -0,0 +1,127 @@
+/*
+ *
+ * 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;
+import java.io.File;
+
+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;
+/**
+ * A description of a file built or to be built
+ */
+public final class TargetInfo {
+ private static final File[] emptyFileArray = new File[0];
+ private/* final */ProcessorConfiguration config;
+ private/* final */File output;
+ private boolean rebuild;
+ private/* final */File[] sources;
+ private File[] sysSources;
+ public TargetInfo(ProcessorConfiguration config, File[] sources,
+ File[] sysSources, File output, boolean rebuild) {
+ if (config == null) {
+ throw new NullPointerException("config");
+ }
+ if (sources == null) {
+ throw new NullPointerException("sources");
+ }
+ if (output == null) {
+ throw new NullPointerException("output");
+ }
+ this.config = config;
+ this.sources = (File[]) sources.clone();
+ if (sysSources == null) {
+ this.sysSources = emptyFileArray;
+ } else {
+ this.sysSources = (File[]) sysSources.clone();
+ }
+ this.output = output;
+ this.rebuild = rebuild;
+ //
+ // if the output doesn't exist, must rebuild it
+ //
+ if (!output.exists()) {
+ rebuild = true;
+ }
+ }
+ public String[] getAllSourcePaths() {
+ String[] paths = new String[sysSources.length + sources.length];
+ for (int i = 0; i < sysSources.length; i++) {
+ paths[i] = sysSources[i].toString();
+ }
+ int offset = sysSources.length;
+ for (int i = 0; i < sources.length; i++) {
+ paths[offset + i] = sources[i].toString();
+ }
+ return paths;
+ }
+ public File[] getAllSources() {
+ File[] allSources = new File[sources.length + sysSources.length];
+ for (int i = 0; i < sysSources.length; i++) {
+ allSources[i] = sysSources[i];
+ }
+ int offset = sysSources.length;
+ for (int i = 0; i < sources.length; i++) {
+ allSources[i + offset] = sources[i];
+ }
+ return allSources;
+ }
+ public ProcessorConfiguration getConfiguration() {
+ return config;
+ }
+ public File getOutput() {
+ return output;
+ }
+ public boolean getRebuild() {
+ return rebuild;
+ }
+ /**
+ * Returns an array of SourceHistory objects (contains relative path and
+ * last modified time) for the source[s] of this target
+ */
+ public SourceHistory[] getSourceHistories(String basePath) {
+ SourceHistory[] histories = new SourceHistory[sources.length];
+ for (int i = 0; i < sources.length; i++) {
+ String relativeName = CUtil.getRelativePath(basePath, sources[i]);
+ long lastModified = sources[i].lastModified();
+ histories[i] = new SourceHistory(relativeName, lastModified);
+ }
+ return histories;
+ }
+ public String[] getSourcePaths() {
+ String[] paths = new String[sources.length];
+ for (int i = 0; i < sources.length; i++) {
+ paths[i] = sources[i].toString();
+ }
+ return paths;
+ }
+ public File[] getSources() {
+ File[] clone = (File[]) sources.clone();
+ return clone;
+ }
+ public String[] getSysSourcePaths() {
+ String[] paths = new String[sysSources.length];
+ for (int i = 0; i < sysSources.length; i++) {
+ paths[i] = sysSources[i].toString();
+ }
+ return paths;
+ }
+ public File[] getSysSources() {
+ File[] clone = (File[]) sysSources.clone();
+ return clone;
+ }
+ public void mustRebuild() {
+ this.rebuild = true;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/TargetMatcher.java b/src/main/java/net/sf/antcontrib/cpptasks/TargetMatcher.java
new file mode 100644
index 0000000..9260f77
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/TargetMatcher.java
@@ -0,0 +1,120 @@
+/*
+ *
+ * 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;
+import java.io.File;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.compiler.LinkerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;
+
+import org.apache.tools.ant.BuildException;
+/**
+ * This class matches each visited file with an appropriate compiler
+ *
+ * @author Curt Arnold
+ */
+public final class TargetMatcher implements FileVisitor {
+ private LinkerConfiguration linker;
+ private Vector objectFiles;
+ private File outputDir;
+ private ProcessorConfiguration[] processors;
+ private final File sourceFiles[] = new File[1];
+ private Hashtable targets;
+ private VersionInfo versionInfo;
+ private CCTask task;
+ public TargetMatcher(CCTask task, File outputDir,
+ ProcessorConfiguration[] processors, LinkerConfiguration linker,
+ Vector objectFiles, Hashtable targets,
+ VersionInfo versionInfo) {
+ this.task = task;
+ this.outputDir = outputDir;
+ this.processors = processors;
+ this.targets = targets;
+ this.linker = linker;
+ this.objectFiles = objectFiles;
+ this.versionInfo = versionInfo;
+ }
+ public void visit(File parentDir, String filename) throws BuildException {
+ File fullPath = new File(parentDir, filename);
+ //
+ // see if any processor wants to bid
+ // on this one
+ ProcessorConfiguration selectedCompiler = null;
+ int bid = 0;
+ if (processors != null) {
+ for (int k = 0; k < processors.length; k++) {
+ int newBid = processors[k].bid(fullPath.toString());
+ if (newBid > bid) {
+ bid = newBid;
+ selectedCompiler = processors[k];
+ }
+ }
+ }
+ //
+ // no processor interested in file
+ // log diagnostic message
+ if (bid <= 0) {
+ if (linker != null) {
+ int linkerbid = linker.bid(filename);
+ if (linkerbid > 0) {
+ objectFiles.addElement(fullPath);
+ if (linkerbid == 1) {
+ task.log("Unrecognized file type " + fullPath.toString()
+ + " will be passed to linker");
+ }
+ }
+ }
+ } else {
+ //
+ // get output file name
+ //
+ String[] outputFileNames = selectedCompiler
+ .getOutputFileNames(filename, versionInfo);
+ sourceFiles[0] = fullPath;
+ //
+ // if there is some output for this task
+ // (that is a source file and not an header file)
+ //
+ for (int i = 0; i < outputFileNames.length; i++) {
+ //
+ // see if the same output file has already been registered
+ //
+ TargetInfo previousTarget = (TargetInfo) targets
+ .get(outputFileNames[i]);
+ if (previousTarget == null) {
+ targets.put(outputFileNames[i], new TargetInfo(
+ selectedCompiler, sourceFiles, null, new File(
+ outputDir, outputFileNames[i]),
+ selectedCompiler.getRebuild()));
+ } else {
+ if (!previousTarget.getSources()[0].equals(sourceFiles[0])) {
+ StringBuffer builder = new StringBuffer(
+ "Output filename conflict: ");
+ builder.append(outputFileNames[i]);
+ builder.append(" would be produced from ");
+ builder.append(previousTarget.getSources()[0]
+ .toString());
+ builder.append(" and ");
+ builder.append(filename);
+ throw new BuildException(builder.toString());
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/VersionInfo.java b/src/main/java/net/sf/antcontrib/cpptasks/VersionInfo.java
new file mode 100644
index 0000000..92cfeb0
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/VersionInfo.java
@@ -0,0 +1,671 @@
+/*
+ *
+ * Copyright 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;
+
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Reference;
+
+/**
+ * Version Information.
+ *
+ * This information is applied in a platform specific manner
+ * to embed version information into executable images. This
+ * behavior is new and subject to change.
+ *
+ * On the Microsoft Windows platform, a resource is generated and added
+ * to the set of files to be compiled. A resource compiler must
+ * be specified to compile the generated file.
+ *
+ * On Unix platforms, versioninfo is currently not used.
+ * Future versions may append fileversion to the output file name,
+ * use compatibility version for -soname and possibly create
+ * symbolic links.
+ */
+public final class VersionInfo extends DataType {
+ /**
+ * if property.
+ */
+ private String ifCond;
+ /**
+ * unless property.
+ */
+ private String unlessCond;
+
+ /**
+ * extends property.
+ */
+ private Reference extendsRef;
+
+ /**
+ * file version.
+ *
+ */
+ private String fileVersion;
+ /**
+ * Product version.
+ *
+ */
+ private String productVersion;
+ /**
+ * file language.
+ *
+ */
+ private String language;
+
+ /**
+ * comments.
+ *
+ */
+ private String fileComments;
+ /**
+ * Company name.
+ *
+ */
+ private String companyName;
+ /**
+ * Description.
+ *
+ */
+ private String fileDescription;
+ /**
+ * internal name.
+ */
+ private String internalName;
+ /**
+ * legal copyright.
+ *
+ */
+ private String legalCopyright;
+ /**
+ * legal trademark.
+ *
+ */
+ private String legalTrademarks;
+ /**
+ * original filename.
+ *
+ */
+ private String originalFilename;
+ /**
+ * private build.
+ *
+ */
+ private String privateBuild;
+ /**
+ * product name.
+ *
+ */
+ private String productName;
+ /**
+ * Special build
+ */
+ private String specialBuild;
+ /**
+ * compatibility version
+ *
+ */
+ private String compatibilityVersion;
+
+ /**
+ * prerease build.
+ *
+ */
+ private Boolean prerelease;
+
+ /**
+ * prerease build.
+ *
+ */
+ private Boolean patched;
+
+
+ /**
+ * Constructor.
+ *
+ */
+ public VersionInfo() {
+ }
+
+ /**
+ * Private constructor for merge.
+ * @param stack list of version infos with most significant first.
+ */
+ private VersionInfo(final Vector stack) {
+ VersionInfo source = null;
+ for(int i = stack.size() - 1; i >= 0; i--) {
+ source = (VersionInfo) stack.elementAt(i);
+ if (source.getIf() != null) {
+ ifCond = source.getIf();
+ }
+ if (source.getUnless() != null) {
+ unlessCond = source.getUnless();
+ }
+ if (source.getFileversion() != null) {
+ fileVersion = source.getFileversion();
+ }
+ if (source.getProductversion() != null) {
+ productVersion = source.getProductversion();
+ }
+ if (source.getLanguage() != null) {
+ language = source.getLanguage();
+ }
+ if (source.getFilecomments() != null) {
+ fileComments = source.getFilecomments();
+ }
+ if (source.getCompanyname() != null) {
+ companyName = source.getCompanyname();
+ }
+ if (source.getFiledescription() != null) {
+ fileDescription = source.getFiledescription();
+ }
+ if (source.getInternalname() != null) {
+ internalName = source.getInternalname();
+ }
+ if (source.getLegalcopyright() != null) {
+ legalCopyright = source.getLegalcopyright();
+ }
+ if (source.getLegaltrademarks() != null) {
+ legalTrademarks = source.getLegaltrademarks();
+ }
+ if (source.getOriginalfilename() != null) {
+ originalFilename = source.getOriginalfilename();
+ }
+ if (source.getPrivatebuild() != null) {
+ privateBuild = source.getPrivatebuild();
+ }
+ if (source.getProductname() != null) {
+ productName = source.getProductname();
+ }
+ if (source.getSpecialbuild() != null) {
+ specialBuild = source.getSpecialbuild();
+ }
+ if (source.getCompatibilityversion() != null) {
+ compatibilityVersion = source.getCompatibilityversion();
+ }
+ if (source.getPrerelease() != null) {
+ prerelease = source.getPrerelease();
+ }
+ if (source.getPatched() != null) {
+ patched = source.getPatched();
+ }
+ }
+ setProject(source.getProject());
+ }
+
+ /**
+ * Returns a VersionInfo that reflects any inherited version information.
+ * @return merged version information.
+ */
+ public VersionInfo merge() {
+ if (isReference()) {
+ VersionInfo refVersion = (VersionInfo)
+ getCheckedRef(VersionInfo.class,
+ "VersionInfo");
+ return refVersion.merge();
+ }
+ Reference currentRef = this.getExtends();
+ if (currentRef == null) {
+ return this;
+ }
+ Vector stack = new Vector(5);
+ stack.addElement(this);
+ while (currentRef != null) {
+ Object obj = currentRef.getReferencedObject(getProject());
+ if (obj instanceof VersionInfo) {
+ VersionInfo current = (VersionInfo) obj;
+ if (current.isReference()) {
+ current = (VersionInfo)
+ current.getCheckedRef(VersionInfo.class,
+ "VersionInfo");
+ }
+ if (stack.contains(current)) {
+ throw this.circularReference();
+ }
+ stack.addElement(current);
+ currentRef = current.getExtends();
+ } else {
+ throw new BuildException("Referenced element "
+ + currentRef.getRefId() + " is not a versioninfo.");
+ }
+ }
+ return new VersionInfo(stack);
+ }
+ /**
+ * Methods is required for documentation generation, throws
+ * exception if called.
+ *
+ * @throws org.apache.tools.ant.BuildException if called
+ */
+ public void execute() throws org.apache.tools.ant.BuildException {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+ /**
+ * Returns true if the define's if and unless conditions (if any) are
+ * satisfied.
+ *
+ * @exception BuildException
+ * throws build exception if name is not set
+ */
+ public final boolean isActive() throws BuildException {
+ return CUtil.isActive(getProject(), ifCond, unlessCond);
+ }
+ /**
+ * Sets an id that can be used to reference this element.
+ *
+ * @param id
+ * id
+ */
+ public void setId(String id) {
+ //
+ // this is actually accomplished by a different
+ // mechanism, but we can document it
+ //
+ }
+
+ public Reference getExtends() {
+ return this.extendsRef;
+ }
+ /**
+ * Specifies that this element extends the element with id attribute with a
+ * matching value. The configuration will be constructed from the settings
+ * of this element, element referenced by extends, and the containing cc
+ * element.
+ *
+ * @param extendsRef
+ * Reference to the extended processor definition.
+ * @throws BuildException
+ * if this processor definition is a reference
+ */
+ public void setExtends(Reference extendsRef) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.extendsRef = extendsRef;
+ }
+
+ /**
+ * Gets if property name.
+ * @return property name, may be null.
+ */
+ public final String getIf() {
+ return ifCond;
+ }
+ /**
+ * Sets the property name for the 'if' condition.
+ *
+ * The define will be ignored unless the property is defined.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") will throw an exception when
+ * evaluated.
+ *
+ * @param propName
+ * property name
+ */
+ public final void setIf(String propName) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ ifCond = propName;
+ }
+ /**
+ * Specifies that this element should behave as if the content of the
+ * element with the matching id attribute was inserted at this location. If
+ * specified, no other attributes should be specified.
+ *
+ */
+ public void setRefid(Reference r) throws BuildException {
+ super.setRefid(r);
+ }
+ /**
+ * Gets if property name.
+ * @return property name, may be null.
+ */
+ public final String getUnless() {
+ return unlessCond;
+ }
+ /**
+ * Set the property name for the 'unless' condition.
+ *
+ * If named property is set, the define will be ignored.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") of the behavior will throw an
+ * exception when evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public final void setUnless(String propName) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ unlessCond = propName;
+ }
+ /**
+ * Gets file version.
+ * @return file version, may be null.
+ *
+ */
+ public String getFileversion() {
+ return fileVersion;
+ }
+ /**
+ * Gets Product version.
+ * @return product version, may be null
+ */
+ public String getProductversion() {
+ return productVersion;
+ }
+ /**
+ * Gets compatibility version.
+ * @return compatibility version, may be null
+ */
+ public String getCompatibilityversion() {
+ return compatibilityVersion;
+ }
+ /**
+ * Gets file language, should be an IETF RFC 3066 identifier, for example, en-US.
+ * @return language, may be null.
+ */
+ public String getLanguage() {
+ return language;
+ }
+
+ /**
+ * Gets comments.
+ * @return comments, may be null.
+ */
+ public String getFilecomments() {
+ return fileComments;
+ }
+ /**
+ * Gets Company name.
+ * @return company name, may be null.
+ */
+ public String getCompanyname() {
+ return companyName;
+ }
+ /**
+ * Gets Description.
+ * @return description, may be null.
+ */
+ public String getFiledescription() {
+ return fileDescription;
+ }
+ /**
+ * Gets internal name.
+ * @return internal name, may be null.
+ */
+ public String getInternalname() {
+ return internalName;
+ }
+ /**
+ * Gets legal copyright.
+ * @return legal copyright, may be null.
+ */
+ public String getLegalcopyright() {
+ return legalCopyright;
+ }
+ /**
+ * Gets legal trademark.
+ * @return legal trademark, may be null;
+ */
+ public String getLegaltrademarks() {
+ return legalTrademarks;
+ }
+ /**
+ * Gets original filename.
+ * @return original filename, may be null.
+ */
+ public String getOriginalfilename() {
+ return originalFilename;
+ }
+ /**
+ * Gets private build.
+ * @return private build, may be null.
+ */
+ public String getPrivatebuild() {
+ return privateBuild;
+ }
+ /**
+ * Gets prerelease.
+ * @return prerelease, may be null.
+ */
+ public Boolean getPrerelease() {
+ return prerelease;
+ }
+ /**
+ * Gets patched.
+ * @return patched, may be null.
+ */
+ public Boolean getPatched() {
+ return patched;
+ }
+ /**
+ * Gets product name.
+ * @return product name, may be null.
+ */
+ public String getProductname() {
+ return productName;
+ }
+ /**
+ * Special build
+ * @return special build, may be null.
+ */
+ public String getSpecialbuild() {
+ return specialBuild;
+ }
+
+ /**
+ * Sets file version.
+ * @param value new value
+ * @throws BuildException if specified with refid
+ */
+ public void setFileversion(String value) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ fileVersion = value;
+ }
+ /**
+ * Sets product version.
+ * @param value new value
+ * @throws BuildException if specified with refid
+ */
+ public void setProductversion(String value) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ productVersion = value;
+ }
+ /**
+ * Sets compatibility version.
+ * @param value new value
+ * @throws BuildException if specified with refid
+ */
+ public void setCompatibilityversion(String value) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ compatibilityVersion = value;
+ }
+ /**
+ * Sets language.
+ * @param value new value, should be an IETF RFC 3066 language identifier.
+ * @throws BuildException if specified with refid
+ */
+ public void setLanguage(String value) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ language = value;
+ }
+ /**
+ * Sets comments.
+ * @param value new value
+ * @throws BuildException if specified with refid
+ */
+ public void setFilecomments(String value) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ fileComments = value;
+ }
+
+ /**
+ * Sets file description.
+ * @param value new value
+ */
+ public void setFiledescription(String value) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ fileDescription = value;
+ }
+
+ /**
+ * Sets company name.
+ * @param value new value
+ * @throws BuildException if specified with refid
+ */
+ public void setCompanyname(String value) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ companyName = value;
+ }
+
+
+ /**
+ * Sets internal name. Internal name will automatically be
+ * specified from build step, only set this value if
+ * intentionally overriding that value.
+ *
+ * @param value new value
+ * @throws BuildException if specified with refid
+ */
+ public void setInternalname(String value) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ internalName = value;
+ }
+
+ /**
+ * Sets legal copyright.
+ * @param value new value
+ * @throws BuildException if specified with refid
+ */
+ public void setLegalcopyright(String value) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ legalCopyright = value;
+ }
+ /**
+ * Sets legal trademark.
+ * @param value new value
+ * @throws BuildException if specified with refid
+ */
+ public void setLegaltrademarks(String value) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ legalTrademarks = value;
+ }
+ /**
+ * Sets original name. Only set this value if
+ * intentionally overriding the value from the build set.
+ *
+ * @param value new value
+ * @throws BuildException if specified with refid
+ */
+ public void setOriginalfilename(String value) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ originalFilename = value;
+ }
+ /**
+ * Sets private build.
+ * @param value new value
+ * @throws BuildException if specified with refid
+ */
+ public void setPrivatebuild(String value) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ privateBuild = value;
+ }
+ /**
+ * Sets prerelease.
+ * @param value new value
+ * @throws BuildException if specified with refid
+ */
+ public void setPrerelease(boolean value) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (value) {
+ prerelease = Boolean.TRUE;
+ } else {
+ prerelease = Boolean.FALSE;
+ }
+ }
+ /**
+ * Sets prerelease.
+ * @param value new value
+ * @throws BuildException if specified with refid
+ */
+ public void setPatched(boolean value) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (value) {
+ patched = Boolean.TRUE;
+ } else {
+ patched = Boolean.FALSE;
+ }
+ }
+ /**
+ * Sets product name.
+ * @param value new value
+ * @throws BuildException if specified with refid
+ */
+ public void setProductname(String value) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ productName= value;
+ }
+ /**
+ * Sets private build.
+ * @param value new value
+ * @throws BuildException if specified with refid
+ */
+ public void setSpecialbuild(String value) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ specialBuild = value;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/WarningLevelEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/WarningLevelEnum.java
new file mode 100644
index 0000000..6ba7438
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/WarningLevelEnum.java
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright 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;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+/**
+ * Enumerated attribute with the values "none", "severe", "default",
+ * "production", "diagnostic", and "aserror".
+ */
+public final class WarningLevelEnum extends EnumeratedAttribute {
+ /**
+ * Constructor.
+ *
+ */
+ public WarningLevelEnum() {
+ setValue("default");
+ }
+ /**
+ * Get allowable values.
+ * @return allowable values
+ */
+ public String[] getValues() {
+ return new String[]{"none", "severe", "default", "production",
+ "diagnostic", "aserror"};
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/apple/PropertyListSerialization.java b/src/main/java/net/sf/antcontrib/cpptasks/apple/PropertyListSerialization.java
new file mode 100644
index 0000000..c3a6807
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/apple/PropertyListSerialization.java
@@ -0,0 +1,235 @@
+/*
+ * Licensed to the Ant-Contrib Project under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The Ant-Contrib licenses this file to You 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.apple;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.io.File;
+import java.io.IOException;
+import java.io.FileOutputStream;
+
+/**
+ * Static class that provides methods to serialize
+ * a Map to a Cocoa XML Property List. Does not currently support
+ * date or data elements.
+ */
+public final class PropertyListSerialization {
+ /**
+ * Private constructor.
+ */
+ private PropertyListSerialization() {
+
+ }
+
+ /**
+ * Serializes a property list into a Cocoa XML Property List document.
+ * @param propertyList property list.
+ * @param file destination.
+ * @param comments comments to insert into document.
+ * @throws SAXException if exception during serialization.
+ * @throws TransformerConfigurationException if exception creating serializer.
+ */
+ public static void serialize(final Map propertyList,
+ final List comments,
+ final File file)
+ throws IOException, SAXException,
+ TransformerConfigurationException {
+ SAXTransformerFactory sf = (SAXTransformerFactory)
+ SAXTransformerFactory.newInstance();
+ TransformerHandler handler = sf.newTransformerHandler();
+
+ FileOutputStream os = new FileOutputStream(file);
+ StreamResult result = new StreamResult(os);
+ handler.setResult(result);
+
+ handler.startDocument();
+ for(Iterator iter = comments.iterator(); iter.hasNext();) {
+ char[] comment = String.valueOf(iter.next()).toCharArray();
+ handler.comment(comment, 0, comment.length);
+ }
+ AttributesImpl attributes = new AttributesImpl();
+ handler.startElement(null, "plist", "plist", attributes);
+ serializeMap(propertyList, handler);
+ handler.endElement(null, "plist", "plist");
+
+ handler.endDocument();
+ }
+
+ /**
+ * Serialize a map as a dict element.
+ * @param map map to serialize.
+ * @param handler destination of serialization events.
+ * @throws SAXException if exception during serialization.
+ */
+ private static void serializeMap(final Map map,
+ final ContentHandler handler)
+ throws SAXException {
+ AttributesImpl attributes = new AttributesImpl();
+ handler.startElement(null, "dict", "dict", attributes);
+
+ if (map.size() > 0) {
+ //
+ // need to output with sorted keys to maintain
+ // reproducability
+ //
+ Object[] keys = map.keySet().toArray();
+ Arrays.sort(keys);
+ for(int i = 0; i < keys.length; i++) {
+ String key = String.valueOf(keys[i]);
+ handler.startElement(null, "key", "key", attributes);
+ handler.characters(key.toCharArray(), 0, key.length());
+ handler.endElement(null, "key", "key");
+ serializeObject(map.get(keys[i]), handler);
+ }
+ }
+ handler.endElement(null, "dict", "dict");
+ }
+
+ /**
+ * Serialize a list as an array element.
+ * @param list list to serialize.
+ * @param handler destination of serialization events.
+ * @throws SAXException if exception during serialization.
+ */
+ private static void serializeList(final List list,
+ final ContentHandler handler)
+ throws SAXException {
+ AttributesImpl attributes = new AttributesImpl();
+ handler.startElement(null, "array", "array", attributes);
+ for(Iterator iter = list.iterator();iter.hasNext();) {
+ serializeObject(iter.next(), handler);
+ }
+ handler.endElement(null, "array", "array");
+ }
+
+ /**
+ * Creates an element with the specified tag name and character content.
+ * @param tag tag name.
+ * @param content character content.
+ * @param handler destination of serialization events.
+ * @throws SAXException if exception during serialization.
+ */
+ private static void serializeElement(final String tag,
+ final String content,
+ final ContentHandler handler)
+ throws SAXException {
+ AttributesImpl attributes = new AttributesImpl();
+ handler.startElement(null, tag, tag, attributes);
+ handler.characters(content.toCharArray(), 0, content.length());
+ handler.endElement(null, tag, tag);
+ }
+
+
+ /**
+ * Serialize a Number as an integer element.
+ * @param integer number to serialize.
+ * @param handler destination of serialization events.
+ * @throws SAXException if exception during serialization.
+ */
+ private static void serializeInteger(final Number integer,
+ final ContentHandler handler)
+ throws SAXException {
+ serializeElement("integer", String.valueOf(integer.longValue()),
+ handler);
+ }
+
+ /**
+ * Serialize a Number as a real element.
+ * @param real number to serialize.
+ * @param handler destination of serialization events.
+ * @throws SAXException if exception during serialization.
+ */
+ private static void serializeReal(final Number real,
+ final ContentHandler handler)
+ throws SAXException {
+ serializeElement("real",
+ String.valueOf(real.doubleValue()),
+ handler);
+ }
+
+
+ /**
+ * Serialize a Boolean as a true or false element.
+ * @param val boolean to serialize.
+ * @param handler destination of serialization events.
+ * @throws SAXException if exception during serialization.
+ */
+ private static void serializeBoolean(final Boolean val,
+ final ContentHandler handler)
+ throws SAXException {
+ String tag = "false";
+ if (val.booleanValue()) {
+ tag = "true";
+ }
+ AttributesImpl attributes = new AttributesImpl();
+ handler.startElement(null, tag, tag, attributes);
+ handler.endElement(null, tag, tag);
+ }
+
+ /**
+ * Serialize a string as a string element.
+ * @param val string to serialize.
+ * @param handler destination of serialization events.
+ * @throws SAXException if exception during serialization.
+ */
+ private static void serializeString(final String val,
+ final ContentHandler handler)
+ throws SAXException {
+ serializeElement("string",
+ val,
+ handler);
+ }
+
+
+ /**
+ * Serialize an object using the best available element.
+ * @param obj object to serialize.
+ * @param handler destination of serialization events.
+ * @throws SAXException if exception during serialization.
+ */
+ private static void serializeObject(final Object obj,
+ final ContentHandler handler)
+ throws SAXException {
+ if (obj instanceof Map) {
+ serializeMap((Map) obj, handler);
+ } else if (obj instanceof List) {
+ serializeList((List) obj, handler);
+ } else if (obj instanceof Number) {
+ if(obj instanceof Double
+ ||obj instanceof Float) {
+ serializeReal((Number) obj, handler);
+ } else {
+ serializeInteger((Number) obj, handler);
+ }
+ } else if (obj instanceof Boolean) {
+ serializeBoolean((Boolean) obj, handler);
+ } else {
+ serializeString(String.valueOf(obj), handler);
+ }
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/apple/XcodeProjectWriter.java b/src/main/java/net/sf/antcontrib/cpptasks/apple/XcodeProjectWriter.java
new file mode 100644
index 0000000..f901b4d
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/apple/XcodeProjectWriter.java
@@ -0,0 +1,1016 @@
+/*
+ *
+ * Copyright 2004-2005 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.apple;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.TargetInfo;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;
+import net.sf.antcontrib.cpptasks.gcc.GccCCompiler;
+import net.sf.antcontrib.cpptasks.ide.DependencyDef;
+import net.sf.antcontrib.cpptasks.ide.ProjectDef;
+import net.sf.antcontrib.cpptasks.ide.ProjectWriter;
+import org.apache.tools.ant.BuildException;
+import org.xml.sax.SAXException;
+
+import javax.xml.transform.TransformerConfigurationException;
+import java.io.File;
+import java.io.IOException;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+
+/**
+ * Writes a Apple Xcode 2.1+ project directory. XCode stores project
+ * configuration as a PropertyList. Though it will always write the project
+ * as a Cocoa Old-Style ASCII property list, it will read projects
+ * stored using Cocoa's XML Property List format.
+ */
+public final class XcodeProjectWriter
+ implements ProjectWriter {
+
+ /**
+ * Constructor.
+ */
+ public XcodeProjectWriter() {
+ }
+
+ /**
+ * Writes a project definition file.
+ *
+ * @param fileName File name base, writer may append appropriate extension
+ * @param task cc task for which to write project
+ * @param projectDef project element
+ * @param targets compilation targets
+ * @param linkTarget link target
+ * @throws IOException if error writing project file
+ */
+ public void writeProject(final File fileName,
+ final CCTask task,
+ final ProjectDef projectDef,
+ final List sources,
+ final Hashtable targets,
+ final TargetInfo linkTarget) throws IOException {
+
+ File xcodeDir = new File(fileName + ".xcodeproj");
+ if (!projectDef.getOverwrite() && xcodeDir.exists()) {
+ throw new BuildException("Not allowed to overwrite project file "
+ + xcodeDir.toString());
+ }
+
+ CommandLineCompilerConfiguration compilerConfig =
+ getBaseCompilerConfiguration(targets);
+ if (compilerConfig == null) {
+ throw new BuildException(
+ "Unable to find compilation target using GNU C++ compiler");
+ }
+
+
+ CommandLineLinkerConfiguration linkerConfig = null;
+ if (linkTarget.getConfiguration() instanceof CommandLineLinkerConfiguration) {
+ linkerConfig = (CommandLineLinkerConfiguration) linkTarget.getConfiguration();
+ }
+
+ String projectName = projectDef.getName();
+ if (projectName == null) {
+ projectName = fileName.getName();
+ }
+ final String basePath = fileName.getAbsoluteFile().getParent();
+
+ xcodeDir.mkdir();
+
+ File xcodeProj = new File(xcodeDir, "project.pbxproj");
+
+ //
+ // create property list
+ //
+ Map propertyList = new HashMap();
+ propertyList.put("archiveVersion", "1");
+ propertyList.put("classes", new HashMap());
+ propertyList.put("objectVersion", "42");
+ Map objects = new HashMap();
+
+ final String sourceTree = "<source>";
+
+ //
+ // add source files and source group to property list
+ //
+ List sourceGroupChildren =
+ addSources(objects, "SOURCE_ROOT", basePath, targets);
+ PBXObjectRef sourceGroup =
+ createPBXGroup("Source", sourceTree, sourceGroupChildren);
+ objects.put(sourceGroup.getID(), sourceGroup.getProperties());
+
+
+
+
+ //
+ // add product to property list
+ //
+ PBXObjectRef product = addProduct(objects, linkTarget);
+ List productsList = new ArrayList();
+ productsList.add(product);
+ PBXObjectRef productsGroup =
+ createPBXGroup("Products", sourceTree, productsList);
+ objects.put(productsGroup.getID(), productsGroup.getProperties());
+
+ //
+ // add documentation group to property list
+ //
+ PBXObjectRef documentationGroup = addDocumentationGroup(objects, sourceTree);
+
+ //
+ // add main group containing source, products and documentation group
+ //
+ ArrayList groups = new ArrayList(3);
+ groups.add(sourceGroup);
+ groups.add(documentationGroup);
+ groups.add(productsGroup);
+ PBXObjectRef mainGroup = createPBXGroup(projectName, sourceTree, groups);
+ StringBuffer comments = new StringBuffer();
+ for(Iterator iter = projectDef.getComments().iterator(); iter.hasNext();) {
+ comments.append(iter.next());
+ }
+ if (comments.length() > 0) {
+ mainGroup.getProperties().put("comments", comments.toString());
+ }
+ objects.put(mainGroup.getID(), mainGroup.getProperties());
+
+ //
+ // add project configurations
+ //
+ PBXObjectRef compilerConfigurations =
+ addProjectConfigurationList(objects,
+ basePath,
+ projectDef.getDependencies(),
+ compilerConfig,
+ linkerConfig);
+
+ String projectDirPath = "";
+ List projectTargets = new ArrayList();
+
+ //
+ // add project to property list
+ //
+ //
+ // Calculate path (typically several ../..) of the root directory
+ // (where build.xml lives) relative to the XCode project directory.
+ // XCode 3.0 will now prompt user to supply the value if not specified.
+ String projectRoot = CUtil.toUnixPath(
+ CUtil.getRelativePath(basePath, projectDef.getProject().getBaseDir()));
+ PBXObjectRef project = createPBXProject(compilerConfigurations, mainGroup,
+ projectDirPath, projectRoot, projectTargets);
+ objects.put(project.getID(), project.getProperties());
+
+ List frameworkBuildFiles = new ArrayList();
+ for (Iterator iter = projectDef.getDependencies().iterator(); iter.hasNext();) {
+ DependencyDef dependency = (DependencyDef) iter.next();
+ PBXObjectRef buildFile = addDependency(objects, project, groups, basePath, dependency);
+ if (buildFile != null) {
+ frameworkBuildFiles.add(buildFile);
+ }
+ }
+ //
+ // add description of native target (that is the executable or
+ // shared library)
+ //
+ PBXObjectRef nativeTarget =
+ addNativeTarget(objects, linkTarget, product,
+ projectName, sourceGroupChildren, frameworkBuildFiles);
+ projectTargets.add(nativeTarget);
+
+
+
+
+
+ //
+ // finish up overall property list
+ //
+ propertyList.put("objects", objects);
+ propertyList.put("rootObject", project.getID());
+
+
+ //
+ // write property list out to XML file
+ //
+ try {
+ PropertyListSerialization.serialize(propertyList,
+ projectDef.getComments(), xcodeProj);
+ } catch (TransformerConfigurationException ex) {
+ throw new IOException(ex.toString());
+ } catch (SAXException ex) {
+ if (ex.getException() instanceof IOException) {
+ throw (IOException) ex.getException();
+ }
+ throw new IOException(ex.toString());
+ }
+ }
+
+
+ /**
+ * Adds a dependency to the object graph.
+ * @param objects
+ * @param project
+ * @param mainGroupChildren
+ * @param baseDir
+ * @param dependency
+ * @return PBXBuildFile to add to PBXFrameworksBuildPhase.
+ */
+ private PBXObjectRef addDependency(final Map objects,
+ final PBXObjectRef project,
+ final List mainGroupChildren,
+ final String baseDir,
+ final DependencyDef dependency) {
+ if (dependency.getFile() != null) {
+ File xcodeDir = new File(dependency.getFile().getAbsolutePath() + ".xcodeproj");
+ if (xcodeDir.exists()) {
+ PBXObjectRef xcodePrj = createPBXFileReference("SOURCE_ROOT", baseDir, xcodeDir);
+ mainGroupChildren.add(xcodePrj);
+ objects.put(xcodePrj.getID(), xcodePrj.getProperties());
+
+ int proxyType = 2;
+ PBXObjectRef proxy = createPBXContainerItemProxy(
+ xcodePrj, proxyType, dependency.getName());
+ objects.put(proxy.getID(), proxy.getProperties());
+
+ PBXObjectRef referenceProxy = createPBXReferenceProxy(proxy, dependency);
+ objects.put(referenceProxy.getID(), referenceProxy.getProperties());
+
+ PBXObjectRef buildFile = createPBXBuildFile(referenceProxy, Collections.EMPTY_MAP);
+ objects.put(buildFile.getID(), buildFile.getProperties());
+
+ List productsChildren = new ArrayList();
+ productsChildren.add(referenceProxy);
+ PBXObjectRef products = createPBXGroup("Products", "<group>", productsChildren);
+ objects.put(products.getID(), products.getProperties());
+
+ Map projectReference = new HashMap();
+ projectReference.put("ProductGroup", products);
+ projectReference.put("ProjectRef", xcodePrj);
+
+ List projectReferences = (List) project.getProperties().get("ProjectReferences");
+ if (projectReferences == null) {
+ projectReferences = new ArrayList();
+ project.getProperties().put("ProjectReferences", projectReferences);
+ }
+ projectReferences.add(projectReference);
+ return buildFile;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Add documentation group to map of objects.
+ * @param objects object map.
+ * @param sourceTree source tree description.
+ * @return documentation group.
+ */
+ private PBXObjectRef addDocumentationGroup(final Map objects,
+ final String sourceTree) {
+ List productsList = new ArrayList();
+ PBXObjectRef products =
+ createPBXGroup("Documentation", sourceTree, productsList);
+ objects.put(products.getID(), products.getProperties());
+ return products;
+ }
+
+ /**
+ * Add file reference of product to map of objects.
+ * @param objects object map.
+ * @param linkTarget build description for executable or shared library.
+ * @return file reference to generated executable or shared library.
+ */
+ private PBXObjectRef addProduct(final Map objects,
+ final TargetInfo linkTarget) {
+
+ //
+ // create file reference for executable file
+ // forget Ant's location, just place in XCode's default location
+ PBXObjectRef executable = createPBXFileReference("BUILD_PRODUCTS_DIR",
+ linkTarget.getOutput().getParent(),
+ linkTarget.getOutput());
+ Map executableProperties = executable.getProperties();
+
+ String fileType = getFileType(linkTarget);
+ executableProperties.put("explicitFileType", fileType);
+ executableProperties.put("includeInIndex", "0");
+ objects.put(executable.getID(), executableProperties);
+
+ return executable;
+ }
+
+
+ /**
+ * Add file references for all source files to map of objects.
+ * @param objects map of objects.
+ * @param sourceTree source tree.
+ * @param basePath parent of XCode project dir
+ * @param targets build targets.
+ * @return list containing file references of source files.
+ */
+ private List addSources(final Map objects,
+ final String sourceTree,
+ final String basePath,
+ final Hashtable targets) {
+ List sourceGroupChildren = new ArrayList();
+
+ ArrayList sourceList = new ArrayList(targets.size());
+ Iterator targetIter = targets.values().iterator();
+ while (targetIter.hasNext()) {
+ TargetInfo info = (TargetInfo) targetIter.next();
+ File[] targetsources = info.getSources();
+ for (int i = 0; i < targetsources.length; i++) {
+ sourceList.add(targetsources[i]);
+ }
+ }
+ Object[] sortedSources = sourceList.toArray();
+ Arrays.sort(sortedSources, new Comparator() {
+ public int compare(final Object o1, final Object o2) {
+ return (((File) o1).getName().compareTo(
+ ((File) o2).getName()));
+ }
+ });
+ for (int i = 0; i < sortedSources.length; i++) {
+ PBXObjectRef fileRef = createPBXFileReference(sourceTree,
+ basePath, (File) sortedSources[i]);
+ sourceGroupChildren.add(fileRef);
+ objects.put(fileRef.getID(), fileRef.getProperties());
+ }
+
+ return sourceGroupChildren;
+ }
+
+ /**
+ * Add native target configuration list.
+ * @param objects map of objects.
+ * @param projectName project name.
+ * @return build configurations for native target.
+ */
+ private PBXObjectRef addNativeTargetConfigurationList(final Map objects,
+ final String projectName) {
+
+ //
+ // Create a configuration list with
+ // two stock configurations: Debug and Release
+ //
+ List configurations = new ArrayList();
+ Map debugSettings = new HashMap();
+ debugSettings.put("COPY_PHASE_STRIP", "NO");
+ debugSettings.put("GCC_DYNAMIC_NO_PIC", "NO");
+ debugSettings.put("GCC_ENABLE_FIX_AND_CONTINUE", "YES");
+ debugSettings.put("GCC_MODEL_TUNING", "G5");
+ debugSettings.put("GCC_OPTIMIZATION_LEVEL", "0");
+ debugSettings.put("INSTALL_PATH", "$(HOME)/bin");
+ debugSettings.put("PRODUCT_NAME", projectName);
+ debugSettings.put("ZERO_LINK", "YES");
+ PBXObjectRef debugConfig = createXCBuildConfiguration("Debug",
+ debugSettings);
+ objects.put(debugConfig.getID(), debugConfig.getProperties());
+ configurations.add(debugConfig);
+
+ Map releaseSettings = new HashMap();
+ List archs = new ArrayList();
+ archs.add("ppc");
+ archs.add("i386");
+ releaseSettings.put("ARCHS", archs);
+ releaseSettings.put("GCC_GENERATE_DEBUGGING_SYMBOLS", "NO");
+ releaseSettings.put("GCC_MODEL_TUNING", "G5");
+ releaseSettings.put("INSTALL_PATH", "$(HOME)/bin");
+ releaseSettings.put("PRODUCT_NAME", projectName);
+ PBXObjectRef releaseConfig = createXCBuildConfiguration("Release",
+ releaseSettings);
+ objects.put(releaseConfig.getID(), releaseConfig.getProperties());
+ configurations.add(releaseConfig);
+
+ PBXObjectRef configurationList = createXCConfigurationList(configurations);
+ objects.put(configurationList.getID(), configurationList.getProperties());
+ return configurationList;
+ }
+
+
+
+ /**
+ * Add project configuration list.
+ * @param objects map of objects.
+ * @param baseDir base directory.
+ * @param compilerConfig compiler configuration.
+ * @return project configuration object.
+ */
+ private PBXObjectRef addProjectConfigurationList(final Map objects,
+ final String baseDir,
+ final List dependencies,
+ final CommandLineCompilerConfiguration compilerConfig,
+ final CommandLineLinkerConfiguration linkerConfig) {
+ //
+ // Create a configuration list with
+ // two stock configurations: Debug and Release
+ //
+ List configurations = new ArrayList();
+ Map debugSettings = new HashMap();
+ debugSettings.put("GCC_WARN_ABOUT_RETURN_TYPE", "YES");
+ debugSettings.put("GCC_WARN_UNUSED_VARIABLE", "YES");
+ debugSettings.put("PREBINDING", "NO");
+ debugSettings.put("SDKROOT", "/Developer/SDKs/MacOSX10.4u.sdk");
+
+
+ PBXObjectRef debugConfig = createXCBuildConfiguration("Debug", debugSettings);
+ objects.put(debugConfig.getID(), debugConfig.getProperties());
+ configurations.add(debugConfig);
+
+ Map releaseSettings = new HashMap();
+ releaseSettings.put("GCC_WARN_ABOUT_RETURN_TYPE", "YES");
+ releaseSettings.put("GCC_WARN_UNUSED_VARIABLE", "YES");
+ releaseSettings.put("PREBINDING", "NO");
+ releaseSettings.put("SDKROOT", "/Developer/SDKs/MacOSX10.4u.sdk");
+ PBXObjectRef releaseConfig =
+ createXCBuildConfiguration("Release", releaseSettings);
+ objects.put(releaseConfig.getID(), releaseConfig.getProperties());
+ configurations.add(releaseConfig);
+ PBXObjectRef configurationList = createXCConfigurationList(configurations);
+ Map projectConfigurationListProperties = configurationList.getProperties();
+ projectConfigurationListProperties.put("defaultConfigurationIsVisible", "0");
+ projectConfigurationListProperties.put("defaultConfigurationName", "Debug");
+ objects.put(configurationList.getID(), configurationList.getProperties());
+
+ //
+ // add include paths to both configurations
+ //
+ File[] includeDirs = compilerConfig.getIncludePath();
+ if (includeDirs.length > 0) {
+ ArrayList includePaths = new ArrayList();
+ Map includePathMap = new HashMap();
+ for (int i = 0; i < includeDirs.length; i++) {
+ if(!CUtil.isSystemPath(includeDirs[i])) {
+ String absPath = includeDirs[i].getAbsolutePath();
+ if (!includePathMap.containsKey(absPath)) {
+ if(absPath.startsWith("/usr/")) {
+ includePaths.add(CUtil.toUnixPath(absPath));
+ } else {
+ String relPath = CUtil.toUnixPath(
+ CUtil.getRelativePath(baseDir, includeDirs[i]));
+ includePaths.add(relPath);
+ }
+ includePathMap.put(absPath, absPath);
+ }
+ }
+ }
+ includePaths.add("${inherited)");
+ debugSettings.put("HEADER_SEARCH_PATHS", includePaths);
+ releaseSettings.put("HEADER_SEARCH_PATHS", includePaths);
+ }
+
+ //
+ // add preprocessor definitions to both configurations
+ //
+ //
+ String[] preArgs = compilerConfig.getPreArguments();
+ List defines = new ArrayList();
+ for (int i = 0; i < preArgs.length; i++) {
+ if (preArgs[i].startsWith("-D")) {
+ defines.add(preArgs[i].substring(2));
+ }
+ }
+ if (defines.size() > 0) {
+ defines.add("$(inherited)");
+ debugSettings.put("GCC_PREPROCESSOR_DEFINITIONS", defines);
+ releaseSettings.put("GCC_PREPROCESSOR_DEFINITIONS", defines);
+ }
+
+
+ if (linkerConfig != null) {
+ Map librarySearchMap = new HashMap();
+ List librarySearchPaths = new ArrayList();
+ List otherLdFlags = new ArrayList();
+ String[] linkerArgs = linkerConfig.getEndArguments();
+ for (int i = 0; i < linkerArgs.length; i++) {
+ if (linkerArgs[i].startsWith("-L")) {
+ String libDir = linkerArgs[i].substring(2);
+ if (!librarySearchMap.containsKey(libDir)) {
+ if (!libDir.equals("/usr/lib")) {
+ librarySearchPaths.add(
+ CUtil.toUnixPath(CUtil.getRelativePath(baseDir,
+ new File(libDir))));
+ }
+ librarySearchMap.put(libDir, libDir);
+
+ }
+ } else if (linkerArgs[i].startsWith("-l")) {
+ //
+ // check if library is in dependencies list
+ //
+ String libName = linkerArgs[i].substring(2);
+ boolean found = false;
+ for(Iterator iter = dependencies.iterator();iter.hasNext();) {
+ DependencyDef dependency = (DependencyDef) iter.next();
+ if (libName.startsWith(dependency.getName())) {
+ File dependencyFile = dependency.getFile();
+ if (dependencyFile != null &&
+ new File(dependencyFile.getAbsolutePath() + ".xcodeproj").exists()) {
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found) {
+ otherLdFlags.add(linkerArgs[i]);
+ }
+ }
+ }
+
+
+ debugSettings.put("LIBRARY_SEARCH_PATHS", librarySearchPaths);
+ debugSettings.put("OTHER_LDFLAGS", otherLdFlags);
+ releaseSettings.put("LIBRARY_SEARCH_PATHS", librarySearchPaths);
+ releaseSettings.put("OTHER_LDFLAGS", otherLdFlags);
+ }
+ return configurationList;
+ }
+
+ /**
+ * Add native target to map of objects.
+ * @param objects map of objects.
+ * @param linkTarget description of executable or shared library.
+ * @param product product.
+ * @param projectName project name.
+ * @param sourceGroupChildren source files needed to build product.
+ * @return native target.
+ */
+ private PBXObjectRef addNativeTarget(final Map objects,
+ final TargetInfo linkTarget,
+ final PBXObjectRef product,
+ final String projectName,
+ final List sourceGroupChildren,
+ final List frameworkBuildFiles) {
+
+ PBXObjectRef buildConfigurations =
+ addNativeTargetConfigurationList(objects, projectName);
+
+ int buildActionMask = 2147483647;
+ List buildPhases = new ArrayList();
+
+ Map settings = new HashMap();
+ settings.put("ATTRIBUTES", new ArrayList());
+ List buildFiles = new ArrayList();
+ for (Iterator iter = sourceGroupChildren.iterator();
+ iter.hasNext();) {
+ PBXObjectRef sourceFile = (PBXObjectRef) iter.next();
+ PBXObjectRef buildFile = createPBXBuildFile(sourceFile, settings);
+ buildFiles.add(buildFile);
+ objects.put(buildFile.getID(), buildFile.getProperties());
+ }
+
+
+ PBXObjectRef sourcesBuildPhase = createPBXSourcesBuildPhase(buildActionMask,
+ buildFiles, false);
+ objects.put(sourcesBuildPhase.getID(), sourcesBuildPhase.getProperties());
+ buildPhases.add(sourcesBuildPhase);
+
+
+ buildActionMask = 8;
+ PBXObjectRef frameworksBuildPhase =
+ createPBXFrameworksBuildPhase(buildActionMask,
+ frameworkBuildFiles, false);
+ objects.put(frameworksBuildPhase.getID(), frameworksBuildPhase.getProperties());
+ buildPhases.add(frameworksBuildPhase);
+
+ PBXObjectRef copyFilesBuildPhase = createPBXCopyFilesBuildPhase(8,
+ "/usr/share/man/man1", "0", new ArrayList(), true);
+ objects.put(copyFilesBuildPhase.getID(), copyFilesBuildPhase.getProperties());
+ buildPhases.add(copyFilesBuildPhase);
+
+ List buildRules = new ArrayList();
+
+ List dependencies = new ArrayList();
+
+ String productInstallPath = "$(HOME)/bin";
+
+ String productType = getProductType(linkTarget);
+
+ PBXObjectRef nativeTarget = createPBXNativeTarget(projectName,
+ buildConfigurations, buildPhases, buildRules, dependencies,
+ productInstallPath, projectName, product, productType);
+ objects.put(nativeTarget.getID(), nativeTarget.getProperties());
+
+ return nativeTarget;
+ }
+
+ private int getProductTypeIndex(final TargetInfo linkTarget) {
+ String outPath = linkTarget.getOutput().getPath();
+ String outExtension = null;
+ int lastDot = outPath.lastIndexOf('.');
+ if (lastDot != -1) {
+ outExtension = outPath.substring(lastDot);
+ }
+ if (".a".equalsIgnoreCase(outExtension) || ".lib".equalsIgnoreCase(outExtension)) {
+ return 1;
+ } else if (".dylib".equalsIgnoreCase(outExtension) ||
+ ".so".equalsIgnoreCase(outExtension) ||
+ ".dll".equalsIgnoreCase(outExtension)) {
+ return 2;
+ }
+ return 0;
+ }
+
+ private String getProductType(final TargetInfo linkTarget) {
+ switch(getProductTypeIndex(linkTarget)) {
+ case 1:
+ return "com.apple.product-type.library.static";
+ case 2:
+ return "com.apple.product-type.library.dynamic";
+ default:
+ return "com.apple.product-type.tool";
+ }
+ }
+
+ private String getFileType(final TargetInfo linkTarget) {
+ switch(getProductTypeIndex(linkTarget)) {
+ case 1:
+ return "archive.ar";
+ case 2:
+ return "compiled.mach-o.dylib";
+ default:
+ return "compiled.mach-o.executable";
+ }
+ }
+
+
+ /**
+ * Create PBXFileReference.
+ * @param sourceTree source tree.
+ * @param baseDir base directory.
+ * @param file file.
+ * @return PBXFileReference object.
+ */
+ private static PBXObjectRef createPBXFileReference(final String sourceTree,
+ final String baseDir,
+ final File file) {
+ Map map = new HashMap();
+ map.put("isa", "PBXFileReference");
+
+ String relPath = CUtil.toUnixPath(CUtil.getRelativePath(baseDir, file));
+ map.put("path", relPath);
+ map.put("name", file.getName());
+ map.put("sourceTree", sourceTree);
+ return new PBXObjectRef(map);
+ }
+
+ /**
+ * Create PBXGroup.
+ * @param name group name.
+ * @param sourceTree source tree.
+ * @param children list of PBXFileReferences.
+ * @return group.
+ */
+ private static PBXObjectRef createPBXGroup(final String name,
+ final String sourceTree,
+ final List children) {
+ Map map = new HashMap();
+ map.put("isa", "PBXGroup");
+ map.put("name", name);
+ map.put("sourceTree", sourceTree);
+ map.put("children", children);
+ return new PBXObjectRef(map);
+ }
+
+ /**
+ * Create PBXProject.
+ * @param buildConfigurationList build configuration list.
+ * @param mainGroup main group.
+ * @param projectDirPath project directory path.
+ * @param targets targets.
+ * @param projectRoot projectRoot directory relative to
+ * @return project.
+ */
+ private static PBXObjectRef createPBXProject(final PBXObjectRef buildConfigurationList,
+ final PBXObjectRef mainGroup,
+ final String projectDirPath,
+ final String projectRoot,
+ final List targets) {
+ Map map = new HashMap();
+ map.put("isa", "PBXProject");
+ map.put("buildConfigurationList", buildConfigurationList.getID());
+ map.put("hasScannedForEncodings", "0");
+ map.put("mainGroup", mainGroup.getID());
+ map.put("projectDirPath", projectDirPath);
+ map.put("targets", targets);
+ map.put("projectRoot", projectRoot);
+ return new PBXObjectRef(map);
+ }
+
+ /**
+ * Create XCConfigurationList.
+ * @param buildConfigurations build configurations.
+ * @return configuration list.
+ */
+ private static PBXObjectRef createXCConfigurationList(final List buildConfigurations) {
+ Map map = new HashMap();
+ map.put("isa", "XCConfigurationList");
+ map.put("buildConfigurations", buildConfigurations);
+ return new PBXObjectRef(map);
+ }
+
+
+ /**
+ * Create XCBuildConfiguration.
+ * @param name name.
+ * @param buildSettings build settings.
+ * @return build configuration.
+ */
+ private static PBXObjectRef createXCBuildConfiguration(final String name,
+ final Map buildSettings) {
+ Map map = new HashMap();
+ map.put("isa", "XCBuildConfiguration");
+ map.put("buildSettings", buildSettings);
+ map.put("name", name);
+ return new PBXObjectRef(map);
+ }
+
+ /**
+ * Create PBXNativeTarget.
+ * @param name name.
+ * @param buildConfigurationList build configuration list.
+ * @param buildPhases build phases.
+ * @param buildRules build rules.
+ * @param dependencies dependencies.
+ * @param productInstallPath product install path.
+ * @param productName product name.
+ * @param productReference file reference for product.
+ * @param productType product type.
+ * @return native target.
+ */
+ private static PBXObjectRef createPBXNativeTarget(final String name,
+ final PBXObjectRef buildConfigurationList,
+ final List buildPhases,
+ final List buildRules,
+ final List dependencies,
+ final String productInstallPath,
+ final String productName,
+ final PBXObjectRef productReference,
+ final String productType) {
+ Map map = new HashMap();
+ map.put("isa", "PBXNativeTarget");
+ map.put("buildConfigurationList", buildConfigurationList);
+ map.put("buildPhases", buildPhases);
+ map.put("buildRules", buildRules);
+ map.put("dependencies", dependencies);
+ map.put("name", name);
+ map.put("productInstallPath", productInstallPath);
+ map.put("productName", productName);
+ map.put("productReference", productReference);
+ map.put("productType", productType);
+ return new PBXObjectRef(map);
+ }
+
+ /**
+ * Create PBXSourcesBuildPhase.
+ * @param buildActionMask build action mask.
+ * @param files source files.
+ * @param runOnly if true, phase should only be run on deployment.
+ * @return PBXSourcesBuildPhase.
+ */
+ private static PBXObjectRef createPBXSourcesBuildPhase(int buildActionMask,
+ List files,
+ boolean runOnly) {
+ Map map = new HashMap();
+ map.put("buildActionMask",
+ String.valueOf(buildActionMask));
+ map.put("files", files);
+ map.put("isa", "PBXSourcesBuildPhase");
+ map.put("runOnlyForDeploymentPostprocessing", toString(runOnly));
+ return new PBXObjectRef(map);
+ }
+
+ /**
+ * Create PBXBuildFile.
+ * @param fileRef source file.
+ * @param settings build settings.
+ * @return PBXBuildFile.
+ */
+ private static PBXObjectRef createPBXBuildFile(PBXObjectRef fileRef,
+ Map settings) {
+ Map map = new HashMap();
+ map.put("fileRef", fileRef);
+ map.put("isa", "PBXBuildFile");
+ if (settings != null) {
+ map.put("settings", settings);
+ }
+ return new PBXObjectRef(map);
+ }
+
+ /**
+ * Create PBXFrameworksBuildPhase.
+ * @param buildActionMask build action mask.
+ * @param files files.
+ * @param runOnly if true, phase should only be run on deployment.
+ * @return PBXFrameworkBuildPhase.
+ */
+ private static PBXObjectRef createPBXFrameworksBuildPhase(
+ final int buildActionMask,
+ final List files,
+ final boolean runOnly) {
+ Map map = new HashMap();
+ map.put("isa", "PBXFrameworksBuildPhase");
+ map.put("buildActionMask", NumberFormat.getIntegerInstance(Locale.US).format(buildActionMask));
+ map.put("files", files);
+ map.put("runOnlyForDeploymentPostprocessing", toString(runOnly));
+ return new PBXObjectRef(map);
+ }
+
+ /**
+ * Create a build phase that copies files to a destination.
+ * @param buildActionMask build action mask.
+ * @param dstPath destination path.
+ * @param dstSubfolderSpec subfolder spec.
+ * @param files files.
+ * @param runOnly if true, phase should only be run on deployment.
+ * @return PBXCopyFileBuildPhase.
+ */
+ private static PBXObjectRef createPBXCopyFilesBuildPhase(
+ final int buildActionMask,
+ final String dstPath,
+ final String dstSubfolderSpec,
+ final List files,
+ final boolean runOnly) {
+ Map map = new HashMap();
+ map.put("isa", "PBXCopyFilesBuildPhase");
+ map.put("buildActionMask", NumberFormat.getIntegerInstance(Locale.US).format(buildActionMask));
+ map.put("dstPath", dstPath);
+ map.put("dstSubfolderSpec", dstSubfolderSpec);
+ map.put("files", files);
+ map.put("runOnlyForDeploymentPostprocessing", toString(runOnly));
+ return new PBXObjectRef(map);
+ }
+
+
+ /**
+ * Create a proxy for a file in a different project.
+ * @param containerPortal XcodeProject containing file.
+ * @param proxyType proxy type.
+ * @return PBXContainerItemProxy.
+ */
+ private static PBXObjectRef createPBXContainerItemProxy(
+ final PBXObjectRef containerPortal,
+ final int proxyType,
+ final String remoteInfo) {
+ Map map = new HashMap();
+ map.put("isa", "PBXContainerItemProxy");
+ map.put("containerPortal", containerPortal);
+ map.put("proxyType", NumberFormat.getIntegerInstance(Locale.US).format(proxyType));
+ map.put("remoteInfo", remoteInfo);
+ return new PBXObjectRef(map);
+ }
+
+
+ /**
+ * Create a proxy for a file in a different project.
+ * @param remoteRef PBXContainerItemProxy for reference.
+ * @param dependency dependency.
+ * @return PBXContainerItemProxy.
+ */
+ private static PBXObjectRef createPBXReferenceProxy(
+ final PBXObjectRef remoteRef,
+ final DependencyDef dependency) {
+ Map map = new HashMap();
+ map.put("isa", "PBXReferenceProxy");
+ String fileType = "compiled.mach-o.dylib";
+ map.put("fileType", fileType);
+ map.put("remoteRef", remoteRef);
+ map.put("path", dependency.getFile().getName() + ".dylib");
+ map.put("sourceTree", "BUILT_PRODUCTS_DIR");
+ return new PBXObjectRef(map);
+ }
+
+ /**
+ * Method returns "1" for true, "0" for false.
+ * @param b boolean value.
+ * @return "1" for true, "0" for false.
+ */
+ private static String toString(boolean b) {
+ if (b) {
+ return "1";
+ } else {
+ return "0";
+ }
+ }
+
+ /**
+ * Represents a property map with an 96 bit identity.
+ * When placed in a property list, this object will
+ * output the string representation of the identity
+ * which XCode uses to find the corresponding property
+ * bag in the "objects" property of the top-level property list.
+ */
+ private static final class PBXObjectRef {
+ /**
+ * Identifier.
+ */
+ private final String id;
+ /**
+ * Properties.
+ */
+ private final Map properties;
+ /**
+ * Next available identifier.
+ */
+ private static int nextID = 0;
+
+ /**
+ * Create reference.
+ * @param props properties.
+ */
+ public PBXObjectRef(final Map props) {
+ if (props == null) {
+ throw new NullPointerException("props");
+ }
+ StringBuffer buf = new StringBuffer("000000000000000000000000");
+ String idStr = Integer.toHexString(nextID++);
+ buf.replace(buf.length() - idStr.length(), buf.length(), idStr);
+ id = buf.toString();
+ properties = props;
+ }
+
+ /**
+ * Get object identifier.
+ * @return identifier.
+ */
+ public String toString() {
+ return id;
+ }
+
+ /**
+ * Get object identifier.
+ * @return object identifier.
+ */
+ public String getID() {
+ return id;
+ }
+
+ /**
+ * Get properties.
+ * @return properties.
+ */
+ public Map getProperties() {
+ return properties;
+ }
+ }
+
+ /**
+ * Gets the first recognized compiler from the
+ * compilation targets.
+ *
+ * @param targets compilation targets
+ * @return representative (hopefully) compiler configuration
+ */
+ private CommandLineCompilerConfiguration
+ getBaseCompilerConfiguration(Hashtable targets) {
+ //
+ // find first target with an GNU C++ compilation
+ //
+ CommandLineCompilerConfiguration compilerConfig;
+ //
+ // get the first target and assume that it is representative
+ //
+ Iterator targetIter = targets.values().iterator();
+ while (targetIter.hasNext()) {
+ TargetInfo targetInfo = (TargetInfo) targetIter.next();
+ ProcessorConfiguration config = targetInfo.getConfiguration();
+ //
+ // for the first cl compiler
+ //
+ if (config instanceof CommandLineCompilerConfiguration) {
+ compilerConfig = (CommandLineCompilerConfiguration) config;
+ if (compilerConfig.getCompiler() instanceof GccCCompiler) {
+ return compilerConfig;
+ }
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/apple/package.html b/src/main/java/net/sf/antcontrib/cpptasks/apple/package.html
new file mode 100644
index 0000000..43a2ac3
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/apple/package.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+Copyright 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.
+
+-->
+</head>
+<body bgcolor="white">
+
+Project writer for Apple Xcode
+</body>
+</html>
+
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSCCompiler.java
new file mode 100644
index 0000000..11004ad
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSCCompiler.java
@@ -0,0 +1,210 @@
+/*
+ *
+ * Copyright 2003-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.arm;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for the ARM C Compilers
+ *
+ * See Doc No: ARM DUI 0151A, Issued: Nov 2001 at
+ * http://www.arm.com/arm/User_Guides?OpenDocument
+ *
+ * @author Curt Arnold
+ *
+ */
+public class ADSCCompiler extends CommandLineCCompiler {
+ /**
+ * Header file extensions
+ */
+ private static final String[] headerExtensions = new String[]{".h", ".hpp",
+ ".inl"};
+ /**
+ * Source file extensions
+ */
+ private static final String[] sourceExtensions = new String[]{".c", ".cc",
+ ".cpp", ".cxx", ".c++"};
+ /**
+ * Singleton for ARM 32-bit C compiler
+ */
+ private static final ADSCCompiler armcc = new ADSCCompiler("armcc", false,
+ null);
+ /**
+ * Singleton for ARM 32-bit C++ compiler
+ */
+ private static final ADSCCompiler armcpp = new ADSCCompiler("armcpp",
+ false, null);
+ /**
+ * Singleton for ARM 16-bit C compiler
+ */
+ private static final ADSCCompiler tcc = new ADSCCompiler("tcc", false, null);
+ /**
+ * Singleton for ARM 16-bit C++ compiler
+ */
+ private static final ADSCCompiler tcpp = new ADSCCompiler("tcpp", false,
+ null);
+ /**
+ * Singleton for ARM 32-bit C compiler
+ */
+ public static ADSCCompiler getArmCC() {
+ return armcc;
+ }
+ /**
+ * Singleton for ARM 32-bit C++ compiler
+ */
+ public static ADSCCompiler getArmCpp() {
+ return armcpp;
+ }
+ /**
+ * Singleton for ARM 16-bit C compiler
+ */
+ public static ADSCCompiler getThumbCC() {
+ return tcc;
+ }
+ /**
+ * Singleton for ARM 16-bit C++ compiler
+ */
+ public static ADSCCompiler getThumbCpp() {
+ return tcpp;
+ }
+ private static void quoteFile(StringBuffer buf, String outPath) {
+ if (outPath.indexOf(' ') >= 0) {
+ buf.append('\"');
+ buf.append(outPath);
+ buf.append('\"');
+ } else {
+ buf.append(outPath);
+ }
+ }
+ /**
+ * Private constructor
+ *
+ * @param command
+ * executable name
+ * @param newEnvironment
+ * Change environment
+ * @param env
+ * New environment
+ */
+ private ADSCCompiler(String command, boolean newEnvironment, Environment env) {
+ super(command, "-vsn", sourceExtensions, headerExtensions, ".o", false,
+ null, newEnvironment, env);
+ }
+ /**
+ * {@inheritDoc}
+ */
+ protected void addImpliedArgs(Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ if (debug) {
+ args.addElement("-g");
+ }
+ //
+ // didn't see anything about producing
+ // anything other than executables in the docs
+ if (linkType.isExecutable()) {
+ } else if (linkType.isSharedLibrary()) {
+ }
+ }
+ /**
+ * Adds flags that customize the warnings reported
+ *
+ * Compiler does not appear to have warning levels but ability to turn off
+ * specific errors by explicit switches, could fabricate levels by
+ * prioritizing errors.
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#addWarningSwitch(java.util.Vector,
+ * int)
+ */
+ protected void addWarningSwitch(Vector args, int warnings) {
+ }
+ /**
+ * Add command line options for preprocessor macro
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getDefineSwitch(java.lang.StringBuffer,
+ * java.lang.String, java.lang.String)
+ */
+ protected void getDefineSwitch(StringBuffer buffer, String define,
+ String value) {
+ buffer.append("-D");
+ buffer.append(define);
+ if (value != null) {
+ buffer.append('=');
+ buffer.append(value);
+ }
+ }
+ /**
+ * ARMINC environment variable contains the default include path
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getEnvironmentIncludePath()
+ */
+ protected File[] getEnvironmentIncludePath() {
+ return CUtil.getPathFromEnvironment("ARMINC", ";");
+ }
+ /**
+ * Returns command line option to specify include directory
+ *
+ */
+ protected String getIncludeDirSwitch(String source) {
+ StringBuffer buf = new StringBuffer("-I");
+ quoteFile(buf, source);
+ return buf.toString();
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType)
+ */
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return ADSLibrarian.getInstance();
+ }
+ if (type.isSharedLibrary()) {
+ return ADSLinker.getDllInstance();
+ }
+ return ADSLinker.getInstance();
+ }
+ /**
+ * Maximum command line length
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getMaximumCommandLength()
+ */
+ public int getMaximumCommandLength() {
+ return 1000;
+ }
+ /*
+ * Adds command to undefine preprocessor macro
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getUndefineSwitch(java.lang.StringBuffer,
+ * java.lang.String)
+ */
+ protected void getUndefineSwitch(StringBuffer buffer, String define) {
+ buffer.append("-U");
+ buffer.append(define);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSLibrarian.java
new file mode 100644
index 0000000..65c430f
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSLibrarian.java
@@ -0,0 +1,159 @@
+/*
+ *
+ * Copyright 2003-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.arm;
+
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+
+/**
+ * Adapter for ARM Librarian
+ *
+ * @author Curt Arnold
+ */
+public class ADSLibrarian extends CommandLineLinker {
+
+ private static final ADSLibrarian instance = new ADSLibrarian();
+
+ public static ADSLibrarian getInstance() {
+ return instance;
+ }
+
+ private ADSLibrarian()
+ {
+ super("armar",null,
+ new String[] { ".o" }, new String[0], ".lib", false, null);
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addBase(long, java.util.Vector)
+ */
+ protected void addBase(long base, Vector args) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addFixed(java.lang.Boolean, java.util.Vector)
+ */
+ protected void addFixed(Boolean fixed, Vector args) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addImpliedArgs(boolean, net.sf.antcontrib.cpptasks.compiler.LinkType, java.util.Vector)
+ */
+ protected void addImpliedArgs(
+ boolean debug,
+ LinkType linkType,
+ Vector args) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addIncremental(boolean, java.util.Vector)
+ */
+ protected void addIncremental(boolean incremental, Vector args) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addMap(boolean, java.util.Vector)
+ */
+ protected void addMap(boolean map, Vector args) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addStack(int, java.util.Vector)
+ */
+ protected void addStack(int stack, Vector args) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)
+ */
+ protected void addEntry(String entry, Vector args) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getCommandFileSwitch(java.lang.String)
+ */
+ protected String getCommandFileSwitch(String commandFile) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPath()
+ */
+ public File[] getLibraryPath() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPatterns(java.lang.String[])
+ */
+ public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {
+ return new String[0];
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType)
+ */
+ public Linker getLinker(LinkType linkType) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getMaximumCommandLength()
+ */
+ protected int getMaximumCommandLength() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getOutputFileSwitch(java.lang.String)
+ */
+ protected String[] getOutputFileSwitch(String outputFile) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.Linker#isCaseSensitive()
+ */
+ public boolean isCaseSensitive() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSLinker.java
new file mode 100644
index 0000000..fda52fa
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSLinker.java
@@ -0,0 +1,166 @@
+/*
+ *
+ * Copyright 2003-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.arm;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+
+/**
+ * Adapter for the ARM Linker
+ *
+ * @author CurtA
+ */
+public class ADSLinker extends CommandLineLinker {
+ private static final ADSLinker dllInstance = new ADSLinker(".o");
+ private static final ADSLinker instance = new ADSLinker(".axf");
+ public static ADSLinker getDllInstance() {
+ return dllInstance;
+ }
+ public static ADSLinker getInstance() {
+ return instance;
+ }
+ private ADSLinker(String outputSuffix) {
+ super("armlink", "-vsn", new String[]{".o", ".lib", ".res"},
+ new String[]{".map", ".pdb", ".lnk"}, outputSuffix, false, null);
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addBase(long,
+ * java.util.Vector)
+ */
+ protected void addBase(long base, Vector args) {
+ // TODO Auto-generated method stub
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addFixed(java.lang.Boolean,
+ * java.util.Vector)
+ */
+ protected void addFixed(Boolean fixed, Vector args) {
+ // TODO Auto-generated method stub
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addImpliedArgs(boolean,
+ * net.sf.antcontrib.cpptasks.compiler.LinkType, java.util.Vector)
+ */
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ if (debug) {
+ args.addElement("-debug");
+ }
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addIncremental(boolean,
+ * java.util.Vector)
+ */
+ protected void addIncremental(boolean incremental, Vector args) {
+ // TODO Auto-generated method stub
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addMap(boolean,
+ * java.util.Vector)
+ */
+ protected void addMap(boolean map, Vector args) {
+ // TODO Auto-generated method stub
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addStack(int,
+ * java.util.Vector)
+ */
+ protected void addStack(int stack, Vector args) {
+ // TODO Auto-generated method stub
+ }
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)
+ */
+ protected void addEntry(String entry, Vector args) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * May have to make this String array return
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getCommandFileSwitch(java.lang.String)
+ */
+ protected String getCommandFileSwitch(String commandFile) {
+ return "-via" + commandFile;
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPath()
+ */
+ public File[] getLibraryPath() {
+ return CUtil.getPathFromEnvironment("ARMLIB", ";");
+ }
+ /*
+ * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPatterns(java.lang.String[])
+ */
+ public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {
+ //
+ // TODO: looks like bad extension
+ //
+ return new String[]{".o"};
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType)
+ */
+ public Linker getLinker(LinkType linkType) {
+ return this;
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getMaximumCommandLength()
+ */
+ protected int getMaximumCommandLength() {
+ return 1024;
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getOutputFileSwitch(java.lang.String)
+ */
+ protected String[] getOutputFileSwitch(String outputFile) {
+ return new String[]{"-output", outputFile};
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.Linker#isCaseSensitive()
+ */
+ public boolean isCaseSensitive() {
+ return false;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandCCompiler.java
new file mode 100644
index 0000000..fd9c657
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandCCompiler.java
@@ -0,0 +1,134 @@
+/*
+ *
+ * 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.borland;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.CompilerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.PrecompilingCommandLineCCompiler;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for the Borland(r) C/C++ compiler.
+ *
+ * @author Curt Arnold
+ */
+public class BorlandCCompiler extends PrecompilingCommandLineCCompiler {
+ private static final String[] headerExtensions = new String[]{".h", ".hpp",
+ ".inl"};
+ private static final String[] sourceExtensions = new String[]{".c", ".cc",
+ ".cpp", ".cxx", ".c++"};
+ private static final BorlandCCompiler instance = new BorlandCCompiler(
+ false, null);
+ public static BorlandCCompiler getInstance() {
+ return instance;
+ }
+ private BorlandCCompiler(boolean newEnvironment, Environment env) {
+ super("bcc32", "--version", sourceExtensions, headerExtensions, ".obj", false,
+ null, newEnvironment, env);
+ }
+ protected void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ args.addElement("-c");
+ //
+ // turn off compiler autodependency since
+ // we do it ourselves
+ args.addElement("-X");
+ if (exceptions) {
+ args.addElement("-x");
+ } else {
+ args.addElement("-x-");
+ }
+ if (multithreaded) {
+ args.addElement("-tWM");
+ }
+ if (debug) {
+ args.addElement("-Od");
+ args.addElement("-v");
+ } else {
+ if (optimization != null) {
+ if (optimization.isSpeed()) {
+ args.addElement("-O1");
+ } else {
+ if (optimization.isSpeed()) {
+ args.addElement("-O2");
+ } else {
+ if (optimization.isNoOptimization()) {
+ args.addElement("-Od");
+ }
+ }
+ }
+ }
+ }
+ if (rtti != null && !rtti.booleanValue()) {
+ args.addElement("-RT-");
+ }
+ }
+ protected void addWarningSwitch(Vector args, int level) {
+ BorlandProcessor.addWarningSwitch(args, level);
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new BorlandCCompiler(newEnvironment, env);
+ }
+ return this;
+ }
+ protected CompilerConfiguration createPrecompileGeneratingConfig(
+ CommandLineCompilerConfiguration baseConfig, File prototype,
+ String lastInclude) {
+ String[] additionalArgs = new String[]{"-H=" + lastInclude, "-Hc"};
+ return new CommandLineCompilerConfiguration(baseConfig, additionalArgs,
+ null, true);
+ }
+ protected CompilerConfiguration createPrecompileUsingConfig(
+ CommandLineCompilerConfiguration baseConfig, File prototype,
+ String lastInclude, String[] exceptFiles) {
+ String[] additionalArgs = new String[]{"-Hu"};
+ return new CommandLineCompilerConfiguration(baseConfig, additionalArgs,
+ exceptFiles, false);
+ }
+ protected void getDefineSwitch(StringBuffer buffer, String define,
+ String value) {
+ BorlandProcessor.getDefineSwitch(buffer, define, value);
+ }
+ protected File[] getEnvironmentIncludePath() {
+ return BorlandProcessor.getEnvironmentPath("bcc32", 'I',
+ new String[]{"..\\include"});
+ }
+ protected String getIncludeDirSwitch(String includeDir) {
+ return BorlandProcessor.getIncludeDirSwitch("-I", includeDir);
+ }
+ public Linker getLinker(LinkType type) {
+ return BorlandLinker.getInstance().getLinker(type);
+ }
+ public int getMaximumCommandLength() {
+ return 1024;
+ }
+ protected void getUndefineSwitch(StringBuffer buffer, String define) {
+ BorlandProcessor.getUndefineSwitch(buffer, define);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandCfgParser.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandCfgParser.java
new file mode 100644
index 0000000..a452b1b
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandCfgParser.java
@@ -0,0 +1,70 @@
+/*
+ *
+ * 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.borland;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.parser.AbstractParser;
+import net.sf.antcontrib.cpptasks.parser.AbstractParserState;
+import net.sf.antcontrib.cpptasks.parser.LetterState;
+import net.sf.antcontrib.cpptasks.parser.WhitespaceOrLetterState;
+/**
+ * A parser that paths from a borland cfg file
+ *
+ * @author Curt Arnold
+ */
+public final class BorlandCfgParser extends AbstractParser {
+ private AbstractParserState newLineState;
+ private final Vector path = new Vector();
+ /**
+ *
+ *
+ */
+ public BorlandCfgParser(char switchChar) {
+ //
+ // a quoted path (-I"some path")
+ // doesn't end till a close quote and will be abandoned
+ // if a new line is encountered first
+ //
+ AbstractParserState quote = new CfgFilenameState(this, new char[]{'"'});
+ //
+ // an unquoted path (-Ic:\borland\include)
+ // ends at the first space or new line
+ AbstractParserState unquote = new CfgFilenameState(this, new char[]{
+ ' ', '\n', '\r'});
+ AbstractParserState quoteBranch = new QuoteBranchState(this, quote,
+ unquote);
+ AbstractParserState toNextSwitch = new ConsumeToSpaceOrNewLine(this);
+ AbstractParserState switchState = new LetterState(this, switchChar,
+ quoteBranch, toNextSwitch);
+ newLineState = new WhitespaceOrLetterState(this, '-', switchState);
+ }
+ public void addFilename(String include) {
+ path.addElement(include);
+ }
+ public AbstractParserState getNewLineState() {
+ return newLineState;
+ }
+ public String[] parsePath(Reader reader) throws IOException {
+ path.setSize(0);
+ super.parse(reader);
+ String[] retval = new String[path.size()];
+ path.copyInto(retval);
+ return retval;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLibrarian.java
new file mode 100644
index 0000000..703ddd3
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLibrarian.java
@@ -0,0 +1,219 @@
+/*
+ *
+ * Copyright 2002-2005 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.borland;
+import java.io.File;
+import java.io.IOException;
+import java.util.Vector;
+import org.apache.tools.ant.BuildException;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+
+/**
+ * Adapter for the Borland(r) tlib Librarian
+ *
+ * @author Curt Arnold
+ */
+public class BorlandLibrarian extends CommandLineLinker {
+ private static final BorlandLibrarian instance = new BorlandLibrarian();
+ public static BorlandLibrarian getInstance() {
+ return instance;
+ }
+ private BorlandLibrarian() {
+ super("tlib", "--version", new String[]{".obj"}, new String[0], ".lib", false,
+ null);
+ }
+ protected void addBase(long base, Vector args) {
+ }
+ protected void addFixed(Boolean fixed, Vector args) {
+ }
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ }
+ protected void addIncremental(boolean incremental, Vector args) {
+ }
+ protected void addMap(boolean map, Vector args) {
+ }
+ protected void addStack(int stack, Vector args) {
+ }
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)
+ */
+ protected void addEntry(String entry, Vector args) {
+ }
+
+ protected String getCommandFileSwitch(String cmdFile) {
+ //
+ // tlib requires quotes around paths containing -
+ // ilink32 doesn't like them
+ StringBuffer buf = new StringBuffer("@");
+ BorlandProcessor.quoteFile(buf, cmdFile);
+ return buf.toString();
+ }
+ public File[] getLibraryPath() {
+ return CUtil.getPathFromEnvironment("LIB", ";");
+ }
+ public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {
+ return BorlandProcessor.getLibraryPatterns(libnames, libType);
+ }
+ public Linker getLinker(LinkType type) {
+ return BorlandLinker.getInstance().getLinker(type);
+ }
+ public int getMaximumCommandLength() {
+ return 1024;
+ }
+ public String[] getOutputFileSwitch(String outFile) {
+ return BorlandProcessor.getOutputFileSwitch(outFile);
+ }
+ public boolean isCaseSensitive() {
+ return BorlandProcessor.isCaseSensitive();
+ }
+ /**
+ * Gets identifier for the linker.
+ *
+ * TLIB will lockup when attempting to get version
+ * information. Since the Librarian version isn't critical
+ * just return a stock response.
+ */
+ public String getIdentifier() {
+ return "TLIB 4.5 Copyright (c) 1987, 1999 Inprise Corporation";
+ }
+
+ /**
+ * Prepares argument list for exec command.
+ *
+ * @param outputDir linker output directory
+ * @param outputName linker output name
+ * @param sourceFiles
+ * linker input files (.obj, .o, .res)
+ * @param config
+ * linker configuration
+ * @return arguments for runTask
+ */
+ protected String[] prepareArguments(
+ CCTask task,
+ String outputDir,
+ String outputName,
+ String[] sourceFiles,
+ CommandLineLinkerConfiguration config) {
+ String[] preargs = config.getPreArguments();
+ String[] endargs = config.getEndArguments();
+ StringBuffer buf = new StringBuffer();
+ Vector execArgs = new Vector(preargs.length + endargs.length + 10
+ + sourceFiles.length);
+
+ execArgs.addElement(this.getCommand());
+ String outputFileName = new File(outputDir, outputName).toString();
+ execArgs.addElement(quoteFilename(buf, outputFileName));
+
+ for (int i = 0; i < preargs.length; i++) {
+ execArgs.addElement(preargs[i]);
+ }
+
+ //
+ // add a place-holder for page size
+ //
+ int pageSizeIndex = execArgs.size();
+ execArgs.addElement(null);
+
+ int objBytes = 0;
+
+ for (int i = 0; i < sourceFiles.length; i++) {
+ String last4 = sourceFiles[i]
+ .substring(sourceFiles[i].length() - 4).toLowerCase();
+ if (last4.equals(".def")) {
+ } else {
+ if (last4.equals(".res")) {
+ } else {
+ if (last4.equals(".lib")) {
+ } else {
+ execArgs.addElement("+" + quoteFilename(buf, sourceFiles[i]));
+ objBytes += new File(sourceFiles[i]).length();
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < endargs.length; i++) {
+ execArgs.addElement(endargs[i]);
+ }
+
+ String[] execArguments = new String[execArgs.size()];
+ execArgs.copyInto(execArguments);
+
+ int minPageSize = objBytes >> 16;
+ int pageSize = 0;
+ for(int i = 4; i <= 15; i++) {
+ pageSize = 1 << i;
+ if (pageSize > minPageSize) break;
+ }
+ execArguments[pageSizeIndex] = "/P" + Integer.toString(pageSize);
+
+ return execArguments;
+ }
+
+ /**
+ * Prepares argument list to execute the linker using a response file.
+ *
+ * @param outputFile
+ * linker output file
+ * @param args
+ * output of prepareArguments
+ * @return arguments for runTask
+ */
+ protected String[] prepareResponseFile(File outputFile, String[] args)
+ throws IOException {
+ String[] cmdargs = BorlandProcessor.prepareResponseFile(outputFile, args, " & \n");
+ cmdargs[cmdargs.length - 1] = getCommandFileSwitch(cmdargs[cmdargs.length -1]);
+ return cmdargs;
+ }
+
+ /**
+ * Builds a library
+ *
+ */
+ public void link(CCTask task,
+ File outputFile,
+ String[] sourceFiles,
+ CommandLineLinkerConfiguration config)
+ throws BuildException
+ {
+ //
+ // delete any existing library
+ outputFile.delete();
+ //
+ // build a new library
+ super.link(task, outputFile, sourceFiles, config);
+ }
+
+ /**
+ * Encloses problematic file names within quotes.
+ * @param buf string buffer
+ * @param filename source file name
+ * @return filename potentially enclosed in quotes.
+ */
+ protected String quoteFilename(StringBuffer buf,String filename) {
+ buf.setLength(0);
+ BorlandProcessor.quoteFile(buf, filename);
+ return buf.toString();
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java
new file mode 100644
index 0000000..6a28805
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java
@@ -0,0 +1,293 @@
+/*
+ *
+ * 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.borland;
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.TargetMatcher;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+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.platforms.WindowsPlatform;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+
+/**
+ * Adapter for the Borland(r) ilink32 linker
+ *
+ * @author Curt Arnold
+ */
+public final class BorlandLinker extends CommandLineLinker {
+ private static final BorlandLinker dllLinker = new BorlandLinker(".dll");
+ private static final BorlandLinker instance = new BorlandLinker(".exe");
+ public static BorlandLinker getInstance() {
+ return instance;
+ }
+ private BorlandLinker(String outputSuffix) {
+ super("ilink32", "-r", new String[]{".obj", ".lib", ".res"},
+ new String[]{".map", ".pdb", ".lnk"}, outputSuffix, false, null);
+ }
+ protected void addBase(long base, Vector args) {
+ if (base >= 0) {
+ String baseAddr = Long.toHexString(base);
+ args.addElement("-b:" + baseAddr);
+ }
+ }
+ protected void addFixed(Boolean fixed, Vector args) {
+ }
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ if (linkType.isExecutable()) {
+ if (linkType.isSubsystemConsole()) {
+ args.addElement("/ap");
+ } else {
+ if (linkType.isSubsystemGUI()) {
+ args.addElement("/Tpe");
+ }
+ }
+ }
+ if (linkType.isSharedLibrary()) {
+ args.addElement("/Tpd");
+ args.addElement("/Gi");
+ }
+ if (debug) {
+ args.addElement("-v");
+ }
+ }
+ protected void addIncremental(boolean incremental, Vector args) {
+ }
+ protected void addMap(boolean map, Vector args) {
+ if (!map) {
+ args.addElement("-x");
+ }
+ }
+ protected void addStack(int stack, Vector args) {
+ if (stack >= 0) {
+ String stackStr = Integer.toHexString(stack);
+ args.addElement("-S:" + stackStr);
+ }
+ }
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)
+ */
+ protected void addEntry(String entry, Vector args) {
+ }
+
+ public String getCommandFileSwitch(String commandFile) {
+ return "@" + commandFile;
+ }
+ public String getIdentifier() {
+ return "Borland Linker";
+ }
+ public File[] getLibraryPath() {
+ return BorlandProcessor.getEnvironmentPath("ilink32", 'L',
+ new String[]{"..\\lib"});
+ }
+ public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {
+ return BorlandProcessor.getLibraryPatterns(libnames, libType);
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return BorlandLibrarian.getInstance();
+ }
+ if (type.isSharedLibrary()) {
+ return dllLinker;
+ }
+ return instance;
+ }
+ public int getMaximumCommandLength() {
+ return 1024;
+ }
+ public String[] getOutputFileSwitch(String outFile) {
+ return BorlandProcessor.getOutputFileSwitch(outFile);
+ }
+ protected String getStartupObject(LinkType linkType) {
+ if (linkType.isSharedLibrary()) {
+ return "c0d32.obj";
+ }
+ if (linkType.isSubsystemGUI()) {
+ return "c0w32.obj";
+ }
+ if (linkType.isSubsystemConsole()) {
+ return "c0x32.obj";
+ }
+ return null;
+ }
+ public boolean isCaseSensitive() {
+ return BorlandProcessor.isCaseSensitive();
+ }
+ /**
+ * Prepares argument list for exec command.
+ *
+ * @param outputDir linker output directory
+ * @param outputName linker output name
+ * @param sourceFiles
+ * linker input files (.obj, .o, .res)
+ * @param config
+ * linker configuration
+ * @return arguments for runTask
+ */
+ protected String[] prepareArguments(
+ CCTask task,
+ String outputDir,
+ String outputName,
+ String[] sourceFiles,
+ CommandLineLinkerConfiguration config) {
+ String[] preargs = config.getPreArguments();
+ String[] endargs = config.getEndArguments();
+ Vector execArgs = new Vector(preargs.length + endargs.length + 10
+ + sourceFiles.length);
+ execArgs.addElement(this.getCommand());
+ for (int i = 0; i < preargs.length; i++) {
+ execArgs.addElement(preargs[i]);
+ }
+ for (int i = 0; i < endargs.length; i++) {
+ execArgs.addElement(endargs[i]);
+ }
+ //
+ // see if the input files have any known startup obj files
+ //
+ String startup = null;
+ for (int i = 0; i < sourceFiles.length; i++) {
+ String filename = new File(sourceFiles[i]).getName().toLowerCase();
+ if (startup != null && filename.substring(0, 2).equals("c0")
+ && filename.substring(3, 5).equals("32")
+ && filename.substring(filename.length() - 4).equals(".obj")) {
+ startup = sourceFiles[i];
+ }
+ }
+ //
+ // c0w32.obj, c0x32.obj or c0d32.obj depending on
+ // link type
+ if (startup == null) {
+ startup = config.getStartupObject();
+ }
+ execArgs.addElement(startup);
+ Vector resFiles = new Vector();
+ Vector libFiles = new Vector();
+ String defFile = null;
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < sourceFiles.length; i++) {
+ String last4 = sourceFiles[i]
+ .substring(sourceFiles[i].length() - 4).toLowerCase();
+ if (last4.equals(".def")) {
+ defFile = quoteFilename(buf, sourceFiles[i]);
+ } else {
+ if (last4.equals(".res")) {
+ resFiles.addElement(quoteFilename(buf, sourceFiles[i]));
+ } else {
+ if (last4.equals(".lib")) {
+ libFiles.addElement(quoteFilename(buf, sourceFiles[i]));
+ } else {
+ execArgs.addElement(quoteFilename(buf, sourceFiles[i]));
+ }
+ }
+ }
+ }
+ //
+ // output file name
+ //
+ String outputFileName = new File(outputDir, outputName).toString();
+ execArgs.addElement("," + quoteFilename(buf, outputFileName));
+ if (config.getMap()) {
+ int lastPeriod = outputFileName.lastIndexOf('.');
+ String mapName;
+ if (lastPeriod < outputFileName.length() - 4) {
+ mapName = outputFileName + ".map";
+ } else {
+ mapName = outputFileName.substring(0, lastPeriod) + ".map";
+ }
+ execArgs.addElement("," + quoteFilename(buf, mapName) + ",");
+ } else {
+ execArgs.addElement(",,");
+ }
+ //
+ // add all the libraries
+ //
+ Enumeration libEnum = libFiles.elements();
+ boolean hasImport32 = false;
+ boolean hasCw32 = false;
+ while (libEnum.hasMoreElements()) {
+ String libName = (String) libEnum.nextElement();
+ if (libName.equalsIgnoreCase("import32.lib")) {
+ hasImport32 = true;
+ }
+ if (libName.equalsIgnoreCase("cw32.lib")) {
+ hasImport32 = true;
+ }
+ execArgs.addElement(quoteFilename(buf, libName));
+ }
+ if (!hasCw32) {
+ execArgs.addElement(quoteFilename(buf, "cw32.lib"));
+ }
+ if (!hasImport32) {
+ execArgs.addElement(quoteFilename(buf, "import32.lib"));
+ }
+ if (defFile == null) {
+ execArgs.addElement(",,");
+ } else {
+ execArgs.addElement("," + quoteFilename(buf, defFile) + ",");
+ }
+ Enumeration resEnum = resFiles.elements();
+ while (resEnum.hasMoreElements()) {
+ String resName = (String) resEnum.nextElement();
+ execArgs.addElement(quoteFilename(buf, resName));
+ }
+ String[] execArguments = new String[execArgs.size()];
+ execArgs.copyInto(execArguments);
+ return execArguments;
+ }
+ /**
+ * Prepares argument list to execute the linker using a response file.
+ *
+ * @param outputFile
+ * linker output file
+ * @param args
+ * output of prepareArguments
+ * @return arguments for runTask
+ */
+ protected String[] prepareResponseFile(File outputFile, String[] args)
+ throws IOException {
+ String cmdargs[] = BorlandProcessor.prepareResponseFile(outputFile, args, " + \n");
+ cmdargs[cmdargs.length - 1] = getCommandFileSwitch(cmdargs[cmdargs.length -1]);
+ return cmdargs;
+ }
+
+ /**
+ * Adds source or object files to the bidded fileset to
+ * support version information.
+ *
+ * @param versionInfo version information
+ * @param linkType link type
+ * @param isDebug true if debug build
+ * @param outputFile name of generated executable
+ * @param objDir directory for generated files
+ * @param matcher bidded fileset
+ */
+ public void addVersionFiles(final VersionInfo versionInfo,
+ final LinkType linkType,
+ final File outputFile,
+ final boolean isDebug,
+ final File objDir,
+ final TargetMatcher matcher) throws IOException {
+ WindowsPlatform.addVersionFiles(versionInfo, linkType, outputFile, isDebug, objDir, matcher);
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandProcessor.java
new file mode 100644
index 0000000..b14c854
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandProcessor.java
@@ -0,0 +1,219 @@
+/*
+ *
+ * Copyright 2002-2005 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.borland;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Vector;
+import java.io.FileWriter;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+/**
+ * A add-in class for Borland(r) processor adapters
+ *
+ *
+ */
+public final class BorlandProcessor {
+ public static void addWarningSwitch(Vector args, int level) {
+ switch (level) {
+ case 0 :
+ args.addElement("-w-");
+ break;
+ case 5 :
+ args.addElement("-w!");
+ break;
+ default :
+ args.addElement("-w");
+ break;
+ }
+ }
+ public static void getDefineSwitch(StringBuffer buffer, String define,
+ String value) {
+ buffer.append("-D");
+ buffer.append(define);
+ if (value != null && value.length() > 0) {
+ buffer.append('=');
+ buffer.append(value);
+ }
+ }
+ /**
+ * This method extracts path information from the appropriate .cfg file in
+ * the install directory.
+ *
+ * @param toolName
+ * Tool name, for example, "bcc32", "brc32", "ilink32"
+ * @param switchChar
+ * Command line switch character, for example "L" for libraries
+ * @param defaultRelativePath
+ * default path relative to executable directory
+ * @return path
+ */
+ public static File[] getEnvironmentPath(String toolName, char switchChar,
+ String[] defaultRelativePath) {
+ if (toolName == null) {
+ throw new NullPointerException("toolName");
+ }
+ if (defaultRelativePath == null) {
+ throw new NullPointerException("defaultRelativePath");
+ }
+ String[] path = defaultRelativePath;
+ File exeDir = CUtil.getExecutableLocation(toolName + ".exe");
+ if (exeDir != null) {
+ File cfgFile = new File(exeDir, toolName + ".cfg");
+ if (cfgFile.exists()) {
+ try {
+ Reader reader = new BufferedReader(new FileReader(cfgFile));
+ BorlandCfgParser cfgParser = new BorlandCfgParser(
+ switchChar);
+ path = cfgParser.parsePath(reader);
+ reader.close();
+ } catch (IOException ex) {
+ //
+ // could be logged
+ //
+ }
+ }
+ } else {
+ //
+ // if can't find the executable,
+ // assume current directory to resolve relative paths
+ //
+ exeDir = new File(System.getProperty("user.dir"));
+ }
+ int nonExistant = 0;
+ File[] resourcePath = new File[path.length];
+ for (int i = 0; i < path.length; i++) {
+ resourcePath[i] = new File(path[i]);
+ if (!resourcePath[i].isAbsolute()) {
+ resourcePath[i] = new File(exeDir, path[i]);
+ }
+ //
+ // if any of the entries do not exist or are
+ // not directories, null them out
+ if (!(resourcePath[i].exists() && resourcePath[i].isDirectory())) {
+ resourcePath[i] = null;
+ nonExistant++;
+ }
+ }
+ //
+ // if there were some non-existant or non-directory
+ // entries in the configuration file then
+ // create a shorter array
+ if (nonExistant > 0) {
+ File[] culled = new File[resourcePath.length - nonExistant];
+ int index = 0;
+ for (int i = 0; i < resourcePath.length; i++) {
+ if (resourcePath[i] != null) {
+ culled[index++] = resourcePath[i];
+ }
+ }
+ resourcePath = culled;
+ }
+ return resourcePath;
+ }
+ public static String getIncludeDirSwitch(String includeOption,
+ String includeDir) {
+ StringBuffer buf = new StringBuffer(includeOption);
+ quoteFile(buf, includeDir);
+ return buf.toString();
+ }
+ public static String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {
+ StringBuffer buf = new StringBuffer();
+ String[] patterns = new String[libnames.length];
+ for (int i = 0; i < libnames.length; i++) {
+ buf.setLength(0);
+ buf.append(libnames[i]);
+ buf.append(".lib");
+ patterns[i] = buf.toString();
+ }
+ return patterns;
+ }
+ public static String[] getOutputFileSwitch(String outFile) {
+ return new String[0];
+ }
+ public static void getUndefineSwitch(StringBuffer buffer, String define) {
+ buffer.append("-U");
+ buffer.append(define);
+ }
+ public static boolean isCaseSensitive() {
+ return false;
+ }
+ public static void quoteFile(StringBuffer buf, String outPath) {
+ if (outPath.charAt(0) != '\"'
+ && (outPath.indexOf(' ') >= 0
+ || outPath.indexOf('-') >= 0
+ || outPath.indexOf('/') >= 0)) {
+ buf.append('\"');
+ buf.append(outPath);
+ buf.append('\"');
+ } else {
+ buf.append(outPath);
+ }
+ }
+
+ /**
+ * Prepares argument list to execute the linker using a response file.
+ *
+ * @param outputFile
+ * linker output file
+ * @param args
+ * output of prepareArguments
+ * @return arguments for runTask
+ */
+ public static String[] prepareResponseFile(File outputFile,
+ String[] args,
+ String continuation)
+ throws IOException {
+ String baseName = outputFile.getName();
+ File commandFile = new File(outputFile.getParent(), baseName + ".rsp");
+ FileWriter writer = new FileWriter(commandFile);
+ for (int i = 1; i < args.length - 1; i++) {
+ writer.write(args[i]);
+ //
+ // if either the current argument ends with
+ // or next argument starts with a comma then
+ // don't split the line
+ if (args[i].endsWith(",") || args[i + 1].startsWith(",")) {
+ writer.write(' ');
+ } else {
+ //
+ // split the line to make it more readable
+ //
+ writer.write(continuation);
+ }
+ }
+ //
+ // write the last argument
+ //
+ if (args.length > 1) {
+ writer.write(args[args.length - 1]);
+ }
+ writer.close();
+ String[] execArgs = new String[2];
+ execArgs[0] = args[0];
+ //
+ // left for the caller to decorate
+ execArgs[1] = commandFile.toString();
+ return execArgs;
+ }
+
+ private BorlandProcessor() {
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandResourceCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandResourceCompiler.java
new file mode 100644
index 0000000..debfa2b
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandResourceCompiler.java
@@ -0,0 +1,129 @@
+/*
+ *
+ * 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.borland;
+import java.io.File;
+import java.util.Vector;
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.compiler.ProgressMonitor;
+import net.sf.antcontrib.cpptasks.parser.CParser;
+import net.sf.antcontrib.cpptasks.parser.Parser;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for the Borland(r) brc32 Resource compiler.
+ *
+ * @author Curt Arnold
+ */
+public class BorlandResourceCompiler extends CommandLineCompiler {
+ private static final BorlandResourceCompiler instance = new BorlandResourceCompiler(
+ false, null);
+ public static BorlandResourceCompiler getInstance() {
+ return instance;
+ }
+ private BorlandResourceCompiler(boolean newEnvironment, Environment env) {
+ super("brc32", "c:\\__bogus\\__bogus.rc", new String[]{".rc"},
+ new String[]{".h", ".hpp", ".inl"}, ".res", false, null,
+ newEnvironment, env);
+ }
+ protected void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ //
+ // compile only
+ //
+ args.addElement("-r");
+ }
+ protected void addWarningSwitch(Vector args, int level) {
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new BorlandResourceCompiler(newEnvironment, env);
+ }
+ return this;
+ }
+ public void compile(CCTask task, File outputDir, String[] sourceFiles,
+ String[] args, String[] endArgs, boolean relentless,
+ CommandLineCompilerConfiguration config, ProgressMonitor monitor)
+ throws BuildException {
+ super.compile(task, outputDir, sourceFiles, args, endArgs, relentless,
+ config, monitor);
+ }
+ /**
+ * The include parser for C will work just fine, but we didn't want to
+ * inherit from CommandLineCCompiler
+ */
+ protected Parser createParser(File source) {
+ return new CParser();
+ }
+ protected int getArgumentCountPerInputFile() {
+ return 2;
+ }
+ protected void getDefineSwitch(StringBuffer buffer, String define,
+ String value) {
+ buffer.append("-d");
+ buffer.append(define);
+ if (value != null && value.length() > 0) {
+ buffer.append('=');
+ buffer.append(value);
+ }
+ }
+ protected File[] getEnvironmentIncludePath() {
+ return BorlandProcessor.getEnvironmentPath("brc32", 'i',
+ new String[]{"..\\include"});
+ }
+ protected String getIncludeDirSwitch(String includeDir) {
+ return BorlandProcessor.getIncludeDirSwitch("-i", includeDir);
+ }
+ protected String getInputFileArgument(File outputDir, String filename,
+ int index) {
+ if (index == 0) {
+ String[] outputFileNames = getOutputFileNames(filename, null);
+ String fullOutputName = new File(outputDir, outputFileNames[0])
+ .toString();
+ return "-fo" + fullOutputName;
+ }
+ return filename;
+ }
+ public Linker getLinker(LinkType type) {
+ return BorlandLinker.getInstance().getLinker(type);
+ }
+ public int getMaximumCommandLength() {
+ return 1024;
+ }
+ protected int getMaximumInputFilesPerCommand() {
+ return 1;
+ }
+ protected int getTotalArgumentLengthForInputFile(File outputDir,
+ String inputFile) {
+ String arg1 = getInputFileArgument(outputDir, inputFile, 0);
+ String arg2 = getInputFileArgument(outputDir, inputFile, 1);
+ return arg1.length() + arg2.length() + 2;
+ }
+ protected void getUndefineSwitch(StringBuffer buffer, String define) {
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/CBuilderXProjectWriter.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/CBuilderXProjectWriter.java
new file mode 100644
index 0000000..dfe5ec6
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/CBuilderXProjectWriter.java
@@ -0,0 +1,542 @@
+/*
+ *
+ * Copyright 2004-2005 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.borland;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.TargetInfo;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;
+import net.sf.antcontrib.cpptasks.gcc.GccCCompiler;
+import net.sf.antcontrib.cpptasks.ide.ProjectDef;
+import net.sf.antcontrib.cpptasks.ide.ProjectWriter;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.xml.serialize.OutputFormat;
+import org.apache.xml.serialize.Serializer;
+import org.apache.xml.serialize.XMLSerializer;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * Writes a CBuilderX 1.0 project file.
+ *
+ * @author curta
+ *
+ */
+public final class CBuilderXProjectWriter
+ implements ProjectWriter {
+ /**
+ * Constructor.
+ */
+ public CBuilderXProjectWriter() {
+ }
+
+ /**
+ * Writes a project definition file.
+ *
+ * @param fileName
+ * project name for file, should has .cbx extension
+ * @param task
+ * cc task for which to write project
+ * @param projectDef
+ * project element
+ * @param sources source files
+ * @param targets compilation targets
+ * @param linkTarget link target
+ * @throws IOException if I/O error
+ * @throws SAXException if XML serialization error
+ */
+ public void writeProject(final File fileName,
+ final CCTask task,
+ final ProjectDef projectDef,
+ final List sources,
+ final Hashtable targets,
+ final TargetInfo linkTarget) throws
+ IOException,
+ SAXException {
+
+ String projectName = projectDef.getName();
+ if (projectName == null) {
+ projectName = fileName.getName();
+ }
+ final String basePath = fileName.getAbsoluteFile().getParent();
+
+ File projectFile = new File(fileName + ".cbx");
+ if (!projectDef.getOverwrite() && projectFile.exists()) {
+ throw new BuildException("Not allowed to overwrite project file "
+ + projectFile.toString());
+ }
+
+ CommandLineCompilerConfiguration compilerConfig =
+ getBaseCompilerConfiguration(targets);
+ if (compilerConfig == null) {
+ throw new BuildException(
+ "Unable to generate C++ BuilderX project when gcc or bcc is not used.");
+ }
+
+ OutputStream outStream = new FileOutputStream(projectFile);
+ OutputFormat format = new OutputFormat("xml", "UTF-8", true);
+ Serializer serializer = new XMLSerializer(outStream, format);
+ ContentHandler content = serializer.asContentHandler();
+ content.startDocument();
+ AttributesImpl emptyAttrs = new AttributesImpl();
+ content.startElement(null, "project", "project", emptyAttrs);
+ PropertyWriter propertyWriter = new PropertyWriter(content);
+ propertyWriter.write("build.config", "active", "0");
+ propertyWriter.write("build.config", "count", "0");
+ propertyWriter.write("build.config", "excludedefaultforzero", "0");
+ propertyWriter.write("build.config.0", "builddir", "Debug");
+ propertyWriter.write("build.config.0", "key", "Debug_Build");
+ propertyWriter.write("build.config.0", "linux.builddir",
+ "linux/Debug_Build");
+ propertyWriter.write("build.config.0", "settings.MinGW",
+ "default;debug");
+ propertyWriter.write("build.config.0", "settings.gnuc++",
+ "default;debug");
+ propertyWriter.write("build.config.0", "settings.intellinia32",
+ "default;debug");
+ propertyWriter.write("build.config.0", "settings.mswin32",
+ "default;debug");
+ propertyWriter.write("build.config.0", "type", "Toolset");
+ propertyWriter.write("build.config.0", "win32.builddir",
+ "windows/Debug_Build");
+ propertyWriter.write("build.node", "name", projectDef.getName());
+ final String buildType = getBuildType(task);
+ propertyWriter.write("build.node", "type", buildType);
+ propertyWriter.write("build.platform", "active",
+ getActivePlatform(task));
+ propertyWriter.write("build.platform", "linux.Debug_Build.toolset",
+ "gnuc++");
+ propertyWriter.write("build.platform", "linux.Release_Build.toolset",
+ "gnuc++");
+ propertyWriter.write("build.platform", "linux.default", "gnuc++");
+ propertyWriter.write("build.platform", "linux.gnuc++.enabled", "1");
+ propertyWriter.write("build.platform", "linux.mswin32.enabled", "1");
+ propertyWriter.write("build.platform", "linux.win32b.enabled", "1");
+ propertyWriter.write("build.platform", "solaris.default", "gnuc++");
+ propertyWriter.write("build.platform", "solaris.enabled", "1");
+ String toolset = getWin32Toolset(compilerConfig);
+ propertyWriter.write("build.platform", "win32.default", toolset);
+ propertyWriter.write("build.platform", "win32." + toolset + ".enabled", "1");
+
+ propertyWriter.write("cbproject", "version", "X.1.0");
+ if ("dllproject".equals(buildType)) {
+ propertyWriter.write("gnuc++.g++compile",
+ "option.fpic_using_GOT.enabled", "1");
+ propertyWriter.write("gnuc++.g++link", "option.shared.enabled", "1");
+ propertyWriter.write("intellinia32.icc", "option.minus_Kpic.enabled",
+ "1");
+ propertyWriter.write("intellinia32.icclink",
+ "option.minus_shared.enabled", "1");
+ }
+ //
+ // assume the first target is representative of all compilation tasks
+ //
+ writeCompileOptions(basePath, propertyWriter, compilerConfig);
+ writeLinkOptions(basePath, propertyWriter, linkTarget);
+ propertyWriter.write("linux.gnuc++.Debug_Build", "saved", "1");
+ if ("dllproject".equals(buildType)) {
+ propertyWriter.write("runtime", "ExcludeDefaultForZero", "1");
+ //propertyWriter.write("unique", "id", "852");
+ } else if ("exeproject".equals(buildType)) {
+ propertyWriter.write("runtime.0", "BuildTargetOnRun",
+ "com.borland.cbuilder.build."
+ + "CBProjectBuilder$ProjectBuildAction;make");
+ propertyWriter.write("runtime.0", "ConfigurationName",
+ projectDef.getName());
+ propertyWriter.write("runtime.0", "RunnableType",
+ "com.borland.cbuilder.runtime.ExecutableRunner");
+ }
+ AttributesImpl fileAttributes = new AttributesImpl();
+ fileAttributes.addAttribute(null, "path", "path", "#PCDATA", "");
+ AttributesImpl gccAttributes = null;
+ if (!"g++".equals(compilerConfig.getCommand())) {
+ gccAttributes = new AttributesImpl();
+ gccAttributes.addAttribute(null, "category", "category", "#PCDATA",
+ "build.basecmd");
+ gccAttributes.addAttribute(null, "name", "name", "#PCDATA",
+ "linux.gnuc++.Debug_Build.g++_key");
+ gccAttributes.addAttribute(null, "value", "value", "#PCDATA",
+ compilerConfig.getCommand());
+ }
+
+ Iterator targetIter = targets.values().iterator();
+ while (targetIter.hasNext()) {
+ TargetInfo info = (TargetInfo) targetIter.next();
+ File[] targetsources = info.getSources();
+ for (int i = 0; i < targetsources.length; i++) {
+ String relativePath = CUtil.getRelativePath(basePath,
+ targetsources[i]);
+ fileAttributes.setValue(0, relativePath);
+ content.startElement(null, "file", "file", fileAttributes);
+
+ //
+ // if file ends with .c, use gcc instead of g++
+ //
+ if (gccAttributes != null) {
+ content.startElement(null, "property", "property", gccAttributes);
+ content.endElement(null, "property", "property");
+ }
+ content.endElement(null, "file", "file");
+ }
+ }
+ content.endElement(null, "project", "project");
+ content.endDocument();
+ }
+
+ /**
+ * Gets build type from link target.
+ * @param task CCTask current task
+ * @return String build type
+ */
+ private String getBuildType(final CCTask task) {
+ String outType = task.getOuttype();
+ if ("executable".equals(outType)) {
+ return "exeproject";
+ } else if ("static".equals(outType)) {
+ return "libraryproject";
+ }
+ return "dllproject";
+ }
+
+ /**
+ * Gets active platform.
+ * @param task CCTask cc task
+ * @return String platform identifier
+ */
+ private String getActivePlatform(final CCTask task) {
+ String osName = System.getProperty("os.name").toLowerCase(Locale.US);
+ if (osName.indexOf("windows") >= 0) {
+ return "win32";
+ }
+ return "linux";
+ }
+
+ private String getWin32Toolset(final CommandLineCompilerConfiguration compilerConfig) {
+ if (compilerConfig != null && compilerConfig.getCompiler() instanceof BorlandCCompiler) {
+ return "win32b";
+ }
+ return "MinGW";
+ }
+
+ /**
+ * Utility class to generate property elements.
+ */
+ private static class PropertyWriter {
+ /**
+ * Content handler.
+ */
+ private ContentHandler content;
+
+ /**
+ * Attributes list.
+ */
+ private AttributesImpl propertyAttributes;
+
+ /**
+ * Constructor.
+ *
+ * @param contentHandler ContentHandler content handler
+ */
+ public PropertyWriter(final ContentHandler contentHandler) {
+ content = contentHandler;
+ propertyAttributes = new AttributesImpl();
+ propertyAttributes.addAttribute(null, "category", "category",
+ "#PCDATA", "");
+ propertyAttributes
+ .addAttribute(null, "name", "name", "#PCDATA", "");
+ propertyAttributes.addAttribute(null, "value", "value", "#PCDATA",
+ "");
+ }
+
+ /**
+ * Write property element.
+ *
+ * @param category String category
+ * @param name String property name
+ * @param value String property value
+ * @throws SAXException if I/O error or illegal content
+ */
+ public final void write(final String category,
+ final String name,
+ final String value) throws SAXException {
+ propertyAttributes.setValue(0, category);
+ propertyAttributes.setValue(1, name);
+ propertyAttributes.setValue(2, value);
+ content.startElement(null, "property", "property",
+ propertyAttributes);
+ content.endElement(null, "property", "property");
+ }
+ }
+
+ /**
+ * Gets the first recognized compiler from the
+ * compilation targets.
+ * @param targets compilation targets
+ * @return representative (hopefully) compiler configuration
+ */
+ private CommandLineCompilerConfiguration
+ getBaseCompilerConfiguration(final Hashtable targets) {
+ //
+ // find first target with an gcc or bcc compilation
+ //
+ CommandLineCompilerConfiguration compilerConfig = null;
+ //
+ // get the first target and assume that it is representative
+ //
+ Iterator targetIter = targets.values().iterator();
+ while (targetIter.hasNext()) {
+ TargetInfo targetInfo = (TargetInfo) targetIter.next();
+ ProcessorConfiguration config = targetInfo.getConfiguration();
+ String identifier = config.getIdentifier();
+ //
+ // for the first gcc or bcc compiler
+ //
+ if (config instanceof CommandLineCompilerConfiguration) {
+ compilerConfig = (CommandLineCompilerConfiguration) config;
+ if (compilerConfig.getCompiler() instanceof GccCCompiler ||
+ compilerConfig.getCompiler() instanceof BorlandCCompiler) {
+ return compilerConfig;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Writes elements corresponding to compilation options.
+ *
+ * @param baseDir String base directory
+ * @param writer PropertyWriter property writer
+ * @param compilerConfig representative configuration
+ * @throws SAXException if I/O error or illegal content
+ */
+ private void writeCompileOptions(final String baseDir,
+ final PropertyWriter writer,
+ final CommandLineCompilerConfiguration
+ compilerConfig) throws SAXException {
+ boolean isBcc = false;
+ boolean isUnix = true;
+ String compileID = "linux.Debug_Build.gnuc++.g++compile";
+ if (compilerConfig.getCompiler() instanceof BorlandCCompiler) {
+ compileID = "win32.Debug_Build.win32b.bcc32";
+ isUnix = false;
+ isBcc = true;
+ }
+
+ File[] includePath = compilerConfig.getIncludePath();
+ int includeIndex = 1;
+ if (isUnix) {
+ writer.write(compileID,
+ "option.I.arg." + (includeIndex++),
+ "/usr/include");
+ writer.write(compileID,
+ "option.I.arg." + (includeIndex++),
+ "/usr/include/g++-3");
+ }
+ for (int i = 0; i < includePath.length; i++) {
+ String relPath = CUtil.getRelativePath(baseDir, includePath[i]);
+ writer.write(compileID,
+ "option.I.arg." + (includeIndex++),
+ relPath);
+ }
+ if (includePath.length > 0) {
+ writer.write(compileID,
+ "option.I.enabled",
+ "1");
+ }
+
+ String defineBase = "option.D_MACRO_VALUE";
+ if (isBcc) {
+ defineBase = "option.D";
+ }
+ String defineOption = defineBase + ".arg.";
+ int defineIndex = 1;
+ int undefineIndex = 1;
+ String[] preArgs = compilerConfig.getPreArguments();
+ for (int i = 0; i < preArgs.length; i++) {
+ if (preArgs[i].startsWith("-D")) {
+ writer.write(compileID,
+ defineOption + (defineIndex++),
+ preArgs[i].substring(2));
+ } else if (preArgs[i].startsWith("-U")) {
+ writer.write(compileID,
+ "option.U.arg."
+ + (undefineIndex++), preArgs[i]
+ .substring(2));
+ } else if (!(preArgs[i].startsWith("-I")
+ || preArgs[i].startsWith("-o"))) {
+ //
+ // any others (-g, -fno-rtti, -w, -Wall, etc)
+ //
+ writer.write(compileID,
+ "option." + preArgs[i].substring(1) + ".enabled",
+ "1");
+ }
+ }
+ if (defineIndex > 1) {
+ writer.write(compileID,
+ defineBase + ".enabled",
+ "1");
+ }
+ if (undefineIndex > 1) {
+ writer.write(compileID,
+ "option.U.enabled",
+ "1");
+ }
+ }
+
+ /**
+ * Writes elements corresponding to link options.
+ *
+ * @param baseDir String base directory
+ * @param writer PropertyWriter property writer
+ * @param linkTarget TargetInfo link target
+ * @throws SAXException if I/O error or illegal content
+ */
+ private void
+ writeLinkOptions(final String baseDir,
+ final PropertyWriter writer,
+ final TargetInfo linkTarget) throws SAXException {
+ if (linkTarget != null) {
+ ProcessorConfiguration config = linkTarget.getConfiguration();
+ if (config instanceof CommandLineLinkerConfiguration) {
+ CommandLineLinkerConfiguration linkConfig =
+ (CommandLineLinkerConfiguration) config;
+
+ if (linkConfig.getLinker() instanceof BorlandLinker) {
+ String linkID = "win32.Debug_Build.win32b.ilink32";
+ writeIlinkArgs(writer, linkID, linkConfig.getPreArguments());
+ writeIlinkArgs(writer, linkID, linkConfig.getEndArguments());
+ writer.write(linkID, "param.libfiles.1", "cw32mt.lib");
+ writer.write(linkID, "param.libfiles.2", "import32.lib");
+ int libIndex = 3;
+ String[] libNames = linkConfig.getLibraryNames();
+ for(int i = 0; i < libNames.length; i++) {
+ writer.write(linkID, "param.libfiles." + (libIndex++),
+ libNames[i]);
+ }
+ String startup = linkConfig.getStartupObject();
+ if (startup != null) {
+ writer.write(linkID, "param.objfiles.1", startup);
+ }
+ } else {
+ String linkID = "linux.Debug_Build.gnuc++.g++link";
+ writeLdArgs(writer, linkID, linkConfig.getPreArguments());
+ writeLdArgs(writer, linkID, linkConfig.getEndArguments());
+ }
+ }
+ }
+ }
+
+ /**
+ * Writes ld linker options to project file.
+ *
+ * @param writer PropertyWriter property writer
+ * @param linkID String linker identifier
+ * @param preArgs String[] linker arguments
+ * @throws SAXException thrown if unable to write option
+ */
+ private void writeLdArgs(final PropertyWriter writer,
+ final String linkID,
+ final String[] preArgs) throws SAXException {
+ int objnameIndex = 1;
+ int libnameIndex = 1;
+ int libpathIndex = 1;
+ for (int i = 0; i < preArgs.length; i++) {
+ if (preArgs[i].startsWith("-o")) {
+ writer.write(linkID,
+ "option.o.arg."
+ + (objnameIndex++), preArgs[i]
+ .substring(2));
+ } else if (preArgs[i].startsWith("-l")) {
+ writer.write(linkID,
+ "option.l.arg."
+ + (libnameIndex++), preArgs[i]
+ .substring(2));
+ } else if (preArgs[i].startsWith("-L")) {
+ writer.write(linkID,
+ "option.L.arg."
+ + (libpathIndex++), preArgs[i]
+ .substring(2));
+ } else {
+ //
+ // any others
+ //
+ writer.write(linkID, "option." + preArgs[i].substring(1) + ".enabled",
+ "1");
+ }
+ }
+ if (objnameIndex > 1) {
+ writer.write(linkID,
+ "option.o.enabled",
+ "1");
+ }
+ if (libnameIndex > 1) {
+ writer.write(linkID,
+ "option.l.enabled",
+ "1");
+ }
+ if (libpathIndex > 1) {
+ writer.write(linkID,
+ "option.L.enabled",
+ "1");
+ }
+ }
+
+ /**
+ * Writes ilink32 linker options to project file.
+ *
+ * @param writer PropertyWriter property writer
+ * @param linkID String linker identifier
+ * @param preArgs String[] linker arguments
+ * @throws SAXException thrown if unable to write option
+ */
+ private void writeIlinkArgs(final PropertyWriter writer,
+ final String linkID,
+ final String[] args) throws SAXException {
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].charAt(0) == '/' || args[i].charAt(0) == '-') {
+ int equalsPos = args[i].indexOf('=');
+ if (equalsPos > 0) {
+ String option = "option." + args[i].substring(0, equalsPos -1);
+ writer.write(linkID,
+ option + ".enabled",
+ "1");
+ writer.write(linkID,
+ option + ".value",
+ args[i].substring(equalsPos + 1));
+ } else {
+ writer.write(linkID, "option." + args[i].substring(1) + ".enabled", "1");
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/CfgFilenameState.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/CfgFilenameState.java
new file mode 100644
index 0000000..82767cb
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/CfgFilenameState.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.borland;
+import net.sf.antcontrib.cpptasks.parser.AbstractParser;
+import net.sf.antcontrib.cpptasks.parser.AbstractParserState;
+import net.sf.antcontrib.cpptasks.parser.FilenameState;
+public class CfgFilenameState extends FilenameState {
+ private char terminator;
+ public CfgFilenameState(AbstractParser parser, char[] terminators) {
+ super(parser, terminators);
+ terminator = terminators[0];
+ }
+ public AbstractParserState consume(char ch) {
+ //
+ // if a ';' is encountered then
+ // close the previous filename by sending a
+ // recognized terminator to our super class
+ // and stay in this state for more filenamese
+ if (ch == ';') {
+ super.consume(terminator);
+ return this;
+ }
+ AbstractParserState newState = super.consume(ch);
+ //
+ // change null (consume to end of line)
+ // to look for next switch character
+ if (newState == null) {
+ newState = getParser().getNewLineState();
+ }
+ return newState;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/ConsumeToSpaceOrNewLine.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/ConsumeToSpaceOrNewLine.java
new file mode 100644
index 0000000..5656af8
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/ConsumeToSpaceOrNewLine.java
@@ -0,0 +1,30 @@
+/*
+ *
+ * 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.borland;
+import net.sf.antcontrib.cpptasks.parser.AbstractParser;
+import net.sf.antcontrib.cpptasks.parser.AbstractParserState;
+public class ConsumeToSpaceOrNewLine extends AbstractParserState {
+ public ConsumeToSpaceOrNewLine(AbstractParser parser) {
+ super(parser);
+ }
+ public AbstractParserState consume(char ch) {
+ if (ch == ' ' || ch == '\t' || ch == '\n') {
+ return getParser().getNewLineState();
+ }
+ return this;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/QuoteBranchState.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/QuoteBranchState.java
new file mode 100644
index 0000000..ec3bc84
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/QuoteBranchState.java
@@ -0,0 +1,35 @@
+/*
+ *
+ * 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.borland;
+import net.sf.antcontrib.cpptasks.parser.AbstractParser;
+import net.sf.antcontrib.cpptasks.parser.AbstractParserState;
+public class QuoteBranchState extends AbstractParserState {
+ private AbstractParserState quote;
+ private AbstractParserState unquote;
+ public QuoteBranchState(AbstractParser parser, AbstractParserState quote,
+ AbstractParserState unquote) {
+ super(parser);
+ this.quote = quote;
+ this.unquote = unquote;
+ }
+ public AbstractParserState consume(char ch) {
+ if (ch == '"') {
+ return quote;
+ }
+ return unquote.consume(ch);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/package.html b/src/main/java/net/sf/antcontrib/cpptasks/borland/package.html
new file mode 100644
index 0000000..a91e91f
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/package.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+Copyright 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.
+
+-->
+</head>
+<body bgcolor="white">
+
+Adapter for Borland tools.
+</body>
+</html>
+
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranCompiler.java
new file mode 100644
index 0000000..1595ae1
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranCompiler.java
@@ -0,0 +1,137 @@
+/*
+ *
+ * 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.compaq;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineFortranCompiler;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for the Compaq(r) Visual Fortran compiler.
+ *
+ * @author Curt Arnold
+ */
+public class CompaqVisualFortranCompiler extends CommandLineFortranCompiler {
+ private static final CompaqVisualFortranCompiler[] instance = new CompaqVisualFortranCompiler[]{new CompaqVisualFortranCompiler(
+ false, null)};
+ public static CompaqVisualFortranCompiler getInstance() {
+ return instance[0];
+ }
+ private CompaqVisualFortranCompiler(boolean newEnvironment, Environment env) {
+ super("DF", null, new String[]{".f90", ".for", ".f"}, new String[]{
+ ".i", ".i90", ".fpp", ".inc", ".bak", ".exe"}, ".obj", false,
+ null, newEnvironment, env);
+ }
+ protected void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ args.addElement("/nologo");
+ args.addElement("/compile_only");
+ if (debug) {
+ args.addElement("/debug:full");
+ args.addElement("/define:_DEBUG");
+ } else {
+ args.addElement("/debug:none");
+ args.addElement("/define:NDEBUG");
+ }
+ if (multithreaded) {
+ args.addElement("/threads");
+ args.addElement("/define:_MT");
+ } else {
+ args.addElement("/nothreads");
+ }
+ boolean staticRuntime = linkType.isStaticRuntime();
+ if (staticRuntime) {
+ args.addElement("/libs:static");
+ } else {
+ args.addElement("/libs:dll");
+ }
+ if (linkType.isSharedLibrary()) {
+ args.addElement("/dll");
+ args.addElement("/define:_DLL");
+ }
+ }
+ public void addWarningSwitch(Vector args, int level) {
+ switch (level) {
+ case 0 :
+ args.addElement("/nowarn");
+ break;
+ case 1 :
+ break;
+ case 2 :
+ break;
+ case 3 :
+ args.addElement("/warn:usage");
+ break;
+ case 4 :
+ args.addElement("/warn:all");
+ break;
+ case 5 :
+ args.addElement("/warn:errors");
+ break;
+ }
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new CompaqVisualFortranCompiler(newEnvironment, env);
+ }
+ return this;
+ }
+ protected void getDefineSwitch(StringBuffer buf, String define, String value) {
+ buf.append("/define:");
+ buf.append(define);
+ if (value != null && value.length() > 0) {
+ buf.append('=');
+ buf.append(value);
+ }
+ }
+ protected File[] getEnvironmentIncludePath() {
+ return CUtil.getPathFromEnvironment("INCLUDE", ";");
+ }
+ protected String getIncludeDirSwitch(String includeDir) {
+ StringBuffer buf = new StringBuffer("/include:");
+ if (includeDir.indexOf(' ') >= 0) {
+ buf.append('"');
+ buf.append(includeDir);
+ buf.append('"');
+ } else {
+ buf.append(includeDir);
+ }
+ return buf.toString();
+ }
+ public Linker getLinker(LinkType type) {
+ return CompaqVisualFortranLinker.getInstance().getLinker(type);
+ }
+ public int getMaximumCommandLength() {
+ return 1024;
+ }
+ protected void getUndefineSwitch(StringBuffer buf, String define) {
+ buf.append("/undefine:");
+ buf.append(define);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLibrarian.java
new file mode 100644
index 0000000..2488619
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLibrarian.java
@@ -0,0 +1,82 @@
+/*
+ *
+ * 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.compaq;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.devstudio.DevStudioLibrarian;
+import net.sf.antcontrib.cpptasks.devstudio.DevStudioProcessor;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+
+/**
+ * Adapter for the Compaq(r) Visual Fortran Librarian
+ *
+ * @author Curt Arnold
+ */
+public class CompaqVisualFortranLibrarian extends CommandLineLinker {
+ private static final CompaqVisualFortranLibrarian instance = new CompaqVisualFortranLibrarian();
+ public static CompaqVisualFortranLibrarian getInstance() {
+ return instance;
+ }
+ private CompaqVisualFortranLibrarian() {
+ super("lib", "/bogus", new String[]{".obj"}, new String[0], ".lib",
+ false, null);
+ }
+ protected void addBase(long base, Vector args) {
+ }
+ protected void addFixed(Boolean fixed, Vector args) {
+ }
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ args.addElement("/nologo");
+ }
+ protected void addIncremental(boolean incremental, Vector args) {
+ }
+ protected void addMap(boolean map, Vector args) {
+ }
+ protected void addStack(int stack, Vector args) {
+ }
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)
+ */
+ protected void addEntry(String entry, Vector args) {
+ }
+
+ protected String getCommandFileSwitch(String commandFile) {
+ return DevStudioProcessor.getCommandFileSwitch(commandFile);
+ }
+ public File[] getLibraryPath() {
+ return new File[0];
+ }
+ public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {
+ return new String[0];
+ }
+ public Linker getLinker(LinkType type) {
+ return CompaqVisualFortranLinker.getInstance().getLinker(type);
+ }
+ protected int getMaximumCommandLength() {
+ return DevStudioLibrarian.getInstance().getMaximumCommandLength();
+ }
+ protected String[] getOutputFileSwitch(String outputFile) {
+ return DevStudioLibrarian.getInstance().getOutputFileSwitch(outputFile);
+ }
+ public boolean isCaseSensitive() {
+ return false;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLinker.java
new file mode 100644
index 0000000..c8930f9
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLinker.java
@@ -0,0 +1,77 @@
+/*
+ *
+ * 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.compaq;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.devstudio.DevStudioCompatibleLinker;
+/**
+ * Adapter for the Compaq(r) Visual Fortran linker.
+ *
+ * @author Curt Arnold
+ */
+public final class CompaqVisualFortranLinker extends DevStudioCompatibleLinker {
+ private static final CompaqVisualFortranLinker dllLinker = new CompaqVisualFortranLinker(
+ ".dll");
+ private static final CompaqVisualFortranLinker instance = new CompaqVisualFortranLinker(
+ ".exe");
+ public static CompaqVisualFortranLinker getInstance() {
+ return instance;
+ }
+ private CompaqVisualFortranLinker(String outputSuffix) {
+ super("DF", "__bogus__.xxx", outputSuffix);
+ }
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ args.addElement("/NOLOGO");
+ boolean staticRuntime = linkType.isStaticRuntime();
+ if (staticRuntime) {
+ args.addElement("/libs:static");
+ } else {
+ args.addElement("/libs:dll");
+ }
+ if (debug) {
+ args.addElement("/debug");
+ } else {
+ }
+ if (linkType.isSharedLibrary()) {
+ args.addElement("/dll");
+ } else {
+ args.addElement("/exe");
+ }
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return CompaqVisualFortranLibrarian.getInstance();
+ }
+ if (type.isSharedLibrary()) {
+ return dllLinker;
+ }
+ return instance;
+ }
+ public String[] getOutputFileSwitch(String outputFile) {
+ StringBuffer buf = new StringBuffer("/OUT:");
+ if (outputFile.indexOf(' ') >= 0) {
+ buf.append('"');
+ buf.append(outputFile);
+ buf.append('"');
+ } else {
+ buf.append(outputFile);
+ }
+ return new String[]{buf.toString()};
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractCompiler.java
new file mode 100644
index 0000000..2d1401f
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractCompiler.java
@@ -0,0 +1,207 @@
+/*
+ *
+ * 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.compiler;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Vector;
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.CompilerDef;
+import net.sf.antcontrib.cpptasks.DependencyInfo;
+import net.sf.antcontrib.cpptasks.ProcessorDef;
+import net.sf.antcontrib.cpptasks.parser.Parser;
+import net.sf.antcontrib.cpptasks.TargetDef;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+
+/**
+ * An abstract compiler implementation.
+ *
+ * @author Adam Murdoch
+ * @author Curt Arnold
+ */
+public abstract class AbstractCompiler extends AbstractProcessor
+ implements
+ Compiler {
+ private static final String[] emptyIncludeArray = new String[0];
+ private String outputSuffix;
+ protected AbstractCompiler(String[] sourceExtensions,
+ String[] headerExtensions, String outputSuffix) {
+ super(sourceExtensions, headerExtensions);
+ this.outputSuffix = outputSuffix;
+ }
+ /**
+ * Checks file name to see if parse should be attempted
+ *
+ * Default implementation returns false for files with extensions '.dll',
+ * 'tlb', '.res'
+ *
+ */
+ protected boolean canParse(File sourceFile) {
+ String sourceName = sourceFile.toString();
+ int lastPeriod = sourceName.lastIndexOf('.');
+ if (lastPeriod >= 0 && lastPeriod == sourceName.length() - 4) {
+ String ext = sourceName.substring(lastPeriod).toUpperCase();
+ if (ext.equals(".DLL") || ext.equals(".TLB") || ext.equals(".RES")) {
+ return false;
+ }
+ }
+ return true;
+ }
+ abstract protected CompilerConfiguration createConfiguration(CCTask task,
+ LinkType linkType, ProcessorDef[] baseConfigs,
+ CompilerDef specificConfig, TargetDef targetPlatform,
+ VersionInfo versionInfo);
+ public ProcessorConfiguration createConfiguration(CCTask task,
+ LinkType linkType, ProcessorDef[] baseConfigs,
+ ProcessorDef specificConfig, TargetDef targetPlatform,
+ VersionInfo versionInfo) {
+ if (specificConfig == null) {
+ throw new NullPointerException("specificConfig");
+ }
+ return createConfiguration(task, linkType, baseConfigs,
+ (CompilerDef) specificConfig, targetPlatform, versionInfo);
+ }
+ abstract protected Parser createParser(File sourceFile);
+ protected String getBaseOutputName(String inputFile) {
+ int lastSlash = inputFile.lastIndexOf('/');
+ int lastReverse = inputFile.lastIndexOf('\\');
+ int lastSep = inputFile.lastIndexOf(File.separatorChar);
+ if (lastReverse > lastSlash) {
+ lastSlash = lastReverse;
+ }
+ if (lastSep > lastSlash) {
+ lastSlash = lastSep;
+ }
+ int lastPeriod = inputFile.lastIndexOf('.');
+ if (lastPeriod < 0) {
+ lastPeriod = inputFile.length();
+ }
+ return inputFile.substring(lastSlash + 1, lastPeriod);
+ }
+ public String[] getOutputFileNames(String inputFile, VersionInfo versionInfo) {
+ //
+ // if a recognized input file
+ //
+ if (bid(inputFile) > 1) {
+ String baseName = getBaseOutputName(inputFile);
+ return new String[] { baseName + outputSuffix };
+ }
+ return new String[0];
+ }
+ /**
+ * Returns dependency info for the specified source file
+ *
+ * @param task
+ * task for any diagnostic output
+ * @param source
+ * file to be parsed
+ * @param includePath
+ * include path to be used to resolve included files
+ *
+ * @param sysIncludePath
+ * sysinclude path from build file, files resolved using
+ * sysInclude path will not participate in dependency analysis
+ *
+ * @param envIncludePath
+ * include path from environment variable, files resolved with
+ * envIncludePath will not participate in dependency analysis
+ *
+ * @param baseDir
+ * used to produce relative paths in DependencyInfo
+ * @param includePathIdentifier
+ * used to distinguish DependencyInfo's from different include
+ * path settings
+ *
+ */
+ public final DependencyInfo parseIncludes(CCTask task, File source,
+ File[] includePath, File[] sysIncludePath, File[] envIncludePath,
+ File baseDir, String includePathIdentifier) {
+ //
+ // if any of the include files can not be identified
+ // change the sourceLastModified to Long.MAX_VALUE to
+ // force recompilation of anything that depends on it
+ long sourceLastModified = source.lastModified();
+ File[] sourcePath = new File[1];
+ sourcePath[0] = new File(source.getParent());
+ Vector onIncludePath = new Vector();
+ Vector onSysIncludePath = new Vector();
+ String baseDirPath;
+ try {
+ baseDirPath = baseDir.getCanonicalPath();
+ } catch (IOException ex) {
+ baseDirPath = baseDir.toString();
+ }
+ String relativeSource = CUtil.getRelativePath(baseDirPath, source);
+ String[] includes = emptyIncludeArray;
+ if (canParse(source)) {
+ Parser parser = createParser(source);
+ try {
+ Reader reader = new BufferedReader(new FileReader(source));
+ parser.parse(reader);
+ includes = parser.getIncludes();
+ } catch (IOException ex) {
+ task.log("Error parsing " + source.toString() + ":"
+ + ex.toString());
+ includes = new String[0];
+ }
+ }
+ for (int i = 0; i < includes.length; i++) {
+ String includeName = includes[i];
+ if (!resolveInclude(includeName, sourcePath, onIncludePath)) {
+ if (!resolveInclude(includeName, includePath, onIncludePath)) {
+ if (!resolveInclude(includeName, sysIncludePath,
+ onSysIncludePath)) {
+ if (!resolveInclude(includeName, envIncludePath,
+ onSysIncludePath)) {
+ //
+ // this should be enough to require us to reparse
+ // the file with the missing include for dependency
+ // information without forcing a rebuild
+ sourceLastModified += 2 * CUtil.FILETIME_EPSILON;
+ }
+ }
+ }
+ }
+ }
+ for (int i = 0; i < onIncludePath.size(); i++) {
+ String relativeInclude = CUtil.getRelativePath(baseDirPath,
+ (File) onIncludePath.elementAt(i));
+ onIncludePath.setElementAt(relativeInclude, i);
+ }
+ for (int i = 0; i < onSysIncludePath.size(); i++) {
+ String relativeInclude = CUtil.getRelativePath(baseDirPath,
+ (File) onSysIncludePath.elementAt(i));
+ onSysIncludePath.setElementAt(relativeInclude, i);
+ }
+ return new DependencyInfo(includePathIdentifier, relativeSource,
+ sourceLastModified, onIncludePath, onSysIncludePath);
+ }
+ protected boolean resolveInclude(String includeName, File[] includePath,
+ Vector onThisPath) {
+ for (int i = 0; i < includePath.length; i++) {
+ File includeFile = new File(includePath[i], includeName);
+ if (includeFile.exists()) {
+ onThisPath.addElement(includeFile);
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractLinker.java
new file mode 100644
index 0000000..5d9cefa
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractLinker.java
@@ -0,0 +1,122 @@
+/*
+ *
+ * Copyright 2001-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.compiler;
+import java.io.File;
+import java.io.IOException;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.LinkerDef;
+import net.sf.antcontrib.cpptasks.ProcessorDef;
+import net.sf.antcontrib.cpptasks.TargetDef;
+import net.sf.antcontrib.cpptasks.TargetMatcher;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * An abstract Linker implementation.
+ *
+ * @author Adam Murdoch
+ */
+public abstract class AbstractLinker extends AbstractProcessor
+ implements
+ Linker {
+ public AbstractLinker(String[] objExtensions, String[] ignoredExtensions) {
+ super(objExtensions, ignoredExtensions);
+ }
+ /**
+ * Returns the bid of the processor for the file.
+ *
+ * A linker will bid 1 on any unrecognized file type.
+ *
+ * @param inputFile
+ * filename of input file
+ * @return bid for the file, 0 indicates no interest, 1 indicates that the
+ * processor recognizes the file but doesn't process it (header
+ * files, for example), 100 indicates strong interest
+ */
+ public int bid(String inputFile) {
+ int bid = super.bid(inputFile);
+ switch (bid) {
+ //
+ // unrecognized extension, take the file
+ //
+ case 0 :
+ return 1;
+ //
+ // discard the ignored extensions
+ //
+ case 1 :
+ return 0;
+ }
+ return bid;
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ return this;
+ }
+ abstract protected LinkerConfiguration createConfiguration(CCTask task,
+ LinkType linkType, ProcessorDef[] baseConfigs,
+ LinkerDef specificConfig, TargetDef targetPlatform,
+ VersionInfo versionInfo);
+ public ProcessorConfiguration createConfiguration(CCTask task,
+ LinkType linkType, ProcessorDef[] baseConfigs,
+ ProcessorDef specificConfig,
+ TargetDef targetPlatform,
+ VersionInfo versionInfo) {
+ if (specificConfig == null) {
+ throw new NullPointerException("specificConfig");
+ }
+ return createConfiguration(task, linkType, baseConfigs,
+ (LinkerDef) specificConfig, targetPlatform, versionInfo);
+ }
+ public String getLibraryKey(File libfile) {
+ return libfile.getName();
+ }
+ public abstract String[] getOutputFileNames(String fileName, VersionInfo versionInfo);
+
+
+ /**
+ * Adds source or object files to the bidded fileset to
+ * support version information.
+ *
+ * @param versionInfo version information
+ * @param linkType link type
+ * @param isDebug true if debug build
+ * @param outputFile name of generated executable
+ * @param objDir directory for generated files
+ * @param matcher bidded fileset
+ */
+ public void addVersionFiles(final VersionInfo versionInfo,
+ final LinkType linkType,
+ final File outputFile,
+ final boolean isDebug,
+ final File objDir,
+ final TargetMatcher matcher) throws IOException {
+ if (versionInfo == null) {
+ throw new NullPointerException("versionInfo");
+ }
+ if (linkType == null) {
+ throw new NullPointerException("linkType");
+ }
+ if (outputFile == null) {
+ throw new NullPointerException("outputFile");
+ }
+ if (objDir == null) {
+ throw new NullPointerException("objDir");
+ }
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractProcessor.java
new file mode 100644
index 0000000..d0cd77b
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractProcessor.java
@@ -0,0 +1,129 @@
+/*
+ *
+ * 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.compiler;
+import org.apache.tools.ant.types.Environment;
+/**
+ * An abstract processor (compiler/linker) implementation.
+ *
+ * @author Curt Arnold
+ */
+public abstract class AbstractProcessor implements Processor, Cloneable {
+ /**
+ * default bid for a file name that the processor recognizes but does not
+ * process and does not want to fall through to the linker
+ */
+ public final static int DEFAULT_DISCARD_BID = 1;
+ /**
+ * default bid for a file name that the processor desires to process
+ */
+ public final static int DEFAULT_PROCESS_BID = 100;
+ /**
+ * Determines the identification of a command line processor by capture the
+ * first line of its output for a specific command.
+ *
+ * @param command
+ * array of command line arguments starting with executable
+ * name. For example, { "cl" }
+ * @param fallback
+ * start of identifier if there is an error in executing the
+ * command
+ * @return identifier for the processor
+ */
+ protected static String getIdentifier(String[] command, String fallback) {
+ String identifier = fallback;
+ try {
+ String[] cmdout = CaptureStreamHandler.run(command);
+ if (cmdout.length > 0) {
+ identifier = cmdout[0];
+ }
+ } catch (Throwable ex) {
+ identifier = fallback + ":" + ex.toString();
+ }
+ return identifier;
+ }
+ private final String[] headerExtensions;
+ private final String[] sourceExtensions;
+ protected AbstractProcessor(String[] sourceExtensions,
+ String[] headerExtensions) {
+ this.sourceExtensions = (String[]) sourceExtensions.clone();
+ this.headerExtensions = (String[]) headerExtensions.clone();
+ }
+ /**
+ * Returns the bid of the processor for the file.
+ *
+ * @param inputFile
+ * filename of input file
+ * @return bid for the file, 0 indicates no interest, 1 indicates that the
+ * processor recognizes the file but doesn't process it (header
+ * files, for example), 100 indicates strong interest
+ */
+ public int bid(String inputFile) {
+ String lower = inputFile.toLowerCase();
+ for (int i = 0; i < sourceExtensions.length; i++) {
+ if (lower.endsWith(sourceExtensions[i])) {
+ return DEFAULT_PROCESS_BID;
+ }
+ }
+ for (int i = 0; i < headerExtensions.length; i++) {
+ if (lower.endsWith(headerExtensions[i])) {
+ return DEFAULT_DISCARD_BID;
+ }
+ }
+ return 0;
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ return this;
+ }
+ protected Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+ public String[] getHeaderExtensions() {
+ return (String[]) this.headerExtensions.clone();
+ }
+ abstract public String getIdentifier();
+ /**
+ * Gets the target operating system architecture
+ *
+ * @return String target operating system architecture
+ */
+ protected String getOSArch() {
+ return System.getProperty("os.arch");
+ }
+ /**
+ * Gets the target operating system name
+ *
+ * @return String target operating system name
+ */
+ protected String getOSName() {
+ return System.getProperty("os.name");
+ }
+ public String[] getSourceExtensions() {
+ return (String[]) this.sourceExtensions.clone();
+ }
+ /**
+ * Returns true if the target operating system is Mac OS X or Darwin.
+ *
+ * @return boolean
+ */
+ protected boolean isDarwin() {
+ String osName = getOSName();
+ return "Mac OS X".equals(osName);
+ }
+ public final String toString() {
+ return getIdentifier();
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CaptureStreamHandler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CaptureStreamHandler.java
new file mode 100644
index 0000000..83c59f7
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CaptureStreamHandler.java
@@ -0,0 +1,122 @@
+/*
+ *
+ * Copyright 2001-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.compiler;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.Vector;
+
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
+/**
+ * Implements ExecuteStreamHandler to capture the output of a Execute to an
+ * array of strings
+ *
+ * @author Curt Arnold
+ */
+public class CaptureStreamHandler implements ExecuteStreamHandler {
+ /**
+ * Runs an executable and captures the output in a String array
+ *
+ * @param cmdline
+ * command line arguments
+ * @return output of process
+ */
+ public static String[] run(String[] cmdline) {
+ CaptureStreamHandler handler = new CaptureStreamHandler();
+ Execute exec = new Execute(handler);
+ exec.setCommandline(cmdline);
+ try {
+ int status = exec.execute();
+ } catch (IOException ex) {
+ }
+ return handler.getOutput();
+ }
+ private InputStream errorStream;
+ private InputStream fromProcess;
+ public CaptureStreamHandler() {
+ }
+ public String[] getOutput() {
+ String[] output;
+ if (fromProcess != null) {
+ Vector lines = new Vector(10);
+ try {
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(errorStream));
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < 100; j++) {
+ String line = reader.readLine();
+ if (line == null) {
+ reader = new BufferedReader(new InputStreamReader(
+ fromProcess));
+ break;
+ }
+ lines.addElement(line);
+ }
+ }
+ } catch (IOException ex) {
+ }
+ output = new String[lines.size()];
+ lines.copyInto(output);
+ return output;
+ }
+ output = new String[0];
+ return output;
+ }
+ /**
+ * Install a handler for the error stream of the subprocess.
+ *
+ * @param is
+ * input stream to read from the error stream from the
+ * subprocess
+ */
+ public void setProcessErrorStream(InputStream is) throws IOException {
+ errorStream = is;
+ }
+ /**
+ * Install a handler for the input stream of the subprocess.
+ *
+ * @param os
+ * output stream to write to the standard input stream of the
+ * subprocess
+ */
+ public void setProcessInputStream(OutputStream os) throws IOException {
+ os.close();
+ }
+ /**
+ * Install a handler for the output stream of the subprocess.
+ *
+ * @param is
+ * input stream to read from the error stream from the
+ * subprocess
+ */
+ public void setProcessOutputStream(InputStream is) throws IOException {
+ fromProcess = is;
+ }
+ /**
+ * Start handling of the streams.
+ */
+ public void start() throws IOException {
+ }
+ /**
+ * Stop handling of the streams - will not be restarted.
+ */
+ public void stop() {
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCCompiler.java
new file mode 100644
index 0000000..adafa08
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCCompiler.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.compiler;
+import java.io.File;
+
+import net.sf.antcontrib.cpptasks.parser.CParser;
+import net.sf.antcontrib.cpptasks.parser.Parser;
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * An abstract Compiler implementation which uses an external program to
+ * perform the compile.
+ *
+ * @author Adam Murdoch
+ */
+public abstract class CommandLineCCompiler extends CommandLineCompiler {
+ protected CommandLineCCompiler(String command, String identifierArg,
+ String[] sourceExtensions, String[] headerExtensions,
+ String outputSuffix, boolean libtool,
+ CommandLineCCompiler libtoolCompiler, boolean newEnvironment,
+ Environment env) {
+ super(command, identifierArg, sourceExtensions, headerExtensions,
+ outputSuffix, libtool, libtoolCompiler, newEnvironment, env);
+ }
+ protected Parser createParser(File source) {
+ return new CParser();
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCompiler.java
new file mode 100644
index 0000000..46ec59a
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCompiler.java
@@ -0,0 +1,437 @@
+/*
+ *
+ * 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.compiler;
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.CompilerDef;
+import net.sf.antcontrib.cpptasks.ProcessorDef;
+import net.sf.antcontrib.cpptasks.ProcessorParam;
+import net.sf.antcontrib.cpptasks.types.CommandLineArgument;
+import net.sf.antcontrib.cpptasks.types.UndefineArgument;
+import net.sf.antcontrib.cpptasks.TargetDef;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Environment;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;;
+/**
+ * An abstract Compiler implementation which uses an external program to
+ * perform the compile.
+ *
+ * @author Adam Murdoch
+ */
+public abstract class CommandLineCompiler extends AbstractCompiler {
+ private String command;
+ private final Environment env;
+ private String identifier;
+ private String identifierArg;
+ private boolean libtool;
+ private CommandLineCompiler libtoolCompiler;
+ private final boolean newEnvironment;
+ protected CommandLineCompiler(String command, String identifierArg,
+ String[] sourceExtensions, String[] headerExtensions,
+ String outputSuffix, boolean libtool,
+ CommandLineCompiler libtoolCompiler, boolean newEnvironment,
+ Environment env) {
+ super(sourceExtensions, headerExtensions, outputSuffix);
+ this.command = command;
+ if (libtool && libtoolCompiler != null) {
+ throw new java.lang.IllegalArgumentException(
+ "libtoolCompiler should be null when libtool is true");
+ }
+ this.libtool = libtool;
+ this.libtoolCompiler = libtoolCompiler;
+ this.identifierArg = identifierArg;
+ this.newEnvironment = newEnvironment;
+ this.env = env;
+ }
+ abstract protected void addImpliedArgs(Vector args, boolean debug,
+ boolean multithreaded, boolean exceptions, LinkType linkType,
+ Boolean rtti, OptimizationEnum optimization);
+ /**
+ * Adds command-line arguments for include directories.
+ *
+ * If relativeArgs is not null will add corresponding relative paths
+ * include switches to that vector (for use in building a configuration
+ * identifier that is consistent between machines).
+ *
+ * @param baseDirPath Base directory path.
+ * @param includeDirs
+ * Array of include directory paths
+ * @param args
+ * Vector of command line arguments used to execute the task
+ * @param relativeArgs
+ * Vector of command line arguments used to build the
+ * configuration identifier
+ */
+ protected void addIncludes(String baseDirPath, File[] includeDirs,
+ Vector args, Vector relativeArgs, StringBuffer includePathId) {
+ for (int i = 0; i < includeDirs.length; i++) {
+ args.addElement(getIncludeDirSwitch(includeDirs[i]
+ .getAbsolutePath()));
+ if (relativeArgs != null) {
+ String relative = CUtil.getRelativePath(baseDirPath,
+ includeDirs[i]);
+ relativeArgs.addElement(getIncludeDirSwitch(relative));
+ if (includePathId != null) {
+ if (includePathId.length() == 0) {
+ includePathId.append("/I");
+ } else {
+ includePathId.append(" /I");
+ }
+ includePathId.append(relative);
+ }
+ }
+ }
+ }
+ abstract protected void addWarningSwitch(Vector args, int warnings);
+ protected void buildDefineArguments(CompilerDef[] defs, Vector args) {
+ //
+ // assume that we aren't inheriting defines from containing <cc>
+ //
+ UndefineArgument[] merged = defs[0].getActiveDefines();
+ for (int i = 1; i < defs.length; i++) {
+ //
+ // if we are inheriting, merge the specific defines with the
+ // containing defines
+ merged = UndefineArgument.merge(defs[i].getActiveDefines(), merged);
+ }
+ StringBuffer buf = new StringBuffer(30);
+ for (int i = 0; i < merged.length; i++) {
+ buf.setLength(0);
+ UndefineArgument current = merged[i];
+ if (current.isDefine()) {
+ getDefineSwitch(buf, current.getName(), current.getValue());
+ } else {
+ getUndefineSwitch(buf, current.getName());
+ }
+ args.addElement(buf.toString());
+ }
+ }
+ /**
+ * Compiles a source file.
+ *
+ */
+ public void compile(CCTask task, File outputDir, String[] sourceFiles,
+ String[] args, String[] endArgs, boolean relentless,
+ CommandLineCompilerConfiguration config, ProgressMonitor monitor)
+ throws BuildException {
+ BuildException exc = null;
+ //
+ // determine length of executable name and args
+ //
+ String command = getCommand();
+ int baseLength = command.length() + args.length + endArgs.length;
+ if (libtool) {
+ baseLength += 8;
+ }
+ for (int i = 0; i < args.length; i++) {
+ baseLength += args[i].length();
+ }
+ for (int i = 0; i < endArgs.length; i++) {
+ baseLength += endArgs[i].length();
+ }
+ if (baseLength > getMaximumCommandLength()) {
+ throw new BuildException(
+ "Command line is over maximum length without specifying source file");
+ }
+ //
+ // typically either 1 or Integer.MAX_VALUE
+ //
+ int maxInputFilesPerCommand = getMaximumInputFilesPerCommand();
+ int argumentCountPerInputFile = getArgumentCountPerInputFile();
+ for (int sourceIndex = 0; sourceIndex < sourceFiles.length;) {
+ int cmdLength = baseLength;
+ int firstFileNextExec;
+ for (firstFileNextExec = sourceIndex; firstFileNextExec < sourceFiles.length
+ && (firstFileNextExec - sourceIndex) < maxInputFilesPerCommand; firstFileNextExec++) {
+ cmdLength += getTotalArgumentLengthForInputFile(outputDir,
+ sourceFiles[firstFileNextExec]);
+ if (cmdLength >= getMaximumCommandLength())
+ break;
+ }
+ if (firstFileNextExec == sourceIndex) {
+ throw new BuildException(
+ "Extremely long file name, can't fit on command line");
+ }
+ int argCount = args.length + 1 + endArgs.length
+ + (firstFileNextExec - sourceIndex)
+ * argumentCountPerInputFile;
+ if (libtool) {
+ argCount++;
+ }
+ String[] commandline = new String[argCount];
+ int index = 0;
+ if (libtool) {
+ commandline[index++] = "libtool";
+ }
+ commandline[index++] = command;
+ for (int j = 0; j < args.length; j++) {
+ commandline[index++] = args[j];
+ }
+ for (int j = sourceIndex; j < firstFileNextExec; j++) {
+ for (int k = 0; k < argumentCountPerInputFile; k++) {
+ commandline[index++] = getInputFileArgument(outputDir,
+ sourceFiles[j], k);
+ }
+ }
+ for (int j = 0; j < endArgs.length; j++) {
+ commandline[index++] = endArgs[j];
+ }
+ int retval = runCommand(task, outputDir, commandline);
+ if (monitor != null) {
+ String[] fileNames = new String[firstFileNextExec - sourceIndex];
+ for (int j = 0; j < fileNames.length; j++) {
+ fileNames[j] = sourceFiles[sourceIndex + j];
+ }
+ monitor.progress(fileNames);
+ }
+ //
+ // if the process returned a failure code and
+ // we aren't holding an exception from an earlier
+ // interation
+ if (retval != 0 && exc == null) {
+ //
+ // construct the exception
+ //
+ exc = new BuildException(this.getCommand()
+ + " failed with return code " + retval, task
+ .getLocation());
+ //
+ // and throw it now unless we are relentless
+ //
+ if (!relentless) {
+ throw exc;
+ }
+ }
+ sourceIndex = firstFileNextExec;
+ }
+ //
+ // if the compiler returned a failure value earlier
+ // then throw an exception
+ if (exc != null) {
+ throw exc;
+ }
+ }
+ protected CompilerConfiguration createConfiguration(final CCTask task,
+ final LinkType linkType,
+ final ProcessorDef[] baseDefs,
+ final CompilerDef specificDef,
+ final TargetDef targetPlatform,
+ final VersionInfo versionInfo) {
+ Vector args = new Vector();
+ CompilerDef[] defaultProviders = new CompilerDef[baseDefs.length + 1];
+ for (int i = 0; i < baseDefs.length; i++) {
+ defaultProviders[i + 1] = (CompilerDef) baseDefs[i];
+ }
+ defaultProviders[0] = specificDef;
+ Vector cmdArgs = new Vector();
+ //
+ // add command line arguments inherited from <cc> element
+ // any "extends" and finally the specific CompilerDef
+ CommandLineArgument[] commandArgs;
+ for (int i = defaultProviders.length - 1; i >= 0; i--) {
+ commandArgs = defaultProviders[i].getActiveProcessorArgs();
+ for (int j = 0; j < commandArgs.length; j++) {
+ if (commandArgs[j].getLocation() == 0) {
+ args.addElement(commandArgs[j].getValue());
+ } else {
+ cmdArgs.addElement(commandArgs[j]);
+ }
+ }
+ }
+ Vector params = new Vector();
+ //
+ // add command line arguments inherited from <cc> element
+ // any "extends" and finally the specific CompilerDef
+ ProcessorParam[] paramArray;
+ for (int i = defaultProviders.length - 1; i >= 0; i--) {
+ paramArray = defaultProviders[i].getActiveProcessorParams();
+ for (int j = 0; j < paramArray.length; j++) {
+ params.add(paramArray[j]);
+ }
+ }
+ paramArray = (ProcessorParam[]) (params
+ .toArray(new ProcessorParam[params.size()]));
+ boolean multithreaded = specificDef.getMultithreaded(defaultProviders,
+ 1);
+ boolean debug = specificDef.getDebug(baseDefs, 0);
+ boolean exceptions = specificDef.getExceptions(defaultProviders, 1);
+ Boolean rtti = specificDef.getRtti(defaultProviders, 1);
+ OptimizationEnum optimization = specificDef.getOptimization(defaultProviders, 1);
+ this.addImpliedArgs(args, debug, multithreaded, exceptions, linkType, rtti, optimization);
+ //
+ // add all appropriate defines and undefines
+ //
+ buildDefineArguments(defaultProviders, args);
+ int warnings = specificDef.getWarnings(defaultProviders, 0);
+ addWarningSwitch(args, warnings);
+ Enumeration argEnum = cmdArgs.elements();
+ int endCount = 0;
+ while (argEnum.hasMoreElements()) {
+ CommandLineArgument arg = (CommandLineArgument) argEnum
+ .nextElement();
+ switch (arg.getLocation()) {
+ case 1 :
+ args.addElement(arg.getValue());
+ break;
+ case 2 :
+ endCount++;
+ break;
+ }
+ }
+ String[] endArgs = new String[endCount];
+ argEnum = cmdArgs.elements();
+ int index = 0;
+ while (argEnum.hasMoreElements()) {
+ CommandLineArgument arg = (CommandLineArgument) argEnum
+ .nextElement();
+ if (arg.getLocation() == 2) {
+ endArgs[index++] = arg.getValue();
+ }
+ }
+ //
+ // Want to have distinct set of arguments with relative
+ // path names for includes that are used to build
+ // the configuration identifier
+ //
+ Vector relativeArgs = (Vector) args.clone();
+ //
+ // add all active include and sysincludes
+ //
+ StringBuffer includePathIdentifier = new StringBuffer();
+ File baseDir = specificDef.getProject().getBaseDir();
+ String baseDirPath;
+ try {
+ baseDirPath = baseDir.getCanonicalPath();
+ } catch (IOException ex) {
+ baseDirPath = baseDir.toString();
+ }
+ Vector includePath = new Vector();
+ Vector sysIncludePath = new Vector();
+ for (int i = defaultProviders.length - 1; i >= 0; i--) {
+ String[] incPath = defaultProviders[i].getActiveIncludePaths();
+ for (int j = 0; j < incPath.length; j++) {
+ includePath.addElement(incPath[j]);
+ }
+ incPath = defaultProviders[i].getActiveSysIncludePaths();
+ for (int j = 0; j < incPath.length; j++) {
+ sysIncludePath.addElement(incPath[j]);
+ }
+ }
+ File[] incPath = new File[includePath.size()];
+ for (int i = 0; i < includePath.size(); i++) {
+ incPath[i] = new File((String) includePath.elementAt(i));
+ }
+ File[] sysIncPath = new File[sysIncludePath.size()];
+ for (int i = 0; i < sysIncludePath.size(); i++) {
+ sysIncPath[i] = new File((String) sysIncludePath.elementAt(i));
+ }
+ addIncludes(baseDirPath, incPath, args, relativeArgs,
+ includePathIdentifier);
+ addIncludes(baseDirPath, sysIncPath, args, null, null);
+ StringBuffer buf = new StringBuffer(getIdentifier());
+ for (int i = 0; i < relativeArgs.size(); i++) {
+ buf.append(' ');
+ buf.append(relativeArgs.elementAt(i));
+ }
+ for (int i = 0; i < endArgs.length; i++) {
+ buf.append(' ');
+ buf.append(endArgs[i]);
+ }
+ String configId = buf.toString();
+ String[] argArray = new String[args.size()];
+ args.copyInto(argArray);
+ boolean rebuild = specificDef.getRebuild(baseDefs, 0);
+ File[] envIncludePath = getEnvironmentIncludePath();
+ return new CommandLineCompilerConfiguration(this, configId, incPath,
+ sysIncPath, envIncludePath, includePathIdentifier.toString(),
+ argArray, paramArray, rebuild, endArgs);
+ }
+ protected int getArgumentCountPerInputFile() {
+ return 1;
+ }
+ protected final String getCommand() {
+ return command;
+ }
+ abstract protected void getDefineSwitch(StringBuffer buffer, String define,
+ String value);
+ protected abstract File[] getEnvironmentIncludePath();
+ public String getIdentifier() {
+ if (identifier == null) {
+ if (identifierArg == null) {
+ identifier = getIdentifier(new String[]{command}, command);
+ } else {
+ identifier = getIdentifier(
+ new String[]{command, identifierArg}, command);
+ }
+ }
+ return identifier;
+ }
+ abstract protected String getIncludeDirSwitch(String source);
+ protected String getInputFileArgument(File outputDir, String filename,
+ int index) {
+ //
+ // if there is an embedded space,
+ // must enclose in quotes
+ if (filename.indexOf(' ') >= 0) {
+ StringBuffer buf = new StringBuffer("\"");
+ buf.append(filename);
+ buf.append("\"");
+ return buf.toString();
+ }
+ return filename;
+ }
+ protected final boolean getLibtool() {
+ return libtool;
+ }
+ /**
+ * Obtains the same compiler, but with libtool set
+ *
+ * Default behavior is to ignore libtool
+ */
+ public final CommandLineCompiler getLibtoolCompiler() {
+ if (libtoolCompiler != null) {
+ return libtoolCompiler;
+ }
+ return this;
+ }
+ abstract public int getMaximumCommandLength();
+ protected int getMaximumInputFilesPerCommand() {
+ return Integer.MAX_VALUE;
+ }
+ protected int getTotalArgumentLengthForInputFile(File outputDir,
+ String inputFile) {
+ return inputFile.length() + 1;
+ }
+ abstract protected void getUndefineSwitch(StringBuffer buffer, String define);
+ /**
+ * This method is exposed so test classes can overload and test the
+ * arguments without actually spawning the compiler
+ */
+ protected int runCommand(CCTask task, File workingDir, String[] cmdline)
+ throws BuildException {
+ return CUtil.runCommand(task, workingDir, cmdline, newEnvironment, env);
+ }
+ protected final void setCommand(String command) {
+ this.command = command;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCompilerConfiguration.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCompilerConfiguration.java
new file mode 100644
index 0000000..38492ea
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCompilerConfiguration.java
@@ -0,0 +1,226 @@
+/*
+ *
+ * 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.compiler;
+import java.io.File;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.CompilerParam;
+import net.sf.antcontrib.cpptasks.DependencyInfo;
+import net.sf.antcontrib.cpptasks.ProcessorParam;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+
+import org.apache.tools.ant.BuildException;
+/**
+ * A configuration for a C++ compiler
+ *
+ * @author Curt Arnold
+ */
+public final class CommandLineCompilerConfiguration
+ implements
+ CompilerConfiguration {
+ private/* final */String[] args;
+ private/* final */CommandLineCompiler compiler;
+ private String[] endArgs;
+ //
+ // include path from environment variable not
+ // explicitly stated in Ant script
+ private/* final */File[] envIncludePath;
+ private String[] exceptFiles;
+ private/* final */String identifier;
+ private/* final */File[] includePath;
+ private/* final */String includePathIdentifier;
+ private boolean isPrecompiledHeaderGeneration;
+ private/* final */ProcessorParam[] params;
+ private/* final */boolean rebuild;
+ private/* final */File[] sysIncludePath;
+ public CommandLineCompilerConfiguration(CommandLineCompiler compiler,
+ String identifier, File[] includePath, File[] sysIncludePath,
+ File[] envIncludePath, String includePathIdentifier, String[] args,
+ ProcessorParam[] params, boolean rebuild, String[] endArgs) {
+ if (compiler == null) {
+ throw new NullPointerException("compiler");
+ }
+ if (identifier == null) {
+ throw new NullPointerException("identifier");
+ }
+ if (includePathIdentifier == null) {
+ throw new NullPointerException("includePathIdentifier");
+ }
+ if (args == null) {
+ this.args = new String[0];
+ } else {
+ this.args = (String[]) args.clone();
+ }
+ if (includePath == null) {
+ this.includePath = new File[0];
+ } else {
+ this.includePath = (File[]) includePath.clone();
+ }
+ if (sysIncludePath == null) {
+ this.sysIncludePath = new File[0];
+ } else {
+ this.sysIncludePath = (File[]) sysIncludePath.clone();
+ }
+ if (envIncludePath == null) {
+ this.envIncludePath = new File[0];
+ } else {
+ this.envIncludePath = (File[]) envIncludePath.clone();
+ }
+ this.compiler = compiler;
+ this.params = (ProcessorParam[]) params.clone();
+ this.rebuild = rebuild;
+ this.identifier = identifier;
+ this.includePathIdentifier = includePathIdentifier;
+ this.endArgs = (String[]) endArgs.clone();
+ exceptFiles = null;
+ isPrecompiledHeaderGeneration = false;
+ }
+ public CommandLineCompilerConfiguration(
+ CommandLineCompilerConfiguration base, String[] additionalArgs,
+ String[] exceptFiles, boolean isPrecompileHeaderGeneration) {
+ compiler = base.compiler;
+ identifier = base.identifier;
+ rebuild = base.rebuild;
+ includePath = (File[]) base.includePath.clone();
+ sysIncludePath = (File[]) base.sysIncludePath.clone();
+ endArgs = (String[]) base.endArgs.clone();
+ envIncludePath = (File[]) base.envIncludePath.clone();
+ includePathIdentifier = base.includePathIdentifier;
+ if (exceptFiles != null) {
+ this.exceptFiles = (String[]) exceptFiles.clone();
+ }
+ this.isPrecompiledHeaderGeneration = isPrecompileHeaderGeneration;
+ args = new String[base.args.length + additionalArgs.length];
+ for (int i = 0; i < base.args.length; i++) {
+ args[i] = base.args[i];
+ }
+ int index = base.args.length;
+ for (int i = 0; i < additionalArgs.length; i++) {
+ args[index++] = additionalArgs[i];
+ }
+ }
+ public int bid(String inputFile) {
+ int compilerBid = compiler.bid(inputFile);
+ if (compilerBid > 0 && exceptFiles != null) {
+ for (int i = 0; i < exceptFiles.length; i++) {
+ if (inputFile.equals(exceptFiles[i])) {
+ return 0;
+ }
+ }
+ }
+ return compilerBid;
+ }
+ public void compile(CCTask task, File outputDir, String[] sourceFiles,
+ boolean relentless, ProgressMonitor monitor) throws BuildException {
+ if (monitor != null) {
+ monitor.start(this);
+ }
+ try {
+ compiler.compile(task, outputDir, sourceFiles, args, endArgs,
+ relentless, this, monitor);
+ if (monitor != null) {
+ monitor.finish(this, true);
+ }
+ } catch (BuildException ex) {
+ if (monitor != null) {
+ monitor.finish(this, false);
+ }
+ throw ex;
+ }
+ }
+ /**
+ *
+ * This method may be used to get two distinct compiler configurations, one
+ * for compiling the specified file and producing a precompiled header
+ * file, and a second for compiling other files using the precompiled
+ * header file.
+ *
+ * The last (preferrably only) include directive in the prototype file will
+ * be used to mark the boundary between pre-compiled and normally compiled
+ * headers.
+ *
+ * @param prototype
+ * A source file (for example, stdafx.cpp) that is used to build
+ * the precompiled header file. @returns null if precompiled
+ * headers are not supported or a two element array containing
+ * the precompiled header generation configuration and the
+ * consuming configuration
+ *
+ */
+ public CompilerConfiguration[] createPrecompileConfigurations(
+ File prototype, String[] nonPrecompiledFiles) {
+ if (compiler instanceof PrecompilingCompiler) {
+ return ((PrecompilingCompiler) compiler)
+ .createPrecompileConfigurations(this, prototype,
+ nonPrecompiledFiles);
+ }
+ return null;
+ }
+ /**
+ * Returns a string representation of this configuration. Should be
+ * canonical so that equivalent configurations will have equivalent string
+ * representations
+ */
+ public String getIdentifier() {
+ return identifier;
+ }
+ public String getIncludePathIdentifier() {
+ return includePathIdentifier;
+ }
+ public String[] getOutputFileNames(String inputFile, VersionInfo versionInfo) {
+ return compiler.getOutputFileNames(inputFile, versionInfo);
+ }
+ public CompilerParam getParam(String name) {
+ for (int i = 0; i < params.length; i++) {
+ if (name.equals(params[i].getName()))
+ return (CompilerParam) params[i];
+ }
+ return null;
+ }
+ public ProcessorParam[] getParams() {
+ return params;
+ }
+ public boolean getRebuild() {
+ return rebuild;
+ }
+ public boolean isPrecompileGeneration() {
+ return isPrecompiledHeaderGeneration;
+ }
+ public DependencyInfo parseIncludes(CCTask task, File baseDir, File source) {
+ return compiler.parseIncludes(task, source, includePath,
+ sysIncludePath, envIncludePath, baseDir,
+ getIncludePathIdentifier());
+ }
+ public String toString() {
+ return identifier;
+ }
+ public String[] getPreArguments() {
+ return (String[]) args.clone();
+ }
+ public String[] getEndArguments() {
+ return (String[]) endArgs.clone();
+ }
+ public File[] getIncludePath() {
+ return (File[]) includePath.clone();
+ }
+ public Compiler getCompiler() {
+ return compiler;
+ }
+ public String getCommand() {
+ return compiler.getCommand();
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineFortranCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineFortranCompiler.java
new file mode 100644
index 0000000..7b0eed2
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineFortranCompiler.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.compiler;
+import java.io.File;
+
+import net.sf.antcontrib.cpptasks.parser.FortranParser;
+import net.sf.antcontrib.cpptasks.parser.Parser;
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * An abstract Compiler implementation which uses an external program to
+ * perform the compile.
+ *
+ * @author Curt Arnold
+ */
+public abstract class CommandLineFortranCompiler extends CommandLineCompiler {
+ protected CommandLineFortranCompiler(String command, String identifierArg,
+ String[] sourceExtensions, String[] headerExtensions,
+ String outputSuffix, boolean libtool,
+ CommandLineFortranCompiler libtoolCompiler, boolean newEnvironment,
+ Environment env) {
+ super(command, identifierArg, sourceExtensions, headerExtensions,
+ outputSuffix, libtool, libtoolCompiler, newEnvironment, env);
+ }
+ protected Parser createParser(File source) {
+ return new FortranParser();
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker.java
new file mode 100644
index 0000000..86594fa
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker.java
@@ -0,0 +1,407 @@
+/*
+ *
+ * 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.compiler;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.LinkerDef;
+import net.sf.antcontrib.cpptasks.ProcessorDef;
+import net.sf.antcontrib.cpptasks.ProcessorParam;
+import net.sf.antcontrib.cpptasks.types.CommandLineArgument;
+import net.sf.antcontrib.cpptasks.types.LibrarySet;
+import net.sf.antcontrib.cpptasks.TargetDef;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Environment;
+
+
+/**
+ * An abstract Linker implementation that performs the link via an external
+ * command.
+ *
+ * @author Adam Murdoch
+ */
+public abstract class CommandLineLinker extends AbstractLinker
+{
+ private String command;
+ private Environment env = null;
+ private String identifier;
+ private String identifierArg;
+ private boolean isLibtool;
+ private String[] librarySets;
+ private CommandLineLinker libtoolLinker;
+ private boolean newEnvironment = false;
+ private String outputSuffix;
+
+
+ /** Creates a comand line linker invocation */
+ public CommandLineLinker(String command,
+ String identifierArg,
+ String[] extensions,
+ String[] ignoredExtensions, String outputSuffix,
+ boolean isLibtool, CommandLineLinker libtoolLinker)
+ {
+ super(extensions, ignoredExtensions);
+ this.command = command;
+ this.identifierArg = identifierArg;
+ this.outputSuffix = outputSuffix;
+ this.isLibtool = isLibtool;
+ this.libtoolLinker = libtoolLinker;
+ }
+ protected abstract void addBase(long base, Vector args);
+
+ protected abstract void addFixed(Boolean fixed, Vector args);
+
+ abstract protected void addImpliedArgs(boolean debug,
+ LinkType linkType, Vector args);
+ protected abstract void addIncremental(boolean incremental, Vector args);
+
+ //
+ // Windows processors handle these through file list
+ //
+ protected String[] addLibrarySets(CCTask task, LibrarySet[] libsets, Vector preargs,
+ Vector midargs, Vector endargs) {
+ return null;
+ }
+ protected abstract void addMap(boolean map, Vector args);
+ protected abstract void addStack(int stack, Vector args);
+ protected abstract void addEntry(String entry, Vector args);
+
+ protected LinkerConfiguration createConfiguration(
+ CCTask task,
+ LinkType linkType,
+ ProcessorDef[] baseDefs, LinkerDef specificDef, TargetDef targetPlatform,
+ VersionInfo versionInfo) {
+
+ Vector preargs = new Vector();
+ Vector midargs = new Vector();
+ Vector endargs = new Vector();
+ Vector[] args = new Vector[] { preargs, midargs, endargs };
+
+ LinkerDef[] defaultProviders = new LinkerDef[baseDefs.length+1];
+ defaultProviders[0] = specificDef;
+ for(int i = 0; i < baseDefs.length; i++) {
+ defaultProviders[i+1] = (LinkerDef) baseDefs[i];
+ }
+ //
+ // add command line arguments inherited from <cc> element
+ // any "extends" and finally the specific CompilerDef
+ CommandLineArgument[] commandArgs;
+ for(int i = defaultProviders.length-1; i >= 0; i--) {
+ commandArgs = defaultProviders[i].getActiveProcessorArgs();
+ for(int j = 0; j < commandArgs.length; j++) {
+ args[commandArgs[j].getLocation()].
+ addElement(commandArgs[j].getValue());
+ }
+ }
+
+ Vector params = new Vector();
+ //
+ // add command line arguments inherited from <cc> element
+ // any "extends" and finally the specific CompilerDef
+ ProcessorParam[] paramArray;
+ for (int i = defaultProviders.length - 1; i >= 0; i--) {
+ paramArray = defaultProviders[i].getActiveProcessorParams();
+ for (int j = 0; j < paramArray.length; j++) {
+ params.add(paramArray[j]);
+ }
+ }
+
+ paramArray = (ProcessorParam[])(params.toArray(new ProcessorParam[params.size()]));
+
+ boolean debug = specificDef.getDebug(baseDefs,0);
+
+
+ String startupObject = getStartupObject(linkType);
+
+ addImpliedArgs(debug, linkType, preargs);
+ addIncremental(specificDef.getIncremental(defaultProviders,1), preargs);
+ addFixed(specificDef.getFixed(defaultProviders,1), preargs);
+ addMap(specificDef.getMap(defaultProviders,1), preargs);
+ addBase(specificDef.getBase(defaultProviders,1), preargs);
+ addStack(specificDef.getStack(defaultProviders,1), preargs);
+ addEntry(specificDef.getEntry(defaultProviders, 1), preargs);
+
+ String[] libnames = null;
+ LibrarySet[] libsets = specificDef.getActiveLibrarySets(defaultProviders,1);
+ if (libsets.length > 0) {
+ libnames = addLibrarySets(task, libsets, preargs, midargs, endargs);
+ }
+
+ StringBuffer buf = new StringBuffer(getIdentifier());
+ for (int i = 0; i < 3; i++) {
+ Enumeration argenum = args[i].elements();
+ while (argenum.hasMoreElements()) {
+ buf.append(' ');
+ buf.append(argenum.nextElement().toString());
+ }
+ }
+ String configId = buf.toString();
+
+ String[][] options = new String[][] {
+ new String[args[0].size() + args[1].size()],
+ new String[args[2].size()] };
+ args[0].copyInto(options[0]);
+ int offset = args[0].size();
+ for (int i = 0; i < args[1].size(); i++) {
+ options[0][i+offset] = (String) args[1].elementAt(i);
+ }
+ args[2].copyInto(options[1]);
+
+
+ boolean rebuild = specificDef.getRebuild(baseDefs,0);
+ boolean map = specificDef.getMap(defaultProviders,1);
+
+ //task.log("libnames:"+libnames.length, Project.MSG_VERBOSE);
+ return new CommandLineLinkerConfiguration(this,configId,options,
+ paramArray,
+ rebuild,map, debug,libnames, startupObject);
+ }
+
+ /**
+ * Allows drived linker to decorate linker option.
+ * Override by GccLinker to prepend a "-Wl," to
+ * pass option to through gcc to linker.
+ *
+ * @param buf buffer that may be used and abused in the decoration process,
+ * must not be null.
+ * @param arg linker argument
+ */
+ protected String decorateLinkerOption(StringBuffer buf, String arg) {
+ return arg;
+ }
+
+ protected final String getCommand() {
+ return command;
+ }
+ protected abstract String getCommandFileSwitch(String commandFile);
+
+
+ public String getIdentifier() {
+ if(identifier == null) {
+ if (identifierArg == null) {
+ identifier = getIdentifier(new String[] { command }, command);
+ } else {
+ identifier = getIdentifier(new String[] { command, identifierArg },
+ command);
+ }
+ }
+ return identifier;
+ }
+ public final CommandLineLinker getLibtoolLinker() {
+ if (libtoolLinker != null) {
+ return libtoolLinker;
+ }
+ return this;
+ }
+ protected abstract int getMaximumCommandLength();
+
+ public String[] getOutputFileNames(String baseName, VersionInfo versionInfo) {
+ return new String[] { baseName + outputSuffix };
+ }
+
+ protected String[] getOutputFileSwitch(CCTask task, String outputFile) {
+ return getOutputFileSwitch(outputFile);
+ }
+ protected abstract String[] getOutputFileSwitch(String outputFile);
+ protected String getStartupObject(LinkType linkType) {
+ return null;
+ }
+
+ /**
+ * Performs a link using a command line linker
+ *
+ */
+ public void link(CCTask task,
+ File outputFile,
+ String[] sourceFiles,
+ CommandLineLinkerConfiguration config)
+ throws BuildException
+ {
+ File parentDir = new File(outputFile.getParent());
+ String parentPath;
+ try {
+ parentPath = parentDir.getCanonicalPath();
+ } catch(IOException ex) {
+ parentPath = parentDir.getAbsolutePath();
+ }
+ String[] execArgs = prepareArguments(task, parentPath,outputFile.getName(),
+ sourceFiles, config);
+ int commandLength = 0;
+ for(int i = 0; i < execArgs.length; i++) {
+ commandLength += execArgs[i].length() + 1;
+ }
+
+ //
+ // if command length exceeds maximum
+ // then create a temporary
+ // file containing everything but the command name
+ if(commandLength >= this.getMaximumCommandLength()) {
+ try {
+ execArgs = prepareResponseFile(outputFile,execArgs);
+ }
+ catch(IOException ex) {
+ throw new BuildException(ex);
+ }
+ }
+
+ int retval = runCommand(task,parentDir,execArgs);
+ //
+ // if the process returned a failure code then
+ // throw an BuildException
+ //
+ if(retval != 0) {
+ //
+ // construct the exception
+ //
+ throw new BuildException(this.getCommand() + " failed with return code " + retval, task.getLocation());
+ }
+
+ }
+
+
+ /**
+ * Prepares argument list for exec command. Will return null
+ * if command line would exceed allowable command line buffer.
+ *
+ * @param task compilation task.
+ * @param outputFile linker output file
+ * @param sourceFiles linker input files (.obj, .o, .res)
+ * @param config linker configuration
+ * @return arguments for runTask
+ */
+ protected String[] prepareArguments(
+ CCTask task,
+ String outputDir,
+ String outputFile,
+ String[] sourceFiles,
+ CommandLineLinkerConfiguration config) {
+
+ String[] preargs = config.getPreArguments();
+ String[] endargs = config.getEndArguments();
+ String outputSwitch[] = getOutputFileSwitch(task, outputFile);
+ int allArgsCount = preargs.length + 1 + outputSwitch.length +
+ sourceFiles.length + endargs.length;
+ if (isLibtool) {
+ allArgsCount++;
+ }
+ String[] allArgs = new String[allArgsCount];
+ int index = 0;
+ if (isLibtool) {
+ allArgs[index++] = "libtool";
+ }
+ allArgs[index++] = this.getCommand();
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < preargs.length; i++) {
+ allArgs[index++] = decorateLinkerOption(buf, preargs[i]);
+ }
+ for (int i = 0; i < outputSwitch.length; i++) {
+ allArgs[index++] = outputSwitch[i];
+ }
+ for (int i = 0; i < sourceFiles.length; i++) {
+ allArgs[index++] = prepareFilename(buf,outputDir,sourceFiles[i]);
+ }
+ for (int i = 0; i < endargs.length; i++) {
+ allArgs[index++] = decorateLinkerOption(buf, endargs[i]);
+ }
+ return allArgs;
+ }
+
+ /**
+ * Processes filename into argument form
+ *
+ */
+ protected String prepareFilename(StringBuffer buf,
+ String outputDir, String sourceFile) {
+ String relativePath = CUtil.getRelativePath(outputDir,
+ new File(sourceFile));
+ return quoteFilename(buf,relativePath);
+ }
+
+ /**
+ * Prepares argument list to execute the linker using a
+ * response file.
+ *
+ * @param outputFile linker output file
+ * @param args output of prepareArguments
+ * @return arguments for runTask
+ */
+ protected String[] prepareResponseFile(File outputFile,String[] args) throws IOException
+ {
+ String baseName = outputFile.getName();
+ File commandFile = new File(outputFile.getParent(),baseName + ".rsp");
+ FileWriter writer = new FileWriter(commandFile);
+ int execArgCount = 1;
+ if (isLibtool) {
+ execArgCount++;
+ }
+ String[] execArgs = new String[execArgCount+1];
+ for (int i = 0; i < execArgCount; i++) {
+ execArgs[i] = args[i];
+ }
+ execArgs[execArgCount] = getCommandFileSwitch(commandFile.toString());
+ for(int i = execArgCount; i < args.length; i++) {
+ //
+ // if embedded space and not quoted then
+ // quote argument
+ if (args[i].indexOf(" ") >= 0 && args[i].charAt(0) != '\"') {
+ writer.write('\"');
+ writer.write(args[i]);
+ writer.write("\"\n");
+ } else {
+ writer.write(args[i]);
+ writer.write('\n');
+ }
+ }
+ writer.close();
+ return execArgs;
+ }
+
+
+ protected String quoteFilename(StringBuffer buf,String filename) {
+ if(filename.indexOf(' ') >= 0) {
+ buf.setLength(0);
+ buf.append('\"');
+ buf.append(filename);
+ buf.append('\"');
+ return buf.toString();
+ }
+ return filename;
+ }
+
+ /**
+ * This method is exposed so test classes can overload
+ * and test the arguments without actually spawning the
+ * compiler
+ */
+ protected int runCommand(CCTask task, File workingDir,String[] cmdline)
+ throws BuildException {
+ return CUtil.runCommand(task,workingDir,cmdline, newEnvironment, env);
+ }
+
+ protected final void setCommand(String command) {
+ this.command = command;
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinkerConfiguration.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinkerConfiguration.java
new file mode 100644
index 0000000..f0aad67
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinkerConfiguration.java
@@ -0,0 +1,128 @@
+/*
+ *
+ * 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.compiler;
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.LinkerParam;
+import net.sf.antcontrib.cpptasks.ProcessorParam;
+import net.sf.antcontrib.cpptasks.TargetInfo;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+
+import org.apache.tools.ant.BuildException;
+/**
+ * A configuration for a command line linker
+ *
+ * @author Curt Arnold
+ */
+public final class CommandLineLinkerConfiguration
+ implements
+ LinkerConfiguration {
+ private/* final */String[][] args;
+ private/* final */String identifier;
+ private String[] libraryNames;
+ private/* final */CommandLineLinker linker;
+ private/* final */boolean map;
+ private/* final */ProcessorParam[] params;
+ private/* final */boolean rebuild;
+ private boolean debug;
+ private String startupObject;
+ public CommandLineLinkerConfiguration(CommandLineLinker linker,
+ String identifier, String[][] args, ProcessorParam[] params,
+ boolean rebuild, boolean map, boolean debug, String[] libraryNames,
+ String startupObject) {
+ if (linker == null) {
+ throw new NullPointerException("linker");
+ }
+ if (args == null) {
+ throw new NullPointerException("args");
+ } else {
+ this.args = (String[][]) args.clone();
+ }
+ this.linker = linker;
+ this.params = (ProcessorParam[]) params.clone();
+ this.rebuild = rebuild;
+ this.identifier = identifier;
+ this.map = map;
+ this.debug = debug;
+ if (libraryNames == null) {
+ this.libraryNames = new String[0];
+ } else {
+ this.libraryNames = (String[]) libraryNames.clone();
+ }
+ this.startupObject = startupObject;
+ }
+ public int bid(String filename) {
+ return linker.bid(filename);
+ }
+ public String[] getEndArguments() {
+ String[] clone = (String[]) args[1].clone();
+ return clone;
+ }
+ /**
+ * Returns a string representation of this configuration. Should be
+ * canonical so that equivalent configurations will have equivalent string
+ * representations
+ */
+ public String getIdentifier() {
+ return identifier;
+ }
+ public String[] getLibraryNames() {
+ String[] clone = (String[]) libraryNames.clone();
+ return clone;
+ }
+ public boolean getMap() {
+ return map;
+ }
+ public String[] getOutputFileNames(String inputFile, VersionInfo versionInfo) {
+ return linker.getOutputFileNames(inputFile, versionInfo);
+ }
+ public LinkerParam getParam(String name) {
+ for (int i = 0; i < params.length; i++) {
+ if (name.equals(params[i].getName()))
+ return (LinkerParam) params[i];
+ }
+ return null;
+ }
+ public ProcessorParam[] getParams() {
+ return params;
+ }
+ public String[] getPreArguments() {
+ String[] clone = (String[]) args[0].clone();
+ return clone;
+ }
+ public boolean getRebuild() {
+ return rebuild;
+ }
+ public String getStartupObject() {
+ return startupObject;
+ }
+ public void link(CCTask task, TargetInfo linkTarget) throws BuildException {
+ //
+ // AllSourcePath's include any syslibsets
+ //
+ String[] sourcePaths = linkTarget.getAllSourcePaths();
+ linker.link(task, linkTarget.getOutput(), sourcePaths, this);
+ }
+ public String toString() {
+ return identifier;
+ }
+ public Linker getLinker() {
+ return linker;
+ }
+ public boolean isDebug() {
+ return debug;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/Compiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/Compiler.java
new file mode 100644
index 0000000..48bc190
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/Compiler.java
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2001-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.compiler;
+/**
+ * A compiler.
+ *
+ * @author Adam Murdoch
+ */
+public interface Compiler extends Processor {
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CompilerConfiguration.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CompilerConfiguration.java
new file mode 100644
index 0000000..6aba345
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CompilerConfiguration.java
@@ -0,0 +1,64 @@
+/*
+ *
+ * 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.compiler;
+import java.io.File;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.CompilerParam;
+import net.sf.antcontrib.cpptasks.DependencyInfo;
+
+import org.apache.tools.ant.BuildException;
+/**
+ * A configuration for a compiler
+ *
+ * @author Curt Arnold
+ */
+public interface CompilerConfiguration extends ProcessorConfiguration {
+ void compile(CCTask task, File outputDir, String[] sourceFiles,
+ boolean relentless, ProgressMonitor monitor) throws BuildException;
+ /**
+ *
+ * This method may be used to get two distinct compiler configurations, one
+ * for compiling the specified file and producing a precompiled header
+ * file, and a second for compiling other files using the precompiled
+ * header file.
+ *
+ * The last (preferrably only) include directive in the prototype file will
+ * be used to mark the boundary between pre-compiled and normally compiled
+ * headers.
+ *
+ * @param prototype
+ * A source file (for example, stdafx.cpp) that is used to build
+ * the precompiled header file. @returns null if precompiled
+ * headers are not supported or a two element array containing
+ * the precompiled header generation configuration and the
+ * consuming configuration
+ *
+ */
+ CompilerConfiguration[] createPrecompileConfigurations(File prototype,
+ String[] nonPrecompiledFiles);
+ /**
+ * Returns an digest for the include path for the configuration.
+ *
+ * This is used to determine if cached dependency information is invalid
+ * because the include paths have changed
+ */
+ String getIncludePathIdentifier();
+ public CompilerParam getParam(String name);
+ boolean isPrecompileGeneration();
+ DependencyInfo parseIncludes(CCTask task, File baseDir, File source);
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkType.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkType.java
new file mode 100644
index 0000000..70ee93f
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkType.java
@@ -0,0 +1,150 @@
+/*
+ *
+ * Copyright 2001-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.compiler;
+import net.sf.antcontrib.cpptasks.OutputTypeEnum;
+import net.sf.antcontrib.cpptasks.SubsystemEnum;
+/**
+ * This class represents the target platform for the compile and link step. The
+ * name is an anachronism and should be changed.
+ *
+ * @author Curt Arnold
+ */
+public class LinkType {
+ private OutputTypeEnum outputType = new OutputTypeEnum();
+ private boolean staticRuntime = false;
+ private SubsystemEnum subsystem = new SubsystemEnum();
+ /**
+ * Constructor
+ *
+ * By default, an gui executable with a dynamically linked runtime
+ *
+ */
+ public LinkType() {
+ }
+ /**
+ * Gets whether the link should produce an executable
+ *
+ * @return boolean
+ */
+ public boolean isExecutable() {
+ String value = outputType.getValue();
+ return value.equals("executable");
+ }
+ /**
+ * Gets whether the link should produce a plugin module.
+ *
+ * @return boolean
+ */
+ public boolean isPluginModule() {
+ String value = outputType.getValue();
+ return value.equals("plugin");
+ }
+ /**
+ * Gets whether the link should produce a shared library.
+ *
+ * @return boolean
+ */
+ public boolean isSharedLibrary() {
+ String value = outputType.getValue();
+ return value.equals("shared") || value.equals("plugin");
+ }
+ /**
+ * Gets whether the link should produce a static library.
+ *
+ * @return boolean
+ */
+ public boolean isStaticLibrary() {
+ String value = outputType.getValue();
+ return value.equals("static");
+ }
+ /**
+ * Gets whether the module should use a statically linked runtime library.
+ *
+ * @return boolean
+ */
+ public boolean isStaticRuntime() {
+ return staticRuntime;
+ }
+ /**
+ * Gets whether the link should produce a module for a console subsystem.
+ *
+ * @return boolean
+ */
+ public boolean isSubsystemConsole() {
+ String value = subsystem.getValue();
+ return value.equals("console");
+ }
+ /**
+ * Gets whether the link should produce a module for a graphical user
+ * interface subsystem.
+ *
+ * @return boolean
+ */
+ public boolean isSubsystemGUI() {
+ String value = subsystem.getValue();
+ return value.equals("gui");
+ }
+ /**
+ * Sets the output type (execuable, shared, etc).
+ *
+ * @param outputType may not be null
+ */
+ public void setOutputType(OutputTypeEnum outputType) {
+ if (outputType == null) {
+ throw new IllegalArgumentException("outputType");
+ }
+ this.outputType = outputType;
+ }
+
+ /**
+ * Gets the output type.
+ * @return output type
+ */
+ public String getOutputType() {
+ return outputType.getValue();
+ }
+
+ /**
+ * Requests use of a static runtime library.
+ *
+ * @param staticRuntime
+ * if true, use static runtime library if possible.
+ */
+ public void setStaticRuntime(boolean staticRuntime) {
+ this.staticRuntime = staticRuntime;
+ }
+ /**
+ * Sets the subsystem (gui, console, etc).
+ *
+ * @param subsystem
+ * subsystem, may not be null
+ */
+ public void setSubsystem(SubsystemEnum subsystem) {
+ if (subsystem == null) {
+ throw new IllegalArgumentException("subsystem");
+ }
+ this.subsystem = subsystem;
+ }
+
+ /**
+ * Get subsystem name.
+ * @return subsystem name
+ */
+ public String getSubsystem() {
+ return subsystem.getValue();
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/Linker.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/Linker.java
new file mode 100644
index 0000000..0638a70
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/Linker.java
@@ -0,0 +1,80 @@
+/*
+ *
+ * Copyright 2001-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.compiler;
+import java.io.File;
+import java.io.IOException;
+
+import net.sf.antcontrib.cpptasks.TargetMatcher;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+
+/**
+ * A linker for executables, and static and dynamic libraries.
+ *
+ * @author Adam Murdoch
+ */
+public interface Linker extends Processor {
+ /**
+ * Extracts the significant part of a library name to ensure there aren't
+ * collisions
+ */
+ String getLibraryKey(File libname);
+ /**
+ * returns the library path for the linker
+ */
+ File[] getLibraryPath();
+ /**
+ * Returns a set of filename patterns corresponding to library names.
+ *
+ * For example, "advapi32" would be expanded to "advapi32.dll" by
+ * DevStudioLinker and to "libadvapi32.a" and "libadvapi32.so" by
+ * GccLinker.
+ *
+ * @param libnames
+ * array of library names
+ */
+ String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libraryType);
+ /**
+ * Gets the linker for the specified link type.
+ *
+ * @return appropriate linker or null, will return this if this linker can
+ * handle the specified link type
+ */
+ Linker getLinker(LinkType linkType);
+ /**
+ * Returns true if the linker is case-sensitive
+ */
+ boolean isCaseSensitive();
+
+ /**
+ * Adds source or object files to the bidded fileset to
+ * support version information.
+ *
+ * @param versionInfo version information
+ * @param linkType link type
+ * @param isDebug true if debug build
+ * @param outputFile name of generated executable
+ * @param objDir directory for generated files
+ * @param matcher bidded fileset
+ */
+ void addVersionFiles(final VersionInfo versionInfo,
+ final LinkType linkType,
+ final File outputFile,
+ final boolean isDebug,
+ final File objDir,
+ final TargetMatcher matcher) throws IOException;
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkerConfiguration.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkerConfiguration.java
new file mode 100644
index 0000000..ff7ac5d
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkerConfiguration.java
@@ -0,0 +1,33 @@
+/*
+ *
+ * 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.compiler;
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.LinkerParam;
+import net.sf.antcontrib.cpptasks.TargetInfo;
+
+import org.apache.tools.ant.BuildException;
+/**
+ * A configuration for a linker
+ *
+ * @author Curt Arnold
+ */
+public interface LinkerConfiguration extends ProcessorConfiguration {
+ public LinkerParam getParam(String name);
+ void link(CCTask task, TargetInfo linkTarget) throws BuildException;
+ Linker getLinker();
+ boolean isDebug();
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCCompiler.java
new file mode 100644
index 0000000..2af1a68
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCCompiler.java
@@ -0,0 +1,43 @@
+/*
+ *
+ * Copyright 2001-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.compiler;
+import java.io.File;
+
+import net.sf.antcontrib.cpptasks.parser.CParser;
+import net.sf.antcontrib.cpptasks.parser.Parser;
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * A command line C compiler that can utilize precompilation of header files
+ *
+ * @author Curt Arnold
+ */
+public abstract class PrecompilingCommandLineCCompiler
+ extends
+ PrecompilingCommandLineCompiler {
+ protected PrecompilingCommandLineCCompiler(String command,
+ String identifierArg, String[] sourceExtensions,
+ String[] headerExtensions, String outputSuffix, boolean libtool,
+ PrecompilingCommandLineCCompiler libtoolCompiler,
+ boolean newEnvironment, Environment env) {
+ super(command, identifierArg, sourceExtensions, headerExtensions,
+ outputSuffix, libtool, libtoolCompiler, newEnvironment, env);
+ }
+ protected Parser createParser(File source) {
+ return new CParser();
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCompiler.java
new file mode 100644
index 0000000..3b66597
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCompiler.java
@@ -0,0 +1,104 @@
+/*
+ *
+ * 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.compiler;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+
+import net.sf.antcontrib.cpptasks.parser.Parser;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Environment;
+/**
+ * A command line C compiler that can utilize precompilation of header files
+ *
+ * @author Curt Arnold
+ */
+public abstract class PrecompilingCommandLineCompiler
+ extends
+ CommandLineCompiler implements PrecompilingCompiler {
+ protected PrecompilingCommandLineCompiler(String command,
+ String identifierArg, String[] sourceExtensions,
+ String[] headerExtensions, String outputSuffix, boolean libtool,
+ PrecompilingCommandLineCompiler libtoolCompiler,
+ boolean newEnvironment, Environment env) {
+ super(command, identifierArg, sourceExtensions, headerExtensions,
+ outputSuffix, libtool, libtoolCompiler, newEnvironment, env);
+ }
+ /**
+ *
+ * This method may be used to get two distinct compiler configurations, one
+ * for compiling the specified file and producing a precompiled header
+ * file, and a second for compiling other files using the precompiled
+ * header file.
+ *
+ * The last (preferrably only) include directive in the prototype file will
+ * be used to mark the boundary between pre-compiled and normally compiled
+ * headers.
+ *
+ * @param config
+ * base configuration
+ * @param prototype
+ * A source file (for example, stdafx.cpp) that is used to build
+ * the precompiled header file. @returns null if precompiled
+ * headers are not supported or a two element array containing
+ * the precompiled header generation configuration and the
+ * consuming configuration
+ *
+ */
+ public CompilerConfiguration[] createPrecompileConfigurations(
+ CompilerConfiguration config, File prototype, String[] exceptFiles) {
+ //
+ // cast should success or someone is passing us a configuration
+ // that was prepared by another processor
+ //
+ CommandLineCompilerConfiguration cmdLineConfig = (CommandLineCompilerConfiguration) config;
+ //
+ // parse prototype file to determine last header
+ //
+ Parser parser = createParser(prototype);
+ String[] includes;
+ try {
+ Reader reader = new BufferedReader(new FileReader(prototype));
+ parser.parse(reader);
+ includes = parser.getIncludes();
+ } catch (IOException ex) {
+ throw new BuildException(
+ "Error parsing precompiled header protoype: "
+ + prototype.toString() + ":" + ex.toString());
+ }
+ if (includes.length == 0) {
+ throw new BuildException("Precompiled header prototype: "
+ + prototype.toString()
+ + " does not contain any include directives.");
+ }
+ CompilerConfiguration[] configs = new CompilerConfiguration[2];
+ configs[0] = createPrecompileGeneratingConfig(cmdLineConfig, prototype,
+ includes[0]);
+ configs[1] = createPrecompileUsingConfig(cmdLineConfig, prototype,
+ includes[0], exceptFiles);
+ return configs;
+ }
+ abstract protected CompilerConfiguration createPrecompileGeneratingConfig(
+ CommandLineCompilerConfiguration baseConfig, File prototype,
+ String lastInclude);
+ abstract protected CompilerConfiguration createPrecompileUsingConfig(
+ CommandLineCompilerConfiguration baseConfig, File prototype,
+ String lastInclude, String[] exceptFiles);
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCompiler.java
new file mode 100644
index 0000000..f707dc5
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCompiler.java
@@ -0,0 +1,49 @@
+/*
+ *
+ * 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.compiler;
+import java.io.File;
+/**
+ * A compiler that can utilize precompilation of header files
+ *
+ * @author Curt Arnold
+ */
+public interface PrecompilingCompiler {
+ /**
+ *
+ * This method may be used to get two distinct compiler configurations, one
+ * for compiling the specified file and producing a precompiled header
+ * file, and a second for compiling other files using the precompiled
+ * header file.
+ *
+ * The last (preferrably only) include directive in the prototype file will
+ * be used to mark the boundary between pre-compiled and normally compiled
+ * headers.
+ *
+ * @param config
+ * base configuration
+ * @param prototype
+ * A source file (for example, stdafx.cpp) that is used to build
+ * the precompiled header file. @returns null if precompiled
+ * headers are not supported or a two element array containing
+ * the precompiled header generation configuration and the
+ * consuming configuration
+ *
+ */
+ CompilerConfiguration[] createPrecompileConfigurations(
+ CompilerConfiguration config, File prototype,
+ String[] nonPrecompiledFiles);
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/Processor.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/Processor.java
new file mode 100644
index 0000000..d6513f7
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/Processor.java
@@ -0,0 +1,75 @@
+/*
+ *
+ * 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.compiler;
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.ProcessorDef;
+import net.sf.antcontrib.cpptasks.TargetDef;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * A processor. Base interface for Compiler and Linker
+ *
+ * @author Curt Arnold
+ */
+public interface Processor {
+ /**
+ * Returns a bid indicating the desire of this compiler to process the
+ * file.
+ *
+ * @param inputFile
+ * input file
+ * @return 0 = no interest, 100 = high interest
+ */
+ int bid(String inputFile);
+ Processor changeEnvironment(boolean newEnvironment, Environment env);
+ /**
+ * Returns the compiler configuration for <cc>or <compiler>element.
+ *
+ * @param defaultProviders
+ * When specificConfig corresponds to a <compiler>or linker
+ * element, defaultProvider will be a zero to two element array.
+ * If there is an extends attribute, the first element will be
+ * the referenced ProcessorDef, unless inherit = false, the last
+ * element will be the containing <cc>element
+ * @param specificConfig
+ * A <cc>or <compiler>element.
+ * @return resulting configuration
+ */
+ ProcessorConfiguration createConfiguration(CCTask task, LinkType linkType,
+ ProcessorDef[] defaultProviders, ProcessorDef specificConfig,
+ TargetDef targetPlatform, VersionInfo versionInfo);
+ /**
+ * Retrieve an identifier that identifies the specific version of the
+ * compiler. Compilers with the same identifier should produce the same
+ * output files for the same input files and command line switches.
+ */
+ String getIdentifier();
+ /**
+ * Gets the linker that is associated with this processors
+ */
+ Linker getLinker(LinkType type);
+ /**
+ * Output file name (no path components) corresponding to source file
+ *
+ * @param inputFile
+ * input file
+ * @return output file name or null if no output file or name not
+ * determined by input file
+ */
+ String[] getOutputFileNames(String inputFile, VersionInfo versionInfo);
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/ProcessorConfiguration.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/ProcessorConfiguration.java
new file mode 100644
index 0000000..870fb33
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/ProcessorConfiguration.java
@@ -0,0 +1,54 @@
+/*
+ *
+ * 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.compiler;
+import net.sf.antcontrib.cpptasks.ProcessorParam;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+
+/**
+ * A configuration for a C++ compiler, linker or other processor
+ *
+ * @author Curt Arnold
+ */
+public interface ProcessorConfiguration {
+ /**
+ * An indication of how much this compiler would like to process this file
+ *
+ * @return 0 is no interest to process, 100 is strong interest to process
+ */
+ int bid(String filename);
+ /**
+ * Returns a string representation of this configuration. Should be
+ * canonical so that equivalent configurations will have equivalent string
+ * representations
+ */
+ String getIdentifier();
+ /**
+ * Output file name (no path components) corresponding to source file
+ *
+ * @param inputFile
+ * input file
+ * @return output file names or zero-length array if no output file or name not
+ * determined by input file
+ */
+ String[] getOutputFileNames(String inputFile, VersionInfo versionInfo);
+ ProcessorParam[] getParams();
+ /**
+ * If true, all files using this configuration should be rebuilt and any
+ * existing output files should be ignored
+ */
+ boolean getRebuild();
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/ProgressMonitor.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/ProgressMonitor.java
new file mode 100644
index 0000000..9949856
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/ProgressMonitor.java
@@ -0,0 +1,31 @@
+/*
+ *
+ * Copyright 2001-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.compiler;
+/**
+ * Interface to receive notification of compile progress
+ *
+ * @author Curt Arnold
+ */
+public interface ProgressMonitor {
+ public void finish(ProcessorConfiguration config, boolean normal);
+ /**
+ * Called to notify monitor of progress
+ *
+ */
+ void progress(String[] sources);
+ public void start(ProcessorConfiguration config);
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudio2005CCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudio2005CCompiler.java
new file mode 100644
index 0000000..8df73bd
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudio2005CCompiler.java
@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright 2002-2007 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.devstudio;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+
+import org.apache.tools.ant.types.Environment;
+
+/**
+ * Adapter for the Microsoft(r) C/C++ 8 Optimizing Compiler
+ *
+ * @author David Haney
+ */
+public final class DevStudio2005CCompiler extends DevStudioCompatibleCCompiler {
+ private static final DevStudio2005CCompiler instance = new DevStudio2005CCompiler(
+ "cl", false, null);
+ public static DevStudio2005CCompiler getInstance() {
+ return instance;
+ }
+ private DevStudio2005CCompiler(String command, boolean newEnvironment,
+ Environment env) {
+ super(command, "/bogus", newEnvironment, env);
+ }
+ /**
+ * Override the default debug flags to use VC 8 compatible versions.
+ */
+ protected void addDebugSwitch(Vector args) {
+ args.addElement("/Zi");
+ args.addElement("/Od");
+ args.addElement("/RTC1");
+ args.addElement("/D_DEBUG");
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new DevStudio2005CCompiler(getCommand(), newEnvironment, env);
+ }
+ return this;
+ }
+ public Linker getLinker(LinkType type) {
+ return DevStudioLinker.getInstance().getLinker(type);
+ }
+ public int getMaximumCommandLength() {
+ return 32767;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCCompiler.java
new file mode 100644
index 0000000..1281046
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCCompiler.java
@@ -0,0 +1,50 @@
+/*
+ *
+ * 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.devstudio;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for the Microsoft(r) C/C++ Optimizing Compiler
+ *
+ * @author Adam Murdoch
+ */
+public final class DevStudioCCompiler extends DevStudioCompatibleCCompiler {
+ private static final DevStudioCCompiler instance = new DevStudioCCompiler(
+ "cl", false, null);
+ public static DevStudioCCompiler getInstance() {
+ return instance;
+ }
+ private DevStudioCCompiler(String command, boolean newEnvironment,
+ Environment env) {
+ super(command, "/bogus", newEnvironment, env);
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new DevStudioCCompiler(getCommand(), newEnvironment, env);
+ }
+ return this;
+ }
+ public Linker getLinker(LinkType type) {
+ return DevStudioLinker.getInstance().getLinker(type);
+ }
+ public int getMaximumCommandLength() {
+ return 32767;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleCCompiler.java
new file mode 100644
index 0000000..5f37855
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleCCompiler.java
@@ -0,0 +1,136 @@
+/*
+ *
+ * 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.devstudio;
+import java.io.File;
+import java.util.Vector;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.CompilerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.PrecompilingCommandLineCCompiler;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Environment;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+/**
+ * An abstract base class for compilers that are basically command line
+ * compatible with Microsoft(r) C/C++ Optimizing Compiler
+ *
+ * @author Curt Arnold
+ */
+public abstract class DevStudioCompatibleCCompiler
+ extends
+ PrecompilingCommandLineCCompiler {
+ private static String[] mflags = new String[]{
+ //
+ // first four are single-threaded
+ // (runtime=static,debug=false), (..,debug=true),
+ // (runtime=dynamic,debug=true), (..,debug=false), (not supported)
+ // next four are multi-threaded, same sequence
+ "/ML", "/MLd", null, null, "/MT", "/MTd", "/MD", "/MDd"};
+ protected DevStudioCompatibleCCompiler(String command,
+ String identifierArg, boolean newEnvironment, Environment env) {
+ super(command, identifierArg, new String[]{".c", ".cc", ".cpp", ".cxx",
+ ".c++"}, new String[]{".h", ".hpp", ".inl"}, ".obj", false,
+ null, newEnvironment, env);
+ }
+ protected void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ args.addElement("/c");
+ args.addElement("/nologo");
+ if (exceptions) {
+ // changed to eliminate warning on VC 2005, should support VC 6 and later
+ // use /GX to support VC5 - 2005 (with warning)
+ args.addElement("/EHsc");
+ }
+ int mindex = 0;
+ if (multithreaded) {
+ mindex += 4;
+ }
+ boolean staticRuntime = linkType.isStaticRuntime();
+ if (!staticRuntime) {
+ mindex += 2;
+ }
+ if (debug) {
+ mindex += 1;
+ addDebugSwitch(args);
+ } else {
+ if (optimization != null) {
+ if (optimization.isSize()) {
+ args.addElement("/O1");
+ }
+ if (optimization.isSpeed()) {
+ args.addElement("/O2");
+ }
+ }
+ args.addElement("/DNDEBUG");
+ }
+ String mflag = mflags[mindex];
+ if (mflag == null) {
+ throw new BuildException(
+ "multithread='false' and runtime='dynamic' not supported");
+ }
+ args.addElement(mflag);
+ if (rtti != null && rtti.booleanValue()) {
+ args.addElement("/GR");
+ }
+ }
+ protected void addDebugSwitch(Vector args) {
+ args.addElement("/Zi");
+ args.addElement("/Od");
+ args.addElement("/GZ");
+ args.addElement("/D_DEBUG");
+ }
+ protected void addWarningSwitch(Vector args, int level) {
+ DevStudioProcessor.addWarningSwitch(args, level);
+ }
+ protected CompilerConfiguration createPrecompileGeneratingConfig(
+ CommandLineCompilerConfiguration baseConfig, File prototype,
+ String lastInclude) {
+ String[] additionalArgs = new String[]{
+ "/Fp" + CUtil.getBasename(prototype) + ".pch", "/Yc"};
+ return new CommandLineCompilerConfiguration(baseConfig, additionalArgs,
+ null, true);
+ }
+ protected CompilerConfiguration createPrecompileUsingConfig(
+ CommandLineCompilerConfiguration baseConfig, File prototype,
+ String lastInclude, String[] exceptFiles) {
+ String[] additionalArgs = new String[]{
+ "/Fp" + CUtil.getBasename(prototype) + ".pch",
+ "/Yu" + lastInclude};
+ return new CommandLineCompilerConfiguration(baseConfig, additionalArgs,
+ exceptFiles, false);
+ }
+ protected void getDefineSwitch(StringBuffer buffer, String define,
+ String value) {
+ DevStudioProcessor.getDefineSwitch(buffer, define, value);
+ }
+ protected File[] getEnvironmentIncludePath() {
+ return CUtil.getPathFromEnvironment("INCLUDE", ";");
+ }
+ protected String getIncludeDirSwitch(String includeDir) {
+ return DevStudioProcessor.getIncludeDirSwitch(includeDir);
+ }
+ protected void getUndefineSwitch(StringBuffer buffer, String define) {
+ DevStudioProcessor.getUndefineSwitch(buffer, define);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLibrarian.java
new file mode 100644
index 0000000..985dfcf
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLibrarian.java
@@ -0,0 +1,80 @@
+/*
+ *
+ * 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.devstudio;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+/**
+ * Abstract base adapter for librarians with command line options compatible
+ * with the Microsoft(r) Library Manager
+ *
+ * @author Curt Arnold
+ */
+public abstract class DevStudioCompatibleLibrarian extends CommandLineLinker {
+ public DevStudioCompatibleLibrarian(String command, String identifierArg) {
+ super(command, identifierArg, new String[]{".obj"}, new String[0],
+ ".lib", false, null);
+ }
+ protected void addBase(long base, Vector args) {
+ }
+ protected void addFixed(Boolean fixed, Vector args) {
+ }
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ args.addElement("/nologo");
+ }
+ protected void addIncremental(boolean incremental, Vector args) {
+ }
+ protected void addMap(boolean map, Vector args) {
+ }
+ protected void addStack(int stack, Vector args) {
+ }
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)
+ */
+ protected void addEntry(String entry, Vector args) {
+ }
+
+ protected String getCommandFileSwitch(String cmdFile) {
+ return "@" + cmdFile;
+ }
+ public File[] getLibraryPath() {
+ return new File[0];
+ }
+ public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {
+ return new String[0];
+ }
+ public int getMaximumCommandLength() {
+ return 32767;
+ }
+ public String[] getOutputFileSwitch(String outFile) {
+ StringBuffer buf = new StringBuffer("/OUT:");
+ if (outFile.indexOf(' ') >= 0) {
+ buf.append('"');
+ buf.append(outFile);
+ buf.append('"');
+ } else {
+ buf.append(outFile);
+ }
+ return new String[]{buf.toString()};
+ }
+ public boolean isCaseSensitive() {
+ return false;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLinker.java
new file mode 100644
index 0000000..80d2aac
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLinker.java
@@ -0,0 +1,148 @@
+/*
+ *
+ * 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.devstudio;
+import java.io.File;
+import java.io.IOException;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.TargetMatcher;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.platforms.WindowsPlatform;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+
+/**
+ * Abstract base class for linkers that try to mimic the command line arguments
+ * for the Microsoft (r) Incremental Linker
+ *
+ * @author Curt Arnold
+ */
+public abstract class DevStudioCompatibleLinker extends CommandLineLinker {
+ public DevStudioCompatibleLinker(String command, String identifierArg,
+ String outputSuffix) {
+ super(command, identifierArg, new String[]{".obj", ".lib", ".res"},
+ new String[]{".map", ".pdb", ".lnk", ".dll"}, outputSuffix,
+ false, null);
+ }
+ protected void addBase(long base, Vector args) {
+ if (base >= 0) {
+ String baseAddr = Long.toHexString(base);
+ args.addElement("/BASE:0x" + baseAddr);
+ }
+ }
+ protected void addFixed(Boolean fixed, Vector args) {
+ if (fixed != null) {
+ if (fixed.booleanValue()) {
+ args.addElement("/FIXED");
+ } else {
+ args.addElement("/FIXED:NO");
+ }
+ }
+ }
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ args.addElement("/NOLOGO");
+ if (debug) {
+ args.addElement("/DEBUG");
+ }
+ if (linkType.isSharedLibrary()) {
+ args.addElement("/DLL");
+ }
+ //
+ // The following lines were commented out
+ // from v 1.5 to v 1.12 with no explanation
+ //
+ if(linkType.isSubsystemGUI()) {
+ args.addElement("/SUBSYSTEM:WINDOWS"); } else {
+ if(linkType.isSubsystemConsole()) {
+ args.addElement("/SUBSYSTEM:CONSOLE"); } }
+ }
+ protected void addIncremental(boolean incremental, Vector args) {
+ if (incremental) {
+ args.addElement("/INCREMENTAL:YES");
+ } else {
+ args.addElement("/INCREMENTAL:NO");
+ }
+ }
+ protected void addMap(boolean map, Vector args) {
+ if (map) {
+ args.addElement("/MAP");
+ }
+ }
+ protected void addStack(int stack, Vector args) {
+ if (stack >= 0) {
+ String stackStr = Integer.toHexString(stack);
+ args.addElement("/STACK:0x" + stackStr);
+ }
+ }
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)
+ */
+ protected void addEntry(String entry, Vector args) {
+ if (entry != null) {
+ args.addElement("/ENTRY:" + entry);
+ }
+ }
+
+ 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];
+ for (int i = 0; i < libnames.length; i++) {
+ buf.setLength(0);
+ buf.append(libnames[i]);
+ buf.append(".lib");
+ patterns[i] = buf.toString();
+ }
+ return patterns;
+ }
+ public int getMaximumCommandLength() {
+ return 32767;
+ }
+ public String[] getOutputFileSwitch(String outputFile) {
+ return new String[]{"/OUT:" + outputFile};
+ }
+ public boolean isCaseSensitive() {
+ return false;
+ }
+
+ /**
+ * Adds source or object files to the bidded fileset to
+ * support version information.
+ *
+ * @param versionInfo version information
+ * @param linkType link type
+ * @param isDebug true if debug build
+ * @param outputFile name of generated executable
+ * @param objDir directory for generated files
+ * @param matcher bidded fileset
+ */
+ public void addVersionFiles(final VersionInfo versionInfo,
+ final LinkType linkType,
+ final File outputFile,
+ final boolean isDebug,
+ final File objDir,
+ final TargetMatcher matcher) throws IOException {
+ WindowsPlatform.addVersionFiles(versionInfo, linkType, outputFile, isDebug, objDir, matcher);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioLibrarian.java
new file mode 100644
index 0000000..bd63f42
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioLibrarian.java
@@ -0,0 +1,36 @@
+/*
+ *
+ * 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.devstudio;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+/**
+ * Adapter for the Microsoft (r) Library Manager
+ *
+ * @author Curt Arnold
+ */
+public final class DevStudioLibrarian extends DevStudioCompatibleLibrarian {
+ private static final DevStudioLibrarian instance = new DevStudioLibrarian();
+ public static DevStudioLibrarian getInstance() {
+ return instance;
+ }
+ private DevStudioLibrarian() {
+ super("lib", "/bogus");
+ }
+ public Linker getLinker(LinkType type) {
+ return DevStudioLinker.getInstance().getLinker(type);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioLinker.java
new file mode 100644
index 0000000..826074b
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioLinker.java
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright 2001-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.devstudio;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+/**
+ * Adapter for the Microsoft (r) Incremental Linker
+ *
+ * @author Adam Murdoch
+ * @author Curt Arnold
+ */
+public final class DevStudioLinker extends DevStudioCompatibleLinker {
+ private static final DevStudioLinker dllLinker = new DevStudioLinker(".dll");
+ private static final DevStudioLinker instance = new DevStudioLinker(".exe");
+ public static DevStudioLinker getInstance() {
+ return instance;
+ }
+ private DevStudioLinker(String outputSuffix) {
+ super("link", "/DLL", outputSuffix);
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isSharedLibrary()) {
+ return dllLinker;
+ }
+ if (type.isStaticLibrary()) {
+ return DevStudioLibrarian.getInstance();
+ }
+ return instance;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioMIDLCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioMIDLCompiler.java
new file mode 100644
index 0000000..fa2e414
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioMIDLCompiler.java
@@ -0,0 +1,112 @@
+/*
+ *
+ * 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.devstudio;
+import java.io.File;
+import java.util.Vector;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.parser.CParser;
+import net.sf.antcontrib.cpptasks.parser.Parser;
+import org.apache.tools.ant.types.Environment;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+/**
+ * Adapter for the Microsoft (r) MIDL Compiler
+ *
+ * @author Curt Arnold
+ */
+public final class DevStudioMIDLCompiler extends CommandLineCompiler {
+ private static final DevStudioMIDLCompiler instance = new DevStudioMIDLCompiler(
+ false, null);
+ public static DevStudioMIDLCompiler getInstance() {
+ return instance;
+ }
+ private DevStudioMIDLCompiler(boolean newEnvironment, Environment env) {
+ super("midl", null, new String[]{".idl", ".odl"}, new String[]{},
+ ".tlb", false, null, newEnvironment, env);
+ }
+ protected void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ }
+ protected void addWarningSwitch(Vector args, int level) {
+ DevStudioProcessor.addWarningSwitch(args, level);
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new DevStudioMIDLCompiler(newEnvironment, env);
+ }
+ return this;
+ }
+ /**
+ * The include parser for C will work just fine, but we didn't want to
+ * inherit from CommandLineCCompiler
+ */
+ protected Parser createParser(File source) {
+ return new CParser();
+ }
+ protected int getArgumentCountPerInputFile() {
+ return 3;
+ }
+ protected void getDefineSwitch(StringBuffer buffer, String define,
+ String value) {
+ DevStudioProcessor.getDefineSwitch(buffer, define, value);
+ }
+ protected File[] getEnvironmentIncludePath() {
+ return CUtil.getPathFromEnvironment("INCLUDE", ";");
+ }
+ protected String getIncludeDirSwitch(String includeDir) {
+ return DevStudioProcessor.getIncludeDirSwitch(includeDir);
+ }
+ protected String getInputFileArgument(File outputDir, String filename,
+ int index) {
+ switch (index) {
+ case 0 :
+ return "/tlb";
+ case 1 :
+ return new File(outputDir, getOutputFileNames(filename, null)[0])
+ .getAbsolutePath();
+ }
+ return filename;
+ }
+ public Linker getLinker(LinkType type) {
+ return DevStudioLinker.getInstance().getLinker(type);
+ }
+ public int getMaximumCommandLength() {
+ return 32767;
+ }
+ protected int getMaximumInputFilesPerCommand() {
+ return 1;
+ }
+ protected int getTotalArgumentLengthForInputFile(File outputDir,
+ String inputFile) {
+ String arg1 = getInputFileArgument(outputDir, inputFile, 0);
+ String arg2 = getInputFileArgument(outputDir, inputFile, 1);
+ String arg3 = getInputFileArgument(outputDir, inputFile, 2);
+ return arg1.length() + arg2.length() + arg3.length() + 3;
+ }
+ protected void getUndefineSwitch(StringBuffer buffer, String define) {
+ DevStudioProcessor.getUndefineSwitch(buffer, define);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioProcessor.java
new file mode 100644
index 0000000..8257c09
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioProcessor.java
@@ -0,0 +1,90 @@
+/*
+ *
+ * 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.devstudio;
+import java.util.Vector;
+/**
+ * A add-in class for Microsoft Developer Studio processors
+ *
+ *
+ */
+public class DevStudioProcessor {
+ public static void addWarningSwitch(Vector args, int level) {
+ switch (level) {
+ case 0 :
+ args.addElement("/W0");
+ break;
+ case 1 :
+ args.addElement("/W1");
+ break;
+ case 2 :
+ break;
+ case 3 :
+ args.addElement("/W3");
+ break;
+ case 4 :
+ args.addElement("/W4");
+ break;
+ case 5 :
+ args.addElement("/WX");
+ break;
+ }
+ }
+ public static String getCommandFileSwitch(String cmdFile) {
+ StringBuffer buf = new StringBuffer("@");
+ if (cmdFile.indexOf(' ') >= 0) {
+ buf.append('\"');
+ buf.append(cmdFile.replace('/', '\\'));
+ buf.append('\"');
+ } else {
+ buf.append(cmdFile);
+ }
+ return buf.toString();
+ }
+ public static void getDefineSwitch(StringBuffer buffer, String define,
+ String value) {
+ buffer.append("/D");
+ buffer.append(define);
+ if (value != null && value.length() > 0) {
+ buffer.append('=');
+ buffer.append(value);
+ }
+ }
+ public static String getIncludeDirSwitch(String includeDir) {
+ return "/I" + includeDir.replace('/', '\\');
+ }
+ public static String[] getOutputFileSwitch(String outPath) {
+ StringBuffer buf = new StringBuffer("/Fo");
+ if (outPath.indexOf(' ') >= 0) {
+ buf.append('\"');
+ buf.append(outPath);
+ buf.append('\"');
+ } else {
+ buf.append(outPath);
+ }
+ String[] retval = new String[]{buf.toString()};
+ return retval;
+ }
+ public static void getUndefineSwitch(StringBuffer buffer, String define) {
+ buffer.append("/U");
+ buffer.append(define);
+ }
+ public static boolean isCaseSensitive() {
+ return false;
+ }
+ private DevStudioProcessor() {
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioProjectWriter.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioProjectWriter.java
new file mode 100644
index 0000000..51ab1dd
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioProjectWriter.java
@@ -0,0 +1,710 @@
+/*
+ *
+ * Copyright 2004-2008 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.devstudio;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.TargetInfo;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;
+import net.sf.antcontrib.cpptasks.ide.DependencyDef;
+import net.sf.antcontrib.cpptasks.ide.ProjectDef;
+import net.sf.antcontrib.cpptasks.ide.ProjectWriter;
+import net.sf.antcontrib.cpptasks.ide.CommentDef;
+import org.apache.tools.ant.BuildException;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.*;
+import java.text.MessageFormat;
+
+/**
+ * Writes a Microsoft Visual Studio 97 or Visual Studio 6 project file.
+ *
+ * Status: Collects file list but does not pick
+ * up libraries and settings from project.
+ *
+ * @author curta
+ */
+public final class DevStudioProjectWriter
+ implements ProjectWriter {
+ /**
+ * Visual Studio version.
+ */
+ private String version;
+
+ /**
+ * Constructor.
+ * @param versionArg String Visual Studio version.
+ */
+ public DevStudioProjectWriter(final String versionArg) {
+ this.version = versionArg;
+ }
+
+ private static String toProjectName(final String name) {
+ //
+ // some characters are apparently not allowed in VS project names
+ // but have not been able to find them documented
+ // limiting characters to alphas, numerics and hyphens
+ StringBuffer projectNameBuf = new StringBuffer(name);
+ for (int i = 0; i < projectNameBuf.length(); i++) {
+ final char ch = projectNameBuf.charAt(i);
+ if (!((ch >= 'a' && ch <= 'z')
+ || (ch >= 'A' && ch <= 'Z')
+ || (ch >= '0' && ch <= '9'))) {
+ projectNameBuf.setCharAt(i, '_');
+ }
+ }
+ return projectNameBuf.toString();
+
+ }
+
+ /**
+ * Writes a project definition file.
+ * @param fileName File name base, writer may append appropriate extension
+ * @param task cc task for which to write project
+ * @param projectDef project element
+ * @param files source files
+ * @param targets compilation targets
+ * @param linkTarget link target
+ * @throws IOException if error writing project file
+ */
+ public void writeProject(final File fileName,
+ final CCTask task,
+ final ProjectDef projectDef,
+ final List files,
+ final Hashtable targets,
+ final TargetInfo linkTarget) throws IOException {
+
+ //
+ // some characters are apparently not allowed in VS project names
+ // but have not been able to find them documented
+ // limiting characters to alphas, numerics and hyphens
+ String projectName = projectDef.getName();
+ if (projectName != null) {
+ projectName = toProjectName(projectName);
+ } else {
+ projectName = toProjectName(fileName.getName());
+ }
+
+ final String basePath = fileName.getAbsoluteFile().getParent();
+
+ File dspFile = new File(fileName + ".dsp");
+ if (!projectDef.getOverwrite() && dspFile.exists()) {
+ throw new BuildException("Not allowed to overwrite project file "
+ + dspFile.toString());
+ }
+ File dswFile = new File(fileName + ".dsw");
+ if (!projectDef.getOverwrite() && dswFile.exists()) {
+ throw new BuildException("Not allowed to overwrite project file "
+ + dswFile.toString());
+ }
+
+ CommandLineCompilerConfiguration compilerConfig =
+ getBaseCompilerConfiguration(targets);
+ if (compilerConfig == null) {
+ throw new BuildException(
+ "Unable to generate Visual Studio project "
+ + "when Microsoft C++ is not used.");
+ }
+
+ Writer writer = new BufferedWriter(new FileWriter(dspFile));
+ writer.write("# Microsoft Developer Studio Project File - Name=\"");
+ writer.write(projectName);
+ writer.write("\" - Package Owner=<4>\r\n");
+ writer.write(
+ "# Microsoft Developer Studio Generated Build File, Format Version ");
+ writer.write(this.version);
+ writer.write("\r\n");
+ writer.write("# ** DO NOT EDIT **\r\n\r\n");
+
+ writeComments(writer, projectDef.getComments());
+
+ String outputType = task.getOuttype();
+ String subsystem = task.getSubsystem();
+ String targtype = "Win32 (x86) Dynamic-Link Library";
+ String targid = "0x0102";
+ if ("executable".equals(outputType)) {
+ if ("console".equals(subsystem)) {
+ targtype = "Win32 (x86) Console Application";
+ targid = "0x0103";
+ } else {
+ targtype = "Win32 (x86) Application";
+ targid = "0x0101";
+ }
+ } else if ("static".equals(outputType)) {
+ targtype = "Win32 (x86) Static Library";
+ targid = "0x0104";
+ }
+ writer.write("# TARGTYPE \"");
+ writer.write(targtype);
+ writer.write("\" ");
+ writer.write(targid);
+ writer.write("\r\n\r\nCFG=");
+
+ writer.write(projectName + " - Win32 Debug");
+ writer.write("\r\n");
+
+ writeMessage(writer, projectName, targtype);
+
+ writer.write("# Begin Project\r\n");
+ if (version.equals("6.00")) {
+ writer.write("# PROP AllowPerConfigDependencies 0\r\n");
+ }
+ writer.write("# PROP Scc_ProjName \"\"\r\n");
+ writer.write("# PROP Scc_LocalPath \"\"\r\n");
+ writer.write("CPP=cl.exe\r\n");
+ writer.write("MTL=midl.exe\r\n");
+ writer.write("RSC=rc.exe\r\n");
+
+ writer.write("\r\n!IF \"$(CFG)\" == \"" + projectName + " - Win32 Release\"\r\n");
+
+ writeConfig(writer, false, projectDef.getDependencies(), basePath, compilerConfig, linkTarget, targets);
+
+ writer.write("\r\n!ELSEIF \"$(CFG)\" == \"" + projectName + " - Win32 Debug\"\r\n");
+
+ writeConfig(writer, true, projectDef.getDependencies(), basePath, compilerConfig, linkTarget, targets);
+
+ writer.write("\r\n!ENDIF\r\n");
+
+ writer.write("# Begin Target\r\n\r\n");
+ writer.write("# Name \"" + projectName + " - Win32 Release\"\r\n");
+ writer.write("# Name \"" + projectName + " - Win32 Debug\"\r\n");
+
+
+
+ File[] sortedSources = getSources(files);
+
+ if (version.equals("6.00")) {
+ final String sourceFilter = "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat";
+ final String headerFilter = "h;hpp;hxx;hm;inl";
+ final String resourceFilter =
+ "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe";
+
+ writer.write("# Begin Group \"Source Files\"\r\n\r\n");
+ writer.write("# PROP Default_Filter \"" + sourceFilter + "\"\r\n");
+
+ for (int i = 0; i < sortedSources.length; i++) {
+ if (!isGroupMember(headerFilter, sortedSources[i])
+ && !isGroupMember(resourceFilter, sortedSources[i])) {
+ writeSource(writer, basePath, sortedSources[i]);
+ }
+ }
+ writer.write("# End Group\r\n");
+
+ writer.write("# Begin Group \"Header Files\"\r\n\r\n");
+ writer.write("# PROP Default_Filter \"" + headerFilter + "\"\r\n");
+
+ for (int i = 0; i < sortedSources.length; i++) {
+ if (isGroupMember(headerFilter, sortedSources[i])) {
+ writeSource(writer, basePath, sortedSources[i]);
+ }
+ }
+ writer.write("# End Group\r\n");
+
+ writer.write("# Begin Group \"Resource Files\"\r\n\r\n");
+ writer.write("# PROP Default_Filter \"" + resourceFilter + "\"\r\n");
+
+ for (int i = 0; i < sortedSources.length; i++) {
+ if (isGroupMember(resourceFilter, sortedSources[i])) {
+ writeSource(writer, basePath, sortedSources[i]);
+ }
+ }
+ writer.write("# End Group\r\n");
+
+ } else {
+ for (int i = 0; i < sortedSources.length; i++) {
+ writeSource(writer, basePath, sortedSources[i]);
+ }
+ }
+
+ writer.write("# End Target\r\n");
+ writer.write("# End Project\r\n");
+ writer.close();
+
+ //
+ // write workspace file
+ //
+ writer = new BufferedWriter(new FileWriter(dswFile));
+ writeWorkspace(writer, projectDef, projectName, dspFile);
+ writer.close();
+
+ }
+
+ private void writeConfig(final Writer writer,
+ boolean isDebug,
+ final List dependencies,
+ final String basePath,
+ CommandLineCompilerConfiguration compilerConfig,
+ TargetInfo linkTarget,
+ Hashtable targets) throws IOException {
+ writer.write("# PROP BASE Use_MFC 0\r\n");
+
+ String configType = "Release";
+ String configInt = "0";
+ String configMacro = "NDEBUG";
+ if (isDebug) {
+ configType = "Debug";
+ configInt = "1";
+ configMacro = "_DEBUG";
+ }
+
+ writer.write("# PROP BASE Use_Debug_Libraries ");
+ writer.write(configInt);
+ writer.write("\r\n# PROP BASE Output_Dir \"");
+ writer.write(configType);
+ writer.write("\"\r\n");
+ writer.write("# PROP BASE Intermediate_Dir \"");
+ writer.write(configType);
+ writer.write("\"\r\n");
+ writer.write("# PROP BASE Target_Dir \"\"\r\n");
+ writer.write("# PROP Use_MFC 0\r\n");
+ writer.write("# PROP Use_Debug_Libraries ");
+ writer.write(configInt);
+ writer.write("\r\n# PROP Output_Dir \"");
+ writer.write(configType);
+ writer.write("\"\r\n");
+ writer.write("# PROP Intermediate_Dir \"");
+ writer.write(configType);
+ writer.write("\"\r\n");
+ writer.write("# PROP Target_Dir \"\"\r\n");
+ writeCompileOptions(writer, isDebug, basePath, compilerConfig);
+ writer.write(
+ "# ADD BASE MTL /nologo /D \"" + configMacro + "\" /mktyplib203 /o NUL /win32\r\n");
+ writer.write(
+ "# ADD MTL /nologo /D \"" + configMacro + "\" /mktyplib203 /o NUL /win32\r\n");
+ writer.write("# ADD BASE RSC /l 0x409 /d \"" + configMacro + "\"\r\n");
+ writer.write("# ADD RSC /l 0x409 /d \"" + configMacro + "\"\r\n");
+ writer.write("BSC32=bscmake.exe\r\n");
+ writer.write("# ADD BASE BSC32 /nologo\r\n");
+ writer.write("# ADD BSC32 /nologo\r\n");
+ writer.write("LINK32=link.exe\r\n");
+ writeLinkOptions(writer, isDebug, dependencies, basePath, linkTarget, targets);
+ }
+ private static void writeWorkspaceProject(final Writer writer,
+ final String projectName,
+ final String projectFile,
+ final List dependsOn) throws IOException {
+ writer.write("############################################");
+ writer.write("###################################\r\n\r\n");
+ String file = projectFile;
+ if(!file.startsWith(".") && !file.startsWith("\\") && !file.startsWith("/")) {
+ file = ".\\" + file;
+ }
+ writer.write("Project: \"" + projectName + "\"=\""
+ + file
+ + "\" - Package Owner=<4>\r\n\r\n");
+
+ writer.write("Package=<5>\r\n{{{\r\n}}}\r\n\r\n");
+ writer.write("Package=<4>\r\n{{{\r\n");
+ if (dependsOn != null) {
+ for(Iterator iter = dependsOn.iterator(); iter.hasNext();) {
+ writer.write(" Begin Project Dependency\r\n");
+ writer.write(" Project_Dep_Name " + toProjectName(String.valueOf(iter.next())) + "\r\n");
+ writer.write(" End Project Dependency\r\n");
+ }
+ }
+ writer.write("}}}\r\n\r\n");
+
+ }
+
+ private void writeWorkspace(final Writer writer,
+ final ProjectDef project,
+ final String projectName,
+ final File dspFile) throws IOException {
+
+ writer.write("Microsoft Developer Studio Workspace File, Format Version ");
+ writer.write(version);
+ writer.write("\r\n");
+ writer.write("# WARNING: DO NOT EDIT OR DELETE");
+ writer.write(" THIS WORKSPACE FILE!\r\n\r\n");
+
+ writeComments(writer, project.getComments());
+
+
+ List dependencies = project.getDependencies();
+ List projectDeps = new ArrayList();
+ String basePath = dspFile.getParent();
+ for(Iterator iter = dependencies.iterator(); iter.hasNext();) {
+ DependencyDef dep = (DependencyDef) iter.next();
+ if (dep.getFile() != null) {
+ String projName = toProjectName(dep.getName());
+ projectDeps.add(projName);
+ String depProject = CUtil.toWindowsPath(
+ CUtil.getRelativePath(basePath,
+ new File(dep.getFile() + ".dsp")));
+ writeWorkspaceProject(writer, projName, depProject, dep.getDependsList());
+ }
+ }
+
+ writeWorkspaceProject(writer, projectName, dspFile.getName(), projectDeps);
+
+ writer.write("############################################");
+ writer.write("###################################\r\n\r\n");
+
+
+ writer.write("Global:\r\n\r\nPackage=<5>\r\n{{{\r\n}}}");
+ writer.write("\r\n\r\nPackage=<3>\r\n{{{\r\n}}}\r\n\r\n");
+
+ writer.write("########################################");
+ writer.write("#######################################\r\n\r\n");
+
+ }
+
+ /**
+ * Returns true if the file has an extension that appears in the group filter.
+ * @param filter String group filter
+ * @param candidate File file
+ * @return boolean true if member of group
+ */
+ private boolean isGroupMember(final String filter, final File candidate) {
+ String fileName = candidate.getName();
+ int lastDot = fileName.lastIndexOf('.');
+ if (lastDot >= 0 && lastDot < fileName.length() - 1) {
+ String extension =
+ ";" + fileName.substring(lastDot + 1).toLowerCase() + ";";
+ String semiFilter = ";" + filter + ";";
+ return semiFilter.indexOf(extension) >= 0;
+ }
+ return false;
+ }
+
+ /**
+ * Writes the entry for one source file in the project.
+ * @param writer Writer writer
+ * @param basePath String base path for project
+ * @param groupMember File project source file
+ * @throws IOException if error writing project file
+ */
+ private void writeSource(final Writer writer,
+ final String basePath,
+ final File groupMember)
+ throws IOException {
+ writer.write("# Begin Source File\r\n\r\nSOURCE=");
+ String relativePath = CUtil.getRelativePath(basePath,
+ groupMember);
+ //
+ // if relative path is just a name (hello.c) then
+ // make it .\hello.c
+ if (!relativePath.startsWith(".")
+ && relativePath.indexOf(":") < 0
+ && !relativePath.startsWith("\\")) {
+ relativePath = ".\\" + relativePath;
+ }
+ writer.write(CUtil.toWindowsPath(relativePath));
+ writer.write("\r\n# End Source File\r\n");
+ }
+
+ /**
+ * Get alphabetized array of source files.
+ * @param sourceList list of source files
+ * @return File[] source files
+ */
+ private File[] getSources(final List sourceList) {
+ File[] sortedSources = new File[sourceList.size()];
+ sourceList.toArray(sortedSources);
+ Arrays.sort(sortedSources, new Comparator() {
+ public int compare(final Object o1, final Object o2) {
+ return ((File) o1).getName().compareTo(((File) o2).getName());
+ }
+ });
+ return sortedSources;
+ }
+
+ /**
+ * Writes "This is not a makefile" warning.
+ * @param writer Writer writer
+ * @param projectName String project name
+ * @param targtype String target type
+ * @throws IOException if error writing project
+ */
+
+ private void writeMessage(final Writer writer,
+ final String projectName,
+ final String targtype) throws IOException {
+ writer.write(
+ "!MESSAGE This is not a valid makefile. ");
+ writer.write("To build this project using NMAKE,\r\n");
+ writer.write("!MESSAGE use the Export Makefile command and run\r\n");
+ writer.write("!MESSAGE \r\n");
+ writer.write("!MESSAGE NMAKE /f \"");
+ writer.write(projectName);
+ writer.write(".mak\".\r\n");
+ writer.write("!MESSAGE \r\n");
+ writer.write(
+ "!MESSAGE You can specify a configuration when running NMAKE\r\n");
+ writer.write(
+ "!MESSAGE by defining the macro CFG on the command line. ");
+ writer.write("For example:\r\n");
+ writer.write("!MESSAGE \r\n");
+ writer.write("!MESSAGE NMAKE /f \"");
+ writer.write(projectName);
+ writer.write(".mak\" CFG=\"");
+ writer.write(projectName);
+ writer.write(" - Win32 Debug\"\r\n");
+ writer.write("!MESSAGE \r\n");
+ writer.write("!MESSAGE Possible choices for configuration are:\r\n");
+ writer.write("!MESSAGE \r\n");
+ String pattern = "!MESSAGE \"{0} - Win32 {1}\" (based on \"{2}\")\r\n";
+ writer.write(MessageFormat.format(pattern, new Object[] { projectName, "Release", targtype }));
+ writer.write(MessageFormat.format(pattern, new Object[] { projectName, "Debug", targtype }));
+ writer.write("!MESSAGE \r\n");
+ writer.write("\r\n");
+
+ }
+
+ /**
+ * Gets the first recognized compiler from the
+ * compilation targets.
+ * @param targets compilation targets
+ * @return representative (hopefully) compiler configuration
+ */
+ private CommandLineCompilerConfiguration
+ getBaseCompilerConfiguration(final Hashtable targets) {
+ //
+ // find first target with an DevStudio C compilation
+ //
+ CommandLineCompilerConfiguration compilerConfig;
+ //
+ // get the first target and assume that it is representative
+ //
+ Iterator targetIter = targets.values().iterator();
+ while (targetIter.hasNext()) {
+ TargetInfo targetInfo = (TargetInfo) targetIter.next();
+ ProcessorConfiguration config = targetInfo.getConfiguration();
+ //
+ // for the first cl compiler
+ //
+ if (config instanceof CommandLineCompilerConfiguration) {
+ compilerConfig = (CommandLineCompilerConfiguration) config;
+ if (compilerConfig.getCompiler() instanceof DevStudioCCompiler) {
+ return compilerConfig;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Writes compiler options.
+ * @param writer Writer writer
+ * @param isDebug true if debug.
+ * @param baseDir String base directory
+ * @param compilerConfig compiler configuration
+ * @throws IOException if error on writing project
+ */
+ private void writeCompileOptions(final Writer writer,
+ final boolean isDebug,
+ final String baseDir,
+ final CommandLineCompilerConfiguration
+ compilerConfig) throws IOException {
+ StringBuffer baseOptions = new StringBuffer(50);
+ baseOptions.append("# ADD BASE CPP");
+ StringBuffer options = new StringBuffer(50);
+ options.append("# ADD CPP");
+ File[] includePath = compilerConfig.getIncludePath();
+ for (int i = 0; i < includePath.length; i++) {
+ options.append(" /I \"");
+ String relPath = CUtil.getRelativePath(baseDir, includePath[i]);
+ options.append(CUtil.toWindowsPath(relPath));
+ options.append('"');
+ }
+ Hashtable optionMap = new Hashtable();
+
+ if (isDebug) {
+ //
+ // release options that should be mapped to debug counterparts
+ //
+ optionMap.put("/MT", "/MTd");
+ optionMap.put("/ML", "/MLd");
+ optionMap.put("/MD", "/MDd");
+ optionMap.put("/O2", "/Od");
+ optionMap.put("/O3", "/Od");
+ } else {
+ //
+ // debug options that should be mapped to release counterparts
+ //
+ optionMap.put("/MTD", "/MT");
+ optionMap.put("/MLD", "/ML");
+ optionMap.put("/MDD", "/MD");
+ optionMap.put("/GM", "");
+ optionMap.put("/ZI", "");
+ optionMap.put("/OD", "/O2");
+ optionMap.put("/GZ", "");
+ }
+
+
+
+ String[] preArgs = compilerConfig.getPreArguments();
+ for (int i = 0; i < preArgs.length; i++) {
+ if (preArgs[i].startsWith("/D")) {
+ options.append(" /D ");
+ baseOptions.append(" /D ");
+ String body = preArgs[i].substring(2);
+ if (preArgs[i].indexOf('=') >= 0) {
+ options.append(body);
+ baseOptions.append(body);
+ } else {
+ StringBuffer buf = new StringBuffer("\"");
+ if ("NDEBUG".equals(body) || "_DEBUG".equals(body)) {
+ if (isDebug) {
+ buf.append("_DEBUG");
+ } else {
+ buf.append("NDEBUG");
+ }
+ } else {
+ buf.append(body);
+ }
+ buf.append("\"");
+ options.append(buf);
+ baseOptions.append(buf);
+ }
+ } else if (!preArgs[i].startsWith("/I")) {
+ String option = preArgs[i];
+ String key = option.toUpperCase(Locale.US);
+ if (optionMap.containsKey(key)) {
+ option = optionMap.get(key).toString();
+ }
+ options.append(" ");
+ options.append(option);
+ baseOptions.append(" ");
+ baseOptions.append(option);
+ }
+ }
+ baseOptions.append("\r\n");
+ options.append("\r\n");
+ writer.write(baseOptions.toString());
+ writer.write(options.toString());
+
+ }
+
+
+
+
+
+ /**
+ * Writes link options.
+ * @param writer Writer writer
+ * @param basePath String base path
+ * @param dependencies project dependencies, used to suppress explicit linking.
+ * @param linkTarget TargetInfo link target
+ * @param targets Hashtable all targets
+ * @throws IOException if unable to write to project file
+ */
+ private void writeLinkOptions(final Writer writer,
+ final boolean isDebug,
+ final List dependencies,
+ final String basePath,
+ final TargetInfo linkTarget,
+ final Hashtable targets) throws IOException {
+
+ StringBuffer baseOptions = new StringBuffer(100);
+ StringBuffer options = new StringBuffer(100);
+ baseOptions.append("# ADD BASE LINK32");
+ options.append("# ADD LINK32");
+
+ ProcessorConfiguration config = linkTarget.getConfiguration();
+ if (config instanceof CommandLineLinkerConfiguration) {
+ CommandLineLinkerConfiguration linkConfig =
+ (CommandLineLinkerConfiguration) config;
+
+ File[] linkSources = linkTarget.getAllSources();
+ for (int i = 0; i < linkSources.length; i++) {
+ //
+ // if file was not compiled or otherwise generated
+ //
+ if (targets.get(linkSources[i].getName()) == null) {
+ //
+ // if source appears to be a system library or object file
+ // just output the name of the file (advapi.lib for example)
+ // otherwise construct a relative path.
+ //
+ String relPath = linkSources[i].getName();
+ //
+ // check if file comes from a project dependency
+ // if it does it should not be explicitly linked
+ boolean fromDependency = false;
+ if (relPath.indexOf(".") > 0) {
+ String baseName = relPath.substring(0, relPath.indexOf("."));
+ for(Iterator iter = dependencies.iterator(); iter.hasNext(); ) {
+ DependencyDef depend = (DependencyDef) iter.next();
+ if (baseName.compareToIgnoreCase(depend.getName()) == 0) {
+ fromDependency = true;
+ }
+ }
+ }
+ if (!fromDependency) {
+ if (!CUtil.isSystemPath(linkSources[i])) {
+ relPath = CUtil.getRelativePath(basePath, linkSources[i]);
+ }
+ //
+ // if path has an embedded space then
+ // must quote
+ if (relPath.indexOf(' ') > 0) {
+ options.append(" \"");
+ options.append(CUtil.toWindowsPath(relPath));
+ options.append("\"");
+ } else {
+ options.append(' ');
+ options.append(CUtil.toWindowsPath(relPath));
+ }
+ }
+ }
+ }
+ String[] preArgs = linkConfig.getPreArguments();
+ for (int i = 0; i < preArgs.length; i++) {
+ if (isDebug || !preArgs[i].equals("/DEBUG")) {
+ options.append(' ');
+ options.append(preArgs[i]);
+ baseOptions.append(' ');
+ baseOptions.append(preArgs[i]);
+ }
+ }
+ String[] endArgs = linkConfig.getEndArguments();
+ for (int i = 0; i < endArgs.length; i++) {
+ options.append(' ');
+ options.append(endArgs[i]);
+ baseOptions.append(' ');
+ baseOptions.append(endArgs[i]);
+ }
+ }
+ baseOptions.append("\r\n");
+ options.append("\r\n");
+ writer.write(baseOptions.toString());
+ writer.write(options.toString());
+ }
+
+ private static void writeComments(final Writer writer,
+ final List comments) throws IOException {
+ for(Iterator iter = comments.iterator();iter.hasNext();) {
+ String comment = ((CommentDef) iter.next()).getText();
+ if (comment != null) {
+ int start = 0;
+ for(int end = comment.indexOf('\n');
+ end != -1;
+ end = comment.indexOf('\n', start)) {
+ writer.write("#" + comment.substring(start, end) + "\r\n");
+ start = end + 1;
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioResourceCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioResourceCompiler.java
new file mode 100644
index 0000000..6f8360b
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioResourceCompiler.java
@@ -0,0 +1,119 @@
+/*
+ *
+ * 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.devstudio;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.parser.CParser;
+import net.sf.antcontrib.cpptasks.parser.Parser;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for the Microsoft (r) Windows 32 Resource Compiler
+ *
+ * @author Curt Arnold
+ */
+public final class DevStudioResourceCompiler extends CommandLineCompiler {
+ private static final DevStudioResourceCompiler instance = new DevStudioResourceCompiler(
+ false, null);
+ public static DevStudioResourceCompiler getInstance() {
+ return instance;
+ }
+ private String identifier;
+ private DevStudioResourceCompiler(boolean newEnvironment, Environment env) {
+ super("rc", null, new String[]{".rc"}, new String[]{".h", ".hpp",
+ ".inl"}, ".res", false, null, newEnvironment, env);
+ }
+ protected void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ if (debug) {
+ args.addElement("/D_DEBUG");
+ } else {
+ args.addElement("/DNDEBUG");
+ }
+ }
+ protected void addWarningSwitch(Vector args, int level) {
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new DevStudioResourceCompiler(newEnvironment, env);
+ }
+ return this;
+ }
+ /**
+ * The include parser for C will work just fine, but we didn't want to
+ * inherit from CommandLineCCompiler
+ */
+ protected Parser createParser(File source) {
+ return new CParser();
+ }
+ protected int getArgumentCountPerInputFile() {
+ return 2;
+ }
+ protected void getDefineSwitch(StringBuffer buffer, String define,
+ String value) {
+ DevStudioProcessor.getDefineSwitch(buffer, define, value);
+ }
+ protected File[] getEnvironmentIncludePath() {
+ return CUtil.getPathFromEnvironment("INCLUDE", ";");
+ }
+ protected String getIncludeDirSwitch(String includeDir) {
+ return DevStudioProcessor.getIncludeDirSwitch(includeDir);
+ }
+ protected String getInputFileArgument(File outputDir, String filename,
+ int index) {
+ if (index == 0) {
+ String outputFileName = getOutputFileNames(filename, null)[0];
+ String fullOutputName = new File(outputDir, outputFileName)
+ .toString();
+ return "/fo" + fullOutputName;
+ }
+ return filename;
+ }
+ public Linker getLinker(LinkType type) {
+ return DevStudioLinker.getInstance().getLinker(type);
+ }
+ public int getMaximumCommandLength() {
+ return 32767;
+ }
+ protected int getMaximumInputFilesPerCommand() {
+ return 1;
+ }
+ protected int getTotalArgumentLengthForInputFile(File outputDir,
+ String inputFile) {
+ String arg1 = getInputFileArgument(outputDir, inputFile, 0);
+ String arg2 = getInputFileArgument(outputDir, inputFile, 1);
+ return arg1.length() + arg2.length() + 2;
+ }
+ protected void getUndefineSwitch(StringBuffer buffer, String define) {
+ DevStudioProcessor.getUndefineSwitch(buffer, define);
+ }
+ public String getIdentifier() {
+ return "Microsoft (R) Windows (R) Resource Compiler";
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/VisualStudioNETProjectWriter.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/VisualStudioNETProjectWriter.java
new file mode 100644
index 0000000..f554e09
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/VisualStudioNETProjectWriter.java
@@ -0,0 +1,866 @@
+/*
+ *
+ * Copyright 2004-2008 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.devstudio;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.TargetInfo;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;
+import net.sf.antcontrib.cpptasks.ide.ProjectDef;
+import net.sf.antcontrib.cpptasks.ide.CommentDef;
+import net.sf.antcontrib.cpptasks.ide.ProjectWriter;
+import net.sf.antcontrib.cpptasks.ide.DependencyDef;
+import org.apache.tools.ant.BuildException;
+import org.apache.xml.serialize.OutputFormat;
+import org.apache.xml.serialize.XMLSerializer;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Writes a Visual Studio.NET project file.
+ *
+ * @author curta
+ */
+public final class VisualStudioNETProjectWriter
+ implements ProjectWriter {
+ /**
+ * Version of VisualStudio.NET.
+ */
+ private final String version;
+
+ /**
+ * Literal to represent a true value.
+ */
+ private final String trueLiteral;
+
+ /**
+ * Literal to represent a false value.
+ */
+ private final String falseLiteral;
+
+ /**
+ * Constructor.
+ *
+ * @param versionArg String VisualStudio.NET version
+ * @param trueArg literal to represent true, "true" in VC 2005.
+ * @param falseArg literal to represent false, "false" in VC 2005.
+ */
+ public VisualStudioNETProjectWriter(final String versionArg,
+ final String trueArg,
+ final String falseArg) {
+ if (versionArg == null) {
+ throw new IllegalArgumentException("versionArg");
+ }
+ if (trueArg == null) {
+ throw new IllegalArgumentException("trueArg");
+ }
+ if (falseArg == null) {
+ throw new IllegalArgumentException("falseArg");
+ }
+ this.version = versionArg;
+ this.trueLiteral = trueArg;
+ this.falseLiteral = falseArg;
+ }
+
+
+
+ /**
+ * Gets the configuration type.
+ *
+ * @param task cc task, may not be null.
+ * @return configuration type
+ */
+ private String getConfigurationType(final CCTask task) {
+ String outputType = task.getOuttype();
+ String targtype = "2"; // Win32 (x86) Dynamic-Link Library";
+ if ("executable".equals(outputType)) {
+ targtype = "1"; // "Win32 (x86) Console Application";
+ } else if ("static".equals(outputType)) {
+ targtype = "4"; //"Win32 (x86) Static Library";
+ }
+ return targtype;
+ }
+
+
+
+ /**
+ * Get character set for Windows API.
+ * @param compilerConfig compiler configuration, may not be null.
+ * @return "1" is TCHAR is unicode, "0" if TCHAR is multi-byte.
+ */
+ private String getCharacterSet(
+ final CommandLineCompilerConfiguration compilerConfig) {
+ String[] args = compilerConfig.getPreArguments();
+ String charset = "0";
+ for (int i = 0; i < args.length; i++) {
+ if ("/D_UNICODE".equals(args[i]) || "/DUNICODE".equals(args[i])) {
+ charset = "1";
+ }
+ if ("/D_MBCS".equals(args[i])) {
+ charset = "2";
+ }
+ }
+ return charset;
+ }
+
+ /**
+ * Write the start tag of the Configuration element.
+ * @param content serialization content handler.
+ * @param isDebug if true, write a debug configuration.
+ * @param task cc task.
+ * @param compilerConfig compiler configuration.
+ * @throws SAXException thrown if serialization error.
+ */
+ private void writeConfigurationStartTag(final ContentHandler content,
+ final boolean isDebug,
+ final CCTask task,
+ final CommandLineCompilerConfiguration compilerConfig)
+ throws SAXException {
+ AttributesImpl attributes = new AttributesImpl();
+ if (isDebug) {
+ addAttribute(attributes, "Name", "Debug|Win32");
+ addAttribute(attributes, "OutputDirectory", "Debug");
+ addAttribute(attributes, "IntermediateDirectory", "Debug");
+ } else {
+ addAttribute(attributes, "Name", "Release|Win32");
+ addAttribute(attributes, "OutputDirectory", "Release");
+ addAttribute(attributes, "IntermediateDirectory", "Release");
+
+ }
+ addAttribute(attributes, "ConfigurationType",
+ getConfigurationType(task));
+ addAttribute(attributes, "CharacterSet",
+ getCharacterSet(compilerConfig));
+ content.startElement(null,
+ "Configuration", "Configuration", attributes);
+ }
+
+ /**
+ * Get value of Optimization property.
+ * @param compilerConfig compiler configuration, may not be null.
+ * @return value of Optimization property.
+ */
+ private String getOptimization(
+ final CommandLineCompilerConfiguration compilerConfig) {
+ String[] args = compilerConfig.getPreArguments();
+ String opt = "0";
+ for (int i = 0; i < args.length; i++) {
+ if ("/Od".equals(args[i])) {
+ opt = "0";
+ }
+ if ("/O1".equals(args[i])) {
+ opt = "1";
+ }
+ if ("/O2".equals(args[i])) {
+ opt = "2";
+ }
+ if ("/Ox".equals(args[i])) {
+ opt = "3";
+ }
+ }
+ return opt;
+ }
+
+ /**
+ * Get value of AdditionalIncludeDirectories property.
+ * @param compilerConfig compiler configuration.
+ * @param baseDir base for relative paths.
+ * @return value of AdditionalIncludeDirectories property.
+ */
+ private String getAdditionalIncludeDirectories(
+ final String baseDir,
+ final CommandLineCompilerConfiguration compilerConfig) {
+ File[] includePath = compilerConfig.getIncludePath();
+ StringBuffer includeDirs = new StringBuffer();
+ for (int i = 0; i < includePath.length; i++) {
+ String relPath = CUtil.getRelativePath(baseDir, includePath[i]);
+ includeDirs.append(CUtil.toWindowsPath(relPath));
+ includeDirs.append(';');
+ }
+
+
+ if (includeDirs.length() > 0) {
+ includeDirs.setLength(includeDirs.length() - 1);
+ }
+ return includeDirs.toString();
+ }
+
+ /**
+ * Get value of PreprocessorDefinitions property.
+ * @param compilerConfig compiler configuration.
+ * @param isDebug true if generating debug configuration.
+ * @return value of PreprocessorDefinitions property.
+ */
+ private String getPreprocessorDefinitions(
+ final CommandLineCompilerConfiguration compilerConfig,
+ final boolean isDebug) {
+ StringBuffer defines = new StringBuffer();
+ String[] args = compilerConfig.getPreArguments();
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].startsWith("/D")) {
+ String macro = args[i].substring(2);
+ if (isDebug) {
+ if (macro.equals("NDEBUG")) {
+ macro = "_DEBUG";
+ }
+ } else {
+ if (macro.equals("_DEBUG")) {
+ macro = "NDEBUG";
+ }
+ }
+ defines.append(macro);
+ defines.append(";");
+ }
+ }
+
+ if (defines.length() > 0) {
+ defines.setLength(defines.length() - 1);
+ }
+ return defines.toString();
+ }
+
+ /**
+ * Get value of RuntimeLibrary property.
+ * @param compilerConfig compiler configuration.
+ * @param isDebug true if generating debug configuration.
+ * @return value of RuntimeLibrary property.
+ */
+ private String getRuntimeLibrary(
+ final CommandLineCompilerConfiguration compilerConfig,
+ final boolean isDebug) {
+ String rtl = null;
+ String[] args = compilerConfig.getPreArguments();
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].startsWith("/MT")) {
+ if (isDebug) {
+ rtl = "1";
+ } else {
+ rtl = "0";
+ }
+ } else if (args[i].startsWith("/MD")) {
+ if (isDebug) {
+ rtl = "3";
+ } else {
+ rtl = "2";
+ }
+ }
+ }
+ return rtl;
+ }
+
+ /**
+ * Get value of UsePrecompiledHeader property.
+ * @param compilerConfig compiler configuration.
+ * @return value of UsePrecompiledHeader property.
+ */
+ private String getUsePrecompiledHeader(
+ final CommandLineCompilerConfiguration compilerConfig) {
+ String usePCH = "0";
+ String[] args = compilerConfig.getPreArguments();
+ for (int i = 0; i < args.length; i++) {
+ if ("/Yc".equals(args[i])) {
+ usePCH = "1";
+ }
+ if ("/Yu".equals(args[i])) {
+ usePCH = "2";
+ }
+ }
+ return usePCH;
+ }
+
+ /**
+ * Get value of PrecompiledHeaderFile property.
+ * @param compilerConfig compiler configuration.
+ * @return value of PrecompiledHeaderFile property.
+ */
+ private String getPrecompiledHeaderFile(
+ final CommandLineCompilerConfiguration compilerConfig) {
+ String pch = null;
+ String[] args = compilerConfig.getPreArguments();
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].startsWith("/Fp")) {
+ pch = args[i].substring(3);
+ }
+ }
+ return pch;
+ }
+
+
+
+ /**
+ * Get value of BasicRuntimeChecks property.
+ * @param compilerConfig compiler configuration.
+ * @return value of BasicRuntimeChecks property.
+ */
+ private String getBasicRuntimeChecks(
+ final CommandLineCompilerConfiguration compilerConfig) {
+ String checks = "0";
+ String[] args = compilerConfig.getPreArguments();
+ for (int i = 0; i < args.length; i++) {
+ if ("/RTCs".equals(args[i])) {
+ checks = "1";
+ }
+ if ("/RTCu".equals(args[i])) {
+ checks = "2";
+ }
+ if ("/RTC1".equals(args[i]) || "/GZ".equals(args[i])) {
+ checks = "3";
+ }
+ }
+ return checks;
+ }
+
+ /**
+ * Get value of WarningLevel property.
+ * @param compilerConfig compiler configuration.
+ * @return value of WarningLevel property.
+ */
+ private String getWarningLevel(
+ final CommandLineCompilerConfiguration compilerConfig) {
+ String warn = null;
+ String[] args = compilerConfig.getPreArguments();
+ for (int i = 0; i < args.length; i++) {
+ if ("/W0".equals(args[i])) {
+ warn = "0";
+ }
+ if ("/W1".equals(args[i])) {
+ warn = "1";
+ }
+ if ("/W2".equals(args[i])) {
+ warn = "2";
+ }
+ if ("/W3".equals(args[i])) {
+ warn = "3";
+ }
+ }
+ return warn;
+ }
+
+ /**
+ * Get value of Detect64BitPortabilityProblems property.
+ * @param compilerConfig compiler configuration.
+ * @return value of Detect64BitPortabilityProblems property.
+ */
+ private String getDetect64BitPortabilityProblems(
+ final CommandLineCompilerConfiguration compilerConfig) {
+ String warn64 = null;
+ String[] args = compilerConfig.getPreArguments();
+ for (int i = 0; i < args.length; i++) {
+ if ("/Wp64".equals(args[i])) {
+ warn64 = trueLiteral;
+ }
+ }
+ return warn64;
+ }
+
+ /**
+ * Get value of DebugInformationFormat property.
+ * @param compilerConfig compiler configuration.
+ * @return value of DebugInformationFormat property.
+ */
+ private String getDebugInformationFormat(
+ final CommandLineCompilerConfiguration compilerConfig) {
+ String format = "0";
+ String[] args = compilerConfig.getPreArguments();
+ for (int i = 0; i < args.length; i++) {
+ if ("/Z7".equals(args[i])) {
+ format = "1";
+ }
+ if ("/Zd".equals(args[i])) {
+ format = "2";
+ }
+ if ("/Zi".equals(args[i])) {
+ format = "3";
+ }
+ if ("/ZI".equals(args[i])) {
+ format = "4";
+ }
+ }
+ return format;
+ }
+
+ /**
+ * write the Compiler element.
+ * @param content serialization content handler.
+ * @param isDebug true if generating debug configuration.
+ * @param basePath base for relative file paths.
+ * @param compilerConfig compiler configuration.
+ * @throws SAXException thrown if error during serialization.
+ */
+ private void writeCompilerElement(final ContentHandler content,
+ final boolean isDebug,
+ final String basePath,
+ final CommandLineCompilerConfiguration compilerConfig)
+ throws SAXException {
+ AttributesImpl attributes = new AttributesImpl();
+ addAttribute(attributes, "Name", "VCCLCompilerTool");
+ String optimization = getOptimization(compilerConfig);
+ String debugFormat = getDebugInformationFormat(compilerConfig);
+ if(isDebug) {
+ optimization = "0";
+ if ("0".equals(debugFormat)) {
+ debugFormat = "4";
+ }
+ } else {
+ if ("0".equals(optimization)) {
+ optimization = "2";
+ }
+ debugFormat = "0";
+ }
+ addAttribute(attributes, "Optimization", optimization);
+ addAttribute(attributes, "AdditionalIncludeDirectories",
+ getAdditionalIncludeDirectories(basePath, compilerConfig));
+ addAttribute(attributes, "PreprocessorDefinitions",
+ getPreprocessorDefinitions(compilerConfig, isDebug));
+ addAttribute(attributes, "MinimalRebuild", trueLiteral);
+ addAttribute(attributes, "BasicRuntimeChecks",
+ getBasicRuntimeChecks(compilerConfig));
+ addAttribute(attributes, "RuntimeLibrary",
+ getRuntimeLibrary(compilerConfig, isDebug));
+ addAttribute(attributes, "UsePrecompiledHeader",
+ getUsePrecompiledHeader(compilerConfig));
+ addAttribute(attributes, "PrecompiledHeaderFile",
+ getPrecompiledHeaderFile(compilerConfig));
+ addAttribute(attributes, "WarningLevel",
+ getWarningLevel(compilerConfig));
+ addAttribute(attributes, "Detect64BitPortabilityProblems",
+ getDetect64BitPortabilityProblems(compilerConfig));
+ addAttribute(attributes, "DebugInformationFormat",
+ debugFormat);
+ content.startElement(null, "Tool", "Tool", attributes);
+ content.endElement(null, "Tool", "Tool");
+
+ }
+
+
+ /**
+ * Get value of LinkIncremental property.
+ * @param linkerConfig linker configuration.
+ * @return value of LinkIncremental property
+ */
+ private String getLinkIncremental(
+ final CommandLineLinkerConfiguration linkerConfig) {
+ String incremental = "0";
+ String[] args = linkerConfig.getPreArguments();
+ for (int i = 0; i < args.length; i++) {
+ if ("/INCREMENTAL:NO".equals(args[i])) {
+ incremental = "1";
+ }
+ if ("/INCREMENTAL:YES".equals(args[i])) {
+ incremental = "2";
+ }
+ }
+ return incremental;
+ }
+
+
+ /**
+ * Get value of Subsystem property.
+ * @param linkerConfig linker configuration.
+ * @return value of Subsystem property
+ */
+ private String getSubsystem(
+ final CommandLineLinkerConfiguration linkerConfig) {
+ String subsystem = "0";
+ String[] args = linkerConfig.getPreArguments();
+ for (int i = 0; i < args.length; i++) {
+ if ("/SUBSYSTEM:CONSOLE".equals(args[i])) {
+ subsystem = "1";
+ }
+ if ("/SUBSYSTEM:WINDOWS".equals(args[i])) {
+ subsystem = "2";
+ }
+ if ("/SUBSYSTEM:WINDOWSCE".equals(args[i])) {
+ subsystem = "9";
+ }
+ }
+ return subsystem;
+ }
+
+ /**
+ * Get value of TargetMachine property.
+ * @param linkerConfig linker configuration.
+ * @return value of TargetMachine property
+ */
+ private String getTargetMachine(
+ final CommandLineLinkerConfiguration linkerConfig) {
+ String subsystem = "0";
+ String[] args = linkerConfig.getPreArguments();
+ for (int i = 0; i < args.length; i++) {
+ if ("/MACHINE:X86".equals(args[i])) {
+ subsystem = "1";
+ }
+ }
+ return subsystem;
+ }
+
+ /**
+ * Get value of AdditionalDependencies property.
+ * @param linkTarget link target.
+ * @param projectDependencies dependencies declared in project.
+ * @param targets all targets.
+ * @param basePath path to directory containing project file.
+ * @return value of AdditionalDependencies property.
+ */
+ private String getAdditionalDependencies(final TargetInfo linkTarget,
+ final List projectDependencies,
+ final Map targets,
+ final String basePath) {
+ String dependencies = null;
+ File[] linkSources = linkTarget.getAllSources();
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < linkSources.length; i++) {
+ //
+ // if file was not compiled or otherwise generated
+ //
+ if (targets.get(linkSources[i].getName()) == null) {
+ //
+ // if source appears to be a system library or object file
+ // just output the name of the file (advapi.lib for example)
+ // otherwise construct a relative path.
+ //
+ String relPath = linkSources[i].getName();
+ //
+ // check if file comes from a project dependency
+ // if it does it should not be explicitly linked
+ boolean fromDependency = false;
+ if (relPath.indexOf(".") > 0) {
+ String baseName = relPath.substring(0, relPath.indexOf("."));
+ for(Iterator iter = projectDependencies.iterator(); iter.hasNext(); ) {
+ DependencyDef depend = (DependencyDef) iter.next();
+ if (baseName.compareToIgnoreCase(depend.getName()) == 0) {
+ fromDependency = true;
+ }
+ }
+ }
+
+ if (!fromDependency) {
+ if (!CUtil.isSystemPath(linkSources[i])) {
+ relPath = CUtil.getRelativePath(basePath, linkSources[i]);
+ }
+ //
+ // if path has an embedded space then
+ // must quote
+ if (relPath.indexOf(' ') > 0) {
+ buf.append('\"');
+ buf.append(CUtil.toWindowsPath(relPath));
+ buf.append('\"');
+ } else {
+ buf.append(relPath);
+ }
+ buf.append(' ');
+ }
+ }
+ }
+ if (buf.length() > 0) {
+ buf.setLength(buf.length() - 1);
+ dependencies = buf.toString();
+ }
+ return dependencies;
+
+ }
+
+ /**
+ * Write Tool element for linker.
+ * @param content serialization content handler.
+ * @param isDebug true if generating debug configuration.
+ * @param dependencies project dependencies.
+ * @param basePath path to directory containing project file.
+ * @param linkTarget link target.
+ * @param targets all targets.
+ * @throws SAXException thrown if error during serialization.
+ */
+ private void writeLinkerElement(final ContentHandler content,
+ final boolean isDebug,
+ final List dependencies,
+ final String basePath,
+ final TargetInfo linkTarget,
+ final Map targets) throws SAXException {
+ AttributesImpl attributes = new AttributesImpl();
+ addAttribute(attributes, "Name", "VCLinkerTool");
+
+ ProcessorConfiguration config = linkTarget.getConfiguration();
+ if (config instanceof CommandLineLinkerConfiguration) {
+ CommandLineLinkerConfiguration linkerConfig =
+ (CommandLineLinkerConfiguration) config;
+ if (linkerConfig.getLinker() instanceof DevStudioCompatibleLinker) {
+ addAttribute(attributes, "LinkIncremental",
+ getLinkIncremental(linkerConfig));
+ if (isDebug) {
+ addAttribute(attributes, "GenerateDebugInformation", trueLiteral);
+ } else {
+ addAttribute(attributes, "GenerateDebugInformation", falseLiteral);
+ }
+ addAttribute(attributes, "SubSystem",
+ getSubsystem(linkerConfig));
+ addAttribute(attributes, "TargetMachine",
+ getTargetMachine(linkerConfig));
+ }
+ }
+ addAttribute(attributes, "AdditionalDependencies",
+ getAdditionalDependencies(linkTarget, dependencies, targets, basePath));
+ content.startElement(null, "Tool", "Tool", attributes);
+ content.endElement(null, "Tool", "Tool");
+ }
+
+ /**
+ * Writes a project definition file.
+ *
+ * @param fileName project name for file, should has .cbx extension
+ * @param task cc task for which to write project
+ * @param projectDef project element
+ * @param sources source files
+ * @param targets compilation targets
+ * @param linkTarget link target
+ * @throws IOException if I/O error
+ * @throws SAXException if XML serialization error
+ */
+ public void writeProject(final File fileName,
+ final CCTask task,
+ final ProjectDef projectDef,
+ final List sources,
+ final Hashtable targets,
+ final TargetInfo linkTarget) throws
+ IOException,
+ SAXException {
+
+ String projectName = projectDef.getName();
+ if (projectName == null) {
+ projectName = fileName.getName();
+ }
+
+
+ File vcprojFile = new File(fileName + ".vcproj");
+ if (!projectDef.getOverwrite() && vcprojFile.exists()) {
+ throw new BuildException("Not allowed to overwrite project file "
+ + vcprojFile.toString());
+ }
+ File slnFile = new File(fileName + ".sln");
+ if (!projectDef.getOverwrite() && slnFile.exists()) {
+ throw new BuildException("Not allowed to overwrite project file "
+ + slnFile.toString());
+ }
+
+ CommandLineCompilerConfiguration compilerConfig =
+ getBaseCompilerConfiguration(targets);
+ if (compilerConfig == null) {
+ throw new BuildException(
+ "Unable to generate Visual Studio.NET project "
+ + "when Microsoft C++ is not used.");
+ }
+
+ OutputStream outStream = new FileOutputStream(fileName + ".vcproj");
+ OutputFormat format = new OutputFormat("xml", "UTF-8", true);
+ XMLSerializer serializer = new XMLSerializer(outStream, format);
+ ContentHandler content = serializer.asContentHandler();
+ String basePath = fileName.getParentFile().getAbsolutePath();
+ content.startDocument();
+
+ for(Iterator iter = projectDef.getComments().iterator(); iter.hasNext(); ) {
+ String comment = ((CommentDef) iter.next()).getText();
+ serializer.comment(comment);
+ }
+
+ AttributesImpl emptyAttrs = new AttributesImpl();
+
+ AttributesImpl attributes = new AttributesImpl();
+ addAttribute(attributes, "ProjectType", "Visual C++");
+ addAttribute(attributes, "Version", version);
+ addAttribute(attributes, "Name", projectName);
+ content.startElement(null, "VisualStudioProject",
+ "VisualStudioProject", attributes);
+
+ content.startElement(null, "Platforms", "Platforms", emptyAttrs);
+ attributes.clear();
+ addAttribute(attributes, "Name", "Win32");
+ content.startElement(null, "Platform", "Platform", attributes);
+ content.endElement(null, "Platform", "Platform");
+ content.endElement(null, "Platforms", "Platforms");
+ content.startElement(null, "Configurations",
+ "Configurations", emptyAttrs);
+
+ //
+ // write debug configuration
+ //
+ writeConfigurationStartTag(content, true, task, compilerConfig);
+ writeCompilerElement(content, true, basePath, compilerConfig);
+ writeLinkerElement(content, true, projectDef.getDependencies(), basePath, linkTarget, targets);
+ content.endElement(null, "Configuration", "Configuration");
+
+ //
+ // write release configuration
+ //
+ writeConfigurationStartTag(content, false, task, compilerConfig);
+ writeCompilerElement(content, false, basePath, compilerConfig);
+ writeLinkerElement(content, false, projectDef.getDependencies(), basePath, linkTarget, targets);
+ content.endElement(null, "Configuration", "Configuration");
+
+ content.endElement(null, "Configurations", "Configurations");
+ content.startElement(null, "References", "References", emptyAttrs);
+ content.endElement(null, "References", "References");
+ content.startElement(null, "Files", "Files", emptyAttrs);
+
+
+ File[] sortedSources = new File[sources.size()];
+ sources.toArray(sortedSources);
+ Arrays.sort(sortedSources, new Comparator() {
+ public int compare(final Object o1, final Object o2) {
+ return ((File) o1).getName().compareTo(((File) o2).getName());
+ }
+ });
+
+ writeFilteredSources("Source Files",
+ "cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx",
+ basePath, sortedSources, content);
+
+ writeFilteredSources("Header Files", "h;hpp;hxx;hm;inl;inc;xsd",
+ basePath, sortedSources, content);
+
+ writeFilteredSources("Resource Files",
+ "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx",
+ basePath, sortedSources, content);
+
+ content.endElement(null, "Files", "Files");
+ content.startElement(null, "Globals", "Globals", emptyAttrs);
+ content.endElement(null, "Globals", "Globals");
+ content.endElement(null, "VisualStudioProject", "VisualStudioProject");
+ content.endDocument();
+ }
+
+ /**
+ * Writes a cluster of source files to the project.
+ *
+ * @param name name of filter
+ * @param filter file extensions
+ * @param basePath base path for files
+ * @param sortedSources array of source files
+ * @param content generated project
+ * @throws SAXException if invalid content
+ */
+ private void writeFilteredSources(final String name, final String filter,
+ final String basePath,
+ final File[] sortedSources,
+ final ContentHandler content)
+ throws SAXException {
+ AttributesImpl filterAttrs = new AttributesImpl();
+ filterAttrs.addAttribute(null, "Name", "Name", "#PCDATA", name);
+ filterAttrs.addAttribute(null, "Filter", "Filter", "#PCDATA", filter);
+ content.startElement(null, "Filter", "Filter", filterAttrs);
+
+
+ AttributesImpl fileAttrs = new AttributesImpl();
+ fileAttrs.addAttribute(null, "RelativePath", "RelativePath",
+ "#PCDATA", "");
+
+
+ for (int i = 0; i < sortedSources.length; i++) {
+ if (isGroupMember(filter, sortedSources[i])) {
+ String relativePath = CUtil.getRelativePath(basePath,
+ sortedSources[i]);
+ fileAttrs.setValue(0, relativePath);
+ content.startElement(null, "File", "File", fileAttrs);
+ content.endElement(null, "File", "File");
+ }
+ }
+ content.endElement(null, "Filter", "Filter");
+
+ }
+
+ /**
+ * Returns true if the file has an extension that
+ * appears in the group filter.
+ *
+ * @param filter String group filter
+ * @param candidate File file
+ * @return boolean true if member of group
+ */
+ private boolean isGroupMember(final String filter, final File candidate) {
+ String fileName = candidate.getName();
+ int lastDot = fileName.lastIndexOf('.');
+ if (lastDot >= 0 && lastDot < fileName.length() - 1) {
+ String extension =
+ ";" + fileName.substring(lastDot + 1).toLowerCase() + ";";
+ String semiFilter = ";" + filter + ";";
+ return semiFilter.indexOf(extension) >= 0;
+ }
+ return false;
+ }
+
+
+ /**
+ * Adds an non-namespace-qualified attribute to attribute list.
+ * @param attributes list of attributes.
+ * @param attrName attribute name, may not be null.
+ * @param attrValue attribute value, if null attribute is not added.
+ */
+ private static void addAttribute(final AttributesImpl attributes,
+ final String attrName,
+ final String attrValue) {
+ if (attrName == null) {
+ throw new IllegalArgumentException("attrName");
+ }
+ if (attrValue != null) {
+ attributes.addAttribute(null, attrName, attrName,
+ "#PCDATA", attrValue);
+ }
+ }
+
+ /**
+ * Gets the first recognized compiler from the
+ * compilation targets.
+ * @param targets compilation targets
+ * @return representative (hopefully) compiler configuration
+ */
+ private CommandLineCompilerConfiguration
+ getBaseCompilerConfiguration(final Hashtable targets) {
+ //
+ // get the first target and assume that it is representative
+ //
+ Iterator targetIter = targets.values().iterator();
+ while (targetIter.hasNext()) {
+ TargetInfo targetInfo = (TargetInfo) targetIter.next();
+ ProcessorConfiguration config = targetInfo.getConfiguration();
+ //
+ // for the first cl compiler
+ //
+ if (config instanceof CommandLineCompilerConfiguration) {
+ CommandLineCompilerConfiguration compilerConfig =
+ (CommandLineCompilerConfiguration) config;
+ if (compilerConfig.getCompiler()
+ instanceof DevStudioCCompiler) {
+ return compilerConfig;
+ }
+ }
+ }
+ return null;
+ }
+}
+
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/package.html b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/package.html
new file mode 100644
index 0000000..46a31b4
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/package.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+Copyright 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.
+
+-->
+</head>
+<body bgcolor="white">
+
+Adapters for Microsoft tools.
+</body>
+</html>
+
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/AbstractArLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/AbstractArLibrarian.java
new file mode 100644
index 0000000..2e8d4af
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/AbstractArLibrarian.java
@@ -0,0 +1,107 @@
+/*
+ *
+ * Copyright 2001-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.gcc;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+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.VersionInfo;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+
+import org.apache.tools.ant.BuildException;
+/**
+ * Adapter for the "ar" tool
+ *
+ * @author Adam Murdoch
+ * @author Curt Arnold
+ */
+public abstract class AbstractArLibrarian extends CommandLineLinker {
+ private/* final */
+ String outputPrefix;
+ protected AbstractArLibrarian(String command, String identificationArg,
+ String[] inputExtensions, String[] ignoredExtensions,
+ String outputPrefix, String outputExtension, boolean isLibtool,
+ AbstractArLibrarian libtoolLibrarian) {
+ super(command, identificationArg, inputExtensions, ignoredExtensions,
+ outputExtension, isLibtool, libtoolLibrarian);
+ this.outputPrefix = outputPrefix;
+ }
+ public void addBase(long base, Vector args) {
+ }
+ public void addFixed(Boolean fixed, Vector args) {
+ }
+ public void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ }
+ public void addIncremental(boolean incremental, Vector args) {
+ }
+ public void addMap(boolean map, Vector args) {
+ }
+ public void addStack(int stack, Vector args) {
+ }
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)
+ */
+ protected void addEntry(String entry, Vector args) {
+ }
+
+ public String getCommandFileSwitch(String commandFile) {
+ return null;
+ }
+ public File[] getLibraryPath() {
+ return new File[0];
+ }
+ public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {
+ return new String[0];
+ }
+ 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;
+ }
+ public String[] getOutputFileSwitch(String outputFile) {
+ return GccProcessor.getOutputFileSwitch("rvs", outputFile);
+ }
+ public boolean isCaseSensitive() {
+ return true;
+ }
+ public void link(CCTask task, File outputFile, String[] sourceFiles,
+ CommandLineLinkerConfiguration config) throws BuildException {
+ //
+ // if there is an existing library then
+ // we must delete it before executing "ar"
+ if (outputFile.exists()) {
+ if (!outputFile.delete()) {
+ throw new BuildException("Unable to delete "
+ + outputFile.getAbsolutePath());
+ }
+ }
+ //
+ // delegate to CommandLineLinker
+ //
+ super.link(task, outputFile, sourceFiles, config);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java
new file mode 100644
index 0000000..75ddcc7
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java
@@ -0,0 +1,339 @@
+/*
+ *
+ * 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.gcc;
+import java.io.File;
+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.VersionInfo;
+import net.sf.antcontrib.cpptasks.types.LibrarySet;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+
+/**
+ * Abstract adapter for ld-like linkers
+ *
+ * @author Curt Arnold
+ */
+public abstract class AbstractLdLinker extends CommandLineLinker {
+ private String outputPrefix;
+ protected AbstractLdLinker(String command, String identifierArg,
+ String[] extensions, String[] ignoredExtensions,
+ String outputPrefix, String outputSuffix, boolean isLibtool,
+ AbstractLdLinker libtoolLinker) {
+ super(command, identifierArg, extensions, ignoredExtensions,
+ outputSuffix, isLibtool, libtoolLinker);
+ this.outputPrefix = outputPrefix;
+ }
+ public void addBase(long base, Vector args) {
+ if (base >= 0) {
+ args.addElement("--image-base");
+ args.addElement(Long.toHexString(base));
+ }
+ }
+ public void addFixed(Boolean fixed, Vector args) {
+ }
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ if (debug) {
+ args.addElement("-g");
+ }
+ if (isDarwin()) {
+ if (linkType.isPluginModule()) {
+ args.addElement("-bundle");
+ } else {
+ if (linkType.isSharedLibrary()) {
+ args.addElement("-prebind");
+ args.addElement("-dynamiclib");
+ }
+ }
+ } else {
+ if (linkType.isStaticRuntime()) {
+ args.addElement("-static");
+ }
+ if (linkType.isPluginModule()) {
+ args.addElement("-shared");
+ } else {
+ if (linkType.isSharedLibrary()) {
+ args.addElement("-shared");
+ }
+ }
+ }
+ }
+ public void addIncremental(boolean incremental, Vector args) {
+ if (incremental) {
+ args.addElement("-i");
+ }
+ }
+ protected 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 String[] addLibrarySets(CCTask task, LibrarySet[] libsets,
+ Vector preargs, Vector midargs, Vector endargs) {
+ Vector libnames = new Vector();
+ super.addLibrarySets(task, libsets, preargs, midargs, endargs);
+ LibraryTypeEnum previousLibraryType = null;
+ for (int i = 0; i < libsets.length; i++) {
+ LibrarySet set = libsets[i];
+ File libdir = set.getDir(null);
+ String[] libs = set.getLibs();
+ if (libdir != null) {
+ String relPath = libdir.getAbsolutePath();
+ File outputFile = task.getOutfile();
+ if (outputFile != null && outputFile.getParentFile() != null) {
+ relPath = CUtil.getRelativePath(
+ outputFile.getParentFile().getAbsolutePath(), libdir);
+ }
+ if (set.getType() != null &&
+ "framework".equals(set.getType().getValue()) &&
+ isDarwin()) {
+ endargs.addElement("-F" + relPath);
+ } else {
+ endargs.addElement("-L" + relPath);
+ }
+ }
+ //
+ // if there has been a change of library type
+ //
+ if (set.getType() != previousLibraryType) {
+ if (set.getType() != null && "static".equals(set.getType().getValue())) {
+ endargs.addElement(getStaticLibFlag());
+ previousLibraryType = set.getType();
+ } else {
+ if (set.getType() == null ||
+ !"framework".equals(set.getType().getValue()) ||
+ !isDarwin()) {
+ endargs.addElement(getDynamicLibFlag());
+ previousLibraryType = set.getType();
+ }
+ }
+ }
+ StringBuffer buf = new StringBuffer("-l");
+ if (set.getType() != null &&
+ "framework".equals(set.getType().getValue()) &&
+ isDarwin()) {
+ buf.setLength(0);
+ buf.append("-framework ");
+ }
+ int initialLength = buf.length();
+ for (int j = 0; j < libs.length; j++) {
+ //
+ // reset the buffer to just "-l"
+ //
+ buf.setLength(initialLength);
+ //
+ // add the library name
+ buf.append(libs[j]);
+ libnames.addElement(libs[j]);
+ //
+ // add the argument to the list
+ endargs.addElement(buf.toString());
+ }
+ }
+ String rc[] = new String[libnames.size()];
+ for (int i = 0; i < libnames.size(); i++) {
+ rc[i] = (String) libnames.elementAt(i);
+ }
+ return rc;
+ }
+ public void addMap(boolean map, Vector args) {
+ if (map) {
+ args.addElement("-M");
+ }
+ }
+ public void addStack(int stack, Vector args) {
+ if (stack > 0) {
+ args.addElement("--stack");
+ args.addElement(Integer.toString(stack));
+ }
+ }
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)
+ */
+ protected void addEntry(String entry, Vector args) {
+ if (entry != null) {
+ args.addElement("-e");
+ args.addElement(entry);
+ }
+ }
+
+ public String getCommandFileSwitch(String commandFile) {
+ throw new IllegalStateException("ld does not support command files");
+ }
+ /**
+ * Returns library path.
+ *
+ */
+ protected File[] getEnvironmentIncludePath() {
+ return CUtil.getPathFromEnvironment("LIB", ":");
+ }
+ public String getLibraryKey(File libfile) {
+ String libname = libfile.getName();
+ int lastDot = libname.lastIndexOf('.');
+ if (lastDot >= 0) {
+ return libname.substring(0, lastDot);
+ }
+ return libname;
+ }
+ /**
+ * Returns library path.
+ *
+ */
+ public File[] getLibraryPath() {
+ return new File[0];
+ }
+ public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {
+ StringBuffer buf = new StringBuffer();
+ int patternCount = libnames.length;
+ if (libType == null) {
+ patternCount *= 2;
+ }
+ String[] patterns = new String[patternCount];
+ int offset = 0;
+ if (libType == null || "static".equals(libType.getValue())) {
+ offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0);
+ }
+ if (libType != null && "framework".equals(libType.getValue()) && isDarwin()) {
+ for(int i = 0; i < libnames.length; i++) {
+ buf.setLength(0);
+ buf.append(libnames[i]);
+ buf.append(".framework/");
+ buf.append(libnames[i]);
+ patterns[offset++] = buf.toString();
+ }
+ } else {
+ if (libType == null || !"static".equals(libType.getValue())) {
+ if (isHPUX()) {
+ offset = addLibraryPatterns(libnames, buf, "lib", ".sl", patterns,
+ offset);
+ } else {
+ offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns,
+ offset);
+ }
+ }
+ }
+ return patterns;
+ }
+ 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;
+ }
+ public String[] getOutputFileSwitch(String outputFile) {
+ return GccProcessor.getOutputFileSwitch("-o", outputFile);
+ }
+
+ public boolean isCaseSensitive() {
+ return true;
+ }
+ protected boolean isHPUX() {
+ String osname = System.getProperty("os.name").toLowerCase();
+ if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) {
+ return true;
+ }
+ return false;
+ }
+ /**
+ * Prepares argument list for exec command. Will return null if command
+ * line would exceed allowable command line buffer.
+ *
+ * @param outputFile
+ * linker output file
+ * @param sourceFiles
+ * linker input files (.obj, .o, .res)
+ * @param config
+ * linker configuration
+ * @return arguments for runTask
+ */
+ public String[] prepareArguments(CCTask task, String outputDir,
+ String outputFile, String[] sourceFiles,
+ CommandLineLinkerConfiguration config) {
+ //
+ // need to suppress sources that correspond to
+ // library set entries since they are already
+ // in the argument list
+ String[] libnames = config.getLibraryNames();
+ if (libnames == null || libnames.length == 0) {
+ return super.prepareArguments(task, outputDir, outputFile,
+ sourceFiles, config);
+ }
+ //
+ //
+ // null out any sources that correspond to library names
+ //
+ String[] localSources = (String[]) sourceFiles.clone();
+ int extra = 0;
+ for (int i = 0; i < libnames.length; i++) {
+ String libname = libnames[i];
+ for (int j = 0; j < localSources.length; j++) {
+ if (localSources[j] != null
+ && localSources[j].indexOf(libname) > 0
+ && localSources[j].indexOf("lib") > 0) {
+ String filename = new File(localSources[j]).getName();
+ if (filename.startsWith("lib")
+ && filename.substring(3).startsWith(libname)) {
+ String extension = filename
+ .substring(libname.length() + 3);
+ if (extension.equals(".a") || extension.equals(".so")
+ || extension.equals(".sl")) {
+ localSources[j] = null;
+ extra++;
+ }
+ }
+ }
+ }
+ }
+ if (extra == 0) {
+ return super.prepareArguments(task, outputDir, outputFile,
+ sourceFiles, config);
+ }
+ String[] finalSources = new String[localSources.length - extra];
+ int index = 0;
+ for (int i = 0; i < localSources.length; i++) {
+ if (localSources[i] != null) {
+ finalSources[index++] = localSources[i];
+ }
+ }
+ return super.prepareArguments(task, outputDir, outputFile,
+ finalSources, config);
+ }
+
+ protected String getDynamicLibFlag() {
+ return "-Bdynamic";
+ }
+
+ protected String getStaticLibFlag() {
+ return "-Bstatic";
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccCCompiler.java
new file mode 100644
index 0000000..999ccf7
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccCCompiler.java
@@ -0,0 +1,242 @@
+/*
+ *
+ * Copyright 2001-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.gcc;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.parser.CParser;
+import net.sf.antcontrib.cpptasks.parser.FortranParser;
+import net.sf.antcontrib.cpptasks.parser.Parser;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Environment;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+/**
+ * Adapter for the GCC C/C++ compiler
+ *
+ * @author Adam Murdoch
+ */
+public final class GccCCompiler extends GccCompatibleCCompiler {
+ private final static String[] sourceExtensions = new String[]{".c", /* C */
+ ".cc", /* C++ */
+ ".cpp", /* C++ */
+ ".cxx", /* C++ */
+ ".c++", /* C++ */
+ ".i", /* preprocessed C */
+ ".ii", /* preprocessed C++ */
+ ".f", /* FORTRAN */
+ ".for", /* FORTRAN */
+ ".m", /* Objective-C */
+ ".mm", /* Objected-C++ */
+ ".s" /* Assembly */
+ };
+ private final static String[] headerExtensions = new String[]{".h", ".hpp",
+ ".inl"};
+ private static final GccCCompiler cppInstance = new GccCCompiler("c++",
+ sourceExtensions, headerExtensions, false,
+ new GccCCompiler("c++", sourceExtensions, headerExtensions, true,
+ null, false, null), false, null);
+ private static final GccCCompiler g77Instance = new GccCCompiler("g77",
+ sourceExtensions, headerExtensions, false,
+ new GccCCompiler("g77", sourceExtensions, headerExtensions, true,
+ null, false, null), false, null);
+ private static final GccCCompiler gppInstance = new GccCCompiler("g++",
+ sourceExtensions, headerExtensions, false,
+ new GccCCompiler("g++", sourceExtensions, headerExtensions, true,
+ null, false, null), false, null);
+ private static final GccCCompiler instance = new GccCCompiler("gcc",
+ sourceExtensions, headerExtensions, false,
+ new GccCCompiler("gcc", sourceExtensions, headerExtensions, true,
+ null, false, null), false, null);
+ /**
+ * Gets c++ adapter
+ */
+ public static GccCCompiler getCppInstance() {
+ return cppInstance;
+ }
+ /**
+ * Gets g77 adapter
+ */
+ public static GccCCompiler getG77Instance() {
+ return g77Instance;
+ }
+ /**
+ * Gets gpp adapter
+ */
+ public static GccCCompiler getGppInstance() {
+ return gppInstance;
+ }
+ /**
+ * Gets gcc adapter
+ */
+ public static GccCCompiler getInstance() {
+ return instance;
+ }
+ private String identifier;
+ private File[] includePath;
+ private boolean isPICMeaningful = true;
+ /**
+ * Private constructor. Use GccCCompiler.getInstance() to get singleton
+ * instance of this class.
+ */
+ private GccCCompiler(String command, String[] sourceExtensions,
+ String[] headerExtensions, boolean isLibtool,
+ GccCCompiler libtoolCompiler, boolean newEnvironment,
+ Environment env) {
+ super(command, null, sourceExtensions, headerExtensions, isLibtool,
+ libtoolCompiler, newEnvironment, env);
+ isPICMeaningful = System.getProperty("os.name").indexOf("Windows") < 0;
+ }
+ public void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ super.addImpliedArgs(args, debug, multithreaded,
+ exceptions, linkType, rtti, optimization);
+ if (isPICMeaningful && linkType.isSharedLibrary()) {
+ args.addElement("-fPIC");
+ }
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new GccCCompiler(getCommand(), this.getSourceExtensions(),
+ this.getHeaderExtensions(), this.getLibtool(),
+ (GccCCompiler) this.getLibtoolCompiler(), newEnvironment,
+ env);
+ }
+ return this;
+ }
+ /**
+ * Create parser to determine dependencies.
+ *
+ * Will create appropriate parser (C++, FORTRAN) based on file extension.
+ *
+ */
+ protected Parser createParser(File source) {
+ if (source != null) {
+ String sourceName = source.getName();
+ int lastDot = sourceName.lastIndexOf('.');
+ if (lastDot >= 0 && lastDot + 1 < sourceName.length()) {
+ char afterDot = sourceName.charAt(lastDot + 1);
+ if (afterDot == 'f' || afterDot == 'F') {
+ return new FortranParser();
+ }
+ }
+ }
+ return new CParser();
+ }
+ public File[] getEnvironmentIncludePath() {
+ if (includePath == null) {
+ //
+ // construct default include path from machine id and version id
+ //
+ String[] defaultInclude = new String[1];
+ StringBuffer buf = new StringBuffer("/lib/");
+ buf.append(GccProcessor.getMachine());
+ buf.append('/');
+ buf.append(GccProcessor.getVersion());
+ buf.append("/include");
+ defaultInclude[0] = buf.toString();
+ //
+ // read specs file and look for -istart and -idirafter
+ //
+ String[] specs = GccProcessor.getSpecs();
+ String[][] optionValues = GccProcessor.parseSpecs(specs, "*cpp:",
+ new String[]{"-isystem ", "-idirafter "});
+ //
+ // if no entries were found, then use a default path
+ //
+ if (optionValues[0].length == 0 && optionValues[1].length == 0) {
+ optionValues[0] = new String[]{"/usr/local/include",
+ "/usr/include", "/usr/include/win32api"};
+ }
+ //
+ // remove mingw entries.
+ // For MinGW compiles this will mean the
+ // location of the sys includes will be
+ // wrong in dependencies.xml
+ // but that should have no significant effect
+ for (int i = 0; i < optionValues.length; i++) {
+ for (int j = 0; j < optionValues[i].length; j++) {
+ if (optionValues[i][j].indexOf("mingw") > 0) {
+ optionValues[i][j] = null;
+ }
+ }
+ }
+ //
+ // if cygwin then
+ // we have to prepend location of gcc32
+ // and .. to start of absolute filenames to
+ // have something that will exist in the
+ // windows filesystem
+ if (GccProcessor.isCygwin()) {
+ GccProcessor.convertCygwinFilenames(optionValues[0]);
+ GccProcessor.convertCygwinFilenames(optionValues[1]);
+ GccProcessor.convertCygwinFilenames(defaultInclude);
+ }
+ int count = CUtil.checkDirectoryArray(optionValues[0]);
+ count += CUtil.checkDirectoryArray(optionValues[1]);
+ count += CUtil.checkDirectoryArray(defaultInclude);
+ includePath = new File[count];
+ int index = 0;
+ for (int i = 0; i < optionValues.length; i++) {
+ for (int j = 0; j < optionValues[i].length; j++) {
+ if (optionValues[i][j] != null) {
+ includePath[index++] = new File(optionValues[i][j]);
+ }
+ }
+ }
+ for (int i = 0; i < defaultInclude.length; i++) {
+ if (defaultInclude[i] != null) {
+ includePath[index++] = new File(defaultInclude[i]);
+ }
+ }
+ }
+ return (File[]) includePath.clone();
+ }
+ public String getIdentifier() throws BuildException {
+ if (identifier == null) {
+ StringBuffer buf;
+ if (getLibtool()) {
+ buf = new StringBuffer("libtool ");
+ } else {
+ buf = new StringBuffer(' ');
+ }
+ buf.append(getCommand());
+ buf.append(' ');
+ buf.append(GccProcessor.getVersion());
+ buf.append(' ');
+ buf.append(GccProcessor.getMachine());
+ identifier = buf.toString();
+ }
+ return identifier;
+ }
+ public Linker getLinker(LinkType linkType) {
+ return GccLinker.getInstance().getLinker(linkType);
+ }
+ public int getMaximumCommandLength() {
+ return Integer.MAX_VALUE;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccCompatibleCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccCompatibleCCompiler.java
new file mode 100644
index 0000000..0485fba
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccCompatibleCCompiler.java
@@ -0,0 +1,146 @@
+/*
+ *
+ * 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.gcc;
+import java.io.File;
+import java.util.Vector;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import org.apache.tools.ant.types.Environment;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+/**
+ * Abstract base class for compilers that attempt to be command line compatible
+ * with GCC
+ *
+ * @author Adam Murdoch
+ * @author Curt Arnold
+ */
+public abstract class GccCompatibleCCompiler extends CommandLineCCompiler {
+ private final static String[] headerExtensions = new String[]{".h", ".hpp",
+ ".inl"};
+ private final static String[] sourceExtensions = new String[]{".c", ".cc",
+ ".cpp", ".cxx", ".c++", ".i", ".f", ".for"};
+ /**
+ * Private constructor. Use GccCCompiler.getInstance() to get singleton
+ * instance of this class.
+ */
+ protected GccCompatibleCCompiler(String command, String identifierArg,
+ boolean libtool, GccCompatibleCCompiler libtoolCompiler,
+ boolean newEnvironment, Environment env) {
+ super(command, identifierArg, sourceExtensions, headerExtensions,
+ libtool ? ".fo" : ".o", libtool, libtoolCompiler,
+ newEnvironment, env);
+ }
+ /**
+ * Private constructor. Use GccCCompiler.getInstance() to get singleton
+ * instance of this class.
+ */
+ protected GccCompatibleCCompiler(String command, String identifierArg,
+ String[] sourceExtensions, String[] headerExtensions,
+ boolean libtool, GccCompatibleCCompiler libtoolCompiler,
+ boolean newEnvironment, Environment env) {
+ super(command, identifierArg, sourceExtensions, headerExtensions,
+ libtool ? ".fo" : ".o", libtool, libtoolCompiler,
+ newEnvironment, env);
+ }
+ public void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ //
+ // -fPIC is too much trouble
+ // users have to manually add it for
+ // operating systems that make sense
+ //
+ args.addElement("-c");
+ if (debug) {
+ args.addElement("-g");
+ } else {
+ if (optimization != null) {
+ if (optimization.isSize()) {
+ args.addElement("-Os");
+ } else if (optimization.isSpeed()) {
+ if ("full".equals(optimization.getValue())) {
+ args.addElement("-O2");
+ } else {
+ if ("speed".equals(optimization.getValue())) {
+ args.addElement("-O1");
+ } else {
+ args.addElement("-O3");
+ }
+ }
+ }
+ }
+ }
+ if (getIdentifier().indexOf("mingw") >= 0) {
+ if (linkType.isSubsystemConsole()) {
+ args.addElement("-mconsole");
+ }
+ if (linkType.isSubsystemGUI()) {
+ args.addElement("-mwindows");
+ }
+ }
+ if (rtti != null && !rtti.booleanValue()) {
+ args.addElement("-fno-rtti");
+ }
+
+ }
+ /**
+ * Adds an include path to the command.
+ */
+ public void addIncludePath(String path, Vector cmd) {
+ cmd.addElement("-I" + path);
+ }
+ public void addWarningSwitch(Vector args, int level) {
+ switch (level) {
+ case 0 :
+ args.addElement("-w");
+ break;
+ case 5 :
+ args.addElement("-Werror");
+ /* nobreak */
+ case 4 :
+ args.addElement("-W");
+ /* nobreak */
+ case 3 :
+ args.addElement("-Wall");
+ break;
+ }
+ }
+ public void getDefineSwitch(StringBuffer buffer, String define, String value) {
+ buffer.append("-D");
+ buffer.append(define);
+ if (value != null && value.length() > 0) {
+ buffer.append('=');
+ buffer.append(value);
+ }
+ }
+ protected File[] getEnvironmentIncludePath() {
+ return CUtil.getPathFromEnvironment("INCLUDE", ":");
+ }
+ public String getIncludeDirSwitch(String includeDir) {
+ return "-I" + includeDir;
+ }
+ public void getUndefineSwitch(StringBuffer buffer, String define) {
+ buffer.append("-U");
+ buffer.append(define);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccLibrarian.java
new file mode 100644
index 0000000..0c6ae4b
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccLibrarian.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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.gcc;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+/**
+ * Adapter for the 'ar' archiver
+ *
+ * @author Adam Murdoch
+ */
+public final class GccLibrarian extends AbstractArLibrarian {
+ private static String[] objFileExtensions = new String[]{".o"};
+ private static GccLibrarian instance = new GccLibrarian("ar",
+ objFileExtensions, false, new GccLibrarian("ar", objFileExtensions,
+ true, null));
+ public static GccLibrarian getInstance() {
+ return instance;
+ }
+ private GccLibrarian(String command, String[] inputExtensions,
+ boolean isLibtool, GccLibrarian libtoolLibrarian) {
+ super(command, "V", inputExtensions, new String[0], "lib", ".a",
+ isLibtool, libtoolLibrarian);
+ }
+ public Linker getLinker(LinkType type) {
+ return GccLinker.getInstance().getLinker(type);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccLinker.java
new file mode 100644
index 0000000..c4720c8
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccLinker.java
@@ -0,0 +1,210 @@
+/*
+ *
+ * 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.gcc;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+/**
+ * Adapter for the GCC linker
+ *
+ * @author Adam Murdoch
+ */
+public class GccLinker extends AbstractLdLinker {
+ private static final String[] discardFiles = new String[0];
+ private static final String[] objFiles = new String[]{".o", ".a", ".lib",
+ ".dll", ".so", ".sl"};
+ private static final String[] libtoolObjFiles = new String[]{".fo", ".a",
+ ".lib", ".dll", ".so", ".sl"};
+ private static String[] linkerOptions = new String[]{"-bundle",
+ "-dynamiclib", "-nostartfiles", "-nostdlib", "-prebind", "-s",
+ "-static", "-shared", "-symbolic", "-Xlinker",
+ "--export-all-symbols", "-static-libgcc",};
+ private static final GccLinker dllLinker = new GccLinker("gcc", objFiles,
+ discardFiles, "lib", ".so", false, new GccLinker("gcc", objFiles,
+ discardFiles, "lib", ".so", true, null));
+ private static final GccLinker instance = new GccLinker("gcc", objFiles,
+ discardFiles, "", "", false, null);
+ private static final GccLinker machBundleLinker = new GccLinker("gcc",
+ objFiles, discardFiles, "lib", ".bundle", false, null);
+ private static final GccLinker machDllLinker = new GccLinker("gcc",
+ objFiles, discardFiles, "lib", ".dylib", false, null);
+ public static GccLinker getInstance() {
+ return instance;
+ }
+ private File[] libDirs;
+ protected GccLinker(String command, String[] extensions,
+ String[] ignoredExtensions, String outputPrefix,
+ String outputSuffix, boolean isLibtool, GccLinker libtoolLinker) {
+ super(command, "-dumpversion", extensions, ignoredExtensions,
+ outputPrefix, outputSuffix, isLibtool, libtoolLinker);
+ }
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ super.addImpliedArgs(debug, linkType, args);
+ if (getIdentifier().indexOf("mingw") >= 0) {
+ if (linkType.isSubsystemConsole()) {
+ args.addElement("-mconsole");
+ }
+ if (linkType.isSubsystemGUI()) {
+ args.addElement("-mwindows");
+ }
+ }
+ }
+ /**
+ * Allows drived linker to decorate linker option. Override by GccLinker to
+ * prepend a "-Wl," to pass option to through gcc to linker.
+ *
+ * @param buf
+ * buffer that may be used and abused in the decoration process,
+ * must not be null.
+ * @param arg
+ * linker argument
+ */
+ public String decorateLinkerOption(StringBuffer buf, String arg) {
+ String decoratedArg = arg;
+ if (arg.length() > 1 && arg.charAt(0) == '-') {
+ switch (arg.charAt(1)) {
+ //
+ // passed automatically by GCC
+ //
+ case 'g' :
+ case 'f' :
+ case 'F' :
+ /* Darwin */
+ case 'm' :
+ case 'O' :
+ case 'W' :
+ case 'l' :
+ case 'L' :
+ case 'u' :
+ case 'v' :
+ break;
+ default :
+ boolean known = false;
+ for (int i = 0; i < linkerOptions.length; i++) {
+ if (linkerOptions[i].equals(arg)) {
+ known = true;
+ break;
+ }
+ }
+ if (!known) {
+ buf.setLength(0);
+ buf.append("-Wl,");
+ buf.append(arg);
+ decoratedArg = buf.toString();
+ }
+ break;
+ }
+ }
+ return decoratedArg;
+ }
+ /**
+ * Returns library path.
+ *
+ */
+ public File[] getLibraryPath() {
+ if (libDirs == null) {
+ //
+ // construct gcc lib path from machine and version
+ //
+ StringBuffer buf = new StringBuffer("/lib/gcc-lib/");
+ buf.append(GccProcessor.getMachine());
+ buf.append('/');
+ buf.append(GccProcessor.getVersion());
+ //
+ // build default path from gcc and system /lib and /lib/w32api
+ //
+ String[] impliedLibPath = new String[]{buf.toString(),
+ "/lib/w32api", "/lib"};
+ //
+ // read gcc specs file for other library paths
+ //
+ String[] specs = GccProcessor.getSpecs();
+ String[][] libpaths = GccProcessor.parseSpecs(specs, "*link:",
+ new String[]{"%q"});
+ String[] libpath;
+ if (libpaths[0].length > 0) {
+ libpath = new String[libpaths[0].length + 3];
+ int i = 0;
+ for (; i < libpaths[0].length; i++) {
+ libpath[i] = libpaths[0][i];
+ }
+ libpath[i++] = buf.toString();
+ libpath[i++] = "/lib/w32api";
+ libpath[i++] = "/lib";
+ } else {
+ //
+ // if a failure to find any matches then
+ // use some default values for lib path entries
+ libpath = new String[]{"/usr/local/lib/mingw",
+ "/usr/local/lib", "/usr/lib/w32api", "/usr/lib/mingw",
+ "/usr/lib", buf.toString(), "/lib/w32api", "/lib"};
+ }
+ for (int i = 0; i < libpath.length; i++) {
+ if (libpath[i].indexOf("mingw") >= 0) {
+ libpath[i] = null;
+ }
+ }
+ //
+ // if cygwin then
+ // we have to prepend location of gcc32
+ // and .. to start of absolute filenames to
+ // have something that will exist in the
+ // windows filesystem
+ if (GccProcessor.isCygwin()) {
+ GccProcessor.convertCygwinFilenames(libpath);
+ }
+ //
+ // check that remaining entries are actual directories
+ //
+ int count = CUtil.checkDirectoryArray(libpath);
+ //
+ // populate return array with remaining entries
+ //
+ libDirs = new File[count];
+ int index = 0;
+ for (int i = 0; i < libpath.length; i++) {
+ if (libpath[i] != null) {
+ libDirs[index++] = new File(libpath[i]);
+ }
+ }
+ }
+ return libDirs;
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return GccLibrarian.getInstance();
+ }
+ if (type.isPluginModule()) {
+ if (isDarwin()) {
+ return machBundleLinker;
+ } else {
+ return dllLinker;
+ }
+ }
+ if (type.isSharedLibrary()) {
+ if (isDarwin()) {
+ return machDllLinker;
+ } else {
+ return dllLinker;
+ }
+ }
+ return instance;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java
new file mode 100644
index 0000000..988848d
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java
@@ -0,0 +1,299 @@
+/*
+ *
+ * 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.gcc;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler;
+/**
+ * A add-in class for Gcc processors
+ *
+ *
+ */
+public class GccProcessor {
+ // the results from gcc -dumpmachine
+ private static String machine;
+ private static String[] specs;
+ // the results from gcc -dumpversion
+ private static String version;
+ 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;
+ }
+ /**
+ * Converts absolute Cygwin file or directory names to the corresponding
+ * Win32 name.
+ *
+ * @param names
+ * array of names, some elements may be null, will be changed in
+ * place.
+ */
+ public static void convertCygwinFilenames(String[] names) {
+ if (names == null) {
+ throw new NullPointerException("names");
+ }
+ File gccDir = CUtil.getExecutableLocation("gcc.exe");
+ if (gccDir != null) {
+ String prefix = gccDir.getAbsolutePath() + "/..";
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < names.length; i++) {
+ String name = names[i];
+ if (name != null && name.length() > 1 && name.charAt(0) == '/') {
+ buf.setLength(0);
+ buf.append(prefix);
+ buf.append(name);
+ names[i] = buf.toString();
+ }
+ }
+ }
+ }
+ public static String[] getLibraryPatterns(String[] libnames) {
+ StringBuffer buf = new StringBuffer();
+ String[] patterns = new String[libnames.length * 2];
+ int offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0);
+ if (isHPUX()) {
+ offset = addLibraryPatterns(libnames, buf, "lib", ".sl", patterns,
+ offset);
+ } else {
+ offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns,
+ offset);
+ }
+ return patterns;
+ }
+ public static String getMachine() {
+ if (machine == null) {
+ String[] args = new String[]{"gcc", "-dumpmachine"};
+ String[] cmdout = CaptureStreamHandler.run(args);
+ if (cmdout.length == 0) {
+ machine = "nomachine";
+ } else {
+ machine = cmdout[0];
+ }
+ }
+ return machine;
+ }
+ public static String[] getOutputFileSwitch(String letter, String outputFile) {
+ StringBuffer buf = new StringBuffer();
+ if (outputFile.indexOf(' ') >= 0) {
+ buf.append('"');
+ buf.append(outputFile.replace('\\', '/'));
+ buf.append('"');
+ } else {
+ buf.append(outputFile.replace('\\', '/'));
+ }
+ String[] retval = new String[]{letter, buf.toString()};
+ return retval;
+ }
+ /**
+ * Returns the contents of the gcc specs file.
+ *
+ * The implementation locates gcc.exe in the executable path and then
+ * builds a relative path name from the results of -dumpmachine and
+ * -dumpversion. Attempts to use gcc -dumpspecs to provide this information
+ * resulted in stalling on the Execute.run
+ *
+ * @return contents of the specs file
+ */
+ public static String[] getSpecs() {
+ if (specs == null) {
+ File gccParent = CUtil.getExecutableLocation("gcc.exe");
+ if (gccParent != null) {
+ //
+ // build a relative path like
+ // ../lib/gcc-lib/i686-pc-cygwin/2.95.3-5/specs
+ //
+ StringBuffer buf = new StringBuffer("../lib/gcc-lib/");
+ buf.append(getMachine());
+ buf.append('/');
+ buf.append(getVersion());
+ buf.append("/specs");
+ //
+ // resolve it relative to the location of gcc.exe
+ //
+ String relativePath = buf.toString();
+ File specsFile = new File(gccParent, relativePath);
+ //
+ // found the specs file
+ //
+ try {
+ //
+ // read the lines in the file
+ //
+ BufferedReader reader = new BufferedReader(new FileReader(
+ specsFile));
+ Vector lines = new Vector(100);
+ String line = reader.readLine();
+ while (line != null) {
+ lines.addElement(line);
+ line = reader.readLine();
+ }
+ specs = new String[lines.size()];
+ lines.copyInto(specs);
+ } catch (IOException ex) {
+ }
+ }
+ }
+ if (specs == null) {
+ specs = new String[0];
+ }
+ return specs;
+ }
+ public static String getVersion() {
+ if (version == null) {
+ String[] args = new String[]{"gcc", "-dumpversion"};
+ String[] cmdout = CaptureStreamHandler.run(args);
+ if (cmdout.length == 0) {
+ version = "noversion";
+ } else {
+ version = cmdout[0];
+ }
+ }
+ return version;
+ }
+ public static boolean isCaseSensitive() {
+ return true;
+ }
+ /**
+ * Determines if task is running with cygwin
+ *
+ * @return true if cygwin was detected
+ */
+ public static boolean isCygwin() {
+ return getMachine().indexOf("cygwin") > 0;
+ }
+ private static boolean isHPUX() {
+ String osname = System.getProperty("os.name").toLowerCase();
+ if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) {
+ return true;
+ }
+ return false;
+ }
+ /**
+ *
+ * Parses the results of the specs file for a specific processor and
+ * options
+ *
+ * @param specsContent
+ * Contents of specs file as returned from getSpecs
+ * @param specSectionStart
+ * start of spec section, for example "*cpp:"
+ * @param options
+ * command line switches such as "-istart"
+ */
+ public static String[][] parseSpecs(String[] specsContent,
+ String specSectionStart, String[] options) {
+ if (specsContent == null) {
+ throw new NullPointerException("specsContent");
+ }
+ if (specSectionStart == null) {
+ throw new NullPointerException("specSectionStart");
+ }
+ if (options == null) {
+ throw new NullPointerException("option");
+ }
+ String[][] optionValues = new String[options.length][];
+ StringBuffer optionValue = new StringBuffer(40);
+ for (int i = 0; i < specsContent.length; i++) {
+ String specLine = specsContent[i];
+ //
+ // if start of section then start paying attention
+ //
+ if (specLine.startsWith(specSectionStart)) {
+ Vector[] optionVectors = new Vector[options.length];
+ for (int j = 0; j < options.length; j++) {
+ optionVectors[j] = new Vector(10);
+ }
+ //
+ // go to next line and examine contents
+ // and repeat until end of file
+ //
+ for (i++; i < specsContent.length; i++) {
+ specLine = specsContent[i];
+ for (int j = 0; j < options.length; j++) {
+ int optionStart = specLine.indexOf(options[j]);
+ while (optionStart >= 0) {
+ optionValue.setLength(0);
+ //
+ // walk rest of line looking for first non
+ // whitespace
+ // and then next space
+ boolean hasNonBlank = false;
+ int k = optionStart + options[j].length();
+ for (; k < specLine.length(); k++) {
+ //
+ // either a blank or a "}" (close of
+ // conditional)
+ // section will end the path
+ //
+ if (specLine.charAt(k) == ' '
+ || specLine.charAt(k) == '}') {
+ if (hasNonBlank) {
+ break;
+ }
+ } else {
+ hasNonBlank = true;
+ optionValue.append(specLine.charAt(k));
+ }
+ }
+ //
+ // transition back to whitespace
+ // value is over, add it to vector
+ if (hasNonBlank) {
+ optionVectors[j].addElement(optionValue
+ .toString());
+ }
+ //
+ // find next occurance on line
+ //
+ optionStart = specLine.indexOf(options[j], k);
+ }
+ }
+ }
+ //
+ // copy vectors over to option arrays
+ //
+ for (int j = 0; j < options.length; j++) {
+ optionValues[j] = new String[optionVectors[j].size()];
+ optionVectors[j].copyInto(optionValues[j]);
+ }
+ }
+ }
+ //
+ // fill in any missing option values with
+ // a zero-length string array
+ for (int i = 0; i < optionValues.length; i++) {
+ String[] zeroLenArray = new String[0];
+ if (optionValues[i] == null) {
+ optionValues[i] = zeroLenArray;
+ }
+ }
+ return optionValues;
+ }
+ private GccProcessor() {
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/GppLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GppLinker.java
new file mode 100644
index 0000000..f3bc174
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GppLinker.java
@@ -0,0 +1,203 @@
+/*
+ *
+ * Copyright 2003-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.gcc;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.types.LibrarySet;
+/**
+ * Adapter for the g++ variant of the GCC linker
+ *
+ * @author Stephen M. Webb <stephen.webb@bregmasoft.com>
+ */
+public class GppLinker extends AbstractLdLinker {
+ protected static final String[] discardFiles = new String[0];
+ protected static final String[] objFiles = new String[]{".o", ".a", ".lib",
+ ".dll", ".so", ".sl"};
+ private static final GppLinker dllLinker = new GppLinker("gcc", objFiles,
+ discardFiles, "lib", ".so", false, new GppLinker("gcc", objFiles,
+ discardFiles, "lib", ".so", true, null));
+ private final static String libPrefix = "libraries: =";
+ protected static final String[] libtoolObjFiles = new String[]{".fo", ".a",
+ ".lib", ".dll", ".so", ".sl"};
+ private static String[] linkerOptions = new String[]{"-bundle", "-dylib",
+ "-dynamic", "-dynamiclib", "-nostartfiles", "-nostdlib",
+ "-prebind", "-s", "-static", "-shared", "-symbolic", "-Xlinker"};
+ private static final GppLinker instance = new GppLinker("gcc", objFiles,
+ discardFiles, "", "", false, null);
+ private static final GppLinker machDllLinker = new GppLinker("gcc",
+ objFiles, discardFiles, "lib", ".dylib", false, null);
+ private static final GppLinker machPluginLinker = new GppLinker("gcc",
+ objFiles, discardFiles, "lib", ".bundle", false, null);
+ public static GppLinker getInstance() {
+ return instance;
+ }
+ private File[] libDirs;
+ private String runtimeLibrary;
+ protected GppLinker(String command, String[] extensions,
+ String[] ignoredExtensions, String outputPrefix,
+ String outputSuffix, boolean isLibtool, GppLinker libtoolLinker) {
+ super(command, "-dumpversion", extensions, ignoredExtensions,
+ outputPrefix, outputSuffix, isLibtool, libtoolLinker);
+ }
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ super.addImpliedArgs(debug, linkType, args);
+ if (getIdentifier().indexOf("mingw") >= 0) {
+ if (linkType.isSubsystemConsole()) {
+ args.addElement("-mconsole");
+ }
+ if (linkType.isSubsystemGUI()) {
+ args.addElement("-mwindows");
+ }
+ }
+ if (linkType.isStaticRuntime()) {
+ String[] cmdin = new String[]{"g++", "-print-file-name=libstdc++.a"};
+ String[] cmdout = CaptureStreamHandler.run(cmdin);
+ if (cmdout.length > 0) {
+ runtimeLibrary = cmdout[0];
+ } else {
+ runtimeLibrary = null;
+ }
+ } else {
+ runtimeLibrary = "-lstdc++";
+ }
+ }
+ public String[] addLibrarySets(CCTask task, LibrarySet[] libsets,
+ Vector preargs, Vector midargs, Vector endargs) {
+ String[] rs = super.addLibrarySets(task, libsets, preargs, midargs,
+ endargs);
+ if (runtimeLibrary != null) {
+ endargs.addElement(runtimeLibrary);
+ }
+ return rs;
+ }
+ /**
+ * Allows drived linker to decorate linker option. Override by GppLinker to
+ * prepend a "-Wl," to pass option to through gcc to linker.
+ *
+ * @param buf
+ * buffer that may be used and abused in the decoration process,
+ * must not be null.
+ * @param arg
+ * linker argument
+ */
+ public String decorateLinkerOption(StringBuffer buf, String arg) {
+ String decoratedArg = arg;
+ if (arg.length() > 1 && arg.charAt(0) == '-') {
+ switch (arg.charAt(1)) {
+ //
+ // passed automatically by GCC
+ //
+ case 'g' :
+ case 'f' :
+ case 'F' :
+ /* Darwin */
+ case 'm' :
+ case 'O' :
+ case 'W' :
+ case 'l' :
+ case 'L' :
+ case 'u' :
+ break;
+ default :
+ boolean known = false;
+ for (int i = 0; i < linkerOptions.length; i++) {
+ if (linkerOptions[i].equals(arg)) {
+ known = true;
+ break;
+ }
+ }
+ if (!known) {
+ buf.setLength(0);
+ buf.append("-Wl,");
+ buf.append(arg);
+ decoratedArg = buf.toString();
+ }
+ break;
+ }
+ }
+ return decoratedArg;
+ }
+ /**
+ * Returns library path.
+ *
+ */
+ public File[] getLibraryPath() {
+ if (libDirs == null) {
+ Vector dirs = new Vector();
+ // Ask GCC where it will look for its libraries.
+ String[] args = new String[]{"g++", "-print-search-dirs"};
+ String[] cmdout = CaptureStreamHandler.run(args);
+ for (int i = 0; i < cmdout.length; ++i) {
+ int prefixIndex = cmdout[i].indexOf(libPrefix);
+ if (prefixIndex >= 0) {
+ // Special case DOS-type GCCs like MinGW or Cygwin
+ int s = prefixIndex + libPrefix.length();
+ int t = cmdout[i].indexOf(';', s);
+ while (t > 0) {
+ dirs.addElement(cmdout[i].substring(s, t));
+ s = t + 1;
+ t = cmdout[i].indexOf(';', s);
+ }
+ dirs.addElement(cmdout[i].substring(s));
+ ++i;
+ for (; i < cmdout.length; ++i) {
+ dirs.addElement(cmdout[i]);
+ }
+ }
+ }
+ // Eliminate all but actual directories.
+ String[] libpath = new String[dirs.size()];
+ dirs.copyInto(libpath);
+ int count = CUtil.checkDirectoryArray(libpath);
+ // Build return array.
+ libDirs = new File[count];
+ int index = 0;
+ for (int i = 0; i < libpath.length; ++i) {
+ if (libpath[i] != null) {
+ libDirs[index++] = new File(libpath[i]);
+ }
+ }
+ }
+ return libDirs;
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return GccLibrarian.getInstance();
+ }
+ if (type.isPluginModule()) {
+ if (GccProcessor.getMachine().indexOf("darwin") >= 0) {
+ return machPluginLinker;
+ } else {
+ return dllLinker;
+ }
+ }
+ if (type.isSharedLibrary()) {
+ if (GccProcessor.getMachine().indexOf("darwin") >= 0) {
+ return machDllLinker;
+ } else {
+ return dllLinker;
+ }
+ }
+ return instance;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/LdLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/LdLinker.java
new file mode 100644
index 0000000..2104e34
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/LdLinker.java
@@ -0,0 +1,57 @@
+/*
+ *
+ * Copyright 2001-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.gcc;
+import java.io.File;
+
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+/**
+ * Adapter for the 'ld' linker
+ *
+ * @author Curt Arnold
+ */
+public final class LdLinker extends AbstractLdLinker {
+ private static final String[] discardFiles = new String[0];
+ private static final String[] objFiles = new String[]{".o", ".a", ".lib",
+ ".dll", ".so", ".sl"};
+ private static final LdLinker dllLinker = new LdLinker("ld", objFiles,
+ discardFiles, "lib", ".so", false, new LdLinker("ld", objFiles,
+ discardFiles, "lib", ".so", true, null));
+ private static final LdLinker instance = new LdLinker("ld", objFiles,
+ discardFiles, "", "", false, null);
+ private static final String[] libtoolObjFiles = new String[]{".fo", ".a",
+ ".lib", ".dll", ".so", ".sl"};
+ public static LdLinker getInstance() {
+ return instance;
+ }
+ private File[] libDirs;
+ private LdLinker(String command, String[] extensions,
+ String[] ignoredExtensions, String outputPrefix,
+ String outputSuffix, boolean isLibtool, LdLinker libtoolLinker) {
+ super(command, "-version", extensions, ignoredExtensions, outputPrefix,
+ outputSuffix, isLibtool, libtoolLinker);
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return GccLibrarian.getInstance();
+ }
+ if (type.isSharedLibrary()) {
+ return dllLinker;
+ }
+ return instance;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/WindresResourceCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/WindresResourceCompiler.java
new file mode 100644
index 0000000..a617024
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/WindresResourceCompiler.java
@@ -0,0 +1,121 @@
+/*
+ *
+ * Copyright 2008 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.gcc;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.parser.CParser;
+import net.sf.antcontrib.cpptasks.parser.Parser;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for the GNU windres resource compiler.
+ *
+ * @author Curt Arnold
+ */
+public final class WindresResourceCompiler extends CommandLineCompiler {
+ private static final WindresResourceCompiler instance = new WindresResourceCompiler(
+ false, null);
+ public static WindresResourceCompiler getInstance() {
+ return instance;
+ }
+ private WindresResourceCompiler(boolean newEnvironment, Environment env) {
+ super("windres", null, new String[]{".rc"}, new String[]{".h", ".hpp",
+ ".inl"}, ".o", false, null, newEnvironment, env);
+ }
+ protected void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ if (debug) {
+ args.addElement("-D_DEBUG");
+ } else {
+ args.addElement("-DNDEBUG");
+ }
+ }
+ protected void addWarningSwitch(Vector args, int level) {
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new WindresResourceCompiler(newEnvironment, env);
+ }
+ return this;
+ }
+ /**
+ * The include parser for C will work just fine, but we didn't want to
+ * inherit from CommandLineCCompiler
+ */
+ protected Parser createParser(File source) {
+ return new CParser();
+ }
+ protected int getArgumentCountPerInputFile() {
+ return 2;
+ }
+ protected void getDefineSwitch(StringBuffer buffer, String define,
+ String value) {
+ buffer.append("-D");
+ buffer.append(define);
+ if (value != null && value.length() > 0) {
+ buffer.append('=');
+ buffer.append(value);
+ }
+ }
+ protected File[] getEnvironmentIncludePath() {
+ return new File[0];
+ }
+ protected String getIncludeDirSwitch(String includeDir) {
+ return "-I" + includeDir;
+ }
+ protected String getInputFileArgument(File outputDir, String filename,
+ int index) {
+ if (index == 0) {
+ String outputFileName = getOutputFileNames(filename, null)[0];
+ return "-o" + outputFileName;
+ }
+ return filename;
+ }
+ public Linker getLinker(LinkType type) {
+ return GccLinker.getInstance().getLinker(type);
+ }
+ public int getMaximumCommandLength() {
+ return 32767;
+ }
+ protected int getMaximumInputFilesPerCommand() {
+ return 1;
+ }
+ protected int getTotalArgumentLengthForInputFile(File outputDir,
+ String inputFile) {
+ String arg1 = getInputFileArgument(outputDir, inputFile, 0);
+ String arg2 = getInputFileArgument(outputDir, inputFile, 1);
+ return arg1.length() + arg2.length() + 2;
+ }
+ protected void getUndefineSwitch(StringBuffer buffer, String define) {
+ buffer.append("-U");
+ buffer.append(define);
+ }
+ public String getIdentifier() {
+ return "GNU windres";
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccCCompiler.java
new file mode 100644
index 0000000..86a8ac7
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccCCompiler.java
@@ -0,0 +1,272 @@
+/*
+ *
+ * Copyright 2001-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.gcc.cross;
+import java.io.File;
+import java.util.Vector;
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.CompilerParam;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.compiler.ProgressMonitor;
+import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler;
+import net.sf.antcontrib.cpptasks.parser.CParser;
+import net.sf.antcontrib.cpptasks.parser.FortranParser;
+import net.sf.antcontrib.cpptasks.parser.Parser;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Environment;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+/**
+ * Adapter for the GCC C/C++ compiler
+ *
+ * @author Adam Murdoch
+ */
+public final class GccCCompiler extends GccCompatibleCCompiler {
+ private final static String[] headerExtensions = new String[]{".h", ".hpp",
+ ".inl"};
+ private final static String[] sourceExtensions = new String[]{".c", /* C */
+ ".cc", /* C++ */
+ ".cpp", /* C++ */
+ ".cxx", /* C++ */
+ ".c++", /* C++ */
+ ".i", /* preprocessed C */
+ ".ii", /* preprocessed C++ */
+ ".f", /* FORTRAN */
+ ".for", /* FORTRAN */
+ ".m", /* Objective-C */
+ ".mm", /* Objected-C++ */
+ ".s" /* Assembly */
+ };
+ private static final GccCCompiler cppInstance = new GccCCompiler("c++",
+ sourceExtensions, headerExtensions, false,
+ new GccCCompiler("c++", sourceExtensions, headerExtensions, true,
+ null, false, null), false, null);
+ private static final GccCCompiler g77Instance = new GccCCompiler("g77",
+ sourceExtensions, headerExtensions, false,
+ new GccCCompiler("g77", sourceExtensions, headerExtensions, true,
+ null, false, null), false, null);
+ private static final GccCCompiler gppInstance = new GccCCompiler("g++",
+ sourceExtensions, headerExtensions, false,
+ new GccCCompiler("g++", sourceExtensions, headerExtensions, true,
+ null, false, null), false, null);
+ private static final GccCCompiler instance = new GccCCompiler("gcc",
+ sourceExtensions, headerExtensions, false,
+ new GccCCompiler("gcc", sourceExtensions, headerExtensions, true,
+ null, false, null), false, null);
+ /**
+ * Gets c++ adapter
+ */
+ public static GccCCompiler getCppInstance() {
+ return cppInstance;
+ }
+ /**
+ * Gets g77 adapter
+ */
+ public static GccCCompiler getG77Instance() {
+ return g77Instance;
+ }
+ /**
+ * Gets gpp adapter
+ */
+ public static GccCCompiler getGppInstance() {
+ return gppInstance;
+ }
+ /**
+ * Gets gcc adapter
+ */
+ public static GccCCompiler getInstance() {
+ return instance;
+ }
+ private String identifier;
+ private File[] includePath;
+ private boolean isPICMeaningful = true;
+ /**
+ * Private constructor. Use GccCCompiler.getInstance() to get singleton
+ * instance of this class.
+ */
+ private GccCCompiler(String command, String[] sourceExtensions,
+ String[] headerExtensions, boolean isLibtool,
+ GccCCompiler libtoolCompiler, boolean newEnvironment,
+ Environment env) {
+ super(command, null, sourceExtensions, headerExtensions, isLibtool,
+ libtoolCompiler, newEnvironment, env);
+ isPICMeaningful = System.getProperty("os.name").indexOf("Windows") < 0;
+ }
+ public void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ super.addImpliedArgs(args, debug, multithreaded,
+ exceptions, linkType, rtti, optimization);
+ if (isPICMeaningful && linkType.isSharedLibrary()) {
+ args.addElement("-fPIC");
+ }
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new GccCCompiler(getCommand(), this.getSourceExtensions(),
+ this.getHeaderExtensions(), this.getLibtool(),
+ (GccCCompiler) this.getLibtoolCompiler(), newEnvironment,
+ env);
+ }
+ return this;
+ }
+ protected Object clone() throws CloneNotSupportedException {
+ GccCCompiler clone = (GccCCompiler) super.clone();
+ return clone;
+ }
+ public void compile(CCTask task, File outputDir, String[] sourceFiles,
+ String[] args, String[] endArgs, boolean relentless,
+ CommandLineCompilerConfiguration config, ProgressMonitor monitor)
+ throws BuildException {
+ try {
+ GccCCompiler clone = (GccCCompiler) this.clone();
+ CompilerParam param = config.getParam("target");
+ if (param != null)
+ clone.setCommand(param.getValue() + "-" + this.getCommand());
+ clone.supercompile(task, outputDir, sourceFiles, args, endArgs,
+ relentless, config, monitor);
+ } catch (CloneNotSupportedException e) {
+ supercompile(task, outputDir, sourceFiles, args, endArgs,
+ relentless, config, monitor);
+ }
+ }
+ /**
+ * Create parser to determine dependencies.
+ *
+ * Will create appropriate parser (C++, FORTRAN) based on file extension.
+ *
+ */
+ protected Parser createParser(File source) {
+ if (source != null) {
+ String sourceName = source.getName();
+ int lastDot = sourceName.lastIndexOf('.');
+ if (lastDot >= 0 && lastDot + 1 < sourceName.length()) {
+ char afterDot = sourceName.charAt(lastDot + 1);
+ if (afterDot == 'f' || afterDot == 'F') {
+ return new FortranParser();
+ }
+ }
+ }
+ return new CParser();
+ }
+ public File[] getEnvironmentIncludePath() {
+ if (includePath == null) {
+ //
+ // construct default include path from machine id and version id
+ //
+ String[] defaultInclude = new String[1];
+ StringBuffer buf = new StringBuffer("/lib/");
+ buf.append(GccProcessor.getMachine());
+ buf.append('/');
+ buf.append(GccProcessor.getVersion());
+ buf.append("/include");
+ defaultInclude[0] = buf.toString();
+ //
+ // read specs file and look for -istart and -idirafter
+ //
+ String[] specs = GccProcessor.getSpecs();
+ String[][] optionValues = GccProcessor.parseSpecs(specs, "*cpp:",
+ new String[]{"-isystem ", "-idirafter "});
+ //
+ // if no entries were found, then use a default path
+ //
+ if (optionValues[0].length == 0 && optionValues[1].length == 0) {
+ optionValues[0] = new String[]{"/usr/local/include",
+ "/usr/include", "/usr/include/win32api"};
+ }
+ //
+ // remove mingw entries.
+ // For MinGW compiles this will mean the
+ // location of the sys includes will be
+ // wrong in dependencies.xml
+ // but that should have no significant effect
+ for (int i = 0; i < optionValues.length; i++) {
+ for (int j = 0; j < optionValues[i].length; j++) {
+ if (optionValues[i][j].indexOf("mingw") > 0) {
+ optionValues[i][j] = null;
+ }
+ }
+ }
+ //
+ // if cygwin then
+ // we have to prepend location of gcc32
+ // and .. to start of absolute filenames to
+ // have something that will exist in the
+ // windows filesystem
+ if (GccProcessor.isCygwin()) {
+ GccProcessor.convertCygwinFilenames(optionValues[0]);
+ GccProcessor.convertCygwinFilenames(optionValues[1]);
+ GccProcessor.convertCygwinFilenames(defaultInclude);
+ }
+ int count = CUtil.checkDirectoryArray(optionValues[0]);
+ count += CUtil.checkDirectoryArray(optionValues[1]);
+ count += CUtil.checkDirectoryArray(defaultInclude);
+ includePath = new File[count];
+ int index = 0;
+ for (int i = 0; i < optionValues.length; i++) {
+ for (int j = 0; j < optionValues[i].length; j++) {
+ if (optionValues[i][j] != null) {
+ includePath[index++] = new File(optionValues[i][j]);
+ }
+ }
+ }
+ for (int i = 0; i < defaultInclude.length; i++) {
+ if (defaultInclude[i] != null) {
+ includePath[index++] = new File(defaultInclude[i]);
+ }
+ }
+ }
+ return (File[]) includePath.clone();
+ }
+ public String getIdentifier() throws BuildException {
+ if (identifier == null) {
+ StringBuffer buf;
+ if (getLibtool()) {
+ buf = new StringBuffer("libtool ");
+ } else {
+ buf = new StringBuffer(' ');
+ }
+ buf.append(getCommand());
+ buf.append(' ');
+ buf.append(GccProcessor.getVersion());
+ buf.append(' ');
+ buf.append(GccProcessor.getMachine());
+ identifier = buf.toString();
+ }
+ return identifier;
+ }
+ public Linker getLinker(LinkType linkType) {
+ return GccLinker.getInstance().getLinker(linkType);
+ }
+ public int getMaximumCommandLength() {
+ return Integer.MAX_VALUE;
+ }
+ private void supercompile(CCTask task, File outputDir,
+ String[] sourceFiles, String[] args, String[] endArgs,
+ boolean relentless, CommandLineCompilerConfiguration config,
+ ProgressMonitor monitor) throws BuildException {
+ super.compile(task, outputDir, sourceFiles, args, endArgs, relentless,
+ config, monitor);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccLibrarian.java
new file mode 100644
index 0000000..c9d28d9
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccLibrarian.java
@@ -0,0 +1,69 @@
+/*
+ *
+ * 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.gcc.cross;
+import java.io.File;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.LinkerParam;
+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.gcc.AbstractArLibrarian;
+
+import org.apache.tools.ant.BuildException;
+/**
+ * Adapter for the 'ar' archiver
+ *
+ * @author Adam Murdoch
+ */
+public final class GccLibrarian extends AbstractArLibrarian {
+ private static String[] objFileExtensions = new String[]{".o"};
+ private static GccLibrarian instance = new GccLibrarian("ar",
+ objFileExtensions, false, new GccLibrarian("ar", objFileExtensions,
+ true, null));
+ public static GccLibrarian getInstance() {
+ return instance;
+ }
+ private GccLibrarian(String command, String[] inputExtensions,
+ boolean isLibtool, GccLibrarian libtoolLibrarian) {
+ super(command, "V", inputExtensions, new String[0], "lib", ".a",
+ isLibtool, libtoolLibrarian);
+ }
+ protected Object clone() throws CloneNotSupportedException {
+ GccLibrarian clone = (GccLibrarian) super.clone();
+ return clone;
+ }
+ public Linker getLinker(LinkType type) {
+ return GccLinker.getInstance().getLinker(type);
+ }
+ public void link(CCTask task, File outputFile, String[] sourceFiles,
+ CommandLineLinkerConfiguration config) throws BuildException {
+ try {
+ GccLibrarian clone = (GccLibrarian) this.clone();
+ LinkerParam param = config.getParam("target");
+ if (param != null)
+ clone.setCommand(param.getValue() + "-" + this.getCommand());
+ clone.superlink(task, outputFile, sourceFiles, config);
+ } catch (CloneNotSupportedException e) {
+ superlink(task, outputFile, sourceFiles, config);
+ }
+ }
+ private void superlink(CCTask task, File outputFile, String[] sourceFiles,
+ CommandLineLinkerConfiguration config) throws BuildException {
+ super.link(task, outputFile, sourceFiles, config);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccLinker.java
new file mode 100644
index 0000000..4347211
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccLinker.java
@@ -0,0 +1,234 @@
+/*
+ *
+ * Copyright 2001-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.gcc.cross;
+import java.io.File;
+import java.util.Vector;
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.LinkerParam;
+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.gcc.AbstractLdLinker;
+import org.apache.tools.ant.BuildException;
+/**
+ * Adapter for the GCC linker
+ *
+ * @author Adam Murdoch
+ */
+public class GccLinker extends AbstractLdLinker {
+ private static final String[] discardFiles = new String[0];
+ private static final String[] objFiles = new String[]{".o", ".a", ".lib",
+ ".dll", ".so", ".sl"};
+ private static final GccLinker dllLinker = new GccLinker("gcc", objFiles,
+ discardFiles, "lib", ".so", false, new GccLinker("gcc", objFiles,
+ discardFiles, "lib", ".so", true, null));
+ private static final GccLinker instance = new GccLinker("gcc", objFiles,
+ discardFiles, "", "", false, null);
+ private static final String[] libtoolObjFiles = new String[]{".fo", ".a",
+ ".lib", ".dll", ".so", ".sl"};
+ private static String[] linkerOptions = new String[]{"-bundle",
+ "-dynamiclib", "-nostartfiles", "-nostdlib", "-prebind", "-s",
+ "-static", "-shared", "-symbolic", "-Xlinker",
+ "--export-all-symbols", "-static-libgcc",};
+ private static final GccLinker machBundleLinker = new GccLinker("gcc",
+ objFiles, discardFiles, "lib", ".bundle", false, null);
+ private static final GccLinker machDllLinker = new GccLinker("gcc",
+ objFiles, discardFiles, "lib", ".dylib", false, null);
+ public static GccLinker getInstance() {
+ return instance;
+ }
+ private File[] libDirs;
+ protected GccLinker(String command, String[] extensions,
+ String[] ignoredExtensions, String outputPrefix,
+ String outputSuffix, boolean isLibtool, GccLinker libtoolLinker) {
+ super(command, "-dumpversion", extensions, ignoredExtensions,
+ outputPrefix, outputSuffix, isLibtool, libtoolLinker);
+ }
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ super.addImpliedArgs(debug, linkType, args);
+ if (getIdentifier().indexOf("mingw") >= 0) {
+ if (linkType.isSubsystemConsole()) {
+ args.addElement("-mconsole");
+ }
+ if (linkType.isSubsystemGUI()) {
+ args.addElement("-mwindows");
+ }
+ }
+ }
+ protected Object clone() throws CloneNotSupportedException {
+ GccLinker clone = (GccLinker) super.clone();
+ return clone;
+ }
+ /**
+ * Allows drived linker to decorate linker option. Override by GccLinker to
+ * prepend a "-Wl," to pass option to through gcc to linker.
+ *
+ * @param buf
+ * buffer that may be used and abused in the decoration process,
+ * must not be null.
+ * @param arg
+ * linker argument
+ */
+ public String decorateLinkerOption(StringBuffer buf, String arg) {
+ String decoratedArg = arg;
+ if (arg.length() > 1 && arg.charAt(0) == '-') {
+ switch (arg.charAt(1)) {
+ //
+ // passed automatically by GCC
+ //
+ case 'g' :
+ case 'f' :
+ case 'F' :
+ /* Darwin */
+ case 'm' :
+ case 'O' :
+ case 'W' :
+ case 'l' :
+ case 'L' :
+ case 'u' :
+ case 'v' :
+ break;
+ default :
+ boolean known = false;
+ for (int i = 0; i < linkerOptions.length; i++) {
+ if (linkerOptions[i].equals(arg)) {
+ known = true;
+ break;
+ }
+ }
+ if (!known) {
+ buf.setLength(0);
+ buf.append("-Wl,");
+ buf.append(arg);
+ decoratedArg = buf.toString();
+ }
+ break;
+ }
+ }
+ return decoratedArg;
+ }
+ /**
+ * Returns library path.
+ *
+ */
+ public File[] getLibraryPath() {
+ if (libDirs == null) {
+ //
+ // construct gcc lib path from machine and version
+ //
+ StringBuffer buf = new StringBuffer("/lib/gcc-lib/");
+ buf.append(GccProcessor.getMachine());
+ buf.append('/');
+ buf.append(GccProcessor.getVersion());
+ //
+ // build default path from gcc and system /lib and /lib/w32api
+ //
+ String[] impliedLibPath = new String[]{buf.toString(),
+ "/lib/w32api", "/lib"};
+ //
+ // read gcc specs file for other library paths
+ //
+ String[] specs = GccProcessor.getSpecs();
+ String[][] libpaths = GccProcessor.parseSpecs(specs, "*link:",
+ new String[]{"%q"});
+ String[] libpath;
+ if (libpaths[0].length > 0) {
+ libpath = new String[libpaths[0].length + 3];
+ int i = 0;
+ for (; i < libpaths[0].length; i++) {
+ libpath[i] = libpaths[0][i];
+ }
+ libpath[i++] = buf.toString();
+ libpath[i++] = "/lib/w32api";
+ libpath[i++] = "/lib";
+ } else {
+ //
+ // if a failure to find any matches then
+ // use some default values for lib path entries
+ libpath = new String[]{"/usr/local/lib/mingw",
+ "/usr/local/lib", "/usr/lib/w32api", "/usr/lib/mingw",
+ "/usr/lib", buf.toString(), "/lib/w32api", "/lib"};
+ }
+ for (int i = 0; i < libpath.length; i++) {
+ if (libpath[i].indexOf("mingw") >= 0) {
+ libpath[i] = null;
+ }
+ }
+ //
+ // if cygwin then
+ // we have to prepend location of gcc32
+ // and .. to start of absolute filenames to
+ // have something that will exist in the
+ // windows filesystem
+ if (GccProcessor.isCygwin()) {
+ GccProcessor.convertCygwinFilenames(libpath);
+ }
+ //
+ // check that remaining entries are actual directories
+ //
+ int count = CUtil.checkDirectoryArray(libpath);
+ //
+ // populate return array with remaining entries
+ //
+ libDirs = new File[count];
+ int index = 0;
+ for (int i = 0; i < libpath.length; i++) {
+ if (libpath[i] != null) {
+ libDirs[index++] = new File(libpath[i]);
+ }
+ }
+ }
+ return libDirs;
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return GccLibrarian.getInstance();
+ }
+ if (type.isPluginModule()) {
+ if (isDarwin()) {
+ return machBundleLinker;
+ } else {
+ return dllLinker;
+ }
+ }
+ if (type.isSharedLibrary()) {
+ if (isDarwin()) {
+ return machDllLinker;
+ } else {
+ return dllLinker;
+ }
+ }
+ return instance;
+ }
+ public void link(CCTask task, File outputFile, String[] sourceFiles,
+ CommandLineLinkerConfiguration config) throws BuildException {
+ try {
+ GccLinker clone = (GccLinker) this.clone();
+ LinkerParam param = config.getParam("target");
+ if (param != null)
+ clone.setCommand(param.getValue() + "-" + this.getCommand());
+ clone.superlink(task, outputFile, sourceFiles, config);
+ } catch (CloneNotSupportedException e) {
+ superlink(task, outputFile, sourceFiles, config);
+ }
+ }
+ private void superlink(CCTask task, File outputFile, String[] sourceFiles,
+ CommandLineLinkerConfiguration config) throws BuildException {
+ super.link(task, outputFile, sourceFiles, config);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccProcessor.java
new file mode 100644
index 0000000..728cd47
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccProcessor.java
@@ -0,0 +1,288 @@
+/*
+ *
+ * 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.gcc.cross;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler;
+
+/**
+ * A add-in class for Gcc processors
+ *
+ *
+ */
+public class GccProcessor {
+ // the results from gcc -dumpmachine
+ private static String machine;
+ private static String[] specs;
+ // the results from gcc -dumpversion
+ private static String version;
+ 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;
+ }
+ /**
+ * Converts absolute Cygwin file or directory names to the corresponding
+ * Win32 name.
+ *
+ * @param names
+ * array of names, some elements may be null, will be changed in
+ * place.
+ */
+ public static void convertCygwinFilenames(String[] names) {
+ if (names == null) {
+ throw new NullPointerException("names");
+ }
+ File gccDir = CUtil.getExecutableLocation("gcc.exe");
+ if (gccDir != null) {
+ String prefix = gccDir.getAbsolutePath() + "/..";
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < names.length; i++) {
+ String name = names[i];
+ if (name != null && name.length() > 1 && name.charAt(0) == '/') {
+ buf.setLength(0);
+ buf.append(prefix);
+ buf.append(name);
+ names[i] = buf.toString();
+ }
+ }
+ }
+ }
+
+ public static String getMachine() {
+ if (machine == null) {
+ String[] args = new String[]{"gcc", "-dumpmachine"};
+ String[] cmdout = CaptureStreamHandler.run(args);
+ if (cmdout.length == 0) {
+ machine = "nomachine";
+ } else {
+ machine = cmdout[0];
+ }
+ }
+ return machine;
+ }
+ public static String[] getOutputFileSwitch(String letter, String outputFile) {
+ StringBuffer buf = new StringBuffer();
+ if (outputFile.indexOf(' ') >= 0) {
+ buf.append('"');
+ buf.append(outputFile.replace('\\', '/'));
+ buf.append('"');
+ } else {
+ buf.append(outputFile.replace('\\', '/'));
+ }
+ String[] retval = new String[]{letter, buf.toString()};
+ return retval;
+ }
+ /**
+ * Returns the contents of the gcc specs file.
+ *
+ * The implementation locates gcc.exe in the executable path and then
+ * builds a relative path name from the results of -dumpmachine and
+ * -dumpversion. Attempts to use gcc -dumpspecs to provide this information
+ * resulted in stalling on the Execute.run
+ *
+ * @return contents of the specs file
+ */
+ public static String[] getSpecs() {
+ if (specs == null) {
+ File gccParent = CUtil.getExecutableLocation("gcc.exe");
+ if (gccParent != null) {
+ //
+ // build a relative path like
+ // ../lib/gcc-lib/i686-pc-cygwin/2.95.3-5/specs
+ //
+ StringBuffer buf = new StringBuffer("../lib/gcc-lib/");
+ buf.append(getMachine());
+ buf.append('/');
+ buf.append(getVersion());
+ buf.append("/specs");
+ //
+ // resolve it relative to the location of gcc.exe
+ //
+ String relativePath = buf.toString();
+ File specsFile = new File(gccParent, relativePath);
+ //
+ // found the specs file
+ //
+ try {
+ //
+ // read the lines in the file
+ //
+ BufferedReader reader = new BufferedReader(new FileReader(
+ specsFile));
+ Vector lines = new Vector(100);
+ String line = reader.readLine();
+ while (line != null) {
+ lines.addElement(line);
+ line = reader.readLine();
+ }
+ specs = new String[lines.size()];
+ lines.copyInto(specs);
+ } catch (IOException ex) {
+ }
+ }
+ }
+ if (specs == null) {
+ specs = new String[0];
+ }
+ return specs;
+ }
+ public static String getVersion() {
+ if (version == null) {
+ String[] args = new String[]{"gcc", "-dumpversion"};
+ String[] cmdout = CaptureStreamHandler.run(args);
+ if (cmdout.length == 0) {
+ version = "noversion";
+ } else {
+ version = cmdout[0];
+ }
+ }
+ return version;
+ }
+ public static boolean isCaseSensitive() {
+ return true;
+ }
+ /**
+ * Determines if task is running with cygwin
+ *
+ * @return true if cygwin was detected
+ */
+ public static boolean isCygwin() {
+ return getMachine().indexOf("cygwin") > 0;
+ }
+ private static boolean isHPUX() {
+ String osname = System.getProperty("os.name").toLowerCase();
+ if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) {
+ return true;
+ }
+ return false;
+ }
+ /**
+ *
+ * Parses the results of the specs file for a specific processor and
+ * options
+ *
+ * @param specsContent
+ * Contents of specs file as returned from getSpecs
+ * @param specSectionStart
+ * start of spec section, for example "*cpp:"
+ * @param options
+ * command line switches such as "-istart"
+ */
+ public static String[][] parseSpecs(String[] specsContent,
+ String specSectionStart, String[] options) {
+ if (specsContent == null) {
+ throw new NullPointerException("specsContent");
+ }
+ if (specSectionStart == null) {
+ throw new NullPointerException("specSectionStart");
+ }
+ if (options == null) {
+ throw new NullPointerException("option");
+ }
+ String[][] optionValues = new String[options.length][];
+ StringBuffer optionValue = new StringBuffer(40);
+ for (int i = 0; i < specsContent.length; i++) {
+ String specLine = specsContent[i];
+ //
+ // if start of section then start paying attention
+ //
+ if (specLine.startsWith(specSectionStart)) {
+ Vector[] optionVectors = new Vector[options.length];
+ for (int j = 0; j < options.length; j++) {
+ optionVectors[j] = new Vector(10);
+ }
+ //
+ // go to next line and examine contents
+ // and repeat until end of file
+ //
+ for (i++; i < specsContent.length; i++) {
+ specLine = specsContent[i];
+ for (int j = 0; j < options.length; j++) {
+ int optionStart = specLine.indexOf(options[j]);
+ while (optionStart >= 0) {
+ optionValue.setLength(0);
+ //
+ // walk rest of line looking for first non
+ // whitespace
+ // and then next space
+ boolean hasNonBlank = false;
+ int k = optionStart + options[j].length();
+ for (; k < specLine.length(); k++) {
+ //
+ // either a blank or a "}" (close of
+ // conditional)
+ // section will end the path
+ //
+ if (specLine.charAt(k) == ' '
+ || specLine.charAt(k) == '}') {
+ if (hasNonBlank) {
+ break;
+ }
+ } else {
+ hasNonBlank = true;
+ optionValue.append(specLine.charAt(k));
+ }
+ }
+ //
+ // transition back to whitespace
+ // value is over, add it to vector
+ if (hasNonBlank) {
+ optionVectors[j].addElement(optionValue
+ .toString());
+ }
+ //
+ // find next occurance on line
+ //
+ optionStart = specLine.indexOf(options[j], k);
+ }
+ }
+ }
+ //
+ // copy vectors over to option arrays
+ //
+ for (int j = 0; j < options.length; j++) {
+ optionValues[j] = new String[optionVectors[j].size()];
+ optionVectors[j].copyInto(optionValues[j]);
+ }
+ }
+ }
+ //
+ // fill in any missing option values with
+ // a zero-length string array
+ for (int i = 0; i < optionValues.length; i++) {
+ String[] zeroLenArray = new String[0];
+ if (optionValues[i] == null) {
+ optionValues[i] = zeroLenArray;
+ }
+ }
+ return optionValues;
+ }
+ private GccProcessor() {
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GppLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GppLinker.java
new file mode 100644
index 0000000..b332c64
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GppLinker.java
@@ -0,0 +1,228 @@
+/*
+ *
+ * Copyright 2003-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.gcc.cross;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.LinkerParam;
+import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler;
+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.gcc.AbstractLdLinker;
+import net.sf.antcontrib.cpptasks.types.LibrarySet;
+
+import org.apache.tools.ant.BuildException;
+/**
+ * Adapter for the g++ variant of the GCC linker
+ *
+ * @author Stephen M. Webb <stephen.webb@bregmasoft.com>
+ */
+public class GppLinker extends AbstractLdLinker {
+ protected static final String[] discardFiles = new String[0];
+ protected static final String[] objFiles = new String[]{".o", ".a", ".lib",
+ ".dll", ".so", ".sl"};
+ private static final GppLinker dllLinker = new GppLinker("gcc", objFiles,
+ discardFiles, "lib", ".so", false, new GppLinker("gcc", objFiles,
+ discardFiles, "lib", ".so", true, null));
+ private final static String libPrefix = "libraries: =";
+ protected static final String[] libtoolObjFiles = new String[]{".fo", ".a",
+ ".lib", ".dll", ".so", ".sl"};
+ private static String[] linkerOptions = new String[]{"-bundle", "-dylib",
+ "-dynamic", "-dynamiclib", "-nostartfiles", "-nostdlib",
+ "-prebind", "-s", "-static", "-shared", "-symbolic", "-Xlinker"};
+ private static final GppLinker instance = new GppLinker("gcc", objFiles,
+ discardFiles, "", "", false, null);
+ private static final GppLinker machDllLinker = new GppLinker("gcc",
+ objFiles, discardFiles, "lib", ".dylib", false, null);
+ private static final GppLinker machPluginLinker = new GppLinker("gcc",
+ objFiles, discardFiles, "lib", ".bundle", false, null);
+ public static GppLinker getInstance() {
+ return instance;
+ }
+ private File[] libDirs;
+ private String runtimeLibrary;
+ protected GppLinker(String command, String[] extensions,
+ String[] ignoredExtensions, String outputPrefix,
+ String outputSuffix, boolean isLibtool, GppLinker libtoolLinker) {
+ super(command, "-dumpversion", extensions, ignoredExtensions,
+ outputPrefix, outputSuffix, isLibtool, libtoolLinker);
+ }
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ super.addImpliedArgs(debug, linkType, args);
+ if (getIdentifier().indexOf("mingw") >= 0) {
+ if (linkType.isSubsystemConsole()) {
+ args.addElement("-mconsole");
+ }
+ if (linkType.isSubsystemGUI()) {
+ args.addElement("-mwindows");
+ }
+ }
+ if (linkType.isStaticRuntime()) {
+ String[] cmdin = new String[]{"g++", "-print-file-name=libstdc++.a"};
+ String[] cmdout = CaptureStreamHandler.run(cmdin);
+ if (cmdout.length > 0) {
+ runtimeLibrary = cmdout[0];
+ } else {
+ runtimeLibrary = null;
+ }
+ } else {
+ runtimeLibrary = "-lstdc++";
+ }
+ }
+ public String[] addLibrarySets(CCTask task, LibrarySet[] libsets,
+ Vector preargs, Vector midargs, Vector endargs) {
+ String[] rs = super.addLibrarySets(task, libsets, preargs, midargs,
+ endargs);
+ if (runtimeLibrary != null) {
+ endargs.addElement(runtimeLibrary);
+ }
+ return rs;
+ }
+ protected Object clone() throws CloneNotSupportedException {
+ GppLinker clone = (GppLinker) super.clone();
+ return clone;
+ }
+ /**
+ * Allows drived linker to decorate linker option. Override by GppLinker to
+ * prepend a "-Wl," to pass option to through gcc to linker.
+ *
+ * @param buf
+ * buffer that may be used and abused in the decoration process,
+ * must not be null.
+ * @param arg
+ * linker argument
+ */
+ public String decorateLinkerOption(StringBuffer buf, String arg) {
+ String decoratedArg = arg;
+ if (arg.length() > 1 && arg.charAt(0) == '-') {
+ switch (arg.charAt(1)) {
+ //
+ // passed automatically by GCC
+ //
+ case 'g' :
+ case 'f' :
+ case 'F' :
+ /* Darwin */
+ case 'm' :
+ case 'O' :
+ case 'W' :
+ case 'l' :
+ case 'L' :
+ case 'u' :
+ break;
+ default :
+ boolean known = false;
+ for (int i = 0; i < linkerOptions.length; i++) {
+ if (linkerOptions[i].equals(arg)) {
+ known = true;
+ break;
+ }
+ }
+ if (!known) {
+ buf.setLength(0);
+ buf.append("-Wl,");
+ buf.append(arg);
+ decoratedArg = buf.toString();
+ }
+ break;
+ }
+ }
+ return decoratedArg;
+ }
+ /**
+ * Returns library path.
+ *
+ */
+ public File[] getLibraryPath() {
+ if (libDirs == null) {
+ Vector dirs = new Vector();
+ // Ask GCC where it will look for its libraries.
+ String[] args = new String[]{"g++", "-print-search-dirs"};
+ String[] cmdout = CaptureStreamHandler.run(args);
+ for (int i = 0; i < cmdout.length; ++i) {
+ int prefixIndex = cmdout[i].indexOf(libPrefix);
+ if (prefixIndex >= 0) {
+ // Special case DOS-type GCCs like MinGW or Cygwin
+ int s = prefixIndex + libPrefix.length();
+ int t = cmdout[i].indexOf(';', s);
+ while (t > 0) {
+ dirs.addElement(cmdout[i].substring(s, t));
+ s = t + 1;
+ t = cmdout[i].indexOf(';', s);
+ }
+ dirs.addElement(cmdout[i].substring(s));
+ ++i;
+ for (; i < cmdout.length; ++i) {
+ dirs.addElement(cmdout[i]);
+ }
+ }
+ }
+ // Eliminate all but actual directories.
+ String[] libpath = new String[dirs.size()];
+ dirs.copyInto(libpath);
+ int count = CUtil.checkDirectoryArray(libpath);
+ // Build return array.
+ libDirs = new File[count];
+ int index = 0;
+ for (int i = 0; i < libpath.length; ++i) {
+ if (libpath[i] != null) {
+ libDirs[index++] = new File(libpath[i]);
+ }
+ }
+ }
+ return libDirs;
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return GccLibrarian.getInstance();
+ }
+ if (type.isPluginModule()) {
+ if (GccProcessor.getMachine().indexOf("darwin") >= 0) {
+ return machPluginLinker;
+ } else {
+ return dllLinker;
+ }
+ }
+ if (type.isSharedLibrary()) {
+ if (GccProcessor.getMachine().indexOf("darwin") >= 0) {
+ return machDllLinker;
+ } else {
+ return dllLinker;
+ }
+ }
+ return instance;
+ }
+ public void link(CCTask task, File outputFile, String[] sourceFiles,
+ CommandLineLinkerConfiguration config) throws BuildException {
+ try {
+ GppLinker clone = (GppLinker) this.clone();
+ LinkerParam param = config.getParam("target");
+ if (param != null)
+ clone.setCommand(param.getValue() + "-" + this.getCommand());
+ clone.superlink(task, outputFile, sourceFiles, config);
+ } catch (CloneNotSupportedException e) {
+ superlink(task, outputFile, sourceFiles, config);
+ }
+ }
+ private void superlink(CCTask task, File outputFile, String[] sourceFiles,
+ CommandLineLinkerConfiguration config) throws BuildException {
+ super.link(task, outputFile, sourceFiles, config);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/LdLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/LdLinker.java
new file mode 100644
index 0000000..26abf8c
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/LdLinker.java
@@ -0,0 +1,83 @@
+/*
+ *
+ * Copyright 2001-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.gcc.cross;
+import java.io.File;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.LinkerParam;
+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.gcc.AbstractLdLinker;
+
+import org.apache.tools.ant.BuildException;
+/**
+ * Adapter for the 'ld' linker
+ *
+ * @author Curt Arnold
+ */
+public final class LdLinker extends AbstractLdLinker {
+ private static final String[] libtoolObjFiles = new String[]{".fo", ".a",
+ ".lib", ".dll", ".so", ".sl"};
+ private static final String[] objFiles = new String[]{".o", ".a", ".lib",
+ ".dll", ".so", ".sl"};
+ private static final String[] discardFiles = new String[0];
+ private static final LdLinker dllLinker = new LdLinker("ld", objFiles,
+ discardFiles, "lib", ".so", false, new LdLinker("ld", objFiles,
+ discardFiles, "lib", ".so", true, null));
+ private static final LdLinker instance = new LdLinker("ld", objFiles,
+ discardFiles, "", "", false, null);
+ public static LdLinker getInstance() {
+ return instance;
+ }
+ private File[] libDirs;
+ private LdLinker(String command, String[] extensions,
+ String[] ignoredExtensions, String outputPrefix,
+ String outputSuffix, boolean isLibtool, LdLinker libtoolLinker) {
+ super(command, "-version", extensions, ignoredExtensions, outputPrefix,
+ outputSuffix, isLibtool, libtoolLinker);
+ }
+ protected Object clone() throws CloneNotSupportedException {
+ LdLinker clone = (LdLinker) super.clone();
+ return clone;
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return GccLibrarian.getInstance();
+ }
+ if (type.isSharedLibrary()) {
+ return dllLinker;
+ }
+ return instance;
+ }
+ public void link(CCTask task, File outputFile, String[] sourceFiles,
+ CommandLineLinkerConfiguration config) throws BuildException {
+ try {
+ LdLinker clone = (LdLinker) this.clone();
+ LinkerParam param = config.getParam("target");
+ if (param != null)
+ clone.setCommand(param.getValue() + "-" + this.getCommand());
+ clone.superlink(task, outputFile, sourceFiles, config);
+ } catch (CloneNotSupportedException e) {
+ superlink(task, outputFile, sourceFiles, config);
+ }
+ }
+ private void superlink(CCTask task, File outputFile, String[] sourceFiles,
+ CommandLineLinkerConfiguration config) throws BuildException {
+ super.link(task, outputFile, sourceFiles, config);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccCCompiler.java
new file mode 100644
index 0000000..44dd968
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccCCompiler.java
@@ -0,0 +1,244 @@
+/*
+ *
+ * Copyright 2001-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.gcc.cross.sparc_sun_solaris2;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler;
+import net.sf.antcontrib.cpptasks.parser.CParser;
+import net.sf.antcontrib.cpptasks.parser.FortranParser;
+import net.sf.antcontrib.cpptasks.parser.Parser;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Environment;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+/**
+ * Adapter for the GCC C/C++ compiler
+ *
+ * @author Adam Murdoch
+ */
+public final class GccCCompiler extends GccCompatibleCCompiler {
+ private final static String[] sourceExtensions = new String[]{".c", /* C */
+ ".cc", /* C++ */
+ ".cpp", /* C++ */
+ ".cxx", /* C++ */
+ ".c++", /* C++ */
+ ".i", /* preprocessed C */
+ ".ii", /* preprocessed C++ */
+ ".f", /* FORTRAN */
+ ".for", /* FORTRAN */
+ ".m", /* Objective-C */
+ ".mm", /* Objected-C++ */
+ ".s" /* Assembly */
+ };
+ private final static String[] headerExtensions = new String[]{".h", ".hpp",
+ ".inl"};
+ public static final String CMD_PREFIX = "sparc-sun-solaris2-";
+ private static final GccCCompiler cppInstance = new GccCCompiler(CMD_PREFIX
+ + "c++", sourceExtensions, headerExtensions, false,
+ new GccCCompiler(CMD_PREFIX + "c++", sourceExtensions,
+ headerExtensions, true, null, false, null), false, null);
+ private static final GccCCompiler g77Instance = new GccCCompiler(CMD_PREFIX
+ + "g77", sourceExtensions, headerExtensions, false,
+ new GccCCompiler(CMD_PREFIX + "g77", sourceExtensions,
+ headerExtensions, true, null, false, null), false, null);
+ private static final GccCCompiler gppInstance = new GccCCompiler(CMD_PREFIX
+ + "g++", sourceExtensions, headerExtensions, false,
+ new GccCCompiler(CMD_PREFIX + "g++", sourceExtensions,
+ headerExtensions, true, null, false, null), false, null);
+ private static final GccCCompiler instance = new GccCCompiler(CMD_PREFIX
+ + "gcc", sourceExtensions, headerExtensions, false,
+ new GccCCompiler(CMD_PREFIX + "gcc", sourceExtensions,
+ headerExtensions, true, null, false, null), false, null);
+ /**
+ * Gets c++ adapter
+ */
+ public static GccCCompiler getCppInstance() {
+ return cppInstance;
+ }
+ /**
+ * Gets g77 adapter
+ */
+ public static GccCCompiler getG77Instance() {
+ return g77Instance;
+ }
+ /**
+ * Gets gpp adapter
+ */
+ public static GccCCompiler getGppInstance() {
+ return gppInstance;
+ }
+ /**
+ * Gets gcc adapter
+ */
+ public static GccCCompiler getInstance() {
+ return instance;
+ }
+ private String identifier;
+ private File[] includePath;
+ private boolean isPICMeaningful = true;
+ /**
+ * Private constructor. Use GccCCompiler.getInstance() to get singleton
+ * instance of this class.
+ */
+ private GccCCompiler(String command, String[] sourceExtensions,
+ String[] headerExtensions, boolean isLibtool,
+ GccCCompiler libtoolCompiler, boolean newEnvironment,
+ Environment env) {
+ super(command, null, sourceExtensions, headerExtensions, isLibtool,
+ libtoolCompiler, newEnvironment, env);
+ isPICMeaningful = System.getProperty("os.name").indexOf("Windows") < 0;
+ }
+ public void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ super.addImpliedArgs(args, debug, multithreaded,
+ exceptions, linkType, rtti, optimization);
+ if (isPICMeaningful && linkType.isSharedLibrary()) {
+ args.addElement("-fPIC");
+ }
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new GccCCompiler(getCommand(), this.getSourceExtensions(),
+ this.getHeaderExtensions(), this.getLibtool(),
+ (GccCCompiler) this.getLibtoolCompiler(), newEnvironment,
+ env);
+ }
+ return this;
+ }
+ /**
+ * Create parser to determine dependencies.
+ *
+ * Will create appropriate parser (C++, FORTRAN) based on file extension.
+ *
+ */
+ protected Parser createParser(File source) {
+ if (source != null) {
+ String sourceName = source.getName();
+ int lastDot = sourceName.lastIndexOf('.');
+ if (lastDot >= 0 && lastDot + 1 < sourceName.length()) {
+ char afterDot = sourceName.charAt(lastDot + 1);
+ if (afterDot == 'f' || afterDot == 'F') {
+ return new FortranParser();
+ }
+ }
+ }
+ return new CParser();
+ }
+ public File[] getEnvironmentIncludePath() {
+ if (includePath == null) {
+ //
+ // construct default include path from machine id and version id
+ //
+ String[] defaultInclude = new String[1];
+ StringBuffer buf = new StringBuffer("/lib/");
+ buf.append(GccProcessor.getMachine());
+ buf.append('/');
+ buf.append(GccProcessor.getVersion());
+ buf.append("/include");
+ defaultInclude[0] = buf.toString();
+ //
+ // read specs file and look for -istart and -idirafter
+ //
+ String[] specs = GccProcessor.getSpecs();
+ String[][] optionValues = GccProcessor.parseSpecs(specs, "*cpp:",
+ new String[]{"-isystem ", "-idirafter "});
+ //
+ // if no entries were found, then use a default path
+ //
+ if (optionValues[0].length == 0 && optionValues[1].length == 0) {
+ optionValues[0] = new String[]{"/usr/local/include",
+ "/usr/include", "/usr/include/win32api"};
+ }
+ //
+ // remove mingw entries.
+ // For MinGW compiles this will mean the
+ // location of the sys includes will be
+ // wrong in dependencies.xml
+ // but that should have no significant effect
+ for (int i = 0; i < optionValues.length; i++) {
+ for (int j = 0; j < optionValues[i].length; j++) {
+ if (optionValues[i][j].indexOf("mingw") > 0) {
+ optionValues[i][j] = null;
+ }
+ }
+ }
+ //
+ // if cygwin then
+ // we have to prepend location of gcc32
+ // and .. to start of absolute filenames to
+ // have something that will exist in the
+ // windows filesystem
+ if (GccProcessor.isCygwin()) {
+ GccProcessor.convertCygwinFilenames(optionValues[0]);
+ GccProcessor.convertCygwinFilenames(optionValues[1]);
+ GccProcessor.convertCygwinFilenames(defaultInclude);
+ }
+ int count = CUtil.checkDirectoryArray(optionValues[0]);
+ count += CUtil.checkDirectoryArray(optionValues[1]);
+ count += CUtil.checkDirectoryArray(defaultInclude);
+ includePath = new File[count];
+ int index = 0;
+ for (int i = 0; i < optionValues.length; i++) {
+ for (int j = 0; j < optionValues[i].length; j++) {
+ if (optionValues[i][j] != null) {
+ includePath[index++] = new File(optionValues[i][j]);
+ }
+ }
+ }
+ for (int i = 0; i < defaultInclude.length; i++) {
+ if (defaultInclude[i] != null) {
+ includePath[index++] = new File(defaultInclude[i]);
+ }
+ }
+ }
+ return (File[]) includePath.clone();
+ }
+ public String getIdentifier() throws BuildException {
+ if (identifier == null) {
+ StringBuffer buf;
+ if (getLibtool()) {
+ buf = new StringBuffer("libtool ");
+ } else {
+ buf = new StringBuffer(' ');
+ }
+ buf.append(getCommand());
+ buf.append(' ');
+ buf.append(GccProcessor.getVersion());
+ buf.append(' ');
+ buf.append(GccProcessor.getMachine());
+ identifier = buf.toString();
+ }
+ return identifier;
+ }
+ public Linker getLinker(LinkType linkType) {
+ return GccLinker.getInstance().getLinker(linkType);
+ }
+ public int getMaximumCommandLength() {
+ return Integer.MAX_VALUE;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLibrarian.java
new file mode 100644
index 0000000..779fb3d
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLibrarian.java
@@ -0,0 +1,43 @@
+/*
+ *
+ * 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.gcc.cross.sparc_sun_solaris2;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.gcc.AbstractArLibrarian;
+/**
+ * Adapter for the 'ar' archiver
+ *
+ * @author Adam Murdoch
+ */
+public final class GccLibrarian extends AbstractArLibrarian {
+ private static String[] objFileExtensions = new String[]{".o"};
+ private static GccLibrarian instance = new GccLibrarian(
+ GccCCompiler.CMD_PREFIX + "ar", objFileExtensions, false,
+ new GccLibrarian(GccCCompiler.CMD_PREFIX + "ar", objFileExtensions,
+ true, null));
+ public static GccLibrarian getInstance() {
+ return instance;
+ }
+ private GccLibrarian(String command, String[] inputExtensions,
+ boolean isLibtool, GccLibrarian libtoolLibrarian) {
+ super(command, "V", inputExtensions, new String[0], "lib", ".a",
+ isLibtool, libtoolLibrarian);
+ }
+ public Linker getLinker(LinkType type) {
+ return GccLinker.getInstance().getLinker(type);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLinker.java
new file mode 100644
index 0000000..d7dd3db
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLinker.java
@@ -0,0 +1,215 @@
+/*
+ *
+ * Copyright 2001-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.gcc.cross.sparc_sun_solaris2;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;
+/**
+ * Adapter for the GCC linker
+ *
+ * @author Adam Murdoch
+ */
+public class GccLinker extends AbstractLdLinker {
+ private static final String[] discardFiles = new String[0];
+ private static final String[] objFiles = new String[]{".o", ".a", ".lib",
+ ".dll", ".so", ".sl"};
+ private static final String[] libtoolObjFiles = new String[]{".fo", ".a",
+ ".lib", ".dll", ".so", ".sl"};
+ private static String[] linkerOptions = new String[]{"-bundle",
+ "-dynamiclib", "-nostartfiles", "-nostdlib", "-prebind", "-s",
+ "-static", "-shared", "-symbolic", "-Xlinker",
+ "--export-all-symbols", "-static-libgcc",};
+ private static final GccLinker dllLinker = new GccLinker(
+ GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib",
+ ".so", false, new GccLinker(GccCCompiler.CMD_PREFIX + "gcc",
+ objFiles, discardFiles, "lib", ".so", true, null));
+ private static final GccLinker instance = new GccLinker(
+ GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "", "",
+ false, null);
+ private static final GccLinker machBundleLinker = new GccLinker(
+ GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib",
+ ".bundle", false, null);
+ private static final GccLinker machDllLinker = new GccLinker(
+ GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib",
+ ".dylib", false, null);
+ public static GccLinker getInstance() {
+ return instance;
+ }
+ private File[] libDirs;
+ protected GccLinker(String command, String[] extensions,
+ String[] ignoredExtensions, String outputPrefix,
+ String outputSuffix, boolean isLibtool, GccLinker libtoolLinker) {
+ super(command, "-dumpversion", extensions, ignoredExtensions,
+ outputPrefix, outputSuffix, isLibtool, libtoolLinker);
+ }
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ super.addImpliedArgs(debug, linkType, args);
+ if (getIdentifier().indexOf("mingw") >= 0) {
+ if (linkType.isSubsystemConsole()) {
+ args.addElement("-mconsole");
+ }
+ if (linkType.isSubsystemGUI()) {
+ args.addElement("-mwindows");
+ }
+ }
+ }
+ /**
+ * Allows drived linker to decorate linker option. Override by GccLinker to
+ * prepend a "-Wl," to pass option to through gcc to linker.
+ *
+ * @param buf
+ * buffer that may be used and abused in the decoration process,
+ * must not be null.
+ * @param arg
+ * linker argument
+ */
+ public String decorateLinkerOption(StringBuffer buf, String arg) {
+ String decoratedArg = arg;
+ if (arg.length() > 1 && arg.charAt(0) == '-') {
+ switch (arg.charAt(1)) {
+ //
+ // passed automatically by GCC
+ //
+ case 'g' :
+ case 'f' :
+ case 'F' :
+ /* Darwin */
+ case 'm' :
+ case 'O' :
+ case 'W' :
+ case 'l' :
+ case 'L' :
+ case 'u' :
+ case 'v' :
+ break;
+ default :
+ boolean known = false;
+ for (int i = 0; i < linkerOptions.length; i++) {
+ if (linkerOptions[i].equals(arg)) {
+ known = true;
+ break;
+ }
+ }
+ if (!known) {
+ buf.setLength(0);
+ buf.append("-Wl,");
+ buf.append(arg);
+ decoratedArg = buf.toString();
+ }
+ break;
+ }
+ }
+ return decoratedArg;
+ }
+ /**
+ * Returns library path.
+ *
+ */
+ public File[] getLibraryPath() {
+ if (libDirs == null) {
+ //
+ // construct gcc lib path from machine and version
+ //
+ StringBuffer buf = new StringBuffer("/lib/gcc-lib/");
+ buf.append(GccProcessor.getMachine());
+ buf.append('/');
+ buf.append(GccProcessor.getVersion());
+ //
+ // build default path from gcc and system /lib and /lib/w32api
+ //
+ String[] impliedLibPath = new String[]{buf.toString(),
+ "/lib/w32api", "/lib"};
+ //
+ // read gcc specs file for other library paths
+ //
+ String[] specs = GccProcessor.getSpecs();
+ String[][] libpaths = GccProcessor.parseSpecs(specs, "*link:",
+ new String[]{"%q"});
+ String[] libpath;
+ if (libpaths[0].length > 0) {
+ libpath = new String[libpaths[0].length + 3];
+ int i = 0;
+ for (; i < libpaths[0].length; i++) {
+ libpath[i] = libpaths[0][i];
+ }
+ libpath[i++] = buf.toString();
+ libpath[i++] = "/lib/w32api";
+ libpath[i++] = "/lib";
+ } else {
+ //
+ // if a failure to find any matches then
+ // use some default values for lib path entries
+ libpath = new String[]{"/usr/local/lib/mingw",
+ "/usr/local/lib", "/usr/lib/w32api", "/usr/lib/mingw",
+ "/usr/lib", buf.toString(), "/lib/w32api", "/lib"};
+ }
+ for (int i = 0; i < libpath.length; i++) {
+ if (libpath[i].indexOf("mingw") >= 0) {
+ libpath[i] = null;
+ }
+ }
+ //
+ // if cygwin then
+ // we have to prepend location of gcc32
+ // and .. to start of absolute filenames to
+ // have something that will exist in the
+ // windows filesystem
+ if (GccProcessor.isCygwin()) {
+ GccProcessor.convertCygwinFilenames(libpath);
+ }
+ //
+ // check that remaining entries are actual directories
+ //
+ int count = CUtil.checkDirectoryArray(libpath);
+ //
+ // populate return array with remaining entries
+ //
+ libDirs = new File[count];
+ int index = 0;
+ for (int i = 0; i < libpath.length; i++) {
+ if (libpath[i] != null) {
+ libDirs[index++] = new File(libpath[i]);
+ }
+ }
+ }
+ return libDirs;
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return GccLibrarian.getInstance();
+ }
+ if (type.isPluginModule()) {
+ if (isDarwin()) {
+ return machBundleLinker;
+ } else {
+ return dllLinker;
+ }
+ }
+ if (type.isSharedLibrary()) {
+ if (isDarwin()) {
+ return machDllLinker;
+ } else {
+ return dllLinker;
+ }
+ }
+ return instance;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccProcessor.java
new file mode 100644
index 0000000..bbcd13d
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccProcessor.java
@@ -0,0 +1,305 @@
+/*
+ *
+ * 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.gcc.cross.sparc_sun_solaris2;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+
+/**
+ * A add-in class for Gcc processors
+ *
+ *
+ */
+public class GccProcessor {
+ // the results from gcc -dumpmachine
+ private static String machine;
+ private static String[] specs;
+ // the results from gcc -dumpversion
+ private static String version;
+ 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;
+ }
+ /**
+ * Converts absolute Cygwin file or directory names to the corresponding
+ * Win32 name.
+ *
+ * @param names
+ * array of names, some elements may be null, will be changed in
+ * place.
+ */
+ public static void convertCygwinFilenames(String[] names) {
+ if (names == null) {
+ throw new NullPointerException("names");
+ }
+ File gccDir = CUtil.getExecutableLocation(GccCCompiler.CMD_PREFIX
+ + "gcc.exe");
+ if (gccDir != null) {
+ String prefix = gccDir.getAbsolutePath() + "/..";
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < names.length; i++) {
+ String name = names[i];
+ if (name != null && name.length() > 1 && name.charAt(0) == '/') {
+ buf.setLength(0);
+ buf.append(prefix);
+ buf.append(name);
+ names[i] = buf.toString();
+ }
+ }
+ }
+ }
+ public static String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {
+ StringBuffer buf = new StringBuffer();
+ String[] patterns = new String[libnames.length * 2];
+ int offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0);
+ if (isHPUX()) {
+ offset = addLibraryPatterns(libnames, buf, "lib", ".sl", patterns,
+ offset);
+ } else {
+ offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns,
+ offset);
+ }
+ return patterns;
+ }
+ public static String getMachine() {
+ if (machine == null) {
+ String[] args = new String[]{GccCCompiler.CMD_PREFIX + "gcc",
+ "-dumpmachine"};
+ String[] cmdout = CaptureStreamHandler.run(args);
+ if (cmdout.length == 0) {
+ machine = "nomachine";
+ } else {
+ machine = cmdout[0];
+ }
+ }
+ return machine;
+ }
+ public static String[] getOutputFileSwitch(String letter, String outputFile) {
+ StringBuffer buf = new StringBuffer();
+ if (outputFile.indexOf(' ') >= 0) {
+ buf.append('"');
+ buf.append(outputFile.replace('\\', '/'));
+ buf.append('"');
+ } else {
+ buf.append(outputFile.replace('\\', '/'));
+ }
+ String[] retval = new String[]{letter, buf.toString()};
+ return retval;
+ }
+ /**
+ * Returns the contents of the gcc specs file.
+ *
+ * The implementation locates gcc.exe in the executable path and then
+ * builds a relative path name from the results of -dumpmachine and
+ * -dumpversion. Attempts to use gcc -dumpspecs to provide this information
+ * resulted in stalling on the Execute.run
+ *
+ * @return contents of the specs file
+ */
+ public static String[] getSpecs() {
+ if (specs == null) {
+ File gccParent = CUtil
+ .getExecutableLocation(GccCCompiler.CMD_PREFIX + "gcc.exe");
+ if (gccParent != null) {
+ //
+ // build a relative path like
+ // ../lib/gcc-lib/i686-pc-cygwin/2.95.3-5/specs
+ //
+ StringBuffer buf = new StringBuffer("../lib/gcc-lib/");
+ buf.append(getMachine());
+ buf.append('/');
+ buf.append(getVersion());
+ buf.append("/specs");
+ //
+ // resolve it relative to the location of gcc.exe
+ //
+ String relativePath = buf.toString();
+ File specsFile = new File(gccParent, relativePath);
+ //
+ // found the specs file
+ //
+ try {
+ //
+ // read the lines in the file
+ //
+ BufferedReader reader = new BufferedReader(new FileReader(
+ specsFile));
+ Vector lines = new Vector(100);
+ String line = reader.readLine();
+ while (line != null) {
+ lines.addElement(line);
+ line = reader.readLine();
+ }
+ specs = new String[lines.size()];
+ lines.copyInto(specs);
+ } catch (IOException ex) {
+ }
+ }
+ }
+ if (specs == null) {
+ specs = new String[0];
+ }
+ return specs;
+ }
+ public static String getVersion() {
+ if (version == null) {
+ String[] args = new String[]{GccCCompiler.CMD_PREFIX + "gcc",
+ "-dumpversion"};
+ String[] cmdout = CaptureStreamHandler.run(args);
+ if (cmdout.length == 0) {
+ version = "noversion";
+ } else {
+ version = cmdout[0];
+ }
+ }
+ return version;
+ }
+ public static boolean isCaseSensitive() {
+ return true;
+ }
+ /**
+ * Determines if task is running with cygwin
+ *
+ * @return true if cygwin was detected
+ */
+ public static boolean isCygwin() {
+ return getMachine().indexOf("cygwin") > 0;
+ }
+ private static boolean isHPUX() {
+ String osname = System.getProperty("os.name").toLowerCase();
+ if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) {
+ return true;
+ }
+ return false;
+ }
+ /**
+ *
+ * Parses the results of the specs file for a specific processor and
+ * options
+ *
+ * @param specsContent
+ * Contents of specs file as returned from getSpecs
+ * @param specSectionStart
+ * start of spec section, for example "*cpp:"
+ * @param options
+ * command line switches such as "-istart"
+ */
+ public static String[][] parseSpecs(String[] specsContent,
+ String specSectionStart, String[] options) {
+ if (specsContent == null) {
+ throw new NullPointerException("specsContent");
+ }
+ if (specSectionStart == null) {
+ throw new NullPointerException("specSectionStart");
+ }
+ if (options == null) {
+ throw new NullPointerException("option");
+ }
+ String[][] optionValues = new String[options.length][];
+ StringBuffer optionValue = new StringBuffer(40);
+ for (int i = 0; i < specsContent.length; i++) {
+ String specLine = specsContent[i];
+ //
+ // if start of section then start paying attention
+ //
+ if (specLine.startsWith(specSectionStart)) {
+ Vector[] optionVectors = new Vector[options.length];
+ for (int j = 0; j < options.length; j++) {
+ optionVectors[j] = new Vector(10);
+ }
+ //
+ // go to next line and examine contents
+ // and repeat until end of file
+ //
+ for (i++; i < specsContent.length; i++) {
+ specLine = specsContent[i];
+ for (int j = 0; j < options.length; j++) {
+ int optionStart = specLine.indexOf(options[j]);
+ while (optionStart >= 0) {
+ optionValue.setLength(0);
+ //
+ // walk rest of line looking for first non
+ // whitespace
+ // and then next space
+ boolean hasNonBlank = false;
+ int k = optionStart + options[j].length();
+ for (; k < specLine.length(); k++) {
+ //
+ // either a blank or a "}" (close of
+ // conditional)
+ // section will end the path
+ //
+ if (specLine.charAt(k) == ' '
+ || specLine.charAt(k) == '}') {
+ if (hasNonBlank) {
+ break;
+ }
+ } else {
+ hasNonBlank = true;
+ optionValue.append(specLine.charAt(k));
+ }
+ }
+ //
+ // transition back to whitespace
+ // value is over, add it to vector
+ if (hasNonBlank) {
+ optionVectors[j].addElement(optionValue
+ .toString());
+ }
+ //
+ // find next occurance on line
+ //
+ optionStart = specLine.indexOf(options[j], k);
+ }
+ }
+ }
+ //
+ // copy vectors over to option arrays
+ //
+ for (int j = 0; j < options.length; j++) {
+ optionValues[j] = new String[optionVectors[j].size()];
+ optionVectors[j].copyInto(optionValues[j]);
+ }
+ }
+ }
+ //
+ // fill in any missing option values with
+ // a zero-length string array
+ for (int i = 0; i < optionValues.length; i++) {
+ String[] zeroLenArray = new String[0];
+ if (optionValues[i] == null) {
+ optionValues[i] = zeroLenArray;
+ }
+ }
+ return optionValues;
+ }
+ private GccProcessor() {
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GppLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GppLinker.java
new file mode 100644
index 0000000..45bbea9
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GppLinker.java
@@ -0,0 +1,210 @@
+/*
+ *
+ * Copyright 2003-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.gcc.cross.sparc_sun_solaris2;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;
+import net.sf.antcontrib.cpptasks.types.LibrarySet;
+/**
+ * Adapter for the g++ variant of the GCC linker
+ *
+ * @author Stephen M. Webb <stephen.webb@bregmasoft.com>
+ */
+public class GppLinker extends AbstractLdLinker {
+ protected static final String[] discardFiles = new String[0];
+ protected static final String[] objFiles = new String[]{".o", ".a", ".lib",
+ ".dll", ".so", ".sl"};
+ private final static String libPrefix = "libraries: =";
+ protected static final String[] libtoolObjFiles = new String[]{".fo", ".a",
+ ".lib", ".dll", ".so", ".sl"};
+ private static String[] linkerOptions = new String[]{"-bundle", "-dylib",
+ "-dynamic", "-dynamiclib", "-nostartfiles", "-nostdlib",
+ "-prebind", "-s", "-static", "-shared", "-symbolic", "-Xlinker"};
+ private static final GppLinker dllLinker = new GppLinker(
+ GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib",
+ ".so", false, new GppLinker(GccCCompiler.CMD_PREFIX + "gcc",
+ objFiles, discardFiles, "lib", ".so", true, null));
+ private static final GppLinker instance = new GppLinker(
+ GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "", "",
+ false, null);
+ private static final GppLinker machDllLinker = new GppLinker(
+ GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib",
+ ".dylib", false, null);
+ private static final GppLinker machPluginLinker = new GppLinker(
+ GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib",
+ ".bundle", false, null);
+ public static GppLinker getInstance() {
+ return instance;
+ }
+ private File[] libDirs;
+ private String runtimeLibrary;
+ protected GppLinker(String command, String[] extensions,
+ String[] ignoredExtensions, String outputPrefix,
+ String outputSuffix, boolean isLibtool, GppLinker libtoolLinker) {
+ super(command, "-dumpversion", extensions, ignoredExtensions,
+ outputPrefix, outputSuffix, isLibtool, libtoolLinker);
+ }
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ super.addImpliedArgs(debug, linkType, args);
+ if (getIdentifier().indexOf("mingw") >= 0) {
+ if (linkType.isSubsystemConsole()) {
+ args.addElement("-mconsole");
+ }
+ if (linkType.isSubsystemGUI()) {
+ args.addElement("-mwindows");
+ }
+ }
+ if (linkType.isStaticRuntime()) {
+ String[] cmdin = new String[]{GccCCompiler.CMD_PREFIX + "g++",
+ "-print-file-name=libstdc++.a"};
+ String[] cmdout = CaptureStreamHandler.run(cmdin);
+ if (cmdout.length > 0) {
+ runtimeLibrary = cmdout[0];
+ } else {
+ runtimeLibrary = null;
+ }
+ } else {
+ runtimeLibrary = "-lstdc++";
+ }
+ }
+ public String[] addLibrarySets(CCTask task, LibrarySet[] libsets,
+ Vector preargs, Vector midargs, Vector endargs) {
+ String[] rs = super.addLibrarySets(task, libsets, preargs, midargs,
+ endargs);
+ if (runtimeLibrary != null) {
+ endargs.addElement(runtimeLibrary);
+ }
+ return rs;
+ }
+ /**
+ * Allows drived linker to decorate linker option. Override by GppLinker to
+ * prepend a "-Wl," to pass option to through gcc to linker.
+ *
+ * @param buf
+ * buffer that may be used and abused in the decoration process,
+ * must not be null.
+ * @param arg
+ * linker argument
+ */
+ public String decorateLinkerOption(StringBuffer buf, String arg) {
+ String decoratedArg = arg;
+ if (arg.length() > 1 && arg.charAt(0) == '-') {
+ switch (arg.charAt(1)) {
+ //
+ // passed automatically by GCC
+ //
+ case 'g' :
+ case 'f' :
+ case 'F' :
+ /* Darwin */
+ case 'm' :
+ case 'O' :
+ case 'W' :
+ case 'l' :
+ case 'L' :
+ case 'u' :
+ break;
+ default :
+ boolean known = false;
+ for (int i = 0; i < linkerOptions.length; i++) {
+ if (linkerOptions[i].equals(arg)) {
+ known = true;
+ break;
+ }
+ }
+ if (!known) {
+ buf.setLength(0);
+ buf.append("-Wl,");
+ buf.append(arg);
+ decoratedArg = buf.toString();
+ }
+ break;
+ }
+ }
+ return decoratedArg;
+ }
+ /**
+ * Returns library path.
+ *
+ */
+ public File[] getLibraryPath() {
+ if (libDirs == null) {
+ Vector dirs = new Vector();
+ // Ask GCC where it will look for its libraries.
+ String[] args = new String[]{GccCCompiler.CMD_PREFIX + "g++",
+ "-print-search-dirs"};
+ String[] cmdout = CaptureStreamHandler.run(args);
+ for (int i = 0; i < cmdout.length; ++i) {
+ int prefixIndex = cmdout[i].indexOf(libPrefix);
+ if (prefixIndex >= 0) {
+ // Special case DOS-type GCCs like MinGW or Cygwin
+ int s = prefixIndex + libPrefix.length();
+ int t = cmdout[i].indexOf(';', s);
+ while (t > 0) {
+ dirs.addElement(cmdout[i].substring(s, t));
+ s = t + 1;
+ t = cmdout[i].indexOf(';', s);
+ }
+ dirs.addElement(cmdout[i].substring(s));
+ ++i;
+ for (; i < cmdout.length; ++i) {
+ dirs.addElement(cmdout[i]);
+ }
+ }
+ }
+ // Eliminate all but actual directories.
+ String[] libpath = new String[dirs.size()];
+ dirs.copyInto(libpath);
+ int count = CUtil.checkDirectoryArray(libpath);
+ // Build return array.
+ libDirs = new File[count];
+ int index = 0;
+ for (int i = 0; i < libpath.length; ++i) {
+ if (libpath[i] != null) {
+ libDirs[index++] = new File(libpath[i]);
+ }
+ }
+ }
+ return libDirs;
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return GccLibrarian.getInstance();
+ }
+ if (type.isPluginModule()) {
+ if (GccProcessor.getMachine().indexOf("darwin") >= 0) {
+ return machPluginLinker;
+ } else {
+ return dllLinker;
+ }
+ }
+ if (type.isSharedLibrary()) {
+ if (GccProcessor.getMachine().indexOf("darwin") >= 0) {
+ return machDllLinker;
+ } else {
+ return dllLinker;
+ }
+ }
+ return instance;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/LdLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/LdLinker.java
new file mode 100644
index 0000000..0cc5fbf
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/LdLinker.java
@@ -0,0 +1,60 @@
+/*
+ *
+ * Copyright 2001-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.gcc.cross.sparc_sun_solaris2;
+import java.io.File;
+
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;
+/**
+ * Adapter for the 'ld' linker
+ *
+ * @author Curt Arnold
+ */
+public final class LdLinker extends AbstractLdLinker {
+ private static final String[] discardFiles = new String[0];
+ private static final String[] libtoolObjFiles = new String[]{".fo", ".a",
+ ".lib", ".dll", ".so", ".sl"};
+ private static final String[] objFiles = new String[]{".o", ".a", ".lib",
+ ".dll", ".so", ".sl"};
+ private static final LdLinker dllLinker = new LdLinker(
+ GccCCompiler.CMD_PREFIX + "ld", objFiles, discardFiles, "lib",
+ ".so", false, new LdLinker(GccCCompiler.CMD_PREFIX + "ld",
+ objFiles, discardFiles, "lib", ".so", true, null));
+ private static final LdLinker instance = new LdLinker(
+ GccCCompiler.CMD_PREFIX + "ld", objFiles, discardFiles, "", "",
+ false, null);
+ public static LdLinker getInstance() {
+ return instance;
+ }
+ private File[] libDirs;
+ private LdLinker(String command, String[] extensions,
+ String[] ignoredExtensions, String outputPrefix,
+ String outputSuffix, boolean isLibtool, LdLinker libtoolLinker) {
+ super(command, "-version", extensions, ignoredExtensions, outputPrefix,
+ outputSuffix, isLibtool, libtoolLinker);
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return GccLibrarian.getInstance();
+ }
+ if (type.isSharedLibrary()) {
+ return dllLinker;
+ }
+ return instance;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/hp/aCCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/hp/aCCCompiler.java
new file mode 100644
index 0000000..b978f67
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/hp/aCCCompiler.java
@@ -0,0 +1,116 @@
+/*
+ *
+ * Copyright 2001-2007 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.hp;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for the HP aC++ C++ compiler
+ *
+ * @author Curt Arnold
+ */
+public final class aCCCompiler extends GccCompatibleCCompiler {
+ private final static String[] headerExtensions = new String[]{".h", ".hpp",
+ ".inl"};
+ private final static String[] sourceExtensions = new String[]{".c", ".cc",
+ ".cxx", ".cpp", ".c++", ".i", ".s"};
+
+ private static final aCCCompiler instance = new aCCCompiler("aCC",
+ sourceExtensions, headerExtensions, false, null);
+ /**
+ * Gets singleton instance of this class
+ */
+ public static aCCCompiler getInstance() {
+ return instance;
+ }
+ private String identifier;
+ private File[] includePath;
+ /**
+ * Private constructor. Use GccCCompiler.getInstance() to get singleton
+ * instance of this class.
+ */
+ private aCCCompiler(String command, String[] sourceExtensions,
+ String[] headerExtensions, boolean newEnvironment,
+ Environment env) {
+ super(command, "-help", sourceExtensions, headerExtensions, false,
+ null, newEnvironment, env);
+ }
+ public void addImpliedArgs(Vector args, boolean debug,
+ boolean multithreaded, boolean exceptions, LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ args.addElement("-c");
+ if (debug) {
+ args.addElement("-g");
+ }
+ /*
+ * if (multithreaded) { args.addElement("-mt"); }
+ */
+
+ //
+ // per patch 1193690
+ //
+ if (linkType.isSharedLibrary() && (! args.contains("+Z"))) {
+ args.addElement("+z");
+ }
+ }
+ public void addWarningSwitch(Vector args, int level) {
+ switch (level) {
+ case 0 :
+ args.addElement("-w");
+ break;
+ case 1 :
+ case 2 :
+ args.addElement("+w");
+ break;
+ /*
+ * case 3: case 4: case 5: args.addElement("+w2"); break;
+ */
+ }
+ }
+ public File[] getEnvironmentIncludePath() {
+ if (includePath == null) {
+ File ccLoc = CUtil.getExecutableLocation("aCC");
+ if (ccLoc != null) {
+ File compilerIncludeDir = new File(
+ new File(ccLoc, "../include").getAbsolutePath());
+ if (compilerIncludeDir.exists()) {
+ includePath = new File[2];
+ includePath[0] = compilerIncludeDir;
+ }
+ }
+ if (includePath == null) {
+ includePath = new File[1];
+ }
+ includePath[includePath.length - 1] = new File("/usr/include");
+ }
+ return includePath;
+ }
+ public Linker getLinker(LinkType linkType) {
+ return aCCLinker.getInstance().getLinker(linkType);
+ }
+ public int getMaximumCommandLength() {
+ return Integer.MAX_VALUE;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/hp/aCCLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/hp/aCCLinker.java
new file mode 100644
index 0000000..94f7fc0
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/hp/aCCLinker.java
@@ -0,0 +1,100 @@
+/*
+ *
+ * Copyright 2001-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.hp;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;
+/**
+ * Adapter for Sun (r) Forte(tm) C++ Linker
+ *
+ * @author Curt Arnold
+ */
+public final class aCCLinker extends AbstractLdLinker {
+ private static final String[] discardFiles = new String[0];
+ private static final String[] objFiles = new String[]{".o", ".a", ".lib",
+ ".dll", ".so", ".sl"};
+ private static final aCCLinker arLinker = new aCCLinker("aCC", objFiles,
+ discardFiles, "", ".a");
+ private static final aCCLinker dllLinker = new aCCLinker("aCC", objFiles,
+ discardFiles, "lib", ".sl");
+ private static final aCCLinker instance = new aCCLinker("aCC", objFiles,
+ discardFiles, "", "");
+ public static aCCLinker getInstance() {
+ return instance;
+ }
+ private File[] libDirs;
+ private aCCLinker(String command, String[] extensions,
+ String[] ignoredExtensions, String outputPrefix, String outputSuffix) {
+ super(command, "-help", extensions, ignoredExtensions, outputPrefix,
+ outputSuffix, false, null);
+ }
+ public void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ if (debug) {
+ args.addElement("-g");
+ }
+ /*
+ * if(linkType.isStaticRuntime()) { args.addElement("-static"); }
+ */
+ if (linkType.isSharedLibrary()) {
+ args.addElement("-b");
+ }
+ /*
+ * if (linkType.isStaticLibrary()) { args.addElement("-Wl,-noshared"); }
+ */
+ }
+ public void addIncremental(boolean incremental, Vector args) {
+ /*
+ * if (incremental) { args.addElement("-xidlon"); } else {
+ * args.addElement("-xidloff"); }
+ */
+ }
+ /**
+ * Returns library path.
+ *
+ */
+ public File[] getLibraryPath() {
+ if (libDirs == null) {
+ File CCloc = CUtil.getExecutableLocation("aCC");
+ if (CCloc != null) {
+ File compilerLib = new File(new File(CCloc, "../lib")
+ .getAbsolutePath());
+ if (compilerLib.exists()) {
+ libDirs = new File[2];
+ libDirs[0] = compilerLib;
+ }
+ }
+ if (libDirs == null) {
+ libDirs = new File[1];
+ }
+ }
+ libDirs[libDirs.length - 1] = new File("/usr/lib");
+ return libDirs;
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return arLinker;
+ }
+ if (type.isSharedLibrary()) {
+ return dllLinker;
+ }
+ return instance;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ibm/VisualAgeCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/ibm/VisualAgeCCompiler.java
new file mode 100644
index 0000000..781b6de
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ibm/VisualAgeCCompiler.java
@@ -0,0 +1,118 @@
+/*
+ *
+ * Copyright 2001-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.ibm;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for the IBM(r) Visual Age(tm) C++ compiler for AIX(tm)
+ *
+ * @author Curt Arnold
+ */
+public final class VisualAgeCCompiler extends GccCompatibleCCompiler {
+ private final static String[] headerExtensions = new String[]{".h", ".hpp",
+ ".inl"};
+ private final static String[] sourceExtensions = new String[]{".c", ".cc",
+ ".cxx", ".cpp", ".i", ".s"};
+
+ private static final VisualAgeCCompiler instance = new VisualAgeCCompiler(
+ "xlC", sourceExtensions, headerExtensions, false, null);
+ /**
+ * Gets singleton instance of this class
+ */
+ public static VisualAgeCCompiler getInstance() {
+ return instance;
+ }
+ private String identifier;
+ private File[] includePath;
+ /**
+ * Private constructor. Use getInstance() to get singleton instance of this
+ * class.
+ */
+ private VisualAgeCCompiler(String command, String[] sourceExtensions,
+ String[] headerExtensions, boolean newEnvironment,
+ Environment env) {
+ super(command, "-help", sourceExtensions, headerExtensions, false,
+ null, newEnvironment, env);
+ }
+ public void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ args.addElement("-c");
+ if (debug) {
+ args.addElement("-g");
+ }
+ if (linkType.isSharedLibrary()) {
+ args.addElement("-fpic");
+ }
+ if (rtti != null) {
+ if (rtti.booleanValue()) {
+ args.addElement("-qrtti=all");
+ } else {
+ args.addElement("-qnortti");
+ }
+ }
+ }
+ public void addWarningSwitch(Vector args, int level) {
+ switch (level) {
+ case 0 :
+ args.addElement("-w");
+ break;
+ case 1 :
+ args.addElement("-qflag=s:s");
+ break;
+ case 2 :
+ args.addElement("-qflag=e:e");
+ break;
+ case 3 :
+ args.addElement("-qflag=w:w");
+ break;
+ case 4 :
+ args.addElement("-qflag=i:i");
+ break;
+ case 5 :
+ args.addElement("-qhalt=w:w");
+ break;
+ }
+ }
+ public Linker getLinker(LinkType linkType) {
+ return VisualAgeLinker.getInstance().getLinker(linkType);
+ }
+ public int getMaximumCommandLength() {
+ return Integer.MAX_VALUE;
+ }
+ /**
+ * Gets identifier for the compiler.
+ *
+ * Initial attempt at extracting version information
+ * would lock up. Using a stock response.
+ */
+ public String getIdentifier() {
+ return "VisualAge compiler - unidentified version";
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ibm/VisualAgeLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/ibm/VisualAgeLinker.java
new file mode 100644
index 0000000..59ad6a3
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ibm/VisualAgeLinker.java
@@ -0,0 +1,83 @@
+/*
+ *
+ * Copyright 2001-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.ibm;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;
+import net.sf.antcontrib.cpptasks.gcc.GccLibrarian;
+/**
+ * Adapter for IBM(r) Visual Age(tm) Linker for AIX(tm)
+ *
+ * @author Curt Arnold
+ */
+public final class VisualAgeLinker extends AbstractLdLinker {
+ private static final String[] discardFiles = new String[]{};
+ private static final String[] objFiles = new String[]{".o", ".a", ".lib",
+ ".dll", ".so", ".sl"};
+ private static final VisualAgeLinker dllLinker = new VisualAgeLinker(
+ "xlC", objFiles, discardFiles, "lib", ".a");
+ private static final VisualAgeLinker instance = new VisualAgeLinker("xlC",
+ objFiles, discardFiles, "", "");
+ public static VisualAgeLinker getInstance() {
+ return instance;
+ }
+ private VisualAgeLinker(String command, String[] extensions,
+ String[] ignoredExtensions, String outputPrefix, String outputSuffix) {
+ //
+ // just guessing that -? might display something useful
+ //
+ super(command, "-?", extensions, ignoredExtensions, outputPrefix,
+ outputSuffix, false, null);
+ }
+ public void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ if (debug) {
+ //args.addElement("-g");
+ }
+ if (linkType.isSharedLibrary()) {
+ args.addElement("-qmkshrobj");
+ }
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return GccLibrarian.getInstance();
+ }
+ if (type.isSharedLibrary()) {
+ return dllLinker;
+ }
+ return instance;
+ }
+ /**
+ * Gets identifier for the compiler.
+ *
+ * Initial attempt at extracting version information
+ * would lock up. Using a stock response.
+ */
+ public String getIdentifier() {
+ return "VisualAge linker - unidentified version";
+ }
+
+ protected String getDynamicLibFlag() {
+ return "-bdynamic";
+ }
+
+ protected String getStaticLibFlag() {
+ return "-bstatic";
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ide/CommentDef.java b/src/main/java/net/sf/antcontrib/cpptasks/ide/CommentDef.java
new file mode 100644
index 0000000..2221aba
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ide/CommentDef.java
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright 2008 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.ide;
+
+import org.apache.tools.ant.util.StringUtils;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Defines a comment to place in the generated project files.
+ *
+ */
+public final class CommentDef {
+ private String text;
+
+ public CommentDef() {
+ text = "";
+ }
+
+
+ public String getText() {
+ return text;
+ }
+ public void addText(final String newText) {
+ text += newText;
+ }
+
+ public String toString() {
+ return text;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ide/DebugDef.java b/src/main/java/net/sf/antcontrib/cpptasks/ide/DebugDef.java
new file mode 100644
index 0000000..8ddd04e
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ide/DebugDef.java
@@ -0,0 +1,127 @@
+/*
+*
+* Copyright 2004-2005 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.ide;
+
+import java.io.File;
+
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Environment;
+import org.apache.tools.ant.types.DataType;
+
+
+/**
+* Specifies a debugging configuration for a project.
+*
+* @author Curt Arnold
+*/
+public final class DebugDef
+ extends DataType {
+
+ /**
+ * Working directory for debug runs.
+ */
+ private File dir;
+ /**
+ * Name of executable.
+ */
+ private String executable;
+ /**
+ * Environment used to hold environment variables.
+ */
+ private Environment env = new Environment();
+ /**
+ * Command line used to hold command line arguments.
+ */
+ private Commandline cmdl = new Commandline();
+
+ /**
+ * Constructor.
+ *
+ */
+ public DebugDef() {
+ }
+
+
+ /**
+ * Set the name of the executable program.
+ * @param value the name of the executable program
+ */
+ public void setExecutable(final String value) {
+ this.executable = value;
+ }
+
+ /**
+ * Get the name of the executable program.
+ * @return the name of the executable program, may be null.
+ */
+ public String getExecutable() {
+ return executable;
+ }
+
+ /**
+ * Set the working directory of the process.
+ * @param d the working directory of the process
+ */
+ public void setDir(final File d) {
+ this.dir = d;
+ }
+
+ /**
+ * Get the working directory of the process.
+ * @return the working directory of the process, may be null.
+ */
+ public File getDir() {
+ return dir;
+ }
+
+ /**
+ * Add an environment variable.
+ *
+ * @param var new environment variable
+ */
+ public void addEnv(final Environment.Variable var) {
+ env.addVariable(var);
+ }
+
+ /**
+ * Get the variable list as an array.
+ * @return array of key=value assignment strings
+ */
+ public String[] getVariables() {
+ return env.getVariables();
+ }
+
+
+ /**
+ * Adds a command-line argument.
+ *
+ * @return new command line argument created
+ */
+ public Commandline.Argument createArg() {
+ return cmdl.createArgument();
+ }
+
+ /**
+ * Returns all arguments defined by <code>addLine</code>,
+ * <code>addValue</code> or the argument object.
+ * @return array of command line arguments, may be zero-length.
+ */
+ public String[] getArguments() {
+ return cmdl.getArguments();
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ide/DependencyDef.java b/src/main/java/net/sf/antcontrib/cpptasks/ide/DependencyDef.java
new file mode 100644
index 0000000..a04cad1
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ide/DependencyDef.java
@@ -0,0 +1,77 @@
+/*
+ *
+ * Copyright 2004-2006 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.ide;
+
+import org.apache.tools.ant.util.StringUtils;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Defines a dependency
+ *
+ */
+public final class DependencyDef {
+ private String id;
+ private File file;
+ private String name;
+ private String depends;
+
+ public DependencyDef() {
+ }
+
+
+ public void setID(final String val) {
+ id = val;
+ }
+ public File getFile() {
+ return file;
+ }
+ public void setFile(final File val) {
+ file = val;
+ }
+ public void setName(final String val) {
+ name = val;
+ }
+ public String getName() {
+ if (name != null) {
+ return name;
+ } else if(file != null) {
+ return file.getName();
+ }
+ return "null";
+ }
+ public String getID() {
+ if (id != null) {
+ return id;
+ }
+ return getName();
+ }
+ public String getDepends() {
+ return depends;
+ }
+ public void setDepends(final String val) {
+ depends = val;
+ }
+ public List getDependsList() {
+ if (depends != null) {
+ return StringUtils.split(depends, ',');
+ }
+ return Collections.EMPTY_LIST;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectDef.java b/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectDef.java
new file mode 100644
index 0000000..8883ebb
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectDef.java
@@ -0,0 +1,372 @@
+/*
+ *
+ * Copyright 2004-2008 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.ide;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.TargetInfo;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+/**
+ * Requests the creation of an IDE project file. Experimental.
+ *
+ * Implementation status: msdev5, msdev6 and cbuilderx
+ * generate reasonable project files for simple projects,
+ * xcode and msdev7 and msdev71 capture source file lists and
+ * a few settings.
+ *
+ * @author Curt Arnold
+ */
+public final class ProjectDef
+ extends DataType {
+ /**
+ * Name of property that must be present or definition will be ignored. May
+ * be null.
+ */
+ private String ifProp;
+
+ /**
+ * Name of property that must be absent or definition will be ignored. May
+ * be null.
+ */
+ private String unlessProp;
+
+ /**
+ * Project file name.
+ */
+ private File outFile;
+
+ /**
+ * Project name.
+ */
+ private String name;
+
+ /**
+ * Fail on error.
+ */
+ private boolean failOnError = true;
+
+ /**
+ * Overwrite existing project file.
+ */
+ private boolean overwrite = true;
+
+ /**
+ * Project writer.
+ */
+ private ProjectWriter projectWriter;
+
+ /**
+ * Object directory.
+ *
+ */
+ private File objDir;
+
+ /**
+ * List of dependency definitions.
+ */
+ private List dependencies = new ArrayList();
+
+ /**
+ * List of comments.
+ */
+ private List comments = new ArrayList();
+
+ /**
+ * Constructor.
+ *
+ */
+ public ProjectDef() {
+ }
+
+ /**
+ * Set project type.
+ *
+ *
+ * <table width="100%" border="1"> <thead>Supported project formats </thead>
+ * <tr>
+ * <td>cbuilderx</td>
+ * <td>Borland C++BuilderX</td>
+ * </tr>
+ * <tr>
+ * <td>msvc5</td>
+ * <td>Microsoft Visual C++ 97</td>
+ * </tr>
+ * <tr>
+ * <td>msvc6</td>
+ * <td>Microsoft Visual C++ 6</td>
+ * </tr>
+ * <tr>
+ * <td>msvc7</td>
+ * <td>Microsoft Visual C++.NET</td>
+ * </tr>
+ * <tr>
+ * <td>msvc71</td>
+ * <td>Microsoft Visual C++.NET 2003</td>
+ * </tr>
+ * <tr>
+ * <td>msvc8</td>
+ * <td>Microsoft Visual C++ 2005</td>
+ * </tr>
+ * <tr>
+ * <td>msvc9</td>
+ * <td>Microsoft Visual C++ 2008</td>
+ * </tr>
+ * <tr>
+ * <td>xcode</td>
+ * <td>Apple Xcode</td>
+ * </tr>
+ * </table>
+ *
+ * @param value new value
+ */
+ public void setType(final ProjectWriterEnum value) {
+ projectWriter = value.getProjectWriter();
+ }
+
+ /**
+ * Sets the name for the generated project file.
+ *
+ * @param outfile
+ * output file name
+ */
+ public void setOutfile(final File outfile) {
+ //
+ // if file name was empty, skip link step
+ //
+ if (outfile == null || outfile.toString().length() > 0) {
+ outFile = outfile;
+ }
+ }
+
+ /**
+ * Sets whether a failure to write the project file should cause the
+ * task to fail. Default is true.
+ *
+ * @param value new value
+ */
+ public void setFailonerror(final boolean value) {
+ failOnError = value;
+ }
+
+ /**
+ * Sets whether an existing project file should be overwritten,
+ * default is true. If false and the project file exists,
+ * the value of failonerror will determine if the task fails.
+ *
+ * @param value new value
+ */
+ public void setOverwrite(final boolean value) {
+ overwrite = value;
+ }
+
+ /**
+ * Gets whether an existing project file should be overwritten,
+ * default is true. If false and the project file exists,
+ * the value of failonerror will determine if the task fails.
+ *
+ * @return value
+ */
+ public boolean getOverwrite() {
+ return overwrite;
+ }
+
+ /**
+ * Determine if this def should be used.
+ *
+ * Definition will be active if the "if" variable (if specified) is set and
+ * the "unless" variable (if specified) is not set and that all reference
+ * or extended definitions are active
+ *
+ * @return true if processor is active
+ */
+ public boolean isActive() {
+ Project project = getProject();
+ if (!CUtil.isActive(project, ifProp, unlessProp)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Class name for a user-supplied project writer. Use the "type"
+ * attribute to specify built-in project writer implementations.
+ *
+ * @param className
+ * full class name
+ *
+ */
+ public void setClassname(final String className) {
+ Object proc = null;
+ try {
+ Class implClass = ProjectDef.class.getClassLoader().loadClass(
+ className);
+ try {
+ Method getInstance = implClass.getMethod("getInstance",
+ new Class[0]);
+ proc = getInstance.invoke(null, new Object[0]);
+ } catch (Exception ex) {
+ proc = implClass.newInstance();
+ }
+ } catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ projectWriter = (ProjectWriter) proc;
+ }
+
+ /**
+ * Sets the property name for the 'if' condition.
+ *
+ * The configuration will be ignored unless the property is defined.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") will throw an exception when
+ * evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public void setIf(final String propName) {
+ ifProp = propName;
+ }
+
+ /**
+ * Set the property name for the 'unless' condition.
+ *
+ * If named property is set, the configuration will be ignored.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") of the behavior will throw an
+ * exception when evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public void setUnless(final String propName) {
+ unlessProp = propName;
+ }
+
+ /**
+ * Get name.
+ * @return String name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Set name.
+ * @param value String name
+ */
+ public void setName(final String value) {
+ name = value;
+ }
+
+ /**
+ * Executes the task. Compiles the given files.
+ *
+ * @param task cc task
+ * @param sources source files (includes headers)
+ * @param targets compilation targets
+ * @param linkTarget link target
+ */
+ public void execute(final CCTask task,
+ final List sources,
+ final Hashtable targets,
+ final TargetInfo linkTarget) {
+ try {
+ projectWriter.writeProject(outFile,
+ task,
+ this,
+ sources,
+ targets,
+ linkTarget);
+ } catch (BuildException ex) {
+ if (failOnError) {
+ throw ex;
+ } else {
+ task.log(ex.toString());
+ }
+ } catch (Exception ex) {
+ if (failOnError) {
+ throw new BuildException(ex);
+ } else {
+ task.log(ex.toString());
+ }
+ }
+ }
+
+ /**
+ * Gets the object files directory.
+ * @return directory, may be null.
+ */
+ public File getObjdir() {
+ return objDir;
+ }
+ /**
+ * Sets the directory used for object files. If not specified,
+ * the object files directory from cc task will be used.
+ * @param oDir object file directory.
+ */
+ public void getObjdir(final File oDir) {
+ this.objDir = oDir;
+ }
+
+ /**
+ * Add a dependency definition to the project.
+ * @param dependency dependency.
+ */
+ public void addDependency(final DependencyDef dependency) {
+ dependencies.add(dependency);
+
+ }
+
+ public List getDependencies() {
+ return new ArrayList(dependencies);
+ }
+
+
+ /**
+ * Add comment for the generated project file.
+ * @param comment comment, may not be null.
+ */
+ public void addComment(final CommentDef comment) {
+ comments.add(comment);
+
+ }
+
+ public List getComments() {
+ return new ArrayList(comments);
+ }
+
+ /**
+ * Required by documentation generator.
+ */
+ public void execute() {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectWriter.java b/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectWriter.java
new file mode 100644
index 0000000..c4c144d
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectWriter.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.ide;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.List;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.TargetInfo;
+import org.xml.sax.SAXException;
+
+/**
+ * Project writer interface.
+ *
+ * @author curta
+ *
+ */
+public interface ProjectWriter {
+ /**
+ * Write project definition file.
+ * @param baseName File name base, writer may append appropriate extension
+ * @param task task
+ * @param projectDef project element
+ * @param files source and header files
+ * @param targets compilation targets
+ * @param linkTarget link target
+ * @throws IOException if I/O error is encountered
+ * @throws SAXException if I/O error during XML serialization
+ */
+ void writeProject(final File baseName,
+ final CCTask task,
+ final ProjectDef projectDef,
+ final List files,
+ final Hashtable targets,
+ final TargetInfo linkTarget)
+ throws IOException, SAXException;
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectWriterEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectWriterEnum.java
new file mode 100644
index 0000000..a50a7b2
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectWriterEnum.java
@@ -0,0 +1,105 @@
+/*
+ *
+ * Copyright 2004-2008 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.ide;
+
+import net.sf.antcontrib.cpptasks.apple.XcodeProjectWriter;
+import net.sf.antcontrib.cpptasks.borland.CBuilderXProjectWriter;
+import net.sf.antcontrib.cpptasks.devstudio.DevStudioProjectWriter;
+import net.sf.antcontrib.cpptasks.devstudio.VisualStudioNETProjectWriter;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+/**
+ * Enumeration of supported project file generators.
+ *
+ * <table width="100%" border="1"> <thead>Supported project generators </thead>
+ * <tr>
+ * <td>cbuilderx</td>
+ * <td>Borland C++BuilderX</td>
+ * </tr>
+ * <tr>
+ * <td>msvc5</td>
+ * <td>Microsoft Visual C++ 97</td>
+ * </tr>
+ * <tr>
+ * <td>msvc6</td>
+ * <td>Microsoft Visual C++ 6</td>
+ * </tr>
+ * <tr>
+ * <td>msvc7</td>
+ * <td>Microsoft Visual C++.NET</td>
+ * </tr>
+ * <tr>
+ * <td>msvc71</td>
+ * <td>Microsoft Visual C++.NET 2003</td>
+ * </tr>
+ * <tr>
+ * <td>msvc8</td>
+ * <td>Microsoft Visual C++ 2005</td>
+ * </tr>
+ * <tr>
+ * <td>msvc9</td>
+ * <td>Microsoft Visual C++ 2008</td>
+ * </tr>
+ * <tr>
+ * <td>xcode</td>
+ * <td>Apple Xcode</td>
+ * </tr>
+ * </table>
+ *
+ * @author Curt Arnold
+ *
+ */
+public final class ProjectWriterEnum
+ extends EnumeratedAttribute {
+ /**
+ * Enumeration values.
+ */
+ private static String[] values = new String[] {
+ "cbuilderx", "msvc5",
+ "msvc6", "msvc7", "msvc71", "msvc8", "msvc9", "xcode"};
+
+ /**
+ * Project writers associated with enumeration values.
+ */
+ private static ProjectWriter[] writers = new ProjectWriter[] {
+ new CBuilderXProjectWriter(), new DevStudioProjectWriter("5.00"),
+ new DevStudioProjectWriter("6.00"),
+ new VisualStudioNETProjectWriter("7.00", "TRUE", "FALSE"),
+ new VisualStudioNETProjectWriter("7.10", "TRUE", "FALSE"),
+ new VisualStudioNETProjectWriter("8.00", "true", "false"),
+ new VisualStudioNETProjectWriter("9.00", "true", "false"),
+ new XcodeProjectWriter()};
+
+ /**
+ * Gets ProjectWriter associated with enumeration value.
+ *
+ * @return project writer
+ */
+ public ProjectWriter getProjectWriter() {
+ return writers[this.getIndex()];
+ }
+
+ /**
+ * Gets acceptible values for enumeration.
+ *
+ * @return acceptible values
+ */
+ public String[] getValues() {
+ return (String[]) values.clone();
+ }
+}
+
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ide/package.html b/src/main/java/net/sf/antcontrib/cpptasks/ide/package.html
new file mode 100644
index 0000000..ed0de56
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ide/package.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+Copyright 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.
+
+-->
+</head>
+<body bgcolor="white">
+
+IDE project file generation.
+</body>
+</html>
+
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux32CCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux32CCompiler.java
new file mode 100644
index 0000000..12fd5bd
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux32CCompiler.java
@@ -0,0 +1,58 @@
+/*
+ *
+ * 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.intel;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler;
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for the Intel (r) C/C++ compiler for IA-32 Linux (r)
+ *
+ * The Intel (r) C/C++ compiler for IA32 Linux mimics the command options for
+ * gcc compiler.
+ *
+ * @author Curt Arnold
+ */
+public final class IntelLinux32CCompiler extends GccCompatibleCCompiler {
+ private static final IntelLinux32CCompiler instance = new IntelLinux32CCompiler(
+ false, new IntelLinux32CCompiler(true, null, false, null), false,
+ null);
+ public static IntelLinux32CCompiler getInstance() {
+ return instance;
+ }
+ private IntelLinux32CCompiler(boolean isLibtool,
+ IntelLinux32CCompiler libtoolCompiler, boolean newEnvironment,
+ Environment env) {
+ super("icc", "-V", isLibtool, libtoolCompiler, newEnvironment, env);
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new IntelLinux32CCompiler(getLibtool(),
+ (IntelLinux32CCompiler) getLibtoolCompiler(),
+ newEnvironment, env);
+ }
+ return this;
+ }
+ public Linker getLinker(LinkType type) {
+ return IntelLinux32Linker.getInstance().getLinker(type);
+ }
+ public int getMaximumCommandLength() {
+ return Integer.MAX_VALUE;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux32Linker.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux32Linker.java
new file mode 100644
index 0000000..9bed915
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux32Linker.java
@@ -0,0 +1,55 @@
+/*
+ *
+ * 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.intel;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;
+import net.sf.antcontrib.cpptasks.gcc.GccLibrarian;
+/**
+ * Adapter for the Intel (r) Linker for Linux (r) for IA-32
+ *
+ * @author Curt Arnold
+ */
+public final class IntelLinux32Linker extends AbstractLdLinker {
+ private static final String[] discardFiles = new String[0];
+ private static final String[] libtoolObjFiles = new String[]{".fo", ".a",
+ ".lib", ".dll", ".so", ".sl"};
+ private static final String[] objFiles = new String[]{".o", ".a", ".lib",
+ ".dll", ".so", ".sl"};
+ private static final IntelLinux32Linker dllLinker = new IntelLinux32Linker(
+ "lib", ".so", false, new IntelLinux32Linker("lib", ".so", true,
+ null));
+ private static final IntelLinux32Linker instance = new IntelLinux32Linker(
+ "", "", false, null);
+ public static IntelLinux32Linker getInstance() {
+ return instance;
+ }
+ private IntelLinux32Linker(String outputPrefix, String outputSuffix,
+ boolean isLibtool, IntelLinux32Linker libtoolLinker) {
+ super("icc", "-V", objFiles, discardFiles, outputPrefix, outputSuffix,
+ isLibtool, libtoolLinker);
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return GccLibrarian.getInstance();
+ }
+ if (type.isSharedLibrary()) {
+ return dllLinker;
+ }
+ return instance;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux64CCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux64CCompiler.java
new file mode 100644
index 0000000..9ed6393
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux64CCompiler.java
@@ -0,0 +1,58 @@
+/*
+ *
+ * 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.intel;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler;
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for the Intel (r) C/C++ compiler for IA-64 Linux (r)
+ *
+ * The Intel C/C++ compiler for IA-64 Linux mimics the command options for gcc
+ * compiler.
+ *
+ * @author Curt Arnold
+ */
+public final class IntelLinux64CCompiler extends GccCompatibleCCompiler {
+ private static final IntelLinux64CCompiler instance = new IntelLinux64CCompiler(
+ false, new IntelLinux64CCompiler(true, null, false, null), false,
+ null);
+ public static IntelLinux64CCompiler getInstance() {
+ return instance;
+ }
+ private IntelLinux64CCompiler(boolean isLibtool,
+ IntelLinux64CCompiler libtoolCompiler, boolean newEnvironment,
+ Environment env) {
+ super("ecc", "-V", isLibtool, libtoolCompiler, newEnvironment, env);
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new IntelLinux64CCompiler(getLibtool(),
+ (IntelLinux64CCompiler) this.getLibtoolCompiler(),
+ newEnvironment, env);
+ }
+ return this;
+ }
+ public Linker getLinker(LinkType type) {
+ return IntelLinux64Linker.getInstance().getLinker(type);
+ }
+ public int getMaximumCommandLength() {
+ return Integer.MAX_VALUE;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux64Linker.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux64Linker.java
new file mode 100644
index 0000000..d712e5b
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux64Linker.java
@@ -0,0 +1,55 @@
+/*
+ *
+ * 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.intel;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;
+import net.sf.antcontrib.cpptasks.gcc.GccLibrarian;
+/**
+ * Adapter for the Intel (r) linker for Linux for IA-64
+ *
+ * @author Curt Arnold
+ */
+public final class IntelLinux64Linker extends AbstractLdLinker {
+ private static final String[] discardFiles = new String[0];
+ private static final String[] libtoolObjFiles = new String[]{".fo", ".a",
+ ".lib", ".dll", ".so", ".sl"};
+ private static final String[] objFiles = new String[]{".o", ".a", ".lib",
+ ".dll", ".so", ".sl"};
+ private static final IntelLinux64Linker dllLinker = new IntelLinux64Linker(
+ "lib", ".so", false, new IntelLinux64Linker("lib", ".so", true,
+ null));
+ private static final IntelLinux64Linker instance = new IntelLinux64Linker(
+ "", "", false, null);
+ public static IntelLinux64Linker getInstance() {
+ return instance;
+ }
+ private IntelLinux64Linker(String outputPrefix, String outputSuffix,
+ boolean isLibtool, IntelLinux64Linker libtoolLinker) {
+ super("ecc", "-V", objFiles, discardFiles, outputPrefix, outputSuffix,
+ isLibtool, libtoolLinker);
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return GccLibrarian.getInstance();
+ }
+ if (type.isSharedLibrary()) {
+ return dllLinker;
+ }
+ return instance;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelProcessor.java
new file mode 100644
index 0000000..ed7c61a
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelProcessor.java
@@ -0,0 +1,51 @@
+/*
+ *
+ * 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.intel;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.devstudio.DevStudioProcessor;
+/**
+ * A add-in class for Intel (r) compilers and linkers
+ *
+ *
+ */
+public class IntelProcessor {
+ public static void addWarningSwitch(Vector args, int level) {
+ DevStudioProcessor.addWarningSwitch(args, level);
+ }
+ public static String getCommandFileSwitch(String cmdFile) {
+ return DevStudioProcessor.getCommandFileSwitch(cmdFile);
+ }
+ public static void getDefineSwitch(StringBuffer buffer, String define,
+ String value) {
+ DevStudioProcessor.getDefineSwitch(buffer, define, value);
+ }
+ public static String getIncludeDirSwitch(String includeDir) {
+ return DevStudioProcessor.getIncludeDirSwitch(includeDir);
+ }
+ public static String[] getOutputFileSwitch(String outPath) {
+ return DevStudioProcessor.getOutputFileSwitch(outPath);
+ }
+ public static void getUndefineSwitch(StringBuffer buffer, String define) {
+ DevStudioProcessor.getUndefineSwitch(buffer, define);
+ }
+ public static boolean isCaseSensitive() {
+ return false;
+ }
+ private IntelProcessor() {
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32CCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32CCompiler.java
new file mode 100644
index 0000000..80ade19
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32CCompiler.java
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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.intel;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.devstudio.DevStudioCompatibleCCompiler;
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for the Intel (r) C++ compiler for 32-bit applications
+ *
+ * The Intel (r) C++ compiler for IA32 Windows mimics the command options for
+ * the Microsoft (r) C++ compiler.
+ *
+ * @author Curt Arnold
+ */
+public final class IntelWin32CCompiler extends DevStudioCompatibleCCompiler {
+ private static final IntelWin32CCompiler instance = new IntelWin32CCompiler(
+ false, null);
+ public static IntelWin32CCompiler getInstance() {
+ return instance;
+ }
+ private IntelWin32CCompiler(boolean newEnvironment, Environment env) {
+ super("icl", "-help", newEnvironment, env);
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new IntelWin32CCompiler(newEnvironment, env);
+ }
+ return this;
+ }
+ public Linker getLinker(LinkType type) {
+ return IntelWin32Linker.getInstance().getLinker(type);
+ }
+ public int getMaximumCommandLength() {
+ return 32767;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32Librarian.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32Librarian.java
new file mode 100644
index 0000000..e9473d5
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32Librarian.java
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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.intel;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.devstudio.DevStudioCompatibleLibrarian;
+/**
+ * Adapter for the xilib from the Intel(r) C++ Compiler for IA-32 or IA-64
+ * systems running Microsoft (r) operating systems
+ *
+ * @author Curt Arnold
+ */
+public class IntelWin32Librarian extends DevStudioCompatibleLibrarian {
+ private static final IntelWin32Librarian instance = new IntelWin32Librarian();
+ public static IntelWin32Librarian getInstance() {
+ return instance;
+ }
+ protected IntelWin32Librarian() {
+ super("xilib", "-qv");
+ }
+ public Linker getLinker(LinkType type) {
+ return IntelWin32Linker.getInstance().getLinker(type);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32Linker.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32Linker.java
new file mode 100644
index 0000000..66009f0
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32Linker.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.intel;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.devstudio.DevStudioCompatibleLinker;
+/**
+ * Adapter for the Intel (r) linker for 32-bit applications
+ *
+ * @author Curt Arnold
+ */
+public final class IntelWin32Linker extends DevStudioCompatibleLinker {
+ private static final IntelWin32Linker dllLinker = new IntelWin32Linker(
+ ".dll");
+ private static final IntelWin32Linker instance = new IntelWin32Linker(
+ ".exe");
+ public static IntelWin32Linker getInstance() {
+ return instance;
+ }
+ private IntelWin32Linker(String outputSuffix) {
+ super("xilink", "-qv", outputSuffix);
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return IntelWin32Librarian.getInstance();
+ }
+ if (type.isSharedLibrary()) {
+ return dllLinker;
+ }
+ return instance;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin64CCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin64CCompiler.java
new file mode 100644
index 0000000..6344022
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin64CCompiler.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.intel;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.devstudio.DevStudioCompatibleCCompiler;
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for the Intel C++ compiler for Itanium(TM) Applications
+ *
+ * @author Curt Arnold
+ */
+public final class IntelWin64CCompiler extends DevStudioCompatibleCCompiler {
+ private static final IntelWin64CCompiler instance = new IntelWin64CCompiler(
+ false, null);
+ public static IntelWin64CCompiler getInstance() {
+ return instance;
+ }
+ private IntelWin64CCompiler(boolean newEnvironment, Environment env) {
+ super("ecl", "-help", newEnvironment, env);
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new IntelWin64CCompiler(newEnvironment, env);
+ }
+ return this;
+ }
+ public Linker getLinker(LinkType type) {
+ //
+ // currently the Intel Win32 and Win64 linkers
+ // are command line equivalent
+ return IntelWin32Linker.getInstance().getLinker(type);
+ }
+ public int getMaximumCommandLength() {
+ return 32767;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/mozilla/XpidlCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/mozilla/XpidlCompiler.java
new file mode 100644
index 0000000..32eb9ec
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/mozilla/XpidlCompiler.java
@@ -0,0 +1,365 @@
+/*
+ *
+ * Copyright 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.mozilla;
+
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.compiler.ProgressMonitor;
+import net.sf.antcontrib.cpptasks.gcc.LdLinker;
+import net.sf.antcontrib.cpptasks.parser.CParser;
+import net.sf.antcontrib.cpptasks.parser.Parser;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Environment;
+
+/**
+ * Adapter for the Mozilla Xpidl Compiler.
+ *
+ * @author Curt Arnold
+ */
+public final class XpidlCompiler
+ extends CommandLineCompiler {
+ /**
+ * Singleton instance.
+ */
+ private static final XpidlCompiler INSTANCE = new XpidlCompiler(
+ false, null);
+ /**
+ * Gets singleton instance of compiler.
+ * @return XpidlCompiler singleton instance
+ */
+ public static XpidlCompiler getInstance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Constructor.
+ * @param newEnvironment boolean establish an new environment.
+ * @param env Environment environment.
+ */
+ private XpidlCompiler(final boolean newEnvironment,
+ final Environment env) {
+ super("xpidl", null, new String[] {".idl", ".xpidl"}
+ , new String[0], ".xpt", false, null, newEnvironment, env);
+ }
+
+ /**
+ * Add arguments for debug, etc.
+ * @param args Vector command argument list
+ * @param debug boolean build for debug if true
+ * @param multithreaded boolean build for multithreading if true
+ * @param exceptions boolean enable exceptions if true
+ * @param linkType LinkType output and runtime type
+ * @param rtti Boolean enable run-time type identification if true
+ * @param optimization OptimizationEnum optimization
+ */
+ protected void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ }
+
+ /**
+ * Add arguments for specified warning level.
+ * @param args Vector command line arguments
+ * @param level int warning level value
+ */
+ protected void addWarningSwitch(final Vector args,
+ final int level) {
+ }
+
+ /**
+ * Change enviroment (deprecated).
+ * @param newEnvironment boolean use new environment.
+ * @param env Environment environment
+ * @return Processor modified processor
+ */
+ public Processor changeEnvironment(final boolean newEnvironment,
+ final Environment env) {
+ return this;
+ }
+
+ /**
+ * Gets dependency parser.
+ * @param source source file
+ * @return parser
+ */
+ protected Parser createParser(final File source) {
+ return new CParser();
+ }
+
+ /**
+ * Gets number of command line arguments per input file.
+ * @return int number of command line arguments per input file.
+ */
+ protected int getArgumentCountPerInputFile() {
+ return 3;
+ }
+
+ /**
+ * Gets output file names.
+ * @param inputFile String input file name
+ * @param versionInfo version info, not used by this compiler.
+ * @return String[] output file names
+ */
+ public String[] getOutputFileNames(final String inputFile,
+ final VersionInfo versionInfo) {
+ //
+ // if a recognized input file
+ //
+ String baseName = getBaseOutputName(inputFile);
+ return new String[] {
+ baseName + ".xpt",
+ baseName + ".h"};
+ }
+
+ /**
+ * Gets input file arguments.
+ * @param outputDir File output directory
+ * @param filename String input file name.
+ * @param index int argument index,
+ * 0 to getNumberOfArgumentsPerInputFile() -1
+ * @return String input file argument
+ */
+ protected String getInputFileArgument(final File outputDir,
+ final String filename,
+ final int index) {
+ return "";
+ }
+
+ /**
+ * Gets maximum length of command line.
+ * @return int maximum length of command line
+ */
+ public int getMaximumCommandLength() {
+ return 1024;
+ }
+
+ /**
+ * Gets maximum number of input files processed per command.
+ * @return int maximum number of input files processed per command.
+ */
+ protected int getMaximumInputFilesPerCommand() {
+ return 1;
+ }
+
+ /**
+ * Adds command line arguments for include paths.
+ *
+ * @param baseDirPath String base directory
+ * @param includeDirs File[] include directories
+ * @param args Vector command line arguments
+ * @param relativeArgs Vector arguments for configuration identification
+ * @param includePathId StringBuffer buffer for configuration identification
+ */
+ protected void addIncludes(final String baseDirPath,
+ final File[] includeDirs,
+ final Vector args,
+ final Vector relativeArgs,
+ final StringBuffer includePathId) {
+ //
+ // requires space between switch and path
+ //
+ for (int i = 0; i < includeDirs.length; i++) {
+ args.addElement("-I");
+ args.addElement(includeDirs[i].getAbsolutePath());
+ if (relativeArgs != null) {
+ String relative = CUtil.getRelativePath(baseDirPath,
+ includeDirs[i]);
+ relativeArgs.addElement("-I");
+ relativeArgs.addElement(relative);
+ if (includePathId != null) {
+ if (includePathId.length() == 0) {
+ includePathId.append("-I ");
+ } else {
+ includePathId.append(" -I ");
+ }
+ includePathId.append(relative);
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets include directory switch.
+ * @param includeDir String include directory
+ * @return String command switch to add specified directory to search path
+ */
+ protected String getIncludeDirSwitch(final String includeDir) {
+ return "-I" + includeDir;
+ }
+
+ /**
+ * Gets switch to define preprocessor macro.
+ * @param buffer StringBuffer command line argument
+ * @param define String macro name
+ * @param value String macro value, may be null.
+ */
+ protected void getDefineSwitch(final StringBuffer buffer,
+ final String define,
+ final String value) {
+ }
+
+ /**
+ * Gets switch to undefine preprocessor macro.
+ * @param buffer StringBuffer command line argument
+ * @param define String macro name
+ */
+ protected void getUndefineSwitch(final StringBuffer buffer,
+ final String define) {
+ }
+
+ /**
+ * Gets standard include paths.
+ * @return File[] standard include paths
+ */
+ protected File[] getEnvironmentIncludePath() {
+ return new File[0];
+ }
+
+ /**
+ * Gets linker associated with this type.
+ * @param type LinkType linker, returns ld.
+ * @return Linker
+ */
+ public Linker getLinker(final LinkType type) {
+ return LdLinker.getInstance();
+ }
+
+ /**
+ * Compiles an .idl file into the corresponding .h and .xpt files.
+ * @param task current cc task
+ * @param outputDir output directory
+ * @param sourceFiles source files
+ * @param args command line arguments that appear before input files
+ * @param endArgs command line arguments that appear after input files
+ * @param relentless if true, do not stop at first compilation error
+ * @param config compiler configuration
+ * @param monitor progress monitor
+ */
+ public void compile(final CCTask task,
+ final File outputDir,
+ final String[] sourceFiles,
+ final String[] args,
+ final String[] endArgs,
+ final boolean relentless,
+ final CommandLineCompilerConfiguration config,
+ final ProgressMonitor monitor) {
+
+ BuildException exc = null;
+ String[] thisSource = new String[1];
+ String[] tlbCommand = new String[args.length + endArgs.length + 6];
+ tlbCommand[0] = "xpidl";
+ tlbCommand[1] = "-m";
+ tlbCommand[2] = "typelib";
+ String[] headerCommand = new String[args.length + endArgs.length + 6];
+ headerCommand[0] = "xpidl";
+ headerCommand[1] = "-m";
+ headerCommand[2] = "header";
+ for (int i = 0; i < args.length; i++) {
+ tlbCommand[i + 3] = args[i];
+ headerCommand[i + 3] = args[i];
+ }
+ tlbCommand[args.length + 3] = "-e";
+ headerCommand[args.length + 3] = "-e";
+
+ int tlbIndex = args.length + 6;
+ int headerIndex = args.length + 6;
+ for (int i = 0; i < endArgs.length; i++) {
+ tlbCommand[tlbIndex++] = endArgs[i];
+ headerCommand[headerIndex++] = endArgs[i];
+ }
+ for (int j = 0; j < sourceFiles.length; j++) {
+ tlbIndex = args.length + 4;
+ headerIndex = args.length + 4;
+ String[] outputFileNames = getOutputFileNames(sourceFiles[j], null);
+
+ tlbCommand[tlbIndex++] = outputFileNames[0];
+ tlbCommand[tlbIndex++] = sourceFiles[j];
+
+ headerCommand[headerIndex++] = outputFileNames[1];
+ headerCommand[headerIndex++] = sourceFiles[j];
+
+ int retval = runCommand(task, outputDir, tlbCommand);
+ if (retval == 0) {
+ retval = runCommand(task, outputDir, headerCommand);
+ }
+ if (monitor != null) {
+ thisSource[0] = sourceFiles[j];
+ monitor.progress(thisSource);
+ }
+ //
+ // if the process returned a failure code and
+ // we aren't holding an exception from an earlier
+ // interation
+ if (retval != 0 && exc == null) {
+ //
+ // construct the exception
+ //
+ exc = new BuildException(this.getCommand()
+ + " failed with return code " + retval, task
+ .getLocation());
+ //
+ // and throw it now unless we are relentless
+ //
+ if (!relentless) {
+ throw exc;
+ }
+ }
+ }
+ //
+ // if the compiler returned a failure value earlier
+ // then throw an exception
+ if (exc != null) {
+ throw exc;
+ }
+ }
+
+ /**
+ * Get total command line length due to the input file.
+ * @param outputDir File output directory
+ * @param inputFile String input file
+ * @return int characters added to command line for the input file.
+ */
+ protected int getTotalArgumentLengthForInputFile(
+ final File outputDir,
+ final String inputFile) {
+ return 0;
+ }
+
+ /**
+ * Gets compiler identifier.
+ * @return String compiler identification string
+ */
+ public String getIdentifier() {
+ return "Mozilla xpidl";
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/mozilla/package.html b/src/main/java/net/sf/antcontrib/cpptasks/mozilla/package.html
new file mode 100644
index 0000000..6be6dff
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/mozilla/package.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+Copyright 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.
+
+-->
+</head>
+<body bgcolor="white">
+
+Compiler adapter for Mozilla's XPCOM compiler.
+</body>
+</html>
+
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCCompiler.java
new file mode 100644
index 0000000..4c36438
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCCompiler.java
@@ -0,0 +1,84 @@
+/*
+ *
+ * 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.openwatcom;
+
+import java.io.File;
+
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.parser.CParser;
+import net.sf.antcontrib.cpptasks.parser.Parser;
+
+import org.apache.tools.ant.types.Environment;
+
+/**
+ * Adapter for the OpenWatcom C Compiler.
+ *
+ * @author Curt Arnold
+ */
+public final class OpenWatcomCCompiler
+ extends OpenWatcomCompiler {
+ /**
+ * Singleton.
+ */
+ private static final OpenWatcomCCompiler INSTANCE = new OpenWatcomCCompiler(
+ "wcl386",
+ false, null);
+
+ /**
+ * Get compiler.
+ * @return OpenWatcomCCompiler compiler
+ */
+ public static OpenWatcomCCompiler getInstance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Constructor.
+ * @param command String command
+ * @param newEnvironment boolean use new environment
+ * @param env Environment environment
+ */
+ private OpenWatcomCCompiler(final String command,
+ final boolean newEnvironment,
+ final Environment env) {
+ super(command, "/?",
+ new String[] {".c", ".cc", ".cpp", ".cxx", ".c++"}
+ ,
+ new String[] {".h", ".hpp", ".inl"}
+ ,
+ newEnvironment, env);
+ }
+
+ /**
+ * Create parser.
+ * @param source File file to be parsed.
+ * @return Parser parser
+ */
+ public Parser createParser(final File source) {
+ return new CParser();
+ }
+
+ /**
+ * Get linker.
+ * @param type link type
+ * @return linker
+ */
+ public Linker getLinker(final LinkType type) {
+ return OpenWatcomCLinker.getInstance().getLinker(type);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCLinker.java
new file mode 100644
index 0000000..93e65b4
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCLinker.java
@@ -0,0 +1,69 @@
+/*
+ *
+ * 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.openwatcom;
+
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+
+/**
+ * Adapter for the OpenWatcom linker.
+ *
+ * @author Curt Arnold
+ */
+public final class OpenWatcomCLinker
+ extends OpenWatcomLinker {
+ /**
+ * Dll linker.
+ */
+ private static final OpenWatcomCLinker DLL_LINKER =
+ new OpenWatcomCLinker(".dll");
+ /**
+ * Exe linker.
+ */
+ private static final OpenWatcomCLinker INSTANCE =
+ new OpenWatcomCLinker(".exe");
+ /**
+ * Get linker instance.
+ * @return OpenWatcomCLinker linker
+ */
+ public static OpenWatcomCLinker getInstance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Constructor.
+ * @param outputSuffix String output suffix.
+ */
+ private OpenWatcomCLinker(final String outputSuffix) {
+ super("wcl386", outputSuffix);
+ }
+
+ /**
+ * Get linker.
+ * @param type LinkType link type
+ * @return Linker linker
+ */
+ public Linker getLinker(final LinkType type) {
+ if (type.isStaticLibrary()) {
+ return OpenWatcomLibrarian.getInstance();
+ }
+ if (type.isSharedLibrary()) {
+ return DLL_LINKER;
+ }
+ return INSTANCE;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCompiler.java
new file mode 100644
index 0000000..4cf2d18
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCompiler.java
@@ -0,0 +1,169 @@
+/*
+ *
+ * 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.openwatcom;
+
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+
+import org.apache.tools.ant.types.Environment;
+
+/**
+ * An abstract base class for the OpenWatcom C and Fortran compilers.
+ *
+ * @author Curt Arnold
+ */
+public abstract class OpenWatcomCompiler
+ extends CommandLineCompiler {
+ /**
+ * Constructor.
+ * @param command String command
+ * @param identifierArg String identifier
+ * @param sourceExtensions String[] source extension
+ * @param headerExtensions String[] header extension
+ * @param newEnvironment boolean use new enviroment
+ * @param env Environment environment
+ */
+ protected OpenWatcomCompiler(final String command,
+ final String identifierArg,
+ final String[] sourceExtensions,
+ final String[] headerExtensions,
+ final boolean newEnvironment,
+ final Environment env) {
+ super(command, identifierArg, sourceExtensions,
+ headerExtensions, ".obj", false,
+ null, newEnvironment, env);
+ }
+
+ /**
+ * Add implied arguments.
+ * @param args Vector command line arguments
+ * @param debug boolean is debug
+ * @param multithreaded boolean multithreaderd
+ * @param exceptions boolean support exceptions
+ * @param linkType LinkType link type
+ * @param rtti Boolean run time type information
+ * @param optimization OptimizationEnum
+ */
+ protected final void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ args.addElement("/c");
+ if (exceptions) {
+ args.addElement("/xs");
+ }
+ if (multithreaded) {
+ args.addElement("/bm");
+ }
+ if (debug) {
+ args.addElement("/d2");
+ args.addElement("/od");
+ args.addElement("/d_DEBUG");
+ } else {
+ if (optimization != null) {
+ if (optimization.isSize()) {
+ args.addElement("/os");
+ }
+ if (optimization.isSpeed()) {
+ args.addElement("/ot");
+ }
+ }
+ args.addElement("/dNDEBUG");
+ }
+ if (rtti != null && rtti.booleanValue()) {
+ args.addElement("/xr");
+ }
+ }
+
+ /**
+ * Add warning switch.
+ * @param args Vector command line arguments
+ * @param level int warning level
+ */
+ protected final void addWarningSwitch(final Vector args, final int level) {
+ OpenWatcomProcessor.addWarningSwitch(args, level);
+ }
+
+ /**
+ * Change enviroment.
+ * @param newEnvironment boolean use new enviroment
+ * @param env Environment environment
+ * @return Processor modified processor
+ */
+ public final Processor changeEnvironment(final boolean newEnvironment,
+ final Environment env) {
+ return this;
+ }
+
+ /**
+ * Get define switch.
+ * @param buffer StringBuffer buffer
+ * @param define String preprocessor macro
+ * @param value String value, may be null.
+ */
+ protected final void getDefineSwitch(final StringBuffer buffer,
+ final String define,
+ final String value) {
+ OpenWatcomProcessor.getDefineSwitch(buffer, define, value);
+ }
+
+ /**
+ * Get include path from environment.
+ * @return File[]
+ */
+ protected final File[] getEnvironmentIncludePath() {
+ return CUtil.getPathFromEnvironment("INCLUDE", ";");
+ }
+
+ /**
+ * Get include directory switch.
+ * @param includeDir String include directory
+ * @return String command line argument
+ */
+ protected final String getIncludeDirSwitch(final String includeDir) {
+ return OpenWatcomProcessor.getIncludeDirSwitch(includeDir);
+ }
+
+
+ /**
+ * Get maximum command line length.
+ * @return int maximum command line length
+ */
+ public final int getMaximumCommandLength() {
+ return 4096;
+ }
+
+ /**
+ * Get undefine switch.
+ * @param buffer StringBuffer argument destination
+ * @param define String preprocessor macro
+ */
+ protected final void getUndefineSwitch(final StringBuffer buffer,
+ final String define) {
+ OpenWatcomProcessor.getUndefineSwitch(buffer, define);
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomFortranCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomFortranCompiler.java
new file mode 100644
index 0000000..ca3abcb
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomFortranCompiler.java
@@ -0,0 +1,86 @@
+/*
+ *
+ * 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.openwatcom;
+
+import java.io.File;
+
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.parser.FortranParser;
+import net.sf.antcontrib.cpptasks.parser.Parser;
+
+import org.apache.tools.ant.types.Environment;
+
+/**
+ * Adapter for the OpenWatcom Fortran compiler.
+ *
+ * @author Curt Arnold
+ */
+public final class OpenWatcomFortranCompiler
+ extends OpenWatcomCompiler {
+ /**
+ * Singleton.
+ */
+ private static final OpenWatcomFortranCompiler[] INSTANCE =
+ new OpenWatcomFortranCompiler[] {
+ new OpenWatcomFortranCompiler(
+ "wfl386", false, null)};
+
+ /**
+ * Get instance.
+ * @return OpenWatcomFortranCompiler compiler instance
+ */
+ public static OpenWatcomFortranCompiler getInstance() {
+ return INSTANCE[0];
+ }
+
+ /**
+ * Constructor.
+ * @param command String command
+ * @param newEnvironment boolean use new environment
+ * @param env Environment environment
+ */
+ private OpenWatcomFortranCompiler(final String command,
+ final boolean newEnvironment,
+ final Environment env) {
+ super(command, "/?",
+ new String[] {".f90", ".for", ".f"}
+ ,
+ new String[] {".i", ".i90", ".fpp"}
+ ,
+ newEnvironment, env);
+ }
+
+ /**
+ * Create dependency parser.
+ * @param source File source file
+ * @return Parser parser
+ */
+ public Parser createParser(final File source) {
+ return new FortranParser();
+ }
+
+ /**
+ * Get linker.
+ * @param type link type
+ * @return linker
+ */
+ public Linker getLinker(final LinkType type) {
+ return OpenWatcomFortranLinker.getInstance().getLinker(type);
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomFortranLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomFortranLinker.java
new file mode 100644
index 0000000..82b6999
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomFortranLinker.java
@@ -0,0 +1,69 @@
+/*
+ *
+ * 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.openwatcom;
+
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+
+/**
+ * Adapter for the OpenWatcom Fortran linker.
+ *
+ * @author Curt Arnold
+ */
+public final class OpenWatcomFortranLinker
+ extends OpenWatcomLinker {
+ /**
+ * Singleton for DLL linking.
+ */
+ private static final OpenWatcomFortranLinker DLL_LINKER = new
+ OpenWatcomFortranLinker(".dll");
+ /**
+ * Singleton for executables.
+ */
+ private static final OpenWatcomFortranLinker INSTANCE = new
+ OpenWatcomFortranLinker(".exe");
+ /**
+ * Get instance.
+ * @return OpenWatcomFortranLinker linker
+ */
+ public static OpenWatcomFortranLinker getInstance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Constructor.
+ * @param outputSuffix String output suffix
+ */
+ private OpenWatcomFortranLinker(final String outputSuffix) {
+ super("wfl386", outputSuffix);
+ }
+
+ /**
+ * Get linker.
+ * @param type LinkType link type
+ * @return Linker linker
+ */
+ public Linker getLinker(final LinkType type) {
+ if (type.isStaticLibrary()) {
+ return OpenWatcomLibrarian.getInstance();
+ }
+ if (type.isSharedLibrary()) {
+ return DLL_LINKER;
+ }
+ return INSTANCE;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomLibrarian.java
new file mode 100644
index 0000000..848c395
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomLibrarian.java
@@ -0,0 +1,254 @@
+/*
+ *
+ * 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.openwatcom;
+
+import java.io.File;
+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.LibraryTypeEnum;
+
+/**
+ * Adapter for the OpenWatcom Librarian.
+ *
+ * @author Curt Arnold
+ */
+public final class OpenWatcomLibrarian
+ extends CommandLineLinker {
+ /**
+ * Singleton.
+ */
+ private static final OpenWatcomLibrarian INSTANCE = new OpenWatcomLibrarian();
+ /**
+ * Singleton accessor.
+ * @return OpenWatcomLibrarian librarian instance
+ */
+ public static OpenWatcomLibrarian getInstance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Constructor.
+ */
+ private OpenWatcomLibrarian() {
+ super("wlib", null, new String[] {".obj"}
+ , new String[0], ".lib", false,
+ null);
+ }
+
+ /**
+ * Add base address.
+ * @param base long base address
+ * @param args Vector command line arguments
+ */
+ protected void addBase(final long base, final Vector args) {
+ }
+
+ /**
+ * Add alternative entry point.
+ * @param entry String entry point
+ * @param args Vector command line arguments
+ */
+ protected void addEntry(final String entry, final Vector args) {
+ }
+
+ /**
+ * Add fixed parameter.
+ * @param fixed Boolean true if fixed
+ * @param args Vector command line arguments
+ */
+ protected void addFixed(final Boolean fixed, final Vector args) {
+ }
+
+ /**
+ * Add implied arguments.
+ * @param debug boolean true if debugging
+ * @param linkType LinkType link type
+ * @param args Vector command line arguments
+ */
+ protected void addImpliedArgs(final boolean debug,
+ final LinkType linkType,
+ final Vector args) {
+ }
+
+ /**
+ * Add incremental option.
+ * @param incremental boolean true if incremental
+ * @param args Vector command line arguments
+ */
+ protected void addIncremental(final boolean incremental,
+ final Vector args) {
+ }
+
+ /**
+ * Add map option.
+ * @param map boolean true to create map file
+ * @param args Vector command line argument
+ */
+ protected void addMap(final boolean map,
+ final Vector args) {
+ }
+
+ /**
+ * Add stack size option.
+ * @param stack int stack size
+ * @param args Vector command line arguments
+ */
+ protected void addStack(final int stack,
+ final Vector args) {
+ }
+
+ /**
+ * Get command file switch.
+ * @param cmdFile String command file
+ * @return String command file switch
+ */
+ protected String getCommandFileSwitch(final String cmdFile) {
+ return OpenWatcomProcessor.getCommandFileSwitch(cmdFile);
+ }
+
+
+ /**
+ * Get library search path.
+ * @return File[] library search path
+ */
+ public File[] getLibraryPath() {
+ return CUtil.getPathFromEnvironment("LIB", ";");
+ }
+
+ /**
+ * Get file selectors for specified library names.
+ * @param libnames String[] library names
+ * @param libType LibraryTypeEnum library type enum
+ * @return String[] file selection patterns
+ */
+ public String[] getLibraryPatterns(final String[] libnames,
+ final LibraryTypeEnum libType) {
+ return OpenWatcomProcessor.getLibraryPatterns(libnames, libType);
+ }
+
+ /**
+ * Get linker.
+ * @param type LinkType link type
+ * @return Linker linker
+ */
+ public Linker getLinker(final LinkType type) {
+ return OpenWatcomCLinker.getInstance().getLinker(type);
+ }
+
+ /**
+ * Gets maximum command line.
+ * @return int maximum command line
+ */
+ public int getMaximumCommandLength() {
+ return 1024;
+ }
+
+ /**
+ * Create output file switch.
+ * @param outFile String output file switch
+ * @return String[] output file switch
+ */
+ public String[] getOutputFileSwitch(final String outFile) {
+ return OpenWatcomProcessor.getOutputFileSwitch(outFile);
+ }
+
+ /**
+ * Gets case-sensisitivity of processor.
+ * @return boolean true if case sensitive
+ */
+ public boolean isCaseSensitive() {
+ return OpenWatcomProcessor.isCaseSensitive();
+ }
+
+ /**
+ * Builds a library.
+ * @param task task
+ * @param outputFile generated library
+ * @param sourceFiles object files
+ * @param config linker configuration
+ */
+ public void link(final CCTask task,
+ final File outputFile,
+ final String[] sourceFiles,
+ final CommandLineLinkerConfiguration config) {
+ //
+ // delete any existing library
+ outputFile.delete();
+ //
+ // build a new library
+ super.link(task, outputFile, sourceFiles, config);
+ }
+
+ /**
+ * Prepares argument list for exec command.
+ * @param task task
+ * @param outputDir output directory
+ * @param outputName output file name
+ * @param sourceFiles object files
+ * @param config linker configuration
+ * @return arguments for runTask
+ */
+ protected String[] prepareArguments(
+ final CCTask task,
+ final String outputDir,
+ final String outputName,
+ final String[] sourceFiles,
+ final CommandLineLinkerConfiguration config) {
+ String[] preargs = config.getPreArguments();
+ String[] endargs = config.getEndArguments();
+ StringBuffer buf = new StringBuffer();
+ Vector execArgs = new Vector(preargs.length + endargs.length + 10
+ + sourceFiles.length);
+
+ execArgs.addElement(this.getCommand());
+ String outputFileName = new File(outputDir, outputName).toString();
+ execArgs.addElement(quoteFilename(buf, outputFileName));
+
+ for (int i = 0; i < preargs.length; i++) {
+ execArgs.addElement(preargs[i]);
+ }
+
+ int objBytes = 0;
+
+ for (int i = 0; i < sourceFiles.length; i++) {
+ String last4 = sourceFiles[i]
+ .substring(sourceFiles[i].length() - 4).toLowerCase();
+ if (!last4.equals(".def")
+ && !last4.equals(".res")
+ && !last4.equals(".lib")) {
+ execArgs.addElement("+" + quoteFilename(buf, sourceFiles[i]));
+ objBytes += new File(sourceFiles[i]).length();
+ }
+ }
+
+ for (int i = 0; i < endargs.length; i++) {
+ execArgs.addElement(endargs[i]);
+ }
+
+ String[] execArguments = new String[execArgs.size()];
+ execArgs.copyInto(execArguments);
+
+ return execArguments;
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomLinker.java
new file mode 100644
index 0000000..f0bbe3d
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomLinker.java
@@ -0,0 +1,205 @@
+/*
+ *
+ * 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.openwatcom;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.TargetMatcher;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.platforms.WindowsPlatform;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+
+/**
+ * Adapter for the OpenWatcom linker.
+ *
+ * @author Curt Arnold
+ */
+public abstract class OpenWatcomLinker
+ extends CommandLineLinker {
+ /**
+ * Constructor.
+ * @param command String command string (wcl386 or wfl386)
+ * @param outputSuffix String output suffix
+ */
+ protected OpenWatcomLinker(final String command,
+ final String outputSuffix) {
+ super(command, "-r", new String[] {".obj", ".lib", ".res"}
+ ,
+ new String[] {".map", ".pdb", ".lnk"}
+ , outputSuffix, false, null);
+ }
+
+ /**
+ * Add specified base address to linker options.
+ * @param base long base address
+ * @param args Vector command options
+ */
+ protected final void addBase(final long base, final Vector args) {
+ }
+
+ /**
+ * Adds non-default entry point.
+ * @param entry entry point name
+ * @param args command line parameters
+ */
+ protected final void addEntry(final String entry, final Vector args) {
+ }
+
+ /**
+ * Adds fixed option.
+ * @param fixed if executable is fixed
+ * @param args command line parameters
+ */
+ protected final void addFixed(final Boolean fixed, final Vector args) {
+ }
+
+ /**
+ * Adds other command line parameters.
+ * @param debug boolean is debug
+ * @param linkType LinkType link type
+ * @param args Vector command line arguments
+ */
+ protected final void addImpliedArgs(final boolean debug,
+ final LinkType linkType,
+ final Vector args) {
+ if (linkType.isExecutable()) {
+ if (linkType.isSubsystemConsole()) {
+ args.addElement("/bc");
+ } else {
+ if (linkType.isSubsystemGUI()) {
+ args.addElement("/bg");
+ }
+ }
+ }
+ if (linkType.isSharedLibrary()) {
+ args.addElement("/bd");
+ }
+ }
+
+ /**
+ * Add command line switch to force incremental linking.
+ * @param incremental boolean do incremental linking
+ * @param args Vector command line arguments
+ */
+ protected final void addIncremental(final boolean incremental,
+ final Vector args) {
+ }
+
+ /**
+ * Add command line switch to force map generation.
+ * @param map boolean build map
+ * @param args Vector command line arguments
+ */
+ protected final void addMap(final boolean map, final Vector args) {
+ if (map) {
+ args.addElement("/fm");
+ }
+ }
+
+ /**
+ * Add command line switch for stack reservation.
+ * @param stack int stack size.
+ * @param args Vector command line arguments.
+ */
+ protected final void addStack(final int stack, final Vector args) {
+ if (stack >= 0) {
+ String stackStr = Integer.toString(stack);
+ args.addElement("/k" + stackStr);
+ }
+ }
+
+ /**
+ * Adds source or object files to the bidded fileset to
+ * support version information.
+ *
+ * @param versionInfo version information
+ * @param linkType link type
+ * @param isDebug true if debug build
+ * @param outputFile name of generated executable
+ * @param objDir directory for generated files
+ * @param matcher bidded fileset
+ * @throws IOException if unable to write version resource
+ */
+ public final void addVersionFiles(final VersionInfo versionInfo,
+ final LinkType linkType,
+ final File outputFile,
+ final boolean isDebug,
+ final File objDir,
+ final TargetMatcher matcher) throws IOException {
+ WindowsPlatform.addVersionFiles(versionInfo, linkType, outputFile, isDebug,
+ objDir, matcher);
+ }
+
+ /**
+ * Get command file switch.
+ * @param commandFile String command file name
+ * @return String command line option
+ */
+ public final String getCommandFileSwitch(final String commandFile) {
+ return "@" + commandFile;
+ }
+
+ /**
+ * Get search path for libraries.
+ * @return File[] library path
+ */
+ public final File[] getLibraryPath() {
+ return CUtil.getPathFromEnvironment("LIB", ";");
+ }
+
+ /**
+ * Get file selectors for libraries.
+ * @param libnames String[]
+ * @param libType LibraryTypeEnum
+ * @return String[]
+ */
+ public final String[] getLibraryPatterns(final String[] libnames,
+ final LibraryTypeEnum libType) {
+ return OpenWatcomProcessor.getLibraryPatterns(libnames, libType);
+ }
+
+ /**
+ * Get maximum command line length.
+ * @return int command line length
+ */
+ public final int getMaximumCommandLength() {
+ return 1024;
+ }
+
+ /**
+ * Get output file switch.
+ * @param outFile Output file name
+ * @return String[] command line switches
+ */
+ public final String[] getOutputFileSwitch(final String outFile) {
+ return OpenWatcomProcessor.getOutputFileSwitch(outFile);
+ }
+
+ /**
+ * Gets file name sensitivity of processors.
+ * @return boolean true if case sensitive.
+ */
+ public final boolean isCaseSensitive() {
+ return OpenWatcomProcessor.isCaseSensitive();
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomProcessor.java
new file mode 100644
index 0000000..5845776
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomProcessor.java
@@ -0,0 +1,169 @@
+/*
+ *
+ * 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.openwatcom;
+
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+
+/**
+ * A add-in class for OpenWatcom processors.
+ *
+ *
+ */
+public final class OpenWatcomProcessor {
+ /**
+ * Adds warning command line options.
+ *
+ * @param args Vector list of options
+ * @param level int value of WarningLevelEnum
+ */
+ public static void addWarningSwitch(final Vector args, final int level) {
+ switch (level) {
+ case 0:
+ args.addElement("/w0");
+ break;
+ case 1:
+ args.addElement("/w1");
+ break;
+ case 2:
+ break;
+ case 3:
+ args.addElement("/w2");
+ break;
+ case 4:
+ args.addElement("/w3");
+ break;
+ case 5:
+ args.addElement("/we");
+ break;
+ default:
+ args.addElement("/w1");
+ break;
+ }
+ }
+
+ /**
+ * Gets command line option to read from an option file.
+ *
+ * @param cmdFile String file name for option file
+ * @return String Command line option
+ */
+ public static String getCommandFileSwitch(final String cmdFile) {
+ StringBuffer buf = new StringBuffer("@");
+ if (cmdFile.indexOf(' ') >= 0) {
+ buf.append('\"');
+ buf.append(cmdFile.replace('/', '\\'));
+ buf.append('\"');
+ } else {
+ buf.append(cmdFile);
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Creates a command line option to define a preprocessor macro.
+ *
+ * @param buffer StringBuffer destination buffer
+ * @param define String parameter to define
+ * @param value String value, may be null
+ */
+ public static void getDefineSwitch(final StringBuffer buffer,
+ final String define,
+ final String value) {
+ buffer.append("/d");
+ buffer.append(define);
+ if (value != null && value.length() > 0) {
+ buffer.append('=');
+ buffer.append(value);
+ }
+ }
+
+ /**
+ * Create a command line option to add a directory to the include path.
+ * @param includeDir String directory
+ * @return String command line option
+ */
+ public static String getIncludeDirSwitch(final String includeDir) {
+ return "/i=" + includeDir.replace('/', '\\');
+ }
+
+ /**
+ * Builds command line options to specify the output file names.
+ *
+ * @param outPath String path to output file
+ * @return String[] command line options
+ */
+ public static String[] getOutputFileSwitch(final String outPath) {
+ StringBuffer buf = new StringBuffer("/fo=");
+ if (outPath.indexOf(' ') >= 0) {
+ buf.append('\"');
+ buf.append(outPath);
+ buf.append('\"');
+ } else {
+ buf.append(outPath);
+ }
+ String[] retval = new String[] {
+ buf.toString()};
+ return retval;
+ }
+
+ /**
+ * Get file selectors for specified libraries.
+ * @param libnames library names
+ * @param libType library type
+ * @return file selectors
+ */
+ public static String[] getLibraryPatterns(final String[] libnames,
+ final LibraryTypeEnum libType) {
+ StringBuffer buf = new StringBuffer();
+ String[] patterns = new String[libnames.length];
+ for (int i = 0; i < libnames.length; i++) {
+ buf.setLength(0);
+ buf.append(libnames[i]);
+ buf.append(".lib");
+ patterns[i] = buf.toString();
+ }
+ return patterns;
+ }
+
+ /**
+ * Builds a command line option to undefine a preprocessor macro.
+ * @param buffer StringBuffer destination
+ * @param define String macro to be undefined
+ */
+ public static void getUndefineSwitch(final StringBuffer buffer,
+ final String define) {
+ buffer.append("/u");
+ buffer.append(define);
+ }
+
+ /**
+ * Gets whether processor tratement of file names is case-sensitive.
+ * @return boolean true if case sensitive
+ */
+ public static boolean isCaseSensitive() {
+ return false;
+ }
+
+ /**
+ * Private constructor.
+ */
+ private OpenWatcomProcessor() {
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/package.html b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/package.html
new file mode 100644
index 0000000..3d9adab
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/package.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+Copyright 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.
+
+-->
+</head>
+<body bgcolor="white">
+
+Adapters for OpenWatcom compilers and tools.
+</body>
+</html>
+
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390CCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390CCompiler.java
new file mode 100644
index 0000000..6b1895f
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390CCompiler.java
@@ -0,0 +1,156 @@
+/*
+ *
+ * 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.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.CompilerDef;
+import net.sf.antcontrib.cpptasks.compiler.AbstractCompiler;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.types.DefineArgument;
+import net.sf.antcontrib.cpptasks.types.UndefineArgument;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for the IBM (R) OS/390 (tm) C++ Compiler
+ *
+ * @author Hiram Chirino (cojonudo14@hotmail.com)
+ */
+public class OS390CCompiler extends CommandLineCCompiler {
+ private static final AbstractCompiler instance = new OS390CCompiler(false,
+ null);
+ public static AbstractCompiler getInstance() {
+ return instance;
+ }
+ private OS390CCompiler(boolean newEnvironment, Environment env) {
+ super("cxx", null, new String[]{".c", ".cc", ".cpp", ".cxx", ".c++",
+ ".s"}, new String[]{".h", ".hpp"}, ".o", false, null,
+ newEnvironment, env);
+ }
+ protected void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ // Specifies that only compilations and assemblies be done.
+ // Link-edit is not done
+ args.addElement("-c");
+ args.addElement("-W");
+ args.addElement("c,NOEXPMAC,NOSHOWINC");
+ /*
+ * if (exceptions) { args.addElement("/GX"); }
+ */
+ if (debug) {
+ args.addElement("-g");
+ args.addElement("-D");
+ args.addElement("_DEBUG");
+ /*
+ * if (multithreaded) { args.addElement("/D_MT"); if (staticLink) {
+ * args.addElement("/MTd"); } else { args.addElement("/MDd");
+ * args.addElement("/D_DLL"); } } else { args.addElement("/MLd"); }
+ */
+ } else {
+ args.addElement("-D");
+ args.addElement("NEBUG");
+ /*
+ * if (multithreaded) { args.addElement("/D_MT"); if (staticLink) {
+ * args.addElement("/MT"); } else { args.addElement("/MD");
+ * args.addElement("/D_DLL"); } } else { args.addElement("/ML"); }
+ */
+ }
+ }
+ protected void addWarningSwitch(Vector args, int level) {
+ OS390Processor.addWarningSwitch(args, level);
+ }
+ /**
+ * The buildDefineArguments implementation CommandLineCCompiler is not good
+ * for us because os390 defines are give by -D definex instead of
+ * /Ddefinex, 2 args not 1! since we implement this ourslefs, we do not
+ * have to implement the getDefineSwitch() and the getUndefineSwitch().
+ */
+ protected void buildDefineArguments(CompilerDef[] defs, Vector args) {
+ //
+ // assume that we aren't inheriting defines from containing <cc>
+ //
+ UndefineArgument[] merged = defs[0].getActiveDefines();
+ for (int i = 1; i < defs.length; i++) {
+ //
+ // if we are inheriting, merge the specific defines with the
+ // containing defines
+ merged = DefineArgument.merge(defs[i].getActiveDefines(), merged);
+ }
+ StringBuffer buf = new StringBuffer(30);
+ for (int i = 0; i < merged.length; i++) {
+ buf.setLength(0);
+ UndefineArgument current = merged[i];
+ if (current.isDefine()) {
+ args.addElement("-D");
+ buf.append(current.getName());
+ if (current.getValue() != null
+ && current.getValue().length() > 0) {
+ buf.append('=');
+ buf.append(current.getValue());
+ }
+ args.addElement(buf.toString());
+ } else {
+ args.addElement("-U");
+ args.addElement(current.getName());
+ }
+ }
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new OS390CCompiler(newEnvironment, env);
+ }
+ return this;
+ }
+ /*
+ * @see CommandLineCompiler#getDefineSwitch(StringBuffer, String, String)
+ */
+ protected void getDefineSwitch(StringBuffer buffer, String define,
+ String value) {
+ }
+ protected File[] getEnvironmentIncludePath() {
+ return CUtil.getPathFromEnvironment("INCLUDE", ":");
+ }
+ protected String getIncludeDirSwitch(String includeDir) {
+ return OS390Processor.getIncludeDirSwitch(includeDir);
+ }
+ public Linker getLinker(LinkType type) {
+ return OS390Linker.getInstance().getLinker(type);
+ }
+ public int getMaximumCommandLength() {
+ return Integer.MAX_VALUE;
+ }
+ /* Only compile one file at time for now */
+ protected int getMaximumInputFilesPerCommand() {
+ return Integer.MAX_VALUE;
+ }
+ /*
+ * @see CommandLineCompiler#getUndefineSwitch(StringBuffer, String)
+ */
+ protected void getUndefineSwitch(StringBuffer buffer, String define) {
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390Linker.java b/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390Linker.java
new file mode 100644
index 0000000..9c4f845
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390Linker.java
@@ -0,0 +1,208 @@
+/*
+ *
+ * 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;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390Processor.java b/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390Processor.java
new file mode 100644
index 0000000..d3243fc
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390Processor.java
@@ -0,0 +1,71 @@
+/*
+ *
+ * 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.util.Vector;
+/**
+ * A add-in class for IBM (r) OS/390 compilers and linkers
+ *
+ * @author Hiram Chirino (cojonudo14@hotmail.com)
+ */
+public class OS390Processor {
+ public static void addWarningSwitch(Vector args, int level) {
+ switch (level) {
+ /*
+ * case 0: args.addElement("/W0"); break;
+ *
+ * case 1: args.addElement("/W1"); break;
+ *
+ * case 2: break;
+ *
+ * case 3: args.addElement("/W3"); break;
+ *
+ * case 4: args.addElement("/W4"); break;
+ */
+ }
+ }
+ public static String getCommandFileSwitch(String cmdFile) {
+ StringBuffer buf = new StringBuffer("@");
+ if (cmdFile.indexOf(' ') >= 0) {
+ buf.append('\"');
+ buf.append(cmdFile);
+ buf.append('\"');
+ } else {
+ buf.append(cmdFile);
+ }
+ return buf.toString();
+ }
+ public static String getIncludeDirSwitch(String includeDir) {
+ return "-I" + includeDir;
+ }
+ public static String[] getOutputFileSwitch(String outPath) {
+ StringBuffer buf = new StringBuffer("-o ");
+ if (outPath.indexOf(' ') >= 0) {
+ buf.append('\"');
+ buf.append(outPath);
+ buf.append('\"');
+ } else {
+ buf.append(outPath);
+ }
+ String[] retval = new String[]{buf.toString()};
+ return retval;
+ }
+ public static boolean isCaseSensitive() {
+ return true;
+ }
+ private OS390Processor() {
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/os400/IccCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/os400/IccCompiler.java
new file mode 100644
index 0000000..952d719
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/os400/IccCompiler.java
@@ -0,0 +1,123 @@
+/*
+ *
+ * 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.os400;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.AbstractCompiler;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for the IBM (R) OS/390 (tm) C++ Compiler
+ *
+ * @author Hiram Chirino (cojonudo14@hotmail.com)
+ */
+public class IccCompiler extends CommandLineCCompiler {
+ private static final AbstractCompiler instance = new IccCompiler(false,
+ null);
+ public static AbstractCompiler getInstance() {
+ return instance;
+ }
+ private IccCompiler(boolean newEnvironment, Environment env) {
+ super("icc", null, new String[]{".c", ".cc", ".cpp", ".cxx", ".c++",
+ ".s"}, new String[]{".h", ".hpp"}, ".o", false, null,
+ newEnvironment, env);
+ }
+ protected void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ // Specifies that only compilations and assemblies be done.
+ // Link-edit is not done
+ args.addElement("-c");
+ /*
+ * if (exceptions) { args.addElement("/GX"); }
+ */
+ if (debug) {
+ args.addElement("-g");
+ /*
+ * args.addElement("-D"); args.addElement("_DEBUG"); if
+ * (multithreaded) { args.addElement("/D_MT"); if (staticLink) {
+ * args.addElement("/MTd"); } else { args.addElement("/MDd");
+ * args.addElement("/D_DLL"); } } else { args.addElement("/MLd"); }
+ */
+ } else {
+ /*
+ * args.addElement("-D"); args.addElement("NEBUG"); if
+ * (multithreaded) { args.addElement("/D_MT"); if (staticLink) {
+ * args.addElement("/MT"); } else { args.addElement("/MD");
+ * args.addElement("/D_DLL"); } } else { args.addElement("/ML"); }
+ */
+ }
+ }
+ protected void addWarningSwitch(Vector args, int level) {
+ IccProcessor.addWarningSwitch(args, level);
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new IccCompiler(newEnvironment, env);
+ }
+ return this;
+ }
+ /*
+ * @see CommandLineCompiler#getDefineSwitch(StringBuffer, String, String)
+ */
+ protected void getDefineSwitch(StringBuffer buffer, String define,
+ String value) {
+ buffer.append("-q");
+ buffer.append(define);
+ if (value != null && value.length() > 0) {
+ buffer.append('=');
+ buffer.append(value);
+ }
+ }
+ protected File[] getEnvironmentIncludePath() {
+ return CUtil.getPathFromEnvironment("INCLUDE", ":");
+ }
+ protected String getIncludeDirSwitch(String includeDir) {
+ return IccProcessor.getIncludeDirSwitch(includeDir);
+ }
+ public Linker getLinker(LinkType type) {
+ return IccLinker.getInstance().getLinker(type);
+ }
+ public int getMaximumCommandLength() {
+ return Integer.MAX_VALUE;
+ }
+ /* Only compile one file at time for now */
+ protected int getMaximumInputFilesPerCommand() {
+ return 1;
+ //return Integer.MAX_VALUE;
+ }
+ /*
+ * @see CommandLineCompiler#getUndefineSwitch(StringBuffer, String)
+ */
+ protected void getUndefineSwitch(StringBuffer buffer, String define) {
+ /*
+ * buffer.addElement("-q"); buf.append(define);
+ */
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/os400/IccLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/os400/IccLinker.java
new file mode 100644
index 0000000..ea10bcc
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/os400/IccLinker.java
@@ -0,0 +1,209 @@
+/*
+ *
+ * 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.os400;
+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 IccLinker extends CommandLineLinker {
+ private static final IccLinker datasetLinker = new IccLinker();
+ private static final IccLinker dllLinker = new IccLinker("", ".dll");
+ private static final IccLinker instance = new IccLinker("", "");
+ public static IccLinker getDataSetInstance() {
+ return datasetLinker;
+ }
+ public static IccLinker getInstance() {
+ return instance;
+ }
+ private boolean isADatasetLinker;
+ File outputFile;
+ private String outputPrefix;
+ CCTask task;
+ private IccLinker() {
+ super("icc", "/bogus", new String[]{".o", ".a", ".lib", ".xds"},
+ new String[]{".dll", ".x"}, ".xds", false, null);
+ this.outputPrefix = "";
+ this.isADatasetLinker = true;
+ }
+ private IccLinker(String outputPrefix, String outputSuffix) {
+ super("icc", "/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) {
+ }
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)
+ */
+ 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;
+ }
+ 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 IccProcessor.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;
+ }
+ 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;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/os400/IccProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/os400/IccProcessor.java
new file mode 100644
index 0000000..f15aa8b
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/os400/IccProcessor.java
@@ -0,0 +1,71 @@
+/*
+ *
+ * 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.os400;
+import java.util.Vector;
+/**
+ * A add-in class for IBM (r) OS/390 compilers and linkers
+ *
+ * @author Hiram Chirino (cojonudo14@hotmail.com)
+ */
+public class IccProcessor {
+ public static void addWarningSwitch(Vector args, int level) {
+ switch (level) {
+ /*
+ * case 0: args.addElement("/W0"); break;
+ *
+ * case 1: args.addElement("/W1"); break;
+ *
+ * case 2: break;
+ *
+ * case 3: args.addElement("/W3"); break;
+ *
+ * case 4: args.addElement("/W4"); break;
+ */
+ }
+ }
+ public static String getCommandFileSwitch(String cmdFile) {
+ StringBuffer buf = new StringBuffer("@");
+ if (cmdFile.indexOf(' ') >= 0) {
+ buf.append('\"');
+ buf.append(cmdFile);
+ buf.append('\"');
+ } else {
+ buf.append(cmdFile);
+ }
+ return buf.toString();
+ }
+ public static String getIncludeDirSwitch(String includeDir) {
+ return "-I" + includeDir;
+ }
+ public static String[] getOutputFileSwitch(String outPath) {
+ StringBuffer buf = new StringBuffer("-o ");
+ if (outPath.indexOf(' ') >= 0) {
+ buf.append('\"');
+ buf.append(outPath);
+ buf.append('\"');
+ } else {
+ buf.append(outPath);
+ }
+ String[] retval = new String[]{buf.toString()};
+ return retval;
+ }
+ public static boolean isCaseSensitive() {
+ return true;
+ }
+ private IccProcessor() {
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/package.html b/src/main/java/net/sf/antcontrib/cpptasks/package.html
new file mode 100644
index 0000000..fba9d80
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/package.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+Copyright 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.
+
+-->
+</head>
+<body bgcolor="white">
+
+C++ and other compiled languages build support for Ant.
+</body>
+</html>
+
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/AbstractParser.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/AbstractParser.java
new file mode 100644
index 0000000..b9bca25
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/AbstractParser.java
@@ -0,0 +1,67 @@
+/*
+ *
+ * Copyright 2001-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.parser;
+import java.io.IOException;
+import java.io.Reader;
+/**
+ * An abstract base class for simple parsers
+ *
+ * @author Curt Arnold
+ */
+public abstract class AbstractParser {
+ /**
+ *
+ *
+ */
+ protected AbstractParser() {
+ }
+ protected abstract void addFilename(String filename);
+ public abstract AbstractParserState getNewLineState();
+ protected void parse(Reader reader) throws IOException {
+ char[] buf = new char[4096];
+ AbstractParserState newLineState = getNewLineState();
+ AbstractParserState state = newLineState;
+ int charsRead = -1;
+ do {
+ charsRead = reader.read(buf, 0, buf.length);
+ if (state == null) {
+ for (int i = 0; i < charsRead; i++) {
+ if (buf[i] == '\n') {
+ state = newLineState;
+ break;
+ }
+ }
+ }
+ if (state != null) {
+ for (int i = 0; i < charsRead; i++) {
+ state = state.consume(buf[i]);
+ //
+ // didn't match a production, skip to a new line
+ //
+ if (state == null) {
+ for (; i < charsRead; i++) {
+ if (buf[i] == '\n') {
+ state = newLineState;
+ break;
+ }
+ }
+ }
+ }
+ }
+ } while (charsRead >= 0);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/AbstractParserState.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/AbstractParserState.java
new file mode 100644
index 0000000..b3e3307
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/AbstractParserState.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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.parser;
+/**
+ * An base class for objects that represent the state of an AbstractParser.
+ *
+ * @author CurtArnold
+ * @see AbstractParser
+ */
+public abstract class AbstractParserState {
+ private AbstractParser parser;
+ protected AbstractParserState(AbstractParser parser) {
+ if (parser == null) {
+ throw new NullPointerException("parser");
+ }
+ this.parser = parser;
+ }
+ /**
+ * Consume a character
+ *
+ * @return new state, may be null to ignore the rest of the line
+ */
+ public abstract AbstractParserState consume(char ch);
+ protected AbstractParser getParser() {
+ return parser;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/BranchState.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/BranchState.java
new file mode 100644
index 0000000..4b869e0
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/BranchState.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.parser;
+public class BranchState extends AbstractParserState {
+ private char[] branchChars;
+ private AbstractParserState[] branchStates;
+ private AbstractParserState noMatchState;
+ public BranchState(AbstractParser parser, char[] branchChars,
+ AbstractParserState[] branchStates, AbstractParserState noMatchState) {
+ super(parser);
+ this.branchChars = (char[]) branchChars.clone();
+ this.branchStates = (AbstractParserState[]) branchStates.clone();
+ this.noMatchState = noMatchState;
+ }
+ public AbstractParserState consume(char ch) {
+ AbstractParserState state;
+ for (int i = 0; i < branchChars.length; i++) {
+ if (ch == branchChars[i]) {
+ state = branchStates[i];
+ return state.consume(ch);
+ }
+ }
+ state = getNoMatchState();
+ if (state != null) {
+ return state.consume(ch);
+ }
+ return state;
+ }
+ protected AbstractParserState getNoMatchState() {
+ return noMatchState;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/CParser.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/CParser.java
new file mode 100644
index 0000000..d10d889
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/CParser.java
@@ -0,0 +1,78 @@
+/*
+ *
+ * Copyright 2002-2005 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.parser;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Vector;
+/**
+ * A parser that extracts #include statements from a Reader.
+ *
+ * @author Adam Murdoch
+ * @author Curt Arnold
+ */
+public final class CParser extends AbstractParser implements Parser {
+ private final Vector includes = new Vector();
+ private AbstractParserState newLineState;
+ /**
+ *
+ *
+ */
+ public CParser() {
+ AbstractParserState quote = new FilenameState(this, new char[]{'"'});
+ AbstractParserState bracket = new FilenameState(this, new char[]{'>'});
+ AbstractParserState postE = new PostE(this, bracket, quote);
+ //
+ // nclude
+ //
+ AbstractParserState e = new LetterState(this, 'e', postE, null);
+ AbstractParserState d = new LetterState(this, 'd', e, null);
+ AbstractParserState u = new LetterState(this, 'u', d, null);
+ AbstractParserState l = new LetterState(this, 'l', u, null);
+ AbstractParserState c = new LetterState(this, 'c', l, null);
+ AbstractParserState n = new LetterState(this, 'n', c, null);
+ //
+ // mport is equivalent to nclude
+ //
+ AbstractParserState t = new LetterState(this, 't', postE, null);
+ AbstractParserState r = new LetterState(this, 'r', t, null);
+ AbstractParserState o = new LetterState(this, 'o', r, null);
+ AbstractParserState p = new LetterState(this, 'p', o, null);
+ AbstractParserState m = new LetterState(this, 'm', p, null);
+ //
+ // switch between
+ //
+ AbstractParserState n_m = new BranchState(this, new char[]{'n', 'm'},
+ new AbstractParserState[]{n, m}, null);
+ AbstractParserState i = new WhitespaceOrLetterState(this, 'i', n_m);
+ newLineState = new WhitespaceOrLetterState(this, '#', i);
+ }
+ public void addFilename(String include) {
+ includes.addElement(include);
+ }
+ public String[] getIncludes() {
+ String[] retval = new String[includes.size()];
+ includes.copyInto(retval);
+ return retval;
+ }
+ public AbstractParserState getNewLineState() {
+ return newLineState;
+ }
+ public void parse(Reader reader) throws IOException {
+ includes.setSize(0);
+ super.parse(reader);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/CaseInsensitiveLetterState.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/CaseInsensitiveLetterState.java
new file mode 100644
index 0000000..edcfe83
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/CaseInsensitiveLetterState.java
@@ -0,0 +1,87 @@
+/*
+ *
+ * Copyright 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.parser;
+
+/**
+ * This parser state checks consumed characters against a specific character
+ * (case insensitive).
+ *
+ * @author Curt Arnold
+ */
+public final class CaseInsensitiveLetterState
+ extends AbstractParserState {
+ /**
+ * Next state if a match is found.
+ */
+ private final AbstractParserState nextState;
+
+ /**
+ * Next state if not match is found.
+ */
+ private final AbstractParserState noMatchState;
+
+ /**
+ * Lower case version of character to match.
+ */
+ private final char lowerLetter;
+
+ /**
+ * Lower case version of character to match.
+ */
+ private final char upperLetter;
+
+ /**
+ * Constructor.
+ *
+ * @param parser
+ * parser
+ * @param matchLetter
+ * letter to match
+ * @param nextStateArg
+ * next state if a match on the letter
+ * @param noMatchStateArg
+ * state if no match on letter
+ */
+ public CaseInsensitiveLetterState(final AbstractParser parser,
+ final char matchLetter,
+ final AbstractParserState nextStateArg,
+ final AbstractParserState noMatchStateArg) {
+ super(parser);
+ this.lowerLetter = Character.toLowerCase(matchLetter);
+ this.upperLetter = Character.toUpperCase(matchLetter);
+ this.nextState = nextStateArg;
+ this.noMatchState = noMatchStateArg;
+ }
+
+ /**
+ * Consumes a character and returns the next state for the parser.
+ *
+ * @param ch
+ * next character
+ * @return the configured nextState if ch is the expected character or the
+ * configure noMatchState otherwise.
+ */
+ public AbstractParserState consume(final char ch) {
+ if (ch == lowerLetter || ch == upperLetter) {
+ return nextState;
+ }
+ if (ch == '\n') {
+ getParser().getNewLineState();
+ }
+ return noMatchState;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/FilenameState.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/FilenameState.java
new file mode 100644
index 0000000..f3a6193
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/FilenameState.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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.parser;
+public class FilenameState extends AbstractParserState {
+ private final StringBuffer buf = new StringBuffer();
+ private final char[] terminators;
+ public FilenameState(AbstractParser parser, char[] terminators) {
+ super(parser);
+ this.terminators = (char[]) terminators.clone();
+ }
+ public AbstractParserState consume(char ch) {
+ for (int i = 0; i < terminators.length; i++) {
+ if (ch == terminators[i]) {
+ getParser().addFilename(buf.toString());
+ buf.setLength(0);
+ return null;
+ }
+ }
+ if (ch == '\n') {
+ buf.setLength(0);
+ return getParser().getNewLineState();
+ } else {
+ buf.append(ch);
+ }
+ return this;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/FortranParser.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/FortranParser.java
new file mode 100644
index 0000000..d393e65
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/FortranParser.java
@@ -0,0 +1,106 @@
+/*
+ *
+ * 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.parser;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Vector;
+
+/**
+ * A parser that extracts INCLUDE statements from a Reader.
+ *
+ * @author Curt Arnold
+ */
+public final class FortranParser
+ extends AbstractParser
+ implements Parser {
+ /**
+ * List of included filenames.
+ */
+ private final Vector includes = new Vector();
+
+ /**
+ * State that starts consuming content at the beginning of a line.
+ */
+ private final AbstractParserState newLineState;
+
+ /**
+ * Default constructor.
+ *
+ */
+ public FortranParser() {
+ AbstractParserState filename = new FilenameState(this, new char[] {'\'',
+ '/'});
+ AbstractParserState apos = new WhitespaceOrLetterState(this, '\'',
+ filename);
+ AbstractParserState blank = new LetterState(this, ' ', apos, null);
+ AbstractParserState e = new CaseInsensitiveLetterState(this, 'E',
+ blank, null);
+ AbstractParserState d = new CaseInsensitiveLetterState(this, 'D', e,
+ null);
+ AbstractParserState u = new CaseInsensitiveLetterState(this, 'U', d,
+ null);
+ AbstractParserState l = new CaseInsensitiveLetterState(this, 'L', u,
+ null);
+ AbstractParserState c = new CaseInsensitiveLetterState(this, 'C', l,
+ null);
+ AbstractParserState n = new CaseInsensitiveLetterState(this, 'N', c,
+ null);
+ newLineState = new WhitespaceOrCaseInsensitiveLetterState(this, 'I', n);
+ }
+
+ /**
+ * Called by FilenameState at completion of file name production.
+ *
+ * @param include
+ * include file name
+ */
+ public void addFilename(final String include) {
+ includes.addElement(include);
+ }
+
+ /**
+ * Gets collection of include file names encountered in parse.
+ * @return include file names
+ */
+ public String[] getIncludes() {
+ String[] retval = new String[includes.size()];
+ includes.copyInto(retval);
+ return retval;
+ }
+
+ /**
+ * Get the state for the beginning of a new line.
+ * @return start of line state
+ */
+ public AbstractParserState getNewLineState() {
+ return newLineState;
+ }
+
+ /**
+ * Collects all included files from the content of the reader.
+ *
+ * @param reader
+ * character reader containing a FORTRAN source module
+ * @throws IOException
+ * throw if I/O error during parse
+ */
+ public void parse(final Reader reader) throws IOException {
+ includes.setSize(0);
+ super.parse(reader);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/LetterState.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/LetterState.java
new file mode 100644
index 0000000..fc62f9b
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/LetterState.java
@@ -0,0 +1,80 @@
+/*
+ *
+ * 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.parser;
+
+/**
+ * This parser state checks consumed characters against a specific character.
+ *
+ * @author Curt Arnold
+ */
+public final class LetterState
+ extends AbstractParserState {
+ /**
+ * Next state if a match is found.
+ */
+ private final AbstractParserState nextState;
+
+ /**
+ * Next state if not match is found.
+ */
+ private final AbstractParserState noMatchState;
+
+ /**
+ * Character to match.
+ */
+ private final char thisLetter;
+
+ /**
+ * Constructor.
+ *
+ * @param parser
+ * parser
+ * @param matchLetter
+ * letter to match
+ * @param nextStateArg
+ * next state if a match on the letter
+ * @param noMatchStateArg
+ * state if no match on letter
+ */
+ public LetterState(final AbstractParser parser,
+ final char matchLetter,
+ final AbstractParserState nextStateArg,
+ final AbstractParserState noMatchStateArg) {
+ super(parser);
+ this.thisLetter = matchLetter;
+ this.nextState = nextStateArg;
+ this.noMatchState = noMatchStateArg;
+ }
+
+ /**
+ * Consumes a character and returns the next state for the parser.
+ *
+ * @param ch
+ * next character
+ * @return the configured nextState if ch is the expected character or the
+ * configure noMatchState otherwise.
+ */
+ public AbstractParserState consume(final char ch) {
+ if (ch == thisLetter) {
+ return nextState;
+ }
+ if (ch == '\n') {
+ getParser().getNewLineState();
+ }
+ return noMatchState;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/Parser.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/Parser.java
new file mode 100644
index 0000000..bf63ae7
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/Parser.java
@@ -0,0 +1,28 @@
+/*
+ *
+ * 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.parser;
+import java.io.IOException;
+import java.io.Reader;
+/**
+ * A parser that extracts #include statements from a Reader.
+ *
+ * @author Curt Arnold
+ */
+public interface Parser {
+ String[] getIncludes();
+ void parse(Reader reader) throws IOException;
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/PostE.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/PostE.java
new file mode 100644
index 0000000..d599f19
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/PostE.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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.parser;
+public class PostE extends AbstractParserState {
+ private AbstractParserState bracket;
+ private AbstractParserState quote;
+ public PostE(CParser parser, AbstractParserState bracket,
+ AbstractParserState quote) {
+ super(parser);
+ this.bracket = bracket;
+ this.quote = quote;
+ }
+ public AbstractParserState consume(char ch) {
+ switch (ch) {
+ case ' ' :
+ case '\t' :
+ return this;
+ case '<' :
+ return bracket;
+ case '"' :
+ return quote;
+ case '\n' :
+ return getParser().getNewLineState();
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/WhitespaceOrCaseInsensitiveLetterState.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/WhitespaceOrCaseInsensitiveLetterState.java
new file mode 100644
index 0000000..f7cbcea
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/WhitespaceOrCaseInsensitiveLetterState.java
@@ -0,0 +1,83 @@
+/*
+ *
+ * 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.parser;
+
+/**
+ * This parser state checks consumed characters against a specific character
+ * (case insensitive) or whitespace.
+ *
+ * @author Curt Arnold
+ */
+public final class WhitespaceOrCaseInsensitiveLetterState
+ extends
+ AbstractParserState {
+ /**
+ * Next state if the character is found.
+ */
+ private final AbstractParserState nextState;
+
+ /**
+ * Character to match (lower case).
+ */
+ private final char lowerLetter;
+
+ /**
+ * Character to match (upper case).
+ */
+ private final char upperLetter;
+
+ /**
+ * Constructor.
+ *
+ * @param parser
+ * parser
+ * @param matchLetter
+ * letter to match
+ * @param nextStateArg
+ * next state if a match on the letter
+ */
+ public WhitespaceOrCaseInsensitiveLetterState(final AbstractParser parser,
+ final char matchLetter,
+ final AbstractParserState
+ nextStateArg) {
+ super(parser);
+ this.lowerLetter = Character.toLowerCase(matchLetter);
+ this.upperLetter = Character.toUpperCase(matchLetter);
+ this.nextState = nextStateArg;
+ }
+
+ /**
+ * Consumes a character and returns the next state for the parser.
+ *
+ * @param ch
+ * next character
+ * @return the configured nextState if ch is the expected character or the
+ * configure noMatchState otherwise.
+ */
+ public AbstractParserState consume(final char ch) {
+ if (ch == lowerLetter || ch == upperLetter) {
+ return nextState;
+ }
+ if (ch == ' ' || ch == '\t') {
+ return this;
+ }
+ if (ch == '\n') {
+ getParser().getNewLineState();
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/WhitespaceOrLetterState.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/WhitespaceOrLetterState.java
new file mode 100644
index 0000000..61c133d
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/WhitespaceOrLetterState.java
@@ -0,0 +1,75 @@
+/*
+ *
+ * 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.parser;
+
+/**
+ * This parser state checks consumed characters against a specific character or
+ * whitespace.
+ *
+ * @author Curt Arnold
+ */
+public final class WhitespaceOrLetterState
+ extends AbstractParserState {
+ /**
+ * Next state if the character is found.
+ */
+ private final AbstractParserState nextState;
+
+ /**
+ * Character to match.
+ */
+ private final char thisLetter;
+
+ /**
+ * Constructor.
+ *
+ * @param parser
+ * parser
+ * @param matchLetter
+ * letter to match
+ * @param nextStateArg
+ * next state if a match on the letter
+ */
+ public WhitespaceOrLetterState(final AbstractParser parser,
+ final char matchLetter,
+ final AbstractParserState nextStateArg) {
+ super(parser);
+ this.thisLetter = matchLetter;
+ this.nextState = nextStateArg;
+ }
+
+ /**
+ * Consumes a character and returns the next state for the parser.
+ *
+ * @param ch
+ * next character @returns the configured nextState if ch is the
+ * expected character or the configure noMatchState otherwise.
+ * @return next state
+ */
+ public AbstractParserState consume(final char ch) {
+ if (ch == thisLetter) {
+ return nextState;
+ }
+ if (ch == ' ' || ch == '\t') {
+ return this;
+ }
+ if (ch == '\n') {
+ getParser().getNewLineState();
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/package.html b/src/main/java/net/sf/antcontrib/cpptasks/parser/package.html
new file mode 100644
index 0000000..1d7aa49
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/package.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+Copyright 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.
+
+-->
+</head>
+<body bgcolor="white">
+
+Provides minimal scanners to extract dependencies,
+such as include statements, from source files.
+
+</body>
+</html>
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/platforms/WindowsPlatform.java b/src/main/java/net/sf/antcontrib/cpptasks/platforms/WindowsPlatform.java
new file mode 100644
index 0000000..f16f94e
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/platforms/WindowsPlatform.java
@@ -0,0 +1,364 @@
+/*
+ *
+ * Copyright 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.platforms;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.TargetMatcher;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+
+
+/**
+ * Platform specific behavior for Microsoft Windows.
+ *
+ * @author Curt Arnold
+ */
+public final class WindowsPlatform {
+
+ /**
+ * Constructor.
+ */
+ private WindowsPlatform() {
+ }
+ /**
+ * Adds source or object files to the bidded fileset to
+ * support version information.
+ *
+ * @param versionInfo version information
+ * @param linkType link type
+ * @param isDebug true if debug build
+ * @param outputFile name of generated executable
+ * @param objDir directory for generated files
+ * @param matcher bidded fileset
+ * @throws IOException if unable to write version resource
+ */
+ public static void addVersionFiles(final VersionInfo versionInfo,
+ final LinkType linkType,
+ final File outputFile,
+ final boolean isDebug,
+ final File objDir,
+ final TargetMatcher matcher)
+ throws IOException {
+ if (versionInfo == null) {
+ throw new NullPointerException("versionInfo");
+ }
+ if (linkType == null) {
+ throw new NullPointerException("linkType");
+ }
+ if (outputFile == null) {
+ throw new NullPointerException("outputFile");
+ }
+ if (objDir == null) {
+ throw new NullPointerException("objDir");
+ }
+
+ /**
+ * Fully resolve version info
+ */
+ VersionInfo mergedInfo = versionInfo.merge();
+
+ File versionResource = new File(objDir, "versioninfo.rc");
+
+ boolean notChanged = false;
+ //
+ // if the resource exists
+ //
+ if (versionResource.exists()) {
+ ByteArrayOutputStream memStream = new ByteArrayOutputStream();
+ Writer writer = new BufferedWriter(new OutputStreamWriter(memStream));
+ writeResource(writer, mergedInfo, outputFile, isDebug, linkType);
+ writer.close();
+ ByteArrayInputStream proposedResource = new ByteArrayInputStream(
+ memStream.toByteArray());
+
+ InputStream existingResource = new FileInputStream(versionResource);
+ //
+ //
+ //
+ notChanged = hasSameContent(proposedResource, existingResource);
+ existingResource.close();
+ }
+
+ //
+ // if the resource file did not exist or will be changed then
+ // write the file
+ //
+ if (!notChanged) {
+ Writer writer = new BufferedWriter(
+ new OutputStreamWriter(
+ new FileOutputStream(versionResource)));
+ writeResource(writer, mergedInfo, outputFile, isDebug, linkType);
+ writer.close();
+ }
+ if (matcher != null) {
+ matcher.visit(new File(versionResource.getParent()),
+ versionResource.getName());
+ }
+
+ }
+
+ /**
+ * Compare two input streams for duplicate content
+ *
+ * Naive implementation, but should not be performance issue.
+ * @param stream1 stream
+ * @param stream2 stream
+ * @return true if streams are identical in content
+ * @throws IOException if error reading streams
+ */
+ private static boolean hasSameContent(final InputStream stream1,
+ final InputStream stream2)
+ throws IOException {
+ int byte1 = -1;
+ int byte2 = -1;
+ do {
+ byte1 = stream1.read();
+ byte2 = stream2.read();
+
+ }
+ while (byte1 == byte2 && byte1 != -1);
+ return (byte1 == byte2);
+ }
+
+
+ /**
+ * Parse version string into array of four short values.
+ * @param version String version
+ * @return short[] four element array
+ */
+ public static short[] parseVersion(final String version) {
+ short[] values = new short[] {
+ 0, 0, 0, 0};
+ if (version != null) {
+ StringBuffer buf = new StringBuffer(version);
+ int start = 0;
+ for (int i = 0; i < 4; i++) {
+ int end = version.indexOf('.', start);
+ if (end <= 0) {
+ end = version.length();
+ for (int j = end; j > start; j--) {
+ String part = buf.substring(start, end);
+ try {
+ values[i] = Short.parseShort(part);
+ break;
+ } catch (NumberFormatException ex) {
+ values[i] = 0;
+ }
+ }
+ break;
+ } else {
+ String part = buf.substring(start, end);
+ try {
+ values[i] = Short.parseShort(part);
+ start = end + 1;
+ } catch (NumberFormatException ex) {
+ break;
+ }
+ }
+ }
+ }
+ return values;
+ }
+
+ /**
+ * Converts parsed version information into a string representation.
+ *
+ * @param buf StringBuffer string buffer to receive version number
+ * @param version short[] four-element array
+ */
+ private static void encodeVersion(final StringBuffer buf,
+ final short[] version) {
+ for (int i = 0; i < 3; i++) {
+ buf.append(Short.toString(version[i]));
+ buf.append(',');
+ }
+ buf.append(Short.toString(version[3]));
+ }
+
+ /**
+ * Writes windows resource.
+ * @param writer writer, may not be nul
+ * @param versionInfo version information
+ * @param outputFile executable file
+ * @param isDebug true if debug
+ * @param linkType link type
+ * @throws IOException if error writing resource file
+ */
+ public static void writeResource(final Writer writer,
+ final VersionInfo versionInfo,
+ final File outputFile,
+ final boolean isDebug,
+ final LinkType linkType) throws IOException {
+
+ //writer.write("#include \"windows.h\"\n");
+
+ writer.write("VS_VERSION_INFO VERSIONINFO\n");
+ StringBuffer buf = new StringBuffer("FILEVERSION ");
+ encodeVersion(buf, parseVersion(versionInfo.getFileversion()));
+ buf.append("\nPRODUCTVERSION ");
+ encodeVersion(buf, parseVersion(versionInfo.getProductversion()));
+ buf.append("\n");
+ writer.write(buf.toString());
+ buf.setLength(0);
+ buf.append("FILEFLAGSMASK 0x1L /* VS_FF_DEBUG */");
+ Boolean patched = versionInfo.getPatched();
+ Boolean prerelease = versionInfo.getPrerelease();
+ if (patched != null) {
+ buf.append(" | 0x4L /* VS_FF_PATCHED */");
+ }
+ if (prerelease != null) {
+ buf.append(" | 0x2L /* VS_FF_PRERELEASE */");
+ }
+ if (versionInfo.getPrivatebuild() != null) {
+ buf.append(" | 0x8L /* VS_FF_PRIVATEBUILD */");
+ }
+ if (versionInfo.getSpecialbuild() != null) {
+ buf.append(" | 0x20L /* VS_FF_SPECIALBUILD */");
+ }
+ buf.append('\n');
+ writer.write(buf.toString());
+ buf.setLength(0);
+ buf.append("FILEFLAGS ");
+
+ if (isDebug) {
+ buf.append("0x1L /* VS_FF_DEBUG */ | ");
+ }
+ if (Boolean.TRUE.equals(patched)) {
+ buf.append("0x4L /* VS_FF_PATCHED */ | ");
+ }
+ if (Boolean.TRUE.equals(prerelease)) {
+ buf.append("0x2L /* VS_FF_PRERELEASE */ | ");
+ }
+ if (Boolean.TRUE.equals(versionInfo.getPrivatebuild())) {
+ buf.append("0x8L /* VS_FF_PRIVATEBUILD */ | ");
+ }
+ if (Boolean.TRUE.equals(versionInfo.getSpecialbuild())) {
+ buf.append("0x20L /* VS_FF_SPECIALBUILD */ | ");
+ }
+ if (buf.length() > 10) {
+ buf.setLength(buf.length() - 3);
+ buf.append('\n');
+ } else {
+ buf.append("0\n");
+ }
+ writer.write(buf.toString());
+ buf.setLength(0);
+
+ writer.write("FILEOS 0x40004 /* VOS_NT_WINDOWS32 */\nFILETYPE ");
+ if (linkType.isExecutable()) {
+ writer.write("0x1L /* VFT_APP */\n");
+ } else {
+ if (linkType.isSharedLibrary()) {
+ writer.write("0x2L /* VFT_DLL */\n");
+ } else if (linkType.isStaticLibrary()) {
+ writer.write("0x7L /* VFT_STATIC_LIB */\n");
+ } else {
+ writer.write("0x0L /* VFT_UNKNOWN */\n");
+ }
+ }
+ writer.write("FILESUBTYPE 0x0L\n");
+ writer.write("BEGIN\n");
+ writer.write("BLOCK \"StringFileInfo\"\n");
+ writer.write(" BEGIN\n#ifdef UNICODE\nBLOCK \"040904B0\"\n");
+ writer.write("#else\nBLOCK \"040904E4\"\n#endif\n");
+ writer.write("BEGIN\n");
+ if (versionInfo.getFilecomments() != null) {
+ writer.write("VALUE \"Comments\", \"");
+ writer.write(versionInfo.getFilecomments());
+ writer.write("\\0\"\n");
+ }
+ if (versionInfo.getCompanyname() != null) {
+ writer.write("VALUE \"CompanyName\", \"");
+ writer.write(versionInfo.getCompanyname());
+ writer.write("\\0\"\n");
+ }
+ if (versionInfo.getFiledescription() != null) {
+ writer.write("VALUE \"FileDescription\", \"");
+ writer.write(versionInfo.getFiledescription());
+ writer.write("\\0\"\n");
+ }
+ if (versionInfo.getFileversion() != null) {
+ writer.write("VALUE \"FileVersion\", \"");
+ writer.write(versionInfo.getFileversion());
+ writer.write("\\0\"\n");
+ }
+ String baseName = CUtil.getBasename(outputFile);
+ String internalName = versionInfo.getInternalname();
+ if (internalName == null) {
+ internalName = baseName;
+ }
+ writer.write("VALUE \"InternalName\", \"");
+ writer.write(internalName);
+ writer.write("\\0\"\n");
+ if (versionInfo.getLegalcopyright() != null) {
+ writer.write("VALUE \"LegalCopyright\", \"");
+ writer.write(versionInfo.getLegalcopyright());
+ writer.write("\\0\"\n");
+ }
+ if (versionInfo.getLegaltrademarks() != null) {
+ writer.write("VALUE \"LegalTrademarks\", \"");
+ writer.write(versionInfo.getLegaltrademarks());
+ writer.write("\\0\"\n");
+ }
+ writer.write("VALUE \"OriginalFilename\", \"");
+ writer.write(baseName);
+ writer.write("\\0\"\n");
+ if (versionInfo.getPrivatebuild() != null) {
+ writer.write("VALUE \"PrivateBuild\", \"");
+ writer.write(versionInfo.getPrivatebuild());
+ writer.write("\\0\"\n");
+ }
+ if (versionInfo.getProductname() != null) {
+ writer.write("VALUE \"ProductName\", \"");
+ writer.write(versionInfo.getProductname());
+ writer.write("\\0\"\n");
+ }
+ if (versionInfo.getProductversion() != null) {
+ writer.write("VALUE \"ProductVersion\", \"");
+ writer.write(versionInfo.getProductversion());
+ writer.write("\\0\"\n");
+ }
+ if (versionInfo.getSpecialbuild() != null) {
+ writer.write("VALUE \"SpecialBuild\", \"");
+ writer.write(versionInfo.getSpecialbuild());
+ writer.write("\\0\"\n");
+ }
+ writer.write("END\n");
+ writer.write("END\n");
+
+ writer.write("BLOCK \"VarFileInfo\"\n");
+ writer.write("BEGIN\n#ifdef UNICODE\n");
+ writer.write("VALUE \"Translation\", 0x409, 1200\n");
+ writer.write("#else\n");
+ writer.write("VALUE \"Translation\", 0x409, 1252\n");
+ writer.write("#endif\n");
+ writer.write("END\n");
+ writer.write("END\n");
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/platforms/package.html b/src/main/java/net/sf/antcontrib/cpptasks/platforms/package.html
new file mode 100644
index 0000000..e054c41
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/platforms/package.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+Copyright 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.
+
+-->
+</head>
+<body bgcolor="white">
+
+Platform specific utilities.
+</body>
+</html>
+
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/sun/C89CCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/sun/C89CCompiler.java
new file mode 100644
index 0000000..4ac8ac1
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/sun/C89CCompiler.java
@@ -0,0 +1,108 @@
+/*
+ *
+ * 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.sun;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.AbstractCompiler;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for the Sun C89 C++ Compiler
+ *
+ * @author Hiram Chirino (cojonudo14@hotmail.com)
+ */
+public class C89CCompiler extends CommandLineCCompiler {
+ private static final AbstractCompiler instance = new C89CCompiler(false,
+ null);
+ public static AbstractCompiler getInstance() {
+ return instance;
+ }
+ private C89CCompiler(boolean newEnvironment, Environment env) {
+ super("c89", null, new String[]{".c", ".cc", ".cpp", ".cxx", ".c++"},
+ new String[]{".h", ".hpp"}, ".o", false, null, newEnvironment,
+ env);
+ }
+ protected void addImpliedArgs(
+ final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ // Specifies that only compilations and assemblies be done.
+ args.addElement("-c");
+ /*
+ * if (exceptions) { args.addElement("/GX"); }
+ */
+ if (debug) {
+ args.addElement("-g");
+ args.addElement("-D_DEBUG");
+ /*
+ * if (multithreaded) { args.addElement("/D_MT"); if (staticLink) {
+ * args.addElement("/MTd"); } else { args.addElement("/MDd");
+ * args.addElement("/D_DLL"); } } else { args.addElement("/MLd"); }
+ */
+ } else {
+ args.addElement("-DNDEBUG");
+ /*
+ * if (multithreaded) { args.addElement("/D_MT"); if (staticLink) {
+ * args.addElement("/MT"); } else { args.addElement("/MD");
+ * args.addElement("/D_DLL"); } } else { args.addElement("/ML"); }
+ */
+ }
+ }
+ protected void addWarningSwitch(Vector args, int level) {
+ C89Processor.addWarningSwitch(args, level);
+ }
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {
+ if (newEnvironment || env != null) {
+ return new C89CCompiler(newEnvironment, env);
+ }
+ return this;
+ }
+ protected void getDefineSwitch(StringBuffer buf, String define, String value) {
+ C89Processor.getDefineSwitch(buf, define, value);
+ }
+ protected File[] getEnvironmentIncludePath() {
+ return CUtil.getPathFromEnvironment("INCLUDE", ":");
+ }
+ protected String getIncludeDirSwitch(String includeDir) {
+ return C89Processor.getIncludeDirSwitch(includeDir);
+ }
+ public Linker getLinker(LinkType type) {
+ return C89Linker.getInstance().getLinker(type);
+ }
+ public int getMaximumCommandLength() {
+ return Integer.MAX_VALUE;
+ }
+ /* Only compile one file at time for now */
+ protected int getMaximumInputFilesPerCommand() {
+ return 1;
+ }
+ protected void getUndefineSwitch(StringBuffer buf, String define) {
+ C89Processor.getUndefineSwitch(buf, define);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/sun/C89Linker.java b/src/main/java/net/sf/antcontrib/cpptasks/sun/C89Linker.java
new file mode 100644
index 0000000..6c41c89
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/sun/C89Linker.java
@@ -0,0 +1,132 @@
+/*
+ *
+ * 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.sun;
+import java.io.File;
+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.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;
+
+/**
+ * Adapter for the Sun C89 Linker
+ *
+ * @author Hiram Chirino (cojonudo14@hotmail.com)
+ */
+public final class C89Linker extends CommandLineLinker {
+ private static final C89Linker dllLinker = new C89Linker("lib", ".so");
+ private static final C89Linker instance = new C89Linker("", "");
+ public static C89Linker getInstance() {
+ return instance;
+ }
+ private String outputPrefix;
+ private C89Linker(String outputPrefix, String outputSuffix) {
+ super("ld", "/bogus", new String[]{".o", ".a", ".lib", ".x"},
+ new String[]{}, outputSuffix, false, null);
+ this.outputPrefix = outputPrefix;
+ }
+ 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("-G");
+ }
+ }
+ protected void addIncremental(boolean incremental, Vector args) {
+ }
+ public String[] addLibrarySets(CCTask task, LibrarySet[] libsets,
+ Vector preargs, Vector midargs, Vector endargs) {
+ super.addLibrarySets(task, libsets, preargs, midargs, endargs);
+ StringBuffer buf = new StringBuffer("-l");
+ for (int i = 0; i < libsets.length; i++) {
+ LibrarySet set = libsets[i];
+ File libdir = set.getDir(null);
+ String[] libs = set.getLibs();
+ if (libdir != null) {
+ endargs.addElement("-L");
+ endargs.addElement(libdir.getAbsolutePath());
+ }
+ for (int j = 0; j < libs.length; j++) {
+ //
+ // reset the buffer to just "-l"
+ //
+ buf.setLength(2);
+ //
+ // add the library name
+ buf.append(libs[j]);
+ //
+ // add the argument to the list
+ endargs.addElement(buf.toString());
+ }
+ }
+ return null;
+ }
+ protected void addMap(boolean map, Vector args) {
+ }
+ protected void addStack(int stack, Vector args) {
+ }
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)
+ */
+ 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) {
+ return C89Processor.getLibraryPatterns(libnames, libType);
+ }
+ public Linker getLinker(LinkType linkType) {
+ if (linkType.isSharedLibrary()) {
+ return dllLinker;
+ }
+ /*
+ * if(linkType.isStaticLibrary()) { return
+ * OS390Librarian.getInstance(); }
+ */
+ 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;
+ }
+ public String[] getOutputFileSwitch(String outputFile) {
+ return new String[]{"-o", outputFile};
+ }
+ public boolean isCaseSensitive() {
+ return C89Processor.isCaseSensitive();
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/sun/C89Processor.java b/src/main/java/net/sf/antcontrib/cpptasks/sun/C89Processor.java
new file mode 100644
index 0000000..343293a
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/sun/C89Processor.java
@@ -0,0 +1,116 @@
+/*
+ *
+ * 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.sun;
+import java.util.Vector;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+
+/**
+ * A add-in class for Sun C89 compilers and linkers
+ *
+ * @author Hiram Chirino (cojonudo14@hotmail.com)
+ */
+public class C89Processor {
+ 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 static void addWarningSwitch(Vector args, int level) {
+ switch (level) {
+ /*
+ * case 0: args.addElement("/W0"); break;
+ *
+ * case 1: args.addElement("/W1"); break;
+ *
+ * case 2: break;
+ *
+ * case 3: args.addElement("/W3"); break;
+ *
+ * case 4: args.addElement("/W4"); break;
+ */
+ }
+ }
+ public static String getCommandFileSwitch(String cmdFile) {
+ StringBuffer buf = new StringBuffer("@");
+ if (cmdFile.indexOf(' ') >= 0) {
+ buf.append('\"');
+ buf.append(cmdFile);
+ buf.append('\"');
+ } else {
+ buf.append(cmdFile);
+ }
+ return buf.toString();
+ }
+ public static void getDefineSwitch(StringBuffer buf, String define,
+ String value) {
+ buf.setLength(0);
+ buf.append("-D");
+ buf.append(define);
+ if (value != null && value.length() > 0) {
+ buf.append('=');
+ buf.append(value);
+ }
+ }
+ public static String getIncludeDirSwitch(String includeDir) {
+ return "-I" + includeDir;
+ }
+ public static String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {
+ StringBuffer buf = new StringBuffer();
+ int patternCount = libnames.length*2;
+ if (libType != null) {
+ patternCount = libnames.length;
+ }
+ String[] patterns = new String[patternCount];
+ int offset = 0;
+ if (libType == null || "static".equals(libType.getValue())) {
+ offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0);
+ }
+ if (libType == null || !"static".equals(libType.getValue())) {
+ offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns,
+ offset);
+ }
+ return patterns;
+ }
+ public static String[] getOutputFileSwitch(String outPath) {
+ StringBuffer buf = new StringBuffer("-o ");
+ if (outPath.indexOf(' ') >= 0) {
+ buf.append('\"');
+ buf.append(outPath);
+ buf.append('\"');
+ } else {
+ buf.append(outPath);
+ }
+ String[] retval = new String[]{buf.toString()};
+ return retval;
+ }
+ public static void getUndefineSwitch(StringBuffer buf, String define) {
+ buf.setLength(0);
+ buf.append("-U");
+ buf.append(define);
+ }
+ public static boolean isCaseSensitive() {
+ return true;
+ }
+ private C89Processor() {
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/sun/ForteCCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/sun/ForteCCCompiler.java
new file mode 100644
index 0000000..9422e49
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/sun/ForteCCCompiler.java
@@ -0,0 +1,130 @@
+/*
+ *
+ * Copyright 2001-2007 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.sun;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+/**
+ * Adapter for the Sun (r) Forte (tm) C++ compiler
+ *
+ * @author Curt Arnold
+ */
+public final class ForteCCCompiler extends GccCompatibleCCompiler {
+ private final static String[] headerExtensions = new String[]{".h", ".hpp",
+ ".inl"};
+ private final static String[] sourceExtensions = new String[]{".c", ".cc",
+ ".cxx", ".cpp", ".c++", ".i", ".s"};
+
+ private static final ForteCCCompiler instance = new ForteCCCompiler("CC",
+ sourceExtensions, headerExtensions);
+ /**
+ * Gets singleton instance of this class
+ */
+ public static ForteCCCompiler getInstance() {
+ return instance;
+ }
+ private String identifier;
+ private File[] includePath;
+ /**
+ * Private constructor. Use ForteCCCompiler.getInstance() to get singleton
+ * instance of this class.
+ */
+ private ForteCCCompiler(String command, String[] sourceExtensions,
+ String[] headerExtensions) {
+ super(command, "-V", sourceExtensions, headerExtensions, false, null,
+ false, null);
+ }
+ public void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ args.addElement("-c");
+ if (debug) {
+ args.addElement("-g");
+ }
+ if (optimization != null) {
+ if (optimization.isSpeed()) {
+ args.addElement("-xO2");
+ }
+ }
+ if (rtti != null) {
+ if (rtti.booleanValue()) {
+ args.addElement("-features=rtti");
+ } else {
+ args.addElement("-features=no%rtti");
+ }
+ }
+ if (multithreaded) {
+ args.addElement("-mt");
+ }
+ if (linkType.isSharedLibrary()) {
+ args.addElement("-KPIC");
+ }
+
+ }
+ public void addWarningSwitch(Vector args, int level) {
+ switch (level) {
+ case 0 :
+ args.addElement("-w");
+ break;
+ case 1 :
+ case 2 :
+ break;
+ case 3 :
+ args.addElement("+w");
+ break;
+ case 4 :
+ args.addElement("+w2");
+ break;
+ case 5 :
+ args.addElement("+w2");
+ args.addElement("-xwe");
+ }
+ }
+ public File[] getEnvironmentIncludePath() {
+ if (includePath == null) {
+ File ccLoc = CUtil.getExecutableLocation("CC");
+ if (ccLoc != null) {
+ File compilerIncludeDir = new File(
+ new File(ccLoc, "../include").getAbsolutePath());
+ if (compilerIncludeDir.exists()) {
+ includePath = new File[2];
+ includePath[0] = compilerIncludeDir;
+ }
+ }
+ if (includePath == null) {
+ includePath = new File[1];
+ }
+ includePath[includePath.length - 1] = new File("/usr/include");
+ }
+ return includePath;
+ }
+ public Linker getLinker(LinkType linkType) {
+ return ForteCCLinker.getInstance().getLinker(linkType);
+ }
+ public int getMaximumCommandLength() {
+ return Integer.MAX_VALUE;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/sun/ForteCCLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/sun/ForteCCLinker.java
new file mode 100644
index 0000000..47d2155
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/sun/ForteCCLinker.java
@@ -0,0 +1,100 @@
+/*
+ *
+ * Copyright 2001-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.sun;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;
+/**
+ * Adapter for Sun (r) Forte(tm) C++ Linker
+ *
+ * @author Curt Arnold
+ */
+public final class ForteCCLinker extends AbstractLdLinker {
+ private static final String[] discardFiles = new String[]{".dll", ".so",
+ ".sl"};
+ private static final String[] objFiles = new String[]{".o", ".a", ".lib"};
+ private static final ForteCCLinker arLinker = new ForteCCLinker("CC",
+ objFiles, discardFiles, "lib", ".a");
+ private static final ForteCCLinker dllLinker = new ForteCCLinker("CC",
+ objFiles, discardFiles, "lib", ".so");
+ private static final ForteCCLinker instance = new ForteCCLinker("CC",
+ objFiles, discardFiles, "", "");
+ public static ForteCCLinker getInstance() {
+ return instance;
+ }
+ private File[] libDirs;
+ private ForteCCLinker(String command, String[] extensions,
+ String[] ignoredExtensions, String outputPrefix, String outputSuffix) {
+ super(command, "-V", extensions, ignoredExtensions, outputPrefix,
+ outputSuffix, false, null);
+ }
+ public void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ if (debug) {
+ args.addElement("-g");
+ }
+ if (linkType.isStaticRuntime()) {
+ args.addElement("-static");
+ }
+ if (linkType.isSharedLibrary()) {
+ args.addElement("-G");
+ }
+ if (linkType.isStaticLibrary()) {
+ args.addElement("-xar");
+ }
+ }
+ public void addIncremental(boolean incremental, Vector args) {
+ /*
+ * if (incremental) { args.addElement("-xidlon"); } else {
+ * args.addElement("-xidloff"); }
+ */
+ }
+ /**
+ * Returns library path.
+ *
+ */
+ public File[] getLibraryPath() {
+ if (libDirs == null) {
+ File CCloc = CUtil.getExecutableLocation("CC");
+ if (CCloc != null) {
+ File compilerLib = new File(new File(CCloc, "../lib")
+ .getAbsolutePath());
+ if (compilerLib.exists()) {
+ libDirs = new File[2];
+ libDirs[0] = compilerLib;
+ }
+ }
+ if (libDirs == null) {
+ libDirs = new File[1];
+ }
+ }
+ libDirs[libDirs.length - 1] = new File("/usr/lib");
+ return libDirs;
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return arLinker;
+ }
+ if (type.isSharedLibrary()) {
+ return dllLinker;
+ }
+ return instance;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxCCompiler.java
new file mode 100644
index 0000000..c844ac4
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxCCompiler.java
@@ -0,0 +1,191 @@
+/*
+ *
+ * Copyright 2001-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.ti;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+
+
+import org.apache.tools.ant.types.Environment;
+/**
+ * Adapter for TI DSP compilers with cl** commands
+ *
+ * @author CurtA
+ */
+public class ClxxCCompiler extends CommandLineCCompiler {
+ /**
+ * Header file extensions
+ */
+ private static final String[] headerExtensions = new String[]{".h", ".hpp",
+ ".inl"};
+ /**
+ * Source file extensions
+ */
+ private static final String[] sourceExtensions = new String[]{".c", ".cc",
+ ".cpp", ".cxx", ".c++"};
+ /**
+ * Singleton for TMS320C55x
+ */
+ private static final ClxxCCompiler cl55 = new ClxxCCompiler("cl55", false,
+ null);
+ /**
+ * Singleton for TMS320C6000
+ */
+ private static final ClxxCCompiler cl6x = new ClxxCCompiler("cl6x", false,
+ null);
+ public static ClxxCCompiler getCl55Instance() {
+ return cl55;
+ }
+ public static ClxxCCompiler getCl6xInstance() {
+ return cl6x;
+ }
+ /**
+ * Private constructor
+ *
+ * @param command
+ * executable name
+ * @param newEnvironment
+ * Change environment
+ * @param env
+ * New environment
+ */
+ private ClxxCCompiler(String command, boolean newEnvironment,
+ Environment env) {
+ super(command, "-h", sourceExtensions, headerExtensions, ".o", false,
+ null, newEnvironment, env);
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#addImpliedArgs(java.util.Vector,
+ * boolean, boolean, boolean,
+ * net.sf.antcontrib.cpptasks.compiler.LinkType)
+ */
+ protected void addImpliedArgs(
+ final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ if (debug) {
+ args.addElement("-gw");
+ }
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#addWarningSwitch(java.util.Vector,
+ * int)
+ */
+ protected void addWarningSwitch(Vector args, int warnings) {
+ // TODO Auto-generated method stub
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getDefineSwitch(java.lang.StringBuffer,
+ * java.lang.String, java.lang.String)
+ */
+ protected void getDefineSwitch(StringBuffer buffer, String define,
+ String value) {
+ buffer.append("-d");
+ buffer.append(define);
+ if (value != null) {
+ buffer.append('=');
+ buffer.append(value);
+ }
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getEnvironmentIncludePath()
+ */
+ protected File[] getEnvironmentIncludePath() {
+ File[] c_dir = CUtil.getPathFromEnvironment("C_DIR", ";");
+ File[] cx_dir = CUtil.getPathFromEnvironment("C6X_C_DIR", ";");
+ if (c_dir.length == 0) {
+ return cx_dir;
+ }
+ if (cx_dir.length == 0) {
+ return c_dir;
+ }
+ File[] combo = new File[c_dir.length + cx_dir.length];
+ for (int i = 0; i < cx_dir.length; i++) {
+ combo[i] = cx_dir[i];
+ }
+ for (int i = 0; i < c_dir.length; i++) {
+ combo[i + cx_dir.length] = c_dir[i];
+ }
+ return combo;
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getIncludeDirSwitch(java.lang.String)
+ */
+ protected String getIncludeDirSwitch(String source) {
+ return "-I" + source;
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType)
+ */
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ if (this == cl6x) {
+ return ClxxLibrarian.getCl6xInstance();
+ }
+ return ClxxLibrarian.getCl55Instance();
+ }
+ if (type.isSharedLibrary()) {
+ if (this == cl6x) {
+ return ClxxLinker.getCl6xDllInstance();
+ }
+ return ClxxLinker.getCl55DllInstance();
+ }
+ if (this == cl6x) {
+ return ClxxLinker.getCl6xInstance();
+ }
+ return ClxxLinker.getCl55Instance();
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getMaximumCommandLength()
+ */
+ public int getMaximumCommandLength() {
+ return 1024;
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getUndefineSwitch(java.lang.StringBuffer,
+ * java.lang.String)
+ */
+ protected void getUndefineSwitch(StringBuffer buffer, String define) {
+ buffer.append("-u");
+ buffer.append(define);
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxLibrarian.java
new file mode 100644
index 0000000..c48815a
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxLibrarian.java
@@ -0,0 +1,162 @@
+/*
+ *
+ * Copyright 2001-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.ti;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+
+/**
+ *
+ * Adapter for TI DSP librarian
+ * *
+ * @author CurtA
+ */
+public class ClxxLibrarian extends CommandLineLinker {
+ private static final ClxxLibrarian cl55Instance = new ClxxLibrarian("ar55");
+ private static final ClxxLibrarian cl6xInstance = new ClxxLibrarian("ar6x");
+ public static final ClxxLibrarian getCl55Instance() {
+ return cl55Instance;
+ }
+ public static final ClxxLibrarian getCl6xInstance() {
+ return cl6xInstance;
+ }
+ private ClxxLibrarian(String command) {
+ super(command, null, new String[]{".o"}, new String[0], ".lib", false,
+ null);
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addBase(long,
+ * java.util.Vector)
+ */
+ protected void addBase(long base, Vector args) {
+ // TODO Auto-generated method stub
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addFixed(java.lang.Boolean,
+ * java.util.Vector)
+ */
+ protected void addFixed(Boolean fixed, Vector args) {
+ // TODO Auto-generated method stub
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addImpliedArgs(boolean,
+ * net.sf.antcontrib.cpptasks.compiler.LinkType, java.util.Vector)
+ */
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ // TODO Auto-generated method stub
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addIncremental(boolean,
+ * java.util.Vector)
+ */
+ protected void addIncremental(boolean incremental, Vector args) {
+ // TODO Auto-generated method stub
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addMap(boolean,
+ * java.util.Vector)
+ */
+ protected void addMap(boolean map, Vector args) {
+ // TODO Auto-generated method stub
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addStack(int,
+ * java.util.Vector)
+ */
+ protected void addStack(int stack, Vector args) {
+ // TODO Auto-generated method stub
+ }
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)
+ */
+ protected void addEntry(String entry, Vector args) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getCommandFileSwitch(java.lang.String)
+ */
+ protected String getCommandFileSwitch(String commandFile) {
+ return "@" + commandFile;
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPath()
+ */
+ public File[] getLibraryPath() {
+ return new File[0];
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPatterns(java.lang.String[])
+ */
+ public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {
+ return new String[0];
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType)
+ */
+ public Linker getLinker(LinkType linkType) {
+ return null;
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getMaximumCommandLength()
+ */
+ protected int getMaximumCommandLength() {
+ return 1024;
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getOutputFileSwitch(java.lang.String)
+ */
+ protected String[] getOutputFileSwitch(String outputFile) {
+ return new String[]{"-o", outputFile};
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.Linker#isCaseSensitive()
+ */
+ public boolean isCaseSensitive() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxLinker.java
new file mode 100644
index 0000000..bb644a4
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxLinker.java
@@ -0,0 +1,181 @@
+/*
+ *
+ * Copyright 2001-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.ti;
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+
+/**
+ * Adapter for TI DSP linkers
+ * *
+ * @author CurtA
+ *
+ */
+public class ClxxLinker extends CommandLineLinker {
+ private static final ClxxLinker cl55DllInstance = new ClxxLinker("lnk55",
+ ".dll");
+ private static final ClxxLinker cl55Instance = new ClxxLinker("lnk55",
+ ".exe");
+ private static final ClxxLinker cl6xDllInstance = new ClxxLinker("lnk6x",
+ ".dll");
+ private static final ClxxLinker cl6xInstance = new ClxxLinker("lnk6x",
+ ".exe");
+ public static ClxxLinker getCl55DllInstance() {
+ return cl55DllInstance;
+ }
+ public static ClxxLinker getCl55Instance() {
+ return cl55Instance;
+ }
+ public static ClxxLinker getCl6xDllInstance() {
+ return cl6xDllInstance;
+ }
+ public static ClxxLinker getCl6xInstance() {
+ return cl6xInstance;
+ }
+ private ClxxLinker(String command, String outputSuffix) {
+ super(command, "-h", new String[]{".o", ".lib", ".res"}, new String[]{
+ ".map", ".pdb", ".lnk"}, outputSuffix, false, null);
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addBase(long,
+ * java.util.Vector)
+ */
+ protected void addBase(long base, Vector args) {
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addFixed(java.lang.Boolean,
+ * java.util.Vector)
+ */
+ protected void addFixed(Boolean fixed, Vector args) {
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addImpliedArgs(boolean,
+ * net.sf.antcontrib.cpptasks.compiler.LinkType, java.util.Vector)
+ */
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ if (linkType.isSharedLibrary()) {
+ args.addElement("-abs");
+ }
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addIncremental(boolean,
+ * java.util.Vector)
+ */
+ protected void addIncremental(boolean incremental, Vector args) {
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addMap(boolean,
+ * java.util.Vector)
+ */
+ protected void addMap(boolean map, Vector args) {
+ if (map) {
+ args.addElement("-m");
+ }
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addStack(int,
+ * java.util.Vector)
+ */
+ protected void addStack(int stack, Vector args) {
+ }
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)
+ */
+ protected void addEntry(String entry, Vector args) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getCommandFileSwitch(java.lang.String)
+ */
+ protected String getCommandFileSwitch(String commandFile) {
+ return "@" + commandFile;
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPath()
+ */
+ public File[] getLibraryPath() {
+ return new File[0];
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPatterns(java.lang.String[])
+ */
+ public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {
+ //
+ // TODO: Looks bogus, should be .a or .so's not .o's
+ //
+ String[] libpats = new String[libnames.length];
+ for (int i = 0; i < libnames.length; i++) {
+ libpats[i] = libnames[i] + ".o";
+ }
+ return libpats;
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType)
+ */
+ public Linker getLinker(LinkType linkType) {
+ return this;
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getMaximumCommandLength()
+ */
+ protected int getMaximumCommandLength() {
+ return 1024;
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getOutputFileSwitch(java.lang.String)
+ */
+ protected String[] getOutputFileSwitch(String outputFile) {
+ return new String[]{"-o", outputFile};
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.sf.antcontrib.cpptasks.compiler.Linker#isCaseSensitive()
+ */
+ public boolean isCaseSensitive() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/trolltech/MetaObjectCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/MetaObjectCompiler.java
new file mode 100644
index 0000000..25651da
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/MetaObjectCompiler.java
@@ -0,0 +1,280 @@
+/*
+ *
+ * Copyright 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.trolltech;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.FileReader;
+import java.io.Reader;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.parser.CParser;
+import net.sf.antcontrib.cpptasks.parser.Parser;
+import net.sf.antcontrib.cpptasks.gcc.LdLinker;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+
+import org.apache.tools.ant.types.Environment;
+
+/**
+ * Adapter for the Trolltech Qt MOC Compiler.
+ *
+ * @author Curt Arnold
+ */
+public final class MetaObjectCompiler
+ extends CommandLineCompiler {
+ /**
+ * Singleton instance.
+ */
+ private static final MetaObjectCompiler INSTANCE = new MetaObjectCompiler(
+ false, null);
+
+ /**
+ * Gets singleton instance of compiler.
+ * @return MetaObjectCompiler singleton instance
+ */
+ public static MetaObjectCompiler getInstance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Constructor.
+ * @param newEnvironment boolean establish an new environment.
+ * @param env Environment environment.
+ */
+ private MetaObjectCompiler(final boolean newEnvironment,
+ final Environment env) {
+ super("moc", "-version", new String[] {".h", ".cpp"}
+ , new String[0], ".moc", false, null, newEnvironment, env);
+ }
+
+ /**
+ * Add arguments for debug, etc.
+ * @param args Vector command argument list
+ * @param debug boolean build for debug if true
+ * @param multithreaded boolean build for multithreading if true
+ * @param exceptions boolean enable exceptions if true
+ * @param linkType LinkType output and runtime type
+ * @param rtti Boolean enable run-time type identification if true
+ * @param optimization OptimizationEnum optimization
+ */
+ protected void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ }
+
+ /**
+ * Add arguments for specified warning level.
+ * @param args Vector command line arguments
+ * @param level int warning level value
+ */
+ protected void addWarningSwitch(final Vector args, final int level) {
+ }
+
+ /**
+ * Change enviroment (deprecated).
+ * @param newEnvironment boolean use new environment.
+ * @param env Environment environment
+ * @return Processor modified processor
+ */
+ public Processor changeEnvironment(final boolean newEnvironment,
+ final Environment env) {
+ return this;
+ }
+
+ /**
+ * Gets a parser to scan source file for dependencies.
+ * @param source source file
+ * @return parser
+ */
+ protected Parser createParser(final File source) {
+ return new CParser();
+ }
+
+ /**
+ * Gets number of command line arguments per input file.
+ * @return int number of command line arguments per input file.
+ */
+ protected int getArgumentCountPerInputFile() {
+ return 3;
+ }
+
+ /**
+ * Returns the bid of the processor for the file.
+ *
+ * @param inputFile
+ * filename of input file
+ * @return bid for the file, 0 indicates no interest, 1 indicates that the
+ * processor recognizes the file but doesn't process it (header
+ * files, for example), 100 indicates strong interest
+ */
+ public int bid(final String inputFile) {
+ //
+ // get base bid
+ int baseBid = super.bid(inputFile);
+ //
+ // if the base bid was non-zero (.h or .cpp extension)
+ //
+ if (baseBid > 0) {
+ //
+ // scan the file for Q_OBJECT
+ // skip file if not present
+ //
+ try {
+ Reader reader = new BufferedReader(new FileReader(inputFile));
+ boolean hasQObject = MetaObjectParser.hasQObject(reader);
+ reader.close();
+ if (hasQObject) {
+ return baseBid;
+ }
+ } catch (IOException ex) {
+ return 0;
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Gets output file names.
+ * @param inputFile String input file name
+ * @param versionInfo version info, not used by this compiler.
+ * @return String[] output file names
+ */
+ public String[] getOutputFileNames(final String inputFile,
+ final VersionInfo versionInfo) {
+ if (inputFile.endsWith(".cpp")) {
+ return super.getOutputFileNames(inputFile, versionInfo);
+ }
+ //
+ // if a recognized input file
+ //
+ String baseName = getBaseOutputName(inputFile);
+ return new String[] {
+ "moc_" + baseName + ".cpp"};
+ }
+
+ /**
+ * Gets input file arguments.
+ * @param outputDir File output directory
+ * @param filename String input file name.
+ * @param index int argument index,
+ * 0 to getNumberOfArgumentsPerInputFile() -1
+ * @return String input file argument
+ */
+ protected String getInputFileArgument(final File outputDir,
+ final String filename,
+ final int index) {
+ switch (index) {
+ case 0:
+ return "-o";
+ case 1:
+ String outputFileName = getOutputFileNames(filename, null)[0];
+ return new File(outputDir, outputFileName)
+ .toString();
+
+ case 2:
+ return filename;
+
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Gets maximum length of command line.
+ * @return int maximum length of command line
+ */
+ public int getMaximumCommandLength() {
+ return 1024;
+ }
+
+ /**
+ * Gets maximum number of input files processed per command.
+ * @return int maximum number of input files processed per command.
+ */
+ protected int getMaximumInputFilesPerCommand() {
+ return 1;
+ }
+
+ /**
+ * Gets include directory switch.
+ * @param includeDir String include directory
+ * @return String command switch to add specified directory to search path
+ */
+ protected String getIncludeDirSwitch(final String includeDir) {
+ return "";
+ }
+
+ /**
+ * Gets switch to define preprocessor macro.
+ * @param buffer StringBuffer command line argument
+ * @param define String macro name
+ * @param value String macro value, may be null.
+ */
+ protected void getDefineSwitch(final StringBuffer buffer,
+ final String define,
+ final String value) {
+ }
+
+ /**
+ * Gets switch to undefine preprocessor macro.
+ * @param buffer StringBuffer command line argument
+ * @param define String macro name
+ */
+ protected void getUndefineSwitch(final StringBuffer buffer,
+ final String define) {
+ }
+
+ /**
+ * Gets standard include paths.
+ * @return File[] standard include paths
+ */
+ protected File[] getEnvironmentIncludePath() {
+ return new File[0];
+ }
+
+ /**
+ * Gets linker associated with this type.
+ * @param type LinkType linker, returns ld.
+ * @return Linker
+ */
+ public Linker getLinker(final LinkType type) {
+ return LdLinker.getInstance();
+ }
+
+ /**
+ * Get total command line length due to the input file.
+ * @param outputDir File output directory
+ * @param inputFile String input file
+ * @return int characters added to command line for the input file.
+ */
+ protected int getTotalArgumentLengthForInputFile(final File outputDir,
+ final String inputFile) {
+ String arg1 = getInputFileArgument(outputDir, inputFile, 0);
+ String arg2 = getInputFileArgument(outputDir, inputFile, 1);
+ return arg1.length() + arg2.length() + 3;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/trolltech/MetaObjectParser.java b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/MetaObjectParser.java
new file mode 100644
index 0000000..e75a116
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/MetaObjectParser.java
@@ -0,0 +1,148 @@
+/*
+ *
+ * Copyright 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.trolltech;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import net.sf.antcontrib.cpptasks.parser.AbstractParser;
+import net.sf.antcontrib.cpptasks.parser.AbstractParserState;
+import net.sf.antcontrib.cpptasks.parser.LetterState;
+import net.sf.antcontrib.cpptasks.parser.WhitespaceOrLetterState;
+
+/**
+ * Scans a source file for Q_OBJECT.
+ *
+ * @author Curt Arnold
+ */
+public final class MetaObjectParser
+ extends AbstractParser {
+ /**
+ * Parser state that matches file T character.
+ */
+ private static final class FinalTState
+ extends AbstractParserState {
+ /**
+ * Parser.
+ */
+ private final MetaObjectParser mocParser;
+
+ /**
+ * Constructor.
+ * @param parser MetaObjectParser parser
+ */
+ public FinalTState(final MetaObjectParser parser) {
+ super(parser);
+ this.mocParser = parser;
+ }
+
+ /**
+ * Consumes a character and returns the next state for the parser.
+ *
+ * @param ch
+ * next character
+ * @return the configured nextState if ch is the expected character or the
+ * configure noMatchState otherwise.
+ */
+ public AbstractParserState consume(final char ch) {
+ if (ch == 'T') {
+ mocParser.setQObject(true);
+ return null;
+ }
+ if (ch == '\n') {
+ getParser().getNewLineState();
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Determines if source file contains Q_OBJECT.
+ * @param reader Reader source reader
+ * @throws IOException if unable to read source file
+ * @return boolean true if source contains Q_OBJECT
+ */
+ public static boolean hasQObject(final Reader reader) throws IOException {
+ MetaObjectParser parser = new MetaObjectParser();
+ parser.parse(reader);
+ return parser.hasQObject;
+
+ }
+
+ /**
+ * Has Q_OBJECT been encountered.
+ */
+ private boolean hasQObject = false;
+
+ /**
+ * Parser state for start of new line.
+ */
+ private AbstractParserState newLineState;
+
+ /**
+ * Constructor.
+ *
+ */
+ private MetaObjectParser() {
+ //
+ // search for Q_OBJECT
+ //
+ AbstractParserState t = new FinalTState(this);
+ AbstractParserState c = new LetterState(this, 'C', t, null);
+ AbstractParserState e = new LetterState(this, 'E', c, null);
+ AbstractParserState j = new LetterState(this, 'J', e, null);
+ AbstractParserState b = new LetterState(this, 'B', j, null);
+ AbstractParserState o = new LetterState(this, 'O', b, null);
+ AbstractParserState underline = new LetterState(this, '_', o, null);
+ newLineState = new WhitespaceOrLetterState(this, 'Q', underline);
+ }
+
+ /**
+ * Adds a filename to the list of included files.
+ *
+ * @param filename filename to be added
+ */
+ protected void addFilename(final String filename) {
+
+ }
+
+ /**
+ * Gets new line state.
+ * @return AbstractParserState new line state.
+ */
+ public AbstractParserState getNewLineState() {
+ return newLineState;
+ }
+
+ /**
+ * Parse input file.
+ * @param reader Reader source file
+ * @throws IOException if error reading source file
+ */
+ public void parse(final Reader reader) throws IOException {
+ hasQObject = false;
+ super.parse(reader);
+ }
+
+ /**
+ * Called FinalTState to set that Q_OBJECT was found.
+ * @param value boolean new value for hasQObject
+ */
+ public void setQObject(final boolean value) {
+ this.hasQObject = value;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/trolltech/UserInterfaceCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/UserInterfaceCompiler.java
new file mode 100644
index 0000000..cc4cf3b
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/UserInterfaceCompiler.java
@@ -0,0 +1,347 @@
+/*
+ *
+ * Copyright 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.trolltech;
+
+import java.io.File;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CCTask;
+import net.sf.antcontrib.cpptasks.OptimizationEnum;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler;
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.compiler.ProgressMonitor;
+import net.sf.antcontrib.cpptasks.gcc.LdLinker;
+import net.sf.antcontrib.cpptasks.parser.Parser;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Environment;
+
+/**
+ * Adapter for the Trolltech Qt UIC Compiler.
+ *
+ * @author Curt Arnold
+ */
+public final class UserInterfaceCompiler
+ extends CommandLineCompiler {
+ /**
+ * Singleton instance.
+ */
+ private static final UserInterfaceCompiler INSTANCE = new
+ UserInterfaceCompiler(
+ false, null);
+
+ /**
+ * Gets singleton instance of compiler.
+ * @return MetaObjectCompiler singleton instance
+ */
+ public static UserInterfaceCompiler getInstance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Constructor.
+ * @param newEnvironment boolean establish an new environment.
+ * @param env Environment environment.
+ */
+ private UserInterfaceCompiler(final boolean newEnvironment,
+ final Environment env) {
+ super("uic", "-version", new String[] {".ui"}
+ , new String[0], ".h", false, null, newEnvironment, env);
+ }
+
+ /**
+ * Add arguments for debug, etc.
+ * @param args Vector command argument list
+ * @param debug boolean build for debug if true
+ * @param multithreaded boolean build for multithreading if true
+ * @param exceptions boolean enable exceptions if true
+ * @param linkType LinkType output and runtime type
+ * @param rtti Boolean enable run-time type identification if true
+ * @param optimization OptimizationEnum optimization
+ */
+ protected void addImpliedArgs(final Vector args,
+ final boolean debug,
+ final boolean multithreaded,
+ final boolean exceptions,
+ final LinkType linkType,
+ final Boolean rtti,
+ final OptimizationEnum optimization) {
+ }
+
+ /**
+ * Add arguments for specified warning level.
+ * @param args Vector command line arguments
+ * @param level int warning level value
+ */
+ protected void addWarningSwitch(final Vector args, final int level) {
+ }
+
+ /**
+ * Change enviroment (deprecated).
+ * @param newEnvironment boolean use new environment.
+ * @param env Environment environment
+ * @return Processor modified processor
+ */
+ public Processor changeEnvironment(final boolean newEnvironment,
+ final Environment env) {
+ return this;
+ }
+
+ /**
+ * The include parser for C will work just fine, but we didn't want to
+ * inherit from CommandLineCCompiler.
+ * @param source source file to be parsed
+ * @return parser
+ */
+ protected Parser createParser(final File source) {
+ return new UserInterfaceParser();
+ }
+
+ /**
+ * Gets number of command line arguments per input file.
+ * @return int number of command line arguments per input file.
+ */
+ protected int getArgumentCountPerInputFile() {
+ return 3;
+ }
+
+ /**
+ * Gets output file names.
+ * @param inputFile String input file name
+ * @param versionInfo version info, not used by this compiler.
+ * @return String[] output file names
+ */
+ public String[] getOutputFileNames(final String inputFile,
+ final VersionInfo versionInfo) {
+ //
+ // if a recognized input file
+ //
+ String baseName = getBaseOutputName(inputFile);
+ return new String[] {
+ baseName + ".h",
+ baseName + ".cpp",
+ "moc_" + baseName + ".cpp"};
+ }
+
+ /**
+ * Gets input file arguments.
+ * @param outputDir File output directory
+ * @param filename String input file name.
+ * @param index int argument index,
+ * 0 to getNumberOfArgumentsPerInputFile() -1
+ * @return String input file argument
+ */
+ protected String getInputFileArgument(final File outputDir,
+ final String filename,
+ final int index) {
+ switch (index) {
+ case 0:
+ return "-o";
+
+ case 1:
+ String outputFileName = getOutputFileNames(filename, null)[0];
+ return new File(outputDir, outputFileName)
+ .toString();
+
+ case 2:
+ return filename;
+
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Gets maximum length of command line.
+ * @return int maximum length of command line
+ */
+ public int getMaximumCommandLength() {
+ return 1024;
+ }
+
+ /**
+ * Gets maximum number of input files processed per command.
+ * @return int maximum number of input files processed per command.
+ */
+ protected int getMaximumInputFilesPerCommand() {
+ return 1;
+ }
+
+ /**
+ * Gets include directory switch.
+ * @param includeDir String include directory
+ * @return String command switch to add specified directory to search path
+ */
+ protected String getIncludeDirSwitch(final String includeDir) {
+ return "";
+ }
+
+ /**
+ * Gets switch to define preprocessor macro.
+ * @param buffer StringBuffer command line argument
+ * @param define String macro name
+ * @param value String macro value, may be null.
+ */
+ protected void getDefineSwitch(final StringBuffer buffer,
+ final String define,
+ final String value) {
+ }
+
+ /**
+ * Gets switch to undefine preprocessor macro.
+ * @param buffer StringBuffer command line argument
+ * @param define String macro name
+ */
+ protected void getUndefineSwitch(final StringBuffer buffer,
+ final String define) {
+ }
+
+ /**
+ * Gets standard include paths.
+ * @return File[] standard include paths
+ */
+ protected File[] getEnvironmentIncludePath() {
+ return new File[0];
+ }
+
+ /**
+ * Gets linker associated with this type.
+ * @param type LinkType linker, returns ld.
+ * @return Linker
+ */
+ public Linker getLinker(final LinkType type) {
+ return LdLinker.getInstance();
+ }
+
+ /**
+ * Compiles an .ui file into the corresponding .h, .cpp and moc_*.cpp files.
+ * @param task current cc task
+ * @param outputDir output directory
+ * @param sourceFiles source files
+ * @param args command line arguments that appear before input files
+ * @param endArgs command line arguments that appear after input files
+ * @param relentless if true, do not stop at first compilation error
+ * @param config compiler configuration
+ * @param monitor progress monitor
+ */
+ public void compile(final CCTask task,
+ final File outputDir,
+ final String[] sourceFiles,
+ final String[] args,
+ final String[] endArgs,
+ final boolean relentless,
+ final CommandLineCompilerConfiguration config,
+ final ProgressMonitor monitor) {
+
+ BuildException exc = null;
+ String[] thisSource = new String[1];
+ String[] uicCommand = new String[args.length + endArgs.length + 4];
+ uicCommand[0] = "uic";
+ String[] uicImplCommand = new String[args.length + endArgs.length + 6];
+ uicImplCommand[0] = "uic";
+ String[] mocCommand = new String[args.length + endArgs.length + 4];
+ mocCommand[0] = "moc";
+ for (int i = 0; i < args.length; i++) {
+ uicCommand[i + 1] = args[i];
+ uicImplCommand[i + 1] = args[i];
+ mocCommand[i + i] = args[i];
+ }
+ uicCommand[args.length + 1] = "-o";
+ uicImplCommand[args.length + 1] = "-o";
+ mocCommand[args.length + 1] = "-o";
+
+ int uicIndex = args.length + 4;
+ int uicImplIndex = args.length + 6;
+ int mocIndex = args.length + 4;
+ for (int i = 0; i < endArgs.length; i++) {
+ uicCommand[uicIndex++] = endArgs[i];
+ uicImplCommand[uicImplIndex++] = endArgs[i];
+ mocCommand[mocIndex++] = endArgs[i];
+ }
+ for (int j = 0; j < sourceFiles.length; j++) {
+ uicIndex = args.length + 2;
+ uicImplIndex = args.length + 2;
+ mocIndex = args.length + 2;
+ String[] outputFileNames = getOutputFileNames(sourceFiles[j], null);
+
+ uicCommand[uicIndex++] = outputFileNames[0];
+ uicCommand[uicIndex++] = sourceFiles[j];
+
+ uicImplCommand[uicImplIndex++] = outputFileNames[1];
+ uicImplCommand[uicImplIndex++] = "-impl";
+ uicImplCommand[uicImplIndex++] = outputFileNames[0];
+ uicImplCommand[uicImplIndex++] = sourceFiles[j];
+
+ mocCommand[mocIndex++] = outputFileNames[2];
+ mocCommand[mocIndex++] = outputFileNames[0];
+
+ int retval = runCommand(task, outputDir, uicCommand);
+ if (retval == 0) {
+ retval = runCommand(task, outputDir, uicImplCommand);
+ if (retval == 0) {
+ retval = runCommand(task, outputDir, mocCommand);
+ }
+ }
+ if (monitor != null) {
+ thisSource[0] = sourceFiles[j];
+ monitor.progress(thisSource);
+ }
+ //
+ // if the process returned a failure code and
+ // we aren't holding an exception from an earlier
+ // interation
+ if (retval != 0 && exc == null) {
+ //
+ // construct the exception
+ //
+ exc = new BuildException(this.getCommand()
+ + " failed with return code " + retval, task
+ .getLocation());
+ //
+ // and throw it now unless we are relentless
+ //
+ if (!relentless) {
+ throw exc;
+ }
+ }
+ }
+ //
+ // if the compiler returned a failure value earlier
+ // then throw an exception
+ if (exc != null) {
+ throw exc;
+ }
+ }
+
+ /**
+ * Get total command line length due to the input file.
+ * @param outputDir File output directory
+ * @param inputFile String input file
+ * @return int characters added to command line for the input file.
+ */
+ protected int getTotalArgumentLengthForInputFile(
+ final File outputDir,
+ final String inputFile) {
+ String arg1 = getInputFileArgument(outputDir, inputFile, 1);
+ String arg2 = getInputFileArgument(outputDir, inputFile, 2);
+ return arg1.length() + arg2.length() + 4;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/trolltech/UserInterfaceParser.java b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/UserInterfaceParser.java
new file mode 100644
index 0000000..e3e309c
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/UserInterfaceParser.java
@@ -0,0 +1,67 @@
+/*
+ *
+ * Copyright 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.trolltech;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import net.sf.antcontrib.cpptasks.parser.Parser;
+
+/**
+ * Dependency scanner for Trolltech Qt User Interface definition files.
+ *
+ * .ui files are XML documents that may contain an include elements,
+ * however the includes are just copied to the generated files and
+ * and changes to the includes do not need to trigger rerunning uic.
+ *
+ * @author Curt Arnold
+ */
+public final class UserInterfaceParser
+ implements Parser {
+
+ /**
+ * Constructor.
+ *
+ */
+ public UserInterfaceParser() {
+ }
+
+ /**
+ * Adds filename to the list of included files.
+ *
+ * @param include String included file name
+ */
+ public void addFilename(final String include) {
+ }
+
+ /**
+ * Gets included files.
+ * @return String[] included files
+ */
+ public String[] getIncludes() {
+ return new String[0];
+ }
+
+ /**
+ * Parses source file for dependencies.
+ *
+ * @param reader Reader reader
+ * @throws IOException if error reading source file
+ */
+ public void parse(final Reader reader) throws IOException {
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/trolltech/package.html b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/package.html
new file mode 100644
index 0000000..c12d506
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/package.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+Copyright 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.
+
+-->
+</head>
+<body bgcolor="white">
+
+Adapters for Trolltech Qt moc and uic compilers.
+</body>
+</html>
+
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/CommandLineArgument.java b/src/main/java/net/sf/antcontrib/cpptasks/types/CommandLineArgument.java
new file mode 100644
index 0000000..e428469
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/types/CommandLineArgument.java
@@ -0,0 +1,104 @@
+/*
+ *
+ * Copyright 2001-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.types;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+/**
+ * An compiler/linker command line flag.
+ */
+public class CommandLineArgument {
+ /**
+ * Enumerated attribute with the values "start", "mid" and "end",
+ */
+ public static class LocationEnum extends EnumeratedAttribute {
+ public String[] getValues() {
+ return new String[]{"start", "mid", "end"};
+ }
+ }
+ private String ifCond;
+ private int location;
+ private String unlessCond;
+ private String value;
+ public CommandLineArgument() {
+ }
+ public int getLocation() {
+ return location;
+ }
+ public String getValue() {
+ return value;
+ }
+ /**
+ * Returns true if the define's if and unless conditions (if any) are
+ * satisfied.
+ */
+ public boolean isActive(org.apache.tools.ant.Project p) {
+ if (value == null) {
+ return false;
+ }
+ if (ifCond != null && p.getProperty(ifCond) == null) {
+ return false;
+ } else if (unlessCond != null && p.getProperty(unlessCond) != null) {
+ return false;
+ }
+ return true;
+ }
+ /**
+ * Sets the property name for the 'if' condition.
+ *
+ * The argument will be ignored unless the property is defined.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") will throw an exception when
+ * evaluated.
+ */
+ public void setIf(String propName) {
+ ifCond = propName;
+ }
+ /**
+ * Specifies relative location of argument on command line. "start" will
+ * place argument at start of command line, "mid" will place argument after
+ * all "start" arguments but before filenames, "end" will place argument
+ * after filenames.
+ *
+ */
+ public void setLocation(LocationEnum location) {
+ this.location = location.getIndex();
+ }
+ /**
+ * Set the property name for the 'unless' condition.
+ *
+ * If named property is set, the argument will be ignored.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") of the behavior will throw an
+ * exception when evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public void setUnless(String propName) {
+ unlessCond = propName;
+ }
+ /**
+ * Specifies the string that should appear on the command line. The
+ * argument will be quoted if it contains embedded blanks. Use multiple
+ * arguments to avoid quoting.
+ *
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/CompilerArgument.java b/src/main/java/net/sf/antcontrib/cpptasks/types/CompilerArgument.java
new file mode 100644
index 0000000..2137186
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/types/CompilerArgument.java
@@ -0,0 +1,28 @@
+/*
+ *
+ * Copyright 2001-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.types;
+/**
+ * A compiler command line argument.
+ */
+public class CompilerArgument extends CommandLineArgument {
+ public CompilerArgument() {
+ }
+ public void execute() throws org.apache.tools.ant.BuildException {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/ConditionalFileSet.java b/src/main/java/net/sf/antcontrib/cpptasks/types/ConditionalFileSet.java
new file mode 100644
index 0000000..7bc22ee
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/types/ConditionalFileSet.java
@@ -0,0 +1,84 @@
+/*
+ *
+ * Copyright 2001-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.types;
+import net.sf.antcontrib.cpptasks.CUtil;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.AbstractFileSet;
+import org.apache.tools.ant.types.FileSet;
+/**
+ * An Ant FileSet object augmented with if and unless conditions.
+ *
+ * @author Curt Arnold
+ */
+public class ConditionalFileSet extends FileSet {
+ private String ifCond;
+ private String unlessCond;
+ public ConditionalFileSet() {
+ }
+ public void execute() throws org.apache.tools.ant.BuildException {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+ /**
+ * overrides FileSet's implementation which would throw an exception since
+ * the referenced object isn't this type.
+ */
+ protected AbstractFileSet getRef(Project p) {
+ return (AbstractFileSet) ref.getReferencedObject(p);
+ }
+ /**
+ * Returns true if the Path's if and unless conditions (if any) are
+ * satisfied.
+ */
+ public boolean isActive() throws BuildException {
+ Project p = getProject();
+ if (p == null) {
+ throw new java.lang.IllegalStateException(
+ "setProject() should have been called");
+ }
+ return CUtil.isActive(p, ifCond, unlessCond);
+ }
+ /**
+ * Sets the property name for the 'if' condition.
+ *
+ * The fileset will be ignored unless the property is defined.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") will throw an exception when
+ * evaluated.
+ */
+ public void setIf(String propName) {
+ ifCond = propName;
+ }
+ /**
+ * Set the property name for the 'unless' condition.
+ *
+ * If named property is set, the fileset will be ignored.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") of the behavior will throw an
+ * exception when evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public void setUnless(String propName) {
+ unlessCond = propName;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/ConditionalPath.java b/src/main/java/net/sf/antcontrib/cpptasks/types/ConditionalPath.java
new file mode 100644
index 0000000..ae45eaa
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/types/ConditionalPath.java
@@ -0,0 +1,75 @@
+/*
+ *
+ * Copyright 2001-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.types;
+import net.sf.antcontrib.cpptasks.CUtil;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+/**
+ * An Ant Path object augmented with if and unless conditionals
+ *
+ * @author Curt Arnold
+ */
+public class ConditionalPath extends Path {
+ private String ifCond;
+ private String unlessCond;
+ public ConditionalPath(Project project) {
+ super(project);
+ }
+ public ConditionalPath(Project p, String path) {
+ super(p, path);
+ }
+ /**
+ * Returns true if the Path's if and unless conditions (if any) are
+ * satisfied.
+ */
+ public boolean isActive(org.apache.tools.ant.Project p)
+ throws BuildException {
+ return CUtil.isActive(p, ifCond, unlessCond);
+ }
+ /**
+ * Sets the property name for the 'if' condition.
+ *
+ * The path will be ignored unless the property is defined.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") will throw an exception when
+ * evaluated.
+ *
+ * @param propName
+ * property name
+ */
+ public void setIf(String propName) {
+ ifCond = propName;
+ }
+ /**
+ * Set the property name for the 'unless' condition.
+ *
+ * If named property is set, the path will be ignored.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") of the behavior will throw an
+ * exception when evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public void setUnless(String propName) {
+ unlessCond = propName;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/DefineArgument.java b/src/main/java/net/sf/antcontrib/cpptasks/types/DefineArgument.java
new file mode 100644
index 0000000..5118e79
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/types/DefineArgument.java
@@ -0,0 +1,38 @@
+/*
+ *
+ * Copyright 2001-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.types;
+/**
+ * Preprocessor macro definition.
+ *
+ * @author Mark A Russell <a
+ * href="mailto:mark_russell@csgsystems.com">mark_russell@csg_systems.com
+ * </a>
+ */
+public class DefineArgument extends UndefineArgument {
+ private String value;
+ public DefineArgument() {
+ super(true);
+ }
+ /** Returns the value of the define */
+ public final String getValue() {
+ return value;
+ }
+ /** Set the value attribute */
+ public final void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/DefineSet.java b/src/main/java/net/sf/antcontrib/cpptasks/types/DefineSet.java
new file mode 100644
index 0000000..f3ab44b
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/types/DefineSet.java
@@ -0,0 +1,199 @@
+/*
+ *
+ * Copyright 2001-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.types;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Reference;
+/**
+ * Set of preprocessor macro defines and undefines.
+ *
+ * @author Mark A Russell <a
+ * href="mailto:mark_russell@csgsystems.com">mark_russell@csg_systems.com
+ * </a>
+ * @author Adam Murdoch
+ */
+public class DefineSet extends DataType {
+ private Vector defineList = new Vector();
+ private String ifCond = null;
+ private String unlessCond = null;
+ /**
+ *
+ * Adds a define element.
+ *
+ * @throws BuildException
+ * if reference
+ */
+ public void addDefine(DefineArgument arg) throws BuildException {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ defineList.addElement(arg);
+ }
+ /** Adds defines/undefines. */
+ private void addDefines(String[] defs, boolean isDefine) {
+ for (int i = 0; i < defs.length; i++) {
+ UndefineArgument def;
+ if (isDefine) {
+ def = new DefineArgument();
+ } else {
+ def = new UndefineArgument();
+ }
+ def.setName(defs[i]);
+ defineList.addElement(def);
+ }
+ }
+ /**
+ *
+ * Adds an undefine element.
+ *
+ * @throws BuildException
+ * if reference
+ */
+ public void addUndefine(UndefineArgument arg) throws BuildException {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ defineList.addElement(arg);
+ }
+ public void execute() throws org.apache.tools.ant.BuildException {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+ /** Returns the defines and undefines in this set. */
+ public UndefineArgument[] getDefines() throws BuildException {
+ if (isReference()) {
+ DefineSet defset = (DefineSet) getCheckedRef(DefineSet.class,
+ "DefineSet");
+ return defset.getDefines();
+ } else {
+ if (isActive()) {
+ UndefineArgument[] defs = new UndefineArgument[defineList
+ .size()];
+ defineList.copyInto(defs);
+ return defs;
+ } else {
+ return new UndefineArgument[0];
+ }
+ }
+ }
+ /**
+ * Returns true if the define's if and unless conditions (if any) are
+ * satisfied.
+ *
+ * @exception BuildException
+ * throws build exception if name is not set
+ */
+ public final boolean isActive() throws BuildException {
+ return CUtil.isActive(getProject(), ifCond, unlessCond);
+ }
+ /**
+ * A comma-separated list of preprocessor macros to define. Use nested
+ * define elements to define macro values.
+ *
+ * @param defList
+ * comma-separated list of preprocessor macros
+ * @throws BuildException
+ * throw if defineset is a reference
+ */
+ public void setDefine(CUtil.StringArrayBuilder defList)
+ throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ addDefines(defList.getValue(), true);
+ }
+ /**
+ * Sets a description of the current data type.
+ */
+ public void setDescription(String desc) {
+ super.setDescription(desc);
+ }
+ /**
+ * Sets an id that can be used to reference this element.
+ *
+ * @param id
+ * id
+ */
+ public void setId(String id) {
+ //
+ // this is actually accomplished by a different
+ // mechanism, but we can document it
+ //
+ }
+ /**
+ * Sets the property name for the 'if' condition.
+ *
+ * The define will be ignored unless the property is defined.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") will throw an exception when
+ * evaluated.
+ *
+ * @param propName
+ * property name
+ */
+ public final void setIf(String propName) {
+ ifCond = propName;
+ }
+ /**
+ * Specifies that this element should behave as if the content of the
+ * element with the matching id attribute was inserted at this location. If
+ * specified, no other attributes or child content should be specified,
+ * other than "description".
+ *
+ */
+ public void setRefid(Reference r) throws BuildException {
+ if (!defineList.isEmpty()) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+ /**
+ * A comma-separated list of preprocessor macros to undefine.
+ *
+ * @param undefList
+ * comma-separated list of preprocessor macros
+ * @throws BuildException
+ * throw if defineset is a reference
+ */
+ public void setUndefine(CUtil.StringArrayBuilder undefList)
+ throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ addDefines(undefList.getValue(), false);
+ }
+ /**
+ * Set the property name for the 'unless' condition.
+ *
+ * If named property is set, the define will be ignored.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") of the behavior will throw an
+ * exception when evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public final void setUnless(String propName) {
+ unlessCond = propName;
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/FlexLong.java b/src/main/java/net/sf/antcontrib/cpptasks/types/FlexLong.java
new file mode 100644
index 0000000..f710aa3
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/types/FlexLong.java
@@ -0,0 +1,59 @@
+/*
+ *
+ * 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.types;
+import java.lang.reflect.Method;
+
+/**
+ * Helper class which can be used for Ant task attribute setter methods to
+ * allow the build file to specify a long in either decimal, octal, or
+ * hexadecimal format.
+ * // FlexInteger author
+ * @author Erik Hatcher
+ * @see org.apache.tools.ant.types.FlexInteger
+ */
+public class FlexLong {
+ private Long value;
+ /**
+ * Constructor used by Ant's introspection mechanism for attribute
+ * population
+ */
+ public FlexLong(String value) {
+ // Java 1.1 did not support Long.decode().. so we call it by
+ // reflection.
+ try {
+ Method m = Long.class
+ .getMethod("decode", new Class[]{String.class});
+ Object rc = m.invoke(null, new Object[]{value});
+ this.value = (Long) rc;
+ } catch (Exception e) {
+ // Try it the old fashioned way, we must be on a 1.1 jre
+ this.value = new Long(value);
+ }
+ }
+ /**
+ * Returns the decimal integer value
+ */
+ public long longValue() {
+ return value.longValue();
+ }
+ /**
+ * Overridden method to return the decimal value for display
+ */
+ public String toString() {
+ return value.toString();
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/IncludePath.java b/src/main/java/net/sf/antcontrib/cpptasks/types/IncludePath.java
new file mode 100644
index 0000000..e4c8414
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/types/IncludePath.java
@@ -0,0 +1,38 @@
+/*
+ *
+ * Copyright 2001-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.types;
+import org.apache.tools.ant.Project;
+/**
+ * An include path.
+ *
+ * Works like other paths in Ant with with the addition of "if" and "unless"
+ * conditions.
+ *
+ * @author Curt Arnold
+ */
+public class IncludePath extends ConditionalPath {
+ public IncludePath(Project project) {
+ super(project);
+ }
+ public IncludePath(Project p, String path) {
+ super(p, path);
+ }
+ public void execute() throws org.apache.tools.ant.BuildException {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/LibrarySet.java b/src/main/java/net/sf/antcontrib/cpptasks/types/LibrarySet.java
new file mode 100644
index 0000000..acac911
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/types/LibrarySet.java
@@ -0,0 +1,347 @@
+/*
+ *
+ * Copyright 2001-2006 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.types;
+import java.io.File;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+import net.sf.antcontrib.cpptasks.FileVisitor;
+import net.sf.antcontrib.cpptasks.compiler.Linker;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.PatternSet;
+/**
+ * A set of library names. Libraries can also be added to a link by specifying
+ * them in a fileset.
+ *
+ * For most Unix-like compilers, libset will result in a series of -l and -L
+ * linker arguments. For Windows compilers, the library names will be used to
+ * locate the appropriate library files which will be added to the linkers
+ * input file list as if they had been specified in a fileset.
+ *
+ * @author Mark A Russell <a
+ * href="mailto:mark_russell@csgsystems.com">mark_russell@csg_systems.com
+ * </a>
+ * @author Adam Murdoch
+ * @author Curt Arnold
+ */
+public class LibrarySet extends DataType {
+ private String dataset;
+ private boolean explicitCaseSensitive;
+ private String ifCond;
+ private String[] libnames;
+ private final FileSet set = new FileSet();
+ private String unlessCond;
+ private LibraryTypeEnum libraryType;
+ public LibrarySet() {
+ libnames = new String[0];
+ }
+ public void execute() throws org.apache.tools.ant.BuildException {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+ /**
+ * Gets the dataset. Used on OS390 if the libs are in a dataset.
+ *
+ * @return Returns a String
+ */
+ public String getDataset() {
+ if (isReference()) {
+ LibrarySet master = ((LibrarySet) getCheckedRef(LibrarySet.class, "LibrarySet"));
+ return master.getDataset();
+ }
+ return dataset;
+ }
+ public File getDir(final Project project) {
+ if (isReference()) {
+ LibrarySet master = ((LibrarySet) getCheckedRef(LibrarySet.class, "LibrarySet"));
+ return master.getDir(project);
+ }
+ return set.getDir(project);
+ }
+ protected FileSet getFileSet() {
+ if (isReference()) {
+ LibrarySet master = ((LibrarySet) getCheckedRef(LibrarySet.class, "LibrarySet"));
+ return master.getFileSet();
+ }
+ return set;
+ }
+ public String[] getLibs() {
+ if (isReference()) {
+ LibrarySet master = ((LibrarySet) getCheckedRef(LibrarySet.class, "LibrarySet"));
+ return master.getLibs();
+ }
+ String[] retval = (String[]) libnames.clone();
+ return retval;
+ }
+
+ /**
+ * Gets preferred library type
+ *
+ * @return library type, may be null.
+ */
+ public LibraryTypeEnum getType() {
+ if (isReference()) {
+ LibrarySet master = ((LibrarySet) getCheckedRef(LibrarySet.class, "LibrarySet"));
+ return master.getType();
+ }
+ return libraryType;
+ }
+ /**
+ * Returns true if the define's if and unless conditions (if any) are
+ * satisfied.
+ */
+ public boolean isActive(final org.apache.tools.ant.Project p) {
+ if (p == null) {
+ throw new NullPointerException("p");
+ }
+ if (ifCond != null) {
+ String ifValue = p.getProperty(ifCond);
+ if (ifValue != null) {
+ if (ifValue.equals("no") || ifValue.equals("false")) {
+ throw new BuildException(
+ "property "
+ + ifCond
+ + " used as if condition has value "
+ + ifValue
+ + " which suggests a misunderstanding of if attributes");
+ }
+ } else {
+ return false;
+ }
+ }
+ if (unlessCond != null) {
+ String unlessValue = p.getProperty(unlessCond);
+ if (unlessValue != null) {
+ if (unlessValue.equals("no") || unlessValue.equals("false")) {
+ throw new BuildException(
+ "property "
+ + unlessCond
+ + " used as unless condition has value "
+ + unlessValue
+ + " which suggests a misunderstanding of unless attributes");
+ }
+ return false;
+ }
+ }
+ if (isReference()) {
+ LibrarySet master = ((LibrarySet) getCheckedRef(LibrarySet.class, "LibrarySet"));
+ return master.isActive(project);
+ }
+ if (libnames.length == 0) {
+ p.log("libnames not specified or empty.", Project.MSG_WARN);
+ return false;
+ }
+ return true;
+ }
+ /**
+ * Sets case sensitivity of the file system. If not set, will default to
+ * the linker's case sensitivity.
+ *
+ * @param isCaseSensitive
+ * "true"|"on"|"yes" if file system is case sensitive,
+ * "false"|"off"|"no" when not.
+ */
+ public void setCaseSensitive(final boolean isCaseSensitive) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ explicitCaseSensitive = true;
+ set.setCaseSensitive(isCaseSensitive);
+ }
+ /**
+ * Sets the dataset. Used on OS390 if the libs are in a dataset.
+ *
+ * @param dataset
+ * The dataset to set
+ */
+ public void setDataset(final String dataset) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.dataset = dataset;
+ }
+ /**
+ * Library directory.
+ *
+ * @param dir
+ * library directory
+ *
+ */
+ public void setDir(final File dir) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ set.setDir(dir);
+ }
+ /**
+ * Sets the property name for the 'if' condition.
+ *
+ * The library set will be ignored unless the property is defined.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") will throw an exception when
+ * evaluated.
+ *
+ * @param propName
+ * property name
+ */
+ public void setIf(String propName) {
+ ifCond = propName;
+ }
+ /**
+ * Comma-separated list of library names without leading prefixes, such as
+ * "lib", or extensions, such as ".so" or ".a".
+ *
+ */
+ public void setLibs(final CUtil.StringArrayBuilder libs) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ libnames = libs.getValue();
+ //
+ // earlier implementations would warn of suspicious library names
+ // (like libpthread for pthread or kernel.lib for kernel).
+ // visitLibraries now provides better feedback and ld type linkers
+ // should provide adequate feedback so the check here is not necessary.
+ }
+ public void setProject(final Project project) {
+ set.setProject(project);
+ super.setProject(project);
+ }
+ /**
+ * Set the property name for the 'unless' condition.
+ *
+ * If named property is set, the library set will be ignored.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") of the behavior will throw an
+ * exception when evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public void setUnless(String propName) {
+ unlessCond = propName;
+ }
+
+ /**
+ * Sets the preferred library type. Supported values "shared", "static", and
+ * "framework". "framework" is equivalent to "shared" on non-Darwin platforms.
+ */
+ public void setType(final LibraryTypeEnum type) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.libraryType = type;
+ }
+
+ public void visitLibraries(final Project project,
+ final Linker linker,
+ final File[] libpath,
+ final FileVisitor visitor) throws BuildException {
+ if (isReference()) {
+ LibrarySet master = ((LibrarySet) getCheckedRef(LibrarySet.class, "LibrarySet"));
+ master.visitLibraries(project, linker, libpath, visitor);
+ }
+ //
+ // if there was a libs attribute then
+ // add the corresponding patterns to the FileSet
+ //
+ if (libnames != null) {
+ for (int i = 0; i < libnames.length; i++) {
+ String[] patterns = linker.getLibraryPatterns(new String[] { libnames[i] }, libraryType);
+ if (patterns.length > 0) {
+ FileSet localSet = (FileSet) set.clone();
+ //
+ // unless explicitly set
+ // will default to the linker case sensitivity
+ //
+ if (!explicitCaseSensitive) {
+ boolean linkerCaseSensitive = linker.isCaseSensitive();
+ localSet.setCaseSensitive(linkerCaseSensitive);
+ }
+ //
+ // add all the patterns for this libname
+ //
+ for (int j = 0; j < patterns.length; j++) {
+ PatternSet.NameEntry entry = localSet.createInclude();
+ entry.setName(patterns[j]);
+ }
+ int matches = 0;
+ //
+ // if there was no specified directory then
+ // run through the libpath backwards
+ //
+ if (localSet.getDir(project) == null) {
+ //
+ // scan libpath in reverse order
+ // to give earlier entries priority
+ //
+ for (int j = libpath.length - 1; j >= 0; j--) {
+ FileSet clone = (FileSet) localSet.clone();
+ clone.setDir(libpath[j]);
+ DirectoryScanner scanner = clone.getDirectoryScanner(project);
+ File basedir = scanner.getBasedir();
+ String[] files = scanner.getIncludedFiles();
+ matches += files.length;
+ for (int k = 0; k < files.length; k++) {
+ visitor.visit(basedir, files[k]);
+ }
+ }
+ } else {
+ DirectoryScanner scanner = localSet.getDirectoryScanner(project);
+ File basedir = scanner.getBasedir();
+ String[] files = scanner.getIncludedFiles();
+ matches += files.length;
+ for (int k = 0; k < files.length; k++) {
+ visitor.visit(basedir, files[k]);
+ }
+ }
+ //
+ // TODO: following section works well for Windows
+ // style linkers but unnecessary fails
+ // Unix style linkers. Will need to revisit.
+ //
+ if (matches == 0 && false) {
+ StringBuffer msg = new StringBuffer("No file matching ");
+ if (patterns.length == 1) {
+ msg.append("pattern (");
+ msg.append(patterns[0]);
+ msg.append(")");
+ } else {
+ msg.append("patterns (\"");
+ msg.append(patterns[0]);
+ for (int k = 1; k < patterns.length; k++) {
+ msg.append(", ");
+ msg.append(patterns[k]);
+ }
+ msg.append(")");
+ }
+ msg.append(" for library name \"");
+ msg.append(libnames[i]);
+ msg.append("\" was found.");
+ throw new BuildException(msg.toString());
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/LibraryTypeEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/types/LibraryTypeEnum.java
new file mode 100644
index 0000000..c0af5f8
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/types/LibraryTypeEnum.java
@@ -0,0 +1,48 @@
+/*
+ *
+ * Copyright 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.types;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+/**
+ * Enumeration of library types for LibrarySet
+ *
+ * @author Curt Arnold
+ *
+ */
+public class LibraryTypeEnum extends EnumeratedAttribute {
+ /**
+ * Constructor
+ *
+ * Set by default to "shared"
+ *
+ * @see java.lang.Object#Object()
+ */
+ public LibraryTypeEnum() {
+ setValue("shared");
+ }
+ /**
+ * Gets list of acceptable values
+ *
+ * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues()
+ */
+ public String[] getValues() {
+ return new String[]{"shared", // prefer shared libraries
+ "static", // prefer static libraries
+ "framework" // framework libraries (Mac OS/X)
+ // equiv to shared on other platforms
+ };
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/LinkerArgument.java b/src/main/java/net/sf/antcontrib/cpptasks/types/LinkerArgument.java
new file mode 100644
index 0000000..bee15cf
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/types/LinkerArgument.java
@@ -0,0 +1,28 @@
+/*
+ *
+ * Copyright 2001-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.types;
+/**
+ * A linker command line argument.
+ */
+public class LinkerArgument extends CommandLineArgument {
+ public LinkerArgument() {
+ }
+ public void execute() throws org.apache.tools.ant.BuildException {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/SystemIncludePath.java b/src/main/java/net/sf/antcontrib/cpptasks/types/SystemIncludePath.java
new file mode 100644
index 0000000..37a3e28
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/types/SystemIncludePath.java
@@ -0,0 +1,45 @@
+/*
+ *
+ * Copyright 2001-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.types;
+import org.apache.tools.ant.Project;
+/**
+ * A system include path.
+ *
+ * Files located using a system include path will not participate in dependency
+ * analysis.
+ *
+ * Standard include paths for a compiler should not be specified since these
+ * should be determined from environment variables or configuration files by
+ * the compiler adapter.
+ *
+ * Works like other paths in Ant with with the addition of "if" and "unless"
+ * conditions.
+ *
+ * @author Curt Arnold
+ */
+public class SystemIncludePath extends ConditionalPath {
+ public SystemIncludePath(Project project) {
+ super(project);
+ }
+ public SystemIncludePath(Project p, String path) {
+ super(p, path);
+ }
+ public void execute() throws org.apache.tools.ant.BuildException {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/SystemLibrarySet.java b/src/main/java/net/sf/antcontrib/cpptasks/types/SystemLibrarySet.java
new file mode 100644
index 0000000..97c4fa2
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/types/SystemLibrarySet.java
@@ -0,0 +1,37 @@
+/*
+ *
+ * Copyright 2001-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.types;
+/**
+ * A set of system library names. Timestamp or location of system libraries are
+ * not considered in dependency analysis.
+ *
+ * Libraries can also be added to a link by specifying them in a fileset.
+ *
+ * For most Unix-like compilers, syslibset will result in a series of -l and -L
+ * linker arguments. For Windows compilers, the library names will be used to
+ * locate the appropriate library files which will be added to the linkers
+ * input file list as if they had been specified in a fileset.
+ */
+public class SystemLibrarySet extends LibrarySet {
+ public SystemLibrarySet() {
+ super();
+ }
+ public void execute() throws org.apache.tools.ant.BuildException {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/UndefineArgument.java b/src/main/java/net/sf/antcontrib/cpptasks/types/UndefineArgument.java
new file mode 100644
index 0000000..aa958ef
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/types/UndefineArgument.java
@@ -0,0 +1,153 @@
+/*
+ *
+ * Copyright 2001-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.types;
+import java.util.Vector;
+
+import net.sf.antcontrib.cpptasks.CUtil;
+
+import org.apache.tools.ant.BuildException;
+/**
+ * Preprocessor macro undefinition.
+ *
+ * @author Mark A Russell <a
+ * href="mailto:mark_russell@csgsystems.com">mark_russell@csg_systems.com
+ * </a>
+ */
+public class UndefineArgument {
+ /**
+ * This method returns an array of UndefineArgument and DefineArgument's by
+ * merging a base list with an override list.
+ *
+ * Any define in the base list with a name that appears in the override
+ * list is suppressed. All entries in the override list are preserved
+ *
+ */
+ public static UndefineArgument[] merge(UndefineArgument[] base,
+ UndefineArgument[] override) {
+ if (base.length == 0) {
+ UndefineArgument[] overrideClone = (UndefineArgument[]) override
+ .clone();
+ return overrideClone;
+ }
+ if (override.length == 0) {
+ UndefineArgument[] baseClone = (UndefineArgument[]) base.clone();
+ return baseClone;
+ }
+ Vector unduplicated = new Vector(base.length);
+ for (int i = 0; i < base.length; i++) {
+ UndefineArgument current = base[i];
+ String currentName = current.getName();
+ boolean match = false;
+ if (currentName == null) {
+ match = true;
+ } else {
+ for (int j = 0; j < override.length; j++) {
+ UndefineArgument over = override[j];
+ String overName = over.getName();
+ if (overName != null && overName.equals(currentName)) {
+ match = true;
+ break;
+ }
+ }
+ }
+ if (!match) {
+ unduplicated.addElement(current);
+ }
+ }
+ UndefineArgument[] combined = new UndefineArgument[unduplicated.size()
+ + override.length];
+ unduplicated.copyInto(combined);
+ int offset = unduplicated.size();
+ for (int i = 0; i < override.length; i++) {
+ combined[offset + i] = override[i];
+ }
+ return combined;
+ }
+ private boolean define = false;
+ private String ifCond;
+ private String name;
+ private String unlessCond;
+ public UndefineArgument() {
+ }
+ protected UndefineArgument(boolean isDefine) {
+ this.define = isDefine;
+ }
+ public void execute() throws org.apache.tools.ant.BuildException {
+ throw new org.apache.tools.ant.BuildException(
+ "Not an actual task, but looks like one for documentation purposes");
+ }
+ /** Returns the name of the define */
+ public final String getName() {
+ return name;
+ }
+ /** Returns the value of the define */
+ public String getValue() {
+ return null;
+ }
+ /**
+ * Returns true if the define's if and unless conditions (if any) are
+ * satisfied.
+ *
+ * @exception BuildException
+ * throws build exception if name is not set
+ */
+ public final boolean isActive(org.apache.tools.ant.Project p)
+ throws BuildException {
+ if (name == null) {
+ throw new BuildException("<define> is missing name attribute");
+ }
+ return CUtil.isActive(p, ifCond, unlessCond);
+ }
+ /** Returns true if this is a define, false if an undefine. */
+ public final boolean isDefine() {
+ return define;
+ }
+ /**
+ * Sets the property name for the 'if' condition.
+ *
+ * The define will be ignored unless the property is defined.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") will throw an exception when
+ * evaluated.
+ *
+ * @param propName
+ * property name
+ */
+ public final void setIf(String propName) {
+ ifCond = propName;
+ }
+ /** Set the name attribute */
+ public final void setName(String name) {
+ this.name = name;
+ }
+ /**
+ * Set the property name for the 'unless' condition.
+ *
+ * If named property is set, the define will be ignored.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") of the behavior will throw an
+ * exception when evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public final void setUnless(String propName) {
+ unlessCond = propName;
+ }
+}