diff -Nru gluegen2-2.2.4/.classpath gluegen2-2.3.2/.classpath --- gluegen2-2.2.4/.classpath 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/.classpath 2015-10-09 04:18:28.000000000 +0000 @@ -21,9 +21,11 @@ + + - + diff -Nru gluegen2-2.2.4/debian/changelog gluegen2-2.3.2/debian/changelog --- gluegen2-2.2.4/debian/changelog 2014-11-14 21:59:41.000000000 +0000 +++ gluegen2-2.3.2/debian/changelog 2015-10-29 12:55:10.000000000 +0000 @@ -1,3 +1,71 @@ +gluegen2 (2.3.2-3) unstable; urgency=medium + + * Team upload. + * Upload to unstable. + * Fix support for architectures s390x, powerpc, ppc64el, and armhf + (closes: #779482): + - New patch s390x-support.diff: add support for s390x. + - Simplify patch ppc64el-support.diff: the preferred pagesize is + the runtime one, then no need to define the size_ppc_64_unix + record where only the pagesize is different from size_lp64_unix. + - d/rules: drop useless DEB_ANT_BUILD_TARGET override which + disabled test cases build for armhf. + + -- Gilles Filippini Tue, 27 Oct 2015 11:34:36 +0100 + +gluegen2 (2.3.2-2) experimental; urgency=medium + + * Team upload. + * Patch tests.diff: restore missing part mistakenly dropped in + previous release. + * Patch fix-arm64-build-config.diff: fix jre native libs path for + arm64. + * d/rules: simplify the test suite launch. + + -- Gilles Filippini Thu, 15 Oct 2015 10:03:21 +0200 + +gluegen2 (2.3.2-1) experimental; urgency=medium + + [ tony mancill ] + * Make the build-dep on default-jdk versioned on >= 2:1.6. + This prevents attempts to build on non-openjdk architectures. + + [ Gilles Filippini ] + * Team upload. + * New upstream release. + * Refresh patches. + * New patch disable-static-linking.diff. + * Patch missing-arch-symbol.diff: don't check at all for specific + glibc symbol version in glibc-compat-symbols.h (fix FTBFS on + armel and arm64). + + -- Gilles Filippini Mon, 12 Oct 2015 10:59:34 +0200 + +gluegen2 (2.3.1-2) experimental; urgency=medium + + * Team upload. + * WIP fixing ppc64el usability: + - New patch: ppc64el-support.diff + - Merge patch fix-ppc64-build-config.patch into ppc64el-support.diff + - New patch fix-arm64-build-config.patch to gathers aarch64 snippets + previously in fix-ppc64-build-config.patch. + * Run the test suite at build time: + - Patch tests.diff + - debian/rules adapted accordingly + - Failed tests don't make the build fail. + + -- Gilles Filippini Sun, 11 Oct 2015 00:28:38 +0200 + +gluegen2 (2.3.1-1) experimental; urgency=medium + + * Team upload. + * New upstream release. (Closes: #791992, #746493, #791993) + * Add build-dep on jsr305-java. + * Update debian/copyright and debian/README.source to document jcpp. + * Update debian/copyright to assign Expat license to debian/*. + + -- tony mancill Thu, 08 Oct 2015 19:49:11 -0700 + gluegen2 (2.2.4-2) unstable; urgency=medium * Team upload. diff -Nru gluegen2-2.2.4/debian/control gluegen2-2.3.2/debian/control --- gluegen2-2.2.4/debian/control 2014-11-14 21:59:41.000000000 +0000 +++ gluegen2-2.3.2/debian/control 2015-10-27 09:53:18.000000000 +0000 @@ -3,9 +3,9 @@ Priority: optional Maintainer: Debian Java Maintainers Uploaders: Sylvestre Ledru -Build-Depends: debhelper (>= 9), cdbs, quilt, default-jdk, +Build-Depends: debhelper (>= 9), cdbs, quilt, default-jdk (>= 2:1.6), ant, junit4, ant-contrib-cpptasks, ant-optional, libantlr-java, - ant-contrib + ant-contrib, libjsr305-java Standards-Version: 3.9.6 Vcs-Git: git://anonscm.debian.org/pkg-java/gluegen2.git Vcs-Browser: http://anonscm.debian.org/cgit/pkg-java/gluegen2.git diff -Nru gluegen2-2.2.4/debian/copyright gluegen2-2.3.2/debian/copyright --- gluegen2-2.2.4/debian/copyright 2014-11-14 21:59:41.000000000 +0000 +++ gluegen2-2.3.2/debian/copyright 2015-10-27 09:53:18.000000000 +0000 @@ -1,9 +1,6 @@ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Source: http://jogamp.org -Files: debian/* -Copyright: 2010-2014, Sylvestre Ledru - Files: * Copyright: 2003-2005, Sun Microsystems, Inc. 2010, JogAmp Community. @@ -117,3 +114,43 @@ Neither the name of Sun Microsystems, Inc. or the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +Files: jcpp/* +Copyright: 2007-2008, Shevek +Comment: As noted by upstream: + This branch is modified for JogAmp + to supply [GlueGen](http://jogamp.org/gluegen/www/) with JCPP. + . + This branch is only intended as a submodule for GlueGen + and hence must be [build from within GlueGen] + (http://jogamp.org/gluegen/doc/HowToBuild.html). + . + # Original JCPP Version + * [Homepage](http://www.anarres.org/projects/jcpp/) + * [GitHub](https://github.com/shevek/jcpp.git) +License: Apache-2.0 + On Debian systems, the complete text of the Apache 2.0 License + can be found in the `/usr/share/common-licenses/Apache-2.0' file. + +Files: debian/* +Copyright: 2010-2014, Sylvestre Ledru + 2013-2015, tony mancill +License: Expat + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + . + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff -Nru gluegen2-2.2.4/debian/orig-tar.sh gluegen2-2.3.2/debian/orig-tar.sh --- gluegen2-2.2.4/debian/orig-tar.sh 2014-11-14 21:59:41.000000000 +0000 +++ gluegen2-2.3.2/debian/orig-tar.sh 2015-10-27 09:53:18.000000000 +0000 @@ -5,14 +5,17 @@ TAR=gluegen2_$VERSION.orig.tar.xz # clean up the upstream tarball -p7zip -d $3 -tar xvf gluegen-v$VERSION.tar -cd $DIR* +tar xvf $3 +cd $DIR rm -rf .gitignore .htaccess make/lib/ rm -f $(find . -iname '*.jar') cd .. +# download jcpp +wget http://jogamp.org/deployment/jogamp-current/archive/Sources/jcpp-v$VERSION.tar.xz +tar xvf jcpp-v$VERSION.tar.xz -C $DIR/jcpp --strip 1 + XZ_OPT=--best tar Jcvf ../$TAR $DIR -rm -rf $DIR gluegen-v$VERSION.tar +rm -rf $DIR jcpp-v$VERSION.tar.xz # move to directory 'tarballs' if [ -r .svn/deb-layout ]; then diff -Nru gluegen2-2.2.4/debian/patches/armhf.diff gluegen2-2.3.2/debian/patches/armhf.diff --- gluegen2-2.2.4/debian/patches/armhf.diff 2014-11-14 21:59:41.000000000 +0000 +++ gluegen2-2.3.2/debian/patches/armhf.diff 2015-10-27 09:53:18.000000000 +0000 @@ -1,8 +1,8 @@ -Index: gluegen-v2.2.0/make/build.xml +Index: gluegen2/make/build.xml =================================================================== ---- gluegen-v2.2.0.orig/make/build.xml 2014-08-10 15:38:35.009555506 +0200 -+++ gluegen-v2.2.0/make/build.xml 2014-08-10 15:38:35.009555506 +0200 -@@ -258,10 +258,16 @@ +--- gluegen2.orig/make/build.xml ++++ gluegen2/make/build.xml +@@ -262,10 +262,16 @@ @@ -12,50 +12,31 @@ - + + -+ -+ ++ ++ + + + + -+ -+ ++ ++ -@@ -312,7 +318,7 @@ +@@ -328,7 +334,7 @@ -- -+ +- ++ - -Index: gluegen-v2.2.0/make/gluegen-cpptasks-base.xml + +Index: gluegen2/make/gluegen-cpptasks-base.xml =================================================================== ---- gluegen-v2.2.0.orig/make/gluegen-cpptasks-base.xml 2014-08-10 15:38:35.009555506 +0200 -+++ gluegen-v2.2.0/make/gluegen-cpptasks-base.xml 2014-08-10 15:38:35.009555506 +0200 -@@ -124,7 +124,7 @@ - - compiler.cfg.linux - - compiler.cfg.linux.x86 - - compiler.cfg.linux.amd64 -- - compiler.cfg.linux.armv6 -+ - compiler.cfg.linux.armv6.armel - - compiler.cfg.linux.alpha - - compiler.cfg.linux.hppa - - compiler.cfg.linux.mips -@@ -145,7 +145,8 @@ - - linker.cfg.linux - - linker.cfg.linux.x86 - - linker.cfg.linux.amd64 -- - linker.cfg.linux.armv6 -+ - linker.cfg.linux.armv6.armel -+ - linker.cfg.linux.armv6.armhf - - linker.cfg.linux.alpha - - linker.cfg.linux.hppa - - linker.cfg.linux.mips -@@ -964,7 +965,7 @@ +--- gluegen2.orig/make/gluegen-cpptasks-base.xml ++++ gluegen2/make/gluegen-cpptasks-base.xml +@@ -1032,7 +1032,7 @@ - lib/gluegen-cpptasks-linux-armv6.xml (armv5te + softfp), or - lib/gluegen-cpptasks-linux-armv6hf.xml (armv6 + hardfp) for official JogAmp builds! --> @@ -64,7 +45,7 @@ -@@ -1181,13 +1182,16 @@ +@@ -1270,7 +1270,7 @@ - lib/gluegen-cpptasks-linux-armv6.xml (armv5te + softfp), or - lib/gluegen-cpptasks-linux-armv6hf.xml (armv6 + hardfp) for official JogAmp builds! --> @@ -73,10 +54,11 @@ - +@@ -1286,6 +1286,9 @@ + -+ ++ + + diff -Nru gluegen2-2.2.4/debian/patches/disableArchive7z.diff gluegen2-2.3.2/debian/patches/disableArchive7z.diff --- gluegen2-2.2.4/debian/patches/disableArchive7z.diff 2014-11-14 21:59:41.000000000 +0000 +++ gluegen2-2.3.2/debian/patches/disableArchive7z.diff 2015-10-27 09:53:18.000000000 +0000 @@ -1,8 +1,8 @@ -Index: gluegen-v2.2.0/make/build.xml +Index: gluegen2/make/build.xml =================================================================== ---- gluegen-v2.2.0.orig/make/build.xml 2014-08-10 15:37:44.463916132 +0200 -+++ gluegen-v2.2.0/make/build.xml 2014-08-10 15:37:44.459916002 +0200 -@@ -1037,9 +1037,9 @@ +--- gluegen2.orig/make/build.xml ++++ gluegen2/make/build.xml +@@ -1088,9 +1088,9 @@ @@ -14,10 +14,10 @@ -@@ -1077,9 +1077,9 @@ - +@@ -1138,9 +1138,9 @@ + - + - diff -Nru gluegen2-2.2.4/debian/patches/disable-static-linking.diff gluegen2-2.3.2/debian/patches/disable-static-linking.diff --- gluegen2-2.2.4/debian/patches/disable-static-linking.diff 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/debian/patches/disable-static-linking.diff 2015-10-29 12:48:27.000000000 +0000 @@ -0,0 +1,44 @@ +Description: disable static linking for native libraries. +Author: Gilles Filippini +Index: gluegen2/make/gluegen-cpptasks-base.xml +=================================================================== +--- gluegen2.orig/make/gluegen-cpptasks-base.xml ++++ gluegen2/make/gluegen-cpptasks-base.xml +@@ -1262,20 +1262,14 @@ + + + +- +- + + + + +- +- + + + + +- +- + + + +- ++ + + + diff -Nru gluegen2-2.2.4/debian/patches/s390x.diff gluegen2-2.3.2/debian/patches/s390x.diff --- gluegen2-2.2.4/debian/patches/s390x.diff 2014-11-14 21:59:41.000000000 +0000 +++ gluegen2-2.3.2/debian/patches/s390x.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,130 +0,0 @@ -diff --git a/make/build.xml b/make/build.xml -index bc04423..87678bc 100644 ---- a/make/build.xml -+++ b/make/build.xml -@@ -343,13 +343,19 @@ - - - -+ -+ -+ -+ -+ -+ - - - - - - -- -+ - - - -diff --git a/make/gluegen-cpptasks-base.xml b/make/gluegen-cpptasks-base.xml -index 92aab28..f0ea963 100755 ---- a/make/gluegen-cpptasks-base.xml -+++ b/make/gluegen-cpptasks-base.xml -@@ -36,6 +36,7 @@ - - isLinuxMipsel - - isLinuxPpc - - isLinuxs390 -+ - isLinuxs390x - - isLinuxSparc - - isOSX - - isOSXPPC -@@ -117,6 +118,7 @@ - - compiler.cfg.linux.mipsel - - compiler.cfg.linux.ppc - - compiler.cfg.linux.s390 -+ - compiler.cfg.linux.s390x - - compiler.cfg.linux.sparc - - compiler.cfg.solaris - - compiler.cfg.solaris.sparcv9 -@@ -137,6 +139,7 @@ - - linker.cfg.linux.mipsel - - linker.cfg.linux.ppc - - linker.cfg.linux.s390 -+ - linker.cfg.linux.s390x - - linker.cfg.linux.sparc - - linker.cfg.freebsd.x86 - - linker.cfg.freebsd.amd64 -@@ -340,6 +343,15 @@ - - - -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -@@ -478,6 +490,7 @@ - - - -+ - - - -@@ -552,6 +565,10 @@ - - - -+ -+ -+ -+ - - - -@@ -561,7 +578,7 @@ - - - -- -+ - - - -@@ -1036,6 +1053,9 @@ - - - -+ -+ -+ - - - -@@ -1244,6 +1264,13 @@ - - - -+ -+ -+ -+ -+ -+ -+ - - - -@@ -1251,7 +1278,7 @@ - - - -- -+ - - - diff -Nru gluegen2-2.2.4/debian/patches/s390x-support.diff gluegen2-2.3.2/debian/patches/s390x-support.diff --- gluegen2-2.2.4/debian/patches/s390x-support.diff 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/debian/patches/s390x-support.diff 2015-10-29 12:48:27.000000000 +0000 @@ -0,0 +1,150 @@ +Description: add support for s390x arch. +Author: Gilles Filippini +Index: gluegen2/make/scripts/make.gluegen.all.linux-s390x.sh +=================================================================== +--- /dev/null ++++ gluegen2/make/scripts/make.gluegen.all.linux-s390x.sh +@@ -0,0 +1,24 @@ ++#! /bin/sh ++ ++# -Dc.compiler.debug=true \ ++# -Dgluegen.cpptasks.detected.os=true \ ++# -DisUnix=true \ ++# -DisLinux=true \ ++# -DisLinuxX86=true \ ++# -DisX11=true \ ++ ++MACHINE=s390x ++ARCH=s390x ++TRIPLET=s390x-linux-gnu ++ ++export TARGET_PLATFORM_LIBS=/usr/lib/$TRIPLET ++export TARGET_JAVA_LIBS=/usr/lib/jvm/java-7-openjdk-$ARCH/jre/lib/$MACHINE ++ ++export GLUEGEN_CPPTASKS_FILE="lib/gluegen-cpptasks-linux-$MACHINE.xml" ++ ++#export JOGAMP_JAR_CODEBASE="Codebase: *.jogamp.org" ++export JOGAMP_JAR_CODEBASE="Codebase: *.goethel.localnet" ++ ++ant \ ++ -Drootrel.build=build-linux-$MACHINE \ ++ $* 2>&1 | tee make.gluegen.all.linux-$MACHINE.log +Index: gluegen2/src/java/jogamp/common/os/PlatformPropsImpl.java +=================================================================== +--- gluegen2.orig/src/java/jogamp/common/os/PlatformPropsImpl.java ++++ gluegen2/src/java/jogamp/common/os/PlatformPropsImpl.java +@@ -527,6 +527,7 @@ public abstract class PlatformPropsImpl + *
  • linux-ia64
  • + *
  • linux-sparcv9
  • + *
  • linux-risc2.0
  • ++ *
  • linux-s390x
  • + *
  • freebsd-i586
  • + *
  • freebsd-amd64
  • + *
  • hpux-hppa
  • +@@ -593,6 +594,9 @@ public abstract class PlatformPropsImpl + case PA_RISC2_0: + _and_arch_tmp = "risc2.0"; + break; ++ case S390X: ++ _and_arch_tmp = "s390x"; ++ break; + default: + throw new InternalError("Unhandled CPUType: "+cpuType); + } +Index: gluegen2/src/java/jogamp/common/os/elf/ElfHeaderPart1.java +=================================================================== +--- gluegen2.orig/src/java/jogamp/common/os/elf/ElfHeaderPart1.java ++++ gluegen2/src/java/jogamp/common/os/elf/ElfHeaderPart1.java +@@ -412,6 +412,15 @@ public class ElfHeaderPart1 { + cpuName = "ppc64"; + abiType = ABIType.GENERIC_ABI; + break; ++ case EM_S390: ++ // Can be 32 or 64 bits ++ if( 64 == getArchClassBits() ) { ++ cpuName = "s390x"; ++ } else { ++ cpuName = "s390"; ++ } ++ abiType = ABIType.GENERIC_ABI; ++ break; + case EM_SH: + cpuName = "superh"; + abiType = ABIType.GENERIC_ABI; +Index: gluegen2/src/java/com/jogamp/common/os/Platform.java +=================================================================== +--- gluegen2.orig/src/java/com/jogamp/common/os/Platform.java ++++ gluegen2/src/java/com/jogamp/common/os/Platform.java +@@ -77,7 +77,9 @@ public class Platform extends PlatformPr + /** Itanium */ + IA64, + /** Hitachi SuperH */ +- SuperH; ++ SuperH, ++ /** IBM ESA/390 and zSystems */ ++ S390; + } + + public enum CPUType { +@@ -118,9 +120,13 @@ public class Platform extends PlatformPr + /** SPARC 64bit, big endian */ + SPARCV9_64(CPUFamily.SPARC, false), + /** PA_RISC2_0 64bit, ??? endian */ +- PA_RISC2_0(CPUFamily.PA_RISC, false); ++ PA_RISC2_0(CPUFamily.PA_RISC, false), + // 17 + ++ /** S390X 64bit big endian */ ++ S390X(CPUFamily.S390, true); ++ // 18 ++ + public final CPUFamily family; + public final boolean is32Bit; + +@@ -201,6 +207,8 @@ public class Platform extends PlatformPr + return MIPS_32; + } else if( cpuABILower.startsWith("superh") ) { + return SuperH; ++ } else if( cpuABILower.equals("s390x") ) { ++ return S390X; + } else { + throw new RuntimeException("Please port CPUType detection to your platform (CPU_ABI string '" + cpuABILower + "')"); + } +Index: gluegen2/src/java/com/jogamp/common/os/MachineDataInfo.java +=================================================================== +--- gluegen2.orig/src/java/com/jogamp/common/os/MachineDataInfo.java ++++ gluegen2/src/java/com/jogamp/common/os/MachineDataInfo.java +@@ -73,6 +73,7 @@ public class MachineDataInfo { + private final static int[] align_sparc_32_sunos = { 1, 2, 4, 8, 4, 4, 4, 8, 8, 4 }; + private final static int[] align_x86_32_windows = { 1, 2, 4, 8, 4, 4, 4, 8, 4, 4 }; + private final static int[] align_lp64_unix = { 1, 2, 4, 8, 4, 8, 4, 8, 16, 8 }; ++ private final static int[] align_s390_64_unix = { 1, 2, 4, 8, 4, 8, 4, 8, 8, 8 }; + private final static int[] align_x86_64_windows = { 1, 2, 4, 8, 4, 4, 4, 8, 16, 8 }; + + /** +@@ -108,9 +109,11 @@ public class MachineDataInfo { + X86_32_WINDOWS( size_x86_32_windows, align_x86_32_windows), + /** LP64 Unix, e.g.: {@link Platform.CPUType#X86_64} Unix, {@link Platform.CPUType#ARM64} EABI, {@link Platform.CPUType#PPC64} Unix, .. */ + LP64_UNIX( size_lp64_unix, align_lp64_unix), ++ /** {@link Platform.CPUType#S390X} Unix */ ++ S390_64_UNIX( size_lp64_unix, align_s390_64_unix), + /** {@link Platform.CPUType#X86_64} Windows */ + X86_64_WINDOWS( size_x86_64_windows, align_x86_64_windows); +- // 8 ++ // 9 + + public final MachineDataInfo md; + +Index: gluegen2/src/java/jogamp/common/os/MachineDataInfoRuntime.java +=================================================================== +--- gluegen2.orig/src/java/jogamp/common/os/MachineDataInfoRuntime.java ++++ gluegen2/src/java/jogamp/common/os/MachineDataInfoRuntime.java +@@ -112,6 +112,8 @@ public class MachineDataInfoRuntime { + } else { + if( osType == Platform.OSType.WINDOWS ) { + return StaticConfig.X86_64_WINDOWS; ++ } else if ( Platform.CPUType.S390X == cpuType ) { ++ return StaticConfig.S390_64_UNIX; + } else { + // for all 64bit unix types (x86_64, aarch64, sparcv9, ..) + return StaticConfig.LP64_UNIX; diff -Nru gluegen2-2.2.4/debian/patches/series gluegen2-2.3.2/debian/patches/series --- gluegen2-2.2.4/debian/patches/series 2014-11-14 21:59:41.000000000 +0000 +++ gluegen2-2.3.2/debian/patches/series 2015-10-29 12:22:56.000000000 +0000 @@ -1,3 +1,4 @@ +ppc64el-support.diff jarPath.diff renamedLibrary.diff disableArchive7z.diff @@ -11,11 +12,14 @@ hideException.diff #TARGET_JAVA_LIBS_disabled.diff -#s390x.diff #duplicatedeclaration.diff #disable_android2.diff armhf.diff fix-alpha-build-config.patch -fix-ppc64-build-config.patch missing-arch-symbol.diff -add-mips-support.patch +#add-mips-support.patch + +fix-arm64-build-config.diff +tests.diff +disable-static-linking.diff +s390x-support.diff diff -Nru gluegen2-2.2.4/debian/patches/tests.diff gluegen2-2.3.2/debian/patches/tests.diff --- gluegen2-2.2.4/debian/patches/tests.diff 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/debian/patches/tests.diff 2015-10-29 12:48:27.000000000 +0000 @@ -0,0 +1,175 @@ +Description: enable testcases build and run. + One testcase can't build because of missing up to date semver-java: + - TestVersionSemantics + Three testcases fail on every arch while the library seems functional: + - TestUri99LaunchOnReservedCharPathBug908 + - TestStructGen01 + - TestStructGen02. +Author: Gilles Filippini +Index: gluegen2/make/build-test.xml +=================================================================== +--- gluegen2.orig/make/build-test.xml ++++ gluegen2/make/build-test.xml +@@ -84,6 +84,7 @@ + + + ++ + + + +Index: gluegen2/make/scripts/runtest.sh +=================================================================== +--- gluegen2.orig/make/scripts/runtest.sh ++++ gluegen2/make/scripts/runtest.sh +@@ -42,7 +42,7 @@ rm -f $LOG + GLUEGEN_ROOT=`dirname $builddir` + ROOTREL_BUILD=`basename $builddir` + +-X_ARGS="-Drootrel.build=$ROOTREL_BUILD -Dgluegen.root=$GLUEGEN_ROOT" ++X_ARGS="-Drootrel.build=$ROOTREL_BUILD -Dgluegen.root=$GLUEGEN_ROOT -Djava.library.path=$builddir/obj:$builddir/test/build/natives" + #D_ARGS="-Djogamp.debug.ProcAddressHelper -Djogamp.debug.NativeLibrary -Djogamp.debug.NativeLibrary.Lookup" + #D_ARGS="-Djogamp.debug.TraceLock" + #D_ARGS="-Djogamp.debug.Platform -Djogamp.debug.NativeLibrary" +@@ -64,12 +64,12 @@ X_ARGS="-Drootrel.build=$ROOTREL_BUILD - + #D_ARGS="-Djogamp.debug.IOUtil -Djogamp.debug.IOUtil.Exe" + #D_ARGS="-Djogamp.debug.ByteBufferInputStream" + #D_ARGS="-Djogamp.debug.Bitstream" +-#D_ARGS="-Djogamp.debug=all" ++D_ARGS="-Djogamp.debug=all" + #D_ARGS="-Djogamp.debug.Logging" + + function onetest() { + #USE_CLASSPATH=lib/junit.jar:$ANT_JARS:lib/semantic-versioning/semver.jar:"$builddir"/../make/lib/TestJarsInJar.jar:"$builddir"/gluegen-rt.jar:"$builddir"/gluegen.jar:"$builddir"/gluegen-test-util.jar:"$builddir"/test/build/gluegen-test.jar +- USE_CLASSPATH=lib/junit.jar:$ANT_JARS:lib/semantic-versioning/semver.jar:"$builddir"/../make/lib/TestJarsInJar.jar:"$builddir"/gluegen-rt.jar:"$builddir"/gluegen.jar:"$builddir"/gluegen-test-util.jar:"$builddir"/test/build/gluegen-test.jar:"$builddir"/gluegen-rt-natives.jar ++ USE_CLASSPATH=/usr/share/java/junit4.jar:$ANT_JARS:lib/semantic-versioning/semver.jar:"$builddir"/../test/TestJarsInJar/TestJarsInJar.jar:"$builddir"/gluegen-rt.jar:"$builddir"/gluegen.jar:"$builddir"/gluegen-test-util.jar:"$builddir"/test/build/gluegen-test.jar:"$builddir"/gluegen-rt-natives.jar + #USE_CLASSPATH=lib/junit.jar:$ANT_JARS:lib/semantic-versioning/semver.jar:"$builddir"/../make/lib/TestJarsInJar.jar:"$builddir"/gluegen-rt-alt.jar:"$builddir"/gluegen.jar:"$builddir"/gluegen-test-util.jar:"$builddir"/test/build/gluegen-test.jar + libspath="$builddir"/test/build/natives + #USE_CLASSPATH=lib/junit.jar:$ANT_JARS:"$builddir"/../make/lib/TestJarsInJar.jar:"$builddir"/classes:"$builddir"/test/build/classes +@@ -88,66 +88,68 @@ function onetest() { + echo + } + # ++(cd $builddir/../test/TestJarsInJar && sh make.sh) ++# +-#onetest com.jogamp.common.GlueGenVersion 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestSystemPropsAndEnvs 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestVersionInfo 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestVersionNumber 2>&1 | tee -a $LOG ++onetest com.jogamp.common.GlueGenVersion 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestSystemPropsAndEnvs 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestVersionInfo 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestVersionNumber 2>&1 | tee -a $LOG + #onetest com.jogamp.common.util.TestVersionSemantics 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestIteratorIndexCORE 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.locks.TestRecursiveLock01 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.locks.TestRecursiveThreadGroupLock01 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.locks.TestSingletonServerSocket00 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.locks.TestSingletonServerSocket01 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.locks.TestSingletonServerSocket02 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestFloatStack01 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestIntegerStack01 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestArrayHashSet01 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestArrayHashMap01 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.IntIntHashMapTest 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.IntObjectHashMapTest 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.LongIntHashMapTest 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestPlatform01 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestRunnableTask01 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestIteratorIndexCORE 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.locks.TestRecursiveLock01 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.locks.TestRecursiveThreadGroupLock01 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.locks.TestSingletonServerSocket00 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.locks.TestSingletonServerSocket01 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.locks.TestSingletonServerSocket02 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestFloatStack01 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestIntegerStack01 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestArrayHashSet01 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestArrayHashMap01 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.IntIntHashMapTest 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.IntObjectHashMapTest 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.LongIntHashMapTest 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestPlatform01 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestRunnableTask01 2>&1 | tee -a $LOG + onetest com.jogamp.common.util.TestIOUtil01 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestTempJarCache 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestJarUtil 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestValueConversion 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestSyncRingBuffer01 $* +-#onetest com.jogamp.common.util.TestLFRingBuffer01 $* +-#onetest com.jogamp.common.util.TestBitfield00 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestBitstream00 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestBitstream01 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestBitstream02 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestBitstream03 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.util.TestBitstream04 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.net.TestUrisWithAssetHandler 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.net.TestUriQueryProps 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.net.TestUri01 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.net.TestUri02Composing 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.net.TestUri03Resolving 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.net.TestUri99LaunchOnReservedCharPathBug908 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.net.AssetURLConnectionUnregisteredTest 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.net.AssetURLConnectionRegisteredTest 2>&1 | tee -a $LOG +-#onetest com.jogamp.junit.sec.TestSecIOUtil01 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.nio.BuffersTest 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.nio.TestBuffersFloatDoubleConversion 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.nio.TestPointerBufferEndian 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.nio.TestStructAccessorEndian 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.nio.TestByteBufferInputStream 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.nio.TestByteBufferOutputStream 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.nio.TestByteBufferCopyStream 2>&1 | tee -a $LOG +-#onetest com.jogamp.common.os.TestElfReader01 $* 2>&1 | tee -a $LOG +-#onetest com.jogamp.gluegen.test.junit.internals.TestType 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestTempJarCache 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestJarUtil 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestValueConversion 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestSyncRingBuffer01 $* ++onetest com.jogamp.common.util.TestLFRingBuffer01 $* ++onetest com.jogamp.common.util.TestBitfield00 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestBitstream00 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestBitstream01 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestBitstream02 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestBitstream03 2>&1 | tee -a $LOG ++onetest com.jogamp.common.util.TestBitstream04 2>&1 | tee -a $LOG ++onetest com.jogamp.common.net.TestUrisWithAssetHandler 2>&1 | tee -a $LOG ++onetest com.jogamp.common.net.TestUriQueryProps 2>&1 | tee -a $LOG ++onetest com.jogamp.common.net.TestUri01 2>&1 | tee -a $LOG ++onetest com.jogamp.common.net.TestUri02Composing 2>&1 | tee -a $LOG ++onetest com.jogamp.common.net.TestUri03Resolving 2>&1 | tee -a $LOG ++onetest com.jogamp.common.net.TestUri99LaunchOnReservedCharPathBug908 2>&1 | tee -a $LOG ++onetest com.jogamp.common.net.AssetURLConnectionUnregisteredTest 2>&1 | tee -a $LOG ++onetest com.jogamp.common.net.AssetURLConnectionRegisteredTest 2>&1 | tee -a $LOG ++onetest com.jogamp.junit.sec.TestSecIOUtil01 2>&1 | tee -a $LOG ++onetest com.jogamp.common.nio.BuffersTest 2>&1 | tee -a $LOG ++onetest com.jogamp.common.nio.TestBuffersFloatDoubleConversion 2>&1 | tee -a $LOG ++onetest com.jogamp.common.nio.TestPointerBufferEndian 2>&1 | tee -a $LOG ++onetest com.jogamp.common.nio.TestStructAccessorEndian 2>&1 | tee -a $LOG ++onetest com.jogamp.common.nio.TestByteBufferInputStream 2>&1 | tee -a $LOG ++onetest com.jogamp.common.nio.TestByteBufferOutputStream 2>&1 | tee -a $LOG ++onetest com.jogamp.common.nio.TestByteBufferCopyStream 2>&1 | tee -a $LOG ++onetest com.jogamp.common.os.TestElfReader01 $* 2>&1 | tee -a $LOG ++onetest com.jogamp.gluegen.test.junit.internals.TestType 2>&1 | tee -a $LOG + +-#onetest com.jogamp.gluegen.test.junit.generation.PCPPTest 2>&1 | tee -a $LOG +-#onetest com.jogamp.gluegen.jcpp.IncludeAbsoluteTest 2>&1 | tee -a $LOG +-#onetest com.jogamp.gluegen.jcpp.CppReaderTest 2>&1 | tee -a $LOG +-#onetest com.jogamp.gluegen.jcpp.TokenPastingWhitespaceTest 2>&1 | tee -a $LOG +-#onetest com.jogamp.gluegen.jcpp.PreprocessorTest 2>&1 | tee -a $LOG ++onetest com.jogamp.gluegen.test.junit.generation.PCPPTest 2>&1 | tee -a $LOG ++onetest com.jogamp.gluegen.jcpp.IncludeAbsoluteTest 2>&1 | tee -a $LOG ++onetest com.jogamp.gluegen.jcpp.CppReaderTest 2>&1 | tee -a $LOG ++onetest com.jogamp.gluegen.jcpp.TokenPastingWhitespaceTest 2>&1 | tee -a $LOG ++onetest com.jogamp.gluegen.jcpp.PreprocessorTest 2>&1 | tee -a $LOG + +-#onetest com.jogamp.gluegen.test.junit.generation.Test1p1JavaEmitter 2>&1 | tee -a $LOG +-#onetest com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter 2>&1 | tee -a $LOG +-#onetest com.jogamp.gluegen.test.junit.generation.Test1p2LoadJNIAndImplLib 2>&1 | tee -a $LOG +-#onetest com.jogamp.gluegen.test.junit.structgen.TestStructGen01 2>&1 | tee -a $LOG +-#onetest com.jogamp.gluegen.test.junit.structgen.TestStructGen02 2>&1 | tee -a $LOG ++onetest com.jogamp.gluegen.test.junit.generation.Test1p1JavaEmitter 2>&1 | tee -a $LOG ++onetest com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter 2>&1 | tee -a $LOG ++onetest com.jogamp.gluegen.test.junit.generation.Test1p2LoadJNIAndImplLib 2>&1 | tee -a $LOG ++onetest com.jogamp.gluegen.test.junit.structgen.TestStructGen01 2>&1 | tee -a $LOG ++onetest com.jogamp.gluegen.test.junit.structgen.TestStructGen02 2>&1 | tee -a $LOG + diff -Nru gluegen2-2.2.4/debian/README.source gluegen2-2.3.2/debian/README.source --- gluegen2-2.2.4/debian/README.source 2014-11-14 21:59:41.000000000 +0000 +++ gluegen2-2.3.2/debian/README.source 2015-10-27 09:53:18.000000000 +0000 @@ -1,7 +1,10 @@ -Here is how to repack gluegen2 +Here is how the current gluegen2 orig tarball was created: -git clone git://jogamp.org/srv/scm/gluegen.git gluegen-xxx -cd gluegen -git checkout -rm -rf .git make/lib/ -tar zcvf gluegen2_xxx.orig.tar.gz gluegen-xxx/ +- Update debian/changelog for the new target verison. +- Use the debian/rules get-orig-source target to retrieve and repack + the gluegen orig tarball. +- Extract the gluegen orig tarball. +- Retrieve the sources for jcpp from: + http://jogamp.org/deployment/jogamp-current/archive/Sources/ +- Extract the jcpp sources into the gluegen tarball. +- Repack as gluegen2_xxx.orig.tar.gz diff -Nru gluegen2-2.2.4/debian/rules gluegen2-2.3.2/debian/rules --- gluegen2-2.2.4/debian/rules 2014-11-14 21:59:41.000000000 +0000 +++ gluegen2-2.3.2/debian/rules 2015-10-28 10:36:36.000000000 +0000 @@ -5,15 +5,14 @@ include /usr/share/cdbs/1/rules/patchsys-quilt.mk JAVA_HOME := /usr/lib/jvm/default-java/ -DEB_JARS := ant-launcher antlrall ant-antlr ant-contrib ant-contrib-cpptasks ant-junit +DEB_JARS := ant-launcher antlrall ant-antlr ant-contrib ant-contrib-cpptasks ant-junit jsr305 DEB_ANT_CLEAN_TARGET := clean DEB_BUILDDIR := make -DEB_ANT_BUILD_TARGET := all.no_junit +DEB_ANT_BUILD_TARGET := all DEB_ANT_ARGS += -Dtarget.sourcelevel=1.6 -Dtarget.targetlevel=1.6 -Dtarget.rt.jar=1.6 ifeq ($(DEB_HOST_ARCH),armhf) DEB_ANT_ARGS += -DisAbiEabiGnuArmhf=true -DEB_ANT_BUILD_TARGET := all.no_junit endif install/libgluegen2-rt-java:: @@ -42,16 +41,28 @@ rm debian/libgluegen2-build-java/usr/share/gluegen2/src/java/com/jogamp/gluegen/cgram/license.txt install/libgluegen2-jni:: - install -m 644 -D build/obj/libgluegen-rt.so debian/libgluegen2-jni/usr/lib/jni/libgluegen2-rt.so + install -m 644 -D build/obj/libgluegen2-rt.so debian/libgluegen2-jni/usr/lib/jni/libgluegen2-rt.so install/libgluegen2-doc:: $(DEB_ANT_INVOKE) javadoc mkdir -p debian/libgluegen2-doc/usr/share/doc/libgluegen2-java/ cp -Rf build/javadoc/gluegen/javadoc/* debian/libgluegen2-doc/usr/share/doc/libgluegen2-java/ +# Run the test suite +common-post-build-arch:: + ANT_PATH=/usr/share/ant make/scripts/runtest.sh $(CURDIR)/build + +DISABLED_TESTS := junit/util/VersionSemanticsUtil common/util/TestVersionSemantics +post-patches:: + cd src/junit/com/jogamp && \ + $(foreach test,$(DISABLED_TESTS),if [ -f $(test).java ]; then mv $(test).java $(test).java.disabled; fi &&) true + clean:: - $(RM) -r gluegen/build + $(RM) -r gluegen/build build-temp $(RM) make/GnuCTreeParserTokenTypes.txt make/STDCTokenTypes.txt + cd src/junit/com/jogamp && \ + $(foreach test,$(DISABLED_TESTS),if [ -f $(test).java.disabled ]; then mv $(test).java.disabled $(test).java; fi &&) true + $(RM) test/TestJarsInJar/TestJarsInJar.jar runtest.log get-orig-source:: uscan --download-current-version --no-symlink --force-download diff -Nru gluegen2-2.2.4/debian/watch gluegen2-2.3.2/debian/watch --- gluegen2-2.2.4/debian/watch 2014-11-14 21:59:41.000000000 +0000 +++ gluegen2-2.3.2/debian/watch 2015-10-27 09:53:18.000000000 +0000 @@ -1,4 +1,4 @@ version=3 -http://jogamp.org/deployment/jogamp-current/archive/Sources/ gluegen-v(.*).tar.7z \ +http://jogamp.org/deployment/jogamp-current/archive/Sources/ gluegen-v(.*).tar.xz \ debian debian/orig-tar.sh diff -Nru gluegen2-2.2.4/doc/HowToBuild.html gluegen2-2.3.2/doc/HowToBuild.html --- gluegen2-2.2.4/doc/HowToBuild.html 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/doc/HowToBuild.html 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,269 @@ + + + + + + How to build JOGL + + +
    + + +
    +
    + +

    Platform and Component Requirements

    +
    + Here is a list of platforms and components, we were able to build GlueGen on,
    + if not stated otherwise.
    + +
      +
    • Java
      + A Java 1.6 compliant SDK. +
    • +
    • Ant 1.9.0 or later
    • +
    • Git 1.6.0 or later
      + +
    • + +
    • GNU Linux x86, 32- and 64-bit
      + You may have to install a few developer packages ... +
        +
      • Debian 5.00 or later +
          +
        • openjdk-7-jre
        • +
        • openjdk-7-jdk
        • +
        • ant
        • +
        • git
        • +
        • p7zip-full
        • +
        • gcc
        • +
        + One liner install command: +
        +apt-get install openjdk-7-jre openjdk-7-jdk ant git-all p7zip-full gcc
        +                                    
        + Optional: Add kernel build utilities: +
        +apt-get install kernel-package build-essential 
        +                                    
        + Optional: Add multiarch i386 next to amd64 +
          +
        • Debian 7.00 +
          +dpkg --add-architecture i386
          +apt-get update
          +apt-get install ia32-libs ia32-libs-gtk gcc-multilib lib32gcc1 lib32gomp1 lib32itm1 lib32quadmath0 libc6-i386 ibc6-dev-i386 g++-multilib lib32stdc++6 openjdk-7-jre:i386 openjdk-7-jdk:i386
          +                                        
        • + +
        • Debian 8.00 +
          +dpkg --add-architecture i386
          +apt-get update
          +apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0 gcc-multilib lib32gcc1 lib32gomp1 lib32itm1 lib32quadmath0 libc6-i386 libc6-dev-i386 g++-multilib lib32stdc++6 openjdk-7-jre:i386 openjdk-7-jdk:i386
          +                                        
        • +
        +
      • +
      • OpenSuSE 10.2 or later +
          +
        • openjdk-7-jre
        • +
        • openjdk-7-jdk
        • +
        • ant
        • +
        • git
        • +
        • p7zip-full
        • +
        • gcc
        • +
        +
      • +
      • CentOS / Red Hat Enterprise Linux 5.4 or later
        +
          +
        • openjdk-7-jre
        • +
        • openjdk-7-jdk
        • +
        • ant
        • +
        • git
        • +
        • p7zip-full
        • +
        • gcc
        • +
        +
      • +
      +
    • +
    • OpenSolaris SPARC and x86, 32- and 64-bit + +
    • +
    • MacOSX Intel +
        +
      • git, see above
      • +
      • Mac OS X 10.3 (note: will not work with earlier releases)
      • +
      • Xcode for gcc, etc (included in OSX)
      • +
      +
    • +
    • Windows/x86 (32 bit) +
        +
      • Windows XP or later
      • +
      • git, see above
      • +
      • MinGW64 +
          +
        • Installer +
            +
          • mingw-build-install
          • +
          • version: 4.8.1
          • +
          • host: x32
          • +
          • threading: win32
          • +
          • exceptions: SJLJ
          • +
          • revision: 5
          • +
        • +
        • or manual + via 7z archive file
        • +
      • +
      +
    • +
    • Windows/x86_64 (64-bit) +
        +
      • Windows XP or later
      • +
      • git, see above
      • +
      • MinGW64 +
          +
        • Installer +
            +
          • mingw-build-install
          • +
          • version: 4.8.1
          • +
          • host: x64
          • +
          • threading: win32
          • +
          • exceptions: SJLJ
          • +
          • revision: 5
          • +
        • +
        • or manual + via 7z archive file
        • +
      • +
      +
    • +
    + +

    + Additional platforms such as FreeBSD and HP/UX are handled by the + build system, but are not officially supported. +

    + +

    Build Steps

    +
    +

    + Here are the steps that are required in order to build JOGL. +

    + +
      +
    1. Optain the source code using git: +
      + It is crucial that you checkout the source code under a common root directory: +
      +    /home/dude/projects/jogamp> git clone --recurse-submodules git://jogamp.org/srv/scm/gluegen.git gluegen
      +                            
      + Now you should have following directory structure: +
      +    /home/dude/projects/jogamp
      +    /home/dude/projects/jogamp/gluegen
      +                            
      +

      + Note-1: The GlueGen source must be fetched using -recurse-submodules, + which imports JCPP, now used as the default C preprocessor. +

      +
    2. + +
    3. Unset your CLASSPATH environment variable:
      + The Ant build requires that the JOGL jars not be visible on the classpath. On Unix, type + unsetenv CLASSPATH into a csh or tcsh shell, or unset CLASSPATH + into a Bourne shell. On Windows, type set CLASSPATH= into a command prompt. +
    4. + +
    5. Optional Copy and edit gluegen.properties:
      + To specify different basic options for components and compilers,
      + copy gluegen/make/gluegen.properties into your home directory (pointed to by the Java system property user.home).
    6. + +
    7. Build the source tree:
      + Open a command shell in the "gluegen/make" directory of the source tree and type "ant". +
    8. + +
    9. Test your build:
      Stay in your command shell in the "gluegen/make" directory of the source tree and type "ant junit.run".
    10. + +
    11. Build Javadoc:
      Stay in your command shell in the "gluegen/make" directory of the source tree and type "ant javadoc". + This will produce the end-user documentation for JOGL along with some auxiliary utility packages. +
    12. +
    + + Note that there might be a few warnings produced by ANTLR about the + C grammar and our modifications to some of the signatures of the + productions; the C grammar warnings have been documented by the + author of the grammar as having been investigated completely and + harmless, and the warnings about our modifications are also + harmless. + +

    Common build problems

    + +
      + +
    1. + Your CLASSPATH environment variable appears to be set (some GlueGen classes are currently visible to the build.), and $CLASSPATH isn't set. + An older version of GlueGen was installed into the extension directory of the JDK you're using to build the + current GlueGen. On Windows and Linux, delete any ANTLR jars from jre/lib/ext, and on Mac OS X, delete them from + /Library/Java/Extensions. It is generally not a good idea to drop GlueGen directly into the extensions directory, + as this can interfere with upgrades via Java Web Start. +
    2. + +
    3. + CharScanner; panic: ClassNotFoundException: com.sun.gluegen.cgram.CToken + + This occurs because ANTLR was dropped into the Extensions + directory of the JRE/JDK. On Windows and Linux, delete any ANTLR jars from jre/lib/ext, + and on Mac OS X, delete them from /Library/Java/Extensions. Use the antlr.jar property in the build.xml + to point to a JRE-external location of this jar file. +
    4. + +
    + +
    +

    + - Christopher Kline and Kenneth Russell, June 2003 (revised November 2006)
    + - Sven Gothel and Michael Bien, May 2010
    + - Sven Gothel, March 2010 (Extracted version from JOGL)
    +

    + +
    +
    + +
    + + diff -Nru gluegen2-2.2.4/doc/Implementation/IOUtil.testDirExe/linux-noexec-file_attribs.log gluegen2-2.3.2/doc/Implementation/IOUtil.testDirExe/linux-noexec-file_attribs.log --- gluegen2-2.2.4/doc/Implementation/IOUtil.testDirExe/linux-noexec-file_attribs.log 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/doc/Implementation/IOUtil.testDirExe/linux-noexec-file_attribs.log 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,119 @@ +LD_LIBRARY_PATH ../build-x86_64/test/build/natives: +USE_CLASSPATH lib/junit.jar:/opt-share/apache-ant/lib/ant.jar:/opt-share/apache-ant/lib/ant-junit.jar:/opt-share/apache-ant/lib/ant-launcher.jar:lib/semantic-versioning/semver.jar:../build-x86_64/../make/lib/TestJarsInJar.jar:../build-x86_64/gluegen-rt.jar:../build-x86_64/gluegen.jar:../build-x86_64/gluegen-test-util.jar:../build-x86_64/test/build/gluegen-test.jar:../build-x86_64/gluegen-rt-natives.jar +/opt-linux-x86_64/jre8/bin/java +java -cp lib/junit.jar:/opt-share/apache-ant/lib/ant.jar:/opt-share/apache-ant/lib/ant-junit.jar:/opt-share/apache-ant/lib/ant-launcher.jar:lib/semantic-versioning/semver.jar:../build-x86_64/../make/lib/TestJarsInJar.jar:../build-x86_64/gluegen-rt.jar:../build-x86_64/gluegen.jar:../build-x86_64/gluegen-test-util.jar:../build-x86_64/test/build/gluegen-test.jar:../build-x86_64/gluegen-rt-natives.jar -Drootrel.build=build-x86_64 -Dgluegen.root=.. -Djogamp.debug.IOUtil -Djogamp.debug.IOUtil.Exe -Djogamp.debug.IOUtil.Exe.NoStream com.jogamp.common.util.TestPlatform01 +JUnit version 4.11 +++++ Test Singleton.ctor() +++++ Test Singleton.lock() +SLOCK [T SingletonServerSocket1-localhost/127.0.0.1:59999 @ 1442811548011 ms III - Start +SLOCK [T main @ 1442811548012 ms +++ localhost/127.0.0.1:59999 - Locked within 5 ms, 1 attempts +.++++ TestCase.setUp: com.jogamp.common.util.TestPlatform01 - testInfo00 + +IOUtil.getTempRoot(): tempX1 , used true +IOUtil.getTempRoot(): tempX3 , used false +IOUtil.getTempRoot(): tempX4 , used true +IOUtil.getTempRoot(): tempX2 , used true +IOUtil.testDirExec: : Caught IOException: Cannot run program "/tmp/jogamp_exe_tst.sh": error=13, Permission denied +java.io.IOException: Cannot run program "/tmp/jogamp_exe_tst.sh": error=13, Permission denied + at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048) + at java.lang.Runtime.exec(Runtime.java:620) + at com.jogamp.common.util.IOUtil.testDirExec(IOUtil.java:948) + at com.jogamp.common.util.IOUtil.testDirImpl(IOUtil.java:986) + at com.jogamp.common.util.IOUtil.getSubTempDir(IOUtil.java:1046) + at com.jogamp.common.util.IOUtil.getTempDir(IOUtil.java:1161) + at com.jogamp.common.util.cache.TempFileCache.(TempFileCache.java:81) + at com.jogamp.common.util.cache.TempJarCache.initSingleton(TempJarCache.java:88) + at com.jogamp.common.os.Platform$1.run(Platform.java:309) + at java.security.AccessController.doPrivileged(Native Method) + at com.jogamp.common.os.Platform.(Platform.java:287) + at com.jogamp.common.util.TestPlatform01.testInfo00(TestPlatform01.java:47) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:497) + at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) + at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) + at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) + at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) + at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) + at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) + at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55) + at org.junit.rules.RunRules.evaluate(RunRules.java:20) + at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) + at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) + at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) + at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) + at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) + at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) + at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) + at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) + at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) + at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) + at org.junit.runners.ParentRunner.run(ParentRunner.java:309) + at org.junit.runners.Suite.runChild(Suite.java:127) + at org.junit.runners.Suite.runChild(Suite.java:26) + at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) + at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) + at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) + at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) + at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) + at org.junit.runners.ParentRunner.run(ParentRunner.java:309) + at org.junit.runner.JUnitCore.run(JUnitCore.java:160) + at org.junit.runner.JUnitCore.run(JUnitCore.java:138) + at org.junit.runner.JUnitCore.run(JUnitCore.java:117) + at org.junit.runner.JUnitCore.runMain(JUnitCore.java:96) + at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:47) + at org.junit.runner.JUnitCore.main(JUnitCore.java:40) + at com.jogamp.common.util.TestPlatform01.main(TestPlatform01.java:93) +Caused by: java.io.IOException: error=13, Permission denied + at java.lang.UNIXProcess.forkAndExec(Native Method) + at java.lang.UNIXProcess.(UNIXProcess.java:248) + at java.lang.ProcessImpl.start(ProcessImpl.java:134) + at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029) + ... 49 more +IOUtil.testDirExec(): test-exe , existingFile true, returned -1 +IOUtil.testDirExec(): abs-path : res -2 -> false +IOUtil.testDirExec(): total 72ms, create 0ms, execute 72ms +IOUtil.testDirImpl(tempX1): , create true, exec true: false +IOUtil.testDirExec(): test-exe , existingFile false, returned 0 +IOUtil.testDirExec(): abs-path : res 0 -> true +IOUtil.testDirExec(): total 17ms, create 13ms, execute 4ms +IOUtil.testDirImpl(tempX2): , create true, exec true: true +IOUtil.testDirExec(): test-exe , existingFile false, returned 0 +IOUtil.testDirExec(): abs-path : res 0 -> true +IOUtil.testDirExec(): total 2ms, create 0ms, execute 2ms +IOUtil.testDirImpl(tempX2): , create true, exec true: true +IOUtil.getTempRoot(): temp dirs: exec: /home/sven/.cache/jogamp_0000, noexec: /home/sven/.cache/jogamp_0000 +IOUtil.testDirImpl(testDir): , create true, exec false: true + +OS name/type: Linux, LINUX +OS version: 4.1.6-x64-k10-nlb-jau01, 4.1.6 + +Arch, CPU: amd64, X86_64/X86 +OS/Arch: linux-amd64 + +Java runtime: Java(TM) SE Runtime Environment +Java vendor[name/url]: Oracle Corporation/http://java.oracle.com/ +Java version, vm: 1.8.0_60, Java HotSpot(TM) 64-Bit Server VM + +MD: MachineDataInfo: runtimeValidated true, 32Bit false, primitive size / alignment: + int8 1 / 1, int16 2 / 2 + int 4 / 4, long 8 / 8 + int32 4 / 4, int64 8 / 8 + float 4 / 4, double 8 / 8, ldouble 16 / 16 + pointer 8 / 8, page 4096 + + +++++ TestCase.tearDown: com.jogamp.common.util.TestPlatform01 - testInfo00 +.++++ TestCase.setUp: com.jogamp.common.util.TestPlatform01 - testPageSize01 +PageSize: 4096 +++++ TestCase.tearDown: com.jogamp.common.util.TestPlatform01 - testPageSize01 +++++ Test Singleton.unlock() +SLOCK [T SingletonServerSocket1-localhost/127.0.0.1:59999 @ 1442811548171 ms III - Stopping: alive true, shallQuit true, hasSocket true +SLOCK [T main @ 1442811548171 ms --- localhost/127.0.0.1:59999 - Unlock ok within 1 ms + +Time: 0.693 + +OK (2 tests) + + diff -Nru gluegen2-2.2.4/doc/Implementation/IOUtil.testDirExe/win32-noexec-invalid_executable.log gluegen2-2.3.2/doc/Implementation/IOUtil.testDirExe/win32-noexec-invalid_executable.log --- gluegen2-2.2.4/doc/Implementation/IOUtil.testDirExe/win32-noexec-invalid_executable.log 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/doc/Implementation/IOUtil.testDirExe/win32-noexec-invalid_executable.log 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,118 @@ +JUnit version 4.11 +++++ Test Singleton.ctor() +++++ Test Singleton.lock() +SLOCK [T SingletonServerSocket1-localhost/127.0.0.1:59999 @ 1442717359736 ms III - Start +SLOCK [T main @ 1442717359736 ms +++ localhost/127.0.0.1:59999 - Locked within 1047 ms, 1 attempts +.++++ TestCase.setUp: com.jogamp.common.util.TestPlatform01 - testInfo00 + +IOUtil.getTempRoot(): tempX1 , used true +IOUtil.getTempRoot(): tempX3 , used false +IOUtil.getTempRoot(): tempX4 , used true +IOUtil.getTempRoot(): tempX2 , used false +IOUtil.testDirExec: : Caught IOException: Cannot run program "C:\cygwin\tmp\jogamp_exe_tst.exe": CreateProcess error=216, This version of %1 is not compatible with the version of Windows you're running. Check your computer's system information to see whether you need a x86 (32-bit) or x64 (64-bit) version of the program, and then contact the software publisher +java.io.IOException: Cannot run program "C:\cygwin\tmp\jogamp_exe_tst.exe": CreateProcess error=216, This version of %1 is not compatible with the version of Windows you're running. Check your computer's system information to see whether you need a x86 (32-bit) or x64 (64-bit) version of the program, and then contact the software publisher + at java.lang.ProcessBuilder.start(Unknown Source) + at java.lang.Runtime.exec(Unknown Source) + at com.jogamp.common.util.IOUtil.testDirExec(IOUtil.java:948) + at com.jogamp.common.util.IOUtil.testDirImpl(IOUtil.java:990) + at com.jogamp.common.util.IOUtil.getSubTempDir(IOUtil.java:1050) + at com.jogamp.common.util.IOUtil.getTempDir(IOUtil.java:1165) + at com.jogamp.common.util.cache.TempFileCache.(TempFileCache.java:81) + at com.jogamp.common.util.cache.TempJarCache.initSingleton(TempJarCache.java:88) + at com.jogamp.common.os.Platform$1.run(Platform.java:309) + at java.security.AccessController.doPrivileged(Native Method) + at com.jogamp.common.os.Platform.(Platform.java:287) + at com.jogamp.common.util.TestPlatform01.testInfo00(TestPlatform01.java:47) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) + at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) + at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) + at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) + at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) + at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) + at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55) + at org.junit.rules.RunRules.evaluate(RunRules.java:20) + at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) + at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) + at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) + at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) + at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) + at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) + at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) + at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) + at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) + at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) + at org.junit.runners.ParentRunner.run(ParentRunner.java:309) + at org.junit.runners.Suite.runChild(Suite.java:127) + at org.junit.runners.Suite.runChild(Suite.java:26) + at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) + at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) + at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) + at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) + at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) + at org.junit.runners.ParentRunner.run(ParentRunner.java:309) + at org.junit.runner.JUnitCore.run(JUnitCore.java:160) + at org.junit.runner.JUnitCore.run(JUnitCore.java:138) + at org.junit.runner.JUnitCore.run(JUnitCore.java:117) + at org.junit.runner.JUnitCore.runMain(JUnitCore.java:96) + at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:47) + at org.junit.runner.JUnitCore.main(JUnitCore.java:40) + at com.jogamp.common.util.TestPlatform01.main(TestPlatform01.java:93) +Caused by: java.io.IOException: CreateProcess error=216, This version of %1 is not compatible with the version of Windows you're running. Check your computer's system information to see whether you need a x86 (32-bit) or x64 (64-bit) version of the program, and then contact the software publisher + at java.lang.ProcessImpl.create(Native Method) + at java.lang.ProcessImpl.(Unknown Source) + at java.lang.ProcessImpl.start(Unknown Source) + ... 50 more +IOUtil.testDirExec(): test-exe , existingFile true +IOUtil.testDirExec(): abs-path : res -2 -> false +IOUtil.testDirExec(): total 63ms, create 0ms, execute 63ms +IOUtil.testDirImpl(tempX1): , create true, exec true: false +IOUtil: locating , has cl: true +AssetURLContext.resolve: +ERR(0): no protocol: com/jogamp/common/util/bin/exe-windows-i386-2048b.bin.316b.gz +AssetURLContext.resolve: type 2: url , conn , connURL +IOUtil: found within class package of given class : true +IOUtil.testDirExec(): test-exe , existingFile false +IOUtil.testDirExec(): abs-path : res 0 -> true +IOUtil.testDirExec(): total 578ms, create 94ms, execute 484ms +IOUtil.testDirImpl(tempX4): , create true, exec true: true +IOUtil.testDirExec(): test-exe , existingFile false +IOUtil.testDirExec(): abs-path : res 0 -> true +IOUtil.testDirExec(): total 16ms, create 0ms, execute 16ms +IOUtil.testDirImpl(tempX4): , create true, exec true: true +IOUtil.getTempRoot(): temp dirs: exec: C:\Users\sven\.jogamp_0000, noexec: C:\Users\sven\.jogamp_0000 +IOUtil.testDirImpl(testDir): , create true, exec false: true + +OS name/type: Windows 7, WINDOWS +OS version: 6.1, 6.1.0 + +Arch, CPU: amd64, X86_64/X86 +OS/Arch: windows-amd64 + +Java runtime: Java(TM) SE Runtime Environment +Java vendor[name/url]: Oracle Corporation/http://java.oracle.com/ +Java version, vm: 1.8.0_60, Java HotSpot(TM) 64-Bit Server VM + +MD: MachineDataInfo: runtimeValidated true, 32Bit false, primitive size / alignment: + int8 1 / 1, int16 2 / 2 + int 4 / 4, long 4 / 4 + int32 4 / 4, int64 8 / 8 + float 4 / 4, double 8 / 8, ldouble 16 / 16 + pointer 8 / 8, page 4096 + + +++++ TestCase.tearDown: com.jogamp.common.util.TestPlatform01 - testInfo00 +.++++ TestCase.setUp: com.jogamp.common.util.TestPlatform01 - testPageSize01 +PageSize: 4096 +++++ TestCase.tearDown: com.jogamp.common.util.TestPlatform01 - testPageSize01 +++++ Test Singleton.unlock() +SLOCK [T SingletonServerSocket1-localhost/127.0.0.1:59999 @ 1442717360611 ms III - Stopping: alive true, shallQuit true, hasSocket true +SLOCK [T main @ 1442717360611 ms --- localhost/127.0.0.1:59999 - Unlock ok within 0 ms + +Time: 2.437 + +OK (2 tests) + diff -Nru gluegen2-2.2.4/doc/Implementation/IOUtil.testDirExe/win32-noexec-ntfs_attribs_deny_execute_file.log gluegen2-2.3.2/doc/Implementation/IOUtil.testDirExe/win32-noexec-ntfs_attribs_deny_execute_file.log --- gluegen2-2.2.4/doc/Implementation/IOUtil.testDirExe/win32-noexec-ntfs_attribs_deny_execute_file.log 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/doc/Implementation/IOUtil.testDirExe/win32-noexec-ntfs_attribs_deny_execute_file.log 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,118 @@ +JUnit version 4.11 +++++ Test Singleton.ctor() +++++ Test Singleton.lock() +SLOCK [T SingletonServerSocket1-localhost/127.0.0.1:59999 @ 1442716830836 ms III - Start +SLOCK [T main @ 1442716830836 ms +++ localhost/127.0.0.1:59999 - Locked within 1032 ms, 1 attempts +.++++ TestCase.setUp: com.jogamp.common.util.TestPlatform01 - testInfo00 + +IOUtil.getTempRoot(): tempX1 , used true +IOUtil.getTempRoot(): tempX3 , used false +IOUtil.getTempRoot(): tempX4 , used true +IOUtil.getTempRoot(): tempX2 , used false +IOUtil: locating , has cl: true +AssetURLContext.resolve: +ERR(0): no protocol: com/jogamp/common/util/bin/exe-windows-i386-2048b.bin.316b.gz +AssetURLContext.resolve: type 2: url , conn , connURL +IOUtil: found within class package of given class : true +IOUtil.testDirExec: : Caught IOException: Cannot run program "C:\cygwin\tmp\jogamp_exe_tst.exe": CreateProcess error=5, Access is denied +java.io.IOException: Cannot run program "C:\cygwin\tmp\jogamp_exe_tst.exe": CreateProcess error=5, Access is denied + at java.lang.ProcessBuilder.start(Unknown Source) + at java.lang.Runtime.exec(Unknown Source) + at com.jogamp.common.util.IOUtil.testDirExec(IOUtil.java:943) + at com.jogamp.common.util.IOUtil.testDirImpl(IOUtil.java:985) + at com.jogamp.common.util.IOUtil.getSubTempDir(IOUtil.java:1045) + at com.jogamp.common.util.IOUtil.getTempDir(IOUtil.java:1160) + at com.jogamp.common.util.cache.TempFileCache.(TempFileCache.java:81) + at com.jogamp.common.util.cache.TempJarCache.initSingleton(TempJarCache.java:88) + at com.jogamp.common.os.Platform$1.run(Platform.java:309) + at java.security.AccessController.doPrivileged(Native Method) + at com.jogamp.common.os.Platform.(Platform.java:287) + at com.jogamp.common.util.TestPlatform01.testInfo00(TestPlatform01.java:47) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) + at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) + at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) + at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) + at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) + at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) + at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55) + at org.junit.rules.RunRules.evaluate(RunRules.java:20) + at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) + at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) + at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) + at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) + at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) + at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) + at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) + at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) + at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) + at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) + at org.junit.runners.ParentRunner.run(ParentRunner.java:309) + at org.junit.runners.Suite.runChild(Suite.java:127) + at org.junit.runners.Suite.runChild(Suite.java:26) + at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) + at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) + at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) + at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) + at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) + at org.junit.runners.ParentRunner.run(ParentRunner.java:309) + at org.junit.runner.JUnitCore.run(JUnitCore.java:160) + at org.junit.runner.JUnitCore.run(JUnitCore.java:138) + at org.junit.runner.JUnitCore.run(JUnitCore.java:117) + at org.junit.runner.JUnitCore.runMain(JUnitCore.java:96) + at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:47) + at org.junit.runner.JUnitCore.main(JUnitCore.java:40) + at com.jogamp.common.util.TestPlatform01.main(TestPlatform01.java:93) +Caused by: java.io.IOException: CreateProcess error=5, Access is denied + at java.lang.ProcessImpl.create(Native Method) + at java.lang.ProcessImpl.(Unknown Source) + at java.lang.ProcessImpl.start(Unknown Source) + ... 50 more +IOUtil.testDirExec(): test-exe +IOUtil.testDirExec(): abs-path : res -2 -> false +IOUtil.testDirExec(): total 125ms, create 0ms, execute 125ms +IOUtil.testDirImpl(tempX1): , create true, exec true: false +IOUtil.testDirExec(): test-exe +IOUtil.testDirExec(): abs-path : res 0 -> true +IOUtil.testDirExec(): total 156ms, create 78ms, execute 78ms +IOUtil.testDirImpl(tempX4): , create true, exec true: true +IOUtil.testDirExec(): test-exe +IOUtil.testDirExec(): abs-path : res 0 -> true +IOUtil.testDirExec(): total 47ms, create 0ms, execute 47ms +IOUtil.testDirImpl(tempX4): , create true, exec true: true +IOUtil.getTempRoot(): temp dirs: exec: C:\Users\sven\.jogamp_0000, noexec: C:\Users\sven\.jogamp_0000 +IOUtil.testDirImpl(testDir): , create true, exec false: true + +OS name/type: Windows 7, WINDOWS +OS version: 6.1, 6.1.0 + +Arch, CPU: amd64, X86_64/X86 +OS/Arch: windows-amd64 + +Java runtime: Java(TM) SE Runtime Environment +Java vendor[name/url]: Oracle Corporation/http://java.oracle.com/ +Java version, vm: 1.8.0_60, Java HotSpot(TM) 64-Bit Server VM + +MD: MachineDataInfo: runtimeValidated true, 32Bit false, primitive size / alignment: + int8 1 / 1, int16 2 / 2 + int 4 / 4, long 4 / 4 + int32 4 / 4, int64 8 / 8 + float 4 / 4, double 8 / 8, ldouble 16 / 16 + pointer 8 / 8, page 4096 + + +++++ TestCase.tearDown: com.jogamp.common.util.TestPlatform01 - testInfo00 +.++++ TestCase.setUp: com.jogamp.common.util.TestPlatform01 - testPageSize01 +PageSize: 4096 +++++ TestCase.tearDown: com.jogamp.common.util.TestPlatform01 - testPageSize01 +++++ Test Singleton.unlock() +SLOCK [T SingletonServerSocket1-localhost/127.0.0.1:59999 @ 1442716831367 ms III - Stopping: alive true, shallQuit true, hasSocket true +SLOCK [T main @ 1442716831367 ms --- localhost/127.0.0.1:59999 - Unlock ok within 0 ms + +Time: 2.078 + +OK (2 tests) + diff -Nru gluegen2-2.2.4/doc/Implementation/IOUtil.testDirExe/win32-noexec-SoftwareRestrictionPolicies.log gluegen2-2.3.2/doc/Implementation/IOUtil.testDirExe/win32-noexec-SoftwareRestrictionPolicies.log --- gluegen2-2.2.4/doc/Implementation/IOUtil.testDirExe/win32-noexec-SoftwareRestrictionPolicies.log 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/doc/Implementation/IOUtil.testDirExe/win32-noexec-SoftwareRestrictionPolicies.log 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,118 @@ +JUnit version 4.11 +++++ Test Singleton.ctor() +++++ Test Singleton.lock() +SLOCK [T SingletonServerSocket1-localhost/127.0.0.1:59999 @ 1442715964261 ms III - Start +SLOCK [T main @ 1442715964261 ms +++ localhost/127.0.0.1:59999 - Locked within 1032 ms, 1 attempts +.++++ TestCase.setUp: com.jogamp.common.util.TestPlatform01 - testInfo00 + +IOUtil.getTempRoot(): tempX1 , used true +IOUtil.getTempRoot(): tempX3 , used false +IOUtil.getTempRoot(): tempX4 , used true +IOUtil.getTempRoot(): tempX2 , used false +IOUtil: locating , has cl: true +AssetURLContext.resolve: +ERR(0): no protocol: com/jogamp/common/util/bin/exe-windows-i386-2048b.bin.316b.gz +AssetURLContext.resolve: type 2: url , conn , connURL +IOUtil: found within class package of given class : true +IOUtil.testDirExec: : Caught IOException: Cannot run program "C:\cygwin\tmp\jogamp_exe_tst2114409495120940481.exe": CreateProcess error=1260, This program is blocked by group policy. For more information, contact your system administrator +java.io.IOException: Cannot run program "C:\cygwin\tmp\jogamp_exe_tst2114409495120940481.exe": CreateProcess error=1260, This program is blocked by group policy. For more information, contact your system administrator + at java.lang.ProcessBuilder.start(Unknown Source) + at java.lang.Runtime.exec(Unknown Source) + at com.jogamp.common.util.IOUtil.testDirExec(IOUtil.java:938) + at com.jogamp.common.util.IOUtil.testDirImpl(IOUtil.java:980) + at com.jogamp.common.util.IOUtil.getSubTempDir(IOUtil.java:1040) + at com.jogamp.common.util.IOUtil.getTempDir(IOUtil.java:1155) + at com.jogamp.common.util.cache.TempFileCache.(TempFileCache.java:81) + at com.jogamp.common.util.cache.TempJarCache.initSingleton(TempJarCache.java:88) + at com.jogamp.common.os.Platform$1.run(Platform.java:309) + at java.security.AccessController.doPrivileged(Native Method) + at com.jogamp.common.os.Platform.(Platform.java:287) + at com.jogamp.common.util.TestPlatform01.testInfo00(TestPlatform01.java:47) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) + at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) + at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) + at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) + at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) + at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) + at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55) + at org.junit.rules.RunRules.evaluate(RunRules.java:20) + at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) + at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) + at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) + at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) + at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) + at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) + at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) + at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) + at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) + at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) + at org.junit.runners.ParentRunner.run(ParentRunner.java:309) + at org.junit.runners.Suite.runChild(Suite.java:127) + at org.junit.runners.Suite.runChild(Suite.java:26) + at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) + at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) + at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) + at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) + at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) + at org.junit.runners.ParentRunner.run(ParentRunner.java:309) + at org.junit.runner.JUnitCore.run(JUnitCore.java:160) + at org.junit.runner.JUnitCore.run(JUnitCore.java:138) + at org.junit.runner.JUnitCore.run(JUnitCore.java:117) + at org.junit.runner.JUnitCore.runMain(JUnitCore.java:96) + at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:47) + at org.junit.runner.JUnitCore.main(JUnitCore.java:40) + at com.jogamp.common.util.TestPlatform01.main(TestPlatform01.java:93) +Caused by: java.io.IOException: CreateProcess error=1260, This program is blocked by group policy. For more information, contact your system administrator + at java.lang.ProcessImpl.create(Native Method) + at java.lang.ProcessImpl.(Unknown Source) + at java.lang.ProcessImpl.start(Unknown Source) + ... 50 more +IOUtil.testDirExec(): test-exe +IOUtil.testDirExec(): abs-path : res -2 -> false +IOUtil.testDirExec(): total 172ms, create 78ms, execute 94ms +IOUtil.testDirImpl(tempX1): , create true, exec true: false +IOUtil.testDirExec(): test-exe +IOUtil.testDirExec(): abs-path : res 0 -> true +IOUtil.testDirExec(): total 78ms, create 0ms, execute 78ms +IOUtil.testDirImpl(tempX4): , create true, exec true: true +IOUtil.testDirExec(): test-exe +IOUtil.testDirExec(): abs-path : res 0 -> true +IOUtil.testDirExec(): total 16ms, create 0ms, execute 16ms +IOUtil.testDirImpl(tempX4): , create true, exec true: true +IOUtil.getTempRoot(): temp dirs: exec: C:\Users\sven\.jogamp_0000, noexec: C:\Users\sven\.jogamp_0000 +IOUtil.testDirImpl(testDir): , create true, exec false: true + +OS name/type: Windows 7, WINDOWS +OS version: 6.1, 6.1.0 + +Arch, CPU: amd64, X86_64/X86 +OS/Arch: windows-amd64 + +Java runtime: Java(TM) SE Runtime Environment +Java vendor[name/url]: Oracle Corporation/http://java.oracle.com/ +Java version, vm: 1.8.0_60, Java HotSpot(TM) 64-Bit Server VM + +MD: MachineDataInfo: runtimeValidated true, 32Bit false, primitive size / alignment: + int8 1 / 1, int16 2 / 2 + int 4 / 4, long 4 / 4 + int32 4 / 4, int64 8 / 8 + float 4 / 4, double 8 / 8, ldouble 16 / 16 + pointer 8 / 8, page 4096 + + +++++ TestCase.tearDown: com.jogamp.common.util.TestPlatform01 - testInfo00 +.++++ TestCase.setUp: com.jogamp.common.util.TestPlatform01 - testPageSize01 +PageSize: 4096 +++++ TestCase.tearDown: com.jogamp.common.util.TestPlatform01 - testPageSize01 +++++ Test Singleton.unlock() +SLOCK [T SingletonServerSocket1-localhost/127.0.0.1:59999 @ 1442715964729 ms III - Stopping: alive true, shallQuit true, hasSocket true +SLOCK [T main @ 1442715964729 ms --- localhost/127.0.0.1:59999 - Unlock ok within 0 ms + +Time: 2.015 + +OK (2 tests) + diff -Nru gluegen2-2.2.4/doc/licenses/Apache.LICENSE-2.0 gluegen2-2.3.2/doc/licenses/Apache.LICENSE-2.0 --- gluegen2-2.2.4/doc/licenses/Apache.LICENSE-2.0 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/doc/licenses/Apache.LICENSE-2.0 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff -Nru gluegen2-2.2.4/doc/manual/index.html gluegen2-2.3.2/doc/manual/index.html --- gluegen2-2.2.4/doc/manual/index.html 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/doc/manual/index.html 2015-10-09 04:18:28.000000000 +0000 @@ -280,7 +280,7 @@ supports binding C and C++ libraries to a variety of scripting languages; JNIWrapper, a commercial tool automating the binding of C APIs to Java; and NoodleGlue, + href="http://web.archive.org/web/20070419183658/http://www.noodleglue.org/noodleglue/noodleglue.html">NoodleGlue, a recently-released tool automating the binding of C++ APIs to Java. Other language-specific tools such as Perl's XS, Boost.Python and many others exist. @@ -350,7 +350,7 @@ The source code for GlueGen may be obtained by cloning the Git repository:
    -    $git clone git://github.com/mbien/gluegen.git gluegen
    +    $git clone --recursive git://jogamp.org/srv/scm/gluegen.git gluegen
                         
    To build GlueGen, cd into the gluegen/make folder and invoke ant. @@ -450,8 +450,8 @@ </gluegen> - Please see the JOGL and JOAL build.xml files for + Please see the JOGL and JOAL build.xml files for concrete, though non-trivial, examples of how to invoke GlueGen via Ant. diff -Nru gluegen2-2.2.4/.gitmodules gluegen2-2.3.2/.gitmodules --- gluegen2-2.2.4/.gitmodules 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/.gitmodules 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,3 @@ +[submodule "jcpp"] + path = jcpp + url = ../jcpp diff -Nru gluegen2-2.2.4/jcpp/.gitignore gluegen2-2.3.2/jcpp/.gitignore --- gluegen2-2.2.4/jcpp/.gitignore 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/.gitignore 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,4 @@ +build +.*.swp +.gradle +.nb-gradle diff -Nru gluegen2-2.2.4/jcpp/LICENSE gluegen2-2.3.2/jcpp/LICENSE --- gluegen2-2.2.4/jcpp/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/LICENSE 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +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. diff -Nru gluegen2-2.2.4/jcpp/README.md gluegen2-2.3.2/jcpp/README.md --- gluegen2-2.2.4/jcpp/README.md 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/README.md 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,31 @@ +# Introduction + +The C Preprocessor is an interesting standard. It appears to be +derived from the de-facto behaviour of the first preprocessors, and +has evolved over the years. Implementation is therefore difficult. + +JCPP is a complete, compliant, standalone, pure Java implementation +of the C preprocessor. It is intended to be of use to people writing +C-style compilers in Java using tools like sablecc, antlr, JLex, +CUP and so forth (although if you aren't using sablecc, you need your +head examined). + +This project has has been used to successfully preprocess much of +the source code of the GNU C library. As of version 1.2.5, it can +also preprocess the Apple Objective C library. + +# JogAmp Branch + +This branch is modified for JogAmp +to supply [GlueGen](http://jogamp.org/gluegen/www/) with JCPP. + +This branch is only intended as a submodule for GlueGen +and hence must be [build from within GlueGen](http://jogamp.org/gluegen/doc/HowToBuild.html). + +# Original JCPP Version +* [Homepage](http://www.anarres.org/projects/jcpp/) +* [GitHub](https://github.com/shevek/jcpp.git) + +# Documentation + +* [JavaDoc API](http://jogamp.org/deployment/jogamp-next/javadoc/gluegen/javadoc/) diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Argument.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Argument.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Argument.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Argument.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,75 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import javax.annotation.Nonnull; + +/** + * A macro argument. + * + * This encapsulates a raw and preprocessed token stream. + */ +/* pp */ class Argument extends ArrayList { + + private List expansion; + + public Argument() { + this.expansion = null; + } + + public void addToken(@Nonnull Token tok) { + add(tok); + } + + /* pp */ void expand(@Nonnull Preprocessor p) + throws IOException, + LexerException { + /* Cache expansion. */ + if (expansion == null) { + this.expansion = p.expand(this); + // System.out.println("Expanded arg " + this); + } + } + + @Nonnull + public Iterator expansion() { + return expansion.iterator(); + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append("Argument("); + // buf.append(super.toString()); + buf.append("raw=[ "); + for (int i = 0; i < size(); i++) + buf.append(get(i).getText()); + buf.append(" ];expansion=[ "); + if (expansion == null) + buf.append("null"); + else + for (Token token : expansion) + buf.append(token.getText()); + buf.append(" ])"); + return buf.toString(); + } + +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/ChrootFileSystem.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/ChrootFileSystem.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/ChrootFileSystem.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/ChrootFileSystem.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,84 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.File; +import java.io.IOException; + +/** + * A virtual filesystem implementation using java.io in a virtual + * chroot. + */ +public class ChrootFileSystem implements VirtualFileSystem { + + private File root; + + public ChrootFileSystem(File root) { + this.root = root; + } + + @Override + public VirtualFile getFile(String path) { + return new ChrootFile(path); + } + + @Override + public VirtualFile getFile(String dir, String name) { + return new ChrootFile(dir, name); + } + + private class ChrootFile extends File implements VirtualFile { + + private File rfile; + + public ChrootFile(String path) { + super(path); + } + + public ChrootFile(String dir, String name) { + super(dir, name); + } + + /* private */ + public ChrootFile(File dir, String name) { + super(dir, name); + } + + @Override + public ChrootFile getParentFile() { + return new ChrootFile(getParent()); + } + + @Override + public ChrootFile getChildFile(String name) { + return new ChrootFile(this, name); + } + + @Override + public boolean isFile() { + File real = new File(root, getPath()); + return real.isFile(); + } + + @Override + public Source getSource() throws IOException { + return new FileLexerSource(new File(root, getPath()), + getPath()); + } + } + +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/CppReader.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/CppReader.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/CppReader.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/CppReader.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,149 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.Closeable; +import java.io.IOException; +import java.io.Reader; + +import javax.annotation.Nonnull; + +import static com.jogamp.gluegen.jcpp.Token.CCOMMENT; +import static com.jogamp.gluegen.jcpp.Token.CPPCOMMENT; +import static com.jogamp.gluegen.jcpp.Token.EOF; + +/** + * A Reader wrapper around the Preprocessor. + * + * This is a utility class to provide a transparent {@link Reader} + * which preprocesses the input text. + * + * @see Preprocessor + * @see Reader + */ +public class CppReader extends Reader implements Closeable { + + private final Preprocessor cpp; + private String token; + private int idx; + + public CppReader(@Nonnull final Reader r) { + cpp = new Preprocessor(new LexerSource(r, true) { + @Override + public String getName() { + return ""; + } + }); + token = ""; + idx = 0; + } + + public CppReader(@Nonnull Preprocessor p) { + cpp = p; + token = ""; + idx = 0; + } + + /** + * Returns the Preprocessor used by this CppReader. + */ + @Nonnull + public Preprocessor getPreprocessor() { + return cpp; + } + + /** + * Defines the given name as a macro. + * + * This is a convnience method. + */ + public void addMacro(@Nonnull String name) + throws LexerException { + cpp.addMacro(name); + } + + /** + * Defines the given name as a macro. + * + * This is a convnience method. + */ + public void addMacro(@Nonnull String name, @Nonnull String value) + throws LexerException { + cpp.addMacro(name, value); + } + + private boolean refill() + throws IOException { + try { + assert cpp != null : "cpp is null : was it closed?"; + if (token == null) + return false; + while (idx >= token.length()) { + Token tok = cpp.token(); + switch (tok.getType()) { + case EOF: + token = null; + return false; + case CCOMMENT: + case CPPCOMMENT: + if (!cpp.getFeature(Feature.KEEPCOMMENTS)) { + token = " "; + break; + } + default: + token = tok.getText(); + break; + } + idx = 0; + } + return true; + } catch (LexerException e) { + throw new IOException(String.valueOf(e), e); + } + } + + @Override + public int read() + throws IOException { + if (!refill()) + return -1; + return token.charAt(idx++); + } + + /* XXX Very slow and inefficient. */ + public int read(char cbuf[], int off, int len) + throws IOException { + if (token == null) + return -1; + for (int i = 0; i < len; i++) { + int ch = read(); + if (ch == -1) + return i; + cbuf[off + i] = (char) ch; + } + return len; + } + + @Override + public void close() + throws IOException { + cpp.close(); + token = null; + } + +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/CppTask.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/CppTask.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/CppTask.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/CppTask.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,215 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.List; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.taskdefs.Copy; +import org.apache.tools.ant.types.FilterSet; +import org.apache.tools.ant.types.FilterSetCollection; +import org.apache.tools.ant.types.Path; + +/** + * An ant task for jcpp. + */ +public class CppTask extends Copy { + + private class Listener extends DefaultPreprocessorListener { + + @Override + protected void print(String msg) { + log(msg); + } + } + + public static class Macro { + + private String name; + private String value; + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setValue(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + private final Listener listener = new Listener(); + private final List macros = new ArrayList(); + private Path systemincludepath; + private Path localincludepath; + + public void addMacro(Macro macro) { + macros.add(macro); + } + + public void addSystemincludepath(Path path) { + if (systemincludepath == null) + systemincludepath = new Path(getProject()); + systemincludepath.add(path); + } + + public void addLocalincludepath(Path path) { + if (localincludepath == null) + localincludepath = new Path(getProject()); + localincludepath.add(path); + } + + /* + public void execute() { + FileWriter writer = null; + try { + if (input == null) + throw new BuildException("Input not specified"); + if (output == null) + throw new BuildException("Output not specified"); + cpp.addInput(this.input); + writer = new FileWriter(this.output); + for (;;) { + Token tok = cpp.token(); + if (tok != null && tok.getType() == Token.EOF) + break; + writer.write(tok.getText()); + } + } + catch (Exception e) { + throw new BuildException(e); + } + finally { + if (writer != null) { + try { + writer.close(); + } + catch (IOException e) { + } + } + } + } + */ + private void preprocess(File input, File output) throws Exception { + Preprocessor cpp = new Preprocessor(); + cpp.setListener(listener); + for (Macro macro : macros) + cpp.addMacro(macro.getName(), macro.getValue()); + if (systemincludepath != null) + cpp.setSystemIncludePath(Arrays.asList(systemincludepath.list())); + if (localincludepath != null) + cpp.setQuoteIncludePath(Arrays.asList(localincludepath.list())); + + File dir = output.getParentFile(); + if (!dir.exists()) { + if (!dir.mkdirs()) + throw new BuildException("Failed to make parent directory " + dir); + } else if (!dir.isDirectory()) { + throw new BuildException("Parent directory of output file " + output + " exists, but is not a directory."); + } + FileWriter writer = null; + try { + if (input == null) + throw new BuildException("Input not specified"); + if (output == null) + throw new BuildException("Output not specified"); + cpp.addInput(input); + writer = new FileWriter(output); + for (;;) { + Token tok = cpp.token(); + if (tok == null) + break; + if (tok.getType() == Token.EOF) + break; + writer.write(tok.getText()); + } + } finally { + if (writer != null) { + try { + writer.close(); + } catch (IOException e) { + } + } + } + } + + @Override + protected void doFileOperations() { + if (fileCopyMap.size() > 0) { + log("Copying " + fileCopyMap.size() + + " file" + (fileCopyMap.size() == 1 ? "" : "s") + + " to " + destDir.getAbsolutePath()); + + Enumeration e = fileCopyMap.keys(); + + while (e.hasMoreElements()) { + String fromFile = e.nextElement(); + String[] toFiles = (String[]) fileCopyMap.get(fromFile); + + for (String toFile : toFiles) { + if (fromFile.equals(toFile)) { + log("Skipping self-copy of " + fromFile, verbosity); + continue; + } + + try { + log("Copying " + fromFile + " to " + toFile, verbosity); + + FilterSetCollection executionFilters + = new FilterSetCollection(); + if (filtering) { + executionFilters + .addFilterSet(getProject().getGlobalFilterSet()); + } + for (Enumeration filterEnum = getFilterSets().elements(); + filterEnum.hasMoreElements();) { + executionFilters + .addFilterSet((FilterSet) filterEnum.nextElement()); + } + + File srcFile = new File(fromFile); + File dstFile = new File(toFile); + preprocess(srcFile, dstFile); + } catch (Exception ioe) { + // ioe.printStackTrace(); + String msg = "Failed to copy " + fromFile + " to " + toFile + + " due to " + ioe.getMessage(); + File targetFile = new File(toFile); + if (targetFile.exists() && !targetFile.delete()) { + msg += " and I couldn't delete the corrupt " + toFile; + } + throw new BuildException(msg, ioe, getLocation()); + } + } + } + } + + } + +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/DefaultPreprocessorListener.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/DefaultPreprocessorListener.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/DefaultPreprocessorListener.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/DefaultPreprocessorListener.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,99 @@ +package com.jogamp.gluegen.jcpp; + +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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. + */ +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; + +import com.jogamp.gluegen.Logging; +import com.jogamp.gluegen.Logging.LoggerIf; + +/** + * A handler for preprocessor events, primarily errors and warnings. + * + * If no PreprocessorListener is installed in a Preprocessor, all + * error and warning events will throw an exception. Installing a + * listener allows more intelligent handling of these events. + */ +public class DefaultPreprocessorListener implements PreprocessorListener { + + private final LoggerIf LOG; + + private int errors; + private int warnings; + + public DefaultPreprocessorListener() { + LOG = Logging.getLogger(DefaultPreprocessorListener.class); + clear(); + } + + public void clear() { + errors = 0; + warnings = 0; + } + + @Nonnegative + public int getErrors() { + return errors; + } + + @Nonnegative + public int getWarnings() { + return warnings; + } + + protected void print(@Nonnull final String msg) { + LOG.info(msg); + } + + /** + * Handles a warning. + * + * The behaviour of this method is defined by the + * implementation. It may simply record the error message, or + * it may throw an exception. + */ + @Override + public void handleWarning(final Source source, final int line, final int column, + final String msg) + throws LexerException { + warnings++; + print(source.getName() + ":" + line + ":" + column + + ": warning: " + msg); + } + + /** + * Handles an error. + * + * The behaviour of this method is defined by the + * implementation. It may simply record the error message, or + * it may throw an exception. + */ + @Override + public void handleError(final Source source, final int line, final int column, + final String msg) + throws LexerException { + errors++; + print(source.getName() + ":" + line + ":" + column + + ": error: " + msg); + } + + @Override + public void handleSourceChange(final Source source, final SourceChangeEvent event) { + } + +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Feature.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Feature.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Feature.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Feature.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,42 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +/** + * Features of the Preprocessor, which may be enabled or disabled. + */ +public enum Feature { + + /** Supports ANSI digraphs. */ + DIGRAPHS, + /** Supports ANSI trigraphs. */ + TRIGRAPHS, + /** Outputs linemarker tokens. */ + LINEMARKERS, + /** Reports tokens of type INVALID as errors. */ + CSYNTAX, + /** Preserves comments in the lexed output. */ + KEEPCOMMENTS, + /** Preserves comments in the lexed output, even when inactive. */ + KEEPALLCOMMENTS, + DEBUG, + /** Supports lexing of objective-C. */ + OBJCSYNTAX, + INCLUDENEXT, + /** Random extensions. */ + PRAGMA_ONCE +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/FileLexerSource.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/FileLexerSource.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/FileLexerSource.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/FileLexerSource.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,89 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import javax.annotation.Nonnull; + +/** + * A {@link Source} which lexes a file. + * + * The input is buffered. + * + * @see Source + */ +public class FileLexerSource extends LexerSource { + + private final String path; + private final File file; + + /** + * Creates a new Source for lexing the given File. + * + * Preprocessor directives are honoured within the file. + */ + public FileLexerSource(@Nonnull File file, String path) + throws IOException { + super( + new BufferedReader( + new FileReader( + file + ) + ), + true + ); + + this.file = file; + this.path = path; + } + + public FileLexerSource(@Nonnull File file) + throws IOException { + this(file, file.getPath()); + } + + public FileLexerSource(@Nonnull String path) + throws IOException { + this(new File(path), path); + } + + @Nonnull + public File getFile() { + return file; + } + + /** + * This is not necessarily the same as getFile().getPath() in case we are in a chroot. + */ + @Override + public String getPath() { + return path; + } + + @Override + public String getName() { + return getPath(); + } + + @Override + public String toString() { + return "file " + getPath(); + } +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/FixedTokenSource.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/FixedTokenSource.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/FixedTokenSource.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/FixedTokenSource.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,59 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +/* pp */ class FixedTokenSource extends Source { + + private static final Token EOF + = new Token(Token.EOF, ""); + + private final List tokens; + private int idx; + + /* pp */ FixedTokenSource(Token... tokens) { + this.tokens = Arrays.asList(tokens); + this.idx = 0; + } + + /* pp */ FixedTokenSource(List tokens) { + this.tokens = tokens; + this.idx = 0; + } + + @Override + public Token token() + throws IOException, + LexerException { + if (idx >= tokens.size()) + return EOF; + return tokens.get(idx++); + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append("constant token stream ").append(tokens); + Source parent = getParent(); + if (parent != null) + buf.append(" in ").append(String.valueOf(parent)); + return buf.toString(); + } +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/InputLexerSource.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/InputLexerSource.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/InputLexerSource.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/InputLexerSource.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,64 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +/** + * A {@link Source} which lexes a file. + * + * The input is buffered. + * + * @see Source + */ +public class InputLexerSource extends LexerSource { + + /** + * Creates a new Source for lexing the given Reader. + * + * Preprocessor directives are honoured within the file. + */ + public InputLexerSource(InputStream input) + throws IOException { + super( + new BufferedReader( + new InputStreamReader( + input + ) + ), + true + ); + } + + @Override + public String getPath() { + return ""; + } + + @Override + public String getName() { + return "standard input"; + } + + @Override + public String toString() { + return String.valueOf(getPath()); + } +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/InternalException.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/InternalException.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/InternalException.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/InternalException.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,31 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +/** + * An internal exception. + * + * This exception is thrown when an internal state violation is + * encountered. This should never happen. If it ever happens, please + * report it as a bug. + */ +public class InternalException extends RuntimeException { + + public InternalException(String msg) { + super(msg); + } +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/JavaFileSystem.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/JavaFileSystem.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/JavaFileSystem.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/JavaFileSystem.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,84 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.File; +import java.io.IOException; + +/** + * A virtual filesystem implementation using java.io. + */ +public class JavaFileSystem implements VirtualFileSystem { + + @Override + public VirtualFile getFile(String path) { + return new JavaFile(path); + } + + @Override + public VirtualFile getFile(String dir, String name) { + return new JavaFile(dir, name); + } + + private class JavaFile extends File implements VirtualFile { + + public JavaFile(String path) { + super(path); + } + + public JavaFile(String dir, String name) { + super(dir, name); + } + + /* private */ + public JavaFile(File dir, String name) { + super(dir, name); + } + + /* + @Override + public String getPath() { + return getCanonicalPath(); + } + */ + @Override + public JavaFile getParentFile() { + String parent = getParent(); + if (parent != null) + return new JavaFile(parent); + File absolute = getAbsoluteFile(); + parent = absolute.getParent(); + /* + if (parent == null) + return null; + */ + return new JavaFile(parent); + } + + @Override + public JavaFile getChildFile(String name) { + return new JavaFile(this, name); + } + + @Override + public Source getSource() throws IOException { + return new FileLexerSource(this); + } + + } + +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/JCPP.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/JCPP.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/JCPP.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/JCPP.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,189 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * 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. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.gluegen.jcpp; + +import java.io.File; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.Reader; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; + +import com.jogamp.gluegen.ASTLocusTag; +import com.jogamp.gluegen.ConstantDefinition; +import com.jogamp.gluegen.GenericCPP; +import com.jogamp.gluegen.GlueGen; +import com.jogamp.gluegen.GlueGenException; +import com.jogamp.gluegen.Logging; +import com.jogamp.gluegen.Logging.LoggerIf; + +public class JCPP implements GenericCPP { + private final LoggerIf LOG; + + public final Preprocessor cpp; + private OutputStream out; + private final List includePaths; + private final boolean enableCopyOutput2Stderr; + + public JCPP(final List includePaths, final boolean debug, final boolean copyOutput2Stderr) { + LOG = Logging.getLogger(JCPP.class); + setOut(System.out); + this.includePaths = includePaths; + this.enableCopyOutput2Stderr = copyOutput2Stderr; + + cpp = new Preprocessor(); + cpp.addFeature(Feature.DIGRAPHS); + cpp.addFeature(Feature.TRIGRAPHS); + cpp.addFeature(Feature.LINEMARKERS); + cpp.addFeature(Feature.CSYNTAX); + cpp.addFeature(Feature.KEEPCOMMENTS); + cpp.addWarning(Warning.IMPORT); + cpp.setListener(new DefaultPreprocessorListener() { + @Override + public void handleError(final Source source, final int line, final int column, + final String msg) throws LexerException { + super.handleError(source, line, column, msg); + throw new GlueGenException(msg, new ASTLocusTag(source.getPath(), line, column, null)); + } + }); + if (debug) { + cpp.addFeature(Feature.DEBUG); + } + cpp.setSystemIncludePath(includePaths); + cpp.setQuoteIncludePath(includePaths); + + if (cpp.getFeature(Feature.DEBUG)) { + LOG.info("#" + "include \"...\" search starts here:"); + for (final String dir : cpp.getQuoteIncludePath()) + LOG.info(" " + dir); + LOG.info("#" + "include <...> search starts here:"); + for (final String dir : cpp.getSystemIncludePath()) + LOG.info(" " + dir); + LOG.info("End of search list."); + } + } + + @Override + public void addDefine(final String name, final String value) throws LexerException { + cpp.addMacro(name, value); + } + + @Override + public List getConstantDefinitions() throws GlueGenException { + final List constants = new ArrayList(); + final List macros; + try { + macros = cpp.getMacros(true); + } catch (final Throwable t) { + throw new GlueGenException(t); + } + final int count = macros.size(); + for(int i=0; i", + null != source ? source.getLine() : -1, + null != source ? source.getColumn() : -1, + macro.toString()); + final ConstantDefinition c = new ConstantDefinition(macro.getName(), value, null, locus); + constants.add(c); + } + } + } + } + return constants; + } + + @Override + public String findFile(final String filename) { + final String sep = File.separator; + for (final String inclPath : includePaths) { + final String fullPath = inclPath + sep + filename; + final File file = new File(fullPath); + if (file.exists()) { + return fullPath; + } + } + return null; + } + + @Override + public OutputStream out() { + return out; + } + @Override + public void setOut(final OutputStream out) { + this.out = out; + } + + @Override + public void run(final Reader reader, final String filename) throws GlueGenException { + final PrintWriter writer = new PrintWriter(out); + cpp.addInput(new LexerSource(reader, true) { + @Override + public String getPath() { return filename; } + @Override + public String getName() { return filename; } + @Override + public String toString() { return "file " + filename; } + } ); + try { + for (;;) { + final Token tok = cpp.token(); + if (tok == null) + break; + if (tok.getType() == Token.EOF) + break; + final String s = tok.getText(); + writer.print(s); + if (enableCopyOutput2Stderr) { + System.err.print(s); + System.err.flush(); + } + } + writer.flush(); + } catch (final Exception e) { + final StringBuilder buf = new StringBuilder("Preprocessor failed:\n"); + Source s = cpp.getSource(); + while (s != null) { + buf.append(" -> ").append(s).append("\n"); + s = s.getParent(); + } + buf.append(" : {0}\n"); + LOG.log(Level.SEVERE, buf.toString(), e); + if( e instanceof GlueGenException ) { + throw (GlueGenException)e; + } else { + throw new GlueGenException("Preprocessor failed", + new ASTLocusTag(null != s ? s.getPath() : "n/a", + null != s ? s.getLine() : -1, + null != s ? s.getColumn() : -1, null), e); + } + } + } + +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/JoinReader.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/JoinReader.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/JoinReader.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/JoinReader.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,218 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.Closeable; +import java.io.IOException; +import java.io.Reader; + +/* pp */ class JoinReader /* extends Reader */ implements Closeable { + + private final Reader in; + + private PreprocessorListener listener; + private LexerSource source; + private boolean trigraphs; + private boolean warnings; + + private int newlines; + private boolean flushnl; + private int[] unget; + private int uptr; + + public JoinReader(Reader in, boolean trigraphs) { + this.in = in; + this.trigraphs = trigraphs; + this.newlines = 0; + this.flushnl = false; + this.unget = new int[2]; + this.uptr = 0; + } + + public JoinReader(Reader in) { + this(in, false); + } + + public void setTrigraphs(boolean enable, boolean warnings) { + this.trigraphs = enable; + this.warnings = warnings; + } + + /* pp */ void init(Preprocessor pp, LexerSource s) { + this.listener = pp.getListener(); + this.source = s; + setTrigraphs(pp.getFeature(Feature.TRIGRAPHS), + pp.getWarning(Warning.TRIGRAPHS)); + } + + private int __read() throws IOException { + if (uptr > 0) + return unget[--uptr]; + return in.read(); + } + + private void _unread(int c) { + if (c != -1) + unget[uptr++] = c; + assert uptr <= unget.length : + "JoinReader ungets too many characters"; + } + + protected void warning(String msg) + throws LexerException { + if (source != null) + source.warning(msg); + else + throw new LexerException(msg); + } + + private char trigraph(char raw, char repl) + throws IOException, LexerException { + if (trigraphs) { + if (warnings) + warning("trigraph ??" + raw + " converted to " + repl); + return repl; + } else { + if (warnings) + warning("trigraph ??" + raw + " ignored"); + _unread(raw); + _unread('?'); + return '?'; + } + } + + private int _read() + throws IOException, LexerException { + int c = __read(); + if (c == '?' && (trigraphs || warnings)) { + int d = __read(); + if (d == '?') { + int e = __read(); + switch (e) { + case '(': + return trigraph('(', '['); + case ')': + return trigraph(')', ']'); + case '<': + return trigraph('<', '{'); + case '>': + return trigraph('>', '}'); + case '=': + return trigraph('=', '#'); + case '/': + return trigraph('/', '\\'); + case '\'': + return trigraph('\'', '^'); + case '!': + return trigraph('!', '|'); + case '-': + return trigraph('-', '~'); + } + _unread(e); + } + _unread(d); + } + return c; + } + + public int read() + throws IOException, LexerException { + if (flushnl) { + if (newlines > 0) { + newlines--; + return '\n'; + } + flushnl = false; + } + + for (;;) { + int c = _read(); + switch (c) { + case '\\': + int d = _read(); + switch (d) { + case '\n': + newlines++; + continue; + case '\r': + newlines++; + int e = _read(); + if (e != '\n') + _unread(e); + continue; + default: + _unread(d); + return c; + } + case '\r': + case '\n': + case '\u2028': + case '\u2029': + case '\u000B': + case '\u000C': + case '\u0085': + flushnl = true; + return c; + case -1: + if (newlines > 0) { + newlines--; + return '\n'; + } + default: + return c; + } + } + } + + public int read(char cbuf[], int off, int len) + throws IOException, LexerException { + for (int i = 0; i < len; i++) { + int ch = read(); + if (ch == -1) + return i; + cbuf[off + i] = (char) ch; + } + return len; + } + + @Override + public void close() + throws IOException { + in.close(); + } + + @Override + public String toString() { + return "JoinReader(nl=" + newlines + ")"; + } + + /* + public static void main(String[] args) throws IOException { + FileReader f = new FileReader(new File(args[0])); + BufferedReader b = new BufferedReader(f); + JoinReader r = new JoinReader(b); + BufferedWriter w = new BufferedWriter( + new java.io.OutputStreamWriter(System.out) + ); + int c; + while ((c = r.read()) != -1) { + w.write((char)c); + } + w.close(); + } + */ +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/LexerException.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/LexerException.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/LexerException.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/LexerException.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,33 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +/** + * A preprocessor exception. + * + * Note to users: I don't really like the name of this class. S. + */ +public class LexerException extends Exception { + + public LexerException(String msg) { + super(msg); + } + + public LexerException(Throwable cause) { + super(cause); + } +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/LexerSource.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/LexerSource.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/LexerSource.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/LexerSource.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,987 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.IOException; +import java.io.Reader; + +import javax.annotation.Nonnull; + +import static com.jogamp.gluegen.jcpp.Token.*; + +/** Does not handle digraphs. */ +public class LexerSource extends Source { + + private static final boolean DEBUG = false; + + private JoinReader reader; + private final boolean ppvalid; + private boolean bol; + private boolean include; + + private boolean digraphs; + + /* Unread. */ + private int u0, u1; + private int ucount; + + private int line; + private int column; + private int lastcolumn; + private boolean cr; + + /* ppvalid is: + * false in StringLexerSource, + * true in FileLexerSource */ + public LexerSource(Reader r, boolean ppvalid) { + this.reader = new JoinReader(r); + this.ppvalid = ppvalid; + this.bol = true; + this.include = false; + + this.digraphs = true; + + this.ucount = 0; + + this.line = 1; + this.column = 0; + this.lastcolumn = -1; + this.cr = false; + } + + @Override + /* pp */ void init(Preprocessor pp) { + super.init(pp); + this.digraphs = pp.getFeature(Feature.DIGRAPHS); + this.reader.init(pp, this); + } + + @Override + public int getLine() { + return line; + } + + @Override + public int getColumn() { + return column; + } + + @Override + /* pp */ boolean isNumbered() { + return true; + } + + /* Error handling. */ + private void _error(String msg, boolean error) + throws LexerException { + int _l = line; + int _c = column; + if (_c == 0) { + _c = lastcolumn; + _l--; + } else { + _c--; + } + if (error) + super.error(_l, _c, msg); + else + super.warning(_l, _c, msg); + } + + /* Allow JoinReader to call this. */ + /* pp */ final void error(String msg) + throws LexerException { + _error(msg, true); + } + + /* Allow JoinReader to call this. */ + /* pp */ final void warning(String msg) + throws LexerException { + _error(msg, false); + } + + /* A flag for string handling. */ + + /* pp */ void setInclude(boolean b) { + this.include = b; + } + + /* + * private boolean _isLineSeparator(int c) { + * return Character.getType(c) == Character.LINE_SEPARATOR + * || c == -1; + * } + */ + + /* XXX Move to JoinReader and canonicalise newlines. */ + private static boolean isLineSeparator(int c) { + switch ((char) c) { + case '\r': + case '\n': + case '\u2028': + case '\u2029': + case '\u000B': + case '\u000C': + case '\u0085': + return true; + default: + return (c == -1); + } + } + + private int read() + throws IOException, + LexerException { + int c; + assert ucount <= 2 : "Illegal ucount: " + ucount; + switch (ucount) { + case 2: + ucount = 1; + c = u1; + break; + case 1: + ucount = 0; + c = u0; + break; + default: + if (reader == null) + c = -1; + else + c = reader.read(); + break; + } + + switch (c) { + case '\r': + cr = true; + line++; + lastcolumn = column; + column = 0; + break; + case '\n': + if (cr) { + cr = false; + break; + } + /* fallthrough */ + case '\u2028': + case '\u2029': + case '\u000B': + case '\u000C': + case '\u0085': + cr = false; + line++; + lastcolumn = column; + column = 0; + break; + case -1: + cr = false; + break; + default: + cr = false; + column++; + break; + } + + /* + * if (isLineSeparator(c)) { + * line++; + * lastcolumn = column; + * column = 0; + * } + * else { + * column++; + * } + */ + return c; + } + + /* You can unget AT MOST one newline. */ + private void unread(int c) + throws IOException { + /* XXX Must unread newlines. */ + if (c != -1) { + if (isLineSeparator(c)) { + line--; + column = lastcolumn; + cr = false; + } else { + column--; + } + switch (ucount) { + case 0: + u0 = c; + ucount = 1; + break; + case 1: + u1 = c; + ucount = 2; + break; + default: + throw new IllegalStateException( + "Cannot unget another character!" + ); + } + // reader.unread(c); + } + } + + /* Consumes the rest of the current line into an invalid. */ + @Nonnull + private Token invalid(StringBuilder text, String reason) + throws IOException, + LexerException { + int d = read(); + while (!isLineSeparator(d)) { + text.append((char) d); + d = read(); + } + unread(d); + return new Token(INVALID, text.toString(), reason); + } + + @Nonnull + private Token ccomment() + throws IOException, + LexerException { + StringBuilder text = new StringBuilder("/*"); + int d; + do { + do { + d = read(); + if (d == -1) + return new Token(INVALID, text.toString(), + "Unterminated comment"); + text.append((char) d); + } while (d != '*'); + do { + d = read(); + if (d == -1) + return new Token(INVALID, text.toString(), + "Unterminated comment"); + text.append((char) d); + } while (d == '*'); + } while (d != '/'); + return new Token(CCOMMENT, text.toString()); + } + + @Nonnull + private Token cppcomment() + throws IOException, + LexerException { + StringBuilder text = new StringBuilder("//"); + int d = read(); + while (!isLineSeparator(d)) { + text.append((char) d); + d = read(); + } + unread(d); + return new Token(CPPCOMMENT, text.toString()); + } + + private int escape(StringBuilder text) + throws IOException, + LexerException { + int d = read(); + switch (d) { + case 'a': + text.append('a'); + return 0x07; + case 'b': + text.append('b'); + return '\b'; + case 'f': + text.append('f'); + return '\f'; + case 'n': + text.append('n'); + return '\n'; + case 'r': + text.append('r'); + return '\r'; + case 't': + text.append('t'); + return '\t'; + case 'v': + text.append('v'); + return 0x0b; + case '\\': + text.append('\\'); + return '\\'; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + int len = 0; + int val = 0; + do { + val = (val << 3) + Character.digit(d, 8); + text.append((char) d); + d = read(); + } while (++len < 3 && Character.digit(d, 8) != -1); + unread(d); + return val; + + case 'x': + text.append((char) d); + len = 0; + val = 0; + while (len++ < 2) { + d = read(); + if (Character.digit(d, 16) == -1) { + unread(d); + break; + } + val = (val << 4) + Character.digit(d, 16); + text.append((char) d); + } + return val; + + /* Exclude two cases from the warning. */ + case '"': + text.append('"'); + return '"'; + case '\'': + text.append('\''); + return '\''; + + default: + warning("Unnecessary escape character " + (char) d); + text.append((char) d); + return d; + } + } + + @Nonnull + private Token character() + throws IOException, + LexerException { + StringBuilder text = new StringBuilder("'"); + int d = read(); + if (d == '\\') { + text.append('\\'); + d = escape(text); + } else if (isLineSeparator(d)) { + unread(d); + return new Token(INVALID, text.toString(), + "Unterminated character literal"); + } else if (d == '\'') { + text.append('\''); + return new Token(INVALID, text.toString(), + "Empty character literal"); + } else if (!Character.isDefined(d)) { + text.append('?'); + return invalid(text, "Illegal unicode character literal"); + } else { + text.append((char) d); + } + + int e = read(); + if (e != '\'') { + // error("Illegal character constant"); + /* We consume up to the next ' or the rest of the line. */ + for (;;) { + if (isLineSeparator(e)) { + unread(e); + break; + } + text.append((char) e); + if (e == '\'') + break; + e = read(); + } + return new Token(INVALID, text.toString(), + "Illegal character constant " + text); + } + text.append('\''); + /* XXX It this a bad cast? */ + return new Token(CHARACTER, + text.toString(), Character.valueOf((char) d)); + } + + @Nonnull + private Token string(char open, char close) + throws IOException, + LexerException { + StringBuilder text = new StringBuilder(); + text.append(open); + + StringBuilder buf = new StringBuilder(); + + for (;;) { + int c = read(); + if (c == close) { + break; + } else if (c == '\\') { + text.append('\\'); + if (!include) { + char d = (char) escape(text); + buf.append(d); + } + } else if (c == -1) { + unread(c); + // error("End of file in string literal after " + buf); + return new Token(INVALID, text.toString(), + "End of file in string literal after " + buf); + } else if (isLineSeparator(c)) { + unread(c); + // error("Unterminated string literal after " + buf); + return new Token(INVALID, text.toString(), + "Unterminated string literal after " + buf); + } else { + text.append((char) c); + buf.append((char) c); + } + } + text.append(close); + switch (close) { + case '"': + return new Token(STRING, + text.toString(), buf.toString()); + case '>': + return new Token(HEADER, + text.toString(), buf.toString()); + case '\'': + if (buf.length() == 1) + return new Token(CHARACTER, + text.toString(), buf.toString()); + return new Token(SQSTRING, + text.toString(), buf.toString()); + default: + throw new IllegalStateException( + "Unknown closing character " + String.valueOf(close)); + } + } + + @Nonnull + private Token _number_suffix(StringBuilder text, NumericValue value, int d) + throws IOException, + LexerException { + int flags = 0; // U, I, L, LL, F, D, MSB + for (;;) { + if (d == 'U' || d == 'u') { + if ((flags & NumericValue.F_UNSIGNED) != 0) + warning("Duplicate unsigned suffix " + d); + flags |= NumericValue.F_UNSIGNED; + text.append((char) d); + d = read(); + } else if (d == 'L' || d == 'l') { + if ((flags & NumericValue.FF_SIZE) != 0) + warning("Multiple length suffixes after " + text); + text.append((char) d); + int e = read(); + if (e == d) { // Case must match. Ll is Welsh. + flags |= NumericValue.F_LONGLONG; + text.append((char) e); + d = read(); + } else { + flags |= NumericValue.F_LONG; + d = e; + } + } else if (d == 'I' || d == 'i') { + if ((flags & NumericValue.FF_SIZE) != 0) + warning("Multiple length suffixes after " + text); + flags |= NumericValue.F_INT; + text.append((char) d); + d = read(); + } else if (d == 'F' || d == 'f') { + if ((flags & NumericValue.FF_SIZE) != 0) + warning("Multiple length suffixes after " + text); + flags |= NumericValue.F_FLOAT; + text.append((char) d); + d = read(); + } else if (d == 'D' || d == 'd') { + if ((flags & NumericValue.FF_SIZE) != 0) + warning("Multiple length suffixes after " + text); + flags |= NumericValue.F_DOUBLE; + text.append((char) d); + d = read(); + } + else if (Character.isUnicodeIdentifierPart(d)) { + String reason = "Invalid suffix \"" + (char) d + "\" on numeric constant"; + // We've encountered something initially identified as a number. + // Read in the rest of this token as an identifer but return it as an invalid. + while (Character.isUnicodeIdentifierPart(d)) { + text.append((char) d); + d = read(); + } + unread(d); + return new Token(INVALID, text.toString(), reason); + } else { + unread(d); + value.setFlags(flags); + return new Token(NUMBER, + text.toString(), value); + } + } + } + + /* Either a decimal part, or a hex exponent. */ + @Nonnull + private String _number_part(StringBuilder text, int base, boolean sign) + throws IOException, + LexerException { + StringBuilder part = new StringBuilder(); + int d = read(); + if (sign && d == '-') { + text.append((char) d); + part.append((char) d); + d = read(); + } + while (Character.digit(d, base) != -1) { + text.append((char) d); + part.append((char) d); + d = read(); + } + unread(d); + return part.toString(); + } + + /* We do not know whether know the first digit is valid. */ + @Nonnull + private Token number_hex(char x) + throws IOException, + LexerException { + StringBuilder text = new StringBuilder("0"); + text.append(x); + String integer = _number_part(text, 16, false); + NumericValue value = new NumericValue(16, integer); + int d = read(); + if (d == '.') { + text.append((char) d); + String fraction = _number_part(text, 16, false); + value.setFractionalPart(fraction); + d = read(); + } + if (d == 'P' || d == 'p') { + text.append((char) d); + String exponent = _number_part(text, 10, true); + value.setExponent(2, exponent); + d = read(); + } + // XXX Make sure it's got enough parts + return _number_suffix(text, value, d); + } + + private static boolean is_octal(@Nonnull String text) { + if (!text.startsWith("0")) + return false; + for (int i = 0; i < text.length(); i++) + if (Character.digit(text.charAt(i), 8) == -1) + return false; + return true; + } + + /* We know we have at least one valid digit, but empty is not + * fine. */ + @Nonnull + private Token number_decimal() + throws IOException, + LexerException { + StringBuilder text = new StringBuilder(); + String integer = _number_part(text, 10, false); + String fraction = null; + String exponent = null; + int d = read(); + if (d == '.') { + text.append((char) d); + fraction = _number_part(text, 10, false); + d = read(); + } + if (d == 'E' || d == 'e') { + text.append((char) d); + exponent = _number_part(text, 10, true); + d = read(); + } + int base = 10; + if (fraction == null && exponent == null && integer.startsWith("0")) { + if (!is_octal(integer)) + warning("Decimal constant starts with 0, but not octal: " + integer); + else + base = 8; + } + NumericValue value = new NumericValue(base, integer); + if (fraction != null) + value.setFractionalPart(fraction); + if (exponent != null) + value.setExponent(10, exponent); + // XXX Make sure it's got enough parts + return _number_suffix(text, value, d); + } + + /** + * Section 6.4.4.1 of C99 + * + * (Not pasted here, but says that the initial negation is a separate token.) + * + * Section 6.4.4.2 of C99 + * + * A floating constant has a significand part that may be followed + * by an exponent part and a suffix that specifies its type. The + * components of the significand part may include a digit sequence + * representing the whole-number part, followed by a period (.), + * followed by a digit sequence representing the fraction part. + * + * The components of the exponent part are an e, E, p, or P + * followed by an exponent consisting of an optionally signed digit + * sequence. Either the whole-number part or the fraction part has to + * be present; for decimal floating constants, either the period or + * the exponent part has to be present. + * + * The significand part is interpreted as a (decimal or hexadecimal) + * rational number; the digit sequence in the exponent part is + * interpreted as a decimal integer. For decimal floating constants, + * the exponent indicates the power of 10 by which the significand + * part is to be scaled. For hexadecimal floating constants, the + * exponent indicates the power of 2 by which the significand part is + * to be scaled. + * + * For decimal floating constants, and also for hexadecimal + * floating constants when FLT_RADIX is not a power of 2, the result + * is either the nearest representable value, or the larger or smaller + * representable value immediately adjacent to the nearest representable + * value, chosen in an implementation-defined manner. For hexadecimal + * floating constants when FLT_RADIX is a power of 2, the result is + * correctly rounded. + */ + @Nonnull + private Token number() + throws IOException, + LexerException { + Token tok; + int c = read(); + if (c == '0') { + int d = read(); + if (d == 'x' || d == 'X') { + tok = number_hex((char) d); + } else { + unread(d); + unread(c); + tok = number_decimal(); + } + } else if (Character.isDigit(c) || c == '.') { + unread(c); + tok = number_decimal(); + } else { + throw new LexerException("Asked to parse something as a number which isn't: " + (char) c); + } + return tok; + } + + @Nonnull + private Token identifier(int c) + throws IOException, + LexerException { + StringBuilder text = new StringBuilder(); + int d; + text.append((char) c); + for (;;) { + d = read(); + if (Character.isIdentifierIgnorable(d)) + ; else if (Character.isJavaIdentifierPart(d)) + text.append((char) d); + else + break; + } + unread(d); + return new Token(IDENTIFIER, text.toString()); + } + + @Nonnull + private Token whitespace(int c) + throws IOException, + LexerException { + StringBuilder text = new StringBuilder(); + int d; + text.append((char) c); + for (;;) { + d = read(); + if (ppvalid && isLineSeparator(d)) /* XXX Ugly. */ + + break; + if (Character.isWhitespace(d)) + text.append((char) d); + else + break; + } + unread(d); + return new Token(WHITESPACE, text.toString()); + } + + /* No token processed by cond() contains a newline. */ + @Nonnull + private Token cond(char c, int yes, int no) + throws IOException, + LexerException { + int d = read(); + if (c == d) + return new Token(yes); + unread(d); + return new Token(no); + } + + @Override + public Token token() + throws IOException, + LexerException { + Token tok = null; + + int _l = line; + int _c = column; + + int c = read(); + int d; + + switch (c) { + case '\n': + if (ppvalid) { + bol = true; + if (include) { + tok = new Token(NL, _l, _c, "\n"); + } else { + int nls = 0; + do { + nls++; + d = read(); + } while (d == '\n'); + unread(d); + char[] text = new char[nls]; + for (int i = 0; i < text.length; i++) + text[i] = '\n'; + // Skip the bol = false below. + tok = new Token(NL, _l, _c, new String(text)); + } + if (DEBUG) + System.out.println("lx: Returning NL: " + tok); + return tok; + } + /* Let it be handled as whitespace. */ + break; + + case '!': + tok = cond('=', NE, '!'); + break; + + case '#': + if (bol) + tok = new Token(HASH); + else + tok = cond('#', PASTE, '#'); + break; + + case '+': + d = read(); + if (d == '+') + tok = new Token(INC); + else if (d == '=') + tok = new Token(PLUS_EQ); + else + unread(d); + break; + case '-': + d = read(); + if (d == '-') + tok = new Token(DEC); + else if (d == '=') + tok = new Token(SUB_EQ); + else if (d == '>') + tok = new Token(ARROW); + else + unread(d); + break; + + case '*': + tok = cond('=', MULT_EQ, '*'); + break; + case '/': + d = read(); + if (d == '*') + tok = ccomment(); + else if (d == '/') + tok = cppcomment(); + else if (d == '=') + tok = new Token(DIV_EQ); + else + unread(d); + break; + + case '%': + d = read(); + if (d == '=') + tok = new Token(MOD_EQ); + else if (digraphs && d == '>') + tok = new Token('}'); // digraph + else if (digraphs && d == ':') + PASTE: + { + d = read(); + if (d != '%') { + unread(d); + tok = new Token('#'); // digraph + break PASTE; + } + d = read(); + if (d != ':') { + unread(d); // Unread 2 chars here. + unread('%'); + tok = new Token('#'); // digraph + break PASTE; + } + tok = new Token(PASTE); // digraph + } + else + unread(d); + break; + + case ':': + /* :: */ + d = read(); + if (digraphs && d == '>') + tok = new Token(']'); // digraph + else + unread(d); + break; + + case '<': + if (include) { + tok = string('<', '>'); + } else { + d = read(); + if (d == '=') + tok = new Token(LE); + else if (d == '<') + tok = cond('=', LSH_EQ, LSH); + else if (digraphs && d == ':') + tok = new Token('['); // digraph + else if (digraphs && d == '%') + tok = new Token('{'); // digraph + else + unread(d); + } + break; + + case '=': + tok = cond('=', EQ, '='); + break; + + case '>': + d = read(); + if (d == '=') + tok = new Token(GE); + else if (d == '>') + tok = cond('=', RSH_EQ, RSH); + else + unread(d); + break; + + case '^': + tok = cond('=', XOR_EQ, '^'); + break; + + case '|': + d = read(); + if (d == '=') + tok = new Token(OR_EQ); + else if (d == '|') + tok = cond('=', LOR_EQ, LOR); + else + unread(d); + break; + case '&': + d = read(); + if (d == '&') + tok = cond('=', LAND_EQ, LAND); + else if (d == '=') + tok = new Token(AND_EQ); + else + unread(d); + break; + + case '.': + d = read(); + if (d == '.') + tok = cond('.', ELLIPSIS, RANGE); + else + unread(d); + if (Character.isDigit(d)) { + unread('.'); + tok = number(); + } + /* XXX decimal fraction */ + break; + + case '\'': + tok = string('\'', '\''); + break; + + case '"': + tok = string('"', '"'); + break; + + case -1: + close(); + tok = new Token(EOF, _l, _c, ""); + break; + } + + if (tok == null) { + if (Character.isWhitespace(c)) { + tok = whitespace(c); + } else if (Character.isDigit(c)) { + unread(c); + tok = number(); + } else if (Character.isJavaIdentifierStart(c)) { + tok = identifier(c); + } else { + tok = new Token(c); + } + } + + if (bol) { + switch (tok.getType()) { + case WHITESPACE: + case CCOMMENT: + break; + default: + bol = false; + break; + } + } + + tok.setLocation(_l, _c); + if (DEBUG) + System.out.println("lx: Returning " + tok); + // (new Exception("here")).printStackTrace(System.out); + return tok; + } + + @Override + public void close() + throws IOException { + if (reader != null) { + reader.close(); + reader = null; + } + super.close(); + } + +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Macro.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Macro.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Macro.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Macro.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,212 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * A macro object. + * + * This encapsulates a name, an argument count, and a token stream + * for replacement. The replacement token stream may contain the + * extra tokens {@link Token#M_ARG} and {@link Token#M_STRING}. + */ +public class Macro { + + private final Source source; + private final String name; + /* It's an explicit decision to keep these around here. We don't + * need to; the argument token type is M_ARG and the value + * is the index. The strings themselves are only used in + * stringification of the macro, for debugging. */ + private List args; + private boolean variadic; + private boolean hasPaste; + private List tokens; + + public Macro(final Source source, final String name) { + this.source = source; + this.name = name; + this.args = null; + this.variadic = false; + this.hasPaste = false; + this.tokens = new ArrayList(); + } + public Macro(final Macro o) { + this(o, o.tokens, true); + } + public Macro(final Macro o, final List tokens) { + this(o, tokens, false); + } + private Macro(final Macro o, final List tokens, final boolean copyTokens) { + this.source = o.source; + this.name = o.name; + if(null != o.args) { + this.args = new ArrayList(o.args); + } else { + this.args = null; + } + this.variadic = o.variadic; + this.hasPaste = o.hasPaste; + if(null != tokens) { + this.tokens = copyTokens ? new ArrayList(tokens) : tokens; + } else { + this.tokens = new ArrayList(); + } + } + + public Macro(final String name) { + this(null, name); + } + + /** + * Returns the Source from which this macro was parsed. + * + * This method may return null if the macro was not parsed + * from a regular file. + */ + public Source getSource() { + return source; + } + + /** + * Returns the name of this macro. + */ + public String getName() { + return name; + } + + /** + * Sets the arguments to this macro. + */ + /* pp */ void setArgs(final List args) { + this.args = args; + } + + /** + * Returns true if this is a function-like macro. + */ + public boolean isFunctionLike() { + return args != null; + } + + /** + * Returns the number of arguments to this macro. + */ + public int getArgs() { + return args.size(); + } + + /** + * Sets the variadic flag on this Macro. + */ + public void setVariadic(final boolean b) { + this.variadic = b; + } + + /** + * Returns true if this is a variadic function-like macro. + */ + public boolean isVariadic() { + return variadic; + } + + /** + * Returns true if this macro contains a "paste" operator. + */ + public boolean hasPaste() { + return hasPaste; + } + + /** + * Adds a token to the expansion of this macro. + */ + public void addToken(final Token tok) { + this.tokens.add(tok); + } + + /** + * Adds a "paste" operator to the expansion of this macro. + * + * A paste operator causes the next token added to be pasted + * to the previous token when the macro is expanded. + * It is an error for a macro to end with a paste token. + */ + public void addPaste(final Token tok) { + /* + * Given: tok0 ## tok1 + * We generate: M_PASTE, tok0, tok1 + * This extends as per a stack language: + * tok0 ## tok1 ## tok2 -> + * M_PASTE, tok0, M_PASTE, tok1, tok2 + */ + this.tokens.add(tokens.size() - 1, tok); + this.hasPaste = true; + } + + /* pp */ List getTokens() { + return tokens; + } + + /* Paste tokens are inserted before the first of the two pasted + * tokens, so it's a kind of bytecode notation. This method + * swaps them around again. We know that there will never be two + * sequential paste tokens, so a boolean is sufficient. */ + public String getText() { + final StringBuilder buf = new StringBuilder(); + boolean paste = false; + for (final Token tok : tokens) { + if (tok.getType() == Token.M_PASTE) { + assert paste == false : "Two sequential pastes."; + paste = true; + continue; + } else { + buf.append(tok.getText()); + } + if (paste) { + buf.append(" #" + "# "); + paste = false; + } + // buf.append(tokens.get(i)); + } + return buf.toString(); + } + + @Override + public String toString() { + final StringBuilder buf = new StringBuilder(name); + if (args != null) { + buf.append('('); + final Iterator it = args.iterator(); + while (it.hasNext()) { + buf.append(it.next()); + if (it.hasNext()) + buf.append(", "); + else if (isVariadic()) + buf.append("..."); + } + buf.append(')'); + } + if (!tokens.isEmpty()) { + buf.append(" => ").append(getText()); + } + return buf.toString(); + } + +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/MacroTokenSource.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/MacroTokenSource.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/MacroTokenSource.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/MacroTokenSource.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,209 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +import javax.annotation.Nonnull; + +import static com.jogamp.gluegen.jcpp.Token.*; + +/* This source should always be active, since we don't expand macros + * in any inactive context. */ +/* pp */ class MacroTokenSource extends Source { + + private final Macro macro; + private final Iterator tokens; /* Pointer into the macro. */ + + private final List args; /* { unexpanded, expanded } */ + + private Iterator arg; /* "current expansion" */ + + /* pp */ MacroTokenSource(@Nonnull Macro m, @Nonnull List args) { + this.macro = m; + this.tokens = m.getTokens().iterator(); + this.args = args; + this.arg = null; + } + + @Override + /* pp */ boolean isExpanding(@Nonnull Macro m) { + /* When we are expanding an arg, 'this' macro is not + * being expanded, and thus we may re-expand it. */ + if (/* XXX this.arg == null && */this.macro == m) + return true; + return super.isExpanding(m); + } + + /* XXX Called from Preprocessor [ugly]. */ + /* pp */ static void escape(@Nonnull StringBuilder buf, @Nonnull CharSequence cs) { + if (buf == null) + throw new NullPointerException("Buffer was null."); + if (cs == null) + throw new NullPointerException("CharSequence was null."); + for (int i = 0; i < cs.length(); i++) { + char c = cs.charAt(i); + switch (c) { + case '\\': + buf.append("\\\\"); + break; + case '"': + buf.append("\\\""); + break; + case '\n': + buf.append("\\n"); + break; + case '\r': + buf.append("\\r"); + break; + default: + buf.append(c); + } + } + } + + private void concat(@Nonnull StringBuilder buf, @Nonnull Argument arg) { + for (Token tok : arg) { + buf.append(tok.getText()); + } + } + + @Nonnull + private Token stringify(@Nonnull Token pos, @Nonnull Argument arg) { + StringBuilder buf = new StringBuilder(); + concat(buf, arg); + // System.out.println("Concat: " + arg + " -> " + buf); + StringBuilder str = new StringBuilder("\""); + escape(str, buf); + str.append("\""); + // System.out.println("Escape: " + buf + " -> " + str); + return new Token(STRING, + pos.getLine(), pos.getColumn(), + str.toString(), buf.toString()); + } + + + /* At this point, we have consumed the first M_PASTE. + * @see Macro#addPaste(Token) */ + private void paste(@Nonnull Token ptok) + throws IOException, + LexerException { + StringBuilder buf = new StringBuilder(); + // Token err = null; + /* We know here that arg is null or expired, + * since we cannot paste an expanded arg. */ + + int count = 2; + for (int i = 0; i < count; i++) { + if (!tokens.hasNext()) { + /* XXX This one really should throw. */ + error(ptok.getLine(), ptok.getColumn(), + "Paste at end of expansion"); + buf.append(' ').append(ptok.getText()); + break; + } + Token tok = tokens.next(); + // System.out.println("Paste " + tok); + switch (tok.getType()) { + case M_PASTE: + /* One extra to paste, plus one because the + * paste token didn't count. */ + count += 2; + ptok = tok; + break; + case M_ARG: + int idx = ((Integer) tok.getValue()).intValue(); + concat(buf, args.get(idx)); + break; + /* XXX Test this. */ + case CCOMMENT: + case CPPCOMMENT: + break; + default: + buf.append(tok.getText()); + break; + } + } + + /* Push and re-lex. */ + /* + StringBuilder src = new StringBuilder(); + escape(src, buf); + StringLexerSource sl = new StringLexerSource(src.toString()); + */ + StringLexerSource sl = new StringLexerSource(buf.toString()); + + /* XXX Check that concatenation produces a valid token. */ + arg = new SourceIterator(sl); + } + + @Override + public Token token() + throws IOException, + LexerException { + for (;;) { + /* Deal with lexed tokens first. */ + + if (arg != null) { + if (arg.hasNext()) { + Token tok = arg.next(); + /* XXX PASTE -> INVALID. */ + assert tok.getType() != M_PASTE : + "Unexpected paste token"; + return tok; + } + arg = null; + } + + if (!tokens.hasNext()) + return new Token(EOF, -1, -1, ""); /* End of macro. */ + + Token tok = tokens.next(); + int idx; + switch (tok.getType()) { + case M_STRING: + /* Use the nonexpanded arg. */ + idx = ((Integer) tok.getValue()).intValue(); + return stringify(tok, args.get(idx)); + case M_ARG: + /* Expand the arg. */ + idx = ((Integer) tok.getValue()).intValue(); + // System.out.println("Pushing arg " + args.get(idx)); + arg = args.get(idx).expansion(); + break; + case M_PASTE: + paste(tok); + break; + default: + return tok; + } + } /* for */ + + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append("expansion of ").append(macro.getName()); + Source parent = getParent(); + if (parent != null) + buf.append(" in ").append(String.valueOf(parent)); + return buf.toString(); + } +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/NumericValue.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/NumericValue.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/NumericValue.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/NumericValue.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,215 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.math.BigDecimal; +import java.math.BigInteger; +import javax.annotation.CheckForNull; +import javax.annotation.CheckForSigned; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; + +public class NumericValue extends Number { + + public static final int F_UNSIGNED = 1; + public static final int F_INT = 2; + public static final int F_LONG = 4; + public static final int F_LONGLONG = 8; + public static final int F_FLOAT = 16; + public static final int F_DOUBLE = 32; + + public static final int FF_SIZE = F_INT | F_LONG | F_LONGLONG | F_FLOAT | F_DOUBLE; + + private final int base; + private final String integer; + private String fraction; + private int expbase = 0; + private String exponent; + private int flags; + + public NumericValue(int base, String integer) { + this.base = base; + this.integer = integer; + } + + @Nonnegative + public int getBase() { + return base; + } + + @Nonnull + public String getIntegerPart() { + return integer; + } + + @CheckForNull + public String getFractionalPart() { + return fraction; + } + + /* pp */ void setFractionalPart(String fraction) { + this.fraction = fraction; + } + + @CheckForSigned + public int getExponentBase() { + return expbase; + } + + @CheckForNull + public String getExponent() { + return exponent; + } + + /* pp */ void setExponent(int expbase, String exponent) { + this.expbase = expbase; + this.exponent = exponent; + } + + public int getFlags() { + return flags; + } + + /* pp */ void setFlags(int flags) { + this.flags = flags; + } + + /** + * So, it turns out that parsing arbitrary bases into arbitrary + * precision numbers is nontrivial, and this routine gets it wrong + * in many important cases. + */ + @Nonnull + public BigDecimal toBigDecimal() { + int scale = 0; + String text = getIntegerPart(); + String t_fraction = getFractionalPart(); + if (t_fraction != null) { + text += getFractionalPart(); + // XXX Wrong for anything but base 10. + scale += t_fraction.length(); + } + String t_exponent = getExponent(); + if (t_exponent != null) + scale -= Integer.parseInt(t_exponent); + BigInteger unscaled = new BigInteger(text, getBase()); + return new BigDecimal(unscaled, scale); + } + + @Nonnull + public Number toJavaLangNumber() { + int flags = getFlags(); + if ((flags & F_DOUBLE) != 0) + return doubleValue(); + else if ((flags & F_FLOAT) != 0) + return floatValue(); + else if ((flags & (F_LONG | F_LONGLONG)) != 0) + return longValue(); + else if ((flags & F_INT) != 0) + return intValue(); + else if (getFractionalPart() != null) + return doubleValue(); // .1 is a double in Java. + else if (getExponent() != null) + return doubleValue(); + else + return intValue(); + } + + private int exponentValue() { + return Integer.parseInt(exponent, 10); + } + + @Override + public int intValue() { + int v = integer.isEmpty() ? 0 : Integer.parseInt(integer, base); + if (expbase == 2) + v = v << exponentValue(); + else if (expbase != 0) + v = (int) (v * Math.pow(expbase, exponentValue())); + return v; + } + + @Override + public long longValue() { + long v = integer.isEmpty() ? 0 : Long.parseLong(integer, base); + if (expbase == 2) + v = v << exponentValue(); + else if (expbase != 0) + v = (long) (v * Math.pow(expbase, exponentValue())); + return v; + } + + @Override + public float floatValue() { + if (getBase() != 10) + return longValue(); + return Float.parseFloat(toString()); + } + + @Override + public double doubleValue() { + if (getBase() != 10) + return longValue(); + return Double.parseDouble(toString()); + } + + private boolean appendFlags(StringBuilder buf, String suffix, int flag) { + if ((getFlags() & flag) != flag) + return false; + buf.append(suffix); + return true; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + switch (base) { + case 8: + buf.append('0'); + break; + case 10: + break; + case 16: + buf.append("0x"); + break; + case 2: + buf.append('b'); + break; + default: + buf.append("[base-").append(base).append("]"); + break; + } + buf.append(getIntegerPart()); + if (getFractionalPart() != null) + buf.append('.').append(getFractionalPart()); + if (getExponent() != null) { + buf.append(base > 10 ? 'p' : 'e'); + buf.append(getExponent()); + } + /* + if (appendFlags(buf, "ui", F_UNSIGNED | F_INT)); + else if (appendFlags(buf, "ul", F_UNSIGNED | F_LONG)); + else if (appendFlags(buf, "ull", F_UNSIGNED | F_LONGLONG)); + else if (appendFlags(buf, "i", F_INT)); + else if (appendFlags(buf, "l", F_LONG)); + else if (appendFlags(buf, "ll", F_LONGLONG)); + else if (appendFlags(buf, "f", F_FLOAT)); + else if (appendFlags(buf, "d", F_DOUBLE)); + */ + return buf.toString(); + } +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/PreprocessorCommand.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/PreprocessorCommand.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/PreprocessorCommand.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/PreprocessorCommand.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,44 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jogamp.gluegen.jcpp; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +/** + * + * @author shevek + */ +public enum PreprocessorCommand { + + PP_DEFINE("define"), + PP_ELIF("elif"), + PP_ELSE("else"), + PP_ENDIF("endif"), + PP_ERROR("error"), + PP_IF("if"), + PP_IFDEF("ifdef"), + PP_IFNDEF("ifndef"), + PP_INCLUDE("include"), + PP_LINE("line"), + PP_PRAGMA("pragma"), + PP_UNDEF("undef"), + PP_WARNING("warning"), + PP_INCLUDE_NEXT("include_next"), + PP_IMPORT("import"); + private final String text; + /* pp */ PreprocessorCommand(String text) { + this.text = text; + } + + @CheckForNull + public static PreprocessorCommand forText(@Nonnull String text) { + for (PreprocessorCommand ppcmd : PreprocessorCommand.values()) + if (ppcmd.text.equals(text)) + return ppcmd; + return null; + } +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Preprocessor.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Preprocessor.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Preprocessor.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Preprocessor.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,2177 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Stack; +import java.util.TreeMap; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +import static com.jogamp.gluegen.jcpp.PreprocessorCommand.*; +import static com.jogamp.gluegen.jcpp.Token.*; + +import com.jogamp.gluegen.Logging; +import com.jogamp.gluegen.Logging.LoggerIf; +import com.jogamp.gluegen.jcpp.PreprocessorListener.SourceChangeEvent; + +/** + * A C Preprocessor. + * The Preprocessor outputs a token stream which does not need + * re-lexing for C or C++. Alternatively, the output text may be + * reconstructed by concatenating the {@link Token#getText() text} + * values of the returned {@link Token Tokens}. (See + * {@link CppReader}, which does this.) + */ +/* + * Source file name and line number information is conveyed by lines of the form + * + * # linenum filename flags + * + * These are called linemarkers. They are inserted as needed into + * the output (but never within a string or character constant). They + * mean that the following line originated in file filename at line + * linenum. filename will never contain any non-printing characters; + * they are replaced with octal escape sequences. + * + * After the file name comes zero or more flags, which are `1', `2', + * `3', or `4'. If there are multiple flags, spaces separate them. Here + * is what the flags mean: + * + * `1' + * This indicates the start of a new file. + * `2' + * This indicates returning to a file (after having included another + * file). + * `3' + * This indicates that the following text comes from a system header + * file, so certain warnings should be suppressed. + * `4' + * This indicates that the following text should be treated as being + * wrapped in an implicit extern "C" block. + */ +public class Preprocessor implements Closeable { + + private final LoggerIf LOG; + + private static final Source INTERNAL = new Source() { + @Override + public Token token() + throws IOException, + LexerException { + throw new LexerException("Cannot read from " + getName()); + } + + @Override + public String getPath() { + return ""; + } + + @Override + public String getName() { + return "internal data"; + } + }; + private static final Macro __LINE__ = new Macro(INTERNAL, "__LINE__"); + private static final Macro __FILE__ = new Macro(INTERNAL, "__FILE__"); + private static final Macro __COUNTER__ = new Macro(INTERNAL, "__COUNTER__"); + + private final List inputs; + + /* The fundamental engine. */ + private final Map macros; + private final Stack states; + private Source source; + + /* Miscellaneous support. */ + private int counter; + private final Set onceseenpaths = new HashSet(); + private final List includes = new ArrayList(); + + /* Support junk to make it work like cpp */ + private List quoteincludepath; /* -iquote */ + + private List sysincludepath; /* -I */ + + private List frameworkspath; + private final Set features; + private final Set warnings; + private VirtualFileSystem filesystem; + private PreprocessorListener listener; + + public Preprocessor() { + LOG = Logging.getLogger(Preprocessor.class); + this.inputs = new ArrayList(); + + this.macros = new HashMap(); + macros.put(__LINE__.getName(), __LINE__); + macros.put(__FILE__.getName(), __FILE__); + macros.put(__COUNTER__.getName(), __COUNTER__); + this.states = new Stack(); + states.push(new State()); + this.source = null; + + this.counter = 0; + + this.quoteincludepath = new ArrayList(); + this.sysincludepath = new ArrayList(); + this.frameworkspath = new ArrayList(); + this.features = EnumSet.noneOf(Feature.class); + this.warnings = EnumSet.noneOf(Warning.class); + this.filesystem = new JavaFileSystem(); + this.listener = null; + } + + public Preprocessor(@Nonnull final Source initial) { + this(); + addInput(initial); + } + + /** Equivalent to + * 'new Preprocessor(new {@link FileLexerSource}(file))' + */ + public Preprocessor(@Nonnull final File file) + throws IOException { + this(new FileLexerSource(file)); + } + + /** + * Sets the VirtualFileSystem used by this Preprocessor. + */ + public void setFileSystem(@Nonnull final VirtualFileSystem filesystem) { + this.filesystem = filesystem; + } + + /** + * Returns the VirtualFileSystem used by this Preprocessor. + */ + @Nonnull + public VirtualFileSystem getFileSystem() { + return filesystem; + } + + /** + * Sets the PreprocessorListener which handles events for + * this Preprocessor. + * + * The listener is notified of warnings, errors and source + * changes, amongst other things. + */ + public void setListener(@Nonnull final PreprocessorListener listener) { + this.listener = listener; + Source s = source; + while (s != null) { + // s.setListener(listener); + s.init(this); + s = s.getParent(); + } + } + + /** + * Returns the PreprocessorListener which handles events for + * this Preprocessor. + */ + @Nonnull + public PreprocessorListener getListener() { + return listener; + } + + /** + * Returns the feature-set for this Preprocessor. + * + * This set may be freely modified by user code. + */ + @Nonnull + public Set getFeatures() { + return features; + } + + /** + * Adds a feature to the feature-set of this Preprocessor. + */ + public void addFeature(@Nonnull final Feature f) { + features.add(f); + } + + /** + * Adds features to the feature-set of this Preprocessor. + */ + public void addFeatures(@Nonnull final Collection f) { + features.addAll(f); + } + + /** + * Adds features to the feature-set of this Preprocessor. + */ + public void addFeatures(final Feature... f) { + addFeatures(Arrays.asList(f)); + } + + /** + * Returns true if the given feature is in + * the feature-set of this Preprocessor. + */ + public boolean getFeature(@Nonnull final Feature f) { + return features.contains(f); + } + + /** + * Returns the warning-set for this Preprocessor. + * + * This set may be freely modified by user code. + */ + @Nonnull + public Set getWarnings() { + return warnings; + } + + /** + * Adds a warning to the warning-set of this Preprocessor. + */ + public void addWarning(@Nonnull final Warning w) { + warnings.add(w); + } + + /** + * Adds warnings to the warning-set of this Preprocessor. + */ + public void addWarnings(@Nonnull final Collection w) { + warnings.addAll(w); + } + + /** + * Returns true if the given warning is in + * the warning-set of this Preprocessor. + */ + public boolean getWarning(@Nonnull final Warning w) { + return warnings.contains(w); + } + + /** + * Adds input for the Preprocessor. + * + * Inputs are processed in the order in which they are added. + */ + public void addInput(@Nonnull final Source source) { + source.init(this); + inputs.add(source); + } + + /** + * Adds input for the Preprocessor. + * + * @see #addInput(Source) + */ + public void addInput(@Nonnull final File file) + throws IOException { + addInput(new FileLexerSource(file)); + } + + /** + * Handles an error. + * + * If a PreprocessorListener is installed, it receives the + * error. Otherwise, an exception is thrown. + */ + protected void error(final int line, final int column, @Nonnull final String msg) + throws LexerException { + if (listener != null) + listener.handleError(source, line, column, msg); + else + throw new LexerException("Error at " + line + ":" + column + ": " + msg); + } + + /** + * Handles an error. + * + * If a PreprocessorListener is installed, it receives the + * error. Otherwise, an exception is thrown. + * + * @see #error(int, int, String) + */ + protected void error(@Nonnull final Token tok, @Nonnull final String msg) + throws LexerException { + error(tok.getLine(), tok.getColumn(), msg); + } + + /** + * Handles a warning. + * + * If a PreprocessorListener is installed, it receives the + * warning. Otherwise, an exception is thrown. + */ + protected void warning(final int line, final int column, @Nonnull final String msg) + throws LexerException { + if (warnings.contains(Warning.ERROR)) + error(line, column, msg); + else if (listener != null) + listener.handleWarning(source, line, column, msg); + else + throw new LexerException("Warning at " + line + ":" + column + ": " + msg); + } + + /** + * Handles a warning. + * + * If a PreprocessorListener is installed, it receives the + * warning. Otherwise, an exception is thrown. + * + * @see #warning(int, int, String) + */ + protected void warning(@Nonnull final Token tok, @Nonnull final String msg) + throws LexerException { + warning(tok.getLine(), tok.getColumn(), msg); + } + + /** + * Adds a Macro to this Preprocessor. + * + * The given {@link Macro} object encapsulates both the name + * and the expansion. + * @throws IOException + */ + public void addMacro(@Nonnull final Macro m) throws LexerException, IOException { + // System.out.println("Macro " + m); + final String name = m.getName(); + /* Already handled as a source error in macro(). */ + if ("defined".equals(name)) { + throw new LexerException("Cannot redefine name 'defined'"); + } + macros.put(m.getName(), m); + } + + /** + * Defines the given name as a macro. + * + * The String value is lexed into a token stream, which is + * used as the macro expansion. + */ + public void addMacro(@Nonnull final String name, @Nonnull final String value) + throws LexerException { + try { + final Macro m = new Macro(name); + final StringLexerSource s = new StringLexerSource(value); + try { + for (;;) { + final Token tok = s.token(); + if (tok.getType() == EOF) + break; + m.addToken(tok); + } + } finally { + s.close(); + } + addMacro(m); + } catch (final IOException e) { + throw new LexerException(e); + } + } + + /** + * Defines the given name as a macro, with the value 1. + * + * This is a convnience method, and is equivalent to + * addMacro(name, "1"). + */ + public void addMacro(@Nonnull final String name) + throws LexerException { + addMacro(name, "1"); + } + + /** + * Sets the user include path used by this Preprocessor. + */ + /* Note for future: Create an IncludeHandler? */ + public void setQuoteIncludePath(@Nonnull final List path) { + this.quoteincludepath = path; + } + + /** + * Returns the user include-path of this Preprocessor. + * + * This list may be freely modified by user code. + */ + @Nonnull + public List getQuoteIncludePath() { + return quoteincludepath; + } + + /** + * Sets the system include path used by this Preprocessor. + */ + /* Note for future: Create an IncludeHandler? */ + public void setSystemIncludePath(@Nonnull final List path) { + this.sysincludepath = path; + } + + /** + * Returns the system include-path of this Preprocessor. + * + * This list may be freely modified by user code. + */ + @Nonnull + public List getSystemIncludePath() { + return sysincludepath; + } + + /** + * Sets the Objective-C frameworks path used by this Preprocessor. + */ + /* Note for future: Create an IncludeHandler? */ + public void setFrameworksPath(@Nonnull final List path) { + this.frameworkspath = path; + } + + /** + * Returns the Objective-C frameworks path used by this + * Preprocessor. + * + * This list may be freely modified by user code. + */ + @Nonnull + public List getFrameworksPath() { + return frameworkspath; + } + + /** + * Returns the Map of Macros parsed during the run of this + * Preprocessor. + */ + @Nonnull + public Map getMacros() { + return macros; + } + + /** + * Returns a list of {@link Macro}s. + *

    + * Implementation returns a new list of copy-ctor {@link Macro}s. + *

    + * @param expand if {@code true} and if macro is not {@link Macro#isFunctionLike() function-like}, + * i.e. a constant, the returned macro will be expanded. + * @throws IOException + * @throws LexerException + */ + public List getMacros(final boolean expand) throws IOException, LexerException { + final List res = new ArrayList(); + final Collection macroList = macros.values(); + for(final Macro m : macroList) { + if( expand && !m.isFunctionLike() ) { + res.add( new Macro( m, expand( m.getTokens() ) ) ); + } else { + res.add( new Macro( m ) ); + } + } + return res; + } + + /** + * Returns the named macro. + * + * While you can modify the returned object, unexpected things + * might happen if you do. + */ + @CheckForNull + public Macro getMacro(final String name) { + return macros.get(name); + } + + /** + * Returns the list of {@link VirtualFile VirtualFiles} which have been + * included by this Preprocessor. + * + * This does not include any {@link Source} provided to the constructor + * or {@link #addInput(java.io.File)} or {@link #addInput(Source)}. + */ + @Nonnull + public List getIncludes() { + return includes; + } + + /* States */ + private void push_state() { + final State top = states.peek(); + states.push(new State(top)); + } + + private void pop_state() + throws LexerException { + final State s = states.pop(); + if (states.isEmpty()) { + error(0, 0, "#" + "endif without #" + "if"); + states.push(s); + } + } + + private boolean isActive() { + final State state = states.peek(); + return state.isParentActive() && state.isActive(); + } + + + /* Sources */ + /** + * Returns the top Source on the input stack. + * + * @see Source + * @see #push_source(Source,boolean) + * @see #pop_source() + */ + // @CheckForNull + public Source getSource() { + return source; + } + + /** + * Pushes a Source onto the input stack. + * + * @see #getSource() + * @see #pop_source() + */ + protected void push_source(@Nonnull final Source source, final boolean autopop) { + source.init(this); + source.setParent(this.source, autopop); + // source.setListener(listener); + if (listener != null) + listener.handleSourceChange(this.source, SourceChangeEvent.SUSPEND); + this.source = source; + if (listener != null) + listener.handleSourceChange(this.source, SourceChangeEvent.PUSH); + } + + /** + * Pops a Source from the input stack. + * + * @see #getSource() + * @see #push_source(Source,boolean) + */ + @CheckForNull + protected Token pop_source(final boolean linemarker) + throws IOException { + if (listener != null) + listener.handleSourceChange(this.source, SourceChangeEvent.POP); + final Source s = this.source; + this.source = s.getParent(); + /* Always a noop unless called externally. */ + s.close(); + if (listener != null && this.source != null) + listener.handleSourceChange(this.source, SourceChangeEvent.RESUME); + + final Source t = getSource(); + if (getFeature(Feature.LINEMARKERS) + && s.isNumbered() + && t != null) { + /* We actually want 'did the nested source + * contain a newline token', which isNumbered() + * approximates. This is not perfect, but works. + * FIXME: Removed the '+ 1', since all lines were off by one. + * This solves this case, but I don't know _why_ this was here in the first place. + */ + return line_token(t.getLine() /* SEE ABOVE: + 1 */, t.getName(), " 2"); + } + + return null; + } + + protected void pop_source() + throws IOException { + pop_source(false); + } + + @Nonnull + private Token next_source() { + if (inputs.isEmpty()) + return new Token(EOF); + final Source s = inputs.remove(0); + push_source(s, true); + return line_token(s.getLine(), s.getName(), " 1"); + } + + /* Source tokens */ + private Token source_token; + + /* XXX Make this include the NL, and make all cpp directives eat + * their own NL. */ + @Nonnull + private Token line_token(final int line, @CheckForNull final String name, @Nonnull final String extra) { + final StringBuilder buf = new StringBuilder(); + buf.append("#line ").append(line) + .append(" \""); + /* XXX This call to escape(name) is correct but ugly. */ + if (name == null) + buf.append(""); + else + MacroTokenSource.escape(buf, name); + buf.append("\"").append(extra).append("\n"); + return new Token(P_LINE, line, 0, buf.toString(), null); + } + + @Nonnull + private Token source_token() + throws IOException, + LexerException { + if (source_token != null) { + final Token tok = source_token; + source_token = null; + if (getFeature(Feature.DEBUG)) + LOG.debug("Returning unget token " + tok); + return tok; + } + + for (;;) { + final Source s = getSource(); + if (s == null) { + final Token t = next_source(); + if (t.getType() == P_LINE && !getFeature(Feature.LINEMARKERS)) + continue; + return t; + } + final Token tok = s.token(); + /* XXX Refactor with skipline() */ + if (tok.getType() == EOF && s.isAutopop()) { + // System.out.println("Autopop " + s); + final Token mark = pop_source(true); + if (mark != null) + return mark; + continue; + } + if (getFeature(Feature.DEBUG)) + LOG.debug("Returning fresh token " + tok); + return tok; + } + } + + private void source_untoken(final Token tok) { + if (this.source_token != null) + throw new IllegalStateException("Cannot return two tokens"); + this.source_token = tok; + } + + private boolean isWhite(final Token tok) { + final int type = tok.getType(); + return (type == WHITESPACE) + || (type == CCOMMENT) + || (type == CPPCOMMENT); + } + + private Token source_token_nonwhite() + throws IOException, + LexerException { + Token tok; + do { + tok = source_token(); + } while (isWhite(tok)); + return tok; + } + + /** + * Returns an NL or an EOF token. + * + * The metadata on the token will be correct, which is better + * than generating a new one. + * + * This method can, as of recent patches, return a P_LINE token. + */ + private Token source_skipline(final boolean white) + throws IOException, + LexerException { + // (new Exception("skipping line")).printStackTrace(System.out); + final Source s = getSource(); + final Token tok = s.skipline(white); + /* XXX Refactor with source_token() */ + if (tok.getType() == EOF && s.isAutopop()) { + // System.out.println("Autopop " + s); + final Token mark = pop_source(true); + if (mark != null) + return mark; + } + return tok; + } + + /* processes and expands a macro. */ + private boolean macro(final Macro m, final Token orig) + throws IOException, + LexerException { + Token tok; + List args; + + // System.out.println("pp: expanding " + m); + if (m.isFunctionLike()) { + OPEN: + for (;;) { + tok = source_token(); + // System.out.println("pp: open: token is " + tok); + switch (tok.getType()) { + case WHITESPACE: /* XXX Really? */ + + case CCOMMENT: + case CPPCOMMENT: + case NL: + break; /* continue */ + + case '(': + break OPEN; + default: + source_untoken(tok); + return false; + } + } + + // tok = expanded_token_nonwhite(); + tok = source_token_nonwhite(); + + /* We either have, or we should have args. + * This deals elegantly with the case that we have + * one empty arg. */ + if (tok.getType() != ')' || m.getArgs() > 0) { + args = new ArrayList(); + + Argument arg = new Argument(); + int depth = 0; + boolean space = false; + + ARGS: + for (;;) { + // System.out.println("pp: arg: token is " + tok); + switch (tok.getType()) { + case EOF: + error(tok, "EOF in macro args"); + return false; + + case ',': + if (depth == 0) { + if (m.isVariadic() + && /* We are building the last arg. */ args.size() == m.getArgs() - 1) { + /* Just add the comma. */ + arg.addToken(tok); + } else { + args.add(arg); + arg = new Argument(); + } + } else { + arg.addToken(tok); + } + space = false; + break; + case ')': + if (depth == 0) { + args.add(arg); + break ARGS; + } else { + depth--; + arg.addToken(tok); + } + space = false; + break; + case '(': + depth++; + arg.addToken(tok); + space = false; + break; + + case WHITESPACE: + case CCOMMENT: + case CPPCOMMENT: + case NL: + /* Avoid duplicating spaces. */ + space = true; + break; + + default: + /* Do not put space on the beginning of + * an argument token. */ + if (space && !arg.isEmpty()) + arg.addToken(Token.space); + arg.addToken(tok); + space = false; + break; + + } + // tok = expanded_token(); + tok = source_token(); + } + /* space may still be true here, thus trailing space + * is stripped from arguments. */ + + if (args.size() != m.getArgs()) { + if (m.isVariadic()) { + if (args.size() == m.getArgs() - 1) { + args.add(new Argument()); + } else { + error(tok, + "variadic macro " + m.getName() + + " has at least " + (m.getArgs() - 1) + " parameters " + + "but given " + args.size() + " args"); + return false; + } + } else { + error(tok, + "macro " + m.getName() + + " has " + m.getArgs() + " parameters " + + "but given " + args.size() + " args"); + /* We could replay the arg tokens, but I + * note that GNU cpp does exactly what we do, + * i.e. output the macro name and chew the args. + */ + return false; + } + } + + for (final Argument a : args) { + a.expand(this); + } + + // System.out.println("Macro " + m + " args " + args); + } else { + /* nargs == 0 and we (correctly) got () */ + args = null; + } + + } else { + /* Macro without args. */ + args = null; + } + + if (m == __LINE__) { + push_source(new FixedTokenSource( + new Token[]{new Token(NUMBER, + orig.getLine(), orig.getColumn(), + Integer.toString(orig.getLine()), + new NumericValue(10, Integer.toString(orig.getLine())))} + ), true); + } else if (m == __FILE__) { + final StringBuilder buf = new StringBuilder("\""); + String name = getSource().getName(); + if (name == null) + name = ""; + for (int i = 0; i < name.length(); i++) { + final char c = name.charAt(i); + switch (c) { + case '\\': + buf.append("\\\\"); + break; + case '"': + buf.append("\\\""); + break; + default: + buf.append(c); + break; + } + } + buf.append("\""); + final String text = buf.toString(); + push_source(new FixedTokenSource( + new Token[]{new Token(STRING, + orig.getLine(), orig.getColumn(), + text, text)} + ), true); + } else if (m == __COUNTER__) { + /* This could equivalently have been done by adding + * a special Macro subclass which overrides getTokens(). */ + final int value = this.counter++; + push_source(new FixedTokenSource( + new Token[]{new Token(NUMBER, + orig.getLine(), orig.getColumn(), + Integer.toString(value), + new NumericValue(10, Integer.toString(value)))} + ), true); + } else { + push_source(new MacroTokenSource(m, args), true); + } + + return true; + } + + /** + * Expands an argument. + */ + /* I'd rather this were done lazily, but doing so breaks spec. */ + @Nonnull + /* pp */ List expand(@Nonnull final List arg) + throws IOException, + LexerException { + final List expansion = new ArrayList(); + boolean space = false; + + push_source(new FixedTokenSource(arg), false); + + EXPANSION: + for (;;) { + final Token tok = expanded_token(); + switch (tok.getType()) { + case EOF: + break EXPANSION; + + case WHITESPACE: + case CCOMMENT: + case CPPCOMMENT: + space = true; + break; + + default: + if (space && !expansion.isEmpty()) + expansion.add(Token.space); + expansion.add(tok); + space = false; + break; + } + } + + // Always returns null. + pop_source(false); + + return expansion; + } + + /* processes a #define directive */ + private Token define() + throws IOException, + LexerException { + Token tok = source_token_nonwhite(); + if (tok.getType() != IDENTIFIER) { + error(tok, "Expected identifier"); + return source_skipline(false); + } + /* if predefined */ + final String name = tok.getText(); + if ("defined".equals(name)) { + error(tok, "Cannot redefine name 'defined'"); + return source_skipline(false); + } + + final Macro m = new Macro(getSource(), name); + List args; + + tok = source_token(); + if (tok.getType() == '(') { + tok = source_token_nonwhite(); + if (tok.getType() != ')') { + args = new ArrayList(); + ARGS: + for (;;) { + switch (tok.getType()) { + case IDENTIFIER: + args.add(tok.getText()); + break; + case ELLIPSIS: + // Unnamed Variadic macro + args.add("__VA_ARGS__"); + // We just named the ellipsis, but we unget the token + // to allow the ELLIPSIS handling below to process it. + source_untoken(tok); + break; + case NL: + case EOF: + error(tok, + "Unterminated macro parameter list"); + return tok; + default: + error(tok, + "error in macro parameters: " + + tok.getText()); + return source_skipline(false); + } + tok = source_token_nonwhite(); + switch (tok.getType()) { + case ',': + break; + case ELLIPSIS: + tok = source_token_nonwhite(); + if (tok.getType() != ')') + error(tok, + "ellipsis must be on last argument"); + m.setVariadic(true); + break ARGS; + case ')': + break ARGS; + + case NL: + case EOF: + /* Do not skip line. */ + error(tok, + "Unterminated macro parameters"); + return tok; + default: + error(tok, + "Bad token in macro parameters: " + + tok.getText()); + return source_skipline(false); + } + tok = source_token_nonwhite(); + } + } else { + assert tok.getType() == ')' : "Expected ')'"; + args = Collections.emptyList(); + } + + m.setArgs(args); + } else { + /* For searching. */ + args = Collections.emptyList(); + source_untoken(tok); + } + + /* Get an expansion for the macro, using indexOf. */ + boolean space = false; + boolean paste = false; + int idx; + + /* Ensure no space at start. */ + tok = source_token_nonwhite(); + EXPANSION: + for (;;) { + switch (tok.getType()) { + case EOF: + break EXPANSION; + case NL: + break EXPANSION; + + case CCOMMENT: + case CPPCOMMENT: + /* XXX This is where we implement GNU's cpp -CC. */ + // break; + case WHITESPACE: + if (!paste) + space = true; + break; + + /* Paste. */ + case PASTE: + space = false; + paste = true; + m.addPaste(new Token(M_PASTE, + tok.getLine(), tok.getColumn(), + "#" + "#", null)); + break; + + /* Stringify. */ + case '#': + if (space) + m.addToken(Token.space); + space = false; + final Token la = source_token_nonwhite(); + if (la.getType() == IDENTIFIER + && ((idx = args.indexOf(la.getText())) != -1)) { + m.addToken(new Token(M_STRING, + la.getLine(), la.getColumn(), + "#" + la.getText(), + Integer.valueOf(idx))); + } else { + m.addToken(tok); + /* Allow for special processing. */ + source_untoken(la); + } + break; + + case IDENTIFIER: + if (space) + m.addToken(Token.space); + space = false; + paste = false; + idx = args.indexOf(tok.getText()); + if (idx == -1) + m.addToken(tok); + else + m.addToken(new Token(M_ARG, + tok.getLine(), tok.getColumn(), + tok.getText(), + Integer.valueOf(idx))); + break; + + default: + if (space) + m.addToken(Token.space); + space = false; + paste = false; + m.addToken(tok); + break; + } + tok = source_token(); + } + + if (getFeature(Feature.DEBUG)) { + LOG.debug("Defined macro " + m); + } + addMacro(m); + + return tok; /* NL or EOF. */ + } + + @Nonnull + private Token undef() + throws IOException, + LexerException { + final Token tok = source_token_nonwhite(); + if (tok.getType() != IDENTIFIER) { + error(tok, + "Expected identifier, not " + tok.getText()); + if (tok.getType() == NL || tok.getType() == EOF) + return tok; + } else { + final Macro m = getMacro(tok.getText()); + if (m != null) { + /* XXX error if predefined */ + macros.remove(m.getName()); + } + } + return source_skipline(true); + } + + /** + * Attempts to include the given file. + * + * User code may override this method to implement a virtual + * file system. + */ + protected boolean include(@Nonnull final VirtualFile file) + throws IOException, + LexerException { + // System.out.println("Try to include " + ((File)file).getAbsolutePath()); + if (!file.isFile()) + return false; + if (getFeature(Feature.DEBUG)) + LOG.debug("pp: including " + file); + includes.add(file); + push_source(file.getSource(), true); + return true; + } + + /** + * Includes a file from an include path, by name. + */ + protected boolean include(@Nonnull final Iterable path, @Nonnull final String name) + throws IOException, + LexerException { + for (final String dir : path) { + final VirtualFile file = getFileSystem().getFile(dir, name); + if (include(file)) + return true; + } + return false; + } + + /** + * Handles an include directive. + */ + private void include( + @CheckForNull final String parent, final int line, + @Nonnull final String name, final boolean quoted, final boolean next) + throws IOException, + LexerException { + if (name.startsWith("/")) { + final VirtualFile file = filesystem.getFile(name); + if (include(file)) + return; + final StringBuilder buf = new StringBuilder(); + buf.append("File not found: ").append(name); + error(line, 0, buf.toString()); + return; + } + + VirtualFile pdir = null; + if (quoted) { + if (parent != null) { + final VirtualFile pfile = filesystem.getFile(parent); + pdir = pfile.getParentFile(); + } + if (pdir != null) { + final VirtualFile ifile = pdir.getChildFile(name); + if (include(ifile)) + return; + } + if (include(quoteincludepath, name)) + return; + } else { + final int idx = name.indexOf('/'); + if (idx != -1) { + final String frameworkName = name.substring(0, idx); + final String headerName = name.substring(idx + 1); + final String headerPath = frameworkName + ".framework/Headers/" + headerName; + if (include(frameworkspath, headerPath)) + return; + } + } + + if (include(sysincludepath, name)) + return; + + final StringBuilder buf = new StringBuilder(); + buf.append("File not found: ").append(name); + buf.append(" in"); + if (quoted) { + buf.append(" .").append('(').append(pdir).append(')'); + for (final String dir : quoteincludepath) + buf.append(" ").append(dir); + } + for (final String dir : sysincludepath) + buf.append(" ").append(dir); + error(line, 0, buf.toString()); + } + + @Nonnull + private Token include(final boolean next) + throws IOException, + LexerException { + final LexerSource lexer = (LexerSource) source; + try { + lexer.setInclude(true); + Token tok = token_nonwhite(); + + String name; + boolean quoted; + + if (tok.getType() == STRING) { + /* XXX Use the original text, not the value. + * Backslashes must not be treated as escapes here. */ + final StringBuilder buf = new StringBuilder((String) tok.getValue()); + HEADER: + for (;;) { + tok = token_nonwhite(); + switch (tok.getType()) { + case STRING: + buf.append((String) tok.getValue()); + break; + case NL: + case EOF: + break HEADER; + default: + warning(tok, + "Unexpected token on #" + "include line"); + return source_skipline(false); + } + } + name = buf.toString(); + quoted = true; + } else if (tok.getType() == HEADER) { + name = (String) tok.getValue(); + quoted = false; + tok = source_skipline(true); + } else { + error(tok, + "Expected string or header, not " + tok.getText()); + switch (tok.getType()) { + case NL: + case EOF: + return tok; + default: + /* Only if not a NL or EOF already. */ + return source_skipline(false); + } + } + + /* Do the inclusion. */ + include(source.getPath(), tok.getLine(), name, quoted, next); + + /* 'tok' is the 'nl' after the include. We use it after the + * #line directive. */ + if (getFeature(Feature.LINEMARKERS)) + return line_token(1, source.getName(), " 1"); + return tok; + } finally { + lexer.setInclude(false); + } + } + + protected void pragma_once(@Nonnull final Token name) + throws IOException, LexerException { + final Source s = this.source; + if (!onceseenpaths.add(s.getPath())) { + final Token mark = pop_source(true); + // FixedTokenSource should never generate a linemarker on exit. + if (mark != null) + push_source(new FixedTokenSource(Arrays.asList(mark)), true); + } + } + + protected void pragma(@Nonnull final Token name, @Nonnull final List value) + throws IOException, + LexerException { + if (getFeature(Feature.PRAGMA_ONCE)) { + if ("once".equals(name.getText())) { + pragma_once(name); + return; + } + } + warning(name, "Unknown #" + "pragma: " + name.getText()); + } + + @Nonnull + private Token pragma() + throws IOException, + LexerException { + Token name; + + NAME: + for (;;) { + final Token tok = token(); + switch (tok.getType()) { + case EOF: + /* There ought to be a newline before EOF. + * At least, in any skipline context. */ + /* XXX Are we sure about this? */ + warning(tok, + "End of file in #" + "pragma"); + return tok; + case NL: + /* This may contain one or more newlines. */ + warning(tok, + "Empty #" + "pragma"); + return tok; + case CCOMMENT: + case CPPCOMMENT: + case WHITESPACE: + continue NAME; + case IDENTIFIER: + name = tok; + break NAME; + default: + return source_skipline(false); + } + } + + Token tok; + final List value = new ArrayList(); + VALUE: + for (;;) { + tok = token(); + switch (tok.getType()) { + case EOF: + /* There ought to be a newline before EOF. + * At least, in any skipline context. */ + /* XXX Are we sure about this? */ + warning(tok, + "End of file in #" + "pragma"); + break VALUE; + case NL: + /* This may contain one or more newlines. */ + break VALUE; + case CCOMMENT: + case CPPCOMMENT: + break; + case WHITESPACE: + value.add(tok); + break; + default: + value.add(tok); + break; + } + } + + pragma(name, value); + + return tok; /* The NL. */ + + } + + /* For #error and #warning. */ + private void error(@Nonnull final Token pptok, final boolean is_error) + throws IOException, + LexerException { + final StringBuilder buf = new StringBuilder(); + buf.append('#').append(pptok.getText()).append(' '); + /* Peculiar construction to ditch first whitespace. */ + Token tok = source_token_nonwhite(); + ERROR: + for (;;) { + switch (tok.getType()) { + case NL: + case EOF: + break ERROR; + default: + buf.append(tok.getText()); + break; + } + tok = source_token(); + } + if (is_error) + error(pptok, buf.toString()); + else + warning(pptok, buf.toString()); + } + + /* This bypasses token() for #elif expressions. + * If we don't do this, then isActive() == false + * causes token() to simply chew the entire input line. */ + @Nonnull + private Token expanded_token() + throws IOException, + LexerException { + for (;;) { + final Token tok = source_token(); + // System.out.println("Source token is " + tok); + if (tok.getType() == IDENTIFIER) { + final Macro m = getMacro(tok.getText()); + if (m == null) + return tok; + if (source.isExpanding(m)) + return tok; + if (macro(m, tok)) + continue; + } + return tok; + } + } + + @Nonnull + private Token expanded_token_nonwhite() + throws IOException, + LexerException { + Token tok; + do { + tok = expanded_token(); + // System.out.println("expanded token is " + tok); + } while (isWhite(tok)); + return tok; + } + + @CheckForNull + private Token expr_token = null; + + @Nonnull + private Token expr_token() + throws IOException, + LexerException { + Token tok = expr_token; + + if (tok != null) { + // System.out.println("ungetting"); + expr_token = null; + } else { + tok = expanded_token_nonwhite(); + // System.out.println("expt is " + tok); + + if (tok.getType() == IDENTIFIER + && tok.getText().equals("defined")) { + Token la = source_token_nonwhite(); + boolean paren = false; + if (la.getType() == '(') { + paren = true; + la = source_token_nonwhite(); + } + + // System.out.println("Core token is " + la); + if (la.getType() != IDENTIFIER) { + error(la, + "defined() needs identifier, not " + + la.getText()); + tok = new Token(NUMBER, + la.getLine(), la.getColumn(), + "0", new NumericValue(10, "0")); + } else if (macros.containsKey(la.getText())) { + // System.out.println("Found macro"); + tok = new Token(NUMBER, + la.getLine(), la.getColumn(), + "1", new NumericValue(10, "1")); + } else { + // System.out.println("Not found macro"); + tok = new Token(NUMBER, + la.getLine(), la.getColumn(), + "0", new NumericValue(10, "0")); + } + + if (paren) { + la = source_token_nonwhite(); + if (la.getType() != ')') { + expr_untoken(la); + error(la, "Missing ) in defined(). Got " + la.getText()); + } + } + } + } + + // System.out.println("expr_token returns " + tok); + return tok; + } + + private void expr_untoken(@Nonnull final Token tok) + throws LexerException { + if (expr_token != null) + throw new InternalException( + "Cannot unget two expression tokens." + ); + expr_token = tok; + } + + private int expr_priority(@Nonnull final Token op) { + switch (op.getType()) { + case '/': + return 11; + case '%': + return 11; + case '*': + return 11; + case '+': + return 10; + case '-': + return 10; + case LSH: + return 9; + case RSH: + return 9; + case '<': + return 8; + case '>': + return 8; + case LE: + return 8; + case GE: + return 8; + case EQ: + return 7; + case NE: + return 7; + case '&': + return 6; + case '^': + return 5; + case '|': + return 4; + case LAND: + return 3; + case LOR: + return 2; + case '?': + return 1; + default: + // System.out.println("Unrecognised operator " + op); + return 0; + } + } + + private long expr(final int priority) + throws IOException, + LexerException { + /* + * (new Exception("expr(" + priority + ") called")).printStackTrace(); + */ + + Token tok = expr_token(); + long lhs, rhs; + + // System.out.println("Expr lhs token is " + tok); + switch (tok.getType()) { + case '(': + lhs = expr(0); + tok = expr_token(); + if (tok.getType() != ')') { + expr_untoken(tok); + error(tok, "Missing ) in expression. Got " + tok.getText()); + return 0; + } + break; + + case '~': + lhs = ~expr(11); + break; + case '!': + lhs = expr(11) == 0 ? 1 : 0; + break; + case '-': + lhs = -expr(11); + break; + case NUMBER: + final NumericValue value = (NumericValue) tok.getValue(); + lhs = value.longValue(); + break; + case CHARACTER: + lhs = ((Character) tok.getValue()).charValue(); + break; + case IDENTIFIER: + if (warnings.contains(Warning.UNDEF)) + warning(tok, "Undefined token '" + tok.getText() + + "' encountered in conditional."); + lhs = 0; + break; + + default: + expr_untoken(tok); + error(tok, + "Bad token in expression: " + tok.getText()); + return 0; + } + + EXPR: + for (;;) { + // System.out.println("expr: lhs is " + lhs + ", pri = " + priority); + final Token op = expr_token(); + final int pri = expr_priority(op); /* 0 if not a binop. */ + + if (pri == 0 || priority >= pri) { + expr_untoken(op); + break EXPR; + } + rhs = expr(pri); + // System.out.println("rhs token is " + rhs); + switch (op.getType()) { + case '/': + if (rhs == 0) { + error(op, "Division by zero"); + lhs = 0; + } else { + lhs = lhs / rhs; + } + break; + case '%': + if (rhs == 0) { + error(op, "Modulus by zero"); + lhs = 0; + } else { + lhs = lhs % rhs; + } + break; + case '*': + lhs = lhs * rhs; + break; + case '+': + lhs = lhs + rhs; + break; + case '-': + lhs = lhs - rhs; + break; + case '<': + lhs = lhs < rhs ? 1 : 0; + break; + case '>': + lhs = lhs > rhs ? 1 : 0; + break; + case '&': + lhs = lhs & rhs; + break; + case '^': + lhs = lhs ^ rhs; + break; + case '|': + lhs = lhs | rhs; + break; + + case LSH: + lhs = lhs << rhs; + break; + case RSH: + lhs = lhs >> rhs; + break; + case LE: + lhs = lhs <= rhs ? 1 : 0; + break; + case GE: + lhs = lhs >= rhs ? 1 : 0; + break; + case EQ: + lhs = lhs == rhs ? 1 : 0; + break; + case NE: + lhs = lhs != rhs ? 1 : 0; + break; + case LAND: + lhs = (lhs != 0) && (rhs != 0) ? 1 : 0; + break; + case LOR: + lhs = (lhs != 0) || (rhs != 0) ? 1 : 0; + break; + + case '?': { + tok = expr_token(); + if (tok.getType() != ':') { + expr_untoken(tok); + error(tok, "Missing : in conditional expression. Got " + tok.getText()); + return 0; + } + final long falseResult = expr(0); + lhs = (lhs != 0) ? rhs : falseResult; + } + break; + + default: + error(op, + "Unexpected operator " + op.getText()); + return 0; + + } + } + + /* + * (new Exception("expr returning " + lhs)).printStackTrace(); + */ + // System.out.println("expr returning " + lhs); + return lhs; + } + + @Nonnull + private Token toWhitespace(@Nonnull final Token tok) { + final String text = tok.getText(); + final int len = text.length(); + boolean cr = false; + int nls = 0; + + for (int i = 0; i < len; i++) { + final char c = text.charAt(i); + + switch (c) { + case '\r': + cr = true; + nls++; + break; + case '\n': + if (cr) { + cr = false; + break; + } + /* fallthrough */ + case '\u2028': + case '\u2029': + case '\u000B': + case '\u000C': + case '\u0085': + cr = false; + nls++; + break; + } + } + + final char[] cbuf = new char[nls]; + Arrays.fill(cbuf, '\n'); + return new Token(WHITESPACE, + tok.getLine(), tok.getColumn(), + new String(cbuf)); + } + + @Nonnull + private Token _token() + throws IOException, + LexerException { + + for (;;) { + Token tok; + if (!isActive()) { + final Source s = getSource(); + if (s == null) { + final Token t = next_source(); + if (t.getType() == P_LINE && !getFeature(Feature.LINEMARKERS)) + continue; + return t; + } + + try { + /* XXX Tell lexer to ignore warnings. */ + s.setActive(false); + tok = source_token(); + } finally { + /* XXX Tell lexer to stop ignoring warnings. */ + s.setActive(true); + } + switch (tok.getType()) { + case HASH: + case NL: + case EOF: + /* The preprocessor has to take action here. */ + break; + case WHITESPACE: + return tok; + case CCOMMENT: + case CPPCOMMENT: + // Patch up to preserve whitespace. + if (getFeature(Feature.KEEPALLCOMMENTS)) + return tok; + if (!isActive()) + return toWhitespace(tok); + if (getFeature(Feature.KEEPCOMMENTS)) + return tok; + return toWhitespace(tok); + default: + // Return NL to preserve whitespace. + /* XXX This might lose a comment. */ + return source_skipline(false); + } + } else { + tok = source_token(); + } + + LEX: + switch (tok.getType()) { + case EOF: + /* Pop the stacks. */ + return tok; + + case WHITESPACE: + case NL: + return tok; + + case CCOMMENT: + case CPPCOMMENT: + return tok; + + case '!': + case '%': + case '&': + case '(': + case ')': + case '*': + case '+': + case ',': + case '-': + case '/': + case ':': + case ';': + case '<': + case '=': + case '>': + case '?': + case '[': + case ']': + case '^': + case '{': + case '|': + case '}': + case '~': + case '.': + + /* From Olivier Chafik for Objective C? */ + case '@': + /* The one remaining ASCII, might as well. */ + case '`': + + // case '#': + case AND_EQ: + case ARROW: + case CHARACTER: + case DEC: + case DIV_EQ: + case ELLIPSIS: + case EQ: + case GE: + case HEADER: /* Should only arise from include() */ + + case INC: + case LAND: + case LE: + case LOR: + case LSH: + case LSH_EQ: + case SUB_EQ: + case MOD_EQ: + case MULT_EQ: + case NE: + case OR_EQ: + case PLUS_EQ: + case RANGE: + case RSH: + case RSH_EQ: + case STRING: + case SQSTRING: + case XOR_EQ: + return tok; + + case NUMBER: + return tok; + + case IDENTIFIER: + final Macro m = getMacro(tok.getText()); + if (m == null) + return tok; + if (source.isExpanding(m)) + return tok; + if (macro(m, tok)) + break; + return tok; + + case P_LINE: + if (getFeature(Feature.LINEMARKERS)) + return tok; + break; + + case INVALID: + if (getFeature(Feature.CSYNTAX)) + error(tok, String.valueOf(tok.getValue())); + return tok; + + default: + throw new InternalException("Bad token " + tok); + // break; + + case HASH: + tok = source_token_nonwhite(); + // (new Exception("here")).printStackTrace(); + switch (tok.getType()) { + case NL: + break LEX; /* Some code has #\n */ + + case IDENTIFIER: + break; + default: + error(tok, + "Preprocessor directive not a word " + + tok.getText()); + return source_skipline(false); + } + final PreprocessorCommand ppcmd = PreprocessorCommand.forText(tok.getText()); + if (ppcmd == null) { + error(tok, + "Unknown preprocessor directive " + + tok.getText()); + return source_skipline(false); + } + + PP: + switch (ppcmd) { + + case PP_DEFINE: + if (!isActive()) + return source_skipline(false); + else + return define(); + // break; + + case PP_UNDEF: + if (!isActive()) + return source_skipline(false); + else + return undef(); + // break; + + case PP_INCLUDE: + if (!isActive()) + return source_skipline(false); + else + return include(false); + // break; + case PP_INCLUDE_NEXT: + if (!isActive()) + return source_skipline(false); + if (!getFeature(Feature.INCLUDENEXT)) { + error(tok, + "Directive include_next not enabled" + ); + return source_skipline(false); + } + return include(true); + // break; + + case PP_WARNING: + case PP_ERROR: + if (!isActive()) + return source_skipline(false); + else + error(tok, ppcmd == PP_ERROR); + break; + + case PP_IF: + push_state(); + if (!isActive()) { + return source_skipline(false); + } + expr_token = null; + states.peek().setActive(expr(0) != 0); + tok = expr_token(); /* unget */ + + if (tok.getType() == NL) + return tok; + return source_skipline(true); + // break; + + case PP_ELIF: + State state = states.peek(); + if (false) { + /* Check for 'if' */; + } else if (state.sawElse()) { + error(tok, + "#elif after #" + "else"); + return source_skipline(false); + } else if (!state.isParentActive()) { + /* Nested in skipped 'if' */ + return source_skipline(false); + } else if (state.isActive()) { + /* The 'if' part got executed. */ + state.setParentActive(false); + /* This is like # else # if but with + * only one # end. */ + state.setActive(false); + return source_skipline(false); + } else { + expr_token = null; + state.setActive(expr(0) != 0); + tok = expr_token(); /* unget */ + + if (tok.getType() == NL) + return tok; + return source_skipline(true); + } + // break; + + case PP_ELSE: + state = states.peek(); + if (false) + /* Check for 'if' */ ; else if (state.sawElse()) { + error(tok, + "#" + "else after #" + "else"); + return source_skipline(false); + } else { + state.setSawElse(); + state.setActive(!state.isActive()); + return source_skipline(warnings.contains(Warning.ENDIF_LABELS)); + } + // break; + + case PP_IFDEF: + push_state(); + if (!isActive()) { + return source_skipline(false); + } else { + tok = source_token_nonwhite(); + // System.out.println("ifdef " + tok); + if (tok.getType() != IDENTIFIER) { + error(tok, + "Expected identifier, not " + + tok.getText()); + return source_skipline(false); + } else { + final String text = tok.getText(); + final boolean exists + = macros.containsKey(text); + states.peek().setActive(exists); + return source_skipline(true); + } + } + // break; + + case PP_IFNDEF: + push_state(); + if (!isActive()) { + return source_skipline(false); + } else { + tok = source_token_nonwhite(); + if (tok.getType() != IDENTIFIER) { + error(tok, + "Expected identifier, not " + + tok.getText()); + return source_skipline(false); + } else { + final String text = tok.getText(); + final boolean exists + = macros.containsKey(text); + states.peek().setActive(!exists); + return source_skipline(true); + } + } + // break; + + case PP_ENDIF: + pop_state(); + return source_skipline(warnings.contains(Warning.ENDIF_LABELS)); + // break; + + case PP_LINE: + return source_skipline(false); + // break; + + case PP_PRAGMA: + if (!isActive()) + return source_skipline(false); + return pragma(); + // break; + + default: + /* Actual unknown directives are + * processed above. If we get here, + * we succeeded the map lookup but + * failed to handle it. Therefore, + * this is (unconditionally?) fatal. */ + // if (isActive()) /* XXX Could be warning. */ + throw new InternalException( + "Internal error: Unknown directive " + + tok); + // return source_skipline(false); + } + + } + } + } + + @Nonnull + private Token token_nonwhite() + throws IOException, + LexerException { + Token tok; + do { + tok = _token(); + } while (isWhite(tok)); + return tok; + } + + /** + * Returns the next preprocessor token. + * + * @see Token + * @throws LexerException if a preprocessing error occurs. + * @throws InternalException if an unexpected error condition arises. + */ + @Nonnull + public Token token() + throws IOException, + LexerException { + final Token tok = _token(); + if (getFeature(Feature.DEBUG)) + LOG.debug("pp: Returning " + tok); + return tok; + } + + @Override + public String toString() { + final StringBuilder buf = new StringBuilder(); + + Source s = getSource(); + while (s != null) { + buf.append(" -> ").append(String.valueOf(s)).append("\n"); + s = s.getParent(); + } + + final Map macros = new TreeMap(getMacros()); + for (final Macro macro : macros.values()) { + buf.append("#").append("macro ").append(macro).append("\n"); + } + + return buf.toString(); + } + + @Override + public void close() + throws IOException { + { + Source s = source; + while (s != null) { + s.close(); + s = s.getParent(); + } + } + for (final Source s : inputs) { + s.close(); + } + } + +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/PreprocessorListener.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/PreprocessorListener.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/PreprocessorListener.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/PreprocessorListener.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,59 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import javax.annotation.Nonnull; + +/** + * A handler for preprocessor events, primarily errors and warnings. + * + * If no PreprocessorListener is installed in a Preprocessor, all + * error and warning events will throw an exception. Installing a + * listener allows more intelligent handling of these events. + */ +public interface PreprocessorListener { + + /** + * Handles a warning. + * + * The behaviour of this method is defined by the + * implementation. It may simply record the error message, or + * it may throw an exception. + */ + public void handleWarning(@Nonnull Source source, int line, int column, + @Nonnull String msg) + throws LexerException; + + /** + * Handles an error. + * + * The behaviour of this method is defined by the + * implementation. It may simply record the error message, or + * it may throw an exception. + */ + public void handleError(@Nonnull Source source, int line, int column, + @Nonnull String msg) + throws LexerException; + + public enum SourceChangeEvent { + + SUSPEND, PUSH, POP, RESUME; + } + + public void handleSourceChange(@Nonnull Source source, @Nonnull SourceChangeEvent event); + +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/ResourceFileSystem.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/ResourceFileSystem.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/ResourceFileSystem.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/ResourceFileSystem.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,81 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jogamp.gluegen.jcpp; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import javax.annotation.Nonnull; + +/** + * + * @author shevek + */ +public class ResourceFileSystem implements VirtualFileSystem { + + private final ClassLoader loader; + + public ResourceFileSystem(@Nonnull ClassLoader loader) { + this.loader = loader; + } + + @Override + public VirtualFile getFile(String path) { + return new ResourceFile(loader, path); + } + + @Override + public VirtualFile getFile(String dir, String name) { + return getFile(dir + "/" + name); + } + + private class ResourceFile implements VirtualFile { + + private final ClassLoader loader; + private final String path; + + public ResourceFile(ClassLoader loader, String path) { + this.loader = loader; + this.path = path; + } + + @Override + public boolean isFile() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public String getPath() { + return path; + } + + @Override + public String getName() { + return path.substring(path.lastIndexOf('/') + 1); + } + + @Override + public ResourceFile getParentFile() { + int idx = path.lastIndexOf('/'); + if (idx < 1) + return null; + return new ResourceFile(loader, path.substring(0, idx)); + } + + @Override + public ResourceFile getChildFile(String name) { + return new ResourceFile(loader, path + "/" + name); + } + + @Override + public Source getSource() throws IOException { + InputStream stream = loader.getResourceAsStream(path); + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + return new LexerSource(reader, true); + } + } +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/SourceIterator.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/SourceIterator.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/SourceIterator.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/SourceIterator.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,88 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.IOException; +import java.util.Iterator; +import java.util.NoSuchElementException; + +import static com.jogamp.gluegen.jcpp.Token.EOF; + +/** + * An Iterator for {@link Source Sources}, + * returning {@link Token Tokens}. + */ +public class SourceIterator implements Iterator { + + private final Source source; + private Token tok; + + public SourceIterator(Source s) { + this.source = s; + this.tok = null; + } + + /** + * Rethrows IOException inside IllegalStateException. + */ + private void advance() { + try { + if (tok == null) + tok = source.token(); + } catch (LexerException e) { + throw new IllegalStateException(e); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + /** + * Returns true if the enclosed Source has more tokens. + * + * The EOF token is never returned by the iterator. + * @throws IllegalStateException if the Source + * throws a LexerException or IOException + */ + public boolean hasNext() { + advance(); + return tok.getType() != EOF; + } + + /** + * Returns the next token from the enclosed Source. + * + * The EOF token is never returned by the iterator. + * @throws IllegalStateException if the Source + * throws a LexerException or IOException + */ + public Token next() { + if (!hasNext()) + throw new NoSuchElementException(); + Token t = this.tok; + this.tok = null; + return t; + } + + /** + * Not supported. + * + * @throws UnsupportedOperationException. + */ + public void remove() { + throw new UnsupportedOperationException(); + } +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Source.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Source.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Source.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Source.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,298 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.Closeable; +import java.io.IOException; +import java.util.Iterator; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; + +import static com.jogamp.gluegen.jcpp.Token.CCOMMENT; +import static com.jogamp.gluegen.jcpp.Token.CPPCOMMENT; +import static com.jogamp.gluegen.jcpp.Token.EOF; +import static com.jogamp.gluegen.jcpp.Token.NL; +import static com.jogamp.gluegen.jcpp.Token.WHITESPACE; + +/** + * An input to the Preprocessor. + * + * Inputs may come from Files, Strings or other sources. The + * preprocessor maintains a stack of Sources. Operations such as + * file inclusion or token pasting will push a new source onto + * the Preprocessor stack. Sources pop from the stack when they + * are exhausted; this may be transparent or explicit. + * + * BUG: Error messages are not handled properly. + */ +public abstract class Source implements Iterable, Closeable { + + private Source parent; + private boolean autopop; + private PreprocessorListener listener; + private boolean active; + private boolean werror; + + /* LineNumberReader */ + + /* + // We can't do this, since we would lose the LexerException + private class Itr implements Iterator { + private Token next = null; + private void advance() { + try { + if (next != null) + next = token(); + } + catch (IOException e) { + throw new UnsupportedOperationException( + "Failed to advance token iterator: " + + e.getMessage() + ); + } + } + public boolean hasNext() { + return next.getType() != EOF; + } + public Token next() { + advance(); + Token t = next; + next = null; + return t; + } + public void remove() { + throw new UnsupportedOperationException( + "Cannot remove tokens from a Source." + ); + } + } + */ + public Source() { + this.parent = null; + this.autopop = false; + this.listener = null; + this.active = true; + this.werror = false; + } + + /** + * Sets the parent source of this source. + * + * Sources form a singly linked list. + */ + /* pp */ void setParent(final Source parent, final boolean autopop) { + this.parent = parent; + this.autopop = autopop; + } + + /** + * Returns the parent source of this source. + * + * Sources form a singly linked list. + */ + public final Source getParent() { + return parent; + } + + + // @OverrideMustInvoke + /* pp */ void init(final Preprocessor pp) { + setListener(pp.getListener()); + this.werror = pp.getWarnings().contains(Warning.ERROR); + } + + /** + * Sets the listener for this Source. + * + * Normally this is set by the Preprocessor when a Source is + * used, but if you are using a Source as a standalone object, + * you may wish to call this. + */ + public void setListener(final PreprocessorListener pl) { + this.listener = pl; + } + + /** + * Returns the File currently being lexed. + * + * If this Source is not a {@link FileLexerSource}, then + * it will ask the parent Source, and so forth recursively. + * If no Source on the stack is a FileLexerSource, returns null. + */ + @CheckForNull + public String getPath() { + final Source parent = getParent(); + if (parent != null) + return parent.getPath(); + return null; + } + + /** + * Returns the human-readable name of the current Source. + */ + @CheckForNull + public String getName() { + final Source parent = getParent(); + if (parent != null) + return parent.getName(); + return null; + } + + /** + * Returns the current line number within this Source. + */ + @Nonnegative + public int getLine() { + final Source parent = getParent(); + if (parent == null) + return 0; + return parent.getLine(); + } + + /** + * Returns the current column number within this Source. + */ + public int getColumn() { + final Source parent = getParent(); + if (parent == null) + return 0; + return parent.getColumn(); + } + + /** + * Returns true if this Source is expanding the given macro. + * + * This is used to prevent macro recursion. + */ + /* pp */ boolean isExpanding(@Nonnull final Macro m) { + final Source parent = getParent(); + if (parent != null) + return parent.isExpanding(m); + return false; + } + + /** + * Returns true if this Source should be transparently popped + * from the input stack. + * + * Examples of such sources are macro expansions. + */ + /* pp */ boolean isAutopop() { + return autopop; + } + + /** + * Returns true if this source has line numbers. + */ + /* pp */ boolean isNumbered() { + return false; + } + + /* This is an incredibly lazy way of disabling warnings when + * the source is not active. */ + /* pp */ void setActive(final boolean b) { + this.active = b; + } + + /* pp */ boolean isActive() { + return active; + } + + /** + * Returns the next Token parsed from this input stream. + * + * @see Token + */ + @Nonnull + public abstract Token token() + throws IOException, + LexerException; + + /** + * Returns a token iterator for this Source. + */ + @Override + public Iterator iterator() { + return new SourceIterator(this); + } + + /** + * Skips tokens until the end of line. + * + * @param white true if only whitespace is permitted on the + * remainder of the line. + * @return the NL token. + */ + @Nonnull + public Token skipline(final boolean white) + throws IOException, + LexerException { + for (;;) { + final Token tok = token(); + switch (tok.getType()) { + case EOF: + /* There ought to be a newline before EOF. + * At least, in any skipline context. */ + /* XXX Are we sure about this? */ + warning(tok.getLine(), tok.getColumn(), + "No newline before end of file"); + return new Token(NL, + tok.getLine(), tok.getColumn(), + "\n"); + // return tok; + case NL: + /* This may contain one or more newlines. */ + return tok; + case CCOMMENT: + case CPPCOMMENT: + case WHITESPACE: + break; + default: + /* XXX Check white, if required. */ + if (white) + warning(tok.getLine(), tok.getColumn(), + "Unexpected nonwhite token"); + break; + } + } + } + + protected void error(final int line, final int column, final String msg) + throws LexerException { + if (listener != null) + listener.handleError(this, line, column, msg); + else + throw new LexerException("Error at " + line + ":" + column + ": " + msg); + } + + protected void warning(final int line, final int column, final String msg) + throws LexerException { + if (werror) + error(line, column, msg); + else if (listener != null) + listener.handleWarning(this, line, column, msg); + else + throw new LexerException("Warning at " + line + ":" + column + ": " + msg); + } + + public void close() + throws IOException { + } + +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/State.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/State.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/State.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/State.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +/* pp */ class State { + + boolean parent; + boolean active; + boolean sawElse; + + /* pp */ State() { + this.parent = true; + this.active = true; + this.sawElse = false; + } + + /* pp */ State(State parent) { + this.parent = parent.isParentActive() && parent.isActive(); + this.active = true; + this.sawElse = false; + } + + /* Required for #elif */ + /* pp */ void setParentActive(boolean b) { + this.parent = b; + } + + /* pp */ boolean isParentActive() { + return parent; + } + + /* pp */ void setActive(boolean b) { + this.active = b; + } + + /* pp */ boolean isActive() { + return active; + } + + /* pp */ void setSawElse() { + sawElse = true; + } + + /* pp */ boolean sawElse() { + return sawElse; + } + + @Override + public String toString() { + return "parent=" + parent + + ", active=" + active + + ", sawelse=" + sawElse; + } +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/StringLexerSource.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/StringLexerSource.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/StringLexerSource.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/StringLexerSource.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,53 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.StringReader; + +/** + * A Source for lexing a String. + * + * This class is used by token pasting, but can be used by user + * code. + */ +public class StringLexerSource extends LexerSource { + + /** + * Creates a new Source for lexing the given String. + * + * @param ppvalid true if preprocessor directives are to be + * honoured within the string. + */ + public StringLexerSource(String string, boolean ppvalid) { + super(new StringReader(string), ppvalid); + } + + /** + * Creates a new Source for lexing the given String. + * + * By default, preprocessor directives are not honoured within + * the string. + */ + public StringLexerSource(String string) { + this(string, false); + } + + @Override + public String toString() { + return "string literal"; + } +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Token.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Token.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Token.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Token.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,193 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +/** + * A Preprocessor token. + * + * @see Preprocessor + */ +public final class Token { + + // public static final int EOF = -1; + private final int type; + private int line; + private int column; + private final Object value; + private final String text; + + public Token(int type, int line, int column, + String text, Object value) { + this.type = type; + this.line = line; + this.column = column; + this.text = text; + this.value = value; + } + + public Token(int type, int line, int column, String text) { + this(type, line, column, text, null); + } + + /* pp */ Token(int type, String text, Object value) { + this(type, -1, -1, text, value); + } + + /* pp */ Token(int type, String text) { + this(type, text, null); + } + + /* pp */ Token(int type) { + this(type, TokenType.getTokenText(type)); + } + + /** + * Returns the semantic type of this token. + */ + public int getType() { + return type; + } + + /* pp */ void setLocation(int line, int column) { + this.line = line; + this.column = column; + } + + /** + * Returns the line at which this token started. + * + * Lines are numbered from zero. + */ + public int getLine() { + return line; + } + + /** + * Returns the column at which this token started. + * + * Columns are numbered from zero. + */ + public int getColumn() { + return column; + } + + /** + * Returns the original or generated text of this token. + * + * This is distinct from the semantic value of the token. + * + * @see #getValue() + */ + public String getText() { + return text; + } + + /** + * Returns the semantic value of this token. + * + * For strings, this is the parsed String. + * For integers, this is an Integer object. + * For other token types, as appropriate. + * + * @see #getText() + */ + public Object getValue() { + return value; + } + + /** + * Returns a description of this token, for debugging purposes. + */ + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + + buf.append('[').append(getTokenName(type)); + if (line != -1) { + buf.append('@').append(line); + if (column != -1) + buf.append(',').append(column); + } + buf.append("]:"); + if (text != null) + buf.append('"').append(text).append('"'); + else if (type > 3 && type < 256) + buf.append((char) type); + else + buf.append('<').append(type).append('>'); + if (value != null) + buf.append('=').append(value); + return buf.toString(); + } + + /** + * Returns the descriptive name of the given token type. + * + * This is mostly used for stringification and debugging. + */ + public static String getTokenName(int type) { + return TokenType.getTokenName(type); + } + + public static final int AND_EQ = 257; + public static final int ARROW = 258; + public static final int CHARACTER = 259; + public static final int CCOMMENT = 260; + public static final int CPPCOMMENT = 261; + public static final int DEC = 262; + public static final int DIV_EQ = 263; + public static final int ELLIPSIS = 264; + public static final int EOF = 265; + public static final int EQ = 266; + public static final int GE = 267; + public static final int HASH = 268; + public static final int HEADER = 269; + public static final int IDENTIFIER = 270; + public static final int INC = 271; + public static final int NUMBER = 272; + public static final int LAND = 273; + public static final int LAND_EQ = 274; + public static final int LE = 275; + public static final int LITERAL = 276; + public static final int LOR = 277; + public static final int LOR_EQ = 278; + public static final int LSH = 279; + public static final int LSH_EQ = 280; + public static final int MOD_EQ = 281; + public static final int MULT_EQ = 282; + public static final int NE = 283; + public static final int NL = 284; + public static final int OR_EQ = 285; + public static final int PASTE = 286; + public static final int PLUS_EQ = 287; + public static final int RANGE = 288; + public static final int RSH = 289; + public static final int RSH_EQ = 290; + public static final int SQSTRING = 291; + public static final int STRING = 292; + public static final int SUB_EQ = 293; + public static final int WHITESPACE = 294; + public static final int XOR_EQ = 295; + public static final int M_ARG = 296; + public static final int M_PASTE = 297; + public static final int M_STRING = 298; + public static final int P_LINE = 299; + public static final int INVALID = 300; + + /** The position-less space token. */ + /* pp */ static final Token space = new Token(WHITESPACE, -1, -1, " "); +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/TokenSnifferSource.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/TokenSnifferSource.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/TokenSnifferSource.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/TokenSnifferSource.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.IOException; +import java.util.List; + +import static com.jogamp.gluegen.jcpp.Token.EOF; + +@Deprecated +/* pp */ class TokenSnifferSource extends Source { + + private final List target; + + /* pp */ TokenSnifferSource(List target) { + this.target = target; + } + + public Token token() + throws IOException, + LexerException { + Token tok = getParent().token(); + if (tok.getType() != EOF) + target.add(tok); + return tok; + } + + @Override + public String toString() { + return getParent().toString(); + } +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/TokenType.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/TokenType.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/TokenType.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/TokenType.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,130 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jogamp.gluegen.jcpp; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; + +import static com.jogamp.gluegen.jcpp.Token.*; + +/** + * + * @author shevek + */ +/* pp */ class TokenType { + + private static final List TYPES = new ArrayList(); + + private static void addTokenType(@Nonnegative int type, @Nonnull String name, @CheckForNull String text) { + while (TYPES.size() <= type) + TYPES.add(null); + TYPES.set(type, new TokenType(name, text)); + } + + private static void addTokenType(@Nonnegative int type, @Nonnull String name) { + addTokenType(type, name, null); + } + + @CheckForNull + public static TokenType getTokenType(@Nonnegative int type) { + try { + return TYPES.get(type); + } catch (IndexOutOfBoundsException e) { + return null; + } + } + + @Nonnull + public static String getTokenName(@Nonnegative int type) { + if (type < 0) + return "Invalid" + type; + TokenType tokenType = getTokenType(type); + if (tokenType == null) + return "Unknown" + type; + return tokenType.getName(); + } + + @CheckForNull + public static String getTokenText(@Nonnegative int type) { + TokenType tokenType = getTokenType(type); + if (tokenType == null) + return null; + return tokenType.getText(); + } + + static { + for (int i = 0; i < 255; i++) { + String text = String.valueOf((char) i); + addTokenType(i, text, text); + } + addTokenType(AND_EQ, "AND_EQ", "&="); + addTokenType(ARROW, "ARROW", "->"); + addTokenType(CHARACTER, "CHARACTER"); + addTokenType(CCOMMENT, "CCOMMENT"); + addTokenType(CPPCOMMENT, "CPPCOMMENT"); + addTokenType(DEC, "DEC", "--"); + addTokenType(DIV_EQ, "DIV_EQ", "/="); + addTokenType(ELLIPSIS, "ELLIPSIS", "..."); + addTokenType(EOF, "EOF"); + addTokenType(EQ, "EQ", "=="); + addTokenType(GE, "GE", ">="); + addTokenType(HASH, "HASH", "#"); + addTokenType(HEADER, "HEADER"); + addTokenType(IDENTIFIER, "IDENTIFIER"); + addTokenType(INC, "INC", "++"); + addTokenType(NUMBER, "NUMBER"); + addTokenType(LAND, "LAND", "&&"); + addTokenType(LAND_EQ, "LAND_EQ", "&&="); + addTokenType(LE, "LE", "<="); + addTokenType(LITERAL, "LITERAL"); + addTokenType(LOR, "LOR", "||"); + addTokenType(LOR_EQ, "LOR_EQ", "||="); + addTokenType(LSH, "LSH", "<<"); + addTokenType(LSH_EQ, "LSH_EQ", "<<="); + addTokenType(MOD_EQ, "MOD_EQ", "%="); + addTokenType(MULT_EQ, "MULT_EQ", "*="); + addTokenType(NE, "NE", "!="); + addTokenType(NL, "NL"); + addTokenType(OR_EQ, "OR_EQ", "|="); + addTokenType(PASTE, "PASTE", "##"); + addTokenType(PLUS_EQ, "PLUS_EQ", "+="); + addTokenType(RANGE, "RANGE", ".."); + addTokenType(RSH, "RSH", ">>"); + addTokenType(RSH_EQ, "RSH_EQ", ">>="); + addTokenType(SQSTRING, "SQSTRING"); + addTokenType(STRING, "STRING"); + addTokenType(SUB_EQ, "SUB_EQ", "-="); + addTokenType(WHITESPACE, "WHITESPACE"); + addTokenType(XOR_EQ, "XOR_EQ", "^="); + addTokenType(M_ARG, "M_ARG"); + addTokenType(M_PASTE, "M_PASTE"); + addTokenType(M_STRING, "M_STRING"); + addTokenType(P_LINE, "P_LINE"); + addTokenType(INVALID, "INVALID"); + } + + private final String name; + private final String text; + + /* pp */ TokenType(@Nonnull String name, @CheckForNull String text) { + this.name = name; + this.text = text; + } + + @Nonnull + public String getName() { + return name; + } + + @CheckForNull + public String getText() { + return text; + } +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/VirtualFile.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/VirtualFile.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/VirtualFile.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/VirtualFile.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,45 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import java.io.IOException; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +/** + * An extremely lightweight virtual file interface. + */ +public interface VirtualFile { + + // public String getParent(); + public boolean isFile(); + + @Nonnull + public String getPath(); + + @Nonnull + public String getName(); + + @CheckForNull + public VirtualFile getParentFile(); + + @Nonnull + public VirtualFile getChildFile(String name); + + @Nonnull + public Source getSource() throws IOException; +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/VirtualFileSystem.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/VirtualFileSystem.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/VirtualFileSystem.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/VirtualFileSystem.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,31 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +import javax.annotation.Nonnull; + +/** + * An extremely lightweight virtual file system interface. + */ +public interface VirtualFileSystem { + + @Nonnull + public VirtualFile getFile(@Nonnull String path); + + @Nonnull + public VirtualFile getFile(@Nonnull String dir, @Nonnull String name); +} diff -Nru gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Warning.java gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Warning.java --- gluegen2-2.2.4/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Warning.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/main/java/com/jogamp/gluegen/jcpp/Warning.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,32 @@ +/* + * Anarres C Preprocessor + * Copyright (c) 2007-2008, Shevek + * + * 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 com.jogamp.gluegen.jcpp; + +/** + * Warning classes which may optionally be emitted by the Preprocessor. + */ +public enum Warning { + + TRIGRAPHS, + // TRADITIONAL, + IMPORT, + UNDEF, + UNUSED_MACROS, + ENDIF_LABELS, + ERROR, + // SYSTEM_HEADERS +} diff -Nru gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/CppReaderTest.java gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/CppReaderTest.java --- gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/CppReaderTest.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/CppReaderTest.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,77 @@ +package com.jogamp.gluegen.jcpp; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.util.Collections; + +import javax.annotation.Nonnull; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import com.jogamp.gluegen.test.junit.generation.BuildEnvironment; +import com.jogamp.junit.util.SingletonJunitCase; + +import static org.junit.Assert.assertEquals; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class CppReaderTest extends SingletonJunitCase { + + public static String testCppReader(@Nonnull final String in, final Feature... f) throws Exception { + final String inclpath = BuildEnvironment.gluegenRoot + "/jcpp/src/test/resources" ; + + System.out.println("Testing " + in); + final StringReader r = new StringReader(in); + final CppReader p = new CppReader(r); + p.getPreprocessor().setSystemIncludePath( + Collections.singletonList(inclpath) + ); + p.getPreprocessor().addFeatures(f); + final BufferedReader b = new BufferedReader(p); + + final StringBuilder out = new StringBuilder(); + String line; + while ((line = b.readLine()) != null) { + System.out.println(" >> " + line); + out.append(line).append("\n"); + } + + return out.toString(); + } + + @Test + public void testCppReader() + throws Exception { + testCppReader("#include \n", Feature.LINEMARKERS); + } + + @Test + public void testVarargs() + throws Exception { + // The newlines are irrelevant, We want exactly one "foo" + testCppReader("#include \n"); + } + + @Test + public void testPragmaOnce() + throws Exception { + // The newlines are irrelevant, We want exactly one "foo" + final String out = testCppReader("#include \n", Feature.PRAGMA_ONCE); + assertEquals("foo", out.trim()); + } + + @Test + public void testPragmaOnceWithMarkers() + throws Exception { + // The newlines are irrelevant, We want exactly one "foo" + testCppReader("#include \n", Feature.PRAGMA_ONCE, Feature.LINEMARKERS); + } + + public static void main(final String args[]) throws IOException { + final String tstname = CppReaderTest.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } + +} diff -Nru gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/ErrorTest.java gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/ErrorTest.java --- gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/ErrorTest.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/ErrorTest.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,72 @@ +package com.jogamp.gluegen.jcpp; + +import java.io.IOException; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import com.jogamp.junit.util.SingletonJunitCase; + +import static com.jogamp.gluegen.jcpp.Token.*; +import static org.junit.Assert.*; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class ErrorTest extends SingletonJunitCase { + + private boolean testError(final Preprocessor p) + throws LexerException, + IOException { + for (;;) { + final Token tok = p.token(); + if (tok.getType() == EOF) + break; + if (tok.getType() == INVALID) + return true; + } + return false; + } + + private void testError(final String input) throws Exception { + StringLexerSource sl; + DefaultPreprocessorListener pl; + Preprocessor p; + + /* Without a PreprocessorListener, throws an exception. */ + sl = new StringLexerSource(input, true); + p = new Preprocessor(); + p.addFeature(Feature.CSYNTAX); + p.addInput(sl); + try { + assertTrue(testError(p)); + fail("Lexing unexpectedly succeeded without listener."); + } catch (final LexerException e) { + /* required */ + } + + /* With a PreprocessorListener, records the error. */ + sl = new StringLexerSource(input, true); + p = new Preprocessor(); + p.addFeature(Feature.CSYNTAX); + p.addInput(sl); + pl = new DefaultPreprocessorListener(); + p.setListener(pl); + assertNotNull("CPP has listener", p.getListener()); + assertTrue(testError(p)); + assertTrue("Listener has errors", pl.getErrors() > 0); + + /* Without CSYNTAX, works happily. */ + sl = new StringLexerSource(input, true); + p = new Preprocessor(); + p.addInput(sl); + assertTrue(testError(p)); + } + + @Test + public void testErrors() throws Exception { + testError("\""); + testError("'"); + // testError("''"); + } + +} diff -Nru gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/IncludeAbsoluteTest.java gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/IncludeAbsoluteTest.java --- gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/IncludeAbsoluteTest.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/IncludeAbsoluteTest.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,55 @@ +package com.jogamp.gluegen.jcpp; + +import java.io.File; +import java.io.IOException; +import java.io.Reader; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import com.jogamp.common.util.IOUtil; +import com.jogamp.gluegen.Logging; +import com.jogamp.gluegen.Logging.LoggerIf; +import com.jogamp.gluegen.test.junit.generation.BuildEnvironment; +import com.jogamp.junit.util.SingletonJunitCase; + +import static org.junit.Assert.*; + +/** + * + * @author shevek + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class IncludeAbsoluteTest extends SingletonJunitCase { + + private static final LoggerIf LOG = Logging.getLogger(IncludeAbsoluteTest.class); + + @Test + public void testAbsoluteInclude() throws Exception { + final String filepath = BuildEnvironment.gluegenRoot + "/jcpp/src/test/resources/absolute.h" ; + LOG.info("filepath: " + filepath); + + final File file = new File(filepath); + assertTrue(file.exists()); + final String slashifiedFilePath = IOUtil.slashify(file.getAbsolutePath(), true, false); + LOG.info("slashifiedFilePath: " + slashifiedFilePath); + + // Expects something like: + // WINDOWS: "/C:/projects/jogamp/gluegen/jcpp/src/test/resources/absolute.h" + // UNIX: "/projects/jogamp/gluegen/jcpp/src/test/resources/absolute.h" + final String input = "#include <" + slashifiedFilePath + ">\n"; + LOG.info("Input: " + input); + final Preprocessor pp = new Preprocessor(); + pp.addInput(new StringLexerSource(input, true)); + final Reader r = new CppReader(pp); + final String output = IOUtil.appendCharStream(new StringBuilder(), r).toString(); + r.close(); + LOG.info("Output: " + output); + assertTrue(output.contains("absolute-result")); + } + public static void main(final String args[]) throws IOException { + final String tstname = IncludeAbsoluteTest.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } +} diff -Nru gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/JavaFileSystemTest.java gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/JavaFileSystemTest.java --- gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/JavaFileSystemTest.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/JavaFileSystemTest.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,46 @@ +package com.jogamp.gluegen.jcpp; + +import java.io.FileNotFoundException; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import com.jogamp.junit.util.SingletonJunitCase; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class JavaFileSystemTest extends SingletonJunitCase { + + @Test + public void testJavaFileSystem() throws Exception { + final JavaFileSystem fs = new JavaFileSystem(); + VirtualFile f; + + /* Anyone who has this file on their Unix box is messed up. */ + f = fs.getFile("/foo/bar baz"); + try { + f.getSource(); /* drop on floor */ + + assertTrue("Got a source for a non-file", f.isFile()); + } catch (final FileNotFoundException e) { + assertFalse("Got no source for a file", f.isFile()); + } + + /* We hope we have this. */ + f = fs.getFile("/usr/include/stdio.h"); + try { + f.getSource(); /* drop on floor */ + + System.out.println("Opened stdio.h"); + assertTrue("Got a source for a non-file", f.isFile()); + } catch (final FileNotFoundException e) { + System.out.println("Failed to open stdio.h"); + assertFalse("Got no source for a file", f.isFile()); + } + + } + +} diff -Nru gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/JoinReaderTest.java gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/JoinReaderTest.java --- gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/JoinReaderTest.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/JoinReaderTest.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,48 @@ +package com.jogamp.gluegen.jcpp; + +import java.io.StringReader; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import com.jogamp.junit.util.SingletonJunitCase; + +import static org.junit.Assert.assertEquals; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class JoinReaderTest extends SingletonJunitCase { + + private void testJoinReader(final String in, final String out, final boolean tg) + throws Exception { + System.out.println("Testing " + in + " => " + out); + final StringReader r = new StringReader(in); + final JoinReader j = new JoinReader(r, tg); + + for (int i = 0; i < out.length(); i++) { + final int c = j.read(); + System.out.println("At offset " + i + ": " + (char) c); + assertEquals(out.charAt(i), c); + } + assertEquals(-1, j.read()); + assertEquals(-1, j.read()); + } + + private void testJoinReader(final String in, final String out) + throws Exception { + testJoinReader(in, out, true); + testJoinReader(in, out, false); + } + + @Test + public void testJoinReader() + throws Exception { + testJoinReader("ab", "ab"); + testJoinReader("a\\b", "a\\b"); + testJoinReader("a\nb", "a\nb"); + testJoinReader("a\\\nb", "ab\n"); + testJoinReader("foo??(bar", "foo[bar", true); + testJoinReader("foo??/\nbar", "foobar\n", true); + } + +} diff -Nru gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/LexerSourceTest.java gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/LexerSourceTest.java --- gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/LexerSourceTest.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/LexerSourceTest.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,147 @@ +package com.jogamp.gluegen.jcpp; + +import java.util.Arrays; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import com.jogamp.gluegen.Logging; +import com.jogamp.gluegen.Logging.LoggerIf; +import com.jogamp.junit.util.SingletonJunitCase; + +import static com.jogamp.gluegen.jcpp.PreprocessorTest.assertType; +import static com.jogamp.gluegen.jcpp.Token.*; +import static org.junit.Assert.*; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class LexerSourceTest extends SingletonJunitCase { + + private static final LoggerIf LOG = Logging.getLogger(LexerSourceTest.class); + + public static void testLexerSource(final String in, final boolean textmatch, final int... out) + throws Exception { + LOG.info("Testing '" + in + "' => " + + Arrays.toString(out)); + final StringLexerSource s = new StringLexerSource(in); + + final StringBuilder buf = new StringBuilder(); + for (int i = 0; i < out.length; i++) { + final Token tok = s.token(); + LOG.info("Token is " + tok); + assertType(out[i], tok); + // assertEquals(col, tok.getColumn()); + buf.append(tok.getText()); + } + + final Token tok = s.token(); + LOG.info("Token is " + tok); + assertType(EOF, tok); + + if (textmatch) + assertEquals(in, buf.toString()); + } + + @Test + public void testLexerSource() + throws Exception { + + testLexerSource("int a = 5;", true, + IDENTIFIER, WHITESPACE, IDENTIFIER, WHITESPACE, + '=', WHITESPACE, NUMBER, ';' + ); + + // \n is WHITESPACE because ppvalid = false + testLexerSource("# # \r\n\n\r \rfoo", true, + HASH, WHITESPACE, '#', WHITESPACE, IDENTIFIER + ); + + // No match - trigraphs + testLexerSource("%:%:", false, PASTE); + testLexerSource("%:?", false, '#', '?'); + testLexerSource("%:%=", false, '#', MOD_EQ); + + testLexerSource("0x1234ffdUL 0765I", true, + NUMBER, WHITESPACE, NUMBER); + + testLexerSource("+= -= *= /= %= <= >= >>= <<= &= |= ^= x", true, + PLUS_EQ, WHITESPACE, + SUB_EQ, WHITESPACE, + MULT_EQ, WHITESPACE, + DIV_EQ, WHITESPACE, + MOD_EQ, WHITESPACE, + LE, WHITESPACE, + GE, WHITESPACE, + RSH_EQ, WHITESPACE, + LSH_EQ, WHITESPACE, + AND_EQ, WHITESPACE, + OR_EQ, WHITESPACE, + XOR_EQ, WHITESPACE, + IDENTIFIER); + + testLexerSource("/**/", true, CCOMMENT); + testLexerSource("/* /**/ */", true, CCOMMENT, WHITESPACE, '*', '/'); + testLexerSource("/** ** **/", true, CCOMMENT); + testLexerSource("//* ** **/", true, CPPCOMMENT); + testLexerSource("'\\r' '\\xf' '\\xff' 'x' 'aa' ''", true, + CHARACTER, WHITESPACE, + CHARACTER, WHITESPACE, + CHARACTER, WHITESPACE, + CHARACTER, WHITESPACE, + SQSTRING, WHITESPACE, + SQSTRING); + + if (false) // Actually, I think this is illegal. + testLexerSource("1i1I1l1L1ui1ul", true, + NUMBER, NUMBER, + NUMBER, NUMBER, + NUMBER, NUMBER); + + testLexerSource("'' 'x' 'xx'", true, + SQSTRING, WHITESPACE, CHARACTER, WHITESPACE, SQSTRING); + } + + @Test + public void testNumbers() throws Exception { + testLexerSource("0", true, NUMBER); + testLexerSource("045", true, NUMBER); + testLexerSource("45", true, NUMBER); + testLexerSource("0.45", true, NUMBER); + testLexerSource("1.45", true, NUMBER); + testLexerSource("1e6", true, NUMBER); + testLexerSource("1.45e6", true, NUMBER); + testLexerSource(".45e6", true, NUMBER); + testLexerSource("-6", true, '-', NUMBER); + } + + @Test + public void testNumbersSuffix() throws Exception { + testLexerSource("6f", true, NUMBER); + testLexerSource("6d", true, NUMBER); + testLexerSource("6l", true, NUMBER); + testLexerSource("6ll", true, NUMBER); + testLexerSource("6ul", true, NUMBER); + testLexerSource("6ull", true, NUMBER); + testLexerSource("6e3f", true, NUMBER); + testLexerSource("6e3d", true, NUMBER); + testLexerSource("6e3l", true, NUMBER); + testLexerSource("6e3ll", true, NUMBER); + testLexerSource("6e3ul", true, NUMBER); + testLexerSource("6e3ull", true, NUMBER); + } + + @Test + public void testNumbersInvalid() throws Exception { + // testLexerSource("0x foo", true, INVALID, WHITESPACE, IDENTIFIER); // FAIL + testLexerSource("6x foo", true, INVALID, WHITESPACE, IDENTIFIER); + testLexerSource("6g foo", true, INVALID, WHITESPACE, IDENTIFIER); + testLexerSource("6xsd foo", true, INVALID, WHITESPACE, IDENTIFIER); + testLexerSource("6gsd foo", true, INVALID, WHITESPACE, IDENTIFIER); + } + + @Test + public void testUnterminatedComment() throws Exception { + testLexerSource("5 /*", false, NUMBER, WHITESPACE, INVALID); // Bug #15 + testLexerSource("5 //", false, NUMBER, WHITESPACE, CPPCOMMENT); + } +} diff -Nru gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/NumericValueTest.java gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/NumericValueTest.java --- gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/NumericValueTest.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/NumericValueTest.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,102 @@ +package com.jogamp.gluegen.jcpp; + +import java.io.IOException; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import com.jogamp.junit.util.SingletonJunitCase; + +import static com.jogamp.gluegen.jcpp.Token.*; +import static org.junit.Assert.*; + +/** + * + * @author shevek + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class NumericValueTest extends SingletonJunitCase { + + private Token testNumericValue(final String in) throws IOException, LexerException { + final StringLexerSource s = new StringLexerSource(in); + + final Token tok = s.token(); + System.out.println("Token is " + tok); + assertEquals(NUMBER, tok.getType()); + + final Token eof = s.token(); + assertEquals("Didn't get EOF, but " + tok, EOF, eof.getType()); + + return tok; + } + + private void testNumericValue(final String in, final double out) throws IOException, LexerException { + System.out.println("Testing '" + in + "' -> " + out); + final Token tok = testNumericValue(in); + assertEquals(in, tok.getText()); + final NumericValue value = (NumericValue) tok.getValue(); + assertEquals("Double mismatch", out, value.doubleValue(), 0.01d); + assertEquals("Float mismatch", (float) out, value.floatValue(), 0.01f); + assertEquals("Long mismatch", (long) out, value.longValue()); + assertEquals("Integer mismatch", (int) out, value.intValue()); + } + + @Test + public void testNumericValue() throws Exception { + + // Zero + testNumericValue("0", 0); + + // Decimal + testNumericValue("1", 1); + testNumericValue("1L", 1); + testNumericValue("12", 12); + testNumericValue("12L", 12); + + // Hex + testNumericValue("0xf", 0xf); + testNumericValue("0xfL", 0xf); + testNumericValue("0x12", 0x12); + testNumericValue("0x12L", 0x12); + + // Negative + // testNumericValue("-0", 0); + // testNumericValue("-1", -1); + // Negative hex + // testNumericValue("-0x56", -0x56); + // testNumericValue("-0x102", -0x102); + // Octal and negative octal + testNumericValue("0673", Integer.parseInt("673", 8)); + // testNumericValue("-0673", Integer.parseInt("-673", 8)); + + // Floating point + testNumericValue(".0", 0); + testNumericValue(".00", 0); + testNumericValue("0.", 0); + testNumericValue("0.0", 0); + testNumericValue("00.0", 0); + testNumericValue("00.", 0); + + // Sign on exponents + testNumericValue("1e1", 1e1); + // testNumericValue("-1e1", -1e1); + testNumericValue("1e-1", 1e-1); + + // Hex numbers with decimal exponents + testNumericValue("0x12e3", 0x12e3); + testNumericValue("0x12p3", 0x12p3); + + // Octal numbers with decimal exponents + testNumericValue("012e3", 012e3); // Fails + testNumericValue("067e4", 067e4); // Fails + + // Issues a warning. + try { + testNumericValue("097", 97); + fail("No warning."); + } catch (final LexerException e) { + } + + } +} diff -Nru gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/PreprocessorTest.java gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/PreprocessorTest.java --- gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/PreprocessorTest.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/PreprocessorTest.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,376 @@ +package com.jogamp.gluegen.jcpp; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.util.List; +import java.util.logging.Level; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import com.jogamp.gluegen.Logging; +import com.jogamp.gluegen.Logging.LoggerIf; +import com.jogamp.junit.util.SingletonJunitCase; + +import static com.jogamp.gluegen.jcpp.Token.*; +import static org.junit.Assert.*; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class PreprocessorTest extends SingletonJunitCase { + + private static final LoggerIf LOG = Logging.getLogger(PreprocessorTest.class); + + private OutputStreamWriter writer; + private Preprocessor p; + + @Before + public void setUp() throws Exception { + LOG.setLevel(Level.INFO); + final PipedOutputStream po = new PipedOutputStream(); + writer = new OutputStreamWriter(po); + + p = new Preprocessor(); + // p.addFeature(Feature.DEBUG); + p.addInput( + new LexerSource( + new InputStreamReader( + new PipedInputStream(po) + ), + true + ) + ); + } + + private static class I { + private final String t; + + public I(final String t) { + this.t = t; + } + + public String getText() { + return t; + } + + @Override + public String toString() { + return getText(); + } + } + private static I I(final String t) { + return new I(t); + } + private static class N { + private final String t; + + public N(final String t) { + this.t = t; + } + + public String getText() { + return t; + } + + @Override + public String toString() { + return getText(); + } + } + private static N N(final String t) { + return new N(t); + } + + /* + * When writing tests in this file, remember the preprocessor + * stashes NLs, so you won't see an immediate NL at the end of any + * input line. You will see it right before the next nonblank on + * the following input line. + */ + @Test + public void test01Preprocessor() throws Exception { + /* Magic macros */ + testInput("line = __LINE__\n", + I("line"), WHITESPACE, '=', WHITESPACE, NUMBER + /*, NL - all nls deferred so as not to block the reader */ + ); + testInput("file = __FILE__\n", NL, /* from before, etc */ + I("file"), WHITESPACE, '=', WHITESPACE, STRING + ); + + /* Simple definitions */ + testInput("#define A a /* a defined */\n", NL); + testInput("A /* a */\n", NL, I("a"), WHITESPACE, CCOMMENT); + testConstMacro("A", true, I("a")); + testInput("#define B b /* b defined */\n", NL); + testInput("B /* b */\n", NL, I("b"), WHITESPACE, CCOMMENT); + testConstMacro("B", false, I("b")); + testInput("#define C c /* c defined */\n", NL); + + /* Expansion of arguments */ + testInput("#define EXPAND(x) x\n", NL); + testInput("EXPAND(a)\n", NL, I("a")); + testInput("EXPAND(A)\n", NL, I("a")); + + /* Stringification */ + testInput("#define _STRINGIFY(x) #x\n", NL); + testInput("_STRINGIFY(A)\n", NL, "A"); + testInput("#define STRINGIFY(x) _STRINGIFY(x)\n", NL); + testInput("STRINGIFY(b)\n", NL, "b"); + testInput("STRINGIFY(A)\n", NL, "a"); + + /* Concatenation */ + testInput("#define _CONCAT(x, y) x ## y\n", NL); + testInput("_CONCAT(A, B)\n", NL, I("AB")); + testInput("#define A_CONCAT done_a_concat\n", NL); + testInput("_CONCAT(A, _CONCAT(B, C))\n", NL, + I("done_a_concat"), '(', I("b"), ',', WHITESPACE, I("c"), ')' + ); + testInput("#define CONCAT(x, y) _CONCAT(x, y)\n", NL); + testInput("CONCAT(A, CONCAT(B, C))\n", NL, I("abc")); + testInput("#define _CONCAT3(x, y, z) x ## y ## z\n", NL); + testInput("_CONCAT3(a, b, c)\n", NL, I("abc")); + testInput("_CONCAT3(A, B, C)\n", NL, I("ABC")); + testInput("_CONCAT(test_, inline)\n", NL, I("test_inline")); + testInput("_CONCAT(test_, \nnewline)\n", NL, I("test_newline")); + + /* Redefinitions, undefinitions. */ + testInput("#define two three\n", NL); + testInput("two /* three */\n", NL, I("three"), WHITESPACE, CCOMMENT); + testInput("one /* one */\n", NL, I("one"), WHITESPACE, CCOMMENT); + testConstMacro("two", false, I("three")); + testConstMacro("two", true, I("three")); + + testInput("#define one two\n", NL); + testInput("one /* three */\n", NL, I("three"), WHITESPACE, CCOMMENT); + testConstMacro("one", false, I("two")); + testConstMacro("one", true, I("three")); + + testInput("#undef two\n", NL); + testInput("one /* two */\n", NL, I("two"), WHITESPACE, CCOMMENT); + testConstMacro("one", false, I("two")); + testConstMacro("one", true, I("two")); + + testInput("#define two five\n", NL); + testInput("one /* five */\n", NL, I("five"), WHITESPACE, CCOMMENT); + testConstMacro("one", false, I("two")); + testConstMacro("one", true, I("five")); + + testInput("#undef two\n", NL); + testInput("one /* two */\n", NL, I("two"), WHITESPACE, CCOMMENT); + testConstMacro("one", false, I("two")); + testConstMacro("one", true, I("two")); + + testInput("#undef one\n", NL); + testInput("#define one four\n", NL); + testInput("one /* four */\n", NL, I("four"), WHITESPACE, CCOMMENT); + testConstMacro("one", false, I("four")); + testConstMacro("one", true, I("four")); + + testInput("#undef one\n", NL); + testInput("#define one one\n", NL); + testInput("one /* one */\n", NL, I("one"), WHITESPACE, CCOMMENT); + testConstMacro("one", false, I("one")); + testConstMacro("one", true, I("one")); + + testInput("#define NUM1 1\n", NL); + testInput("#define NUM4 ( 1 << ( NUM1 + NUM1 ) )\n", NL); + testInput("NUM4 /* ( 1 << ( 1 + 1 ) ) */\n", NL, + '(', WHITESPACE, N("1"), WHITESPACE, LSH, WHITESPACE, + '(', WHITESPACE, N("1"), WHITESPACE, '+', WHITESPACE, N("1"), WHITESPACE, ')', WHITESPACE, ')', + WHITESPACE, CCOMMENT); + testConstMacro("NUM4", false, '(', WHITESPACE, N("1"), WHITESPACE, LSH, WHITESPACE, + '(', WHITESPACE, I("NUM1"), WHITESPACE, '+', WHITESPACE, I("NUM1"), WHITESPACE, ')', + WHITESPACE, ')'); + testConstMacro("NUM4", true, '(', WHITESPACE, N("1"), WHITESPACE, LSH, WHITESPACE, + '(', WHITESPACE, N("1"), WHITESPACE, '+', WHITESPACE, N("1"), WHITESPACE, ')', WHITESPACE, ')'); + + /* Variadic macros. */ + testInput("#define var(x...) a x __VA_ARGS__ b\n", NL); + testInput("var(e, f, g)\n", NL, + I("a"), WHITESPACE, + I("e"), ',', WHITESPACE, + I("f"), ',', WHITESPACE, + I("g"), WHITESPACE, + I("__VA_ARGS__"), WHITESPACE, // __VA_ARGS__ is not expanded in this case. + I("b") + ); + /* Missing arguments are fine. */ + testInput("var()\n", NL, + I("a"), WHITESPACE, + /* No expansion for 'x'. */ WHITESPACE, + I("__VA_ARGS__"), WHITESPACE, + I("b") + ); + + /* Variadic macros with anonymous args. */ + testInput("#define var2(x, ...) a x __VA_ARGS__ e\n", NL); + testInput("var2(b, c, d)\n", NL, + I("a"), WHITESPACE, + I("b"), WHITESPACE, + I("c"), ',', WHITESPACE, + I("d"), WHITESPACE, + I("e") + ); + /* Missing arguments are fine. */ + testInput("var2(b)\n", NL, + I("a"), WHITESPACE, + I("b"), WHITESPACE, + /* No expansion for '__VA_ARGS__'. */ WHITESPACE, + I("e") + ); + + testInput("#define var3(...) a __VA_ARGS__ d\n", NL); + testInput("var3(b, c)\n", NL, + I("a"), WHITESPACE, + I("b"), ',', WHITESPACE, + I("c"), WHITESPACE, + I("d") + ); + testInput("var3()\n", NL, + I("a"), WHITESPACE, + /* No expansion for '__VA_ARGS__'. */ WHITESPACE, + I("d") + ); + + testInput("#define _Widen(x) L ## x\n", NL); + testInput("#define Widen(x) _Widen(x)\n", NL); + testInput("#define LStr(x) _Widen(#x)\n", NL); + testInput("LStr(x);\n", NL, I("L"), "x", ';'); + + testInput("'foo'\n", NL, SQSTRING); + testInput("#if 1 ? 2 : 0\nTEXT\n#endif\n", NL, NL, I("TEXT"), NL); + testInput("#if 1 ? 0 : 2\nTEXT\n#endif\n", NL, NL, NL); + testInput("#if 0 ? 0 : 2\nTEXT\n#endif\n", NL, NL, I("TEXT"), NL); + testInput("#if 0 ? 2 : 0\nTEXT\n#endif\n", NL, NL, NL); + + writer.close(); + + Token t; + do { + t = p.token(); + LOG.warning("Remaining token " + t); + } while (t.getType() != EOF); + } + + @Test + public void test02PreprocessorUnterminated() throws Exception { + testInput("#ifndef X\na\n#else\nb\n"); // Bug #16 + + writer.close(); + + Token t; + do { + t = p.token(); + LOG.warning("Remaining token " + t); + } while (t.getType() != EOF); + } + + public static void assertType(final int type, final Token t) { + final String typeExpect = TokenType.getTokenName(type); + final String typeActual = TokenType.getTokenName(t.getType()); + assertEquals("Expected " + typeExpect + " but got " + typeActual, type, t.getType()); + } + + private void testInput(final String in, final Object... out) + throws Exception { + LOG.info("Input: " + in); + writer.write(in); + writer.flush(); + for (final Object v : out) { + final Token t = p.token(); + LOG.info("READ: "+String.valueOf(t)); + if (v instanceof String) { + if (t.getType() != STRING) + fail("Expected STRING, but got " + t); + assertEquals(v, t.getValue()); + } else if (v instanceof I) { + if (t.getType() != IDENTIFIER) { + fail("Expected IDENTIFIER " + v + ", but got " + t); + } + assertEquals(((I) v).getText(), t.getText()); + } else if (v instanceof N) { + if (t.getType() != NUMBER) { + fail("Expected NUMBER " + v + ", but got " + t); + } + assertEquals(((N) v).getText(), t.getText()); + } else if (v instanceof Character) { + assertType(((Character) v).charValue(), t); + } else if (v instanceof Integer) { + assertType(((Number) v).intValue(), t); + } else { + fail("Bad object " + v.getClass()); + } + } + } + // slow .. + private Macro findMacro(final List macros, final String macroName) { + final int count = macros.size(); + for(int i=0; i macros) { + final int count = macros.size(); + System.err.println("Macro count: "+count); + for(int i=0; i macros = p.getMacros(expandMacro); + final Macro m = findMacro(macros, macroName); + if( null == m ) { + dumpMacros(macros); + } + Assert.assertNotNull("Macro <"+macroName+"> is missing!", m); + Assert.assertFalse(m.isFunctionLike()); + + final Source s = new MacroTokenSource(m, null); + try { + for (final Object v : out) { + final Token t = s.token(); + LOG.info("READ: "+String.valueOf(t)); + if (v instanceof String) { + if (t.getType() != STRING) { + fail("Expected STRING, but got " + t); + } + assertEquals(v, t.getValue()); + } else if (v instanceof I) { + if (t.getType() != IDENTIFIER) { + fail("Expected IDENTIFIER " + v + ", but got " + t); + } + assertEquals(((I) v).getText(), t.getText()); + } else if (v instanceof N) { + if (t.getType() != NUMBER) { + fail("Expected NUMBER " + v + ", but got " + t); + } + assertEquals(((N) v).getText(), t.getText()); + } else if (v instanceof Character) { + assertType(((Character) v).charValue(), t); + } else if (v instanceof Integer) { + assertType(((Number) v).intValue(), t); + } else { + fail("Bad object " + v.getClass()); + } + } + } finally { + s.close(); + } + } + public static void main(final String args[]) throws IOException { + final String tstname = PreprocessorTest.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } +} diff -Nru gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/TokenPastingWhitespaceTest.java gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/TokenPastingWhitespaceTest.java --- gluegen2-2.2.4/jcpp/src/test/java/com/jogamp/gluegen/jcpp/TokenPastingWhitespaceTest.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/java/com/jogamp/gluegen/jcpp/TokenPastingWhitespaceTest.java 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,59 @@ +package com.jogamp.gluegen.jcpp; + +import com.jogamp.common.util.IOUtil; + +import java.io.IOException; +import java.io.Reader; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import com.jogamp.gluegen.Logging; +import com.jogamp.gluegen.Logging.LoggerIf; +import com.jogamp.junit.util.SingletonJunitCase; + +import static org.junit.Assert.*; + +/** + * https://github.com/shevek/jcpp/issues/25 + * + * @author shevek + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TokenPastingWhitespaceTest extends SingletonJunitCase { + + private static final LoggerIf LOG = Logging.getLogger(TokenPastingWhitespaceTest.class); + + @Test + public void test01WhitespacePasting() throws IOException { + final Preprocessor pp = new Preprocessor(); + testWhitespacePastingImpl(pp); + } + void testWhitespacePastingImpl(final Preprocessor pp) throws IOException { + pp.addInput(new StringLexerSource( + "#define ONE(arg) one_##arg\n" + + "#define TWO(arg) ONE(two_##arg)\n" + + "\n" + + "TWO(good)\n" + + "TWO( /* evil newline */\n" + + " bad)\n" + + "\n" + + "ONE(good)\n" + + "ONE( /* evil newline */\n" + + " bad)\n", true)); + final Reader r = new CppReader(pp); + final String text = IOUtil.appendCharStream(new StringBuilder(), r).toString().trim(); + LOG.info("Output is:\n" + text); + assertEquals("one_two_good\n" + + "one_two_bad\n" + + "\n" + + "one_good\n" + + "one_bad", text); + } + + public static void main(final String args[]) throws IOException { + final String tstname = TokenPastingWhitespaceTest.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } +} diff -Nru gluegen2-2.2.4/jcpp/src/test/resources/absolute.h gluegen2-2.3.2/jcpp/src/test/resources/absolute.h --- gluegen2-2.2.4/jcpp/src/test/resources/absolute.h 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/resources/absolute.h 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1 @@ +absolute-result diff -Nru gluegen2-2.2.4/jcpp/src/test/resources/once.c gluegen2-2.3.2/jcpp/src/test/resources/once.c --- gluegen2-2.2.4/jcpp/src/test/resources/once.c 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/resources/once.c 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,2 @@ +#include "once.h" +#include "once.h" diff -Nru gluegen2-2.2.4/jcpp/src/test/resources/once.h gluegen2-2.3.2/jcpp/src/test/resources/once.h --- gluegen2-2.2.4/jcpp/src/test/resources/once.h 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/resources/once.h 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,2 @@ +#pragma once +foo diff -Nru gluegen2-2.2.4/jcpp/src/test/resources/test0.c gluegen2-2.3.2/jcpp/src/test/resources/test0.c --- gluegen2-2.2.4/jcpp/src/test/resources/test0.c 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/resources/test0.c 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,61 @@ +line = __LINE__ +file = __FILE__ + +#define A a /* a defined */ +#define B b /* b defined */ +#define C c /* c defined */ + +#define EXPAND(x) x +EXPAND(a) -> a +EXPAND(A) -> a + +#define _STRINGIFY(x) #x +_STRINGIFY(A) -> "A" + +#define STRINGIFY(x) _STRINGIFY(x) +STRINGIFY(b) -> "b" +STRINGIFY(A) -> "a" + +#define _CONCAT(x, y) x ## y +_CONCAT(A, B) -> AB + +#define A_CONCAT done_a_concat +_CONCAT(A, _CONCAT(B, C)) -> done_a_concat(b, c) + +#define CONCAT(x, y) _CONCAT(x, y) +CONCAT(A, CONCAT(B, C)) -> abc + +#define _CONCAT3(x, y, z) x ## y ## z +_CONCAT3(a, b, c) -> abc +_CONCAT3(A, B, C) -> ABC +_CONCAT3(A, EXPAND(B), C) -> AEXPAND(b)C + +Line is __LINE__ +File is __FILE__ + +#define two three +one /* one */ +#define one two +one /* three */ +#undef two +#define two five +one /* five */ +#undef two +one /* two */ +#undef one +#define one four +one /* four */ +#undef one +#define one one +one /* one */ + +/* warning line 57 column 0 */ +#warning arse + +#define foo(x) foo(x, b) +foo(1) -> _foo(1, b) without the _ +foo(foo(2)) -> _foo(_foo(2, b), b) without the _ +// foo(y, z) + +#define var(x...) a x b +var(e, f, g) -> a e, f, g b diff -Nru gluegen2-2.2.4/jcpp/src/test/resources/test0.h gluegen2-2.3.2/jcpp/src/test/resources/test0.h --- gluegen2-2.2.4/jcpp/src/test/resources/test0.h 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/resources/test0.h 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,7 @@ + +test0start_2 + +#include "test1.h" + +test0end___6 + diff -Nru gluegen2-2.2.4/jcpp/src/test/resources/test1.c gluegen2-2.3.2/jcpp/src/test/resources/test1.c --- gluegen2-2.2.4/jcpp/src/test/resources/test1.c 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/resources/test1.c 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,2 @@ +#include "./test0.h" +#include diff -Nru gluegen2-2.2.4/jcpp/src/test/resources/test1.h gluegen2-2.3.2/jcpp/src/test/resources/test1.h --- gluegen2-2.2.4/jcpp/src/test/resources/test1.h 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/resources/test1.h 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,7 @@ + +test1start_2 + +test1mid___4 + +test1end___6 + diff -Nru gluegen2-2.2.4/jcpp/src/test/resources/trigraph.c gluegen2-2.3.2/jcpp/src/test/resources/trigraph.c --- gluegen2-2.2.4/jcpp/src/test/resources/trigraph.c 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/resources/trigraph.c 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1 @@ +??/ diff -Nru gluegen2-2.2.4/jcpp/src/test/resources/varargs.c gluegen2-2.3.2/jcpp/src/test/resources/varargs.c --- gluegen2-2.2.4/jcpp/src/test/resources/varargs.c 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/jcpp/src/test/resources/varargs.c 2015-04-01 13:52:14.000000000 +0000 @@ -0,0 +1,8 @@ +#define var(x...) a x __VA_ARGS__ b +var(b, c, d) + +#define var2(x, ...) a x __VA_ARGS__ b +var2(b, c, d) + +#define var3(...) a x __VA_ARGS__ b +var3(b, c, d) diff -Nru gluegen2-2.2.4/LICENSE.txt gluegen2-2.3.2/LICENSE.txt --- gluegen2-2.2.4/LICENSE.txt 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/LICENSE.txt 2015-10-09 04:18:28.000000000 +0000 @@ -1,7 +1,13 @@ - The GlueGen source code is mostly licensed under the New BSD 2-clause license, however it contains other licensed material as well. +Other licensed material is compatible with the 'New BSD 2-Clause License', +if not stated otherwise. + +'New BSD 2-Clause License' incompatible materials are optional, they are: + + NONE + Below you find a detailed list of licenses used in this project. +++ @@ -131,3 +137,46 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +A.1) The GlueGen source tree contains code from The Apache Software Foundation + which is covered by the Apache License Version 2.0 + + Apache Harmony - Open Source Java SE + ===================================== + + + + Author: The Apache Software Foundation (http://www.apache.org/). + + Copyright 2006, 2010 The Apache Software Foundation. + + Apache License Version 2.0, January 2004 + http://www.apache.org/licenses/LICENSE-2.0 + Or within this repository: doc/licenses/Apache.LICENSE-2.0 + + Files: + - src/java/com/jogamp/common/net/Uri.java + (derived from java.net.URI.Helper and heavily modified) + +A.2) The GlueGen source tree contains code from Ben Mankin, a.k.a 'Shevek', + which is covered by the Apache License Version 2.0 + + JCPP - A Java C Preprocessor + ============================= + + + + + Author: Ben Mankin, a.k.a 'Shevek' (http://www.anarres.org/about/). + + Copyright (c) 2007-2008, Shevek + + Apache License Version 2.0, January 2004 + http://www.apache.org/licenses/LICENSE-2.0 + Or within this repository: doc/licenses/Apache.LICENSE-2.0 + + Files: + The complete git submodule 'jcpp', + which is a patched version of the original mentioned above. + + Used for the compile-time module gluegen.jar only. + diff -Nru gluegen2-2.2.4/make/build-test.xml gluegen2-2.3.2/make/build-test.xml --- gluegen2-2.2.4/make/build-test.xml 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/build-test.xml 2015-10-09 04:18:28.000000000 +0000 @@ -36,6 +36,9 @@ + + + @@ -50,6 +53,7 @@ + @@ -148,7 +152,7 @@ debug="${javacdebug}" debuglevel="${javacdebuglevel}"> - + @@ -167,6 +171,7 @@ + @@ -264,9 +269,10 @@ - - - + + + + @@ -516,6 +522,12 @@
    + + + + + +
    @@ -59,6 +60,8 @@ + + @@ -138,8 +141,10 @@ + +
    @@ -245,7 +250,6 @@ - @@ -322,7 +326,6 @@ - @@ -349,7 +352,6 @@ - @@ -375,7 +377,6 @@ - @@ -383,7 +384,6 @@ - @@ -426,7 +426,7 @@ - + @@ -602,6 +602,7 @@ + @@ -609,6 +610,7 @@ + @@ -718,6 +720,13 @@ + + + + + + @@ -629,6 +659,10 @@ + + + + @@ -669,7 +703,11 @@ - + + + + + @@ -884,7 +922,6 @@ - @@ -892,15 +929,11 @@ value="${java.home}/.."> - - - - + @@ -950,6 +983,8 @@ + + @@ -977,6 +1012,22 @@ + + + + + + + + + + + + + + + + @@ -1055,6 +1106,8 @@ + + @@ -1165,16 +1218,19 @@ + + + @@ -1257,6 +1325,7 @@ + @@ -1266,6 +1335,7 @@ + @@ -1273,6 +1343,7 @@ + @@ -1281,6 +1352,7 @@ + @@ -1289,6 +1361,7 @@ + @@ -1390,6 +1463,13 @@ + + + + + + + @@ -1446,8 +1526,8 @@ - - + + @@ -1469,7 +1549,7 @@ - + @@ -1477,25 +1557,13 @@ - - - - - + - - - @@ -1513,19 +1581,22 @@ - + - + - + + + + @@ -1584,7 +1655,9 @@ - + + + diff -Nru gluegen2-2.2.4/make/jogamp-androidtasks.xml gluegen2-2.3.2/make/jogamp-androidtasks.xml --- gluegen2-2.2.4/make/jogamp-androidtasks.xml 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/jogamp-androidtasks.xml 2015-10-09 04:18:28.000000000 +0000 @@ -7,6 +7,22 @@ + + + + + + + + + val: ${jarbasename} + ___: ${m.aapt.apkbasename0} + res: ${m.aapt.apkbasename1} + + + + + + + + - + - - - + + + @@ -105,7 +140,7 @@ - aapt.signed @{jarbasename}: generating Android R.java from the resources... + aapt.signed ${m.aapt.apkbasename}: generating Android R.java from the resources... @@ -121,7 +156,7 @@ - aapt.signed @{jarbasename}: compiling R.java... + aapt.signed ${m.aapt.apkbasename}: compiling R.java... - aapt.signed @{jarbasename}: dex'ing + aapt.signed ${m.aapt.apkbasename}: dex'ing @@ -153,7 +188,7 @@ - aapt.signed @{jarbasename}: packaging + aapt.signed ${m.aapt.apkbasename}: packaging @@ -182,7 +217,7 @@ - aapt.signed @{jarbasename}: gen temp keystore @{keystore.alias} @ ${m.aapt.build.apk}/debug.keystore + aapt.signed ${m.aapt.apkbasename}: gen temp keystore @{keystore.alias} @ ${m.aapt.build.apk}/debug.keystore @@ -211,7 +246,7 @@ - aapt.signed @{jarbasename}: signing w/ key @{keystore.alias} @ ${m.aapt.keystore.file} + aapt.signed ${m.aapt.apkbasename}: signing w/ key @{keystore.alias} @ ${m.aapt.keystore.file} @@ -225,6 +236,9 @@ + + + @@ -236,6 +250,9 @@ + + + diff -Nru gluegen2-2.2.4/make/jogamp-fat.mf gluegen2-2.3.2/make/jogamp-fat.mf --- gluegen2-2.2.4/make/jogamp-fat.mf 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/make/jogamp-fat.mf 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,26 @@ +Manifest-Version: 1.0 +Application-Name: JogAmp Java Bindings +Specification-Title: JogAmp Java Bindings Specification +Specification-Version: @BASEVERSION@ +Specification-Vendor: JogAmp Community +Implementation-Title: JogAmp Java Bindings Fat Jar +Implementation-Version: @VERSION@ +Implementation-Build: @BUILD_VERSION@ +Implementation-Branch: @SCM_BRANCH@ +Implementation-Commit: @SCM_COMMIT@ +Implementation-Vendor: JogAmp Community +Implementation-URL: http://jogamp.org/ +Extension-Name: com.jogamp +Implementation-Vendor-Id: com.jogamp +Main-Class: jogamp.opengl.awt.VersionApplet +Trusted-Library: true +Permissions: all-permissions +Application-Library-Allowable-Codebase: * +@JAR_CODEBASE_TAG@ + +Name: jogamp/common/ +Sealed: true + +Name: com/jogamp/common/ +Sealed: true + diff -Nru gluegen2-2.2.4/make/jogamp-fat-test.mf gluegen2-2.3.2/make/jogamp-fat-test.mf --- gluegen2-2.2.4/make/jogamp-fat-test.mf 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/make/jogamp-fat-test.mf 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,20 @@ +Manifest-Version: 1.0 +Application-Name: JogAmp Java Bindings Test +Specification-Title: JogAmp Java Bindings Specification Test +Specification-Version: @BASEVERSION@ +Specification-Vendor: JogAmp Community +Implementation-Title: JogAmp Java Bindings Fat Test Jar +Implementation-Version: @VERSION@ +Implementation-Build: @BUILD_VERSION@ +Implementation-Branch: @SCM_BRANCH@ +Implementation-Commit: @SCM_COMMIT@ +Implementation-Vendor: JogAmp Community +Implementation-URL: http://jogamp.org/ +Extension-Name: com.jogamp +Implementation-Vendor-Id: com.jogamp +Main-Class: com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2SimpleNEWT +Class-Path: jogamp-fat.jar +Permissions: sandbox +Application-Library-Allowable-Codebase: * +@JAR_CODEBASE_TAG@ + diff -Nru gluegen2-2.2.4/make/scripts/adb-install-all-aarch64.sh gluegen2-2.3.2/make/scripts/adb-install-all-aarch64.sh --- gluegen2-2.2.4/make/scripts/adb-install-all-aarch64.sh 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/adb-install-all-aarch64.sh 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,2 @@ +adb $* install ../build-android-aarch64/jogamp-android-launcher.apk +adb $* install ../build-android-aarch64/gluegen-rt-android-aarch64.apk diff -Nru gluegen2-2.2.4/make/scripts/adb-install-all-armv6.sh gluegen2-2.3.2/make/scripts/adb-install-all-armv6.sh --- gluegen2-2.2.4/make/scripts/adb-install-all-armv6.sh 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/adb-install-all-armv6.sh 2015-10-09 04:18:28.000000000 +0000 @@ -1,2 +1,2 @@ adb $* install ../build-android-armv6/jogamp-android-launcher.apk -adb $* install ../build-android-armv6/gluegen-rt-android-armeabi.apk +adb $* install ../build-android-armv6/gluegen-rt-android-armv6.apk diff -Nru gluegen2-2.2.4/make/scripts/adb-install-all-armv7.sh gluegen2-2.3.2/make/scripts/adb-install-all-armv7.sh --- gluegen2-2.2.4/make/scripts/adb-install-all-armv7.sh 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/adb-install-all-armv7.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -adb $* install ../build-android-armv7/jogamp-android-launcher.apk -adb $* install ../build-android-armv7/gluegen-rt-android-armeabi-v7a.apk diff -Nru gluegen2-2.2.4/make/scripts/adb-reinstall-all-aarch64.sh gluegen2-2.3.2/make/scripts/adb-reinstall-all-aarch64.sh --- gluegen2-2.2.4/make/scripts/adb-reinstall-all-aarch64.sh 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/adb-reinstall-all-aarch64.sh 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,5 @@ +sdir=`dirname $0` + +$sdir/adb-uninstall-all.sh $* +$sdir/adb-install-all-aarch64.sh $* + diff -Nru gluegen2-2.2.4/make/scripts/adb-reinstall-all-armv7.sh gluegen2-2.3.2/make/scripts/adb-reinstall-all-armv7.sh --- gluegen2-2.2.4/make/scripts/adb-reinstall-all-armv7.sh 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/adb-reinstall-all-armv7.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -sdir=`dirname $0` - -$sdir/adb-uninstall-all.sh $* -$sdir/adb-install-all-armv7.sh $* - diff -Nru gluegen2-2.2.4/make/scripts/crosstest-junit-android-armv7-rel.sh gluegen2-2.3.2/make/scripts/crosstest-junit-android-armv7-rel.sh --- gluegen2-2.2.4/make/scripts/crosstest-junit-android-armv7-rel.sh 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/crosstest-junit-android-armv7-rel.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -#! /bin/bash - -export HOST_UID=sven -export HOST_IP=192.168.0.52 -export HOST_RSYNC_ROOT=PROJECTS/JOGL - -export TARGET_UID=jogamp -export TARGET_IP=beagle02 -export TARGET_ROOT=/projects - -export BUILD_DIR=../build-android-armv7 - -if [ -e /opt-linux-x86/android-sdk-linux_x86 ] ; then - export ANDROID_HOME=/opt-linux-x86/android-sdk-linux_x86 - export PATH=$ANDROID_HOME/platform-tools:$PATH -fi - -# -# orig android: -# export LD_LIBRARY_PATH /system/lib -# export BOOTCLASSPATH /system/framework/core.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/core-junit.jar -# - -#TSTCLASS=com.jogamp.gluegen.test.junit.generation.Test1p1JavaEmitter -TSTCLASS=com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter - -LOGFILE=`basename $0 .sh`.log - -# -Djava.class.path=lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:$BUILD_DIR/gluegen.jar:$BUILD_DIR/test/build/gluegen-test.jar \ -# -Djava.class.path=lib/ant-junit-all.apk:$BUILD_DIR/gluegen-rt.apk \ -# -Djava.library.path=/system/lib:$TARGET_ROOT/gluegen/make/$BUILD_DIR/obj:$BUILD_DIR/test/build/natives \ - -RSYNC_EXCLUDES="--exclude 'build-x86*/' --exclude 'build-linux*/' --exclude 'build-win*/' --exclude 'build-mac*/' \ - --exclude 'classes/' --exclude 'src/' --exclude '.git/' --exclude 'gluegen-java-src.zip' \ - --delete-excluded" - -echo "#! /system/bin/sh" > $BUILD_DIR/targetcommand.sh - -echo "\ -rsync -av --delete --delete-after $RSYNC_EXCLUDES $HOST_UID@$HOST_IP::$HOST_RSYNC_ROOT/gluegen $TARGET_ROOT ; \ -cd $TARGET_ROOT/gluegen/make ; \ -export LD_LIBRARY_PATH=/system/lib:$TARGET_ROOT/gluegen/make/$BUILD_DIR/obj:$TARGET_ROOT/gluegen/make/$BUILD_DIR/test/build/natives ; \ -export BOOTCLASSPATH=/system/framework/core.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar ; \ -dalvikvm \ - -Xjnigreflimit:2000 \ - -cp ../make/lib/ant-junit-all.apk:../build-android-armv7/gluegen.apk:../build-android-armv7/test/build/gluegen-test.apk \ - -Djogamp.debug.JNILibLoader=true \ - -Djogamp.debug.NativeLibrary=true \ - -Djogamp.debug.NativeLibrary.Lookup=true \ - -Djogamp.debug.ProcAddressHelper=true \ - com.android.internal.util.WithFramework \ - org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner \ - $TSTCLASS \ - filtertrace=true \ - haltOnError=false \ - haltOnFailure=false \ - showoutput=true \ - outputtoformatters=true \ - logfailedtests=true \ - logtestlistenerevents=true \ - formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter \ - formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,./TEST-result.xml \ -" >> $BUILD_DIR/targetcommand.sh - -chmod ugo+x $BUILD_DIR/targetcommand.sh -adb push $BUILD_DIR/targetcommand.sh $TARGET_ROOT/targetcommand.sh -adb shell $TARGET_ROOT/targetcommand.sh 2>&1 | tee $LOGFILE -adb pull $TARGET_ROOT/gluegen/make/TEST-result.xml TEST-result.xml - diff -Nru gluegen2-2.2.4/make/scripts/java-win32.bat gluegen2-2.3.2/make/scripts/java-win32.bat --- gluegen2-2.2.4/make/scripts/java-win32.bat 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/java-win32.bat 2015-10-09 04:18:28.000000000 +0000 @@ -1,21 +1,24 @@ set BLD_SUB=build-win32 -set J2RE_HOME=c:\jre1.7.0_67_x32 -set JAVA_HOME=c:\jdk1.7.0_67_x32 +set J2RE_HOME=c:\jre1.8.0_60_x32 +set JAVA_HOME=c:\jdk1.8.0_60_x32 set ANT_PATH=C:\apache-ant-1.9.4 set BLD_DIR=..\%BLD_SUB% REM set LIB_DIR=..\%BLD_SUB%\obj;..\%BLD_SUB%\test\build\natives -set LIB_DIR=..\%BLD_SUB%\test\build\natives +REM set LIB_DIR=..\%BLD_SUB%\test\build\natives -set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%LIB_DIR%;%PATH% +REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%LIB_DIR%;%PATH% +set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH% set CP_ALL=.;lib\junit.jar;%ANT_PATH%\lib\ant.jar;%ANT_PATH%\lib\ant-junit.jar;lib/semantic-versioning/semver.jar;%BLD_DIR%\gluegen-rt.jar;%BLD_DIR%\gluegen.jar;%BLD_DIR%\gluegen-test-util.jar;%BLD_DIR%\test\build\gluegen-test.jar echo CP_ALL %CP_ALL% -set D_ARGS="-Djogamp.debug.Platform" "-Djogamp.debug.NativeLibrary" -REM set D_ARGS="-Djogamp.debug.IOUtil" +set X_ARGS="-Drootrel.build=%BLD_SUB%" "-Dgluegen.root=.." +REM set D_ARGS="-Djogamp.debug.Platform" "-Djogamp.debug.NativeLibrary" +set D_ARGS="-Djogamp.debug.IOUtil" "-Djogamp.debug.IOUtil.Exe" REM set D_ARGS="-Djogamp.debug=all" -%J2RE_HOME%\bin\java -classpath %CP_ALL% %D_ARGS% "-Djava.library.path=%LIB_DIR%" "-Dsun.java2d.noddraw=true" "-Dsun.awt.noerasebackground=true" %1 %2 %3 %4 %5 %6 %7 %8 %9 > java-win32.log 2>&1 +REM %J2RE_HOME%\bin\java -classpath %CP_ALL% %X_ARGS% %D_ARGS% "-Djava.library.path=%LIB_DIR%" "-Dsun.java2d.noddraw=true" "-Dsun.awt.noerasebackground=true" %1 %2 %3 %4 %5 %6 %7 %8 %9 > java-win32.log 2>&1 +%J2RE_HOME%\bin\java -classpath %CP_ALL% %X_ARGS% %D_ARGS% "-Dsun.java2d.noddraw=true" "-Dsun.awt.noerasebackground=true" %1 %2 %3 %4 %5 %6 %7 %8 %9 > java-win32.log 2>&1 diff -Nru gluegen2-2.2.4/make/scripts/java-win64.bat gluegen2-2.3.2/make/scripts/java-win64.bat --- gluegen2-2.2.4/make/scripts/java-win64.bat 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/java-win64.bat 2015-10-09 04:18:28.000000000 +0000 @@ -1,23 +1,26 @@ set BLD_SUB=build-win64 -set J2RE_HOME=c:\jre1.7.0_67_x64 -set JAVA_HOME=c:\jdk1.7.0_67_x64 +set J2RE_HOME=c:\jre1.8.0_60_x64 +set JAVA_HOME=c:\jdk1.8.0_60_x64 set ANT_PATH=C:\apache-ant-1.9.4 set BLD_DIR=..\%BLD_SUB% REM set LIB_DIR=..\%BLD_SUB%\obj;..\%BLD_SUB%\test\build\natives -set LIB_DIR=..\%BLD_SUB%\test\build\natives +REM set LIB_DIR=..\%BLD_SUB%\test\build\natives -set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%LIB_DIR%;%PATH% +REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%LIB_DIR%;%PATH% +set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH% -set CP_ALL=.;lib\junit.jar;%ANT_PATH%\lib\ant.jar;%ANT_PATH%\lib\ant-junit.jar;lib/semantic-versioning/semver.jar;%BLD_DIR%\gluegen-rt.jar;%BLD_DIR%\gluegen.jar;%BLD_DIR%\gluegen-test-util.jar;%BLD_DIR%\test\build\gluegen-test.jar +set CP_ALL=.;lib\junit.jar;%ANT_PATH%\lib\ant.jar;%ANT_PATH%\lib\ant-junit.jar;lib/semantic-versioning/semver.jar;lib\TestJarsInJar.jar;%BLD_DIR%\gluegen-rt.jar;%BLD_DIR%\gluegen.jar;%BLD_DIR%\gluegen-test-util.jar;%BLD_DIR%\test\build\gluegen-test.jar echo CP_ALL %CP_ALL% -set D_ARGS="-Djogamp.debug.IOUtil" "-Djogamp.debug.JNILibLoader" "-Djogamp.debug.TempFileCache" "-Djogamp.debug.JarUtil" "-Djogamp.debug.TempJarCache" +set X_ARGS="-Drootrel.build=%BLD_SUB%" "-Dgluegen.root=.." +REM set D_ARGS="-Djogamp.debug.IOUtil" "-Djogamp.debug.JNILibLoader" "-Djogamp.debug.TempFileCache" "-Djogamp.debug.JarUtil" "-Djogamp.debug.TempJarCache" REM set D_ARGS="-Djogamp.debug.Platform" "-Djogamp.debug.NativeLibrary" "-Djogamp.debug.IOUtil" -REM set D_ARGS="-Djogamp.debug.IOUtil" +set D_ARGS="-Djogamp.debug.IOUtil" "-Djogamp.debug.IOUtil.Exe" "-Djogamp.debug.IOUtil.Exe.NoStream" REM set D_ARGS="-Djogamp.debug=all" -%J2RE_HOME%\bin\java -classpath %CP_ALL% %D_ARGS% "-Djava.library.path=%LIB_DIR%" "-Dsun.java2d.noddraw=true" "-Dsun.awt.noerasebackground=true" %1 %2 %3 %4 %5 %6 %7 %8 %9 > java-win64.log 2>&1 +REM %J2RE_HOME%\bin\java -classpath %CP_ALL% %X_ARGS% %D_ARGS% "-Djava.library.path=%LIB_DIR%" "-Dsun.java2d.noddraw=true" "-Dsun.awt.noerasebackground=true" %1 %2 %3 %4 %5 %6 %7 %8 %9 > java-win64.log 2>&1 +%J2RE_HOME%\bin\java -classpath %CP_ALL% %X_ARGS% %D_ARGS% "-Dsun.java2d.noddraw=true" "-Dsun.awt.noerasebackground=true" %1 %2 %3 %4 %5 %6 %7 %8 %9 > java-win64.log 2>&1 diff -Nru gluegen2-2.2.4/make/scripts/make.gluegen.all.android-aarch64-cross.sh gluegen2-2.3.2/make/scripts/make.gluegen.all.android-aarch64-cross.sh --- gluegen2-2.2.4/make/scripts/make.gluegen.all.android-aarch64-cross.sh 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/make.gluegen.all.android-aarch64-cross.sh 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,62 @@ +#! /bin/sh + +SDIR=`dirname $0` + +if [ -e $SDIR/setenv-build-jogl-x86_64.sh ] ; then + . $SDIR/setenv-build-jogl-x86_64.sh +fi + +if [ -e $SDIR/setenv-android-tools.sh ] ; then + . $SDIR/setenv-android-tools.sh +fi + +export NODE_LABEL=. + +export HOST_UID=jogamp +# jogamp02 - 10.1.0.122 +export HOST_IP=10.1.0.122 +export HOST_RSYNC_ROOT=PROJECTS/JOGL + +export TARGET_UID=jogamp +export TARGET_IP=panda02 +#export TARGET_IP=jautab03 +#export TARGET_IP=jauphone04 +export TARGET_ADB_PORT=5555 +# needs executable bit (probably su) +export TARGET_ROOT=/data/projects +export TARGET_ANT_HOME=/usr/share/ant + +export ANDROID_VERSION=21 +export SOURCE_LEVEL=1.6 +export TARGET_LEVEL=1.6 +export TARGET_RT_JAR=/opt-share/jre1.6.0_30/lib/rt.jar + +#export GCC_VERSION=4.4.3 +export GCC_VERSION=4.9 +HOST_ARCH=linux-x86_64 +export TARGET_TRIPLE=aarch64-linux-android + +export NDK_TOOLCHAIN_ROOT=$NDK_ROOT/toolchains/${TARGET_TRIPLE}-${GCC_VERSION}/prebuilt/${HOST_ARCH} +export TARGET_PLATFORM_ROOT=${NDK_ROOT}/platforms/android-${ANDROID_VERSION}/arch-arm64 + +# Need to add toolchain bins to the PATH. +# May need to create symbolic links within $NDK_TOOLCHAIN_ROOT/$TARGET_TRIPLE/bin +# cd $NDK_TOOLCHAIN_ROOT/$TARGET_TRIPLE/bin +# ln -s ../../bin/aarch64-linux-android-gcc gcc +export PATH="$NDK_TOOLCHAIN_ROOT/$TARGET_TRIPLE/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools/$ANDROID_BUILD_TOOLS_VERSION:$PATH" + +export GLUEGEN_CPPTASKS_FILE="lib/gluegen-cpptasks-android-aarch64.xml" + +#export JUNIT_DISABLED="true" +#export JUNIT_RUN_ARG0="-Dnewt.test.Screen.disableScreenMode" + +echo PATH $PATH 2>&1 | tee make.gluegen.all.android-aarch64-cross.log +echo gcc `which gcc` 2>&1 | tee -a make.gluegen.all.android-aarch64-cross.log + +#export JOGAMP_JAR_CODEBASE="Codebase: *.jogamp.org" +export JOGAMP_JAR_CODEBASE="Codebase: *.goethel.localnet" + +#BUILD_ARCHIVE=true \ +ant \ + -Drootrel.build=build-android-aarch64 \ + $* 2>&1 | tee -a make.gluegen.all.android-aarch64-cross.log diff -Nru gluegen2-2.2.4/make/scripts/make.gluegen.all.android-armv6-cross.sh gluegen2-2.3.2/make/scripts/make.gluegen.all.android-armv6-cross.sh --- gluegen2-2.2.4/make/scripts/make.gluegen.all.android-armv6-cross.sh 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/make.gluegen.all.android-armv6-cross.sh 2015-10-09 04:18:28.000000000 +0000 @@ -6,6 +6,10 @@ . $SDIR/setenv-build-jogl-x86_64.sh fi +if [ -e $SDIR/setenv-android-tools.sh ] ; then + . $SDIR/setenv-android-tools.sh +fi + export NODE_LABEL=. export HOST_UID=jogamp @@ -22,70 +26,21 @@ export TARGET_ROOT=/data/projects export TARGET_ANT_HOME=/usr/share/ant -echo ANDROID_HOME $ANDROID_HOME -echo NDK_ROOT $NDK_ROOT - -if [ -z "$NDK_ROOT" ] ; then - # - # Generic android-ndk - # - if [ -e /usr/local/android-ndk ] ; then - NDK_ROOT=/usr/local/android-ndk - elif [ -e /opt-linux-x86/android-ndk ] ; then - NDK_ROOT=/opt-linux-x86/android-ndk - elif [ -e /opt/android-ndk ] ; then - NDK_ROOT=/opt/android-ndk - # - # Specific android-ndk-r8d - # - elif [ -e /usr/local/android-ndk-r8d ] ; then - NDK_ROOT=/usr/local/android-ndk-r8d - elif [ -e /opt-linux-x86/android-ndk-r8d ] ; then - NDK_ROOT=/opt-linux-x86/android-ndk-r8d - elif [ -e /opt/android-ndk-r8d ] ; then - NDK_ROOT=/opt/android-ndk-r8d - else - echo NDK_ROOT is not specified and does not exist in default locations - exit 1 - fi -elif [ ! -e $NDK_ROOT ] ; then - echo NDK_ROOT $NDK_ROOT does not exist - exit 1 -fi -export NDK_ROOT - -if [ -z "$ANDROID_HOME" ] ; then - if [ -e /usr/local/android-sdk-linux_x86 ] ; then - ANDROID_HOME=/usr/local/android-sdk-linux_x86 - elif [ -e /opt-linux-x86/android-sdk-linux_x86 ] ; then - ANDROID_HOME=/opt-linux-x86/android-sdk-linux_x86 - elif [ -e /opt/android-sdk-linux_x86 ] ; then - ANDROID_HOME=/opt/android-sdk-linux_x86 - else - echo ANDROID_HOME is not specified and does not exist in default locations - exit 1 - fi -elif [ ! -e $ANDROID_HOME ] ; then - echo ANDROID_HOME $ANDROID_HOME does not exist - exit 1 -fi -export ANDROID_HOME - export ANDROID_VERSION=9 export SOURCE_LEVEL=1.6 export TARGET_LEVEL=1.6 export TARGET_RT_JAR=/opt-share/jre1.6.0_30/lib/rt.jar #export GCC_VERSION=4.4.3 -export GCC_VERSION=4.7 -HOST_ARCH=linux-x86 +export GCC_VERSION=4.8 +HOST_ARCH=linux-x86_64 export TARGET_TRIPLE=arm-linux-androideabi export NDK_TOOLCHAIN_ROOT=$NDK_ROOT/toolchains/${TARGET_TRIPLE}-${GCC_VERSION}/prebuilt/${HOST_ARCH} export TARGET_PLATFORM_ROOT=${NDK_ROOT}/platforms/android-${ANDROID_VERSION}/arch-arm # Need to add toolchain bins to the PATH. -export PATH="$NDK_TOOLCHAIN_ROOT/$TARGET_TRIPLE/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools/17.0.0:$PATH" +export PATH="$NDK_TOOLCHAIN_ROOT/$TARGET_TRIPLE/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools/$ANDROID_BUILD_TOOLS_VERSION:$PATH" export GLUEGEN_CPPTASKS_FILE="lib/gluegen-cpptasks-android-armv6.xml" diff -Nru gluegen2-2.2.4/make/scripts/make.gluegen.all.android-armv7-cross.sh gluegen2-2.3.2/make/scripts/make.gluegen.all.android-armv7-cross.sh --- gluegen2-2.2.4/make/scripts/make.gluegen.all.android-armv7-cross.sh 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/make.gluegen.all.android-armv7-cross.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -#! /bin/sh - -if [ -e $SDIR/setenv-build-jogl-x86_64.sh ] ; then - . $SDIR/setenv-build-jogl-x86_64.sh -fi - -export NODE_LABEL=. - -export HOST_UID=jogamp -# jogamp02 - 10.1.0.122 -export HOST_IP=10.1.0.122 -export HOST_RSYNC_ROOT=PROJECTS/JOGL - -export TARGET_UID=jogamp -export TARGET_IP=panda02 -#export TARGET_IP=jautab03 -#export TARGET_IP=jauphone04 -export TARGET_ADB_PORT=5555 -# needs executable bit (probably su) -export TARGET_ROOT=/data/projects -export TARGET_ANT_HOME=/usr/share/ant - -echo ANDROID_HOME $ANDROID_HOME -echo NDK_ROOT $NDK_ROOT - -if [ -z "$NDK_ROOT" ] ; then - # - # Generic android-ndk - # - if [ -e /usr/local/android-ndk ] ; then - NDK_ROOT=/usr/local/android-ndk - elif [ -e /opt-linux-x86/android-ndk ] ; then - NDK_ROOT=/opt-linux-x86/android-ndk - elif [ -e /opt/android-ndk ] ; then - NDK_ROOT=/opt/android-ndk - # - # Specific android-ndk-r8d - # - elif [ -e /usr/local/android-ndk-r8d ] ; then - NDK_ROOT=/usr/local/android-ndk-r8d - elif [ -e /opt-linux-x86/android-ndk-r8d ] ; then - NDK_ROOT=/opt-linux-x86/android-ndk-r8d - elif [ -e /opt/android-ndk-r8d ] ; then - NDK_ROOT=/opt/android-ndk-r8d - else - echo NDK_ROOT is not specified and does not exist in default locations - exit 1 - fi -elif [ ! -e $NDK_ROOT ] ; then - echo NDK_ROOT $NDK_ROOT does not exist - exit 1 -fi -export NDK_ROOT - -if [ -z "$ANDROID_HOME" ] ; then - if [ -e /usr/local/android-sdk-linux_x86 ] ; then - ANDROID_HOME=/usr/local/android-sdk-linux_x86 - elif [ -e /opt-linux-x86/android-sdk-linux_x86 ] ; then - ANDROID_HOME=/opt-linux-x86/android-sdk-linux_x86 - elif [ -e /opt/android-sdk-linux_x86 ] ; then - ANDROID_HOME=/opt/android-sdk-linux_x86 - else - echo ANDROID_HOME is not specified and does not exist in default locations - exit 1 - fi -elif [ ! -e $ANDROID_HOME ] ; then - echo ANDROID_HOME $ANDROID_HOME does not exist - exit 1 -fi -export ANDROID_HOME - -export ANDROID_VERSION=9 -export SOURCE_LEVEL=1.6 -export TARGET_LEVEL=1.6 -export TARGET_RT_JAR=/opt-share/jre1.6.0_30/lib/rt.jar - -#export GCC_VERSION=4.4.3 -export GCC_VERSION=4.7 -HOST_ARCH=linux-x86 -export TARGET_TRIPLE=arm-linux-androideabi - -export NDK_TOOLCHAIN_ROOT=$NDK_ROOT/toolchains/${TARGET_TRIPLE}-${GCC_VERSION}/prebuilt/${HOST_ARCH} -export TARGET_PLATFORM_ROOT=${NDK_ROOT}/platforms/android-${ANDROID_VERSION}/arch-arm - -# Need to add toolchain bins to the PATH. -export PATH="$NDK_TOOLCHAIN_ROOT/$TARGET_TRIPLE/bin:$ANDROID_HOME/platform-tools:$PATH" - -export GLUEGEN_CPPTASKS_FILE="lib/gluegen-cpptasks-android-armv7.xml" - -#export JUNIT_DISABLED="true" -#export JUNIT_RUN_ARG0="-Dnewt.test.Screen.disableScreenMode" - -which gcc 2>&1 | tee make.gluegen.all.android-armv7-cross.log - -#export JOGAMP_JAR_CODEBASE="Codebase: *.jogamp.org" -export JOGAMP_JAR_CODEBASE="Codebase: *.goethel.localnet" - -#BUILD_ARCHIVE=true \ -ant \ - -Drootrel.build=build-android-armv7 \ - $* 2>&1 | tee -a make.gluegen.all.android-armv7-cross.log diff -Nru gluegen2-2.2.4/make/scripts/make.gluegen.all.macosx-java6.sh gluegen2-2.3.2/make/scripts/make.gluegen.all.macosx-java6.sh --- gluegen2-2.2.4/make/scripts/make.gluegen.all.macosx-java6.sh 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/make.gluegen.all.macosx-java6.sh 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,29 @@ +#! /bin/sh + +if [ -e /opt-share/etc/profile.ant ] ; then + . /opt-share/etc/profile.ant +fi + +# -Dc.compiler.debug=true +# +# -Dtarget.sourcelevel=1.6 \ +# -Dtarget.targetlevel=1.6 \ +# -Dtarget.rt.jar=/opt-share/jre1.6.0_30/lib/rt.jar \ + +# Force OSX SDK 10.6, if desired +# export SDKROOT=macosx10.6 + +JAVA_HOME=`/usr/libexec/java_home -version 1.6` +PATH=$JAVA_HOME/bin:$PATH +export JAVA_HOME PATH + +export SOURCE_LEVEL=1.6 +export TARGET_LEVEL=1.6 +export TARGET_RT_JAR=/opt-share/jre1.6.0_30/lib/rt.jar + +#export JOGAMP_JAR_CODEBASE="Codebase: *.jogamp.org" +export JOGAMP_JAR_CODEBASE="Codebase: *.goethel.localnet" + +ant \ + -Drootrel.build=build-macosx-java6 \ + $* 2>&1 | tee make.gluegen.all.macosx-java6.log diff -Nru gluegen2-2.2.4/make/scripts/make.gluegen.all.macosx-java7.sh gluegen2-2.3.2/make/scripts/make.gluegen.all.macosx-java7.sh --- gluegen2-2.2.4/make/scripts/make.gluegen.all.macosx-java7.sh 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/make.gluegen.all.macosx-java7.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -#! /bin/sh - -if [ -e /opt-share/etc/profile.ant ] ; then - . /opt-share/etc/profile.ant -fi - -# -Dc.compiler.debug=true -# -# -Dtarget.sourcelevel=1.6 \ -# -Dtarget.targetlevel=1.6 \ -# -Dtarget.rt.jar=/opt-share/jre1.6.0_30/lib/rt.jar \ - -JAVA_HOME=`/usr/libexec/java_home -version 1.7` -PATH=$JAVA_HOME/bin:$PATH -export JAVA_HOME PATH - -#export JOGAMP_JAR_CODEBASE="Codebase: *.jogamp.org" -export JOGAMP_JAR_CODEBASE="Codebase: *.goethel.localnet" - -ant \ - -Drootrel.build=build-macosx-java7 \ - $* 2>&1 | tee make.gluegen.all.macosx-java7.log diff -Nru gluegen2-2.2.4/make/scripts/make.gluegen.all.macosx.sh gluegen2-2.3.2/make/scripts/make.gluegen.all.macosx.sh --- gluegen2-2.2.4/make/scripts/make.gluegen.all.macosx.sh 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/make.gluegen.all.macosx.sh 2015-10-09 04:18:28.000000000 +0000 @@ -10,7 +10,10 @@ # -Dtarget.targetlevel=1.6 \ # -Dtarget.rt.jar=/opt-share/jre1.6.0_30/lib/rt.jar \ -JAVA_HOME=`/usr/libexec/java_home -version 1.7` +# Force OSX SDK 10.6, if desired +# export SDKROOT=macosx10.6 + +JAVA_HOME=`/usr/libexec/java_home -version 1.8` PATH=$JAVA_HOME/bin:$PATH export JAVA_HOME PATH diff -Nru gluegen2-2.2.4/make/scripts/make.gluegen.all.win32.bat gluegen2-2.3.2/make/scripts/make.gluegen.all.win32.bat --- gluegen2-2.2.4/make/scripts/make.gluegen.all.win32.bat 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/make.gluegen.all.win32.bat 2015-10-09 04:18:28.000000000 +0000 @@ -1,7 +1,7 @@ set THISDIR="C:\JOGL" -set J2RE_HOME=c:\jre1.8.0_20_x32 -set JAVA_HOME=c:\jdk1.8.0_20_x32 +set J2RE_HOME=c:\jre1.8.0_60_x32 +set JAVA_HOME=c:\jdk1.8.0_60_x32 set ANT_PATH=C:\apache-ant-1.9.4 set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH% diff -Nru gluegen2-2.2.4/make/scripts/make.gluegen.all.win64.bat gluegen2-2.3.2/make/scripts/make.gluegen.all.win64.bat --- gluegen2-2.2.4/make/scripts/make.gluegen.all.win64.bat 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/make.gluegen.all.win64.bat 2015-10-09 04:18:28.000000000 +0000 @@ -1,7 +1,7 @@ set THISDIR="C:\JOGL" -set J2RE_HOME=c:\jre1.8.0_20_x64 -set JAVA_HOME=c:\jdk1.8.0_20_x64 +set J2RE_HOME=c:\jre1.8.0_60_x64 +set JAVA_HOME=c:\jdk1.8.0_60_x64 set ANT_PATH=C:\apache-ant-1.9.4 set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw64\bin;c:\mingw\bin;%PATH% diff -Nru gluegen2-2.2.4/make/scripts/runtest.sh gluegen2-2.3.2/make/scripts/runtest.sh --- gluegen2-2.2.4/make/scripts/runtest.sh 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/runtest.sh 2015-10-09 04:18:28.000000000 +0000 @@ -39,6 +39,10 @@ LOG=runtest.log rm -f $LOG +GLUEGEN_ROOT=`dirname $builddir` +ROOTREL_BUILD=`basename $builddir` + +X_ARGS="-Drootrel.build=$ROOTREL_BUILD -Dgluegen.root=$GLUEGEN_ROOT" #D_ARGS="-Djogamp.debug.ProcAddressHelper -Djogamp.debug.NativeLibrary -Djogamp.debug.NativeLibrary.Lookup" #D_ARGS="-Djogamp.debug.TraceLock" #D_ARGS="-Djogamp.debug.Platform -Djogamp.debug.NativeLibrary" @@ -46,16 +50,22 @@ #D_ARGS="-Djogamp.debug.TempJarCache" #D_ARGS="-Djogamp.debug.TempFileCache" #D_ARGS="-Djogamp.debug.IOUtil -Djogamp.debug.JNILibLoader -Djogamp.debug.TempFileCache -Djogamp.debug.JarUtil -Djava.io.tmpdir=/run/tmp" -D_ARGS="-Djogamp.debug.IOUtil -Djogamp.debug.JNILibLoader -Djogamp.debug.TempFileCache -Djogamp.debug.JarUtil -Djogamp.debug.TempJarCache" +#D_ARGS="-Djogamp.debug.IOUtil -Djogamp.debug.JNILibLoader -Djogamp.debug.TempFileCache -Djogamp.debug.JarUtil -Djogamp.debug.TempJarCache" +#D_ARGS="-Djogamp.debug.IOUtil -Djogamp.debug.JarUtil -Djogamp.debug.TempJarCache -Djogamp.debug.Uri -Djogamp.debug.Uri.ShowFix" +#D_ARGS="-Djogamp.debug.Uri -Djogamp.debug.Uri.ShowFix" #D_ARGS="-Djogamp.debug.JNILibLoader -Djogamp.gluegen.UseTempJarCache=false" #D_ARGS="-Djogamp.debug.JNILibLoader -Djogamp.debug.TempJarCache" #D_ARGS="-Djogamp.debug.JNILibLoader" +#D_ARGS="-Djogamp.debug.JNILibLoader.Perf" #D_ARGS="-Djogamp.debug.Lock" #D_ARGS="-Djogamp.debug.Lock -Djogamp.debug.Lock.TraceLock" #D_ARGS="-Djogamp.debug.Lock.TraceLock" -#D_ARGS="-Djogamp.debug.IOUtil" +#D_ARGS="-Djogamp.debug.IOUtil -Djogamp.debug.IOUtil.Exe -Djogamp.debug.IOUtil.Exe.NoStream" +#D_ARGS="-Djogamp.debug.IOUtil -Djogamp.debug.IOUtil.Exe" +#D_ARGS="-Djogamp.debug.ByteBufferInputStream" #D_ARGS="-Djogamp.debug.Bitstream" #D_ARGS="-Djogamp.debug=all" +#D_ARGS="-Djogamp.debug.Logging" function onetest() { #USE_CLASSPATH=lib/junit.jar:$ANT_JARS:lib/semantic-versioning/semver.jar:"$builddir"/../make/lib/TestJarsInJar.jar:"$builddir"/gluegen-rt.jar:"$builddir"/gluegen.jar:"$builddir"/gluegen-test-util.jar:"$builddir"/test/build/gluegen-test.jar @@ -70,11 +80,11 @@ echo LD_LIBRARY_PATH $LD_LIBRARY_PATH echo USE_CLASSPATH $USE_CLASSPATH which java - #echo java -cp $USE_CLASSPATH $D_ARGS -Djava.library.path=$libspath $* - #java -cp $USE_CLASSPATH $D_ARGS -Djava.library.path="$libspath" $* - echo java -cp "$USE_CLASSPATH" $D_ARGS $* - java -cp "$USE_CLASSPATH" $D_ARGS $* - #j3 -cp "$USE_CLASSPATH" $D_ARGS $* + #echo java -cp $USE_CLASSPATH $X_ARGS $D_ARGS -Djava.library.path=$libspath $* + #java -cp $USE_CLASSPATH $X_ARGS $D_ARGS -Djava.library.path="$libspath" $* + echo java -cp "$USE_CLASSPATH" $X_ARGS $D_ARGS $* + java -cp "$USE_CLASSPATH" $X_ARGS $D_ARGS $* + #j3 -cp "$USE_CLASSPATH" $X_ARGS $D_ARGS $* echo } # @@ -92,35 +102,49 @@ #onetest com.jogamp.common.util.TestFloatStack01 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestIntegerStack01 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestArrayHashSet01 2>&1 | tee -a $LOG +#onetest com.jogamp.common.util.TestArrayHashMap01 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.IntIntHashMapTest 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.IntObjectHashMapTest 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.LongIntHashMapTest 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestPlatform01 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestRunnableTask01 2>&1 | tee -a $LOG -#onetest com.jogamp.common.util.TestIOUtil01 2>&1 | tee -a $LOG -#onetest com.jogamp.common.util.TestIOUtilURICompose 2>&1 | tee -a $LOG -#onetest com.jogamp.common.util.TestIOUtilURIHandling 2>&1 | tee -a $LOG +onetest com.jogamp.common.util.TestIOUtil01 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestTempJarCache 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestJarUtil 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestValueConversion 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestSyncRingBuffer01 $* #onetest com.jogamp.common.util.TestLFRingBuffer01 $* +#onetest com.jogamp.common.util.TestBitfield00 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestBitstream00 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestBitstream01 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestBitstream02 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestBitstream03 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestBitstream04 2>&1 | tee -a $LOG #onetest com.jogamp.common.net.TestUrisWithAssetHandler 2>&1 | tee -a $LOG -#onetest com.jogamp.common.net.TestURIQueryProps 2>&1 | tee -a $LOG +#onetest com.jogamp.common.net.TestUriQueryProps 2>&1 | tee -a $LOG +#onetest com.jogamp.common.net.TestUri01 2>&1 | tee -a $LOG +#onetest com.jogamp.common.net.TestUri02Composing 2>&1 | tee -a $LOG +#onetest com.jogamp.common.net.TestUri03Resolving 2>&1 | tee -a $LOG +#onetest com.jogamp.common.net.TestUri99LaunchOnReservedCharPathBug908 2>&1 | tee -a $LOG #onetest com.jogamp.common.net.AssetURLConnectionUnregisteredTest 2>&1 | tee -a $LOG #onetest com.jogamp.common.net.AssetURLConnectionRegisteredTest 2>&1 | tee -a $LOG -onetest com.jogamp.common.net.TestNetIOURIReservedCharsBug908 2>&1 | tee -a $LOG #onetest com.jogamp.junit.sec.TestSecIOUtil01 2>&1 | tee -a $LOG +#onetest com.jogamp.common.nio.BuffersTest 2>&1 | tee -a $LOG #onetest com.jogamp.common.nio.TestBuffersFloatDoubleConversion 2>&1 | tee -a $LOG #onetest com.jogamp.common.nio.TestPointerBufferEndian 2>&1 | tee -a $LOG #onetest com.jogamp.common.nio.TestStructAccessorEndian 2>&1 | tee -a $LOG -#onetest com.jogamp.common.os.TestElfReader01 2>&1 | tee -a $LOG -#onetest com.jogamp.gluegen.PCPPTest 2>&1 | tee -a $LOG +#onetest com.jogamp.common.nio.TestByteBufferInputStream 2>&1 | tee -a $LOG +#onetest com.jogamp.common.nio.TestByteBufferOutputStream 2>&1 | tee -a $LOG +#onetest com.jogamp.common.nio.TestByteBufferCopyStream 2>&1 | tee -a $LOG +#onetest com.jogamp.common.os.TestElfReader01 $* 2>&1 | tee -a $LOG +#onetest com.jogamp.gluegen.test.junit.internals.TestType 2>&1 | tee -a $LOG + +#onetest com.jogamp.gluegen.test.junit.generation.PCPPTest 2>&1 | tee -a $LOG +#onetest com.jogamp.gluegen.jcpp.IncludeAbsoluteTest 2>&1 | tee -a $LOG +#onetest com.jogamp.gluegen.jcpp.CppReaderTest 2>&1 | tee -a $LOG +#onetest com.jogamp.gluegen.jcpp.TokenPastingWhitespaceTest 2>&1 | tee -a $LOG +#onetest com.jogamp.gluegen.jcpp.PreprocessorTest 2>&1 | tee -a $LOG + #onetest com.jogamp.gluegen.test.junit.generation.Test1p1JavaEmitter 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.generation.Test1p2LoadJNIAndImplLib 2>&1 | tee -a $LOG diff -Nru gluegen2-2.2.4/make/scripts/runtest-x32.bat gluegen2-2.3.2/make/scripts/runtest-x32.bat --- gluegen2-2.2.4/make/scripts/runtest-x32.bat 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/runtest-x32.bat 2015-10-09 04:18:28.000000000 +0000 @@ -1,8 +1,16 @@ +REM set TEMP=C:\Documents and Settings\jogamp\temp-exec +REM set TMP=C:\Documents and Settings\jogamp\temp-exec +REM set TEMP=C:\Users\jogamp\temp-exec +REM set TMP=C:\Users\jogamp\temp-exec + REM scripts\java-win32.bat com.jogamp.common.GlueGenVersion REM scripts\java-win32.bat com.jogamp.common.util.TestVersionInfo REM scripts\java-win32.bat com.jogamp.gluegen.test.junit.generation.Test1p1JavaEmitter REM scripts\java-win32.bat com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter -scripts\java-win32.bat com.jogamp.common.util.TestTempJarCache +REM scripts\java-win32.bat com.jogamp.common.util.TestTempJarCache +scripts\java-win32.bat com.jogamp.common.util.TestPlatform01 REM scripts\java-win32.bat com.jogamp.common.os.TestElfReader01 REM scripts\java-win32.bat com.jogamp.common.util.TestIOUtilURIHandling +REM scripts\java-win32.bat com.jogamp.common.nio.TestByteBufferInputStream +REM scripts\java-win32.bat com.jogamp.common.nio.TestByteBufferOutputStream diff -Nru gluegen2-2.2.4/make/scripts/runtest-x64.bat gluegen2-2.3.2/make/scripts/runtest-x64.bat --- gluegen2-2.2.4/make/scripts/runtest-x64.bat 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/runtest-x64.bat 2015-10-09 04:18:28.000000000 +0000 @@ -1,15 +1,27 @@ +REM set TEMP=C:\Documents and Settings\jogamp\temp-exec +REM set TMP=C:\Documents and Settings\jogamp\temp-exec +REM set TEMP=C:\Users\jogamp\temp-exec +REM set TMP=C:\Users\jogamp\temp-exec + REM scripts\java-win64.bat com.jogamp.common.GlueGenVersion REM scripts\java-win64.bat com.jogamp.common.util.TestVersionInfo + +REM scripts\java-win64.bat com.jogamp.gluegen.jcpp.IncludeAbsoluteTest + REM scripts\java-win64.bat com.jogamp.gluegen.test.junit.generation.Test1p1JavaEmitter REM scripts\java-win64.bat com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter REM scripts\java-win64.bat com.jogamp.common.util.TestTempJarCache REM scripts\java-win64.bat com.jogamp.common.os.TestElfReader01 +scripts\java-win64.bat com.jogamp.common.util.TestPlatform01 REM scripts\java-win64.bat com.jogamp.common.util.TestIOUtil01 -REM scripts\java-win64.bat com.jogamp.common.util.TestIOUtilURICompose -REM scripts\java-win64.bat com.jogamp.common.util.TestIOUtilURIHandling +REM scripts\java-win64.bat com.jogamp.common.util.TestJarUtil REM scripts\java-win64.bat com.jogamp.common.net.TestUrisWithAssetHandler REM scripts\java-win64.bat com.jogamp.common.net.TestURIQueryProps -scripts\java-win64.bat com.jogamp.common.net.TestNetIOURIReservedCharsBug908 -REM scripts\java-win64.bat com.jogamp.common.util.TestIOUtilURIHandling +REM scripts\java-win64.bat com.jogamp.common.net.TestUri01 +REM scripts\java-win64.bat com.jogamp.common.net.TestUri02Composing +REM scripts\java-win64.bat com.jogamp.common.net.TestUri03Resolving +REM scripts\java-win64.bat com.jogamp.common.net.TestUri99LaunchOnReservedCharPathBug908 +REM scripts\java-win64.bat com.jogamp.common.nio.TestByteBufferInputStream +REM scripts\java-win64.bat com.jogamp.common.nio.TestByteBufferOutputStream diff -Nru gluegen2-2.2.4/make/scripts/setenv-android-tools.sh gluegen2-2.3.2/make/scripts/setenv-android-tools.sh --- gluegen2-2.2.4/make/scripts/setenv-android-tools.sh 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/setenv-android-tools.sh 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,79 @@ +#! /bin/sh + +echo $0 + +echo Presets +echo NDK_ROOT $NDK_ROOT +echo ANDROID_HOME $ANDROID_HOME +echo ANDROID_BUILD_TOOLS_VERSION $ANDROID_BUILD_TOOLS_VERSION + +if [ -z "$NDK_ROOT" ] ; then + # + # Generic android-ndk + # + if [ -e /usr/local/android-ndk ] ; then + NDK_ROOT=/usr/local/android-ndk + elif [ -e /opt-linux-x86_64/android-ndk ] ; then + NDK_ROOT=/opt-linux-x86_64/android-ndk + elif [ -e /opt-linux-x86/android-ndk ] ; then + NDK_ROOT=/opt-linux-x86/android-ndk + elif [ -e /opt/android-ndk ] ; then + NDK_ROOT=/opt/android-ndk + # + # Specific android-ndk-r10d + # + elif [ -e /usr/local/android-ndk-r10d ] ; then + NDK_ROOT=/usr/local/android-ndk-r10d + elif [ -e /opt-linux-x86_64/android-ndk-r10d ] ; then + NDK_ROOT=/opt-linux-x86_64/android-ndk-r10d + elif [ -e /opt-linux-x86/android-ndk-r10d ] ; then + NDK_ROOT=/opt-linux-x86/android-ndk-r10d + elif [ -e /opt/android-ndk-r10d ] ; then + NDK_ROOT=/opt/android-ndk-r10d + else + echo NDK_ROOT is not specified and does not exist in default locations + exit 1 + fi +elif [ ! -e $NDK_ROOT ] ; then + echo NDK_ROOT $NDK_ROOT does not exist + exit 1 +fi +export NDK_ROOT + +if [ -z "$ANDROID_HOME" ] ; then + if [ -e /usr/local/android-sdk-linux_x86 ] ; then + ANDROID_HOME=/usr/local/android-sdk-linux_x86 + elif [ -e /opt-linux-x86/android-sdk-linux_x86 ] ; then + ANDROID_HOME=/opt-linux-x86/android-sdk-linux_x86 + elif [ -e /opt/android-sdk-linux_x86 ] ; then + ANDROID_HOME=/opt/android-sdk-linux_x86 + else + echo ANDROID_HOME is not specified and does not exist in default locations + exit 1 + fi +elif [ ! -e $ANDROID_HOME ] ; then + echo ANDROID_HOME $ANDROID_HOME does not exist + exit 1 +fi +export ANDROID_HOME + +if [ -z "$ANDROID_BUILD_TOOLS_VERSION" ] ; then + if [ -e $ANDROID_HOME/build-tools/21.1.2/zipalign ] ; then + ANDROID_BUILD_TOOLS_VERSION=21.1.2 + elif [ -e $ANDROID_HOME/build-tools/20.0.0/zipalign ] ; then + ANDROID_BUILD_TOOLS_VERSION=20.0.0 + else + echo ANDROID_BUILD_TOOLS_VERSION $ANDROID_HOME/build-tools/ANDROID_BUILD_TOOLS_VERSION/zipalign does not exist in default locations + exit 1 + fi +elif [ ! -e $ANDROID_HOME/build-tools/$ANDROID_BUILD_TOOLS_VERSION/zipalign ] ; then + echo ANDROID_BUILD_TOOLS_VERSION $ANDROID_HOME/build-tools/$ANDROID_BUILD_TOOLS_VERSION/zipalign does not exist + exit 1 +fi +export ANDROID_BUILD_TOOLS_VERSION + +echo Set +echo NDK_ROOT $NDK_ROOT +echo ANDROID_HOME $ANDROID_HOME +echo ANDROID_BUILD_TOOLS_VERSION $ANDROID_BUILD_TOOLS_VERSION + diff -Nru gluegen2-2.2.4/make/scripts/setenv-build-jogl-x86_64.sh gluegen2-2.3.2/make/scripts/setenv-build-jogl-x86_64.sh --- gluegen2-2.2.4/make/scripts/setenv-build-jogl-x86_64.sh 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/setenv-build-jogl-x86_64.sh 2015-10-09 04:18:28.000000000 +0000 @@ -15,13 +15,6 @@ fi fi if [ -z "$ANT_PATH" ] ; then - if [ -e /usr/share/ant/bin/ant -a -e /usr/share/ant/lib/ant.jar ] ; then - ANT_PATH=/usr/share/ant - export ANT_PATH - echo autosetting ANT_PATH to $ANT_PATH - fi -fi -if [ -z "$ANT_PATH" ] ; then echo ANT_PATH does not exist, set it exit fi diff -Nru gluegen2-2.2.4/make/scripts/test-win32-smb_share.bat gluegen2-2.3.2/make/scripts/test-win32-smb_share.bat --- gluegen2-2.2.4/make/scripts/test-win32-smb_share.bat 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/scripts/test-win32-smb_share.bat 2015-10-09 04:18:28.000000000 +0000 @@ -2,9 +2,9 @@ set SMB_ROOT=\\risa.goethel.localnet\deployment\test\jogamp set BLD_SUB=build-win32 -set J2RE_HOME=c:\jre1.7.0_45_x32 -set JAVA_HOME=c:\jdk1.7.0_45_x32 -set ANT_PATH=C:\apache-ant-1.8.2 +set J2RE_HOME=c:\jre1.8.0_60_x32 +set JAVA_HOME=c:\jdk1.8.0_60_x32 +set ANT_PATH=C:\apache-ant-1.9.4 set PROJECT_ROOT=%SMB_ROOT%\gluegen set BLD_DIR=%PROJECT_ROOT%\%BLD_SUB% diff -Nru gluegen2-2.2.4/make/stub_includes/gluegen/stdio.h gluegen2-2.3.2/make/stub_includes/gluegen/stdio.h --- gluegen2-2.2.4/make/stub_includes/gluegen/stdio.h 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/make/stub_includes/gluegen/stdio.h 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,7 @@ +#ifndef __stdio_h +#define __stdio_h + +#include + +#endif /* __stdio_h */ + diff -Nru gluegen2-2.2.4/make/stub_includes/jni/jawt.h gluegen2-2.3.2/make/stub_includes/jni/jawt.h --- gluegen2-2.2.4/make/stub_includes/jni/jawt.h 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/make/stub_includes/jni/jawt.h 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,106 @@ +/* + * @(#)jawt.h 1.11 05/11/17 + * + * This C header file is derived from Sun Microsystem's Java SDK provided C header file + * with the following copyright notice: + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * This version has complex comments removed and does not contain inlined algorithms etc, if any existed. + * + * The original C header file was included to JOGL on Sat Jun 21 02:10:30 2008 + * (commit cbc45e816f4ee81031bffce19a99550681462a24) by Sun Microsystem's staff and were approved. + * + * This C header file is included due to ensure compatibility with - and invocation of the JAWT protocol. + * They are processed by GlueGen to create a Java binding for JAWT invocation only. + * + * http://ftp.resource.org/courts.gov/c/F3/387/387.F3d.522.03-5400.html (36) + * "Atari Games Corp. v. Nintendo of Am., Inc., Nos. 88-4805 & 89-0027, 1993 WL 207548, at *1 (N.D.Cal. May 18, 1993) ("Atari III") + * ("Program code that is strictly necessary to achieve current compatibility presents a merger problem, almost by definition, + * and is thus excluded from the scope of any copyright.")." + * + * http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=OJ:L:2009:111:0016:0022:EN:PDF + * L 111/17 (10) and (15) + */ + +#ifndef _JAVASOFT_JAWT_H_ +#define _JAVASOFT_JAWT_H_ + +#include "jni.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * AWT native interface (new in JDK 1.3) + */ + +typedef struct jawt_Rectangle { + jint x; + jint y; + jint width; + jint height; +} JAWT_Rectangle; + +struct jawt_DrawingSurface; + +typedef struct jawt_DrawingSurfaceInfo { + void* platformInfo; + struct jawt_DrawingSurface* ds; + JAWT_Rectangle bounds; + jint clipSize; + JAWT_Rectangle* clip; +} JAWT_DrawingSurfaceInfo; + +#define JAWT_LOCK_ERROR 0x00000001 +#define JAWT_LOCK_CLIP_CHANGED 0x00000002 +#define JAWT_LOCK_BOUNDS_CHANGED 0x00000004 +#define JAWT_LOCK_SURFACE_CHANGED 0x00000008 + +typedef struct jawt_DrawingSurface { + JNIEnv* env; + jobject target; + jint (JNICALL *Lock) + (struct jawt_DrawingSurface* ds); + JAWT_DrawingSurfaceInfo* (JNICALL *GetDrawingSurfaceInfo) + (struct jawt_DrawingSurface* ds); + void (JNICALL *FreeDrawingSurfaceInfo) + (JAWT_DrawingSurfaceInfo* dsi); + void (JNICALL *Unlock) + (struct jawt_DrawingSurface* ds); +} JAWT_DrawingSurface; + +typedef struct jawt { + jint version; + JAWT_DrawingSurface* (JNICALL *GetDrawingSurface) + (JNIEnv* env, jobject target); + void (JNICALL *FreeDrawingSurface) + (JAWT_DrawingSurface* ds); + /* + * Since 1.4 + */ + void (JNICALL *Lock)(JNIEnv* env); + /* + * Since 1.4 + */ + void (JNICALL *Unlock)(JNIEnv* env); + /* + * Since 1.4 + */ + jobject (JNICALL *GetComponent)(JNIEnv* env, void* platformInfo); + +} JAWT; + +_JNI_IMPORT_OR_EXPORT_ +jboolean JNICALL JAWT_GetAWT(JNIEnv* env, JAWT* awt); + +#define JAWT_VERSION_1_3 0x00010003 +#define JAWT_VERSION_1_4 0x00010004 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* !_JAVASOFT_JAWT_H_ */ diff -Nru gluegen2-2.2.4/make/stub_includes/jni/jni.h gluegen2-2.3.2/make/stub_includes/jni/jni.h --- gluegen2-2.2.4/make/stub_includes/jni/jni.h 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/make/stub_includes/jni/jni.h 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,1934 @@ +/* + * @(#)jni.h 1.62 06/02/02 + * + * This C header file is derived from Sun Microsystem's Java SDK provided C header file + * with the following copyright notice: + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * This version has complex comments removed and does not contain inlined algorithms etc, if any existed. + * + * The original C header file was included to JOGL on Sat Jun 21 02:10:30 2008 + * (commit cbc45e816f4ee81031bffce19a99550681462a24) by Sun Microsystem's staff and were approved. + * + * This C header file is included due to ensure compatibility with - and invocation of the JAWT protocol. + * They are processed by GlueGen to create a Java binding for JAWT invocation only. + * + * http://ftp.resource.org/courts.gov/c/F3/387/387.F3d.522.03-5400.html (36) + * "Atari Games Corp. v. Nintendo of Am., Inc., Nos. 88-4805 & 89-0027, 1993 WL 207548, at *1 (N.D.Cal. May 18, 1993) ("Atari III") + * ("Program code that is strictly necessary to achieve current compatibility presents a merger problem, almost by definition, + * and is thus excluded from the scope of any copyright.")." + * + * http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=OJ:L:2009:111:0016:0022:EN:PDF + * L 111/17 (10) and (15) + */ + +/* + * We used part of Netscape's Java Runtime Interface (JRI) as the starting + * point of our design and implementation. + */ + +/****************************************************************************** + * Java Runtime Interface + * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved. + *****************************************************************************/ + +#ifndef _JAVASOFT_JNI_H_ +#define _JAVASOFT_JNI_H_ + +#include +#include +#include + +#include "jni_md.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H + +typedef uint8_t jboolean; +typedef uint16_t jchar; +typedef int16_t jshort; +typedef float jfloat; +typedef double jdouble; + +typedef jint jsize; + +#ifdef __cplusplus + +class _jobject {}; +class _jclass : public _jobject {}; +class _jthrowable : public _jobject {}; +class _jstring : public _jobject {}; +class _jarray : public _jobject {}; +class _jbooleanArray : public _jarray {}; +class _jbyteArray : public _jarray {}; +class _jcharArray : public _jarray {}; +class _jshortArray : public _jarray {}; +class _jintArray : public _jarray {}; +class _jlongArray : public _jarray {}; +class _jfloatArray : public _jarray {}; +class _jdoubleArray : public _jarray {}; +class _jobjectArray : public _jarray {}; + +typedef _jobject *jobject; +typedef _jclass *jclass; +typedef _jthrowable *jthrowable; +typedef _jstring *jstring; +typedef _jarray *jarray; +typedef _jbooleanArray *jbooleanArray; +typedef _jbyteArray *jbyteArray; +typedef _jcharArray *jcharArray; +typedef _jshortArray *jshortArray; +typedef _jintArray *jintArray; +typedef _jlongArray *jlongArray; +typedef _jfloatArray *jfloatArray; +typedef _jdoubleArray *jdoubleArray; +typedef _jobjectArray *jobjectArray; + +#else + +struct _jobject; + +typedef struct _jobject *jobject; +typedef jobject jclass; +typedef jobject jthrowable; +typedef jobject jstring; +typedef jobject jarray; +typedef jarray jbooleanArray; +typedef jarray jbyteArray; +typedef jarray jcharArray; +typedef jarray jshortArray; +typedef jarray jintArray; +typedef jarray jlongArray; +typedef jarray jfloatArray; +typedef jarray jdoubleArray; +typedef jarray jobjectArray; + +#endif + +typedef jobject jweak; + +typedef union jvalue { + jboolean z; + jbyte b; + jchar c; + jshort s; + jint i; + jlong j; + jfloat f; + jdouble d; + jobject l; +} jvalue; + +struct _jfieldID; +typedef struct _jfieldID *jfieldID; + +struct _jmethodID; +typedef struct _jmethodID *jmethodID; + +typedef enum _jobjectType { + JNIInvalidRefType = 0, + JNILocalRefType = 1, + JNIGlobalRefType = 2, + JNIWeakGlobalRefType = 3 +} jobjectRefType; + + +#endif /* JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H */ + +#define JNI_FALSE 0 +#define JNI_TRUE 1 + +#define JNI_OK 0 /* success */ +#define JNI_ERR (-1) /* unknown error */ +#define JNI_EDETACHED (-2) /* thread detached from the VM */ +#define JNI_EVERSION (-3) /* JNI version error */ +#define JNI_ENOMEM (-4) /* not enough memory */ +#define JNI_EEXIST (-5) /* VM already created */ +#define JNI_EINVAL (-6) /* invalid arguments */ + +#define JNI_COMMIT 1 +#define JNI_ABORT 2 + +#ifdef __GLUEGEN__ + +// GlueGen 'shortcut': We don't want to create bindings for JNI invocations! +// Hence dropping the JNI details, use-case: jawt.h + +/** Special opaque GlueGen handling of JNIEnv */ +typedef long JNIEnv; + +#define JDK1_2 +#define JDK1_4 + +#define _JNI_IMPORT_OR_EXPORT_ JNIIMPORT + +#define JNI_VERSION_1_1 0x00010001 +#define JNI_VERSION_1_2 0x00010002 +#define JNI_VERSION_1_4 0x00010004 +#define JNI_VERSION_1_6 0x00010006 + +#else /* __GLUEGEN__ */ + +typedef struct { + char *name; + char *signature; + void *fnPtr; +} JNINativeMethod; + +struct JNINativeInterface_; + +struct JNIEnv_; + +#ifdef __cplusplus +typedef JNIEnv_ JNIEnv; +#else +typedef const struct JNINativeInterface_ *JNIEnv; +#endif + +struct JNIInvokeInterface_; + +struct JavaVM_; + +#ifdef __cplusplus +typedef JavaVM_ JavaVM; +#else +typedef const struct JNIInvokeInterface_ *JavaVM; +#endif + +struct JNINativeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + void *reserved3; + jint (JNICALL *GetVersion)(JNIEnv *env); + + jclass (JNICALL *DefineClass) + (JNIEnv *env, const char *name, jobject loader, const jbyte *buf, + jsize len); + jclass (JNICALL *FindClass) + (JNIEnv *env, const char *name); + + jmethodID (JNICALL *FromReflectedMethod) + (JNIEnv *env, jobject method); + jfieldID (JNICALL *FromReflectedField) + (JNIEnv *env, jobject field); + + jobject (JNICALL *ToReflectedMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic); + + jclass (JNICALL *GetSuperclass) + (JNIEnv *env, jclass sub); + jboolean (JNICALL *IsAssignableFrom) + (JNIEnv *env, jclass sub, jclass sup); + + jobject (JNICALL *ToReflectedField) + (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic); + + jint (JNICALL *Throw) + (JNIEnv *env, jthrowable obj); + jint (JNICALL *ThrowNew) + (JNIEnv *env, jclass clazz, const char *msg); + jthrowable (JNICALL *ExceptionOccurred) + (JNIEnv *env); + void (JNICALL *ExceptionDescribe) + (JNIEnv *env); + void (JNICALL *ExceptionClear) + (JNIEnv *env); + void (JNICALL *FatalError) + (JNIEnv *env, const char *msg); + + jint (JNICALL *PushLocalFrame) + (JNIEnv *env, jint capacity); + jobject (JNICALL *PopLocalFrame) + (JNIEnv *env, jobject result); + + jobject (JNICALL *NewGlobalRef) + (JNIEnv *env, jobject lobj); + void (JNICALL *DeleteGlobalRef) + (JNIEnv *env, jobject gref); + void (JNICALL *DeleteLocalRef) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsSameObject) + (JNIEnv *env, jobject obj1, jobject obj2); + jobject (JNICALL *NewLocalRef) + (JNIEnv *env, jobject ref); + jint (JNICALL *EnsureLocalCapacity) + (JNIEnv *env, jint capacity); + + jobject (JNICALL *AllocObject) + (JNIEnv *env, jclass clazz); + jobject (JNICALL *NewObject) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *NewObjectV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *NewObjectA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jclass (JNICALL *GetObjectClass) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsInstanceOf) + (JNIEnv *env, jobject obj, jclass clazz); + + jmethodID (JNICALL *GetMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallObjectMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jobject (JNICALL *CallObjectMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jobject (JNICALL *CallObjectMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jboolean (JNICALL *CallBooleanMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jboolean (JNICALL *CallBooleanMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jboolean (JNICALL *CallBooleanMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jbyte (JNICALL *CallByteMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jbyte (JNICALL *CallByteMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jbyte (JNICALL *CallByteMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jchar (JNICALL *CallCharMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jchar (JNICALL *CallCharMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jchar (JNICALL *CallCharMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jshort (JNICALL *CallShortMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jshort (JNICALL *CallShortMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jshort (JNICALL *CallShortMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jint (JNICALL *CallIntMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jint (JNICALL *CallIntMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jint (JNICALL *CallIntMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jlong (JNICALL *CallLongMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jlong (JNICALL *CallLongMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jlong (JNICALL *CallLongMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jfloat (JNICALL *CallFloatMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jfloat (JNICALL *CallFloatMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jfloat (JNICALL *CallFloatMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jdouble (JNICALL *CallDoubleMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jdouble (JNICALL *CallDoubleMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jdouble (JNICALL *CallDoubleMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + void (JNICALL *CallVoidMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + void (JNICALL *CallVoidMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + void (JNICALL *CallVoidMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jobject (JNICALL *CallNonvirtualObjectMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallNonvirtualObjectMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jobject (JNICALL *CallNonvirtualObjectMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jboolean (JNICALL *CallNonvirtualBooleanMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallNonvirtualBooleanMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jboolean (JNICALL *CallNonvirtualBooleanMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jbyte (JNICALL *CallNonvirtualByteMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallNonvirtualByteMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jbyte (JNICALL *CallNonvirtualByteMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jchar (JNICALL *CallNonvirtualCharMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallNonvirtualCharMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jchar (JNICALL *CallNonvirtualCharMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jshort (JNICALL *CallNonvirtualShortMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallNonvirtualShortMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jshort (JNICALL *CallNonvirtualShortMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jint (JNICALL *CallNonvirtualIntMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallNonvirtualIntMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jint (JNICALL *CallNonvirtualIntMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jlong (JNICALL *CallNonvirtualLongMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallNonvirtualLongMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jlong (JNICALL *CallNonvirtualLongMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jfloat (JNICALL *CallNonvirtualFloatMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallNonvirtualFloatMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jfloat (JNICALL *CallNonvirtualFloatMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jdouble (JNICALL *CallNonvirtualDoubleMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallNonvirtualDoubleMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jdouble (JNICALL *CallNonvirtualDoubleMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + void (JNICALL *CallNonvirtualVoidMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + void (JNICALL *CallNonvirtualVoidMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + void (JNICALL *CallNonvirtualVoidMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jfieldID (JNICALL *GetFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *GetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jboolean (JNICALL *GetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jbyte (JNICALL *GetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jchar (JNICALL *GetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jshort (JNICALL *GetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jint (JNICALL *GetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jlong (JNICALL *GetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jfloat (JNICALL *GetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jdouble (JNICALL *GetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + + void (JNICALL *SetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val); + void (JNICALL *SetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val); + void (JNICALL *SetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val); + void (JNICALL *SetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val); + void (JNICALL *SetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val); + void (JNICALL *SetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jint val); + void (JNICALL *SetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val); + void (JNICALL *SetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val); + void (JNICALL *SetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val); + + jmethodID (JNICALL *GetStaticMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallStaticObjectMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallStaticObjectMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *CallStaticObjectMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jboolean (JNICALL *CallStaticBooleanMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallStaticBooleanMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jboolean (JNICALL *CallStaticBooleanMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jbyte (JNICALL *CallStaticByteMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallStaticByteMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jbyte (JNICALL *CallStaticByteMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jchar (JNICALL *CallStaticCharMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallStaticCharMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jchar (JNICALL *CallStaticCharMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jshort (JNICALL *CallStaticShortMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallStaticShortMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jshort (JNICALL *CallStaticShortMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jint (JNICALL *CallStaticIntMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallStaticIntMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jint (JNICALL *CallStaticIntMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jlong (JNICALL *CallStaticLongMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallStaticLongMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jlong (JNICALL *CallStaticLongMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jfloat (JNICALL *CallStaticFloatMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallStaticFloatMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jfloat (JNICALL *CallStaticFloatMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jdouble (JNICALL *CallStaticDoubleMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallStaticDoubleMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jdouble (JNICALL *CallStaticDoubleMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + void (JNICALL *CallStaticVoidMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, ...); + void (JNICALL *CallStaticVoidMethodV) + (JNIEnv *env, jclass cls, jmethodID methodID, va_list args); + void (JNICALL *CallStaticVoidMethodA) + (JNIEnv *env, jclass cls, jmethodID methodID, const jvalue * args); + + jfieldID (JNICALL *GetStaticFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + jobject (JNICALL *GetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jboolean (JNICALL *GetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jbyte (JNICALL *GetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jchar (JNICALL *GetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jshort (JNICALL *GetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jint (JNICALL *GetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jlong (JNICALL *GetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jfloat (JNICALL *GetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jdouble (JNICALL *GetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + + void (JNICALL *SetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value); + void (JNICALL *SetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value); + void (JNICALL *SetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value); + void (JNICALL *SetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value); + void (JNICALL *SetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value); + void (JNICALL *SetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value); + void (JNICALL *SetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value); + void (JNICALL *SetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value); + void (JNICALL *SetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value); + + jstring (JNICALL *NewString) + (JNIEnv *env, const jchar *unicode, jsize len); + jsize (JNICALL *GetStringLength) + (JNIEnv *env, jstring str); + const jchar *(JNICALL *GetStringChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringChars) + (JNIEnv *env, jstring str, const jchar *chars); + + jstring (JNICALL *NewStringUTF) + (JNIEnv *env, const char *utf); + jsize (JNICALL *GetStringUTFLength) + (JNIEnv *env, jstring str); + const char* (JNICALL *GetStringUTFChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringUTFChars) + (JNIEnv *env, jstring str, const char* chars); + + + jsize (JNICALL *GetArrayLength) + (JNIEnv *env, jarray array); + + jobjectArray (JNICALL *NewObjectArray) + (JNIEnv *env, jsize len, jclass clazz, jobject init); + jobject (JNICALL *GetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index); + void (JNICALL *SetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index, jobject val); + + jbooleanArray (JNICALL *NewBooleanArray) + (JNIEnv *env, jsize len); + jbyteArray (JNICALL *NewByteArray) + (JNIEnv *env, jsize len); + jcharArray (JNICALL *NewCharArray) + (JNIEnv *env, jsize len); + jshortArray (JNICALL *NewShortArray) + (JNIEnv *env, jsize len); + jintArray (JNICALL *NewIntArray) + (JNIEnv *env, jsize len); + jlongArray (JNICALL *NewLongArray) + (JNIEnv *env, jsize len); + jfloatArray (JNICALL *NewFloatArray) + (JNIEnv *env, jsize len); + jdoubleArray (JNICALL *NewDoubleArray) + (JNIEnv *env, jsize len); + + jboolean * (JNICALL *GetBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *isCopy); + jbyte * (JNICALL *GetByteArrayElements) + (JNIEnv *env, jbyteArray array, jboolean *isCopy); + jchar * (JNICALL *GetCharArrayElements) + (JNIEnv *env, jcharArray array, jboolean *isCopy); + jshort * (JNICALL *GetShortArrayElements) + (JNIEnv *env, jshortArray array, jboolean *isCopy); + jint * (JNICALL *GetIntArrayElements) + (JNIEnv *env, jintArray array, jboolean *isCopy); + jlong * (JNICALL *GetLongArrayElements) + (JNIEnv *env, jlongArray array, jboolean *isCopy); + jfloat * (JNICALL *GetFloatArrayElements) + (JNIEnv *env, jfloatArray array, jboolean *isCopy); + jdouble * (JNICALL *GetDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jboolean *isCopy); + + void (JNICALL *ReleaseBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode); + void (JNICALL *ReleaseByteArrayElements) + (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode); + void (JNICALL *ReleaseCharArrayElements) + (JNIEnv *env, jcharArray array, jchar *elems, jint mode); + void (JNICALL *ReleaseShortArrayElements) + (JNIEnv *env, jshortArray array, jshort *elems, jint mode); + void (JNICALL *ReleaseIntArrayElements) + (JNIEnv *env, jintArray array, jint *elems, jint mode); + void (JNICALL *ReleaseLongArrayElements) + (JNIEnv *env, jlongArray array, jlong *elems, jint mode); + void (JNICALL *ReleaseFloatArrayElements) + (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode); + void (JNICALL *ReleaseDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode); + + void (JNICALL *GetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); + void (JNICALL *GetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); + void (JNICALL *GetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); + void (JNICALL *GetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); + void (JNICALL *GetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); + void (JNICALL *GetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); + void (JNICALL *GetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); + void (JNICALL *GetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); + + void (JNICALL *SetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, const jboolean *buf); + void (JNICALL *SetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, const jbyte *buf); + void (JNICALL *SetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, const jchar *buf); + void (JNICALL *SetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, const jshort *buf); + void (JNICALL *SetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, const jint *buf); + void (JNICALL *SetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, const jlong *buf); + void (JNICALL *SetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, const jfloat *buf); + void (JNICALL *SetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, const jdouble *buf); + + jint (JNICALL *RegisterNatives) + (JNIEnv *env, jclass clazz, const JNINativeMethod *methods, + jint nMethods); + jint (JNICALL *UnregisterNatives) + (JNIEnv *env, jclass clazz); + + jint (JNICALL *MonitorEnter) + (JNIEnv *env, jobject obj); + jint (JNICALL *MonitorExit) + (JNIEnv *env, jobject obj); + + jint (JNICALL *GetJavaVM) + (JNIEnv *env, JavaVM **vm); + + void (JNICALL *GetStringRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf); + void (JNICALL *GetStringUTFRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, char *buf); + + void * (JNICALL *GetPrimitiveArrayCritical) + (JNIEnv *env, jarray array, jboolean *isCopy); + void (JNICALL *ReleasePrimitiveArrayCritical) + (JNIEnv *env, jarray array, void *carray, jint mode); + + const jchar * (JNICALL *GetStringCritical) + (JNIEnv *env, jstring string, jboolean *isCopy); + void (JNICALL *ReleaseStringCritical) + (JNIEnv *env, jstring string, const jchar *cstring); + + jweak (JNICALL *NewWeakGlobalRef) + (JNIEnv *env, jobject obj); + void (JNICALL *DeleteWeakGlobalRef) + (JNIEnv *env, jweak ref); + + jboolean (JNICALL *ExceptionCheck) + (JNIEnv *env); + + jobject (JNICALL *NewDirectByteBuffer) + (JNIEnv* env, void* address, jlong capacity); + void* (JNICALL *GetDirectBufferAddress) + (JNIEnv* env, jobject buf); + jlong (JNICALL *GetDirectBufferCapacity) + (JNIEnv* env, jobject buf); + + /* New JNI 1.6 Features */ + + jobjectRefType (JNICALL *GetObjectRefType) + (JNIEnv* env, jobject obj); +}; + +struct JNIEnv_ { + const struct JNINativeInterface_ *functions; +#ifdef __cplusplus + + jint GetVersion() { + return functions->GetVersion(this); + } + jclass DefineClass(const char *name, jobject loader, const jbyte *buf, + jsize len) { + return functions->DefineClass(this, name, loader, buf, len); + } + jclass FindClass(const char *name) { + return functions->FindClass(this, name); + } + jmethodID FromReflectedMethod(jobject method) { + return functions->FromReflectedMethod(this,method); + } + jfieldID FromReflectedField(jobject field) { + return functions->FromReflectedField(this,field); + } + + jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) { + return functions->ToReflectedMethod(this, cls, methodID, isStatic); + } + + jclass GetSuperclass(jclass sub) { + return functions->GetSuperclass(this, sub); + } + jboolean IsAssignableFrom(jclass sub, jclass sup) { + return functions->IsAssignableFrom(this, sub, sup); + } + + jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) { + return functions->ToReflectedField(this,cls,fieldID,isStatic); + } + + jint Throw(jthrowable obj) { + return functions->Throw(this, obj); + } + jint ThrowNew(jclass clazz, const char *msg) { + return functions->ThrowNew(this, clazz, msg); + } + jthrowable ExceptionOccurred() { + return functions->ExceptionOccurred(this); + } + void ExceptionDescribe() { + functions->ExceptionDescribe(this); + } + void ExceptionClear() { + functions->ExceptionClear(this); + } + void FatalError(const char *msg) { + functions->FatalError(this, msg); + } + + jint PushLocalFrame(jint capacity) { + return functions->PushLocalFrame(this,capacity); + } + jobject PopLocalFrame(jobject result) { + return functions->PopLocalFrame(this,result); + } + + jobject NewGlobalRef(jobject lobj) { + return functions->NewGlobalRef(this,lobj); + } + void DeleteGlobalRef(jobject gref) { + functions->DeleteGlobalRef(this,gref); + } + void DeleteLocalRef(jobject obj) { + functions->DeleteLocalRef(this, obj); + } + + jboolean IsSameObject(jobject obj1, jobject obj2) { + return functions->IsSameObject(this,obj1,obj2); + } + + jobject NewLocalRef(jobject ref) { + return functions->NewLocalRef(this,ref); + } + jint EnsureLocalCapacity(jint capacity) { + return functions->EnsureLocalCapacity(this,capacity); + } + + jobject AllocObject(jclass clazz) { + return functions->AllocObject(this,clazz); + } + jobject NewObject(jclass clazz, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args, methodID); + result = functions->NewObjectV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject NewObjectV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->NewObjectV(this,clazz,methodID,args); + } + jobject NewObjectA(jclass clazz, jmethodID methodID, + const jvalue *args) { + return functions->NewObjectA(this,clazz,methodID,args); + } + + jclass GetObjectClass(jobject obj) { + return functions->GetObjectClass(this,obj); + } + jboolean IsInstanceOf(jobject obj, jclass clazz) { + return functions->IsInstanceOf(this,obj,clazz); + } + + jmethodID GetMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetMethodID(this,clazz,name,sig); + } + + jobject CallObjectMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallObjectMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jobject CallObjectMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallObjectMethodV(this,obj,methodID,args); + } + jobject CallObjectMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallObjectMethodA(this,obj,methodID,args); + } + + jboolean CallBooleanMethod(jobject obj, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallBooleanMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jboolean CallBooleanMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallBooleanMethodV(this,obj,methodID,args); + } + jboolean CallBooleanMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallBooleanMethodA(this,obj,methodID, args); + } + + jbyte CallByteMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallByteMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jbyte CallByteMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallByteMethodV(this,obj,methodID,args); + } + jbyte CallByteMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallByteMethodA(this,obj,methodID,args); + } + + jchar CallCharMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallCharMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jchar CallCharMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallCharMethodV(this,obj,methodID,args); + } + jchar CallCharMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallCharMethodA(this,obj,methodID,args); + } + + jshort CallShortMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallShortMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jshort CallShortMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallShortMethodV(this,obj,methodID,args); + } + jshort CallShortMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallShortMethodA(this,obj,methodID,args); + } + + jint CallIntMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallIntMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jint CallIntMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallIntMethodV(this,obj,methodID,args); + } + jint CallIntMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallIntMethodA(this,obj,methodID,args); + } + + jlong CallLongMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallLongMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jlong CallLongMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallLongMethodV(this,obj,methodID,args); + } + jlong CallLongMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallLongMethodA(this,obj,methodID,args); + } + + jfloat CallFloatMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallFloatMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jfloat CallFloatMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallFloatMethodV(this,obj,methodID,args); + } + jfloat CallFloatMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallFloatMethodA(this,obj,methodID,args); + } + + jdouble CallDoubleMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallDoubleMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jdouble CallDoubleMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallDoubleMethodV(this,obj,methodID,args); + } + jdouble CallDoubleMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallDoubleMethodA(this,obj,methodID,args); + } + + void CallVoidMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallVoidMethodV(this,obj,methodID,args); + va_end(args); + } + void CallVoidMethodV(jobject obj, jmethodID methodID, + va_list args) { + functions->CallVoidMethodV(this,obj,methodID,args); + } + void CallVoidMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + functions->CallVoidMethodA(this,obj,methodID,args); + } + + jobject CallNonvirtualObjectMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jobject CallNonvirtualObjectMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + } + jobject CallNonvirtualObjectMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualObjectMethodA(this,obj,clazz, + methodID,args); + } + + jboolean CallNonvirtualBooleanMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jboolean CallNonvirtualBooleanMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + } + jboolean CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualBooleanMethodA(this,obj,clazz, + methodID, args); + } + + jbyte CallNonvirtualByteMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jbyte CallNonvirtualByteMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + } + jbyte CallNonvirtualByteMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualByteMethodA(this,obj,clazz, + methodID,args); + } + + jchar CallNonvirtualCharMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jchar CallNonvirtualCharMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + } + jchar CallNonvirtualCharMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualCharMethodA(this,obj,clazz, + methodID,args); + } + + jshort CallNonvirtualShortMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jshort CallNonvirtualShortMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + } + jshort CallNonvirtualShortMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualShortMethodA(this,obj,clazz, + methodID,args); + } + + jint CallNonvirtualIntMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jint CallNonvirtualIntMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + } + jint CallNonvirtualIntMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualIntMethodA(this,obj,clazz, + methodID,args); + } + + jlong CallNonvirtualLongMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jlong CallNonvirtualLongMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + } + jlong CallNonvirtualLongMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualLongMethodA(this,obj,clazz, + methodID,args); + } + + jfloat CallNonvirtualFloatMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jfloat CallNonvirtualFloatMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + } + jfloat CallNonvirtualFloatMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + return functions->CallNonvirtualFloatMethodA(this,obj,clazz, + methodID,args); + } + + jdouble CallNonvirtualDoubleMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jdouble CallNonvirtualDoubleMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + } + jdouble CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + return functions->CallNonvirtualDoubleMethodA(this,obj,clazz, + methodID,args); + } + + void CallNonvirtualVoidMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + va_end(args); + } + void CallNonvirtualVoidMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + } + void CallNonvirtualVoidMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + functions->CallNonvirtualVoidMethodA(this,obj,clazz,methodID,args); + } + + jfieldID GetFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetFieldID(this,clazz,name,sig); + } + + jobject GetObjectField(jobject obj, jfieldID fieldID) { + return functions->GetObjectField(this,obj,fieldID); + } + jboolean GetBooleanField(jobject obj, jfieldID fieldID) { + return functions->GetBooleanField(this,obj,fieldID); + } + jbyte GetByteField(jobject obj, jfieldID fieldID) { + return functions->GetByteField(this,obj,fieldID); + } + jchar GetCharField(jobject obj, jfieldID fieldID) { + return functions->GetCharField(this,obj,fieldID); + } + jshort GetShortField(jobject obj, jfieldID fieldID) { + return functions->GetShortField(this,obj,fieldID); + } + jint GetIntField(jobject obj, jfieldID fieldID) { + return functions->GetIntField(this,obj,fieldID); + } + jlong GetLongField(jobject obj, jfieldID fieldID) { + return functions->GetLongField(this,obj,fieldID); + } + jfloat GetFloatField(jobject obj, jfieldID fieldID) { + return functions->GetFloatField(this,obj,fieldID); + } + jdouble GetDoubleField(jobject obj, jfieldID fieldID) { + return functions->GetDoubleField(this,obj,fieldID); + } + + void SetObjectField(jobject obj, jfieldID fieldID, jobject val) { + functions->SetObjectField(this,obj,fieldID,val); + } + void SetBooleanField(jobject obj, jfieldID fieldID, + jboolean val) { + functions->SetBooleanField(this,obj,fieldID,val); + } + void SetByteField(jobject obj, jfieldID fieldID, + jbyte val) { + functions->SetByteField(this,obj,fieldID,val); + } + void SetCharField(jobject obj, jfieldID fieldID, + jchar val) { + functions->SetCharField(this,obj,fieldID,val); + } + void SetShortField(jobject obj, jfieldID fieldID, + jshort val) { + functions->SetShortField(this,obj,fieldID,val); + } + void SetIntField(jobject obj, jfieldID fieldID, + jint val) { + functions->SetIntField(this,obj,fieldID,val); + } + void SetLongField(jobject obj, jfieldID fieldID, + jlong val) { + functions->SetLongField(this,obj,fieldID,val); + } + void SetFloatField(jobject obj, jfieldID fieldID, + jfloat val) { + functions->SetFloatField(this,obj,fieldID,val); + } + void SetDoubleField(jobject obj, jfieldID fieldID, + jdouble val) { + functions->SetDoubleField(this,obj,fieldID,val); + } + + jmethodID GetStaticMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticMethodID(this,clazz,name,sig); + } + + jobject CallStaticObjectMethod(jclass clazz, jmethodID methodID, + ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallStaticObjectMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject CallStaticObjectMethodV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->CallStaticObjectMethodV(this,clazz,methodID,args); + } + jobject CallStaticObjectMethodA(jclass clazz, jmethodID methodID, + const jvalue *args) { + return functions->CallStaticObjectMethodA(this,clazz,methodID,args); + } + + jboolean CallStaticBooleanMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jboolean CallStaticBooleanMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + } + jboolean CallStaticBooleanMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticBooleanMethodA(this,clazz,methodID,args); + } + + jbyte CallStaticByteMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallStaticByteMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jbyte CallStaticByteMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticByteMethodV(this,clazz,methodID,args); + } + jbyte CallStaticByteMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticByteMethodA(this,clazz,methodID,args); + } + + jchar CallStaticCharMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallStaticCharMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jchar CallStaticCharMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticCharMethodV(this,clazz,methodID,args); + } + jchar CallStaticCharMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticCharMethodA(this,clazz,methodID,args); + } + + jshort CallStaticShortMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallStaticShortMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jshort CallStaticShortMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticShortMethodV(this,clazz,methodID,args); + } + jshort CallStaticShortMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticShortMethodA(this,clazz,methodID,args); + } + + jint CallStaticIntMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallStaticIntMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jint CallStaticIntMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticIntMethodV(this,clazz,methodID,args); + } + jint CallStaticIntMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticIntMethodA(this,clazz,methodID,args); + } + + jlong CallStaticLongMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallStaticLongMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jlong CallStaticLongMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticLongMethodV(this,clazz,methodID,args); + } + jlong CallStaticLongMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticLongMethodA(this,clazz,methodID,args); + } + + jfloat CallStaticFloatMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallStaticFloatMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jfloat CallStaticFloatMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticFloatMethodV(this,clazz,methodID,args); + } + jfloat CallStaticFloatMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticFloatMethodA(this,clazz,methodID,args); + } + + jdouble CallStaticDoubleMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jdouble CallStaticDoubleMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + } + jdouble CallStaticDoubleMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticDoubleMethodA(this,clazz,methodID,args); + } + + void CallStaticVoidMethod(jclass cls, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallStaticVoidMethodV(this,cls,methodID,args); + va_end(args); + } + void CallStaticVoidMethodV(jclass cls, jmethodID methodID, + va_list args) { + functions->CallStaticVoidMethodV(this,cls,methodID,args); + } + void CallStaticVoidMethodA(jclass cls, jmethodID methodID, + const jvalue * args) { + functions->CallStaticVoidMethodA(this,cls,methodID,args); + } + + jfieldID GetStaticFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticFieldID(this,clazz,name,sig); + } + jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticObjectField(this,clazz,fieldID); + } + jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticBooleanField(this,clazz,fieldID); + } + jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticByteField(this,clazz,fieldID); + } + jchar GetStaticCharField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticCharField(this,clazz,fieldID); + } + jshort GetStaticShortField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticShortField(this,clazz,fieldID); + } + jint GetStaticIntField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticIntField(this,clazz,fieldID); + } + jlong GetStaticLongField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticLongField(this,clazz,fieldID); + } + jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticFloatField(this,clazz,fieldID); + } + jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticDoubleField(this,clazz,fieldID); + } + + void SetStaticObjectField(jclass clazz, jfieldID fieldID, + jobject value) { + functions->SetStaticObjectField(this,clazz,fieldID,value); + } + void SetStaticBooleanField(jclass clazz, jfieldID fieldID, + jboolean value) { + functions->SetStaticBooleanField(this,clazz,fieldID,value); + } + void SetStaticByteField(jclass clazz, jfieldID fieldID, + jbyte value) { + functions->SetStaticByteField(this,clazz,fieldID,value); + } + void SetStaticCharField(jclass clazz, jfieldID fieldID, + jchar value) { + functions->SetStaticCharField(this,clazz,fieldID,value); + } + void SetStaticShortField(jclass clazz, jfieldID fieldID, + jshort value) { + functions->SetStaticShortField(this,clazz,fieldID,value); + } + void SetStaticIntField(jclass clazz, jfieldID fieldID, + jint value) { + functions->SetStaticIntField(this,clazz,fieldID,value); + } + void SetStaticLongField(jclass clazz, jfieldID fieldID, + jlong value) { + functions->SetStaticLongField(this,clazz,fieldID,value); + } + void SetStaticFloatField(jclass clazz, jfieldID fieldID, + jfloat value) { + functions->SetStaticFloatField(this,clazz,fieldID,value); + } + void SetStaticDoubleField(jclass clazz, jfieldID fieldID, + jdouble value) { + functions->SetStaticDoubleField(this,clazz,fieldID,value); + } + + jstring NewString(const jchar *unicode, jsize len) { + return functions->NewString(this,unicode,len); + } + jsize GetStringLength(jstring str) { + return functions->GetStringLength(this,str); + } + const jchar *GetStringChars(jstring str, jboolean *isCopy) { + return functions->GetStringChars(this,str,isCopy); + } + void ReleaseStringChars(jstring str, const jchar *chars) { + functions->ReleaseStringChars(this,str,chars); + } + + jstring NewStringUTF(const char *utf) { + return functions->NewStringUTF(this,utf); + } + jsize GetStringUTFLength(jstring str) { + return functions->GetStringUTFLength(this,str); + } + const char* GetStringUTFChars(jstring str, jboolean *isCopy) { + return functions->GetStringUTFChars(this,str,isCopy); + } + void ReleaseStringUTFChars(jstring str, const char* chars) { + functions->ReleaseStringUTFChars(this,str,chars); + } + + jsize GetArrayLength(jarray array) { + return functions->GetArrayLength(this,array); + } + + jobjectArray NewObjectArray(jsize len, jclass clazz, + jobject init) { + return functions->NewObjectArray(this,len,clazz,init); + } + jobject GetObjectArrayElement(jobjectArray array, jsize index) { + return functions->GetObjectArrayElement(this,array,index); + } + void SetObjectArrayElement(jobjectArray array, jsize index, + jobject val) { + functions->SetObjectArrayElement(this,array,index,val); + } + + jbooleanArray NewBooleanArray(jsize len) { + return functions->NewBooleanArray(this,len); + } + jbyteArray NewByteArray(jsize len) { + return functions->NewByteArray(this,len); + } + jcharArray NewCharArray(jsize len) { + return functions->NewCharArray(this,len); + } + jshortArray NewShortArray(jsize len) { + return functions->NewShortArray(this,len); + } + jintArray NewIntArray(jsize len) { + return functions->NewIntArray(this,len); + } + jlongArray NewLongArray(jsize len) { + return functions->NewLongArray(this,len); + } + jfloatArray NewFloatArray(jsize len) { + return functions->NewFloatArray(this,len); + } + jdoubleArray NewDoubleArray(jsize len) { + return functions->NewDoubleArray(this,len); + } + + jboolean * GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy) { + return functions->GetBooleanArrayElements(this,array,isCopy); + } + jbyte * GetByteArrayElements(jbyteArray array, jboolean *isCopy) { + return functions->GetByteArrayElements(this,array,isCopy); + } + jchar * GetCharArrayElements(jcharArray array, jboolean *isCopy) { + return functions->GetCharArrayElements(this,array,isCopy); + } + jshort * GetShortArrayElements(jshortArray array, jboolean *isCopy) { + return functions->GetShortArrayElements(this,array,isCopy); + } + jint * GetIntArrayElements(jintArray array, jboolean *isCopy) { + return functions->GetIntArrayElements(this,array,isCopy); + } + jlong * GetLongArrayElements(jlongArray array, jboolean *isCopy) { + return functions->GetLongArrayElements(this,array,isCopy); + } + jfloat * GetFloatArrayElements(jfloatArray array, jboolean *isCopy) { + return functions->GetFloatArrayElements(this,array,isCopy); + } + jdouble * GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy) { + return functions->GetDoubleArrayElements(this,array,isCopy); + } + + void ReleaseBooleanArrayElements(jbooleanArray array, + jboolean *elems, + jint mode) { + functions->ReleaseBooleanArrayElements(this,array,elems,mode); + } + void ReleaseByteArrayElements(jbyteArray array, + jbyte *elems, + jint mode) { + functions->ReleaseByteArrayElements(this,array,elems,mode); + } + void ReleaseCharArrayElements(jcharArray array, + jchar *elems, + jint mode) { + functions->ReleaseCharArrayElements(this,array,elems,mode); + } + void ReleaseShortArrayElements(jshortArray array, + jshort *elems, + jint mode) { + functions->ReleaseShortArrayElements(this,array,elems,mode); + } + void ReleaseIntArrayElements(jintArray array, + jint *elems, + jint mode) { + functions->ReleaseIntArrayElements(this,array,elems,mode); + } + void ReleaseLongArrayElements(jlongArray array, + jlong *elems, + jint mode) { + functions->ReleaseLongArrayElements(this,array,elems,mode); + } + void ReleaseFloatArrayElements(jfloatArray array, + jfloat *elems, + jint mode) { + functions->ReleaseFloatArrayElements(this,array,elems,mode); + } + void ReleaseDoubleArrayElements(jdoubleArray array, + jdouble *elems, + jint mode) { + functions->ReleaseDoubleArrayElements(this,array,elems,mode); + } + + void GetBooleanArrayRegion(jbooleanArray array, + jsize start, jsize len, jboolean *buf) { + functions->GetBooleanArrayRegion(this,array,start,len,buf); + } + void GetByteArrayRegion(jbyteArray array, + jsize start, jsize len, jbyte *buf) { + functions->GetByteArrayRegion(this,array,start,len,buf); + } + void GetCharArrayRegion(jcharArray array, + jsize start, jsize len, jchar *buf) { + functions->GetCharArrayRegion(this,array,start,len,buf); + } + void GetShortArrayRegion(jshortArray array, + jsize start, jsize len, jshort *buf) { + functions->GetShortArrayRegion(this,array,start,len,buf); + } + void GetIntArrayRegion(jintArray array, + jsize start, jsize len, jint *buf) { + functions->GetIntArrayRegion(this,array,start,len,buf); + } + void GetLongArrayRegion(jlongArray array, + jsize start, jsize len, jlong *buf) { + functions->GetLongArrayRegion(this,array,start,len,buf); + } + void GetFloatArrayRegion(jfloatArray array, + jsize start, jsize len, jfloat *buf) { + functions->GetFloatArrayRegion(this,array,start,len,buf); + } + void GetDoubleArrayRegion(jdoubleArray array, + jsize start, jsize len, jdouble *buf) { + functions->GetDoubleArrayRegion(this,array,start,len,buf); + } + + void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, + const jboolean *buf) { + functions->SetBooleanArrayRegion(this,array,start,len,buf); + } + void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, + const jbyte *buf) { + functions->SetByteArrayRegion(this,array,start,len,buf); + } + void SetCharArrayRegion(jcharArray array, jsize start, jsize len, + const jchar *buf) { + functions->SetCharArrayRegion(this,array,start,len,buf); + } + void SetShortArrayRegion(jshortArray array, jsize start, jsize len, + const jshort *buf) { + functions->SetShortArrayRegion(this,array,start,len,buf); + } + void SetIntArrayRegion(jintArray array, jsize start, jsize len, + const jint *buf) { + functions->SetIntArrayRegion(this,array,start,len,buf); + } + void SetLongArrayRegion(jlongArray array, jsize start, jsize len, + const jlong *buf) { + functions->SetLongArrayRegion(this,array,start,len,buf); + } + void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, + const jfloat *buf) { + functions->SetFloatArrayRegion(this,array,start,len,buf); + } + void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, + const jdouble *buf) { + functions->SetDoubleArrayRegion(this,array,start,len,buf); + } + + jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, + jint nMethods) { + return functions->RegisterNatives(this,clazz,methods,nMethods); + } + jint UnregisterNatives(jclass clazz) { + return functions->UnregisterNatives(this,clazz); + } + + jint MonitorEnter(jobject obj) { + return functions->MonitorEnter(this,obj); + } + jint MonitorExit(jobject obj) { + return functions->MonitorExit(this,obj); + } + + jint GetJavaVM(JavaVM **vm) { + return functions->GetJavaVM(this,vm); + } + + void GetStringRegion(jstring str, jsize start, jsize len, jchar *buf) { + functions->GetStringRegion(this,str,start,len,buf); + } + void GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf) { + functions->GetStringUTFRegion(this,str,start,len,buf); + } + + void * GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) { + return functions->GetPrimitiveArrayCritical(this,array,isCopy); + } + void ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode) { + functions->ReleasePrimitiveArrayCritical(this,array,carray,mode); + } + + const jchar * GetStringCritical(jstring string, jboolean *isCopy) { + return functions->GetStringCritical(this,string,isCopy); + } + void ReleaseStringCritical(jstring string, const jchar *cstring) { + functions->ReleaseStringCritical(this,string,cstring); + } + + jweak NewWeakGlobalRef(jobject obj) { + return functions->NewWeakGlobalRef(this,obj); + } + void DeleteWeakGlobalRef(jweak ref) { + functions->DeleteWeakGlobalRef(this,ref); + } + + jboolean ExceptionCheck() { + return functions->ExceptionCheck(this); + } + + jobject NewDirectByteBuffer(void* address, jlong capacity) { + return functions->NewDirectByteBuffer(this, address, capacity); + } + void* GetDirectBufferAddress(jobject buf) { + return functions->GetDirectBufferAddress(this, buf); + } + jlong GetDirectBufferCapacity(jobject buf) { + return functions->GetDirectBufferCapacity(this, buf); + } + jobjectRefType GetObjectRefType(jobject obj) { + return functions->GetObjectRefType(this, obj); + } + +#endif /* __cplusplus */ +}; + +typedef struct JavaVMOption { + char *optionString; + void *extraInfo; +} JavaVMOption; + +typedef struct JavaVMInitArgs { + jint version; + + jint nOptions; + JavaVMOption *options; + jboolean ignoreUnrecognized; +} JavaVMInitArgs; + +typedef struct JavaVMAttachArgs { + jint version; + + char *name; + jobject group; +} JavaVMAttachArgs; + +#define JDK1_2 +#define JDK1_4 + +struct JNIInvokeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + jint (JNICALL *DestroyJavaVM)(JavaVM *vm); + + jint (JNICALL *AttachCurrentThread)(JavaVM *vm, void **penv, void *args); + + jint (JNICALL *DetachCurrentThread)(JavaVM *vm); + + jint (JNICALL *GetEnv)(JavaVM *vm, void **penv, jint version); + + jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM *vm, void **penv, void *args); +}; + +struct JavaVM_ { + const struct JNIInvokeInterface_ *functions; +#ifdef __cplusplus + + jint DestroyJavaVM() { + return functions->DestroyJavaVM(this); + } + jint AttachCurrentThread(void **penv, void *args) { + return functions->AttachCurrentThread(this, penv, args); + } + jint DetachCurrentThread() { + return functions->DetachCurrentThread(this); + } + + jint GetEnv(void **penv, jint version) { + return functions->GetEnv(this, penv, version); + } + jint AttachCurrentThreadAsDaemon(void **penv, void *args) { + return functions->AttachCurrentThreadAsDaemon(this, penv, args); + } +#endif +}; + +#ifdef _JNI_IMPLEMENTATION_ +#define _JNI_IMPORT_OR_EXPORT_ JNIEXPORT +#else +#define _JNI_IMPORT_OR_EXPORT_ JNIIMPORT +#endif +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_GetDefaultJavaVMInitArgs(void *args); + +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args); + +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *); + +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM *vm, void *reserved); + +JNIEXPORT void JNICALL +JNI_OnUnload(JavaVM *vm, void *reserved); + +#define JNI_VERSION_1_1 0x00010001 +#define JNI_VERSION_1_2 0x00010002 +#define JNI_VERSION_1_4 0x00010004 +#define JNI_VERSION_1_6 0x00010006 + +#endif /* __GLUEGEN__ */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* !_JAVASOFT_JNI_H_ */ + diff -Nru gluegen2-2.2.4/make/stub_includes/jni/macosx/jawt_md.h gluegen2-2.3.2/make/stub_includes/jni/macosx/jawt_md.h --- gluegen2-2.2.4/make/stub_includes/jni/macosx/jawt_md.h 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/stub_includes/jni/macosx/jawt_md.h 2015-10-09 04:18:28.000000000 +0000 @@ -1,9 +1,4 @@ /** - * Temporary workaround! - * - * Provided darwin/jawt_md.h from Oracle for OSX / Java7 - * has X11 dependencies and does not define JAWT_SurfaceLayers. - * * This C header file is derived from Apple's Java SDK provided C header file * with the following copyright notice: * diff -Nru gluegen2-2.2.4/make/stub_includes/jni/macosx/jni_md.h gluegen2-2.3.2/make/stub_includes/jni/macosx/jni_md.h --- gluegen2-2.2.4/make/stub_includes/jni/macosx/jni_md.h 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/stub_includes/jni/macosx/jni_md.h 2015-10-09 04:18:28.000000000 +0000 @@ -1,9 +1,4 @@ /* - * Temporary workaround! - * - * Provided darwin/jawt_md.h from Oracle for OSX / Java7 - * has X11 dependencies and does not define JAWT_SurfaceLayers. - * * @(#)jni_md.h 1.18 03/12/19 * * This C header file is derived from Sun Microsystem's Java SDK provided C header file @@ -32,16 +27,20 @@ #ifndef _JAVASOFT_JNI_MD_H_ #define _JAVASOFT_JNI_MD_H_ -#define JNIEXPORT __attribute__((visibility("default"))) -#define JNIIMPORT -#define JNICALL +#include + +#ifdef __GLUEGEN__ + #define JNIEXPORT + #define JNIIMPORT + #define JNICALL +#else /* __GLUEGEN__ */ + #define JNIEXPORT __attribute__((visibility("default"))) + #define JNIIMPORT __attribute__((visibility("default"))) + #define JNICALL +#endif /* __GLUEGEN__ */ -#if __LP64__ -typedef int jint; -#else -typedef long jint; -#endif -typedef long long jlong; -typedef signed char jbyte; +typedef int8_t jbyte; +typedef int32_t jint; +typedef int64_t jlong; #endif /* !_JAVASOFT_JNI_MD_H_ */ diff -Nru gluegen2-2.2.4/make/stub_includes/jni/win32/jawt_md.h gluegen2-2.3.2/make/stub_includes/jni/win32/jawt_md.h --- gluegen2-2.2.4/make/stub_includes/jni/win32/jawt_md.h 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/make/stub_includes/jni/win32/jawt_md.h 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,54 @@ +/* + * @(#)jawt_md.h 1.8 05/11/17 + * + * This C header file is derived from Sun Microsystem's Java SDK provided C header file + * with the following copyright notice: + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * This version has complex comments removed and does not contain inlined algorithms etc, if any existed. + * + * The original C header file was included to JOGL on Sat Jun 21 02:10:30 2008 + * (commit cbc45e816f4ee81031bffce19a99550681462a24) by Sun Microsystem's staff and were approved. + * + * This C header file is included due to ensure compatibility with - and invocation of the JAWT protocol. + * They are processed by GlueGen to create a Java binding for JAWT invocation only. + * + * http://ftp.resource.org/courts.gov/c/F3/387/387.F3d.522.03-5400.html (36) + * "Atari Games Corp. v. Nintendo of Am., Inc., Nos. 88-4805 & 89-0027, 1993 WL 207548, at *1 (N.D.Cal. May 18, 1993) ("Atari III") + * ("Program code that is strictly necessary to achieve current compatibility presents a merger problem, almost by definition, + * and is thus excluded from the scope of any copyright.")." + * + * http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=OJ:L:2009:111:0016:0022:EN:PDF + * L 111/17 (10) and (15) + */ + +#ifndef _JAVASOFT_JAWT_MD_H_ +#define _JAVASOFT_JAWT_MD_H_ + +#include +#include "jawt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct jawt_Win32DrawingSurfaceInfo { + /** + union { + HWND hwnd; + HBITMAP hbitmap; + void* pbits; + }; */ + HWND handle; + + HDC hdc; + HPALETTE hpalette; +} JAWT_Win32DrawingSurfaceInfo; + +#ifdef __cplusplus +} +#endif + +#endif /* !_JAVASOFT_JAWT_MD_H_ */ diff -Nru gluegen2-2.2.4/make/stub_includes/jni/win32/jni_md.h gluegen2-2.3.2/make/stub_includes/jni/win32/jni_md.h --- gluegen2-2.2.4/make/stub_includes/jni/win32/jni_md.h 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/make/stub_includes/jni/win32/jni_md.h 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * @(#)jni_md.h 1.15 05/11/17 + * + * This C header file is derived from Sun Microsystem's Java SDK provided C header file + * with the following copyright notice: + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * This version has complex comments removed and does not contain inlined algorithms etc, if any existed. + * + * The original C header file was included to JOGL on Sat Jun 21 02:10:30 2008 + * (commit cbc45e816f4ee81031bffce19a99550681462a24) by Sun Microsystem's staff and were approved. + * + * This C header file is included due to ensure compatibility with - and invocation of the JAWT protocol. + * They are processed by GlueGen to create a Java binding for JAWT invocation only. + * + * http://ftp.resource.org/courts.gov/c/F3/387/387.F3d.522.03-5400.html (36) + * "Atari Games Corp. v. Nintendo of Am., Inc., Nos. 88-4805 & 89-0027, 1993 WL 207548, at *1 (N.D.Cal. May 18, 1993) ("Atari III") + * ("Program code that is strictly necessary to achieve current compatibility presents a merger problem, almost by definition, + * and is thus excluded from the scope of any copyright.")." + * + * http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=OJ:L:2009:111:0016:0022:EN:PDF + * L 111/17 (10) and (15) + */ + +#ifndef _JAVASOFT_JNI_MD_H_ +#define _JAVASOFT_JNI_MD_H_ + +#include + +#ifdef __GLUEGEN__ + #define JNIEXPORT + #define JNIIMPORT + #define JNICALL +#else /* __GLUEGEN__ */ + #define JNIEXPORT __declspec(dllexport) + #define JNIIMPORT __declspec(dllimport) + #define JNICALL __stdcall +#endif /* __GLUEGEN__ */ + +typedef int8_t jbyte; +typedef int32_t jint; +typedef int64_t jlong; + +#endif /* !_JAVASOFT_JNI_MD_H_ */ diff -Nru gluegen2-2.2.4/make/stub_includes/jni/x11/jawt_md.h gluegen2-2.3.2/make/stub_includes/jni/x11/jawt_md.h --- gluegen2-2.2.4/make/stub_includes/jni/x11/jawt_md.h 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/make/stub_includes/jni/x11/jawt_md.h 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,56 @@ +/* + * @(#)jawt_md.h 1.12 05/11/17 + * + * This C header file is derived from Sun Microsystem's Java SDK provided C header file + * with the following copyright notice: + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * This version has complex comments removed and does not contain inlined algorithms etc, if any existed. + * + * The original C header file was included to JOGL on Sat Jun 21 02:10:30 2008 + * (commit cbc45e816f4ee81031bffce19a99550681462a24) by Sun Microsystem's staff and were approved. + * + * This C header file is included due to ensure compatibility with - and invocation of the JAWT protocol. + * They are processed by GlueGen to create a Java binding for JAWT invocation only. + * + * http://ftp.resource.org/courts.gov/c/F3/387/387.F3d.522.03-5400.html (36) + * "Atari Games Corp. v. Nintendo of Am., Inc., Nos. 88-4805 & 89-0027, 1993 WL 207548, at *1 (N.D.Cal. May 18, 1993) ("Atari III") + * ("Program code that is strictly necessary to achieve current compatibility presents a merger problem, almost by definition, + * and is thus excluded from the scope of any copyright.")." + * + * http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=OJ:L:2009:111:0016:0022:EN:PDF + * L 111/17 (10) and (15) + */ + +#ifndef _JAVASOFT_JAWT_MD_H_ +#define _JAVASOFT_JAWT_MD_H_ + +#include +#include +#include +#include "jawt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct jawt_X11DrawingSurfaceInfo { + Drawable drawable; + Display* display; + VisualID visualID; + Colormap colormapID; + int depth; + /* + * Since 1.4 + */ + int (JNICALL *GetAWTColor)(JAWT_DrawingSurface* ds, + int r, int g, int b); +} JAWT_X11DrawingSurfaceInfo; + +#ifdef __cplusplus +} +#endif + +#endif /* !_JAVASOFT_JAWT_MD_H_ */ diff -Nru gluegen2-2.2.4/make/stub_includes/jni/x11/jni_md.h gluegen2-2.3.2/make/stub_includes/jni/x11/jni_md.h --- gluegen2-2.2.4/make/stub_includes/jni/x11/jni_md.h 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/make/stub_includes/jni/x11/jni_md.h 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,40 @@ +/* + * @(#)jni_md.h 1.19 05/11/17 + * + * This C header file is derived from Sun Microsystem's Java SDK provided C header file + * with the following copyright notice: + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * This version has complex comments removed and does not contain inlined algorithms etc, if any existed. + * + * The original C header file was included to JOGL on Sat Jun 21 02:10:30 2008 + * (commit cbc45e816f4ee81031bffce19a99550681462a24) by Sun Microsystem's staff and were approved. + * + * This C header file is included due to ensure compatibility with - and invocation of the JAWT protocol. + * They are processed by GlueGen to create a Java binding for JAWT invocation only. + * + * http://ftp.resource.org/courts.gov/c/F3/387/387.F3d.522.03-5400.html (36) + * "Atari Games Corp. v. Nintendo of Am., Inc., Nos. 88-4805 & 89-0027, 1993 WL 207548, at *1 (N.D.Cal. May 18, 1993) ("Atari III") + * ("Program code that is strictly necessary to achieve current compatibility presents a merger problem, almost by definition, + * and is thus excluded from the scope of any copyright.")." + * + * http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=OJ:L:2009:111:0016:0022:EN:PDF + * L 111/17 (10) and (15) + */ + +#ifndef _JAVASOFT_JNI_MD_H_ +#define _JAVASOFT_JNI_MD_H_ + +#include + +#define JNIEXPORT +#define JNIIMPORT +#define JNICALL + +typedef int8_t jbyte; +typedef int32_t jint; +typedef int64_t jlong; + +#endif /* !_JAVASOFT_JNI_MD_H_ */ diff -Nru gluegen2-2.2.4/make/stub_includes/os/elf_header.h gluegen2-2.3.2/make/stub_includes/os/elf_header.h --- gluegen2-2.2.4/make/stub_includes/os/elf_header.h 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/stub_includes/os/elf_header.h 2015-10-09 04:18:28.000000000 +0000 @@ -15,6 +15,9 @@ uint16_t e_type; uint16_t e_machine; uint32_t e_version; +} Ehdr_p1; + +typedef struct { ElfN_Addr e_entry; ElfN_Off e_phoff; ElfN_Off e_shoff; @@ -25,7 +28,7 @@ uint16_t e_shentsize; uint16_t e_shnum; uint16_t e_shstrndx; -} Ehdr; +} Ehdr_p2; typedef struct { uint32_t sh_name; diff -Nru gluegen2-2.2.4/make/stub_includes/platform/glibc-compat-symbols.h gluegen2-2.3.2/make/stub_includes/platform/glibc-compat-symbols.h --- gluegen2-2.2.4/make/stub_includes/platform/glibc-compat-symbols.h 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/stub_includes/platform/glibc-compat-symbols.h 2015-10-09 04:18:28.000000000 +0000 @@ -17,7 +17,9 @@ */ #if defined(__linux__) /* Actually we like to test whether we link against GLIBC .. */ #if defined(__GNUC__) - #if defined(__arm__) + #if defined(__aarch64__) + #define GLIBC_COMPAT_SYMBOL(FFF) __asm__(".symver " #FFF "," #FFF "@GLIBC_2.4"); + #elif defined(__arm__) #define GLIBC_COMPAT_SYMBOL(FFF) __asm__(".symver " #FFF "," #FFF "@GLIBC_2.4"); #elif defined(__amd64__) #define GLIBC_COMPAT_SYMBOL(FFF) __asm__(".symver " #FFF "," #FFF "@GLIBC_2.2.5"); @@ -25,7 +27,9 @@ #define GLIBC_COMPAT_SYMBOL(FFF) __asm__(".symver " #FFF "," #FFF "@GLIBC_2.0"); #endif /*__amd64__*/ #elif defined(__clang__) - #if defined(__arm__) + #if defined(__aarch64__) + #define GLIBC_COMPAT_SYMBOL(FFF) asm(".symver " #FFF "," #FFF "@GLIBC_2.4"); + #elif defined(__arm__) #define GLIBC_COMPAT_SYMBOL(FFF) asm(".symver " #FFF "," #FFF "@GLIBC_2.4"); #elif defined(__amd64__) #define GLIBC_COMPAT_SYMBOL(FFF) asm(".symver " #FFF "," #FFF "@GLIBC_2.2.5"); diff -Nru gluegen2-2.2.4/make/stub_includes/platform/gluegen_stddef.h gluegen2-2.3.2/make/stub_includes/platform/gluegen_stddef.h --- gluegen2-2.2.4/make/stub_includes/platform/gluegen_stddef.h 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/stub_includes/platform/gluegen_stddef.h 2015-10-09 04:18:28.000000000 +0000 @@ -15,7 +15,7 @@ #elif defined(_WIN32) typedef __int32 ptrdiff_t; typedef unsigned __int32 size_t; -#elif defined(__ia64__) || defined(__x86_64__) +#elif defined(__LP64__) || defined(__ia64__) || defined(__x86_64__) || defined(__aarch64__) typedef long ptrdiff_t; typedef unsigned long size_t; #else diff -Nru gluegen2-2.2.4/make/stub_includes/platform/gluegen_stdint.h gluegen2-2.3.2/make/stub_includes/platform/gluegen_stdint.h --- gluegen2-2.2.4/make/stub_includes/platform/gluegen_stdint.h 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/make/stub_includes/platform/gluegen_stdint.h 2015-10-09 04:18:28.000000000 +0000 @@ -33,7 +33,7 @@ typedef __int32 intptr_t; typedef unsigned __int32 uintptr_t; -#elif defined(__ia64__) || defined(__x86_64__) +#elif defined(__LP64__) || defined(__ia64__) || defined(__x86_64__) || defined(__aarch64__) typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed short int16_t; diff -Nru gluegen2-2.2.4/src/antlr/com/jogamp/gluegen/cgram/GnuCParser.g gluegen2-2.3.2/src/antlr/com/jogamp/gluegen/cgram/GnuCParser.g --- gluegen2-2.2.4/src/antlr/com/jogamp/gluegen/cgram/GnuCParser.g 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/antlr/com/jogamp/gluegen/cgram/GnuCParser.g 2015-10-09 04:18:28.000000000 +0000 @@ -23,6 +23,7 @@ import antlr.CommonAST; import antlr.DumpASTVisitor; + import com.jogamp.gluegen.ASTLocusTag; } @@ -715,7 +716,7 @@ public void addDefine(String name, String value) { - defines.add(new Define(name, value)); + defines.add(new Define(name, value, new ASTLocusTag(lineObject.getSource(), lineObject.getLine()+deferredLineCount, -1, name))); } /** Returns a list of Define objects corresponding to the diff -Nru gluegen2-2.2.4/src/antlr/com/jogamp/gluegen/cgram/HeaderParser.g gluegen2-2.3.2/src/antlr/com/jogamp/gluegen/cgram/HeaderParser.g --- gluegen2-2.2.4/src/antlr/com/jogamp/gluegen/cgram/HeaderParser.g 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/antlr/com/jogamp/gluegen/cgram/HeaderParser.g 2015-10-09 04:18:28.000000000 +0000 @@ -45,7 +45,14 @@ import java.util.*; import antlr.CommonAST; + import com.jogamp.gluegen.ASTLocusTag; + import com.jogamp.gluegen.ConstantDefinition; + import com.jogamp.gluegen.ConstantDefinition.CNumber; + import com.jogamp.gluegen.GlueGenException; + import com.jogamp.gluegen.JavaConfiguration; import com.jogamp.gluegen.cgram.types.*; + import com.jogamp.gluegen.cgram.types.EnumType; + import com.jogamp.gluegen.cgram.types.EnumType.Enumerator; } class HeaderParser extends GnuCTreeParser; @@ -67,6 +74,12 @@ this.debug = debug; } + /** Set the configuration for this + HeaderParser. Must be done before parsing. */ + public void setJavaConfiguration(JavaConfiguration cfg) { + this.cfg = cfg; + } + /** Set the dictionary mapping typedef names to types for this HeaderParser. Must be done before parsing. */ public void setTypedefDictionary(TypeDictionary dict) { @@ -105,7 +118,7 @@ // the enumerates from each EnumType, and fill in the enumHash // so that each enumerate maps to the enumType to which it // belongs. - throw new RuntimeException("setEnums is Unimplemented!"); + throw new RuntimeException("setEnums is Unimplemented!"); } /** Returns the EnumTypes this HeaderParser processed. */ @@ -125,22 +138,25 @@ return functions; } - private CompoundType lookupInStructDictionary(String typeName, + private CompoundType lookupInStructDictionary(String structName, CompoundTypeKind kind, - int cvAttrs) { - CompoundType t = (CompoundType) structDictionary.get(typeName); + int cvAttrs, final ASTLocusTag locusTag) + { + CompoundType t = (CompoundType) structDictionary.get(structName); if (t == null) { - t = CompoundType.create(null, null, kind, cvAttrs); - t.setStructName(typeName); - structDictionary.put(typeName, t); + t = CompoundType.create(structName, null, kind, cvAttrs, locusTag); + structDictionary.put(structName, t); + debugPrintln("Adding compound mapping: [" + structName + "] -> "+getDebugTypeString(t)+" @ "+locusTag); + debugPrintln(t.getStructString()); } return t; } - private Type lookupInTypedefDictionary(String typeName) { + private Type lookupInTypedefDictionary(final AST _t, String typeName) { Type t = typedefDictionary.get(typeName); if (t == null) { - throw new RuntimeException("Undefined reference to typedef name " + typeName); + throwGlueGenException(_t, + "Undefined reference to typedef name " + typeName); } return t; } @@ -153,8 +169,10 @@ this.id = id; this.type = type; } - String id() { return id; } - Type type() { return type; } + String id() { return id; } + Type type() { return type; } + void setType(final Type t) { type = t; } + public String toString() { return "ParamDecl["+id+": "+type.getDebugString()+"]"; } } // A box for a Type. Allows type to be passed down to be modified by recursive rules. @@ -207,22 +225,27 @@ } } + private String getDebugTypeString(Type t) { + if(debug) { + return getTypeString(t); + } else { + return null; + } + } private String getTypeString(Type t) { StringBuilder sb = new StringBuilder(); sb.append("["); - sb.append(t); - sb.append(", size: "); if(null!=t) { - SizeThunk st = t.getSize(); - if(null!=st) { - sb.append(st.getClass().getName()); - } else { - sb.append("undef"); - } + sb.append(t.getDebugString()); + sb.append(", opaque ").append(isOpaque(t)).append("]"); + } else { + sb.append("nil]"); } - sb.append("]"); return sb.toString(); } + private boolean isOpaque(final Type type) { + return (cfg.typeInfo(type) != null); + } private void debugPrintln(String msg) { if(debug) { @@ -236,14 +259,13 @@ } } - private boolean doDeclaration; // Used to only process function typedefs - private String declId; - private List parameters; + private JavaConfiguration cfg; private TypeDictionary typedefDictionary; private TypeDictionary structDictionary; private List functions = new ArrayList(); // hash from name of an enumerated value to the EnumType to which it belongs private HashMap enumHash = new HashMap(); + private HashMap enumMap = new HashMap(); // Storage class specifiers private static final int AUTO = 1 << 0; @@ -259,25 +281,41 @@ private static final int SIGNED = 1 << 8; private static final int UNSIGNED = 1 << 9; - private void initDeclaration() { - doDeclaration = false; - declId = null; - } - - private void doDeclaration() { - doDeclaration = true; + private boolean isFuncDeclaration; // Used to only process function typedefs + private String funcDeclName; + private List funcDeclParams; + private ASTLocusTag funcLocusTag; + + private void resetFuncDeclaration() { + isFuncDeclaration = false; + funcDeclName = null; + funcDeclParams = null; + funcLocusTag = null; + } + private void setFuncDeclaration(final String name, final List p, final ASTLocusTag locusTag) { + isFuncDeclaration = true; + funcDeclName = name; + funcDeclParams = p; + funcLocusTag = locusTag; } private void processDeclaration(Type returnType) { - if (doDeclaration) { - FunctionSymbol sym = new FunctionSymbol(declId, new FunctionType(null, null, returnType, 0)); - if (parameters != null) { // handle funcs w/ empty parameter lists (e.g., "foo()") - for (Iterator iter = parameters.iterator(); iter.hasNext(); ) { - ParameterDeclaration pd = (ParameterDeclaration) iter.next(); + if (isFuncDeclaration) { + final FunctionSymbol sym = new FunctionSymbol(funcDeclName, + new FunctionType(null, null, returnType, 0, funcLocusTag), + funcLocusTag); + debugPrintln("Function ... "+sym.toString()+" @ "+funcLocusTag); + if (funcDeclParams != null) { // handle funcs w/ empty parameter lists (e.g., "foo()") + for (Iterator iter = funcDeclParams.iterator(); iter.hasNext(); ) { + ParameterDeclaration pd = iter.next(); + pd.setType(pd.type()); + debugPrintln(" add "+pd.toString()); sym.addArgument(pd.type(), pd.id()); } - } + } + debugPrintln("Function Added "+sym.toString()); functions.add(sym); + resetFuncDeclaration(); } } @@ -294,19 +332,18 @@ /** Helper routine which handles creating a pointer or array type for [] expressions */ - private void handleArrayExpr(TypeBox tb, AST t) { + private void handleArrayExpr(TypeBox tb, AST t, ASTLocusTag locusTag) { if (t != null) { try { final int len = parseIntConstExpr(t); - tb.setType(canonicalize(new ArrayType(tb.type(), SizeThunk.mul(SizeThunk.constant(len), tb.type().getSize()), len, 0))); + tb.setType(canonicalize(new ArrayType(tb.type(), SizeThunk.mul(SizeThunk.constant(len), tb.type().getSize()), len, 0, locusTag))); return; } catch (RecognitionException e) { // Fall through } } tb.setType(canonicalize(new PointerType(SizeThunk.POINTER, - tb.type(), - 0))); + tb.type(), 0, locusTag))); } private int parseIntConstExpr(AST t) throws RecognitionException { @@ -315,49 +352,104 @@ /** Utility function: creates a new EnumType with the given name, or returns an existing one if it has already been created. */ - private EnumType getEnumType(String enumTypeName) { + private EnumType getEnumType(String enumTypeName, ASTLocusTag locusTag) { EnumType enumType = null; Iterator it = enumHash.values().iterator(); while (it.hasNext()) { EnumType potentialMatch = it.next(); if (potentialMatch.getName().equals(enumTypeName)) { - enumType = potentialMatch; - break; + enumType = potentialMatch; + break; } } if (enumType == null) { - // This isn't quite correct. In theory the enum should expand to - // the size of the largest element, so if there were a long long - // entry the enum should expand to e.g. int64. However, using - // "long" here (which is what used to be the case) was - // definitely incorrect and caused problems. - enumType = new EnumType(enumTypeName, SizeThunk.INT32); + // This isn't quite correct. In theory the enum should expand to + // the size of the largest element, so if there were a long long + // entry the enum should expand to e.g. int64. However, using + // "long" here (which is what used to be the case) was + // definitely incorrect and caused problems. + enumType = new EnumType(enumTypeName, SizeThunk.INT32, locusTag); } return enumType; - } + } // Map used to canonicalize types. For example, we may typedef // struct foo { ... } *pfoo; subsequent references to struct foo* should // point to the same PointerType object that had its name set to "pfoo". - private Map canonMap = new HashMap(); + // Opaque canonical types are excluded. + private Map canonMap = new HashMap(); private Type canonicalize(Type t) { Type res = (Type) canonMap.get(t); if (res != null) { return res; + } else { + canonMap.put(t, t); + return t; + } + } + + private void throwGlueGenException(final AST t, final String message) throws GlueGenException { + // dumpASTTree("XXX", t); + throw new GlueGenException(message, findASTLocusTag(t)); + } + private void throwGlueGenException(final ASTLocusTag locusTag, final String message) throws GlueGenException { + // dumpASTTree("XXX", t); + throw new GlueGenException(message, locusTag); + } + + /** + * Return ASTLocusTag in tree, or null if not found. + */ + private ASTLocusTag findASTLocusTag(final AST astIn) { + AST ast = astIn; + while(null != ast) { + if( ast instanceof TNode ) { + final TNode tn = (TNode) ast; + final ASTLocusTag tag = tn.getASTLocusTag(); + if( null != tag ) { + return tag; + } + } + ast = ast.getFirstChild(); + } + return null; + } + private void dumpASTTree(final String pre, final AST t) { + int i=0; + AST it = t; + while( null != it ) { + it = dumpAST(pre+"."+i, it); + i++; + } + } + private AST dumpAST(final String pre, final AST ast) { + if( null == ast ) { + System.err.println(pre+".0: AST NULL"); + return null; + } else { + System.err.println(pre+".0: AST Type: "+ast.getClass().getName()); + System.err.println(pre+".1: line:col "+ast.getLine()+":"+ast.getColumn()+" -> "+ast.getText()); + if( ast instanceof TNode ) { + final TNode tn = (TNode) ast; + final ASTLocusTag tag = tn.getASTLocusTag(); + System.err.println(pre+".TN.1: "+tag); + final Hashtable attributes = tn.getAttributesTable(); + System.err.println(pre+".TN.2: "+attributes); + } + return ast.getFirstChild(); } - canonMap.put(t, t); - return t; } } declarator[TypeBox tb] returns [String s] { - initDeclaration(); + resetFuncDeclaration(); s = null; - List params = null; + List params = null; String funcPointerName = null; TypeBox dummyTypeBox = null; + final ASTLocusTag locusTag = findASTLocusTag(declarator_AST_in); } : #( NDeclarator ( pointerGroup[tb] )? @@ -374,32 +466,29 @@ RPAREN ) { if (id != null) { - declId = id.getText(); - parameters = params; // FIXME: Ken, why are we setting this class member here? - doDeclaration(); + setFuncDeclaration(id.getText(), params, locusTag); } else if ( funcPointerName != null ) { /* TypeBox becomes function pointer in this case */ - FunctionType ft = new FunctionType(null, null, tb.type(), 0); + final FunctionType ft = new FunctionType(null, null, tb.type(), 0, locusTag); if (params == null) { - // If the function pointer has no declared parameters, it's a - // void function. I'm not sure if the parameter name is - // ever referenced anywhere when the type is VoidType, so + // If the function pointer has no declared parameters, it's a + // void function. I'm not sure if the parameter name is + // ever referenced anywhere when the type is VoidType, so // just in case I'll set it to a comment string so it will - // still compile if written out to code anywhere. - ft.addArgument(new VoidType(0), "/*unnamed-void*/"); - } else { - for (Iterator iter = params.iterator(); iter.hasNext(); ) { - ParameterDeclaration pd = (ParameterDeclaration) iter.next(); - ft.addArgument(pd.type(), pd.id()); - } + // still compile if written out to code anywhere. + ft.addArgument(new VoidType(0, locusTag), "/*unnamed-void*/"); + } else { + for (Iterator iter = params.iterator(); iter.hasNext(); ) { + ParameterDeclaration pd = (ParameterDeclaration) iter.next(); + ft.addArgument(pd.type(), pd.id()); + } } tb.setType(canonicalize(new PointerType(SizeThunk.POINTER, - ft, - 0))); + ft, 0, locusTag))); s = funcPointerName; } } - | LBRACKET ( e:expr )? RBRACKET { handleArrayExpr(tb, e); } + | LBRACKET ( e:expr )? RBRACKET { handleArrayExpr(tb, e, locusTag); } )* ) ; @@ -422,8 +511,8 @@ ) { processDeclaration(tb.type()); } ; -parameterTypeList returns [List l] { l = new ArrayList(); ParameterDeclaration decl = null; } - : ( decl = parameterDeclaration { if (decl != null) l.add(decl); } ( COMMA | SEMI )? )+ ( VARARGS )? +parameterTypeList returns [List l] { l = new ArrayList(); ParameterDeclaration decl = null; } + : ( decl = parameterDeclaration { if (decl != null) { l.add(decl); } } ( COMMA | SEMI )? )+ ( VARARGS )? ; parameterDeclaration returns [ParameterDeclaration pd] { @@ -435,7 +524,13 @@ : #( NParameterDeclaration tb = declSpecifiers (decl = declarator[tb] | nonemptyAbstractDeclarator[tb])? - ) { pd = new ParameterDeclaration(decl, tb.type()); } + ) { + if( null == tb ) { + throwGlueGenException(parameterDeclaration_AST_in, + String.format("Undefined type for declaration '%s'", decl)); + } + pd = new ParameterDeclaration(decl, tb.type()); + } ; functionDef { @@ -462,7 +557,10 @@ { if (t == null && (x & (SIGNED | UNSIGNED)) != 0) { - t = new IntType("int", SizeThunk.INTxx, ((x & UNSIGNED) != 0), attrs2CVAttrs(x)); + t = new IntType("int", SizeThunk.INTxx, + ((x & UNSIGNED) != 0), + attrs2CVAttrs(x), + findASTLocusTag(declSpecifiers_AST_in)); } tb = new TypeBox(t, ((x & TYPEDEF) != 0)); } @@ -493,30 +591,35 @@ typeSpecifier[int attributes] returns [Type t] { t = null; int cvAttrs = attrs2CVAttrs(attributes); - boolean unsigned = ((attributes & UNSIGNED) != 0); + boolean unsig = ((attributes & UNSIGNED) != 0); + final ASTLocusTag locusTag = findASTLocusTag(typeSpecifier_AST_in); } - : "void" { t = new VoidType(cvAttrs); } - | "char" { t = new IntType("char" , SizeThunk.INT8, unsigned, cvAttrs); } - | "short" { t = new IntType("short", SizeThunk.INT16, unsigned, cvAttrs); } - | "int" { t = new IntType("int" , SizeThunk.INTxx, unsigned, cvAttrs); } - | "long" { t = new IntType("long" , SizeThunk.LONG, unsigned, cvAttrs); } - | "float" { t = new FloatType("float", SizeThunk.FLOAT, cvAttrs); } - | "double" { t = new DoubleType("double", SizeThunk.DOUBLE, cvAttrs); } - | "__int32" { t = new IntType("__int32", SizeThunk.INT32, unsigned, cvAttrs); } - | "__int64" { t = new IntType("__int64", SizeThunk.INT64, unsigned, cvAttrs); } - | "int8_t" { t = new IntType("int8_t", SizeThunk.INT8, false, cvAttrs); /* TS: always signed */ } - | "uint8_t" { t = new IntType("uint8_t", SizeThunk.INT8, true, cvAttrs); /* TS: always unsigned */ } - | "int16_t" { t = new IntType("int16_t", SizeThunk.INT16, false, cvAttrs); /* TS: always signed */ } - | "uint16_t" { t = new IntType("uint16_t", SizeThunk.INT16, true, cvAttrs); /* TS: always unsigned */ } - | "int32_t" { t = new IntType("int32_t", SizeThunk.INT32, false, cvAttrs); /* TS: always signed */ } - | "wchar_t" { t = new IntType("wchar_t", SizeThunk.INT32, false, cvAttrs); /* TS: always signed */ } - | "uint32_t" { t = new IntType("uint32_t", SizeThunk.INT32, true, cvAttrs, true); /* TS: always unsigned */ } - | "int64_t" { t = new IntType("int64_t", SizeThunk.INT64, false, cvAttrs); /* TS: always signed */ } - | "uint64_t" { t = new IntType("uint64_t", SizeThunk.INT64, true, cvAttrs, true); /* TS: always unsigned */ } - | "ptrdiff_t" { t = new IntType("ptrdiff_t", SizeThunk.POINTER, false, cvAttrs); /* TS: always signed */ } - | "intptr_t" { t = new IntType("intptr_t", SizeThunk.POINTER, false, cvAttrs); /* TS: always signed */ } - | "size_t" { t = new IntType("size_t", SizeThunk.POINTER, true, cvAttrs, true); /* TS: always unsigned */ } - | "uintptr_t" { t = new IntType("uintptr_t", SizeThunk.POINTER, true, cvAttrs, true); /* TS: always unsigned */ } + // TYPEDEF + // | TYPEDEF-UNSIGNED + // UNSIGNED | | + // TOKEN TYPE NAME SIZE | ATTRIBS | | LOCUS + : "void" { t = new VoidType( cvAttrs, locusTag); } + | "char" { t = new IntType("char" , SizeThunk.INT8, unsig, cvAttrs, false, false, locusTag); } + | "short" { t = new IntType("short", SizeThunk.INT16, unsig, cvAttrs, false, false, locusTag); } + | "int" { t = new IntType("int" , SizeThunk.INTxx, unsig, cvAttrs, false, false, locusTag); } + | "long" { t = new IntType("long" , SizeThunk.LONG, unsig, cvAttrs, false, false, locusTag); } + | "float" { t = new FloatType("float", SizeThunk.FLOAT, cvAttrs, locusTag); } + | "double" { t = new DoubleType("double", SizeThunk.DOUBLE, cvAttrs, locusTag); } + | "__int32" { t = new IntType("__int32", SizeThunk.INT32, unsig, cvAttrs, true, false, locusTag); } /* TD: signed */ + | "__int64" { t = new IntType("__int64", SizeThunk.INT64, unsig, cvAttrs, true, false, locusTag); } /* TD: signed */ + | "int8_t" { t = new IntType("int8_t", SizeThunk.INT8, unsig, cvAttrs, true, false, locusTag); } /* TD: signed */ + | "uint8_t" { t = new IntType("uint8_t", SizeThunk.INT8, unsig, cvAttrs, true, true, locusTag); } /* TD: unsigned */ + | "int16_t" { t = new IntType("int16_t", SizeThunk.INT16, unsig, cvAttrs, true, false, locusTag); } /* TD: signed */ + | "uint16_t" { t = new IntType("uint16_t", SizeThunk.INT16, unsig, cvAttrs, true, true, locusTag); } /* TD: unsigned */ + | "int32_t" { t = new IntType("int32_t", SizeThunk.INT32, unsig, cvAttrs, true, false, locusTag); } /* TD: signed */ + | "wchar_t" { t = new IntType("wchar_t", SizeThunk.INT32, unsig, cvAttrs, true, false, locusTag); } /* TD: signed */ + | "uint32_t" { t = new IntType("uint32_t", SizeThunk.INT32, unsig, cvAttrs, true, true, locusTag); } /* TS: unsigned */ + | "int64_t" { t = new IntType("int64_t", SizeThunk.INT64, unsig, cvAttrs, true, false, locusTag); } /* TD: signed */ + | "uint64_t" { t = new IntType("uint64_t", SizeThunk.INT64, unsig, cvAttrs, true, true, locusTag); } /* TD: unsigned */ + | "ptrdiff_t" { t = new IntType("ptrdiff_t", SizeThunk.POINTER, unsig, cvAttrs, true, false, locusTag); } /* TD: signed */ + | "intptr_t" { t = new IntType("intptr_t", SizeThunk.POINTER, unsig, cvAttrs, true, false, locusTag); } /* TD: signed */ + | "size_t" { t = new IntType("size_t", SizeThunk.POINTER, unsig, cvAttrs, true, true, locusTag); } /* TD: unsigned */ + | "uintptr_t" { t = new IntType("uintptr_t", SizeThunk.POINTER, unsig, cvAttrs, true, true, locusTag); } /* TD: unsigned */ | t = structSpecifier[cvAttrs] ( attributeDecl )* | t = unionSpecifier [cvAttrs] ( attributeDecl )* | t = enumSpecifier [cvAttrs] @@ -533,9 +636,12 @@ typedefName[int cvAttrs] returns [Type t] { t = null; } : #(NTypedefName id : ID) { - Type tdict = lookupInTypedefDictionary(id.getText()); - t = canonicalize(tdict.getCVVariant(cvAttrs)); - debugPrintln("Adding typedef canon : [" + id.getText() + "] -> [" + tdict + "] -> "+getTypeString(t)); + final Type t0 = lookupInTypedefDictionary(typedefName_AST_in, id.getText()); + debugPrint("Adding typedef lookup: [" + id.getText() + "] -> "+getDebugTypeString(t0)); + final Type t1 = t0.newCVVariant(cvAttrs); + debugPrintln(" - cvvar -> "+getDebugTypeString(t1)); + t = canonicalize(t1); + debugPrintln(" - canon -> "+getDebugTypeString(t)); } ; @@ -549,31 +655,50 @@ structOrUnionBody[CompoundTypeKind kind, int cvAttrs] returns [CompoundType t] { t = null; + boolean addedAny = false; + final ASTLocusTag locusTag = findASTLocusTag(structOrUnionBody_AST_in); } : ( (ID LCURLY) => id:ID LCURLY { - t = (CompoundType) canonicalize(lookupInStructDictionary(id.getText(), kind, cvAttrs)); - } ( structDeclarationList[t] )? + // fully declared struct, i.e. not anonymous + t = (CompoundType) canonicalize(lookupInStructDictionary(id.getText(), kind, cvAttrs, locusTag)); + } ( addedAny = structDeclarationList[t] )? RCURLY { t.setBodyParsed(); } - | LCURLY { t = CompoundType.create(null, null, kind, cvAttrs); } - ( structDeclarationList[t] )? + | LCURLY { + // anonymous declared struct + t = CompoundType.create(null, null, kind, cvAttrs, locusTag); + } ( structDeclarationList[t] )? RCURLY { t.setBodyParsed(); } - | id2:ID { t = (CompoundType) canonicalize(lookupInStructDictionary(id2.getText(), kind, cvAttrs)); } - ) + | id2:ID { + // anonymous struct + t = (CompoundType) canonicalize(lookupInStructDictionary(id2.getText(), kind, cvAttrs, locusTag)); + } + ) { + debugPrintln("Adding compound body: [" + t.getName() + "] -> "+getDebugTypeString(t)+" @ "+locusTag); + debugPrintln(t.getStructString()); + } ; -structDeclarationList[CompoundType t] - : ( structDeclaration[t] )+ +structDeclarationList[CompoundType t] returns [boolean addedAny] { + addedAny = false; + boolean addedOne = false; +} + : ( addedOne = structDeclaration[t] { addedAny |= addedOne; } )+ ; -structDeclaration[CompoundType containingType] { +structDeclaration[CompoundType containingType] returns [boolean addedAny] { + addedAny = false; Type t = null; - boolean addedAny = false; } : t = specifierQualifierList addedAny = structDeclaratorList[containingType, t] { if (!addedAny) { if (t != null) { CompoundType ct = t.asCompound(); - if (ct.isUnion()) { + if( null == ct ) { + throwGlueGenException(structDeclaration_AST_in, + String.format("Anonymous compound, w/ NULL type:%n containing '%s'", + getTypeString(containingType))); + } + if ( ct.isUnion() ) { // Anonymous union containingType.addField(new Field(null, t, null)); } @@ -591,7 +716,8 @@ )+ { if (t == null && (x & (SIGNED | UNSIGNED)) != 0) { - t = new IntType("int", SizeThunk.INTxx, ((x & UNSIGNED) != 0), attrs2CVAttrs(x)); + t = new IntType("int", SizeThunk.INTxx, ((x & UNSIGNED) != 0), attrs2CVAttrs(x), + findASTLocusTag(specifierQualifierList_AST_in)); } } ; @@ -616,7 +742,7 @@ ) ; -// FIXME: this will not correctly set the name of the enumeration when +// This will not correctly set the name of the enumeration when // encountering a declaration like this: // // typedef enum { } enumName; @@ -625,65 +751,88 @@ // incorrectly return HeaderParser.ANONYMOUS_ENUM_NAME instead of // "enumName" // -// I haven't implemented it yet because I'm not sure how to get the -// "enumName" *before* executing the enumList rule. +// The followup typedef, see 'initDecl', will alias this name, +// hence correct the issue! enumSpecifier [int cvAttrs] returns [Type t] { t = null; + EnumType e = null; + ASTLocusTag locusTag = findASTLocusTag(enumSpecifier_AST_in); } : #( "enum" - ( ( ID LCURLY )=> i:ID LCURLY enumList[(EnumType)(t = getEnumType(i.getText()))] RCURLY - | LCURLY enumList[(EnumType)(t = getEnumType(ANONYMOUS_ENUM_NAME))] RCURLY - | ID { t = getEnumType(i.getText()); } - ) - ) + ( ( ID LCURLY )=> i:ID LCURLY enumList[(EnumType)(e = getEnumType(i.getText(), locusTag))] RCURLY + | LCURLY enumList[(EnumType)(e = getEnumType(ANONYMOUS_ENUM_NAME, locusTag))] RCURLY + | ID { e = getEnumType(i.getText(), locusTag); } + ) { + debugPrintln("Adding enum mapping: "+getDebugTypeString(e)); + if( null != e ) { + final String eName = e.getName(); + if( null != eName && !eName.equals(ANONYMOUS_ENUM_NAME) ) { // validate only non-anonymous enum + final EnumType dupE = enumMap.get(eName); + if( null != dupE && !dupE.equalSemantics(e) ) { + throwGlueGenException(enumSpecifier_AST_in, + String.format("Duplicate enum w/ incompatible type:%n this '%s',%n have '%s',%n %s: previous definition is here", + getTypeString(e), getTypeString(dupE), dupE.getASTLocusTag().toString(new StringBuilder(), "note", true))); + } + enumMap.put(eName, (EnumType)e.clone(locusTag)); + } + } + t = e; // return val + } + ) ; enumList[EnumType enumeration] { - long defaultEnumerantValue = 0; + ConstantDefinition defEnumerant = new ConstantDefinition("def", "0", new CNumber(true, false, 0), findASTLocusTag(enumList_AST_in)); } - : ( defaultEnumerantValue = enumerator[enumeration, defaultEnumerantValue] )+ + : ( defEnumerant = enumerator[enumeration, defEnumerant] )+ ; -enumerator[EnumType enumeration, long defaultValue] returns [long newDefaultValue] { +enumerator[EnumType enumeration, ConstantDefinition defaultValue] returns [ConstantDefinition newDefaultValue] { newDefaultValue = defaultValue; } : eName:ID ( ASSIGN eVal:expr )? { - long value = 0; + final String eTxt = eName.getText(); + final Enumerator newEnum; if (eVal != null) { - String vTxt = eVal.getAllChildrenText(); + String vTxt = eVal.getAllChildrenText(eTxt); if (enumHash.containsKey(vTxt)) { EnumType oldEnumType = enumHash.get(vTxt); - value = oldEnumType.getEnumValue(vTxt); + Enumerator oldEnum = oldEnumType.getEnum(vTxt); + newEnum = oldEnum; } else { - try { - value = Long.decode(vTxt).longValue(); - } catch (NumberFormatException e) { - System.err.println("NumberFormatException: ID[" + eName.getText() + "], VALUE=[" + vTxt + "]"); - throw e; - } + newEnum = new Enumerator(eTxt, vTxt); } + } else if( defaultValue.hasNumber() ) { + newEnum = new Enumerator(eTxt, defaultValue.getNumber()); } else { - value = defaultValue; + newEnum = new Enumerator(eTxt, defaultValue.getNativeExpr()); } - - newDefaultValue = value+1; - String eTxt = eName.getText(); - if (enumHash.containsKey(eTxt)) { - EnumType oldEnumType = enumHash.get(eTxt); - long oldValue = oldEnumType.getEnumValue(eTxt); - System.err.println("WARNING: redefinition of enumerated value '" + eTxt + "';" + - " existing definition is in enumeration '" + oldEnumType.getName() + - "' with value " + oldValue + " and new definition is in enumeration '" + - enumeration.getName() + "' with value " + value); - // remove old definition - oldEnumType.removeEnumerate(eTxt); - } - // insert new definition - enumeration.addEnum(eTxt, value); - enumHash.put(eTxt, enumeration); - debugPrintln("ENUM [" + enumeration.getName() + "]: " + eTxt + " = " + enumeration.getEnumValue(eTxt) + - " (new default = " + newDefaultValue + ")"); - } + final ASTLocusTag locus = findASTLocusTag(enumerator_AST_in); + final CNumber newEnumNum = newEnum.getNumber(); + if( null != newEnumNum && newEnumNum.isInteger ) { + final long n = newEnumNum.i+1; + newDefaultValue = new ConstantDefinition("def", String.valueOf(n), new CNumber(newEnumNum.isLong, newEnumNum.isUnsigned, n), locus); + } else { + newDefaultValue = new ConstantDefinition("def", "("+newEnum.getExpr()+")+1", null, locus); + } + if (enumHash.containsKey(eTxt)) { + EnumType oldEnumType = enumHash.get(eTxt); + final Enumerator oldEnum = oldEnumType.getEnum(eTxt); + final String oldExpr = oldEnum.getExpr(); + if( !oldExpr.equals(newEnum.getExpr()) ) { + throwGlueGenException(enumerator_AST_in, + String.format("Duplicate enum value '%s.%s' w/ diff value:%n this %s,%n have %s", + oldEnumType.getName(), eTxt, newEnum, oldEnum)); + } + // remove old definition + oldEnumType.removeEnumerate(eTxt); + } + // insert new definition + enumeration.addEnum(eTxt, newEnum); + enumHash.put(eTxt, enumeration); + debugPrintln("ENUM [" + enumeration.getName() + "]: " + eTxt + " = " + newEnum + + " (new default = " + newDefaultValue + ")"); + } ; initDeclList[TypeBox tb] @@ -692,6 +841,7 @@ initDecl[TypeBox tb] { String declName = null; + final ASTLocusTag locusTag = findASTLocusTag(initDecl_AST_in); } : #( NInitDecl declName = declarator[tb] { @@ -705,23 +855,99 @@ { if ((declName != null) && (tb != null) && tb.isTypedef()) { Type t = tb.type(); - debugPrint("Adding typedef mapping: [" + declName + "] -> "+getTypeString(t)); - if (!t.hasTypedefName()) { - t.setName(declName); - debugPrint(" - declName -> "+getTypeString(t)); + debugPrintln("Adding typedef mapping: [" + declName + "] -> "+getDebugTypeString(t)); + final Type tg; + if( t.isPointer() ) { + tg = t.getTargetType(); + debugPrintln(" - has target: "+getDebugTypeString(tg)); } else { - // copy type to preserve declName ! - t = (Type) t.clone(); - t.setName(declName); - debugPrint(" - copy -> "+getTypeString(t)); + tg = null; + } + // NOTE: Struct Name Resolution (JavaEmitter, HeaderParser) + // Also see NOTE below. + if (!t.isTypedef()) { + if( t.isCompound() || t.isEnum() ) { + // This aliases '_a' -> 'A' for 'typedef struct _a { } A;' in-place + // This aliases '_a' -> 'A' for 'typedef enum _a { } A;' in-place + t.setTypedefName(declName); + debugPrintln(" - alias.11 -> "+getDebugTypeString(t)); + } else { + // Use new typedef, using a copy to preserve canonicalized base type + t = t.clone(locusTag); + t.setTypedefName(declName); + debugPrintln(" - newdefine.12 -> "+getDebugTypeString(t)); + } + } else { + // Adds typeInfo alias w/ t's typeInfo, if exists + cfg.addTypeInfo(declName, t); + final Type alias; + if( t.isCompound() ) { + // This aliases 'D' -> 'A' for 'typedef struct _a { } A, D;' in-place + debugPrintln(" - alias.21 -> "+getDebugTypeString(t)); + } else { + // copy to preserve canonicalized base type + t = t.clone(locusTag); + t.setTypedefName(declName); + debugPrintln(" - copy.22 -> "+getDebugTypeString(t)); + } + } + final Type dupT = typedefDictionary.get(declName); + if( null != dupT && !dupT.equalSemantics(t) ) { + throwGlueGenException(locusTag, + String.format("Duplicate typedef w/ incompatible type:%n this '%s',%n have '%s',%n %s: previous definition is here", + getTypeString(t), getTypeString(dupT), dupT.getASTLocusTag().toString(new StringBuilder(), "note", true))); } t = canonicalize(t); - debugPrintln(" - canon -> "+getTypeString(t)); + debugPrintln(" - canon -> "+getDebugTypeString(t)); typedefDictionary.put(declName, t); // Clear out PointerGroup effects in case another typedef variant follows tb.reset(); } } + /* + // Below just shows a different handling using copying + // and enforcing aliased names, which is not desired. + // Keeping it in here for documentation. + // NOTE: Struct Name Resolution (JavaEmitter, HeaderParser) + if ( !t.isTypedef() ) { + if( t.isCompound() ) { + // This aliases '_a' -> 'A' for 'typedef struct _a { } A;' + t.setTypedefName(declName); + debugPrintln(" - alias.10 -> "+getDebugTypeString(t)); + } else if( null != tg && tg.isCompound() ) { + if( !tg.isTypedef() ) { + // This aliases '_a *' -> 'A*' for 'typedef struct _a { } *A;' + t.setTypedefName(declName); + debugPrintln(" - alias.11 -> "+getDebugTypeString(t)); + } else { + // This aliases 'B' -> 'A*' for 'typedef struct _a { } A, *B;' and 'typedef A * B;' + t = new PointerType(SizeThunk.POINTER, tg, 0, locusTag); // name: 'A*' + t.setTypedefName(t.getName()); // make typedef + debugPrintln(" - alias.12 -> "+getDebugTypeString(t)); + } + } else { + // Use new typedef, using a copy to preserve canonicalized base type + t = t.clone(locusTag); + t.setTypedefName(declName); + debugPrintln(" - newdefine.13 -> "+getDebugTypeString(t)); + } + } else { + // Adds typeInfo alias w/ t's typeInfo, if exists + cfg.addTypeInfo(declName, t); + if( t.isCompound() ) { + // This aliases 'D' -> 'A' for 'typedef struct _a { } A, D;' + debugPrintln(" - alias.20 -> "+getDebugTypeString(t)); + } else if( null != tg && tg.isCompound() ) { + // This aliases 'B' -> 'A' for 'typedef A B;', where A is pointer to compound + debugPrintln(" - alias.21 -> "+getDebugTypeString(t)); + } else { + // copy to preserve canonicalized base type + t = t.clone(locusTag); + t.setTypedefName(declName); + debugPrintln(" - copy.22 -> "+getDebugTypeString(t)); + } + } +*/ ; pointerGroup[TypeBox tb] { int x = 0; int y = 0; } @@ -731,7 +957,8 @@ if (tb != null) { tb.setType(canonicalize(new PointerType(SizeThunk.POINTER, tb.type(), - attrs2CVAttrs(x)))); + attrs2CVAttrs(x), + findASTLocusTag(pointerGroup_AST_in)))); } } )+ ) @@ -756,7 +983,9 @@ /* FIXME: the handling of types in this rule has not been well thought out and is known to be incomplete. Currently it is only used to handle pointerGroups for unnamed parameters. */ -nonemptyAbstractDeclarator[TypeBox tb] +nonemptyAbstractDeclarator[TypeBox tb] { + final ASTLocusTag locusTag = findASTLocusTag(nonemptyAbstractDeclarator_AST_in); +} : #( NNonemptyAbstractDeclarator ( pointerGroup[tb] ( (LPAREN @@ -764,7 +993,7 @@ | parameterTypeList )? RPAREN) - | (LBRACKET (e1:expr)? RBRACKET) { handleArrayExpr(tb, e1); } + | (LBRACKET (e1:expr)? RBRACKET) { handleArrayExpr(tb, e1, locusTag); } )* | ( (LPAREN @@ -772,7 +1001,7 @@ | parameterTypeList )? RPAREN) - | (LBRACKET (e2:expr)? RBRACKET) { handleArrayExpr(tb, e2); } + | (LBRACKET (e2:expr)? RBRACKET) { handleArrayExpr(tb, e2, locusTag); } )+ ) ) @@ -786,13 +1015,17 @@ final String enumName = e.getText(); final EnumType enumType = enumHash.get(enumName); if( null == enumType ) { - throw new IllegalArgumentException("Error: intConstExpr ID "+enumName+" recognized, but no containing enum-type found"); + throwGlueGenException(intConstExpr_AST_in, + "Error: intConstExpr ID "+enumName+" recognized, but no containing enum-type found"); } - final long enumValue = enumType.getEnumValue(enumName); - System.err.println("INFO: intConstExpr: enum[Type "+enumType.getName()+", name "+enumName+", value "+enumValue+"]"); - if( (long)Integer.MIN_VALUE > enumValue || (long)Integer.MAX_VALUE < enumValue ) { - throw new IndexOutOfBoundsException("Error: intConstExpr ID "+enumName+" enum-value "+enumValue+" out of int range"); + final Enumerator enumerator = enumType.getEnum(enumName); + final CNumber number = enumerator.getNumber(); + if( null != number && number.isInteger && !number.isLong ) { + debugPrintln("INFO: intConstExpr: enum[Type "+enumType.getName()+", "+enumerator+"]"); + } else { + throwGlueGenException(intConstExpr_AST_in, + "Error: intConstExpr ID "+enumName+" enum "+enumerator+" not an int32_t"); } - return (int)enumValue; + return (int)number.i; } ; diff -Nru gluegen2-2.2.4/src/antlr/com/jogamp/gluegen/cgram/StdCParser.g gluegen2-2.3.2/src/antlr/com/jogamp/gluegen/cgram/StdCParser.g --- gluegen2-2.2.4/src/antlr/com/jogamp/gluegen/cgram/StdCParser.g 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/antlr/com/jogamp/gluegen/cgram/StdCParser.g 2015-10-09 04:18:28.000000000 +0000 @@ -1131,11 +1131,12 @@ nw:NonWhitespace ("\r\n" | "\r" | "\n") ) { if (n != null) { - //System.out.println("addDefine: #define " + i.getText() + " " + n.getText()); + // System.out.println("addDefine: #define " + i.getText() + " " + n.getText()+" @ "+lineObject.getSource()+":"+(lineObject.line+deferredLineCount)); addDefine(i.getText(), n.getText()); } else { setPreprocessingDirective("#define " + i.getText() + " " + nw.getText()); } + deferredNewline(); } | (~'\n')* { setPreprocessingDirective(getText()); } ) @@ -1165,15 +1166,19 @@ } : { - lineObject = new LineObject(); - deferredLineCount = 0; + lineObject = new LineObject(); + deferredLineCount = 0; } ("line")? //this would be for if the directive started "#line", but not there for GNU directives (Space)+ - n:Number { lineObject.setLine(Integer.parseInt(n.getText())); } + n:Number { + lineObject.setLine(Integer.parseInt(n.getText())); + } (Space)+ ( fn:StringLiteral { try { - lineObject.setSource(fn.getText().substring(1,fn.getText().length()-1)); + final String newSource = fn.getText().substring(1,fn.getText().length()-1); + // System.out.println("line: "+lineObject.getSource()+" -> "+newSource+", line "+(lineObject.line+deferredLineCount)); + lineObject.setSource(newSource); } catch (StringIndexOutOfBoundsException e) { /*not possible*/ } } diff -Nru gluegen2-2.2.4/src/antlr/com/jogamp/gluegen/jgram/JavaParser.g gluegen2-2.3.2/src/antlr/com/jogamp/gluegen/jgram/JavaParser.g --- gluegen2-2.2.4/src/antlr/com/jogamp/gluegen/jgram/JavaParser.g 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/antlr/com/jogamp/gluegen/jgram/JavaParser.g 2015-10-09 04:18:28.000000000 +0000 @@ -8,105 +8,105 @@ * Run 'java Main ' * * Contributing authors: - * John Mitchell johnm@non.net - * Terence Parr parrt@magelang.com - * John Lilley jlilley@empathy.com - * Scott Stanchfield thetick@magelang.com - * Markus Mohnen mohnen@informatik.rwth-aachen.de + * John Mitchell johnm@non.net + * Terence Parr parrt@magelang.com + * John Lilley jlilley@empathy.com + * Scott Stanchfield thetick@magelang.com + * Markus Mohnen mohnen@informatik.rwth-aachen.de * Peter Williams pete.williams@sun.com * Allan Jacobs Allan.Jacobs@eng.sun.com * Steve Messick messick@redhills.com - * John Pybus john@pybus.org + * John Pybus john@pybus.org * * Version 1.00 December 9, 1997 -- initial release * Version 1.01 December 10, 1997 - * fixed bug in octal def (0..7 not 0..8) + * fixed bug in octal def (0..7 not 0..8) * Version 1.10 August 1998 (parrt) - * added tree construction - * fixed definition of WS,comments for mac,pc,unix newlines - * added unary plus + * added tree construction + * fixed definition of WS,comments for mac,pc,unix newlines + * added unary plus * Version 1.11 (Nov 20, 1998) - * Added "shutup" option to turn off last ambig warning. - * Fixed inner class def to allow named class defs as statements - * synchronized requires compound not simple statement - * add [] after builtInType DOT class in primaryExpression - * "const" is reserved but not valid..removed from modifiers + * Added "shutup" option to turn off last ambig warning. + * Fixed inner class def to allow named class defs as statements + * synchronized requires compound not simple statement + * add [] after builtInType DOT class in primaryExpression + * "const" is reserved but not valid..removed from modifiers * Version 1.12 (Feb 2, 1999) - * Changed LITERAL_xxx to xxx in tree grammar. - * Updated java.g to use tokens {...} now for 2.6.0 (new feature). + * Changed LITERAL_xxx to xxx in tree grammar. + * Updated java.g to use tokens {...} now for 2.6.0 (new feature). * * Version 1.13 (Apr 23, 1999) - * Didn't have (stat)? for else clause in tree parser. - * Didn't gen ASTs for interface extends. Updated tree parser too. - * Updated to 2.6.0. + * Didn't have (stat)? for else clause in tree parser. + * Didn't gen ASTs for interface extends. Updated tree parser too. + * Updated to 2.6.0. * Version 1.14 (Jun 20, 1999) - * Allowed final/abstract on local classes. - * Removed local interfaces from methods - * Put instanceof precedence where it belongs...in relationalExpr - * It also had expr not type as arg; fixed it. - * Missing ! on SEMI in classBlock - * fixed: (expr) + "string" was parsed incorrectly (+ as unary plus). - * fixed: didn't like Object[].class in parser or tree parser + * Allowed final/abstract on local classes. + * Removed local interfaces from methods + * Put instanceof precedence where it belongs...in relationalExpr + * It also had expr not type as arg; fixed it. + * Missing ! on SEMI in classBlock + * fixed: (expr) + "string" was parsed incorrectly (+ as unary plus). + * fixed: didn't like Object[].class in parser or tree parser * Version 1.15 (Jun 26, 1999) - * Screwed up rule with instanceof in it. :( Fixed. - * Tree parser didn't like (expr).something; fixed. - * Allowed multiple inheritance in tree grammar. oops. + * Screwed up rule with instanceof in it. :( Fixed. + * Tree parser didn't like (expr).something; fixed. + * Allowed multiple inheritance in tree grammar. oops. * Version 1.16 (August 22, 1999) - * Extending an interface built a wacky tree: had extra EXTENDS. - * Tree grammar didn't allow multiple superinterfaces. - * Tree grammar didn't allow empty var initializer: {} + * Extending an interface built a wacky tree: had extra EXTENDS. + * Tree grammar didn't allow multiple superinterfaces. + * Tree grammar didn't allow empty var initializer: {} * Version 1.17 (October 12, 1999) - * ESC lexer rule allowed 399 max not 377 max. - * java.tree.g didn't handle the expression of synchronized - * statements. + * ESC lexer rule allowed 399 max not 377 max. + * java.tree.g didn't handle the expression of synchronized + * statements. * Version 1.18 (August 12, 2001) - * Terence updated to Java 2 Version 1.3 by - * observing/combining work of Allan Jacobs and Steve - * Messick. Handles 1.3 src. Summary: - * o primary didn't include boolean.class kind of thing - * o constructor calls parsed explicitly now: - * see explicitConstructorInvocation - * o add strictfp modifier - * o missing objBlock after new expression in tree grammar - * o merged local class definition alternatives, moved after declaration - * o fixed problem with ClassName.super.field - * o reordered some alternatives to make things more efficient - * o long and double constants were not differentiated from int/float - * o whitespace rule was inefficient: matched only one char - * o add an examples directory with some nasty 1.3 cases - * o made Main.java use buffered IO and a Reader for Unicode support - * o supports UNICODE? - * Using Unicode charVocabulay makes code file big, but only - * in the bitsets at the end. I need to make ANTLR generate - * unicode bitsets more efficiently. + * Terence updated to Java 2 Version 1.3 by + * observing/combining work of Allan Jacobs and Steve + * Messick. Handles 1.3 src. Summary: + * o primary didn't include boolean.class kind of thing + * o constructor calls parsed explicitly now: + * see explicitConstructorInvocation + * o add strictfp modifier + * o missing objBlock after new expression in tree grammar + * o merged local class definition alternatives, moved after declaration + * o fixed problem with ClassName.super.field + * o reordered some alternatives to make things more efficient + * o long and double constants were not differentiated from int/float + * o whitespace rule was inefficient: matched only one char + * o add an examples directory with some nasty 1.3 cases + * o made Main.java use buffered IO and a Reader for Unicode support + * o supports UNICODE? + * Using Unicode charVocabulay makes code file big, but only + * in the bitsets at the end. I need to make ANTLR generate + * unicode bitsets more efficiently. * Version 1.19 (April 25, 2002) - * Terence added in nice fixes by John Pybus concerning floating - * constants and problems with super() calls. John did a nice - * reorg of the primary/postfix expression stuff to read better - * and makes f.g.super() parse properly (it was METHOD_CALL not - * a SUPER_CTOR_CALL). Also: - * - * o "finally" clause was a root...made it a child of "try" - * o Added stuff for asserts too for Java 1.4, but *commented out* - * as it is not backward compatible. + * Terence added in nice fixes by John Pybus concerning floating + * constants and problems with super() calls. John did a nice + * reorg of the primary/postfix expression stuff to read better + * and makes f.g.super() parse properly (it was METHOD_CALL not + * a SUPER_CTOR_CALL). Also: + * + * o "finally" clause was a root...made it a child of "try" + * o Added stuff for asserts too for Java 1.4, but *commented out* + * as it is not backward compatible. * * Version 1.20 (October 27, 2002) * * Terence ended up reorging John Pybus' stuff to * remove some nondeterminisms and some syntactic predicates. * Note that the grammar is stricter now; e.g., this(...) must - * be the first statement. + * be the first statement. * * Trinary ?: operator wasn't working as array name: * (isBig ? bigDigits : digits)[i]; * * Checked parser/tree parser on source for * Resin-2.0.5, jive-2.1.1, jdk 1.3.1, Lucene, antlr 2.7.2a4, - * and the 110k-line jGuru server source. + * and the 110k-line jGuru server source. * * Version 1.21 (October 17, 2003) - * Fixed lots of problems including: - * Ray Waldin: add typeDefinition to interfaceBlock in java.tree.g + * Fixed lots of problems including: + * Ray Waldin: add typeDefinition to interfaceBlock in java.tree.g * He found a problem/fix with floating point that start with 0 * Ray also fixed problem that (int.class) was not recognized. * Thorsten van Ellen noticed that \n are allowed incorrectly in strings. @@ -129,24 +129,24 @@ class JavaParser extends Parser; options { - k = 2; // two token lookahead - exportVocab=Java; // Call its vocabulary "Java" - codeGenMakeSwitchThreshold = 2; // Some optimizations - codeGenBitsetTestThreshold = 3; - defaultErrorHandler = false; // Don't generate parser error handlers - buildAST = true; - //buildAST = false; + k = 2; // two token lookahead + exportVocab=Java; // Call its vocabulary "Java" + codeGenMakeSwitchThreshold = 2; // Some optimizations + codeGenBitsetTestThreshold = 3; + defaultErrorHandler = false; // Don't generate parser error handlers + buildAST = true; + //buildAST = false; } tokens { - BLOCK; MODIFIERS; OBJBLOCK; SLIST; CTOR_DEF; METHOD_DEF; VARIABLE_DEF; - INSTANCE_INIT; STATIC_INIT; TYPE; CLASS_DEF; INTERFACE_DEF; - PACKAGE_DEF; ARRAY_DECLARATOR; EXTENDS_CLAUSE; IMPLEMENTS_CLAUSE; - PARAMETERS; PARAMETER_DEF; LABELED_STAT; TYPECAST; INDEX_OP; - POST_INC; POST_DEC; METHOD_CALL; EXPR; ARRAY_INIT; - IMPORT; UNARY_MINUS; UNARY_PLUS; CASE_GROUP; ELIST; FOR_INIT; FOR_CONDITION; - FOR_ITERATOR; EMPTY_STAT; FINAL="final"; ABSTRACT="abstract"; - STRICTFP="strictfp"; SUPER_CTOR_CALL; CTOR_CALL; + BLOCK; MODIFIERS; OBJBLOCK; SLIST; CTOR_DEF; METHOD_DEF; VARIABLE_DEF; + INSTANCE_INIT; STATIC_INIT; TYPE; CLASS_DEF; INTERFACE_DEF; + PACKAGE_DEF; ARRAY_DECLARATOR; EXTENDS_CLAUSE; IMPLEMENTS_CLAUSE; + PARAMETERS; PARAMETER_DEF; LABELED_STAT; TYPECAST; INDEX_OP; + POST_INC; POST_DEC; METHOD_CALL; EXPR; ARRAY_INIT; + IMPORT; UNARY_MINUS; UNARY_PLUS; CASE_GROUP; ELIST; FOR_INIT; FOR_CONDITION; + FOR_ITERATOR; EMPTY_STAT; FINAL="final"; ABSTRACT="abstract"; + STRICTFP="strictfp"; SUPER_CTOR_CALL; CTOR_CALL; } { @@ -181,250 +181,250 @@ // Compilation Unit: In Java, this is a single file. This is the start // rule for this parser compilationUnit - : // A compilation unit starts with an optional package definition - ( packageDefinition - | /* nothing */ - ) - - // Next we have a series of zero or more import statements - ( importDefinition )* - - // Wrapping things up with any number of class or interface - // definitions - ( typeDefinition )* + : // A compilation unit starts with an optional package definition + ( packageDefinition + | /* nothing */ + ) + + // Next we have a series of zero or more import statements + ( importDefinition )* + + // Wrapping things up with any number of class or interface + // definitions + ( typeDefinition )* - EOF! - ; + EOF! + ; // Package statement: "package" followed by an identifier. packageDefinition - options {defaultErrorHandler = true;} // let ANTLR handle errors - : p:"package"^ {#p.setType(PACKAGE_DEF);} identifier SEMI! - ; + options {defaultErrorHandler = true;} // let ANTLR handle errors + : p:"package"^ {#p.setType(PACKAGE_DEF);} identifier SEMI! + ; // Import statement: import followed by a package or class name importDefinition - options {defaultErrorHandler = true;} - : i:"import"^ {#i.setType(IMPORT);} identifierStar SEMI! - ; + options {defaultErrorHandler = true;} + : i:"import"^ {#i.setType(IMPORT);} identifierStar SEMI! + ; // A type definition in a file is either a class or interface definition. typeDefinition - options {defaultErrorHandler = true;} - : m:modifiers! - ( classDefinition[#m] - | interfaceDefinition[#m] - ) - | SEMI! - ; + options {defaultErrorHandler = true;} + : m:modifiers! + ( classDefinition[#m] + | interfaceDefinition[#m] + ) + | SEMI! + ; /** A declaration is the creation of a reference or primitive-type variable * Create a separate Type/Var tree for each var in the var list. */ declaration! - : m:modifiers t:typeSpec[false] v:variableDefinitions[#m,#t] - {#declaration = #v;} - ; + : m:modifiers t:typeSpec[false] v:variableDefinitions[#m,#t] + {#declaration = #v;} + ; // A type specification is a type name with possible brackets afterwards // (which would make it an array type). typeSpec[boolean addImagNode] - : classTypeSpec[addImagNode] - | builtInTypeSpec[addImagNode] - ; + : classTypeSpec[addImagNode] + | builtInTypeSpec[addImagNode] + ; // A class type specification is a class type with possible brackets afterwards // (which would make it an array type). classTypeSpec[boolean addImagNode] - : identifier (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)* - { - if ( addImagNode ) { - #classTypeSpec = #(#[TYPE,"TYPE"], #classTypeSpec); - } - } - ; + : identifier (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)* + { + if ( addImagNode ) { + #classTypeSpec = #(#[TYPE,"TYPE"], #classTypeSpec); + } + } + ; // A builtin type specification is a builtin type with possible brackets // afterwards (which would make it an array type). builtInTypeSpec[boolean addImagNode] - : builtInType (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)* - { - if ( addImagNode ) { - #builtInTypeSpec = #(#[TYPE,"TYPE"], #builtInTypeSpec); - } - } - ; + : builtInType (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)* + { + if ( addImagNode ) { + #builtInTypeSpec = #(#[TYPE,"TYPE"], #builtInTypeSpec); + } + } + ; // A type name. which is either a (possibly qualified) class name or // a primitive (builtin) type type - : identifier - | builtInType - ; + : identifier + | builtInType + ; // The primitive types. builtInType - : "void" - | "boolean" - | "byte" - | "char" - | "short" - | "int" - | "float" - | "long" - | "double" - ; + : "void" + | "boolean" + | "byte" + | "char" + | "short" + | "int" + | "float" + | "long" + | "double" + ; // A (possibly-qualified) java identifier. We start with the first IDENT // and expand its name by adding dots and following IDENTS identifier - : IDENT ( DOT^ IDENT )* - ; + : IDENT ( DOT^ IDENT )* + ; identifierStar - : IDENT - ( DOT^ IDENT )* - ( DOT^ STAR )? - ; + : IDENT + ( DOT^ IDENT )* + ( DOT^ STAR )? + ; // A list of zero or more modifiers. We could have used (modifier)* in // place of a call to modifiers, but I thought it was a good idea to keep // this rule separate so they can easily be collected in a Vector if // someone so desires modifiers - : ( modifier )* - {#modifiers = #([MODIFIERS, "MODIFIERS"], #modifiers);} - ; + : ( modifier )* + {#modifiers = #([MODIFIERS, "MODIFIERS"], #modifiers);} + ; // modifiers for Java classes, interfaces, class/instance vars and methods modifier - : "private" - | "public" - | "protected" - | "static" - | "transient" - | "final" - | "abstract" - | "native" - | "threadsafe" - | "synchronized" -// | "const" // reserved word, but not valid - | "volatile" - | "strictfp" - ; + : "private" + | "public" + | "protected" + | "static" + | "transient" + | "final" + | "abstract" + | "native" + | "threadsafe" + | "synchronized" +// | "const" // reserved word, but not valid + | "volatile" + | "strictfp" + ; // Definition of a Java class classDefinition![AST modifiers] - : "class" IDENT - // it _might_ have a superclass... - sc:superClassClause - // it might implement some interfaces... - ic:implementsClause - // now parse the body of the class - cb:classBlock - {#classDefinition = #(#[CLASS_DEF,"CLASS_DEF"], - modifiers,IDENT,sc,ic,cb);} - ; + : "class" IDENT + // it _might_ have a superclass... + sc:superClassClause + // it might implement some interfaces... + ic:implementsClause + // now parse the body of the class + cb:classBlock + {#classDefinition = #(#[CLASS_DEF,"CLASS_DEF"], + modifiers,IDENT,sc,ic,cb);} + ; superClassClause! - : ( "extends" id:identifier )? - {#superClassClause = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"],id);} - ; + : ( "extends" id:identifier )? + {#superClassClause = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"],id);} + ; // Definition of a Java Interface interfaceDefinition![AST modifiers] - : "interface" IDENT - // it might extend some other interfaces - ie:interfaceExtends - // now parse the body of the interface (looks like a class...) - cb:classBlock - {#interfaceDefinition = #(#[INTERFACE_DEF,"INTERFACE_DEF"], - modifiers,IDENT,ie,cb);} - ; + : "interface" IDENT + // it might extend some other interfaces + ie:interfaceExtends + // now parse the body of the interface (looks like a class...) + cb:classBlock + {#interfaceDefinition = #(#[INTERFACE_DEF,"INTERFACE_DEF"], + modifiers,IDENT,ie,cb);} + ; // This is the body of a class. You can have fields and extra semicolons, // That's about it (until you see what a field is...) classBlock - : LCURLY! { blockDepth++; } - ( field | SEMI! )* - RCURLY! { blockDepth--; } - {#classBlock = #([OBJBLOCK, "OBJBLOCK"], #classBlock);} - ; + : LCURLY! { blockDepth++; } + ( field | SEMI! )* + RCURLY! { blockDepth--; } + {#classBlock = #([OBJBLOCK, "OBJBLOCK"], #classBlock);} + ; // An interface can extend several other interfaces... interfaceExtends - : ( - e:"extends"! - identifier ( COMMA! identifier )* - )? - {#interfaceExtends = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"], - #interfaceExtends);} - ; + : ( + e:"extends"! + identifier ( COMMA! identifier )* + )? + {#interfaceExtends = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"], + #interfaceExtends);} + ; // A class can implement several interfaces... implementsClause - : ( - i:"implements"! identifier ( COMMA! identifier )* - )? - {#implementsClause = #(#[IMPLEMENTS_CLAUSE,"IMPLEMENTS_CLAUSE"], - #implementsClause);} - ; + : ( + i:"implements"! identifier ( COMMA! identifier )* + )? + {#implementsClause = #(#[IMPLEMENTS_CLAUSE,"IMPLEMENTS_CLAUSE"], + #implementsClause);} + ; // Now the various things that can be defined inside a class or interface... // Note that not all of these are really valid in an interface (constructors, // for example), and if this grammar were used for a compiler there would // need to be some semantic checks to make sure we're doing the right thing... field! - : // method, constructor, or variable declaration - mods:modifiers - ( h:ctorHead s:constructorBody // constructor - {#field = #(#[CTOR_DEF,"CTOR_DEF"], mods, h, s);} - - | cd:classDefinition[#mods] // inner class - {#field = #cd;} - - | id:interfaceDefinition[#mods] // inner interface - {#field = #id;} - - | t:typeSpec[false] // method or variable declaration(s) - ( fn:IDENT // the name of the method - - // parse the formal parameter declarations. - LPAREN! param:parameterDeclarationList RPAREN! - - rt:declaratorBrackets[#t] - - // get the list of exceptions that this method is - // declared to throw - (tc:throwsClause)? - - ( s2:compoundStatement | SEMI ) - {#field = #(#[METHOD_DEF,"METHOD_DEF"], - mods, - #(#[TYPE,"TYPE"],rt), - fn, - param, - tc, - s2); + : // method, constructor, or variable declaration + mods:modifiers + ( h:ctorHead s:constructorBody // constructor + {#field = #(#[CTOR_DEF,"CTOR_DEF"], mods, h, s);} + + | cd:classDefinition[#mods] // inner class + {#field = #cd;} + + | id:interfaceDefinition[#mods] // inner interface + {#field = #id;} + + | t:typeSpec[false] // method or variable declaration(s) + ( fn:IDENT // the name of the method + + // parse the formal parameter declarations. + LPAREN! param:parameterDeclarationList RPAREN! + + rt:declaratorBrackets[#t] + + // get the list of exceptions that this method is + // declared to throw + (tc:throwsClause)? + + ( s2:compoundStatement | SEMI ) + {#field = #(#[METHOD_DEF,"METHOD_DEF"], + mods, + #(#[TYPE,"TYPE"],rt), + fn, + param, + tc, + s2); if(blockDepth==1) { functionNames.add(fn.getText()); } } - | v:variableDefinitions[#mods,#t] SEMI -// {#field = #(#[VARIABLE_DEF,"VARIABLE_DEF"], v);} - {#field = #v;} - ) - ) + | v:variableDefinitions[#mods,#t] SEMI +// {#field = #(#[VARIABLE_DEF,"VARIABLE_DEF"], v);} + {#field = #v;} + ) + ) // "static { ... }" class initializer - | "static" s3:compoundStatement - {#field = #(#[STATIC_INIT,"STATIC_INIT"], s3);} + | "static" s3:compoundStatement + {#field = #(#[STATIC_INIT,"STATIC_INIT"], s3);} // "{ ... }" instance initializer - | s4:compoundStatement - {#field = #(#[INSTANCE_INIT,"INSTANCE_INIT"], s4);} - ; + | s4:compoundStatement + {#field = #(#[INSTANCE_INIT,"INSTANCE_INIT"], s4);} + ; constructorBody : lc:LCURLY^ {#lc.setType(SLIST); blockDepth++; } @@ -436,108 +436,108 @@ /** Catch obvious constructor calls, but not the expr.super(...) calls */ explicitConstructorInvocation : "this"! lp1:LPAREN^ argList RPAREN! SEMI! - {#lp1.setType(CTOR_CALL);} + {#lp1.setType(CTOR_CALL);} | "super"! lp2:LPAREN^ argList RPAREN! SEMI! - {#lp2.setType(SUPER_CTOR_CALL);} + {#lp2.setType(SUPER_CTOR_CALL);} ; variableDefinitions[AST mods, AST t] - : variableDeclarator[getASTFactory().dupTree(mods), - getASTFactory().dupTree(t)] - ( COMMA! - variableDeclarator[getASTFactory().dupTree(mods), - getASTFactory().dupTree(t)] - )* - ; + : variableDeclarator[getASTFactory().dupTree(mods), + getASTFactory().dupTree(t)] + ( COMMA! + variableDeclarator[getASTFactory().dupTree(mods), + getASTFactory().dupTree(t)] + )* + ; /** Declaration of a variable. This can be a class/instance variable, * or a local variable in a method * It can also include possible initialization. */ variableDeclarator![AST mods, AST t] - : id:IDENT d:declaratorBrackets[t] v:varInitializer - {#variableDeclarator = #(#[VARIABLE_DEF,"VARIABLE_DEF"], mods, #(#[TYPE,"TYPE"],d), id, v); + : id:IDENT d:declaratorBrackets[t] v:varInitializer + {#variableDeclarator = #(#[VARIABLE_DEF,"VARIABLE_DEF"], mods, #(#[TYPE,"TYPE"],d), id, v); if(blockDepth==1) { enumNames.add(id.getText()); } } - ; + ; declaratorBrackets[AST typ] - : {#declaratorBrackets=typ;} - (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)* - ; + : {#declaratorBrackets=typ;} + (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)* + ; varInitializer - : ( ASSIGN^ initializer )? - ; + : ( ASSIGN^ initializer )? + ; // This is an initializer used to set up an array. arrayInitializer - : lc:LCURLY^ {#lc.setType(ARRAY_INIT); blockDepth++; } - ( initializer - ( - // CONFLICT: does a COMMA after an initializer start a new - // initializer or start the option ',' at end? - // ANTLR generates proper code by matching - // the comma as soon as possible. - options { - warnWhenFollowAmbig = false; - } - : - COMMA! initializer - )* - (COMMA!)? - )? - RCURLY! { blockDepth--; } - ; + : lc:LCURLY^ {#lc.setType(ARRAY_INIT); blockDepth++; } + ( initializer + ( + // CONFLICT: does a COMMA after an initializer start a new + // initializer or start the option ',' at end? + // ANTLR generates proper code by matching + // the comma as soon as possible. + options { + warnWhenFollowAmbig = false; + } + : + COMMA! initializer + )* + (COMMA!)? + )? + RCURLY! { blockDepth--; } + ; // The two "things" that can initialize an array element are an expression // and another (nested) array initializer. initializer - : expression - | arrayInitializer - ; + : expression + | arrayInitializer + ; // This is the header of a method. It includes the name and parameters // for the method. // This also watches for a list of exception classes in a "throws" clause. ctorHead - : IDENT // the name of the method + : IDENT // the name of the method - // parse the formal parameter declarations. - LPAREN! parameterDeclarationList RPAREN! + // parse the formal parameter declarations. + LPAREN! parameterDeclarationList RPAREN! - // get the list of exceptions that this method is declared to throw - (throwsClause)? - ; + // get the list of exceptions that this method is declared to throw + (throwsClause)? + ; // This is a list of exception classes that the method is declared to throw throwsClause - : "throws"^ identifier ( COMMA! identifier )* - ; + : "throws"^ identifier ( COMMA! identifier )* + ; // A list of formal parameters parameterDeclarationList - : ( parameterDeclaration ( COMMA! parameterDeclaration )* )? - {#parameterDeclarationList = #(#[PARAMETERS,"PARAMETERS"], - #parameterDeclarationList);} - ; + : ( parameterDeclaration ( COMMA! parameterDeclaration )* )? + {#parameterDeclarationList = #(#[PARAMETERS,"PARAMETERS"], + #parameterDeclarationList);} + ; // A formal parameter. parameterDeclaration! - : pm:parameterModifier t:typeSpec[false] id:IDENT - pd:declaratorBrackets[#t] - {#parameterDeclaration = #(#[PARAMETER_DEF,"PARAMETER_DEF"], - pm, #([TYPE,"TYPE"],pd), id);} - ; + : pm:parameterModifier t:typeSpec[false] id:IDENT + pd:declaratorBrackets[#t] + {#parameterDeclaration = #(#[PARAMETER_DEF,"PARAMETER_DEF"], + pm, #([TYPE,"TYPE"],pd), id);} + ; parameterModifier - : (f:"final")? - {#parameterModifier = #(#[MODIFIERS,"MODIFIERS"], f);} - ; + : (f:"final")? + {#parameterModifier = #(#[MODIFIERS,"MODIFIERS"], f);} + ; // Compound statement. This is used in many contexts: // Inside a class definition prefixed with "static": @@ -549,151 +549,151 @@ // it starts a new scope for variable definitions compoundStatement - : lc:LCURLY^ {#lc.setType(SLIST); blockDepth++; } - // include the (possibly-empty) list of statements - (statement)* - RCURLY! { blockDepth--; } - ; + : lc:LCURLY^ {#lc.setType(SLIST); blockDepth++; } + // include the (possibly-empty) list of statements + (statement)* + RCURLY! { blockDepth--; } + ; statement - // A list of statements in curly braces -- start a new scope! - : compoundStatement + // A list of statements in curly braces -- start a new scope! + : compoundStatement - // declarations are ambiguous with "ID DOT" relative to expression - // statements. Must backtrack to be sure. Could use a semantic - // predicate to test symbol table to see what the type was coming - // up, but that's pretty hard without a symbol table ;) - | (declaration)=> declaration SEMI! - - // An expression statement. This could be a method call, - // assignment statement, or any other expression evaluated for - // side-effects. - | expression SEMI! - - // class definition - | m:modifiers! classDefinition[#m] - - // Attach a label to the front of a statement - | IDENT c:COLON^ {#c.setType(LABELED_STAT);} statement - - // If-else statement - | "if"^ LPAREN! expression RPAREN! statement - ( - // CONFLICT: the old "dangling-else" problem... - // ANTLR generates proper code matching - // as soon as possible. Hush warning. - options { - warnWhenFollowAmbig = false; - } - : - "else"! statement - )? - - // For statement - | "for"^ - LPAREN! - forInit SEMI! // initializer - forCond SEMI! // condition test - forIter // updater - RPAREN! - statement // statement to loop over - - // While statement - | "while"^ LPAREN! expression RPAREN! statement - - // do-while statement - | "do"^ statement "while"! LPAREN! expression RPAREN! SEMI! - - // get out of a loop (or switch) - | "break"^ (IDENT)? SEMI! - - // do next iteration of a loop - | "continue"^ (IDENT)? SEMI! - - // Return an expression - | "return"^ (expression)? SEMI! - - // switch/case statement - | "switch"^ LPAREN! expression RPAREN! LCURLY! { blockDepth++; } - ( casesGroup )* - RCURLY! { blockDepth--; } - - // exception try-catch block - | tryBlock - - // throw an exception - | "throw"^ expression SEMI! - - // synchronize a statement - | "synchronized"^ LPAREN! expression RPAREN! compoundStatement - - // asserts (uncomment if you want 1.4 compatibility) - // | "assert"^ expression ( COLON! expression )? SEMI! - - // empty statement - | s:SEMI {#s.setType(EMPTY_STAT);} - ; + // declarations are ambiguous with "ID DOT" relative to expression + // statements. Must backtrack to be sure. Could use a semantic + // predicate to test symbol table to see what the type was coming + // up, but that's pretty hard without a symbol table ;) + | (declaration)=> declaration SEMI! + + // An expression statement. This could be a method call, + // assignment statement, or any other expression evaluated for + // side-effects. + | expression SEMI! + + // class definition + | m:modifiers! classDefinition[#m] + + // Attach a label to the front of a statement + | IDENT c:COLON^ {#c.setType(LABELED_STAT);} statement + + // If-else statement + | "if"^ LPAREN! expression RPAREN! statement + ( + // CONFLICT: the old "dangling-else" problem... + // ANTLR generates proper code matching + // as soon as possible. Hush warning. + options { + warnWhenFollowAmbig = false; + } + : + "else"! statement + )? + + // For statement + | "for"^ + LPAREN! + forInit SEMI! // initializer + forCond SEMI! // condition test + forIter // updater + RPAREN! + statement // statement to loop over + + // While statement + | "while"^ LPAREN! expression RPAREN! statement + + // do-while statement + | "do"^ statement "while"! LPAREN! expression RPAREN! SEMI! + + // get out of a loop (or switch) + | "break"^ (IDENT)? SEMI! + + // do next iteration of a loop + | "continue"^ (IDENT)? SEMI! + + // Return an expression + | "return"^ (expression)? SEMI! + + // switch/case statement + | "switch"^ LPAREN! expression RPAREN! LCURLY! { blockDepth++; } + ( casesGroup )* + RCURLY! { blockDepth--; } + + // exception try-catch block + | tryBlock + + // throw an exception + | "throw"^ expression SEMI! + + // synchronize a statement + | "synchronized"^ LPAREN! expression RPAREN! compoundStatement + + // asserts (uncomment if you want 1.4 compatibility) + // | "assert"^ expression ( COLON! expression )? SEMI! + + // empty statement + | s:SEMI {#s.setType(EMPTY_STAT);} + ; casesGroup - : ( // CONFLICT: to which case group do the statements bind? - // ANTLR generates proper code: it groups the - // many "case"/"default" labels together then - // follows them with the statements - options { - greedy = true; - } - : - aCase - )+ - caseSList - {#casesGroup = #([CASE_GROUP, "CASE_GROUP"], #casesGroup);} - ; + : ( // CONFLICT: to which case group do the statements bind? + // ANTLR generates proper code: it groups the + // many "case"/"default" labels together then + // follows them with the statements + options { + greedy = true; + } + : + aCase + )+ + caseSList + {#casesGroup = #([CASE_GROUP, "CASE_GROUP"], #casesGroup);} + ; aCase - : ("case"^ expression | "default") COLON! - ; + : ("case"^ expression | "default") COLON! + ; caseSList - : (statement)* - {#caseSList = #(#[SLIST,"SLIST"],#caseSList);} - ; + : (statement)* + {#caseSList = #(#[SLIST,"SLIST"],#caseSList);} + ; // The initializer for a for loop forInit - // if it looks like a declaration, it is - : ( (declaration)=> declaration - // otherwise it could be an expression list... - | expressionList - )? - {#forInit = #(#[FOR_INIT,"FOR_INIT"],#forInit);} - ; + // if it looks like a declaration, it is + : ( (declaration)=> declaration + // otherwise it could be an expression list... + | expressionList + )? + {#forInit = #(#[FOR_INIT,"FOR_INIT"],#forInit);} + ; forCond - : (expression)? - {#forCond = #(#[FOR_CONDITION,"FOR_CONDITION"],#forCond);} - ; + : (expression)? + {#forCond = #(#[FOR_CONDITION,"FOR_CONDITION"],#forCond);} + ; forIter - : (expressionList)? - {#forIter = #(#[FOR_ITERATOR,"FOR_ITERATOR"],#forIter);} - ; + : (expressionList)? + {#forIter = #(#[FOR_ITERATOR,"FOR_ITERATOR"],#forIter);} + ; // an exception handler try/catch block tryBlock - : "try"^ compoundStatement - (handler)* - ( finallyClause )? - ; + : "try"^ compoundStatement + (handler)* + ( finallyClause )? + ; finallyClause - : "finally"^ compoundStatement - ; + : "finally"^ compoundStatement + ; // an exception handler handler - : "catch"^ LPAREN! parameterDeclaration RPAREN! compoundStatement - ; + : "catch"^ LPAREN! parameterDeclaration RPAREN! compoundStatement + ; // expressions @@ -732,22 +732,22 @@ // the mother of all expressions expression - : assignmentExpression - {#expression = #(#[EXPR,"EXPR"],#expression);} - ; + : assignmentExpression + {#expression = #(#[EXPR,"EXPR"],#expression);} + ; // This is a list of expressions. expressionList - : expression (COMMA! expression)* - {#expressionList = #(#[ELIST,"ELIST"], expressionList);} - ; + : expression (COMMA! expression)* + {#expressionList = #(#[ELIST,"ELIST"], expressionList);} + ; // assignment expression (level 13) assignmentExpression - : conditionalExpression - ( ( ASSIGN^ + : conditionalExpression + ( ( ASSIGN^ | PLUS_ASSIGN^ | MINUS_ASSIGN^ | STAR_ASSIGN^ @@ -760,99 +760,99 @@ | BXOR_ASSIGN^ | BOR_ASSIGN^ ) - assignmentExpression - )? - ; + assignmentExpression + )? + ; // conditional test (level 12) conditionalExpression - : logicalOrExpression - ( QUESTION^ assignmentExpression COLON! conditionalExpression )? - ; + : logicalOrExpression + ( QUESTION^ assignmentExpression COLON! conditionalExpression )? + ; // logical or (||) (level 11) logicalOrExpression - : logicalAndExpression (LOR^ logicalAndExpression)* - ; + : logicalAndExpression (LOR^ logicalAndExpression)* + ; // logical and (&&) (level 10) logicalAndExpression - : inclusiveOrExpression (LAND^ inclusiveOrExpression)* - ; + : inclusiveOrExpression (LAND^ inclusiveOrExpression)* + ; // bitwise or non-short-circuiting or (|) (level 9) inclusiveOrExpression - : exclusiveOrExpression (BOR^ exclusiveOrExpression)* - ; + : exclusiveOrExpression (BOR^ exclusiveOrExpression)* + ; // exclusive or (^) (level 8) exclusiveOrExpression - : andExpression (BXOR^ andExpression)* - ; + : andExpression (BXOR^ andExpression)* + ; // bitwise or non-short-circuiting and (&) (level 7) andExpression - : equalityExpression (BAND^ equalityExpression)* - ; + : equalityExpression (BAND^ equalityExpression)* + ; // equality/inequality (==/!=) (level 6) equalityExpression - : relationalExpression ((NOT_EQUAL^ | EQUAL^) relationalExpression)* - ; + : relationalExpression ((NOT_EQUAL^ | EQUAL^) relationalExpression)* + ; // boolean relational expressions (level 5) relationalExpression - : shiftExpression - ( ( ( LT^ - | GT^ - | LE^ - | GE^ - ) - shiftExpression - )* - | "instanceof"^ typeSpec[true] - ) - ; + : shiftExpression + ( ( ( LT^ + | GT^ + | LE^ + | GE^ + ) + shiftExpression + )* + | "instanceof"^ typeSpec[true] + ) + ; // bit shift expressions (level 4) shiftExpression - : additiveExpression ((SL^ | SR^ | BSR^) additiveExpression)* - ; + : additiveExpression ((SL^ | SR^ | BSR^) additiveExpression)* + ; // binary addition/subtraction (level 3) additiveExpression - : multiplicativeExpression ((PLUS^ | MINUS^) multiplicativeExpression)* - ; + : multiplicativeExpression ((PLUS^ | MINUS^) multiplicativeExpression)* + ; // multiplication/division/modulo (level 2) multiplicativeExpression - : unaryExpression ((STAR^ | DIV^ | MOD^ ) unaryExpression)* - ; + : unaryExpression ((STAR^ | DIV^ | MOD^ ) unaryExpression)* + ; unaryExpression - : INC^ unaryExpression - | DEC^ unaryExpression - | MINUS^ {#MINUS.setType(UNARY_MINUS);} unaryExpression - | PLUS^ {#PLUS.setType(UNARY_PLUS);} unaryExpression - | unaryExpressionNotPlusMinus - ; + : INC^ unaryExpression + | DEC^ unaryExpression + | MINUS^ {#MINUS.setType(UNARY_MINUS);} unaryExpression + | PLUS^ {#PLUS.setType(UNARY_PLUS);} unaryExpression + | unaryExpressionNotPlusMinus + ; unaryExpressionNotPlusMinus - : BNOT^ unaryExpression - | LNOT^ unaryExpression + : BNOT^ unaryExpression + | LNOT^ unaryExpression - // use predicate to skip cases like: (int.class) + // use predicate to skip cases like: (int.class) | (LPAREN builtInTypeSpec[true] RPAREN) => lpb:LPAREN^ {#lpb.setType(TYPECAST);} builtInTypeSpec[true] RPAREN! unaryExpression @@ -860,108 +860,108 @@ // Have to backtrack to see if operator follows. If no operator // follows, it's a typecast. No semantic checking needed to parse. // if it _looks_ like a cast, it _is_ a cast; else it's a "(expr)" - | (LPAREN classTypeSpec[true] RPAREN unaryExpressionNotPlusMinus)=> + | (LPAREN classTypeSpec[true] RPAREN unaryExpressionNotPlusMinus)=> lp:LPAREN^ {#lp.setType(TYPECAST);} classTypeSpec[true] RPAREN! unaryExpressionNotPlusMinus - | postfixExpression - ; + | postfixExpression + ; // qualified names, array expressions, method invocation, post inc/dec postfixExpression - : + : /* "this"! lp1:LPAREN^ argList RPAREN! - {#lp1.setType(CTOR_CALL);} + {#lp1.setType(CTOR_CALL);} | "super"! lp2:LPAREN^ argList RPAREN! - {#lp2.setType(SUPER_CTOR_CALL);} + {#lp2.setType(SUPER_CTOR_CALL);} | */ primaryExpression - ( + ( /* options { - // the use of postfixExpression in SUPER_CTOR_CALL adds DOT - // to the lookahead set, and gives loads of false non-det - // warnings. - // shut them off. - generateAmbigWarnings=false; - } - : */ + // the use of postfixExpression in SUPER_CTOR_CALL adds DOT + // to the lookahead set, and gives loads of false non-det + // warnings. + // shut them off. + generateAmbigWarnings=false; + } + : */ DOT^ IDENT - ( lp:LPAREN^ {#lp.setType(METHOD_CALL);} - argList - RPAREN! - )? - | DOT^ "this" + ( lp:LPAREN^ {#lp.setType(METHOD_CALL);} + argList + RPAREN! + )? + | DOT^ "this" - | DOT^ "super" + | DOT^ "super" ( // (new Outer()).super() (create enclosing instance) lp3:LPAREN^ argList RPAREN! {#lp3.setType(SUPER_CTOR_CALL);} - | DOT^ IDENT - ( lps:LPAREN^ {#lps.setType(METHOD_CALL);} + | DOT^ IDENT + ( lps:LPAREN^ {#lps.setType(METHOD_CALL);} argList RPAREN! )? ) - | DOT^ newExpression - | lb:LBRACK^ {#lb.setType(INDEX_OP);} expression RBRACK! - )* + | DOT^ newExpression + | lb:LBRACK^ {#lb.setType(INDEX_OP);} expression RBRACK! + )* - ( // possibly add on a post-increment or post-decrement. + ( // possibly add on a post-increment or post-decrement. // allows INC/DEC on too much, but semantics can check - in:INC^ {#in.setType(POST_INC);} - | de:DEC^ {#de.setType(POST_DEC);} - )? - ; + in:INC^ {#in.setType(POST_INC);} + | de:DEC^ {#de.setType(POST_DEC);} + )? + ; // the basic element of an expression primaryExpression - : identPrimary ( options {greedy=true;} : DOT^ "class" )? + : identPrimary ( options {greedy=true;} : DOT^ "class" )? | constant - | "true" - | "false" - | "null" + | "true" + | "false" + | "null" | newExpression - | "this" - | "super" - | LPAREN! assignmentExpression RPAREN! - // look for int.class and int[].class - | builtInType - ( lbt:LBRACK^ {#lbt.setType(ARRAY_DECLARATOR);} RBRACK! )* - DOT^ "class" - ; + | "this" + | "super" + | LPAREN! assignmentExpression RPAREN! + // look for int.class and int[].class + | builtInType + ( lbt:LBRACK^ {#lbt.setType(ARRAY_DECLARATOR);} RBRACK! )* + DOT^ "class" + ; /** Match a, a.b.c refs, a.b.c(...) refs, a.b.c[], a.b.c[].class, * and a.b.c.class refs. Also this(...) and super(...). Match * this or super. */ identPrimary - : IDENT - ( + : IDENT + ( options { - // .ident could match here or in postfixExpression. - // We do want to match here. Turn off warning. - greedy=true; - } - : DOT^ IDENT - )* - ( + // .ident could match here or in postfixExpression. + // We do want to match here. Turn off warning. + greedy=true; + } + : DOT^ IDENT + )* + ( options { - // ARRAY_DECLARATOR here conflicts with INDEX_OP in - // postfixExpression on LBRACK RBRACK. - // We want to match [] here, so greedy. This overcomes + // ARRAY_DECLARATOR here conflicts with INDEX_OP in + // postfixExpression on LBRACK RBRACK. + // We want to match [] here, so greedy. This overcomes // limitation of linear approximate lookahead. - greedy=true; - } - : ( lp:LPAREN^ {#lp.setType(METHOD_CALL);} argList RPAREN! ) - | ( options {greedy=true;} : + greedy=true; + } + : ( lp:LPAREN^ {#lp.setType(METHOD_CALL);} argList RPAREN! ) + | ( options {greedy=true;} : lbc:LBRACK^ {#lbc.setType(ARRAY_DECLARATOR);} RBRACK! )+ - )? + )? ; /** object instantiation. @@ -1014,53 +1014,53 @@ * */ newExpression - : "new"^ type - ( LPAREN! argList RPAREN! (classBlock)? + : "new"^ type + ( LPAREN! argList RPAREN! (classBlock)? - //java 1.1 - // Note: This will allow bad constructs like - // new int[4][][3] {exp,exp}. - // There needs to be a semantic check here... - // to make sure: - // a) [ expr ] and [ ] are not mixed - // b) [ expr ] and an init are not used together - - | newArrayDeclarator (arrayInitializer)? - ) - ; + //java 1.1 + // Note: This will allow bad constructs like + // new int[4][][3] {exp,exp}. + // There needs to be a semantic check here... + // to make sure: + // a) [ expr ] and [ ] are not mixed + // b) [ expr ] and an init are not used together + + | newArrayDeclarator (arrayInitializer)? + ) + ; argList - : ( expressionList - | /*nothing*/ - {#argList = #[ELIST,"ELIST"];} - ) - ; + : ( expressionList + | /*nothing*/ + {#argList = #[ELIST,"ELIST"];} + ) + ; newArrayDeclarator - : ( - // CONFLICT: - // newExpression is a primaryExpression which can be - // followed by an array index reference. This is ok, - // as the generated code will stay in this loop as - // long as it sees an LBRACK (proper behavior) - options { - warnWhenFollowAmbig = false; - } - : - lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} - (expression)? - RBRACK! - )+ - ; + : ( + // CONFLICT: + // newExpression is a primaryExpression which can be + // followed by an array index reference. This is ok, + // as the generated code will stay in this loop as + // long as it sees an LBRACK (proper behavior) + options { + warnWhenFollowAmbig = false; + } + : + lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} + (expression)? + RBRACK! + )+ + ; constant - : NUM_INT - | CHAR_LITERAL - | STRING_LITERAL - | NUM_FLOAT - | NUM_LONG - | NUM_DOUBLE - ; + : NUM_INT + | CHAR_LITERAL + | STRING_LITERAL + | NUM_FLOAT + | NUM_LONG + | NUM_DOUBLE + ; //---------------------------------------------------------------------------- // The Java scanner @@ -1068,121 +1068,121 @@ class JavaLexer extends Lexer; options { - exportVocab=Java; // call the vocabulary "Java" - testLiterals=false; // don't automatically test for literals - k=4; // four characters of lookahead - charVocabulary='\u0003'..'\u7FFE'; - // without inlining some bitset tests, couldn't do unicode; - // I need to make ANTLR generate smaller bitsets; see - // bottom of JavaLexer.java - codeGenBitsetTestThreshold=20; + exportVocab=Java; // call the vocabulary "Java" + testLiterals=false; // don't automatically test for literals + k=4; // four characters of lookahead + charVocabulary='\u0003'..'\u7FFE'; + // without inlining some bitset tests, couldn't do unicode; + // I need to make ANTLR generate smaller bitsets; see + // bottom of JavaLexer.java + codeGenBitsetTestThreshold=20; } // OPERATORS -QUESTION : '?' ; -LPAREN : '(' ; -RPAREN : ')' ; -LBRACK : '[' ; -RBRACK : ']' ; -LCURLY : '{' ; -RCURLY : '}' ; -COLON : ':' ; -COMMA : ',' ; -//DOT : '.' ; -ASSIGN : '=' ; -EQUAL : "==" ; -LNOT : '!' ; -BNOT : '~' ; -NOT_EQUAL : "!=" ; -DIV : '/' ; -DIV_ASSIGN : "/=" ; -PLUS : '+' ; -PLUS_ASSIGN : "+=" ; -INC : "++" ; -MINUS : '-' ; -MINUS_ASSIGN : "-=" ; -DEC : "--" ; -STAR : '*' ; -STAR_ASSIGN : "*=" ; -MOD : '%' ; -MOD_ASSIGN : "%=" ; -SR : ">>" ; -SR_ASSIGN : ">>=" ; -BSR : ">>>" ; -BSR_ASSIGN : ">>>=" ; -GE : ">=" ; -GT : ">" ; -SL : "<<" ; -SL_ASSIGN : "<<=" ; -LE : "<=" ; -LT : '<' ; -BXOR : '^' ; -BXOR_ASSIGN : "^=" ; -BOR : '|' ; -BOR_ASSIGN : "|=" ; -LOR : "||" ; -BAND : '&' ; -BAND_ASSIGN : "&=" ; -LAND : "&&" ; -SEMI : ';' ; +QUESTION : '?' ; +LPAREN : '(' ; +RPAREN : ')' ; +LBRACK : '[' ; +RBRACK : ']' ; +LCURLY : '{' ; +RCURLY : '}' ; +COLON : ':' ; +COMMA : ',' ; +//DOT : '.' ; +ASSIGN : '=' ; +EQUAL : "==" ; +LNOT : '!' ; +BNOT : '~' ; +NOT_EQUAL : "!=" ; +DIV : '/' ; +DIV_ASSIGN : "/=" ; +PLUS : '+' ; +PLUS_ASSIGN : "+=" ; +INC : "++" ; +MINUS : '-' ; +MINUS_ASSIGN : "-=" ; +DEC : "--" ; +STAR : '*' ; +STAR_ASSIGN : "*=" ; +MOD : '%' ; +MOD_ASSIGN : "%=" ; +SR : ">>" ; +SR_ASSIGN : ">>=" ; +BSR : ">>>" ; +BSR_ASSIGN : ">>>=" ; +GE : ">=" ; +GT : ">" ; +SL : "<<" ; +SL_ASSIGN : "<<=" ; +LE : "<=" ; +LT : '<' ; +BXOR : '^' ; +BXOR_ASSIGN : "^=" ; +BOR : '|' ; +BOR_ASSIGN : "|=" ; +LOR : "||" ; +BAND : '&' ; +BAND_ASSIGN : "&=" ; +LAND : "&&" ; +SEMI : ';' ; // Whitespace -- ignored -WS : ( ' ' - | '\t' - | '\f' - // handle newlines - | ( options {generateAmbigWarnings=false;} - : "\r\n" // Evil DOS - | '\r' // Macintosh - | '\n' // Unix (the right way) - ) - { newline(); } - )+ - { _ttype = Token.SKIP; } - ; +WS : ( ' ' + | '\t' + | '\f' + // handle newlines + | ( options {generateAmbigWarnings=false;} + : "\r\n" // Evil DOS + | '\r' // Macintosh + | '\n' // Unix (the right way) + ) + { newline(); } + )+ + { _ttype = Token.SKIP; } + ; // Single-line comments SL_COMMENT - : "//" - (~('\n'|'\r'))* ('\n'|'\r'('\n')?)? - {$setType(Token.SKIP); newline();} - ; + : "//" + (~('\n'|'\r'))* ('\n'|'\r'('\n')?)? + {$setType(Token.SKIP); newline();} + ; // multiple-line comments ML_COMMENT - : "/*" - ( /* '\r' '\n' can be matched in one alternative or by matching - '\r' in one iteration and '\n' in another. I am trying to - handle any flavor of newline that comes in, but the language - that allows both "\r\n" and "\r" and "\n" to all be valid - newline is ambiguous. Consequently, the resulting grammar - must be ambiguous. I'm shutting this warning off. - */ - options { - generateAmbigWarnings=false; - } - : - { LA(2)!='/' }? '*' - | '\r' '\n' {newline();} - | '\r' {newline();} - | '\n' {newline();} - | ~('*'|'\n'|'\r') - )* - "*/" - {$setType(Token.SKIP);} - ; + : "/*" + ( /* '\r' '\n' can be matched in one alternative or by matching + '\r' in one iteration and '\n' in another. I am trying to + handle any flavor of newline that comes in, but the language + that allows both "\r\n" and "\r" and "\n" to all be valid + newline is ambiguous. Consequently, the resulting grammar + must be ambiguous. I'm shutting this warning off. + */ + options { + generateAmbigWarnings=false; + } + : + { LA(2)!='/' }? '*' + | '\r' '\n' {newline();} + | '\r' {newline();} + | '\n' {newline();} + | ~('*'|'\n'|'\r') + )* + "*/" + {$setType(Token.SKIP);} + ; // character literals CHAR_LITERAL - : '\'' ( ESC | ~('\''|'\n'|'\r'|'\\') ) '\'' - ; + : '\'' ( ESC | ~('\''|'\n'|'\r'|'\\') ) '\'' + ; // string literals STRING_LITERAL - : '"' (ESC|~('"'|'\\'|'\n'|'\r'))* '"' - ; + : '"' (ESC|~('"'|'\\'|'\n'|'\r'))* '"' + ; // escape sequence -- note that this is protected; it can only be called @@ -1195,121 +1195,132 @@ // the FOLLOW ambig warnings. protected ESC - : '\\' - ( 'n' - | 'r' - | 't' - | 'b' - | 'f' - | '"' - | '\'' - | '\\' - | ('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT - | '0'..'3' - ( - options { - warnWhenFollowAmbig = false; - } - : '0'..'7' - ( - options { - warnWhenFollowAmbig = false; - } - : '0'..'7' - )? - )? - | '4'..'7' - ( - options { - warnWhenFollowAmbig = false; - } - : '0'..'7' - )? - ) - ; + : '\\' + ( 'n' + | 'r' + | 't' + | 'b' + | 'f' + | '"' + | '\'' + | '\\' + | ('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT + | '0'..'3' + ( + options { + warnWhenFollowAmbig = false; + } + : '0'..'7' + ( + options { + warnWhenFollowAmbig = false; + } + : '0'..'7' + )? + )? + | '4'..'7' + ( + options { + warnWhenFollowAmbig = false; + } + : '0'..'7' + )? + ) + ; // hexadecimal digit (again, note it's protected!) protected HEX_DIGIT - : ('0'..'9'|'A'..'F'|'a'..'f') - ; + : ('0'..'9'|'A'..'F'|'a'..'f') + ; // an identifier. Note that testLiterals is set to true! This means // that after we match the rule, we look in the literals table to see // if it's a literal or really an identifer IDENT - options {testLiterals=true;} - : ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'$')* - ; + options {testLiterals=true;} + : ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'$')* + ; // a numeric literal NUM_INT - {boolean isDecimal=false; Token t=null;} + {boolean isDecimal=false, isHexadecimal=false; Token t=null;} : '.' {_ttype = DOT;} - ( ('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})? + ( ('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})? { - if (t != null && t.getText().toUpperCase().indexOf('F')>=0) { - _ttype = NUM_FLOAT; - } - else { - _ttype = NUM_DOUBLE; // assume double - } - } + if (t != null && t.getText().toUpperCase().indexOf('F')>=0) { + _ttype = NUM_FLOAT; + } + else { + _ttype = NUM_DOUBLE; // assume double + } + } )? - | ( '0' {isDecimal = true;} // special case for just '0' - ( ('x'|'X') - ( // hex - // the 'e'|'E' and float suffix stuff look - // like hex digits, hence the (...)+ doesn't - // know when to stop: ambig. ANTLR resolves - // it correctly by matching immediately. It - // is therefor ok to hush warning. - options { - warnWhenFollowAmbig=false; - } - : HEX_DIGIT - )+ - - | //float or double with leading zero - (('0'..'9')+ ('.'|EXPONENT|FLOAT_SUFFIX)) => ('0'..'9')+ - - | ('0'..'7')+ // octal - )? - | ('1'..'9') ('0'..'9')* {isDecimal=true;} // non-zero decimal - ) - ( ('l'|'L') { _ttype = NUM_LONG; } - - // only check to see if it's a float if looks like decimal so far - | {isDecimal}? - ( '.' ('0'..'9')* (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})? - | EXPONENT (f3:FLOAT_SUFFIX {t=f3;})? - | f4:FLOAT_SUFFIX {t=f4;} - ) - { - if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0) { - _ttype = NUM_FLOAT; - } - else { - _ttype = NUM_DOUBLE; // assume double - } - } + | ( '0' {isDecimal = true;} // special case for just '0' + ( ('x'|'X') { isHexadecimal=true; } // hex + ( + // the 'e'|'E' and float suffix stuff look + // like hex digits, hence the (...)+ doesn't + // know when to stop: ambig. ANTLR resolves + // it correctly by matching immediately. It + // is therefor ok to hush warning. + options { + warnWhenFollowAmbig=false; + } + : HEX_DIGIT + )+ + + | //float or double with leading zero + (('0'..'9')+ ('.'|EXPONENT|FLOAT_SUFFIX)) => ('0'..'9')+ + + | ('0'..'7')+ // octal + )? + | ('1'..'9') ('0'..'9')* {isDecimal=true;} // non-zero decimal + ) + ( + ('l'|'L') { _ttype = NUM_LONG; } + + // check to see if it's a hexadecimal w/ binary exponent float if looks like hexadecimal so far + | {isHexadecimal}? + ( '.' ( options { warnWhenFollowAmbig=false; } : HEX_DIGIT )* )? + ('p'|'P') ('+'|'-')? ('0'..'9')+ (f5:FLOAT_SUFFIX {t=f5;})? + { + if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0) { + _ttype = NUM_FLOAT; + } else { + _ttype = NUM_DOUBLE; // assume double + } + } + // check to see if it's a float if looks like decimal so far + | {isDecimal}? + ( '.' ('0'..'9')* (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})? + | EXPONENT (f3:FLOAT_SUFFIX {t=f3;})? + | f4:FLOAT_SUFFIX {t=f4;} + ) + { + if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0) { + _ttype = NUM_FLOAT; + } else { + _ttype = NUM_DOUBLE; // assume double + } + } )? - ; + ; // a couple protected methods to assist in matching floating point numbers protected EXPONENT - : ('e'|'E') ('+'|'-')? ('0'..'9')+ - ; + : ('e'|'E') (PLUS|MINUS)? ('0'..'9')+ + ; protected FLOAT_SUFFIX - : 'f'|'F'|'d'|'D' - ; + : 'f'|'F'|'d'|'D' + ; diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/ExceptionUtils.java gluegen2-2.3.2/src/java/com/jogamp/common/ExceptionUtils.java --- gluegen2-2.2.4/src/java/com/jogamp/common/ExceptionUtils.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/ExceptionUtils.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,154 @@ +/** + * Copyright 2014 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.common; + +import java.io.PrintStream; + +/** + * @since 2.3.0 + */ +public class ExceptionUtils { + public static void dumpStack(final PrintStream out) { + dumpStack(out, 1, -1); + } + public static void dumpStack(final PrintStream out, final int skip, final int depth) { + dumpStack(out, new Exception(""), skip+1, depth); + } + public static void dumpStack(final PrintStream out, final Throwable t, final int skip, final int depth) { + dumpStack(out, t.getStackTrace(), skip, depth); + } + public static void dumpStack(final PrintStream out, final StackTraceElement[] stack, final int skip, final int depth) { + if( null == stack ) { + return; + } + final int maxDepth; + if( 0 > depth ) { + maxDepth = stack.length; + } else { + maxDepth = Math.min(depth+skip, stack.length); + } + for(int i=skip; i + * Implementation will iterate through all {@link Throwable#getCause() causes}. + *

    + * @param additionalDescr additional text placed before the {@link Throwable} details. + * @param t the {@link Throwable} for output + */ + public static void dumpThrowable(final String additionalDescr, final Throwable t) { + dumpThrowable(additionalDescr, t, -1, -1); + } + /** + * Dumps a {@link Throwable} to {@link System.err} in a decorating message including the current thread name, + * and its {@link #dumpStack(PrintStream, StackTraceElement[], int, int) stack trace}. + *

    + * Implementation will iterate through all {@link Throwable#getCause() causes}. + *

    + * @param additionalDescr additional text placed before the {@link Throwable} details. + * @param t the {@link Throwable} for output + * @param causeDepth the maximum depth for causes, or {@code -1} for all + * @param stackDepth the maximum depth for stack entries, or {@code -1} for all + * @since 2.3.2 + */ + public static void dumpThrowable(final String additionalDescr, final Throwable t, final int causeDepth, final int stackDepth) { + System.err.print("Caught "+additionalDescr+" "); + printStackTrace(System.err, t, causeDepth, stackDepth); + } +} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/JogampRuntimeException.java gluegen2-2.3.2/src/java/com/jogamp/common/JogampRuntimeException.java --- gluegen2-2.2.4/src/java/com/jogamp/common/JogampRuntimeException.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/JogampRuntimeException.java 2015-10-09 04:18:28.000000000 +0000 @@ -28,9 +28,10 @@ package com.jogamp.common; -/** A generic exception for Jogamp errors used throughout the binding - as a substitute for {@link RuntimeException}. */ - +/** + * A generic unchecked exception for Jogamp errors used throughout the binding + * as a substitute for {@link RuntimeException}. + */ @SuppressWarnings("serial") public class JogampRuntimeException extends RuntimeException { /** Constructs a JogampRuntimeException object. */ diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java gluegen2-2.3.2/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java --- gluegen2-2.2.4/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java 2015-10-09 04:18:28.000000000 +0000 @@ -42,7 +42,6 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.security.AccessController; @@ -52,8 +51,8 @@ import java.util.Iterator; import java.util.List; +import com.jogamp.common.net.Uri; import com.jogamp.common.os.NativeLibrary; -import com.jogamp.common.util.IOUtil; import com.jogamp.common.util.JarUtil; import com.jogamp.common.util.PropertyAccess; import com.jogamp.common.util.cache.TempJarCache; @@ -62,7 +61,18 @@ import jogamp.common.os.PlatformPropsImpl; public class JNILibLoaderBase { - public static final boolean DEBUG = Debug.debug("JNILibLoader"); + public static final boolean DEBUG; + protected static final boolean PERF; + + static { + Debug.initSingleton(); + DEBUG = Debug.debug("JNILibLoader"); + PERF = DEBUG || PropertyAccess.isPropertyDefined("jogamp.debug.JNILibLoader.Perf", true); + } + + private static final Object perfSync = new Object(); + private static long perfTotal = 0; + private static long perfCount = 0; public interface LoaderAction { /** @@ -155,7 +165,7 @@ /** * * @param classFromJavaJar - * @param classJarURI + * @param classJarUri * @param jarBasename jar basename w/ suffix * @param nativeJarBasename native jar basename w/ suffix * @return @@ -163,69 +173,51 @@ * @throws SecurityException * @throws URISyntaxException */ - private static final boolean addNativeJarLibsImpl(final Class classFromJavaJar, final URI classJarURI, - final String jarBasename, final String nativeJarBasename) + private static final boolean addNativeJarLibsImpl(final Class classFromJavaJar, final Uri classJarUri, + final Uri.Encoded jarBasename, final Uri.Encoded nativeJarBasename) throws IOException, SecurityException, URISyntaxException { if (DEBUG) { final StringBuilder msg = new StringBuilder(); msg.append("JNILibLoaderBase: addNativeJarLibsImpl(").append(PlatformPropsImpl.NEWLINE); msg.append(" classFromJavaJar = ").append(classFromJavaJar).append(PlatformPropsImpl.NEWLINE); - msg.append(" classJarURI = ").append(classJarURI).append(PlatformPropsImpl.NEWLINE); + msg.append(" classJarURI = ").append(classJarUri).append(PlatformPropsImpl.NEWLINE); msg.append(" jarBasename = ").append(jarBasename).append(PlatformPropsImpl.NEWLINE); msg.append(" os.and.arch = ").append(PlatformPropsImpl.os_and_arch).append(PlatformPropsImpl.NEWLINE); msg.append(" nativeJarBasename = ").append(nativeJarBasename).append(PlatformPropsImpl.NEWLINE); msg.append(")"); System.err.println(msg.toString()); } + final long t0 = PERF ? System.currentTimeMillis() : 0; // 'Platform.currentTimeMillis()' not yet available! boolean ok = false; - final URI jarSubURI = JarUtil.getJarSubURI( classJarURI ); + final Uri jarSubURI = classJarUri.getContainedUri(); if (null == jarSubURI) { - throw new IllegalArgumentException("JarSubURI is null of: "+classJarURI); + throw new IllegalArgumentException("JarSubURI is null of: "+classJarUri); } - final String jarUriRoot_s = IOUtil.getURIDirname( jarSubURI.toString() ); + final Uri jarSubUriRoot = jarSubURI.getDirectory(); if (DEBUG) { - System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: initial: %s -> %s%n", jarSubURI, jarUriRoot_s); + System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: initial: %s -> %s%n", jarSubURI, jarSubUriRoot); } final String nativeLibraryPath = String.format("natives/%s/", PlatformPropsImpl.os_and_arch); if (DEBUG) { System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: nativeLibraryPath: %s%n", nativeLibraryPath); } - final ClassLoader cl = classFromJavaJar.getClassLoader(); - final URL nativeLibraryURI = cl.getResource(nativeLibraryPath); - if (null != nativeLibraryURI) { - // We probably have one big-fat jar file, containing java classes - // and all native platform libraries under 'natives/os.and.arch'! - final URI nativeJarURI = JarUtil.getJarFileURI(jarUriRoot_s+jarBasename); - try { - if( TempJarCache.addNativeLibs(classFromJavaJar, nativeJarURI, nativeLibraryPath) ) { - ok = true; - if (DEBUG) { - System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: fat: %s -> %s%n", jarBasename, nativeJarURI); - } - } - } catch(final Exception e) { - if(DEBUG) { - System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: Caught %s%n", e.getMessage()); - e.printStackTrace(); - } - } - } - if (!ok) { - // We assume one slim native jar file per 'os.and.arch'! - final URI nativeJarURI = JarUtil.getJarFileURI(jarUriRoot_s+nativeJarBasename); + { + // Attempt-1 a 'one slim native jar file' per 'os.and.arch' layout + // with native platform libraries under 'natives/os.and.arch'! + final Uri nativeJarURI = JarUtil.getJarFileUri( jarSubUriRoot.getEncoded().concat(nativeJarBasename) ); if (DEBUG) { System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: module: %s -> %s%n", nativeJarBasename, nativeJarURI); } try { - ok = TempJarCache.addNativeLibs(classFromJavaJar, nativeJarURI, null /* nativeLibraryPath */); + ok = TempJarCache.addNativeLibs(classFromJavaJar, nativeJarURI, nativeLibraryPath); } catch(final Exception e) { if(DEBUG) { System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: Caught %s%n", e.getMessage()); @@ -234,40 +226,75 @@ } } if (!ok) { - // Attempt to find via ClassLoader and Native-Jar-Tag, - // assuming one slim native jar file per 'os.and.arch'! - final String moduleName; + final ClassLoader cl = classFromJavaJar.getClassLoader(); { - final String packageName = classFromJavaJar.getPackage().getName(); - final int idx = packageName.lastIndexOf('.'); - if( 0 <= idx ) { - moduleName = packageName.substring(idx+1); - } else { - moduleName = packageName; + // Attempt-2 a 'one big-fat jar file' layout, containing java classes + // and all native platform libraries under 'natives/os.and.arch' per platform! + final URL nativeLibraryURI = cl.getResource(nativeLibraryPath); + if (null != nativeLibraryURI) { + final Uri nativeJarURI = JarUtil.getJarFileUri( jarSubUriRoot.getEncoded().concat(jarBasename) ); + try { + if( TempJarCache.addNativeLibs(classFromJavaJar, nativeJarURI, nativeLibraryPath) ) { + ok = true; + if (DEBUG) { + System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: fat: %s -> %s%n", jarBasename, nativeJarURI); + } + } + } catch(final Exception e) { + if(DEBUG) { + System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: Caught %s%n", e.getMessage()); + e.printStackTrace(); + } + } } } - final String os_and_arch_dot = PlatformPropsImpl.os_and_arch.replace('-', '.'); - final String nativeJarTagClassName = nativeJarTagPackage + "." + moduleName + "." + os_and_arch_dot + ".TAG" ; // TODO: sync with gluegen-cpptasks-base.xml - try { - if(DEBUG) { - System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: ClassLoader/TAG: Locating module %s, os.and.arch %s: %s%n", - moduleName, os_and_arch_dot, nativeJarTagClassName); - } - final URI nativeJarTagClassJarURI = JarUtil.getJarURI(nativeJarTagClassName, cl); - if (DEBUG) { - System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: ClassLoader/TAG: %s -> %s%n", nativeJarTagClassName, nativeJarTagClassJarURI); + if (!ok) { + // Attempt-3 to find via ClassLoader and Native-Jar-Tag, + // assuming one slim native jar file per 'os.and.arch' + // and native platform libraries under 'natives/os.and.arch'! + final String moduleName; + { + final String packageName = classFromJavaJar.getPackage().getName(); + final int idx = packageName.lastIndexOf('.'); + if( 0 <= idx ) { + moduleName = packageName.substring(idx+1); + } else { + moduleName = packageName; + } } - ok = TempJarCache.addNativeLibs(classFromJavaJar, nativeJarTagClassJarURI, null /* nativeLibraryPath */); - } catch (final Exception e ) { - if(DEBUG) { - System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: Caught %s%n", e.getMessage()); - e.printStackTrace(); + final String os_and_arch_dot = PlatformPropsImpl.os_and_arch.replace('-', '.'); + final String nativeJarTagClassName = nativeJarTagPackage + "." + moduleName + "." + os_and_arch_dot + ".TAG"; // TODO: sync with gluegen-cpptasks-base.xml + try { + if(DEBUG) { + System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: ClassLoader/TAG: Locating module %s, os.and.arch %s: %s%n", + moduleName, os_and_arch_dot, nativeJarTagClassName); + } + final Uri nativeJarTagClassJarURI = JarUtil.getJarUri(nativeJarTagClassName, cl); + if (DEBUG) { + System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: ClassLoader/TAG: %s -> %s%n", nativeJarTagClassName, nativeJarTagClassJarURI); + } + ok = TempJarCache.addNativeLibs(classFromJavaJar, nativeJarTagClassJarURI, nativeLibraryPath); + } catch (final Exception e ) { + if(DEBUG) { + System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: Caught %s%n", e.getMessage()); + e.printStackTrace(); + } } } } - if (DEBUG) { - System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: ok: %b%n", ok); + if (DEBUG || PERF) { + final long tNow = System.currentTimeMillis() - t0; + final long tTotal, tCount; + synchronized(perfSync) { + tCount = perfCount+1; + tTotal = perfTotal + tNow; + perfTotal = tTotal; + perfCount = tCount; + } + final double tAvrg = tTotal / (double)tCount; + System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl.X: %s / %s -> ok: %b; duration: now %d ms, total %d ms (count %d, avrg %.3f ms)%n", + jarBasename, nativeJarBasename, ok, tNow, tTotal, tCount, tAvrg); } return ok; } @@ -399,14 +426,14 @@ } final ClassLoader cl = c.getClassLoader(); - final URI classJarURI = JarUtil.getJarURI(c.getName(), cl); - final String jarName = JarUtil.getJarBasename(classJarURI); + final Uri classJarURI = JarUtil.getJarUri(c.getName(), cl); + final Uri.Encoded jarName = JarUtil.getJarBasename(classJarURI); if (jarName == null) { continue; } - final String jarBasename = jarName.substring(0, jarName.indexOf(".jar")); + final Uri.Encoded jarBasename = jarName.substring(0, jarName.indexOf(".jar")); if(DEBUG) { System.err.printf("JNILibLoaderBase: jarBasename: %s%n", jarBasename); @@ -423,7 +450,8 @@ } } - final String nativeJarBasename = String.format("%s-natives-%s.jar", jarBasename, PlatformPropsImpl.os_and_arch); + final Uri.Encoded nativeJarBasename = + Uri.Encoded.cast( String.format("%s-natives-%s.jar", jarBasename.get(), PlatformPropsImpl.os_and_arch) ); ok = JNILibLoaderBase.addNativeJarLibsImpl(c, classJarURI, jarName, nativeJarBasename); if (ok) { @@ -585,7 +613,7 @@ if(DEBUG) { System.err.println("ERROR (retry w/ enumLibPath) - "+ex1.getMessage()); } - final List possiblePaths = NativeLibrary.enumerateLibraryPaths(libraryName, libraryName, libraryName, true, cl); + final List possiblePaths = NativeLibrary.enumerateLibraryPaths(libraryName, libraryName, libraryName, cl); // Iterate down these and see which one if any we can actually find. for (final Iterator iter = possiblePaths.iterator(); 0 == mode && iter.hasNext(); ) { final String path = iter.next(); diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/net/AssetURLContext.java gluegen2-2.3.2/src/java/com/jogamp/common/net/AssetURLContext.java --- gluegen2-2.2.4/src/java/com/jogamp/common/net/AssetURLContext.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/net/AssetURLContext.java 2015-10-09 04:18:28.000000000 +0000 @@ -164,7 +164,7 @@ url = new URL(path); conn = open(url); type = null != conn ? 1 : -1; - } catch(final MalformedURLException e1) { if(DEBUG) { System.err.println("ERR(0): "+e1.getMessage()); } } + } catch(final MalformedURLException e1) { if(DEBUG) { System.err.println("FAIL(1): "+e1.getMessage()); } } if(null == conn && null != cl) { // lookup via ClassLoader .. cleanup leading '/' @@ -185,11 +185,11 @@ try { final File file = new File(path); if(file.exists()) { - url = IOUtil.toURISimple(file).toURL(); + url = Uri.valueOf(file).toURL(); conn = open(url); type = null != conn ? 3 : -1; } - } catch (final Throwable e) { if(DEBUG) { System.err.println("ERR(1): "+e.getMessage()); } } + } catch (final Throwable e) { if(DEBUG) { System.err.println("FAIL(3): "+e.getMessage()); } } } if(DEBUG) { @@ -209,7 +209,7 @@ final URLConnection c = url.openConnection(); c.connect(); // redundant return c; - } catch (final IOException ioe) { if(DEBUG) { System.err.println("ERR: "+ioe.getMessage()); } } + } catch (final IOException ioe) { if(DEBUG) { System.err.println("FAIL(2): "+ioe.getMessage()); } } return null; } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/net/Uri.java gluegen2-2.3.2/src/java/com/jogamp/common/net/Uri.java --- gluegen2-2.2.4/src/java/com/jogamp/common/net/Uri.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/net/Uri.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,2524 @@ +/** + * Copyright 2014 JogAmp Community. All rights reserved. + * Copyright 2006, 2010 The Apache Software Foundation. + * + * This code is derived from the Apache Harmony project's {@code class java.net.URI.Helper}, + * and has been heavily modified for GlueGen/JogAmp. + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the LICENSE.txt file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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 com.jogamp.common.net; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.util.StringTokenizer; +import java.util.regex.Pattern; + +import jogamp.common.Debug; + +import com.jogamp.common.util.IOUtil; +import com.jogamp.common.util.PropertyAccess; + +/** + * This class implements an immutable Uri as defined by RFC 2396. + *

    + * Character encoding is employed as defined by RFC 3986, + * see RFC 3986 section 2.1, + * while multibyte unicode characters are preserved in encoded parts. + *

    + * + *
    +     1 [scheme:]scheme-specific-part[#fragment]
    +     2 [scheme:][//authority]path[?query][#fragment]
    +     3 [scheme:][//[user-info@]host[:port]]path[?query][#fragment]
    +
    +        scheme-specific-part: [//authority]path[?query]
    +        authority:            [user-info@]host[:port]
    + * 
    + *

    + * RFC 3986 section 2.2 Reserved Characters (January 2005) + * + + + + + + + + + + + + + + + + + + + + + *
    !*'();:@&=+$,/?#[]
    + *

    + *

    + * RFC 3986 section 2.3 Unreserved Characters (January 2005) + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + *
    ABCDEFGHIJKLMNOPQRSTUVWXYZ
    abcdefghijklmnopqrstuvwxyz
    0123456789-_.~
    + *

    + *

    + * Other characters in a Uri must be percent encoded. + *

    + * @since 2.2.1 + */ +public class Uri { + private static final boolean DEBUG; + private static final boolean DEBUG_SHOWFIX; + + static { + Debug.initSingleton(); + DEBUG = IOUtil.DEBUG || Debug.debug("Uri"); + DEBUG_SHOWFIX = PropertyAccess.isPropertyDefined("jogamp.debug.Uri.ShowFix", true); + } + + /** + * Usually used to fix a path from a previously contained and opaque Uri, + * i.e. {@link #getContainedUri()}. + *

    + * Such an opaque Uri w/ erroneous encoding may have been injected via + * {@link #valueOf(URI)} and {@link #valueOf(URL)} where the given URL or URI was opaque! + *

    + *

    + * This remedies issues when dealing w/ java URI/URL opaque sources, + * which do not comply to the spec, i.e. containe un-encoded chars, e.g. ':', '$', .. + *

    + */ + private static final int PARSE_HINT_FIX_PATH = 1 << 0; + + private static final String DIGITS = "0123456789ABCDEF"; + + private static final String ENCODING = "UTF8"; + private static final String MSG_ENCODING_NA = "Charset UTF8 not available"; + private static final Pattern patternSingleFS = Pattern.compile("/{1}"); + + /** + * RFC 3986 section 2.3 Unreserved Characters (January 2005) + *

    + * {@value} + {@code alphanum} + *

    + */ + public static final String UNRESERVED = "_-.~"; + // Harmony: _ - ! . ~ ' ( ) * + + private static final String punct = ",;:$&+="; + // Harmony: , ; : $ & + = + + /** + * RFC 3986 section 2.2 Reserved Characters (January 2005) + *

    + * {@value} + {@code alphanum} + *

    + */ + public static final String RESERVED = punct + "!*\'()@/?#[]"; + // Harmony: , ; : $ & + = ? / [ ] @ + + public static final String RESERVED_2 = punct + "!*\'()@/?[]"; + // Harmony: , ; : $ & + = ? / [ ] @ + + // Bug 908, issues w/ windows file path char: $ ^ ~ # [ ] + // Windows invalid File characters: * ? " < > | + + /** + * Valid charset for RFC 2396 {@code authority}'s {@code user-info}, + * additional to legal {@code alphanum} characters. + *

    + * {@value} + {@code alphanum} + *

    + */ + public static final String USERINFO_LEGAL = UNRESERVED + punct; + // Harmony: someLegal = unreserved + punct -> _ - ! . ~ ' ( ) * , ; : $ & + = + + /** + * Valid charset for RFC 2396 {@code authority}, + * additional to legal {@code alphanum} characters. + *

    + * {@value} + {@code alphanum} + *

    + */ + public static final String AUTHORITY_LEGAL = "@[]" + USERINFO_LEGAL; + + /** + * Valid charset for RFC 2396 {@code path}, + * additional to legal {@code alphanum} characters. + *

    + * {@value} + {@code alphanum} + *

    + */ + public static final String PATH_LEGAL = "/!" + UNRESERVED; // no RESERVED chars but '!', to allow JAR Uris; + // Harmony: "/@" + unreserved + punct -> / @ _ - ! . ~ \ ' ( ) * , ; : $ & + = + + /** + * Valid charset for RFC 2396 {@code query}, + * additional to legal {@code alphanum} characters. + *

    + * {@value} + {@code alphanum} + *

    + */ + public static final String QUERY_LEGAL = UNRESERVED + RESERVED_2 + "\\\""; + // Harmony: unreserved + reserved + "\\\"" + + /** + * Valid charset for RFC 2396 {@code scheme-specific-part}, + * additional to legal {@code alphanum} characters. + *

    + * {@value} + {@code alphanum} + *

    + */ + public static final String SSP_LEGAL = QUERY_LEGAL; + // Harmony: unreserved + reserved + + /** + * Valid charset for RFC 2396 {@code fragment}, + * additional to legal {@code alphanum} characters. + *

    + * {@value} + {@code alphanum} + *

    + */ + public static final String FRAG_LEGAL = UNRESERVED + RESERVED; + // Harmony: unreserved + reserved + + /** {@value} */ + public static final char SCHEME_SEPARATOR = ':'; + /** {@value} */ + public static final char QUERY_SEPARATOR = '?'; + /** {@value} */ + public static final char FRAGMENT_SEPARATOR = '#'; + /** {@value} */ + public static final String FILE_SCHEME = "file"; + /** {@value} */ + public static final String HTTP_SCHEME = "http"; + /** {@value} */ + public static final String HTTPS_SCHEME = "https"; + /** {@value} */ + public static final String JAR_SCHEME = "jar"; + /** A JAR sub-protocol is separated from the JAR entry w/ this separator {@value}. Even if no class is specified '!/' must follow!. */ + public static final char JAR_SCHEME_SEPARATOR = '!'; + + /** + * Immutable RFC3986 encoded string. + */ + public static class Encoded implements Comparable, CharSequence { + private final String s; + + /** + * Casts the given encoded String by creating a new Encoded instance. + *

    + * No encoding will be performed, use with care. + *

    + */ + public static Encoded cast(final String encoded) { + return new Encoded(encoded); + } + + Encoded(final String encodedString) { + this.s = encodedString; + } + + /** + * Encodes all characters into their hexadecimal value prepended by '%', except: + *
      + *
    1. letters ('a'..'z', 'A'..'Z')
    2. + *
    3. numbers ('0'..'9')
    4. + *
    5. characters in the legal-set parameter
    6. + *
    7. others (unicode characters that are not in + * US-ASCII set, and are not ISO Control or are not ISO Space characters)
    8. + *
    + *

    + * Uses {@link Uri#encode(String, String)} for implementation.. + *

    + * + * @param vanilla the string to be encoded + * @param legal extended character set, allowed to be preserved in the vanilla string + */ + public Encoded(final String vanilla, final String legal) { + this.s = encode(vanilla, legal); + } + + public boolean isASCII() { return false; } + + /** Returns the encoded String */ + public final String get() { return s; } + + /** + * Decodes the string argument which is assumed to be encoded in the {@code + * x-www-form-urlencoded} MIME content type using the UTF-8 encoding scheme. + *

    + *'%' and two following hex digit characters are converted to the + * equivalent byte value. All other characters are passed through + * unmodified. + *

    + *

    + * e.g. "A%20B%20C %24%25" -> "A B C $%" + *

    + *

    + * Uses {@link Uri#decode(String)} for implementation.. + *

    + */ + public final String decode() { return Uri.decode(s); } + + // + // Basic Object / Identity + // + + /** + * {@inheritDoc} + *

    + * Returns the encoded String, same as {@link #get()}. + *

    + */ + @Override + public final String toString() { return s; } + + @Override + public final int hashCode() { return s.hashCode(); } + + /** + * {@inheritDoc} + * + * @param o The comparison argument, either a {@link Encoded} or a {@link String} + * + * @return {@code true} if the given object is equivalent to this instance, + * otherwise {@code false}. + * + * @see #compareTo(Encoded) + * @see #equalsIgnoreCase(Encoded) + */ + @Override + public final boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o instanceof Encoded) { + return s.equals(((Encoded)o).s); + } + return s.equals(o); + } + + // + // CharSequence + // + + @Override + public final int length() { return s.length(); } + + @Override + public final char charAt(final int index) { return s.charAt(index); } + + @Override + public final CharSequence subSequence(final int start, final int end) { return s.subSequence(start, end); } + + @Override + public final int compareTo(final Encoded o) { return s.compareTo(o.s); } + + // + // String derived .. + // + /** See {@link String#concat(String)}. */ + public Encoded concat(final Encoded encoded) { return new Encoded(s.concat(encoded.s)); } + + /** See {@link String#substring(int)}. */ + public final Encoded substring(final int start) { return new Encoded(s.substring(start)); } + /** See {@link String#substring(int, int)}. */ + public final Encoded substring(final int start, final int end) { return new Encoded(s.substring(start, end)); } + + /** See {@link String#indexOf(int)}. */ + public final int indexOf(final int ch) { return s.indexOf(ch); } + /** See {@link String#indexOf(int, int)}. */ + public final int indexOf(final int ch, final int fromIndex) { return s.indexOf(ch, fromIndex); } + /** See {@link String#indexOf(String)}. */ + public final int indexOf(final String str) { return s.indexOf(str); } + /** See {@link String#indexOf(String, int)}. */ + public final int indexOf(final String str, final int fromIndex) { return s.indexOf(str, fromIndex); } + + /** See {@link String#lastIndexOf(int)}. */ + public final int lastIndexOf(final int ch) { return s.lastIndexOf(ch); } + /** See {@link String#lastIndexOf(int, int)}. */ + public int lastIndexOf(final int ch, final int fromIndex) { return s.lastIndexOf(ch, fromIndex); } + /** See {@link String#lastIndexOf(String)}. */ + public int lastIndexOf(final String str) { return s.lastIndexOf(str); } + /** See {@link String#lastIndexOf(String, int)}. */ + public int lastIndexOf(final String str, final int fromIndex) { return s.lastIndexOf(str, fromIndex); } + + /** See {@link String#startsWith(String)} */ + public boolean startsWith(final String prefix) { return s.startsWith(prefix); } + /** See {@link String#startsWith(String, int)} */ + public boolean startsWith(final String prefix, final int toffset) { return s.startsWith(prefix, toffset); } + /** See {@link String#endsWith(String)} */ + public boolean endsWith(final String suffix) { return s.endsWith(suffix); } + + /** See {@link String#equalsIgnoreCase(String)}. */ + public final boolean equalsIgnoreCase(final Encoded anotherEncoded) { return s.equalsIgnoreCase(anotherEncoded.s); } + } + + public static class ASCIIEncoded extends Encoded { + /** + * Casts the given encoded String by creating a new ASCIIEncoded instance. + *

    + * No encoding will be performed, use with care. + *

    + */ + public static ASCIIEncoded cast(final String encoded) { + return new ASCIIEncoded(encoded, null); + } + private ASCIIEncoded(final String encoded, final Object unused) { + super(encoded); + } + + /** + * Other characters, which are Unicode chars that are not US-ASCII, and are + * not ISO Control or are not ISO Space chars are not preserved + * and encoded into their hexidecimal value prepended by '%'. + *

    + * For example: Euro currency symbol -> "%E2%82%AC". + *

    + *

    + * Uses {@link Uri#encodeToASCIIString(String)} for implementation. + *

    + * @param unicode unencoded input + */ + public ASCIIEncoded(final String unicode) { + super(encodeToASCIIString(unicode)); + } + public boolean isASCII() { return true; } + } + + private static void encodeChar2UTF8(final StringBuilder buf, final char ch) { + final byte[] bytes; + try { + bytes = new String(new char[] { ch }).getBytes(ENCODING); + } catch (final UnsupportedEncodingException e) { + throw new RuntimeException(MSG_ENCODING_NA, e); + } + // FIXME: UTF-8 produces more than one byte ? Optimization might be possible. + for (int j = 0; j < bytes.length; j++) { + final byte b = bytes[j]; + buf.append('%'); + buf.append(DIGITS.charAt( ( b & 0xf0 ) >> 4 )); + buf.append(DIGITS.charAt( b & 0xf )); + } + } + + /** + * All characters are encoded into their hexadecimal value prepended by '%', except: + *
      + *
    1. letters ('a'..'z', 'A'..'Z')
    2. + *
    3. numbers ('0'..'9')
    4. + *
    5. characters in the legal-set parameter
    6. + *
    7. others (unicode characters that are not in + * US-ASCII set, and are not ISO Control or are not ISO Space characters)
    8. + *
    + *

    + * Use {@link #encodeToASCIIString(String)} for US-ASCII encoding. + *

    + *

    + * Consider using {@link Encoded#Encoded(String, String)} in APIs + * to distinguish encoded from unencoded data by type. + *

    + * + * @param vanilla the string to be encoded + * @param legal extended character set, allowed to be preserved in the vanilla string + * @return java.lang.String the converted string + */ + public static String encode(final String vanilla, final String legal) { + if( null == vanilla ) { + return null; + } + final StringBuilder buf = new StringBuilder(); + for (int i = 0; i < vanilla.length(); i++) { + final char ch = vanilla.charAt(i); + if ( (ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9') || + legal.indexOf(ch) > -1 || + ( ch > 127 && !Character.isSpaceChar(ch) && !Character.isISOControl(ch) ) + ) { + buf.append(ch); + } else { + encodeChar2UTF8(buf, ch); + } + } + return buf.toString(); + } + + /** + * Other characters, which are Unicode chars that are not US-ASCII, and are + * not ISO Control or are not ISO Space chars are not preserved + * and encoded into their hexidecimal value prepended by '%'. + *

    + * For example: Euro currency symbol -> "%E2%82%AC". + *

    + *

    + * Consider using {@link ASCIIEncoded#ASCIIEncoded(String)} in APIs + * to distinguish encoded from unencoded data by type. + *

    + * @param unicode string to be converted + * @return java.lang.String the converted string + */ + public static String encodeToASCIIString(final String unicode) { + final StringBuilder buf = new StringBuilder(); + for (int i = 0; i < unicode.length(); i++) { + final char ch = unicode.charAt(i); + if (ch <= 127) { + buf.append(ch); + } else { + encodeChar2UTF8(buf, ch); + } + } + return buf.toString(); + } + + /** + * Safe {@link Encoded#decode()} call on optional {@code encoded} instance. + * @param encoded {@link Encoded} instance to be decoded, may be {@code null}. + * @return the {@link Encoded#decode() decoded} String or {@code null} if {@code encoded} was {@code null}. + */ + public static String decode(final Encoded encoded) { + return null != encoded ? encoded.decode() : null; + } + + /** + * Decodes the string argument which is assumed to be encoded in the {@code + * x-www-form-urlencoded} MIME content type using the UTF-8 encoding scheme. + *

    + *'%' and two following hex digit characters are converted to the + * equivalent byte value. All other characters are passed through + * unmodified. + *

    + *

    + * e.g. "A%20B%20C %24%25" -> "A B C $%" + *

    + * + * @param encoded The encoded string. + * @return java.lang.String The decoded version. + */ + public static String decode(final String encoded) { + if( null == encoded ) { + return null; + } + final StringBuilder result = new StringBuilder(); + final byte[] buf = new byte[32]; + int bufI = 0; + for (int i = 0; i < encoded.length();) { + final char c = encoded.charAt(i); + if (c == '%') { + bufI = 0; + do { + if (i + 2 >= encoded.length()) { + throw new IllegalArgumentException("missing '%' hex-digits at index "+i); + } + final int d1 = Character.digit(encoded.charAt(i + 1), 16); + final int d2 = Character.digit(encoded.charAt(i + 2), 16); + if (d1 == -1 || d2 == -1) { + throw new IllegalArgumentException("invalid hex-digits at index "+i+": "+encoded.substring(i, i + 3)); + } + buf[bufI++] = (byte) ((d1 << 4) + d2); + if( 32 == bufI ) { + appendUTF8(result, buf, bufI); + bufI = 0; + } + i += 3; + } while (i < encoded.length() && encoded.charAt(i) == '%'); + if( 0 < bufI ) { + appendUTF8(result, buf, bufI); + } + } else { + result.append(c); + i++; + } + } + return result.toString(); + } + private static void appendUTF8(final StringBuilder sb, final byte[] buf, final int count) { + try { + sb.append(new String(buf, 0, count, ENCODING)); + } catch (final UnsupportedEncodingException e) { + throw new RuntimeException(MSG_ENCODING_NA, e); + } + } + + /** + * Creates a new Uri instance using the given unencoded arguments. + *

    + * This constructor first creates a temporary Uri string from the given unencoded components. This + * string will be parsed later on to create the Uri instance. + *

    + *

    + * {@code [scheme:]scheme-specific-part[#fragment]} + *

    + *

    + * {@code host} and {@code port} may be undefined or invalid within {@code scheme-specific-part}. + *

    + * + * @param scheme the unencoded scheme part of the Uri. + * @param ssp the unencoded scheme-specific-part of the Uri. + * @param fragment the unencoded fragment part of the Uri. + * @throws URISyntaxException + * if the temporary created string doesn't fit to the + * specification RFC2396 or could not be parsed correctly. + */ + public static Uri create(final String scheme, final String ssp, final String fragment) throws URISyntaxException { + if ( emptyString(scheme) && emptyString(ssp) && emptyString(fragment) ) { + throw new URISyntaxException("", "all empty parts"); + } + final StringBuilder uri = new StringBuilder(); + if ( !emptyString(scheme) ) { + uri.append(scheme); + uri.append(SCHEME_SEPARATOR); + } + if ( !emptyString(ssp) ) { + // QUOTE ILLEGAL CHARACTERS + uri.append(encode(ssp, SSP_LEGAL)); + } + if ( !emptyString(fragment) ) { + uri.append(FRAGMENT_SEPARATOR); + // QUOTE ILLEGAL CHARACTERS + uri.append(encode(fragment, FRAG_LEGAL)); + } + return new Uri(new Encoded(uri.toString()), false, 0); + } + + /** + * Creates a new Uri instance using the given encoded arguments. + *

    + * This constructor first creates a temporary Uri string from the given encoded components. This + * string will be parsed later on to create the Uri instance. + *

    + *

    + * The given encoded components are taken as-is, i.e. no re-encoding will be performed! + * However, Uri parsing will re-evaluate encoding of the resulting components. + *

    + *

    + * {@code [scheme:]scheme-specific-part[#fragment]} + *

    + *

    + * {@code host} and {@code port} may be undefined or invalid within {@code scheme-specific-part}. + *

    + * + * @param scheme the encoded scheme part of the Uri. + * @param ssp the encoded scheme-specific-part of the Uri. + * @param fragment the encoded fragment part of the Uri. + * @throws URISyntaxException + * if the temporary created string doesn't fit to the + * specification RFC2396 or could not be parsed correctly. + */ + public static Uri create(final Encoded scheme, final Encoded ssp, final Encoded fragment) throws URISyntaxException { + if ( emptyString(scheme) && emptyString(ssp) && emptyString(fragment) ) { + throw new URISyntaxException("", "all empty parts"); + } + final StringBuilder uri = new StringBuilder(); + if ( !emptyString(scheme) ) { + uri.append(scheme); + uri.append(SCHEME_SEPARATOR); + } + if ( !emptyString(ssp) ) { + uri.append(ssp.get()); + } + if ( !emptyString(fragment) ) { + uri.append(FRAGMENT_SEPARATOR); + uri.append(fragment.get()); + } + return new Uri(new Encoded(uri.toString()), false, 0); + } + + /** + * Creates a new Uri instance using the given unencoded arguments. + *

    + * This constructor first creates a temporary Uri string from the given unencoded components. This + * string will be parsed later on to create the Uri instance. + *

    + *

    + * {@code [scheme:][user-info@]host[:port][path][?query][#fragment]} + *

    + *

    + * {@code host} and {@code port} must be defined and valid, if any {@code authority} components are defined, + * i.e. {@code user-info}, {@code host} or {@code port}. + *

    + * + * @param scheme the unencoded scheme part of the Uri. + * @param userinfo the unencoded user information of the Uri for authentication and authorization, {@code null} for undefined. + * @param host the unencoded host name of the Uri, {@code null} for undefined. + * @param port the port number of the Uri, -1 for undefined. + * @param path the unencoded path to the resource on the host. + * @param query the unencoded query part of the Uri to specify parameters for the resource. + * @param fragment the unencoded fragment part of the Uri. + * @throws URISyntaxException + * if the temporary created string doesn't fit to the + * specification RFC2396 or could not be parsed correctly. + */ + public static Uri create (final String scheme, final String userinfo, String host, final int port, + final String path, final String query, final String fragment) throws URISyntaxException { + if ( emptyString(scheme) && emptyString(userinfo) && emptyString(host) && emptyString(path) && + emptyString(query) && emptyString(fragment) ) { + throw new URISyntaxException("", "all empty parts"); + } + + if ( !emptyString(scheme) && !emptyString(path) && path.length() > 0 && path.charAt(0) != '/') { + throw new URISyntaxException(path, "path doesn't start with '/'"); + } + + final StringBuilder uri = new StringBuilder(); + if ( !emptyString(scheme) ) { + uri.append(scheme); + uri.append(SCHEME_SEPARATOR); + } + + if ( !emptyString(userinfo) || !emptyString(host) || port != -1) { + uri.append("//"); + } + + if ( !emptyString(userinfo) ) { + // QUOTE ILLEGAL CHARACTERS in userinfo + uri.append(encode(userinfo, USERINFO_LEGAL)); + uri.append('@'); + } + + if ( !emptyString(host) ) { + // check for ipv6 addresses that hasn't been enclosed + // in square brackets + if (host.indexOf(SCHEME_SEPARATOR) != -1 && host.indexOf(']') == -1 + && host.indexOf('[') == -1) { + host = "[" + host + "]"; + } + uri.append(host); + } + + if ( port != -1 ) { + uri.append(SCHEME_SEPARATOR); + uri.append(port); + } + + if ( !emptyString(path) ) { + // QUOTE ILLEGAL CHARS + uri.append(encode(path, PATH_LEGAL)); + } + + if ( !emptyString(query) ) { + uri.append(QUERY_SEPARATOR); + // QUOTE ILLEGAL CHARS + uri.append(encode(query, QUERY_LEGAL)); + } + + if ( !emptyString(fragment) ) { + // QUOTE ILLEGAL CHARS + uri.append(FRAGMENT_SEPARATOR); + uri.append(encode(fragment, FRAG_LEGAL)); + } + return new Uri(new Encoded(uri.toString()), true, 0); + } + + /** + * Creates a new Uri instance using the given encoded arguments. + *

    + * This constructor first creates a temporary Uri string from the given encoded components. This + * string will be parsed later on to create the Uri instance. + *

    + *

    + * The given encoded components are taken as-is, i.e. no re-encoding will be performed! + * However, Uri parsing will re-evaluate encoding of the resulting components. + *

    + *

    + * {@code [scheme:][user-info@]host[:port][path][?query][#fragment]} + *

    + *

    + * {@code host} and {@code port} must be defined and valid, if any {@code authority} components are defined, + * i.e. {@code user-info}, {@code host} or {@code port}. + *

    + * + * @param scheme the encoded scheme part of the Uri. + * @param userinfo the encoded user information of the Uri for authentication and authorization, {@code null} for undefined. + * @param host the encoded host name of the Uri, {@code null} for undefined. + * @param port the port number of the Uri, -1 for undefined. + * @param path the encoded path to the resource on the host. + * @param query the encoded query part of the Uri to specify parameters for the resource. + * @param fragment the encoded fragment part of the Uri. + * @throws URISyntaxException + * if the temporary created string doesn't fit to the + * specification RFC2396 or could not be parsed correctly. + */ + public static Uri create (final Encoded scheme, final Encoded userinfo, final Encoded host, final int port, + final Encoded path, final Encoded query, final Encoded fragment) throws URISyntaxException { + if ( emptyString(scheme) && emptyString(userinfo) && emptyString(host) && emptyString(path) && + emptyString(query) && emptyString(fragment) ) { + throw new URISyntaxException("", "all empty parts"); + } + + if ( !emptyString(scheme) && !emptyString(path) && path.length() > 0 && path.charAt(0) != '/') { + throw new URISyntaxException(path.get(), "path doesn't start with '/'"); + } + + final StringBuilder uri = new StringBuilder(); + if ( !emptyString(scheme) ) { + uri.append(scheme); + uri.append(SCHEME_SEPARATOR); + } + + if ( !emptyString(userinfo) || !emptyString(host) || port != -1) { + uri.append("//"); + } + + if ( !emptyString(userinfo) ) { + uri.append(userinfo.get()); + uri.append('@'); + } + + if ( !emptyString(host) ) { + uri.append(host.get()); + } + + if ( port != -1 ) { + uri.append(SCHEME_SEPARATOR); + uri.append(port); + } + + if ( !emptyString(path) ) { + uri.append(path.get()); + } + + if ( !emptyString(query) ) { + uri.append(QUERY_SEPARATOR); + uri.append(query.get()); + } + + if ( !emptyString(fragment) ) { + uri.append(FRAGMENT_SEPARATOR); + uri.append(fragment.get()); + } + return new Uri(new Encoded(uri.toString()), true, 0); + } + + /** + * Creates a new Uri instance using the given unencoded arguments. + *

    + * This constructor first creates a temporary Uri string from the given unencoded components. This + * string will be parsed later on to create the Uri instance. + *

    + *

    + * {@code [scheme:]host[path][#fragment]} + *

    + *

    + * {@code host} must be valid, if defined. + *

    + * + * @param scheme the unencoded scheme part of the Uri. + * @param host the unencoded host name of the Uri. + * @param path the unencoded path to the resource on the host. + * @param fragment the unencoded fragment part of the Uri. + * @throws URISyntaxException + * if the temporary created string doesn't fit to the + * specification RFC2396 or could not be parsed correctly. + */ + public static Uri create(final String scheme, final String host, final String path, final String fragment) throws URISyntaxException { + return create(scheme, null, host, -1, path, null, fragment); + } + + /** + * Creates a new Uri instance using the given encoded arguments. + *

    + * This constructor first creates a temporary Uri string from the given encoded components. This + * string will be parsed later on to create the Uri instance. + *

    + *

    + * The given encoded components are taken as-is, i.e. no re-encoding will be performed! + * However, Uri parsing will re-evaluate encoding of the resulting components. + *

    + *

    + * {@code [scheme:]host[path][#fragment]} + *

    + *

    + * {@code host} must be valid, if defined. + *

    + * + * @param scheme the encoded scheme part of the Uri. + * @param host the encoded host name of the Uri. + * @param path the encoded path to the resource on the host. + * @param fragment the encoded fragment part of the Uri. + * @throws URISyntaxException + * if the temporary created string doesn't fit to the + * specification RFC2396 or could not be parsed correctly. + */ + public static Uri create(final Encoded scheme, final Encoded host, final Encoded path, final Encoded fragment) throws URISyntaxException { + return create(scheme, null, host, -1, path, null, fragment); + } + + /** + * Creates a new Uri instance using the given unencoded arguments. + *

    + * This constructor first creates a temporary Uri string from the given unencoded components. This + * string will be parsed later on to create the Uri instance. + *

    + *

    + * {@code [scheme:][//authority][path][?query][#fragment]} + *

    + *

    + * {@code host} and {@code port} may be undefined or invalid, in the optional {@code authority}. + *

    + * + * @param scheme the unencoded scheme part of the Uri. + * @param authority the unencoded authority part of the Uri. + * @param path the unencoded path to the resource on the host. + * @param query the unencoded query part of the Uri to specify parameters for the resource. + * @param fragment the unencoded fragment part of the Uri. + * + * @throws URISyntaxException + * if the temporary created string doesn't fit to the + * specification RFC2396 or could not be parsed correctly. + */ + public static Uri create(final String scheme, final String authority, final String path, final String query, final String fragment) throws URISyntaxException { + if ( emptyString(scheme) && emptyString(authority) && emptyString(path) && + emptyString(query) && emptyString(fragment) ) { + throw new URISyntaxException("", "all empty parts"); + } + if ( !emptyString(scheme) && !emptyString(path) && path.length() > 0 && path.charAt(0) != '/') { + throw new URISyntaxException(path, "path doesn't start with '/'"); + } + + final StringBuilder uri = new StringBuilder(); + if ( !emptyString(scheme) ) { + uri.append(scheme); + uri.append(SCHEME_SEPARATOR); + } + if ( !emptyString(authority) ) { + uri.append("//"); + // QUOTE ILLEGAL CHARS + uri.append(encode(authority, AUTHORITY_LEGAL)); + } + + if ( !emptyString(path) ) { + // QUOTE ILLEGAL CHARS + uri.append(encode(path, PATH_LEGAL)); + } + if ( !emptyString(query) ) { + // QUOTE ILLEGAL CHARS + uri.append(QUERY_SEPARATOR); + uri.append(encode(query, QUERY_LEGAL)); + } + if ( !emptyString(fragment) ) { + // QUOTE ILLEGAL CHARS + uri.append(FRAGMENT_SEPARATOR); + uri.append(encode(fragment, FRAG_LEGAL)); + } + return new Uri(new Encoded(uri.toString()), false, 0); + } + + /** + * Creates a new Uri instance using the given encoded arguments. + *

    + * This constructor first creates a temporary Uri string from the given encoded encoded components. This + * string will be parsed later on to create the Uri instance. + *

    + *

    + * The given encoded components are taken as-is, i.e. no re-encoding will be performed! + * However, Uri parsing will re-evaluate encoding of the resulting components. + *

    + *

    + * {@code [scheme:][//authority][path][?query][#fragment]} + *

    + *

    + * {@code host} and {@code port} may be undefined or invalid, in the optional {@code authority}. + *

    + * + * @param scheme the encoded scheme part of the Uri. + * @param authority the encoded authority part of the Uri. + * @param path the encoded path to the resource on the host. + * @param query the encoded query part of the Uri to specify parameters for the resource. + * @param fragment the encoded fragment part of the Uri. + * + * @throws URISyntaxException + * if the temporary created string doesn't fit to the + * specification RFC2396 or could not be parsed correctly. + */ + public static Uri create(final Encoded scheme, final Encoded authority, final Encoded path, final Encoded query, final Encoded fragment) throws URISyntaxException { + if ( emptyString(scheme) && emptyString(authority) && emptyString(path) && + emptyString(query) && emptyString(fragment) ) { + throw new URISyntaxException("", "all empty parts"); + } + if ( !emptyString(scheme) && !emptyString(path) && path.length() > 0 && path.charAt(0) != '/') { + throw new URISyntaxException(path.get(), "path doesn't start with '/'"); + } + + final StringBuilder uri = new StringBuilder(); + if ( !emptyString(scheme) ) { + uri.append(scheme); + uri.append(SCHEME_SEPARATOR); + } + if ( !emptyString(authority) ) { + uri.append("//"); + uri.append(authority.get()); + } + + if ( !emptyString(path) ) { + uri.append(path.get()); + } + if ( !emptyString(query) ) { + uri.append(QUERY_SEPARATOR); + uri.append(query.get()); + } + if ( !emptyString(fragment) ) { + uri.append(FRAGMENT_SEPARATOR); + uri.append(fragment.get()); + } + return new Uri(new Encoded(uri.toString()), false, 0); + } + + /** + * Casts the given encoded String to a {@link Encoded#cast(String) new Encoded instance} + * used to create the resulting Uri instance via {@link #Uri(Encoded)}. + *

    + * No encoding will be performed on the given {@code encodedUri}, use with care. + *

    + * @throws URISyntaxException + */ + public static Uri cast(final String encodedUri) throws URISyntaxException { + return new Uri(Encoded.cast(encodedUri)); + } + + /** + * Creates a new Uri instance using the given file-path argument. + *

    + * This constructor first creates a temporary Uri string from the given components. This + * string will be parsed later on to create the Uri instance. + *

    + *

    + * {@code file:path} + *

    + * + * @param path the unencoded path of the {@code file} {@code schema}. + * @throws URISyntaxException + * if the temporary created string doesn't fit to the + * specification RFC2396 or could not be parsed correctly. + */ + public static Uri valueOfFilepath(final String path) throws URISyntaxException { + if ( emptyString(path) ) { + throw new URISyntaxException("", "empty path"); + } + if ( path.charAt(0) != '/' ) { + throw new URISyntaxException(path, "path doesn't start with '/'"); + } + + final StringBuilder uri = new StringBuilder(); + uri.append(FILE_SCHEME); + uri.append(SCHEME_SEPARATOR); + + // QUOTE ILLEGAL CHARS + uri.append(encode(path, PATH_LEGAL)); + + return new Uri(new Encoded(uri.toString()), false, 0); + } + + /** + * Creates a new Uri instance using the given File instance. + *

    + * This constructor first creates a temporary Uri string from the given components. This + * string will be parsed later on to create the Uri instance. + *

    + *

    + * {@code file:path} + *

    + * + * @param file using {@link IOUtil#slashify(String, boolean, boolean) slashified} {@link File#getAbsolutePath() absolute-path} + * for the path of the {@code file} {@code schema}, utilizing {@link #valueOfFilepath(String)}. + * @throws URISyntaxException + * if the temporary created string doesn't fit to the + * specification RFC2396 or could not be parsed correctly. + */ + public static Uri valueOf(final File file) throws URISyntaxException { + return Uri.valueOfFilepath(IOUtil.slashify(file.getAbsolutePath(), true, file.isDirectory())); + } + + /** + * Creates a new Uri instance using the given URI instance. + *

    + * Re-encoding will be performed if the given URI is {@link URI#isOpaque() not opaque}. + *

    + *

    + * See {@link #PARSE_HINT_FIX_PATH} for issues of injecting opaque URLs. + *

    + * + * @param uri A given URI instance + * @throws URISyntaxException + * if the temporary created string doesn't fit to the + * specification RFC2396 or could not be parsed correctly. + */ + public static Uri valueOf(final java.net.URI uri) throws URISyntaxException { + if( uri.isOpaque()) { + // opaque, without host validation. + // Note: This may induce encoding errors of authority and path, see {@link #PARSE_HINT_FIX_PATH} + return new Uri(new Encoded( uri.toString() ), false, 0); + } else { + // with host validation if authority is defined + return Uri.create(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), + uri.getPath(), uri.getQuery(), uri.getFragment()); + } + } + + /** + * Creates a new Uri instance using the given URL instance, + * convenient wrapper for {@link #valueOf(URI)} and {@link URL#toURI()}. + *

    + * Re-encoding will be performed if the given URL is {@link URI#isOpaque() not opaque}, see {@link #valueOf(URI)}. + *

    + *

    + * See {@link #PARSE_HINT_FIX_PATH} for issues of injecting opaque URLs. + *

    + * + * @param url A given URL instance + * + * @throws URISyntaxException + * if the temporary created string doesn't fit to the + * specification RFC2396 or could not be parsed correctly. + */ + public static Uri valueOf(final java.net.URL url) throws URISyntaxException { + return valueOf(url.toURI()); + } + + // + // All string fields are encoded! + // + + /** Encoded input string used at construction, never {@code null}. */ + public final Encoded input; + + private final Object lazyLock = new Object(); + + /** Encoded input string used at construction, in US-ASCII encoding. */ + private ASCIIEncoded inputASCII; + + private int hash; + + /** Encoded {@code scheme}, {@code null} if undefined. */ + public final Encoded scheme; + + /** Encoded {@code scheme-specific-part}, never {@code null}. */ + public final Encoded schemeSpecificPart; + /** Encoded {@code path} part of {@code scheme-specific-part}, never {@code null}. */ + public final Encoded path; + + /** Indicating whether {@code authority} part is defined or not. */ + public final boolean hasAuthority; + /** Encoded {@code authority} part of {@code scheme-specific-part}, {@code null} if undefined. */ + public final Encoded authority; + /** Encoded {@code userinfo} part of {@code authority} and {@code scheme-specific-part}, {@code null} if undefined. */ + public final Encoded userInfo; // part of authority + /** Encoded {@code host} part of {@code authority} and {@code scheme-specific-part}, {@code null} if undefined. */ + public final Encoded host; // part of authority + /** Encoded {@code port} part of {@code authority} and {@code scheme-specific-part}, {@code -1} if undefined. */ + public final int port; // part of authority + + /** Encoded {@code query} part of {@code scheme-specific-part}, {@code null} if undefined. */ + public final Encoded query; + + /** Encoded {@code fragment}, {@code null} if undefined. */ + public final Encoded fragment; + + /** Indicating whether this Uri is absolute, i.e. has a {@code scheme} and hence an absolute {@code scheme-specific-part}. */ + public final boolean absolute; + + /** + * Indicating whether this Uri is opaque, i.e. non-hierarchical {@code scheme-specific-part}. + *

    + * An opaque Uri has no {@code scheme-specific-part} being parsed, + * i.e. {@code path}, {@code query} and {@code authority} are {@code null}. + *

    + */ + public final boolean opaque; + + /** + * Creates a new Uri instance according to the given encoded string {@code uri}. + * + * @param uri the RFC3986 encoded RFC2396 Uri representation to be parsed into a Uri object + * @throws URISyntaxException + * if the given string {@code uri} doesn't fit to the + * specification RFC2396 and RFC3986 or could not be parsed correctly. + */ + public Uri(final Encoded uri) throws URISyntaxException { + this(uri, false, 0); + } + + /** Returns true, if this instance is a {@code file} {@code scheme}, otherwise false. */ + public final boolean isFileScheme() { + return null != scheme && FILE_SCHEME.equals( scheme.get() ); + } + + /** + * Returns true, if this instance is a {@code jar} {@code scheme}, otherwise false. + * @since 2.3.2 + */ + public final boolean isJarScheme() { + return null != scheme && JAR_SCHEME.equals( scheme.get() ); + } + + /** + * Returns the encoded {@link #input}, never {@code null}. + */ + public final Encoded getEncoded() { + return input; + } + + /** + * Returns the encoded {@link #input} as String, never {@code null}, same as {@link #getEncoded()}. + */ + @Override + public final String toString() { + return input.get(); + } + + /** + * Returns the encoded {@link #input} encoded in US-ASCII. + */ + public ASCIIEncoded toASCIIString() { + synchronized( lazyLock ) { + if( null == inputASCII ) { + inputASCII = new ASCIIEncoded(input.get()); + } + return inputASCII; + } + } + + /** + * Returns a new {@link URI} instance using the encoded {@link #input} string, {@code new URI(uri.input)}, + * i.e. no re-encoding will be performed. + * @see #toURIReencoded(boolean) + * @see #valueOf(URI) + */ + public final java.net.URI toURI() { + try { + return new java.net.URI(input.get()); + } catch (final URISyntaxException e) { + throw new Error(e); // Can't happen + } + } + + /** + * Returns a new {@link URI} instance based upon this instance. + *

    + * All Uri parts of this instance will be decoded + * and encoded by the URI constructor, i.e. re-encoding will be performed. + *

    + * + * @throws URISyntaxException + * if the given string {@code uri} doesn't fit to the + * specification RFC2396 or could not be parsed correctly. + * @see #toURI() + * @see #valueOf(URI) + */ + public final java.net.URI toURIReencoded() throws URISyntaxException { + final java.net.URI recomposedURI; + if( opaque ) { + // opaque, without host validation + recomposedURI = new java.net.URI(decode(scheme), decode(schemeSpecificPart), decode(fragment)); + } else if( null != host ) { + // with host validation + recomposedURI = new java.net.URI(decode(scheme), decode(userInfo), decode(host), port, + decode(path), decode(query), decode(fragment)); + } else { + // without host validation + recomposedURI = new java.net.URI(decode(scheme), decode(authority), + decode(path), decode(query), decode(fragment)); + } + return recomposedURI; + } + + + /** + * Returns a new {@link URL} instance using the encoded {@link #input} string, {@code new URL(uri.input)}, + * i.e. no re-encoding will be performed. + * @throws MalformedURLException + * if an error occurs while creating the URL or no protocol + * handler could be found. + */ + public final java.net.URL toURL() throws MalformedURLException { + if (!absolute) { + throw new IllegalArgumentException("Cannot convert relative Uri: "+input); + } + return new java.net.URL(input.get()); + } + + /** + * If this instance {@link #isFileScheme() is a file scheme}, + * implementation decodes [ "//"+{@link #authority} ] + {@link #path},
    + * then it processes the result if {@link File#separatorChar} == '\\' + * as follows: + *
      + *
    • slash -> backslash
    • + *
    • drop a starting single backslash, preserving windows UNC
    • + *
    + * and returns the resulting new {@link File} instance. + *

    + * Otherwise implementation returns {@code null}. + *

    + */ + public final File toFile() { + if( isFileScheme() && !emptyString(path) ) { + final String authorityS; + if( null == authority ) { + authorityS = ""; + } else { + authorityS = "//"+authority.decode(); + } + final String path = authorityS+this.path.decode(); + if( File.separator.equals("\\") ) { + final String r = patternSingleFS.matcher(path).replaceAll("\\\\"); + if( r.startsWith("\\") && !r.startsWith("\\\\") ) { // '\\\\' denotes UNC hostname, which shall not be cut-off + return new File(r.substring(1)); + } else { + return new File(r); + } + } + return new File(path); + } + return null; + } + + /** + * If this instance's {@link #schemeSpecificPart} contains a Uri itself, a sub-Uri, + * return {@link #schemeSpecificPart} + {@code #} {@link #fragment} via it's own new Uri instance. + *

    + * In case this Uri is a {@code jar-scheme}, the {@code query} is omitted, + * since it shall be invalid for {@code jar-schemes} anyway. + *

    + *

    + * Otherwise method returns {@code null}. + *

    + *
    +     * Example 1:
    +     *     This instance: jar:scheme2:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class
    +     *     Returned Uri:  scheme2:/some/path/gluegen-rt.jar
    +     *
    +     * Example 2:
    +     *     This instance: jar:scheme2:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class?lala=01#fragment
    +     *     Returned Uri:  scheme2:/some/path/gluegen-rt.jar#fragment
    +     *
    +     * Example 3:
    +     *     This instance: scheme1:scheme2:/some/path/gluegen-rt.jar!/?lala=01#fragment
    +     *     Returned Uri:  scheme2:/some/path/gluegen-rt.jar?lala=01#fragment
    +     * 
    + * @throws URISyntaxException if this Uri is a container Uri and does not comply with the container spec, i.e. a JAR Uri + */ + public final Uri getContainedUri() throws URISyntaxException { + if( !emptyString(schemeSpecificPart) ) { + final StringBuilder sb = new StringBuilder(); + + if( isJarScheme() ) { + final int idx = schemeSpecificPart.lastIndexOf(JAR_SCHEME_SEPARATOR); + if (0 > idx) { + throw new URISyntaxException(input.get(), "missing jar separator"); + } + sb.append( schemeSpecificPart.get().substring(0, idx) ); // exclude '!/' + } else { + sb.append( schemeSpecificPart.get() ); + } + if ( !emptyString(fragment) ) { + sb.append(FRAGMENT_SEPARATOR); + sb.append(fragment); + } + try { + final int parseHints = opaque ? PARSE_HINT_FIX_PATH : 0; + final Uri res = new Uri(new Encoded(sb.toString()), false, parseHints); + if( null != res.scheme ) { + return res; + } + } catch(final URISyntaxException e) { + // OK, does not contain uri + if( DEBUG ) { + System.err.println("Caught "+e.getClass().getSimpleName()+": "+e.getMessage()); + e.printStackTrace(); + } + } + } + return null; + } + + private static final boolean cutoffLastPathSegementImpl(final StringBuilder pathBuf, + final boolean cutoffFile, + final boolean cutoffDir, + final Encoded appendPath) throws URISyntaxException { + final boolean cleaned; + {// clean-up existing path + final String pathS = pathBuf.toString(); + if( 0 > pathS.indexOf("/") && emptyString(appendPath) ) { + return false; // nothing to cut-off + } + pathBuf.setLength(0); + pathBuf.append( IOUtil.cleanPathString( pathS ) ); + cleaned = pathBuf.length() != pathS.length(); + } + + {// cut-off file or last dir-segment + final String pathS = pathBuf.toString(); + final int jarSepIdx = pathS.lastIndexOf(JAR_SCHEME_SEPARATOR); + final int e = pathS.lastIndexOf("/"); + if( 0 > jarSepIdx || e - 1 > jarSepIdx ) { // stop at jar-separator '!/', if exist + if( cutoffFile && e < pathS.length() - 1 ) { + // cut-off file + pathBuf.setLength(0); + pathBuf.append( pathS.substring(0, e+1) ); + } else if( cutoffDir ) { + // cut-off dir-segment + final int p = pathS.lastIndexOf("/", e-1); + if( p >= 0 ) { + pathBuf.setLength(0); + pathBuf.append( pathS.substring(0, p+1) ); + } // else keep + } // else keep + } + final boolean cutoff = pathBuf.length() != pathS.length(); + if( !cutoff && ( cutoffDir || !cleaned ) && emptyString(appendPath) ) { + return false; // no modifications! + } + } + if( !emptyString(appendPath) ) { + pathBuf.append(appendPath.get()); + // 2nd round of cleaning! + final String pathS = pathBuf.toString(); + pathBuf.setLength(0); + pathBuf.append( IOUtil.cleanPathString( pathS ) ); + } + return true; // continue processing w/ buffer + } + private final Uri cutoffLastPathSegementImpl(final boolean cutoffFile, final boolean cutoffDir, final Encoded appendPath) throws URISyntaxException { + if( opaque ) { + if( emptyString(schemeSpecificPart) ) { + // nothing to cut-off + if( !emptyString(appendPath) ) { + return Uri.create(scheme, appendPath, fragment); + } else { + return null; + } + } + final StringBuilder sspBuf = new StringBuilder(); // without path! + + // save optional query in scheme-specific-part + final Encoded queryTemp; + final int queryI = schemeSpecificPart.lastIndexOf(QUERY_SEPARATOR); + if( queryI >= 0 ) { + queryTemp = schemeSpecificPart.substring(queryI+1); + sspBuf.append( schemeSpecificPart.substring(0, queryI).get() ); + } else { + queryTemp = null; + sspBuf.append( schemeSpecificPart.get() ); + } + + if( !cutoffLastPathSegementImpl(sspBuf, cutoffFile, cutoffDir, appendPath) ) { + return null; // no modifications + } + + if ( !emptyString(queryTemp) ) { + sspBuf.append(QUERY_SEPARATOR); + sspBuf.append( queryTemp.get() ); + } + + // without host validation if authority is defined + return Uri.create(scheme, new Encoded(sspBuf.toString()), fragment); + } else { + if( emptyString(path) ) { + return null; // nothing to cut-off + } + final StringBuilder pathBuf = new StringBuilder(); + pathBuf.append( path.get() ); + + if( !cutoffLastPathSegementImpl(pathBuf, cutoffFile, cutoffDir, appendPath) ) { + return null; // no modifications + } + + // with host validation if authority is defined + return Uri.create(scheme, userInfo, host, port, new Encoded(pathBuf.toString()), query, fragment); + } + } + + /** + * {@link IOUtil#cleanPathString(String) Normalizes} this Uri's path and return the + * {@link IOUtil#cleanPathString(String) normalized} form if it differs, otherwise {@code this} instance. + *

    + *

    +     * Example-1:
    +     *     This instance  : jar:http://some/path/../gluegen-rt.jar!/com/Test.class?arg=1#frag
    +     *     Normalized     : jar:http://some/gluegen-rt.jar!/com/Test.class?arg=1#frag
    +     *
    +     * Example-2:
    +     *     This instance  : http://some/path/../gluegen-rt.jar?arg=1#frag
    +     *     Normalized     : http://some/gluegen-rt.jar?arg=1#frag
    +     * 
    + *

    + */ + public final Uri getNormalized() { + try { + final Uri res = cutoffLastPathSegementImpl(false, false, null); + return null != res ? res : this; + } catch (final URISyntaxException e) { + if( DEBUG ) { + System.err.println("Caught "+e.getClass().getSimpleName()+": "+e.getMessage()); + e.printStackTrace(); + } + return this; + } + } + + /** + * Returns this Uri's directory Uri. + *

    + * This Uri path will be {@link IOUtil#cleanPathString(String) normalized} before returning the directory. + *

    + *

    + * If this Uri's directory cannot be found, or already denotes a directory, method returns {@code this} instance. + *

    + *

    + *

    +     * Example-1:
    +     *     this-uri: http:/some/path/gluegen-rt.jar?arg=1#frag
    +     *     result:   http:/some/path/?arg=1#frag
    +     *
    +     * Example-2:
    +     *     this-uri: file:/some/path/
    +     *     result:   file:/some/path/
    +     *
    +     * Example-3:
    +     *     this-uri: file:/some/path/lala/lili/../../hello.txt
    +     *     result:   file:/some/path/
    +     * 
    + *

    + * @throws URISyntaxException if the new string {@code uri} doesn't fit to the + * specification RFC2396 and RFC3986 or could not be parsed correctly. + */ + public Uri getDirectory() { + try { + final Uri res = cutoffLastPathSegementImpl(true, false, null); + return null != res ? res : this; + } catch (final URISyntaxException e) { + if( DEBUG ) { + System.err.println("Caught "+e.getClass().getSimpleName()+": "+e.getMessage()); + e.printStackTrace(); + } + return this; + } + } + + /** + * Returns this Uri's parent directory Uri.. + *

    + * This Uri path will be {@link IOUtil#cleanPathString(String) normalized} before traversing up one directory. + *

    + *

    + * If a parent folder cannot be found, method returns {@code null}. + *

    + *

    + *

    +     * Example-1:
    +     *     This instance  : jar:http://some/path/gluegen-rt.jar!/com/Test.class?arg=1#frag
    +     *     Returned Uri #1: jar:http://some/path/gluegen-rt.jar!/com/?arg=1#frag
    +     *     Returned Uri #2: jar:http://some/path/gluegen-rt.jar!/?arg=1#frag
    +     *     Returned Uri #3: null
    +     *
    +     * Example-2:
    +     *     This instance  : http://some/path/gluegen-rt.jar?arg=1#frag
    +     *     Returned Uri #1: http://some/path/?arg=1#frag
    +     *     Returned Uri #2: http://some/?arg=1#frag
    +     *     Returned Uri #2: null
    +     *
    +     * Example-3:
    +     *     This instance  : http://some/path/../gluegen-rt.jar?arg=1#frag
    +     *     Returned Uri #1: http://some/?arg=1#frag
    +     *     Returned Uri #2: null
    +     * 
    + *

    + */ + public final Uri getParent() { + try { + return cutoffLastPathSegementImpl(true, true, null); + } catch (final URISyntaxException e) { + if( DEBUG ) { + System.err.println("Caught "+e.getClass().getSimpleName()+": "+e.getMessage()); + e.printStackTrace(); + } + return null; + } + } + + /** + * Returns a new Uri appending the given {@code appendPath} + * to this instance's {@link #getDirectory() directory}. + *

    + * If {@code appendPath} is empty, method behaves like {@link #getNormalized()}. + *

    + *

    + * This resulting path will be {@link IOUtil#cleanPathString(String) normalized}. + *

    + *

    + *

    +     * Example-1:
    +     *     append: null
    +     *     this-uri: http:/some/path/gluegen-rt.jar
    +     *     result:   http:/some/path/gluegen-rt.jar
    +     *
    +     * Example-2:
    +     *     append: test.txt
    +     *     this-uri: file:/some/path/gluegen-rt.jar
    +     *     result:   file:/some/path/test.txt
    +     *
    +     * Example-3:
    +     *     append: test.txt
    +     *     this-uri: file:/some/path/lala/lili/../../hello.txt
    +     *     result:   file:/some/path/test.txt
    +     * 
    + *

    + * + * @param appendPath denotes a relative path to be appended to this Uri's directory + * @throws URISyntaxException + * if the resulting {@code uri} doesn't fit to the + * specification RFC2396 and RFC3986 or could not be parsed correctly. + */ + public Uri getRelativeOf(final Encoded appendPath) throws URISyntaxException { + if( emptyString(appendPath) ) { + return getNormalized(); + } else { + return cutoffLastPathSegementImpl(true, false, appendPath); + } + } + + /** + * Concatenates the given encoded string to the {@link #getEncoded() encoded uri} + * of this instance and returns {@link #Uri(Encoded) a new Uri instance} with the result. + * + * @throws URISyntaxException + * if the concatenated string {@code uri} doesn't fit to the + * specification RFC2396 and RFC3986 or could not be parsed correctly. + */ + public final Uri concat(final Encoded suffix) throws URISyntaxException { + if( null == suffix ) { + return this; + } else { + return new Uri( input.concat(suffix) ); + } + } + + /** + * Returns a new Uri instance w/ the given new query {@code newQuery}. + * + * @throws URISyntaxException if this Uri is {@link #opaque} + * or if the new string {@code uri} doesn't fit to the + * specification RFC2396 and RFC3986 or could not be parsed correctly. + */ + public final Uri getNewQuery(final Encoded newQuery) throws URISyntaxException { + if( opaque ) { + throw new URISyntaxException(input.decode(), "Opaque Uri cannot permute by query"); + } else { + // with host validation if authority is defined + return Uri.create(scheme, userInfo, host, port, path, newQuery, fragment); + } + } + + /** + * {@inheritDoc} + *

    + * Compares this Uri instance with the given argument {@code o} and + * determines if both are equal. Two Uri instances are equal if all single + * parts are identical in their meaning. + *

    + * + * @param o + * the Uri this instance has to be compared with. + * @return {@code true} if both Uri instances point to the same resource, + * {@code false} otherwise. + */ + @Override + public final boolean equals(final Object o) { + if (!(o instanceof Uri)) { + return false; + } + final Uri uri = (Uri) o; + + if (uri.fragment == null && fragment != null || uri.fragment != null && fragment == null) { + return false; + } else if (uri.fragment != null && fragment != null) { + if (!equalsHexCaseInsensitive(uri.fragment, fragment)) { + return false; + } + } + + if (uri.scheme == null && scheme != null || uri.scheme != null && scheme == null) { + return false; + } else if (uri.scheme != null && scheme != null) { + if (!uri.scheme.equalsIgnoreCase(scheme)) { + return false; + } + } + + if (uri.opaque && opaque) { + return equalsHexCaseInsensitive(uri.schemeSpecificPart, schemeSpecificPart); + } else if (!uri.opaque && !opaque) { + if (!equalsHexCaseInsensitive(path, uri.path)) { + return false; + } + + if (uri.query != null && query == null || uri.query == null && query != null) { + return false; + } else if (uri.query != null && query != null) { + if (!equalsHexCaseInsensitive(uri.query, query)) { + return false; + } + } + + if (uri.authority != null && authority == null || uri.authority == null && authority != null) { + return false; + } else if (uri.authority != null && authority != null) { + if (uri.host != null && host == null || uri.host == null && host != null) { + return false; + } else if (uri.host == null && host == null) { + // both are registry based, so compare the whole authority + return equalsHexCaseInsensitive(uri.authority, authority); + } else { // uri.host != null && host != null, so server-based + if (!host.equalsIgnoreCase(uri.host)) { + return false; + } + + if (port != uri.port) { + return false; + } + + if ( uri.userInfo != null && userInfo == null || + uri.userInfo == null && userInfo != null + ) { + return false; + } else if (uri.userInfo != null && userInfo != null) { + return equalsHexCaseInsensitive(userInfo, uri.userInfo); + } else { + return true; + } + } + } else { + // no authority + return true; + } + + } else { + // one is opaque, the other hierarchical + return false; + } + } + + /** + * {@inheritDoc} + *

    + * Gets the hashcode value of this Uri instance. + *

    + */ + @Override + public final int hashCode() { + synchronized( lazyLock ) { + if (hash == -1) { + hash = getHashString().hashCode(); + } + return hash; + } + } + + /* + * Takes a string that may contain hex sequences like %F1 or %2b and + * converts the hex values following the '%' to lowercase + */ + private String convertHexToLowerCase(final String s) { + if (s.indexOf('%') == -1) { + return s; + } + final StringBuilder result = new StringBuilder(""); + int index = 0, previndex = 0; + while ((index = s.indexOf('%', previndex)) != -1) { + result.append(s.substring(previndex, index + 1)); + result.append(s.substring(index + 1, index + 3).toLowerCase()); + index += 3; + previndex = index; + } + return result.toString(); + } + + /* + * Takes two strings that may contain hex sequences like %F1 or %2b and + * compares them, ignoring case for the hex values. Hex values must always + * occur in pairs as above + */ + private boolean equalsHexCaseInsensitive(final Encoded first, final Encoded second) { + if (first.indexOf('%') != second.indexOf('%')) { + return first.equals(second); + } + + int index = 0, previndex = 0; + while ( ( index = first.indexOf('%', previndex) ) != -1 && + second.indexOf('%', previndex) == index + ) { + if( !first.get().substring(previndex, index).equals( second.get().substring(previndex, index) ) ) { + return false; + } + if( !first.get().substring(index + 1, index + 3).equalsIgnoreCase( second.get().substring(index + 1, index + 3) ) ) { + return false; + } + index += 3; + previndex = index; + } + return first.get().substring(previndex).equals( second.get().substring(previndex) ); + } + + /* + * Form a string from the components of this Uri, similarly to the + * toString() method. But this method converts scheme and host to lowercase, + * and converts escaped octets to lowercase. + */ + private String getHashString() { + final StringBuilder result = new StringBuilder(); + if (scheme != null) { + result.append(scheme.get().toLowerCase()); + result.append(SCHEME_SEPARATOR); + } + if (opaque) { + result.append(schemeSpecificPart.get()); + } else { + if (authority != null) { + result.append("//"); + if (host == null) { + result.append(authority.get()); + } else { + if (userInfo != null) { + result.append(userInfo.get() + "@"); + } + result.append(host.get().toLowerCase()); + if (port != -1) { + result.append(SCHEME_SEPARATOR + port); + } + } + } + + if (path != null) { + result.append(path.get()); + } + + if (query != null) { + result.append(QUERY_SEPARATOR); + result.append(query.get()); + } + } + + if (fragment != null) { + result.append(FRAGMENT_SEPARATOR); + result.append(fragment.get()); + } + return convertHexToLowerCase(result.toString()); + } + + /** + * + * @param input + * @param expectServer + * @param parseHints TODO + * @throws URISyntaxException + */ + private Uri(final Encoded input, final boolean expectServer, final int parseHints) throws URISyntaxException { + if( emptyString(input) ) { + throw new URISyntaxException(input.get(), "empty input"); + } + String temp = input.get(); + int index; + // parse into Fragment, Scheme, and SchemeSpecificPart + // then parse SchemeSpecificPart if necessary + + // Fragment + index = temp.indexOf(FRAGMENT_SEPARATOR); + if (index != -1) { + // remove the fragment from the end + fragment = new Encoded( temp.substring(index + 1) ); + validateFragment(input, fragment, index + 1); + temp = temp.substring(0, index); + } else { + fragment = null; + } + + String inputTemp = input.get(); // may get modified due to error correction + + // Scheme and SchemeSpecificPart + final int indexSchemeSep = temp.indexOf(SCHEME_SEPARATOR); + index = indexSchemeSep; + final int indexSSP = temp.indexOf('/'); + final int indexQuerySep = temp.indexOf(QUERY_SEPARATOR); + + String sspTemp; // may get modified due to error correction + + // if a '/' or '?' occurs before the first ':' the uri has no + // specified scheme, and is therefore not absolute + if ( indexSchemeSep != -1 && + ( indexSSP >= indexSchemeSep || indexSSP == -1 ) && + ( indexQuerySep >= indexSchemeSep || indexQuerySep == -1 ) + ) { + // the characters up to the first ':' comprise the scheme + absolute = true; + scheme = new Encoded( temp.substring(0, indexSchemeSep) ); + if (scheme.length() == 0) { + failExpecting(input, "scheme", indexSchemeSep); + } + validateScheme(input, scheme, 0); + sspTemp = temp.substring(indexSchemeSep + 1); + if (sspTemp.length() == 0) { + failExpecting(input, "scheme-specific-part", indexSchemeSep); + } + } else { + absolute = false; + scheme = null; + sspTemp = temp; + } + + if ( scheme == null || sspTemp.length() > 0 && sspTemp.charAt(0) == '/' ) { + // Uri is hierarchical, not opaque + opaque = false; + + // Query + temp = sspTemp; + index = temp.indexOf(QUERY_SEPARATOR); + if (index != -1) { + query = new Encoded( temp.substring(index + 1) ); + temp = temp.substring(0, index); + validateQuery(input, query, indexSSP + 1 + index); + } else { + query = null; + } + + String pathTemp; // may get modified due to error correction + final int indexPathInSSP; + + // Authority and Path + if (temp.startsWith("//")) { + index = temp.indexOf('/', 2); + final String authorityS; + if (index != -1) { + authorityS = temp.substring(2, index); + pathTemp = temp.substring(index); + indexPathInSSP = index; + } else { + authorityS = temp.substring(2); + if (authorityS.length() == 0 && query == null && fragment == null) { + failExpecting(input, "authority, path [, query, fragment]", index); + } + pathTemp = ""; + indexPathInSSP = -1; + // nothing left, so path is empty + // (not null, path should never be null if hierarchical/non-opaque) + } + if ( emptyString(authorityS) ) { + authority = null; + } else { + authority = new Encoded( authorityS ); + validateAuthority(input, authority, indexSchemeSep + 3); + } + } else { // no authority specified + pathTemp = temp; + indexPathInSSP = 0; + authority = null; + } + + int indexPath = 0; // in input + if (indexSSP > -1) { + indexPath += indexSSP; + } + if (indexPathInSSP > -1) { + indexPath += indexPathInSSP; + } + + final int pathErrIdx = validateEncoded(pathTemp, PATH_LEGAL); + if( 0 <= pathErrIdx ) { + // Perform error correction on PATH if requested! + if( 0 != ( parseHints & PARSE_HINT_FIX_PATH ) ) { + if( DEBUG_SHOWFIX ) { + System.err.println("Uri FIX_FILEPATH: input at index "+(indexPath+pathErrIdx)+": "+inputTemp); + System.err.println("Uri FIX_FILEPATH: ssp at index "+(indexPathInSSP+pathErrIdx)+": "+sspTemp); + System.err.println("Uri FIX_FILEPATH: path at index "+pathErrIdx+": "+pathTemp); + } + final int pathTempOldLen = pathTemp.length(); + pathTemp = encode( decode( pathTemp ), PATH_LEGAL); // re-encode, and hope for the best! + validatePath(input, pathTemp, indexPath); // re-validate! + { + // Patch SSP + INPUT ! + final StringBuilder sb = new StringBuilder(); + if( indexPathInSSP > 0 ) { + sb.append( sspTemp.substring(0, indexPathInSSP) ); + } + sb.append( pathTemp ).append( sspTemp.substring( indexPathInSSP + pathTempOldLen ) ); + sspTemp = sb.toString(); // update + + sb.setLength(0); + if( indexPath > 0 ) { + sb.append( inputTemp.substring(0, indexPath) ); + } + sb.append( pathTemp ).append( inputTemp.substring( indexPath + pathTempOldLen ) ); + inputTemp = sb.toString(); // update + } + if( DEBUG_SHOWFIX ) { + System.err.println("Uri FIX_FILEPATH: result : "+pathTemp); + System.err.println("Uri FIX_FILEPATH: ssp after : "+sspTemp); + System.err.println("Uri FIX_FILEPATH: input after : "+inputTemp); + } + } else { + fail(input, "invalid path", indexPath+pathErrIdx); + } + } + path = new Encoded( pathTemp ); + } else { + // Uri is not hierarchical, Uri is opaque + opaque = true; + query = null; + path = null; + authority = null; + validateSsp(input, sspTemp, indexSchemeSep + 1); + } + schemeSpecificPart = new Encoded( sspTemp ); + this.input = inputTemp == input.get() ? input : new Encoded( inputTemp ); + + /** + * determine the host, port and userinfo if the authority parses + * successfully to a server based authority + * + * Behavior in error cases: if forceServer is true, throw + * URISyntaxException with the proper diagnostic messages. if + * forceServer is false assume this is a registry based uri, and just + * return leaving the host, port and userinfo fields undefined. + * + * and there are some error cases where URISyntaxException is thrown + * regardless of the forceServer parameter e.g. malformed ipv6 address + */ + Encoded tempUserinfo = null, tempHost = null; + int tempPort = -1; + boolean authorityComplete; + + if ( null != authority ) { + authorityComplete = true; // set to false later + int hostindex = 0; + + temp = authority.get(); + index = temp.indexOf('@'); + if (index != -1) { + // remove user info + tempUserinfo = new Encoded( temp.substring(0, index) ); + validateUserinfo(authority, tempUserinfo, 0); + temp = temp.substring(index + 1); // host[:port] is left + hostindex = index + 1; + } + + index = temp.lastIndexOf(SCHEME_SEPARATOR); + final int endindex = temp.indexOf(']'); + + if (index != -1 && endindex < index) { + // determine port and host + tempHost = new Encoded( temp.substring(0, index) ); + + if (index < (temp.length() - 1)) { // port part is not empty + try { + tempPort = Integer.parseInt(temp.substring(index + 1)); + if (tempPort < 0) { + if (expectServer) { + fail(authority, "invalid port <"+authority+">", hostindex + index + 1); + } + authorityComplete = false; + } + } catch (final NumberFormatException e) { + if (expectServer) { + fail(authority, "invalid port <"+authority+">, "+e.getMessage(), hostindex + index + 1); + } + authorityComplete = false; + } + } + } else { + tempHost = new Encoded( temp ); + } + + if( authorityComplete ) { + if ( emptyString(tempHost) ) { + if (expectServer) { + fail(authority, "empty host <"+authority+">", hostindex); + } + authorityComplete = false; + } else if (!isValidHost(expectServer, tempHost)) { + if (expectServer) { + fail(authority, "invalid host <"+tempHost+">", hostindex); + } + authorityComplete = false; + } + } + } else { + authorityComplete = false; + } + + if( authorityComplete ) { + // this is a server based uri, + // fill in the userinfo, host and port fields + userInfo = tempUserinfo; + host = tempHost; + port = tempPort; + hasAuthority = true; + } else { + userInfo = null; + host = null; + port = -1; + hasAuthority = false; + } + } + + private static void validateScheme(final Encoded uri, final Encoded scheme, final int index) throws URISyntaxException { + // first char needs to be an alpha char + final char ch = scheme.charAt(0); + if ( !((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) ) { + fail(uri, "invalid scheme", index); + } + final int errIdx = validateAlphaNum(scheme.get(), "+-."); + if( 0 <= errIdx ) { + fail(uri, "invalid scheme", index+errIdx); + } + } + + private static void validateSsp(final Encoded uri, final String ssp, final int index) throws URISyntaxException { + final int errIdx = validateEncoded(ssp, SSP_LEGAL); + if( 0 <= errIdx ) { + fail(uri, "invalid scheme-specific-part", index+errIdx); + } + } + + private static void validateAuthority(final Encoded uri, final Encoded authority, final int index) throws URISyntaxException { + final int errIdx = validateEncoded(authority.get(), AUTHORITY_LEGAL); + if( 0 <= errIdx ) { + fail(uri, "invalid authority", index+errIdx); + } + } + + private static void validatePath(final Encoded uri, final String path, final int index) throws URISyntaxException { + final int errIdx = validateEncoded(path, PATH_LEGAL); + if( 0 <= errIdx ) { + fail(uri, "invalid path", index+errIdx); + } + } + + private static void validateQuery(final Encoded uri, final Encoded query, final int index) throws URISyntaxException { + final int errIdx = validateEncoded(query.get(), QUERY_LEGAL); + if( 0 <= errIdx ) { + fail(uri, "invalid query", index+errIdx); + } + } + + private static void validateFragment(final Encoded uri, final Encoded fragment, final int index) throws URISyntaxException { + final int errIdx = validateEncoded(fragment.get(), FRAG_LEGAL); + if( 0 <= errIdx ) { + fail(uri, "invalid fragment", index+errIdx); + } + } + + private static void validateUserinfo(final Encoded uri, final Encoded userinfo, final int index) throws URISyntaxException { + for (int i = 0; i < userinfo.length(); i++) { + final char ch = userinfo.charAt(i); + if (ch == ']' || ch == '[') { + fail(uri, "invalid userinfo", index+i); + } + } + } + + /** + * distinguish between IPv4, IPv6, domain name and validate it based on + * its type + */ + private boolean isValidHost(final boolean expectServer, final Encoded host) throws URISyntaxException { + if (host.charAt(0) == '[') { + // ipv6 address + if (host.charAt(host.length() - 1) != ']') { + fail(input, "invalid host, missing closing ipv6: "+host, 0); + } + if (!isValidIP6Address(host.get())) { + fail(input, "invalid ipv6: "+host, 0); + } + return true; + } + + // '[' and ']' can only be the first char and last char + // of the host name + if (host.indexOf('[') != -1 || host.indexOf(']') != -1) { + fail(input, "invalid host: "+host, 0); + } + + final int index = host.lastIndexOf('.'); + if ( index < 0 || index == host.length() - 1 || + !Character.isDigit(host.charAt(index + 1)) ) + { + // domain name + if (isValidDomainName(host)) { + return true; + } + if (expectServer) { + fail(input, "invalid host, invalid domain-name or ipv4: "+host, 0); + } + return false; + } + + // IPv4 address + if (isValidIPv4Address(host.get())) { + return true; + } + if (expectServer) { + fail(input, "invalid host, invalid ipv4: "+host, 0); + } + return false; + } + + private static boolean isValidDomainName(final Encoded host) { + final String hostS = host.get(); + if( 0 <= validateAlphaNum(hostS, "-.") ) { + return false; + } + String label = null; + final StringTokenizer st = new StringTokenizer(hostS, "."); + while (st.hasMoreTokens()) { + label = st.nextToken(); + if (label.startsWith("-") || label.endsWith("-")) { + return false; + } + } + + if (!label.equals(hostS)) { + final char ch = label.charAt(0); + if (ch >= '0' && ch <= '9') { + return false; + } + } + return true; + } + + private static boolean isValidIPv4Address(final String ipv4Address) { + int index; + int index2; + try { + int num; + index = ipv4Address.indexOf('.'); + num = Integer.parseInt(ipv4Address.substring(0, index)); + if (num < 0 || num > 255) { + return false; + } + index2 = ipv4Address.indexOf('.', index + 1); + num = Integer.parseInt(ipv4Address.substring(index + 1, index2)); + if (num < 0 || num > 255) { + return false; + } + index = ipv4Address.indexOf('.', index2 + 1); + num = Integer.parseInt(ipv4Address.substring(index2 + 1, index)); + if (num < 0 || num > 255) { + return false; + } + num = Integer.parseInt(ipv4Address.substring(index + 1)); + if (num < 0 || num > 255) { + return false; + } + } catch (final Exception e) { + return false; + } + return true; + } + + private static boolean isValidIP6Address(final String ipv6Address) { + final int length = ipv6Address.length(); + boolean doubleColon = false; + int numberOfColons = 0; + int numberOfPeriods = 0; + String word = ""; + char c = 0; + char prevChar = 0; + int offset = 0; // offset for [] ip addresses + + if (length < 2) { + return false; + } + + for (int i = 0; i < length; i++) { + prevChar = c; + c = ipv6Address.charAt(i); + switch (c) { + + // case for an open bracket [x:x:x:...x] + case '[': + if (i != 0) { + return false; // must be first character + } + if (ipv6Address.charAt(length - 1) != ']') { + return false; // must have a close ] + } + if ((ipv6Address.charAt(1) == SCHEME_SEPARATOR) + && (ipv6Address.charAt(2) != SCHEME_SEPARATOR)) { + return false; + } + offset = 1; + if (length < 4) { + return false; + } + break; + + // case for a closed bracket at end of IP [x:x:x:...x] + case ']': + if (i != length - 1) { + return false; // must be last character + } + if (ipv6Address.charAt(0) != '[') { + return false; // must have a open [ + } + break; + + // case for the last 32-bits represented as IPv4 + // x:x:x:x:x:x:d.d.d.d + case '.': + numberOfPeriods++; + if (numberOfPeriods > 3) { + return false; + } + if (!isValidIP4Word(word)) { + return false; + } + if (numberOfColons != 6 && !doubleColon) { + return false; + } + // a special case ::1:2:3:4:5:d.d.d.d allows 7 colons + // with + // an IPv4 ending, otherwise 7 :'s is bad + if (numberOfColons == 7 + && ipv6Address.charAt(0 + offset) != SCHEME_SEPARATOR + && ipv6Address.charAt(1 + offset) != SCHEME_SEPARATOR) { + return false; + } + word = ""; + break; + + case SCHEME_SEPARATOR: + numberOfColons++; + if (numberOfColons > 7) { + return false; + } + if (numberOfPeriods > 0) { + return false; + } + if (prevChar == SCHEME_SEPARATOR) { + if (doubleColon) { + return false; + } + doubleColon = true; + } + word = ""; + break; + + default: + if (word.length() > 3) { + return false; + } + if (!isValidHexChar(c)) { + return false; + } + word += c; + } + } + + // Check if we have an IPv4 ending + if (numberOfPeriods > 0) { + if (numberOfPeriods != 3 || !isValidIP4Word(word)) { + return false; + } + } else { + // If we're at then end and we haven't had 7 colons then there + // is a problem unless we encountered a doubleColon + if (numberOfColons != 7 && !doubleColon) { + return false; + } + + // If we have an empty word at the end, it means we ended in + // either a : or a . + // If we did not end in :: then this is invalid + if (word == "" && ipv6Address.charAt(length - 1 - offset) != SCHEME_SEPARATOR + && ipv6Address.charAt(length - 2 - offset) != SCHEME_SEPARATOR) { + return false; + } + } + + return true; + } + + private static boolean isValidIP4Word(final String word) { + char c; + if (word.length() < 1 || word.length() > 3) { + return false; + } + for (int i = 0; i < word.length(); i++) { + c = word.charAt(i); + if (!(c >= '0' && c <= '9')) { + return false; + } + } + if (Integer.parseInt(word) > 255) { + return false; + } + return true; + } + + /** + * Validate a string by checking if it contains any characters other than: + *
      + *
    1. letters ('a'..'z', 'A'..'Z')
    2. + *
    3. numbers ('0'..'9')
    4. + *
    5. characters in the legal-set parameter
    6. + *
    7. others (unicode characters that are not in + * US-ASCII set, and are not ISO Control or are not ISO Space characters)
    8. + *
    + * + * @param encoded + * {@code java.lang.String} the string to be validated + * @param legal + * {@code java.lang.String} the characters allowed in the String + * s + */ + private static int validateEncoded(final String encoded, final String legal) { + for (int i = 0; i < encoded.length();) { + final char ch = encoded.charAt(i); + if (ch == '%') { + do { + if (i + 2 >= encoded.length()) { + throw new IllegalArgumentException("missing '%' hex-digits at index "+i); + } + final int d1 = Character.digit(encoded.charAt(i + 1), 16); + final int d2 = Character.digit(encoded.charAt(i + 2), 16); + if (d1 == -1 || d2 == -1) { + throw new IllegalArgumentException("invalid hex-digits at index "+i+": "+encoded.substring(i, i + 3)); + } + i += 3; + } while (i < encoded.length() && encoded.charAt(i) == '%'); + continue; + } + if ( !( (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9') || legal.indexOf(ch) > -1 || + (ch > 127 && !Character.isSpaceChar(ch) && !Character.isISOControl(ch)) + ) + ) { + return i; + } + i++; + } + return -1; + } + private static int validateAlphaNum(final String s, final String legal) { + for (int i = 0; i < s.length();) { + final char ch = s.charAt(i); + if ( !( (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9') || legal.indexOf(ch) > -1 + ) + ) { + return i; + } + i++; + } + return -1; + } + + private static boolean isValidHexChar(final char c) { + return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); + } + private static boolean emptyString(final Encoded s) { + return null == s || 0 == s.length(); + } + private static boolean emptyString(final String s) { + return null == s || 0 == s.length(); + } + + private static void fail(final Encoded input, final String reason, final int p) throws URISyntaxException { + throw new URISyntaxException(input.get(), reason, p); + } + private static void failExpecting(final Encoded input, final String expected, final int p) throws URISyntaxException { + fail(input, "Expecting " + expected, p); + } +} \ No newline at end of file diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/net/UriQueryProps.java gluegen2-2.3.2/src/java/com/jogamp/common/net/UriQueryProps.java --- gluegen2-2.2.4/src/java/com/jogamp/common/net/UriQueryProps.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/net/UriQueryProps.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,138 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.common.net; + +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +/** + * Helper class to process URI's query, handled as properties. + *

    + * The order of the URI segments (any properties) are not preserved. + *

    + *
    + *  URI: [scheme:][//authority][path][?query][#fragment]
    + *  w/ authority: [user-info@]host[:port]
    + *  Note: 'path' starts w/ fwd slash
    + * 
    + *

    + * Since 2.3.0 renamed from {@code URIQueryProps} to {@code UriQueryProps}, + * and using {@link Uri} instead of {@link java.net.URI}. + *

    + */ +public class UriQueryProps { + private static final String QMARK = "?"; + private static final char ASSIG = '='; + private static final String EMPTY = ""; + private final String query_separator; + + private final HashMap properties = new HashMap(); + + private UriQueryProps(final char querySeparator) { + query_separator = String.valueOf(querySeparator); + } + + public final Map getProperties() { return properties; } + public final char getQuerySeparator() { return query_separator.charAt(0); } + + public final Uri.Encoded appendQuery(Uri.Encoded baseQuery) { + boolean needsSep = false; + final StringBuilder sb = new StringBuilder(); + if ( null != baseQuery ) { + if( baseQuery.startsWith(QMARK) ) { + baseQuery = baseQuery.substring(1); // cut off '?' + } + sb.append(baseQuery.get()); + if( !baseQuery.endsWith(query_separator) ) { + needsSep = true; + } + } + final Iterator> entries = properties.entrySet().iterator(); + while(entries.hasNext()) { + if(needsSep) { + sb.append(query_separator); + } + final Entry entry = entries.next(); + sb.append(entry.getKey()); + if( EMPTY != entry.getValue() ) { + sb.append(ASSIG).append(entry.getValue()); + } + needsSep = true; + } + return new Uri.Encoded(sb.toString(), Uri.QUERY_LEGAL); + } + + public final Uri appendQuery(final Uri base) throws URISyntaxException { + return base.getNewQuery( appendQuery( base.query ) ); + } + + /** + * + * @param uri + * @param querySeparator should be either ; or &, ; is encouraged due to troubles of escaping &. + * @return + * @throws IllegalArgumentException if querySeparator is illegal, i.e. neither ; nor & + */ + public static final UriQueryProps create(final Uri uri, final char querySeparator) throws IllegalArgumentException { + if( ';' != querySeparator && '&' != querySeparator ) { + throw new IllegalArgumentException("querySeparator is invalid: "+querySeparator); + } + final UriQueryProps data = new UriQueryProps(querySeparator); + final String q = Uri.decode(uri.query); + final int q_l = null != q ? q.length() : -1; + int q_e = -1; + while(q_e < q_l) { + final int q_b = q_e + 1; // next term + q_e = q.indexOf(querySeparator, q_b); + if(0 == q_e) { + // single separator + continue; + } + if(0 > q_e) { + // end + q_e = q_l; + } + // n-part + final String part = q.substring(q_b, q_e); + final int assignment = part.indexOf(ASSIG); + if(0 < assignment) { + // assignment + final String k = part.substring(0, assignment); + final String v = part.substring(assignment+1); + data.properties.put(k, v); + } else { + // property key only + data.properties.put(part, EMPTY); + } + } + return data; + } +} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/net/URIQueryProps.java gluegen2-2.3.2/src/java/com/jogamp/common/net/URIQueryProps.java --- gluegen2-2.2.4/src/java/com/jogamp/common/net/URIQueryProps.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/net/URIQueryProps.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,137 +0,0 @@ -/** - * Copyright 2013 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ -package com.jogamp.common.net; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; - -/** - * Helper class to process URI's query, handled as properties. - *

    - * The order of the URI segments (any properties) are not preserved. - *

    - *
    - *  URI: [scheme:][//authority][path][?query][#fragment]
    - *  w/ authority: [user-info@]host[:port]
    - *  Note: 'path' starts w/ fwd slash
    - * 
    - */ -public class URIQueryProps { - private static final String QMARK = "?"; - private static final char ASSIG = '='; - private static final String EMPTY = ""; - private final String query_separator; - - private final HashMap properties = new HashMap(); - - private URIQueryProps(final char querySeparator) { - query_separator = String.valueOf(querySeparator); - } - - public final Map getProperties() { return properties; } - public final char getQuerySeparator() { return query_separator.charAt(0); } - - public final String appendQuery(String baseQuery) { - boolean needsSep = false; - final StringBuilder sb = new StringBuilder(); - if ( null != baseQuery ) { - if( !baseQuery.startsWith(QMARK) ) { - baseQuery = baseQuery.substring(1); - } - sb.append(baseQuery); - if( !baseQuery.endsWith(query_separator) ) { - needsSep = true; - } - } - final Iterator> entries = properties.entrySet().iterator(); - while(entries.hasNext()) { - if(needsSep) { - sb.append(query_separator); - } - final Entry entry = entries.next(); - sb.append(entry.getKey()); - if( EMPTY != entry.getValue() ) { - sb.append(ASSIG).append(entry.getValue()); - } - needsSep = true; - } - return sb.toString(); - } - - public final URI appendQuery(final URI base) throws URISyntaxException { - return new URI(base.getScheme(), - base.getRawUserInfo(), base.getHost(), base.getPort(), - base.getRawPath(), appendQuery(base.getRawQuery()), base.getRawFragment()); - } - - /** - * - * @param uri - * @param querySeparator should be either ; or &, ; is encouraged due to troubles of escaping &. - * @return - * @throws IllegalArgumentException if querySeparator is illegal, i.e. neither ; nor & - */ - public static final URIQueryProps create(final URI uri, final char querySeparator) throws IllegalArgumentException { - if( ';' != querySeparator && '&' != querySeparator ) { - throw new IllegalArgumentException("querySeparator is invalid: "+querySeparator); - } - final URIQueryProps data = new URIQueryProps(querySeparator); - final String q = uri.getQuery(); - final int q_l = null != q ? q.length() : -1; - int q_e = -1; - while(q_e < q_l) { - final int q_b = q_e + 1; // next term - q_e = q.indexOf(querySeparator, q_b); - if(0 == q_e) { - // single separator - continue; - } - if(0 > q_e) { - // end - q_e = q_l; - } - // n-part - final String part = q.substring(q_b, q_e); - final int assignment = part.indexOf(ASSIG); - if(0 < assignment) { - // assignment - final String k = part.substring(0, assignment); - final String v = part.substring(assignment+1); - data.properties.put(k, v); - } else { - // property key only - data.properties.put(part, EMPTY); - } - } - return data; - } -} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/nio/Buffers.java gluegen2-2.3.2/src/java/com/jogamp/common/nio/Buffers.java --- gluegen2-2.2.4/src/java/com/jogamp/common/nio/Buffers.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/nio/Buffers.java 2015-10-09 04:18:28.000000000 +0000 @@ -39,9 +39,15 @@ */ package com.jogamp.common.nio; -import java.nio.*; - -import jogamp.common.os.PlatformPropsImpl; +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.CharBuffer; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; import com.jogamp.common.util.ValueConv; @@ -445,30 +451,10 @@ if (buf == null) { return true; } - if ( PlatformPropsImpl.JAVA_6 ) { - if (buf instanceof Buffer) { - return ((Buffer) buf).isDirect(); - } else if (buf instanceof PointerBuffer) { - return ((PointerBuffer) buf).isDirect(); - } - } else { - if (buf instanceof ByteBuffer) { - return ((ByteBuffer) buf).isDirect(); - } else if (buf instanceof IntBuffer) { - return ((IntBuffer) buf).isDirect(); - } else if (buf instanceof ShortBuffer) { - return ((ShortBuffer) buf).isDirect(); - } else if (buf instanceof FloatBuffer) { - return ((FloatBuffer) buf).isDirect(); - } else if (buf instanceof DoubleBuffer) { - return ((DoubleBuffer) buf).isDirect(); - } else if (buf instanceof LongBuffer) { - return ((LongBuffer) buf).isDirect(); - } else if (buf instanceof CharBuffer) { - return ((CharBuffer) buf).isDirect(); - } else if (buf instanceof PointerBuffer) { - return ((PointerBuffer) buf).isDirect(); - } + if (buf instanceof Buffer) { + return ((Buffer) buf).isDirect(); + } else if (buf instanceof PointerBuffer) { + return ((PointerBuffer) buf).isDirect(); } throw new IllegalArgumentException("Unexpected buffer type " + buf.getClass().getName()); } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/nio/ByteBufferInputStream.java gluegen2-2.3.2/src/java/com/jogamp/common/nio/ByteBufferInputStream.java --- gluegen2-2.2.4/src/java/com/jogamp/common/nio/ByteBufferInputStream.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/nio/ByteBufferInputStream.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,186 @@ +/** + * Copyright 2014 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.common.nio; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.FileChannel.MapMode; + +/** + * An {@link InputStream} implementation based on an underlying {@link ByteBuffer} + * supporting {@link #markSupported() mark}. + *

    + * May be utilized as well with a {@link MappedByteBuffer memory-mapped} {@link FileChannel#map(MapMode, long, long) FileChannel} + * using a size ≤ {@link Integer#MAX_VALUE}.
    + * This becomes efficient with files ≥ 10 MiB, depending on the platform + * and whether the traditional method uses a {@link BufferedInputStream} supporting {@code mark} incl. it's buffer size.
    + * See test case {@code com.jogamp.common.nio.TestByteBufferInputStream}. + *

    + * @since 2.3.0 + */ +public class ByteBufferInputStream extends InputStream { + private final ByteBuffer buf; + private int mark; + + /** + * Creates a new byte-buffer input stream. + * + * @param buf the underlying byte buffer. + */ + public ByteBufferInputStream(final ByteBuffer buf) { + this.buf = buf; + this.mark = -1; + } + + @Override + public final int available() { + return buf.remaining(); + } + + /** + * This implementation supports {@code mark}. + *

    + * {@inheritDoc} + *

    + */ + @Override + public final boolean markSupported() { + return true; + } + + /** + * This implementation supports {@code mark}. + *

    + * {@inheritDoc} + *

    + * @see #markSupported() + */ + @Override + public final synchronized void mark(final int unused) { + mark = buf.position(); + } + + /** + * This implementation supports {@code mark}. + *

    + * {@inheritDoc} + *

    + * @see #markSupported() + */ + @Override + public final synchronized void reset() throws IOException { + if ( mark == -1 ) { + throw new IOException(); + } + buf.position(mark); + } + + @Override + public final long skip(final long n) throws IOException { + if( 0 > n ) { + return 0; + } + final int s = (int) Math.min( buf.remaining(), n ); + buf.position(buf.position() + s); + return s; + } + + @Override + public final int read() { + if ( ! buf.hasRemaining() ) { + return -1; + } + return buf.get() & 0xFF; + } + + @Override + public final int read(final byte[] b, final int off, final int len) { + if (b == null) { + throw new NullPointerException(); + } else if( off < 0 || + len < 0 || + off > b.length || + off + len > b.length || + off + len < 0 + ) { + throw new IndexOutOfBoundsException("offset "+off+", length "+len+", b.length "+b.length); + } else if ( 0 == len ) { + return 0; + } + final int totalRem = buf.remaining(); + if ( 0 == totalRem ) { + return -1; + } + final int maxLen = Math.min(totalRem, len); + if( buf.hasArray() ) { + System.arraycopy(buf.array(), buf.arrayOffset() + buf.position(), b, off, maxLen); + buf.position( buf.position() + maxLen ); + } else { + buf.get(b, off, maxLen); + } + return maxLen; + } + + // @Override + public final int read(final ByteBuffer b, final int len) { + if (b == null) { + throw new NullPointerException(); + } else if (len < 0 || len > b.remaining()) { + throw new IndexOutOfBoundsException("length "+len+", b "+b); + } else if ( 0 == len ) { + return 0; + } + final int remaining = buf.remaining(); + if ( 0 == remaining ) { + return -1; + } + final int maxLen = Math.min(remaining, len); + if( buf.hasArray() && b.hasArray() ) { + System.arraycopy(buf.array(), buf.arrayOffset() + buf.position(), b.array(), b.arrayOffset() + b.position(), maxLen); + buf.position( buf.position() + maxLen ); + b.position( b.position() + maxLen ); + } else if( maxLen == remaining ) { + b.put(buf); + } else { + final int _limit = buf.limit(); + buf.limit(maxLen); + try { + b.put(buf); + } finally { + buf.limit(_limit); + } + } + return maxLen; + } + + public final ByteBuffer getBuffer() { return buf; } +} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/nio/MappedByteBufferInputStream.java gluegen2-2.3.2/src/java/com/jogamp/common/nio/MappedByteBufferInputStream.java --- gluegen2-2.2.4/src/java/com/jogamp/common/nio/MappedByteBufferInputStream.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/nio/MappedByteBufferInputStream.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,958 @@ +/** + * Copyright 2014 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.common.nio; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.RandomAccessFile; +import java.lang.ref.WeakReference; +import java.lang.reflect.Method; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.FileChannel.MapMode; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import jogamp.common.Debug; + +import com.jogamp.common.os.Platform; + +/** + * An {@link InputStream} implementation based on an underlying {@link FileChannel}'s memory mapped {@link ByteBuffer}, + * {@link #markSupported() supporting} {@link #mark(int) mark} and {@link #reset()}. + *

    + * Implementation allows full memory mapped {@link ByteBuffer} coverage via {@link FileChannel#map(MapMode, long, long) FileChannel} + * beyond its size limitation of {@link Integer#MAX_VALUE} utilizing an array of {@link ByteBuffer} slices.
    + *

    + *

    + * Implementation further allows full random access via {@link #position()} and {@link #position(long)} + * and accessing the memory mapped {@link ByteBuffer} slices directly via {@link #currentSlice()} and {@link #nextSlice()}. + *

    + * @since 2.3.0 + */ +public class MappedByteBufferInputStream extends InputStream { + public static enum CacheMode { + /** + * Keep all previous lazily cached buffer slices alive, useful for hopping readers, + * i.e. random access via {@link MappedByteBufferInputStream#position(long) position(p)} + * or {@link MappedByteBufferInputStream#reset() reset()}. + *

    + * Note that without flushing, the platform may fail memory mapping + * due to virtual address space exhaustion.
    + * In such case an {@link OutOfMemoryError} may be thrown directly, + * or encapsulated as the {@link IOException#getCause() the cause} + * of a thrown {@link IOException}. + *

    + */ + FLUSH_NONE, + /** + * Soft flush the previous lazily cached buffer slice when caching the next buffer slice, + * useful for sequential forward readers, as well as for hopping readers like {@link #FLUSH_NONE} + * in case of relatively short periods between hopping across slices. + *

    + * Implementation clears the buffer slice reference + * while preserving a {@link WeakReference} to allow its resurrection if not yet + * {@link System#gc() garbage collected}. + *

    + */ + FLUSH_PRE_SOFT, + /** + * Hard flush the previous lazily cached buffer slice when caching the next buffer slice, + * useful for sequential forward readers. + *

    + * Besides clearing the buffer slice reference, + * implementation attempts to hard flush the mapped buffer + * using a {@code sun.misc.Cleaner} by reflection. + * In case such method does not exist nor works, implementation falls back to {@link #FLUSH_PRE_SOFT}. + *

    + *

    + * This is the default. + *

    + */ + FLUSH_PRE_HARD + }; + + /** + * File resize interface allowing a file to change its size, + * e.g. via {@link RandomAccessFile#setLength(long)}. + */ + public static interface FileResizeOp { + /** + * @param newSize the new file size + * @throws IOException if file size change is not supported or any other I/O error occurs + */ + void setLength(final long newSize) throws IOException; + } + private static final FileResizeOp NoFileResize = new FileResizeOp() { + @Override + public void setLength(final long newSize) throws IOException { + throw new IOException("file size change not supported"); + } + }; + + /** + * Default slice shift, i.e. 1L << shift, denoting slice size in MiB: + *
      + *
    • {@link Platform#is64Bit() 64bit machines} -> 30 = 1024 MiB
    • + *
    • {@link Platform#is32Bit() 32bit machines} -> 29 = 512 MiB
    • + *
    + *

    + * In case the default is too much of-used up address-space, one may choose other values: + *

      + *
    • 29 -> 512 MiB
    • + *
    • 28 -> 256 MiB
    • + *
    • 27 -> 128 MiB
    • + *
    • 26 -> 64 MiB
    • + *
    + *

    + */ + public static final int DEFAULT_SLICE_SHIFT; + + static final boolean DEBUG; + + static { + Platform.initSingleton(); + if( Platform.is32Bit() ) { + DEFAULT_SLICE_SHIFT = 29; + } else { + DEFAULT_SLICE_SHIFT = 30; + } + + DEBUG = Debug.debug("ByteBufferInputStream"); + } + + private final int sliceShift; + private final FileChannel fc; + private final FileChannel.MapMode mmode; + private FileResizeOp fileResizeOp = NoFileResize; + + private int sliceCount; + private ByteBuffer[] slices; + private WeakReference[] slices2GC; + private long totalSize; + private int slicesEntries, slices2GCEntries; + private boolean synchronous; + + private int refCount; + + private Method mbbCleaner; + private Method cClean; + private boolean cleanerInit; + private boolean hasCleaner; + private CacheMode cmode; + + private int sliceIdx; + private long mark; + + final void dbgDump(final String prefix, final PrintStream out) { + int _slicesEntries = 0; + for(int i=0; i ref = slices2GC[i]; + if( null != ref ) { + _slices2GCEntries++; + if( null != ref.get() ) { + _slices2GCAliveEntries++; + } + } + } + long fcSz = 0, pos = 0, rem = 0; + try { + fcSz = fc.size(); + } catch (final IOException e) { + e.printStackTrace(); + } + if( 0 < refCount ) { + try { + pos = position(); + rem = totalSize - pos; + } catch (final IOException e) { + e.printStackTrace(); + } + } + final int sliceCount2 = null != slices ? slices.length : 0; + out.println(prefix+" refCount "+refCount+", fcSize "+fcSz+", totalSize "+totalSize); + out.println(prefix+" position "+pos+", remaining "+rem); + out.println(prefix+" mmode "+mmode+", cmode "+cmode+", fileResizeOp "+fileResizeOp); + out.println(prefix+" slice "+sliceIdx+" / "+sliceCount+" ("+sliceCount2+"), synchronous "+synchronous); + out.println(prefix+" mapped "+slicesEntries+" / "+_slicesEntries); + out.println(prefix+" GC-queue "+slices2GCEntries+" / "+_slices2GCEntries+" (alive "+_slices2GCAliveEntries+")"); + out.println(prefix+" sliceShift "+sliceShift+" -> "+(1L << sliceShift)); + } + + MappedByteBufferInputStream(final FileChannel fc, final FileChannel.MapMode mmode, final CacheMode cmode, + final int sliceShift, final long totalSize, final int currSliceIdx) throws IOException { + this.sliceShift = sliceShift; + this.fc = fc; + this.mmode = mmode; + + if( 0 > totalSize ) { + throw new IllegalArgumentException("Negative size "+totalSize); + } + // trigger notifyLengthChange + this.totalSize = -1; + this.sliceCount = 0; + notifyLengthChange( totalSize ); + + this.refCount = 1; + this.cleanerInit = false; + this.hasCleaner = false; + this.cmode = cmode; + + this.sliceIdx = currSliceIdx; + this.mark = -1; + + currentSlice().position(0); + } + + /** + * Creates a new instance using the given {@link FileChannel}. + *

    + * The {@link ByteBuffer} slices will be mapped lazily at first usage. + *

    + * @param fileChannel the file channel to be mapped lazily. + * @param mmode the map mode, default is {@link FileChannel.MapMode#READ_ONLY}. + * @param cmode the caching mode, default is {@link CacheMode#FLUSH_PRE_HARD}. + * @param sliceShift the pow2 slice size, default is {@link #DEFAULT_SLICE_SHIFT}. + * @throws IOException + */ + public MappedByteBufferInputStream(final FileChannel fileChannel, + final FileChannel.MapMode mmode, + final CacheMode cmode, + final int sliceShift) throws IOException { + this(fileChannel, mmode, cmode, sliceShift, fileChannel.size(), 0); + } + + /** + * Creates a new instance using the given {@link FileChannel}, + * given mapping-mode, given cache-mode and the {@link #DEFAULT_SLICE_SHIFT}. + *

    + * The {@link ByteBuffer} slices will be mapped lazily at first usage. + *

    + * @param fileChannel the file channel to be used. + * @param mmode the map mode, default is {@link FileChannel.MapMode#READ_ONLY}. + * @param cmode the caching mode, default is {@link CacheMode#FLUSH_PRE_HARD}. + * @throws IOException + */ + public MappedByteBufferInputStream(final FileChannel fileChannel, final FileChannel.MapMode mmode, final CacheMode cmode) throws IOException { + this(fileChannel, mmode, cmode, DEFAULT_SLICE_SHIFT); + } + + /** + * Creates a new instance using the given {@link FileChannel}, + * {@link FileChannel.MapMode#READ_ONLY read-only} mapping mode, {@link CacheMode#FLUSH_PRE_HARD} + * and the {@link #DEFAULT_SLICE_SHIFT}. + *

    + * The {@link ByteBuffer} slices will be mapped {@link FileChannel.MapMode#READ_ONLY} lazily at first usage. + *

    + * @param fileChannel the file channel to be used. + * @throws IOException + */ + public MappedByteBufferInputStream(final FileChannel fileChannel) throws IOException { + this(fileChannel, FileChannel.MapMode.READ_ONLY, CacheMode.FLUSH_PRE_HARD, DEFAULT_SLICE_SHIFT); + } + + /** + * Enable or disable synchronous mode. + *

    + * If synchronous mode is enabled, mapped buffers will be {@link #flush(boolean) flushed} + * if {@link #notifyLengthChange(long) resized}, written to or {@link #close() closing} in {@link FileChannel.MapMode#READ_WRITE read-write} mapping mode. + *

    + *

    + * If synchronous mode is enabled, {@link FileChannel#force(boolean)} is issued + * if {@link #setLength(long) resizing} or {@link #close() closing} and not in {@link FileChannel.MapMode#READ_ONLY read-only} mapping mode. + *

    + * @param s {@code true} to enable synchronous mode + */ + public final synchronized void setSynchronous(final boolean s) { + synchronous = s; + } + /** + * Return {@link #setSynchronous(boolean) synchronous mode}. + */ + public final synchronized boolean getSynchronous() { + return synchronous ; + } + + final synchronized void checkOpen() throws IOException { + if( 0 == refCount ) { + throw new IOException("stream closed"); + } + } + + @Override + public final synchronized void close() throws IOException { + if( 0 < refCount ) { + refCount--; + if( 0 == refCount ) { + try { + cleanAllSlices( true /* syncBuffer */ ); + } finally { + flushImpl(true /* metaData */, false /* syncBuffer */); + fc.close(); + mark = -1; + sliceIdx = -1; + super.close(); + } + } + } + } + + final FileChannel.MapMode getMapMode() { return mmode; } + + /** + * @param fileResizeOp the new {@link FileResizeOp}. + * @throws IllegalStateException if attempting to set the {@link FileResizeOp} to a different value than before + */ + public final synchronized void setFileResizeOp(final FileResizeOp fileResizeOp) throws IllegalStateException { + if( NoFileResize != this.fileResizeOp && this.fileResizeOp != fileResizeOp ) { + throw new IllegalStateException("FileResizeOp already set, this value differs"); + } + this.fileResizeOp = null != fileResizeOp ? fileResizeOp : NoFileResize; + } + + /** + * Resize the underlying {@link FileChannel}'s size and adjusting this instance + * via {@link #notifyLengthChange(long) accordingly}. + *

    + * User must have a {@link FileResizeOp} {@link #setFileResizeOp(FileResizeOp) registered} before. + *

    + *

    + * Implementation calls {@link #notifyLengthChange(long)} after {@link FileResizeOp#setLength(long)}. + *

    + * @param newTotalSize the new total size + * @throws IOException if no {@link FileResizeOp} has been {@link #setFileResizeOp(FileResizeOp) registered} + * or if a buffer slice operation failed + */ + public final synchronized void setLength(final long newTotalSize) throws IOException { + final long currentPosition; + if( 0 != newTotalSize && totalSize != newTotalSize ) { + currentPosition = position(); + } else { + currentPosition = -1L; + } + if( fc.size() != newTotalSize ) { + if( Platform.OSType.WINDOWS == Platform.getOSType() ) { + // On Windows, we have to close all mapped slices. + // Otherwise we will receive: + // java.io.IOException: The requested operation cannot be performed on a file with a user-mapped section open + // at java.io.RandomAccessFile.setLength(Native Method) + cleanAllSlices( synchronous ); + } + fileResizeOp.setLength(newTotalSize); + if( synchronous ) { + // buffers will be synchronized in notifyLengthChangeImpl(..) + flushImpl( true /* metaData */, false /* syncBuffer */); + } + } + notifyLengthChangeImpl(newTotalSize, currentPosition); + } + + /** + * Notify this instance that the underlying {@link FileChannel}'s size has been changed + * and adjusting this instances buffer slices and states accordingly. + *

    + * Should be called by user API when aware of such event. + *

    + * @param newTotalSize the new total size + * @throws IOException if a buffer slice operation failed + */ + public final synchronized void notifyLengthChange(final long newTotalSize) throws IOException { + notifyLengthChangeImpl(newTotalSize, -1L); + } + private final synchronized void notifyLengthChangeImpl(final long newTotalSize, final long currentPosition) throws IOException { + /* if( DEBUG ) { + System.err.println("notifyLengthChange.0: "+totalSize+" -> "+newTotalSize); + dbgDump("notifyLengthChange.0:", System.err); + } */ + if( totalSize == newTotalSize ) { + // NOP + return; + } else if( 0 == newTotalSize ) { + // ZERO - ensure one entry avoiding NULL checks + cleanAllSlices( synchronous ); + @SuppressWarnings("unchecked") + final WeakReference[] newSlices2GC = new WeakReference[ 1 ]; + slices2GC = newSlices2GC; + slices = new ByteBuffer[1]; + slices[0] = ByteBuffer.allocate(0); + sliceCount = 0; + totalSize = 0; + mark = -1; + sliceIdx = 0; + } else { + final long prePosition = 0 <= currentPosition ? currentPosition : position(); + + final long sliceSize = 1L << sliceShift; + final int newSliceCount = (int)( ( newTotalSize + ( sliceSize - 1 ) ) / sliceSize ); + @SuppressWarnings("unchecked") + final WeakReference[] newSlices2GC = new WeakReference[ newSliceCount ]; + final ByteBuffer[] newSlices = new ByteBuffer[ newSliceCount ]; + final int copySliceCount = Math.min(newSliceCount, sliceCount-1); // drop last (resize) + if( 0 <= copySliceCount ) { + if( 0 < copySliceCount ) { + System.arraycopy(slices2GC, 0, newSlices2GC, 0, copySliceCount); + System.arraycopy(slices, 0, newSlices, 0, copySliceCount); + } + for(int i=copySliceCount; i clipped position (set currSlice and re-map/-pos buffer) + } + /* if( DEBUG ) { + System.err.println("notifyLengthChange.X: "+slices[currSlice]); + dbgDump("notifyLengthChange.X:", System.err); + } */ + } + + /** + * Similar to {@link OutputStream#flush()}, synchronizes all mapped buffers + * from local storage via {@link MappedByteBuffer#force()} + * as well as the {@link FileChannel#force(boolean)} w/o {@code metaData}. + * @param metaData TODO + * @throws IOException if this stream has been {@link #close() closed}. + */ + public final synchronized void flush(final boolean metaData) throws IOException { + checkOpen(); + flushImpl(metaData, true); + } + private final synchronized void flushImpl(final boolean metaData, final boolean syncBuffer) throws IOException { + if( FileChannel.MapMode.READ_ONLY != mmode ) { + if( syncBuffer && FileChannel.MapMode.READ_WRITE == mmode ) { + for(int i=0; i ref = slices2GC[i]; + if( null != ref ) { + syncSlice(ref.get(), true); + } + } + } + fc.force(metaData); + } + } + + + /** + * Returns a new MappedByteBufferOutputStream instance sharing + * all resources of this input stream, including all buffer slices. + * + * @throws IllegalStateException if attempting to set the {@link FileResizeOp} to a different value than before + * @throws IOException if this instance was opened w/ {@link FileChannel.MapMode#READ_ONLY} + * or if this stream has been {@link #close() closed}. + */ + public final synchronized MappedByteBufferOutputStream getOutputStream(final FileResizeOp fileResizeOp) + throws IllegalStateException, IOException + { + checkOpen(); + final MappedByteBufferOutputStream res = new MappedByteBufferOutputStream(this, fileResizeOp); + refCount++; + return res; + } + + /** + * Return the mapped {@link ByteBuffer} slice at the current {@link #position()}. + *

    + * Due to the nature of using sliced buffers mapping the whole region, + * user has to determine whether the returned buffer covers the desired region + * and may fetch the {@link #nextSlice()} until satisfied.
    + * It is also possible to repeat this operation after reposition the stream via {@link #position(long)} + * or {@link #skip(long)} to a position within the next block, similar to {@link #nextSlice()}. + *

    + * @throws IOException if a buffer slice operation failed. + */ + public final synchronized ByteBuffer currentSlice() throws IOException { + final ByteBuffer s0 = slices[sliceIdx]; + if ( null != s0 ) { + return s0; + } else { + if( CacheMode.FLUSH_PRE_SOFT == cmode ) { + final WeakReference ref = slices2GC[sliceIdx]; + if( null != ref ) { + final ByteBuffer mbb = ref.get(); + slices2GC[sliceIdx] = null; + slices2GCEntries--; + if( null != mbb ) { + slices[sliceIdx] = mbb; + slicesEntries++; + return mbb; + } + } + } + final long pos = (long)sliceIdx << sliceShift; + final MappedByteBuffer s1 = fc.map(mmode, pos, Math.min(1L << sliceShift, totalSize - pos)); + slices[sliceIdx] = s1; + slicesEntries++; + return s1; + } + } + + /** + * Return the next mapped {@link ByteBuffer} slice from the current {@link #position()}, + * implicitly setting {@link #position(long)} to the start of the returned next slice, + * see {@link #currentSlice()}. + *

    + * If no subsequent slice is available, {@code null} is being returned. + *

    + * @throws IOException if a buffer slice operation failed. + */ + public final synchronized ByteBuffer nextSlice() throws IOException { + if ( sliceIdx < sliceCount - 1 ) { + flushSlice(sliceIdx, synchronous); + sliceIdx++; + final ByteBuffer slice = currentSlice(); + slice.position( 0 ); + return slice; + } else { + return null; + } + } + + synchronized void syncSlice(final ByteBuffer s) throws IOException { + syncSlice(s, synchronous); + } + synchronized void syncSlice(final ByteBuffer s, final boolean syncBuffer) throws IOException { + if( syncBuffer && null != s && FileChannel.MapMode.READ_WRITE == mmode ) { + try { + ((MappedByteBuffer)s).force(); + } catch( final Throwable t ) { + // On Windows .. this may happen, like: + // java.io.IOException: The process cannot access the file because another process has locked a portion of the file + // at java.nio.MappedByteBuffer.force0(Native Method) + // at java.nio.MappedByteBuffer.force(MappedByteBuffer.java:203) + if( DEBUG ) { + System.err.println("Caught "+t.getMessage()); + t.printStackTrace(); + } + } + } + } + private synchronized void flushSlice(final int i, final boolean syncBuffer) throws IOException { + final ByteBuffer s = slices[i]; + if ( null != s ) { + if( CacheMode.FLUSH_NONE != cmode ) { + slices[i] = null; // trigger slice GC + slicesEntries--; + if( CacheMode.FLUSH_PRE_HARD == cmode ) { + if( !cleanBuffer(s, syncBuffer) ) { + // buffer already synced in cleanBuffer(..) if requested + slices2GC[i] = new WeakReference(s); + slices2GCEntries++; + } + } else { + syncSlice(s, syncBuffer); + slices2GC[i] = new WeakReference(s); + slices2GCEntries++; + } + } else { + syncSlice(s, syncBuffer); + } + } + } + private synchronized void cleanAllSlices(final boolean syncBuffers) throws IOException { + if( null != slices ) { + for(int i=0; i ref = slices2GC[i]; + slices2GC[i] = null; + if( null != ref ) { + slices2GCEntries--; + s2 = ref.get(); + } else { + s2 = null; + } + } + if( null != s1 ) { + slices[i] = null; + slicesEntries--; + cleanBuffer(s1, syncBuffer); + if( null != s2 ) { + throw new InternalError("XXX"); + } + } else if( null != s2 ) { + cleanBuffer(s2, syncBuffer); + } + } + private synchronized boolean cleanBuffer(final ByteBuffer mbb, final boolean syncBuffer) throws IOException { + if( !cleanerInit ) { + initCleaner(mbb); + } + syncSlice(mbb, syncBuffer); + if( !mbb.isDirect() ) { + return false; + } + boolean res = false; + if ( hasCleaner ) { + try { + cClean.invoke(mbbCleaner.invoke(mbb)); + res = true; + } catch(final Throwable t) { + hasCleaner = false; + if( DEBUG ) { + System.err.println("Caught "+t.getMessage()); + t.printStackTrace(); + } + } + } + if( !res && CacheMode.FLUSH_PRE_HARD == cmode ) { + cmode = CacheMode.FLUSH_PRE_SOFT; + } + return res; + } + private synchronized void initCleaner(final ByteBuffer bb) { + final Method[] _mbbCleaner = { null }; + final Method[] _cClean = { null }; + AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Object run() { + try { + _mbbCleaner[0] = bb.getClass().getMethod("cleaner"); + _mbbCleaner[0].setAccessible(true); + _cClean[0] = Class.forName("sun.misc.Cleaner").getMethod("clean"); + _cClean[0].setAccessible(true); + } catch(final Throwable t) { + if( DEBUG ) { + System.err.println("Caught "+t.getMessage()); + t.printStackTrace(); + } + } + return null; + } } ); + mbbCleaner = _mbbCleaner[0]; + cClean = _cClean[0]; + final boolean res = null != mbbCleaner && null != cClean; + if( DEBUG ) { + System.err.println("initCleaner: Has cleaner: "+res+", mbbCleaner "+mbbCleaner+", cClean "+cClean); + } + hasCleaner = res; + cleanerInit = true; + } + + /** + * Return the used {@link CacheMode}. + *

    + * If a desired {@link CacheMode} is not available, it may fall back to an available one at runtime, + * see {@link CacheMode#FLUSH_PRE_HARD}.
    + * This evaluation only happens if the {@link CacheMode} != {@link CacheMode#FLUSH_NONE} + * and while attempting to flush an unused buffer slice. + *

    + */ + public final synchronized CacheMode getCacheMode() { return cmode; } + + /** + * Returns the total size in bytes of the {@link InputStream} + *
    +     *   0 <= {@link #position()} <= {@link #length()}
    +     * 
    + */ + // @Override + public final synchronized long length() { + return totalSize; + } + + /** + * Returns the number of remaining available bytes of the {@link InputStream}, + * i.e. {@link #length()} - {@link #position()}. + *
    +     *   0 <= {@link #position()} <= {@link #length()}
    +     * 
    + *

    + * In contrast to {@link InputStream}'s {@link #available()} method, + * this method returns the proper return type {@code long}. + *

    + * @throws IOException if a buffer slice operation failed. + */ + public final synchronized long remaining() throws IOException { + return 0 < refCount ? totalSize - position() : 0; + } + + /** + * See {@link #remaining()} for an accurate variant. + *

    + * {@inheritDoc} + *

    + * @throws IOException if a buffer slice operation failed. + */ + @Override + public final synchronized int available() throws IOException { + final long available = remaining(); + return available <= Integer.MAX_VALUE ? (int)available : Integer.MAX_VALUE; + } + + /** + * Returns the absolute position of the {@link InputStream}. + *
    +     *   0 <= {@link #position()} <= {@link #length()}
    +     * 
    + * @throws IOException if a buffer slice operation failed. + */ + // @Override + public final synchronized long position() throws IOException { + if( 0 < refCount ) { + return ( (long)sliceIdx << sliceShift ) + currentSlice().position(); + } else { + return 0; + } + } + + /** + * Sets the absolute position of the {@link InputStream} to {@code newPosition}. + *
    +     *   0 <= {@link #position()} <= {@link #length()}
    +     * 
    + * @param newPosition The new position, which must be non-negative and ≤ {@link #length()}. + * @return this instance + * @throws IOException if a buffer slice operation failed or stream is {@link #close() closed}. + */ + // @Override + public final synchronized MappedByteBufferInputStream position( final long newPosition ) throws IOException { + checkOpen(); + if ( totalSize < newPosition || 0 > newPosition ) { + throw new IllegalArgumentException("new position "+newPosition+" not within [0.."+totalSize+"]"); + } + final int preSlice = sliceIdx; + + if ( totalSize == newPosition ) { + // EOF, pos == maxPos + 1 + sliceIdx = Math.max(0, sliceCount - 1); // handle zero size + if( preSlice != sliceIdx ) { + flushSlice(preSlice, synchronous); + } + final ByteBuffer s = currentSlice(); + s.position( s.capacity() ); + } else { + sliceIdx = (int)( newPosition >>> sliceShift ); + if( preSlice != sliceIdx ) { + flushSlice(preSlice, synchronous); + } + currentSlice().position( (int)( newPosition - ( (long)sliceIdx << sliceShift ) ) ); + } + return this; + } + private final synchronized void position2( final long newPosition ) throws IOException { + if ( totalSize == newPosition ) { + // EOF, pos == maxPos + 1 + sliceIdx = Math.max(0, sliceCount - 1); // handle zero size + final ByteBuffer s = currentSlice(); + s.position( s.capacity() ); + } else { + sliceIdx = (int)( newPosition >>> sliceShift ); + currentSlice().position( (int)( newPosition - ( (long)sliceIdx << sliceShift ) ) ); + } + } + + @Override + public final boolean markSupported() { + return true; + } + + /** + * {@inheritDoc} + *

    + * Parameter {@code readLimit} is not used in this implementation, + * since the whole file is memory mapped and no read limitation occurs. + *

    + */ + @Override + public final synchronized void mark( final int readlimit ) { + if( 0 < refCount ) { + try { + mark = position(); + } catch (final IOException e) { + throw new RuntimeException(e); // FIXME: oops + } + } + } + + /** + * {@inheritDoc} + * @throws IOException if this stream has not been marked, + * a buffer slice operation failed or stream has been {@link #close() closed}. + */ + @Override + public final synchronized void reset() throws IOException { + checkOpen(); + if ( mark == -1 ) { + throw new IOException("mark not set"); + } + position( mark ); + } + + /** + * {@inheritDoc} + * @throws IOException if a buffer slice operation failed or stream is {@link #close() closed}. + */ + @Override + public final synchronized long skip( final long n ) throws IOException { + checkOpen(); + if( 0 > n ) { + return 0; + } + final long pos = position(); + final long rem = totalSize - pos; // remaining + final long s = Math.min( rem, n ); + position( pos + s ); + return s; + } + + @Override + public final synchronized int read() throws IOException { + checkOpen(); + ByteBuffer slice = currentSlice(); + if ( !slice.hasRemaining() ) { + if ( null == ( slice = nextSlice() ) ) { + return -1; + } + } + return slice.get() & 0xFF; + } + + @Override + public final synchronized int read( final byte[] b, final int off, final int len ) throws IOException { + checkOpen(); + if (b == null) { + throw new NullPointerException(); + } else if( off < 0 || + len < 0 || + off > b.length || + off + len > b.length || + off + len < 0 + ) { + throw new IndexOutOfBoundsException("offset "+off+", length "+len+", b.length "+b.length); + } else if ( 0 == len ) { + return 0; + } + final long totalRem = remaining(); + if ( 0 == totalRem ) { + return -1; + } + final int maxLen = (int)Math.min( totalRem, len ); + int read = 0; + while( read < maxLen ) { + ByteBuffer slice = currentSlice(); + int currRem = slice.remaining(); + if ( 0 == currRem ) { + if ( null == ( slice = nextSlice() ) ) { + throw new InternalError("Unexpected EOT"); + } + currRem = slice.remaining(); + } + final int currLen = Math.min( maxLen - read, currRem ); + slice.get( b, off + read, currLen ); + read += currLen; + } + return maxLen; + } + + /** + * Perform similar to {@link #read(byte[], int, int)} + * with {@link ByteBuffer} instead of byte array. + * @param b the {@link ByteBuffer} sink, data is written at current {@link ByteBuffer#position()} + * @param len the number of bytes to read + * @return the number of bytes read, -1 for EOS + * @throws IOException if a buffer slice operation failed or stream has been {@link #close() closed}. + */ + // @Override + public final synchronized int read(final ByteBuffer b, final int len) throws IOException { + checkOpen(); + if (b == null) { + throw new NullPointerException(); + } else if (len < 0 || len > b.remaining()) { + throw new IndexOutOfBoundsException("length "+len+", b "+b); + } else if ( 0 == len ) { + return 0; + } + final long totalRem = remaining(); + if ( 0 == totalRem ) { + return -1; + } + final int maxLen = (int)Math.min( totalRem, len ); + int read = 0; + while( read < maxLen ) { + ByteBuffer slice = currentSlice(); + int currRem = slice.remaining(); + if ( 0 == currRem ) { + if ( null == ( slice = nextSlice() ) ) { + throw new InternalError("Unexpected EOT"); + } + currRem = slice.remaining(); + } + final int currLen = Math.min( maxLen - read, currRem ); + if( slice.hasArray() && b.hasArray() ) { + System.arraycopy(slice.array(), slice.arrayOffset() + slice.position(), + b.array(), b.arrayOffset() + b.position(), + currLen); + slice.position( slice.position() + currLen ); + b.position( b.position() + currLen ); + } else if( currLen == currRem ) { + b.put(slice); + } else { + final int _limit = slice.limit(); + slice.limit(currLen); + try { + b.put(slice); + } finally { + slice.limit(_limit); + } + } + read += currLen; + } + return maxLen; + } +} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/nio/MappedByteBufferOutputStream.java gluegen2-2.3.2/src/java/com/jogamp/common/nio/MappedByteBufferOutputStream.java --- gluegen2-2.2.4/src/java/com/jogamp/common/nio/MappedByteBufferOutputStream.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/nio/MappedByteBufferOutputStream.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,351 @@ +/** + * Copyright 2014 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.common.nio; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.FileChannel.MapMode; + +import com.jogamp.common.nio.MappedByteBufferInputStream.CacheMode; +import com.jogamp.common.nio.MappedByteBufferInputStream.FileResizeOp; + +/** + * An {@link OutputStream} implementation based on an underlying {@link FileChannel}'s memory mapped {@link ByteBuffer}. + *

    + * Implementation is based on {@link MappedByteBufferInputStream}, using it as its parent instance. + *

    + *

    + * An instance maybe created via its parent {@link MappedByteBufferInputStream#getOutputStream(FileResizeOp)} + * or directly {@link #MappedByteBufferOutputStream(FileChannel, MapMode, CacheMode, int, FileResizeOp)}. + *

    + * @since 2.3.0 + */ +public class MappedByteBufferOutputStream extends OutputStream { + private final MappedByteBufferInputStream parent; + + MappedByteBufferOutputStream(final MappedByteBufferInputStream parent, + final FileResizeOp fileResizeOp) throws IOException { + if( FileChannel.MapMode.READ_ONLY == parent.getMapMode() ) { + throw new IOException("FileChannel map-mode is read-only"); + } + this.parent = parent; + this.parent.setFileResizeOp(fileResizeOp); + } + + /** + * Creates a new instance using the given {@link FileChannel}. + *

    + * The {@link ByteBuffer} slices will be mapped lazily at first usage. + *

    + * @param fileChannel the file channel to be mapped lazily. + * @param mmode the map mode, default is {@link FileChannel.MapMode#READ_WRITE}. + * @param cmode the caching mode, default is {@link MappedByteBufferInputStream.CacheMode#FLUSH_PRE_SOFT}. + * @param sliceShift the pow2 slice size, default is {@link MappedByteBufferInputStream#DEFAULT_SLICE_SHIFT}. + * @param fileResizeOp {@link MappedByteBufferInputStream.FileResizeOp} as described on {@link MappedByteBufferInputStream#setFileResizeOp(FileResizeOp)}. + * @throws IOException + */ + public MappedByteBufferOutputStream(final FileChannel fileChannel, + final FileChannel.MapMode mmode, + final CacheMode cmode, + final int sliceShift, final FileResizeOp fileResizeOp) throws IOException { + this(new MappedByteBufferInputStream(fileChannel, mmode, cmode, sliceShift, fileChannel.size(), 0), fileResizeOp); + } + + /** + * See {@link MappedByteBufferInputStream#setSynchronous(boolean)}. + */ + public final synchronized void setSynchronous(final boolean s) { + parent.setSynchronous(s); + } + /** + * See {@link MappedByteBufferInputStream#getSynchronous()}. + */ + public final synchronized boolean getSynchronous() { + return parent.getSynchronous(); + } + + /** + * See {@link MappedByteBufferInputStream#setLength(long)}. + */ + public final synchronized void setLength(final long newTotalSize) throws IOException { + parent.setLength(newTotalSize); + } + + /** + * See {@link MappedByteBufferInputStream#notifyLengthChange(long)}. + */ + public final synchronized void notifyLengthChange(final long newTotalSize) throws IOException { + parent.notifyLengthChange(newTotalSize); + } + + /** + * See {@link MappedByteBufferInputStream#length()}. + */ + public final synchronized long length() { + return parent.length(); + } + + /** + * See {@link MappedByteBufferInputStream#remaining()}. + */ + public final synchronized long remaining() throws IOException { + return parent.remaining(); + } + + /** + * See {@link MappedByteBufferInputStream#position()}. + */ + public final synchronized long position() throws IOException { + return parent.position(); + } + + /** + * See {@link MappedByteBufferInputStream#position(long)}. + */ + public final synchronized MappedByteBufferInputStream position( final long newPosition ) throws IOException { + return parent.position(newPosition); + } + + /** + * See {@link MappedByteBufferInputStream#skip(long)}. + */ + public final synchronized long skip( final long n ) throws IOException { + return parent.skip(n); + } + + @Override + public final synchronized void flush() throws IOException { + parent.flush( true /* metaData */); + } + + /** + * See {@link MappedByteBufferInputStream#flush(boolean)}. + */ + // @Override + public final synchronized void flush(final boolean metaData) throws IOException { + parent.flush(metaData); + } + + @Override + public final synchronized void close() throws IOException { + parent.close(); + } + + @Override + public final synchronized void write(final int b) throws IOException { + parent.checkOpen(); + final long totalRem = parent.remaining(); + if ( totalRem < 1 ) { // grow if required + parent.setLength( parent.length() + 1 ); + } + ByteBuffer slice = parent.currentSlice(); + final int currRem = slice.remaining(); + if ( 0 == currRem ) { + if ( null == ( slice = parent.nextSlice() ) ) { + if( MappedByteBufferInputStream.DEBUG ) { + System.err.println("EOT write: "+parent.currentSlice()); + parent.dbgDump("EOT write:", System.err); + } + throw new IOException("EOT"); // 'end-of-tape' + } + } + slice.put( (byte)(b & 0xFF) ); + + // sync last buffer (happens only in synchronous mode) + if( null != slice ) { + parent.syncSlice(slice); + } + } + + @Override + public final synchronized void write(final byte b[], final int off, final int len) throws IOException { + parent.checkOpen(); + if (b == null) { + throw new NullPointerException(); + } else if( off < 0 || + len < 0 || + off > b.length || + off + len > b.length || + off + len < 0 + ) { + throw new IndexOutOfBoundsException("offset "+off+", length "+len+", b.length "+b.length); + } else if( 0 == len ) { + return; + } + final long totalRem = parent.remaining(); + if ( totalRem < len ) { // grow if required + parent.setLength( parent.length() + len - totalRem ); + } + int written = 0; + ByteBuffer slice = null; + while( written < len ) { + slice = parent.currentSlice(); + int currRem = slice.remaining(); + if ( 0 == currRem ) { + if ( null == ( slice = parent.nextSlice() ) ) { + if( MappedByteBufferInputStream.DEBUG ) { + System.err.println("EOT write: offset "+off+", length "+len+", b.length "+b.length); + System.err.println("EOT write: written "+written+" / "+len+", currRem "+currRem); + System.err.println("EOT write: "+parent.currentSlice()); + parent.dbgDump("EOT write:", System.err); + } + throw new InternalError("EOT"); // 'end-of-tape' + } + currRem = slice.remaining(); + } + final int currLen = Math.min( len - written, currRem ); + slice.put( b, off + written, currLen ); + written += currLen; + } + // sync last buffer (happens only in synchronous mode) + if( null != slice ) { + parent.syncSlice(slice); + } + } + + /** + * Perform similar to {@link #write(byte[], int, int)} + * with {@link ByteBuffer} instead of byte array. + * @param b the {@link ByteBuffer} source, data is read from current {@link ByteBuffer#position()} + * @param len the number of bytes to write + * @throws IOException if a buffer slice operation failed or stream has been {@link #close() closed}. + */ + // @Override + public final synchronized void write(final ByteBuffer b, final int len) throws IOException { + parent.checkOpen(); + if (b == null) { + throw new NullPointerException(); + } else if (len < 0 || len > b.remaining()) { + throw new IndexOutOfBoundsException("length "+len+", b "+b); + } else if( 0 == len ) { + return; + } + final long totalRem = parent.remaining(); + if ( totalRem < len ) { // grow if required + parent.setLength( parent.length() + len - totalRem ); + } + int written = 0; + ByteBuffer slice = null; + while( written < len ) { + slice = parent.currentSlice(); + int currRem = slice.remaining(); + if ( 0 == currRem ) { + if ( null == ( slice = parent.nextSlice() ) ) { + if( MappedByteBufferInputStream.DEBUG ) { + System.err.println("EOT write: length "+len+", b "+b); + System.err.println("EOT write: written "+written+" / "+len+", currRem "+currRem); + System.err.println("EOT write: "+parent.currentSlice()); + parent.dbgDump("EOT write:", System.err); + } + throw new InternalError("EOT"); // 'end-of-tape' + } + currRem = slice.remaining(); + } + final int currLen = Math.min( len - written, currRem ); + + if( slice.hasArray() && b.hasArray() ) { + System.arraycopy(b.array(), b.arrayOffset() + b.position(), + slice.array(), slice.arrayOffset() + slice.position(), + currLen); + b.position( b.position() + currLen ); + slice.position( slice.position() + currLen ); + } else if( currLen == currRem ) { + slice.put(b); + } else { + final int _limit = b.limit(); + b.limit(currLen); + try { + slice.put(b); + } finally { + b.limit(_limit); + } + } + written += currLen; + } + // sync last buffer (happens only in synchronous mode) + if( null != slice ) { + parent.syncSlice(slice); + } + } + + /** + * Perform similar to {@link #write(ByteBuffer, int)} + * with {@link MappedByteBufferInputStream} instead of byte array. + *

    + * Method directly copies memory mapped {@link ByteBuffer}'ed data + * from the given input stream to this stream without extra data copy. + *

    + * @param b the {@link ByteBuffer} source, data is read from current {@link MappedByteBufferInputStream#position()} + * @param len the number of bytes to write + * @throws IOException if a buffer slice operation failed or stream has been {@link #close() closed}. + */ + // @Override + public final synchronized void write(final MappedByteBufferInputStream b, final long len) throws IOException { + parent.checkOpen(); + if (b == null) { + throw new NullPointerException(); + } else if (len < 0 || len > b.remaining()) { + throw new IndexOutOfBoundsException("length "+len+", b "+b); + } else if( 0 == len ) { + return; + } + final long totalRem = parent.remaining(); + if ( totalRem < len ) { // grow if required + parent.setLength( parent.length() + len - totalRem ); + } + long written = 0; + ByteBuffer slice = null; + while( written < len ) { + slice = parent.currentSlice(); + int currRem = slice.remaining(); + if ( 0 == currRem ) { + if ( null == ( slice = parent.nextSlice() ) ) { + if( MappedByteBufferInputStream.DEBUG ) { + System.err.println("EOT write: length "+len+", b "+b); + System.err.println("EOT write: written "+written+" / "+len+", currRem "+currRem); + System.err.println("EOT write: "+parent.currentSlice()); + parent.dbgDump("EOT write:", System.err); + } + throw new InternalError("EOT"); // 'end-of-tape' + } + currRem = slice.remaining(); + } + final int currLen = b.read(slice, (int)Math.min( len - written, currRem )); + if( 0 > currLen ) { + throw new InternalError("Unexpected InputStream EOT"); // 'end-of-tape' + } + written += currLen; + } + // sync last buffer (happens only in synchronous mode) + if( null != slice ) { + parent.syncSlice(slice); + } + } +} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/nio/StructAccessor.java gluegen2-2.3.2/src/java/com/jogamp/common/nio/StructAccessor.java --- gluegen2-2.2.4/src/java/com/jogamp/common/nio/StructAccessor.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/nio/StructAccessor.java 2015-10-09 04:18:28.000000000 +0000 @@ -83,6 +83,16 @@ bb.put(byteOffset, v); } + /** Retrieves the boolean at the specified byteOffset. */ + public final boolean getBooleanAt(final int byteOffset) { + return (byte)0 != bb.get(byteOffset); + } + + /** Puts a boolean at the specified byteOffset. */ + public final void setBooleanAt(final int byteOffset, final boolean v) { + bb.put(byteOffset, v?(byte)1:(byte)0); + } + /** Retrieves the char at the specified byteOffset. */ public final char getCharAt(final int byteOffset) { return bb.getChar(byteOffset); @@ -212,6 +222,19 @@ } return v; } + + public final void setBooleansAt(int byteOffset, final boolean[] v) { + for (int i = 0; i < v.length; i++) { + bb.put(byteOffset++, v[i]?(byte)1:(byte)0); + } + } + + public final boolean[] getBooleansAt(int byteOffset, final boolean[] v) { + for (int i = 0; i < v.length; i++) { + v[i] = (byte)0 != bb.get(byteOffset++); + } + return v; + } public final void setCharsAt(int byteOffset, final char[] v) { for (int i = 0; i < v.length; i++, byteOffset+=2) { diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/os/AndroidVersion.java gluegen2-2.3.2/src/java/com/jogamp/common/os/AndroidVersion.java --- gluegen2-2.2.4/src/java/com/jogamp/common/os/AndroidVersion.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/os/AndroidVersion.java 2015-10-09 04:18:28.000000000 +0000 @@ -30,7 +30,6 @@ import java.lang.reflect.Field; import com.jogamp.common.os.Platform.ABIType; -import com.jogamp.common.os.Platform.CPUFamily; import com.jogamp.common.os.Platform.CPUType; import com.jogamp.common.util.IntObjectHashMap; import com.jogamp.common.util.ReflectionUtil; @@ -67,46 +66,6 @@ private static final String androidBuildVersion = "android.os.Build$VERSION"; private static final String androidBuildVersionCodes = "android.os.Build$VERSION_CODES"; - /** - * Returns {@link CPUType} for matching cpuABI, - * i.e. {@link #CPU_ABI} or {@link #CPU_ABI2}, - * or null for no match. - *

    - * FIXME: Where is a comprehensive list of known 'android.os.Build.CPU_ABI' and 'android.os.Build.CPU_ABI2' strings ?
    - * Fount this one: http://www.kandroid.org/ndk/docs/CPU-ARCH-ABIS.html - *

    -     *  lib/armeabi/libfoo.so
    -     *  lib/armeabi-v7a/libfoo.so
    -     *  lib/x86/libfoo.so
    -     *  lib/mips/libfoo.so
    -     * 
    - *

    - */ - private static final CPUType getCPUTypeImpl(final String cpuABI) { - if( null == cpuABI ) { - return null; - } else if( cpuABI.equals("armeabi-v7a") ) { - return CPUType.ARMv7; - } else if( cpuABI.equals("armeabi") || - cpuABI.startsWith("arm") ) { // last chance .. - return CPUType.ARM; - } else if( cpuABI.equals("x86") ) { - return CPUType.X86_32; - } else if( cpuABI.equals("mips") ) { // no 32bit vs 64bit identifier ? - return CPUType.MIPS_32; - } else { - return null; - } - } - private static final ABIType getABITypeImpl(final CPUType cpuType, final String cpuABI) { - if( null == cpuType || null == cpuABI ) { - return null; - } else if( CPUFamily.ARM != cpuType.family ) { - return ABIType.GENERIC_ABI; - } - return ABIType.EABI_GNU_ARMEL; // FIXME: How will they name ABIType.EABI_GNU_ARMHF - } - static { final ClassLoader cl = AndroidVersion.class.getClassLoader(); Class abClass = null; @@ -123,7 +82,7 @@ abvcClass = ReflectionUtil.getClass(androidBuildVersionCodes, true, cl); abvcObject = abvcClass.newInstance(); } catch (final Exception e) { /* n/a */ } - isAvailable = null != abObject && null != abvObject && null != abvcObject; + isAvailable = null != abObject && null != abvObject; if(isAvailable) { CPU_ABI = getString(abClass, abObject, "CPU_ABI", true); CPU_ABI2 = getString(abClass, abObject, "CPU_ABI2", true); @@ -131,9 +90,36 @@ INCREMENTAL = getString(abvClass, abvObject, "INCREMENTAL", false); RELEASE = getString(abvClass, abvObject, "RELEASE", false); SDK_INT = getInt(abvClass, abvObject, "SDK_INT"); - final IntObjectHashMap version_codes = getVersionCodes(abvcClass, abvcObject); - final String sdk_name = (String) version_codes.get(SDK_INT); + final String sdk_name; + if( null != abvcObject ) { + final IntObjectHashMap version_codes = getVersionCodes(abvcClass, abvcObject); + sdk_name = (String) version_codes.get(SDK_INT); + } else { + sdk_name = null; + } SDK_NAME = ( null != sdk_name ) ? sdk_name : "SDK_"+SDK_INT ; + + /** + *

    + * FIXME: Where is a comprehensive list of known 'android.os.Build.CPU_ABI' and 'android.os.Build.CPU_ABI2' strings ?
    + * Fount this one: http://www.kandroid.org/ndk/docs/CPU-ARCH-ABIS.html + *

    +             *  lib/armeabi/libfoo.so
    +             *  lib/armeabi-v7a/libfoo.so
    +             *  lib/x86/libfoo.so
    +             *  lib/mips/libfoo.so
    +             * 
    + *

    + */ + CPU_TYPE = Platform.CPUType.query(CPU_ABI); + ABI_TYPE = Platform.ABIType.query(CPU_TYPE, CPU_ABI); + if( null != CPU_ABI2 && CPU_ABI2.length() > 0 ) { + CPU_TYPE2 = Platform.CPUType.query(CPU_ABI2); + ABI_TYPE2 = Platform.ABIType.query(CPU_TYPE2, CPU_ABI2); + } else { + CPU_TYPE2 = null; + ABI_TYPE2 = null; + } } else { CPU_ABI = null; CPU_ABI2 = null; @@ -142,11 +128,11 @@ RELEASE = null; SDK_INT = -1; SDK_NAME = null; + CPU_TYPE = null; + ABI_TYPE = null; + CPU_TYPE2 = null; + ABI_TYPE2 = null; } - CPU_TYPE = getCPUTypeImpl(CPU_ABI); - ABI_TYPE = getABITypeImpl(CPU_TYPE, CPU_ABI); - CPU_TYPE2 = getCPUTypeImpl(CPU_ABI2); - ABI_TYPE2 = getABITypeImpl(CPU_TYPE2, CPU_ABI2); } private static final IntObjectHashMap getVersionCodes(final Class cls, final Object obj) { diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/os/DynamicLibraryBundle.java gluegen2-2.3.2/src/java/com/jogamp/common/os/DynamicLibraryBundle.java --- gluegen2-2.2.4/src/java/com/jogamp/common/os/DynamicLibraryBundle.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/os/DynamicLibraryBundle.java 2015-10-09 04:18:28.000000000 +0000 @@ -62,6 +62,7 @@ private final DynamicLibraryBundleInfo info; protected final List nativeLibraries; + private final DynamicLinker dynLinkGlobal; private final List> toolLibNames; private final List glueLibNames; private final boolean[] toolLibLoaded; @@ -118,11 +119,15 @@ glueLibLoaded[i] = false; } - info.getLibLoaderExecutor().invoke(true, new Runnable() { - @Override - public void run() { - loadLibraries(); - } } ) ; + { + final DynamicLinker[] _dynLinkGlobal = { null }; + info.getLibLoaderExecutor().invoke(true, new Runnable() { + @Override + public void run() { + _dynLinkGlobal[0] = loadLibraries(); + } } ) ; + dynLinkGlobal = _dynLinkGlobal[0]; + } toolGetProcAddressFuncNameList = info.getToolGetProcAddressFuncNameList(); if( null != toolGetProcAddressFuncNameList ) { @@ -184,7 +189,10 @@ * @see DynamicLibraryBundleInfo#getToolLibNames() */ public final boolean isToolLibComplete() { - return toolGetProcAddressComplete && getToolLibNumber() == getToolLibLoadedNumber(); + final int toolLibNumber = getToolLibNumber(); + return toolGetProcAddressComplete && + ( 0 == toolLibNumber || null != dynLinkGlobal ) && + toolLibNumber == getToolLibLoadedNumber(); } public final boolean isToolLibLoaded() { @@ -226,7 +234,7 @@ public final DynamicLibraryBundleInfo getBundleInfo() { return info; } - protected final long getToolGetProcAddressHandle() { + protected final long getToolGetProcAddressHandle() throws SecurityException { if(!isToolLibLoaded()) { return 0; } @@ -241,7 +249,7 @@ return aptr; } - protected final NativeLibrary loadFirstAvailable(final List libNames, final ClassLoader loader, final boolean global) { + protected static final NativeLibrary loadFirstAvailable(final List libNames, final ClassLoader loader, final boolean global) throws SecurityException { for (int i=0; i < libNames.size(); i++) { final NativeLibrary lib = NativeLibrary.open(libNames.get(i), loader, global); if (lib != null) { @@ -251,11 +259,12 @@ return null; } - final void loadLibraries() { + final DynamicLinker loadLibraries() throws SecurityException { int i; toolLibLoadedNumber = 0; final ClassLoader cl = info.getClass().getClassLoader(); NativeLibrary lib = null; + DynamicLinker dynLinkGlobal = null; for (i=0; i < toolLibNames.size(); i++) { final List libNames = toolLibNames.get(i); @@ -266,6 +275,9 @@ System.err.println("Unable to load any Tool library of: "+libNames); } } else { + if( null == dynLinkGlobal ) { + dynLinkGlobal = lib.getDynamicLinker(); + } nativeLibraries.add(lib); toolLibLoaded[i]=true; toolLibLoadedNumber++; @@ -279,7 +291,7 @@ if(DEBUG) { System.err.println("No Tool libraries loaded"); } - return; + return dynLinkGlobal; } glueLibLoadedNumber = 0; @@ -304,9 +316,16 @@ glueLibLoadedNumber++; } } + + return dynLinkGlobal; } - private final long dynamicLookupFunctionOnLibs(final String funcName) { + /** + * @param funcName + * @return + * @throws SecurityException if user is not granted access for the library set. + */ + private final long dynamicLookupFunctionOnLibs(final String funcName) throws SecurityException { if(!isToolLibLoaded() || null==funcName) { if(DEBUG_LOOKUP && !isToolLibLoaded()) { System.err.println("Lookup-Native: <" + funcName + "> ** FAILED ** Tool native library not loaded"); @@ -318,7 +337,8 @@ if( info.shallLookupGlobal() ) { // Try a global symbol lookup first .. - addr = NativeLibrary.dynamicLookupFunctionGlobal(funcName); + // addr = NativeLibrary.dynamicLookupFunctionGlobal(funcName); + addr = dynLinkGlobal.lookupSymbolGlobal(funcName); } // Look up this function name in all known libraries for (int i=0; 0==addr && i < nativeLibraries.size(); i++) { @@ -341,7 +361,7 @@ final long addr = info.toolGetProcAddress(toolGetProcAddressHandle, funcName); if(DEBUG_LOOKUP) { if(0!=addr) { - System.err.println("Lookup-Tool: <"+funcName+"> 0x"+Long.toHexString(addr)); + System.err.println("Lookup-Tool: <"+funcName+"> 0x"+Long.toHexString(addr)+", via tool 0x"+Long.toHexString(toolGetProcAddressHandle)); } } return addr; @@ -350,7 +370,20 @@ } @Override - public final long dynamicLookupFunction(final String funcName) { + public final void claimAllLinkPermission() throws SecurityException { + for (int i=0; i < nativeLibraries.size(); i++) { + nativeLibraries.get(i).claimAllLinkPermission(); + } + } + @Override + public final void releaseAllLinkPermission() throws SecurityException { + for (int i=0; i < nativeLibraries.size(); i++) { + nativeLibraries.get(i).releaseAllLinkPermission(); + } + } + + @Override + public final long dynamicLookupFunction(final String funcName) throws SecurityException { if(!isToolLibLoaded() || null==funcName) { if(DEBUG_LOOKUP && !isToolLibLoaded()) { System.err.println("Lookup: <" + funcName + "> ** FAILED ** Tool native library not loaded"); @@ -378,7 +411,7 @@ } @Override - public final boolean isFunctionAvailable(final String funcName) { + public final boolean isFunctionAvailable(final String funcName) throws SecurityException { return 0 != dynamicLookupFunction(funcName); } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/os/DynamicLinker.java gluegen2-2.3.2/src/java/com/jogamp/common/os/DynamicLinker.java --- gluegen2-2.2.4/src/java/com/jogamp/common/os/DynamicLinker.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/os/DynamicLinker.java 2015-10-09 04:18:28.000000000 +0000 @@ -34,6 +34,16 @@ public static final boolean DEBUG_LOOKUP = NativeLibrary.DEBUG_LOOKUP; /** + * @throws SecurityException if user is not granted global access + */ + public void claimAllLinkPermission() throws SecurityException; + + /** + * @throws SecurityException if user is not granted global access + */ + public void releaseAllLinkPermission() throws SecurityException; + + /** * If a {@link SecurityManager} is installed, user needs link permissions * for the named library. *

    @@ -80,8 +90,9 @@ * @param symbolName global symbol name to lookup up system wide. * @return the library handle, maybe 0 if not found. * @throws IllegalArgumentException in case case libraryHandle is unknown. + * @throws SecurityException if user is not granted access for the given library handle */ - public long lookupSymbol(long libraryHandle, String symbolName) throws IllegalArgumentException; + public long lookupSymbol(long libraryHandle, String symbolName) throws SecurityException, IllegalArgumentException; /** * Security checks are implicit by previous call of @@ -89,9 +100,11 @@ * retrieving the librarHandle. * * @param libraryHandle a library handle previously retrieved via {@link #openLibraryLocal(String, boolean)} or {@link #openLibraryGlobal(String, boolean)}. + * @param debug set to true to enable debugging * @throws IllegalArgumentException in case case libraryHandle is unknown. + * @throws SecurityException if user is not granted access for the given library handle */ - public void closeLibrary(long libraryHandle) throws IllegalArgumentException; + public void closeLibrary(long libraryHandle, boolean debug) throws SecurityException, IllegalArgumentException; /** * Returns a string containing the last error. diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/os/DynamicLookupHelper.java gluegen2-2.3.2/src/java/com/jogamp/common/os/DynamicLookupHelper.java --- gluegen2-2.2.4/src/java/com/jogamp/common/os/DynamicLookupHelper.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/os/DynamicLookupHelper.java 2015-10-09 04:18:28.000000000 +0000 @@ -51,12 +51,23 @@ public static final boolean DEBUG_LOOKUP = Debug.debug("NativeLibrary.Lookup"); /** + * @throws SecurityException if user is not granted access for the library set. + */ + public void claimAllLinkPermission() throws SecurityException; + /** + * @throws SecurityException if user is not granted access for the library set. + */ + public void releaseAllLinkPermission() throws SecurityException; + + /** * Returns the function handle for function 'funcName'. + * @throws SecurityException if user is not granted access for the library set. */ - public long dynamicLookupFunction(String funcName); + public long dynamicLookupFunction(String funcName) throws SecurityException; /** * Queries whether function 'funcName' is available. + * @throws SecurityException if user is not granted access for the library set. */ - public boolean isFunctionAvailable(String funcName); + public boolean isFunctionAvailable(String funcName) throws SecurityException; } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/os/MachineDataInfo.java gluegen2-2.3.2/src/java/com/jogamp/common/os/MachineDataInfo.java --- gluegen2-2.2.4/src/java/com/jogamp/common/os/MachineDataInfo.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/os/MachineDataInfo.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.common.os; + +import jogamp.common.os.PlatformPropsImpl; + +/** + * Machine data description for alignment and size onle, see {@link com.jogamp.gluegen}. + *

    + * {@code little-endian} / {@code big/endian} description is left, + * allowing re-using instances in {@link MachineDataInfo.StaticConfig StaticConfig}. + * Use {@link {@link PlatformPropsImpl#LITTLE_ENDIAN}. + *

    + *

    + * Further more, the value {@ MachineDataInfo#pageSizeInBytes} shall be ignored + * in {@link MachineDataInfo.StaticConfig StaticConfig}, see {@link MachineDataInfo#compatible(MachineDataInfo)}. + *

    + */ +public class MachineDataInfo { + /* arch os int, long, float, doubl, ldoubl, ptr, page */ + private final static int[] size_arm_mips_32 = { 4, 4, 4, 8, 8, 4, 4096 }; + private final static int[] size_x86_32_unix = { 4, 4, 4, 8, 12, 4, 4096 }; + private final static int[] size_x86_32_macos = { 4, 4, 4, 8, 16, 4, 4096 }; + private final static int[] size_ppc_32_unix = { 4, 4, 4, 8, 16, 4, 4096 }; + private final static int[] size_sparc_32_sunos = { 4, 4, 4, 8, 16, 4, 8192 }; + private final static int[] size_x86_32_windows = { 4, 4, 4, 8, 12, 4, 4096 }; + private final static int[] size_lp64_unix = { 4, 8, 4, 8, 16, 8, 4096 }; + private final static int[] size_x86_64_windows = { 4, 4, 4, 8, 16, 8, 4096 }; + + /* arch os i8, i16, i32, i64, int, long, float, doubl, ldoubl, ptr */ + private final static int[] align_arm_mips_32 = { 1, 2, 4, 8, 4, 4, 4, 8, 8, 4 }; + private final static int[] align_x86_32_unix = { 1, 2, 4, 4, 4, 4, 4, 4, 4, 4 }; + private final static int[] align_x86_32_macos = { 1, 2, 4, 4, 4, 4, 4, 4, 16, 4 }; + private final static int[] align_ppc_32_unix = { 1, 2, 4, 8, 4, 4, 4, 8, 16, 4 }; + private final static int[] align_sparc_32_sunos = { 1, 2, 4, 8, 4, 4, 4, 8, 8, 4 }; + private final static int[] align_x86_32_windows = { 1, 2, 4, 8, 4, 4, 4, 8, 4, 4 }; + private final static int[] align_lp64_unix = { 1, 2, 4, 8, 4, 8, 4, 8, 16, 8 }; + private final static int[] align_x86_64_windows = { 1, 2, 4, 8, 4, 4, 4, 8, 16, 8 }; + + /** + * Static enumeration of {@link MachineDataInfo} instances + * used for high performance data size and alignment lookups, + * e.g. for generated structures. + *

    + * The value {@link MachineDataInfo#pageSizeInBytes} shall be ignored + * for static instances! + *

    + *

    + * If changing this table, you need to: + *

      + *
    • Rebuild GlueGen.
    • + *
    • Run ant {@code build.xml} target {@code generate.os.sources}.
    • + *
    • Rebuild everything.
    • + *
    + * .. b/c the generated code for glued structures must reflect this change! + *

    + */ + public enum StaticConfig { + /** {@link Platform.CPUType#ARM} or {@link Platform.CPUType#MIPS_32} */ + ARM_MIPS_32( size_arm_mips_32, align_arm_mips_32), + /** {@link Platform.CPUType#X86_32} Unix */ + X86_32_UNIX( size_x86_32_unix, align_x86_32_unix), + /** {@link Platform.CPUType#X86_32} MacOS (Special case gcc4/OSX) */ + X86_32_MACOS( size_x86_32_macos, align_x86_32_macos), + /** {@link Platform.CPUType#PPC} Unix */ + PPC_32_UNIX( size_ppc_32_unix, align_ppc_32_unix), + /** {@link Platform.CPUType#SPARC_32} Solaris */ + SPARC_32_SUNOS( size_sparc_32_sunos, align_sparc_32_sunos), + /** {@link Platform.CPUType#X86_32} Windows */ + X86_32_WINDOWS( size_x86_32_windows, align_x86_32_windows), + /** LP64 Unix, e.g.: {@link Platform.CPUType#X86_64} Unix, {@link Platform.CPUType#ARM64} EABI, {@link Platform.CPUType#PPC64} Unix, .. */ + LP64_UNIX( size_lp64_unix, align_lp64_unix), + /** {@link Platform.CPUType#X86_64} Windows */ + X86_64_WINDOWS( size_x86_64_windows, align_x86_64_windows); + // 8 + + public final MachineDataInfo md; + + StaticConfig(final int[] sizes, final int[] alignments) { + int i=0, j=0; + this.md = new MachineDataInfo(false, + sizes[i++], + sizes[i++], + sizes[i++], + sizes[i++], + sizes[i++], + sizes[i++], + sizes[i++], + alignments[j++], + alignments[j++], + alignments[j++], + alignments[j++], + alignments[j++], + alignments[j++], + alignments[j++], + alignments[j++], + alignments[j++], + alignments[j++]); + } + + public final StringBuilder toString(StringBuilder sb) { + if(null==sb) { + sb = new StringBuilder(); + } + sb.append("MachineDataInfoStatic: ").append(this.name()).append("(").append(this.ordinal()).append("): "); + md.toString(sb); + return sb; + } + public final String toShortString() { + return this.name()+"("+this.ordinal()+")"; + } + @Override + public String toString() { + return toString(null).toString(); + } + + /** + * Static's {@link MachineDataInfo} shall be unique by the + * {@link MachineDataInfo#compatible(MachineDataInfo) compatible} criteria. + */ + public static final void validateUniqueMachineDataInfo() { + final StaticConfig[] scs = StaticConfig.values(); + for(int i=scs.length-1; i>=0; i--) { + final StaticConfig a = scs[i]; + for(int j=scs.length-1; j>=0; j--) { + if( i != j ) { + final StaticConfig b = scs[j]; + if( a.md.compatible(b.md) ) { + // oops + final String msg = "Duplicate/Compatible MachineDataInfo in StaticConfigs: Elements ["+i+": "+a.toShortString()+"] and ["+j+": "+b.toShortString()+"]"; + System.err.println(msg); + System.err.println(a); + System.err.println(b); + throw new InternalError(msg); + } + } + } + } + } + public static final StaticConfig findCompatible(final MachineDataInfo md) { + final StaticConfig[] scs = StaticConfig.values(); + for(int i=scs.length-1; i>=0; i--) { + final StaticConfig a = scs[i]; + if( a.md.compatible(md) ) { + return a; + } + } + return null; + } + } + + final private boolean runtimeValidated; + + final private int int8SizeInBytes = 1; + final private int int16SizeInBytes = 2; + final private int int32SizeInBytes = 4; + final private int int64SizeInBytes = 8; + + final private int intSizeInBytes; + final private int longSizeInBytes; + final private int floatSizeInBytes; + final private int doubleSizeInBytes; + final private int ldoubleSizeInBytes; + final private int pointerSizeInBytes; + final private int pageSizeInBytes; + + final private int int8AlignmentInBytes; + final private int int16AlignmentInBytes; + final private int int32AlignmentInBytes; + final private int int64AlignmentInBytes; + final private int intAlignmentInBytes; + final private int longAlignmentInBytes; + final private int floatAlignmentInBytes; + final private int doubleAlignmentInBytes; + final private int ldoubleAlignmentInBytes; + final private int pointerAlignmentInBytes; + + public MachineDataInfo(final boolean runtimeValidated, + + final int intSizeInBytes, + final int longSizeInBytes, + final int floatSizeInBytes, + final int doubleSizeInBytes, + final int ldoubleSizeInBytes, + final int pointerSizeInBytes, + final int pageSizeInBytes, + + final int int8AlignmentInBytes, + final int int16AlignmentInBytes, + final int int32AlignmentInBytes, + final int int64AlignmentInBytes, + final int intAlignmentInBytes, + final int longAlignmentInBytes, + final int floatAlignmentInBytes, + final int doubleAlignmentInBytes, + final int ldoubleAlignmentInBytes, + final int pointerAlignmentInBytes) { + this.runtimeValidated = runtimeValidated; + + this.intSizeInBytes = intSizeInBytes; + this.longSizeInBytes = longSizeInBytes; + this.floatSizeInBytes = floatSizeInBytes; + this.doubleSizeInBytes = doubleSizeInBytes; + this.ldoubleSizeInBytes = ldoubleSizeInBytes; + this.pointerSizeInBytes = pointerSizeInBytes; + this.pageSizeInBytes = pageSizeInBytes; + + this.int8AlignmentInBytes = int8AlignmentInBytes; + this.int16AlignmentInBytes = int16AlignmentInBytes; + this.int32AlignmentInBytes = int32AlignmentInBytes; + this.int64AlignmentInBytes = int64AlignmentInBytes; + this.intAlignmentInBytes = intAlignmentInBytes; + this.longAlignmentInBytes = longAlignmentInBytes; + this.floatAlignmentInBytes = floatAlignmentInBytes; + this.doubleAlignmentInBytes = doubleAlignmentInBytes; + this.ldoubleAlignmentInBytes = ldoubleAlignmentInBytes; + this.pointerAlignmentInBytes = pointerAlignmentInBytes; + } + + /** + * @return true if all values are validated at runtime, otherwise false (i.e. for static compilation w/ preset values) + */ + public final boolean isRuntimeValidated() { + return runtimeValidated; + } + + public final int intSizeInBytes() { return intSizeInBytes; } + public final int longSizeInBytes() { return longSizeInBytes; } + public final int int8SizeInBytes() { return int8SizeInBytes; } + public final int int16SizeInBytes() { return int16SizeInBytes; } + public final int int32SizeInBytes() { return int32SizeInBytes; } + public final int int64SizeInBytes() { return int64SizeInBytes; } + public final int floatSizeInBytes() { return floatSizeInBytes; } + public final int doubleSizeInBytes() { return doubleSizeInBytes; } + public final int ldoubleSizeInBytes() { return ldoubleSizeInBytes; } + public final int pointerSizeInBytes() { return pointerSizeInBytes; } + public final int pageSizeInBytes() { return pageSizeInBytes; } + + public final int intAlignmentInBytes() { return intAlignmentInBytes; } + public final int longAlignmentInBytes() { return longAlignmentInBytes; } + public final int int8AlignmentInBytes() { return int8AlignmentInBytes; } + public final int int16AlignmentInBytes() { return int16AlignmentInBytes; } + public final int int32AlignmentInBytes() { return int32AlignmentInBytes; } + public final int int64AlignmentInBytes() { return int64AlignmentInBytes; } + public final int floatAlignmentInBytes() { return floatAlignmentInBytes; } + public final int doubleAlignmentInBytes() { return doubleAlignmentInBytes; } + public final int ldoubleAlignmentInBytes() { return ldoubleAlignmentInBytes; } + public final int pointerAlignmentInBytes() { return pointerAlignmentInBytes; } + + /** + * @return number of pages required for size in bytes + */ + public int pageCount(final int size) { + return ( size + ( pageSizeInBytes - 1) ) / pageSizeInBytes ; // integer arithmetic + } + + /** + * @return page aligned size in bytes + */ + public int pageAlignedSize(final int size) { + return pageCount(size) * pageSizeInBytes; + } + + /** + * Checks whether two size objects are equal. Two instances + * of MachineDataInfo are considered equal if all components + * match but {@link #runtimeValidated}, {@link #isRuntimeValidated()}. + * @return true if the two MachineDataInfo are equal; + * otherwise false. + */ + @Override + public final boolean equals(final Object obj) { + if (this == obj) { return true; } + if ( !(obj instanceof MachineDataInfo) ) { return false; } + final MachineDataInfo md = (MachineDataInfo) obj; + + return pageSizeInBytes == md.pageSizeInBytes && + compatible(md); + } + + /** + * Checks whether two {@link MachineDataInfo} objects are equal. + *

    + * Two {@link MachineDataInfo} instances are considered equal if all components + * match but {@link #isRuntimeValidated()} and {@link #pageSizeInBytes()}. + *

    + * @return true if the two {@link MachineDataInfo} are equal; + * otherwise false. + */ + public final boolean compatible(final MachineDataInfo md) { + return intSizeInBytes == md.intSizeInBytes && + longSizeInBytes == md.longSizeInBytes && + floatSizeInBytes == md.floatSizeInBytes && + doubleSizeInBytes == md.doubleSizeInBytes && + ldoubleSizeInBytes == md.ldoubleSizeInBytes && + pointerSizeInBytes == md.pointerSizeInBytes && + + int8AlignmentInBytes == md.int8AlignmentInBytes && + int16AlignmentInBytes == md.int16AlignmentInBytes && + int32AlignmentInBytes == md.int32AlignmentInBytes && + int64AlignmentInBytes == md.int64AlignmentInBytes && + intAlignmentInBytes == md.intAlignmentInBytes && + longAlignmentInBytes == md.longAlignmentInBytes && + floatAlignmentInBytes == md.floatAlignmentInBytes && + doubleAlignmentInBytes == md.doubleAlignmentInBytes && + ldoubleAlignmentInBytes == md.ldoubleAlignmentInBytes && + pointerAlignmentInBytes == md.pointerAlignmentInBytes ; + } + + public StringBuilder toString(StringBuilder sb) { + if(null==sb) { + sb = new StringBuilder(); + } + sb.append("MachineDataInfo: runtimeValidated ").append(isRuntimeValidated()).append(", 32Bit ").append(4 == pointerAlignmentInBytes).append(", primitive size / alignment:").append(PlatformPropsImpl.NEWLINE); + sb.append(" int8 ").append(int8SizeInBytes) .append(" / ").append(int8AlignmentInBytes); + sb.append(", int16 ").append(int16SizeInBytes) .append(" / ").append(int16AlignmentInBytes).append(Platform.getNewline()); + sb.append(" int ").append(intSizeInBytes) .append(" / ").append(intAlignmentInBytes); + sb.append(", long ").append(longSizeInBytes) .append(" / ").append(longAlignmentInBytes).append(Platform.getNewline()); + sb.append(" int32 ").append(int32SizeInBytes) .append(" / ").append(int32AlignmentInBytes); + sb.append(", int64 ").append(int64SizeInBytes) .append(" / ").append(int64AlignmentInBytes).append(Platform.getNewline()); + sb.append(" float ").append(floatSizeInBytes) .append(" / ").append(floatAlignmentInBytes); + sb.append(", double ").append(doubleSizeInBytes) .append(" / ").append(doubleAlignmentInBytes); + sb.append(", ldouble ").append(ldoubleSizeInBytes).append(" / ").append(ldoubleAlignmentInBytes).append(Platform.getNewline()); + sb.append(" pointer ").append(pointerSizeInBytes).append(" / ").append(pointerAlignmentInBytes); + sb.append(", page ").append(pageSizeInBytes); + return sb; + } + + @Override + public String toString() { + return toString(null).toString(); + } + +} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/os/MachineDescription.java gluegen2-2.3.2/src/java/com/jogamp/common/os/MachineDescription.java --- gluegen2-2.2.4/src/java/com/jogamp/common/os/MachineDescription.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/os/MachineDescription.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,358 +0,0 @@ -/* - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - * - * Sun gratefully acknowledges that this software was originally authored - * and developed by Kenneth Bradley Russell and Christopher John Kline. - */ - -package com.jogamp.common.os; - -import jogamp.common.os.PlatformPropsImpl; - -/** - * For alignment and size see {@link com.jogamp.gluegen} - */ -public class MachineDescription { - public enum ID { - /** {@link Platform.CPUType#ARM} EABI Little Endian */ - ARMle_EABI(Platform.CPUType.ARM), - /** {@link Platform.CPUType#X86_32} Little Endian Unix */ - X86_32_UNIX(Platform.CPUType.X86_32), - /** {@link Platform.CPUType#X86_64} Little Endian Unix */ - X86_64_UNIX(Platform.CPUType.X86_64), - /** {@link Platform.CPUType#X86_32} Little Endian MacOS (Special case gcc4/OSX) */ - X86_32_MACOS(Platform.CPUType.X86_32), - /** {@link Platform.CPUType#X86_64} Little Endian MacOS */ - X86_32_WINDOWS(Platform.CPUType.X86_32), - /** {@link Platform.CPUType#X86_64} Little Endian Windows */ - X86_64_WINDOWS(Platform.CPUType.X86_64), - /** {@link Platform.CPUType#SPARC_32} Big Endian Solaris */ - SPARC_32_SUNOS(Platform.CPUType.SPARC_32); - - public final Platform.CPUType cpu; - - ID(final Platform.CPUType cpu){ - this.cpu = cpu; - } - } - - /* arch os int, long, float, doubl, ldoubl, ptr, page */ - private final static int[] size_armeabi = { 4, 4, 4, 8, 8, 4, 4096 }; - private final static int[] size_x86_32_unix = { 4, 4, 4, 8, 12, 4, 4096 }; - private final static int[] size_x86_32_macos = { 4, 4, 4, 8, 16, 4, 4096 }; - private final static int[] size_x86_32_windows = { 4, 4, 4, 8, 12, 4, 4096 }; - private final static int[] size_x86_64_unix = { 4, 8, 4, 8, 16, 8, 4096 }; - private final static int[] size_x86_64_windows = { 4, 4, 4, 8, 16, 8, 4096 }; - private final static int[] size_sparc_32_sunos = { 4, 4, 4, 8, 16, 4, 8192 }; - - /* arch os i8, i16, i32, i64, int, long, float, doubl, ldoubl, ptr */ - private final static int[] align_armeabi = { 1, 2, 4, 8, 4, 4, 4, 8, 8, 4 }; - private final static int[] align_x86_32_unix = { 1, 2, 4, 4, 4, 4, 4, 4, 4, 4 }; - private final static int[] align_x86_32_macos = { 1, 2, 4, 4, 4, 4, 4, 4, 16, 4 }; - private final static int[] align_x86_32_windows = { 1, 2, 4, 8, 4, 4, 4, 8, 4, 4 }; - private final static int[] align_x86_64_unix = { 1, 2, 4, 8, 4, 8, 4, 8, 16, 8 }; - private final static int[] align_x86_64_windows = { 1, 2, 4, 8, 4, 4, 4, 8, 16, 8 }; - private final static int[] align_sparc_32_sunos = { 1, 2, 4, 8, 4, 4, 4, 8, 8, 4 }; - - public enum StaticConfig { - /** {@link MachineDescription.ID#ARMle_EABI } */ - ARMle_EABI(ID.ARMle_EABI, true, size_armeabi, align_armeabi), - /** {@link MachineDescription.ID#X86_32_UNIX } */ - X86_32_UNIX(ID.X86_32_UNIX, true, size_x86_32_unix, align_x86_32_unix), - /** {@link MachineDescription.ID#X86_64_UNIX } */ - X86_64_UNIX(ID.X86_64_UNIX, true, size_x86_64_unix, align_x86_64_unix), - /** {@link MachineDescription.ID#X86_32_MACOS } */ - X86_32_MACOS(ID.X86_32_MACOS, true, size_x86_32_macos, align_x86_32_macos), - /** {@link MachineDescription.ID#X86_32_WINDOWS } */ - X86_32_WINDOWS(ID.X86_32_WINDOWS, true, size_x86_32_windows, align_x86_32_windows), - /** {@link MachineDescription.ID#X86_64_WINDOWS } */ - X86_64_WINDOWS(ID.X86_64_WINDOWS, true, size_x86_64_windows, align_x86_64_windows), - /** {@link MachineDescription.ID#SPARC_32_SUNOS } */ - SPARC_32_SUNOS(ID.SPARC_32_SUNOS, false, size_sparc_32_sunos, align_sparc_32_sunos); - - public final ID id; - public final MachineDescription md; - - StaticConfig(final ID id, final boolean littleEndian, final int[] sizes, final int[] alignments) { - this.id = id; - int i=0, j=0; - this.md = new MachineDescription(false, littleEndian, - sizes[i++], - sizes[i++], - sizes[i++], - sizes[i++], - sizes[i++], - sizes[i++], - sizes[i++], - alignments[j++], - alignments[j++], - alignments[j++], - alignments[j++], - alignments[j++], - alignments[j++], - alignments[j++], - alignments[j++], - alignments[j++], - alignments[j++]); - } - - public StringBuilder toString(StringBuilder sb) { - if(null==sb) { - sb = new StringBuilder(); - } - sb.append("MachineDescriptionStatic: ").append(this.name()).append("(").append(this.ordinal()).append("): "); - md.toString(sb); - return sb; - } - - @Override - public String toString() { - return toString(null).toString(); - } - } - - - final private boolean runtimeValidated; - - final private boolean littleEndian; - - final private int int8SizeInBytes = 1; - final private int int16SizeInBytes = 2; - final private int int32SizeInBytes = 4; - final private int int64SizeInBytes = 8; - - final private int intSizeInBytes; - final private int longSizeInBytes; - final private int floatSizeInBytes; - final private int doubleSizeInBytes; - final private int ldoubleSizeInBytes; - final private int pointerSizeInBytes; - final private int pageSizeInBytes; - final private boolean is32Bit; - - final private int int8AlignmentInBytes; - final private int int16AlignmentInBytes; - final private int int32AlignmentInBytes; - final private int int64AlignmentInBytes; - final private int intAlignmentInBytes; - final private int longAlignmentInBytes; - final private int floatAlignmentInBytes; - final private int doubleAlignmentInBytes; - final private int ldoubleAlignmentInBytes; - final private int pointerAlignmentInBytes; - - public MachineDescription(final boolean runtimeValidated, - final boolean littleEndian, - - final int intSizeInBytes, - final int longSizeInBytes, - final int floatSizeInBytes, - final int doubleSizeInBytes, - final int ldoubleSizeInBytes, - final int pointerSizeInBytes, - final int pageSizeInBytes, - - final int int8AlignmentInBytes, - final int int16AlignmentInBytes, - final int int32AlignmentInBytes, - final int int64AlignmentInBytes, - final int intAlignmentInBytes, - final int longAlignmentInBytes, - final int floatAlignmentInBytes, - final int doubleAlignmentInBytes, - final int ldoubleAlignmentInBytes, - final int pointerAlignmentInBytes) { - this.runtimeValidated = runtimeValidated; - this.littleEndian = littleEndian; - - this.intSizeInBytes = intSizeInBytes; - this.longSizeInBytes = longSizeInBytes; - this.floatSizeInBytes = floatSizeInBytes; - this.doubleSizeInBytes = doubleSizeInBytes; - this.ldoubleSizeInBytes = ldoubleSizeInBytes; - this.pointerSizeInBytes = pointerSizeInBytes; - this.pageSizeInBytes = pageSizeInBytes; - this.is32Bit = 4 == pointerSizeInBytes; - - this.int8AlignmentInBytes = int8AlignmentInBytes; - this.int16AlignmentInBytes = int16AlignmentInBytes; - this.int32AlignmentInBytes = int32AlignmentInBytes; - this.int64AlignmentInBytes = int64AlignmentInBytes; - this.intAlignmentInBytes = intAlignmentInBytes; - this.longAlignmentInBytes = longAlignmentInBytes; - this.floatAlignmentInBytes = floatAlignmentInBytes; - this.doubleAlignmentInBytes = doubleAlignmentInBytes; - this.ldoubleAlignmentInBytes = ldoubleAlignmentInBytes; - this.pointerAlignmentInBytes = pointerAlignmentInBytes; - } - - /** - * @return true if all values are validated at runtime, otherwise false (i.e. for static compilation w/ preset values) - */ - public final boolean isRuntimeValidated() { - return runtimeValidated; - } - - /** - * Returns true only if this system uses little endian byte ordering. - */ - public final boolean isLittleEndian() { - return littleEndian; - } - - /** - * Returns true if this JVM/ARCH is 32bit. - */ - public final boolean is32Bit() { - return is32Bit; - } - - /** - * Returns true if this JVM/ARCH is 64bit. - */ - public final boolean is64Bit() { - return !is32Bit; - } - - public final int intSizeInBytes() { return intSizeInBytes; } - public final int longSizeInBytes() { return longSizeInBytes; } - public final int int8SizeInBytes() { return int8SizeInBytes; } - public final int int16SizeInBytes() { return int16SizeInBytes; } - public final int int32SizeInBytes() { return int32SizeInBytes; } - public final int int64SizeInBytes() { return int64SizeInBytes; } - public final int floatSizeInBytes() { return floatSizeInBytes; } - public final int doubleSizeInBytes() { return doubleSizeInBytes; } - public final int ldoubleSizeInBytes() { return ldoubleSizeInBytes; } - public final int pointerSizeInBytes() { return pointerSizeInBytes; } - public final int pageSizeInBytes() { return pageSizeInBytes; } - - public final int intAlignmentInBytes() { return intAlignmentInBytes; } - public final int longAlignmentInBytes() { return longAlignmentInBytes; } - public final int int8AlignmentInBytes() { return int8AlignmentInBytes; } - public final int int16AlignmentInBytes() { return int16AlignmentInBytes; } - public final int int32AlignmentInBytes() { return int32AlignmentInBytes; } - public final int int64AlignmentInBytes() { return int64AlignmentInBytes; } - public final int floatAlignmentInBytes() { return floatAlignmentInBytes; } - public final int doubleAlignmentInBytes() { return doubleAlignmentInBytes; } - public final int ldoubleAlignmentInBytes() { return ldoubleAlignmentInBytes; } - public final int pointerAlignmentInBytes() { return pointerAlignmentInBytes; } - - /** - * @return number of pages required for size in bytes - */ - public int pageCount(final int size) { - return ( size + ( pageSizeInBytes - 1) ) / pageSizeInBytes ; // integer arithmetic - } - - /** - * @return page aligned size in bytes - */ - public int pageAlignedSize(final int size) { - return pageCount(size) * pageSizeInBytes; - } - - /** - * Checks whether two size objects are equal. Two instances - * of MachineDescription are considered equal if all components - * match but {@link #runtimeValidated}, {@link #isRuntimeValidated()}. - * @return true if the two MachineDescription are equal; - * otherwise false. - */ - @Override - public final boolean equals(final Object obj) { - if (this == obj) { return true; } - if ( !(obj instanceof MachineDescription) ) { return false; } - final MachineDescription md = (MachineDescription) obj; - - return pageSizeInBytes == md.pageSizeInBytes && - compatible(md); - } - - /** - * Checks whether two size objects are equal. Two instances - * of MachineDescription are considered equal if all components - * match but {@link #isRuntimeValidated()} and {@link #pageSizeInBytes()}. - * @return true if the two MachineDescription are equal; - * otherwise false. - */ - public final boolean compatible(final MachineDescription md) { - return littleEndian == md.littleEndian && - - intSizeInBytes == md.intSizeInBytes && - longSizeInBytes == md.longSizeInBytes && - floatSizeInBytes == md.floatSizeInBytes && - doubleSizeInBytes == md.doubleSizeInBytes && - ldoubleSizeInBytes == md.ldoubleSizeInBytes && - pointerSizeInBytes == md.pointerSizeInBytes && - is32Bit == md.is32Bit && - - int8AlignmentInBytes == md.int8AlignmentInBytes && - int16AlignmentInBytes == md.int16AlignmentInBytes && - int32AlignmentInBytes == md.int32AlignmentInBytes && - int64AlignmentInBytes == md.int64AlignmentInBytes && - intAlignmentInBytes == md.intAlignmentInBytes && - longAlignmentInBytes == md.longAlignmentInBytes && - floatAlignmentInBytes == md.floatAlignmentInBytes && - doubleAlignmentInBytes == md.doubleAlignmentInBytes && - ldoubleAlignmentInBytes == md.ldoubleAlignmentInBytes && - pointerAlignmentInBytes == md.pointerAlignmentInBytes ; - } - - public StringBuilder toString(StringBuilder sb) { - if(null==sb) { - sb = new StringBuilder(); - } - sb.append("MachineDescription: runtimeValidated ").append(isRuntimeValidated()).append(", littleEndian ").append(isLittleEndian()).append(", 32Bit ").append(is32Bit()).append(", primitive size / alignment:").append(PlatformPropsImpl.NEWLINE); - sb.append(" int8 ").append(int8SizeInBytes) .append(" / ").append(int8AlignmentInBytes); - sb.append(", int16 ").append(int16SizeInBytes) .append(" / ").append(int16AlignmentInBytes).append(Platform.getNewline()); - sb.append(" int ").append(intSizeInBytes) .append(" / ").append(intAlignmentInBytes); - sb.append(", long ").append(longSizeInBytes) .append(" / ").append(longAlignmentInBytes).append(Platform.getNewline()); - sb.append(" int32 ").append(int32SizeInBytes) .append(" / ").append(int32AlignmentInBytes); - sb.append(", int64 ").append(int64SizeInBytes) .append(" / ").append(int64AlignmentInBytes).append(Platform.getNewline()); - sb.append(" float ").append(floatSizeInBytes) .append(" / ").append(floatAlignmentInBytes); - sb.append(", double ").append(doubleSizeInBytes) .append(" / ").append(doubleAlignmentInBytes); - sb.append(", ldouble ").append(ldoubleSizeInBytes).append(" / ").append(ldoubleAlignmentInBytes).append(Platform.getNewline()); - sb.append(" pointer ").append(pointerSizeInBytes).append(" / ").append(pointerAlignmentInBytes); - sb.append(", page ").append(pageSizeInBytes); - return sb; - } - - @Override - public String toString() { - return toString(null).toString(); - } - -} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/os/NativeLibrary.java gluegen2-2.3.2/src/java/com/jogamp/common/os/NativeLibrary.java --- gluegen2-2.2.4/src/java/com/jogamp/common/os/NativeLibrary.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/os/NativeLibrary.java 2015-10-09 04:18:28.000000000 +0000 @@ -50,12 +50,14 @@ import java.util.List; import java.util.StringTokenizer; -import jogamp.common.os.BionicDynamicLinkerImpl; +import jogamp.common.os.BionicDynamicLinker32bitImpl; +import jogamp.common.os.BionicDynamicLinker64BitImpl; import jogamp.common.os.MacOSXDynamicLinkerImpl; import jogamp.common.os.PlatformPropsImpl; import jogamp.common.os.PosixDynamicLinkerImpl; import jogamp.common.os.WindowsDynamicLinkerImpl; +import com.jogamp.common.ExceptionUtils; import com.jogamp.common.util.IOUtil; import com.jogamp.common.util.cache.TempJarCache; @@ -73,45 +75,42 @@ supporting code needed in the generated library. */ public final class NativeLibrary implements DynamicLookupHelper { - private static final DynamicLinker dynLink; private static final String[] prefixes; private static final String[] suffixes; + private static final boolean isOSX; static { // Instantiate dynamic linker implementation switch (PlatformPropsImpl.OS_TYPE) { case WINDOWS: - dynLink = new WindowsDynamicLinkerImpl(); prefixes = new String[] { "" }; suffixes = new String[] { ".dll" }; + isOSX = false; break; case MACOS: - dynLink = new MacOSXDynamicLinkerImpl(); prefixes = new String[] { "lib" }; suffixes = new String[] { ".dylib", ".jnilib" }; - break; - - case ANDROID: - dynLink = new BionicDynamicLinkerImpl(); - prefixes = new String[] { "lib" }; - suffixes = new String[] { ".so" }; + isOSX = true; break; /* + case ANDROID: case FREEBSD: case SUNOS: case HPUX: case OPENKODE: case LINUX: */ default: - dynLink = new PosixDynamicLinkerImpl(); prefixes = new String[] { "lib" }; suffixes = new String[] { ".so" }; + isOSX = false; break; } } + private final DynamicLinker dynLink; + // Platform-specific representation for the handle to the open // library. This is an HMODULE on Windows and a void* (the result of // a dlopen() call) on Unix and Mac OS X platforms. @@ -123,7 +122,8 @@ private final boolean global; // Private constructor to prevent arbitrary instances from floating around - private NativeLibrary(final long libraryHandle, final String libraryPath, final boolean global) { + private NativeLibrary(final DynamicLinker dynLink, final long libraryHandle, final String libraryPath, final boolean global) { + this.dynLink = dynLink; this.libraryHandle = libraryHandle; this.libraryPath = libraryPath; this.global = global; @@ -134,22 +134,26 @@ @Override public final String toString() { - return "NativeLibrary[" + libraryPath + ", 0x" + Long.toHexString(libraryHandle) + ", global " + global + "]"; + return "NativeLibrary[" + dynLink.getClass().getSimpleName() + ", " + libraryPath + ", 0x" + Long.toHexString(libraryHandle) + ", global " + global + "]"; } /** Opens the given native library, assuming it has the same base name on all platforms, looking first in the system's search path, and in the context of the specified ClassLoader, which is - used to help find the library in the case of e.g. Java Web Start. */ - public static final NativeLibrary open(final String libName, final ClassLoader loader) { + used to help find the library in the case of e.g. Java Web Start. + * @throws SecurityException if user is not granted access for the named library. + */ + public static final NativeLibrary open(final String libName, final ClassLoader loader) throws SecurityException { return open(libName, libName, libName, true, loader, true); } /** Opens the given native library, assuming it has the same base name on all platforms, looking first in the system's search path, and in the context of the specified ClassLoader, which is - used to help find the library in the case of e.g. Java Web Start. */ - public static final NativeLibrary open(final String libName, final ClassLoader loader, final boolean global) { + used to help find the library in the case of e.g. Java Web Start. + * @throws SecurityException if user is not granted access for the named library. + */ + public static final NativeLibrary open(final String libName, final ClassLoader loader, final boolean global) throws SecurityException { return open(libName, libName, libName, true, loader, global); } @@ -157,9 +161,11 @@ names (no "lib" prefix or ".dll/.so/.dylib" suffix) on the Windows, Unix and Mac OS X platforms, respectively, and in the context of the specified ClassLoader, which is used to help find - the library in the case of e.g. Java Web Start. The - searchSystemPathFirst argument changes the behavior to first + the library in the case of e.g. Java Web Start. +

    + The {@code searchSystemPathFirst} argument changes the behavior to first search the default system path rather than searching it last. +

    Note that we do not currently handle DSO versioning on Unix. Experience with JOAL and OpenAL has shown that it is extremely problematic to rely on a specific .so version (for one thing, @@ -167,26 +173,55 @@ ending in .so, for example .so.0), and in general if this dynamic loading facility is used correctly the version number will be irrelevant. - */ + * @throws SecurityException if user is not granted access for the named library. + */ public static final NativeLibrary open(final String windowsLibName, final String unixLibName, final String macOSXLibName, final boolean searchSystemPathFirst, - final ClassLoader loader) { + final ClassLoader loader) throws SecurityException { return open(windowsLibName, unixLibName, macOSXLibName, searchSystemPathFirst, loader, true); } + /** + * @throws SecurityException if user is not granted access for the named library. + */ public static final NativeLibrary open(final String windowsLibName, final String unixLibName, final String macOSXLibName, final boolean searchSystemPathFirst, - final ClassLoader loader, final boolean global) { + final ClassLoader loader, + final boolean global) throws SecurityException { final List possiblePaths = enumerateLibraryPaths(windowsLibName, unixLibName, macOSXLibName, searchSystemPathFirst, loader); Platform.initSingleton(); // loads native gluegen-rt library + + final DynamicLinker dynLink; + switch (PlatformPropsImpl.OS_TYPE) { + case WINDOWS: + dynLink = new WindowsDynamicLinkerImpl(); + break; + + case MACOS: + dynLink = new MacOSXDynamicLinkerImpl(); + break; + + case ANDROID: + if( PlatformPropsImpl.CPU_ARCH.is32Bit ) { + dynLink = new BionicDynamicLinker32bitImpl(); + } else { + dynLink = new BionicDynamicLinker64BitImpl(); + } + break; + + default: + dynLink = new PosixDynamicLinkerImpl(); + break; + } + // Iterate down these and see which one if any we can actually find. for (final Iterator iter = possiblePaths.iterator(); iter.hasNext(); ) { final String path = iter.next(); @@ -206,7 +241,7 @@ res = 0; } if ( 0 != res ) { - return new NativeLibrary(res, path, global); + return new NativeLibrary(dynLink, res, path, global); } else if( DEBUG ) { if( null != t ) { System.err.println("NativeLibrary.open: Caught "+t.getClass().getSimpleName()+": "+t.getMessage()); @@ -233,7 +268,16 @@ } @Override - public final long dynamicLookupFunction(final String funcName) { + public final void claimAllLinkPermission() throws SecurityException { + dynLink.claimAllLinkPermission(); + } + @Override + public final void releaseAllLinkPermission() throws SecurityException { + dynLink.releaseAllLinkPermission(); + } + + @Override + public final long dynamicLookupFunction(final String funcName) throws SecurityException { if ( 0 == libraryHandle ) { throw new RuntimeException("Library is not open"); } @@ -241,22 +285,21 @@ } @Override - public final boolean isFunctionAvailable(final String funcName) { + public final boolean isFunctionAvailable(final String funcName) throws SecurityException { if ( 0 == libraryHandle ) { throw new RuntimeException("Library is not open"); } return 0 != dynLink.lookupSymbol(libraryHandle, funcName); } - /** Looks up the given function name in all loaded libraries. */ - public static final long dynamicLookupFunctionGlobal(final String funcName) { + /** Looks up the given function name in all loaded libraries. + * @throws SecurityException if user is not granted access for the named library. + */ + public final long dynamicLookupFunctionGlobal(final String funcName) throws SecurityException { return dynLink.lookupSymbolGlobal(funcName); } - /** Looks up the given function name in all loaded libraries. */ - public static final boolean isFunctionAvailableGlobal(final String funcName) { - return 0 != dynLink.lookupSymbolGlobal(funcName); - } + /* pp */ final DynamicLinker getDynamicLinker() { return dynLink; } /** Retrieves the low-level library handle from this NativeLibrary object. On the Windows platform this is an HMODULE, and on Unix @@ -271,8 +314,10 @@ } /** Closes this native library. Further lookup operations are not - allowed after calling this method. */ - public final void close() { + allowed after calling this method. + * @throws SecurityException if user is not granted access for the named library. + */ + public final void close() throws SecurityException { if (DEBUG) { System.err.println("NativeLibrary.close(): closing " + this); } @@ -281,10 +326,10 @@ } final long handle = libraryHandle; libraryHandle = 0; - dynLink.closeLibrary(handle); + dynLink.closeLibrary(handle, DEBUG); if (DEBUG) { System.err.println("NativeLibrary.close(): Successfully closed " + this); - Thread.dumpStack(); + ExceptionUtils.dumpStack(System.err); } } @@ -325,12 +370,33 @@ /** Given the base library names (no prefixes/suffixes) for the various platforms, enumerate the possible locations and names of - the indicated native library on the system. */ + the indicated native library on the system not using the system path. */ + public static final List enumerateLibraryPaths(final String windowsLibName, + final String unixLibName, + final String macOSXLibName, + final ClassLoader loader) { + return enumerateLibraryPaths(windowsLibName, unixLibName, macOSXLibName, + false /* searchSystemPath */, false /* searchSystemPathFirst */, + loader); + } + /** Given the base library names (no prefixes/suffixes) for the + various platforms, enumerate the possible locations and names of + the indicated native library on the system using the system path. */ public static final List enumerateLibraryPaths(final String windowsLibName, final String unixLibName, final String macOSXLibName, final boolean searchSystemPathFirst, final ClassLoader loader) { + return enumerateLibraryPaths(windowsLibName, unixLibName, macOSXLibName, + true /* searchSystemPath */, searchSystemPathFirst, + loader); + } + private static final List enumerateLibraryPaths(final String windowsLibName, + final String unixLibName, + final String macOSXLibName, + final boolean searchSystemPath, + final boolean searchSystemPathFirst, + final ClassLoader loader) { final List paths = new ArrayList(); final String libName = selectName(windowsLibName, unixLibName, macOSXLibName); if (libName == null) { @@ -346,11 +412,18 @@ final String[] baseNames = buildNames(libName); - if (searchSystemPathFirst) { - // Add just the library names to use the OS's search algorithm - for (int i = 0; i < baseNames.length; i++) { - paths.add(baseNames[i]); - } + if( searchSystemPath && searchSystemPathFirst ) { + // Add just the library names to use the OS's search algorithm + for (int i = 0; i < baseNames.length; i++) { + paths.add(baseNames[i]); + } + // Add probable Mac OS X-specific paths + if ( isOSX ) { + // Add historical location + addPaths("/Library/Frameworks/" + libName + ".Framework", baseNames, paths); + // Add current location + addPaths("/System/Library/Frameworks/" + libName + ".Framework", baseNames, paths); + } } // The idea to ask the ClassLoader to find the library is borrowed @@ -370,24 +443,25 @@ if(null != usrPath) { count++; } - final String sysPath = System.getProperty("sun.boot.library.path"); - if(null != sysPath) { - count++; + final String sysPath; + if( searchSystemPath ) { + sysPath = System.getProperty("sun.boot.library.path"); + if(null != sysPath) { + count++; + } + } else { + sysPath = null; } final String[] res = new String[count]; int i=0; - if (searchSystemPathFirst) { - if(null != sysPath) { - res[i++] = sysPath; - } + if( null != sysPath && searchSystemPathFirst ) { + res[i++] = sysPath; } if(null != usrPath) { res[i++] = usrPath; } - if (!searchSystemPathFirst) { - if(null != sysPath) { - res[i++] = sysPath; - } + if( null != sysPath && !searchSystemPathFirst ) { + res[i++] = sysPath; } return res; } @@ -411,19 +485,22 @@ }); addPaths(userDir, baseNames, paths); - if (!searchSystemPathFirst) { - // Add just the library names to use the OS's search algorithm - for (int i = 0; i < baseNames.length; i++) { - paths.add(baseNames[i]); - } - } - - // Add probable Mac OS X-specific paths - if (PlatformPropsImpl.OS_TYPE == Platform.OSType.MACOS) { - // Add historical location - addPaths("/Library/Frameworks/" + libName + ".Framework", baseNames, paths); - // Add current location - addPaths("/System/Library/Frameworks/" + libName + ".Framework", baseNames, paths); + // Add current working directory + natives/os-arch/ + library names + // to handle Bug 1145 cc1 using an unpacked fat-jar + addPaths(userDir+File.separator+"natives"+File.separator+PlatformPropsImpl.os_and_arch+File.separator, baseNames, paths); + + if( searchSystemPath && !searchSystemPathFirst ) { + // Add just the library names to use the OS's search algorithm + for (int i = 0; i < baseNames.length; i++) { + paths.add(baseNames[i]); + } + // Add probable Mac OS X-specific paths + if ( isOSX ) { + // Add historical location + addPaths("/Library/Frameworks/" + libName + ".Framework", baseNames, paths); + // Add current location + addPaths("/System/Library/Frameworks/" + libName + ".Framework", baseNames, paths); + } } return paths; @@ -440,13 +517,6 @@ case MACOS: return macOSXLibName; - /* - case FREEBSD: - case DALVIK: - case SUNOS: - case HPUX: - case OPENKODE: - case LINUX: */ default: return unixLibName; } @@ -497,15 +567,14 @@ } } - final String[] res = new String[prefixes.length * suffixes.length + - ( PlatformPropsImpl.OS_TYPE == Platform.OSType.MACOS ? 1 : 0 )]; + final String[] res = new String[prefixes.length * suffixes.length + ( isOSX ? 1 : 0 )]; int idx = 0; for (int i = 0; i < prefixes.length; i++) { for (int j = 0; j < suffixes.length; j++) { res[idx++] = prefixes[i] + libName + suffixes[j]; } } - if (PlatformPropsImpl.OS_TYPE == Platform.OSType.MACOS) { + if ( isOSX ) { // Plain library-base-name in Framework folder res[idx++] = libName; } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/os/Platform.java gluegen2-2.3.2/src/java/com/jogamp/common/os/Platform.java --- gluegen2-2.2.4/src/java/com/jogamp/common/os/Platform.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/os/Platform.java 2015-10-09 04:18:28.000000000 +0000 @@ -28,12 +28,12 @@ package com.jogamp.common.os; -import java.net.URI; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.concurrent.TimeUnit; import com.jogamp.common.jvm.JNILibLoaderBase; +import com.jogamp.common.net.Uri; import com.jogamp.common.util.JarUtil; import com.jogamp.common.util.PropertyAccess; import com.jogamp.common.util.ReflectionUtil; @@ -41,7 +41,7 @@ import com.jogamp.common.util.cache.TempJarCache; import jogamp.common.jvm.JVMUtil; -import jogamp.common.os.MachineDescriptionRuntime; +import jogamp.common.os.MachineDataInfoRuntime; import jogamp.common.os.PlatformPropsImpl; /** @@ -50,7 +50,7 @@ * Some field declarations and it's static initialization has been delegated * to it's super class {@link PlatformPropsImpl} to solve * static initialization interdependencies w/ the GlueGen native library loading - * and it's derived information {@link #getMachineDescription()}, {@link #is32Bit()}, ..
    + * and it's derived information {@link #getMachineDataInfo()}, {@link #is32Bit()}, ..
    * This mechanism is preferred in this case to avoid synchronization and locking * and allow better performance accessing the mentioned fields/methods. *

    @@ -58,89 +58,199 @@ public class Platform extends PlatformPropsImpl { public enum OSType { - LINUX(0), FREEBSD(1), ANDROID(2), MACOS(3), SUNOS(4), HPUX(5), WINDOWS(6), OPENKODE(7); - - public final int id; - - OSType(final int id){ - this.id = id; - } + LINUX, FREEBSD, ANDROID, MACOS, SUNOS, HPUX, WINDOWS, OPENKODE; } public enum CPUFamily { /** AMD/Intel */ - X86( 0x00000000), + X86, /** ARM */ - ARM( 0x00010000), + ARM, /** Power PC */ - PPC( 0x00020000), + PPC, /** SPARC */ - SPARC( 0x00030000), + SPARC, /** Mips */ - MIPS( 0x00040000), + MIPS, /** PA RISC */ - PA_RISC(0xFFFF0000), + PA_RISC, /** Itanium */ - IA64( 0xFFFF1000); - - public final int id; - - CPUFamily(final int id){ - this.id = id; - } + IA64, + /** Hitachi SuperH */ + SuperH; } public enum CPUType { - /** X86 32bit */ - X86_32( CPUFamily.X86, 0x0001), - /** X86 64bit */ - X86_64( CPUFamily.X86, 0x0002), - /** ARM default */ - ARM( CPUFamily.ARM, 0x0000), - /** ARM7EJ, ARM9E, ARM10E, XScale */ - ARMv5( CPUFamily.ARM, 0x0001), - /** ARM11 */ - ARMv6( CPUFamily.ARM, 0x0002), - /** ARM Cortex */ - ARMv7( CPUFamily.ARM, 0x0004), - /** PPC default */ - PPC( CPUFamily.PPC, 0x0000), - /** SPARC 32bit */ - SPARC_32( CPUFamily.SPARC, 0x0001), - /** SPARC 64bit */ - SPARCV9_64(CPUFamily.SPARC, 0x0002), - /** MIPS 32bit */ - MIPS_32( CPUFamily.MIPS, 0x0001), - /** MIPS 64bit */ - MIPS_64( CPUFamily.MIPS, 0x0002), - /** Itanium default */ - IA64( CPUFamily.IA64, 0x0000), - /** PA_RISC2_0 */ - PA_RISC2_0(CPUFamily.PA_RISC, 0x0001); + /** ARM 32bit default, usually little endian */ + ARM( CPUFamily.ARM, true), + /** ARM7EJ, ARM9E, ARM10E, XScale, usually little endian */ + ARMv5( CPUFamily.ARM, true), + /** ARM11, usually little endian */ + ARMv6( CPUFamily.ARM, true), + /** ARM Cortex, usually little endian */ + ARMv7( CPUFamily.ARM, true), + // 4 + + /** X86 32bit, little endian */ + X86_32( CPUFamily.X86, true), + /** PPC 32bit default, usually big endian */ + PPC( CPUFamily.PPC, true), + /** MIPS 32bit, big endian (mips) or little endian (mipsel) */ + MIPS_32( CPUFamily.MIPS, true), + /** Hitachi SuperH 32bit default, ??? endian */ + SuperH( CPUFamily.SuperH, true), + /** SPARC 32bit, big endian */ + SPARC_32( CPUFamily.SPARC, true), + // 9 + + /** ARM64 default (64bit), usually little endian */ + ARM64( CPUFamily.ARM, false), + /** ARM AArch64 (64bit), usually little endian */ + ARMv8_A( CPUFamily.ARM, false), + /** X86 64bit, little endian */ + X86_64( CPUFamily.X86, false), + /** PPC 64bit default, usually big endian */ + PPC64( CPUFamily.PPC, false), + /** MIPS 64bit, big endian (mips64) or little endian (mipsel64) ? */ + MIPS_64( CPUFamily.MIPS, false), + /** Itanium 64bit default, little endian */ + IA64( CPUFamily.IA64, false), + /** SPARC 64bit, big endian */ + SPARCV9_64(CPUFamily.SPARC, false), + /** PA_RISC2_0 64bit, ??? endian */ + PA_RISC2_0(CPUFamily.PA_RISC, false); + // 17 - public final int id; public final CPUFamily family; + public final boolean is32Bit; - CPUType(final CPUFamily type, final int id){ + CPUType(final CPUFamily type, final boolean is32Bit){ this.family = type; - this.id = id; + this.is32Bit = is32Bit; + } + + /** + * Returns {@code true} if the given {@link CPUType} is compatible + * w/ this one, i.e. at least {@link #family} and {@link #is32Bit} is equal. + */ + public final boolean isCompatible(final CPUType other) { + if( null == other ) { + return false; + } else if( other == this ) { + return true; + } else { + return this.family == other.family && + this.is32Bit == other.is32Bit; + } } - public CPUFamily getFamily() { return family; } + public static final CPUType query(final String cpuABILower) { + if( null == cpuABILower ) { + throw new IllegalArgumentException("Null cpuABILower arg"); + } + if( cpuABILower.equals("x86") || + cpuABILower.equals("i386") || + cpuABILower.equals("i486") || + cpuABILower.equals("i586") || + cpuABILower.equals("i686") ) { + return X86_32; + } else if( cpuABILower.equals("x86_64") || + cpuABILower.equals("amd64") ) { + return X86_64; + } else if( cpuABILower.equals("ia64") ) { + return IA64; + } else if( cpuABILower.equals("aarch64") ) { + return ARM64; + } else if( cpuABILower.startsWith("arm") ) { + if( cpuABILower.equals("armv8-a") || + cpuABILower.equals("arm-v8-a") || + cpuABILower.equals("arm-8-a") || + cpuABILower.equals("arm64-v8a") ) { + return ARMv8_A; + } else if( cpuABILower.startsWith("arm64") ) { + return ARM64; + } else if( cpuABILower.startsWith("armv7") || + cpuABILower.startsWith("arm-v7") || + cpuABILower.startsWith("arm-7") || + cpuABILower.startsWith("armeabi-v7") ) { + return ARMv7; + } else if( cpuABILower.startsWith("armv5") || + cpuABILower.startsWith("arm-v5") || + cpuABILower.startsWith("arm-5") ) { + return ARMv5; + } else if( cpuABILower.startsWith("armv6") || + cpuABILower.startsWith("arm-v6") || + cpuABILower.startsWith("arm-6") ) { + return ARMv6; + } else { + return ARM; + } + } else if( cpuABILower.equals("sparcv9") ) { + return SPARCV9_64; + } else if( cpuABILower.equals("sparc") ) { + return SPARC_32; + } else if( cpuABILower.equals("pa_risc2.0") ) { + return PA_RISC2_0; + } else if( cpuABILower.startsWith("ppc64") ) { + return PPC64; + } else if( cpuABILower.startsWith("ppc") ) { + return PPC; + } else if( cpuABILower.startsWith("mips64") ) { + return MIPS_64; + } else if( cpuABILower.startsWith("mips") ) { + return MIPS_32; + } else if( cpuABILower.startsWith("superh") ) { + return SuperH; + } else { + throw new RuntimeException("Please port CPUType detection to your platform (CPU_ABI string '" + cpuABILower + "')"); + } + } } public enum ABIType { - GENERIC_ABI ( 0x0000 ), + GENERIC_ABI ( 0x00 ), /** ARM GNU-EABI ARMEL -mfloat-abi=softfp */ - EABI_GNU_ARMEL ( 0x0001 ), + EABI_GNU_ARMEL ( 0x01 ), /** ARM GNU-EABI ARMHF -mfloat-abi=hard */ - EABI_GNU_ARMHF ( 0x0002 ); + EABI_GNU_ARMHF ( 0x02 ), + /** ARM EABI AARCH64 (64bit) */ + EABI_AARCH64 ( 0x03 ); public final int id; ABIType(final int id){ this.id = id; } + + /** + * Returns {@code true} if the given {@link ABIType} is compatible + * w/ this one, i.e. they are equal. + */ + public final boolean isCompatible(final ABIType other) { + if( null == other ) { + return false; + } else { + return other == this; + } + } + + public static final ABIType query(final CPUType cpuType, final String cpuABILower) { + if( null == cpuType ) { + throw new IllegalArgumentException("Null cpuType"); + } else if( null == cpuABILower ) { + throw new IllegalArgumentException("Null cpuABILower"); + } else if( CPUFamily.ARM == cpuType.family ) { + if( !cpuType.is32Bit ) { + return EABI_AARCH64; + } else if( cpuABILower.equals("armeabi-v7a-hard") ) { + return EABI_GNU_ARMHF; + } else { + return EABI_GNU_ARMEL; + } + } else { + return GENERIC_ABI; + } + } } private static final String useTempJarCachePropName = "jogamp.gluegen.UseTempJarCache"; @@ -162,9 +272,7 @@ // post loading native lib: // - private static final MachineDescription machineDescription; - - private static final boolean is32Bit; + private static final MachineDataInfo machineDescription; /** true if AWT is available and not in headless mode, otherwise false. */ public static final boolean AWT_AVAILABLE; @@ -184,11 +292,11 @@ final ClassLoader cl = Platform.class.getClassLoader(); - final URI platformClassJarURI; + final Uri platformClassJarURI; { - URI _platformClassJarURI = null; + Uri _platformClassJarURI = null; try { - _platformClassJarURI = JarUtil.getJarURI(Platform.class.getName(), cl); + _platformClassJarURI = JarUtil.getJarUri(Platform.class.getName(), cl); } catch (final Exception e) { } platformClassJarURI = _platformClassJarURI; } @@ -225,21 +333,11 @@ USE_TEMP_JAR_CACHE = _USE_TEMP_JAR_CACHE[0]; AWT_AVAILABLE = _AWT_AVAILABLE[0]; - MachineDescription md = MachineDescriptionRuntime.getRuntime(); - if(null == md) { - final MachineDescription.StaticConfig smd = MachineDescriptionRuntime.getStatic(); - md = smd.md; - System.err.println("Warning: Using static MachineDescription: "+smd); - } else { - final MachineDescription.StaticConfig smd = MachineDescriptionRuntime.getStatic(); - if(!md.compatible(smd.md)) { - throw new RuntimeException("Incompatible MachineDescriptions:"+PlatformPropsImpl.NEWLINE+ - " Static "+smd+PlatformPropsImpl.NEWLINE+ - " Runtime "+md); - } - } - machineDescription = md; - is32Bit = machineDescription.is32Bit(); + // + // Validate and setup MachineDataInfo.StaticConfig + // + MachineDataInfoRuntime.initialize(); + machineDescription = MachineDataInfoRuntime.getRuntime(); } private Platform() {} @@ -257,26 +355,6 @@ public static void initSingleton() { } /** - * Returns true only if having {@link java.nio.LongBuffer} and {@link java.nio.DoubleBuffer} available. - */ - public static boolean isJavaSE() { - return JAVA_SE; - } - - /** - * Returns true only if being compatible w/ language level 6, e.g. JRE 1.6. - *

    - * Implies {@link #isJavaSE()}. - *

    - *

    - * Note: We claim Android is compatible. - *

    - */ - public static boolean isJava6() { - return JAVA_6; - } - - /** * Returns true if this machine is little endian, otherwise false. */ public static boolean isLittleEndian() { @@ -324,7 +402,7 @@ * Returns the CPU family. */ public static CPUFamily getCPUFamily() { - return CPU_ARCH.getFamily(); + return CPU_ARCH.family; } /** @@ -335,6 +413,22 @@ } /** + * Returns true if this JVM/ARCH is 32bit. + *

    Shortcut to {@link #getCPUType()}.{@link CPUType#is32Bit is32Bit}

    + */ + public static boolean is32Bit() { + return CPU_ARCH.is32Bit; // used very often + } + + /** + * Returns true if this JVM/ARCH is 64bit. + *

    Shortcut to !{@link #getCPUType()}.{@link CPUType#is32Bit is32Bit}

    + */ + public static boolean is64Bit() { + return !CPU_ARCH.is32Bit; // used very often + } + + /** * Returns the ABI type. *

    * In case of {@link CPUFamily#ARM}, the value is determined by parsing the Elf Headers of the running VM. @@ -407,27 +501,9 @@ } /** - * Returns true if this JVM/ARCH is 32bit. - *

    Shortcut to {@link #getMachineDescription()}.{@link MachineDescription#is32Bit() is32Bit()}

    - */ - public static boolean is32Bit() { - // return Platform.machineDescription.is32Bit(); - return Platform.is32Bit; // used very often - } - - /** - * Returns true if this JVM/ARCH is 64bit. - *

    Shortcut to {@link #getMachineDescription()}.{@link MachineDescription#is32Bit() is64Bit()}

    - */ - public static boolean is64Bit() { - // return Platform.machineDescription.is64Bit(); - return !Platform.is32Bit; // used very often - } - - /** - * Returns the MachineDescription of the running machine. + * Returns the MachineDataInfo of the running machine. */ - public static MachineDescription getMachineDescription() { + public static MachineDataInfo getMachineDataInfo() { return machineDescription; } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/ArrayHashMap.java gluegen2-2.3.2/src/java/com/jogamp/common/util/ArrayHashMap.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/ArrayHashMap.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/ArrayHashMap.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,305 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.common.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * {@link HashMap} implementation backed by an {@link ArrayList} to preserve order of values. + * + * Implementation properties are: + *
      + *
    • Unique elements utilizing {@link java.lang.Object#hashCode()} for O(1) operations, see below.
    • + *
    • Java 1.5 compatible
    • + *
    + * + * O(1) operations: + *
      + *
    • put new key-value-pair(s)
    • + *
    • test for containment
    • + *
    • trying to remove non existent elements
    • + *
    + * + * O(n) operations: + *
      + *
    • put existing key-value-pair(s)
    • + *
    • removing existing elements
    • + *
    + * + * For thread safety, the application shall decorate access to instances via + * {@link com.jogamp.common.util.locks.RecursiveLock}. + * +*/ +public class ArrayHashMap + implements Cloneable, Map +{ + /** + * Default load factor: {@value} + */ + public static final float DEFAULT_LOAD_FACTOR = 0.75f; + /** + * The default initial capacity: {@value} + */ + public static final int DEFAULT_INITIAL_CAPACITY = 16; + + private final HashMap map; // key -> object + private final ArrayList data; // list of objects + private final boolean supportNullValue; + + /** + * + * @param supportNullValue Use {@code true} for default behavior, i.e. {@code null} can be a valid value. + * Use {@code false} if {@code null} is not a valid value, + * here {@link #put(Object, Object)} and {@link #remove(Object)} will be optimized. + * @param initialCapacity use {@link #DEFAULT_INITIAL_CAPACITY} for default + * @param loadFactor use {@link #DEFAULT_LOAD_FACTOR} for default + * @see #supportsNullValue() + */ + public ArrayHashMap(final boolean supportNullValue, final int initialCapacity, final float loadFactor) { + this.map = new HashMap(initialCapacity, loadFactor); + this.data = new ArrayList(initialCapacity); + this.supportNullValue = supportNullValue; + } + + /** + * @return a shallow copy of this ArrayHashMap, elements are not copied. + */ + public ArrayHashMap(final ArrayHashMap o) { + map = new HashMap(o.map); + data = new ArrayList(o.data); + supportNullValue = o.supportNullValue; + } + + /** + * Returns {@code true} for default behavior, i.e. {@code null} can be a valid value. + *

    + * Returns {@code false} if {@code null} is not a valid value, + * here {@link #put(Object, Object)} and {@link #remove(Object)} are optimized operations. + *

    + * @see #ArrayHashMap(boolean, int, float) + */ + public final boolean supportsNullValue() { return supportNullValue; } + + // + // Cloneable + // + + /** + * Implementation uses {@link #ArrayHashMap(ArrayHashMap)}. + * @return a shallow copy of this ArrayHashMap, elements are not copied. + */ + @Override + public final Object clone() { + return new ArrayHashMap(this); + } + + /** + * Returns this object ordered ArrayList. Use w/ care, it's not a copy. + * @see #toArrayList() + */ + public final ArrayList getData() { return data; } + + /** + * @return a shallow copy of this ArrayHashMap's ArrayList, elements are not copied. + * @see #getData() + */ + public final ArrayList toArrayList() { + return new ArrayList(data); + } + + /** Returns this object hash map. Use w/ care, it's not a copy. */ + public final HashMap getMap() { return map; } + + @Override + public final String toString() { return data.toString(); } + + // + // Map + // + + @Override + public final void clear() { + data.clear(); + map.clear(); + } + + @Override + public Set keySet() { + return map.keySet(); + } + + /** + * {@inheritDoc} + *

    + * See {@link #getData()} and {@link #toArrayList()}. + *

    + * @see #getData() + * @see #toArrayList() + */ + @Override + public Collection values() { + return map.values(); + } + + @Override + public Set> entrySet() { + return map.entrySet(); + } + + @Override + public final V get(final Object key) { + return map.get(key); + } + + /** + * {@inheritDoc} + *

    + * This is an O(1) operation, in case the key does not exist, + * otherwise O(n). + *

    + * @throws NullPointerException if {@code value} is {@code null} but {@link #supportsNullValue()} == {@code false} + */ + @Override + public final V put(final K key, final V value) throws NullPointerException { + final V oldValue; + if( supportNullValue ) { + // slow path + final boolean exists = map.containsKey(key); + if(!exists) { + // !exists + if( null != ( oldValue = map.put(key, value) ) ) { + // slips a valid null .. + throw new InternalError("Already existing, but checked before: "+key+" -> "+oldValue); + } + } else { + // exists + oldValue = map.put(key, value); + if( !data.remove(oldValue) ) { + throw new InternalError("Already existing, but not in list: "+oldValue); + } + } + } else { + checkNullValue(value); + // fast path + if( null != ( oldValue = map.put(key, value) ) ) { + // exists + if( !data.remove(oldValue) ) { + throw new InternalError("Already existing, but not in list: "+oldValue); + } + } + } + if(!data.add(value)) { + throw new InternalError("Couldn't add value to list: "+value); + } + return oldValue; + } + + @Override + public void putAll(final Map m) { + for (final Iterator> i = m.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry e = i.next(); + put(e.getKey(), e.getValue()); + } + } + + /** + * {@inheritDoc} + *

    + * This is an O(1) operation, in case the key does not exist, + * otherwise O(n). + *

    + */ + @Override + public final V remove(final Object key) { + if( supportNullValue ) { + if( map.containsKey(key) ) { + // exists + final V oldValue = map.remove(key); + if ( !data.remove(oldValue) ) { + throw new InternalError("Couldn't remove prev mapped pair: "+key+" -> "+oldValue); + } + return oldValue; + } + } else { + final V oldValue; + if ( null != (oldValue = map.remove(key) ) ) { + // exists + if ( !data.remove(oldValue) ) { + throw new InternalError("Couldn't remove prev mapped pair: "+key+" -> "+oldValue); + } + } + return oldValue; + } + return null; + } + + @Override + public final boolean containsKey(final Object key) { + return map.containsKey(key); + } + + @Override + public boolean containsValue(final Object value) { + return map.containsValue(value); + } + + @Override + public final boolean equals(final Object arrayHashMap) { + if ( !(arrayHashMap instanceof ArrayHashMap) ) { + return false; + } + return map.equals(((ArrayHashMap)arrayHashMap).map); + } + + @Override + public final int hashCode() { + return map.hashCode(); + } + + @Override + public final boolean isEmpty() { + return data.isEmpty(); + } + + @Override + public final int size() { + return data.size(); + } + + private static final void checkNullValue(final Object value) throws NullPointerException { + if( null == value ) { + throw new NullPointerException("Null value not supported"); + } + } +} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/ArrayHashSet.java gluegen2-2.3.2/src/java/com/jogamp/common/util/ArrayHashSet.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/ArrayHashSet.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/ArrayHashSet.java 2015-10-09 04:18:28.000000000 +0000 @@ -68,24 +68,77 @@ public class ArrayHashSet implements Cloneable, Collection, List { + /** + * Default load factor: {@value} + */ + public static final float DEFAULT_LOAD_FACTOR = 0.75f; + /** + * The default initial capacity: {@value} + */ + public static final int DEFAULT_INITIAL_CAPACITY = 16; + private final HashMap map; // object -> object private final ArrayList data; // list of objects + private final boolean supportNullValue; + /** + * @deprecated Use {@link #ArrayHashSet(boolean, int, float)} + */ public ArrayHashSet() { - map = new HashMap(); - data = new ArrayList(); + this(true, DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR); } + /** + * @param initialCapacity + * @deprecated Use {@link #ArrayHashSet(boolean, int, float)} + */ public ArrayHashSet(final int initialCapacity) { - map = new HashMap(initialCapacity); - data = new ArrayList(initialCapacity); + this(true, initialCapacity, DEFAULT_LOAD_FACTOR); } + /** + * @param initialCapacity + * @param loadFactor + * @deprecated Use {@link #ArrayHashSet(boolean, int, float)} + */ public ArrayHashSet(final int initialCapacity, final float loadFactor) { - map = new HashMap(initialCapacity, loadFactor); - data = new ArrayList(initialCapacity); + this(true, initialCapacity, loadFactor); } + /** + * + * @param supportNullValue Use {@code true} for default behavior, i.e. {@code null} can be a valid value. + * Use {@code false} if {@code null} is not a valid value, + * here {@link #remove(E)} and {@link #getOrAdd(Object)} will be optimized. + * @param initialCapacity use {@link #DEFAULT_INITIAL_CAPACITY} for default + * @param loadFactor use {@link #DEFAULT_LOAD_FACTOR} for default + * @see #supportsNullValue() + */ + public ArrayHashSet(final boolean supportNullValue, final int initialCapacity, final float loadFactor) { + this.map = new HashMap(initialCapacity, loadFactor); + this.data = new ArrayList(initialCapacity); + this.supportNullValue = supportNullValue; + } + + /** + * @return a shallow copy of this ArrayHashSet, elements are not copied. + */ + public ArrayHashSet(final ArrayHashSet o) { + map = new HashMap(o.map); + data = new ArrayList(o.data); + supportNullValue = o.supportNullValue; + } + + /** + * Returns {@code true} for default behavior, i.e. {@code null} can be a valid value. + *

    + * Returns {@code false} if {@code null} is not a valid value, + * here {@link #remove(E)} and {@link #getOrAdd(Object)} are optimized operations. + *

    + * @see #ArrayHashSet(boolean, int, float) + */ + public final boolean supportsNullValue() { return supportNullValue; } + // // Cloneable // @@ -95,12 +148,7 @@ */ @Override public final Object clone() { - final ArrayList clonedList = new ArrayList(data); - - final ArrayHashSet newObj = new ArrayHashSet(); - newObj.addAll(clonedList); - - return newObj; + return new ArrayHashSet(this); } /** Returns this object ordered ArrayList. Use w/ care, it's not a copy. */ @@ -125,40 +173,66 @@ * Add element at the end of this list, if it is not contained yet. *
    * This is an O(1) operation + *

    + * {@inheritDoc} + *

    * * @return true if the element was added to this list, * otherwise false (already contained). + * @throws NullPointerException if {@code element} is {@code null} but {@link #supportsNullValue()} == {@code false} */ @Override - public final boolean add(final E element) { - final boolean exists = map.containsKey(element); - if(!exists) { + public final boolean add(final E element) throws NullPointerException { + if( !supportNullValue ) { + checkNull(element); + } + if( !map.containsKey(element) ) { + // !exists if(null != map.put(element, element)) { + // slips a valid null .. throw new InternalError("Already existing, but checked before: "+element); } if(!data.add(element)) { throw new InternalError("Couldn't add element: "+element); } + return true; } - return !exists; + return false; } /** * Remove element from this list. *
    - * This is an O(1) operation, in case it does not exist, + * This is an O(1) operation, in case the element does not exist, * otherwise O(n). + *

    + * {@inheritDoc} + *

    * * @return true if the element was removed from this list, * otherwise false (not contained). + * @throws NullPointerException if {@code element} is {@code null} but {@link #supportsNullValue()} == {@code false} */ @Override - public final boolean remove(final Object element) { - if ( null != map.remove(element) ) { - if ( ! data.remove(element) ) { - throw new InternalError("Couldn't remove prev mapped element: "+element); + public final boolean remove(final Object element) throws NullPointerException { + if( supportNullValue ) { + if( map.containsKey(element) ) { + // exists + map.remove(element); + if ( !data.remove(element) ) { + throw new InternalError("Couldn't remove prev mapped element: "+element); + } + return true; + } + } else { + checkNull(element); + if ( null != map.remove(element) ) { + // exists + if ( !data.remove(element) ) { + throw new InternalError("Couldn't remove prev mapped element: "+element); + } + return true; } - return true; } return false; } @@ -167,6 +241,9 @@ * Add all elements of given {@link java.util.Collection} at the end of this list. *
    * This is an O(n) operation, over the given Collection size. + *

    + * {@inheritDoc} + *

    * * @return true if at least one element was added to this list, * otherwise false (completely container). @@ -184,6 +261,9 @@ * Test for containment *
    * This is an O(1) operation. + *

    + * {@inheritDoc} + *

    * * @return true if the given element is contained by this list using fast hash map, * otherwise false. @@ -197,6 +277,9 @@ * Test for containment of given {@link java.util.Collection} *
    * This is an O(n) operation, over the given Collection size. + *

    + * {@inheritDoc} + *

    * * @return true if the given Collection is completly contained by this list using hash map, * otherwise false. @@ -215,6 +298,9 @@ * Remove all elements of given {@link java.util.Collection} from this list. *
    * This is an O(n) operation. + *

    + * {@inheritDoc} + *

    * * @return true if at least one element of this list was removed, * otherwise false. @@ -233,6 +319,9 @@ * remove all elements not contained by the given {@link java.util.Collection} c. *
    * This is an O(n) operation. + *

    + * {@inheritDoc} + *

    * * @return true if at least one element of this list was removed, * otherwise false. @@ -250,6 +339,9 @@ /** * This is an O(n) operation. + *

    + * {@inheritDoc} + *

    * * @return true if arrayHashSet is of type ArrayHashSet and all entries are equal * Performance: arrayHashSet(1) @@ -264,6 +356,9 @@ /** * This is an O(n) operation over the size of this list. + *

    + * {@inheritDoc} + *

    * * @return the hash code of this list as define in {@link java.util.List#hashCode()}, * ie hashing all elements of this list. @@ -316,30 +411,44 @@ * Add element at the given index in this list, if it is not contained yet. *
    * This is an O(1) operation + *

    + * {@inheritDoc} + *

    * * @throws IllegalArgumentException if the given element was already contained + * @throws NullPointerException if {@code element} is {@code null} but {@link #supportsNullValue()} == {@code false} */ @Override - public final void add(final int index, final E element) { + public final void add(final int index, final E element) throws IllegalArgumentException, NullPointerException { + if( !supportNullValue ) { + checkNull(element); + } if ( map.containsKey(element) ) { throw new IllegalArgumentException("Element "+element+" is already contained"); } if(null != map.put(element, element)) { + // slips a valid null .. throw new InternalError("Already existing, but checked before: "+element); } + // !exists data.add(index, element); } /** + *

    + * {@inheritDoc} + *

    * @throws UnsupportedOperationException */ @Override - public final boolean addAll(final int index, final Collection c) { + public final boolean addAll(final int index, final Collection c) throws UnsupportedOperationException { throw new UnsupportedOperationException("Not supported yet."); } /** - * @throws UnsupportedOperationException + *

    + * {@inheritDoc} + *

    */ @Override public final E set(final int index, final E element) { @@ -354,6 +463,9 @@ * Remove element at given index from this list. *
    * This is an O(n) operation. + *

    + * {@inheritDoc} + *

    * * @return the removed object */ @@ -370,6 +482,9 @@ * Since this list is unique, equivalent to {@link #indexOf(java.lang.Object)}. *
    * This is an O(n) operation. + *

    + * {@inheritDoc} + *

    * * @return index of element, or -1 if not found */ @@ -409,34 +524,44 @@ *
    * This is an O(1) operation. * - * @param key hash source to find the identical Object within this list + * @param element hash source to find the identical Object within this list * @return object from this list, identical to the given key hash code, * or null if not contained */ - public final E get(final Object key) { - return map.get(key); + public final E get(final Object element) { + return map.get(element); } /** * Identity method allowing to get the identical object, using the internal hash map.
    - * If the key is not yet contained, add it. + * If the element is not yet contained, add it. *
    * This is an O(1) operation. * - * @param key hash source to find the identical Object within this list + * @param element hash source to find the identical Object within this list * @return object from this list, identical to the given key hash code, * or add the given key and return it. + * @throws NullPointerException if {@code element} is {@code null} but {@link #supportsNullValue()} == {@code false} */ - public final E getOrAdd(final E key) { - final E identity = get(key); - if(null == identity) { - // object not contained yet, add it - if(!this.add(key)) { - throw new InternalError("Key not mapped, but contained in list: "+key); + public final E getOrAdd(final E element) throws NullPointerException { + if( supportNullValue ) { + if( map.containsKey(element) ) { + // existent + return map.get(element); } - return key; + } else { + checkNull(element); + final E identity = map.get(element); + if(null != identity) { + // existent + return identity; + } + } + // !existent + if(!this.add(element)) { + throw new InternalError("Element not mapped, but contained in list: "+element); } - return identity; + return element; } /** @@ -455,4 +580,9 @@ return data.contains(element); } + private static final void checkNull(final Object element) throws NullPointerException { + if( null == element ) { + throw new NullPointerException("Null element not supported"); + } + } } Binary files /tmp/yg4EU94J7l/gluegen2-2.2.4/src/java/com/jogamp/common/util/bin/exe-windows-i386.defl and /tmp/m1DqcEnz2H/gluegen2-2.3.2/src/java/com/jogamp/common/util/bin/exe-windows-i386.defl differ Binary files /tmp/yg4EU94J7l/gluegen2-2.2.4/src/java/com/jogamp/common/util/bin/exe-windows-x86_64.defl and /tmp/m1DqcEnz2H/gluegen2-2.3.2/src/java/com/jogamp/common/util/bin/exe-windows-x86_64.defl differ diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/Bitfield.java gluegen2-2.3.2/src/java/com/jogamp/common/util/Bitfield.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/Bitfield.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/Bitfield.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,208 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.common.util; + +import jogamp.common.util.SyncedBitfield; + +/** + * Simple bitfield interface for efficient bit storage access in O(1). + * @since 2.3.2 + */ +public interface Bitfield { + /** Maximum 32 bit Unsigned Integer Value: {@code 0xffffffff} == {@value}. */ + public static final int UNSIGNED_INT_MAX_VALUE = 0xffffffff; + + /** + * Bit operation utilities (static). + */ + public static class Util { + /** + * Returns the 32 bit mask of n-bits, i.e. n low order 1’s. + *

    + * Implementation handles n == 32. + *

    + * @throws IndexOutOfBoundsException if {@code b} is out of bounds, i.e. > 32 + */ + public static int getBitMask(final int n) { + if( 32 > n ) { + return ( 1 << n ) - 1; + } else if ( 32 == n ) { + return UNSIGNED_INT_MAX_VALUE; + } else { + throw new IndexOutOfBoundsException("n <= 32 expected, is "+n); + } + } + + /** + * Returns the number of set bits within given 32bit integer in O(1) + * using a HAKEM 169 Bit Count inspired implementation: + *
    +         *   http://www.inwap.com/pdp10/hbaker/hakmem/hakmem.html
    +         *   http://home.pipeline.com/~hbaker1/hakmem/hacks.html#item169
    +         *   http://tekpool.wordpress.com/category/bit-count/
    +         *   http://www.hackersdelight.org/
    +         * 
    + */ + public static final int bitCount(int n) { + // Note: Original used 'unsigned int', + // hence we use the unsigned right-shift '>>>' + /** + * Original does not work due to lack of 'unsigned' right-shift and modulo, + * we need 2-complementary solution, i.e. 'signed'. + int c = n; + c -= (n >>> 1) & 033333333333; + c -= (n >>> 2) & 011111111111; + return ( (c + ( c >>> 3 ) ) & 030707070707 ) & 0x3f; // % 63 + */ + // Hackers Delight, Figure 5-2, pop1 of pop.c.txt + n = n - ((n >>> 1) & 0x55555555); + n = (n & 0x33333333) + ((n >>> 2) & 0x33333333); + n = (n + (n >>> 4)) & 0x0f0f0f0f; + n = n + (n >>> 8); + n = n + (n >>> 16); + return n & 0x3f; + } + } + /** + * Simple {@link Bitfield} factory for returning the efficient implementation. + */ + public static class Factory { + /** + * Creates am efficient {@link Bitfield} instance based on the requested {@code storageBitSize}. + *

    + * Implementation returns a plain 32 bit integer field implementation for + * {@code storageBitSize} ≤ 32 bits or an 32 bit integer array implementation otherwise. + *

    + */ + public static Bitfield create(final int storageBitSize) { + if( 32 >= storageBitSize ) { + return new jogamp.common.util.Int32Bitfield(); + } else { + return new jogamp.common.util.Int32ArrayBitfield(storageBitSize); + } + } + /** + * Creates a synchronized {@link Bitfield} by wrapping the given {@link Bitfield} instance. + */ + public static Bitfield synchronize(final Bitfield impl) { + return new SyncedBitfield(impl); + } + } + /** + * Returns the storage size in bit units, e.g. 32 bit for implementations using one {@code int} field. + */ + int size(); + + + /** + * Set all bits of this bitfield to the given value {@code bit}. + */ + void clearField(final boolean bit); + + /** + * Returns {@code length} bits from this storage, + * starting with the lowest bit from the storage position {@code lowBitnum}. + * @param lowBitnum storage bit position of the lowest bit, restricted to [0..{@link #size()}-{@code length}]. + * @param length number of bits to read, constrained to [0..32]. + * @throws IndexOutOfBoundsException if {@code rightBitnum} is out of bounds + * @see #put32(int, int, int) + */ + int get32(final int lowBitnum, final int length) throws IndexOutOfBoundsException; + + /** + * Puts {@code length} bits of given {@code data} into this storage, + * starting w/ the lowest bit to the storage position {@code lowBitnum}. + * @param lowBitnum storage bit position of the lowest bit, restricted to [0..{@link #size()}-{@code length}]. + * @param length number of bits to write, constrained to [0..32]. + * @param data the actual bits to be put into this storage + * @throws IndexOutOfBoundsException if {@code rightBitnum} is out of bounds + * @see #get32(int, int) + */ + void put32(final int lowBitnum, final int length, final int data) throws IndexOutOfBoundsException; + + /** + * Copies {@code length} bits at position {@code srcLowBitnum} to position {@code dstLowBitnum} + * and returning the bits. + *

    + * Implementation shall operate as if invoking {@link #get32(int, int)} + * and then {@link #put32(int, int, int)} sequentially. + *

    + * @param srcLowBitnum source bit number, restricted to [0..{@link #size()}-1]. + * @param dstLowBitnum destination bit number, restricted to [0..{@link #size()}-1]. + * @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds + * @see #get32(int, int) + * @see #put32(int, int, int) + */ + int copy32(final int srcLowBitnum, final int dstLowBitnum, final int length) throws IndexOutOfBoundsException; + + /** + * Return true if the bit at position bitnum is set, otherwise false. + * @param bitnum bit number, restricted to [0..{@link #size()}-1]. + * @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds + */ + boolean get(final int bitnum) throws IndexOutOfBoundsException; + + /** + * Set or clear the bit at position bitnum according to bit + * and return the previous value. + * @param bitnum bit number, restricted to [0..{@link #size()}-1]. + * @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds + */ + boolean put(final int bitnum, final boolean bit) throws IndexOutOfBoundsException; + + /** + * Set the bit at position bitnum according to bit. + * @param bitnum bit number, restricted to [0..{@link #size()}-1]. + * @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds + */ + void set(final int bitnum) throws IndexOutOfBoundsException; + + /** + * Clear the bit at position bitnum according to bit. + * @param bitnum bit number, restricted to [0..{@link #size()}-1]. + * @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds + */ + void clear(final int bitnum) throws IndexOutOfBoundsException; + + /** + * Copies the bit at position {@code srcBitnum} to position {@code dstBitnum} + * and returning true if the bit is set, otherwise false. + * @param srcBitnum source bit number, restricted to [0..{@link #size()}-1]. + * @param dstBitnum destination bit number, restricted to [0..{@link #size()}-1]. + * @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds + */ + boolean copy(final int srcBitnum, final int dstBitnum) throws IndexOutOfBoundsException; + + /** + * Returns the number of one bits within this bitfield. + *

    + * Utilizes {#link {@link Bitfield.Util#bitCount(int)}}. + *

    + */ + int bitCount(); +} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/Bitstream.java gluegen2-2.3.2/src/java/com/jogamp/common/util/Bitstream.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/Bitstream.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/Bitstream.java 2015-10-09 04:18:28.000000000 +0000 @@ -91,6 +91,28 @@ long position(); /** + * Sets this stream's position. + *

    + * A set mark is cleared if > new position. + *

    + *

    + * Returns {@link Bitstream#EOS} is end-of-stream is reached, + * otherwise the new position. + *

    + *

    + * Known supporting implementation is {@link ByteBufferStream} and {@link ByteArrayStream}. + *

    + * + * @param newPosition The new positive position. + * + * @return The new set position or {@link Bitstream#EOS} if end-of-stream is reached. + * + * @throws UnsupportedOperationException if not supported, i.e. {@link ByteInputStream} or {@link ByteOutputStream} + * @throws IllegalArgumentException If the {@code newPosition} is negative + */ + long position(long newPosition) throws UnsupportedOperationException, IllegalArgumentException; + + /** * It is implementation dependent, whether backward skip giving a negative number is supported or not. * @param n number of bytes to skip * @return actual skipped bytes @@ -99,9 +121,9 @@ long skip(final long n) throws IOException; /** - * Set markpos to current position, allowing the stream to be {@link #reset()}. - * @param readLimit - * @throws UnsupportedOperationException is not supported, i.e. if stream is not an {@link #canInput() input stream}. + * Set {@code markpos} to current position, allowing the stream to be {@link #reset()}. + * @param readlimit maximum number of bytes able to read before invalidating the {@code markpos}. + * @throws UnsupportedOperationException if not supported, i.e. if stream is not an {@link #canInput() input stream}. */ void mark(final int readLimit) throws UnsupportedOperationException; @@ -110,7 +132,7 @@ *

    * markpos is kept, hence {@link #reset()} can be called multiple times. *

    - * @throws UnsupportedOperationException is not supported, i.e. if stream is not an {@link #canInput() input stream}. + * @throws UnsupportedOperationException if not supported, i.e. if stream is not an {@link #canInput() input stream}. * @throws IllegalStateException if markpos has not been set via {@link #mark(int)} or reset operation failed. * @throws IOException if reset operation failed. */ @@ -123,7 +145,7 @@ * otherwise the resulting value. *

    * @throws IOException - * @throws UnsupportedOperationException is not supported, i.e. if stream is not an {@link #canInput() input stream}. + * @throws UnsupportedOperationException if not supported, i.e. if stream is not an {@link #canInput() input stream}. */ int read() throws UnsupportedOperationException, IOException; @@ -134,7 +156,7 @@ * otherwise the written value. *

    * @throws IOException - * @throws UnsupportedOperationException is not supported, i.e. if stream is not an {@link #canOutput() output stream}. + * @throws UnsupportedOperationException if not supported, i.e. if stream is not an {@link #canOutput() output stream}. */ int write(final byte val) throws UnsupportedOperationException, IOException; } @@ -183,6 +205,18 @@ public long position() { return pos; } @Override + public long position(final long newPosition) throws UnsupportedOperationException, IllegalArgumentException { + if( newPosition >= media.length ) { + return Bitstream.EOS; + } + pos = (int)newPosition; + if( posMark > pos ) { + posMark = -1; + } + return pos; + } + + @Override public long skip(final long n) { final long skip; if( n >= 0 ) { @@ -220,7 +254,7 @@ } if( DEBUG ) { if( EOS != r ) { - System.err.println("u8["+(pos-1)+"] -> "+toHexBinString(r, 8)); + System.err.println("u8["+(pos-1)+"] -> "+toHexBinString(true, r, 8)); } else { System.err.println("u8["+(pos-0)+"] -> EOS"); } @@ -239,7 +273,7 @@ } if( DEBUG ) { if( EOS != r ) { - System.err.println("u8["+(pos-1)+"] <- "+toHexBinString(r, 8)); + System.err.println("u8["+(pos-1)+"] <- "+toHexBinString(true, r, 8)); } else { System.err.println("u8["+(pos-0)+"] <- EOS"); } @@ -292,6 +326,19 @@ public long position() { return pos; } @Override + public long position(final long newPosition) throws UnsupportedOperationException, IllegalArgumentException { + if( newPosition >= media.limit() ) { + return Bitstream.EOS; + } + media.position((int)newPosition); + pos = (int)newPosition; + if( posMark > pos ) { + posMark = -1; + } + return pos; + } + + @Override public long skip(final long n) { final long skip; if( n >= 0 ) { @@ -330,7 +377,7 @@ } if( DEBUG ) { if( EOS != r ) { - System.err.println("u8["+(pos-1)+"] -> "+toHexBinString(r, 8)); + System.err.println("u8["+(pos-1)+"] -> "+toHexBinString(true, r, 8)); } else { System.err.println("u8["+(pos-0)+"] -> EOS"); } @@ -349,7 +396,7 @@ } if( DEBUG ) { if( EOS != r ) { - System.err.println("u8["+(pos-1)+"] <- "+toHexBinString(r, 8)); + System.err.println("u8["+(pos-1)+"] <- "+toHexBinString(true, r, 8)); } else { System.err.println("u8["+(pos-0)+"] <- EOS"); } @@ -411,6 +458,11 @@ public long position() { return pos; } @Override + public long position(final long newPosition) throws UnsupportedOperationException, IllegalArgumentException { + throw new UnsupportedOperationException("N/a for "+getClass().getCanonicalName()); + } + + @Override public long skip(final long n) throws IOException { final long skip = media.skip(n); pos += skip; @@ -438,7 +490,7 @@ final int r = media.read(); if(DEBUG) { if( EOS != r ) { - System.err.println("u8["+pos+"] -> "+toHexBinString(r, 8)); + System.err.println("u8["+pos+"] -> "+toHexBinString(true, r, 8)); } else { System.err.println("u8["+pos+"] -> EOS"); } @@ -505,6 +557,11 @@ public long position() { return pos; } @Override + public long position(final long newPosition) throws UnsupportedOperationException, IllegalArgumentException { + throw new UnsupportedOperationException("N/a for "+getClass().getCanonicalName()); + } + + @Override public long skip(final long n) throws IOException { long i = n; while(i > 0) { @@ -539,7 +596,7 @@ final int r = 0xff & val; media.write(r); if(DEBUG) { - System.err.println("u8["+pos+"] <- "+toHexBinString(r, 8)); + System.err.println("u8["+pos+"] <- "+toHexBinString(true, r, 8)); } pos++; return r; @@ -685,8 +742,8 @@ public final boolean canOutput() { return null != bytes ? bytes.canOutput() : false; } /** - * Set markpos to current position, allowing the stream to be {@link #reset()}. - * @param readLimit + * Set {@code markpos} to current position, allowing the stream to be {@link #reset()}. + * @param readlimit maximum number of bytes able to read before invalidating the {@code markpos}. * @throws IllegalStateException if not in input mode or stream closed */ public final void mark(final int readLimit) throws IllegalStateException { @@ -779,46 +836,68 @@ } /** + * Sets this stream's bit position. + *

    + * A set mark is cleared. + *

    + *

    + * Returns {@link Bitstream#EOS} is end-of-stream is reached, + * otherwise the new position. + *

    + *

    + * Known supporting implementation is {@link ByteBufferStream} and {@link ByteArrayStream}. + *

    + * + * @param newPosition The new positive position. + * + * @return The new set position or {@link Bitstream#EOS} if end-of-stream is reached. + * + * @throws UnsupportedOperationException if not supported, i.e. {@link ByteInputStream} or {@link ByteOutputStream} + * @throws IllegalArgumentException If the {@code newPosition} is negative + * @throws IOException if read error occurs or EOS is reached and {@link #setThrowIOExceptionOnEOF(boolean)} is set to true. + * @throws IllegalStateException + */ + public final long position(final long newPosition) throws UnsupportedOperationException, IllegalArgumentException, IllegalStateException, IOException { + if( 0 > newPosition ) { + throw new IllegalArgumentException("new position not positive: "+newPosition); + } + bytes.position(0); // throws UnsupportedOperationException + resetLocal(); + if( newPosition > skip(newPosition) ) { + return EOS; + } + return newPosition; + } + + /** * @param msbFirst if true incoming stream bit order is MSB to LSB, otherwise LSB to MSB. * @return the read bit or {@link #EOS} if end-of-stream is reached. * @throws IOException * @throws IllegalStateException if not in input mode or stream closed */ - public final int readBit(final boolean msbFirst) throws IllegalStateException, IOException { + public final int readBit(final boolean msbFirst) throws UnsupportedOperationException, IllegalStateException, IOException { if( outputMode || null == bytes ) { throw new IllegalStateException("not in input-mode: "+this); } - if( msbFirst ) { - // MSB - if ( 0 < bitCount ) { - bitCount--; + if ( 0 < bitCount ) { + bitCount--; + if( msbFirst ) { return ( bitBuffer >>> bitCount ) & 0x01; } else { - bitBuffer = bytes.read(); - if( EOS == bitBuffer ) { - if( throwIOExceptionOnEOF ) { - throw new IOException("EOS "+this); - } - return EOS; - } else { - bitCount=7; - return bitBuffer >>> 7; - } + return ( bitBuffer >>> ( 7 - bitCount ) ) & 0x01; } } else { - // LSB - if ( 0 < bitCount ) { - bitCount--; - return ( bitBuffer >>> ( 7 - bitCount ) ) & 0x01; + bitBuffer = bytes.read(); + if( EOS == bitBuffer ) { + if( throwIOExceptionOnEOF ) { + throw new IOException("EOS "+this); + } + return EOS; } else { - bitBuffer = bytes.read(); - if( EOS == bitBuffer ) { - if( throwIOExceptionOnEOF ) { - throw new IOException("EOS "+this); - } - return EOS; + bitCount=7; + if( msbFirst ) { + return bitBuffer >>> 7; } else { - bitCount=7; return bitBuffer & 0x01; } } @@ -836,36 +915,25 @@ if( !outputMode || null == bytes ) { throw new IllegalStateException("not in output-mode: "+this); } - if( msbFirst ) { - // MSB - if ( 0 < bitCount ) { - bitCount--; + if ( 0 < bitCount ) { + bitCount--; + if( msbFirst ) { bitBuffer |= ( 0x01 & bit ) << bitCount; - if( 0 == bitCount ) { - final int r = bytes.write((byte)bitBuffer); - if( throwIOExceptionOnEOF && EOS == r ) { - throw new IOException("EOS "+this); - } - return r; - } } else { - bitCount = 7; - bitBuffer = ( 0x01 & bit ) << 7; - } - } else { - // LSB - if ( 0 < bitCount ) { - bitCount--; bitBuffer |= ( 0x01 & bit ) << ( 7 - bitCount ); - if( 0 == bitCount ) { - final int r = bytes.write((byte)bitBuffer); - if( throwIOExceptionOnEOF && EOS == r ) { - throw new IOException("EOS "+this); - } - return r; + } + if( 0 == bitCount ) { + final int r = bytes.write((byte)bitBuffer); + if( throwIOExceptionOnEOF && EOS == r ) { + throw new IOException("EOS "+this); } + return r; + } + } else { + bitCount = 7; + if( msbFirst ) { + bitBuffer = ( 0x01 & bit ) << 7; } else { - bitCount = 7; bitBuffer = 0x01 & bit; } } @@ -877,7 +945,7 @@ * * @param n number of bits to skip * @return actual skipped bits - * @throws IOException + * @throws IOException if read error occurs or EOS is reached and {@link #setThrowIOExceptionOnEOF(boolean)} is set to true. * @throws IllegalStateException if closed */ public long skip(final long n) throws IllegalStateException, IOException { @@ -939,85 +1007,96 @@ return nX - notReadBits; } } else { - // FIXME: Backward skip + // Zero skip or backward skip + // FIXME: Backward skip n < 0 return 0; } } + private static final boolean useFastPathStream = true; + private static final boolean useFastPathTypes = true; + /** - * Return incoming bits as read via {@link #readBit(boolean)}. + * Return incoming bits as read via {@link #readBit(boolean)} LSB-first as little-endian. *

    - * The incoming bits are stored in MSB-first order, i.e. first on highest position and last bit on lowest position. - * Hence reading w/ lsbFirst, the bit order will be reversed! + * The incoming bit order is from low- to most-significant-bit, maintaining bit LSB-first order. *

    - * @param msbFirst if true incoming stream bit order is MSB to LSB, otherwise LSB to MSB. * @param n number of bits, maximum 31 bits * @return the read bits from 0-n in the given order or {@link #EOS}. * @throws IllegalStateException if not in input mode or stream closed * @throws IllegalArgumentException if n > 31 * @throws IOException */ - public int readBits31(final boolean msbFirst, final int n) throws IllegalArgumentException, IOException { + public int readBits31(final int n) throws IllegalArgumentException, IOException { if( 31 < n ) { throw new IllegalArgumentException("n > 31: "+n); } if( outputMode || null == bytes ) { throw new IllegalStateException("not in input-mode: "+this); } - if( !msbFirst || 0 == n ) { - // Slow path - int r = 0; - int c = n; - while(--c >= 0) { - final int b = readBit(msbFirst); - if( EOS == b ) { - return EOS; - } - r |= b << c; - } - return r; + if( 0 == n ) { + return 0; } else { - // fast path: MSB - int c = n; - final int n1 = Math.min(c, bitCount); // remaining portion - int r; - if( 0 < n1 ) { - final int m1 = ( 1 << n1 ) - 1; - bitCount -= n1; - c -= n1; - r = ( m1 & ( bitBuffer >>> bitCount ) ) << c; - if( 0 == c ) { - return r; + if( !useFastPathStream ) { + // Slow path + int r = 0; + for(int i=0; i < n; i++) { + final int b = readBit(false /* msbFirst */); + if( EOS == b ) { + if( throwIOExceptionOnEOF ) { + throw new IOException("EOS "+this); + } + return EOS; + } + r |= b << i; } + return r; } else { - r = 0; - } - assert( 0 == bitCount ); - do { - bitBuffer = bytes.read(); - if( EOS == bitBuffer ) { - if( throwIOExceptionOnEOF ) { - throw new IOException("EOS "+this); + // fast path + int c = n; + final int n1 = Math.min(n, bitCount); // remaining portion + int r; + if( 0 < n1 ) { + final int m1 = ( 1 << n1 ) - 1; + final int s1 = 7 - bitCount + 1; // LSBfirst: right-shift to new bits + bitCount -= n1; + c -= n1; + // MSBfirst: r = ( m1 & ( bitBuffer >>> bitCount ) ) << c; + r = ( m1 & ( bitBuffer >>> s1 ) ); // LSBfirst + if( 0 == c ) { + return r; } - return EOS; + } else { + r = 0; } - final int n2 = Math.min(c, 8); // full portion - final int m2 = ( 1 << n2 ) - 1; - bitCount = 8 - n2; - c -= n2; - r |= ( m2 & ( bitBuffer >>> bitCount ) ) << c; - } while ( 0 < c ); - return r; + assert( 0 == bitCount ); + int s = n1; // LSBfirst: left shift for additional elements + do { + bitBuffer = bytes.read(); + if( EOS == bitBuffer ) { + if( throwIOExceptionOnEOF ) { + throw new IOException("EOS "+this); + } + return EOS; + } + final int n2 = Math.min(c, 8); // full portion + final int m2 = ( 1 << n2 ) - 1; + bitCount = 8 - n2; + c -= n2; + // MSBfirst: r |= ( m2 & ( bitBuffer >>> bitCount ) ) << c; + r |= ( m2 & bitBuffer ) << s; // LSBfirst on new bits + s += n2; + } while ( 0 < c ); + return r; + } } } /** - * Write the given bits via {@link #writeBit(boolean, int)}. + * Write the given bits via {@link #writeBit(boolean, int)} LSB-first as little-endian. *

    - * The given bits are scanned from LSB-first order. - * Hence reading w/ msbFirst, the bit order will be reversed! + * The outgoing bit order is from low- to most-significant-bit, maintaining bit LSB-first order. *

    - * @param msbFirst if true incoming stream bit order is MSB to LSB, otherwise LSB to MSB. * @param n number of bits, maximum 31 bits * @param bits the bits to write * @return the written bits or {@link #EOS}. @@ -1025,76 +1104,81 @@ * @throws IllegalArgumentException if n > 31 * @throws IOException */ - public int writeBits31(final boolean msbFirst, final int n, final int bits) throws IllegalStateException, IllegalArgumentException, IOException { + public int writeBits31(final int n, final int bits) throws IllegalStateException, IllegalArgumentException, IOException { if( 31 < n ) { throw new IllegalArgumentException("n > 31: "+n); } if( !outputMode || null == bytes ) { throw new IllegalStateException("not in output-mode: "+this); } - if( !msbFirst || 0 == n ) { - // Slow path - int c = n; - while(--c >= 0) { - final int b = writeBit(msbFirst, ( bits >>> c ) & 0x1); - if( EOS == b ) { - return EOS; - } - } - } else { - // fast path: MSB - int c = n; - final int n1 = Math.min(c, bitCount); // remaining portion - if( 0 < n1 ) { - final int m1 = ( 1 << n1 ) - 1; - bitCount -= n1; - c -= n1; - bitBuffer |= ( m1 & ( bits >> c ) ) << bitCount; - if( 0 == bitCount ) { - if( EOS == bytes.write((byte)bitBuffer) ) { - if( throwIOExceptionOnEOF ) { - throw new IOException("EOS "+this); - } + if( 0 < n ) { + if( !useFastPathStream ) { + // Slow path + for(int i=0; i < n; i++) { + final int b = writeBit(false /* msbFirst */, ( bits >>> i ) & 0x1); + if( EOS == b ) { return EOS; } } - if( 0 == c ) { - return bits; - } - } - assert( 0 == bitCount ); - do { - final int n2 = Math.min(c, 8); // full portion - final int m2 = ( 1 << n2 ) - 1; - bitCount = 8 - n2; - c -= n2; - bitBuffer = ( m2 & ( bits >> c ) ) << bitCount; - if( 0 == bitCount ) { - if( EOS == bytes.write((byte)bitBuffer) ) { - if( throwIOExceptionOnEOF ) { - throw new IOException("EOS "+this); + } else { + // fast path + int c = n; + final int n1 = Math.min(n, bitCount); // remaining portion + if( 0 < n1 ) { + final int m1 = ( 1 << n1 ) - 1; + final int s1 = 7 - bitCount + 1; // LSBfirst: left-shift to free bit-pos + bitCount -= n1; + c -= n1; + // MSBfirst: bitBuffer |= ( m1 & ( bits >>> c ) ) << bitCount; + bitBuffer |= ( m1 & bits ) << s1 ; // LSBfirst + if( 0 == bitCount ) { + if( EOS == bytes.write((byte)bitBuffer) ) { + if( throwIOExceptionOnEOF ) { + throw new IOException("EOS "+this); + } + return EOS; } - return EOS; + } + if( 0 == c ) { + return bits; } } - } while ( 0 < c ); + assert( 0 == bitCount ); + int s = n1; // LSBfirst: left shift for additional elements + do { + final int n2 = Math.min(c, 8); // full portion + final int m2 = ( 1 << n2 ) - 1; + bitCount = 8 - n2; + c -= n2; + // MSBfirst: bitBuffer = ( m2 & ( bits >>> c ) ) << bitCount; + bitBuffer = ( m2 & ( bits >>> s ) ); // LSBfirst + s += n2; + if( 0 == bitCount ) { + if( EOS == bytes.write((byte)bitBuffer) ) { + if( throwIOExceptionOnEOF ) { + throw new IOException("EOS "+this); + } + return EOS; + } + } + } while ( 0 < c ); + } } return bits; } /** - * Return incoming uint8_t as read via {@link #readBits31(boolean, int)}. + * Return incoming uint8_t as read via {@link #readBits31(int)}. *

    * In case of a int8_t 2-complement signed value, simply cast the result to byte * after checking for {@link #EOS}. *

    - * @param msbFirst if true incoming stream bit order is MSB to LSB, otherwise LSB to MSB. * @return {@link #EOS} or the 8bit unsigned value within the lower bits. * @throws IllegalStateException if not in input mode or stream closed * @throws IOException */ - public final int readUInt8(final boolean msbFirst) throws IllegalStateException, IOException { - if( 0 == bitCount && msbFirst ) { + public final int readUInt8() throws IllegalStateException, IOException { + if( 0 == bitCount && useFastPathTypes ) { // fast path if( outputMode || null == bytes ) { throw new IllegalStateException("not in input-mode: "+this); @@ -1105,19 +1189,18 @@ } return r; } else { - return readBits31(msbFirst, 8); + return readBits31(8); } } /** - * Write the given 8 bits via {@link #writeBits31(boolean, int, int)}. - * @param msbFirst if true incoming stream bit order is MSB to LSB, otherwise LSB to MSB. + * Write the given 8 bits via {@link #writeBits31(int, int)}. * @return {@link #EOS} or the written 8bit value. * @throws IllegalStateException if not in output mode or stream closed * @throws IOException */ - public final int writeInt8(final boolean msbFirst, final byte int8) throws IllegalStateException, IOException { - if( 0 == bitCount && msbFirst ) { + public final int writeInt8(final byte int8) throws IllegalStateException, IOException { + if( 0 == bitCount && useFastPathTypes ) { // fast path if( !outputMode || null == bytes ) { throw new IllegalStateException("not in output-mode: "+this); @@ -1128,25 +1211,24 @@ } return r; } else { - return this.writeBits31(msbFirst, 8, int8); + return this.writeBits31(8, int8); } } /** - * Return incoming uint16_t as read via {@link #readBits31(boolean, int)} - * and swap bytes if !bigEndian. + * Return incoming uint16_t as read via {@link #readBits31(int)} LSB-first as little-endian, + * hence bytes are swapped if bigEndian. *

    * In case of a int16_t 2-complement signed value, simply cast the result to short * after checking for {@link #EOS}. *

    - * @param msbFirst if true incoming stream bit order is MSB to LSB, otherwise LSB to MSB. - * @param bigEndian if false, swap incoming bytes to little-endian, otherwise leave them as big-endian. + * @param bigEndian if true, swap incoming bytes to little-endian, otherwise leave them as little-endian. * @return {@link #EOS} or the 16bit unsigned value within the lower bits. * @throws IllegalStateException if not in input mode or stream closed * @throws IOException */ - public final int readUInt16(final boolean msbFirst, final boolean bigEndian) throws IllegalStateException, IOException { - if( 0 == bitCount && msbFirst ) { + public final int readUInt16(final boolean bigEndian) throws IllegalStateException, IOException { + if( 0 == bitCount && useFastPathTypes ) { // fast path if( outputMode || null == bytes ) { throw new IllegalStateException("not in input-mode: "+this); @@ -1164,21 +1246,21 @@ return b2 << 8 | b1; } } else { - final int i16 = readBits31(msbFirst, 16); + final int i16 = readBits31(16); if( EOS == i16 ) { return EOS; } else if( bigEndian ) { - return i16; - } else { final int b1 = 0xff & ( i16 >>> 8 ); final int b2 = 0xff & i16; return b2 << 8 | b1; + } else { + return i16; } } } /** - * Return incoming uint16_t value and swap bytes if !bigEndian. + * Return incoming uint16_t value and swap bytes according to bigEndian. *

    * In case of a int16_t 2-complement signed value, simply cast the result to short. *

    @@ -1199,16 +1281,15 @@ } /** - * Write the given 16 bits via {@link #writeBits31(boolean, int, int)}, - * while swapping bytes if !bigEndian beforehand. - * @param msbFirst if true incoming stream bit order is MSB to LSB, otherwise LSB to MSB. - * @param bigEndian if false, swap given bytes to little-endian, otherwise leave them as big-endian. + * Write the given 16 bits via {@link #writeBits31(int, int)} LSB-first as little-endian, + * hence bytes are swapped if bigEndian. + * @param bigEndian if true, swap given bytes to little-endian, otherwise leave them as little-endian. * @return {@link #EOS} or the written 16bit value. * @throws IllegalStateException if not in output mode or stream closed * @throws IOException */ - public final int writeInt16(final boolean msbFirst, final boolean bigEndian, final short int16) throws IllegalStateException, IOException { - if( 0 == bitCount && msbFirst ) { + public final int writeInt16(final boolean bigEndian, final short int16) throws IllegalStateException, IOException { + if( 0 == bitCount && useFastPathTypes ) { // fast path if( !outputMode || null == bytes ) { throw new IllegalStateException("not in output-mode: "+this); @@ -1233,29 +1314,28 @@ } return EOS; } else if( bigEndian ) { - return writeBits31(msbFirst, 16, int16); - } else { final int b1 = 0xff & ( int16 >>> 8 ); final int b2 = 0xff & int16; - return writeBits31(msbFirst, 16, b2 << 8 | b1); + return writeBits31(16, b2 << 8 | b1); + } else { + return writeBits31(16, int16); } } /** - * Return incoming uint32_t as read via {@link #readBits31(boolean, int)} - * and swap bytes if !bigEndian. + * Return incoming uint32_t as read via {@link #readBits31(int)} LSB-first as little-endian, + * hence bytes are swapped if bigEndian. *

    * In case of a int32_t 2-complement signed value, simply cast the result to int * after checking for {@link #EOS}. *

    - * @param msbFirst if true incoming stream bit order is MSB to LSB, otherwise LSB to MSB. - * @param bigEndian if false, swap incoming bytes to little-endian, otherwise leave them as big-endian. + * @param bigEndian if true, swap incoming bytes to little-endian, otherwise leave them as little-endian. * @return {@link #EOS} or the 32bit unsigned value within the lower bits. * @throws IllegalStateException if not in input mode or stream closed * @throws IOException */ - public final long readUInt32(final boolean msbFirst, final boolean bigEndian) throws IllegalStateException, IOException { - if( 0 == bitCount && msbFirst ) { + public final long readUInt32(final boolean bigEndian) throws IllegalStateException, IOException { + if( 0 == bitCount && useFastPathTypes ) { // fast path if( outputMode || null == bytes ) { throw new IllegalStateException("not in input-mode: "+this); @@ -1275,24 +1355,24 @@ return 0xffffffffL & ( b4 << 24 | b3 << 16 | b2 << 8 | b1 ); } } else { - final int i16a = readBits31(msbFirst, 16); - final int i16b = EOS != i16a ? readBits31(msbFirst, 16) : EOS; + final int i16a = readBits31(16); + final int i16b = EOS != i16a ? readBits31(16) : EOS; if( EOS == i16b ) { return EOS; } else if( bigEndian ) { - return 0xffffffffL & ( i16a << 16 | i16b ); - } else { - final int b1 = 0xff & ( i16a >>> 8 ); - final int b2 = 0xff & i16a; - final int b3 = 0xff & ( i16b >>> 8 ); - final int b4 = 0xff & i16b; + final int b1 = 0xff & ( i16b >>> 8 ); + final int b2 = 0xff & i16b; + final int b3 = 0xff & ( i16a >>> 8 ); + final int b4 = 0xff & i16a; return 0xffffffffL & ( b4 << 24 | b3 << 16 | b2 << 8 | b1 ); + } else { + return 0xffffffffL & ( i16b << 16 | i16a ); } } } /** - * Return incoming uint32_t and swap bytes if !bigEndian. + * Return incoming uint32_t and swap bytes according to bigEndian. *

    * In case of a int32_t 2-complement signed value, simply cast the result to int. *

    @@ -1314,16 +1394,15 @@ } /** - * Write the given 32 bits via {@link #writeBits31(boolean, int, int)}, - * while swapping bytes if !bigEndian beforehand. - * @param msbFirst if true incoming stream bit order is MSB to LSB, otherwise LSB to MSB. - * @param bigEndian if false, swap given bytes to little-endian, otherwise leave them as little-endian. + * Write the given 32 bits via {@link #writeBits31(int, int)} LSB-first as little-endian, + * hence bytes are swapped if bigEndian. + * @param bigEndian if true, swap given bytes to little-endian, otherwise leave them as little-endian. * @return {@link #EOS} or the written 32bit value. * @throws IllegalStateException if not in output mode or stream closed * @throws IOException */ - public final int writeInt32(final boolean msbFirst, final boolean bigEndian, final int int32) throws IllegalStateException, IOException { - if( 0 == bitCount && msbFirst ) { + public final int writeInt32(final boolean bigEndian, final int int32) throws IllegalStateException, IOException { + if( 0 == bitCount && useFastPathTypes ) { // fast path if( !outputMode || null == bytes ) { throw new IllegalStateException("not in output-mode: "+this); @@ -1358,21 +1437,21 @@ } return EOS; } else if( bigEndian ) { - final int hi = 0x0000ffff & ( int32 >>> 16 ); - final int lo = 0x0000ffff & int32 ; - if( EOS != writeBits31(msbFirst, 16, hi) ) { - if( EOS != writeBits31(msbFirst, 16, lo) ) { + final int p1 = 0xff & ( int32 >>> 24 ); + final int p2 = 0xff & ( int32 >>> 16 ); + final int p3 = 0xff & ( int32 >>> 8 ); + final int p4 = 0xff & int32 ; + if( EOS != writeBits31(16, p2 << 8 | p1) ) { + if( EOS != writeBits31(16, p4 << 8 | p3) ) { return int32; } } return EOS; } else { - final int p1 = 0xff & ( int32 >>> 24 ); - final int p2 = 0xff & ( int32 >>> 16 ); - final int p3 = 0xff & ( int32 >>> 8 ); - final int p4 = 0xff & int32 ; - if( EOS != writeBits31(msbFirst, 16, p4 << 8 | p3) ) { - if( EOS != writeBits31(msbFirst, 16, p2 << 8 | p1) ) { + final int hi = 0x0000ffff & ( int32 >>> 16 ); + final int lo = 0x0000ffff & int32 ; + if( EOS != writeBits31(16, lo) ) { + if( EOS != writeBits31(16, hi) ) { return int32; } } @@ -1429,22 +1508,52 @@ bpos = bytes.position(); } return String.format("%s, pos %d [byteP %d, bitCnt %d], bitbuf %s", - mode, position(), bpos, bitCount, toHexBinString(bitBuffer, 8)); + mode, position(), bpos, bitCount, toHexBinString(true, bitBuffer, 8)); } private static final String strZeroPadding= "0000000000000000000000000000000000000000000000000000000000000000"; // 64 - public static String toBinString(final int v, final int bitCount) { + public static String toBinString(final boolean msbFirst, final int v, final int bitCount) { if( 0 == bitCount ) { return ""; } - final int mask = (int) ( ( 1L << bitCount ) - 1L ); - final String s0 = Integer.toBinaryString( mask & v ); - return strZeroPadding.substring(0, bitCount-s0.length())+s0; + if( msbFirst ) { + final int mask = (int) ( ( 1L << bitCount ) - 1L ); + final String s0 = Integer.toBinaryString( mask & v ); + return strZeroPadding.substring(0, bitCount-s0.length())+s0; + } else { + final char[] c = new char[32]; + for(int i=0; i sb.length ) { throw new IndexOutOfBoundsException("Buffer of size "+sb.length+" cannot hold offset "+offset+" + remaining "+remaining); diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/cache/TempFileCache.java gluegen2-2.3.2/src/java/com/jogamp/common/util/cache/TempFileCache.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/cache/TempFileCache.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/cache/TempFileCache.java 2015-10-09 04:18:28.000000000 +0000 @@ -35,6 +35,7 @@ import java.nio.channels.FileLock; import com.jogamp.common.util.IOUtil; +import com.jogamp.common.util.InterruptSource; import jogamp.common.Debug; @@ -87,8 +88,11 @@ tmpBaseDir = _tmpBaseDir; if (DEBUG) { + final String tmpBaseDirAbsPath = null != tmpBaseDir ? tmpBaseDir.getAbsolutePath() : null; System.err.println("TempFileCache: Static Initialization ---------------------------------------------- OK: "+(!staticInitError)); - System.err.println("TempFileCache: Thread: "+Thread.currentThread().getName()+", CL 0x"+Integer.toHexString(TempFileCache.class.getClassLoader().hashCode())+", tempBaseDir "+tmpBaseDir.getAbsolutePath()); + System.err.println("TempFileCache: Thread: "+Thread.currentThread().getName()+ + ", CL 0x"+Integer.toHexString(TempFileCache.class.getClassLoader().hashCode())+ + ", tempBaseDir "+tmpBaseDirAbsPath); } if(!staticInitError) { @@ -235,7 +239,7 @@ // Add shutdown hook to cleanup the OutputStream, FileChannel, // and FileLock for the jlnNNNN.lck and jlnNNNN.lck files. // We do this so that the locks never get garbage-collected. - Runtime.getRuntime().addShutdownHook(new Thread() { + Runtime.getRuntime().addShutdownHook(new InterruptSource.Thread() { /* @Override */ @Override public void run() { @@ -262,7 +266,7 @@ } // Start a new Reaper thread to do stuff... - final Thread reaperThread = new Thread() { + final Thread reaperThread = new InterruptSource.Thread() { /* @Override */ @Override public void run() { diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/cache/TempJarCache.java gluegen2-2.3.2/src/java/com/jogamp/common/util/cache/TempJarCache.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/cache/TempJarCache.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/cache/TempJarCache.java 2015-10-09 04:18:28.000000000 +0000 @@ -29,7 +29,6 @@ import java.io.File; import java.io.IOException; -import java.net.URI; import java.net.URISyntaxException; import java.security.cert.Certificate; import java.util.HashMap; @@ -38,8 +37,8 @@ import jogamp.common.Debug; +import com.jogamp.common.net.Uri; import com.jogamp.common.os.NativeLibrary; -import com.jogamp.common.util.IOUtil; import com.jogamp.common.util.JarUtil; import com.jogamp.common.util.SecurityUtil; @@ -68,9 +67,9 @@ } // Set of jar files added - private static Map nativeLibJars; - private static Map classFileJars; - private static Map resourceFileJars; + private static Map nativeLibJars; + private static Map classFileJars; + private static Map resourceFileJars; private static TempFileCache tmpFileCache; @@ -96,12 +95,14 @@ if(!staticInitError) { // Initialize the collections of resources nativeLibMap = new HashMap(); - nativeLibJars = new HashMap(); - classFileJars = new HashMap(); - resourceFileJars = new HashMap(); + nativeLibJars = new HashMap(); + classFileJars = new HashMap(); + resourceFileJars = new HashMap(); } if(DEBUG) { - System.err.println("TempJarCache.initSingleton(): ok "+(false==staticInitError)+", "+ tmpFileCache.getTempDir()); + final File tempDir = null != tmpFileCache ? tmpFileCache.getTempDir() : null; + final String tempDirAbsPath = null != tempDir ? tempDir.getAbsolutePath() : null; + System.err.println("TempJarCache.initSingleton(): ok "+(false==staticInitError)+", "+ tempDirAbsPath); } isInit = true; } @@ -182,62 +183,62 @@ return tmpFileCache; } - public synchronized static boolean checkNativeLibs(final URI jarURI, final LoadState exp) throws IOException { + public synchronized static boolean checkNativeLibs(final Uri jarUri, final LoadState exp) throws IOException { checkInitialized(); - if(null == jarURI) { - throw new IllegalArgumentException("jarURI is null"); + if(null == jarUri) { + throw new IllegalArgumentException("jarUri is null"); } - return testLoadState(nativeLibJars.get(jarURI), exp); + return testLoadState(nativeLibJars.get(jarUri), exp); } - public synchronized static boolean checkClasses(final URI jarURI, final LoadState exp) throws IOException { + public synchronized static boolean checkClasses(final Uri jarUri, final LoadState exp) throws IOException { checkInitialized(); - if(null == jarURI) { - throw new IllegalArgumentException("jarURI is null"); + if(null == jarUri) { + throw new IllegalArgumentException("jarUri is null"); } - return testLoadState(classFileJars.get(jarURI), exp); + return testLoadState(classFileJars.get(jarUri), exp); } - public synchronized static boolean checkResources(final URI jarURI, final LoadState exp) throws IOException { + public synchronized static boolean checkResources(final Uri jarUri, final LoadState exp) throws IOException { checkInitialized(); - if(null == jarURI) { - throw new IllegalArgumentException("jarURI is null"); + if(null == jarUri) { + throw new IllegalArgumentException("jarUri is null"); } - return testLoadState(resourceFileJars.get(jarURI), exp); + return testLoadState(resourceFileJars.get(jarUri), exp); } /** * Adds native libraries, if not yet added. * * @param certClass if class is certified, the JarFile entries needs to have the same certificate - * @param jarURI + * @param jarUri * @param nativeLibraryPath if not null, only extracts native libraries within this path. - * @return true if native libraries were added or previously loaded from given jarURI, otherwise false - * @throws IOException if the jarURI could not be loaded or a previous load attempt failed + * @return true if native libraries were added or previously loaded from given jarUri, otherwise false + * @throws IOException if the jarUri could not be loaded or a previous load attempt failed * @throws SecurityException * @throws URISyntaxException * @throws IllegalArgumentException */ - public synchronized static final boolean addNativeLibs(final Class certClass, final URI jarURI, final String nativeLibraryPath) throws IOException, SecurityException, IllegalArgumentException, URISyntaxException { + public synchronized static final boolean addNativeLibs(final Class certClass, final Uri jarUri, final String nativeLibraryPath) throws IOException, SecurityException, IllegalArgumentException, URISyntaxException { checkInitialized(); - final LoadState nativeLibJarsLS = nativeLibJars.get(jarURI); + final LoadState nativeLibJarsLS = nativeLibJars.get(jarUri); if( !testLoadState(nativeLibJarsLS, LoadState.LOOKED_UP) ) { - nativeLibJars.put(jarURI, LoadState.LOOKED_UP); - final JarFile jarFile = JarUtil.getJarFile(jarURI); + nativeLibJars.put(jarUri, LoadState.LOOKED_UP); + final JarFile jarFile = JarUtil.getJarFile(jarUri); if(DEBUG) { - System.err.println("TempJarCache: addNativeLibs: "+jarURI+": nativeJar "+jarFile.getName()+" (NEW)"); + System.err.println("TempJarCache: addNativeLibs: "+jarUri+": nativeJar "+jarFile.getName()+" (NEW)"); } validateCertificates(certClass, jarFile); final int num = JarUtil.extract(tmpFileCache.getTempDir(), nativeLibMap, jarFile, nativeLibraryPath, true, false, false); - nativeLibJars.put(jarURI, LoadState.LOADED); + nativeLibJars.put(jarUri, LoadState.LOADED); return num > 0; } else if( testLoadState(nativeLibJarsLS, LoadState.LOADED) ) { if(DEBUG) { - System.err.println("TempJarCache: addNativeLibs: "+jarURI+": nativeJar "+jarURI+" (REUSE)"); + System.err.println("TempJarCache: addNativeLibs: "+jarUri+": nativeJar "+jarUri+" (REUSE)"); } return true; } - throw new IOException("TempJarCache: addNativeLibs: "+jarURI+", previous load attempt failed"); + throw new IOException("TempJarCache: addNativeLibs: "+jarUri+", previous load attempt failed"); } /** @@ -247,56 +248,69 @@ * needs Classloader.defineClass(..) access, ie. own derivation - will do when needed .. * * @param certClass if class is certified, the JarFile entries needs to have the same certificate - * @param jarURI - * @throws IOException if the jarURI could not be loaded or a previous load attempt failed + * @param jarUri + * @throws IOException if the jarUri could not be loaded or a previous load attempt failed * @throws SecurityException * @throws URISyntaxException * @throws IllegalArgumentException */ - public synchronized static final void addClasses(final Class certClass, final URI jarURI) throws IOException, SecurityException, IllegalArgumentException, URISyntaxException { + public synchronized static final void addClasses(final Class certClass, final Uri jarUri) throws IOException, SecurityException, IllegalArgumentException, URISyntaxException { checkInitialized(); - final LoadState classFileJarsLS = classFileJars.get(jarURI); + final LoadState classFileJarsLS = classFileJars.get(jarUri); if( !testLoadState(classFileJarsLS, LoadState.LOOKED_UP) ) { - classFileJars.put(jarURI, LoadState.LOOKED_UP); - final JarFile jarFile = JarUtil.getJarFile(jarURI); + classFileJars.put(jarUri, LoadState.LOOKED_UP); + final JarFile jarFile = JarUtil.getJarFile(jarUri); if(DEBUG) { - System.err.println("TempJarCache: addClasses: "+jarURI+": nativeJar "+jarFile.getName()); + System.err.println("TempJarCache: addClasses: "+jarUri+": nativeJar "+jarFile.getName()); } validateCertificates(certClass, jarFile); JarUtil.extract(tmpFileCache.getTempDir(), null, jarFile, null /* nativeLibraryPath */, false, true, false); - classFileJars.put(jarURI, LoadState.LOADED); + classFileJars.put(jarUri, LoadState.LOADED); } else if( !testLoadState(classFileJarsLS, LoadState.LOADED) ) { - throw new IOException("TempJarCache: addClasses: "+jarURI+", previous load attempt failed"); + throw new IOException("TempJarCache: addClasses: "+jarUri+", previous load attempt failed"); } } /** + * See {@link #addResources(Class, Uri)} + * @param certClass + * @param jarURI + * @throws IOException + * @throws SecurityException + * @throws IllegalArgumentException + * @throws URISyntaxException + * @deprecated Use {@link #addResources(Class, Uri)} + */ + public synchronized static final void addResources(final Class certClass, final java.net.URI jarURI) throws IOException, SecurityException, IllegalArgumentException, URISyntaxException { + addResources(certClass, Uri.valueOf(jarURI)); + } + /** * Adds native resources, if not yet added. * * @param certClass if class is certified, the JarFile entries needs to have the same certificate - * @param jarURI + * @param jarUri * @return - * @throws IOException if the jarURI could not be loaded or a previous load attempt failed + * @throws IOException if the jarUri could not be loaded or a previous load attempt failed * @throws SecurityException * @throws URISyntaxException * @throws IllegalArgumentException */ - public synchronized static final void addResources(final Class certClass, final URI jarURI) throws IOException, SecurityException, IllegalArgumentException, URISyntaxException { + public synchronized static final void addResources(final Class certClass, final Uri jarUri) throws IOException, SecurityException, IllegalArgumentException, URISyntaxException { checkInitialized(); - final LoadState resourceFileJarsLS = resourceFileJars.get(jarURI); + final LoadState resourceFileJarsLS = resourceFileJars.get(jarUri); if( !testLoadState(resourceFileJarsLS, LoadState.LOOKED_UP) ) { - resourceFileJars.put(jarURI, LoadState.LOOKED_UP); - final JarFile jarFile = JarUtil.getJarFile(jarURI); + resourceFileJars.put(jarUri, LoadState.LOOKED_UP); + final JarFile jarFile = JarUtil.getJarFile(jarUri); if(DEBUG) { - System.err.println("TempJarCache: addResources: "+jarURI+": nativeJar "+jarFile.getName()); + System.err.println("TempJarCache: addResources: "+jarUri+": nativeJar "+jarFile.getName()); } validateCertificates(certClass, jarFile); JarUtil.extract(tmpFileCache.getTempDir(), null, jarFile, null /* nativeLibraryPath */, false, false, true); - resourceFileJars.put(jarURI, LoadState.LOADED); + resourceFileJars.put(jarUri, LoadState.LOADED); } else if( !testLoadState(resourceFileJarsLS, LoadState.LOADED) ) { - throw new IOException("TempJarCache: addResources: "+jarURI+", previous load attempt failed"); + throw new IOException("TempJarCache: addResources: "+jarUri+", previous load attempt failed"); } } @@ -308,20 +322,20 @@ * needs Classloader.defineClass(..) access, ie. own derivation - will do when needed .. * * @param certClass if class is certified, the JarFile entries needs to have the same certificate - * @param jarURI - * @throws IOException if the jarURI could not be loaded or a previous load attempt failed + * @param jarUri + * @throws IOException if the jarUri could not be loaded or a previous load attempt failed * @throws SecurityException * @throws URISyntaxException * @throws IllegalArgumentException */ - public synchronized static final void addAll(final Class certClass, final URI jarURI) throws IOException, SecurityException, IllegalArgumentException, URISyntaxException { + public synchronized static final void addAll(final Class certClass, final Uri jarUri) throws IOException, SecurityException, IllegalArgumentException, URISyntaxException { checkInitialized(); - if(null == jarURI) { - throw new IllegalArgumentException("jarURI is null"); + if(null == jarUri) { + throw new IllegalArgumentException("jarUri is null"); } - final LoadState nativeLibJarsLS = nativeLibJars.get(jarURI); - final LoadState classFileJarsLS = classFileJars.get(jarURI); - final LoadState resourceFileJarsLS = resourceFileJars.get(jarURI); + final LoadState nativeLibJarsLS = nativeLibJars.get(jarUri); + final LoadState classFileJarsLS = classFileJars.get(jarUri); + final LoadState resourceFileJarsLS = resourceFileJars.get(jarUri); if( !testLoadState(nativeLibJarsLS, LoadState.LOOKED_UP) || !testLoadState(classFileJarsLS, LoadState.LOOKED_UP) || !testLoadState(resourceFileJarsLS, LoadState.LOOKED_UP) ) { @@ -332,18 +346,18 @@ // mark looked-up (those who are not loaded) if(extractNativeLibraries) { - nativeLibJars.put(jarURI, LoadState.LOOKED_UP); + nativeLibJars.put(jarUri, LoadState.LOOKED_UP); } if(extractClassFiles) { - classFileJars.put(jarURI, LoadState.LOOKED_UP); + classFileJars.put(jarUri, LoadState.LOOKED_UP); } if(extractOtherFiles) { - resourceFileJars.put(jarURI, LoadState.LOOKED_UP); + resourceFileJars.put(jarUri, LoadState.LOOKED_UP); } - final JarFile jarFile = JarUtil.getJarFile(jarURI); + final JarFile jarFile = JarUtil.getJarFile(jarUri); if(DEBUG) { - System.err.println("TempJarCache: addAll: "+jarURI+": nativeJar "+jarFile.getName()); + System.err.println("TempJarCache: addAll: "+jarUri+": nativeJar "+jarFile.getName()); } validateCertificates(certClass, jarFile); JarUtil.extract(tmpFileCache.getTempDir(), nativeLibMap, jarFile, @@ -351,18 +365,18 @@ // mark loaded (those were just loaded) if(extractNativeLibraries) { - nativeLibJars.put(jarURI, LoadState.LOADED); + nativeLibJars.put(jarUri, LoadState.LOADED); } if(extractClassFiles) { - classFileJars.put(jarURI, LoadState.LOADED); + classFileJars.put(jarUri, LoadState.LOADED); } if(extractOtherFiles) { - resourceFileJars.put(jarURI, LoadState.LOADED); + resourceFileJars.put(jarUri, LoadState.LOADED); } } else if( !testLoadState(nativeLibJarsLS, LoadState.LOADED) || !testLoadState(classFileJarsLS, LoadState.LOADED) || !testLoadState(resourceFileJarsLS, LoadState.LOADED) ) { - throw new IOException("TempJarCache: addAll: "+jarURI+", previous load attempt failed"); + throw new IOException("TempJarCache: addAll: "+jarUri+", previous load attempt failed"); } } @@ -407,12 +421,20 @@ return null; } + /** + * See {@link #getResourceUri(String)} + * @deprecated Use {@link #getResourceUri(String)} + */ + public synchronized static final java.net.URI getResource(final String name) throws URISyntaxException { + return getResourceUri(name).toURI(); + } + /** Similar to {@link ClassLoader#getResource(String)}. */ - public synchronized static final URI getResource(final String name) throws URISyntaxException { + public synchronized static final Uri getResourceUri(final String name) throws URISyntaxException { checkInitialized(); final File f = new File(tmpFileCache.getTempDir(), name); if(f.exists()) { - return IOUtil.toURISimple(f); + return Uri.valueOf(f); } return null; } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/CustomCompress.java gluegen2-2.3.2/src/java/com/jogamp/common/util/CustomCompress.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/CustomCompress.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/CustomCompress.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,167 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.common.util; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.zip.DataFormatException; +import java.util.zip.Deflater; +import java.util.zip.Inflater; + +/** + * All in memory inflater / deflator for small chunks using streams + *

    + * Stream header of deflated data: + *

      + *
    • 4 bytes magic 0xDEF1A7E0 (Big Endian)
    • + *
    • 4 bytes integer deflated-size (Big Endian)
    • + *
    • 4 bytes integer inflated-size (Big Endian)
    • + *
    • deflated bytes
    • + *
    + *

    + */ +public class CustomCompress { + /** Start of stream header for deflated data */ + public static final int MAGIC = 0xDEF1A7E0; + + /** + * + * @param in {@link InputStream} at start of stream header, i.e. position {@link #MAGIC}. + * @return the inflated bytes from the stream + * @throws IOException if an I/O or deflation exception occurs + * @throws IllegalArgumentException if {@code inLen} ≤ 0 or {@code outLen} ≤ 0, as read from header + */ + public static byte[] inflateFromStream(final InputStream in) + throws IOException, ArrayIndexOutOfBoundsException, IllegalArgumentException + { + final int inLen; + final int outLen; + { + final DataInputStream din = new DataInputStream(in); + final int _magic = din.readInt(); + if( _magic != MAGIC ) { + throw new IOException("wrong magic: "+Integer.toHexString(_magic)+", expected "+Integer.toHexString(MAGIC)); + } + inLen = din.readInt(); + outLen = din.readInt(); + } + return inflateFromStream(in, inLen, outLen, new byte[outLen], 0); + } + + /** + * + * @param in {@link InputStream} at start of deflated bytes, i.e. after the stream header. + * @param inLen number of deflated bytes in stream {@code in} + * @param outLen number of inflated {@code output} bytes at {@code outOff} + * @param output sink for deflated bytes + * @param outOff offset to {@code output} + * @return the inflated bytes from the stream, passing {@code output} for chaining + * @throws IOException if an I/O or deflation exception occurs + * @throws ArrayIndexOutOfBoundsException if {@code outOff} and {@code outLen} exceeds {@code output} + * @throws IllegalArgumentException if {@code inLen} ≤ 0 or {@code outLen} ≤ 0 + */ + public static byte[] inflateFromStream(final InputStream in, final int inLen, final int outLen, + final byte[] output, final int outOff) + throws IOException, ArrayIndexOutOfBoundsException, IllegalArgumentException + { + if (inLen <= 0 || outLen <= 0 ) { + throw new IllegalArgumentException("Length[input "+inLen+", output "+outLen+"]"); + } + if (outOff < 0 || output.length < outOff + outLen) { + throw new ArrayIndexOutOfBoundsException("output.length "+output.length+", offset "+outOff+", length "+outLen); + } + final byte[] input = new byte[inLen]; + int numBytes = 0; + try { + while (true) { + final int remBytes = inLen - numBytes; + int count; + if ( 0 >= remBytes || (count = in.read(input, numBytes, remBytes)) == -1 ) { + break; + } + numBytes += count; + } + } finally { + in.close(); + } + if( inLen != numBytes ) { + throw new IOException("Got "+numBytes+" bytes != expected "+inLen); + } + try { + final Inflater inflater = new Inflater(); + inflater.setInput(input, 0, inLen); + final int outSize = inflater.inflate(output, outOff, outLen); + inflater.end(); + if( outLen != outSize ) { + throw new IOException("Got inflated "+outSize+" bytes != expected "+outLen); + } + } catch(final DataFormatException dfe) { + throw new IOException(dfe); + } + return output; + } + + /** + * @param input raw input bytes + * @param inOff offset to {@code input} + * @param inLen number of {@code input} bytes at {@code inOff} + * @param level compression level 0-9 or {@link Deflater#DEFAULT_COMPRESSION} + * @param out sink for deflated bytes + * @return number of deflated bytes written, not including the header. + * @throws IOException if an I/O or deflation exception occurs + * @throws ArrayIndexOutOfBoundsException if {@code inOff} and {@code inLen} exceeds {@code input} + * @throws IllegalArgumentException if {@code inLen} ≤ 0 + */ + public static int deflateToStream(final byte[] input, final int inOff, final int inLen, + final int level, final OutputStream out) throws IOException, ArrayIndexOutOfBoundsException, IllegalArgumentException { + if (inLen <= 0 ) { + throw new IllegalArgumentException("Length[input "+inLen+"]"); + } + if (inOff < 0 || input.length < inOff + inLen) { + throw new ArrayIndexOutOfBoundsException("input.length "+input.length+", offset "+inOff+", length "+inLen); + } + final byte[] output = new byte[inLen]; + final Deflater deflater = new Deflater(level); + deflater.setInput(input, inOff, inLen); + deflater.finish(); + final int outSize = deflater.deflate(output, 0, inLen); + deflater.end(); + { + final DataOutputStream dout = new DataOutputStream(out); + dout.writeInt(CustomCompress.MAGIC); + dout.writeInt(outSize); + dout.writeInt(inLen); + } + out.write(output, 0, outSize); + return outSize; + } + +} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/FunctionTask.java gluegen2-2.3.2/src/java/com/jogamp/common/util/FunctionTask.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/FunctionTask.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/FunctionTask.java 2015-10-09 04:18:28.000000000 +0000 @@ -30,6 +30,8 @@ import java.io.PrintStream; +import com.jogamp.common.JogampRuntimeException; + /** * Helper class to provide a Runnable queue implementation with a Runnable wrapper * which notifies after execution for the invokeAndWait() semantics. @@ -40,34 +42,56 @@ protected A[] args; /** - * Invokes func. + * @deprecated Simply invoke {@link Function#eval(Object...)} + */ + public static U invoke(final boolean waitUntilDone, final Function func, final V... args) { + return func.eval(args); + } + + /** + * Invokes func on a new {@link InterruptSource.Thread}, + * see {@link InterruptSource.Thread#Thread(ThreadGroup, Runnable, String)} for details. + *

    + * The result can be retrieved via {@link FunctionTask#getResult()}, + * using the returned instance. + *

    + * @param tg the {@link ThreadGroup} for the new thread, maybe null + * @param threadName the name for the new thread, maybe null * @param waitUntilDone if true, waits until func execution is completed, otherwise returns immediately. * @param func the {@link Function} to execute. * @param args the {@link Function} arguments - * @return the {@link Function} return value + * @return the newly created and invoked {@link FunctionTask} + * @since 2.3.2 */ - public static U invoke(final boolean waitUntilDone, final Function func, final V... args) { - Throwable throwable = null; - final Object sync = new Object(); - final FunctionTask rt = new FunctionTask( func, waitUntilDone ? sync : null, true, waitUntilDone ? null : System.err ); - final U res; - synchronized(sync) { - res = rt.eval(args); - if( waitUntilDone ) { - try { - sync.wait(); - } catch (final InterruptedException ie) { - throwable = ie; - } - if(null==throwable) { - throwable = rt.getThrowable(); - } - if(null!=throwable) { - throw new RuntimeException(throwable); + public static FunctionTask invokeOnNewThread(final ThreadGroup tg, final String threadName, + final boolean waitUntilDone, final Function func, final V... args) { + final FunctionTask rt; + if( !waitUntilDone ) { + rt = new FunctionTask( func, null, true, System.err ); + final InterruptSource.Thread t = InterruptSource.Thread.create(tg, rt, threadName); + rt.args = args; + t.start(); + } else { + final Object sync = new Object(); + rt = new FunctionTask( func, sync, true, null ); + final InterruptSource.Thread t = InterruptSource.Thread.create(tg, rt, threadName); + synchronized(sync) { + rt.args = args; + t.start(); + while( rt.isInQueue() ) { + try { + sync.wait(); + } catch (final InterruptedException ie) { + throw new InterruptedRuntimeException(ie); + } + final Throwable throwable = rt.getThrowable(); + if(null!=throwable) { + throw new JogampRuntimeException(throwable); + } } } } - return res; + return rt; } /** @@ -124,6 +148,8 @@ */ @Override public final void run() { + execThread = Thread.currentThread(); + final A[] args = this.args; this.args = null; this.result = null; @@ -144,6 +170,7 @@ } } finally { tExecuted = System.currentTimeMillis(); + isExecuted = true; } } else { synchronized (syncObject) { @@ -161,6 +188,7 @@ } } finally { tExecuted = System.currentTimeMillis(); + isExecuted = true; syncObject.notifyAll(); } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/IntBitfield.java gluegen2-2.3.2/src/java/com/jogamp/common/util/IntBitfield.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/IntBitfield.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/IntBitfield.java 2015-10-09 04:18:28.000000000 +0000 @@ -28,7 +28,10 @@ package com.jogamp.common.util; /** + * @deprecated Use {@link Bitfield} implementations via {@link Bitfield.Factory#create(int)}. + *

    * Simple bitfield holder class using an int[] storage. + *

    *

    * IntBitfield allows convenient access of a wide field of transient bits using efficient storage in O(1). *

    @@ -51,7 +54,7 @@ * @param bitCount */ public IntBitfield(final long bitCount) { - final int units = (int) Math.max(1L, ( bitCount + 7L ) >>> UNIT_SHIFT_L); + final int units = (int) Math.max(1L, ( bitCount + 31L ) >>> UNIT_SHIFT_L); this.storage = new int[units]; this.bitsCountL = (long)units << UNIT_SHIFT_L ; this.bitsCountI = bitsCountL > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)bitsCountL; @@ -61,7 +64,7 @@ * @param bitCount */ public IntBitfield(final int bitCount) { - final int units = Math.max(1, ( bitCount + 7 ) >>> UNIT_SHIFT_I); + final int units = Math.max(1, ( bitCount + 31 ) >>> UNIT_SHIFT_I); this.storage = new int[units]; this.bitsCountI = units << UNIT_SHIFT_I; this.bitsCountL = bitsCountI; @@ -137,21 +140,10 @@ return prev; } /** - * Returns the number of set bits within given 32bit integer in O(1) - * using HAKEM Bit Count: - *
    -     *   http://www.inwap.com/pdp10/hbaker/hakmem/hakmem.html
    -     *   http://home.pipeline.com/~hbaker1/hakmem/hacks.html#item169
    -     *   http://tekpool.wordpress.com/category/bit-count/
    -     * 
    + * @deprecated Use {@link Bitfield.Util#bitCount(int)}. */ public static final int getBitCount(final int n) { - // Note: Original used 'unsigned int', - // hence we use the unsigned right-shift '>>>' - int c = n; - c -= (n >>> 1) & 033333333333; - c -= (n >>> 2) & 011111111111; - return ( (c + ( c >>> 3 ) ) & 030707070707 ) % 63; + return Bitfield.Util.bitCount(n); } /** @@ -163,7 +155,7 @@ public long getBitCount() { long c = 0; for(int i = storage.length-1; i>=0; i--) { - c += getBitCount(storage[i]); + c += Bitfield.Util.bitCount(storage[i]); } return c; } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/InterruptedRuntimeException.java gluegen2-2.3.2/src/java/com/jogamp/common/util/InterruptedRuntimeException.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/InterruptedRuntimeException.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/InterruptedRuntimeException.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,80 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.common.util; + +import com.jogamp.common.JogampRuntimeException; + +/** + * Unchecked exception propagating an {@link InterruptedException} + * where handling of the latter is not desired. + *

    + * {@link InterruptedRuntimeException} may be thrown either by waiting for any {@link Runnable} + * to be completed, or during its execution. + *

    + *

    + * The propagated {@link InterruptedException} may be of type {@link SourcedInterruptedException}. + *

    + *

    + *

    + */ +@SuppressWarnings("serial") +public class InterruptedRuntimeException extends JogampRuntimeException { + + /** + * Constructor attempts to {@link SourcedInterruptedException#wrap(InterruptedException) wrap} + * the given {@link InterruptedException} {@code cause} into a {@link SourcedInterruptedException}. + * + * @param message the message of this exception + * @param cause the propagated {@link InterruptedException} + */ + public InterruptedRuntimeException(final String message, final InterruptedException cause) { + super(message, SourcedInterruptedException.wrap(cause)); + } + + /** + * Constructor attempts to {@link SourcedInterruptedException#wrap(InterruptedException) wrap} + * the given {@link InterruptedException} {@code cause} into a {@link SourcedInterruptedException}. + * + * @param cause the propagated {@link InterruptedException} + */ + public InterruptedRuntimeException(final InterruptedException cause) { + super(SourcedInterruptedException.wrap(cause)); + } + + /** + * Returns the propagated {@link InterruptedException}, i.e. the cause of this exception. + *

    + * {@inheritDoc} + *

    + */ + @Override + public InterruptedException getCause() { + return (InterruptedException)super.getCause(); + } +} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/InterruptSource.java gluegen2-2.3.2/src/java/com/jogamp/common/util/InterruptSource.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/InterruptSource.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/InterruptSource.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,157 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.common.util; + +/** + * Interface exposing {@link java.lang.Thread#interrupt()} source, + * intended for {@link java.lang.Thread} specializations. + * @since 2.3.2 + */ +public interface InterruptSource { + /** + * Returns the source of the last {@link #interrupt()} call. + * @param clear if true, issues {@link #clearInterruptSource()} + */ + Throwable getInterruptSource(final boolean clear); + + /** + * Returns the count of {@link java.lang.Thread#interrupt()} calls. + * @param clear if true, issues {@link #clearInterruptSource()} + */ + int getInterruptCounter(final boolean clear); + + /** + * Clears source and count of {@link java.lang.Thread#interrupt()} calls, if any. + */ + void clearInterruptSource(); + + public static class Util { + /** + * Casts given {@link java.lang.Thread} to {@link InterruptSource} + * if applicable, otherwise returns {@code null}. + */ + public static InterruptSource get(final java.lang.Thread t) { + if(t instanceof InterruptSource) { + return (InterruptSource)t; + } else { + return null; + } + } + /** + * Casts current {@link java.lang.Thread} to {@link InterruptSource} + * if applicable, otherwise returns {@code null}. + */ + public static InterruptSource currentThread() { + return get(java.lang.Thread.currentThread()); + } + } + + /** + * {@link java.lang.Thread} specialization implementing {@link InterruptSource} + * to track {@link java.lang.Thread#interrupt()} calls. + * @since 2.3.2 + */ + public static class Thread extends java.lang.Thread implements InterruptSource { + volatile Throwable interruptSource = null; + volatile int interruptCounter = 0; + final Object sync = new Object(); + + /** + * See {@link Thread#Thread(} for details. + */ + public Thread() { + super(); + } + /** + * See {@link Thread#Thread(ThreadGroup, Runnable)} for details. + * @param tg explicit {@link ThreadGroup}, may be {@code null} + * @param target explicit {@link Runnable}, may be {@code null} + */ + public Thread(final ThreadGroup tg, final Runnable target) { + super(tg, target); + } + /** + * See {@link Thread#Thread(ThreadGroup, Runnable, String)} for details. + * @param tg explicit {@link ThreadGroup}, may be {@code null} + * @param target explicit {@link Runnable}, may be {@code null} + * @param name explicit name of thread, must not be {@code null} + */ + public Thread(final ThreadGroup tg, final Runnable target, final String name) { + super(tg, target, name); + } + + /** + * Depending on whether {@code name} is null, either + * {@link #Thread(ThreadGroup, Runnable, String)} or + * {@link #Thread(ThreadGroup, Runnable)} is being utilized. + * @param tg explicit {@link ThreadGroup}, may be {@code null} + * @param target explicit {@link Runnable}, may be {@code null} + * @param name explicit name of thread, may be {@code null} + */ + public static Thread create(final ThreadGroup tg, final Runnable target, final String name) { + return null != name ? new Thread(tg, target, name) : new Thread(tg, target); + } + + @Override + public final Throwable getInterruptSource(final boolean clear) { + synchronized(sync) { + final Throwable r = interruptSource; + if( clear ) { + clearInterruptSource(); + } + return r; + } + } + @Override + public final int getInterruptCounter(final boolean clear) { + synchronized(sync) { + final int r = interruptCounter; + if( clear ) { + clearInterruptSource(); + } + return r; + } + } + @Override + public final void clearInterruptSource() { + synchronized(sync) { + interruptCounter = 0; + interruptSource = null; + } + } + @Override + public final void interrupt() { + synchronized(sync) { + interruptCounter++; + interruptSource = new Throwable(getName()+".interrupt() #"+interruptCounter); + } + super.interrupt(); + } + } +} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/IOUtil.java gluegen2-2.3.2/src/java/com/jogamp/common/util/IOUtil.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/IOUtil.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/IOUtil.java 2015-10-09 04:18:28.000000000 +0000 @@ -39,8 +39,10 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; +import java.io.Reader; +import java.io.SyncFailedException; +import java.lang.ref.WeakReference; import java.lang.reflect.Constructor; -import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; @@ -51,26 +53,27 @@ import jogamp.common.os.AndroidUtils; import jogamp.common.os.PlatformPropsImpl; +import com.jogamp.common.ExceptionUtils; import com.jogamp.common.net.AssetURLContext; +import com.jogamp.common.net.Uri; import com.jogamp.common.nio.Buffers; -import com.jogamp.common.os.MachineDescription; +import com.jogamp.common.os.MachineDataInfo; import com.jogamp.common.os.Platform; public class IOUtil { - public static final boolean DEBUG = Debug.debug("IOUtil"); - - /** {@value} */ - public static final String SCHEME_SEPARATOR = ":"; - /** {@value} */ - public static final String FILE_SCHEME = "file"; - /** {@value} */ - public static final String HTTP_SCHEME = "http"; - /** {@value} */ - public static final String HTTPS_SCHEME = "https"; - /** {@value} */ - public static final String JAR_SCHEME = "jar"; - /** A JAR subprotocol is separeted from the JAR entry w/ this separator {@value}. Even if no class is specified '!/' must follow!. */ - public static final char JAR_SCHEME_SEPARATOR = '!'; + public static final boolean DEBUG; + private static final boolean DEBUG_EXE; + private static final boolean DEBUG_EXE_NOSTREAM; + private static final boolean DEBUG_EXE_EXISTING_FILE; + + static { + Debug.initSingleton(); + DEBUG = Debug.debug("IOUtil"); + DEBUG_EXE = PropertyAccess.isPropertyDefined("jogamp.debug.IOUtil.Exe", true); + DEBUG_EXE_NOSTREAM = PropertyAccess.isPropertyDefined("jogamp.debug.IOUtil.Exe.NoStream", true); + // For security reasons, we have to hardcode this, i.e. disable this manual debug feature! + DEBUG_EXE_EXISTING_FILE = false; // PropertyAccess.isPropertyDefined("jogamp.debug.IOUtil.Exe.ExistingFile", true); + } /** Std. temporary directory property key java.io.tmpdir. */ private static final String java_io_tmpdir_propkey = "java.io.tmpdir"; @@ -121,7 +124,7 @@ /** * Copy the specified URL resource to the specified output file. The total - * number of bytes written is returned. Both streams are closed upon completion. + * number of bytes written is returned. * * @param conn the open URLConnection * @param outFile the destination @@ -143,7 +146,7 @@ /** * Copy the specified input stream to the specified output file. The total - * number of bytes written is returned. Both streams are closed upon completion. + * number of bytes written is returned. * * @param in the source * @param outFile the destination @@ -172,14 +175,14 @@ * @throws IOException */ public static int copyStream2Stream(final InputStream in, final OutputStream out, final int totalNumBytes) throws IOException { - return copyStream2Stream(Platform.getMachineDescription().pageSizeInBytes(), in, out, totalNumBytes); + return copyStream2Stream(Platform.getMachineDataInfo().pageSizeInBytes(), in, out, totalNumBytes); } /** * Copy the specified input stream to the specified output stream. The total * number of bytes written is returned. * - * @param bufferSize the intermediate buffer size, should be {@link MachineDescription#pageSizeInBytes()} for best performance. + * @param bufferSize the intermediate buffer size, should be {@link MachineDataInfo#pageSizeInBytes()} for best performance. * @param in the source * @param out the destination * @param totalNumBytes informal number of expected bytes, maybe used for user feedback while processing. -1 if unknown @@ -200,6 +203,15 @@ return numBytes; } + public static StringBuilder appendCharStream(final StringBuilder sb, final Reader r) throws IOException { + final char[] cbuf = new char[1024]; + int count; + while( 0 < ( count = r.read(cbuf) ) ) { + sb.append(cbuf, 0, count); + } + return sb; + } + /** * Copy the specified input stream to a byte array, which is being returned. */ @@ -258,7 +270,7 @@ if( initialCapacity < avail ) { initialCapacity = avail; } - final MachineDescription machine = Platform.getMachineDescription(); + final MachineDataInfo machine = Platform.getMachineDataInfo(); ByteBuffer data = Buffers.newDirectByteBuffer( machine.pageAlignedSize( initialCapacity ) ); final byte[] chunk = new byte[machine.pageSizeInBytes()]; int chunk2Read = Math.min(machine.pageSizeInBytes(), avail); @@ -289,6 +301,8 @@ * */ + private static final Pattern patternSingleBS = Pattern.compile("\\\\{1}"); + /** * * @param path @@ -298,7 +312,7 @@ * @throws URISyntaxException if path is empty or has no parent directory available while resolving ../ */ public static String slashify(final String path, final boolean startWithSlash, final boolean endWithSlash) throws URISyntaxException { - String p = path.replace('\\', '/'); // unify file separator + String p = patternSingleBS.matcher(path).replaceAll("/"); if (startWithSlash && !p.startsWith("/")) { p = "/" + p; } @@ -309,24 +323,6 @@ } /** - * Using the simple conversion via File -> URI, assuming proper characters. - * @throws URISyntaxException if path is empty or has no parent directory available while resolving ../ - * @throws URISyntaxException if the resulting string does not comply w/ an RFC 2396 URI - */ - public static URI toURISimple(final File file) throws URISyntaxException { - return new URI(FILE_SCHEME, null, slashify(file.getAbsolutePath(), true /* startWithSlash */, file.isDirectory() /* endWithSlash */), null); - } - - /** - * Using the simple conversion via File -> URI, assuming proper characters. - * @throws URISyntaxException if path is empty or has no parent directory available while resolving ../ - * @throws URISyntaxException if the resulting string does not comply w/ an RFC 2396 URI - */ - public static URI toURISimple(final String protocol, final String path, final boolean isDirectory) throws URISyntaxException { - return new URI(protocol, null, slashify(new File(path).getAbsolutePath(), true /* startWithSlash */, isDirectory /* endWithSlash */), null); - } - - /** * Returns the lowercase suffix of the given file name (the text * after the last '.' in the file name). Returns null if the file * name has no suffix. Only operates on the given file name; @@ -434,82 +430,9 @@ return fname; } - /** - * The URI's protocol:/some/path/gluegen-rt.jar - * parent dirname URI protocol:/some/path/ will be returned. - *

    - * protocol may be "file", "http", etc.. - *

    - * - * @param uri "protocol:/some/path/gluegen-rt.jar" - * @return "protocol:/some/path/" - * @throws IllegalArgumentException if the URI doesn't match the expected formatting, or is null - * @throws URISyntaxException - */ - public static URI getURIDirname(final URI uri) throws IllegalArgumentException, URISyntaxException { - if(null == uri) { - throw new IllegalArgumentException("URI is null"); - } - final String uriS = uri.toString(); - if( DEBUG ) { - System.err.println("getURIDirname "+uri+", extForm: "+uriS); - } - return new URI( getURIDirname(uriS) ); - } - - /** - * The URI's protocol:/some/path/gluegen-rt.jar - * parent dirname URI protocol:/some/path/ will be returned. - *

    - * protocol may be "file", "http", etc.. - *

    - * - * @param uri "protocol:/some/path/gluegen-rt.jar" (URI encoded) - * @return "protocol:/some/path/" - * @throws IllegalArgumentException if the URI doesn't match the expected formatting, or is null - * @throws URISyntaxException - */ - public static String getURIDirname(String uriS) throws IllegalArgumentException, URISyntaxException { - if(null == uriS) { - throw new IllegalArgumentException("uriS is null"); - } - // from - // file:/some/path/gluegen-rt.jar _or_ rsrc:gluegen-rt.jar - // to - // file:/some/path/ _or_ rsrc: - int idx = uriS.lastIndexOf('/'); - if(0 > idx) { - // no abs-path, check for protocol terminator ':' - idx = uriS.lastIndexOf(':'); - if(0 > idx) { - throw new IllegalArgumentException("URI does not contain protocol terminator ':', in <"+uriS+">"); - } - } - uriS = uriS.substring(0, idx+1); // exclude jar name, include terminal '/' or ':' - - if( DEBUG ) { - System.err.println("getJarURIDirname res: "+uriS); - } - return uriS; - } - - /** - * Simply returns {@link URI#toURL()}. - * @param uri - * @return - * @throws IOException - * @throws IllegalArgumentException - * @throws URISyntaxException - * - * @deprecated Useless - */ - public static URL toURL(final URI uri) throws IOException, IllegalArgumentException, URISyntaxException { - return uri.toURL(); - } - /*** * - * RESOURCE LOCATION STUFF + * RESOURCE LOCATION HELPER * */ @@ -518,7 +441,10 @@ * to be {@link #resolve(int) resolved} at a later time. */ public static class ClassResources { - /** Class instance used to {@link #resolve(int)} the {@link #resourcePaths}. */ + /** Optional {@link ClassLoader} used to {@link #resolve(int)} {@link #resourcePaths}. */ + public final ClassLoader classLoader; + + /** Optional class instance used to {@link #resolve(int)} relative {@link #resourcePaths}. */ public final Class contextCL; /** Resource paths, see {@link #resolve(int)}. */ @@ -530,23 +456,34 @@ /** * @param contextCL class instance to {@link #resolve(int)} {@link #resourcePaths}. * @param resourcePaths array of strings denominating multiple resource paths. None shall be null. + * @deprecated Use {@link #IOUtil(String[], ClassLoader, Class)} for clarity! */ public ClassResources(final Class contextCL, final String[] resourcePaths) { + this(resourcePaths, contextCL.getClassLoader(), contextCL); + } + /** + * @param resourcePaths multiple relative or absolute resource locations + * @param classLoader optional {@link ClassLoader}, see {@link IOUtil#getResource(String, ClassLoader, Class)} + * @param relContext optional relative context, see {@link IOUtil#getResource(String, ClassLoader, Class)} + */ + public ClassResources(final String[] resourcePaths, final ClassLoader classLoader, final Class relContext) { for(int i=resourcePaths.length-1; i>=0; i--) { if( null == resourcePaths[i] ) { throw new IllegalArgumentException("resourcePath["+i+"] is null"); } } - this.contextCL = contextCL; + this.classLoader = classLoader; + this.contextCL = relContext; this.resourcePaths = resourcePaths; } /** - * Resolving one of the {@link #resourcePaths} indexed by uriIndex using {@link #contextCL} and {@link IOUtil#getResource(Class, String)}. + * Resolving one of the {@link #resourcePaths} indexed by uriIndex using + * {@link #classLoader}, {@link #contextCL} through {@link IOUtil#getResource(String, ClassLoader, Class)}. * @throws ArrayIndexOutOfBoundsException if uriIndex is < 0 or >= {@link #resourceCount()}. */ public URLConnection resolve(final int uriIndex) throws ArrayIndexOutOfBoundsException { - return getResource(contextCL, resourcePaths[uriIndex]); + return getResource(resourcePaths[uriIndex], classLoader, contextCL); } } @@ -555,10 +492,11 @@ *
      *
    • relative: context's package name-path plus resourcePath via context's ClassLoader. * This allows locations relative to JAR- and other URLs. - * The resourcePath may start with ../ to navigate to parent folder.
    • - *
    • absolute: context's ClassLoader and the resourcePath as is (filesystem)
    • + * The resourcePath may start with ../ to navigate to parent folder. + * This attempt is skipped if {@code context} is {@code null}. + *
    • absolute: resourcePath as is via context's ClassLoader. + * In case {@code context} is {@code null}, this class {@link ClassLoader} is being used.
    • *
    - * *

    * Returns the resolved and open URLConnection or null if not found. *

    @@ -566,29 +504,55 @@ * @see #getResource(String, ClassLoader) * @see ClassLoader#getResource(String) * @see ClassLoader#getSystemResource(String) + * @deprecated Use {@link IOUtil#getResource(String, ClassLoader, Class)} for clarity! */ public static URLConnection getResource(final Class context, final String resourcePath) { + final ClassLoader contextCL = null != context ? context.getClassLoader() : IOUtil.class.getClassLoader(); + return getResource(resourcePath, contextCL, context); + } + + /** + * Locating a resource using {@link #getResource(String, ClassLoader)}: + *
      + *
    • relative: relContext's package name-path plus resourcePath via classLoader. + * This allows locations relative to JAR- and other URLs. + * The resourcePath may start with ../ to navigate to parent folder. + * This attempt is skipped if {@code relContext} is {@code null}.
    • + *
    • absolute: resourcePath as is via classLoader. + *
    + *

    + * Returns the resolved and open URLConnection or null if not found. + *

    + * + * @param resourcePath the resource path to locate relative or absolute + * @param classLoader the optional {@link ClassLoader}, recommended + * @param relContext relative context, i.e. position, of the {@code resourcePath}, + * to perform the relative lookup, if not {@code null}. + * @see #getResource(String, ClassLoader) + * @see ClassLoader#getResource(String) + * @see ClassLoader#getSystemResource(String) + */ + public static URLConnection getResource(final String resourcePath, final ClassLoader classLoader, final Class relContext) { if(null == resourcePath) { return null; } - final ClassLoader contextCL = (null!=context)?context.getClassLoader():IOUtil.class.getClassLoader(); URLConnection conn = null; - if(null != context) { + if(null != relContext) { // scoping the path within the class's package - final String className = context.getName().replace('.', '/'); + final String className = relContext.getName().replace('.', '/'); final int lastSlash = className.lastIndexOf('/'); if (lastSlash >= 0) { final String pkgName = className.substring(0, lastSlash + 1); - conn = getResource(pkgName + resourcePath, contextCL); + conn = getResource(pkgName + resourcePath, classLoader); if(DEBUG) { - System.err.println("IOUtil: found <"+resourcePath+"> within class package <"+pkgName+"> of given class <"+context.getName()+">: "+(null!=conn)); + System.err.println("IOUtil: found <"+resourcePath+"> within class package <"+pkgName+"> of given class <"+relContext.getName()+">: "+(null!=conn)); } } } else if(DEBUG) { - System.err.println("IOUtil: null context"); + System.err.println("IOUtil: null context, skip rel. lookup"); } if(null == conn) { - conn = getResource(resourcePath, contextCL); + conn = getResource(resourcePath, classLoader); if(DEBUG) { System.err.println("IOUtil: found <"+resourcePath+"> by classloader: "+(null!=conn)); } @@ -619,8 +583,7 @@ return AssetURLContext.createURL(resourcePath, cl).openConnection(); } catch (final IOException ioe) { if(DEBUG) { - System.err.println("IOUtil: Caught Exception:"); - ioe.printStackTrace(); + ExceptionUtils.dumpThrowable("IOUtil", ioe); } return null; } @@ -629,8 +592,7 @@ return AssetURLContext.resolve(resourcePath, cl); } catch (final IOException ioe) { if(DEBUG) { - System.err.println("IOUtil: Caught Exception:"); - ioe.printStackTrace(); + ExceptionUtils.dumpThrowable("IOUtil", ioe); } } } @@ -658,7 +620,7 @@ } /** - * @param path assuming a slashified path beginning with "/" as it's root directory, either denotes a file or directory. + * @param path assuming a slashified path, either denotes a file or directory, either relative or absolute. * @return parent of path * @throws URISyntaxException if path is empty or has no parent directory available */ @@ -670,11 +632,11 @@ final int e = path.lastIndexOf("/"); if( e < 0 ) { - throw new URISyntaxException(path, "path contains no '/'"); + throw new URISyntaxException(path, "path contains no '/': <"+path+">"); } if( e == 0 ) { // path is root directory - throw new URISyntaxException(path, "path has no parents"); + throw new URISyntaxException(path, "path has no parents: <"+path+">"); } if( e < pl - 1 ) { // path is file, return it's parent directory @@ -684,239 +646,64 @@ // path is a directory .. final int p = path.lastIndexOf("/", e-1); if( p >= j) { + // parent itself has '/' - post '!' or no '!' at all return path.substring(0, p+1); - } - throw new URISyntaxException(path, "parent of path contains no '/'"); - } - - /** - * @param path assuming a slashified path beginning with "/" as it's root directory, either denotes a file or directory. - * @return clean path string where ../ and ./ is resolved. - * @throws URISyntaxException if path is empty or has no parent directory available while resolving ../ - */ - public static String cleanPathString(String path) throws URISyntaxException { - int idx; - while ( ( idx = path.indexOf("../") ) >= 0 ) { - path = getParentOf(path.substring(0, idx)) + path.substring(idx+3); - } - while ( ( idx = path.indexOf("./") ) >= 0 ) { - path = path.substring(0, idx) + path.substring(idx+2); - } - return path; - } - - /** - * Generates a URI for the relativePath relative to the baseURI, - * hence the result is a absolute location. - *

    - * Impl. operates on the scheme-specific-part, and hence is sub-protocol savvy. - *

    - *

    - * In case baseURI is not a path ending w/ '/', it's a assumed to be a file and it's parent is being used. - *

    - * - * @param baseURI denotes a URI to a directory ending w/ '/', or a file. In the latter case the file's directory is being used. - * @param relativePath denotes a relative file to the baseLocation's parent directory (URI encoded) - * @throws URISyntaxException if path is empty or has no parent directory available while resolving ../ - */ - public static URI getRelativeOf(final URI baseURI, final String relativePath) throws URISyntaxException { - return compose(baseURI.getScheme(), baseURI.getRawSchemeSpecificPart(), relativePath, baseURI.getRawFragment()); - } - - /** - * Wraps {@link #getRelativeOf(URI, String)} for convenience. - * @param relativePath denotes a relative file to the baseLocation's parent directory (URI encoded) - * @throws IOException - */ - public static URL getRelativeOf(final URL baseURL, final String relativePath) throws IOException { - try { - return getRelativeOf(baseURL.toURI(), relativePath).toURL(); - } catch (final URISyntaxException e) { - throw new IOException(e); - } - } - - /** - * Generates a URI for the relativePath relative to the schemeSpecificPart, - * hence the result is a absolute location. - *

    - * schemeSpecificPart's query, if exist is split to path and query. - *

    - *

    - * In case path is not a path ending w/ '/', it's a assumed to be a file and it's parent is being used. - *

    - * - * @param scheme scheme of the resulting URI - * @param schemeSpecificPart may include a query, which is separated while processing (URI encoded) - * @param relativePath denotes a relative file to the baseLocation's parent directory (URI encoded) - * @param fragment the URI fragment (URI encoded) - * @throws URISyntaxException if path is empty or has no parent directory available while resolving ../ - * @see #encodeToURI(String) - */ - public static URI compose(final String scheme, String schemeSpecificPart, final String relativePath, final String fragment) throws URISyntaxException { - // cut off optional query in scheme-specific-part - final String query; - final int queryI = schemeSpecificPart.lastIndexOf('?'); - if( queryI >= 0 ) { - query = schemeSpecificPart.substring(queryI+1); - schemeSpecificPart = schemeSpecificPart.substring(0, queryI); } else { - query = null; - } - if( null != relativePath ) { - if( !schemeSpecificPart.endsWith("/") ) { - schemeSpecificPart = getParentOf(schemeSpecificPart); + // parent itself has no '/' + final String parent = path.substring(j, e); + if( parent.equals("..") ) { + throw new URISyntaxException(path, "parent is unresolved: <"+path+">"); + } else { + // parent is '!' or empty (relative path) + return path.substring(0, j); } - schemeSpecificPart = schemeSpecificPart + relativePath; - } - schemeSpecificPart = cleanPathString( schemeSpecificPart ); - final StringBuilder uri = new StringBuilder(); - uri.append(scheme); - uri.append(':'); - uri.append(schemeSpecificPart); - if ( null != query ) { - uri.append('?'); - uri.append(query); } - if ( null != fragment ) { - uri.append('#'); - uri.append(fragment); - } - return new URI(uri.toString()); - } - - private static final Pattern patternSpaceRaw = Pattern.compile(" "); - private static final Pattern patternSpaceEnc = Pattern.compile("%20"); - - /** - * Escapes characters not complying w/ RFC 2396 and the {@link URI#URI(String)} ctor. - *
      - *
    • SPACE -> %20
    • - *
    - * @deprecated Useless - */ - public static String encodeToURI(final String vanilla) { - return patternSpaceRaw.matcher(vanilla).replaceAll("%20"); // Uri TODO: Uri.encode(vanilla, Uri.PATH_MIN_LEGAL); } /** - * Reverses escaping of characters as performed via {@link #encodeToURI(String)}. - *
      - *
    • %20 -> SPACE
    • - *
    - * @deprecated Use {@link #decodeURIIfFilePath(URI)} - */ - public static String decodeFromURI(final String encodedUri) { - return patternSpaceEnc.matcher(encodedUri).replaceAll(" "); // Uri TODO: Uri.decode(encoded); - } - - private static final Pattern patternSingleBS = Pattern.compile("\\\\{1}"); - private static final Pattern patternSingleFS = Pattern.compile("/{1}"); - - /** - * Encodes file path characters not complying w/ RFC 2396 and the {@link URI#URI(String)} ctor. - *

    - * Implementation processes the filePath if {@link File#separatorChar} == '\\' - * as follows: - *

      - *
    • backslash -> slash
    • - *
    • ensure starting with slash
    • - *
    - *

    - *

    - * Note that this method does not perform space encoding, - * which can be utilized via {@link #encodeToURI(String)}. - *

    - *

    - * Even though Oracle's JarURLStreamHandler can handle backslashes and - * erroneous URIs w/ e.g. Windows file 'syntax', other may not (Netbeans).
    - * See Bug 857 - http://jogamp.org/bugzilla/show_bug.cgi?id=857 - *

    - * @see #encodeToURI(String) - * @deprecated Useless + * @param path assuming a slashified path, either denoting a file or directory, either relative or absolute. + * @return clean path string where {@code ./} and {@code ../} is resolved, + * while keeping a starting {@code ../} at the beginning of a relative path. + * @throws URISyntaxException if path is empty or has no parent directory available while resolving ../ */ - public static String encodeFilePathToURI(final String filePath) { - if( File.separator.equals("\\") ) { - final String r = patternSingleBS.matcher(filePath).replaceAll("/"); - if( !r.startsWith("/") ) { - return "/" + r; + public static String cleanPathString(String path) throws URISyntaxException { + // Resolve './' before '../' to handle case 'parent/./../a.txt' properly. + int idx = path.length() - 1; + while ( idx >= 1 && ( idx = path.lastIndexOf("./", idx) ) >= 0 ) { + if( 0 < idx && path.charAt(idx-1) == '.' ) { + idx-=2; // skip '../' -> idx upfront } else { - return r; + path = path.substring(0, idx) + path.substring(idx+2); + idx--; // idx upfront } } - return filePath; - } - - /** - * Completes decoding uri-file path characters complying w/ RFC 2396 to native file-path. - *

    - * Implementation decodes the space-encoding path={@link #decodeFromURI(String) decodeFromURI}(uriPath). - *

    - *

    - * Then it processes the path if {@link File#separatorChar} == '\\' - * as follows: - *

      - *
    • slash -> backslash
    • - *
    • drop a starting single backslash, preserving windows UNC
    • - *
    - *

    - * @param encodedUriPath URI encoded path - * @see #decodeFromURI(String) - * @deprecated Use {@link #decodeURIIfFilePath(URI)} - */ - public static String decodeURIToFilePath(final String encodedUriPath) { - final String path = patternSpaceEnc.matcher(encodedUriPath).replaceAll(" "); // Uri TODO: Uri.decode(encoded); - if( File.separator.equals("\\") ) { - final String r = patternSingleFS.matcher(path).replaceAll("\\\\"); - if( r.startsWith("\\") && !r.startsWith("\\\\") ) { // '\\\\' denotes UNC hostname, which shall not be cut-off - return r.substring(1); + idx = 0; + while ( ( idx = path.indexOf("../", idx) ) >= 0 ) { + if( 0 == idx ) { + idx += 3; // skip starting '../' } else { - return r; + path = getParentOf(path.substring(0, idx)) + path.substring(idx+3); + idx = 0; } } return path; } + public static final Pattern patternSpaceEnc = Pattern.compile("%20"); + /** - * If uri is a file scheme, - * implementation completes space-decoding [ "//"+{@link URI#getAuthority()} ] + {@link URI#getPath()}.
    - * Then it processes the path if {@link File#separatorChar} == '\\' - * as follows: - *
      - *
    • slash -> backslash
    • - *
    • drop a starting single backslash, preserving windows UNC
    • - *
    - *

    + * If uri is a file scheme + * implementation returns {@link Uri#toFile()}.{@link File#getPath()}. *

    * Otherwise it returns the {@link URI#toASCIIString()} encoded URI. *

    - * - * @see #decodeFromURI(String) - * @see #decodeURIToFilePath(String) */ - public static String decodeURIIfFilePath(final URI uri) { - if( IOUtil.FILE_SCHEME.equals( uri.getScheme() ) ) { - final String authorityS; - { - final String authority = uri.getAuthority(); - if( null == authority ) { - authorityS = ""; - } else { - authorityS = "//"+authority; - } - final String path = patternSpaceEnc.matcher(authorityS+uri.getPath()).replaceAll(" "); // Uri TODO: Uri.decode(encoded); - if( File.separator.equals("\\") ) { - final String r = patternSingleFS.matcher(path).replaceAll("\\\\"); - if( r.startsWith("\\") && !r.startsWith("\\\\") ) { // '\\\\' denotes UNC hostname, which shall not be cut-off - return r.substring(1); - } else { - return r; - } - } - return path; - } + public static String getUriFilePathOrASCII(final Uri uri) { + if( uri.isFileScheme() ) { + return uri.toFile().getPath(); + } else { + return uri.toASCIIString().get(); } - return uri.toASCIIString(); } /** @@ -940,8 +727,7 @@ return c; } catch (final IOException ioe) { if(DEBUG) { - System.err.println("IOUtil: urlExists("+url+") ["+dbgmsg+"] - false - "+ioe.getClass().getSimpleName()+": "+ioe.getMessage()); - ioe.printStackTrace(); + ExceptionUtils.dumpThrowable("IOUtil: urlExists("+url+") ["+dbgmsg+"] - false -", ioe); } } } else if(DEBUG) { @@ -951,15 +737,19 @@ return null; } - private static String getShellSuffix() { + private static String getExeTestFileSuffix() { switch(PlatformPropsImpl.OS_TYPE) { case WINDOWS: - return ".bat"; + if( Platform.CPUFamily.X86 == PlatformPropsImpl.CPU_ARCH.family ) { + return ".exe"; + } else { + return ".bat"; + } default: return ".sh"; } } - private static String getShellCode() { + private static String getExeTestShellCode() { switch(PlatformPropsImpl.OS_TYPE) { case WINDOWS: return "echo off"+PlatformPropsImpl.NEWLINE; @@ -967,7 +757,77 @@ return null; } } + private static String[] getExeTestCommandArgs(final String scriptFile) { + switch(PlatformPropsImpl.OS_TYPE) { + case WINDOWS: + // return new String[] { "cmd", "/c", scriptFile }; + default: + return new String[] { scriptFile }; + } + } + private static final byte[] readCode(final String fname) throws IOException { + final URLConnection con = IOUtil.getResource(fname, IOUtil.class.getClassLoader(), IOUtil.class); + final InputStream in = con.getInputStream(); + byte[] output = null; + try { + output = CustomCompress.inflateFromStream(in); + } finally { + in.close(); + } + return output; + } + private static final Object exeTestLock = new Object(); + private static WeakReference exeTestCodeRef = null; + + private static void fillExeTestFile(final File exefile) throws IOException { + if( Platform.OSType.WINDOWS == PlatformPropsImpl.OS_TYPE && + Platform.CPUFamily.X86 == PlatformPropsImpl.CPU_ARCH.family + ) { + final byte[] exeTestCode; + synchronized ( exeTestLock ) { + byte[] _exeTestCode = null; + if( null == exeTestCodeRef || null == ( _exeTestCode = exeTestCodeRef.get() ) ) { + final String fname; + if( Platform.CPUType.X86_64 == PlatformPropsImpl.CPU_ARCH ) { + fname = "bin/exe-windows-x86_64.defl"; + } else { + fname = "bin/exe-windows-i386.defl"; + } + exeTestCode = readCode(fname); + exeTestCodeRef = new WeakReference(exeTestCode); + } else { + exeTestCode = _exeTestCode; + } + } + final FileOutputStream out = new FileOutputStream(exefile); + try { + out.write(exeTestCode, 0, exeTestCode.length); + try { + out.getFD().sync(); + } catch (final SyncFailedException sfe) { + ExceptionUtils.dumpThrowable("", sfe); + } + } finally { + out.close(); + } + } else { + final String shellCode = getExeTestShellCode(); + if( isStringSet(shellCode) ) { + final FileWriter fout = new FileWriter(exefile); + try { + fout.write(shellCode); + try { + fout.flush(); + } catch (final IOException sfe) { + ExceptionUtils.dumpThrowable("", sfe); + } + } finally { + fout.close(); + } + } + } + } private static boolean getOSHasNoexecFS() { switch(PlatformPropsImpl.OS_TYPE) { case OPENKODE: @@ -1026,44 +886,52 @@ public static class StreamMonitor implements Runnable { private final InputStream[] istreams; + private final boolean[] eos; private final PrintStream ostream; private final String prefix; public StreamMonitor(final InputStream[] streams, final PrintStream ostream, final String prefix) { this.istreams = streams; + this.eos = new boolean[streams.length]; this.ostream = ostream; this.prefix = prefix; - new Thread(this, "StreamMonitor-"+Thread.currentThread().getName()).start(); + final InterruptSource.Thread t = new InterruptSource.Thread(null, this, "StreamMonitor-"+Thread.currentThread().getName()); + t.setDaemon(true); + t.start(); } + @Override public void run() { final byte[] buffer = new byte[4096]; try { - int numRead; + final int streamCount = istreams.length; + int eosCount = 0; do { - numRead = 0; for(int i=0; i 0) { - if( null != ostream ) { - if( null != prefix ) { - ostream.write(prefix.getBytes()); + if( !eos[i] ) { + final int numReadI = istreams[i].read(buffer); + if (numReadI > 0) { + if( null != ostream ) { + if( null != prefix ) { + ostream.write(prefix.getBytes()); + } + ostream.write(buffer, 0, numReadI); } - ostream.write(buffer, 0, numReadI); + } else { + // numReadI == -1 + eosCount++; + eos[i] = true; } - numRead += numReadI; } } if( null != ostream ) { ostream.flush(); } - } while (numRead >= 0); - } - catch (final IOException e) { - for(int i=0; i: Not writeable dir"); } return false; } if(!getOSHasNoexecFS()) { - if(DEBUG) { + if( debug ) { System.err.println("IOUtil.testDirExec: <"+dir.getAbsolutePath()+">: Always executable"); } return true; } - final long t0 = DEBUG ? System.currentTimeMillis() : 0; - File exetst; + final long t0 = debug ? System.currentTimeMillis() : 0; + final File exeTestFile; + final boolean existingExe; try { - exetst = File.createTempFile("jogamp_exe_tst", getShellSuffix(), dir); + final File permExeTestFile = DEBUG_EXE_EXISTING_FILE ? new File(dir, "jogamp_exe_tst"+getExeTestFileSuffix()) : null; + if( null != permExeTestFile && permExeTestFile.exists() ) { + exeTestFile = permExeTestFile; + existingExe = true; + } else { + exeTestFile = File.createTempFile("jogamp_exe_tst", getExeTestFileSuffix(), dir); + existingExe = false; + } } catch (final SecurityException se) { throw se; // fwd Security exception } catch (final IOException e) { - if(DEBUG) { + if( debug ) { e.printStackTrace(); } return false; } - final long t1 = DEBUG ? System.currentTimeMillis() : 0; + final long t1 = debug ? System.currentTimeMillis() : 0; + long t2; int res = -1; - if(exetst.setExecutable(true /* exec */, true /* ownerOnly */)) { - final String shellCode = getShellCode(); + int exitValue = -1; + if( existingExe || exeTestFile.setExecutable(true /* exec */, true /* ownerOnly */) ) { + Process pr = null; try { - if( isStringSet(shellCode) ) { - final FileWriter fout = new FileWriter(exetst); - fout.write(shellCode); - fout.close(); + if( !existingExe ) { + fillExeTestFile(exeTestFile); } + t2 = debug ? System.currentTimeMillis() : 0; // Using 'Process.exec(String[])' avoids StringTokenizer of 'Process.exec(String)' // and hence splitting up command by spaces! - final Process pr = Runtime.getRuntime().exec(new String[] { exetst.getCanonicalPath() } ); - /** - * Disable StreamMonitor, which throttles exec-test performance a lot! - * - * if( isStringSet(shellCode) ) { + // Note: All no-exec cases throw an IOExceptions at ProcessBuilder.start(), i.e. below exec() call! + pr = Runtime.getRuntime().exec( getExeTestCommandArgs( exeTestFile.getCanonicalPath() ), null, null ); + if( DEBUG_EXE && !DEBUG_EXE_NOSTREAM ) { new StreamMonitor(new InputStream[] { pr.getInputStream(), pr.getErrorStream() }, System.err, "Exe-Tst: "); - } - */ - pr.waitFor() ; - res = pr.exitValue(); + } + pr.waitFor(); + exitValue = pr.exitValue(); // Note: Bug 1219 Comment 50: On reporter's machine exit value 1 is being returned + res = 0; // file has been executed } catch (final SecurityException se) { throw se; // fwd Security exception } catch (final Throwable t) { + t2 = debug ? System.currentTimeMillis() : 0; res = -2; - if(DEBUG) { - System.err.println("IOUtil.testDirExec: <"+exetst.getAbsolutePath()+">: Caught "+t.getClass().getSimpleName()+": "+t.getMessage()); - // t.printStackTrace(); + if( debug ) { + System.err.println("IOUtil.testDirExec: <"+exeTestFile.getAbsolutePath()+">: Caught "+t.getClass().getSimpleName()+": "+t.getMessage()); + t.printStackTrace(); + } + } finally { + if( null != pr ) { + // Bug 1219 Comment 58: Ensure that the launched process gets terminated! + // This is Process implementation specific and varies on different platforms, + // hence it may be required. + try { + pr.destroy(); + } catch (final Throwable t) { + ExceptionUtils.dumpThrowable("", t); + } } } + } else { + t2 = debug ? System.currentTimeMillis() : 0; + } + + final boolean ok = 0 == res; + if( !DEBUG_EXE && !existingExe ) { + exeTestFile.delete(); } - final long t2 = DEBUG ? System.currentTimeMillis() : 0; - exetst.delete(); - if( DEBUG) { - System.err.println("IOUtil.testDirExec(): <"+dir.getAbsolutePath()+">: res "+res); - System.err.println("IOUtil.testDirExec(): total "+(t2-t0)+"ms, create "+(t1-t0)+"ms, execute "+(t2-t1)+"ms"); + if( debug ) { + final long t3 = System.currentTimeMillis(); + System.err.println("IOUtil.testDirExec(): test-exe <"+exeTestFile.getAbsolutePath()+">, existingFile "+existingExe+", returned "+exitValue); + System.err.println("IOUtil.testDirExec(): abs-path <"+dir.getAbsolutePath()+">: res "+res+" -> "+ok); + System.err.println("IOUtil.testDirExec(): total "+(t3-t0)+"ms, create "+(t1-t0)+"ms, fill "+(t2-t1)+"ms, execute "+(t3-t2)+"ms"); } - return 0 == res; + return ok; } private static File testDirImpl(final File dir, final boolean create, final boolean executable, final String dbgMsg) @@ -1256,14 +1152,14 @@ * a dot is being prepended to {@link #tmpSubDir}, i.e.: {@code /home/user/.jogamp_0000/}. *

    * @param executable true if the user intents to launch executables from the temporary directory, otherwise false. - * @throws RuntimeException if no temporary directory could be determined + * @throws IOException if no temporary directory could be determined * @throws SecurityException if access to java.io.tmpdir is not allowed within the current security context * * @see PropertyAccess#getProperty(String, boolean) * @see Context#getDir(String, int) */ public static File getTempDir(final boolean executable) - throws SecurityException, RuntimeException + throws SecurityException, IOException { if(!tempRootSet) { // volatile: ok synchronized(IOUtil.class) { @@ -1388,7 +1284,7 @@ final File r = executable ? tempRootExec : tempRootNoexec ; if(null == r) { final String exe_s = executable ? "executable " : ""; - throw new RuntimeException("Could not determine a temporary "+exe_s+"directory"); + throw new IOException("Could not determine a temporary "+exe_s+"directory"); } final FilePermission fp = new FilePermission(r.getAbsolutePath(), "read,write,delete"); SecurityUtil.checkPermission(fp); @@ -1412,7 +1308,7 @@ * @param executable true if the temporary root folder needs to hold executable files, otherwise false. * @return * @throws IllegalArgumentException - * @throws IOException + * @throws IOException if no temporary directory could be determined or temp file could not be created * @throws SecurityException */ public static File createTempFile(final String prefix, final String suffix, final boolean executable) @@ -1435,4 +1331,29 @@ } } } + + /** + * Helper to simplify closing {@link Closeable}s. + * + * @param stream the {@link Closeable} instance to close + * @param saveOneIfFree cache for one {@link IOException} to store, if not already used (excess) + * @param dumpExcess dump the excess {@link IOException} on this {@link PrintStream} + * @return the excess {@link IOException} or {@code null}. + */ + public static IOException close(final Closeable stream, final IOException[] saveOneIfFree, final PrintStream dumpExcess) { + try { + stream.close(); + } catch(final IOException e) { + if( null == saveOneIfFree[0] ) { + saveOneIfFree[0] = e; + } else { + if( null != dumpExcess ) { + dumpExcess.println("Caught "+e.getClass().getSimpleName()+": "+e.getMessage()); + e.printStackTrace(dumpExcess); + } + return e; + } + } + return null; + } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/JarUtil.java gluegen2-2.3.2/src/java/com/jogamp/common/util/JarUtil.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/JarUtil.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/JarUtil.java 2015-10-09 04:18:28.000000000 +0000 @@ -35,7 +35,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.JarURLConnection; -import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; @@ -46,6 +45,7 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; +import com.jogamp.common.net.Uri; import com.jogamp.common.os.NativeLibrary; import com.jogamp.common.os.Platform; @@ -111,18 +111,18 @@ * @param clazzBinName "com.jogamp.common.GlueGenVersion" * @param cl * @return true if the class is loaded from a Jar file, otherwise false. - * @see {@link #getJarURI(String, ClassLoader)} + * @see {@link #getJarUri(String, ClassLoader)} */ - public static boolean hasJarURI(final String clazzBinName, final ClassLoader cl) { + public static boolean hasJarUri(final String clazzBinName, final ClassLoader cl) { try { - return null != getJarURI(clazzBinName, cl); + return null != getJarUri(clazzBinName, cl); } catch (final Exception e) { /* ignore */ } return false; } /** * The Class's "com.jogamp.common.GlueGenVersion" - * URI jar:sub_protocol:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class" + * Uri jar:sub_protocol:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class" * will be returned. *

    * sub_protocol may be "file", "http", etc.. @@ -131,108 +131,107 @@ * @param clazzBinName "com.jogamp.common.GlueGenVersion" * @param cl ClassLoader to locate the JarFile * @return "jar:sub_protocol:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class" - * @throws IllegalArgumentException if the URI doesn't match the expected formatting or null arguments + * @throws IllegalArgumentException if the Uri doesn't match the expected formatting or null arguments * @throws IOException if the class's Jar file could not been found by the ClassLoader - * @throws URISyntaxException if the URI could not be translated into a RFC 2396 URI + * @throws URISyntaxException if the Uri could not be translated into a RFC 2396 Uri * @see {@link IOUtil#getClassURL(String, ClassLoader)} */ - public static URI getJarURI(final String clazzBinName, final ClassLoader cl) throws IllegalArgumentException, IOException, URISyntaxException { + public static Uri getJarUri(final String clazzBinName, final ClassLoader cl) throws IllegalArgumentException, IOException, URISyntaxException { if(null == clazzBinName || null == cl) { throw new IllegalArgumentException("null arguments: clazzBinName "+clazzBinName+", cl "+cl); } - final URI uri; + final Uri uri; final URL url; { url = IOUtil.getClassURL(clazzBinName, cl); final String scheme = url.getProtocol(); if( null != resolver && - !scheme.equals( IOUtil.JAR_SCHEME ) && - !scheme.equals( IOUtil.FILE_SCHEME ) && - !scheme.equals( IOUtil.HTTP_SCHEME ) && - !scheme.equals( IOUtil.HTTPS_SCHEME ) ) + !scheme.equals( Uri.JAR_SCHEME ) && + !scheme.equals( Uri.FILE_SCHEME ) && + !scheme.equals( Uri.HTTP_SCHEME ) && + !scheme.equals( Uri.HTTPS_SCHEME ) ) { final URL _url = resolver.resolve( url ); - uri = _url.toURI(); + uri = Uri.valueOf(_url); if(DEBUG) { - System.err.println("getJarURI Resolver: "+url+"\n\t-> "+_url+"\n\t-> "+uri); + System.err.println("getJarUri Resolver: "+url+"\n\t-> "+_url+"\n\t-> "+uri); } } else { - uri = url.toURI(); + uri = Uri.valueOf(url); if(DEBUG) { - System.err.println("getJarURI Default "+url+"\n\t-> "+uri); + System.err.println("getJarUri Default "+url+"\n\t-> "+uri); } } } - // test name .. - if( !uri.getScheme().equals( IOUtil.JAR_SCHEME ) ) { - throw new IllegalArgumentException("URI is not using scheme "+IOUtil.JAR_SCHEME+": <"+uri+">"); + if( !uri.isJarScheme() ) { + throw new IllegalArgumentException("Uri is not using scheme "+Uri.JAR_SCHEME+": <"+uri+">"); } if(DEBUG) { - System.err.println("getJarURI res: "+clazzBinName+" -> "+url+" -> "+uri); + System.err.println("getJarUri res: "+clazzBinName+" -> "+url+" -> "+uri); } return uri; } /** - * The Class's Jar URI jar:sub_protocol:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class + * The Class's Jar Uri jar:sub_protocol:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class * Jar basename gluegen-rt.jar will be returned. *

    * sub_protocol may be "file", "http", etc.. *

    * - * @param classJarURI as retrieved w/ {@link #getJarURI(String, ClassLoader) getJarURI("com.jogamp.common.GlueGenVersion", cl).toURI()}, + * @param classJarUri as retrieved w/ {@link #getJarUri(String, ClassLoader) getJarUri("com.jogamp.common.GlueGenVersion", cl)}, * i.e. jar:sub_protocol:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class * @return gluegen-rt.jar - * @throws IllegalArgumentException if the URI doesn't match the expected formatting or is null + * @throws IllegalArgumentException if the Uri doesn't match the expected formatting or is null * @see {@link IOUtil#getClassURL(String, ClassLoader)} */ - public static String getJarBasename(final URI classJarURI) throws IllegalArgumentException { - if(null == classJarURI) { - throw new IllegalArgumentException("URI is null"); + public static Uri.Encoded getJarBasename(final Uri classJarUri) throws IllegalArgumentException { + if(null == classJarUri) { + throw new IllegalArgumentException("Uri is null"); } - if( !classJarURI.getScheme().equals(IOUtil.JAR_SCHEME) ) { - throw new IllegalArgumentException("URI is not using scheme "+IOUtil.JAR_SCHEME+": <"+classJarURI+">"); + if( !classJarUri.isJarScheme() ) { + throw new IllegalArgumentException("Uri is not using scheme "+Uri.JAR_SCHEME+": <"+classJarUri+">"); } - String uriS = classJarURI.getSchemeSpecificPart(); + Uri.Encoded ssp = classJarUri.schemeSpecificPart; // from // file:/some/path/gluegen-rt.jar!/com/jogamp/common/util/cache/TempJarCache.class // to // file:/some/path/gluegen-rt.jar - int idx = uriS.lastIndexOf(IOUtil.JAR_SCHEME_SEPARATOR); + int idx = ssp.lastIndexOf(Uri.JAR_SCHEME_SEPARATOR); if (0 <= idx) { - uriS = uriS.substring(0, idx); // exclude '!/' + ssp = ssp.substring(0, idx); // exclude '!/' } else { - throw new IllegalArgumentException("URI does not contain jar uri terminator '!', in <"+classJarURI+">"); + throw new IllegalArgumentException("Uri does not contain jar uri terminator '!', in <"+classJarUri+">"); } // from // file:/some/path/gluegen-rt.jar // to // gluegen-rt.jar - idx = uriS.lastIndexOf('/'); + idx = ssp.lastIndexOf('/'); if(0 > idx) { // no abs-path, check for protocol terminator ':' - idx = uriS.lastIndexOf(':'); + idx = ssp.lastIndexOf(':'); if(0 > idx) { - throw new IllegalArgumentException("URI does not contain protocol terminator ':', in <"+classJarURI+">"); + throw new IllegalArgumentException("Uri does not contain protocol terminator ':', in <"+classJarUri+">"); } } - uriS = uriS.substring(idx+1); // just the jar name + ssp = ssp.substring(idx+1); // just the jar name - if(0 >= uriS.lastIndexOf(".jar")) { - throw new IllegalArgumentException("No Jar name in <"+classJarURI+">"); + if(0 >= ssp.lastIndexOf(".jar")) { + throw new IllegalArgumentException("No Jar name in <"+classJarUri+">"); } if(DEBUG) { - System.err.println("getJarName res: "+uriS); + System.err.println("getJarName res: "+ssp); } - return uriS; + return ssp; } /** * The Class's com.jogamp.common.GlueGenVersion - * URI jar:sub_protocol:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class + * Uri jar:sub_protocol:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class * Jar basename gluegen-rt.jar will be returned. *

    * sub_protocol may be "file", "http", etc.. @@ -241,119 +240,54 @@ * @param clazzBinName com.jogamp.common.GlueGenVersion * @param cl * @return gluegen-rt.jar - * @throws IllegalArgumentException if the URI doesn't match the expected formatting + * @throws IllegalArgumentException if the Uri doesn't match the expected formatting * @throws IOException if the class's Jar file could not been found by the ClassLoader. - * @throws URISyntaxException if the URI could not be translated into a RFC 2396 URI + * @throws URISyntaxException if the Uri could not be translated into a RFC 2396 Uri * @see {@link IOUtil#getClassURL(String, ClassLoader)} */ - public static String getJarBasename(final String clazzBinName, final ClassLoader cl) throws IllegalArgumentException, IOException, URISyntaxException { - return getJarBasename( getJarURI(clazzBinName, cl) ); + public static Uri.Encoded getJarBasename(final String clazzBinName, final ClassLoader cl) throws IllegalArgumentException, IOException, URISyntaxException { + return getJarBasename( getJarUri(clazzBinName, cl) ); } /** - * The Class's Jar URI jar:sub_protocol:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class - * Jar file's sub URI sub_protocol:/some/path/gluegen-rt.jar will be returned. - *

    - * sub_protocol may be "file", "http", etc.. - *

    - * - * @param classJarURI as retrieved w/ {@link #getJarURI(String, ClassLoader) getJarURI("com.jogamp.common.GlueGenVersion", cl).toURI()}, - * i.e. jar:sub_protocol:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class - * @return sub_protocol:/some/path/gluegen-rt.jar - * @throws IllegalArgumentException if the URI doesn't match the expected formatting or is null - * @throws URISyntaxException if the URI could not be translated into a RFC 2396 URI - * @see {@link IOUtil#getClassURL(String, ClassLoader)} - */ - public static URI getJarSubURI(final URI classJarURI) throws IllegalArgumentException, URISyntaxException { - if(null == classJarURI) { - throw new IllegalArgumentException("URI is null"); - } - if( !classJarURI.getScheme().equals(IOUtil.JAR_SCHEME) ) { - throw new IllegalArgumentException("URI is not a using scheme "+IOUtil.JAR_SCHEME+": <"+classJarURI+">"); - } - - // from - // file:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class - // to - // file:/some/path/gluegen-rt.jar - final String uriSSP = classJarURI.getRawSchemeSpecificPart(); - final int idx = uriSSP.lastIndexOf(IOUtil.JAR_SCHEME_SEPARATOR); - final String uriSSPJar; - if (0 <= idx) { - uriSSPJar = uriSSP.substring(0, idx); // exclude '!/' - } else { - throw new IllegalArgumentException("JAR URI does not contain jar uri terminator '!', uri <"+classJarURI+">"); - } - if(0 >= uriSSPJar.lastIndexOf(".jar")) { - throw new IllegalArgumentException("No Jar name in <"+classJarURI+">"); - } - if(DEBUG) { - System.err.println("getJarSubURI res: "+classJarURI+" -> "+uriSSP+" -> "+uriSSPJar); - } - return new URI(uriSSPJar); - } - - /** - * The Class's Jar URI jar:sub_protocol:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class + * The Class's Jar Uri jar:sub_protocol:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class * Jar file's entry /com/jogamp/common/GlueGenVersion.class will be returned. * - * @param classJarURI as retrieved w/ {@link #getJarURI(String, ClassLoader) getJarURI("com.jogamp.common.GlueGenVersion", cl).toURI()}, + * @param classJarUri as retrieved w/ {@link #getJarUri(String, ClassLoader) getJarUri("com.jogamp.common.GlueGenVersion", cl)}, * i.e. jar:sub_protocol:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class * @return /com/jogamp/common/GlueGenVersion.class * @see {@link IOUtil#getClassURL(String, ClassLoader)} - * @deprecated Useless */ - public static String getJarEntry(final URI classJarURI) { - if(null == classJarURI) { - throw new IllegalArgumentException("URI is null"); + public static Uri.Encoded getJarEntry(final Uri classJarUri) { + if(null == classJarUri) { + throw new IllegalArgumentException("Uri is null"); } - if( !classJarURI.getScheme().equals(IOUtil.JAR_SCHEME) ) { - throw new IllegalArgumentException("URI is not a using scheme "+IOUtil.JAR_SCHEME+": <"+classJarURI+">"); + if( !classJarUri.isJarScheme() ) { + throw new IllegalArgumentException("Uri is not a using scheme "+Uri.JAR_SCHEME+": <"+classJarUri+">"); } - final String uriSSP = classJarURI.getSchemeSpecificPart(); - // Uri TODO ? final String uriSSP = classJarURI.getRawSchemeSpecificPart(); + final Uri.Encoded uriSSP = classJarUri.schemeSpecificPart; // from // file:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class // to // /com/jogamp/common/GlueGenVersion.class - final int idx = uriSSP.lastIndexOf(IOUtil.JAR_SCHEME_SEPARATOR); + final int idx = uriSSP.lastIndexOf(Uri.JAR_SCHEME_SEPARATOR); if (0 <= idx) { - final String res = uriSSP.substring(idx+1); // right of '!' + final Uri.Encoded res = uriSSP.substring(idx+1); // right of '!' // Uri TODO ? final String res = Uri.decode(uriSSP.substring(idx+1)); // right of '!' if(DEBUG) { - System.err.println("getJarEntry res: "+classJarURI+" -> "+uriSSP+" -> "+idx+" -> "+res); + System.err.println("getJarEntry res: "+classJarUri+" -> "+uriSSP+" -> "+idx+" -> "+res); } return res; } else { - throw new IllegalArgumentException("JAR URI does not contain jar uri terminator '!', uri <"+classJarURI+">"); + throw new IllegalArgumentException("JAR Uri does not contain jar uri terminator '!', uri <"+classJarUri+">"); } } /** - * The Class's com.jogamp.common.GlueGenVersion - * URI jar:sub_protocol:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class - * Jar file's sub URI sub_protocol:/some/path/gluegen-rt.jar will be returned. - *

    - * sub_protocol may be "file", "http", etc.. - *

    - * - * @param clazzBinName com.jogamp.common.GlueGenVersion - * @param cl - * @return sub_protocol:/some/path/gluegen-rt.jar - * @throws IllegalArgumentException if the URI doesn't match the expected formatting - * @throws IOException if the class's Jar file could not been found by the ClassLoader - * @throws URISyntaxException if the URI could not be translated into a RFC 2396 URI - * @see {@link IOUtil#getClassURL(String, ClassLoader)} - */ - public static URI getJarSubURI(final String clazzBinName, final ClassLoader cl) throws IllegalArgumentException, IOException, URISyntaxException { - return getJarSubURI( getJarURI(clazzBinName, cl) ); - } - - /** * The Class's "com.jogamp.common.GlueGenVersion" - * URI jar:sub_protocol:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class" - * Jar file URI jar:sub_protocol:/some/path/gluegen-rt.jar!/ will be returned. + * Uri jar:sub_protocol:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class" + * Jar file Uri jar:sub_protocol:/some/path/gluegen-rt.jar!/ will be returned. *

    * sub_protocol may be "file", "http", etc.. *

    @@ -361,34 +295,35 @@ * @param clazzBinName "com.jogamp.common.GlueGenVersion" * @param cl * @return "jar:sub_protocol:/some/path/gluegen-rt.jar!/" - * @throws IllegalArgumentException if the URI doesn't match the expected formatting or null arguments + * @throws IllegalArgumentException if the Uri doesn't match the expected formatting or null arguments * @throws IOException if the class's Jar file could not been found by the ClassLoader - * @throws URISyntaxException if the URI could not be translated into a RFC 2396 URI + * @throws URISyntaxException if the Uri could not be translated into a RFC 2396 Uri * @see {@link IOUtil#getClassURL(String, ClassLoader)} */ - public static URI getJarFileURI(final String clazzBinName, final ClassLoader cl) throws IllegalArgumentException, IOException, URISyntaxException { + public static Uri getJarFileUri(final String clazzBinName, final ClassLoader cl) throws IllegalArgumentException, IOException, URISyntaxException { if(null == clazzBinName || null == cl) { throw new IllegalArgumentException("null arguments: clazzBinName "+clazzBinName+", cl "+cl); } - final URI uri = new URI(IOUtil.JAR_SCHEME+IOUtil.SCHEME_SEPARATOR+getJarSubURI(clazzBinName, cl).toString()+"!/"); + final Uri jarSubUri = getJarUri(clazzBinName, cl).getContainedUri(); + final Uri uri = Uri.cast(Uri.JAR_SCHEME+Uri.SCHEME_SEPARATOR+jarSubUri.toString()+"!/"); if(DEBUG) { - System.err.println("getJarFileURI res: "+uri); + System.err.println("getJarFileUri res: "+uri); } return uri; } /** * @param baseUri file:/some/path/ - * @param jarFileName gluegen-rt.jar (URI encoded) + * @param jarFileName gluegen-rt.jar (Uri encoded) * @return jar:file:/some/path/gluegen-rt.jar!/ * @throws URISyntaxException * @throws IllegalArgumentException null arguments */ - public static URI getJarFileURI(final URI baseUri, final String jarFileName) throws IllegalArgumentException, URISyntaxException { + public static Uri getJarFileUri(final Uri baseUri, final Uri.Encoded jarFileName) throws IllegalArgumentException, URISyntaxException { if(null == baseUri || null == jarFileName) { - throw new IllegalArgumentException("null arguments: baseURI "+baseUri+", jarFileName "+jarFileName); + throw new IllegalArgumentException("null arguments: baseUri "+baseUri+", jarFileName "+jarFileName); } - return new URI(IOUtil.JAR_SCHEME+IOUtil.SCHEME_SEPARATOR+baseUri.toString()+jarFileName+"!/"); + return Uri.cast(Uri.JAR_SCHEME+Uri.SCHEME_SEPARATOR+baseUri.toString()+jarFileName+"!/"); } /** @@ -397,38 +332,38 @@ * @throws IllegalArgumentException null arguments * @throws URISyntaxException */ - public static URI getJarFileURI(final URI jarSubUri) throws IllegalArgumentException, URISyntaxException { + public static Uri getJarFileUri(final Uri jarSubUri) throws IllegalArgumentException, URISyntaxException { if(null == jarSubUri) { - throw new IllegalArgumentException("jarSubURI is null"); + throw new IllegalArgumentException("jarSubUri is null"); } - return new URI(IOUtil.JAR_SCHEME+IOUtil.SCHEME_SEPARATOR+jarSubUri.toString()+"!/"); + return Uri.cast(Uri.JAR_SCHEME+Uri.SCHEME_SEPARATOR+jarSubUri.toString()+"!/"); } /** - * @param jarSubUriS file:/some/path/gluegen-rt.jar (URI encoded) + * @param jarSubUriS file:/some/path/gluegen-rt.jar (Uri encoded) * @return jar:file:/some/path/gluegen-rt.jar!/ * @throws IllegalArgumentException null arguments * @throws URISyntaxException */ - public static URI getJarFileURI(final String jarSubUriS) throws IllegalArgumentException, URISyntaxException { + public static Uri getJarFileUri(final Uri.Encoded jarSubUriS) throws IllegalArgumentException, URISyntaxException { if(null == jarSubUriS) { - throw new IllegalArgumentException("jarSubURIS is null"); + throw new IllegalArgumentException("jarSubUriS is null"); } - return new URI(IOUtil.JAR_SCHEME+IOUtil.SCHEME_SEPARATOR+jarSubUriS+"!/"); + return Uri.cast(Uri.JAR_SCHEME+Uri.SCHEME_SEPARATOR+jarSubUriS+"!/"); } /** - * @param jarFileURI jar:file:/some/path/gluegen-rt.jar!/ + * @param jarFileUri jar:file:/some/path/gluegen-rt.jar!/ * @param jarEntry com/jogamp/common/GlueGenVersion.class * @return jar:file:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class * @throws IllegalArgumentException null arguments * @throws URISyntaxException */ - public static URI getJarEntryURI(final URI jarFileURI, final String jarEntry) throws IllegalArgumentException, URISyntaxException { + public static Uri getJarEntryUri(final Uri jarFileUri, final Uri.Encoded jarEntry) throws IllegalArgumentException, URISyntaxException { if(null == jarEntry) { throw new IllegalArgumentException("jarEntry is null"); } - return new URI(jarFileURI.toString()+jarEntry); + return Uri.cast(jarFileUri.toString()+jarEntry); } /** @@ -437,28 +372,28 @@ * @return JarFile containing the named class within the given ClassLoader * @throws IOException if the class's Jar file could not been found by the ClassLoader * @throws IllegalArgumentException null arguments - * @throws URISyntaxException if the URI could not be translated into a RFC 2396 URI - * @see {@link #getJarFileURI(String, ClassLoader)} + * @throws URISyntaxException if the Uri could not be translated into a RFC 2396 Uri + * @see {@link #getJarFileUri(String, ClassLoader)} */ public static JarFile getJarFile(final String clazzBinName, final ClassLoader cl) throws IOException, IllegalArgumentException, URISyntaxException { - return getJarFile( getJarFileURI(clazzBinName, cl) ); + return getJarFile( getJarFileUri(clazzBinName, cl) ); } /** - * @param jarFileURI jar:file:/some/path/gluegen-rt.jar!/ - * @return JarFile as named by URI within the given ClassLoader + * @param jarFileUri jar:file:/some/path/gluegen-rt.jar!/ + * @return JarFile as named by Uri within the given ClassLoader * @throws IllegalArgumentException null arguments * @throws IOException if the Jar file could not been found * @throws URISyntaxException */ - public static JarFile getJarFile(final URI jarFileURI) throws IOException, IllegalArgumentException, URISyntaxException { - if(null == jarFileURI) { - throw new IllegalArgumentException("null jarFileURI"); + public static JarFile getJarFile(final Uri jarFileUri) throws IOException, IllegalArgumentException, URISyntaxException { + if(null == jarFileUri) { + throw new IllegalArgumentException("null jarFileUri"); } if(DEBUG) { - System.err.println("getJarFile.0: "+jarFileURI.toString()); + System.err.println("getJarFile.0: "+jarFileUri.toString()); } - final URL jarFileURL = jarFileURI.toURL(); + final URL jarFileURL = jarFileUri.toURL(); if(DEBUG) { System.err.println("getJarFile.1: "+jarFileURL.toString()); } @@ -478,8 +413,22 @@ } /** - * Locates the {@link JarUtil#getJarFileURI(URI) Jar file URI} of a given resource - * relative to a given class's Jar's URI. + * See {@link #getRelativeOf(Class, com.jogamp.common.net.Uri.Encoded, com.jogamp.common.net.Uri.Encoded)}. + * @param classFromJavaJar URI encoded! + * @param cutOffInclSubDir URI encoded! + * @param relResPath URI encoded! + * @return + * @throws IllegalArgumentException + * @throws IOException + * @throws URISyntaxException + * @deprecated Use {@link #getRelativeOf(Class, com.jogamp.common.net.Uri.Encoded, com.jogamp.common.net.Uri.Encoded)}. + */ + public static java.net.URI getRelativeOf(final Class classFromJavaJar, final String cutOffInclSubDir, final String relResPath) throws IllegalArgumentException, IOException, URISyntaxException { + return getRelativeOf(classFromJavaJar, Uri.Encoded.cast(cutOffInclSubDir), Uri.Encoded.cast(relResPath)).toURI(); + } + /** + * Locates the {@link JarUtil#getJarFileUri(Uri) Jar file Uri} of a given resource + * relative to a given class's Jar's Uri. *
          *   class's jar url path + cutOffInclSubDir + relResPath,
          * 
    @@ -500,47 +449,47 @@ * * TODO: Enhance documentation! * - * @param classFromJavaJar Used to get the root URI for the class's Jar URI. + * @param classFromJavaJar Used to get the root Uri for the class's Jar Uri. * @param cutOffInclSubDir The cut off included sub-directory prepending the relative resource path. - * If the root URI includes cutOffInclSubDir, it is no more added to the result. - * @param relResPath The relative resource path. (URI encoded) - * @return The resulting resource URI, which is not tested. + * If the root Uri includes cutOffInclSubDir, it is no more added to the result. + * @param relResPath The relative resource path. (Uri encoded) + * @return The resulting resource Uri, which is not tested. * @throws IllegalArgumentException * @throws IOException * @throws URISyntaxException */ - public static URI getRelativeOf(final Class classFromJavaJar, final String cutOffInclSubDir, final String relResPath) throws IllegalArgumentException, IOException, URISyntaxException { + public static Uri getRelativeOf(final Class classFromJavaJar, final Uri.Encoded cutOffInclSubDir, final Uri.Encoded relResPath) throws IllegalArgumentException, IOException, URISyntaxException { final ClassLoader cl = classFromJavaJar.getClassLoader(); - final URI classJarURI = JarUtil.getJarURI(classFromJavaJar.getName(), cl); + final Uri classJarUri = JarUtil.getJarUri(classFromJavaJar.getName(), cl); if( DEBUG ) { - System.err.println("JarUtil.getRelativeOf: "+"(classFromJavaJar "+classFromJavaJar+", classJarURI "+classJarURI+ + System.err.println("JarUtil.getRelativeOf: "+"(classFromJavaJar "+classFromJavaJar+", classJarUri "+classJarUri+ ", cutOffInclSubDir "+cutOffInclSubDir+", relResPath "+relResPath+"): "); } - final URI jarSubURI = JarUtil.getJarSubURI( classJarURI ); - if(null == jarSubURI) { - throw new IllegalArgumentException("JarSubURI is null of: "+classJarURI); + final Uri jarSubUri = classJarUri.getContainedUri(); + if(null == jarSubUri) { + throw new IllegalArgumentException("JarSubUri is null of: "+classJarUri); } - final String jarUriRoot_s = IOUtil.getURIDirname( jarSubURI.toString() ); + final Uri.Encoded jarUriRoot = jarSubUri.getDirectory().getEncoded(); if( DEBUG ) { - System.err.println("JarUtil.getRelativeOf: "+"uri "+jarSubURI.toString()+" -> "+jarUriRoot_s); + System.err.println("JarUtil.getRelativeOf: "+"uri "+jarSubUri.toString()+" -> "+jarUriRoot); } - final String resUri_s; - if( jarUriRoot_s.endsWith(cutOffInclSubDir) ) { - resUri_s = jarUriRoot_s+relResPath; + final Uri.Encoded resUri; + if( jarUriRoot.endsWith(cutOffInclSubDir.get()) ) { + resUri = jarUriRoot.concat(relResPath); } else { - resUri_s = jarUriRoot_s+cutOffInclSubDir+relResPath; + resUri = jarUriRoot.concat(cutOffInclSubDir).concat(relResPath); } if( DEBUG ) { - System.err.println("JarUtil.getRelativeOf: "+"... -> "+resUri_s); + System.err.println("JarUtil.getRelativeOf: "+"... -> "+resUri); } - final URI resURI = JarUtil.getJarFileURI(resUri_s); + final Uri resJarUri = JarUtil.getJarFileUri(resUri); if( DEBUG ) { - System.err.println("JarUtil.getRelativeOf: "+"fin "+resURI); + System.err.println("JarUtil.getRelativeOf: "+"fin "+resJarUri); } - return resURI; + return resJarUri; } /** diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/JogampVersion.java gluegen2-2.3.2/src/java/com/jogamp/common/util/JogampVersion.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/JogampVersion.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/JogampVersion.java 2015-10-09 04:18:28.000000000 +0000 @@ -46,6 +46,9 @@ /** See {@link #getImplementationCommit()} */ public static final Attributes.Name IMPLEMENTATION_COMMIT = new Attributes.Name("Implementation-Commit"); + /** For FAT JogAmp jar files */ + private static final String packageNameFAT = "com.jogamp"; + private final String packageName; private final Manifest mf; private final int hash; @@ -55,12 +58,27 @@ private final String androidPackageVersionName; protected JogampVersion(final String packageName, final Manifest mf) { - this.packageName = packageName; - this.mf = ( null != mf ) ? mf : new Manifest(); + if( null != mf ) { + // use provided valid data + this.mf = mf; + this.packageName = packageName; + } else { + // try FAT jar file + final Manifest fatMF = VersionUtil.getManifest(JogampVersion.class.getClassLoader(), packageNameFAT); + if( null != fatMF ) { + // use FAT jar file + this.mf = fatMF; + this.packageName = packageNameFAT; + } else { + // use faulty data, unresolvable .. + this.mf = new Manifest(); + this.packageName = packageName; + } + } this.hash = this.mf.hashCode(); mainAttributes = this.mf.getMainAttributes(); mainAttributeNames = mainAttributes.keySet(); - androidPackageVersionName = AndroidUtils.getPackageInfoVersionName(packageName); // null if !Android + androidPackageVersionName = AndroidUtils.getPackageInfoVersionName(this.packageName); // null if !Android } @Override diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/ReflectionUtil.java gluegen2-2.3.2/src/java/com/jogamp/common/util/ReflectionUtil.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/ReflectionUtil.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/ReflectionUtil.java 2015-10-09 04:18:28.000000000 +0000 @@ -48,6 +48,7 @@ import jogamp.common.Debug; +import com.jogamp.common.ExceptionUtils; import com.jogamp.common.JogampRuntimeException; public final class ReflectionUtil { @@ -140,7 +141,7 @@ System.err.printf("ReflectionUtil.getClassImpl.%03d: %8.3f ms, init %b, [%s]@ Thread %s%n", forNameCount, nanoCosts/1e6, initializeClazz, cnl.toString(), Thread.currentThread().getName()); if(DEBUG) { - Thread.dumpStack(); + ExceptionUtils.dumpStack(System.err); } } return res; diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/RunnableTask.java gluegen2-2.3.2/src/java/com/jogamp/common/util/RunnableTask.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/RunnableTask.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/RunnableTask.java 2015-10-09 04:18:28.000000000 +0000 @@ -30,6 +30,8 @@ import java.io.PrintStream; +import com.jogamp.common.JogampRuntimeException; + /** * Helper class to provide a Runnable queue implementation with a Runnable wrapper * which notifies after execution for the invokeAndWait() semantics. @@ -38,70 +40,60 @@ protected final Runnable runnable; /** - * Invokes runnable on the current thread. - * @param waitUntilDone if true, waits until runnable execution is completed, otherwise returns immediately. - * @param runnable the {@link Runnable} to execute. + * @deprecated Simply invoke {@link Runnable#run()} */ public static void invoke(final boolean waitUntilDone, final Runnable runnable) { - Throwable throwable = null; - final Object sync = new Object(); - final RunnableTask rt = new RunnableTask( runnable, waitUntilDone ? sync : null, true, waitUntilDone ? null : System.err ); - synchronized(sync) { - rt.run(); - if( waitUntilDone ) { - try { - sync.wait(); - } catch (final InterruptedException ie) { - throwable = ie; - } - if(null==throwable) { - throwable = rt.getThrowable(); - } - if(null!=throwable) { - throw new RuntimeException(throwable); - } - } - } + runnable.run(); + } + + /** + * @deprecated Use {@link #invokeOnNewThread(ThreadGroup, String, boolean, Runnable)} + */ + public static Thread invokeOnNewThread(final ThreadGroup tg, final boolean waitUntilDone, final Runnable runnable, final String threadName) { + final RunnableTask rt = invokeOnNewThread(tg, threadName, waitUntilDone, runnable); + return rt.getExecutionThread(); } /** - * Invokes runnable on a new thread belonging to the given {@link ThreadGroup}. + * Invokes runnable on a new {@link InterruptSource.Thread}, + * see {@link InterruptSource.Thread#Thread(ThreadGroup, Runnable, String)} for details. * @param tg the {@link ThreadGroup} for the new thread, maybe null + * @param threadName the name for the new thread, maybe null * @param waitUntilDone if true, waits until runnable execution is completed, otherwise returns immediately. * @param runnable the {@link Runnable} to execute on the new thread. If waitUntilDone is true, - * the runnable must exist, i.e. not loop forever. - * @param threadName the name for the new thread - * @return the newly created {@link Thread} + * the runnable must exit, i.e. not loop forever. + * @return the newly created and invoked {@link RunnableTask} + * @since 2.3.2 */ - public static Thread invokeOnNewThread(final ThreadGroup tg, final boolean waitUntilDone, final Runnable runnable, final String threadName) { - final Thread t = new Thread(tg, threadName) { - @Override - public void run() { - Throwable throwable = null; - final Object sync = new Object(); - final RunnableTask rt = new RunnableTask( runnable, waitUntilDone ? sync : null, true, waitUntilDone ? null : System.err ); - synchronized(sync) { - rt.run(); - if( waitUntilDone ) { - try { - sync.wait(); - } catch (final InterruptedException ie) { - throwable = ie; - } - if(null==throwable) { - throwable = rt.getThrowable(); - } - if(null!=throwable) { - throw new RuntimeException(throwable); - } + public static RunnableTask invokeOnNewThread(final ThreadGroup tg, final String threadName, + final boolean waitUntilDone, final Runnable runnable) { + final RunnableTask rt; + if( !waitUntilDone ) { + rt = new RunnableTask( runnable, null, true, System.err ); + final InterruptSource.Thread t = InterruptSource.Thread.create(tg, rt, threadName); + t.start(); + } else { + final Object sync = new Object(); + rt = new RunnableTask( runnable, sync, true, null ); + final InterruptSource.Thread t = InterruptSource.Thread.create(tg, rt, threadName); + synchronized(sync) { + t.start(); + while( rt.isInQueue() ) { + try { + sync.wait(); + } catch (final InterruptedException ie) { + throw new InterruptedRuntimeException(ie); + } + final Throwable throwable = rt.getThrowable(); + if(null!=throwable) { + throw new JogampRuntimeException(throwable); } } - } }; - t.start(); - return t; + } + } + return rt; } - /** * Create a RunnableTask object w/ synchronization, * ie. suitable for invokeAndWait(), i.e. {@link #invoke(boolean, Runnable) invoke(true, runnable)}. @@ -126,6 +118,8 @@ @Override public final void run() { + execThread = Thread.currentThread(); + runnableException = null; tStarted = System.currentTimeMillis(); if(null == syncObject) { @@ -143,6 +137,7 @@ } } finally { tExecuted = System.currentTimeMillis(); + isExecuted = true; } } else { synchronized (syncObject) { @@ -160,6 +155,7 @@ } } finally { tExecuted = System.currentTimeMillis(); + isExecuted = true; syncObject.notifyAll(); } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/SourcedInterruptedException.java gluegen2-2.3.2/src/java/com/jogamp/common/util/SourcedInterruptedException.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/SourcedInterruptedException.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/SourcedInterruptedException.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,166 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.common.util; + +import java.io.PrintStream; + +import com.jogamp.common.ExceptionUtils; +import com.jogamp.common.ExceptionUtils.CustomStackTrace; + +/** + * {@link InterruptedException}, which may include the source, see {@link #getInterruptSource()}. + *

    + * This exception may be created directly where {@link #getCause()} returns {@code null}, + * or by propagating an existing {@link InterruptedException} as returned by {@link #getCause()}. + *

    + * @since 2.3.2 + */ +@SuppressWarnings("serial") +public class SourcedInterruptedException extends InterruptedException implements CustomStackTrace { + final Throwable interruptSource; + + /** + * Wraps the given {@link InterruptedException} into a {@link SourcedInterruptedException} + * if it is not yet of the desired type and + * if the current thread if a {@link InterruptSource}, i.e. the source is known. + *

    + * Otherwise the given {@link InterruptedException} instance is returned. + *

    + *

    + * In case method is creating a new wrapping instance, + * {@link InterruptSource#clearInterruptSource()} is being issued. + *

    + * + * @param ie the to be wrapped {@link InterruptedException} + */ + public static InterruptedException wrap(final InterruptedException ie) { + return wrap(ie, InterruptSource.Util.currentThread()); + } + + /** + * Wraps the given {@link InterruptedException} into a {@link SourcedInterruptedException} + * if it is not yet of the same type and if {@code source} is not {@code null}. + *

    + * Otherwise the given {@link InterruptedException} instance is returned. + *

    + *

    + * In case method is creating a new wrapping instance, + * {@link InterruptSource#clearInterruptSource()} is being issued. + *

    + * + * @param ie the to be wrapped {@link InterruptedException} + * @param source the {@link InterruptSource} + */ + public static InterruptedException wrap(final InterruptedException ie, final InterruptSource source) { + if( !(ie instanceof SourcedInterruptedException) && null != source ) { + return new SourcedInterruptedException(ie, source.getInterruptSource(true)); + } else { + return ie; + } + } + + /** + * @param message mandatory message of this exception + * @param cause optional propagated cause + * @param interruptSource optional propagated source of {@link Thread#interrupt()} call + */ + public SourcedInterruptedException(final String message, final InterruptedException cause, final Throwable interruptSource) { + super(message); + if( null != cause ) { + initCause(cause); + } + this.interruptSource = interruptSource; + } + + /** + * @param cause mandatory propagated cause + * @param interruptSource optional propagated source of {@link Thread#interrupt()} call + */ + public SourcedInterruptedException(final InterruptedException cause, final Throwable interruptSource) { + super(cause.getMessage()); + initCause(cause); + this.interruptSource = interruptSource; + } + + /** + * Returns the source of the {@link Thread#interrupt()} call if known, + * otherwise {@code null} is returned. + */ + public final Throwable getInterruptSource() { + return interruptSource; + } + + /** + * Returns the propagated {@link InterruptedException}, i.e. the cause of this exception, + * or {@code null} if not applicable. + *

    + * {@inheritDoc} + *

    + */ + @Override + public InterruptedException getCause() { + return (InterruptedException)super.getCause(); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(256); + sb.append(getClass().getSimpleName()).append(": "); + if (null != interruptSource) { + sb.append("[sourced]"); + } else { + sb.append("[unknown]"); + } + final String m = getLocalizedMessage(); + if( null != m ) { + sb.append(" ").append(m); + } + return sb.toString(); + } + + @Override + public final void printCauseStack(final PrintStream s, final String causeStr, final int causeIdx, final int stackDepth) { + final String s0 = causeStr+"["+causeIdx+"]"; + s.println(s0+" by "+getClass().getSimpleName()+": "+getMessage()+" on thread "+Thread.currentThread().getName()); + ExceptionUtils.dumpStack(s, getStackTrace(), 0, stackDepth); + if( null != interruptSource ) { + ExceptionUtils.printCause(s, s0, interruptSource, 0, 1, stackDepth); + } + } + + @Override + public final void printStackTrace(final PrintStream s, final int causeDepth, final int stackDepth) { + s.println(getClass().getSimpleName()+": "+getMessage()+" on thread "+Thread.currentThread().getName()); + ExceptionUtils.dumpStack(s, getStackTrace(), 0, stackDepth); + ExceptionUtils.printCause(s, "Caused", getCause(), 0, causeDepth, stackDepth); + if( null != interruptSource ) { + ExceptionUtils.printCause(s, "InterruptSource", interruptSource, 0, causeDepth, stackDepth); + } + } +} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/TaskBase.java gluegen2-2.3.2/src/java/com/jogamp/common/util/TaskBase.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/TaskBase.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/TaskBase.java 2015-10-09 04:18:28.000000000 +0000 @@ -54,7 +54,9 @@ protected Throwable runnableException; protected long tCreated, tStarted; protected volatile long tExecuted; + protected volatile boolean isExecuted; protected volatile boolean isFlushed; + protected volatile Thread execThread; protected TaskBase(final Object syncObject, final boolean catchExceptions, final PrintStream exceptionOut) { this.syncObject = syncObject; @@ -64,7 +66,9 @@ tCreated = System.currentTimeMillis(); tStarted = 0; tExecuted = 0; + isExecuted = false; isFlushed = false; + execThread = null; } protected final String getExceptionOutIntro() { @@ -77,6 +81,14 @@ } /** + * Returns the execution thread or {@code null} if not yet {@link #run()}. + * @since 2.3.2 + */ + public final Thread getExecutionThread() { + return execThread; + } + + /** * Return the synchronization object if any. * @see #RunnableTask(Runnable, Object, boolean) */ @@ -126,12 +138,12 @@ /** * @return !{@link #isExecuted()} && !{@link #isFlushed()} */ - public final boolean isInQueue() { return 0 != tExecuted && !isFlushed; } + public final boolean isInQueue() { return !isExecuted && !isFlushed; } /** * @return True if executed, otherwise false; */ - public final boolean isExecuted() { return 0 != tExecuted ; } + public final boolean isExecuted() { return isExecuted; } /** * @return True if flushed, otherwise false; @@ -159,7 +171,7 @@ @Override public String toString() { - return "RunnableTask[executed "+isExecuted()+", tTotal "+getDurationTotal()+" ms, tExec "+getDurationInExec()+" ms, tQueue "+getDurationInQueue()+" ms, attachment "+attachment+", throwable "+getThrowable()+"]"; + return "RunnableTask[enqueued "+isInQueue()+"[executed "+isExecuted()+", flushed "+isFlushed()+"], tTotal "+getDurationTotal()+" ms, tExec "+getDurationInExec()+" ms, tQueue "+getDurationInQueue()+" ms, attachment "+attachment+", throwable "+getThrowable()+"]"; } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/common/util/VersionUtil.java gluegen2-2.3.2/src/java/com/jogamp/common/util/VersionUtil.java --- gluegen2-2.2.4/src/java/com/jogamp/common/util/VersionUtil.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/common/util/VersionUtil.java 2015-10-09 04:18:28.000000000 +0000 @@ -58,23 +58,23 @@ // environment sb.append("Platform: ").append(Platform.getOSType()).append(" / ").append(Platform.getOSName()).append(' ').append(Platform.getOSVersion()).append(" (").append(Platform.getOSVersionNumber()).append("), "); - sb.append(Platform.getArchName()).append(" (arch), ").append(Platform.getABIType()).append(", "); - sb.append(Runtime.getRuntime().availableProcessors()).append(" cores"); + sb.append(Platform.getArchName()).append(" (").append(Platform.getCPUType()).append(", ").append(Platform.getABIType()).append("), "); + sb.append(Runtime.getRuntime().availableProcessors()).append(" cores, ").append("littleEndian ").append(PlatformPropsImpl.LITTLE_ENDIAN); sb.append(Platform.getNewline()); - if( AndroidVersion.isAvailable) { + if( Platform.OSType.ANDROID == PlatformPropsImpl.OS_TYPE ) { sb.append("Platform: Android Version: ").append(AndroidVersion.CODENAME).append(", "); sb.append(AndroidVersion.RELEASE).append(" [").append(AndroidVersion.RELEASE).append("], SDK: ").append(AndroidVersion.SDK_INT).append(", ").append(AndroidVersion.SDK_NAME); sb.append(Platform.getNewline()); } - Platform.getMachineDescription().toString(sb).append(Platform.getNewline()); + Platform.getMachineDataInfo().toString(sb).append(Platform.getNewline()); // JVM/JRE sb.append("Platform: Java Version: ").append(Platform.getJavaVersion()).append(" (").append(Platform.getJavaVersionNumber()).append("u").append(PlatformPropsImpl.JAVA_VERSION_UPDATE).append("), VM: ").append(Platform.getJavaVMName()); sb.append(", Runtime: ").append(Platform.getJavaRuntimeName()).append(Platform.getNewline()); sb.append("Platform: Java Vendor: ").append(Platform.getJavaVendor()).append(", ").append(Platform.getJavaVendorURL()); - sb.append(", JavaSE: ").append(Platform.isJavaSE()); - sb.append(", Java6: ").append(Platform.isJava6()); + sb.append(", JavaSE: ").append(PlatformPropsImpl.JAVA_SE); + sb.append(", Java6: ").append(PlatformPropsImpl.JAVA_6); sb.append(", AWT enabled: ").append(Platform.AWT_AVAILABLE); sb.append(Platform.getNewline()).append(SEPERATOR); diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/ant/GlueGenTask.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/ant/GlueGenTask.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/ant/GlueGenTask.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/ant/GlueGenTask.java 2015-10-09 04:18:28.000000000 +0000 @@ -73,7 +73,8 @@ emitter="[emitter class name]" config="[configuration file]" dumpCPP="[optional boolean]" - debug="[optional boolean]" /> + debug="[optional boolean]" + logLevel="[optional string]" /> * * * @author Rob Grzywinski rgrzywinski@yahoo.com @@ -101,6 +102,11 @@ private boolean debug=false; /** + *

    The optional logLevel.

    + */ + private String logLevel = null; + + /** *

    The optional dumpCPP flag.

    */ private boolean dumpCPP=false; @@ -182,6 +188,15 @@ } /** + *

    Set the logLevel (optional). This is called by ANT.

    + */ + public void setLogLevel(final String logLevel) + { + log( ("Setting logLevel: " + logLevel), Project.MSG_VERBOSE); + this.logLevel=logLevel; + } + + /** *

    Set the dumpCPP flag (optional). This is called by ANT.

    */ public void setDumpCPP(final boolean dumpCPP) @@ -456,6 +471,12 @@ gluegenCommandline.createArgument().setValue("--debug"); } + // add the logLevel if enabled + if(null != logLevel) { + gluegenCommandline.createArgument().setValue("--logLevel"); + gluegenCommandline.createArgument().setValue(logLevel); + } + // add the debug flag if enabled if(dumpCPP) { gluegenCommandline.createArgument().setValue("--dumpCPP"); diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/ASTLocusTag.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/ASTLocusTag.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/ASTLocusTag.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/ASTLocusTag.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,99 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.gluegen; + +/** + * An AST location tag. + */ +public class ASTLocusTag { + /** Source object, might be {@link String}. */ + public final Object source; + /** Line number, {@code -1} if undefined */ + public final int line; + /** Column number, {@code -1} if undefined */ + public final int column; + /** Source text reflecting current location, {@code null} if undefined */ + public final String text; + + public ASTLocusTag(final Object source, final int line, final int column, final String text) { + this.source = source; + this.line = line; + this.column = column; + this.text = text; + } + + public String toString() { + return toString(new StringBuilder(), null, true).toString(); + } + public StringBuilder toString(final StringBuilder sb, final String level, final boolean inclText) { + boolean preCol = false; + if (source != null) { + sb.append(source); + preCol = true; + } + if (line != -1) { + if( preCol ) { + sb.append(":"); + } else { + sb.append("line "); + } + sb.append(line); + if (column != -1) { + sb.append(":" + column); + } + preCol = true; + } + if( null != level && level.length()>0 ) { + if( preCol ) { + sb.append(": "); + } + sb.append(level); + preCol = true; + } + if( inclText && null != text && text.length()>0 ) { + if( preCol ) { + sb.append(": "); + } else { + sb.append("text "); + } + sb.append("'").append(text).append("'"); + } + return sb; + } + + /** + * Interface tag for {@link ASTLocusTag} provider. + */ + public static interface ASTLocusTagProvider { + /** + * Returns this instance's {@link ASTLocusTag}, if available, + * otherwise returns {@code null}. + */ + ASTLocusTag getASTLocusTag(); + } +} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/Define.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/Define.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/Define.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/Define.java 2015-10-09 04:18:28.000000000 +0000 @@ -39,18 +39,32 @@ package com.jogamp.gluegen.cgram; +import com.jogamp.gluegen.ASTLocusTag; +import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider; + /** Represents a #define of a literal to a value (a number represented in string form.) */ -public class Define { +public class Define implements ASTLocusTagProvider { private final String name; private final String value; + private final ASTLocusTag astLocus; public Define(final String name, final String value) { this.name = name; this.value = value; + this.astLocus = null; + } + + public Define(final String name, final String value, final ASTLocusTag astLocus) { + this.name = name; + this.value = value; + this.astLocus = astLocus; } public String getName() { return name; } public String getValue() { return value; } + + @Override + public ASTLocusTag getASTLocusTag() { return astLocus; } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/TNode.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/TNode.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/TNode.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/TNode.java 2015-10-09 04:18:28.000000000 +0000 @@ -3,10 +3,15 @@ import antlr.collections.AST; import antlr.CommonAST; import antlr.Token; + import java.lang.reflect.*; import java.util.Hashtable; import java.util.Enumeration; +import com.jogamp.gluegen.ASTLocusTag; +import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider; +import com.jogamp.gluegen.GlueGen; + /** Class TNode is an implementation of the AST interface and adds many useful features: @@ -29,7 +34,8 @@ */ -public class TNode extends CommonAST { +@SuppressWarnings("serial") +public class TNode extends CommonAST implements ASTLocusTagProvider { protected int ttype; protected String text; protected int lineNum = 0; @@ -40,7 +46,22 @@ protected Hashtable attributes = null; static String tokenVocabulary; - + /** + * {@inheritDoc} + *

    + * If source is not available, + * implementation returns {@code null}. + *

    + */ + @Override + public ASTLocusTag getASTLocusTag() { + final Object s = getAttribute("source"); + if( null != s ) { + return new ASTLocusTag(s, getLineNum(), -1, getText()); + } else { + return null; + } + } /** Set the token vocabulary to a tokentypes class @@ -159,15 +180,87 @@ text = text_; } - /** Returns the text for this node and all children */ - public String getAllChildrenText() { + static class DebugASTVisitor { + protected int level; + private String tabs(final StringBuilder sb) { + sb.setLength(0); + for (int i = 0; i < level; i++) { + sb.append(" "); + } + return sb.toString(); + } + DebugASTVisitor(final int level) { + this.level = level; + } + void visit(final AST node) { + final StringBuilder sb = new StringBuilder(); + AST node2; + for (node2 = node; node2 != null; node2 = node2.getNextSibling()) { + if (node2.getText() == null) { + System.err.printf("%03d: %snil [%d]%n", level, tabs(sb), node2.getType()); + } else { + System.err.printf("%03d: %s%s [%d]%n", level, tabs(sb), node2.getText(), node2.getType()); + } + if (node2.getFirstChild() != null) { + level++; + visit(node2.getFirstChild()); + level--; + } + } + } + } + + /** + * Returns the text for this node, its children and siblings. + *

    + * Implementation converts the AST LISP notation to serialized form. + *

    + */ + public String getAllChildrenText(final String name) { + if( GlueGen.debug() ) { + System.err.println("TNode.XXX: "+name); + new DebugASTVisitor(1).visit(getFirstChild()); + } final StringBuilder buf = new StringBuilder(); - buf.append(getText()); - for (TNode node = (TNode) getFirstChild(); node != null; node = (TNode) node.getNextSibling()) { - buf.append(node.getText()); + final TNode down = (TNode) this.getFirstChild(); + if( null == down ) { + buf.append(this.getText()); + } else { + getAllChildrenText(buf, this, down); } return buf.toString(); } + private static void getAllChildrenText(final StringBuilder buf, + final TNode upNode, TNode thisNode) { + boolean first = true; + while( null != thisNode ) { + final boolean isClosing = HeaderParserTokenTypes.RPAREN == thisNode.getType(); + final boolean isGroupStart = HeaderParserTokenTypes.NExpressionGroup == thisNode.getType(); + + final TNode nextNode = (TNode) thisNode.getNextSibling(); + final TNode downNode = (TNode) thisNode.getFirstChild(); + if( !isClosing && + ( null == downNode && null == nextNode || // unary + !first // binary + ) + ) { + buf.append(" ").append(upNode.getText()); + } + if( null != downNode ) { + if( !isGroupStart ) { + buf.append(" ("); + } + getAllChildrenText(buf, thisNode, downNode); + if( !isGroupStart ) { + buf.append(" )"); + } + } else if( !isClosing ) { + buf.append(" ").append(thisNode.getText()); + } + thisNode = nextNode; + first = false; + } + } /** return the last child of this node, or null if there is none */ public TNode getLastChild() { diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/AliasedSymbol.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/AliasedSymbol.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/AliasedSymbol.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/AliasedSymbol.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,185 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.gluegen.cgram.types; + +import java.util.HashSet; +import java.util.Set; + +/** + * Supports symbol aliasing, i.e. renaming, + * while preserving all its original names, i.e. aliases. + */ +public interface AliasedSymbol { + /** + * Rename this symbol with the given {@code newName} if not equal {@link #getName() current-name}. + *

    + * Before renaming the {@link #getName() current-name} will be added + * to the list of {@link #getAliasedNames() aliases}. + * while the given {@code newName} will be removed. + *

    + *

    + * Operation will be ignored if {@code newName} is {@code null}. + *

    + * @param newName the new {@link #getName() current-name}, maybe {@code null} + */ + void rename(final String newName); + /** + * Add the given {@code origName} to the list of {@link #getAliasedNames() aliases} + * if not equal {@link #getName() current-name}. + *

    + * Operation will be ignored if {@code newName} is {@code null}. + *

    + * @param origName the new alias to be added, maybe {@code null} + */ + void addAliasedName(final String origName); + /** + * + * Returns {@code true} if this symbol has aliases, i.e. either being {@link #rename(String) renamed} + * or {@link #addAliasedName(String) aliases-added}. + *

    + * Otherwise {@code false} is being returned. + *

    + */ + boolean hasAliases(); + /** + * Return all aliases for this symbol, i.e. original names, for this symbol. + *

    + * Inclusive {@link #getOrigName() original-name}, if {@link #rename(String) renamed}, + *

    + *

    + * Exclusive {@link #getName() current-name}. + *

    + *

    + * May return {@code null} or a zero sized {@link Set} for no aliases. + *

    + */ + Set getAliasedNames(); + /** + * Return the original-name as set at creation. + */ + String getOrigName(); + /** + * Return the current-name, which is the last {@link #rename(String) renamed-name} if issued, + * or the {@link #getOrigName() original-name}. + */ + String getName(); + /** + * Return this object's {@link #toString()} wrapped w/ the {@link #getName() current-name} + * and all {@link #getAliasedNames() aliases}. + */ + String getAliasedString(); + + public static class AliasedSymbolImpl implements AliasedSymbol { + private final String origName; + private final HashSet aliasedNames; + private String name; + + public AliasedSymbolImpl(final String origName) { + if( null == origName ) { + throw new IllegalArgumentException("Null origName not allowed"); + } + this.origName = origName; + this.aliasedNames=new HashSet(); + this.name = origName; + } + public AliasedSymbolImpl(final AliasedSymbolImpl o) { + this.origName = o.origName; + this.aliasedNames = new HashSet(o.aliasedNames); + this.name = o.name; + } + @Override + public void rename(final String newName) { + if( null != newName && !name.equals(newName) ) { + aliasedNames.add(name); + aliasedNames.remove(newName); + name = newName; + } + } + @Override + public void addAliasedName(final String origName) { + if( null != origName && !name.equals(origName) ) { + aliasedNames.add(origName); + } + } + @Override + public boolean hasAliases() { + return aliasedNames.size() > 0; + } + @Override + public Set getAliasedNames() { + return aliasedNames; + } + @Override + public String getOrigName() { + return origName; + } + @Override + public String getName() { + return name; + } + @Override + public String getAliasedString() { + return "["+name+", aliases "+aliasedNames.toString()+", "+toString()+"]"; + } + } + public static class NoneAliasedSymbol implements AliasedSymbol { + private final String name; + + public NoneAliasedSymbol(final String origName) { + this.name = origName; + } + @Override + public void rename(final String newName) { + throw new UnsupportedOperationException(); + } + @Override + public void addAliasedName(final String origName) { + throw new UnsupportedOperationException(); + } + @Override + public boolean hasAliases() { + return false; + } + @Override + public Set getAliasedNames() { + return null; + } + @Override + public String getOrigName() { + return name; + } + @Override + public String getName() { + return name; + } + @Override + public String getAliasedString() { + return toString(); + } + } +} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/ArrayType.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/ArrayType.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/ArrayType.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/ArrayType.java 2015-10-09 04:18:28.000000000 +0000 @@ -40,6 +40,8 @@ package com.jogamp.gluegen.cgram.types; +import com.jogamp.gluegen.ASTLocusTag; + /** Represents an array type. This differs from a pointer type in C syntax by the use of "[]" rather than "*". The length may or may not be known; if the length is unknown then a negative number @@ -48,50 +50,79 @@ public class ArrayType extends MemoryLayoutType implements Cloneable { private final Type elementType; private final int length; - private String computedName; - public ArrayType(final Type elementType, final SizeThunk sizeInBytes, final int length, final int cvAttributes) { - super(elementType.getName() + " *", sizeInBytes, cvAttributes); + public ArrayType(final Type elementType, final SizeThunk sizeInBytes, final int length, + final int cvAttributes) { + this(elementType, sizeInBytes, length, cvAttributes, null); + } + public ArrayType(final Type elementType, final SizeThunk sizeInBytes, final int length, + final int cvAttributes, final ASTLocusTag astLocus) { + super(elementType.getName() + " *", sizeInBytes, cvAttributes, astLocus); this.elementType = elementType; this.length = length; } + private ArrayType(final ArrayType o, final int cvAttributes, final ASTLocusTag astLocus) { + super(o, cvAttributes, astLocus); + elementType = o.elementType; + length = o.length; + } @Override - public boolean equals(final Object arg) { - if (arg == this) return true; - if (arg == null || (!(arg instanceof ArrayType))) { - return false; - } + Type newVariantImpl(final boolean newCVVariant, final int cvAttributes, final ASTLocusTag astLocus) { + return new ArrayType(this, cvAttributes, astLocus); + } + + @Override + protected int hashCodeImpl() { + // 31 * x == (x << 5) - x + final int hash = elementType.hashCode(); + return ((hash << 5) - hash) + length; + } + + @Override + protected boolean equalsImpl(final Type arg) { + final ArrayType t = (ArrayType) arg; + return elementType.equals(t.elementType) && + length == t.length; + } + + @Override + protected int hashCodeSemanticsImpl() { + // 31 * x == (x << 5) - x + final int hash = elementType.hashCodeSemantics(); + return ((hash << 5) - hash) + length; + } + + @Override + protected boolean equalSemanticsImpl(final Type arg) { final ArrayType t = (ArrayType) arg; - return (super.equals(arg) && elementType.equals(t.elementType) && (length == t.length)); + return elementType.equalSemantics(t.elementType) && + length == t.length; } @Override + public boolean isAnon() { return elementType.isAnon(); } + + @Override public String getName(final boolean includeCVAttrs) { - // Lazy computation of name due to lazy setting of compound type - // names during parsing - // Note: don't think cvAttributes can be set for array types (unlike pointer types) - if (computedName == null) { - computedName = (elementType.getName() + " *").intern(); - } - return computedName; + return elementType.getName() + " *"; } @Override - public ArrayType asArray() { return this; } + public final ArrayType asArray() { return this; } public Type getElementType() { return elementType; } public int getLength() { return length; } public boolean hasLength() { return length >= 0; } @Override - public Type getBaseElementType() { - ArrayType t = this; - while (t.getElementType().isArray()) { - t = t.getElementType().asArray(); - } - return t.getElementType(); - // return elementType.getBaseElementType(); + public final Type getBaseElementType() { + return elementType.getBaseElementType(); + } + + @Override + public final int arrayDimension() { + return 1 + elementType.arrayDimension(); } /** Recompute the size of this array if necessary. This needs to be @@ -114,7 +145,7 @@ if(elementType.isConst()) { buf.append("const "); } - buf.append(elementType.getName()); + buf.append(elementType.getCName()); if (variableName != null) { buf.append(" "); buf.append(variableName); @@ -130,9 +161,4 @@ super.visit(arg); elementType.visit(arg); } - - @Override - Type newCVVariant(final int cvAttributes) { - return new ArrayType(elementType, getSize(), length, cvAttributes); - } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/BitType.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/BitType.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/BitType.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/BitType.java 2015-10-09 04:18:28.000000000 +0000 @@ -40,6 +40,8 @@ package com.jogamp.gluegen.cgram.types; +import com.jogamp.gluegen.ASTLocusTag; + /** Represents a bitfield in a struct. */ public class BitType extends IntType implements Cloneable { @@ -47,22 +49,60 @@ private final int sizeInBits; private final int offset; - public BitType(final IntType underlyingType, final int sizeInBits, final int lsbOffset, final int cvAttributes) { - super(underlyingType.getName(), underlyingType.getSize(), underlyingType.isUnsigned(), cvAttributes); + public BitType(final IntType underlyingType, final int sizeInBits, final int lsbOffset, + final int cvAttributes, final ASTLocusTag astLocus) { + super(underlyingType.getName(), underlyingType.getSize(), underlyingType.isUnsigned(), cvAttributes, astLocus); this.underlyingType = underlyingType; this.sizeInBits = sizeInBits; this.offset = lsbOffset; } + private BitType(final BitType o, final int cvAttributes, final ASTLocusTag astLocus) { + super(o, cvAttributes, astLocus); + underlyingType = o.underlyingType; + sizeInBits = o.sizeInBits; + offset = o.offset; + } + + @Override + Type newVariantImpl(final boolean newCVVariant, final int cvAttributes, final ASTLocusTag astLocus) { + return new BitType(this, cvAttributes, astLocus); + } + + @Override + protected int hashCodeImpl() { + // 31 * x == (x << 5) - x + int hash = super.hashCodeImpl(); + hash = ((hash << 5) - hash) + underlyingType.hashCode(); + hash = ((hash << 5) - hash) + sizeInBits; + return ((hash << 5) - hash) + offset; + } + @Override - public boolean equals(final Object arg) { - if (arg == this) return true; - if (arg == null || (!(arg instanceof BitType))) { - return false; - } - final BitType t = (BitType) arg; - return (super.equals(arg) && underlyingType.equals(t.underlyingType) && - (sizeInBits == t.sizeInBits) && (offset == t.offset)); + protected boolean equalsImpl(final Type arg) { + final BitType t = (BitType) arg; + return super.equalsImpl(arg) && + underlyingType.equals(t.underlyingType) && + sizeInBits == t.sizeInBits && + offset == t.offset; + } + + @Override + protected int hashCodeSemanticsImpl() { + // 31 * x == (x << 5) - x + int hash = super.hashCodeSemanticsImpl(); + hash = ((hash << 5) - hash) + underlyingType.hashCodeSemantics(); + hash = ((hash << 5) - hash) + sizeInBits; + return ((hash << 5) - hash) + offset; + } + + @Override + protected boolean equalSemanticsImpl(final Type arg) { + final BitType t = (BitType) arg; + return super.equalSemanticsImpl(arg) && + underlyingType.equalSemantics(t.underlyingType) && + sizeInBits == t.sizeInBits && + offset == t.offset; } @Override @@ -84,9 +124,4 @@ super.visit(arg); underlyingType.visit(arg); } - - @Override - Type newCVVariant(final int cvAttributes) { - return new BitType(underlyingType, sizeInBits, offset, cvAttributes); - } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/CompoundType.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/CompoundType.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/CompoundType.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/CompoundType.java 2015-10-09 04:18:28.000000000 +0000 @@ -42,73 +42,110 @@ import java.util.*; +import com.jogamp.gluegen.ASTLocusTag; + /** Models all compound types, i.e., those containing fields: structs and unions. The boolean type accessors indicate how the type is really defined. */ -public abstract class CompoundType extends MemoryLayoutType implements Cloneable { +public abstract class CompoundType extends MemoryLayoutType implements Cloneable, AliasedSymbol { // The name "foo" in the construct "struct foo { ... }"; - private String structName; + private final String structName; private ArrayList fields; private boolean visiting; private boolean bodyParsed; - private boolean computedHashcode; - private int hashcode; - CompoundType(final String name, final SizeThunk size, final int cvAttributes, final String structName) { - super(name, size, cvAttributes); - this.structName = structName; + @Override + public void rename(final String newName) { + throw new UnsupportedOperationException(); } - - public static CompoundType create(final String name, final SizeThunk size, final CompoundTypeKind kind, final int cvAttributes) { + @Override + public void addAliasedName(final String origName) { + throw new UnsupportedOperationException(); + } + @Override + public boolean hasAliases() { + return false; + } + @Override + public Set getAliasedNames() { + return null; + } + @Override + public String getAliasedString() { + return toString(); + } + @Override + public String getOrigName() { + return getName(); + } + /** + * @param structName struct name of this CompoundType, i.e. the "foo" in the + construct {@code struct foo { int a, ... };} or {@code struct foo;} even for anonymous structs. + * @param size + * @param kind + * @param cvAttributes + * @return + */ + public static CompoundType create(final String structName, final SizeThunk size, + final CompoundTypeKind kind, final int cvAttributes, + final ASTLocusTag astLocus) + { + final CompoundType res; switch (kind) { case STRUCT: - return new StructType(name, size, cvAttributes); + res = new StructType(null, size, cvAttributes, structName, astLocus); + break; case UNION: - return new UnionType(name, size, cvAttributes); + res = new UnionType(null, size, cvAttributes, structName, astLocus); + break; default: throw new RuntimeException("OO relation "+kind+" / Compount not yet supported"); } + return res; } - @Override - public Object clone() { - final CompoundType n = (CompoundType) super.clone(); - if(null!=this.fields) { - n.fields = new ArrayList(this.fields); + CompoundType(final String name, final SizeThunk size, final int cvAttributes, + final String structName, final ASTLocusTag astLocus) { + super(null == name ? structName : name, size, cvAttributes, astLocus); + this.structName = structName; + } + + CompoundType(final CompoundType o, final int cvAttributes, final ASTLocusTag astLocus) { + super(o, cvAttributes, astLocus); + this.structName = o.structName; + if(null != o.fields) { + fields = new ArrayList(o.fields); } - return n; + bodyParsed = o.bodyParsed; } @Override - public int hashCode() { - if (computedHashcode) { - return hashcode; - } + protected int hashCodeImpl() { + // 31 * x == (x << 5) - x + final int hash = 31 + ( null != structName ? structName.hashCode() : 0 ); + return ((hash << 5) - hash) + TypeComparator.listsHashCode(fields); + } - if (structName != null) { - hashcode = structName.hashCode(); - } else if (getName() != null) { - hashcode = getName().hashCode(); - } else { - hashcode = 0; - } + @Override + protected boolean equalsImpl(final Type arg) { + final CompoundType ct = (CompoundType) arg; + return ( (structName == null ? ct.structName == null : structName.equals(ct.structName)) || + (structName != null && structName.equals(ct.structName)) + ) && + TypeComparator.listsEqual(fields, ct.fields); + } - computedHashcode = true; - return hashcode; + @Override + protected int hashCodeSemanticsImpl() { + // 31 * x == (x << 5) - x + return TypeComparator.listsHashCodeSemantics(fields); } @Override - public boolean equals(final Object arg) { - if (arg == this) return true; - if (arg == null || !(arg instanceof CompoundType)) { - return false; - } - final CompoundType t = (CompoundType) arg; - return super.equals(arg) && - ((structName == null ? t.structName == null : structName.equals(t.structName)) || - (structName != null && structName.equals(t.structName))) && - listsEqual(fields, t.fields); + protected boolean equalSemanticsImpl(final Type arg) { + final CompoundType ct = (CompoundType) arg; + return TypeComparator.listsEqualSemantics(fields, ct.fields); } /** Returns the struct name of this CompoundType, i.e. the "foo" in @@ -117,22 +154,20 @@ return structName; } - /** Sets the struct name of this CompoundType, i.e. the "foo" in the - construct "struct foo { ... };". */ - public void setStructName(final String structName) { - this.structName = structName; - } - @Override - public void setSize(final SizeThunk size) { - super.setSize(size); - } + public CompoundType asCompound() { return this; } @Override - public CompoundType asCompound() { return this; } + public String getCName(final boolean includeCVAttrs) { + if( isTypedef() ) { + return getName(includeCVAttrs); + } else { + return (isStruct() ? "struct " : "union ")+getName(includeCVAttrs); + } + } ArrayList getFields() { return fields; } - void setFields(final ArrayList fields) { this.fields = fields; } + void setFields(final ArrayList fields) { this.fields = fields; clearCache(); } /** Returns the number of fields in this type. */ public int getNumFields() { @@ -147,17 +182,24 @@ /** Adds a field to this type. */ public void addField(final Field f) { if (bodyParsed) { - throw new RuntimeException("Body of this CompoundType has already been parsed; should not be adding more fields"); + throw new IllegalStateException("Body of this CompoundType has been already closed"); } if (fields == null) { fields = new ArrayList(); } fields.add(f); + clearCache(); } - /** Indicates to this CompoundType that its body has been parsed and - that no more {@link #addField} operations will be made. */ - public void setBodyParsed() { + /** + * Indicates to this CompoundType that its body has been parsed and + * that no more {@link #addField} operations will be made. + * @throws IllegalStateException If called twice. + */ + public void setBodyParsed() throws IllegalStateException { + if (bodyParsed) { + throw new IllegalStateException("Body of this CompoundType has been already closed"); + } bodyParsed = true; } @@ -169,8 +211,9 @@ @Override public String toString() { final String cvAttributesString = getCVAttributesString(); - if (getName() != null) { - return cvAttributesString + getName(); + final String cname = getCName(); + if ( null != cname ) { + return cvAttributesString + cname; } else if (getStructName() != null) { return cvAttributesString + "struct " + getStructName(); } else { @@ -188,12 +231,12 @@ super.visit(arg); final int n = getNumFields(); for (int i = 0; i < n; i++) { - final Field f = getField(i); - f.getType().visit(arg); + getField(i).getType().visit(arg); } } finally { visiting = false; } + return; } public String getStructString() { diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/DoubleType.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/DoubleType.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/DoubleType.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/DoubleType.java 2015-10-09 04:18:28.000000000 +0000 @@ -39,22 +39,22 @@ */ package com.jogamp.gluegen.cgram.types; +import com.jogamp.gluegen.ASTLocusTag; + /** Represents a double-word floating-point type (C type "double".) */ public class DoubleType extends PrimitiveType implements Cloneable { - public DoubleType(final String name, final SizeThunk size, final int cvAttributes) { - super(name, size, cvAttributes); + public DoubleType(final String name, final SizeThunk size, final int cvAttributes, final ASTLocusTag astLocus) { + super(name, size, cvAttributes, astLocus); + } + + private DoubleType(final DoubleType o, final int cvAttributes, final ASTLocusTag astLocus) { + super(o, cvAttributes, astLocus); } @Override - public boolean equals(final Object arg) { - if (arg == this) { - return true; - } - if (arg == null || (!(arg instanceof DoubleType))) { - return false; - } - return super.equals(arg); + Type newVariantImpl(final boolean newCVVariant, final int cvAttributes, final ASTLocusTag astLocus) { + return new DoubleType(this, cvAttributes, astLocus); } @Override @@ -63,7 +63,22 @@ } @Override - Type newCVVariant(final int cvAttributes) { - return new DoubleType(getName(), getSize(), cvAttributes); + protected int hashCodeImpl() { + return 0; + } + + @Override + protected boolean equalsImpl(final Type t) { + return true; + } + + @Override + protected int hashCodeSemanticsImpl() { + return 0; + } + + @Override + protected boolean equalSemanticsImpl(final Type t) { + return true; } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/EnumType.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/EnumType.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/EnumType.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/EnumType.java 2015-10-09 04:18:28.000000000 +0000 @@ -42,73 +42,132 @@ import java.util.ArrayList; import java.util.NoSuchElementException; +import com.jogamp.gluegen.ASTLocusTag; +import com.jogamp.gluegen.ConstantDefinition; +import com.jogamp.gluegen.ConstantDefinition.CNumber; +import com.jogamp.gluegen.GlueGenException; +import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp; + /** Describes enumerated types. Enumerations are like ints except that they have a set of named values. */ public class EnumType extends IntType implements Cloneable { - private IntType underlyingType; + public static class Enumerator implements TypeComparator.SemanticEqualityOp { + private final String name; + private final String expr; + private final CNumber number; - private static class Enum { + public Enumerator(final String name, final long value) { + this.name = name; + this.number = new CNumber(false, false, value); + this.expr = this.number.toJavaString(); + } + public Enumerator(final String name, final CNumber number) { + this.name = name; + this.number = number; + this.expr = this.number.toJavaString(); + } + public Enumerator(final String name, final String value) { + this.name = name; + this.expr = value; + this.number = ConstantDefinition.decodeIntegerNumber(value); + } - String name; - long value; + public String getName() { return name; } + public String getExpr() { return expr; } + public CNumber getNumber() { return number; } + public boolean hasNumber() { return null != number; } - Enum(final String name, final long value) { - this.name = name; - this.value = value; + @Override + public int hashCode() { + // 31 * x == (x << 5) - x + final int hash = name.hashCode(); + return ((hash << 5) - hash) + expr.hashCode(); } - String getName() { - return name; + @Override + public boolean equals(final Object arg) { + if (arg == this) { + return true; + } else if ( !(arg instanceof Enumerator) ) { + return false; + } + final Enumerator t = (Enumerator) arg; + return name.equals(t.name) && + expr.equals(t.expr); } - long getValue() { - return value; + @Override + public int hashCodeSemantics() { + return hashCode(); } + + @Override + public boolean equalSemantics(final SemanticEqualityOp arg) { + return equals(arg); + } + + @Override + public String toString() { return "["+name+" = ["+expr+", "+number+"]"; } } - private ArrayList enums; + private final IntType underlyingType; + private ArrayList enums; public EnumType(final String name) { super(name, SizeThunk.LONG, false, CVAttributes.CONST); this.underlyingType = new IntType(name, SizeThunk.LONG, false, CVAttributes.CONST); } - public EnumType(final String name, final SizeThunk enumSizeInBytes) { - super(name, enumSizeInBytes, false, CVAttributes.CONST); - this.underlyingType = new IntType(name, enumSizeInBytes, false, CVAttributes.CONST); + public EnumType(final String name, final SizeThunk enumSizeInBytes, final ASTLocusTag astLocus) { + super(name, enumSizeInBytes, false, CVAttributes.CONST, astLocus); + this.underlyingType = new IntType(name, enumSizeInBytes, false, CVAttributes.CONST, astLocus); } - protected EnumType(final String name, final IntType underlyingType, final int cvAttributes) { - super(name, underlyingType.getSize(), underlyingType.isUnsigned(), cvAttributes); - this.underlyingType = underlyingType; + private EnumType(final EnumType o, final int cvAttributes, final ASTLocusTag astLocus) { + super(o, cvAttributes, astLocus); + underlyingType = o.underlyingType; + if(null != o.enums) { + enums = new ArrayList(o.enums); + } } @Override - public Object clone() { - final EnumType n = (EnumType) super.clone(); - if(null!=this.underlyingType) { - n.underlyingType = (IntType) this.underlyingType.clone(); - } - if(null!=this.enums) { - n.enums = new ArrayList(this.enums); - } - return n; + Type newVariantImpl(final boolean newCVVariant, final int cvAttributes, final ASTLocusTag astLocus) { + return new EnumType(this, cvAttributes, astLocus); } @Override - public boolean equals(final Object arg) { - if (arg == this) { - return true; - } - if (arg == null || (!(arg instanceof EnumType))) { - return false; - } + protected int hashCodeImpl() { + // 31 * x == (x << 5) - x + int hash = super.hashCodeImpl(); + hash = ((hash << 5) - hash) + underlyingType.hashCode(); + return ((hash << 5) - hash) + TypeComparator.listsHashCode(enums); + } + + @Override + protected boolean equalsImpl(final Type arg) { + final EnumType t = (EnumType) arg; + return super.equalsImpl(arg) && + underlyingType.equals(t.underlyingType) && + TypeComparator.listsEqual(enums, t.enums); + } + + @Override + protected int hashCodeSemanticsImpl() { + // 31 * x == (x << 5) - x + int hash = super.hashCodeSemanticsImpl(); + hash = ((hash << 5) - hash) + underlyingType.hashCodeSemantics(); + return ((hash << 5) - hash) + TypeComparator.listsHashCodeSemantics(enums); + } + + @Override + protected boolean equalSemanticsImpl(final Type arg) { final EnumType t = (EnumType) arg; - return (super.equals(arg) - && underlyingType.equals(t.underlyingType) - && listsEqual(enums, t.enums)); + return super.equalSemanticsImpl(arg) && + underlyingType.equalSemantics(t.underlyingType) && + TypeComparator.listsEqualSemantics(enums, t.enums); } @Override @@ -116,11 +175,14 @@ return this; } - public void addEnum(final String name, final long val) { + public Type getUnderlyingType() { return this.underlyingType; } + + public void addEnum(final String name, final Enumerator newEnum) { if (enums == null) { - enums = new ArrayList(); + enums = new ArrayList(); } - enums.add(new Enum(name, val)); + enums.add(newEnum); + clearCache(); } /** Number of enumerates defined in this enum. */ @@ -128,22 +190,17 @@ return enums.size(); } - /** Fetch ith (0..getNumEnumerates() - 1) name */ - public String getEnumName(final int i) { - return (enums.get(i)).getName(); + /** Fetch ith (0..getNumEnumerates() - 1) {@link Enumerator} */ + public Enumerator getEnum(final int i) { + return enums.get(i); } - /** Fetch ith (0..getNumEnumerates() - 1) value */ - public long getEnumValue(final int i) { - return (enums.get(i)).getValue(); - } - - /** Fetch the value of the enumerate with the given name. */ - public long getEnumValue(final String name) { + /** Fetch the enumerate with the given name. */ + public Enumerator getEnum(final String name) { for (int i = 0; i < enums.size(); ++i) { - final Enum n = (enums.get(i)); + final Enumerator n = (enums.get(i)); if (n.getName().equals(name)) { - return n.getValue(); + return n; } } throw new NoSuchElementException( @@ -166,25 +223,30 @@ */ public boolean removeEnumerate(final String name) { for (int i = 0; i < enums.size(); ++i) { - final Enum e = enums.get(i); + final Enumerator e = enums.get(i); if (e.getName().equals(name)) { enums.remove(e); + clearCache(); return true; } } return false; } + public StringBuilder appendEnums(final StringBuilder sb, final boolean cr) { + for(int i=0; i **/ -public class FunctionSymbol { +public class FunctionSymbol extends AliasedSymbolImpl implements AliasedSemanticSymbol, ASTLocusTagProvider { - private final String name; private final FunctionType type; + private final ASTLocusTag astLocus; public FunctionSymbol(final String name, final FunctionType type) { - this.name = name; + super(name); this.type = type; + this.astLocus = null; } - public String getName() { - return name; + public FunctionSymbol(final String name, final FunctionType type, final ASTLocusTag locus) { + super(name); + this.type = type; + this.astLocus = locus; } + /** Shallow'ish copy, only aliased names are re-created. */ + public static FunctionSymbol cloneWithDeepAliases(final FunctionSymbol o) { + return new FunctionSymbol(o); + } + /** Warning: Shallow'ish copy, only aliased names are re-created. */ + private FunctionSymbol(final FunctionSymbol o) { + super(o); + this.type = o.type; + this.astLocus = o.astLocus; + } + + @Override + public ASTLocusTag getASTLocusTag() { return astLocus; } + /** Returns the type of this function. Do not add arguments to it directly; use addArgument instead. */ public FunctionType getType() { @@ -99,7 +124,7 @@ @Override public String toString() { - return getType().toString(getName()); + return getType().toString(getName(), false); } /** Helper routine for emitting native javadoc tags */ @@ -109,10 +134,10 @@ @Override public int hashCode() { - if (name == null) { + if (getName() == null) { return 0; } - return name.hashCode(); + return getName().hashCode(); } @Override @@ -120,25 +145,54 @@ if (arg == this) { return true; } - - if (arg == null || (!(arg instanceof FunctionSymbol))) { + if ( !(arg instanceof FunctionSymbol) ) { return false; } - final FunctionSymbol other = (FunctionSymbol) arg; - if (getName() == null && other.getName() != null) { return false; } - return getName().equals(other.getName()); } + @Override + public int hashCodeSemantics() { + return type.hashCodeSemantics(); + } + @Override + public final boolean equalSemantics(final SemanticEqualityOp arg) { + if (arg == this) { + return true; + } + if ( !(arg instanceof FunctionSymbol) ) { + return false; + } + final FunctionSymbol other = (FunctionSymbol) arg; + return type.equalSemantics(other.type); + } + + + public static boolean containsExactly(final List l, final FunctionSymbol s) { + return exactIndexOf(l, s) >= 0; + } + + public static int exactIndexOf(final List l, final FunctionSymbol s) { + final int size = l.size(); + for (int i = 0; i < size; i++) { + final FunctionSymbol e = l.get(i); + if( null == s && null == e || + s.equals( e ) && s.type.equals(e.type) ) { + return i; + } + } + return -1; + } + /** * Compares the function type as well, since {@link #equals(Object)} * and {@link #hashCode()} won't. */ - public boolean isCompletelyEqual(final Object arg) { + public boolean exactlyEqual(final Object arg) { if( !this.equals(arg) ) { return false; } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/FunctionType.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/FunctionType.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/FunctionType.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/FunctionType.java 2015-10-09 04:18:28.000000000 +0000 @@ -41,6 +41,8 @@ import java.util.*; +import com.jogamp.gluegen.ASTLocusTag; + /** Describes a function type, used to model both function declarations and (via PointerType) function pointers. */ public class FunctionType extends Type implements Cloneable { @@ -49,35 +51,63 @@ private ArrayList argumentTypes; private ArrayList argumentNames; - public FunctionType(final String name, final SizeThunk size, final Type returnType, final int cvAttributes) { - super(name, size, cvAttributes); + public FunctionType(final String name, final SizeThunk size, final Type returnType, + final int cvAttributes) { + this(name, size, returnType, cvAttributes, null); + } + public FunctionType(final String name, final SizeThunk size, final Type returnType, + final int cvAttributes, final ASTLocusTag astLocus) { + super(name, size, cvAttributes, astLocus); this.returnType = returnType; } - @Override - public Object clone() { - final FunctionType n = (FunctionType) super.clone(); - if(null!=this.argumentTypes) { - n.argumentTypes = new ArrayList(this.argumentTypes); + private FunctionType(final FunctionType o, final ASTLocusTag astLocus) { + super(o, o.getCVAttributes(), astLocus); + returnType = o.returnType; + if(null != o.argumentTypes) { + argumentTypes = new ArrayList(o.argumentTypes); } - if(null!=this.argumentNames) { - n.argumentNames = new ArrayList(this.argumentNames); + if(null != o.argumentNames) { + argumentNames = new ArrayList(o.argumentNames); } - return n; } @Override - public boolean equals(final Object arg) { - if (arg == this) { - return true; - } - if (arg == null || (!(arg instanceof FunctionType))) { - return false; + Type newVariantImpl(final boolean newCVVariant, final int cvAttributes, final ASTLocusTag astLocus) { + if( newCVVariant ) { + // Functions don't have const/volatile attributes + return this; + } else { + return new FunctionType(this, astLocus); } + } + + @Override + protected int hashCodeImpl() { + // 31 * x == (x << 5) - x + final int hash = returnType.hashCode(); + return ((hash << 5) - hash) + TypeComparator.listsHashCode(argumentTypes); + } + + @Override + protected boolean equalsImpl(final Type arg) { + final FunctionType t = (FunctionType) arg; + return returnType.equals(t.returnType) && + TypeComparator.listsEqual(argumentTypes, t.argumentTypes); + } + + @Override + protected int hashCodeSemanticsImpl() { + // 31 * x == (x << 5) - x + final int hash = returnType.hashCodeSemantics(); + return ((hash << 5) - hash) + TypeComparator.listsHashCodeSemantics(argumentTypes); + } + + @Override + protected boolean equalSemanticsImpl(final Type arg) { final FunctionType t = (FunctionType) arg; - return (super.equals(arg) - && returnType.equals(t.returnType) - && listsEqual(argumentTypes, t.argumentTypes)); + return returnType.equalSemantics(t.returnType) && + TypeComparator.listsEqualSemantics(argumentTypes, t.argumentTypes); } @Override @@ -115,28 +145,27 @@ } argumentTypes.add(argumentType); argumentNames.add(argumentName); + clearCache(); } public void setArgumentName(final int i, final String name) { argumentNames.set(i, name); + clearCache(); } @Override public String toString() { - return toString(null); - } - - public String toString(final String functionName) { - return toString(functionName, false); + return toString(null, false); } public String toString(final String functionName, final boolean emitNativeTag) { return toString(functionName, null, emitNativeTag, false); } - String toString(final String functionName, final String callingConvention, final boolean emitNativeTag, final boolean isPointer) { + String toString(final String functionName, final String callingConvention, + final boolean emitNativeTag, final boolean isPointer) { final StringBuilder res = new StringBuilder(); - res.append(getReturnType()); + res.append(getReturnType().getCName(true)); res.append(" "); if (isPointer) { res.append("("); @@ -169,7 +198,7 @@ } else if (t.isArray()) { res.append(t.asArray().toString(getArgumentName(i))); } else { - res.append(t); + res.append(t.getCName(true)); final String argumentName = getArgumentName(i); if (argumentName != null) { res.append(" "); @@ -193,10 +222,4 @@ getArgumentType(i).visit(arg); } } - - @Override - Type newCVVariant(final int cvAttributes) { - // Functions don't have const/volatile attributes - return this; - } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/IntType.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/IntType.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/IntType.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/IntType.java 2015-10-09 04:18:28.000000000 +0000 @@ -39,37 +39,95 @@ */ package com.jogamp.gluegen.cgram.types; +import com.jogamp.gluegen.ASTLocusTag; + public class IntType extends PrimitiveType implements Cloneable { private final boolean unsigned; - private boolean typedefedUnsigned; + private boolean typedefUnsigned; public IntType(final String name, final SizeThunk size, final boolean unsigned, final int cvAttributes) { - this(name, size, unsigned, cvAttributes, false); + this(name, size, unsigned, cvAttributes, null); } - public IntType(final String name, final SizeThunk size, final boolean unsigned, final int cvAttributes, final boolean typedefedUnsigned) { - super(name, size, cvAttributes); + public IntType(final String name, final SizeThunk size, + final boolean unsigned, final int cvAttributes, + final ASTLocusTag astLocus) { + super(name, size, cvAttributes, astLocus); this.unsigned = unsigned; - this.typedefedUnsigned = typedefedUnsigned; + this.typedefUnsigned = false; } - @Override - public boolean equals(final Object arg) { - if (arg == this) { - return true; - } - if (arg == null || (!(arg instanceof IntType))) { - return false; + /** + * Only for HeaderParser! + * + * @param name the name + * @param size the size + * @param unsigned true if this instance is unsigned, not the typedef! + * @param cvAttributes the cvAttributes for this instance, not for the typedef! + * @param isTypedef true if this instance is a typedef variant + * @param typedefUnsigned true if the typedef itself is unsigned + * @param astLocus the location in source code + */ + public IntType(final String name, final SizeThunk size, + final boolean unsigned, final int cvAttributes, + final boolean isTypedef, final boolean typedefUnsigned, + final ASTLocusTag astLocus) { + super(name, size, cvAttributes, astLocus); + this.unsigned = unsigned; + if( isTypedef ) { + // the 'cvAttributes' are intended for this instance, not the 'typedef cvAttributes'! + setTypedef(0); + this.typedefUnsigned = typedefUnsigned; + } else { + this.typedefUnsigned = false; } + } + + IntType(final IntType o, final int cvAttributes, final ASTLocusTag astLocus) { + super(o, cvAttributes, astLocus); + this.unsigned = o.unsigned; + this.typedefUnsigned = o.typedefUnsigned; + } + + @Override + Type newVariantImpl(final boolean newCVVariant, final int cvAttributes, final ASTLocusTag astLocus) { + return new IntType(this, cvAttributes, astLocus); + } + + @Override + protected int hashCodeImpl() { + // 31 * x == (x << 5) - x + int hash = 1; + hash = ((hash << 5) - hash) + ( unsigned ? 1 : 0 ); + return ((hash << 5) - hash) + ( typedefUnsigned ? 1 : 0 ); + } + + @Override + protected boolean equalsImpl(final Type arg) { final IntType t = (IntType) arg; - return (super.equals(arg) && (unsigned == t.unsigned)); + return unsigned == t.unsigned && + typedefUnsigned == t.typedefUnsigned; } @Override - public void setName(final String name) { - super.setName(name); - typedefedUnsigned = unsigned; + protected int hashCodeSemanticsImpl() { + // 31 * x == (x << 5) - x + int hash = 1; + if( !relaxedEqSem ) { + hash = ((hash << 5) - hash) + ( unsigned ? 1 : 0 ); + hash = ((hash << 5) - hash) + ( typedefUnsigned ? 1 : 0 ); + } + return hash; + } + + @Override + protected boolean equalSemanticsImpl(final Type arg) { + final IntType t = (IntType) arg; + return relaxedEqSem || + ( unsigned == t.unsigned && + typedefUnsigned == t.typedefUnsigned + ); } @Override @@ -82,18 +140,27 @@ return unsigned; } - /** Indicates whether this type is an unsigned primitive type, as opposed to a typedef type that's unsigned. */ - public boolean isPrimitiveUnsigned() { - return unsigned && !typedefedUnsigned; + @Override + public String getCName(final boolean includeCVAttrs) { + if ( !unsigned || typedefUnsigned ) { + return super.getCName(includeCVAttrs); + } else { + return "unsigned "+super.getCName(includeCVAttrs); + } } @Override public String toString() { - return getCVAttributesString() + ((isUnsigned() & (!typedefedUnsigned)) ? "unsigned " : "") + getName(); + return getCVAttributesString() + ( unsigned && !typedefUnsigned ? "unsigned " : "") + getCName(); } @Override - Type newCVVariant(final int cvAttributes) { - return new IntType(getName(), getSize(), isUnsigned(), cvAttributes, typedefedUnsigned); + public boolean setTypedefName(final String name) { + if( super.setTypedefName(name) ) { + typedefUnsigned = unsigned; + return true; + } else { + return false; + } } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/MemoryLayoutType.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/MemoryLayoutType.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/MemoryLayoutType.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/MemoryLayoutType.java 2015-10-09 04:18:28.000000000 +0000 @@ -27,15 +27,23 @@ */ package com.jogamp.gluegen.cgram.types; +import com.jogamp.gluegen.ASTLocusTag; + public abstract class MemoryLayoutType extends Type { private boolean isLayouted; - protected MemoryLayoutType(final String name, final SizeThunk size, final int cvAttributes) { - super(name, size, cvAttributes); + protected MemoryLayoutType(final String name, final SizeThunk size, final int cvAttributes, final ASTLocusTag astLocus) { + super(name, size, cvAttributes, astLocus); isLayouted = false; } + MemoryLayoutType(final MemoryLayoutType o, final int cvAttributes, final ASTLocusTag astLocus) { + super(o, cvAttributes, astLocus); + isLayouted = o.isLayouted; + } public boolean isLayouted() { return isLayouted; } - public void setLayouted() { isLayouted = true; } + public void setLayouted() { + isLayouted = true; + } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/PointerType.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/PointerType.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/PointerType.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/PointerType.java 2015-10-09 04:18:28.000000000 +0000 @@ -39,111 +39,124 @@ */ package com.jogamp.gluegen.cgram.types; +import com.jogamp.gluegen.ASTLocusTag; + public class PointerType extends Type implements Cloneable { private final Type targetType; - private String computedName; - private boolean hasTypedefedName; public PointerType(final SizeThunk size, final Type targetType, final int cvAttributes) { + this(size, targetType, cvAttributes, null); + } + public PointerType(final SizeThunk size, final Type targetType, final int cvAttributes, final ASTLocusTag astLocus) { // can pass null for the final name parameter because the PointerType's getName() // completely replaces superclass behavior - this(size, targetType, cvAttributes, false, null); + super(targetType.getName() + " *", size, cvAttributes, astLocus); + this.targetType = targetType; } - private PointerType(final SizeThunk size, final Type targetType, final int cvAttributes, final boolean hasTypedefedName, final String typedefedName) { - super(targetType.getName() + " *", size, cvAttributes); - this.hasTypedefedName = false; - this.targetType = targetType; - if (hasTypedefedName) { - setName(typedefedName); - } + private PointerType(final PointerType o, final int cvAttributes, final ASTLocusTag astLocus) { + super(o, cvAttributes, astLocus); + targetType = o.targetType; } @Override - public int hashCode() { - return targetType.hashCode(); + Type newVariantImpl(final boolean newCVVariant, final int cvAttributes, final ASTLocusTag astLocus) { + return new PointerType(this, cvAttributes, astLocus); } @Override - public boolean equals(final Object arg) { - if (arg == this) { - return true; - } - if (arg == null || (!(arg instanceof PointerType))) { - return false; - } + protected int hashCodeImpl() { + return targetType.hashCode(); + } + + @Override + protected boolean equalsImpl(final Type arg) { final PointerType t = (PointerType) arg; - // Note we ignore the name of this type (which might be a typedef - // name) for comparison purposes because this is what allows - // e.g. a newly-fabricated type "PIXELFORMATDESCRIPTOR *" to be - // canonicalized to e.g. "LPPIXELFORMATDESCRIPTOR" - return ((getSize() == t.getSize()) - && (getCVAttributes() == t.getCVAttributes()) - && targetType.equals(t.targetType)); + return targetType.equals(t.targetType); + } + + @Override + protected int hashCodeSemanticsImpl() { + return targetType.hashCodeSemantics(); } @Override - public void setName(final String name) { - super.setName(name); - hasTypedefedName = true; + protected boolean equalSemanticsImpl(final Type arg) { + final PointerType pt = (PointerType) arg; + return targetType.equalSemantics(pt.targetType); + } + + @Override + public boolean isAnon() { + if ( isTypedef() ) { + return super.isAnon(); + } else { + return targetType.isAnon(); + } } @Override public String getName(final boolean includeCVAttrs) { - if (hasTypedefedName) { + if ( isTypedef() ) { return super.getName(includeCVAttrs); + } else if (!includeCVAttrs) { + return targetType.getName(includeCVAttrs) + " *"; } else { - // Lazy computation of name due to lazy setting of compound type - // names during parsing - if (computedName == null) { - computedName = (targetType.getName(includeCVAttrs) + " *").intern(); - } - if (!includeCVAttrs) { - return computedName; - } return targetType.getName(includeCVAttrs) + " * " + getCVAttributesString(); } } - public boolean hasTypedefedName() { - return hasTypedefedName; + @Override + public String getCName(final boolean includeCVAttrs) { + if ( isTypedef() ) { + return super.getCName(includeCVAttrs); + } else if (!includeCVAttrs) { + return targetType.getCName(includeCVAttrs) + " *"; + } else { + return targetType.getCName(includeCVAttrs) + " * " + getCVAttributesString(); + } } @Override - public PointerType asPointer() { + public final PointerType asPointer() { return this; } - public Type getTargetType() { + @Override + public final Type getTargetType() { return targetType; } @Override - public Type getBaseElementType() { - /** - if(targetType.isPointer()) { - return ((PointerType)targetType).getBaseElementType(); - } else { - return targetType; - } */ + public final Type getBaseElementType() { return targetType.getBaseElementType(); } @Override - public boolean isFunctionPointer() { + public final boolean isFunctionPointer() { return targetType.isFunction(); } @Override + public final int pointerDepth() { + return 1 + targetType.pointerDepth(); + } + + @Override public String toString() { - if (hasTypedefedName) { - return super.getName(true); + if ( isTypedef() ) { + return super.getCName(true); + } else { + return toStringInt(); + } + } + private String toStringInt() { + if (!targetType.isFunction()) { + return targetType.getCName(true) + " * " + getCVAttributesString(); } else { - if (!targetType.isFunction()) { - return targetType.toString() + " * " + getCVAttributesString(); - } - return toString(null, null); // this is a pointer to an unnamed function + // return toString(null, null); // this is a pointer to an unnamed function + return ((FunctionType) targetType).toString(null /* functionName */, null /* callingConvention */, false, true); } } @@ -162,9 +175,4 @@ super.visit(arg); targetType.visit(arg); } - - @Override - Type newCVVariant(final int cvAttributes) { - return new PointerType(getSize(), targetType, cvAttributes, hasTypedefedName, (hasTypedefedName ? getName() : null)); - } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/PrimitiveType.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/PrimitiveType.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/PrimitiveType.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/PrimitiveType.java 2015-10-09 04:18:28.000000000 +0000 @@ -39,10 +39,16 @@ */ package com.jogamp.gluegen.cgram.types; +import com.jogamp.gluegen.ASTLocusTag; + public abstract class PrimitiveType extends Type implements Cloneable { - protected PrimitiveType(final String name, final SizeThunk size, final int cvAttributes) { - super(name, size, cvAttributes); + protected PrimitiveType(final String name, final SizeThunk size, final int cvAttributes, final ASTLocusTag astLocus) { + super(name, size, cvAttributes, astLocus); + } + + PrimitiveType(final PrimitiveType o, final int cvAttributes, final ASTLocusTag astLocus) { + super(o, cvAttributes, astLocus); } @Override diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/SizeThunk.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/SizeThunk.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/SizeThunk.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/SizeThunk.java 2015-10-09 04:18:28.000000000 +0000 @@ -40,18 +40,26 @@ package com.jogamp.gluegen.cgram.types; -import com.jogamp.common.os.MachineDescription; +import com.jogamp.common.os.MachineDataInfo; +import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp; /** Provides a level of indirection between the definition of a type's size and the absolute value of this size. Necessary when generating glue code for two different CPU architectures (e.g., 32-bit and 64-bit) from the same internal representation of the various types involved. */ -public abstract class SizeThunk implements Cloneable { +public abstract class SizeThunk implements Cloneable, SemanticEqualityOp { + /* pp */ static boolean relaxedEqSem = false; private final boolean fixedNativeSize; + public static void setRelaxedEqualSemanticsTest(final boolean v) { + relaxedEqSem = v; + } + // Private constructor because there are only a few of these - private SizeThunk(final boolean fixedNativeSize) { this.fixedNativeSize = fixedNativeSize; } + private SizeThunk(final boolean fixedNativeSize) { + this.fixedNativeSize = fixedNativeSize; + } @Override public Object clone() { @@ -64,106 +72,191 @@ public final boolean hasFixedNativeSize() { return fixedNativeSize; } - public abstract long computeSize(MachineDescription machDesc); - public abstract long computeAlignment(MachineDescription machDesc); + public abstract long computeSize(MachineDataInfo machDesc); + public abstract long computeAlignment(MachineDataInfo machDesc); + + @Override + public final int hashCode() { + final int hash = 0x02DEAD6F; // magic hash start + return ((hash << 5) - hash) + hashCodeImpl(); + } + /* pp */ abstract int hashCodeImpl(); + + @Override + public final boolean equals(final Object arg) { + if (arg == this) { + return true; + } else if ( !(arg instanceof SizeThunk) ) { + return false; + } else { + final SizeThunk t = (SizeThunk) arg; + return hashCodeImpl() == t.hashCodeImpl(); + } + } + + @Override + public final int hashCodeSemantics() { + final int hash = 0x01DEAD5F; // magic hash start + return ((hash << 5) - hash) + hashCodeSemanticsImpl(); + } + /* pp */ abstract int hashCodeSemanticsImpl(); + + @Override + public final boolean equalSemantics(final SemanticEqualityOp arg) { + if (arg == this) { + return true; + } else if ( !(arg instanceof SizeThunk) ) { + return false; + } else { + final SizeThunk t = (SizeThunk) arg; + return hashCodeSemanticsImpl() == t.hashCodeSemanticsImpl(); + } + } + + static final int magic_int08 = 0x00000010; + static final int magic_int16 = 0x00000012; + static final int magic_int32 = 0x00000014; + static final int magic_intxx = 0x00000016; + static final int magic_long64 = 0x00000020; + static final int magic_longxx = 0x00000022; + static final int magic_float32 = 0x00000030; + static final int magic_float64 = 0x00000032; + static final int magic_aptr64 = 0x00000040; + static final int magic_ops = 0x00010000; public static final SizeThunk INT8 = new SizeThunk(true) { @Override - public long computeSize(final MachineDescription machDesc) { + public long computeSize(final MachineDataInfo machDesc) { return machDesc.int8SizeInBytes(); } @Override - public long computeAlignment(final MachineDescription machDesc) { + public long computeAlignment(final MachineDataInfo machDesc) { return machDesc.int8AlignmentInBytes(); } + @Override + protected int hashCodeImpl() { return 1; } + @Override + protected int hashCodeSemanticsImpl() { return relaxedEqSem ? magic_int32 : magic_int08; } }; public static final SizeThunk INT16 = new SizeThunk(true) { @Override - public long computeSize(final MachineDescription machDesc) { + public long computeSize(final MachineDataInfo machDesc) { return machDesc.int16SizeInBytes(); } @Override - public long computeAlignment(final MachineDescription machDesc) { + public long computeAlignment(final MachineDataInfo machDesc) { return machDesc.int16AlignmentInBytes(); } + @Override + protected int hashCodeImpl() { return 2; } + @Override + protected int hashCodeSemanticsImpl() { return relaxedEqSem ? magic_int32 : magic_int16; } }; public static final SizeThunk INT32 = new SizeThunk(true) { @Override - public long computeSize(final MachineDescription machDesc) { + public long computeSize(final MachineDataInfo machDesc) { return machDesc.int32SizeInBytes(); } @Override - public long computeAlignment(final MachineDescription machDesc) { + public long computeAlignment(final MachineDataInfo machDesc) { return machDesc.int32AlignmentInBytes(); } + @Override + protected int hashCodeImpl() { return 3; } + @Override + protected int hashCodeSemanticsImpl() { return magic_int32; } }; public static final SizeThunk INTxx = new SizeThunk(false) { @Override - public long computeSize(final MachineDescription machDesc) { + public long computeSize(final MachineDataInfo machDesc) { return machDesc.intSizeInBytes(); } @Override - public long computeAlignment(final MachineDescription machDesc) { + public long computeAlignment(final MachineDataInfo machDesc) { return machDesc.intAlignmentInBytes(); } + @Override + protected int hashCodeImpl() { return 4; } + @Override + protected int hashCodeSemanticsImpl() { return relaxedEqSem ? magic_int32 : magic_intxx; } }; public static final SizeThunk LONG = new SizeThunk(false) { @Override - public long computeSize(final MachineDescription machDesc) { + public long computeSize(final MachineDataInfo machDesc) { return machDesc.longSizeInBytes(); } @Override - public long computeAlignment(final MachineDescription machDesc) { + public long computeAlignment(final MachineDataInfo machDesc) { return machDesc.longAlignmentInBytes(); } + @Override + protected int hashCodeImpl() { return 5; } + @Override + protected int hashCodeSemanticsImpl() { return relaxedEqSem ? magic_long64 : magic_longxx; } }; public static final SizeThunk INT64 = new SizeThunk(true) { @Override - public long computeSize(final MachineDescription machDesc) { + public long computeSize(final MachineDataInfo machDesc) { return machDesc.int64SizeInBytes(); } @Override - public long computeAlignment(final MachineDescription machDesc) { + public long computeAlignment(final MachineDataInfo machDesc) { return machDesc.int64AlignmentInBytes(); } + @Override + protected int hashCodeImpl() { return 6; } + @Override + protected int hashCodeSemanticsImpl() { return magic_long64; } }; public static final SizeThunk FLOAT = new SizeThunk(true) { @Override - public long computeSize(final MachineDescription machDesc) { + public long computeSize(final MachineDataInfo machDesc) { return machDesc.floatSizeInBytes(); } @Override - public long computeAlignment(final MachineDescription machDesc) { + public long computeAlignment(final MachineDataInfo machDesc) { return machDesc.floatAlignmentInBytes(); } + @Override + protected int hashCodeImpl() { return 7; } + @Override + protected int hashCodeSemanticsImpl() { return magic_float32; } }; public static final SizeThunk DOUBLE = new SizeThunk(true) { @Override - public long computeSize(final MachineDescription machDesc) { + public long computeSize(final MachineDataInfo machDesc) { return machDesc.doubleSizeInBytes(); } @Override - public long computeAlignment(final MachineDescription machDesc) { + public long computeAlignment(final MachineDataInfo machDesc) { return machDesc.doubleAlignmentInBytes(); } + @Override + protected int hashCodeImpl() { return 8; } + @Override + protected int hashCodeSemanticsImpl() { return magic_float64; } }; public static final SizeThunk POINTER = new SizeThunk(false) { @Override - public long computeSize(final MachineDescription machDesc) { + public long computeSize(final MachineDataInfo machDesc) { return machDesc.pointerSizeInBytes(); } @Override - public long computeAlignment(final MachineDescription machDesc) { + public long computeAlignment(final MachineDataInfo machDesc) { return machDesc.pointerAlignmentInBytes(); } + @Override + protected int hashCodeImpl() { return 9; } + @Override + protected int hashCodeSemanticsImpl() { return magic_aptr64; } }; // Factory methods for performing certain limited kinds of @@ -172,15 +265,24 @@ final SizeThunk thunk2) { return new SizeThunk(false) { @Override - public long computeSize(final MachineDescription machDesc) { + public long computeSize(final MachineDataInfo machDesc) { return thunk1.computeSize(machDesc) + thunk2.computeSize(machDesc); } @Override - public long computeAlignment(final MachineDescription machDesc) { + public long computeAlignment(final MachineDataInfo machDesc) { final long thunk1A = thunk1.computeAlignment(machDesc); final long thunk2A = thunk2.computeAlignment(machDesc); return ( thunk1A > thunk2A ) ? thunk1A : thunk2A ; } + @Override + protected int hashCodeImpl() { + // 31 * x == (x << 5) - x + int hash = 31 + 10; + hash = ((hash << 5) - hash) + ( null != thunk1 ? thunk1.hashCode() : 0 ); + return ((hash << 5) - hash) + ( null != thunk2 ? thunk2.hashCode() : 0 ); + } + @Override + protected int hashCodeSemanticsImpl() { return magic_ops + 1; } }; } @@ -188,15 +290,24 @@ final SizeThunk thunk2) { return new SizeThunk(false) { @Override - public long computeSize(final MachineDescription machDesc) { + public long computeSize(final MachineDataInfo machDesc) { return thunk1.computeSize(machDesc) * thunk2.computeSize(machDesc); } @Override - public long computeAlignment(final MachineDescription machDesc) { + public long computeAlignment(final MachineDataInfo machDesc) { final long thunk1A = thunk1.computeAlignment(machDesc); final long thunk2A = thunk2.computeAlignment(machDesc); return ( thunk1A > thunk2A ) ? thunk1A : thunk2A ; } + @Override + protected int hashCodeImpl() { + // 31 * x == (x << 5) - x + int hash = 31 + 11; + hash = ((hash << 5) - hash) + ( null != thunk1 ? thunk1.hashCode() : 0 ); + return ((hash << 5) - hash) + ( null != thunk2 ? thunk2.hashCode() : 0 ); + } + @Override + protected int hashCodeSemanticsImpl() { return magic_ops + 2; } }; } @@ -204,26 +315,50 @@ final SizeThunk alignmentThunk) { return new SizeThunk(false) { @Override - public long computeSize(final MachineDescription machDesc) { - // x % 2n == x & (2n - 1) - // remainder = net_size & ( alignment - 1 ) - // padding = alignment - remainder ; - // aligned_size = net_size + padding ; + public long computeSize(final MachineDataInfo machDesc) { + /** + * padding = ( alignment - ( net_size % alignment ) ) % alignment ; + * aligned_size = net_size + padding ; + * + * With x % 2n == x & (2n - 1) + * + * Either: + * remainder = net_size & ( alignment - 1 ) + * padding = ( remainder > 0 ) ? alignment - remainder ; + * aligned_size = net_size + padding ; + * + * Or: + * padding = ( alignment - ( net_size & ( alignment - 1 ) ) ) & ( alignment - 1 ); + * aligned_size = net_size + padding ; + * + */ - final long size = offsetThunk.computeSize(machDesc); + final long net_size = offsetThunk.computeSize(machDesc); final long alignment = alignmentThunk.computeAlignment(machDesc); - final long remainder = size & ( alignment - 1 ) ; + /** + final long remainder = net_size & ( alignment - 1 ) ; final long padding = (remainder > 0) ? alignment - remainder : 0; - return size + padding; + */ + final long padding = ( alignment - ( net_size & ( alignment - 1 ) ) ) & ( alignment - 1 ); + return net_size + padding; } @Override - public long computeAlignment(final MachineDescription machDesc) { + public long computeAlignment(final MachineDataInfo machDesc) { final long thunk1A = offsetThunk.computeAlignment(machDesc); final long thunk2A = alignmentThunk.computeAlignment(machDesc); return ( thunk1A > thunk2A ) ? thunk1A : thunk2A ; } + @Override + protected int hashCodeImpl() { + // 31 * x == (x << 5) - x + int hash = 31 + 12; + hash = ((hash << 5) - hash) + ( null != offsetThunk ? offsetThunk.hashCode() : 0 ); + return ((hash << 5) - hash) + ( null != alignmentThunk ? alignmentThunk.hashCode() : 0 ); + } + @Override + protected int hashCodeSemanticsImpl() { return magic_ops + 3; } }; } @@ -231,28 +366,45 @@ final SizeThunk thunk2) { return new SizeThunk(false) { @Override - public long computeSize(final MachineDescription machDesc) { + public long computeSize(final MachineDataInfo machDesc) { return Math.max(thunk1.computeSize(machDesc), thunk2.computeSize(machDesc)); } @Override - public long computeAlignment(final MachineDescription machDesc) { + public long computeAlignment(final MachineDataInfo machDesc) { final long thunk1A = thunk1.computeAlignment(machDesc); final long thunk2A = thunk2.computeAlignment(machDesc); return ( thunk1A > thunk2A ) ? thunk1A : thunk2A ; } + @Override + protected int hashCodeImpl() { + // 31 * x == (x << 5) - x + int hash = 31 + 13; + hash = ((hash << 5) - hash) + ( null != thunk1 ? thunk1.hashCode() : 0 ); + return ((hash << 5) - hash) + ( null != thunk2 ? thunk2.hashCode() : 0 ); + } + @Override + protected int hashCodeSemanticsImpl() { return magic_ops + 4; } }; } public static SizeThunk constant(final int constant) { return new SizeThunk(false) { @Override - public long computeSize(final MachineDescription machDesc) { + public long computeSize(final MachineDataInfo machDesc) { return constant; } @Override - public long computeAlignment(final MachineDescription machDesc) { + public long computeAlignment(final MachineDataInfo machDesc) { return 1; // no alignment for constants } + @Override + protected int hashCodeImpl() { + // 31 * x == (x << 5) - x + final int hash = 31 + 14; + return ((hash << 5) - hash) + constant; + } + @Override + protected int hashCodeSemanticsImpl() { return magic_ops + 5; } }; } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/StructLayout.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/StructLayout.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/StructLayout.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/StructLayout.java 2015-10-09 04:18:28.000000000 +0000 @@ -40,7 +40,7 @@ package com.jogamp.gluegen.cgram.types; -import com.jogamp.common.os.MachineDescription; +import com.jogamp.common.os.MachineDataInfo; import com.jogamp.gluegen.GlueGen; /** Encapsulates algorithm for laying out data structures. Note that @@ -67,9 +67,9 @@ SizeThunk curOffset = SizeThunk.constant(baseOffset); SizeThunk maxSize = SizeThunk.constant(0); - final MachineDescription dbgMD; + final MachineDataInfo dbgMD; if( GlueGen.debug() ) { - dbgMD = MachineDescription.StaticConfig.X86_64_UNIX.md; + dbgMD = MachineDataInfo.StaticConfig.LP64_UNIX.md; System.err.printf("SL.__: o %03d, s %03d, t %s{%d}%n", curOffset.computeSize(dbgMD), 0, t, t.getNumFields()); } else { dbgMD = null; diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/StructType.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/StructType.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/StructType.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/StructType.java 2015-10-09 04:18:28.000000000 +0000 @@ -27,34 +27,25 @@ */ package com.jogamp.gluegen.cgram.types; +import com.jogamp.gluegen.ASTLocusTag; + public class StructType extends CompoundType { - public StructType(final String name, final SizeThunk size, final int cvAttributes) { - this(name, size, cvAttributes, null); + StructType(final String name, final SizeThunk size, final int cvAttributes, final String structName, final ASTLocusTag astLocus) { + super (name, size, cvAttributes, structName, astLocus); } - StructType(final String name, final SizeThunk size, final int cvAttributes, final String structName) { - super (name, size, cvAttributes, structName); + private StructType(final StructType o, final int cvAttributes, final ASTLocusTag astLocus) { + super(o, cvAttributes, astLocus); } @Override - public boolean equals(final Object arg) { - if (arg == null || !(arg instanceof StructType)) { - return false; - } - return super.equals(arg); + Type newVariantImpl(final boolean newCVVariant, final int cvAttributes, final ASTLocusTag astLocus) { + return new StructType(this, cvAttributes, astLocus); } @Override public final boolean isStruct() { return true; } @Override public final boolean isUnion() { return false; } - - @Override - Type newCVVariant(final int cvAttributes) { - final StructType t = new StructType(getName(), getSize(), cvAttributes, getStructName()); - t.setFields(getFields()); - return t; - } - } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/TypeComparator.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/TypeComparator.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/TypeComparator.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/TypeComparator.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,143 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.gluegen.cgram.types; + +import java.util.List; + +public class TypeComparator { + /** + * Supports semantic equality and hash functions for types. + */ + public static interface SemanticEqualityOp { + /** + * Semantic hashcode for Types exclusive its given {@link #getName() name}. + * @see #equalSemantics(SemanticEqualityOp) + */ + int hashCodeSemantics(); + + /** + * Semantic equality test for Types exclusive its given {@link #getName() name}. + * @see #hashCodeSemantics() + */ + boolean equalSemantics(final SemanticEqualityOp arg); + } + /** + * Supports common interface for {@link SemanticEqualityOp} and {@link AliasedSymbol}. + */ + public static interface AliasedSemanticSymbol extends AliasedSymbol, SemanticEqualityOp { }; + + /** Helper routine for list equality comparison*/ + static boolean listsEqual(final List a, final List b) { + if( a == null ) { + if( null != b ) { + return false; + } else { + return true; // elements equal, i.e. both null + } + } + if( b != null && a.size() == b.size() ) { + final int count = a.size(); + for(int i=0; i int listsHashCode(final List a) { + if( a == null ) { + return 0; + } else { + final int count = a.size(); + int hash = 31; + for(int i=0; i boolean listsEqualSemantics(final List a, final List b) { + if( a == null ) { + if( null != b ) { + return false; + } else { + return true; // elements equal, i.e. both null + } + } + if( b != null && a.size() == b.size() ) { + final int count = a.size(); + for(int i=0; i int listsHashCodeSemantics(final List a) { + if( a == null ) { + return 0; + } else { + final int count = a.size(); + int hash = 31; + for(int i=0; i getEqualSemantics(final Type s, final JavaConfiguration cfg, final boolean skipOpaque) { + final List res = new ArrayList(); + if( !skipOpaque || null == cfg.typeInfo(s) ) { + final Set> entries = entrySet(); + for(final Iterator> iter = entries.iterator(); iter.hasNext(); ) { + final Map.Entry entry = iter.next(); + final Type t = entry.getValue(); + if( s.equalSemantics(t) ) { + if( !skipOpaque || null == cfg.typeInfo(t) ) { + if( GlueGen.debug() ) { + System.err.println(" tls["+res.size()+"]: -> "+entry.getKey()+" -> "+t.getDebugString()); + } + res.add(t); + } + } + } + } + return res; + } + public Type getEqualSemantics1(final Type s, final JavaConfiguration cfg, final boolean skipOpaque) { + final List tls = getEqualSemantics(s, cfg, skipOpaque); + if( tls.size() > 0 ) { + final Type res = tls.get(0); + if( GlueGen.debug() ) { + System.err.println(" tls.0: "+res.getDebugString()); + } + return res; + } else { + return null; + } + } + //this method is broken /** * Get the names that correspond to the given type. There will be more than diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/Type.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/Type.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/Type.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/Type.java 2015-10-09 04:18:28.000000000 +0000 @@ -40,46 +40,110 @@ package com.jogamp.gluegen.cgram.types; -import java.util.List; - -import com.jogamp.common.os.MachineDescription; +import com.jogamp.common.os.MachineDataInfo; +import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider; +import com.jogamp.gluegen.ASTLocusTag; +import com.jogamp.gluegen.GlueGen; +import com.jogamp.gluegen.TypeConfig; +import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp; /** Models a C type. Primitive types include int, float, and double. All types have an associated name. Structs and unions are modeled as "compound" types -- composed of fields of primitive or other types. */ -public abstract class Type implements Cloneable { - +public abstract class Type implements SemanticEqualityOp, ASTLocusTagProvider { + public final boolean relaxedEqSem; + private final int cvAttributes; + final ASTLocusTag astLocus; private String name; private SizeThunk size; - private final int cvAttributes; - private int typedefedCVAttributes; - private boolean hasTypedefName; - - protected Type(final String name, final SizeThunk size, final int cvAttributes) { - setName(name); + private int typedefCVAttributes; + private boolean isTypedef; + private boolean hasCachedHash; + private int cachedHash; + private boolean hasCachedSemanticHash; + private int cachedSemanticHash; + + protected Type(final String name, final SizeThunk size, final int cvAttributes, final ASTLocusTag astLocus) { + setName(name); // -> clearCache() + this.relaxedEqSem = TypeConfig.relaxedEqualSemanticsTest(); + this.cvAttributes = cvAttributes; + this.astLocus = astLocus; this.size = size; + this.typedefCVAttributes = 0; + this.isTypedef = false; + } + Type(final Type o, final int cvAttributes, final ASTLocusTag astLocus) { + this.relaxedEqSem = o.relaxedEqSem; this.cvAttributes = cvAttributes; - hasTypedefName = false; + this.astLocus = astLocus; + this.name = o.name; + this.size = o.size; + this.typedefCVAttributes = o.typedefCVAttributes; + this.isTypedef = o.isTypedef; + clearCache(); } - @Override - public Object clone() { - try { - return super.clone(); - } catch (final CloneNotSupportedException ex) { - throw new InternalError(); + protected final void clearCache() { + hasCachedHash = false; + cachedHash = 0; + hasCachedSemanticHash = false; + cachedSemanticHash = 0; + } + + /** + * Return a variant of this type matching the given const/volatile + * attributes. May return this object if the attributes match. + */ + public final Type newCVVariant(final int cvAttributes) { + if (this.cvAttributes == cvAttributes) { + return this; + } else { + return newVariantImpl(true, cvAttributes, astLocus); } } + /** + * Clones this instance using a new {@link ASTLocusTag}. + */ + public Type clone(final ASTLocusTag newLoc) { + return newVariantImpl(true, cvAttributes, newLoc); + } + + /** + * Create a new variant of this type matching the given parameter + *

    + * Implementation must use {@link Type}'s copy-ctor: {@link #Type(Type, int, ASTLocusTag)}! + *

    + * @param newCVVariant true if new variant is intended to have new cvAttributes + * @param cvAttributes the cvAttributes to be used + * @param astLocus the {@link ASTLocusTag} to be used + */ + abstract Type newVariantImpl(final boolean newCVVariant, final int cvAttributes, final ASTLocusTag astLocus); + + @Override + public final ASTLocusTag getASTLocusTag() { return astLocus; } + + public boolean isAnon() { return null == name; } + /** Returns the name of this type. The returned string is suitable - for use as a type specifier. Does not include any const/volatile + for use as a type specifier for native C. Does not include any const/volatile + attributes. */ + public final String getCName() { return getCName(false); } + + /** Returns the name of this type, optionally including + const/volatile attributes. The returned string is suitable for + use as a type specifier for native C. */ + public String getCName(final boolean includeCVAttrs) { return getName(includeCVAttrs); } + + /** Returns the name of this type. The returned string is suitable + for use as a type specifier for Java. Does not include any const/volatile attributes. */ public final String getName() { return getName(false); } /** Returns the name of this type, optionally including const/volatile attributes. The returned string is suitable for - use as a type specifier. */ + use as a type specifier for Java. */ public String getName(final boolean includeCVAttrs) { if (!includeCVAttrs) { return name; @@ -87,32 +151,59 @@ return getCVAttributesString() + name; } - private void append(final StringBuilder sb, final String val, final boolean prepComma) { + /** + * Returns a string representation of this type. + * The returned string is suitable for use as a type specifier for native C. + * It does contain an expanded description of structs/unions, + * hence may not be suitable for type declarations. + */ + @Override + public String toString() { + return getCName(true); + } + + + private static StringBuilder append(final StringBuilder sb, final String val, final boolean prepComma) { if( prepComma ) { sb.append(", "); } sb.append(val); + return sb; } // For debugging - public String getDebugString() { + public final String getDebugString() { final StringBuilder sb = new StringBuilder(); boolean prepComma = false; sb.append("CType["); + sb.append("(").append(getClass().getSimpleName()).append(") "); + if( isTypedef() ) { + sb.append("typedef "); + } if( null != name ) { - append(sb, "'"+name+"'", prepComma); prepComma=true; + sb.append("'").append(name).append("'"); } else { - append(sb, "ANON", prepComma); prepComma=true; + sb.append("ANON"); + } + final Type targetType = getTargetType(); + if( null != targetType && this != targetType ) { + sb.append(" -> "); + if (!targetType.isFunction()) { + sb.append("(" + targetType.toString() + ") * " + getCVAttributesString()); + } else { + sb.append(((FunctionType) targetType).toString(null /* functionName */, null /* callingConvention */, false, true)); + } } - if( hasTypedefName() ) { - sb.append(" (typedef)"); + if( GlueGen.debug() ) { + sb.append(", o=0x"+Integer.toHexString(objHash())); } - append(sb, "size ", prepComma); prepComma=true; + sb.append(", size "); + prepComma=true; if( null != size ) { final long mdSize; { long _mdSize = -1; try { - _mdSize = size.computeSize(MachineDescription.StaticConfig.X86_64_UNIX.md); + _mdSize = size.computeSize(MachineDataInfo.StaticConfig.LP64_UNIX.md); } catch (final Exception e) {} mdSize = _mdSize; } @@ -121,67 +212,135 @@ sb.append(" ZERO"); } append(sb, "[", prepComma); prepComma=false; - if( isConst() ) { - append(sb, "const ", false); - } - if( isVolatile() ) { - append(sb, "volatile ", false); - } - if( isPointer() ) { - append(sb, "pointer*"+pointerDepth(), prepComma); prepComma=true; - } - if( isArray() ) { - append(sb, "array*"+arrayDimension(), prepComma); prepComma=true; - } - if( isBit() ) { - append(sb, "bit", prepComma); prepComma=true; - } - if( isCompound() ) { - sb.append("struct{").append(asCompound().getNumFields()); - append(sb, "}", prepComma); prepComma=true; - } - if( isDouble() ) { - append(sb, "double", prepComma); prepComma=true; - } - if( isEnum() ) { - append(sb, "enum", prepComma); prepComma=true; - } - if( isFloat() ) { - append(sb, "float", prepComma); prepComma=true; - } - if( isFunction() ) { - append(sb, "function", prepComma); prepComma=true; - } - if( isFunctionPointer() ) { - append(sb, "funcPointer", prepComma); prepComma=true; - } - if( isInt() ) { - append(sb, "int", prepComma); prepComma=true; - } - if( isVoid() ) { - append(sb, "void", prepComma); prepComma=true; + { + append(sb, "const[", prepComma); prepComma=false; + { + if( isConstTypedef() ) { + append(sb, "type ", prepComma); prepComma=true; + } + if( isConstRaw() ) { + append(sb, "inst -> ", prepComma); prepComma=false; + } + if( isConst() ) { + append(sb, "true]", prepComma); + } else { + append(sb, "false]", prepComma); + } + prepComma=true; + } + if( isVolatile() ) { + append(sb, "volatile ", prepComma); prepComma=true; + } + if( isPointer() ) { + append(sb, "pointer*"+pointerDepth(), prepComma); prepComma=true; + } + if( isArray() ) { + append(sb, "array*"+arrayDimension(), prepComma); prepComma=true; + } + if( isBit() ) { + append(sb, "bit", prepComma); prepComma=true; + } + if( isCompound() ) { + append(sb, "struct{", prepComma).append(asCompound().getStructName()).append(": ").append(asCompound().getNumFields()); + append(sb, "}", prepComma); prepComma=true; + } + if( isDouble() ) { + append(sb, "double", prepComma); prepComma=true; + } + if( isEnum() ) { + final EnumType eT = asEnum(); + append(sb, "enum ", prepComma).append(" [").append(eT.getUnderlyingType()).append("] {").append(eT.getNumEnumerates()).append(": "); + eT.appendEnums(sb, false); + prepComma=true; + } + if( isFloat() ) { + append(sb, "float", prepComma); prepComma=true; + } + if( isFunction() ) { + append(sb, "function", prepComma); prepComma=true; + } + if( isFunctionPointer() ) { + append(sb, "funcPointer", prepComma); prepComma=true; + } + if( isInt() ) { + append(sb, "int", prepComma); prepComma=true; + } + if( isVoid() ) { + append(sb, "void", prepComma); prepComma=true; + } + sb.append("]"); } - sb.append("]]"); + sb.append("]"); return sb.toString(); } + private final int objHash() { return super.hashCode(); } + - /** Set the name of this type; used for handling typedefs. */ - public void setName(final String name) { - if (name == null) { + /** + * Returns {@code true} if given {@code name} is not {@code null} + * and has a length > 0. In this case this instance's names will + * be set to the internalized version. + *

    + * Otherwise method returns {@code false} + * and this instance's name will be set to {@code null}. + *

    + *

    + * Method issues {@link #clearCache()}, to force re-evaluation + * of hashes. + *

    + */ + private final boolean setName(final String name) { + clearCache(); + if( null == name || 0 == name.length() ) { this.name = name; + return false; } else { this.name = name.intern(); + return true; + } + } + + /** + * Set the typedef name of this type and renders this type a typedef, + * if given {@code name} has a length. + *

    + * Method issues {@link #clearCache()}, to force re-evaluation + * of hashes. + *

    + */ + public boolean setTypedefName(final String name) { + if( setName(name) ) { + // Capture the const/volatile attributes at the time of typedef so + // we don't redundantly repeat them in the CV attributes string + typedefCVAttributes = cvAttributes; + isTypedef = true; + return true; + } else { + return false; } - // Capture the const/volatile attributes at the time of typedef so - // we don't redundantly repeat them in the CV attributes string - typedefedCVAttributes = cvAttributes; - hasTypedefName = true; + } + final void setTypedef(final int typedefedCVAttributes) { + this.name = this.name.intern(); // just make sure .. + this.typedefCVAttributes = typedefedCVAttributes; + this.isTypedef = true; + clearCache(); + } + final int getTypedefCVAttributes() { + return typedefCVAttributes; + } + + /** + * Indicates whether this type is a typedef type, + * i.e. declared via {@link #setTypedefName(String)}. + */ + public final boolean isTypedef() { + return isTypedef; } /** SizeThunk which computes size of this type in bytes. */ - public SizeThunk getSize() { return size; } - /** Size of this type in bytes according to the given MachineDescription. */ - public long getSize(final MachineDescription machDesc) { + public final SizeThunk getSize() { return size; } + /** Size of this type in bytes according to the given MachineDataInfo. */ + public final long getSize(final MachineDataInfo machDesc) { final SizeThunk thunk = getSize(); if (thunk == null) { throw new RuntimeException("No size set for type \"" + getName() + "\""); @@ -189,7 +348,10 @@ return thunk.computeSize(machDesc); } /** Set the size of this type; only available for CompoundTypes. */ - void setSize(final SizeThunk size) { this.size = size; } + final void setSize(final SizeThunk size) { + this.size = size; + clearCache(); + } /** Casts this to a BitType or returns null if not a BitType. */ public BitType asBit() { return null; } @@ -213,82 +375,153 @@ public VoidType asVoid() { return null; } /** Indicates whether this is a BitType. */ - public boolean isBit() { return (asBit() != null); } + public final boolean isBit() { return (asBit() != null); } /** Indicates whether this is an IntType. */ - public boolean isInt() { return (asInt() != null); } + public final boolean isInt() { return (asInt() != null); } /** Indicates whether this is an EnumType. */ - public boolean isEnum() { return (asEnum() != null); } + public final boolean isEnum() { return (asEnum() != null); } /** Indicates whether this is a FloatType. */ - public boolean isFloat() { return (asFloat() != null); } + public final boolean isFloat() { return (asFloat() != null); } /** Indicates whether this is a DoubleType. */ - public boolean isDouble() { return (asDouble() != null); } + public final boolean isDouble() { return (asDouble() != null); } /** Indicates whether this is a PointerType. */ - public boolean isPointer() { return (asPointer() != null); } + public final boolean isPointer() { return (asPointer() != null); } /** Indicates whether this is an ArrayType. */ - public boolean isArray() { return (asArray() != null); } + public final boolean isArray() { return (asArray() != null); } /** Indicates whether this is a CompoundType. */ - public boolean isCompound() { return (asCompound() != null); } + public final boolean isCompound() { return (asCompound() != null); } /** Indicates whether this is a FunctionType. */ - public boolean isFunction() { return (asFunction() != null); } + public final boolean isFunction() { return (asFunction() != null); } /** Indicates whether this is a VoidType. */ - public boolean isVoid() { return (asVoid() != null); } + public final boolean isVoid() { return (asVoid() != null); } - /** Indicates whether this type is const. */ - public boolean isConst() { return (((cvAttributes & ~typedefedCVAttributes) & CVAttributes.CONST) != 0); } /** Indicates whether this type is volatile. */ - public boolean isVolatile() { return (((cvAttributes & ~typedefedCVAttributes) & CVAttributes.VOLATILE) != 0); } + public final boolean isVolatile() { return 0 != ( ( cvAttributes & ~typedefCVAttributes ) & CVAttributes.VOLATILE ); } + /** Indicates whether this type is const. */ + public final boolean isConst() { return 0 != ( ( cvAttributes & ~typedefCVAttributes ) & CVAttributes.CONST ); } + + private final boolean isConstTypedef() { return 0 != ( typedefCVAttributes & CVAttributes.CONST ); } + private final boolean isConstRaw() { return 0 != ( cvAttributes & CVAttributes.CONST ); } /** Indicates whether this type is a primitive type. */ - public boolean isPrimitive(){ return false; } + public boolean isPrimitive(){ return false; } /** Convenience routine indicating whether this Type is a pointer to a function. */ public boolean isFunctionPointer() { - return (isPointer() && asPointer().getTargetType().isFunction()); + return false; + } + + /** + * Checks the base type of pointer-to-pointer, pointer, array or plain for const-ness. + *

    + * Note: Intermediate 'const' qualifier are not considered, e.g. const pointer. + *

    + */ + public final boolean isBaseTypeConst() { + return getBaseElementType().isConst(); } /** Hashcode for Types. */ @Override - public int hashCode() { - if (name == null) { - return 0; - } - - if (cvAttributes != 0) { - final String nameWithAttribs = name + cvAttributes; - return nameWithAttribs.hashCode(); + public final int hashCode() { + if( !hasCachedHash ) { + // 31 * x == (x << 5) - x + int hash = 31 + ( isTypedef ? 1 : 0 ); + hash = ((hash << 5) - hash) + ( null != size ? size.hashCode() : 0 ); + hash = ((hash << 5) - hash) + cvAttributes; + hash = ((hash << 5) - hash) + typedefCVAttributes; + hash = ((hash << 5) - hash) + ( null != name ? name.hashCode() : 0 ); + if( !isTypedef ) { + hash = ((hash << 5) - hash) + hashCodeImpl(); + } + cachedHash = hash; + hasCachedHash = true; } - return name.hashCode(); + return cachedHash; } + protected abstract int hashCodeImpl(); /** - * Equality test for Types. + * Equality test for Types inclusive its given {@link #getName() name}. */ @Override - public boolean equals(final Object arg) { + public final boolean equals(final Object arg) { if (arg == this) { - return true; + return true; + } else if ( !getClass().isInstance(arg) ) { // implies null == arg || !(arg instanceof Type) + return false; + } else { + final Type t = (Type)arg; + if( isTypedef == t.isTypedef && + ( ( null != size && size.equals(t.size) ) || + ( null == size && null == t.size ) + ) && + cvAttributes == t.cvAttributes && + typedefCVAttributes == t.typedefCVAttributes && + ( null == name ? null == t.name : name.equals(t.name) ) + ) + { + if( !isTypedef ) { + return equalsImpl(t); + } else { + return true; + } + } else { + return false; + } } + } + protected abstract boolean equalsImpl(final Type t); - if ( !(arg instanceof Type) ) { - return false; + @Override + public final int hashCodeSemantics() { + if( !hasCachedSemanticHash ) { + // 31 * x == (x << 5) - x + int hash = 31 + ( null != size ? size.hashCodeSemantics() : 0 ); + if( !relaxedEqSem ) { + hash = ((hash << 5) - hash) + cvAttributes; + hash = ((hash << 5) - hash) + typedefCVAttributes; + } + hash = ((hash << 5) - hash) + hashCodeSemanticsImpl(); + cachedSemanticHash = hash; + hasCachedSemanticHash = true; } - - final Type t = (Type)arg; - return size == t.size && cvAttributes == t.cvAttributes && - ( null == name ? null == t.name : name.equals(t.name) ) ; + return cachedSemanticHash; } + protected abstract int hashCodeSemanticsImpl(); - /** Returns a string representation of this type. This string is not - necessarily suitable for use as a type specifier; for example, - it will contain an expanded description of structs/unions. */ @Override - public String toString() { - return getName(true); + public final boolean equalSemantics(final SemanticEqualityOp arg) { + if (arg == this) { + return true; + } else if ( !(arg instanceof Type) || + !getClass().isInstance(arg) ) { // implies null == arg + return false; + } else { + final Type t = (Type) arg; + if( ( ( null != size && size.equalSemantics(t.size) ) || + ( null == size && null == t.size ) + ) && + ( relaxedEqSem || + ( cvAttributes == t.cvAttributes && + typedefCVAttributes == t.typedefCVAttributes + ) + ) + ) + { + return equalSemanticsImpl(t); + } else { + return false; + } + } } + protected abstract boolean equalSemanticsImpl(final Type t); - /** Visit this type and all of the component types of this one; for - example, the return type and argument types of a FunctionType. */ + /** + * Traverse this {@link Type} and all of its component types; for + * example, the return type and argument types of a FunctionType. + */ public void visit(final TypeVisitor visitor) { visitor.visitType(this); } @@ -306,45 +539,18 @@ return ""; } - /** Return a variant of this type matching the given const/volatile - attributes. May return this object if the attributes match. */ - public final Type getCVVariant(final int cvAttributes) { - if (this.cvAttributes == cvAttributes) { - return this; - } - return newCVVariant(cvAttributes); - } - - /** Create a new variant of this type matching the given - const/volatile attributes. */ - abstract Type newCVVariant(int cvAttributes); - - /** Indicates whether setName() has been called on this type, - indicating that it already has a typedef name. */ - public boolean hasTypedefName() { - return hasTypedefName; - } - /** Helper method for determining how many pointer indirections this type represents (i.e., "void **" returns 2). Returns 0 if this type is not a pointer type. */ public int pointerDepth() { - final PointerType pt = asPointer(); - if (pt == null) { - return 0; - } - return 1 + pt.getTargetType().pointerDepth(); + return 0; } /** Helper method for determining how many array dimentions this type represents (i.e., "char[][]" returns 2). Returns 0 if this type is not an array type. */ public int arrayDimension() { - final ArrayType arrayType = asArray(); - if (arrayType == null) { - return 0; - } - return 1 + arrayType.getElementType().arrayDimension(); + return 0; } /** @@ -358,8 +564,10 @@ return this; } - /** Helper routine for list equality comparison */ - static boolean listsEqual(final List a, final List b) { - return ((a == null && b == null) || (a != null && b != null && a.equals(b))); + /** + * Helper method to returns the target type of this type, in case another type is being referenced. + */ + public Type getTargetType() { + return this; } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/TypeVisitor.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/TypeVisitor.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/TypeVisitor.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/TypeVisitor.java 2015-10-09 04:18:28.000000000 +0000 @@ -39,6 +39,12 @@ package com.jogamp.gluegen.cgram.types; +/** + * A visitor for {@link Type}'s visitor model. + */ public interface TypeVisitor { + /** + * Visiting the given {@link Type}. + */ public void visitType(Type t); } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/UnionType.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/UnionType.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/UnionType.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/UnionType.java 2015-10-09 04:18:28.000000000 +0000 @@ -27,34 +27,25 @@ */ package com.jogamp.gluegen.cgram.types; +import com.jogamp.gluegen.ASTLocusTag; + public class UnionType extends CompoundType { - public UnionType(final String name, final SizeThunk size, final int cvAttributes) { - this(name, size, cvAttributes, null); + UnionType(final String name, final SizeThunk size, final int cvAttributes, final String structName, final ASTLocusTag astLocus) { + super (name, size, cvAttributes, structName, astLocus); } - UnionType(final String name, final SizeThunk size, final int cvAttributes, final String structName) { - super (name, size, cvAttributes, structName); + private UnionType(final UnionType o, final int cvAttributes, final ASTLocusTag astLocus) { + super(o, cvAttributes, astLocus); } @Override - public boolean equals(final Object arg) { - if (arg == null || !(arg instanceof UnionType)) { - return false; - } - return super.equals(arg); + Type newVariantImpl(final boolean newCVVariant, final int cvAttributes, final ASTLocusTag astLocus) { + return new UnionType(this, cvAttributes, astLocus); } @Override public final boolean isStruct() { return false; } @Override public final boolean isUnion() { return true; } - - @Override - Type newCVVariant(final int cvAttributes) { - final UnionType t = new UnionType(getName(), getSize(), cvAttributes, getStructName()); - t.setFields(getFields()); - return t; - } - } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/VoidType.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/VoidType.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/cgram/types/VoidType.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/cgram/types/VoidType.java 2015-10-09 04:18:28.000000000 +0000 @@ -39,14 +39,25 @@ */ package com.jogamp.gluegen.cgram.types; +import com.jogamp.gluegen.ASTLocusTag; + public class VoidType extends Type implements Cloneable { - public VoidType(final int cvAttributes) { - this("void", cvAttributes); + public VoidType(final int cvAttributes, final ASTLocusTag astLocus) { + this("void", cvAttributes, astLocus); + } + + private VoidType(final String name, final int cvAttributes, final ASTLocusTag astLocus) { + super(name, null, cvAttributes, astLocus); + } + + private VoidType(final VoidType o, final int cvAttributes, final ASTLocusTag astLocus) { + super(o, cvAttributes, astLocus); } - private VoidType(final String name, final int cvAttributes) { - super(name, null, cvAttributes); + @Override + Type newVariantImpl(final boolean newCVVariant, final int cvAttributes, final ASTLocusTag astLocus) { + return new VoidType(this, cvAttributes, astLocus); } @Override @@ -55,7 +66,22 @@ } @Override - Type newCVVariant(final int cvAttributes) { - return new VoidType(getName(), cvAttributes); + protected int hashCodeImpl() { + return 0; + } + + @Override + protected boolean equalsImpl(final Type t) { + return true; + } + + @Override + protected int hashCodeSemanticsImpl() { + return 0; + } + + @Override + protected boolean equalSemanticsImpl(final Type t) { + return true; } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java 2015-10-09 04:18:28.000000000 +0000 @@ -43,21 +43,21 @@ import java.io.*; import java.text.MessageFormat; -import com.jogamp.common.os.MachineDescription; +import com.jogamp.common.os.MachineDataInfo; +import com.jogamp.gluegen.Logging.LoggerIf; import com.jogamp.gluegen.cgram.types.*; -import java.util.logging.Logger; - /** Emits the C-side component of the Java<->C JNI binding. */ public class CMethodBindingEmitter extends FunctionEmitter { - protected static final Logger LOG = Logger.getLogger(CMethodBindingEmitter.class.getPackage().getName()); protected static final CommentEmitter defaultCommentEmitter = new DefaultCommentEmitter(); protected static final String arrayResLength = "_array_res_length"; protected static final String arrayRes = "_array_res"; protected static final String arrayIdx = "_array_idx"; + protected final LoggerIf LOG; + protected MethodBinding binding; /** Name of the package in which the corresponding Java method resides.*/ @@ -109,7 +109,7 @@ protected static final String STRING_CHARS_PREFIX = "_strchars_"; // We need this in order to compute sizes of certain types - protected MachineDescription machDesc; + protected MachineDataInfo machDesc; /** * Constructs an emitter for the specified binding, and sets a default @@ -124,9 +124,11 @@ final boolean isJavaMethodStatic, final boolean forImplementingMethodCall, final boolean forIndirectBufferAndArrayImplementation, - final MachineDescription machDesc) + final MachineDataInfo machDesc, + final JavaConfiguration configuration) { - super(output, false); + super(output, false, configuration); + LOG = Logging.getLogger(CMethodBindingEmitter.class.getPackage().getName(), CMethodBindingEmitter.class.getSimpleName()); assert(binding != null); assert(javaClassName != null); @@ -148,8 +150,21 @@ public final MethodBinding getBinding() { return binding; } @Override - public String getName() { - return binding.getName(); + public String getInterfaceName() { + return binding.getInterfaceName(); + } + @Override + public String getImplName() { + return binding.getImplName(); + } + @Override + public String getNativeName() { + return binding.getNativeName(); + } + + @Override + public FunctionSymbol getCSymbol() { + return binding.getCSymbol(); } /** @@ -289,7 +304,7 @@ /** * Used for certain internal type size computations */ - public final MachineDescription getMachineDescription() { return machDesc; } + public final MachineDataInfo getMachineDataInfo() { return machDesc; } @Override @@ -306,12 +321,8 @@ writer.print("_"); if (isOverloadedBinding) { writer.print(jniMangle(binding)); - //System.err.println("OVERLOADED MANGLING FOR " + getName() + - // " = " + jniMangle(binding)); } else { - writer.print(JavaEmitter.jniMangle(getName())); - //System.err.println(" NORMAL MANGLING FOR " + binding.getName() + - // " = " + jniMangle(getName())); + writer.print(JavaEmitter.jniMangle(getImplName())); } } @@ -450,8 +461,10 @@ final JavaType javaReturnType = binding.getJavaReturnType(); if (!cReturnType.isVoid()) { writer.print(" "); - // Note we must respect const/volatile for return argument - writer.print(binding.getCSymbol().getReturnType().getName(true)); + // Note we respect const/volatile in the function return type. + // However, we cannot have it 'const' for our local variable. + // See cast in emitBodyCallCFunction(..)! + writer.print(binding.getCSymbol().getReturnType().getCName(false)); writer.println(" _res;"); if (javaReturnType.isNIOByteBufferArray() || javaReturnType.isArrayOfCompoundTypeWrappers()) { @@ -569,7 +582,7 @@ writer.println(" if ( NULL != " + javaArgName + " ) {"); final Type cArgType = binding.getCArgumentType(i); - String cArgTypeName = cArgType.getName(); + String cArgTypeName = cArgType.getCName(); final String convName = pointerConversionArgumentName(javaArgName); @@ -595,14 +608,14 @@ // // Note that we properly handle only the case of an array of // compound type wrappers in emitBodyVariablePostCallCleanup below - if (!isBaseTypeConst(cArgType) && + if (!cArgType.isBaseTypeConst() && !javaArgType.isArrayOfCompoundTypeWrappers()) { // FIXME: if the arg type is non-const, the sematics might be that // the function modifies the argument -- we don't yet support // this. - throw new RuntimeException( - "Cannot copy data for ptr-to-ptr arg type \"" + cArgType + - "\": support for non-const ptr-to-ptr types not implemented."); + throw new GlueGenException( + "Cannot copy data for ptr-to-ptr arg type \"" + cArgType.getDebugString() + + "\": support for non-const ptr-to-ptr types not implemented: "+binding, binding.getCSymbol().getASTLocusTag()); } writer.println(); @@ -646,16 +659,17 @@ error = 100; } if( 0 < error ) { - throw new RuntimeException( - "Could not copy data for type \"" + cArgType + - "\"; currently only pointer- and array-types are supported. (error "+error+")"); + throw new GlueGenException( + "Could not copy data for type \"" + cArgType.getDebugString() + + "\"; currently only pointer- and array-types are supported. (error "+error+"): "+binding, + binding.getCSymbol().getASTLocusTag()); } } emitMalloc( writer, convName+"_copy", - cArgElementType.getName(), - isBaseTypeConst(cArgType), + cArgElementType.getCName(), + cArgType.isBaseTypeConst(), arrayLenName, "Could not allocate buffer for copying data in argument \\\""+javaArgName+"\\\""); @@ -692,7 +706,7 @@ in the method binding. */ emitGetDirectBufferAddress(writer, "_tmpObj", - cArgElementType.getName(), + cArgElementType.getCName(), convName + "_copy[_copyIndex]", true, "_offsetHandle[_copyIndex]", true); @@ -702,13 +716,14 @@ // offset argument emitGetDirectBufferAddress(writer, "_tmpObj", - cArgElementType.getName(), + cArgElementType.getCName(), "("+convName + "_copy + _copyIndex)", false /* !receivingIsPtrPtr -> linear layout -> use memcpy */, null, true); } else { if( null == cArgElementType2 ) { - throw new RuntimeException("XXX: Type "+cArgType+" not properly handled as ptr-to-ptr"); + throw new GlueGenException("XXX: Type "+cArgType.getDebugString()+" not properly handled as ptr-to-ptr: "+binding, + binding.getCSymbol().getASTLocusTag()); } // Question: do we always need to copy the sub-arrays, or just // GetPrimitiveArrayCritical on each jobjectarray element and @@ -719,14 +734,15 @@ emitMalloc( writer, convName+"_copy[_copyIndex]", - cArgElementType2.getName(), // assumes cArgPtrType is ptr-to-ptr-to-primitive !! - isBaseTypeConst(cArgType), + cArgElementType2.getCName(), // assumes cArgPtrType is ptr-to-ptr-to-primitive !! + cArgType.isBaseTypeConst(), "(*env)->GetArrayLength(env, _tmpObj)", "Could not allocate buffer during copying of data in argument \\\""+javaArgName+"\\\""); // FIXME: copy the data (use matched Get/ReleasePrimitiveArrayCritical() calls) if (true) { - throw new RuntimeException("Cannot yet handle type \"" + cArgType.getName() + - "\"; need to add support for copying ptr-to-ptr-to-primitiveType subarrays"); + throw new GlueGenException("Cannot yet handle type \"" + cArgType.getDebugString() + + "\"; need to add support for copying ptr-to-ptr-to-primitiveType subarrays: "+binding, + binding.getCSymbol().getASTLocusTag()); } } @@ -781,7 +797,7 @@ writer.println(" if ( JNI_FALSE == " + isNIOArgName(i) + " && NULL != " + javaArgName + " ) {"); // Release array - final String modeFlag = isBaseTypeConst(cArgType) ? "JNI_ABORT" : "0" ; + final String modeFlag = cArgType.isBaseTypeConst() ? "JNI_ABORT" : "0" ; writer.print(" (*env)->ReleasePrimitiveArrayCritical(env, " + javaArgName + ", " + convName + ", "+modeFlag+");"); } else { writer.println(" if ( NULL != " + javaArgName + " ) {"); @@ -792,7 +808,7 @@ // // FIXME: should factor out this whole block of code into a separate // method for clarity and maintenance purposes - if (!isBaseTypeConst(cArgType)) { + if (!cArgType.isBaseTypeConst()) { // FIXME: handle any cleanup from treatment of non-const args, // assuming they were treated differently in // emitBodyVariablePreCallSetup() (see the similar section in that @@ -804,15 +820,16 @@ writer.println(" _tmpObj = (*env)->GetObjectArrayElement(env, " + javaArgName + ", _copyIndex);"); emitReturnDirectBufferAddress(writer, "_tmpObj", - cArgType.asArray().getBaseElementType().getName(), + cArgType.asArray().getBaseElementType().getCName(), "("+convName + "_copy + _copyIndex)", false /* receivingIsPtrPtr */, null); writer.println(" }"); } else { - throw new RuntimeException( - "Cannot clean up copied data for ptr-to-ptr arg type \"" + cArgType + - "\": support for cleaning up most non-const ptr-to-ptr types not implemented."); + throw new GlueGenException( + "Cannot clean up copied data for ptr-to-ptr arg type \"" + cArgType.getDebugString() + + "\": support for cleaning up most non-const ptr-to-ptr types not implemented.", + binding.getCSymbol().getASTLocusTag()); } } @@ -833,9 +850,10 @@ // free each element final PointerType cArgPtrType = cArgType.asPointer(); if (cArgPtrType == null) { - throw new RuntimeException( - "Could not copy data for type \"" + cArgType + - "\"; currently only pointer types supported."); + throw new GlueGenException( + "Could not copy data for type \"" + cArgType.getDebugString() + + "\"; currently only pointer types supported.", + binding.getCSymbol().getASTLocusTag()); } // process each element in the array @@ -854,9 +872,10 @@ writer.print(convName+"_copy[_copyIndex]"); writer.println(");"); } else { - if (true) throw new RuntimeException( - "Cannot yet handle type \"" + cArgType.getName() + - "\"; need to add support for cleaning up copied ptr-to-ptr-to-primitiveType subarrays"); + throw new GlueGenException( + "Cannot yet handle type \"" + cArgType.getDebugString() + + "\"; need to add support for cleaning up copied ptr-to-ptr-to-primitiveType subarrays", + binding.getCSymbol().getASTLocusTag()); } writer.println(" }"); } @@ -915,20 +934,9 @@ javaArgType.isArray() || javaArgType.isArrayOfCompoundTypeWrappers() || ( javaArgType.isNIOBuffer() && forIndirectBufferAndArrayImplementation ) ); - if (isBaseTypeConst(cArgType)) { - writer.print("const "); - } - - // if this is a pointer to an unsigned type, add unsigned to the name to avoid compiler warnings - if(cArgType.isPointer()) { - final Type baseType = cArgType.getBaseElementType(); - if(baseType.isInt() && (((IntType)baseType).isPrimitiveUnsigned())) { - writer.print("unsigned "); - } - } - - writer.print(cArgType.getName()); + writer.print(cArgType.getCName(true)); writer.print(") "); + if (cArgType.isPointer() && javaArgType.isPrimitive()) { writer.print("(intptr_t) "); } @@ -975,13 +983,18 @@ final Type cReturnType = binding.getCReturnType(); if (!cReturnType.isVoid()) { - writer.print("_res = "); + // Note we respect const/volatile in the function return type. + // However, we cannot have it 'const' for our local variable. + // See return type in emitBodyVariableDeclarations(..)! + writer.print("_res = ("); + writer.print(cReturnType.getCName(false)); + writer.print(") "); } if ( isCStructFunctionPointer && binding.hasContainingType() ) { // Call through function pointer writer.print(CMethodBindingEmitter.cThisArgumentName() + "->"); } - writer.print(binding.getCSymbol().getName()); + writer.print(getNativeName()); writer.print("("); emitBodyPassCArguments(writer); writer.println(");"); @@ -1020,7 +1033,7 @@ if (returnValueCapacityExpression != null) { returnSizeOf = returnValueCapacityExpression.format(argumentNameArray()); } else { - returnSizeOf = "sizeof(" + cReturnType.getName() + ")"; + returnSizeOf = "sizeof(" + cReturnType.getCName() + ")"; } writer.println(" return JVMUtil_NewDirectByteBufferCopy(env, &_res, "+returnSizeOf+");"); } else if (javaReturnType.isNIOBuffer() || javaReturnType.isCompoundTypeWrapper()) { @@ -1029,36 +1042,76 @@ // See whether capacity has been specified if (returnValueCapacityExpression != null) { - writer.print( returnValueCapacityExpression.format( argumentNameArray() ) ); + writer.println( returnValueCapacityExpression.format( argumentNameArray() ) + ");"); } else { - if (cReturnType.isPointer() && - cReturnType.asPointer().getTargetType().isCompound()) { - if (cReturnType.asPointer().getTargetType().getSize() == null) { - throw new RuntimeException( - "Error emitting code for compound return type "+ - "for function \"" + binding + "\": " + - "Structs to be emitted should have been laid out by this point " + - "(type " + cReturnType.asPointer().getTargetType().getName() + " / " + - cReturnType.asPointer().getTargetType() + " was not) for "+binding - ); + final Type cReturnTargetType = cReturnType.isPointer() ? cReturnType.getTargetType() : null; + int mode = 0; + if ( 1 == cReturnType.pointerDepth() && null != cReturnTargetType ) { + if( cReturnTargetType.isCompound() ) { + if( !cReturnTargetType.isAnon() && + cReturnTargetType.asCompound().getNumFields() > 0 ) + { + // fully declared non-anonymous struct pointer: pass content + if ( cReturnTargetType.getSize() == null ) { + throw new GlueGenException( + "Error emitting code for compound return type "+ + "for function \"" + binding + "\": " + + "Structs to be emitted should have been laid out by this point " + + "(type " + cReturnTargetType.getCName() + " / " + + cReturnTargetType.getDebugString() + " was not) for "+binding.getCSymbol(), + binding.getCSymbol().getASTLocusTag() + ); + } + writer.println("sizeof(" + cReturnTargetType.getCName() + ") );"); + mode = 10; + } else if( cReturnTargetType.asCompound().getNumFields() == 0 ) { + // anonymous struct pointer: pass pointer + writer.println("sizeof(" + cReturnType.getCName() + ") );"); + mode = 11; + } + } + if( 0 == mode ) { + if( cReturnTargetType.isPrimitive() ) { + // primitive pointer: pass primitive + writer.println("sizeof(" + cReturnTargetType.getCName() + ") );"); + mode = 20; + } else if( cReturnTargetType.isVoid() ) { + // void pointer: pass pointer + writer.println("sizeof(" + cReturnType.getCName() + ") );"); + mode = 21; + } + } + } + if( 0 == mode ) { + if( null != cfg.typeInfo(cReturnType) ) { // javaReturnType.isOpaqued() covered above via isPrimitive() + // Opaque + writer.println("sizeof(" + cReturnType.getCName() + ") );"); + mode = 88; + } else { + final String wmsg = "Assumed return size of equivalent C return type"; + writer.println("sizeof(" + cReturnType.getCName() + ") ); // WARNING: "+wmsg); + mode = 99; + LOG.warning(binding.getCSymbol().getASTLocusTag(), + "No capacity specified for java.nio.Buffer return " + + "value for function \"" + binding.getName() + "\". " + wmsg + " (sizeof(" + cReturnType.getCName() + ")): " + binding); } } - writer.print("sizeof(" + cReturnType.getName() + ")"); - LOG.warning( - "No capacity specified for java.nio.Buffer return " + - "value for function \"" + binding.getName() + "\"" + - " assuming size of equivalent C return type (sizeof(" + cReturnType.getName() + ")): " + binding); + writer.println(" /** "); + writer.println(" * mode: "+mode); + writer.println(" * cReturnType: "+cReturnType.getDebugString()); + writer.println(" * cReturnTargetType: "+cReturnTargetType.getDebugString()); + writer.println(" * javaReturnType: "+javaReturnType.getDebugString()); + writer.println(" */"); } - writer.println(");"); } else if (javaReturnType.isString()) { writer.println(" if (NULL == _res) return NULL;"); - writer.println(" return (*env)->NewStringUTF(env, _res);"); + writer.println(" return (*env)->NewStringUTF(env, (const char *)_res);"); } else if (javaReturnType.isArrayOfCompoundTypeWrappers() || (javaReturnType.isArray() && javaReturnType.isNIOByteBufferArray())) { writer.println(" if (NULL == _res) return NULL;"); if (returnValueLengthExpression == null) { - throw new RuntimeException("Error while generating C code: no length specified for array returned from function " + - binding); + throw new GlueGenException("Error while generating C code: no length specified for array returned from function " + + binding, binding.getCSymbol().getASTLocusTag()); } writer.println(" " + arrayResLength + " = " + returnValueLengthExpression.format(argumentNameArray()) + ";"); writer.println(" " + arrayRes + " = (*env)->NewObjectArray(env, " + arrayResLength + ", (*env)->FindClass(env, \"java/nio/ByteBuffer\"), NULL);"); @@ -1071,7 +1124,7 @@ pointerType = retType.asArray().getBaseElementType(); } writer.println(" (*env)->SetObjectArrayElement(env, " + arrayRes + ", " + arrayIdx + - ", (*env)->NewDirectByteBuffer(env, (void *)_res[" + arrayIdx + "], sizeof(" + pointerType.getName() + ")));"); + ", (*env)->NewDirectByteBuffer(env, (void *)_res[" + arrayIdx + "], sizeof(" + pointerType.getCName() + ")));"); writer.println(" }"); writer.println(" return " + arrayRes + ";"); } else if (javaReturnType.isArray()) { @@ -1080,9 +1133,10 @@ // expression which computes the array size (already present // as ReturnValueCapacity, not yet implemented / tested here) - throw new RuntimeException( + throw new GlueGenException( "Could not emit native code for function \"" + binding + - "\": array return values for non-char types not implemented yet, for "+binding); + "\": array return values for non-char types not implemented yet, for "+binding, + binding.getCSymbol().getASTLocusTag()); // FIXME: This is approximately what will be required here // @@ -1104,8 +1158,8 @@ //writer.print(arrayRes); //writer.println(";"); } else { - System.err.print("Unhandled return type: "+javaReturnType.getDebugString()); - throw new RuntimeException("Unhandled return type: "+javaReturnType.getDebugString()+" for "+binding); + throw new GlueGenException("Unhandled return type: "+javaReturnType.getDebugString()+" for "+binding, + binding.getCSymbol().getReturnType().getASTLocusTag()); } } } @@ -1116,7 +1170,7 @@ protected String jniMangle(final MethodBinding binding) { final StringBuilder buf = new StringBuilder(); - buf.append(JavaEmitter.jniMangle(getName())); + buf.append(JavaEmitter.jniMangle(getImplName())); buf.append(getImplSuffix()); buf.append("__"); if (binding.hasContainingType()) { @@ -1132,7 +1186,8 @@ // We should only see "void" as the first argument of a 1-argument function // FIXME: should normalize this in the parser if ((i != 0) || (binding.getNumArguments() > 1)) { - throw new RuntimeException("Saw illegal \"void\" argument while emitting \"" + getName() + "\""); + throw new GlueGenException("Saw illegal \"void\" argument while emitting arg "+i+" of "+binding, + binding.getCArgumentType(i).getASTLocusTag()); } } else { Class c = type.getJavaClass(); @@ -1164,7 +1219,8 @@ // These are not exposed at the Java level } else { // FIXME: add support for char* -> String conversion - throw new RuntimeException("Unknown kind of JavaType: name="+type.getName()); + throw new GlueGenException("Unknown kind of JavaType: arg "+i+", name="+type.getName()+" of "+binding, + binding.getCArgumentType(i).getASTLocusTag()); } } } @@ -1225,7 +1281,7 @@ writer.println(" (*env)->ThrowNew(env, (*env)->FindClass(env, \"java/lang/OutOfMemoryError\"),"); writer.print(" \"" + errorMessage); writer.print(" in native dispatcher for \\\""); - writer.print(getName()); + writer.print(getInterfaceName()); writer.println("\\\"\");"); writer.print(" return"); if (!binding.getJavaReturnType().isVoid()) { @@ -1386,33 +1442,34 @@ // Note that we don't need to obey const/volatile for outgoing arguments // if (javaType.isNIOBuffer()) { - ptrTypeString = cType.getName(); + // primitive NIO object + ptrTypeString = cType.getCName(); } else if (javaType.isArray() || javaType.isArrayOfCompoundTypeWrappers()) { needsDataCopy = javaArgTypeNeedsDataCopy(javaType); if (javaType.isPrimitiveArray() || javaType.isNIOBufferArray() || javaType.isArrayOfCompoundTypeWrappers()) { - ptrTypeString = cType.getName(); + ptrTypeString = cType.getCName(); } else if (!javaType.isStringArray()) { final Class elementType = javaType.getJavaClass().getComponentType(); if (elementType.isArray()) { final Class subElementType = elementType.getComponentType(); if (subElementType.isPrimitive()) { // type is pointer to pointer to primitive - ptrTypeString = cType.getName(); + ptrTypeString = cType.getCName(); } else { // type is pointer to pointer of some type we don't support (maybe // it's an array of pointers to structs?) - throw new RuntimeException("Unsupported pointer type: \"" + cType.getName() + "\""); + throw new GlueGenException("Unsupported pointer type: \"" + cType.getDebugString() + "\"", cType.getASTLocusTag()); } } else { // type is pointer to pointer of some type we don't support (maybe // it's an array of pointers to structs?) - throw new RuntimeException("Unsupported pointer type: \"" + cType.getName() + "\""); + throw new GlueGenException("Unsupported pointer type: \"" + cType.getDebugString() + "\"", cType.getASTLocusTag()); } } } else { - ptrTypeString = cType.getName(); + ptrTypeString = cType.getCName(); } writer.print(" "); @@ -1434,14 +1491,14 @@ String cElementTypeName = "char *"; final PointerType cPtrType = cType.asPointer(); if (cPtrType != null) { - cElementTypeName = cPtrType.getTargetType().asPointer().getName(); + cElementTypeName = cPtrType.getTargetType().asPointer().getCName(); } - if (isBaseTypeConst(cType)) { + if (cType.isBaseTypeConst()) { writer.print("const "); } writer.print(cElementTypeName+" *"); } else { - if (isBaseTypeConst(cType)) { + if (cType.isBaseTypeConst()) { writer.print("const "); } writer.print(ptrTypeString); @@ -1470,9 +1527,9 @@ final String cVariableType; if( !cType.isPointer() && type.isCompoundTypeWrapper() ) { // FIXME: Compound call-by-value - cVariableType = cType.getName()+" *"; + cVariableType = cType.getCName()+" *"; } else { - cVariableType = cType.getName(); + cVariableType = cType.getCName(); } emitGetDirectBufferAddress(writer, incomingArgumentName, diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/ConstantDefinition.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/ConstantDefinition.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/ConstantDefinition.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/ConstantDefinition.java 2015-10-09 04:18:28.000000000 +0000 @@ -1,71 +1,481 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. +/** + * Copyright 2015 JogAmp Community. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. */ - package com.jogamp.gluegen; -import java.util.*; +import java.math.BigInteger; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider; +import com.jogamp.gluegen.cgram.types.AliasedSymbol.AliasedSymbolImpl; +import com.jogamp.gluegen.cgram.types.TypeComparator.AliasedSemanticSymbol; +import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp; + +/** + * Represents a [native] constant expression, + * comprises the [native] expression, see {@link #getNativeExpr()} + * and the optional {@link CNumber} representation, see {@link #getNumber()}. + *

    + * The representation of the equivalent java expression including + * the result type is covered by {@link JavaExpr}, + * which can be computed via {@link #computeJavaExpr(Map)}. + *

    + *

    + * This class and its sub-classes define and convert all native expressions + * to Java space. + *

    + */ +public class ConstantDefinition extends AliasedSymbolImpl implements AliasedSemanticSymbol, ASTLocusTagProvider { + public static final long UNSIGNED_INT_MAX_VALUE = 0xffffffffL; + public static final BigInteger UNSIGNED_LONG_MAX_VALUE = new BigInteger("ffffffffffffffff", 16); + + /** + * A Number, either integer, optionally [long, unsigned], + * or floating point, optionally [double]. + */ + public static class CNumber { + /** + * {@code true} if number is integer and value stored in {@link #i}, + * otherwise {@code false} for floating point and value stored in {@link #f}. + */ + public final boolean isInteger; + /** {@code true} if number is a {@code long} {@link #isInteger}. */ + public final boolean isLong; + /** {@code true} if number is an {@code unsigned} {@link #isInteger}. */ + public final boolean isUnsigned; + /** The value if {@link #isInteger} */ + public final long i; + + /** {@code true} if number is a {@code double precision} {@code floating point}, i.e. !{@link #isInteger}. */ + public final boolean isDouble; + /** The value if !{@link #isInteger} */ + public final double f; + + /** ctor for integer number */ + public CNumber(final boolean isLong, final boolean isUnsigned, final long value) { + this.isInteger = true; + this.isLong = isLong; + this.isUnsigned = isUnsigned; + this.i = value; + this.isDouble = false; + this.f = 0.0; + } + /** ctor for floating point number */ + public CNumber(final boolean isDouble, final double value) { + this.isInteger = false; + this.isLong = false; + this.isUnsigned = false; + this.i = 0; + this.isDouble = isDouble; + this.f = value; + } + @Override + public int hashCode() { + return isInteger ? Long.valueOf(i).hashCode() : Double.valueOf(f).hashCode(); + } + @Override + public boolean equals(final Object arg) { + if (arg == this) { + return true; + } else if ( !(arg instanceof CNumber) ) { + return false; + } + final CNumber t = (CNumber) arg; + return isInteger == t.isInteger && + ( isInteger ? i == t.i : f == t.f ); + } + public final String toJavaString() { + if( isInteger ) { + if( i >= 0 || isUnsigned ) { + if( isLong ) { + return "0x"+Long.toHexString(i)+"L"; + } else { + return "0x"+Integer.toHexString((int)i); + } + } else { + if( isLong ) { + return String.valueOf(i)+"L"; + } else { + return String.valueOf((int)i); + } + } + } else { + return String.valueOf(f) + ( !isDouble ? "f" : ""); + } + } + public final String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("["); + if( isInteger ) { + if( isUnsigned ) { + sb.append("unsigned "); + } + if( isLong) { + sb.append("long: "); + } else { + sb.append("int: "); + } + sb.append(i); + } else { + if( isDouble ) { + sb.append("double: "); + } else { + sb.append("float: "); + } + sb.append(f); + } + sb.append("]"); + return sb.toString(); + } + } + + /** + * A valid java expression, including its result type, + * usually generated from a native [C] expression, + * see {@link JavaExpr#create(ConstantDefinition)}. + */ + public static class JavaExpr { + public final String javaExpression; + public final CNumber resultType; + public final Number resultJavaType; + public final String resultJavaTypeName; + public JavaExpr(final String javaExpression, final CNumber resultType) { + this.javaExpression = javaExpression; + this.resultType = resultType; + if( resultType.isDouble ) { + resultJavaTypeName = "double"; + resultJavaType = Double.valueOf(resultType.f); + } else if( !resultType.isInteger ) { + resultJavaTypeName = "float"; + resultJavaType = Double.valueOf(resultType.f).floatValue(); + } else if( resultType.isLong ) { + resultJavaTypeName = "long"; + resultJavaType = Long.valueOf(resultType.i); + } else /* if( resultType.isInteger ) */ { + resultJavaTypeName = "int"; + resultJavaType = Long.valueOf(resultType.i).intValue(); + } + } + /** + * Computes a valid {@link JavaExpr java expression} based on the given {@link ConstantDefinition}, + * which may either be a single {@link CNumber}, see {@link ConstantDefinition#getNumber()}, + * or represents a native expression, see {@link ConstantDefinition#getExpr()}. + */ + public static JavaExpr compute(final ConstantDefinition constDef, + final Map constMap) { + final boolean debug = GlueGen.debug(); + if( debug ) { + System.err.println("ConstJavaExpr.create: "+constDef); + } + if( constDef.hasNumber() ) { + // Already parsed as CNumber completely! + if( debug ) { + System.err.printf("V %s (isCNumber)%n", constDef); + } + return new JavaExpr(constDef.getNumber().toJavaString(), constDef.getNumber()); + } + final StringBuilder javaExpr = new StringBuilder(); + final String nativeExpr = constDef.getNativeExpr(); + + // "calculates" the result type of a simple expression + // example: (2+3)-(2.0f-3.0) -> Double + // example: (1 << 2) -> Integer + CNumber resultType = null; + final Matcher matcher = patternCPPOperand.matcher(nativeExpr); + int preStartIdx = 0; + int opEndIdx = 0; + while ( matcher.find() ) { + final int opStartIdx = matcher.start(); + if( opStartIdx > preStartIdx ) { + final String sValue = nativeExpr.substring(preStartIdx, opStartIdx).trim(); + if( sValue.length() > 0 ) { + if( debug ) { + System.err.printf("V %03d-%03d: %s%n", preStartIdx, opStartIdx, sValue); + } + resultType = processValue(constDef, sValue, constMap, resultType, javaExpr); + javaExpr.append(" "); + } + } + opEndIdx = matcher.end(); + final String op = nativeExpr.substring(opStartIdx, opEndIdx); + if( debug ) { + System.err.printf("O %03d-%03d: %s%n", opStartIdx, opEndIdx, op); + } + javaExpr.append(op).append(" "); + preStartIdx = opEndIdx; + } + if( opEndIdx < nativeExpr.length() ) { + // tail .. + final String sValue = nativeExpr.substring(opEndIdx).trim(); + if( sValue.length() > 0 ) { + if( debug ) { + System.err.printf("V %03d %03d-%03d: %s (tail)%n", preStartIdx, opEndIdx, nativeExpr.length(), sValue); + } + resultType = processValue(constDef, sValue, constMap, resultType, javaExpr); + } + } + final String javaExprS = javaExpr.toString().trim(); + if( null == resultType ) { + throw new GlueGenException("Cannot emit const \""+constDef.getName()+"\": value \""+nativeExpr+ + "\", parsed \""+javaExprS+"\" does not contain a constant number", constDef.getASTLocusTag()); + } + return new JavaExpr(javaExprS, resultType); + } + private static CNumber processValue(final ConstantDefinition constDef, + final String sValue, + final Map constMap, + CNumber resultType, + final StringBuilder javaExpr) { + final CNumber nValue = getANumber(constDef, sValue); + if( null != nValue ) { + resultType = evalType(resultType , nValue); + javaExpr.append(nValue.toJavaString()); + } else { + // Lookup CNumber type in const-map, to evaluate this result type + final JavaExpr cje = constMap.get(sValue); + if( null != cje ) { + resultType = evalType(resultType , cje.resultType); + } + javaExpr.append(sValue); + } + return resultType; + } + private static CNumber getANumber(final ConstantDefinition constDef, final String value) { + try { + final CNumber number = decodeANumber(value); + if( null != number ) { + return number; + } + } catch( final Throwable _t ) { + final String msg = "Cannot emit const \""+constDef.getName()+"\": value \""+value+ + "\" cannot be assigned to a int, long, float, or double"; + throw new GlueGenException(msg, constDef.getASTLocusTag(), _t); + } + return null; + } + private static CNumber evalType(final CNumber resultType, final CNumber type) { + //fast path + if( type.isDouble ) { + return type; + } + if( null != resultType ) { + if( resultType.isInteger ) { + if( resultType.isLong ) { + /* resultType is Long */ + if( !type.isInteger ) { + /* resultType: Long -> [ Float || Double ] */ + return type; + } + } else if( type.isLong || !type.isInteger ) { + /* resultType: Integer -> [ Long || Float || Double ] */ + return type; + } + } else if( !resultType.isInteger && !resultType.isDouble ) { + if( type.isDouble ) { + /* resultType: Float -> Double */ + return type; + } + } + } else { + return type; + } + return resultType; + } + } -/** Represents the definition of a constant which was provided either - via a #define statement or through an enum definition. */ -public class ConstantDefinition { - - private final String origName; - private final HashSet aliasedNames; - private String name; - private final String value; + private final boolean relaxedEqSem; + private final String nativeExpr; + private final CNumber number; private final boolean isEnum; private final String enumName; - private Set aliases; + private final ASTLocusTag astLocus; + /** + * Constructor for plain const-values, non-enumerates. + * @param name unique name of this constant expression + * @param nativeExpr original [native] expression + * @param number optional {@link CNumber} representing this constant. + * If {@code null}, implementation attempts to derive a {@link CNumber} + * of the given {@code nativeExpr}. + * @param astLocus AST location of the represented constant. + */ public ConstantDefinition(final String name, - final String value, - final boolean isEnum, - final String enumName) { - this.origName = name; - this.name = name; - this.value = value; + final String nativeExpr, + final CNumber number, + final ASTLocusTag astLocus) { + this(name, nativeExpr, number, false, null, astLocus); + } + /** + * Constructor for enumerates + * @param name unique name of this constant expression + * @param nativeExpr original [native] expression + * @param number optional {@link CNumber} representing this constant. + * If {@code null}, implementation attempts to derive a {@link CNumber} + * of the given {@code nativeExpr}. + * @param enumName optional name of the represented enumeration + * @param astLocus AST location of the represented constant. + */ + public ConstantDefinition(final String name, + final String nativeExpr, + final CNumber number, + final String enumName, final ASTLocusTag astLocus) { + this(name, nativeExpr, number, true, enumName, astLocus); + } + /** + * @param name unique name of this constant expression + * @param nativeExpr original [native] expression + * @param number optional {@link CNumber} representing this constant. + * If {@code null}, implementation attempts to derive a {@link CNumber} + * of the given {@code nativeExpr}. + * @param isEnum {@code true} if this constant is an enumerate, otherwise {@code false}. + * @param enumName optional name of the represented enumeration + * @param astLocus AST location of the represented constant. + */ + private ConstantDefinition(final String name, + final String nativeExpr, + final CNumber number, + final boolean isEnum, final String enumName, final ASTLocusTag astLocus) { + super(name); + this.nativeExpr = nativeExpr; + this.relaxedEqSem = TypeConfig.relaxedEqualSemanticsTest(); + if( null != number ) { + this.number = number; + } else { + // Attempt to parse define string as number + final CNumber iNum = decodeIntegerNumber(nativeExpr); + if( null != iNum ) { + this.number = iNum; + } else { + final CNumber fNum = decodeDecimalNumber(nativeExpr); + if( null != fNum ) { + this.number = fNum; + } else { + this.number = null; + } + } + } this.isEnum = isEnum; this.enumName = enumName; - this.aliasedNames=new HashSet(); + this.astLocus = astLocus; } - public boolean equals(final ConstantDefinition other) { - return (equals(name, other.name) && - equals(value, other.value) && - equals(enumName, other.enumName)); + @Override + public ASTLocusTag getASTLocusTag() { return astLocus; } + + /** + * Hash by its given {@link #getName() name}. + */ + @Override + public final int hashCode() { + return getName().hashCode(); + } + + /** + * Equality test by its given {@link #getName() name}. + */ + @Override + public final boolean equals(final Object arg) { + if (arg == this) { + return true; + } else if ( !(arg instanceof ConstantDefinition) ) { + return false; + } else { + final ConstantDefinition t = (ConstantDefinition)arg; + return equals(getName(), t.getName()); + } + } + + @Override + public final int hashCodeSemantics() { + // 31 * x == (x << 5) - x + int hash = 31 + ( null != getName() ? getName().hashCode() : 0 ); + hash = ((hash << 5) - hash) + ( isEnum ? 1 : 0 ); + hash = ((hash << 5) - hash) + ( null != enumName ? enumName.hashCode() : 0 ); + hash = ((hash << 5) - hash) + ( null != number ? number.hashCode() : 0 ); + return ((hash << 5) - hash) + ( !relaxedEqSem && null != nativeExpr ? nativeExpr.hashCode() : 0 ); + } + + @Override + public final boolean equalSemantics(final SemanticEqualityOp arg) { + if (arg == this) { + return true; + } else if ( !(arg instanceof ConstantDefinition) ) { + return false; + } else { + final ConstantDefinition t = (ConstantDefinition) arg; + if( !equals(getName(), t.getName()) || + isEnum != t.isEnum || + !equals(enumName, t.enumName) ) { + return false; + } + if( null != number ) { + if( number.isInteger ) { + return number.i == t.number.i; + } else { + return number.f == t.number.f; + } + } else { + // define's string value may be semantical equal .. but formatted differently! + return relaxedEqSem || equals(nativeExpr, t.nativeExpr); + } + } } - private boolean equals(final String s1, final String s2) { + /** Returns the original [native] expression. */ + public String getNativeExpr() { return nativeExpr; } + /** + * Returns the parsed {@link CNumber} of the {@link #getNativeExpr() native expression}, + * or {@code null} if the latter does not comprise a single number, + * i.e. is a complex expression. + */ + public CNumber getNumber() { return number; } + /** + * Returns {@code true} if this instance represents has a {@link #getNumber() number}, + * otherwise {@code false}. + */ + public boolean hasNumber() { return null != number; } + + /** Returns {@code null} if this definition was not part of an + enumeration, or if the enumeration is anonymous. */ + public String getEnumName() { return enumName; } + + public boolean isEnum() { return isEnum; } + + @Override + public String toString() { + return "ConstantDefinition [name \"" + getName() + + "\", expression \"" + nativeExpr + + "\", number "+number + + "], enum[is " + isEnum + ", name \"" + enumName + "\"]]"; + } + + private static boolean equals(final String s1, final String s2) { if (s1 == null || s2 == null) { if (s1 == null && s2 == null) { return true; @@ -76,57 +486,469 @@ return s1.equals(s2); } - @Override - public int hashCode() { - return name.hashCode(); + /** + * Computes the {@link JavaExpr java expression} based on this instance, + * see {@link JavaExpr#create(ConstantDefinition)}. + */ + public final JavaExpr computeJavaExpr(final Map constMap) { + return JavaExpr.compute(this, constMap); + } + + // + // Static utility functions for type detection + // + + public static boolean isConstantExpression(final String value) { + if( null != value && value.length() > 0 ) { + // Single numeric value + if ( isNumber(value) ) { + return true; + } + // Find constant expressions like (1 << 3) + // if found just pass them through, they will most likely work in java too + // expressions containing identifiers are currently ignored (casts too) + final String[] values = value.split("[\\s\\(\\)]"); // [ whitespace '(' ')' ] + int numberCount = 0; + for (final String s : values) { + if( s.length() > 0 ) { + if( isCPPOperand(s) ) { + // OK + } else if ( isNumber(s) ) { + // OK + numberCount++; + } else { + return false; + } + } + } + final boolean res = numberCount > 0; + return res; + } + return false; } - /** Supports renaming in Java binding. */ - public void rename(final String name) { - if(null!=name) { - this.name = name; - aliasedNames.add(origName); - } - } + public static boolean isIdentifier(final String value) { + boolean identifier = false; - public void addAliasedName(final String name) { - aliasedNames.add(name); - } - public Collection getAliasedNames() { - return aliasedNames; - } + final char[] chars = value.toCharArray(); - public String getOrigName() { - return origName; + for (int i = 0; i < chars.length; i++) { + final char c = chars[i]; + if (i == 0) { + if (Character.isJavaIdentifierStart(c)) { + identifier = true; + } + } else { + if (!Character.isJavaIdentifierPart(c)) { + identifier = false; + break; + } + } + } + return identifier; } - public String getName() { - return name; + /** + * Returns either {@link #decodeIntegerNumber(String)}, + * {@link #decodeDecimalNumber(String)} or {@code null}. + * @param v + */ + public static CNumber decodeANumber(final String v) { + final CNumber iNumber = ConstantDefinition.decodeIntegerNumber(v); + if( null != iNumber ) { + return iNumber; + } + return ConstantDefinition.decodeDecimalNumber(v); } - public String getValue() { return value; } - /** Returns null if this definition was not part of an - enumeration, or if the enum was anonymous. */ - public String getEnumName() { return enumName; } + /** + * If the given string {@link #isIntegerNumber(String)}, + * return the decoded integer value, represented as a {@code ANumber}, + * otherwise returns {@code null}. + *

    + * Method strips off sign prefix {@code +} + * and integer modifier suffixes {@code [uUlL]} + * before utilizing {@link Long#decode(String)}. + *

    + * @param v + */ + public static CNumber decodeIntegerNumber(final String v) { + if( null == v || !isIntegerNumber(v) ) { + return null; + } + String s0 = v.trim(); + if( 0 == s0.length() ) { + return null; + } + if (s0.startsWith("+")) { + s0 = s0.substring(1, s0.length()).trim(); + if( 0 == s0.length() ) { + return null; + } + } + final boolean neg; + if (s0.startsWith("-")) { + s0 = s0.substring(1, s0.length()).trim(); + if( 0 == s0.length() ) { + return null; + } + neg = true; + } else { + neg = false; + } - public boolean isEnum() { return isEnum; } + // Test last two chars for [lL] and [uU] modifiers! + boolean isUnsigned = false; + boolean isLong = false; + final int j = s0.length() - 2; + for(int i = s0.length() - 1; i >= 0 && i >= j; i--) { + final char lastChar = s0.charAt(s0.length()-1); + if( lastChar == 'u' || lastChar == 'U' ) { + s0 = s0.substring(0, s0.length()-1); + isUnsigned = true; + } else if( lastChar == 'l' || lastChar == 'L' ) { + s0 = s0.substring(0, s0.length()-1); + isLong = true; + } else { + // early out, no modifier match! + break; + } + } + if( 0 == s0.length() ) { + return null; + } + final long res; + if( isLong && isUnsigned ) { + res = decodeULong(s0, neg); + } else { + if( neg ) { + s0 = "-" + s0; + } + res = Long.decode(s0).longValue(); + } + final boolean isLong2 = isLong || + ( !isUnsigned && ( Integer.MIN_VALUE > res || res > Integer.MAX_VALUE ) ) || + ( isUnsigned && res > UNSIGNED_INT_MAX_VALUE ); + return new CNumber(isLong2, isUnsigned, res); + } + private static long decodeULong(final String v, final boolean neg) throws NumberFormatException { + final int radix; + final int idx; + if (v.startsWith("0x") || v.startsWith("0X")) { + idx = 2; + radix = 16; + } else if (v.startsWith("#")) { + idx = 1; + radix = 16; + } else if (v.startsWith("0") && v.length() > 1) { + idx = 1; + radix = 8; + } else { + idx = 0; + radix = 10; + } + final String s0 = ( neg ? "-" : "" ) + v.substring(idx); + final BigInteger res = new BigInteger(s0, radix); + if( res.compareTo(UNSIGNED_LONG_MAX_VALUE) > 0 ) { + throw new NumberFormatException("Value \""+v+"\" is > UNSIGNED_LONG_MAX"); + } + return res.longValue(); + } - public Set getAliases() { - return aliases; + /** + * If the given string {@link #isDecimalNumber(String)}, + * return the decoded floating-point value, represented as a {@code ANumber} object, + * otherwise returns {@code null}. + *

    + * Method utilizes {@link Double#valueOf(String)}. + *

    + * @param v + * @param isDouble return value for {@code double} flag + */ + public static CNumber decodeDecimalNumber(final String v) { + if( null == v || !isDecimalNumber(v) ) { + return null; + } + final String s0 = v.trim(); + if( 0 == s0.length() ) { + return null; + } + boolean _isDouble = false; + final char lastChar = s0.charAt(s0.length()-1); + if( lastChar == 'd' || lastChar == 'D' ) { + _isDouble = true; + } + final double res = Double.valueOf(s0).doubleValue(); + final double ares = Math.abs(res); + return new CNumber(_isDouble || Float.MIN_VALUE > ares || ares > Float.MAX_VALUE, res); } - public void addAlias(final String alias) { - if (aliases == null) { - aliases = new LinkedHashSet(); + /** + * Matches {@link #isHexNumber(String)} or {@link #isDecimalOrIntNumber(String)}. + */ + public static boolean isNumber(final String s) { + if( isHexNumber(s) ) { + return true; + } else { + return isDecimalOrIntNumber(s); } - aliases.add(alias); } - @Override - public String toString() { - return "ConstantDefinition [name " + name + " origName " + origName + " value " + value - + " aliasedNames " + aliasedNames + " aliases " + aliases - + " enumName " + enumName + " isEnum " + isEnum + "]"; + /** + * Matches {@link #isHexNumber(String)} or {@link #patternIntegerNumber}. + */ + public static boolean isIntegerNumber(final String s) { + if( isHexNumber(s) ) { + return true; + } else { + return patternIntegerNumber.matcher(s).matches(); + } } + /** + * Matches {@link #patternHexNumber}. + */ + public static boolean isHexNumber(final String s) { + return patternHexNumber.matcher(s).matches(); + } + + /** + * Matches pattern for floating point number, + * compatible and described in {@link Double#valueOf(String)}. + */ + public static boolean isDecimalNumber(final String s) { + return patternDecimalNumber.matcher(s).matches(); + } + + /** + * Complete pattern for floating point and integer number, + * covering {@link #patternDecimalNumber} and {@link #patternIntegerNumber}. + */ + public static boolean isDecimalOrIntNumber(final String s) { + return patternDecimalOrIntNumber.matcher(s).matches(); + } + + /** + * Matches pattern for valid CPP operands, see {@link #patternCPPOperand}. + */ + public static boolean isCPPOperand(final String s) { + return patternCPPOperand.matcher(s).matches(); + } + + /** + * Complete pattern for hexadecimal number, + * including an optional sign {@code [+-]} and optional suffixes {@code [uUlL]}. + */ + public static Pattern patternHexNumber; + + /** + * Complete pattern for floating point number, + * compatible and described in {@link Double#valueOf(String)}. + */ + public final static Pattern patternDecimalNumber; + + /** + * Complete pattern for floating point and integer number, + * covering {@link #patternDecimalNumber} and {@link #patternIntegerNumber}. + */ + public final static Pattern patternDecimalOrIntNumber; + + /** + * Complete pattern for integer number, + * including an optional sign {@code [+-]} and optional suffixes {@code [uUlL]}. + */ + public final static Pattern patternIntegerNumber; + + /** + * One of: {@code +} {@code -} {@code *} {@code /} {@code |} {@code &} {@code (} {@code )} {@code <<} {@code >>} + *

    + * Expression excludes {@link #patternDecimalOrIntNumber}. + *

    + */ + public static Pattern patternCPPOperand; + + static { + final String WhiteSpace = "[\\x00-\\x20]*"; + final String Digits = "(\\p{Digit}+)"; + final String HexDigits = "(\\p{XDigit}+)"; + final String IntTypeSuffix = + "(" + + "[uU]|" + + "([uU][lL])|" + + "[lL]|" + + "([lL][uU])" + + ")"; + + final String hexRegex = + WhiteSpace + // Optional leading "whitespace" + "[+-]?" + // Optional sign character + // HexDigits IntTypeSuffix_opt + "0[xX]" + HexDigits + IntTypeSuffix + "?" + + WhiteSpace // Optional trailing "whitespace" + ; + patternHexNumber = Pattern.compile(hexRegex); + + final String intRegex = + WhiteSpace + // Optional leading "whitespace" + "[+-]?" + // Optional sign character + // Digits IntTypeSuffix_opt + Digits + IntTypeSuffix + "?" + + WhiteSpace // Optional trailing "whitespace" + ; + patternIntegerNumber = Pattern.compile(intRegex); + + // an exponent is 'e' or 'E' followed by an optionally + // signed decimal integer. + final String Exp = "[eE][+-]?"+Digits; + final String fpRegex = + WhiteSpace + // Optional leading "whitespace" + "[+-]?" + // Optional sign character + "("+ + "NaN|" + // "NaN" string + "Infinity|" + // "Infinity" string + + // A decimal floating-point string representing a finite positive + // number without a leading sign has at most five basic pieces: + // Digits . Digits ExponentPart FloatTypeSuffix + // + // Since this method allows integer-only strings as input + // in addition to strings of floating-point literals, the + // two sub-patterns below are simplifications of the grammar + // productions from the Java Language Specification, 2nd + // edition, section 3.10.2. + + "("+ + "("+ + // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt + "("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+ + + // . Digits ExponentPart_opt FloatTypeSuffix_opt + "(\\.("+Digits+")("+Exp+")?)|"+ + + // Hexadecimal w/ binary exponent + "(" + + "(" + + // Hexadecimal strings + // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt + "(0[xX]" + HexDigits + "(\\.)?)|" + + + // 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt + "(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" + + ")" + + + // binary exponent + "[pP][+-]?" + Digits + + ")" + + ")" + + "[fFdD]?"+ + ")"+ + ")" + + WhiteSpace // Optional trailing "whitespace" + ; + patternDecimalNumber = Pattern.compile(fpRegex); + + final String fpOrIntRegex = + WhiteSpace + // Optional leading "whitespace" + "[+-]?" + // Optional sign character + "("+ + "NaN|" + // "NaN" string + "Infinity|" + // "Infinity" string + + // Matching integers w/ IntTypeSuffix, + // which are otherwise not matched by the below floating point matcher! + // Digits IntTypeSuffix + "(" + Digits + IntTypeSuffix +")|" + + + // A decimal floating-point string representing a finite positive + // number without a leading sign has at most five basic pieces: + // Digits . Digits ExponentPart FloatTypeSuffix + // + // Since this method allows integer-only strings as input + // in addition to strings of floating-point literals, the + // two sub-patterns below are simplifications of the grammar + // productions from the Java Language Specification, 2nd + // edition, section 3.10.2. + + "("+ + "("+ + // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt + "(" + Digits + "(\\.)?(" + Digits + "?)(" + Exp + ")?)|" + + + // . Digits ExponentPart_opt FloatTypeSuffix_opt + "(\\.(" + Digits + ")(" + Exp + ")?)|" + + + // Hexadecimal w/ binary exponent + "(" + + "(" + + // Hexadecimal strings + // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt + "(0[xX]" + HexDigits + "(\\.)?)|" + + + // 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt + "(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" + + ")" + + + // binary exponent + "[pP][+-]?" + Digits + + ")" + + ")" + + "[fFdD]?"+ + ")"+ + ")" + + WhiteSpace // Optional trailing "whitespace" + ; + patternDecimalOrIntNumber = Pattern.compile(fpOrIntRegex); + + final String fpOrIntRegex2 = + WhiteSpace + // Optional leading "whitespace" + // "[+-]?" + // Optional sign character + "("+ + "NaN|" + // "NaN" string + "Infinity|" + // "Infinity" string + + // Matching integers w/ IntTypeSuffix, + // which are otherwise not matched by the below floating point matcher! + // Digits IntTypeSuffix + "(" + Digits + IntTypeSuffix +")|" + + + // A decimal floating-point string representing a finite positive + // number without a leading sign has at most five basic pieces: + // Digits . Digits ExponentPart FloatTypeSuffix + // + // Since this method allows integer-only strings as input + // in addition to strings of floating-point literals, the + // two sub-patterns below are simplifications of the grammar + // productions from the Java Language Specification, 2nd + // edition, section 3.10.2. + + "("+ + "("+ + // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt + "(" + Digits + "(\\.)?(" + Digits + "?)(" + Exp + ")?)|" + + + // . Digits ExponentPart_opt FloatTypeSuffix_opt + "(\\.(" + Digits + ")(" + Exp + ")?)|" + + + // Hexadecimal w/ binary exponent + "(" + + "(" + + // Hexadecimal strings + // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt + "(0[xX]" + HexDigits + "(\\.)?)|" + + + // 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt + "(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" + + ")" + + + // binary exponent + "[pP][+-]?" + Digits + + ")" + + ")" + + "[fFdD]?"+ + ")"+ + ")" + + WhiteSpace // Optional trailing "whitespace" + ; + patternCPPOperand = Pattern.compile("(?!"+fpOrIntRegex2+")[\\+\\-\\*\\/\\|\\&\\(\\)]|(\\<\\<)|(\\>\\>)"); + } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/DebugEmitter.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/DebugEmitter.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/DebugEmitter.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/DebugEmitter.java 2015-10-09 04:18:28.000000000 +0000 @@ -39,6 +39,7 @@ package com.jogamp.gluegen; +import java.io.IOException; import java.util.*; import com.jogamp.gluegen.cgram.types.*; @@ -46,9 +47,16 @@ /** Debug emitter which prints the parsing results to standard output. */ public class DebugEmitter implements GlueEmitter { + protected JavaConfiguration cfg; @Override - public void readConfigurationFile(final String filename) {} + public void readConfigurationFile(final String filename) throws IOException { + cfg = createConfig(); + cfg.read(filename); + } + + @Override + public JavaConfiguration getConfiguration() { return cfg; } @Override public void beginEmission(final GlueEmitterControls controls) { @@ -66,7 +74,7 @@ @Override public void emitDefine(final ConstantDefinition def, final String optionalComment) { final String name = def.getName(); - final String value = def.getValue(); + final String value = def.getNativeExpr(); System.out.println("#define " + name + " " + value + (optionalComment != null ? ("// " + optionalComment) : "")); } @@ -110,10 +118,10 @@ } @Override - public void emitStruct(final CompoundType t, final String alternateName) { + public void emitStruct(final CompoundType t, final Type typedefType) { String name = t.getName(); - if (name == null && alternateName != null) { - name = alternateName; + if (name == null && typedefType != null) { + name = typedefType.getName(); } System.out.println("Referenced type \"" + name + "\""); @@ -121,4 +129,13 @@ @Override public void endStructs() {} + + /** + * Create the object that will read and store configuration information for + * this JavaEmitter. + */ + protected JavaConfiguration createConfig() { + return new JavaConfiguration(); + } + } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/FunctionEmitter.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/FunctionEmitter.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/FunctionEmitter.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/FunctionEmitter.java 2015-10-09 04:18:28.000000000 +0000 @@ -42,57 +42,43 @@ import java.util.*; import java.io.*; +import com.jogamp.gluegen.cgram.types.FunctionSymbol; import com.jogamp.gluegen.cgram.types.Type; public abstract class FunctionEmitter { public static final EmissionModifier STATIC = new EmissionModifier("static"); - private final boolean isInterfaceVal; + private final boolean isInterface; private final ArrayList modifiers; private CommentEmitter commentEmitter = null; private final PrintWriter defaultOutput; + // Only present to provide more clear comments + protected final JavaConfiguration cfg; /** * Constructs the FunctionEmitter with a CommentEmitter that emits nothing. */ - public FunctionEmitter(final PrintWriter defaultOutput, final boolean isInterface) { + public FunctionEmitter(final PrintWriter defaultOutput, final boolean isInterface, final JavaConfiguration configuration) { assert(defaultOutput != null); + this.isInterface = isInterface; this.modifiers = new ArrayList(); this.defaultOutput = defaultOutput; - this.isInterfaceVal = isInterface; + this.cfg = configuration; } /** * Makes this FunctionEmitter a copy of the passed one. */ public FunctionEmitter(final FunctionEmitter arg) { + isInterface = arg.isInterface; modifiers = new ArrayList(arg.modifiers); commentEmitter = arg.commentEmitter; defaultOutput = arg.defaultOutput; - isInterfaceVal = arg.isInterfaceVal; + cfg = arg.cfg; } - public boolean isInterface() { return isInterfaceVal; } - - /** - * Checks the base type of pointer-to-pointer, pointer, array or plain for const-ness. - *

    - * Note: Implementation walks down to the base type and returns it's const-ness. - * Intermediate 'const' qualifier are not considered, e.g. const pointer. - *

    - */ - protected final boolean isBaseTypeConst(final Type type) { - if ( 2 == type.pointerDepth() ) { - return type.asPointer().getTargetType().asPointer().getTargetType().isConst(); - } else if ( 1 == type.pointerDepth() ) { - return type.asPointer().getTargetType().isConst(); - } else if( type.isArray() ) { - return type.asArray().getBaseElementType().isConst(); - } else { - return type.isConst(); - } - } + public boolean isInterface() { return isInterface; } public PrintWriter getDefaultOutput() { return defaultOutput; } @@ -111,7 +97,11 @@ public Iterator getModifiers() { return modifiers.iterator(); } - public abstract String getName(); + public abstract String getInterfaceName(); + public abstract String getImplName(); + public abstract String getNativeName(); + + public abstract FunctionSymbol getCSymbol(); /** * Emit the function to the specified output (instead of the default diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/GenericCPP.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/GenericCPP.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/GenericCPP.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/GenericCPP.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,63 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.gluegen; + +import java.io.OutputStream; +import java.io.Reader; +import java.util.List; + +import com.jogamp.gluegen.jcpp.LexerException; + +/** + * Generic C preprocessor interface for GlueGen + */ +public interface GenericCPP { + + public void addDefine(String name, String value) throws LexerException; + + public String findFile(String filename); + + public OutputStream out(); + public void setOut(OutputStream out); + + public void run(Reader reader, String filename) throws GlueGenException; + + /** + * Returns a list of {@link ConstantDefinition}, i.e. + * non-function-like and non-empty macros w/ constant-value, + * as derived during parsing. + *

    + * May return an empty list, in case this preprocessor does not + * store {@link ConstantDefinition}s. + *

    + * @throws GlueGenException + */ + public List getConstantDefinitions() throws GlueGenException; + + +} \ No newline at end of file diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/GlueEmitter.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/GlueEmitter.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/GlueEmitter.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/GlueEmitter.java 2015-10-09 04:18:28.000000000 +0000 @@ -50,6 +50,7 @@ public interface GlueEmitter { public void readConfigurationFile(String filename) throws Exception; + public JavaConfiguration getConfiguration(); /** * Begin the emission of glue code. This might include opening files, @@ -91,11 +92,11 @@ public void beginStructs(TypeDictionary typedefDictionary, TypeDictionary structDictionary, Map canonMap) throws Exception; - /** Emit glue code for the given CompoundType. alternateName is + /** Emit glue code for the given CompoundType. typedefType is provided when the CompoundType (e.g. "struct foo_t") has not been typedefed to anything but the type of "pointer to struct foo_t" has (e.g. "typedef struct foo_t {} *Foo"); in this case - alternateName would be set to Foo. */ - public void emitStruct(CompoundType t, String alternateName) throws Exception; + typedefType would be set to pointer type Foo. */ + public void emitStruct(CompoundType t, Type typedefType) throws Exception; public void endStructs() throws Exception; } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/GlueGenException.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/GlueGenException.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/GlueGenException.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/GlueGenException.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,92 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.gluegen; + +import com.jogamp.common.JogampRuntimeException; + +/** A generic exception for Jogamp errors used throughout the binding + as a substitute for {@link RuntimeException}. */ + +@SuppressWarnings("serial") +public class GlueGenException extends JogampRuntimeException { + final ASTLocusTag locus; + + public ASTLocusTag getASTLocusTag() { return locus; } + + /** Constructs a GlueGenException object. */ + public GlueGenException() { + super(); + locus = null; + } + + /** Constructs a GlueGenException object with the specified detail + message. */ + public GlueGenException(final String message) { + super(message); + locus = null; + } + + /** Constructs a GlueGenException object with the specified detail + message and root cause. */ + public GlueGenException(final String message, final Throwable cause) { + super(message, cause); + locus = null; + } + + /** Constructs a GlueGenException object with the specified root + cause. */ + public GlueGenException(final Throwable cause) { + super(cause); + locus = null; + } + + /** Constructs a GlueGenException object with the specified detail + message and root cause. */ + public GlueGenException(final String message, final ASTLocusTag locusTag) { + super(message); + this.locus = locusTag; + } + + /** Constructs a GlueGenException object with the specified detail + message and root cause. */ + public GlueGenException(final String message, final ASTLocusTag locusTag, final Throwable cause) { + super(message, cause); + this.locus = locusTag; + } + + public String toString() { + final StringBuilder sb = new StringBuilder(256); + if (null != locus) { + locus.toString(sb, "error", true).append(": "); + } + sb.append(getClass().getSimpleName()).append(": ").append(getLocalizedMessage()); + return sb.toString(); + } + +} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/GlueGen.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/GlueGen.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/GlueGen.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/GlueGen.java 2015-10-09 04:18:28.000000000 +0000 @@ -43,11 +43,13 @@ import java.io.*; import java.util.*; +import java.util.logging.Level; import antlr.*; + import com.jogamp.gluegen.cgram.*; import com.jogamp.gluegen.cgram.types.*; -import com.jogamp.gluegen.pcpp.*; +import com.jogamp.gluegen.jcpp.JCPP; import static java.lang.System.*; @@ -61,14 +63,18 @@ } private final List forcedStructNames = new ArrayList(); - private PCPP preprocessor; + private GenericCPP preprocessor; // State for SymbolFilters - private List constants; - private List functions; + private List allConstants; + private List allFunctions; private static boolean debug = false; + private static Level logLevel = null; + + public static void setDebug(final boolean v) { debug=v; } + public static void setLogLevel(final Level l) { logLevel=l; } public static boolean debug() { return debug; } @Override @@ -83,38 +89,66 @@ @Override public void runSymbolFilter(final SymbolFilter filter) { - filter.filterSymbols(constants, functions); + filter.filterSymbols(allConstants, allFunctions); final List newConstants = filter.getConstants(); final List newFunctions = filter.getFunctions(); if (newConstants != null) { - constants = newConstants; + allConstants = newConstants; } if (newFunctions != null) { - functions = newFunctions; + allFunctions = newFunctions; } } + /** GlueGen's build in macro name {@value}, when compiling w/ GlueGen. */ + public static final String __GLUEGEN__ = "__GLUEGEN__"; @SuppressWarnings("unchecked") - public void run(final Reader reader, final String filename, final Class emitterClass, final List includePaths, final List cfgFiles, final String outputRootDir, final boolean copyPCPPOutput2Stderr) { + public void run(final Reader reader, final String filename, final Class emitterClass, final List includePaths, final List cfgFiles, final String outputRootDir, final boolean copyCPPOutput2Stderr) { try { - final File out = File.createTempFile("PCPPTemp", ".pcpp"); + if(debug) { + Logging.getLogger().setLevel(Level.ALL); + } else if( null != logLevel ) { + Logging.getLogger().setLevel(logLevel); + } + final GlueEmitter emit; + if (emitterClass == null) { + emit = new JavaEmitter(); + } else { + try { + emit = (GlueEmitter) emitterClass.newInstance(); + } catch (final Exception e) { + throw new RuntimeException("Exception occurred while instantiating emitter class.", e); + } + } + + for (final String config : cfgFiles) { + emit.readConfigurationFile(config); + } + final JavaConfiguration cfg = emit.getConfiguration(); + + final File out = File.createTempFile("CPPTemp", ".cpp"); final FileOutputStream outStream = new FileOutputStream(out); + // preprocessor = new PCPP(includePaths, debug, copyCPPOutput2Stderr); + preprocessor = new JCPP(includePaths, debug, copyCPPOutput2Stderr); + final String cppName = preprocessor.getClass().getSimpleName(); if(debug) { - System.err.println("PCPP output at (persistent): " + out.getAbsolutePath()); + System.err.println("CPP <"+cppName+"> output at (persistent): " + out.getAbsolutePath()); } else { out.deleteOnExit(); } - preprocessor = new PCPP(includePaths, debug, copyPCPPOutput2Stderr); - preprocessor.addDefine("__GLUEGEN__", "2"); + preprocessor.addDefine(__GLUEGEN__, "2"); preprocessor.setOut(outStream); preprocessor.run(reader, filename); outStream.flush(); outStream.close(); + if(debug) { + System.err.println("CPP <"+cppName+"> done"); + } final FileInputStream inStream = new FileInputStream(out); final DataInputStream dis = new DataInputStream(inStream); @@ -140,6 +174,7 @@ final HeaderParser headerParser = new HeaderParser(); headerParser.setDebug(debug); + headerParser.setJavaConfiguration(cfg); final TypeDictionary td = new TypeDictionary(); headerParser.setTypedefDictionary(td); final TypeDictionary sd = new TypeDictionary(); @@ -162,21 +197,6 @@ // generate glue code: the #defines to constants, the set of // typedefs, and the set of functions. - GlueEmitter emit = null; - if (emitterClass == null) { - emit = new JavaEmitter(); - } else { - try { - emit = (GlueEmitter) emitterClass.newInstance(); - } catch (final Exception e) { - throw new RuntimeException("Exception occurred while instantiating emitter class.", e); - } - } - - for (final String config : cfgFiles) { - emit.readConfigurationFile(config); - } - if (null != outputRootDir && outputRootDir.trim().length() > 0) { if (emit instanceof JavaEmitter) { // FIXME: hack to interfere with the *Configuration setting via commandlines @@ -189,7 +209,7 @@ // Repackage the enum and #define statements from the parser into a common format // so that SymbolFilters can operate upon both identically - constants = new ArrayList(); + allConstants = new ArrayList(); for (final EnumType enumeration : headerParser.getEnums()) { String enumName = enumeration.getName(); if (enumName.equals("")) { @@ -197,63 +217,93 @@ } // iterate over all values in the enumeration for (int i = 0; i < enumeration.getNumEnumerates(); ++i) { - final String enumElementName = enumeration.getEnumName(i); - final String value = String.valueOf(enumeration.getEnumValue(i)); - constants.add(new ConstantDefinition(enumElementName, value, true, enumName)); + final EnumType.Enumerator enumerate = enumeration.getEnum(i); + final ConstantDefinition def = + new ConstantDefinition(enumerate.getName(), enumerate.getExpr(), + enumerate.getNumber(), + enumName, enumeration.getASTLocusTag()); + allConstants.add(def); } } for (final Object elem : lexer.getDefines()) { final Define def = (Define) elem; - constants.add(new ConstantDefinition(def.getName(), def.getValue(), false, null)); + allConstants.add(new ConstantDefinition(def.getName(), def.getValue(), null, def.getASTLocusTag())); } + allConstants.addAll(preprocessor.getConstantDefinitions()); - functions = headerParser.getParsedFunctions(); + allFunctions = headerParser.getParsedFunctions(); - // begin emission of glue code + // begin emission of glue code, + // incl. firing up 'runSymbolFilter(SymbolFilter)' calls, which: + // - filters all ConstantDefinition + // - filters all FunctionSymbol emit.beginEmission(this); - emit.beginDefines(); - final Set emittedDefines = new HashSet(100); - // emit java equivalent of enum { ... } statements - final StringBuilder comment = new StringBuilder(); - for (final ConstantDefinition def : constants) { - if (!emittedDefines.contains(def.getName())) { - emittedDefines.add(def.getName()); - final Set aliases = def.getAliases(); - if (aliases != null) { - comment.append("Alias for: "); - for (final String alias : aliases) { - comment.append(" ").append(alias); - } - comment.append(""); - } - if (def.getEnumName() != null) { - if (comment.length() > 0) - comment.append("
    \n"); - - comment.append("Defined as part of enum type \""); - comment.append(def.getEnumName()); - comment.append("\""); + if( debug() ) { + int i=0; + System.err.println("Filtered Constants: "+allConstants.size()); + for (final ConstantDefinition def : allConstants) { + if( debug() ) { + System.err.println("Filtered ["+i+"]: "+def.getAliasedString()); + i++; } - if (comment.length() > 0) { - emit.emitDefine(def, comment.toString()); - comment.setLength(0); - } - else { - emit.emitDefine(def, null); + } + i=0; + System.err.println("Filtered Functions: "+allFunctions.size()); + for (final FunctionSymbol cFunc : allFunctions) { + System.err.println("Filtered ["+i+"]: "+cFunc.getAliasedString()); + i++; + } + } + + if ( !cfg.structsOnly() ) { + emit.beginDefines(); + final Set emittedDefines = new HashSet(100); + // emit java equivalent of enum { ... } statements + final StringBuilder comment = new StringBuilder(); + for (final ConstantDefinition def : allConstants) { + if (!emittedDefines.contains(def.getName())) { + emittedDefines.add(def.getName()); + final Set aliases = cfg.getAliasedDocNames(def); + if (aliases != null && aliases.size() > 0 ) { + int i=0; + comment.append("Alias for: "); + for (final String alias : aliases) { + if(0 < i) { + comment.append(", "); + } + comment.append(alias); + i++; + } + comment.append(""); + } + if (def.getEnumName() != null) { + if (comment.length() > 0) + comment.append("
    \n"); + + comment.append("Defined as part of enum type \""); + comment.append(def.getEnumName()); + comment.append("\""); + } + if (comment.length() > 0) { + emit.emitDefine(def, comment.toString()); + comment.setLength(0); + } + else { + emit.emitDefine(def, null); + } } } + emit.endDefines(); } - emit.endDefines(); // Iterate through the functions finding structs that are referenced in // the function signatures; these will be remembered for later emission final ReferencedStructs referencedStructs = new ReferencedStructs(); - for (final FunctionSymbol sym : functions) { + for (final FunctionSymbol sym : allFunctions) { // FIXME: this doesn't take into account the possibility that some of // the functions we send to emitMethodBindings() might not actually be - // emitted (e.g., if an Ignore directive in the JavaEmitter causes it - // to be skipped). + // emitted (e.g., if an Ignore directive in the JavaEmitter causes it to be skipped). sym.getType().visit(referencedStructs); } @@ -273,13 +323,9 @@ // Lay out structs emit.beginStructLayout(); - for (final Iterator iter = referencedStructs.results(); iter.hasNext();) { - final Type t = iter.next(); - if (t.isCompound()) { - emit.layoutStruct(t.asCompound()); - } else if (t.isPointer()) { - final PointerType p = t.asPointer(); - final CompoundType c = p.getTargetType().asCompound(); + for (final Iterator iter = referencedStructs.layouts(); iter.hasNext();) { + final CompoundType c = iter.next(); + if( !c.isLayouted() ) { emit.layoutStruct(c); } } @@ -290,20 +336,23 @@ for (final Iterator iter = referencedStructs.results(); iter.hasNext();) { final Type t = iter.next(); if (t.isCompound()) { + assert t.isTypedef() && t.getName() == null : "ReferencedStructs incorrectly recorded compound type " + t; emit.emitStruct(t.asCompound(), null); } else if (t.isPointer()) { final PointerType p = t.asPointer(); final CompoundType c = p.getTargetType().asCompound(); - assert p.hasTypedefedName() && c.getName() == null : "ReferencedStructs incorrectly recorded pointer type " + p; - emit.emitStruct(c, p.getName()); + assert p.isTypedef() && c.getName() == null : "ReferencedStructs incorrectly recorded pointer type " + p; + emit.emitStruct(c, p); } } emit.endStructs(); - // emit java and C code to interface with the native functions - emit.beginFunctions(td, sd, headerParser.getCanonMap()); - emit.emitFunctions(functions); - emit.endFunctions(); + if ( !cfg.structsOnly() ) { + // emit java and C code to interface with the native functions + emit.beginFunctions(td, sd, headerParser.getCanonMap()); + emit.emitFunctions(allFunctions); + emit.endFunctions(); + } // end emission of glue code emit.endEmission(); @@ -340,6 +389,9 @@ emitterFQN = arg.substring(2); } else if (arg.startsWith("-C")) { cfgFiles.add(arg.substring(2)); + } else if (arg.equals("--logLevel")) { + i++; + logLevel = Level.parse(args[i]); } else if (arg.equals("--debug")) { debug=true; } else if (arg.equals("--dumpCPP")) { @@ -392,7 +444,7 @@ out.println("file or files can be specified with -C option; e.g,"); out.println("-Cjava-emitter.cfg."); out.println(" --debug enables debug mode"); - out.println(" --dumpCPP directs PCPP to dump all output to stderr as well"); + out.println(" --dumpCPP directs CPP to dump all output to stderr as well"); exit(1); } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/JavaConfiguration.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/JavaConfiguration.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/JavaConfiguration.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/JavaConfiguration.java 2015-10-09 04:18:28.000000000 +0000 @@ -40,19 +40,19 @@ package com.jogamp.gluegen; +import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider; import com.jogamp.gluegen.JavaEmitter.EmissionStyle; import com.jogamp.gluegen.JavaEmitter.MethodAccess; +import com.jogamp.gluegen.Logging.LoggerIf; + import java.io.*; import java.lang.reflect.Array; import java.util.*; -import java.util.Map.Entry; import java.util.regex.*; import com.jogamp.gluegen.jgram.*; import com.jogamp.gluegen.cgram.types.*; -import java.util.logging.Logger; - import static java.util.logging.Level.*; import static com.jogamp.gluegen.JavaEmitter.MethodAccess.*; import static com.jogamp.gluegen.JavaEmitter.EmissionStyle.*; @@ -61,17 +61,13 @@ JavaEmitter. */ public class JavaConfiguration { - - public static final boolean DEBUG_IGNORES = GlueGen.debug() || false; - public static final boolean DEBUG_RENAMES = GlueGen.debug() || false; - private int nestedReads; private String packageName; private String implPackageName; private String className; private String implClassName; - protected static final Logger LOG = Logger.getLogger(JavaConfiguration.class.getPackage().getName()); + protected final LoggerIf LOG; public static String NEWLINE = System.getProperty("line.separator"); @@ -106,6 +102,13 @@ private boolean tagNativeBinding; /** + * If true, {@link TypeConfig.SemanticEqualityOp#equalSemantics(TypeConfig.SemanticEqualityOp)} + * will attempt to perform a relaxed semantic equality test, e.g. skip the {@code const} and {@code volatile} qualifiers. + * Otherwise a full semantic equality test will be performed. + */ + private boolean relaxedEqualSemanticsTest; + + /** * Style of code emission. Can emit everything into one class * (AllStatic), separate interface and implementing classes * (InterfaceAndImpl), only the interface (InterfaceOnly), or only @@ -135,6 +138,7 @@ private final Map accessControl = new HashMap(); private final Map typeInfoMap = new HashMap(); private final Set returnsString = new HashSet(); + private final Map returnsOpaqueJType = new HashMap(); private final Map returnedArrayLengths = new HashMap(); /** @@ -156,6 +160,7 @@ private boolean forceUseNIODirectOnly4All = false; private final Set useNIODirectOnly = new HashSet(); private final Set manuallyImplement = new HashSet(); + private final Map delegatedImplementation = new HashMap(); private final Set manualStaticInitCall = new HashSet(); private final Set forceStaticInitCode = new HashSet(); private final Map> customJavaCode = new HashMap>(); @@ -164,6 +169,7 @@ private final Map structPackages = new HashMap(); private final List customCCode = new ArrayList(); private final List forcedStructs = new ArrayList(); + private final Map structMachineDataInfoIndex = new HashMap(); private final Map returnValueCapacities = new HashMap(); private final Map returnValueLengths = new HashMap(); private final Map> temporaryCVariableDeclarations = new HashMap>(); @@ -177,6 +183,10 @@ private final Map> javaPrologues = new HashMap>(); private final Map> javaEpilogues = new HashMap>(); + public JavaConfiguration() { + LOG = Logging.getLogger(JavaConfiguration.class.getPackage().getName(), JavaConfiguration.class.getSimpleName()); + } + /** Reads the configuration file. @param filename path to file that should be read */ @@ -314,20 +324,32 @@ return tagNativeBinding; } + /** + * Returns whether {@link TypeConfig.SemanticEqualityOp#equalSemantics(TypeConfig.SemanticEqualityOp)} + * shall attempt to perform a relaxed semantic equality test, e.g. skip the {@code const} and {@code volatile} qualifier + * - or not. + */ + public boolean relaxedEqualSemanticsTest() { + return relaxedEqualSemanticsTest; + } + /** Returns the code emission style (constants in JavaEmitter) parsed from the configuration file. */ public EmissionStyle emissionStyle() { return emissionStyle; } - /** Returns the access control for the emitted Java method. Returns one of JavaEmitter.ACC_PUBLIC, JavaEmitter.ACC_PROTECTED, JavaEmitter.ACC_PRIVATE, or JavaEmitter.ACC_PACKAGE_PRIVATE. */ - public MethodAccess accessControl(final String methodName) { - final MethodAccess ret = accessControl.get(methodName); + /** + * Returns the access control for the given method-name + * or fully qualified class-name. + */ + public MethodAccess accessControl(final String name) { + final MethodAccess ret = accessControl.get(name); if (ret != null) { return ret; } // Default access control is public return PUBLIC; - } + } /** Returns the package in which the generated glue code expects to find its run-time helper classes (Buffers, Platform, @@ -352,15 +374,31 @@ } private static final boolean DEBUG_TYPE_INFO = false; + + /** + * If the given {@code canonicalName} should be considered opaque, + * returns the TypeInfo describing the replacement type. + *

    + * Returns null if this type should not be considered opaque. + *

    + *

    + * If symbol references a struct fields, see {@link #canonicalStructFieldSymbol(String, String)}, + * it describes field's array-length or element-count referenced by a pointer. + *

    + */ + public TypeInfo canonicalNameOpaque(final String canonicalName) { + return typeInfoMap.get(canonicalName); + } + /** If this type should be considered opaque, returns the TypeInfo describing the replacement type. Returns null if this type should not be considered opaque. */ - public TypeInfo typeInfo(Type type, final TypeDictionary typedefDictionary) { + public TypeInfo typeInfo(Type type) { // Because typedefs of pointer types can show up at any point, // walk the pointer chain looking for a typedef name that is in // the TypeInfo map. if (DEBUG_TYPE_INFO) - System.err.println("Incoming type = " + type); + System.err.println("Incoming type = " + type + ", " + type.getDebugString()); final int pointerDepth = type.pointerDepth(); for (int i = 0; i <= pointerDepth; i++) { String name = type.getName(); @@ -371,12 +409,13 @@ if (name != null) { final TypeInfo info = closestTypeInfo(name, i + type.pointerDepth()); if (info != null) { + final TypeInfo res = promoteTypeInfo(info, i); if (DEBUG_TYPE_INFO) { - System.err.println(" info.name=" + info.name() + ", name=" + name + + System.err.println(" [1] info.name=" + info.name() + ", name=" + name + ", info.pointerDepth=" + info.pointerDepth() + - ", type.pointerDepth=" + type.pointerDepth()); + ", type.pointerDepth=" + type.pointerDepth() + " -> "+res); } - return promoteTypeInfo(info, i); + return res; } } @@ -386,33 +425,13 @@ if (name != null) { final TypeInfo info = closestTypeInfo(name, i + type.pointerDepth()); if (info != null) { + final TypeInfo res = promoteTypeInfo(info, i); if (DEBUG_TYPE_INFO) { - System.err.println(" info.name=" + info.name() + ", name=" + name + + System.err.println(" [2] info.name=" + info.name() + ", name=" + name + ", info.pointerDepth=" + info.pointerDepth() + - ", type.pointerDepth=" + type.pointerDepth()); + ", type.pointerDepth=" + type.pointerDepth() + " -> "+res); } - return promoteTypeInfo(info, i); - } - } - } - - // Try all typedef names that map to this type - final Set> entrySet = typedefDictionary.entrySet(); - for (final Map.Entry entry : entrySet) { - // "eq" equality is OK to use here since all types have been canonicalized - if (entry.getValue() == type) { - name = entry.getKey(); - if (DEBUG_TYPE_INFO) { - System.err.println("Looking under typedef name " + name); - } - final TypeInfo info = closestTypeInfo(name, i + type.pointerDepth()); - if (info != null) { - if (DEBUG_TYPE_INFO) { - System.err.println(" info.name=" + info.name() + ", name=" + name + - ", info.pointerDepth=" + info.pointerDepth() + - ", type.pointerDepth=" + type.pointerDepth()); - } - return promoteTypeInfo(info, i); + return res; } } } @@ -421,7 +440,9 @@ type = type.asPointer().getTargetType(); } } - + if (DEBUG_TYPE_INFO) { + System.err.println(" [X] NULL"); + } return null; } @@ -491,6 +512,13 @@ public boolean returnsString(final String functionName) { return returnsString.contains(functionName); } + /** Indicates whether the given function (which returns a + char* in C) should be translated as returning a + java.lang.String. */ + public boolean returnsString(final AliasedSymbol symbol) { + return returnsString.contains( symbol.getName() ) || + oneInSet(returnsString, symbol.getAliasedNames()); + } /** * Returns a MessageFormat string of the Java expression calculating @@ -543,12 +571,6 @@ return forceUseNIODirectOnly4All || useNIODirectOnly.contains(functionName); } - /** Returns true if the glue code for the given function will be - manually implemented by the end user. */ - public boolean manuallyImplement(final String functionName) { - return manuallyImplement.contains(functionName); - } - /** * Returns true if the static initialization java code calling initializeImpl() * for the given class will be manually implemented by the end user @@ -634,6 +656,20 @@ } /** + * Returns a MessageFormat string of the Java code defining {@code mdIdx}, + * i.e. the index of the static MachineDescriptor index for structs. + *

    + * If undefined, code generation uses the default expression: + *

    +   *     private static final int mdIdx = MachineDataInfoRuntime.getStatic().ordinal();
    +   * 
    + *

    + */ + public String returnStructMachineDataInfoIndex(final String structName) { + return structMachineDataInfoIndex.get(structName); + } + + /** * Returns a MessageFormat string of the C expression calculating * the capacity of the java.nio.ByteBuffer being returned from a * native method, or null if no expression has been specified. @@ -702,52 +738,94 @@ return parentClass.get(className); } - public void dumpIgnoresOnce() { - if(!dumpedIgnores) { - dumpedIgnores = true; - dumpIgnores(); + public void logIgnoresOnce() { + if(!loggedIgnores) { + loggedIgnores = true; + logIgnores(); } } - private static boolean dumpedIgnores = false; + private static boolean loggedIgnores = false; - public void dumpIgnores() { - System.err.println("Extended Intf: "); + public void logIgnores() { + LOG.log(INFO, "Extended Intf: {0}", extendedIntfSymbolsIgnore.size()); for (final String str : extendedIntfSymbolsIgnore) { - System.err.println("\t"+str); + LOG.log(INFO, "\t{0}", str); } - System.err.println("Extended Impl: "); + LOG.log(INFO, "Extended Impl: {0}", extendedImplSymbolsIgnore.size()); for (final String str : extendedImplSymbolsIgnore) { - System.err.println("\t"+str); + LOG.log(INFO, "\t{0}", str); } - System.err.println("Ignores (All): "); + LOG.log(INFO, "Ignores (All): {0}", ignores.size()); for (final Pattern pattern : ignores) { - System.err.println("\t"+pattern); + LOG.log(INFO, "\t{0}", pattern); } } - public void dumpRenamesOnce() { - if(!dumpedRenames) { - dumpedRenames = true; - dumpRenames(); + public void logRenamesOnce() { + if(!loggedRenames) { + loggedRenames = true; + logRenames(); } } - private static boolean dumpedRenames = false; + private static boolean loggedRenames = false; - public void dumpRenames() { - System.err.println("Symbol Renames: "); + public void logRenames() { + LOG.log(INFO, "Symbol Renames: {0}", javaSymbolRenames.size()); for (final String key : javaSymbolRenames.keySet()) { - System.err.println("\t"+key+" -> "+javaSymbolRenames.get(key)); + LOG.log(INFO, "\t{0} -> {1}", key, javaSymbolRenames.get(key)); } - System.err.println("Symbol Aliasing (through renaming): "); + LOG.log(INFO, "Symbol Aliasing (through renaming): {0}", javaSymbolRenames.size()); for(final String newName : javaSymbolRenames.values()) { final Set origNames = javaRenamedSymbols.get(newName); if(null!=origNames) { - System.err.println("\t"+newName+" <- "+origNames); + LOG.log(INFO, "\t{0} <- {1}", newName, origNames); } } } + public static V oneInMap(final Map map, final Set symbols) { + if( null != map && map.size() > 0 && + null != symbols && symbols.size() > 0 ) { + for(final K sym : symbols) { + final V v = map.get(sym); + if( null != v ) { + return v; + } + } + } + return null; + } + public static boolean oneInSet(final Set set1, final Set set2) { + if( null != set1 && set1.size() > 0 && + null != set2 && set2.size() > 0 ) { + for(final K sym : set2) { + if( set1.contains( sym ) ) { + return true; + } + } + } + return false; + } + private static boolean onePatternMatch(final Pattern ignoreRegexp, final Set set) { + if( null != ignoreRegexp && null != set && set.size() > 0 ) { + for(final String sym : set) { + final Matcher matcher = ignoreRegexp.matcher(sym); + if (matcher.matches()) { + return true; + } + } + } + return false; + } + protected static ASTLocusTag getASTLocusTag(final AliasedSymbol s) { + if( s instanceof ASTLocusTagProvider ) { + return ((ASTLocusTagProvider)s).getASTLocusTag(); + } else { + return null; + } + } + /** * Returns the canonical configuration name for a struct field name, * i.e. 'struct-name'.'field-name' @@ -757,136 +835,286 @@ } /** - * Returns true if this #define, function, struct, or field within - * a struct should be ignored during glue code generation of interfaces and implementation. + * Variant of {@link #manuallyImplement(AliasedSymbol)}, + * where this method only considers the {@link AliasedSymbol#getName() current-name} + * of the given symbol, not the {@link #getJavaSymbolRename(String) renamed-symbol}. + */ + public boolean manuallyImplement(final String functionName) { + if( manuallyImplement.contains(functionName) ) { + LOG.log(INFO, "ManuallyImplement: \"{0}\"", functionName); + return true; + } else { + return false; + } + } + + /** + * Returns true if the glue code for the given aliased function will be + * manually implemented by the end user. *

    - * For struct fields see {@link #canonicalStructFieldSymbol(String, String)}. + * Both, the {@link AliasedSymbol#getName() current-name} + * and all {@link AliasedSymbol#getAliasedNames() aliases} shall be considered. *

    + *

    + * If symbol references a struct field or method, see {@link #canonicalStructFieldSymbol(String, String)}, + * it describes field's array-length or element-count referenced by a pointer. + *

    + * @see #manuallyImplement(String) */ - public boolean shouldIgnoreInInterface(final String symbol) { - if(DEBUG_IGNORES) { - dumpIgnoresOnce(); - } - // Simple case-1; the entire symbol (orig or renamed) is in the interface ignore table - final String renamedSymbol = getJavaSymbolRename(symbol); - if ( extendedIntfSymbolsIgnore.contains( symbol ) || - extendedIntfSymbolsIgnore.contains( renamedSymbol ) ) { - if(DEBUG_IGNORES) { - System.err.println("Ignore Intf ignore : "+symbol); - } - return true; - } - // Simple case-2; the entire symbol (orig or renamed) is _not_ in the not-empty interface only table - if ( !extendedIntfSymbolsOnly.isEmpty() && - !extendedIntfSymbolsOnly.contains( symbol ) && - !extendedIntfSymbolsOnly.contains( renamedSymbol ) ) { - if(DEBUG_IGNORES) { - System.err.println("Ignore Intf !extended: " + symbol); - } + public boolean manuallyImplement(final AliasedSymbol symbol) { + final String name = symbol.getName(); + final Set aliases = symbol.getAliasedNames(); + + if ( manuallyImplement.contains( name ) || + oneInSet(manuallyImplement, aliases) + ) + { + LOG.log(INFO, getASTLocusTag(symbol), "ManuallyImplement: {0}", symbol); return true; - } - return shouldIgnoreInImpl_Int(symbol); + } else { + return false; + } } /** - * Returns true if this #define, function, struct, or field within - * a struct should be ignored during glue code generation of implementation only. + * Variant of {@link #getDelegatedImplementation(AliasedSymbol)}, + * where this method only considers the {@link AliasedSymbol#getName() current-name} + * of the given symbol, not the {@link #getJavaSymbolRename(String) renamed-symbol}. + */ + public String getDelegatedImplementation(final String functionName) { + final String res = delegatedImplementation.get(functionName); + if( null == res ) { + return null; + } + LOG.log(INFO, "DelegatedImplementation: {0} -> {1}", functionName, res); + return res; + } + + /** + * Returns the {@code RENAMED-IMPL-SYMBOL} if the implementation of the glue code + * of the given function shall be manually delegated by the end user. + *

    + * {@code DelegateImplementation } + *

    + *

    + * The interface is emitted unchanged. + *

    + *

    + * The Java and native-code implementation is renamed to {@code RENAMED-IMPL-SYMBOL}. + * The user's manual implementation of {@code ORIG-SYMBOL} + * may delegate to {@code RENAMED-IMPL-SYMBOL}. + *

    *

    - * For struct fields see {@link #canonicalStructFieldSymbol(String, String)}. + * If symbol references a struct field or method, see {@link #canonicalStructFieldSymbol(String, String)}, + * it describes field's array-length or element-count referenced by a pointer. *

    */ - public boolean shouldIgnoreInImpl(final String symbol) { - return shouldIgnoreInImpl_Int(symbol); + public String getDelegatedImplementation(final AliasedSymbol symbol) { + final String name = symbol.getName(); + final Set aliases = symbol.getAliasedNames(); + + String res = delegatedImplementation.get(name); + if( null == res ) { + res = oneInMap(delegatedImplementation, aliases); + if( null == res ) { + return null; + } + } + LOG.log(INFO, getASTLocusTag(symbol), "DelegatedImplementation: {0} -> {1}", symbol, res); + return res; } - private boolean shouldIgnoreInImpl_Int(final String symbol) { - - if(DEBUG_IGNORES) { - dumpIgnoresOnce(); - } + /** + * Variant of {@link #getOpaqueReturnType(AliasedSymbol)}, + * where this method only considers the {@link AliasedSymbol#getName() current-name} + * of the given symbol, not the {@link #getJavaSymbolRename(String) renamed-symbol}. + */ + public JavaType getOpaqueReturnType(final String functionName) { + final JavaType res = returnsOpaqueJType.get(functionName); + if( null == res ) { + return null; + } + LOG.log(INFO, "ReturnsOpaque: {0} -> {1}", functionName, res); + return res; + } - // Simple case-1; the entire symbol (orig or renamed) is in the implementation ignore table - final String renamedSymbol = getJavaSymbolRename(symbol); - if ( extendedImplSymbolsIgnore.contains( symbol ) || - extendedImplSymbolsIgnore.contains( renamedSymbol ) ) { - if(DEBUG_IGNORES) { - System.err.println("Ignore Impl ignore : "+symbol); - } - return true; - } - // Simple case-2; the entire symbol (orig or renamed) is _not_ in the not-empty implementation only table - if ( !extendedImplSymbolsOnly.isEmpty() && - !extendedImplSymbolsOnly.contains( symbol ) && - !extendedImplSymbolsOnly.contains( renamedSymbol ) ) { - if(DEBUG_IGNORES) { - System.err.println("Ignore Impl !extended: " + symbol); + /** + * Returns the opaque {@link JavaType} for the given function {@link AliasedSymbol} + * or {@code null} if not opaque. + *

    + * {@code ReturnsOpaque } + *

    + */ + public JavaType getOpaqueReturnType(final AliasedSymbol symbol) { + final String name = symbol.getName(); + final Set aliases = symbol.getAliasedNames(); + JavaType res = returnsOpaqueJType.get(name); + if( null == res ) { + res = oneInMap(returnsOpaqueJType, aliases); + if( null == res ) { + return null; } + } + LOG.log(INFO, getASTLocusTag(symbol), "ReturnsOpaque: {0} -> {1}", symbol, res); + return res; + } + + /** + * Variant of {@link #shouldIgnoreInInterface(AliasedSymbol)}, + * where this method only considers the {@link AliasedSymbol#getName() current-name} + * of the given symbol, not the {@link #getJavaSymbolRename(String) renamed-symbol}. + */ + public final boolean shouldIgnoreInInterface(final String symbol) { + return shouldIgnoreInInterface( new AliasedSymbol.NoneAliasedSymbol(symbol) ); + } + /** + * Returns true if this aliased symbol should be ignored + * during glue code generation of interfaces and implementation. + *

    + * Both, the {@link AliasedSymbol#getName() current-name} + * and all {@link AliasedSymbol#getAliasedNames() aliases} shall be considered. + *

    + *

    + * Implementation calls {@link #shouldIgnoreInInterface_Int(AliasedSymbol)} + * and overriding implementations shall ensure its being called as well! + *

    + * @param symbol the symbolic aliased name to check for exclusion + */ + public boolean shouldIgnoreInInterface(final AliasedSymbol symbol) { + return shouldIgnoreInInterface_Int(symbol); + } + + protected final boolean shouldIgnoreInInterface_Int(final AliasedSymbol symbol) { + if( GlueGen.debug() ) { + logIgnoresOnce(); + } + final String name = symbol.getName(); + final Set aliases = symbol.getAliasedNames(); + + // Simple case-1; the symbol (orig or renamed) is in the interface ignore table + if ( extendedIntfSymbolsIgnore.contains( name ) || + oneInSet(extendedIntfSymbolsIgnore, aliases) + ) + { + LOG.log(INFO, getASTLocusTag(symbol), "Ignore Intf ignore (one): {0}", symbol); return true; - } + } + // Simple case-2; the entire symbol (orig and renamed) is _not_ in the not-empty interface only table + if ( !extendedIntfSymbolsOnly.isEmpty() && + !extendedIntfSymbolsOnly.contains( name ) && + !oneInSet(extendedIntfSymbolsOnly, aliases) ) { + LOG.log(INFO, getASTLocusTag(symbol), "Ignore Intf !extended (all): {0}", symbol); + return true; + } + return shouldIgnoreInImpl_Int(symbol); + } - // Ok, the slow case. We need to check the entire table, in case the table - // contains an regular expression that matches the symbol. - for (final Pattern regexp : ignores) { - final Matcher matcher = regexp.matcher(symbol); - if (matcher.matches()) { - if(DEBUG_IGNORES) { - System.err.println("Ignore Impl RegEx: "+symbol); - } - return true; + /** + * Returns true if this aliased symbol should be ignored + * during glue code generation of implementation only. + *

    + * Both, the {@link AliasedSymbol#getName() current-name} + * and all {@link AliasedSymbol#getAliasedNames() aliases} shall be considered. + *

    + *

    + * Implementation calls {@link #shouldIgnoreInImpl_Int(AliasedSymbol)} + * and overriding implementations shall ensure its being called as well! + *

    + * @param symbol the symbolic aliased name to check for exclusion + */ + public boolean shouldIgnoreInImpl(final AliasedSymbol symbol) { + return shouldIgnoreInImpl_Int(symbol); + } + + protected final boolean shouldIgnoreInImpl_Int(final AliasedSymbol symbol) { + final String name = symbol.getName(); + final Set aliases = symbol.getAliasedNames(); + + // Simple case-1; the symbol (orig or renamed) is in the interface ignore table + if ( extendedImplSymbolsIgnore.contains( name ) || + oneInSet(extendedImplSymbolsIgnore, aliases) + ) + { + LOG.log(INFO, getASTLocusTag(symbol), "Ignore Impl ignore (one): {0}", symbol); + return true; + } + // Simple case-2; the entire symbol (orig and renamed) is _not_ in the not-empty interface only table + if ( !extendedImplSymbolsOnly.isEmpty() && + !extendedImplSymbolsOnly.contains( name ) && + !oneInSet(extendedImplSymbolsOnly, aliases) ) { + LOG.log(INFO, getASTLocusTag(symbol), "Ignore Impl !extended (all): {0}", symbol); + return true; } - } - // Check negated ignore table if not empty - if (ignoreNots.size() > 0) { // Ok, the slow case. We need to check the entire table, in case the table // contains an regular expression that matches the symbol. - for (final Pattern regexp : ignoreNots) { - final Matcher matcher = regexp.matcher(symbol); - if (!matcher.matches()) { - // Special case as this is most often likely to be the case. - // Unignores are not used very often. - if(unignores.isEmpty()) { - if(DEBUG_IGNORES) { - System.err.println("Ignore Impl unignores==0: "+symbol); - } - return true; + for (final Pattern ignoreRegexp : ignores) { + final Matcher matcher = ignoreRegexp.matcher(name); + if ( matcher.matches() || onePatternMatch(ignoreRegexp, aliases) ) { + LOG.log(INFO, getASTLocusTag(symbol), "Ignore Impl RegEx: {0}", symbol); + return true; } + } - boolean unignoreFound = false; - for (final Pattern unignoreRegexp : unignores) { - final Matcher unignoreMatcher = unignoreRegexp.matcher(symbol); - if (unignoreMatcher.matches()) { - unignoreFound = true; - break; - } + // Check negated ignore table if not empty + if (ignoreNots.size() > 0) { + // Ok, the slow case. We need to check the entire table, in case the table + // contains an regular expression that matches the symbol. + for (final Pattern ignoreNotRegexp : ignoreNots) { + final Matcher matcher = ignoreNotRegexp.matcher(name); + if ( !matcher.matches() && !onePatternMatch(ignoreNotRegexp, aliases) ) { + // Special case as this is most often likely to be the case. + // Unignores are not used very often. + if(unignores.isEmpty()) { + LOG.log(INFO, getASTLocusTag(symbol), "Ignore Impl unignores==0: {0} -> {1}", symbol, name); + return true; + } + boolean unignoreFound = false; + for (final Pattern unignoreRegexp : unignores) { + final Matcher unignoreMatcher = unignoreRegexp.matcher(name); + if ( unignoreMatcher.matches() || onePatternMatch(unignoreRegexp, aliases) ) { + unignoreFound = true; + break; + } + } + + if (!unignoreFound) { + LOG.log(INFO, getASTLocusTag(symbol), "Ignore Impl !unignore: {0} -> {1}", symbol, name); + return true; + } + } } - - if (!unignoreFound) - if(DEBUG_IGNORES) { - System.err.println("Ignore Impl !unignore: "+symbol); - } - return true; - } } - } - - return false; + return false; } /** Returns true if this function should be given a body which throws a run-time exception with an "unimplemented" message during glue code generation. */ - public boolean isUnimplemented(final String symbol) { - // Ok, the slow case. We need to check the entire table, in case the table - // contains an regular expression that matches the symbol. - for (final Pattern regexp : unimplemented) { - final Matcher matcher = regexp.matcher(symbol); - if (matcher.matches()) { - return true; + public boolean isUnimplemented(final AliasedSymbol symbol) { + // Ok, the slow case. We need to check the entire table, in case the table + // contains an regular expression that matches the symbol. + for (final Pattern unimplRegexp : unimplemented) { + final Matcher matcher = unimplRegexp.matcher(symbol.getName()); + if ( matcher.matches() || onePatternMatch(unimplRegexp, symbol.getAliasedNames()) ) { + return true; + } } - } + return false; + } + - return false; + /** + * Return a set of aliased-name for comment in docs. + *

    + * This is usually {@link AliasedSymbol#addAliasedName(String)}, + * however an implementation may choose otherwise. + *

    + * @param symbol the aliased symbol to retrieve the aliases + * @return set of aliased-names or {@code null}. + */ + public Set getAliasedDocNames(final AliasedSymbol symbol) { + return symbol.getAliasedNames(); } /** Returns a replacement name for this type, which should be the @@ -907,8 +1135,8 @@ function under the hood. Returns null if this symbol has not been explicitly renamed. */ public String getJavaSymbolRename(final String origName) { - if(DEBUG_RENAMES) { - dumpRenamesOnce(); + if( LOG.isLoggable(INFO) ) { + logRenamesOnce(); } return javaSymbolRenames.get(origName); } @@ -920,18 +1148,12 @@ /** Programmatically adds a rename directive for the given symbol. */ public void addJavaSymbolRename(final String origName, final String newName) { - if(DEBUG_RENAMES) { - System.err.print("\tRename "+origName+" -> "+newName); - } + LOG.log(INFO, "\tRename {0} -> {1}", origName, newName); final String prevValue = javaSymbolRenames.put(origName, newName); if(null != prevValue && !prevValue.equals(newName)) { throw new RuntimeException("Rename-Override Attampt: "+origName+" -> "+newName+ ", but "+origName+" -> "+prevValue+" already exist. Run in 'debug' mode to analyze!"); } - if(DEBUG_RENAMES) { - System.err.println(); - } - Set origNames = javaRenamedSymbols.get(newName); if(null == origNames) { origNames = new HashSet(); @@ -940,6 +1162,16 @@ origNames.add(origName); } + /** Programmatically adds a delegate implementation directive for the given symbol. */ + public void addDelegateImplementation(final String origName, final String renamedImpl) { + LOG.log(INFO, "\tDelegateImplementation {0} -> {1}", origName, renamedImpl); + final String prevValue = delegatedImplementation.put(origName, renamedImpl); + if(null != prevValue && !prevValue.equals(renamedImpl)) { + throw new RuntimeException("Rename-Override Attampt: "+origName+" -> "+renamedImpl+ + ", but "+origName+" -> "+prevValue+" already exist. Run in 'debug' mode to analyze!"); + } + } + /** Returns true if the emission style is AllStatic. */ public boolean allStatic() { return emissionStyle == AllStatic; @@ -1008,11 +1240,14 @@ nativeOutputUsesJavaHierarchy = Boolean.valueOf(tmp).booleanValue(); } else if (cmd.equalsIgnoreCase("TagNativeBinding")) { tagNativeBinding = readBoolean("TagNativeBinding", tok, filename, lineNo).booleanValue(); + } else if (cmd.equalsIgnoreCase("RelaxedEqualSemanticsTest")) { + relaxedEqualSemanticsTest = readBoolean("RelaxedEqualSemanticsTest", tok, filename, lineNo).booleanValue(); + TypeConfig.setRelaxedEqualSemanticsTest(relaxedEqualSemanticsTest); // propagate .. } else if (cmd.equalsIgnoreCase("Style")) { try{ emissionStyle = EmissionStyle.valueOf(readString("Style", tok, filename, lineNo)); }catch(final IllegalArgumentException ex) { - LOG.log(WARNING, "Error parsing \"style\" command at line {0} in file \"{1}\"", new Object[]{lineNo, filename}); + LOG.log(WARNING, "Error parsing \"style\" command at line {0} in file \"{1}\"", lineNo, filename); } } else if (cmd.equalsIgnoreCase("AccessControl")) { readAccessControl(tok, filename, lineNo); @@ -1022,6 +1257,8 @@ readOpaque(tok, filename, lineNo); } else if (cmd.equalsIgnoreCase("ReturnsString")) { readReturnsString(tok, filename, lineNo); + } else if (cmd.equalsIgnoreCase("ReturnsOpaque")) { + readReturnsOpaque(tok, filename, lineNo); } else if (cmd.equalsIgnoreCase("ReturnedArrayLength")) { readReturnedArrayLength(tok, filename, lineNo); // Warning: make sure delimiters are reset at the top of this loop @@ -1098,6 +1335,10 @@ readTemporaryCVariableAssignment(tok, filename, lineNo); // Warning: make sure delimiters are reset at the top of this loop // because TemporaryCVariableAssignment changes them. + } else if (cmd.equalsIgnoreCase("StructMachineDataInfoIndex")) { + readStructMachineDataInfoIndex(tok, filename, lineNo); + // Warning: make sure delimiters are reset at the top of this loop + // because StructMachineDescriptorIndex changes them. } else if (cmd.equalsIgnoreCase("ReturnValueCapacity")) { readReturnValueCapacity(tok, filename, lineNo); // Warning: make sure delimiters are reset at the top of this loop @@ -1118,10 +1359,10 @@ readParentClass(tok, filename, lineNo); } else if (cmd.equalsIgnoreCase("RenameJavaType")) { readRenameJavaType(tok, filename, lineNo); - } else if (cmd.equalsIgnoreCase("RenameJavaSymbol") || - // Backward compatibility - cmd.equalsIgnoreCase("RenameJavaMethod")) { + } else if (cmd.equalsIgnoreCase("RenameJavaSymbol")) { readRenameJavaSymbol(tok, filename, lineNo); + } else if (cmd.equalsIgnoreCase("DelegateImplementation")) { + readDelegateImplementation(tok, filename, lineNo); } else if (cmd.equalsIgnoreCase("RuntimeExceptionType")) { runtimeExceptionType = readString("RuntimeExceptionType", tok, filename, lineNo); } else if (cmd.equalsIgnoreCase("UnsupportedExceptionType")) { @@ -1193,7 +1434,7 @@ protected void readOpaque(final StringTokenizer tok, final String filename, final int lineNo) { try { - final JavaType javaType = JavaType.createForClass(stringToPrimitiveType(tok.nextToken())); + final JavaType javaType = JavaType.createForOpaqueClass(stringToPrimitiveType(tok.nextToken())); String cType = null; while (tok.hasMoreTokens()) { if (cType == null) { @@ -1214,6 +1455,17 @@ } } + protected void readReturnsOpaque(final StringTokenizer tok, final String filename, final int lineNo) { + try { + final JavaType javaType = JavaType.createForOpaqueClass(stringToPrimitiveType(tok.nextToken())); + final String funcName = tok.nextToken(); + returnsOpaqueJType.put(funcName, javaType); + } catch (final Exception e) { + throw new RuntimeException("Error parsing \"ReturnsOpaque\" command at line " + lineNo + + " in file \"" + filename + "\"", e); + } + } + protected void readReturnsString(final StringTokenizer tok, final String filename, final int lineNo) { try { final String name = tok.nextToken(); @@ -1496,6 +1748,18 @@ } } + protected void readStructMachineDataInfoIndex(final StringTokenizer tok, final String filename, final int lineNo) { + try { + final String structName = tok.nextToken(); + String restOfLine = tok.nextToken("\n\r\f"); + restOfLine = restOfLine.trim(); + structMachineDataInfoIndex.put(structName, restOfLine); + } catch (final NoSuchElementException e) { + throw new RuntimeException("Error parsing \"StructMachineDataInfoIndex\" command at line " + lineNo + + " in file \"" + filename + "\"", e); + } + } + protected void readReturnValueCapacity(final StringTokenizer tok, final String filename, final int lineNo) { try { final String functionName = tok.nextToken(); @@ -1643,6 +1907,17 @@ } } + public void readDelegateImplementation(final StringTokenizer tok, final String filename, final int lineNo) { + try { + final String fromName = tok.nextToken(); + final String toName = tok.nextToken(); + addDelegateImplementation(fromName, toName); + } catch (final NoSuchElementException e) { + throw new RuntimeException("Error parsing \"DelegateImplementation\" command at line " + lineNo + + " in file \"" + filename + "\": missing expected parameter", e); + } + } + protected void readJavaPrologueOrEpilogue(final StringTokenizer tok, final String filename, final int lineNo, final boolean prologue) { try { String methodName = tok.nextToken(); @@ -1714,6 +1989,16 @@ return new TypeInfo(typeName, pointerDepth, javaType); } + public TypeInfo addTypeInfo(final String alias, final Type superType) { + final TypeInfo superInfo = typeInfo(superType); + if( null != superInfo ) { + final TypeInfo res = new TypeInfo(alias, superInfo.pointerDepth(), superInfo.javaType()); + addTypeInfo(res); + return res; + } else { + return null; + } + } protected void addTypeInfo(final TypeInfo info) { TypeInfo tmp = typeInfoMap.get(info.name()); if (tmp == null) { diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/JavaEmitter.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/JavaEmitter.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/JavaEmitter.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/JavaEmitter.java 2015-10-09 04:18:28.000000000 +0000 @@ -40,22 +40,56 @@ package com.jogamp.gluegen; -import com.jogamp.common.nio.Buffers; -import com.jogamp.common.os.DynamicLookupHelper; -import com.jogamp.common.os.MachineDescription; - -import java.io.*; -import java.util.*; +import static com.jogamp.gluegen.JavaEmitter.MethodAccess.PACKAGE_PRIVATE; +import static com.jogamp.gluegen.JavaEmitter.MethodAccess.PRIVATE; +import static com.jogamp.gluegen.JavaEmitter.MethodAccess.PROTECTED; +import static com.jogamp.gluegen.JavaEmitter.MethodAccess.PUBLIC; +import static com.jogamp.gluegen.JavaEmitter.MethodAccess.PUBLIC_ABSTRACT; +import static java.util.logging.Level.FINE; +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.Buffer; import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; -import com.jogamp.gluegen.cgram.types.*; +import jogamp.common.os.MachineDataInfoRuntime; -import java.nio.Buffer; -import java.util.logging.Logger; - -import jogamp.common.os.MachineDescriptionRuntime; -import static java.util.logging.Level.*; -import static com.jogamp.gluegen.JavaEmitter.MethodAccess.*; +import com.jogamp.common.nio.Buffers; +import com.jogamp.common.os.DynamicLookupHelper; +import com.jogamp.common.os.MachineDataInfo; +import com.jogamp.common.util.ArrayHashMap; +import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider; +import com.jogamp.gluegen.Logging.LoggerIf; +import com.jogamp.gluegen.cgram.types.AliasedSymbol; +import com.jogamp.gluegen.cgram.types.ArrayType; +import com.jogamp.gluegen.cgram.types.CVAttributes; +import com.jogamp.gluegen.cgram.types.CompoundType; +import com.jogamp.gluegen.cgram.types.Field; +import com.jogamp.gluegen.cgram.types.FunctionSymbol; +import com.jogamp.gluegen.cgram.types.FunctionType; +import com.jogamp.gluegen.cgram.types.IntType; +import com.jogamp.gluegen.cgram.types.PointerType; +import com.jogamp.gluegen.cgram.types.SizeThunk; +import com.jogamp.gluegen.cgram.types.StructLayout; +import com.jogamp.gluegen.cgram.types.Type; +import com.jogamp.gluegen.cgram.types.TypeComparator.AliasedSemanticSymbol; +import com.jogamp.gluegen.cgram.types.TypeDictionary; // PROBLEMS: // - what if something returns 'const int *'? Could we @@ -70,7 +104,6 @@ public class JavaEmitter implements GlueEmitter { private StructLayout layout; - private TypeDictionary typedefDictionary; private Map canonMap; protected JavaConfiguration cfg; private boolean requiresStaticInitialization = false; @@ -97,13 +130,19 @@ private final String javaName; } - private PrintWriter javaWriter; // Emits either interface or, in AllStatic mode, everything + private String javaFileName; // of javaWriter or javaImplWriter + private PrintWriter javaWriter; // Emits either interface or, in AllStatic mode, everything private PrintWriter javaImplWriter; // Only used in non-AllStatic modes for impl class + private String cFileName; // of cWriter private PrintWriter cWriter; - private final MachineDescription machDescJava = MachineDescription.StaticConfig.X86_64_UNIX.md; - private final MachineDescription.StaticConfig[] machDescTargetConfigs = MachineDescription.StaticConfig.values(); + private final MachineDataInfo machDescJava = MachineDataInfo.StaticConfig.LP64_UNIX.md; + private final MachineDataInfo.StaticConfig[] machDescTargetConfigs = MachineDataInfo.StaticConfig.values(); + + protected final LoggerIf LOG; - protected final static Logger LOG = Logger.getLogger(JavaEmitter.class.getPackage().getName()); + public JavaEmitter() { + LOG = Logging.getLogger(JavaEmitter.class.getPackage().getName(), JavaEmitter.class.getSimpleName()); + } @Override public void readConfigurationFile(final String filename) throws Exception { @@ -111,61 +150,129 @@ cfg.read(filename); } - class ConstantRenamer implements SymbolFilter { + @Override + public JavaConfiguration getConfiguration() { return cfg; } + class ConstFuncRenamer implements SymbolFilter { private List constants; - - @Override - public void filterSymbols(final List constants, final List functions) { - this.constants = constants; - doWork(); - } + private List functions; @Override public List getConstants() { return constants; } - @Override public List getFunctions() { - return null; + return functions; } - private void doWork() { - final List newConstants = new ArrayList(); - final JavaConfiguration cfg = getConfig(); - for (final ConstantDefinition def : constants) { - def.rename(cfg.getJavaSymbolRename(def.getName())); - newConstants.add(def); - } - constants = newConstants; + private List filterSymbolsInt(final List inList, + final boolean preserveOrder, + final List outList) { + final JavaConfiguration cfg = getConfig(); + final ArrayHashMap symMap = + new ArrayHashMap(false, 100, ArrayHashMap.DEFAULT_LOAD_FACTOR); + for (final T sym : inList) { + final String origName = sym.getName(); + final String newName = cfg.getJavaSymbolRename(origName); + final T dupSym; + if( null != newName ) { + // Alias Name + dupSym = symMap.get(newName); + if( null != dupSym ) { + // only rename to allow 'equalSemantics' to not care .. + sym.rename(newName); + } + } else { + // Original Name + dupSym = symMap.get(origName); + } + if( null != dupSym ) { + // Duplicate alias .. check + if( !dupSym.equalSemantics(sym) ) { + final ASTLocusTag loc; + final String preLoc; + if( sym instanceof ASTLocusTagProvider ) { + loc = ((ASTLocusTagProvider)sym).getASTLocusTag(); + } else { + loc = null; + } + if( dupSym instanceof ASTLocusTagProvider ) { + preLoc = String.format(",%n %s: previous definition is here", + ((ASTLocusTagProvider)dupSym).getASTLocusTag().toString(new StringBuilder(), "note", true)); + } else { + preLoc = ""; + } + final String mode = null != newName ? "alias" : "orig"; + final String message = + String.format("Duplicate Name (%s) w/ incompatible value:%n this '%s',%n have '%s'%s", + mode, sym.getAliasedString(), dupSym.getAliasedString(), preLoc); + throw new GlueGenException(message, loc); + } + } + if( null != newName ) { + // Alias Name + if( null != dupSym ) { + // Duplicate alias .. add aliased name + dupSym.addAliasedName(origName); + } else { + // No duplicate .. rename and add + sym.rename(newName); + symMap.put(newName, sym); + } + } else { + // Original Name + if( null != dupSym ) { + // Duplicate orig .. drop + } else { + // No duplicate orig .. add + symMap.put(origName, sym); + } + } + } + outList.addAll(symMap.getData()); + if( !preserveOrder ) { + // sort constants to make them easier to find in native code + Collections.sort(outList, new Comparator() { + @Override + public int compare(final T o1, final T o2) { + return o1.getName().compareTo(o2.getName()); + } + }); + } + return outList; + } + + @Override + public void filterSymbols(final List inConstList, final List inFuncList) { + constants = filterSymbolsInt(inConstList, true, new ArrayList(100)); + functions = filterSymbolsInt(inFuncList, true, new ArrayList(100)); } } @Override public void beginEmission(final GlueEmitterControls controls) throws IOException { + // Handle renaming of constants and functions + controls.runSymbolFilter(new ConstFuncRenamer()); // Request emission of any structs requested for (final String structs : cfg.forcedStructs()) { controls.forceStructEmission(structs); } - if (!cfg.structsOnly()) { + if ( !cfg.structsOnly() ) { try { openWriters(); } catch (final Exception e) { throw new RuntimeException("Unable to open files for writing", e); } emitAllFileHeaders(); - - // Handle renaming of constants - controls.runSymbolFilter(new ConstantRenamer()); } } @Override public void endEmission() { - if (!cfg.structsOnly()) { + if ( !cfg.structsOnly() ) { emitAllFileFooters(); try { @@ -178,177 +285,11 @@ @Override public void beginDefines() throws Exception { - if ((cfg.allStatic() || cfg.emitInterface()) && !cfg.structsOnly()) { + if ( ( cfg.allStatic() || cfg.emitInterface() ) && !cfg.structsOnly() ) { javaWriter().println(); } } - protected static int getJavaRadix(final String name, final String value) { - // FIXME: need to handle when type specifier is in last char (e.g., - // "1.0d or 2759L", because parseXXX() methods don't allow the type - // specifier character in the string. - // - //char lastChar = value.charAt(value.length()-1); - - try { - // see if it's a long or int - int radix; - String parseValue; - // FIXME: are you allowed to specify hex/octal constants with - // negation, e.g. "-0xFF" or "-056"? If so, need to modify the - // following "if(..)" checks and parseValue computation - if (value.startsWith("0x") || value.startsWith("0X")) { - radix = 16; - parseValue = value.substring(2); - } - else if (value.startsWith("0") && value.length() > 1) { - // TODO: is "0" the prefix in C to indicate octal??? - radix = 8; - parseValue = value.substring(1); - } - else { - radix = 10; - parseValue = value; - } - //System.err.println("parsing " + value + " as long w/ radix " + radix); - Long.parseLong(parseValue, radix); - return radix; - } catch (final NumberFormatException e) { - try { - // see if it's a double or float - Double.parseDouble(value); - return 10; - } catch (final NumberFormatException e2) { - throw new RuntimeException( - "Cannot emit define \""+name+"\": value \""+value+ - "\" cannot be assigned to a int, long, float, or double", e2); - } - } - } - - protected static Object getJavaValue(final String name, final String value) { - - // "calculates" the result type of a simple expression - // example: (2+3)-(2.0f-3.0) -> Double - // example: (1 << 2) -> Integer - - final Scanner scanner = new Scanner(value).useDelimiter("[+-/*/> 1) { - // TODO: is "0" the prefix in C to indicate octal??? - radix = 8; - parseValue = value.substring(1); - } else { - radix = 10; - parseValue = value; - } - if(lastChar == 'u' || lastChar == 'U') { - parseValue = parseValue.substring(0, parseValue.length()-1); - } - - //System.err.println("parsing " + value + " as long w/ radix " + radix); - final long longVal = Long.parseLong(parseValue, radix); - // if constant is small enough, store it as an int instead of a long - if (longVal > Integer.MIN_VALUE && longVal < Integer.MAX_VALUE) { - return (int)longVal; - } - return longVal; - - } catch (final NumberFormatException e) { - try { - // see if it's a double or float - final double dVal = Double.parseDouble(value); - final double absVal = Math.abs(dVal); - // if constant is small enough, store it as a float instead of a double - if (absVal < Float.MIN_VALUE || absVal > Float.MAX_VALUE) { - return new Double(dVal); - } - return new Float((float) dVal); - } catch (final NumberFormatException e2) { - throw new RuntimeException( - "Cannot emit define \""+name+"\": value \""+value+ - "\" cannot be assigned to a int, long, float, or double", e2); - } - } - } - - - protected static String getJavaType(final String name, final String value) { - final Object oval = getJavaValue(name, value); - return getJavaType(name, oval); - } - - protected static String getJavaType(final String name, final Object oval) { - if(oval instanceof Integer) { - return "int"; - } else if(oval instanceof Long) { - return "long"; - } else if(oval instanceof Float) { - return "float"; - } else if(oval instanceof Double) { - return "double"; - } - - throw new RuntimeException( - "Cannot emit define (2) \""+name+"\": value \""+oval+ - "\" cannot be assigned to a int, long, float, or double"); - } - /** Mangle a class, package or function name for JNI usage, i.e. replace all '.' w/ '_' */ protected static String jniMangle(final String name) { return name.replaceAll("_", "_1").replace('.', '_'); @@ -358,10 +299,12 @@ return "Java_"+jniMangle(javaPackageName)+"_"+jniMangle(javaClassName); } + private final Map constMap = + new HashMap(); + @Override public void emitDefine(final ConstantDefinition def, final String optionalComment) throws Exception { - - if (cfg.allStatic() || cfg.emitInterface()) { + if ( ( cfg.allStatic() || cfg.emitInterface() ) && !cfg.structsOnly() ) { // TODO: Some defines (e.g., GL_DOUBLE_EXT in gl.h) are defined in terms // of other defines -- should we emit them as references to the original // define (not even sure if the lexer supports this)? Right now they're @@ -371,24 +314,22 @@ // currently only emits only numeric defines -- if it handled #define'd // objects it would make a bigger difference. - final String name = def.getName(); - String value = def.getValue(); - - if (!cfg.shouldIgnoreInInterface(name)) { - final String type = getJavaType(name, value); + if ( !cfg.shouldIgnoreInInterface(def) ) { + final ConstantDefinition.JavaExpr constExpr = def.computeJavaExpr(constMap); + constMap.put(def.getName(), constExpr); + javaWriter().print(" /** "); if (optionalComment != null && optionalComment.length() != 0) { - javaWriter().println(" /** " + optionalComment + " */"); - } - String suffix = ""; - if(!value.endsWith(")")) { - if (type.equals("float") && !value.endsWith("f")) { - suffix = "f"; - }else if(value.endsWith("u") || value.endsWith("U")) { - value = value.substring(0, value.length()-1); - } + javaWriter().print(optionalComment); + javaWriter().print(" - "); } - - javaWriter().println(" public static final " + type + " " + name + " = " + value + suffix + ";"); + javaWriter().print("CType: "); + if( constExpr.resultType.isUnsigned ) { + javaWriter().print("unsigned "); + } + javaWriter().print(constExpr.resultJavaTypeName); + javaWriter().println(" */"); + javaWriter().println(" public static final " + constExpr.resultJavaTypeName + + " " + def.getName() + " = " + constExpr.javaExpression + ";"); } } } @@ -402,67 +343,51 @@ final TypeDictionary structDictionary, final Map canonMap) throws Exception { - this.typedefDictionary = typedefDictionary; + // this.typedefDictionary = typedefDictionary; this.canonMap = canonMap; this.requiresStaticInitialization = false; // reset - if ((cfg.allStatic() || cfg.emitInterface()) && !cfg.structsOnly()) { + if ( ( cfg.allStatic() || cfg.emitInterface() ) && !cfg.structsOnly() ) { javaWriter().println(); } } @Override - public Iterator emitFunctions(final List originalCFunctions) throws Exception { - - // Sometimes headers will have the same function prototype twice, once - // with the argument names and once without. We'll remember the signatures - // we've already processed we don't generate duplicate bindings. - // - // Note: this code assumes that on the equals() method in FunctionSymbol - // only considers function name and argument types (i.e., it does not - // consider argument *names*) when comparing FunctionSymbols for equality - final Set funcsToBindSet = new HashSet(100); - for (final FunctionSymbol cFunc : originalCFunctions) { - if (!funcsToBindSet.contains(cFunc)) { - funcsToBindSet.add(cFunc); - } - } - - // validateFunctionsToBind(funcsToBindSet); + public Iterator emitFunctions(final List funcsToBind) throws Exception { + if ( !cfg.structsOnly() ) { + // Bind all the C funcs to Java methods + final ArrayList methodBindingEmitters = new ArrayList(2*funcsToBind.size()); + { + int i=0; + for (final FunctionSymbol cFunc : funcsToBind) { + // Check to see whether this function should be ignored + if ( !cfg.shouldIgnoreInImpl(cFunc) ) { + methodBindingEmitters.addAll(generateMethodBindingEmitters(cFunc)); + LOG.log(INFO, cFunc.getASTLocusTag(), "Non-Ignored Impl[{0}]: {1}", i++, cFunc); + } - final ArrayList funcsToBind = new ArrayList(funcsToBindSet); - // sort functions to make them easier to find in native code - Collections.sort(funcsToBind, new Comparator() { - @Override - public int compare(final FunctionSymbol o1, final FunctionSymbol o2) { - return o1.getName().compareTo(o2.getName()); } - }); - - // Bind all the C funcs to Java methods - final HashSet methodBindingSet = new HashSet(); - final ArrayList methodBindingEmitters = new ArrayList(2*funcsToBind.size()); - for (final FunctionSymbol cFunc : funcsToBind) { - // Check to see whether this function should be ignored - if (!cfg.shouldIgnoreInImpl(cFunc.getName())) { - methodBindingEmitters.addAll(generateMethodBindingEmitters(methodBindingSet, cFunc)); - } - - } + } - // Emit all the methods - for (final FunctionEmitter emitter : methodBindingEmitters) { - try { - if (!emitter.isInterface() || !cfg.shouldIgnoreInInterface(emitter.getName())) { - emitter.emit(); - emitter.getDefaultOutput().println(); // put newline after method body + // Emit all the methods + { + int i=0; + for (final FunctionEmitter emitter : methodBindingEmitters) { + try { + final FunctionSymbol cFunc = emitter.getCSymbol(); + if ( !emitter.isInterface() || !cfg.shouldIgnoreInInterface(cFunc) ) { + emitter.emit(); + emitter.getDefaultOutput().println(); // put newline after method body + LOG.log(INFO, cFunc.getASTLocusTag(), "Non-Ignored Intf[{0}]: {1}", i++, cFunc); + } + } catch (final Exception e) { + throw new GlueGenException( + "Error while emitting binding for \"" + emitter.getCSymbol().getAliasedString() + "\"", + emitter.getCSymbol().getASTLocusTag(), e); + } + } } - } catch (final Exception e) { - throw new RuntimeException( - "Error while emitting binding for \"" + emitter.getName() + "\"", e); - } } - // Return the list of FunctionSymbols that we generated gluecode for return funcsToBind.iterator(); } @@ -506,25 +431,33 @@ * native code because it doesn't need any processing of the * outgoing arguments). */ - protected void generatePublicEmitters(final MethodBinding binding, final List allEmitters, final boolean signatureOnly) { - if (cfg.manuallyImplement(binding.getName()) && !signatureOnly) { + protected void generatePublicEmitters(final MethodBinding binding, final List allEmitters, + final boolean signatureOnly) { + final FunctionSymbol cSymbol = binding.getCSymbol(); + if ( !signatureOnly && cfg.manuallyImplement(cSymbol) ) { // We only generate signatures for manually-implemented methods; // user provides the implementation return; } - final MethodAccess accessControl = cfg.accessControl(binding.getName()); + final MethodAccess accessControl; + + if ( !signatureOnly && null != binding.getDelegationImplName() ) { + // private access for delegation implementation methods + accessControl = PRIVATE; + } else { + accessControl = cfg.accessControl(binding.getName()); + } + // We should not emit anything except public APIs into interfaces - if (signatureOnly && (accessControl != PUBLIC)) { + if ( signatureOnly && PUBLIC != accessControl ) { return; } - final PrintWriter writer = ((signatureOnly || cfg.allStatic()) ? javaWriter() : javaImplWriter()); - // It's possible we may not need a body even if signatureOnly is // set to false; for example, if the routine doesn't take any // arrays or buffers as arguments - final boolean isUnimplemented = cfg.isUnimplemented(binding.getName()); + final boolean isUnimplemented = cfg.isUnimplemented(cSymbol); final List prologue = cfg.javaPrologueForMethod(binding, false, false); final List epilogue = cfg.javaEpilogueForMethod(binding, false, false); final boolean needsBody = isUnimplemented || @@ -536,25 +469,31 @@ if( !requiresStaticInitialization ) { requiresStaticInitialization = binding.signatureRequiresStaticInitialization(); if( requiresStaticInitialization ) { - LOG.log(INFO, "StaticInit Trigger.1 \"{0}\"", binding); + LOG.log(INFO, cSymbol.getASTLocusTag(), "StaticInit Trigger.1 \"{0}\"", binding); } } + final boolean emitBody = !signatureOnly && needsBody; + final boolean isNativeMethod = !isUnimplemented && !needsBody && !signatureOnly; + + final PrintWriter writer = ((signatureOnly || cfg.allStatic()) ? javaWriter() : javaImplWriter()); + final JavaMethodBindingEmitter emitter = new JavaMethodBindingEmitter(binding, writer, cfg.runtimeExceptionType(), cfg.unsupportedExceptionType(), - !signatureOnly && needsBody, + emitBody, // emitBody cfg.tagNativeBinding(), - false, // eraseBufferAndArrayTypes + false, // eraseBufferAndArrayTypes cfg.useNIOOnly(binding.getName()), cfg.useNIODirectOnly(binding.getName()), - false, - false, - false, - isUnimplemented, - signatureOnly, + false, // forDirectBufferImplementation + false, // forIndirectBufferAndArrayImplementation + isUnimplemented, // isUnimplemented + signatureOnly, // isInterface + isNativeMethod, // isNativeMethod + false, // isPrivateNativeMethod cfg); switch (accessControl) { case PUBLIC: emitter.addModifier(JavaMethodBindingEmitter.PUBLIC); break; @@ -565,7 +504,7 @@ if (cfg.allStatic()) { emitter.addModifier(FunctionEmitter.STATIC); } - if (!isUnimplemented && !needsBody && !signatureOnly) { + if (isNativeMethod) { emitter.addModifier(JavaMethodBindingEmitter.NATIVE); } emitter.setReturnedArrayLengthExpression(cfg.returnedArrayLength(binding.getName())); @@ -585,7 +524,8 @@ */ protected void generatePrivateEmitters(final MethodBinding binding, final List allEmitters) { - if (cfg.manuallyImplement(binding.getName())) { + final FunctionSymbol cSymbol = binding.getCSymbol(); + if (cfg.manuallyImplement(cSymbol)) { // Don't produce emitters for the implementation class return; } @@ -594,11 +534,11 @@ cfg.javaPrologueForMethod(binding, false, false) != null || cfg.javaEpilogueForMethod(binding, false, false) != null ; - if ( !cfg.isUnimplemented( binding.getName() ) ) { + if ( !cfg.isUnimplemented( cSymbol ) ) { if( !requiresStaticInitialization ) { requiresStaticInitialization = binding.signatureRequiresStaticInitialization(); if( requiresStaticInitialization ) { - LOG.log(INFO, "StaticInit Trigger.2 \"{0}\"", binding); + LOG.log(INFO, cSymbol.getASTLocusTag(), "StaticInit Trigger.2 \"{0}\"", binding); } } @@ -621,16 +561,17 @@ writer, cfg.runtimeExceptionType(), cfg.unsupportedExceptionType(), - false, + false, // emitBody cfg.tagNativeBinding(), - true, // eraseBufferAndArrayTypes + true, // eraseBufferAndArrayTypes cfg.useNIOOnly(binding.getName()), cfg.useNIODirectOnly(binding.getName()), - true, - true, - false, - false, - false, + true, // forDirectBufferImplementation + false, // forIndirectBufferAndArrayImplementation + false, // isUnimplemented + false, // isInterface + true, // isNativeMethod + true, // isPrivateNativeMethod cfg); emitter.addModifier(JavaMethodBindingEmitter.PRIVATE); if (cfg.allStatic()) { @@ -658,7 +599,7 @@ cfg.allStatic(), (binding.needsNIOWrappingOrUnwrapping() || hasPrologueOrEpilogue), !cfg.useNIODirectOnly(binding.getName()), - machDescJava); + machDescJava, getConfiguration()); prepCEmitter(binding.getName(), binding.getJavaReturnType(), cEmitter); allEmitters.add(cEmitter); } @@ -700,18 +641,34 @@ * Generate all appropriate Java bindings for the specified C function * symbols. */ - protected List generateMethodBindingEmitters(final Set methodBindingSet, final FunctionSymbol sym) throws Exception { - + protected List generateMethodBindingEmitters(final FunctionSymbol sym) throws Exception { final ArrayList allEmitters = new ArrayList(); - try { + if( cfg.emitInterface() ) { + generateMethodBindingEmittersImpl(allEmitters, sym, true); + } + if( cfg.emitImpl() ) { + generateMethodBindingEmittersImpl(allEmitters, sym, false); + } + } catch (final Exception e) { + throw new GlueGenException("Error while generating bindings for \"" + sym + "\"", sym.getASTLocusTag(), e); + } + + return allEmitters; + } + private void generateMethodBindingEmittersImpl(final ArrayList allEmitters, + final FunctionSymbol sym, + final boolean forInterface) throws Exception + { // Get Java binding for the function - final MethodBinding mb = bindFunction(sym, null, null, machDescJava); + final MethodBinding mb = bindFunction(sym, forInterface, machDescJava, null, null); // JavaTypes representing C pointers in the initial // MethodBinding have not been lowered yet to concrete types final List bindings = expandMethodBinding(mb); + final HashSet methodBindingSet = new HashSet(); + for (final MethodBinding binding : bindings) { if(!methodBindingSet.add(binding)) { @@ -772,25 +729,19 @@ // Note in particular that the public entry point taking an // array is merely a special case of the indirect buffer case. - if (cfg.emitInterface()) { + if ( forInterface ) { generatePublicEmitters(binding, allEmitters, true); - } - if (cfg.emitImpl()) { + } else { generatePublicEmitters(binding, allEmitters, false); generatePrivateEmitters(binding, allEmitters); } } // end iteration over expanded bindings - } catch (final Exception e) { - throw new RuntimeException("Error while generating bindings for \"" + sym + "\"", e); } - return allEmitters; - } - @Override public void endFunctions() throws Exception { - if (!cfg.structsOnly()) { + if ( !cfg.structsOnly() ) { if (cfg.allStatic() || cfg.emitInterface()) { emitCustomJavaCode(javaWriter(), cfg.className()); } @@ -821,44 +772,93 @@ public void beginStructs(final TypeDictionary typedefDictionary, final TypeDictionary structDictionary, final Map canonMap) throws Exception { - this.typedefDictionary = typedefDictionary; + // this.typedefDictionary = typedefDictionary; this.canonMap = canonMap; } @Override - public void emitStruct(final CompoundType structCType, final String alternateName) throws Exception { - final String structCTypeName; + public void emitStruct(final CompoundType structCType, final Type structCTypedefPtr) throws Exception { + final String structCTypeName, typedefedName; { - String _name = structCType.getName(); - if (_name == null && alternateName != null) { - _name = alternateName; + final String _name = structCType.getName(); + if ( null != structCTypedefPtr && null != structCTypedefPtr.getName() ) { + // always use typedef'ed name if available + typedefedName = structCTypedefPtr.getName(); + structCTypeName = typedefedName; + } else { + // fall back to actual struct type name + typedefedName = null; + structCTypeName = _name; + } + LOG.log(INFO, structCType.getASTLocusTag(), "Struct emission of structCType {0}", structCType); + LOG.log(INFO, structCType.getASTLocusTag()," structCTypedefPtr {0}", structCTypedefPtr); + LOG.log(INFO, structCType.getASTLocusTag()," : structCTypeName \"{0}\" -> typedefedName \"{1}\" -> \"{2}\"", + _name, typedefedName, structCTypeName); + if ( null == structCTypeName ) { + LOG.log(INFO, structCType.getASTLocusTag(), + "skipping emission of unnamed struct {0} w/o typedef", structCType); + return; } - structCTypeName = _name; - } - - if (structCTypeName == null) { - final String structName = structCType.getStructName(); - if ( null != structName && cfg.shouldIgnoreInInterface(structName) ) { + final AliasedSymbol.AliasedSymbolImpl aliases = new AliasedSymbol.AliasedSymbolImpl(structCTypeName); + aliases.addAliasedName(_name); + aliases.addAliasedName(typedefedName); + if ( cfg.shouldIgnoreInInterface(aliases) ) { + LOG.log(INFO, structCType.getASTLocusTag(), + "skipping emission of ignored \"{0}\": {1}", aliases, structCType); return; } - LOG.log(WARNING, "skipping emission of unnamed struct \"{0}\"", structCType); - return; } - if (cfg.shouldIgnoreInInterface(structCTypeName)) { - return; + if( null != structCTypedefPtr && isOpaque(structCTypedefPtr) ) { + LOG.log(INFO, structCType.getASTLocusTag(), + "skipping emission of opaque typedef {0}", structCTypedefPtr); + return; + } + if( isOpaque(structCType) ) { + LOG.log(INFO, structCType.getASTLocusTag(), + "skipping emission of opaque c-struct {0}", structCType); + return; } - final Type containingCType = canonicalize(new PointerType(SizeThunk.POINTER, structCType, 0)); + final Type containingCType; + { + // NOTE: Struct Name Resolution (JavaEmitter, HeaderParser) + final Type aptr; + int mode; + if( null != typedefedName ) { + aptr = structCTypedefPtr; + mode = 1; + } else { + aptr = new PointerType(SizeThunk.POINTER, structCType, 0); + aptr.setTypedefName(typedefedName); + mode = 2; + } + containingCType = canonicalize(aptr); + LOG.log(INFO, structCType.getASTLocusTag(), "containingCType[{0}]: {1} -canon-> {2}", mode, aptr, containingCType); + } final JavaType containingJType = typeToJavaType(containingCType, null); - if (!containingJType.isCompoundTypeWrapper()) { - return; + if( containingJType.isOpaqued() ) { + LOG.log(INFO, structCType.getASTLocusTag(), + "skipping emission of opaque {0}, {1}", containingJType, structCType); + return; + } + if( !containingJType.isCompoundTypeWrapper() ) { + LOG.log(WARNING, structCType.getASTLocusTag(), + "skipping emission of non-compound {0}, {1}", containingJType, structCType); + return; } final String containingJTypeName = containingJType.getName(); + LOG.log(INFO, structCType.getASTLocusTag(), + "perform emission of \"{0}\" -> \"{1}\": {2}", structCTypeName, containingJTypeName, structCType); + + if( 0 == structCType.getNumFields() ) { + LOG.log(INFO, structCType.getASTLocusTag(), + "emission of \"{0}\" with zero fields {1}", containingJTypeName, structCType); + } this.requiresStaticInitialization = false; // reset - // machDescJava global MachineDescription is the one used to determine + // machDescJava global MachineDataInfo is the one used to determine // the sizes of the primitive types seen in the public API in Java. // For example, if a C long is an element of a struct, it is the size // of a Java int on a 32-bit machine but the size of a Java long @@ -868,11 +868,11 @@ // implementation on a 32-bit platform must downcast this to an // int and set only an int's worth of data in the struct. // - // The machDescTarget MachineDescription is the one used to determine how + // The machDescTarget MachineDataInfo is the one used to determine how // much data to set in or get from the struct and exactly from // where it comes. // - // Note that machDescJava MachineDescription is always 64bit unix, + // Note that machDescJava MachineDataInfo is always 64bit unix, // which complies w/ Java types. boolean needsNativeCode = false; @@ -884,13 +884,13 @@ final Field field = structCType.getField(i); final Type fieldType = field.getType(); - final String cfgFieldName0 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, field.getName()); + final String cfgFieldName0 = JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, field.getName()); if (!cfg.shouldIgnoreInInterface(cfgFieldName0)) { final String renamed = cfg.getJavaSymbolRename(cfgFieldName0); final String fieldName = renamed==null ? field.getName() : renamed; - final String cfgFieldName1 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, fieldName); + final String cfgFieldName1 = JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, fieldName); if ( fieldType.isFunctionPointer() || fieldType.isPointer() || requiresGetCStringLength(fieldType, cfgFieldName1) ) { needsNativeCode = true; @@ -935,7 +935,7 @@ javaWriter.println("import " + cfg.gluegenRuntimePackage() + ".*;"); javaWriter.println("import " + DynamicLookupHelper.class.getPackage().getName() + ".*;"); javaWriter.println("import " + Buffers.class.getPackage().getName() + ".*;"); - javaWriter.println("import " + MachineDescriptionRuntime.class.getName() + ";"); + javaWriter.println("import " + MachineDataInfoRuntime.class.getName() + ";"); javaWriter.println(); final List imports = cfg.imports(); for (final String str : imports) { @@ -963,7 +963,10 @@ javaWriter.println(); javaWriter.println(" StructAccessor accessor;"); javaWriter.println(); - javaWriter.println(" private static final int mdIdx = MachineDescriptionRuntime.getStatic().ordinal();"); + final String cfgMachDescrIdxCode = cfg.returnStructMachineDataInfoIndex(containingJTypeName); + final String machDescrIdxCode = null != cfgMachDescrIdxCode ? cfgMachDescrIdxCode : "private static final int mdIdx = MachineDataInfoRuntime.getStatic().ordinal();"; + javaWriter.println(" "+machDescrIdxCode); + javaWriter.println(" private final MachineDataInfo md;"); javaWriter.println(); // generate all offset and size arrays generateOffsetAndSizeArrays(javaWriter, " ", containingJTypeName, structCType, null, null); /* w/o offset */ @@ -975,11 +978,11 @@ for (int i = 0; i < structCType.getNumFields(); i++) { final Field field = structCType.getField(i); final Type fieldType = field.getType(); - final String cfgFieldName0 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, field.getName()); + final String cfgFieldName0 = JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, field.getName()); if ( !cfg.shouldIgnoreInInterface(cfgFieldName0) ) { final String renamed = cfg.getJavaSymbolRename(cfgFieldName0); final String fieldName = null==renamed ? field.getName() : renamed; - final String cfgFieldName1 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, fieldName); + final String cfgFieldName1 = JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, fieldName); if (fieldType.isFunctionPointer()) { // no offset/size for function pointer .. if( GlueGen.debug() ) { @@ -990,8 +993,8 @@ // handle the union in jawt_Win32DrawingSurfaceInfo (fabricate // a name?) if (fieldType.getName() == null) { - throw new RuntimeException("Anonymous structs as fields not supported yet, field \"" + - cfgFieldName1 + "\", "+fieldType.getDebugString()); + throw new GlueGenException("Anonymous structs as fields not supported yet, field \"" + + cfgFieldName1 + "\", "+fieldType.getDebugString(), fieldType.getASTLocusTag()); } if( GlueGen.debug() ) { System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, cfgFieldName1, fieldType.getDebugString(), "compound"); @@ -1009,11 +1012,11 @@ try { externalJavaType = typeToJavaType(fieldType, machDescJava); } catch (final Exception e) { - throw new RuntimeException("Error occurred while creating accessor for field \"" + - cfgFieldName1 + "\", "+fieldType.getDebugString(), e); + throw new GlueGenException("Error occurred while creating accessor for field \"" + + cfgFieldName1 + "\", "+fieldType.getDebugString(), fieldType.getASTLocusTag(), e); } if( GlueGen.debug() ) { - System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, fieldName, fieldType.getDebugString(), "MISC"); + System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, cfgFieldName1, fieldType.getDebugString(), "MISC"); System.err.printf("SE.os.%02d: javaType %s%n", (i+1), externalJavaType.getDebugString()); } if (externalJavaType.isPrimitive()) { @@ -1037,22 +1040,30 @@ } } javaWriter.println(); - javaWriter.println(" public static int size() {"); - javaWriter.println(" return "+containingJTypeName+"_size[mdIdx];"); - javaWriter.println(" }"); - javaWriter.println(); - javaWriter.println(" public static " + containingJTypeName + " create() {"); - javaWriter.println(" return create(Buffers.newDirectByteBuffer(size()));"); - javaWriter.println(" }"); - javaWriter.println(); - javaWriter.println(" public static " + containingJTypeName + " create(java.nio.ByteBuffer buf) {"); - javaWriter.println(" return new " + containingJTypeName + "(buf);"); - javaWriter.println(" }"); - javaWriter.println(); - javaWriter.println(" " + containingJTypeName + "(java.nio.ByteBuffer buf) {"); - javaWriter.println(" accessor = new StructAccessor(buf);"); - javaWriter.println(" }"); - javaWriter.println(); + // getDelegatedImplementation + if( !cfg.manuallyImplement(JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, "size")) ) { + javaWriter.println(" public static int size() {"); + javaWriter.println(" return "+containingJTypeName+"_size[mdIdx];"); + javaWriter.println(" }"); + javaWriter.println(); + } + if( !cfg.manuallyImplement(JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, "create")) ) { + javaWriter.println(" public static " + containingJTypeName + " create() {"); + javaWriter.println(" return create(Buffers.newDirectByteBuffer(size()));"); + javaWriter.println(" }"); + javaWriter.println(); + javaWriter.println(" public static " + containingJTypeName + " create(java.nio.ByteBuffer buf) {"); + javaWriter.println(" return new " + containingJTypeName + "(buf);"); + javaWriter.println(" }"); + javaWriter.println(); + } + if( !cfg.manuallyImplement(JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, containingJTypeName)) ) { + javaWriter.println(" " + containingJTypeName + "(java.nio.ByteBuffer buf) {"); + javaWriter.println(" md = MachineDataInfo.StaticConfig.values()[mdIdx].md;"); + javaWriter.println(" accessor = new StructAccessor(buf);"); + javaWriter.println(" }"); + javaWriter.println(); + } javaWriter.println(" public java.nio.ByteBuffer getBuffer() {"); javaWriter.println(" return accessor.getBuffer();"); javaWriter.println(" }"); @@ -1063,52 +1074,62 @@ final Field field = structCType.getField(i); final Type fieldType = field.getType(); - final String cfgFieldName0 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, field.getName()); + final String cfgFieldName0 = JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, field.getName()); if (!cfg.shouldIgnoreInInterface(cfgFieldName0)) { final String renamed = cfg.getJavaSymbolRename(cfgFieldName0); final String fieldName = renamed==null ? field.getName() : renamed; - final String cfgFieldName1 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, fieldName); + final String cfgFieldName1 = JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, fieldName); + final TypeInfo opaqueFieldType = cfg.typeInfo(fieldType); + final boolean isOpaqueFieldType = null != opaqueFieldType; + final TypeInfo opaqueField = cfg.canonicalNameOpaque(cfgFieldName1); + final boolean isOpaqueField = null != opaqueField; if( GlueGen.debug() ) { - System.err.printf("SE.ac.%02d: %s / %s, %s%n", (i+1), field, cfgFieldName1, fieldType.getDebugString()); + System.err.printf("SE.ac.%02d: %s / %s (opaque %b), %s (opaque %b)%n", (i+1), + (i+1), field, cfgFieldName1, isOpaqueField, fieldType.getDebugString(), isOpaqueFieldType); } - if (fieldType.isFunctionPointer()) { + if ( fieldType.isFunctionPointer() && !isOpaqueField ) { + final FunctionSymbol func = new FunctionSymbol(field.getName(), fieldType.asPointer().getTargetType().asFunction()); + func.rename(renamed); // null is OK generateFunctionPointerCode(methodBindingSet, javaWriter, jniWriter, structCTypeName, structClassPkgName, containingCType, containingJType, i, - new FunctionSymbol(fieldName, fieldType.asPointer().getTargetType().asFunction()), cfgFieldName1); - } else if (fieldType.isCompound()) { + func, cfgFieldName1); + } else if ( fieldType.isCompound() && !isOpaqueField ) { // FIXME: will need to support this at least in order to // handle the union in jawt_Win32DrawingSurfaceInfo (fabricate a name?) if (fieldType.getName() == null) { - throw new RuntimeException("Anonymous structs as fields not supported yet (field \"" + - field + "\" in type \"" + structCTypeName + "\")"); + throw new GlueGenException("Anonymous structs as fields not supported yet (field \"" + + field + "\" in type \"" + structCTypeName + "\")", + fieldType.getASTLocusTag()); } javaWriter.println(); - generateGetterSignature(javaWriter, fieldType, false, fieldType.getName(), capitalizeString(fieldName), null, null); + generateGetterSignature(javaWriter, fieldType, false, false, fieldType.getName(), fieldName, capitalizeString(fieldName), null, null); javaWriter.println(" {"); javaWriter.println(" return " + fieldType.getName() + ".create( accessor.slice( " + fieldName+"_offset[mdIdx], "+fieldName+"_size[mdIdx] ) );"); javaWriter.println(" }"); - } else if ( fieldType.isArray() || fieldType.isPointer() ) { - generateArrayGetterSetterCode(methodBindingSet, javaWriter, jniWriter, structCTypeName, structClassPkgName, - containingCType, containingJType, - i, field, fieldName, cfgFieldName1); + } else if ( ( fieldType.isArray() || fieldType.isPointer() ) && !isOpaqueField ) { + generateArrayGetterSetterCode(methodBindingSet, javaWriter, jniWriter, structCType, structCTypeName, + structClassPkgName, containingCType, + containingJType, i, field, fieldName, cfgFieldName1); } else { final JavaType javaType; try { javaType = typeToJavaType(fieldType, machDescJava); } catch (final Exception e) { - System.err.println("Error occurred while creating accessor for field \"" + - field.getName() + "\", "+fieldType.getDebugString()); - throw(e); + throw new GlueGenException("Error occurred while creating accessor for field \"" + + field.getName() + "\", "+fieldType.getDebugString(), fieldType.getASTLocusTag(), e); } - if (javaType.isPrimitive()) { + if ( isOpaqueFieldType || isOpaqueField || javaType.isPrimitive()) { // Primitive type final boolean fieldTypeNativeSizeFixed = fieldType.getSize().hasFixedNativeSize(); final String javaTypeName; - if ( isOpaque(fieldType) ) { - javaTypeName = compatiblePrimitiveJavaTypeName(fieldType, javaType, machDescJava); + if ( isOpaqueFieldType ) { + javaTypeName = opaqueFieldType.javaType().getName(); + } else if ( isOpaqueField ) { + javaTypeName = opaqueField.javaType().getName(); + // javaTypeName = compatiblePrimitiveJavaTypeName(fieldType, javaType, machDescJava); } else { javaTypeName = javaType.getName(); } @@ -1116,20 +1137,19 @@ final String capFieldName = capitalizeString(fieldName); final String sizeDenominator = fieldType.isPointer() ? "pointer" : javaTypeName ; - if(GlueGen.debug()) { - System.err.println("Java.StructEmitter.Primitive: "+field.getName()+", "+fieldType.getDebugString()+", "+javaTypeName+", "+ - ", fixedSize "+fieldTypeNativeSizeFixed+", opaque "+isOpaque(fieldType)+", sizeDenominator "+sizeDenominator); - } + LOG.log(FINE, structCType.getASTLocusTag(), + "Java.StructEmitter.Primitive: "+field.getName()+", "+fieldType+", "+javaTypeName+", "+ + ", fixedSize "+fieldTypeNativeSizeFixed+", opaque[t "+isOpaqueFieldType+", f "+isOpaqueField+"], sizeDenominator "+sizeDenominator); if( !fieldType.isConst() ) { // Setter javaWriter.println(); - generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capFieldName, null, javaTypeName, null, null); + generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, fieldName, capFieldName, null, javaTypeName, null, null); javaWriter.println(" {"); if( fieldTypeNativeSizeFixed ) { javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val);"); } else { - javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md."+sizeDenominator+"SizeInBytes());"); + javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val, md."+sizeDenominator+"SizeInBytes());"); } javaWriter.println(" return this;"); javaWriter.println(" }"); @@ -1137,13 +1157,13 @@ // Getter javaWriter.println(); - generateGetterSignature(javaWriter, fieldType, false, javaTypeName, capFieldName, null, null); + generateGetterSignature(javaWriter, fieldType, false, false, javaTypeName, fieldName, capFieldName, null, null); javaWriter.println(" {"); javaWriter.print (" return "); if( fieldTypeNativeSizeFixed ) { javaWriter.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx]);"); } else { - javaWriter.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], MachineDescriptionRuntime.getStatic().md."+sizeDenominator+"SizeInBytes());"); + javaWriter.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], md."+sizeDenominator+"SizeInBytes());"); } javaWriter.println(" }"); } else { @@ -1204,15 +1224,16 @@ // Internals only below this point // - private void generateGetterSignature(final PrintWriter writer, final Type origFieldType, final boolean abstractMethod, - final String returnTypeName, final String capitalizedFieldName, - final String customArgs, final String arrayLengthExpr) { - writer.print(" /** Getter for native field: "+origFieldType.getDebugString()); + private void generateGetterSignature(final PrintWriter writer, final Type origFieldType, + final boolean staticMethod, final boolean abstractMethod, + final String returnTypeName, final String fieldName, + final String capitalizedFieldName, final String customArgs, final String arrayLengthExpr) { + writer.print(" /** Getter for native field "+fieldName+": "+origFieldType.getDebugString()); if( null != arrayLengthExpr ) { writer.print(", with array length of "+arrayLengthExpr+""); } writer.println(" */"); - writer.print(" public " + (abstractMethod ? "abstract " : "") + returnTypeName + " get" + capitalizedFieldName + "("); + writer.print(" public " + (staticMethod ? "static " : "") + (abstractMethod ? "abstract " : "") + returnTypeName + " get" + capitalizedFieldName + "("); if( null != customArgs ) { writer.print(customArgs); } @@ -1220,10 +1241,10 @@ } private void generateSetterSignature(final PrintWriter writer, final Type origFieldType, final boolean abstractMethod, - final String returnTypeName, final String capitalizedFieldName, - final String customArgsPre, final String paramTypeName, final String customArgsPost, - final String arrayLengthExpr) { - writer.print(" /** Setter for native field: "+origFieldType.getDebugString()); + final String returnTypeName, final String fieldName, + final String capitalizedFieldName, final String customArgsPre, final String paramTypeName, + final String customArgsPost, final String arrayLengthExpr) { + writer.print(" /** Setter for native field "+fieldName+": "+origFieldType.getDebugString()); if( null != arrayLengthExpr ) { writer.print(", with array length of "+arrayLengthExpr+""); } @@ -1239,7 +1260,9 @@ writer.print(")"); } - private void generateOffsetAndSizeArrays(final PrintWriter writer, final String prefix, final String fieldName, final Type fieldType, final Field field, final String postfix) { + private void generateOffsetAndSizeArrays(final PrintWriter writer, final String prefix, + final String fieldName, final Type fieldType, + final Field field, final String postfix) { if(null != field) { writer.print(prefix+"private static final int[] "+fieldName+"_offset = new int[] { "); for( int i=0; i < machDescTargetConfigs.length; i++ ) { @@ -1275,7 +1298,7 @@ final Type containingCType, final JavaType containingJType, final int i, final FunctionSymbol funcSym, final String returnSizeLookupName) { // Emit method call and associated native code - final MethodBinding mb = bindFunction(funcSym, containingJType, containingCType, machDescJava); + final MethodBinding mb = bindFunction(funcSym, true /* forInterface */, machDescJava, containingJType, containingCType); mb.findThisPointer(); // FIXME: need to provide option to disable this on per-function basis // JavaTypes representing C pointers in the initial @@ -1297,16 +1320,17 @@ javaWriter, cfg.runtimeExceptionType(), cfg.unsupportedExceptionType(), - true, + true, // emitBody cfg.tagNativeBinding(), false, // eraseBufferAndArrayTypes useNIOOnly, useNIODirectOnly, - false, - false, // FIXME: should unify this with the general emission code + false, // forDirectBufferImplementation false, // forIndirectBufferAndArrayImplementation - false, // FIXME: should unify this with the general emission code - false, + false, // isUnimplemented + false, // isInterface + false, // isNativeMethod + false, // isPrivateNativeMethod cfg); emitter.addModifier(JavaMethodBindingEmitter.PUBLIC); emitter.emit(); @@ -1317,17 +1341,17 @@ javaWriter, cfg.runtimeExceptionType(), cfg.unsupportedExceptionType(), - false, + false, // emitBody cfg.tagNativeBinding(), - true, // eraseBufferAndArrayTypes + true, // eraseBufferAndArrayTypes useNIOOnly, useNIODirectOnly, - true, - true, // FIXME: should unify this with the general emission code + true, // forDirectBufferImplementation false, // forIndirectBufferAndArrayImplementation - false, // FIXME: should unify this with the general emission code - false, - cfg); + false, // isUnimplemented + false, // isInterface + false, // isNativeMethod + true, cfg); emitter.addModifier(JavaMethodBindingEmitter.PRIVATE); emitter.addModifier(JavaMethodBindingEmitter.NATIVE); emitter.emit(); @@ -1342,7 +1366,7 @@ false, true, false, // forIndirectBufferAndArrayImplementation - machDescJava); + machDescJava, getConfiguration()); cEmitter.setIsCStructFunctionPointer(true); prepCEmitter(returnSizeLookupName, binding.getJavaReturnType(), cEmitter); cEmitter.emit(); @@ -1356,7 +1380,7 @@ final int i, final FunctionSymbol funcSym, final String returnSizeLookupName, final String docArrayLenExpr, final String nativeArrayLenExpr) { // Emit method call and associated native code - final MethodBinding mb = bindFunction(funcSym, containingJType, containingCType, machDescJava); + final MethodBinding mb = bindFunction(funcSym, true /* forInterface */, machDescJava, containingJType, containingCType); mb.findThisPointer(); // FIXME: need to provide option to disable this on per-function basis // JavaTypes representing C pointers in the initial @@ -1379,16 +1403,17 @@ javaWriter, cfg.runtimeExceptionType(), cfg.unsupportedExceptionType(), - false, - cfg.tagNativeBinding(), - true, // eraseBufferAndArrayTypes + false, // emitBody + cfg.tagNativeBinding(), // tagNativeBinding + true, // eraseBufferAndArrayTypes useNIOOnly, useNIODirectOnly, - true, - true, // FIXME: should unify this with the general emission code - false, // forIndirectBufferAndArrayImplementation - false, // FIXME: should unify this with the general emission code - false, + false, // forDirectBufferImplementation + false, // forIndirectBufferAndArrayImplementation + false, // isUnimplemented + true, // isInterface + true, // isNativeMethod + true, // isPrivateNativeMethod cfg); if( null != docArrayLenExpr ) { emitter.setReturnedArrayLengthExpression(docArrayLenExpr, true); @@ -1407,7 +1432,7 @@ false, true, false, // forIndirectBufferAndArrayImplementation - machDescJava); + machDescJava, getConfiguration()); cEmitter.setIsCStructFunctionPointer(false); final String lenExprSet; if( null != nativeArrayLenExpr ) { @@ -1457,14 +1482,16 @@ final String cfgVal = cfg.returnedArrayLength(returnSizeLookupName); if( null != cfgVal ) { if( hasFixedTypeLen[0] ) { - System.err.println("WARNING: struct array field '"+returnSizeLookupName+"' of '"+type+"' length '"+Arrays.toString(length)+"' overwritten by cfg-expression: "+cfgVal); + LOG.log(WARNING, type.getASTLocusTag(), + "struct array field '"+returnSizeLookupName+"' of '"+type+"' length '"+Arrays.toString(length)+"' overwritten by cfg-expression: "+cfgVal); } return cfgVal; } if( hasFixedTypeLen[0] ) { return lengthExpr.toString(); } else { - System.err.println("WARNING: struct array field '"+returnSizeLookupName+"' length '"+Arrays.toString(length)+"' without fixed- nor configured-size: "+type.getDebugString()); + LOG.log(WARNING, type.getASTLocusTag(), + "struct array field '"+returnSizeLookupName+"' length '"+Arrays.toString(length)+"' without fixed- nor configured-size: {0}", type); return null; } } @@ -1497,16 +1524,18 @@ private void generateArrayGetterSetterCode(final Set methodBindingSet, final PrintWriter javaWriter, final PrintWriter jniWriter, + final CompoundType structCType, final String structCTypeName, final String structClassPkgName, final Type containingCType, final JavaType containingJType, - final int i, final Field field, final String fieldName, final String returnSizeLookupName) throws Exception { + final int i, final Field field, final String fieldName, + final String returnSizeLookupName) throws Exception { final Type fieldType = field.getType(); final JavaType javaType; try { javaType = typeToJavaType(fieldType, machDescJava); } catch (final Exception e) { - throw new RuntimeException("Error occurred while creating array/pointer accessor for field \"" + - returnSizeLookupName + "\", "+fieldType.getDebugString(), e); + throw new GlueGenException("Error occurred while creating array/pointer accessor for field \"" + + returnSizeLookupName + "\", "+fieldType.getDebugString(), fieldType.getASTLocusTag(), e); } if( GlueGen.debug() ) { System.err.printf("SE.ac.%02d: javaType %s%n", (i+1), javaType.getDebugString()); @@ -1520,6 +1549,7 @@ final boolean isString = cfg.returnsString(returnSizeLookupName); // FIXME: Allow custom Charset ? US-ASCII, UTF-8 or UTF-16 ? final boolean useGetCStringLength; final String arrayLengthExpr; + final boolean arrayLengthExprIsConst; final int[] arrayLengths; final boolean useFixedTypeLen[] = { false }; final boolean isPointer; @@ -1538,11 +1568,13 @@ final Type baseCElemType; final ArrayType arrayType = fieldType.asArray(); String _arrayLengthExpr = null; + boolean _arrayLengthExprIsConst = false; if( isOpaque || javaType.isPrimitive() ) { // Overridden by JavaConfiguration.typeInfo(..), i.e. Opaque! // Emulating array w/ 1 element isPrimitive = true; _arrayLengthExpr = nativeArrayLengthONE; + _arrayLengthExprIsConst = true; arrayLengths = new int[] { 1 }; baseCElemType = null; isPointer = false; @@ -1555,12 +1587,14 @@ if( null != arrayType ) { final int[][] lengthRes = new int[1][]; _arrayLengthExpr = getArrayArrayLengthExpr(arrayType, returnSizeLookupName, useFixedTypeLen, lengthRes); + _arrayLengthExprIsConst = true; arrayLengths = lengthRes[0]; baseCElemType = arrayType.getBaseElementType(); isPointer = false; } else { final PointerType pointerType = fieldType.asPointer(); _arrayLengthExpr = getPointerArrayLengthExpr(pointerType, returnSizeLookupName); + _arrayLengthExprIsConst = false; arrayLengths = null; baseCElemType = pointerType.getBaseElementType(); isPointer = true; @@ -1568,7 +1602,7 @@ javaWriter.println(); final String msg = "SKIP ptr-ptr (depth "+pointerType.pointerDepth()+"): "+returnSizeLookupName +": "+fieldType; javaWriter.println(" // "+msg); - System.err.println("WARNING: "+msg); + LOG.log(WARNING, structCType.getASTLocusTag(), msg); return; } } @@ -1580,8 +1614,9 @@ try { baseJElemType = typeToJavaType(baseCElemType, machDescJava); } catch (final Exception e ) { - throw new RuntimeException("Error occurred while creating array/pointer accessor for field \"" + - returnSizeLookupName + "\", baseType "+baseCElemType.getDebugString()+", topType "+fieldType.getDebugString(), e); + throw new GlueGenException("Error occurred while creating array/pointer accessor for field \"" + + returnSizeLookupName + "\", baseType "+baseCElemType.getDebugString()+", topType "+fieldType.getDebugString(), + fieldType.getASTLocusTag(), e); } baseJElemTypeName = baseJElemType.getName(); baseCElemNativeSizeFixed = baseCElemType.isPrimitive() ? baseCElemType.getSize().hasFixedNativeSize() : true; @@ -1591,7 +1626,7 @@ javaWriter.println(); final String msg = "SKIP primitive w/ platform dependent sized type in struct: "+returnSizeLookupName+": "+fieldType.getDebugString(); javaWriter.println(" // "+msg); - System.err.println("WARNING: "+msg); + LOG.log(WARNING, structCType.getASTLocusTag(), msg); return; } } @@ -1605,17 +1640,19 @@ if( null == _arrayLengthExpr && isString && isPointer ) { useGetCStringLength = true; _arrayLengthExpr = "getCStringLengthImpl(pString)+1"; + _arrayLengthExprIsConst = false; this.requiresStaticInitialization = true; - LOG.log(INFO, "StaticInit Trigger.3 \"{0}\"", returnSizeLookupName); + LOG.log(INFO, structCType.getASTLocusTag(), "StaticInit Trigger.3 \"{0}\"", returnSizeLookupName); } else { useGetCStringLength = false; } arrayLengthExpr = _arrayLengthExpr; + arrayLengthExprIsConst = _arrayLengthExprIsConst; if( null == arrayLengthExpr ) { javaWriter.println(); final String msg = "SKIP unsized array in struct: "+returnSizeLookupName+": "+fieldType.getDebugString(); javaWriter.println(" // "+msg); - System.err.println("WARNING: "+msg); + LOG.log(WARNING, structCType.getASTLocusTag(), msg); return; } boolean _hasSingleElement=false; @@ -1626,8 +1663,8 @@ } if( GlueGen.debug() ) { System.err.printf("SE.ac.%02d: baseJElemTypeName %s, array-lengths %s%n", (i+1), baseJElemTypeName, Arrays.toString(arrayLengths)); - System.err.printf("SE.ac.%02d: arrayLengthExpr: %s, hasSingleElement %b, isByteBuffer %b, isString %b, isPointer %b, isPrimitive %b, isOpaque %b, baseCElemNativeSizeFixed %b, baseCElemSizeDenominator %s, isConst %b, useGetCStringLength %b%n", - (i+1), arrayLengthExpr, hasSingleElement, isByteBuffer, isString, isPointer, isPrimitive, isOpaque, + System.err.printf("SE.ac.%02d: arrayLengthExpr: %s (const %b), hasSingleElement %b, isByteBuffer %b, isString %b, isPointer %b, isPrimitive %b, isOpaque %b, baseCElemNativeSizeFixed %b, baseCElemSizeDenominator %s, isConst %b, useGetCStringLength %b%n", + (i+1), arrayLengthExpr, arrayLengthExprIsConst, hasSingleElement, isByteBuffer, isString, isPointer, isPrimitive, isOpaque, baseCElemNativeSizeFixed, baseCElemSizeDenominator, isConst, useGetCStringLength); } @@ -1637,7 +1674,7 @@ // if( !hasSingleElement && useFixedTypeLen[0] ) { javaWriter.println(); - generateGetterSignature(javaWriter, fieldType, false, "final int", capitalFieldName+"ArrayLength", null, arrayLengthExpr); + generateGetterSignature(javaWriter, fieldType, arrayLengthExprIsConst, false, "final int", fieldName, capitalFieldName+"ArrayLength", null, arrayLengthExpr); javaWriter.println(" {"); javaWriter.println(" return "+arrayLengthExpr+";"); javaWriter.println(" }"); @@ -1651,21 +1688,21 @@ // Setter Primitive Pointer final String msg = "SKIP setter for primitive-pointer type in struct: "+returnSizeLookupName+": "+fieldType.getDebugString(); javaWriter.println(" // "+msg); - System.err.println("INFO: "+msg); + LOG.log(INFO, structCType.getASTLocusTag(), msg); } else { // Setter Primitive Array if( hasSingleElement ) { - generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capitalFieldName, null, baseJElemTypeName, null, arrayLengthExpr); + generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName, null, arrayLengthExpr); javaWriter.println(" {"); if( baseCElemNativeSizeFixed ) { javaWriter.println(" accessor.set" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx], val);"); } else { - javaWriter.println(" accessor.set" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md."+baseCElemSizeDenominator+"SizeInBytes());"); + javaWriter.println(" accessor.set" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx], val, md."+baseCElemSizeDenominator+"SizeInBytes());"); } javaWriter.println(" return this;"); javaWriter.println(" }"); } else { - generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capitalFieldName, "final int offset", baseJElemTypeName+"[]", null, arrayLengthExpr); + generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, fieldName, capitalFieldName, "final int offset", baseJElemTypeName+"[]", null, arrayLengthExpr); javaWriter.println(" {"); javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";"); javaWriter.println(" if( offset + val.length > arrayLength ) { throw new IndexOutOfBoundsException(\"offset \"+offset+\" + val.length \"+val.length+\" > array-length \"+arrayLength); };"); @@ -1688,11 +1725,11 @@ // Setter Struct Pointer final String msg = "SKIP setter for complex-pointer type in struct: "+returnSizeLookupName+": "+fieldType.getDebugString(); javaWriter.println(" // "+msg); - System.err.println("INFO: "+msg); + LOG.log(INFO, structCType.getASTLocusTag(), msg); } else { // Setter Struct Array if( hasSingleElement ) { - generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capitalFieldName, null, baseJElemTypeName, null, arrayLengthExpr); + generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName, null, arrayLengthExpr); javaWriter.println(" {"); javaWriter.println(" final int elemSize = "+baseJElemTypeName+".size();"); javaWriter.println(" final ByteBuffer destB = getBuffer();"); @@ -1708,7 +1745,7 @@ javaWriter.println(" return this;"); javaWriter.println(" }"); } else { - generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capitalFieldName, "final int offset", baseJElemTypeName+"[]", null, arrayLengthExpr); + generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, fieldName, capitalFieldName, "final int offset", baseJElemTypeName+"[]", null, arrayLengthExpr); javaWriter.println(" {"); javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";"); javaWriter.println(" if( offset + val.length > arrayLength ) { throw new IndexOutOfBoundsException(\"offset \"+offset+\" + val.length \"+val.length+\" > array-length \"+arrayLength); };"); @@ -1730,7 +1767,7 @@ javaWriter.println(" return this;"); javaWriter.println(" }"); javaWriter.println(); - generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capitalFieldName, "final int index", baseJElemTypeName, null, arrayLengthExpr); + generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, fieldName, capitalFieldName, "final int index", baseJElemTypeName, null, arrayLengthExpr); javaWriter.println(" {"); javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";"); javaWriter.println(" final int elemSize = "+baseJElemTypeName+".size();"); @@ -1759,12 +1796,12 @@ if( isPointer ) { // Getter Primitive Pointer final FunctionType ft = new FunctionType(dummyFuncTypeName, SizeThunk.POINTER, fieldType, 0); - ft.addArgument(containingCType.getCVVariant(containingCType.getCVAttributes() | CVAttributes.CONST), + ft.addArgument(containingCType.newCVVariant(containingCType.getCVAttributes() | CVAttributes.CONST), CMethodBindingEmitter.cThisArgumentName()); ft.addArgument(int32Type, nativeArrayLengthArg); final FunctionSymbol fs = new FunctionSymbol("get"+capitalFieldName, ft); jniWriter.println(); - jniWriter.print("static "+fs.toString()); + jniWriter.print("static "+fs.toString(false)); jniWriter.println("{"); jniWriter.println(" return "+CMethodBindingEmitter.cThisArgumentName()+"->"+field.getName()+";"); jniWriter.println("}"); @@ -1772,7 +1809,7 @@ generateArrayPointerCode(methodBindingSet, javaWriter, jniWriter, structCTypeName, structClassPkgName, containingCType, containingJType, i, fs, returnSizeLookupName, arrayLengthExpr, nativeArrayLengthArg); javaWriter.println(); - generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeNameC+"Buffer", capitalFieldName, null, arrayLengthExpr); + generateGetterSignature(javaWriter, fieldType, false, false, baseJElemTypeNameC+"Buffer", fieldName, capitalFieldName, null, arrayLengthExpr); javaWriter.println(" {"); if( useGetCStringLength ) { javaWriter.println(" final int arrayLength = get"+capitalFieldName+"ArrayLength();"); @@ -1789,7 +1826,7 @@ javaWriter.println(" }"); if( isString && isByteBuffer ) { javaWriter.println(); - generateGetterSignature(javaWriter, fieldType, false, "String", capitalFieldName+"AsString", null, arrayLengthExpr); + generateGetterSignature(javaWriter, fieldType, false, false, "String", fieldName, capitalFieldName+"AsString", null, arrayLengthExpr); javaWriter.println(" {"); if( useGetCStringLength ) { javaWriter.println(" final int arrayLength = get"+capitalFieldName+"ArrayLength();"); @@ -1809,7 +1846,7 @@ } if( useGetCStringLength ) { javaWriter.println(); - generateGetterSignature(javaWriter, fieldType, false, "final int", capitalFieldName+"ArrayLength", null, arrayLengthExpr); + generateGetterSignature(javaWriter, fieldType, false, false, "final int", fieldName, capitalFieldName+"ArrayLength", null, arrayLengthExpr); javaWriter.println(" {"); javaWriter.println(" final long pString = PointerBuffer.wrap( accessor.slice(" + fieldName+"_offset[mdIdx], PointerBuffer.ELEMENT_SIZE) ).get(0);"); javaWriter.println(" return "+arrayLengthExpr+";"); @@ -1818,17 +1855,17 @@ } else { // Getter Primitive Array if( hasSingleElement ) { - generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName, capitalFieldName, null, arrayLengthExpr); + generateGetterSignature(javaWriter, fieldType, false, false, baseJElemTypeName, fieldName, capitalFieldName, null, arrayLengthExpr); javaWriter.println(" {"); if( baseCElemNativeSizeFixed ) { javaWriter.println(" return accessor.get" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx]);"); } else { - javaWriter.println(" return accessor.get" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx], MachineDescriptionRuntime.getStatic().md."+baseCElemSizeDenominator+"SizeInBytes());"); + javaWriter.println(" return accessor.get" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx], md."+baseCElemSizeDenominator+"SizeInBytes());"); } javaWriter.println(" }"); javaWriter.println(); } else { - generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeNameC+"Buffer", capitalFieldName, null, arrayLengthExpr); + generateGetterSignature(javaWriter, fieldType, false, false, baseJElemTypeNameC+"Buffer", fieldName, capitalFieldName, null, arrayLengthExpr); javaWriter.println(" {"); javaWriter.print(" return accessor.slice(" + fieldName+"_offset[mdIdx], Buffers.SIZEOF_"+baseJElemTypeNameU+" * "+arrayLengthExpr+")"); if( !isByteBuffer ) { @@ -1838,7 +1875,7 @@ javaWriter.println(" }"); javaWriter.println(); if( isString && isByteBuffer ) { - generateGetterSignature(javaWriter, fieldType, false, "String", capitalFieldName+"AsString", null, arrayLengthExpr); + generateGetterSignature(javaWriter, fieldType, false, false, "String", fieldName, capitalFieldName+"AsString", null, arrayLengthExpr); javaWriter.println(" {"); javaWriter.println(" final int offset = " + fieldName+"_offset[mdIdx];"); javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";"); @@ -1852,7 +1889,7 @@ javaWriter.println(" return new String(ba, 0, i);"); javaWriter.println(" }"); } else { - generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName+"[]", capitalFieldName, "final int offset, "+baseJElemTypeName+" result[]", arrayLengthExpr); + generateGetterSignature(javaWriter, fieldType, false, false, baseJElemTypeName+"[]", fieldName, capitalFieldName, "final int offset, "+baseJElemTypeName+" result[]", arrayLengthExpr); javaWriter.println(" {"); javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";"); javaWriter.println(" if( offset + result.length > arrayLength ) { throw new IndexOutOfBoundsException(\"offset \"+offset+\" + result.length \"+result.length+\" > array-length \"+arrayLength); };"); @@ -1867,12 +1904,12 @@ if( isPointer ) { // Getter Struct Pointer final FunctionType ft = new FunctionType(dummyFuncTypeName, SizeThunk.POINTER, fieldType, 0); - ft.addArgument(containingCType.getCVVariant(containingCType.getCVAttributes() | CVAttributes.CONST), + ft.addArgument(containingCType.newCVVariant(containingCType.getCVAttributes() | CVAttributes.CONST), CMethodBindingEmitter.cThisArgumentName()); ft.addArgument(int32Type, nativeArrayElemOffsetArg); final FunctionSymbol fs = new FunctionSymbol("get"+capitalFieldName, ft); jniWriter.println(); - jniWriter.print("static "+fs.toString()); + jniWriter.print("static "+fs.toString(false)); jniWriter.println("{"); jniWriter.println(" return "+CMethodBindingEmitter.cThisArgumentName()+"->"+field.getName()+"+"+nativeArrayElemOffsetArg+";"); jniWriter.println("}"); @@ -1881,7 +1918,7 @@ containingCType, containingJType, i, fs, returnSizeLookupName, arrayLengthExpr, nativeArrayLengthONE); javaWriter.println(); if( hasSingleElement ) { - generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName, capitalFieldName, null, arrayLengthExpr); + generateGetterSignature(javaWriter, fieldType, false, false, baseJElemTypeName, fieldName, capitalFieldName, null, arrayLengthExpr); javaWriter.println(" {"); javaWriter.println(" final ByteBuffer source = getBuffer();"); javaWriter.println(" final ByteBuffer _res = get"+capitalFieldName+"0(source, 0);"); @@ -1889,7 +1926,7 @@ javaWriter.println(" return "+baseJElemTypeName+".create(_res);"); javaWriter.println(" }"); } else { - generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName+"[]", capitalFieldName, "final int offset, "+baseJElemTypeName+" result[]", arrayLengthExpr); + generateGetterSignature(javaWriter, fieldType, false, false, baseJElemTypeName+"[]", fieldName, capitalFieldName, "final int offset, "+baseJElemTypeName+" result[]", arrayLengthExpr); javaWriter.println(" {"); javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";"); javaWriter.println(" if( offset + result.length > arrayLength ) { throw new IndexOutOfBoundsException(\"offset \"+offset+\" + result.length \"+result.length+\" > array-length \"+arrayLength); };"); @@ -1905,12 +1942,12 @@ } else { // Getter Struct Array if( hasSingleElement ) { - generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName, capitalFieldName, null, arrayLengthExpr); + generateGetterSignature(javaWriter, fieldType, false, false, baseJElemTypeName, fieldName, capitalFieldName, null, arrayLengthExpr); javaWriter.println(" {"); javaWriter.println(" return "+baseJElemTypeName+".create(accessor.slice("+fieldName+"_offset[mdIdx], "+baseJElemTypeName+".size()));"); javaWriter.println(" }"); } else { - generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName+"[]", capitalFieldName, "final int offset, "+baseJElemTypeName+" result[]", arrayLengthExpr); + generateGetterSignature(javaWriter, fieldType, false, false, baseJElemTypeName+"[]", fieldName, capitalFieldName, "final int offset, "+baseJElemTypeName+" result[]", arrayLengthExpr); javaWriter.println(" {"); javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";"); javaWriter.println(" if( offset + result.length > arrayLength ) { throw new IndexOutOfBoundsException(\"offset \"+offset+\" + result.length \"+result.length+\" > array-length \"+arrayLength); };"); @@ -1927,12 +1964,9 @@ } } - private static final boolean DEBUG_TYPEC2JAVA = false; - private JavaType typeToJavaType(final Type cType, final MachineDescription curMachDesc) { + private JavaType typeToJavaType(final Type cType, final MachineDataInfo curMachDesc) { final JavaType jt = typeToJavaTypeImpl(cType, curMachDesc); - if( DEBUG_TYPEC2JAVA ) { - System.err.println("typeToJavaType: "+cType.getDebugString()+" -> "+jt.getDebugString()); - } + LOG.log(FINE, cType.getASTLocusTag(), "typeToJavaType: {0} -> {1}", cType, jt); return jt; } private boolean isJNIEnvPointer(final Type cType) { @@ -1941,14 +1975,14 @@ (opt.getTargetType().getName() != null) && (opt.getTargetType().getName().equals("JNIEnv")); } - private JavaType typeToJavaTypeImpl(final Type cType, final MachineDescription curMachDesc) { + private JavaType typeToJavaTypeImpl(final Type cType, final MachineDataInfo curMachDesc) { // Recognize JNIEnv* case up front if( isJNIEnvPointer(cType) ) { return JavaType.createForJNIEnv(); } // Opaque specifications override automatic conversions // in case the identity is being used .. not if ptr-ptr - final TypeInfo info = cfg.typeInfo(cType, typedefDictionary); + final TypeInfo info = cfg.typeInfo(cType); if (info != null) { boolean isPointerPointer = false; if (cType.pointerDepth() > 0 || cType.arrayDimension() > 0) { @@ -1966,16 +2000,16 @@ // target type) if (targetType.isPointer()) { isPointerPointer = true; - - // t is**, targetType is *, we need to get - final Type bottomType = targetType.asPointer().getTargetType(); if( GlueGen.debug() ) { - LOG.log(INFO, "Opaque Type: {0}, targetType: {1}, bottomType: {2} is ptr-ptr", new Object[]{cType.getDebugString(), targetType, bottomType}); + // t is**, targetType is *, we need to get + final Type bottomType = targetType.asPointer().getTargetType(); + LOG.log(INFO, cType.getASTLocusTag(), "Opaque Type: {0}, targetType: {1}, bottomType: {2} is ptr-ptr", + cType, targetType, bottomType); } } } } - if(!isPointerPointer) { + if( !isPointerPointer ) { return info.javaType(); } } @@ -1986,8 +2020,9 @@ case 2: return javaType(Short.TYPE); case 4: return javaType(Integer.TYPE); case 8: return javaType(Long.TYPE); - default: throw new RuntimeException("Unknown integer type of size " + - cType.getSize(curMachDesc) + " and name " + cType.getName()); + default: throw new GlueGenException("Unknown integer type of size " + + cType.getSize(curMachDesc) + " and name " + cType.getName(), + cType.getASTLocusTag()); } } else if (cType.isFloat()) { return javaType(Float.TYPE); @@ -2022,8 +2057,9 @@ case 2: return JavaType.createForCShortPointer(); case 4: return JavaType.createForCInt32Pointer(); case 8: return JavaType.createForCInt64Pointer(); - default: throw new RuntimeException("Unknown integer array type of size " + - cType.getSize(curMachDesc) + " and name " + cType.getName()+", "+cType.getDebugString()); + default: throw new GlueGenException("Unknown integer array type of size " + + cType.getSize(curMachDesc) + " and name " + cType.getName()+", "+cType.getDebugString(), + cType.getASTLocusTag()); } } else if (targetType.isFloat()) { return JavaType.createForCFloatPointer(); @@ -2038,19 +2074,28 @@ cType.getName().equals("jobject")) { return javaType(java.lang.Object.class); } - String name = targetType.getName(); - if (name == null) { - // Try containing pointer type for any typedefs - name = cType.getName(); - if (name == null) { - throw new RuntimeException("Couldn't find a proper type name for pointer type " + cType.getDebugString()); - } + // NOTE: Struct Name Resolution (JavaEmitter, HeaderParser) + String name; + if( !targetType.isTypedef() && cType.isTypedef() ) { + // If compound is not a typedef _and_ containing pointer is typedef, use the latter. + name = cType.getName(); + } else { + // .. otherwise try compound name + name = targetType.getName(); + if( null == name ) { + // .. fall back to pointer type name + name = cType.getName(); + if (name == null) { + throw new GlueGenException("Couldn't find a proper type name for pointer type " + cType.getDebugString(), + cType.getASTLocusTag()); + } + } } - return JavaType.createForCStruct(cfg.renameJavaType(name)); } else { - throw new RuntimeException("Don't know how to convert pointer/array type \"" + - cType.getDebugString() + "\""); + throw new GlueGenException("Don't know how to convert pointer/array type \"" + + cType.getDebugString() + "\"", + cType.getASTLocusTag()); } } // Handle Types of form pointer-to-pointer-to-type or @@ -2064,19 +2109,22 @@ // t is**, targetType is *, we need to get bottomType = targetType.asPointer().getTargetType(); if( GlueGen.debug() ) { - LOG.log(INFO, "typeToJavaType(ptr-ptr): {0}, targetType: {1}, bottomType: {2}", new Object[]{cType.getDebugString(), targetType, bottomType}); + LOG.log(INFO, cType.getASTLocusTag(), "typeToJavaType(ptr-ptr): {0}, targetType: {1}, bottomType: {2}", + cType.getDebugString(), targetType, bottomType); } return JavaType.forNIOPointerBufferClass(); } else if(targetType.isArray()) { // t is[][], targetType is [], we need to get bottomType = targetType.asArray().getBaseElementType(); if( GlueGen.debug() ) { - LOG.log(INFO, "typeToJavaType(ptr-ptr.array): {0}, targetType: {1}, bottomType: {2}", new Object[]{cType.getDebugString(), targetType, bottomType}); + LOG.log(INFO, cType.getASTLocusTag(), "typeToJavaType(ptr-ptr.array): {0}, targetType: {1}, bottomType: {2}", + cType.getDebugString(), targetType, bottomType); } } else { bottomType = targetType; if( GlueGen.debug() ) { - LOG.log(INFO, "typeToJavaType(ptr-ptr.primitive): {0}, targetType: {1}, bottomType: {2}", new Object[]{cType.getDebugString(), targetType, bottomType}); + LOG.log(INFO, cType.getASTLocusTag(), "typeToJavaType(ptr-ptr.primitive): {0}, targetType: {1}, bottomType: {2}", + cType.getDebugString(), targetType, bottomType); } } @@ -2090,16 +2138,17 @@ case 2: return javaType(ArrayTypes.shortBufferArrayClass); case 4: return javaType(ArrayTypes.intBufferArrayClass); case 8: return javaType(ArrayTypes.longBufferArrayClass); - default: throw new RuntimeException("Unknown two-dimensional integer array type of element size " + - bottomType.getSize(curMachDesc) + " and name " + bottomType.getName()+", "+bottomType.getDebugString()); + default: throw new GlueGenException("Unknown two-dimensional integer array type of element size " + + bottomType.getSize(curMachDesc) + " and name " + bottomType.getName()+", "+bottomType.getDebugString(), + bottomType.getASTLocusTag()); } } else if (bottomType.isFloat()) { return javaType(ArrayTypes.floatBufferArrayClass); } else if (bottomType.isDouble()) { return javaType(ArrayTypes.doubleBufferArrayClass); } else { - throw new RuntimeException("Unexpected primitive type " + bottomType.getDebugString() + - " in two-dimensional array"); + throw new GlueGenException("Unexpected primitive type " + bottomType.getDebugString() + + " in two-dimensional array", bottomType.getASTLocusTag()); } } else if (bottomType.isVoid()) { return javaType(ArrayTypes.bufferArrayClass); @@ -2108,32 +2157,38 @@ // Array of pointers; convert as array of StructAccessors return JavaType.createForCArray(bottomType); } else { - throw new RuntimeException( + throw new GlueGenException( "Could not convert C type \"" + cType.getDebugString() + "\" " + "to appropriate Java type; need to add more support for " + "depth=2 pointer/array types [debug info: targetType=\"" + - targetType + "\"]"); + targetType + "\"]", cType.getASTLocusTag()); } } else { // can't handle this type of pointer/array argument - throw new RuntimeException( + throw new GlueGenException( "Could not convert C pointer/array \"" + cType.getDebugString() + "\" to " + "appropriate Java type; types with pointer/array depth " + "greater than 2 are not yet supported [debug info: " + "pointerDepth=" + cType.pointerDepth() + " arrayDimension=" + - cType.arrayDimension() + " targetType=\"" + targetType + "\"]"); + cType.arrayDimension() + " targetType=\"" + targetType + "\"]", + cType.getASTLocusTag()); } - } else if(cType.isCompound() ) { // FIXME: Compound and Compound-Arrays - final String name = cType.getName(); + } else if( cType.isCompound() ) { // FIXME: Compound and Compound-Arrays + String name = cType.getName(); if (name == null) { - throw new RuntimeException("Couldn't find a proper type name for pointer type " + cType.getDebugString()); + name = cType.asCompound().getStructName(); + if (name == null) { + throw new GlueGenException("Couldn't find a proper type name for pointer type " + cType.getDebugString(), + cType.getASTLocusTag()); + } } return JavaType.createForCStruct(cfg.renameJavaType(name)); } else { - throw new RuntimeException( + throw new GlueGenException( "Could not convert C type \"" + cType.getDebugString() + "\" (class " + - cType.getClass().getName() + ") to appropriate Java type"); + cType.getClass().getName() + ") to appropriate Java type", + cType.getASTLocusTag()); } } @@ -2169,23 +2224,25 @@ } private boolean isOpaque(final Type type) { - return (cfg.typeInfo(type, typedefDictionary) != null); + return null != cfg.typeInfo(type); } private String compatiblePrimitiveJavaTypeName(final Type fieldType, final JavaType javaType, - final MachineDescription curMachDesc) { + final MachineDataInfo curMachDesc) { final Class c = javaType.getJavaClass(); if (!isIntegerType(c)) { // FIXME - throw new RuntimeException("Can't yet handle opaque definitions of structs' fields to non-integer types (byte, short, int, long, etc.): type: "+fieldType+", javaType "+javaType+", javaClass "+c); + throw new GlueGenException("Can't yet handle opaque definitions of structs' fields to non-integer types (byte, short, int, long, etc.): type: "+fieldType+", javaType "+javaType+", javaClass "+c, + fieldType.getASTLocusTag()); } switch ((int) fieldType.getSize(curMachDesc)) { case 1: return "byte"; case 2: return "short"; case 4: return "int"; case 8: return "long"; - default: throw new RuntimeException("Can't handle opaque definitions if the starting type isn't compatible with integral types"); + default: throw new GlueGenException("Can't handle opaque definitions if the starting type isn't compatible with integral types", + fieldType.getASTLocusTag()); } } @@ -2209,13 +2266,16 @@ } if (cfg.allStatic() || cfg.emitInterface()) { - javaWriter = openFile(jRoot + File.separator + cfg.className() + ".java", cfg.className()); + javaFileName = jRoot + File.separator + cfg.className() + ".java"; + javaWriter = openFile(javaFileName, cfg.className()); } if (!cfg.allStatic() && cfg.emitImpl()) { - javaImplWriter = openFile(jImplRoot + File.separator + cfg.implClassName() + ".java", cfg.implClassName()); + javaFileName = jImplRoot + File.separator + cfg.implClassName() + ".java"; + javaImplWriter = openFile(javaFileName, cfg.implClassName()); } if (cfg.emitImpl()) { - cWriter = openFile(nRoot + File.separator + cfg.implClassName() + "_JNI.c", cfg.implClassName()); + cFileName = nRoot + File.separator + cfg.implClassName() + "_JNI.c"; + cWriter = openFile(cFileName, cfg.implClassName()); } if (javaWriter != null) { @@ -2229,6 +2289,9 @@ } } + /** For {@link #javaWriter} or {@link #javaImplWriter} */ + protected String javaFileName() { return javaFileName; } + protected PrintWriter javaWriter() { if (!cfg.allStatic() && !cfg.emitInterface()) { throw new InternalError("Should not call this"); @@ -2243,6 +2306,9 @@ return javaImplWriter; } + /** For {@link #cImplWriter} */ + protected String cFileName() { return cFileName; } + protected PrintWriter cWriter() { if (!cfg.emitImpl()) { throw new InternalError("Should not call this"); @@ -2311,6 +2377,23 @@ writer.println(" // ---- End CustomJavaCode .cfg declarations"); } + public String[] getClassAccessModifiers(final String classFQName) { + String[] accessModifiers; + final MethodAccess acc = cfg.accessControl(classFQName); + if( PUBLIC_ABSTRACT == acc ) { + accessModifiers = new String[] { PUBLIC.getJavaName(), PUBLIC_ABSTRACT.getJavaName() }; + } else if( PACKAGE_PRIVATE == acc ) { + accessModifiers = new String[] { PACKAGE_PRIVATE.getJavaName() }; + } else if( PRIVATE == acc ) { + throw new IllegalArgumentException("Class access "+classFQName+" cannot be private"); + } else if( PROTECTED == acc ) { + accessModifiers = new String[] { PROTECTED.getJavaName() }; + } else { // default PUBLIC + accessModifiers = new String[] { PUBLIC.getJavaName() }; + } + return accessModifiers; + } + /** * Write out any header information for the output files (class declaration * and opening brace, import statements, etc). @@ -2346,13 +2429,7 @@ } }; - String[] accessModifiers = null; - if(cfg.accessControl(cfg.className()) == PUBLIC_ABSTRACT) { - accessModifiers = new String[] { "public", "abstract" }; - } else { - accessModifiers = new String[] { "public" }; - } - + final String[] accessModifiers = getClassAccessModifiers(cfg.className()); CodeGenUtils.emitJavaHeaders( javaWriter, cfg.packageName(), @@ -2390,13 +2467,7 @@ interfaces[userSpecifiedInterfaces.size()] = cfg.className(); } - String[] accessModifiers = null; - if(cfg.accessControl(cfg.implClassName()) == PUBLIC_ABSTRACT) { - accessModifiers = new String[] { "public", "abstract" }; - } else { - accessModifiers = new String[] { "public" }; - } - + final String[] accessModifiers = getClassAccessModifiers(cfg.implClassName()); CodeGenUtils.emitJavaHeaders( javaImplWriter, cfg.implPackageName(), @@ -2429,8 +2500,9 @@ if (getConfig().emitImpl()) { cWriter.println("#include "); + cWriter.println("#include "); cWriter.println(); - cWriter.println("static jobject JVMUtil_NewDirectByteBufferCopy(JNIEnv *env, void * source_address, jlong capacity); /* forward decl. */"); + cWriter.println("static jobject JVMUtil_NewDirectByteBufferCopy(JNIEnv *env, void * source_address, size_t capacity); /* forward decl. */"); cWriter.println(); } for (final String code : cfg.customCCode()) { @@ -2443,6 +2515,7 @@ "static const char * clazzNameBuffers = \"com/jogamp/common/nio/Buffers\";\n"+ "static const char * clazzNameBuffersStaticNewCstrName = \"newDirectByteBuffer\";\n"+ "static const char * clazzNameBuffersStaticNewCstrSignature = \"(I)Ljava/nio/ByteBuffer;\";\n"+ + "static const char * sFatalError = \"FatalError:\";\n"+ "static jclass clazzBuffers = NULL;\n"+ "static jmethodID cstrBuffersNew = NULL;\n"+ "static jboolean _initClazzAccessDone = JNI_FALSE;\n"+ @@ -2454,13 +2527,13 @@ "\n"+ " c = (*env)->FindClass(env, clazzNameBuffers);\n"+ " if(NULL==c) {\n"+ - " fprintf(stderr, \"FatalError: Can't find %s\\n\", clazzNameBuffers);\n"+ + " fprintf(stderr, \"%s Can't find %s\\n\", sFatalError, clazzNameBuffers);\n"+ " (*env)->FatalError(env, clazzNameBuffers);\n"+ " return JNI_FALSE;\n"+ " }\n"+ " clazzBuffers = (jclass)(*env)->NewGlobalRef(env, c);\n"+ " if(NULL==clazzBuffers) {\n"+ - " fprintf(stderr, \"FatalError: Can't use %s\\n\", clazzNameBuffers);\n"+ + " fprintf(stderr, \"%s Can't use %s\\n\", sFatalError, clazzNameBuffers);\n"+ " (*env)->FatalError(env, clazzNameBuffers);\n"+ " return JNI_FALSE;\n"+ " }\n"+ @@ -2468,7 +2541,7 @@ " cstrBuffersNew = (*env)->GetStaticMethodID(env, clazzBuffers,\n"+ " clazzNameBuffersStaticNewCstrName, clazzNameBuffersStaticNewCstrSignature);\n"+ " if(NULL==cstrBuffersNew) {\n"+ - " fprintf(stderr, \"FatalError: can't create %s.%s %s\\n\",\n"+ + " fprintf(stderr, \"%s can't create %s.%s %s\\n\", sFatalError,\n"+ " clazzNameBuffers,\n"+ " clazzNameBuffersStaticNewCstrName, clazzNameBuffersStaticNewCstrSignature);\n"+ " (*env)->FatalError(env, clazzNameBuffersStaticNewCstrName);\n"+ @@ -2478,18 +2551,35 @@ " return JNI_TRUE;\n"+ "}\n"+ "\n"+ - "static jobject JVMUtil_NewDirectByteBufferCopy(JNIEnv *env, void * source_address, jlong capacity) {\n"+ + "#define JINT_MAX_VALUE ((size_t)0x7fffffffU)\n"+ + "static const char * sNewBufferImplNotCalled = \"initializeImpl() not called\";\n"+ + "static const char * sNewBufferMAX_INT = \"capacity > MAX_INT\";\n"+ + "static const char * sNewBufferNULL = \"New direct ByteBuffer is NULL\";\n"+ + "\n"+ + "static jobject JVMUtil_NewDirectByteBufferCopy(JNIEnv *env, void * source_address, size_t capacity) {\n"+ " jobject jbyteBuffer;\n"+ " void * byteBufferPtr;\n"+ "\n"+ " if( JNI_FALSE == _initClazzAccessDone ) {\n"+ - " fprintf(stderr, \"FatalError: initializeImpl() not called\\n\");\n"+ - " (*env)->FatalError(env, \"initializeImpl() not called\");\n"+ + " fprintf(stderr, \"%s %s\\n\", sFatalError, sNewBufferImplNotCalled);\n"+ + " (*env)->FatalError(env, sNewBufferImplNotCalled);\n"+ + " return NULL;\n"+ + " }\n"+ + " if( JINT_MAX_VALUE < capacity ) {\n"+ + " fprintf(stderr, \"%s %s: %lu\\n\", sFatalError, sNewBufferMAX_INT, (unsigned long)capacity);\n"+ + " (*env)->FatalError(env, sNewBufferMAX_INT);\n"+ + " return NULL;\n"+ + " }\n"+ + " jbyteBuffer = (*env)->CallStaticObjectMethod(env, clazzBuffers, cstrBuffersNew, (jint)capacity);\n"+ + " if( NULL == jbyteBuffer ) {\n"+ + " fprintf(stderr, \"%s %s: size %lu\\n\", sFatalError, sNewBufferNULL, (unsigned long)capacity);\n"+ + " (*env)->FatalError(env, sNewBufferNULL);\n"+ " return NULL;\n"+ " }\n"+ - " jbyteBuffer = (*env)->CallStaticObjectMethod(env, clazzBuffers, cstrBuffersNew, capacity);\n"+ - " byteBufferPtr = (*env)->GetDirectBufferAddress(env, jbyteBuffer);\n"+ - " memcpy(byteBufferPtr, source_address, capacity);\n"+ + " if( 0 < capacity ) {\n"+ + " byteBufferPtr = (*env)->GetDirectBufferAddress(env, jbyteBuffer);\n"+ + " memcpy(byteBufferPtr, source_address, capacity);\n"+ + " }\n"+ " return jbyteBuffer;\n"+ "}\n"+ "\n"; @@ -2555,36 +2645,46 @@ potentially representing C pointers rather than true Java types) and must be lowered to concrete Java types before creating emitters for them. */ - private MethodBinding bindFunction(final FunctionSymbol sym, - final JavaType containingType, - final Type containingCType, - final MachineDescription curMachDesc) { - - final MethodBinding binding = new MethodBinding(sym, containingType, containingCType); - - binding.renameMethodName(cfg.getJavaSymbolRename(sym.getName())); - - // System.out.println("bindFunction(0) "+sym.getReturnType()); + private MethodBinding bindFunction(FunctionSymbol sym, + final boolean forInterface, + final MachineDataInfo curMachDesc, + final JavaType containingType, final Type containingCType) { + + final String delegationImplName = null == containingType && null == containingCType ? + cfg.getDelegatedImplementation(sym) : null; + if( !forInterface && null != delegationImplName ) { + // We need to reflect the 'delegationImplName' for implementations + // to allow all subsequent type/cfg checks to hit on AliasedSymbol! + sym = FunctionSymbol.cloneWithDeepAliases(sym); + sym.addAliasedName(delegationImplName); + } + final String name = sym.getName(); + final JavaType javaReturnType; - if (cfg.returnsString(binding.getName())) { + if (cfg.returnsString(sym)) { final PointerType prt = sym.getReturnType().asPointer(); if (prt == null || prt.getTargetType().asInt() == null || prt.getTargetType().getSize(curMachDesc) != 1) { - throw new RuntimeException( + throw new GlueGenException( "Cannot apply ReturnsString configuration directive to \"" + sym + - "\". ReturnsString requires native method to have return type \"char *\""); + "\". ReturnsString requires native method to have return type \"char *\"", + sym.getASTLocusTag()); } - binding.setJavaReturnType(javaType(java.lang.String.class)); + javaReturnType = javaType(java.lang.String.class); } else { - binding.setJavaReturnType(typeToJavaType(sym.getReturnType(), curMachDesc)); + final JavaType r = cfg.getOpaqueReturnType(sym); + if( null != r ) { + javaReturnType = r; + } else { + javaReturnType = typeToJavaType(sym.getReturnType(), curMachDesc); + } } - // System.out.println("bindFunction(1) "+binding.getJavaReturnType()); - // List of the indices of the arguments in this function that should be // converted from byte[] or short[] to String - final List stringArgIndices = cfg.stringArguments(binding.getName()); + final List javaArgumentTypes = new ArrayList(); + final List stringArgIndices = cfg.stringArguments(name); for (int i = 0; i < sym.getNumArguments(); i++) { final Type cArgType = sym.getArgumentType(i); @@ -2612,20 +2712,21 @@ } } else { - throw new RuntimeException( + throw new GlueGenException( "Cannot apply ArgumentIsString configuration directive to " + "argument " + i + " of \"" + sym + "\": argument type is not " + - "a \"void*\", \"char *\", \"short *\", \"char**\", or \"short**\" equivalent"); + "a \"void*\", \"char *\", \"short *\", \"char**\", or \"short**\" equivalent", + sym.getASTLocusTag()); } } - binding.addJavaArgumentType(mappedType); + javaArgumentTypes.add(mappedType); //System.out.println("During binding of [" + sym + "], added mapping from C type: " + cArgType + " to Java type: " + mappedType); } - - // System.out.println("---> " + binding); - // System.out.println(" ---> " + binding.getCSymbol()); - // System.out.println("bindFunction(3) "+binding); - return binding; + final MethodBinding mb = new MethodBinding(sym, delegationImplName, + javaReturnType, javaArgumentTypes, + containingType, containingCType); + mangleBinding(mb); + return mb; } private MethodBinding lowerMethodBindingPointerTypes(final MethodBinding inputBinding, @@ -2685,7 +2786,7 @@ result = result.replaceJavaArgumentType(i, JavaType.forNIODoubleBufferClass()); } } else { - throw new RuntimeException("Unknown C pointer type " + t); + throw new GlueGenException("Unknown C pointer type " + t); } } } @@ -2710,7 +2811,7 @@ } else if (t.isCDoublePointerType()) { result = result.replaceJavaArgumentType(-1, JavaType.forNIODoubleBufferClass()); } else { - throw new RuntimeException("Unknown C pointer type " + t); + throw new GlueGenException("Unknown C pointer type " + t, result.getCReturnType().getASTLocusTag()); } } @@ -2723,6 +2824,14 @@ return result; } + /** + * Allow specializations to modify the given {@link MethodBinding} + * before {@link #expandMethodBinding(MethodBinding) expanding} and emission. + */ + protected void mangleBinding(final MethodBinding binding) { + // NOP + } + // Expands a MethodBinding containing C primitive pointer types into // multiple variants taking Java primitive arrays and NIO buffers, subject // to the per-function "NIO only" rule in the configuration file @@ -2754,10 +2863,11 @@ private Type canonicalize(final Type t) { final Type res = canonMap.get(t); if (res != null) { - return res; + return res; + } else { + canonMap.put(t, t); + return t; } - canonMap.put(t, t); - return t; } /** diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java 2015-10-09 04:18:28.000000000 +0000 @@ -40,14 +40,17 @@ package com.jogamp.gluegen; import com.jogamp.gluegen.cgram.HeaderParser; +import com.jogamp.gluegen.cgram.types.AliasedSymbol; import com.jogamp.gluegen.cgram.types.ArrayType; import com.jogamp.gluegen.cgram.types.EnumType; +import com.jogamp.gluegen.cgram.types.FunctionSymbol; import com.jogamp.gluegen.cgram.types.Type; import java.io.PrintWriter; import java.text.MessageFormat; import java.util.Iterator; import java.util.List; +import java.util.Set; /** * An emitter that emits only the interface for a Java<->C JNI binding. @@ -64,22 +67,22 @@ protected final CommentEmitter defaultJavaCommentEmitter = new DefaultCommentEmitter(); protected final CommentEmitter defaultInterfaceCommentEmitter = new InterfaceCommentEmitter(); + protected final boolean tagNativeBinding; + protected final boolean useNIODirectOnly; + protected final MethodBinding binding; // Exception type raised in the generated code if runtime checks fail private final String runtimeExceptionType; private final String unsupportedExceptionType; - - protected boolean emitBody; - protected boolean eraseBufferAndArrayTypes; - protected boolean useNIOOnly; - protected boolean useNIODirectOnly; - protected boolean forImplementingMethodCall; - protected boolean forDirectBufferImplementation; - protected boolean forIndirectBufferAndArrayImplementation; - protected boolean isUnimplemented; - protected boolean tagNativeBinding; - - protected MethodBinding binding; + private final boolean useNIOOnly; + private final boolean isNativeMethod; + private final boolean isUnimplemented; + + private boolean emitBody; + private boolean eraseBufferAndArrayTypes; + private boolean isPrivateNativeMethod; + private boolean forDirectBufferImplementation; + private boolean forIndirectBufferAndArrayImplementation; // Manually-specified prologue and epilogue code protected List prologue; @@ -97,9 +100,6 @@ // represent an array of compound type wrappers private static final String COMPOUND_ARRAY_SUFFIX = "_buf_array_copy"; - // Only present to provide more clear comments - private final JavaConfiguration cfg; - public JavaMethodBindingEmitter(final MethodBinding binding, final PrintWriter output, final String runtimeExceptionType, @@ -109,13 +109,13 @@ final boolean eraseBufferAndArrayTypes, final boolean useNIOOnly, final boolean useNIODirectOnly, - final boolean forImplementingMethodCall, final boolean forDirectBufferImplementation, final boolean forIndirectBufferAndArrayImplementation, final boolean isUnimplemented, final boolean isInterface, - final JavaConfiguration configuration) { - super(output, isInterface); + final boolean isNativeMethod, + final boolean isPrivateNativeMethod, final JavaConfiguration configuration) { + super(output, isInterface, configuration); this.binding = binding; this.runtimeExceptionType = runtimeExceptionType; this.unsupportedExceptionType = unsupportedExceptionType; @@ -124,16 +124,17 @@ this.eraseBufferAndArrayTypes = eraseBufferAndArrayTypes; this.useNIOOnly = useNIOOnly; this.useNIODirectOnly = useNIODirectOnly; - this.forImplementingMethodCall = forImplementingMethodCall; this.forDirectBufferImplementation = forDirectBufferImplementation; this.forIndirectBufferAndArrayImplementation = forIndirectBufferAndArrayImplementation; this.isUnimplemented = isUnimplemented; - if (forImplementingMethodCall) { + this.isNativeMethod = isNativeMethod; + this.isPrivateNativeMethod = isPrivateNativeMethod; + if (isPrivateNativeMethod) { setCommentEmitter(defaultJavaCommentEmitter); } else { setCommentEmitter(defaultInterfaceCommentEmitter); } - cfg = configuration; + // !forImplementingMethodCall && !isInterface } public JavaMethodBindingEmitter(final JavaMethodBindingEmitter arg) { @@ -146,7 +147,8 @@ eraseBufferAndArrayTypes = arg.eraseBufferAndArrayTypes; useNIOOnly = arg.useNIOOnly; useNIODirectOnly = arg.useNIODirectOnly; - forImplementingMethodCall = arg.forImplementingMethodCall; + isNativeMethod = arg.isNativeMethod; + isPrivateNativeMethod = arg.isPrivateNativeMethod; forDirectBufferImplementation = arg.forDirectBufferImplementation; forIndirectBufferAndArrayImplementation = arg.forIndirectBufferAndArrayImplementation; isUnimplemented = arg.isUnimplemented; @@ -154,18 +156,31 @@ epilogue = arg.epilogue; returnedArrayLengthExpression = arg.returnedArrayLengthExpression; returnedArrayLengthExpressionOnlyForComments = arg.returnedArrayLengthExpressionOnlyForComments; - cfg = arg.cfg; } public final MethodBinding getBinding() { return binding; } - public boolean isForImplementingMethodCall() { return forImplementingMethodCall; } + public boolean isNativeMethod() { return isNativeMethod; } + public boolean isPrivateNativeMethod() { return isPrivateNativeMethod; } public boolean isForDirectBufferImplementation() { return forDirectBufferImplementation; } public boolean isForIndirectBufferAndArrayImplementation() { return forIndirectBufferAndArrayImplementation; } @Override - public String getName() { - return binding.getName(); + public String getInterfaceName() { + return binding.getInterfaceName(); + } + @Override + public String getImplName() { + return binding.getImplName(); + } + @Override + public String getNativeName() { + return binding.getNativeName(); + } + + @Override + public FunctionSymbol getCSymbol() { + return binding.getCSymbol(); } protected String getArgumentName(final int i) { @@ -233,8 +248,8 @@ } /** Accessor for subclasses. */ - public void setForImplementingMethodCall(final boolean impl) { - this.forImplementingMethodCall = impl; + public void setPrivateNativeMethod(final boolean v) { + this.isPrivateNativeMethod = v; } /** Accessor for subclasses. */ @@ -322,10 +337,12 @@ @Override protected void emitName(final PrintWriter writer) { - if (forImplementingMethodCall) { - writer.print(getImplMethodName()); + if (isPrivateNativeMethod) { + writer.print(getNativeImplMethodName()); + } else if( isInterface()) { + writer.print(getInterfaceName()); } else { - writer.print(getName()); + writer.print(getImplName()); } } @@ -334,7 +351,7 @@ boolean needComma = false; int numEmitted = 0; - if (forImplementingMethodCall && binding.hasContainingType()) { + if (isPrivateNativeMethod && binding.hasContainingType()) { // Always emit outgoing "this" argument writer.print("ByteBuffer "); writer.print(javaThisArgumentName()); @@ -395,8 +412,8 @@ } - protected String getImplMethodName() { - return binding.getName() + ( useNIODirectOnly ? "0" : "1" ); + protected String getNativeImplMethodName() { + return binding.getImplName() + ( useNIODirectOnly ? "0" : "1" ); } protected String byteOffsetArgName(final int i) { @@ -544,7 +561,7 @@ } protected void emitCall(final MethodBinding binding, final PrintWriter writer) { - writer.print(getImplMethodName()); + writer.print(getNativeImplMethodName()); writer.print("("); emitCallArguments(binding, writer); writer.print(");"); @@ -675,9 +692,10 @@ } else if(type.isIntArray()) { writer.print(", Buffers.SIZEOF_INT * "); } else { - throw new RuntimeException("Unsupported type for calculating array offset argument for " + + throw new GlueGenException("Unsupported type for calculating array offset argument for " + getArgumentName(i) + - " -- error occurred while processing Java glue code for " + getName()); + " -- error occurred while processing Java glue code for " + getCSymbol().getAliasedString(), + getCSymbol().getASTLocusTag()); } writer.print(offsetArgName(i)); } @@ -688,7 +706,8 @@ } } else if (type.isPrimitiveArray()) { if (useNIOOnly) { - throw new RuntimeException("NIO[Direct]Only "+binding+" is set, but "+getArgumentName(i)+" is a primitive array"); + throw new GlueGenException("NIO[Direct]Only "+binding+" is set, but "+getArgumentName(i)+" is a primitive array", + getCSymbol().getASTLocusTag()); } writer.print( ", false"); } @@ -706,7 +725,7 @@ // ByteBuffers back into the wrapper types for (int i = 0; i < binding.getNumArguments(); i++) { final JavaType javaArgType = binding.getJavaArgumentType(i); - if ( javaArgType.isArrayOfCompoundTypeWrappers() && !isBaseTypeConst(javaArgType.getElementCType()) ) { + if ( javaArgType.isArrayOfCompoundTypeWrappers() && !javaArgType.getElementCType().isBaseTypeConst() ) { final String argName = binding.getArgumentName(i); writer.println(" for (int _ctr = 0; _ctr < " + argName + ".length; _ctr++) {"); writer.println(" if ((" + argName + "[_ctr] == null && " + argName + COMPOUND_ARRAY_SUFFIX + "[_ctr] == null) ||"); @@ -743,8 +762,9 @@ } else if (returnType.isNIOLongBuffer()) { writer.println(" return _res.asLongBuffer();"); } else { - throw new RuntimeException("While emitting glue code for " + getName() + - ": can not legally make pointers opaque to anything but PointerBuffer or LongBuffer/long"); + throw new GlueGenException("While emitting glue code for " + getCSymbol().getAliasedString() + + ": can not legally make pointers opaque to anything but PointerBuffer or LongBuffer/long", + getCSymbol().getASTLocusTag()); } } else if (getBinding().getCReturnType().pointerDepth() == 1 && returnType.isNIOLongBuffer()) { writer.println(" return _res.asLongBuffer();"); @@ -812,6 +832,26 @@ * emitter java method. */ protected class DefaultCommentEmitter implements CommentEmitter { + protected void emitAliasedDocNamesComment(final AliasedSymbol sym, final PrintWriter writer) { + writer.print(emitAliasedDocNamesComment(sym, new StringBuilder()).toString()); + } + protected StringBuilder emitAliasedDocNamesComment(final AliasedSymbol sym, final StringBuilder sb) { + final Set aliases = cfg.getAliasedDocNames(sym); + if (aliases != null && aliases.size() > 0 ) { + int i=0; + sb.append("Alias for: "); + for (final String alias : aliases) { + if(0 < i) { + sb.append(", "); + } + sb.append(alias); + i++; + } + sb.append(""); + } + return sb; + } + @Override public void emit(final FunctionEmitter emitter, final PrintWriter writer) { emitBeginning(emitter, writer); @@ -826,9 +866,11 @@ writer.print("Entry point to C language function: "); } protected void emitBindingCSignature(final MethodBinding binding, final PrintWriter writer) { - writer.print(" "); - writer.print(binding.getCSymbol().toString(tagNativeBinding)); - writer.print(" "); + final FunctionSymbol funcSym = binding.getCSymbol(); + writer.print(""); + writer.print(funcSym.toString(tagNativeBinding)); + writer.print("
    "); + emitAliasedDocNamesComment(funcSym, writer); } protected void emitEnding(final FunctionEmitter emitter, final PrintWriter writer) { // If argument type is a named enum, then emit a comment detailing the @@ -852,7 +894,7 @@ writer.print(" valid values are: "); for (int j = 0; j < enumType.getNumEnumerates(); ++j) { if (j>0) writer.print(", "); - writer.print(enumType.getEnumName(j)); + writer.print(enumType.getEnum(j).getName()); } writer.println(""); } else if (javaType.isNIOBuffer()) { diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/JavaType.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/JavaType.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/JavaType.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/JavaType.java 2015-10-09 04:18:28.000000000 +0000 @@ -63,6 +63,7 @@ private final String structName; // Types we're generating glue code for (i.e., C structs) private final Type elementType; // Element type if this JavaType represents a C array private final C_PTR primitivePointerType; + private final boolean opaqued; private static JavaType nioBufferType; private static JavaType nioByteBufferType; @@ -107,12 +108,20 @@ return elementType; } + /** Creates a JavaType corresponding to the given opaque Java type. This + can be used to represent arrays of primitive values or Strings; + the emitters understand how to perform proper conversion from + the corresponding C type. */ + public static JavaType createForOpaqueClass(final Class clazz) { + return new JavaType(clazz, true); + } + /** Creates a JavaType corresponding to the given Java type. This can be used to represent arrays of primitive values or Strings; the emitters understand how to perform proper conversion from the corresponding C type. */ public static JavaType createForClass(final Class clazz) { - return new JavaType(clazz); + return new JavaType(clazz, false); } /** Creates a JavaType corresponding to the specified C CompoundType @@ -336,6 +345,8 @@ return "jobject"; } + public boolean isOpaqued() { return opaqued; } + public boolean isNIOBuffer() { return clazz != null && ( java.nio.Buffer.class.isAssignableFrom(clazz) || com.jogamp.common.nio.NativeBuffer.class.isAssignableFrom(clazz)) ; @@ -528,34 +539,39 @@ append(sb, "primitivePointerType = "+primitivePointerType, prepComma); prepComma=true; } append(sb, "is[", prepComma); prepComma=false; - if( isArray() ) { - append(sb, "array", prepComma); prepComma=true; - } - if( isArrayOfCompoundTypeWrappers() ) { - append(sb, "compoundArray", prepComma); prepComma=true; - } - if( isCompoundTypeWrapper() ) { - append(sb, "compound", prepComma); prepComma=true; - } - if( isArray() ) { - append(sb, "array", prepComma); prepComma=true; - } - if( isPrimitive() ) { - append(sb, "primitive", prepComma); prepComma=true; - } - if( isPrimitiveArray() ) { - append(sb, "primitiveArray", prepComma); prepComma=true; - } - if( isNIOBuffer() ) { - append(sb, "nioBuffer", prepComma); prepComma=true; - } - if( isNIOBufferArray() ) { - append(sb, "nioBufferArray", prepComma); prepComma=true; - } - if( isCPrimitivePointerType() ) { - append(sb, "C-Primitive-Pointer", prepComma); prepComma=true; + { + if( isOpaqued() ) { + append(sb, "opaque", prepComma); prepComma=true; + } + if( isArray() ) { + append(sb, "array", prepComma); prepComma=true; + } + if( isArrayOfCompoundTypeWrappers() ) { + append(sb, "compoundArray", prepComma); prepComma=true; + } + if( isCompoundTypeWrapper() ) { + append(sb, "compound", prepComma); prepComma=true; + } + if( isArray() ) { + append(sb, "array", prepComma); prepComma=true; + } + if( isPrimitive() ) { + append(sb, "primitive", prepComma); prepComma=true; + } + if( isPrimitiveArray() ) { + append(sb, "primitiveArray", prepComma); prepComma=true; + } + if( isNIOBuffer() ) { + append(sb, "nioBuffer", prepComma); prepComma=true; + } + if( isNIOBufferArray() ) { + append(sb, "nioBufferArray", prepComma); prepComma=true; + } + if( isCPrimitivePointerType() ) { + append(sb, "C-Primitive-Pointer", prepComma); prepComma=true; + } } - append(sb, "descriptor '"+getDescriptor()+"'", prepComma); prepComma=true; + append(sb, "], descriptor '"+getDescriptor()+"']", prepComma); prepComma=true; return sb.toString(); } @@ -563,11 +579,12 @@ * Constructs a representation for a type corresponding to the given Class * argument. */ - private JavaType(final Class clazz) { + private JavaType(final Class clazz, final boolean opaqued) { this.primitivePointerType = null; this.clazz = clazz; this.structName = null; this.elementType = null; + this.opaqued = opaqued; } /** Constructs a type representing a named C struct. */ @@ -576,6 +593,7 @@ this.clazz = null; this.structName = structName; this.elementType = null; + this.opaqued = false; } /** Constructs a type representing a pointer to a C primitive @@ -585,6 +603,7 @@ this.clazz = null; this.structName = null; this.elementType = null; + this.opaqued = false; } /** Constructs a type representing an array of C pointers. */ @@ -593,6 +612,7 @@ this.clazz = null; this.structName = null; this.elementType = elementType; + this.opaqued = false; } /** clone only */ @@ -601,6 +621,7 @@ this.clazz = clazz; this.structName = name; this.elementType = elementType; + this.opaqued = false; } private String arrayName(Class clazz) { diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/Logging.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/Logging.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/Logging.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/Logging.java 2015-10-09 04:18:28.000000000 +0000 @@ -31,57 +31,352 @@ */ package com.jogamp.gluegen; +import java.util.HashMap; +import java.util.Map; import java.util.logging.ConsoleHandler; import java.util.logging.Formatter; +import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; +import jogamp.common.Debug; + import com.jogamp.common.util.PropertyAccess; +import com.jogamp.gluegen.cgram.types.AliasedSymbol; +import com.jogamp.gluegen.cgram.types.Type; /** * - * @author Michael Bien + * @author Michael Bien, et.al. */ public class Logging { + public static final boolean DEBUG = Debug.debug("Logging"); + + /** + * An interface for {@link Logger}. + */ + public static interface LoggerIf { + /** + * See {@link Logger#info(String)} + */ + void info(final String msg); + /** + * See {@link Logger#info(String)} + */ + void info(final ASTLocusTag loc, final String msg); + + /** + * See {@link Logger#warning(String)} + */ + void warning(final String msg); + /** + * See {@link Logger#warning(String)} + */ + void warning(final ASTLocusTag loc, final String msg); + + /** + * Calls {@link #log(Level, String)} w/ {@link Level#FINE}. + */ + void debug(final String msg); + /** + * Calls {@link #log(Level, ASTLocusTag, String)} w/ {@link Level#FINE}. + */ + void debug(final ASTLocusTag loc, final String msg); + + /** + * See {@link Logger#log(Level, String)} + */ + void log(final Level level, final String msg); + /** + * See {@link Logger#log(Level, String, Object)} + */ + void log(final Level level, final String msg, final Object param); + /** + * See {@link Logger#log(Level, String, Object[])} + */ + void log(final Level level, final String msg, final Object ... params); + + /** + * See {@link Logger#log(Level, String)} + */ + void log(final Level level, final ASTLocusTag loc, final String msg); + /** + * See {@link Logger#log(Level, String, Object)} + */ + void log(final Level level, final ASTLocusTag loc, final String msg, final Object param); + /** + * See {@link Logger#log(Level, String, Object[])} + */ + void log(final Level level, final ASTLocusTag loc, final String msg, final Object ... params); + + /** + * See {@link Logger#setLevel(Level)} + */ + void setLevel(final Level newLevel) throws SecurityException; + /** + * See {@link Handler#setLevel(Level)} + */ + void setLevelOfAllHandler(final Level newLevel) throws SecurityException; + /** + * See {@link Logger#getLevel()} + */ + Level getLevel(); + /** + * See {@link Logger#isLoggable(Level)} + */ + boolean isLoggable(Level level); + /** + * See {@link Logger#getName()} + */ + String getName(); + /** + * See {@link Logger#getHandlers()} + */ + Handler[] getHandlers(); + /** + * See {@link LogRecord#getSourceClassName()} + */ + String getSourceClassName(); + } + /* pp */ static class FQNLogger implements LoggerIf { + public final Logger impl; + public final PlainLogConsoleHandler handler; + /* pp */ FQNLogger(final String fqnClassName, final String simpleClassName, final Level level) { + this.impl = Logger.getLogger(fqnClassName); + this.handler = new PlainLogConsoleHandler(new PlainLogFormatter(simpleClassName), Level.ALL); + this.impl.setUseParentHandlers(false); + this.impl.setLevel(level); + this.impl.addHandler(this.handler); + this.impl.log(Level.INFO, "Logging.new: "+impl.getName()+": level "+level+ + ": obj 0x"+Integer.toHexString(impl.hashCode())); + } + @Override + public void info(final String msg) { + impl.info(msg); + } + @Override + public void info(final ASTLocusTag loc, final String msg) { + handler.plf.setASTLocusTag(loc); + try { + impl.info(msg); + } finally { + handler.plf.setASTLocusTag(null); + } + } + + @Override + public void warning(final String msg) { + impl.warning(msg); + } + @Override + public void warning(final ASTLocusTag loc, final String msg) { + handler.plf.setASTLocusTag(loc); + try { + impl.warning(msg); + } finally { + handler.plf.setASTLocusTag(null); + } + } + + @Override + public void debug(final String msg) { + log(Level.FINE, msg); + } + @Override + public void debug(final ASTLocusTag loc, final String msg) { + log(Level.FINE, loc, msg); + } + + @Override + public void log(final Level level, final String msg) { + impl.log(level, msg); + } + @Override + public void log(final Level level, final String msg, final Object param) { + impl.log(level, msg, param); + } + @Override + public void log(final Level level, final String msg, final Object ... params) { + impl.log(level, msg, params); + } + + @Override + public void log(final Level level, final ASTLocusTag loc, final String msg) { + handler.plf.setASTLocusTag(loc); + try { + impl.log(level, msg); + } finally { + handler.plf.setASTLocusTag(null); + } + } + @Override + public void log(final Level level, final ASTLocusTag loc, final String msg, final Object param) { + handler.plf.setASTLocusTag(loc); + try { + impl.log(level, msg, param); + } finally { + handler.plf.setASTLocusTag(null); + } + } + @Override + public void log(final Level level, final ASTLocusTag loc, final String msg, final Object ... params) { + handler.plf.setASTLocusTag(loc); + try { + impl.log(level, msg, params); + } finally { + handler.plf.setASTLocusTag(null); + } + } + + @Override + public void setLevel(final Level newLevel) throws SecurityException { + impl.setLevel(newLevel); + } + @Override + public void setLevelOfAllHandler(final Level newLevel) throws SecurityException { + final Handler[] hs = getHandlers(); + for(final Handler h:hs) { + h.setLevel(newLevel); + } + } + @Override + public Level getLevel() { + return impl.getLevel(); + } + @Override + public boolean isLoggable(final Level level) { + return impl.isLoggable(level); + } + @Override + public String getName() { + return impl.getName(); + } + @Override + public synchronized Handler[] getHandlers() { + return impl.getHandlers(); + } + @Override + public String getSourceClassName() { + return handler.plf.simpleClassName; + } + } + static class PlainLogConsoleHandler extends ConsoleHandler { + final PlainLogFormatter plf; + PlainLogConsoleHandler(final PlainLogFormatter plf, final Level level) { + this.plf = plf; + setFormatter(plf); + setLevel(level); + } + @Override + public java.util.logging.Formatter getFormatter() { + return plf; + } + } + static class PlainLogFormatter extends Formatter { + final String simpleClassName; + ASTLocusTag astLocus; + PlainLogFormatter(final String simpleClassName) { + this.simpleClassName = simpleClassName; + } + public void setASTLocusTag(final ASTLocusTag loc) { astLocus = loc; } + @Override + public String format(final LogRecord record) { + // Replace [Type, JavaType] -> its debug string! + final Object[] params = record.getParameters(); + if( null != params ) { + for(int i=params.length-1; 0<=i; i--) { + final Object o = params[i]; + if( o instanceof Type ) { + params[i] = ((Type)o).getDebugString(); + } else if( o instanceof JavaType ) { + params[i] = ((JavaType)o).getDebugString(); + } else if( o instanceof AliasedSymbol ) { + params[i] = ((AliasedSymbol)o).getAliasedString(); + } + } + } + final StringBuilder sb = new StringBuilder(256); + if( null != astLocus ) { + astLocus.toString(sb, getCanonicalName(record.getLevel()), GlueGen.debug()).append(": "); + } + if( GlueGen.debug() ) { + sb.append(simpleClassName).append(": "); + } + sb.append(formatMessage(record)).append("\n"); + return sb.toString(); + } + } - static void init() { + private final static Map loggers; + private final static FQNLogger rootPackageLogger; + static { + loggers = new HashMap(); final String packageName = Logging.class.getPackage().getName(); final String property = PropertyAccess.getProperty(packageName+".level", true); Level level; if(property != null) { level = Level.parse(property); } else { - level = Level.WARNING; + if( DEBUG || GlueGen.debug() ) { + level = Level.ALL; + } else { + level = Level.WARNING; + } } + final String simpleClassName = Logging.class.getSimpleName(); + final String fqnClassName = packageName+"."+simpleClassName; + rootPackageLogger = new FQNLogger(fqnClassName, simpleClassName, level); + loggers.put(fqnClassName, rootPackageLogger); + } - final ConsoleHandler handler = new ConsoleHandler() { - @Override - public java.util.logging.Formatter getFormatter() { - return new PlainLogFormatter(); - } - }; - handler.setFormatter(new PlainLogFormatter()); - handler.setLevel(level); - - final Logger rootPackageLogger = Logger.getLogger(packageName); - rootPackageLogger.setUseParentHandlers(false); - rootPackageLogger.setLevel(level); - rootPackageLogger.addHandler(handler); + /** provokes static initialization */ + static void init() { } + + public static String getCanonicalName(final Level level) { + if( Level.CONFIG == level ) { + return "config"; + } else if( Level.FINER == level ) { + return "verbose"; + } else if( Level.FINE == level ) { + return "debug"; + } else if( Level.INFO == level ) { + return "info"; + } else if( Level.WARNING == level ) { + return "warning"; + } else if( Level.SEVERE == level ) { + return "error"; + } else { + return level.getName().toLowerCase(); + } } - /** - * This log formatter needs usually one line per log record. - * @author Michael Bien - */ - private static class PlainLogFormatter extends Formatter { + /** Returns the root package logger. */ + public static LoggerIf getLogger() { + return rootPackageLogger; + } + /** Returns the demanded logger, while aligning its log-level to the root logger's level. */ + public static synchronized LoggerIf getLogger(final Class clazz) { + return getLogger(clazz.getPackage().getName(), clazz.getSimpleName()); + } - @Override - public String format(final LogRecord record) { - final StringBuilder sb = new StringBuilder(128); - sb.append("[").append(record.getLevel()).append(' ').append(record.getSourceClassName()).append("]: "); - sb.append(formatMessage(record)).append("\n"); - return sb.toString(); + /** Returns the demanded logger, while aligning its log-level to the root logger's level. */ + public static synchronized LoggerIf getLogger(final String packageName, final String simpleClassName) { + final String fqnClassName = packageName+"."+simpleClassName; + LoggerIf res = loggers.get(fqnClassName); + if( null == res ) { + res = new FQNLogger(fqnClassName, simpleClassName, rootPackageLogger.getLevel()); + loggers.put(fqnClassName, res); } + return res; + } + /** Align log-level of given logger to the root logger's level. */ + public static void alignLevel(final LoggerIf l) { + alignLevel(l, rootPackageLogger.getLevel()); + } + /** Align log-level of given logger and all its handlers to the given level. */ + public static void alignLevel(final LoggerIf l, final Level level) { + l.setLevel(level); + l.setLevelOfAllHandler(level); } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/MethodBinding.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/MethodBinding.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/MethodBinding.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/MethodBinding.java 2015-10-09 04:18:28.000000000 +0000 @@ -43,8 +43,6 @@ import com.jogamp.gluegen.cgram.types.Type; import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; import java.util.List; /** Represents the binding of a C function to a Java method. Also used @@ -54,8 +52,10 @@ public class MethodBinding { private final FunctionSymbol sym; - private String renamedMethodName; - private final HashSet aliasedNames; + private final String delegationImplName; + private final JavaType containingType; + private final Type containingCType; + private String nativeName; private JavaType javaReturnType; private List javaArgumentTypes; private boolean computedSignatureProperties; @@ -69,8 +69,6 @@ private boolean signatureUsesCArrays; private boolean signatureUsesJavaPrimitiveArrays; private boolean signatureRequiresStaticInitialization; - private JavaType containingType; - private Type containingCType; private int thisPointerIndex = -1; /** @@ -79,12 +77,12 @@ * types. It's safe to modify this binding after construction. */ public MethodBinding(final MethodBinding bindingToCopy) { - this.sym = bindingToCopy.sym; - - this.renamedMethodName = bindingToCopy.renamedMethodName; - this.aliasedNames = new HashSet(bindingToCopy.aliasedNames); + this.sym = bindingToCopy.sym; + this.delegationImplName = bindingToCopy.delegationImplName; this.containingType = bindingToCopy.containingType; this.containingCType = bindingToCopy.containingCType; + + this.nativeName = bindingToCopy.nativeName; this.javaReturnType = bindingToCopy.javaReturnType; this.javaArgumentTypes = ( null != bindingToCopy.javaArgumentTypes ) ? new ArrayList(bindingToCopy.javaArgumentTypes) : null; this.computedSignatureProperties = bindingToCopy.computedSignatureProperties; @@ -101,19 +99,27 @@ this.thisPointerIndex = bindingToCopy.thisPointerIndex; } - /** Constructor for calling a C function. */ - public MethodBinding(final FunctionSymbol sym) { - this.sym = sym; - this.aliasedNames = new HashSet(); - } - - /** Constructor for calling a function pointer contained in a - struct. */ - public MethodBinding(final FunctionSymbol sym, final JavaType containingType, final Type containingCType) { + /** + * Constructor for calling a C function or a function pointer contained in a struct. + *

    + * In case of the latter, a struct function pointer, + * the arguments {@code containingType} and {@code containingCType} must not be {@code null}! + *

    + */ + public MethodBinding(final FunctionSymbol sym, + final String delegationImplName, + final JavaType javaReturnType, + final List javaArgumentTypes, + final JavaType containingType, + final Type containingCType) { this.sym = sym; + this.delegationImplName = delegationImplName; this.containingType = containingType; this.containingCType = containingCType; - this.aliasedNames = new HashSet(); + + this.nativeName = null; + this.javaReturnType = javaReturnType; + this.javaArgumentTypes = javaArgumentTypes; } public void setJavaReturnType(final JavaType type) { @@ -149,6 +155,7 @@ return sym.getArgumentType(i); } + /** Returns the {@link FunctionSymbol}. */ public FunctionSymbol getCSymbol() { return sym; } @@ -166,33 +173,42 @@ return "arg" + i; } - public String getOrigName() { - return sym.getName(); - } - + /** Returns the {@link FunctionSymbol}'s current {@link FunctionSymbol#getName() aliased} API name. */ public String getName() { - // Defaults to same as C symbol unless renamed - if (renamedMethodName != null) { - return renamedMethodName; - } return sym.getName(); } - - /** Supports renaming C function in Java binding. */ - public void renameMethodName(final String name) { - if (null != name) { - renamedMethodName = name; - aliasedNames.add(sym.getName()); - } + /** + * The + * {@link JavaConfiguration#getDelegatedImplementation(com.jogamp.gluegen.cgram.types.AliasedSymbol) implementation delegation} + * name, or {@code null} for no delegation. + * @see #getImplName() + */ + public String getDelegationImplName() { + return delegationImplName; } - public void addAliasedName(final String name) { - aliasedNames.add(name); + /** Returns the {@link FunctionSymbol}'s current {@link FunctionSymbol#getName() aliased} API name for the interface. */ + public String getInterfaceName() { + return sym.getName(); } - - public Collection getAliasedNames() { - return aliasedNames; + /** + * Returns the {@link FunctionSymbol}'s name for the implementation, + * which is the current {@link FunctionSymbol#getName() aliased} API name per default, + * or the {@link #getDelegationImplName() delegation} name. + * @see #getDelegationImplName() + */ + public String getImplName() { + return null != delegationImplName ? delegationImplName : sym.getName(); + } + /** + * Returns the {@link FunctionSymbol}'s name for the native function + * which is the {@link FunctionSymbol#getOrigName() original} C API name per default, + * but may be overridden via {@link #setNativeName(String)}. + */ + public String getNativeName() { + return null != nativeName ? nativeName : sym.getOrigName(); } + public void setNativeName(final String s) { nativeName = s; } /** Creates a new MethodBinding replacing the specified Java argument type with a new argument type. If argumentNumber is diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/package.html gluegen2-2.3.2/src/java/com/jogamp/gluegen/package.html --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/package.html 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/package.html 2015-10-09 04:18:28.000000000 +0000 @@ -60,13 +60,23 @@
    Simple alignment arithmetic
    -
    remainder = offset % alignment
    - since alignment is a multiple of 2 -> x % 2n == x & (2n - 1)
    -
    remainder = offset & ( alignment - 1 )
    + Modulo operation, where the 2nd handles the case offset == alignment:
    - padding = (remainder > 0) ? alignment - remainder : 0 ;
    + padding = ( alignment - ( offset % alignment ) ) % alignment ;
    + aligned_offset = offset + padding ; +
    + Optimization utilizing alignment as a multiple of 2 -> x % 2n == x & ( 2n - 1 )
    +
    + remainder = offset & ( alignment - 1 ) ;
    + padding = ( remainder > 0 ) ? alignment - remainder : 0 ;
    + aligned_offset = offset + padding ; +
    + Without branching, using the 2nd modulo operation for the case offset == alignment: +
    + padding = ( alignment - ( offset & ( alignment - 1 ) ) ) & ( alignment - 1 ) ;
    aligned_offset = offset + padding ;
    + See com.jogamp.gluegen.cgram.types.SizeThunk.align(..).
    Type Size & Alignment for x86, x86_64, armv6l-32bit-eabi and Window(mingw/mingw64)
    Runtime query is implemented as follows: diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/pcpp/PCPP.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/pcpp/PCPP.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/pcpp/PCPP.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/pcpp/PCPP.java 2015-10-09 04:18:28.000000000 +0000 @@ -56,16 +56,24 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.logging.Logger; +import java.util.logging.Level; + +import com.jogamp.gluegen.ASTLocusTag; +import com.jogamp.gluegen.ConstantDefinition; +import com.jogamp.gluegen.GenericCPP; +import com.jogamp.gluegen.GlueGenException; +import com.jogamp.gluegen.Logging; +import com.jogamp.gluegen.Logging.LoggerIf; + import static java.util.logging.Level.*; /** A minimal pseudo-C-preprocessor designed in particular to preserve #define statements defining constants so they can be observed by a glue code generator. */ -public class PCPP { +public class PCPP implements GenericCPP { - private static final Logger LOG = Logger.getLogger(PCPP.class.getPackage().getName()); + private final LoggerIf LOG; /** Map containing the results of #define statements. We must evaluate certain very simple definitions (to properly handle @@ -86,13 +94,15 @@ private final boolean enableCopyOutput2Stderr; public PCPP(final List includePaths, final boolean debug, final boolean copyOutput2Stderr) { + LOG = Logging.getLogger(PCPP.class.getPackage().getName(), PCPP.class.getSimpleName()); this.includePaths = includePaths; setOut(System.out); enableDebugPrint = debug; enableCopyOutput2Stderr = copyOutput2Stderr; } - public void run(final Reader reader, final String filename) throws IOException { + @Override + public void run(final Reader reader, final String filename) throws GlueGenException { StreamTokenizer tok = null; BufferedReader bufReader = null; if (reader instanceof BufferedReader) { @@ -108,13 +118,29 @@ final ParseState oldState = state; state = curState; lineDirective(); - parse(); + try { + parse(); + } catch (final Exception e) { + final StringBuilder buf = new StringBuilder("Preprocessor failed"); + LOG.log(Level.SEVERE, buf.toString(), e); + if( e instanceof GlueGenException ) { + throw (GlueGenException)e; + } else { + throw new GlueGenException("Preprocessor failed", + new ASTLocusTag(filename(), lineNumber(), -1, null), e); + } + } state = oldState; if (state != null) { lineDirective(); } } + @Override + public List getConstantDefinitions() throws GlueGenException { + return new ArrayList(); // NOP + } + private void initTokenizer(final StreamTokenizer tok) { tok.resetSyntax(); tok.wordChars('a', 'z'); @@ -131,6 +157,7 @@ tok.slashStarComments(true); } + @Override public String findFile(final String filename) { final String sep = File.separator; for (final String inclPath : includePaths) { @@ -143,10 +170,12 @@ return null; } + @Override public OutputStream out() { return out; } + @Override public void setOut(final OutputStream out) { this.out = out; writer = new PrintWriter(out); @@ -375,7 +404,7 @@ } } - if(isIdentifier(value)) { + if(ConstantDefinition.isIdentifier(value)) { newS +=" "; } @@ -459,28 +488,30 @@ if (enabled()) { final String oldDef = defineMap.remove(name); if (oldDef == null) { - LOG.log(WARNING, "ignoring redundant \"#undef {0}\", at \"{1}\" line {2}: \"{3}\" was not previously defined", - new Object[]{name, filename(), lineNumber(), name}); + LOG.log(WARNING, new ASTLocusTag(filename(), lineNumber(), -1, name), + "ignoring redundant \"#undef {0}\" - was not previously defined", + name); } else { // System.err.println("UNDEFINED: '" + name + "' (line " + lineNumber() + " file " + filename() + ")"); } nonConstantDefines.remove(name); } else { - LOG.log(WARNING, "FAILED TO UNDEFINE: ''{0}'' (line {1} file {2})", new Object[]{name, lineNumber(), filename()}); + LOG.log(INFO, new ASTLocusTag(filename(), lineNumber(), -1, name), + "DISABLED UNDEFINE: ''{0}''", name); } } private void handleWarning() throws IOException { final String msg = nextWordOrString(); if (enabled()) { - LOG.log(WARNING, "#warning {0} at \"{1}\" line \"{2}\"", new Object[]{msg, filename(), lineNumber()}); + LOG.log(WARNING, new ASTLocusTag(filename(), lineNumber(), -1, null), msg); } } - private void handleError() throws IOException { + private void handleError() throws IOException, GlueGenException { final String msg = nextWordOrString(); if (enabled()) { - throw new RuntimeException("#error "+msg+" at \""+filename()+"\" line "+lineNumber()); + throw new GlueGenException(msg, new ASTLocusTag(filename(), lineNumber(), -1, null)); } } @@ -520,6 +551,7 @@ addDefine(name, macroDefinition, values); } + @Override public void addDefine(final String name, final String value) { final List values = new ArrayList(); values.add(value); @@ -541,7 +573,8 @@ final String value = ""; final String oldDef = defineMap.put(name, value); if (oldDef != null && !oldDef.equals(value)) { - LOG.log(WARNING, "\"{0}\" redefined from \"{1}\" to \"\"", new Object[]{name, oldDef}); + LOG.log(WARNING, new ASTLocusTag(filename(), lineNumber(), -1, null), + "\"{0}\" redefined from \"{1}\" to \"\"", name, oldDef); } // We don't want to emit the define, because it would serve no purpose // and cause GlueGen errors (confuse the GnuCParser) @@ -551,12 +584,13 @@ // See whether the value is a constant final String value = values.get(0); - if (isConstant(value)) { + if (ConstantDefinition.isNumber(value)) { // Value is numeric constant like "#define FOO 5". // Put it in the #define map final String oldDef = defineMap.put(name, value); if (oldDef != null && !oldDef.equals(value)) { - LOG.log(WARNING, "\"{0}\" redefined from \"{1}\" to \"{2}\"", new Object[]{name, oldDef, value}); + LOG.log(WARNING, new ASTLocusTag(filename(), lineNumber(), -1, null), + "\"{0}\" redefined from \"{1}\" to \"{2}\"", name, oldDef, value); } debugPrint(true, "DEFINE " + name + " ["+oldDef+" ] -> "+value + " CONST"); //System.err.println("//---DEFINED: " + name + " to \"" + value + "\""); @@ -606,7 +640,8 @@ final Macro macro = new Macro(params, values); final Macro oldDef = macroMap.put(name, macro); if (oldDef != null) { - LOG.log(WARNING, "\"{0}\" redefined from \"{1}\" to \"{2}\"", new Object[]{name, oldDef, macro}); + LOG.log(WARNING, new ASTLocusTag(filename(), lineNumber(), -1, null), + "\"{0}\" redefined from \"{1}\" to \"{2}\"", name, oldDef, macro); } emitDefine = false; @@ -618,7 +653,7 @@ boolean containsIdentifier = false; for (final String value : values) { - if(isIdentifier(value)) { + if(ConstantDefinition.isIdentifier(value)) { containsIdentifier = true; break; } @@ -657,7 +692,8 @@ final String oldDef = defineMap.put(name, value); if (oldDef != null && !oldDef.equals(value)) { - LOG.log(WARNING, "\"{0}\" redefined from \"{1}\" to \"{2}\"", new Object[]{name, oldDef, value}); + LOG.log(WARNING, new ASTLocusTag(filename(), lineNumber(), -1, null), + "\"{0}\" redefined from \"{1}\" to \"{2}\"", name, oldDef, value); } debugPrint(true, "DEFINE " + name + " ["+oldDef+" ] -> "+value + " CONST"); // System.err.println("#define " + name +" "+value + " CONST EXPRESSION"); @@ -681,68 +717,6 @@ //System.err.println("OUT HANDLE_DEFINE: " + name); } - private boolean isIdentifier(final String value) { - - boolean identifier = false; - - final char[] chars = value.toCharArray(); - - for (int i = 0; i < chars.length; i++) { - final char c = chars[i]; - if (i == 0) { - if (Character.isJavaIdentifierStart(c)) { - identifier = true; - } - } else { - if (!Character.isJavaIdentifierPart(c)) { - identifier = false; - break; - } - } - } - return identifier; - } - - private boolean isConstant(final String s) { - if (s.startsWith("0x") || s.startsWith("0X")) { - return checkHex(s); - } else { - return checkDecimal(s); - } - } - - private boolean checkHex(final String s) { - char c='\0'; - int i; - for (i = 2; i < s.length(); i++) { - c = s.charAt(i); - if (!((c >= '0' && c <= '9') || - (c >= 'a' && c <= 'f') || - (c >= 'A' && c <= 'F'))) { - break; - } - } - if(i==s.length()) { - return true; - } else if(i==s.length()-1) { - // Const qualifier .. - return c == 'l' || c == 'L' || - c == 'f' || c == 'F' || - c == 'u' || c == 'U' ; - } - return false; - } - - private boolean checkDecimal(final String s) { - try { - Float.valueOf(s); - } catch (final NumberFormatException e) { - // not parsable as a number - return false; - } - return true; - } - private String resolveDefine(final String word, final boolean returnNullIfNotFound) { String lastWord = defineMap.get(word); if (lastWord == null) { @@ -920,6 +894,27 @@ ifValue = false; } break; + case '*': + { + // NOTE: we don't handle expressions like this properly + final boolean rhs = handleIfRecursive(false); + ifValue = false; + } + break; + case '+': + { + // NOTE: we don't handle expressions like this properly + final boolean rhs = handleIfRecursive(false); + ifValue = false; + } + break; + case '-': + { + // NOTE: we don't handle expressions like this properly + final boolean rhs = handleIfRecursive(false); + ifValue = false; + } + break; case '=': { // NOTE: we don't handle expressions like this properly @@ -1008,7 +1003,8 @@ buf.append(curTokenAsString()); } if (t == StreamTokenizer.TT_EOF) { - LOG.warning("unexpected EOF while processing #include directive"); + LOG.warning(new ASTLocusTag(filename(), lineNumber(), -1, null), + "unexpected EOF while processing #include directive"); } filename = buf.toString(); } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java 2015-10-09 04:18:28.000000000 +0000 @@ -42,30 +42,35 @@ import com.jogamp.gluegen.CMethodBindingEmitter; import com.jogamp.gluegen.MethodBinding; import com.jogamp.gluegen.JavaType; + import java.io.*; + import com.jogamp.gluegen.cgram.types.*; public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { private boolean callThroughProcAddress; - private boolean needsLocalTypedef; + private boolean hasProcAddrTypedef; private String localTypedefCallingConvention; private static final String procAddressJavaTypeName = JavaType.createForClass(Long.TYPE).jniTypeName(); private ProcAddressEmitter emitter; - public ProcAddressCMethodBindingEmitter(final CMethodBindingEmitter methodToWrap, final boolean callThroughProcAddress, - final boolean needsLocalTypedef, final String localTypedefCallingConvention, final ProcAddressEmitter emitter) { + public ProcAddressCMethodBindingEmitter(final CMethodBindingEmitter methodToWrap, + final boolean callThroughProcAddress, + final boolean hasProcAddrTypedef, + final String localTypedefCallingConvention, + final ProcAddressEmitter emitter) { super( new MethodBinding(methodToWrap.getBinding()) { @Override - public String getName() { + public String getImplName() { if (callThroughProcAddress) { - return ProcAddressEmitter.WRAP_PREFIX + super.getName(); + return ProcAddressEmitter.WRAP_PREFIX + super.getImplName(); } else { - return super.getName(); + return super.getImplName(); } } }, @@ -76,9 +81,9 @@ methodToWrap.getIsJavaMethodStatic(), true, methodToWrap.forIndirectBufferAndArrayImplementation(), - methodToWrap.getMachineDescription() + methodToWrap.getMachineDataInfo(), + emitter.getConfiguration() ); - if (methodToWrap.getReturnValueCapacityExpression() != null) { setReturnValueCapacityExpression(methodToWrap.getReturnValueCapacityExpression()); } @@ -91,7 +96,7 @@ setCommentEmitter(defaultCommentEmitter); this.callThroughProcAddress = callThroughProcAddress; - this.needsLocalTypedef = needsLocalTypedef; + this.hasProcAddrTypedef = hasProcAddrTypedef; this.localTypedefCallingConvention = localTypedefCallingConvention; this.emitter = emitter; } @@ -116,28 +121,31 @@ if (callThroughProcAddress) { // create variable for the function pointer with the right type, and set // it to the value of the passed-in proc address - final FunctionSymbol cSym = getBinding().getCSymbol(); - String funcPointerTypedefName = - emitter.getFunctionPointerTypedefName(cSym); - - if (needsLocalTypedef) { - // We (probably) didn't get a typedef for this function - // pointer type in the header file; the user requested that we - // forcibly generate one. Here we force the emission of one. - final PointerType funcPtrType = new PointerType(null, cSym.getType(), 0); - // Just for safety, emit this name slightly differently than - // the mangling would otherwise produce - funcPointerTypedefName = "_local_" + funcPointerTypedefName; - - writer.print(" typedef "); - writer.print(funcPtrType.toString(funcPointerTypedefName, localTypedefCallingConvention)); - writer.println(";"); + final FunctionSymbol cSym = binding.getCSymbol(); + + // Always emit the local typedef, based on our parsing results. + // In case we do have the public typedef from the original header, + // we use it for the local var and assign our proc-handle to it, + // cast to the local typedef. + // This allows the native C compiler to validate our types! + final String funcPointerTypedefBaseName = emitter.getFunctionPointerTypedefName(cSym); + final String funcPointerTypedefLocalName = "_local_" + funcPointerTypedefBaseName; + final String funcPointerTypedefName; + if (hasProcAddrTypedef) { + funcPointerTypedefName = funcPointerTypedefBaseName; + } else { + funcPointerTypedefName = funcPointerTypedefLocalName; } + final PointerType funcPtrType = new PointerType(null, cSym.getType(), 0); + + writer.print(" typedef "); + writer.print(funcPtrType.toString(funcPointerTypedefLocalName, localTypedefCallingConvention)); + writer.println(";"); writer.print(" "); - writer.print(funcPointerTypedefName); + writer.print(funcPointerTypedefName); // Uses public typedef if available! writer.print(" ptr_"); - writer.print(cSym.getName()); + writer.print(getNativeName()); writer.println(";"); } @@ -150,18 +158,25 @@ if (callThroughProcAddress) { // set the function pointer to the value of the passed-in procAddress - final FunctionSymbol cSym = getBinding().getCSymbol(); - String funcPointerTypedefName = emitter.getFunctionPointerTypedefName(cSym); - if (needsLocalTypedef) { - funcPointerTypedefName = "_local_" + funcPointerTypedefName; + // See above notes in emitBodyVariableDeclarations(..)! + final String funcPointerTypedefBaseName = emitter.getFunctionPointerTypedefName(binding.getCSymbol()); + final String funcPointerTypedefLocalName = "_local_" + funcPointerTypedefBaseName; + final String funcPointerTypedefName; + if (hasProcAddrTypedef) { + funcPointerTypedefName = funcPointerTypedefBaseName; + } else { + funcPointerTypedefName = funcPointerTypedefLocalName; } - final String ptrVarName = "ptr_" + cSym.getName(); + final String ptrVarName = "ptr_" + getNativeName(); + if (hasProcAddrTypedef) { + writer.println(" // implicit type validation of "+funcPointerTypedefLocalName+" -> "+funcPointerTypedefName); + } writer.print(" "); writer.print(ptrVarName); writer.print(" = ("); - writer.print(funcPointerTypedefName); + writer.print(funcPointerTypedefLocalName); writer.println(") (intptr_t) procAddress;"); writer.println(" assert(" + ptrVarName + " != NULL);"); @@ -181,7 +196,12 @@ final Type cReturnType = binding.getCReturnType(); if (!cReturnType.isVoid()) { - writer.print("_res = "); + // Note we respect const/volatile in the function return type. + // However, we cannot have it 'const' for our local variable. + // See return type in CMethodBindingEmitter.emitBodyVariableDeclarations(..)! + writer.print("_res = ("); + writer.print(cReturnType.getCName(false)); + writer.print(") "); } final MethodBinding mBinding = getBinding(); if (mBinding.hasContainingType()) { @@ -192,7 +212,7 @@ // call throught the run-time function pointer writer.print("(* ptr_"); - writer.print(mBinding.getCSymbol().getName()); + writer.print(getNativeName()); writer.print(") "); writer.print("("); emitBodyPassCArguments(writer); diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/procaddress/ProcAddressConfiguration.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/procaddress/ProcAddressConfiguration.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/procaddress/ProcAddressConfiguration.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/procaddress/ProcAddressConfiguration.java 2015-10-09 04:18:28.000000000 +0000 @@ -38,7 +38,12 @@ */ package com.jogamp.gluegen.procaddress; +import static java.util.logging.Level.INFO; + import com.jogamp.gluegen.JavaConfiguration; +import com.jogamp.gluegen.cgram.types.AliasedSymbol; +import com.jogamp.gluegen.cgram.types.FunctionSymbol; + import java.io.*; import java.text.*; import java.util.*; @@ -82,7 +87,7 @@ addForceProcAddressGen(funcName); } } else if (cmd.equalsIgnoreCase("GetProcAddressTableExpr")) { - getProcAddressTableExpr = readGetProcAddressTableExpr(tok, filename, lineNo); + setProcAddressTableExpr( readGetProcAddressTableExpr(tok, filename, lineNo) ); } else if (cmd.equalsIgnoreCase("ProcAddressNameExpr")) { readProcAddressNameExpr(tok, filename, lineNo); } else if (cmd.equalsIgnoreCase("LocalProcAddressCallingConvention")) { @@ -269,8 +274,15 @@ return tableClassName; } - public boolean skipProcAddressGen(final String name) { - return skipProcAddressGen.contains(name); + public boolean skipProcAddressGen(final FunctionSymbol symbol) { + if ( skipProcAddressGen.contains( symbol.getName() ) || + oneInSet(skipProcAddressGen, symbol.getAliasedNames()) + ) + { + LOG.log(INFO, symbol.getASTLocusTag(), "Skip ProcAddress: {0}", symbol); + return true; + } + return false; } public boolean isForceProcAddressGen4All() { @@ -287,6 +299,9 @@ } return getProcAddressTableExpr; } + protected void setProcAddressTableExpr(final String s) { + getProcAddressTableExpr = s; + } public String convertToFunctionPointerName(final String funcName) { if (procAddressNameConverter == null) { @@ -295,9 +310,25 @@ return procAddressNameConverter.convert(funcName); } - public boolean forceProcAddressGen(final String funcName) { - return forceProcAddressGen4All || forceProcAddressGenSet.contains(funcName); + public boolean forceProcAddressGen(final FunctionSymbol symbol) { + if( forceProcAddressGen4All ) { + if(!forceProcAddressGen4AllOnce) { + forceProcAddressGen4AllOnce = true; + LOG.log(INFO, symbol.getASTLocusTag(), "Force ALL ProcAddress"); + } + return true; + } + + if ( forceProcAddressGenSet.contains( symbol.getName() ) || + oneInSet(forceProcAddressGenSet, symbol.getAliasedNames()) + ) + { + LOG.log(INFO, symbol.getASTLocusTag(), "Force ProcAddress: {0}", symbol); + return true; + } + return false; } + private static boolean forceProcAddressGen4AllOnce = false; public void addForceProcAddressGen(final String funcName) { forceProcAddressGen.add(funcName); @@ -308,11 +339,15 @@ localProcAddressCallingConventionMap.put(funcName, callingConvention); } - public String getLocalProcAddressCallingConvention(final String funcName) { - if (isLocalProcAddressCallingConvention4All()) { + public String getLocalProcAddressCallingConvention(final FunctionSymbol symbol) { + if ( isLocalProcAddressCallingConvention4All() ) { return getLocalProcAddressCallingConvention4All(); } - return localProcAddressCallingConventionMap.get(funcName); + final String res = localProcAddressCallingConventionMap.get(symbol.getName()); + if( null != res ) { + return res; + } + return oneInMap(localProcAddressCallingConventionMap, symbol.getAliasedNames()); } public boolean isLocalProcAddressCallingConvention4All() { diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/procaddress/ProcAddressEmitter.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/procaddress/ProcAddressEmitter.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/procaddress/ProcAddressEmitter.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/procaddress/ProcAddressEmitter.java 2015-10-09 04:18:28.000000000 +0000 @@ -47,6 +47,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.logging.Level; import com.jogamp.gluegen.CMethodBindingEmitter; import com.jogamp.gluegen.CodeGenUtils; @@ -54,7 +55,6 @@ import com.jogamp.gluegen.JavaConfiguration; import com.jogamp.gluegen.JavaEmitter; import com.jogamp.gluegen.JavaMethodBindingEmitter; -import com.jogamp.gluegen.MethodBinding; import com.jogamp.gluegen.cgram.types.FunctionSymbol; import com.jogamp.gluegen.cgram.types.Type; import com.jogamp.gluegen.cgram.types.TypeDictionary; @@ -114,40 +114,45 @@ } @Override - protected List generateMethodBindingEmitters(final Set methodBindingSet, final FunctionSymbol sym) throws Exception { - return generateMethodBindingEmittersImpl(methodBindingSet, sym); + protected List generateMethodBindingEmitters(final FunctionSymbol sym) throws Exception { + return generateMethodBindingEmittersImpl(sym); } protected boolean needsModifiedEmitters(final FunctionSymbol sym) { - if (!needsProcAddressWrapper(sym) || getConfig().isUnimplemented(getAliasedSymName(sym))) { + if ( !callThroughProcAddress(sym) || getConfig().isUnimplemented(sym) ) { return false; + } else { + return true; } - - return true; } - private List generateMethodBindingEmittersImpl(final Set methodBindingSet, final FunctionSymbol sym) throws Exception { - final List defaultEmitters = super.generateMethodBindingEmitters(methodBindingSet, sym); + private List generateMethodBindingEmittersImpl(final FunctionSymbol sym) throws Exception { + final List defaultEmitters = super.generateMethodBindingEmitters(sym); // if the superclass didn't generate any bindings for the symbol, let's // honor that (for example, the superclass might have caught an Ignore // direction that matched the symbol's name). if (defaultEmitters.isEmpty()) { + LOG.log(Level.INFO, sym.getASTLocusTag(), "genModProcAddrEmitter: SKIP, empty binding set: {0}", sym); return defaultEmitters; } - // Don't do anything special if this symbol doesn't require - // modifications - if (!needsModifiedEmitters(sym)) { + final boolean callThroughProcAddress = callThroughProcAddress(sym); + final boolean isUnimplemented = getConfig().isUnimplemented(sym); + + // Don't do anything special if this symbol doesn't require modifications + if( !callThroughProcAddress || isUnimplemented ) { + LOG.log(Level.INFO, sym.getASTLocusTag(), "genModProcAddrEmitter: SKIP, not needed: callThrough {0}, isUnimplemented {1}: {2}", + callThroughProcAddress, isUnimplemented, sym); return defaultEmitters; } final ArrayList modifiedEmitters = new ArrayList(defaultEmitters.size()); - if (needsProcAddressWrapper(sym)) { + if ( callThroughProcAddress ) { if (getProcAddressConfig().emitProcAddressTable()) { // emit an entry in the GL proc address table for this method. - emitProcAddressTableEntryForString(getAliasedSymName(sym)); + emitProcAddressTableEntryForString(sym.getName()); } } for (final FunctionEmitter emitter : defaultEmitters) { @@ -172,7 +177,7 @@ * whether or not the typedef is actually defined. */ protected String getFunctionPointerTypedefName(final FunctionSymbol sym) { - return getProcAddressConfig().convertToFunctionPointerName(sym.getName()); + return getProcAddressConfig().convertToFunctionPointerName(sym.getOrigName()); } //---------------------------------------------------------------------- @@ -194,20 +199,14 @@ protected void generateModifiedEmitters(final JavaMethodBindingEmitter baseJavaEmitter, final List emitters) { // See whether we need a proc address entry for this one - final boolean callThroughProcAddress = needsProcAddressWrapper(baseJavaEmitter.getBinding().getCSymbol()); + final boolean callThroughProcAddress = callThroughProcAddress(baseJavaEmitter.getBinding().getCSymbol()); // If this emitter doesn't have a body (i.e., is a direct native // call with no intervening argument processing), we need to force - // it to emit a body, and produce another one to act as the entry - // point - // FIXME: the negative test against the PRIVATE modifier is a - // nasty hack to prevent the ProcAddressJavaMethodBindingEmitter - // from incorrectly introducing method bodies to the private - // native implementing methods; want this to work at least for - // public and package-private methods + // it to emit a body, and produce another one to act as the entry point final boolean needsJavaWrapper = baseJavaEmitter.signatureOnly() && - !baseJavaEmitter.hasModifier(JavaMethodBindingEmitter.PRIVATE) && - baseJavaEmitter.hasModifier(JavaMethodBindingEmitter.NATIVE) && + baseJavaEmitter.isNativeMethod() && + !baseJavaEmitter.isPrivateNativeMethod() && callThroughProcAddress; @@ -215,7 +214,7 @@ final ProcAddressJavaMethodBindingEmitter emitter = new ProcAddressJavaMethodBindingEmitter(baseJavaEmitter, callThroughProcAddress, getProcAddressConfig().getProcAddressTableExpr(), - baseJavaEmitter.isForImplementingMethodCall(), + baseJavaEmitter.isPrivateNativeMethod(), this); if( needsJavaWrapper ) { emitter.setEmitBody(true); @@ -232,7 +231,7 @@ getProcAddressConfig().getProcAddressTableExpr(), true, this); - emitter.setForImplementingMethodCall(true); + emitter.setPrivateNativeMethod(true); fixSecurityModifiers(emitter); emitters.add(emitter); } @@ -243,13 +242,13 @@ final FunctionSymbol cSymbol = baseCEmitter.getBinding().getCSymbol(); // See whether we need a proc address entry for this one - final boolean callThroughProcAddress = needsProcAddressWrapper(cSymbol); - final boolean forceProcAddress = getProcAddressConfig().forceProcAddressGen(cSymbol.getName()); + final boolean hasProcAddrTypedef = hasFunctionPointerTypedef(cSymbol); + final boolean callThroughProcAddress = hasProcAddrTypedef || callThroughProcAddress(cSymbol); + final String localProcCallingConvention = getProcAddressConfig().getLocalProcAddressCallingConvention(cSymbol); + + LOG.log(Level.INFO, cSymbol.getASTLocusTag(), "genModProcAddrEmitter: callThrough {0}, hasTypedef {1}, localCallConv {2}: {3}", + callThroughProcAddress, hasProcAddrTypedef, localProcCallingConvention, cSymbol); - String forcedCallingConvention = null; - if (forceProcAddress) { - forcedCallingConvention = getProcAddressConfig().getLocalProcAddressCallingConvention(cSymbol.getName()); - } // Note that we don't care much about the naming of the C argument // variables so to keep things simple we ignore the buffer object // property for the binding @@ -258,7 +257,7 @@ // extra final argument, which is the address (the OpenGL procedure // address) of the function it needs to call final ProcAddressCMethodBindingEmitter res = new ProcAddressCMethodBindingEmitter( - baseCEmitter, callThroughProcAddress, forceProcAddress, forcedCallingConvention, this); + baseCEmitter, callThroughProcAddress, hasProcAddrTypedef, localProcCallingConvention, this); final MessageFormat exp = baseCEmitter.getReturnValueCapacityExpression(); if (exp != null) { @@ -267,34 +266,30 @@ emitters.add(res); } - private String getAliasedSymName(final FunctionSymbol sym) { - String symName = getConfig().getJavaSymbolRename(sym.getName()); - if (null == symName) { - symName = sym.getName(); + protected boolean callThroughProcAddress(final FunctionSymbol sym) { + final ProcAddressConfiguration cfg = getProcAddressConfig(); + boolean res = false; + int mode = 0; + if (cfg.forceProcAddressGen(sym)) { + res = true; + mode = 1; + } else { + if (cfg.skipProcAddressGen(sym)) { + res = false; + mode = 2; + } else { + res = hasFunctionPointerTypedef(sym); + mode = 3; + } } - return symName; + LOG.log(Level.INFO, sym.getASTLocusTag(), "callThroughProcAddress: {0} [m {1}]: {2}", res, mode, sym); + return res; } - - protected boolean needsProcAddressWrapper(final FunctionSymbol sym) { - final String symName = getAliasedSymName(sym); - - final ProcAddressConfiguration config = getProcAddressConfig(); - - // We should only generate code to call through a function pointer - // if the symbol has an associated function pointer typedef. + protected boolean hasFunctionPointerTypedef(final FunctionSymbol sym) { final String funcPointerTypedefName = getFunctionPointerTypedefName(sym); - boolean shouldWrap = typedefDictionary.containsKey(funcPointerTypedefName); - //System.err.println(funcPointerTypedefName + " defined: " + shouldWrap); - - if (config.skipProcAddressGen(symName)) { - shouldWrap = false; - } - - if (config.forceProcAddressGen(symName)) { - shouldWrap = true; - } - - return shouldWrap; + final boolean res = typedefDictionary.containsKey(funcPointerTypedefName); + LOG.log(Level.INFO, sym.getASTLocusTag(), "hasFunctionPointerTypedef: {0}: {1}", res, sym); + return res; } protected void beginProcAddressTable() throws Exception { @@ -307,8 +302,8 @@ if (implPackageName == null) { implPackageName = getImplPackageName(); } - final String fullTableClassName = implPackageName + "." + tableClassName; - final MethodAccess tableClassAccess = cfg.accessControl(fullTableClassName); + final String tableClassFQN = implPackageName + "." + tableClassName; + final String[] accessModifiers = getClassAccessModifiers(tableClassFQN); final String jImplRoot = getJavaOutputDir() + File.separator + CodeGenUtils.packageAsPath(implPackageName); @@ -330,7 +325,11 @@ tableWriter.println(" * This table is a cache of pointers to the dynamically-linkable C library."); tableWriter.println(" * @see " + ProcAddressTable.class.getSimpleName()); tableWriter.println(" */"); - tableWriter.println(tableClassAccess.getJavaName() + " final class " + tableClassName + " extends "+ ProcAddressTable.class.getSimpleName() + " {"); + for (int i = 0; accessModifiers != null && i < accessModifiers.length; ++i) { + tableWriter.print(accessModifiers[i]); + tableWriter.print(' '); + } + tableWriter.println("final class " + tableClassName + " extends "+ ProcAddressTable.class.getSimpleName() + " {"); tableWriter.println(); for (final String string : getProcAddressConfig().getForceProcAddressGen()) { diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java 2015-10-09 04:18:28.000000000 +0000 @@ -41,6 +41,7 @@ import com.jogamp.gluegen.MethodBinding; import com.jogamp.gluegen.FunctionEmitter; import com.jogamp.gluegen.JavaMethodBindingEmitter; + import java.io.*; /** A specialization of JavaMethodBindingEmitter with knowledge of how @@ -76,12 +77,12 @@ public ProcAddressJavaMethodBindingEmitter(final ProcAddressJavaMethodBindingEmitter methodToWrap) { this(methodToWrap, methodToWrap.callThroughProcAddress, methodToWrap.getProcAddressTableExpr, - methodToWrap.changeNameAndArguments, methodToWrap.emitter); + methodToWrap.changeNameAndArguments, methodToWrap.emitter); } @Override - public String getName() { - final String res = super.getName(); + public String getImplName() { + final String res = super.getImplName(); if (changeNameAndArguments) { return ProcAddressEmitter.WRAP_PREFIX + res; } @@ -106,8 +107,8 @@ } @Override - protected String getImplMethodName() { - final String name = super.getImplMethodName(); + protected String getNativeImplMethodName() { + final String name = super.getNativeImplMethodName(); if (callThroughProcAddress) { return ProcAddressEmitter.WRAP_PREFIX + name; } @@ -119,7 +120,7 @@ super.emitPreCallSetup(binding, writer); if (callThroughProcAddress) { - final String procAddressVariable = ProcAddressEmitter.PROCADDRESS_VAR_PREFIX + binding.getName(); + final String procAddressVariable = ProcAddressEmitter.PROCADDRESS_VAR_PREFIX + binding.getNativeName(); writer.println(" final long __addr_ = " + getProcAddressTableExpr + "." + procAddressVariable + ";"); writer.println(" if (__addr_ == 0) {"); writer.format(" throw new %s(String.format(\"Method \\\"%%s\\\" not available\", \"%s\"));%n", diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/ReferencedStructs.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/ReferencedStructs.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/ReferencedStructs.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/ReferencedStructs.java 2015-10-09 04:18:28.000000000 +0000 @@ -44,31 +44,43 @@ public class ReferencedStructs implements TypeVisitor { - private final Set results = new HashSet(); + private final Map resultMap = new HashMap(); + private final Set layoutSet = new HashSet(); + private final Set skip = new HashSet(); - public void clear() { - results.clear(); - } + public void clear() { + resultMap.clear(); + } - public Iterator results() { - return results.iterator(); - } + public Iterator results() { + return resultMap.values().iterator(); + } + public Iterator layouts() { + return layoutSet.iterator(); + } - @Override - public void visitType(final Type t) { - if (t.isPointer()) { - final PointerType p = t.asPointer(); - if (p.hasTypedefedName()) { - final CompoundType c = p.getTargetType().asCompound(); - if (c != null && c.getName() == null) { - // This otherwise-unnamed CompoundType is referred to by a - // PointerType that has a typedef name. Assume that it is - // referred to in the glue code and emit it. - results.add(p); + @Override + public void visitType(final Type t) { + if( skip.contains(t) ) { + return; + } + if ( t.isPointer() ) { + final PointerType p = t.asPointer(); + final CompoundType c = p.getTargetType().asCompound(); + if( p.isTypedef() && null != c ) { + // If containing pointer is typedef, use it (preferred) + skip.add(c); // earmark to skip the compound! + resultMap.put(c.getName(), p); + layoutSet.add(c); + } else { + // .. otherwise skip pointer and use followup compound + } + } else if( t.isCompound() ) { + // Use compound if not yet mapped, e.g. by typedef'ed (preferred) + if( !resultMap.containsKey(t.getName()) ) { + resultMap.put(t.getName(), t); + } + layoutSet.add(t.asCompound()); // always: could be const/volatile variants .. } - } - } else if (t.isCompound()) { - results.add(t); } - } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/runtime/FunctionAddressResolver.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/runtime/FunctionAddressResolver.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/runtime/FunctionAddressResolver.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/runtime/FunctionAddressResolver.java 2015-10-09 04:18:28.000000000 +0000 @@ -32,16 +32,20 @@ package com.jogamp.gluegen.runtime; import com.jogamp.common.os.DynamicLookupHelper; +import com.jogamp.common.util.SecurityUtil; /** - * - * @author Michael Bien + * @author Michael Bien, et.al. */ public interface FunctionAddressResolver { /** * Resolves the name of the function bound to the method and returns the address. + *

    + * Implementation shall ensure {@link SecurityUtil#checkLinkPermission(String)} is performed. + *

    + * @throws SecurityException if user is not granted access for the library set. */ - public long resolve(String name, DynamicLookupHelper lookup); + public long resolve(String name, DynamicLookupHelper lookup) throws SecurityException; } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java 2015-10-09 04:18:28.000000000 +0000 @@ -119,8 +119,6 @@ * @throws SecurityException if user is not granted access for all libraries. */ public void reset(final DynamicLookupHelper lookup) throws SecurityException, RuntimeException { - SecurityUtil.checkAllLinkPermission(); - if(null==lookup) { throw new RuntimeException("Passed null DynamicLookupHelper"); } @@ -137,13 +135,17 @@ // All at once - performance. AccessibleObject.setAccessible(fields, true); - - for (int i = 0; i < fields.length; ++i) { - final String fieldName = fields[i].getName(); - if ( isAddressField(fieldName) ) { - final String funcName = fieldToFunctionName(fieldName); - setEntry(fields[i], funcName, lookup); + lookup.claimAllLinkPermission(); + try { + for (int i = 0; i < fields.length; ++i) { + final String fieldName = fields[i].getName(); + if ( isAddressField(fieldName) ) { + final String funcName = fieldToFunctionName(fieldName); + setEntry(fields[i], funcName, lookup); + } } + } finally { + lookup.releaseAllLinkPermission(); } if (DEBUG) { @@ -165,7 +167,6 @@ * @throws SecurityException if user is not granted access for all libraries. */ public void initEntry(final String name, final DynamicLookupHelper lookup) throws SecurityException, IllegalArgumentException { - SecurityUtil.checkAllLinkPermission(); final Field addressField = fieldForFunction(name); addressField.setAccessible(true); setEntry(addressField, name, lookup); @@ -174,7 +175,7 @@ private final void setEntry(final Field addressField, final String funcName, final DynamicLookupHelper lookup) throws SecurityException { try { assert (addressField.getType() == Long.TYPE); - final long newProcAddress = resolver.resolve(funcName, lookup); + final long newProcAddress = resolver.resolve(funcName, lookup); // issues SecurityUtil.checkLinkPermission(String) addressField.setLong(this, newProcAddress); if (DEBUG) { getDebugOutStream().println(" " + addressField.getName() + " -> 0x" + Long.toHexString(newProcAddress)); @@ -343,7 +344,7 @@ private static class One2OneResolver implements FunctionAddressResolver { @Override - public long resolve(final String name, final DynamicLookupHelper lookup) { + public long resolve(final String name, final DynamicLookupHelper lookup) throws SecurityException { return lookup.dynamicLookupFunction(name); } } diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java 2015-10-09 04:18:28.000000000 +0000 @@ -131,7 +131,11 @@ if( f.exists() ) { return f; } - } catch (final IOException e) { if(DEBUG) { System.err.println("Caught "+e.getClass().getSimpleName()+": "+e.getMessage()); /* e.printStackTrace(); */ } } + } catch (final IOException e) { + if(DEBUG) { + System.err.println("Caught "+e.getClass().getSimpleName()+": "+e.getMessage()); /* e.printStackTrace(); */ + } + } return null; } @@ -263,6 +267,9 @@ } catch (final FileNotFoundException ex) { throw new RuntimeException("input file not found", ex); } + if( DEBUG ) { + GlueGen.setDebug(true); + } new GlueGen().run(reader, filename, AnnotationProcessorJavaStructEmitter.class, includePaths, cfgFiles, outputPath1, false /* copyCPPOutput2Stderr */); diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/TypeConfig.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/TypeConfig.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/TypeConfig.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/TypeConfig.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,52 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.gluegen; + +import com.jogamp.gluegen.cgram.types.SizeThunk; +import com.jogamp.gluegen.cgram.types.Type; + +/** + * Static {@link Type} config helper + * binding {@link JavaConfiguration#relaxedEqualSemanticsTest()} system wide. + */ +public class TypeConfig { + private static boolean relaxedEqualSemanticsTest = false; + + /** + * Returns whether {@link TypeConfig.SemanticEqualityOp#equalSemantics(TypeConfig.SemanticEqualityOp)} + * shall attempt to perform a relaxed semantic equality test, e.g. skip the {@code const} and {@code volatile} qualifier + * - or not. + */ + public static boolean relaxedEqualSemanticsTest() { + return relaxedEqualSemanticsTest; + } + /* pp */ static void setRelaxedEqualSemanticsTest(final boolean v) { + relaxedEqualSemanticsTest = v; + SizeThunk.setRelaxedEqualSemanticsTest(v); + } +} diff -Nru gluegen2-2.2.4/src/java/com/jogamp/gluegen/TypeInfo.java gluegen2-2.3.2/src/java/com/jogamp/gluegen/TypeInfo.java --- gluegen2-2.2.4/src/java/com/jogamp/gluegen/TypeInfo.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/com/jogamp/gluegen/TypeInfo.java 2015-10-09 04:18:28.000000000 +0000 @@ -66,7 +66,7 @@ buf.append(name); buf.append(" pointerDepth "); buf.append(pointerDepth); - buf.append(" JavaType " + javaType); + buf.append(" JavaType " + javaType.getDebugString()); return buf.toString(); } } diff -Nru gluegen2-2.2.4/src/java/jogamp/android/launcher/ClassLoaderUtil.java gluegen2-2.3.2/src/java/jogamp/android/launcher/ClassLoaderUtil.java --- gluegen2-2.2.4/src/java/jogamp/android/launcher/ClassLoaderUtil.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/android/launcher/ClassLoaderUtil.java 2015-10-09 04:18:28.000000000 +0000 @@ -28,7 +28,14 @@ package jogamp.android.launcher; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -46,6 +53,7 @@ // location where optimized dex files will be written private static final String dexPathName= "jogampDex"; private static File dexPath = null; + private static boolean needsAPKCopy; private static LauncherTempFileCache tmpFileCache = null; @@ -64,6 +72,9 @@ dexPath = new File(tmpFileCache.getTempDir(), dexPathName); Log.d(TAG, "jogamp dexPath: " + dexPath.getAbsolutePath()); dexPath.mkdir(); + + needsAPKCopy = android.os.Build.VERSION.SDK_INT >= 21; // >= LOLLIPOP + Log.d(TAG, "jogamp Android SDK "+android.os.Build.VERSION.SDK_INT+", needsAPKCopy "+needsAPKCopy); } } @@ -151,6 +162,18 @@ libs.append(ELEM_SEP); } } + if( needsAPKCopy ) { + final File src = new File(userAPK); + userAPK = dexPath + "/" + lastUserPackageName + "-1.apk"; + final File dst = new File(userAPK); + try { + copyFile(src, dst); + } catch (final IOException e) { + Log.d(TAG, "error copying <"+src+"> -> <"+dst+">: "+e, e); + return null; + } + Log.d(TAG, "APK["+apkCount+"] copied: <"+src+"> -> <"+dst+">"); + } apks.append(userAPK); Log.d(TAG, "APK["+apkCount+"] found: <"+lastUserPackageName+"> -> <"+userAPK+">"); Log.d(TAG, "APK["+apkCount+"] apks: <"+apks.toString()+">"); @@ -194,6 +217,31 @@ return new AssetDexClassLoader(apks.toString(), dexPath.getAbsolutePath(), libs.toString(), parent); } + private static int copyFile(final File src, final File dst) throws IOException { + int totalBytes = 0; + final InputStream in = new BufferedInputStream(new FileInputStream(src)); + try { + final OutputStream out = new BufferedOutputStream(new FileOutputStream(dst)); + try { + final byte[] buf = new byte[bufferSize]; + while (true) { + int count; + if ((count = in.read(buf)) == -1) { + break; + } + out.write(buf, 0, count); + totalBytes += count; + } + } finally { + out.close(); + } + } finally { + in.close(); + } + return totalBytes; + } + private static final int bufferSize = 4096; + /*** * public boolean setAPKClassLoader(String activityPackageName, ClassLoader classLoader) diff -Nru gluegen2-2.2.4/src/java/jogamp/android/launcher/MainLauncher.java gluegen2-2.3.2/src/java/jogamp/android/launcher/MainLauncher.java --- gluegen2-2.2.4/src/java/jogamp/android/launcher/MainLauncher.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/android/launcher/MainLauncher.java 2015-10-09 04:18:28.000000000 +0000 @@ -33,6 +33,8 @@ import java.util.Arrays; import java.util.List; +import com.jogamp.common.util.InterruptSource; + import android.app.Activity; import android.net.Uri; import android.os.Bundle; @@ -117,17 +119,17 @@ public void onResume() { Log.d(TAG, "onResume - S - "+Thread.currentThread().getName()); super.onResume(); - final Thread mainThread = new Thread("Main") { + final Thread mainThread = new InterruptSource.Thread(null, null, "Main") { public void run() { try { - Log.d(TAG, "onResume - main.0 - "+Thread.currentThread().getName()); + Log.d(TAG, "onResume - main.0 - "+java.lang.Thread.currentThread().getName()); mainClazzMain.invoke(null, new Object[] { mainClassArgs } ); } catch (final InvocationTargetException ite) { ite.getTargetException().printStackTrace(); } catch (final Throwable t) { t.printStackTrace(); } - Log.d(TAG, "onResume - main.X -> finish() - "+Thread.currentThread().getName()); + Log.d(TAG, "onResume - main.X -> finish() - "+java.lang.Thread.currentThread().getName()); finish(); } }; mainThread.start(); diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/BionicDynamicLinker32bitImpl.java gluegen2-2.3.2/src/java/jogamp/common/os/BionicDynamicLinker32bitImpl.java --- gluegen2-2.2.4/src/java/jogamp/common/os/BionicDynamicLinker32bitImpl.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/BionicDynamicLinker32bitImpl.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,63 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.common.os; + +/** + * Bionic 32bit specialization of {@link UnixDynamicLinkerImpl} + * utilizing Bionic's non POSIX flags and mode values. + *

    + * Bionic is used on Android. + *

    + */ +public final class BionicDynamicLinker32bitImpl extends UnixDynamicLinkerImpl { + + // static final int RTLD_NOW = 0x00000; + private static final int RTLD_LAZY = 0x00001; + + private static final int RTLD_LOCAL = 0x00000; + private static final int RTLD_GLOBAL = 0x00002; + // static final int RTLD_NOLOAD = 0x00004; + + private static final long RTLD_DEFAULT = 0xffffffffL; + // static final long RTLD_NEXT = 0xfffffffeL; + + @Override + protected final long openLibraryLocalImpl(final String pathname) throws SecurityException { + return dlopen(pathname, RTLD_LAZY | RTLD_LOCAL); + } + + @Override + protected final long openLibraryGlobalImpl(final String pathname) throws SecurityException { + return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL); + } + + @Override + protected final long lookupSymbolGlobalImpl(final String symbolName) throws SecurityException { + return dlsym(RTLD_DEFAULT, symbolName); + } +} diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/BionicDynamicLinker64BitImpl.java gluegen2-2.3.2/src/java/jogamp/common/os/BionicDynamicLinker64BitImpl.java --- gluegen2-2.2.4/src/java/jogamp/common/os/BionicDynamicLinker64BitImpl.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/BionicDynamicLinker64BitImpl.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,63 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.common.os; + +/** + * Bionic 64bit specialization of {@link UnixDynamicLinkerImpl} + * utilizing Bionic's non POSIX flags and mode values. + *

    + * Bionic is used on Android. + *

    + */ +public final class BionicDynamicLinker64BitImpl extends UnixDynamicLinkerImpl { + // static final int RTLD_NOW = 0x00002; + private static final int RTLD_LAZY = 0x00001; + + private static final int RTLD_LOCAL = 0x00000; + private static final int RTLD_GLOBAL = 0x00100; + // static final int RTLD_NOLOAD = 0x00004; + + private static final long RTLD_DEFAULT = 0x00000000L; + // static final long RTLD_NEXT = -1L; + + @Override + protected final long openLibraryLocalImpl(final String pathname) throws SecurityException { + return dlopen(pathname, RTLD_LAZY | RTLD_LOCAL); + } + + @Override + protected final long openLibraryGlobalImpl(final String pathname) throws SecurityException { + return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL); + } + + @Override + protected final long lookupSymbolGlobalImpl(final String symbolName) throws SecurityException { + return dlsym(RTLD_DEFAULT, symbolName); + } + +} diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/BionicDynamicLinkerImpl.java gluegen2-2.3.2/src/java/jogamp/common/os/BionicDynamicLinkerImpl.java --- gluegen2-2.2.4/src/java/jogamp/common/os/BionicDynamicLinkerImpl.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/BionicDynamicLinkerImpl.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -/** - * Copyright 2013 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ -package jogamp.common.os; - -/** - * Bionic specialization of {@link UnixDynamicLinkerImpl} - * utilizing Bionic's non POSIX flags and mode values. - *

    - * Bionic is used on Android. - *

    - */ -public final class BionicDynamicLinkerImpl extends UnixDynamicLinkerImpl { - private static final long RTLD_DEFAULT = 0xffffffffL; - // static final long RTLD_NEXT = 0xfffffffeL; - - private static final int RTLD_LAZY = 0x00001; - // static final int RTLD_NOW = 0x00000; - private static final int RTLD_LOCAL = 0x00000; - private static final int RTLD_GLOBAL = 0x00002; - - @Override - public final long openLibraryLocal(final String pathname, final boolean debug) throws SecurityException { - return this.openLibraryImpl(pathname, RTLD_LAZY | RTLD_LOCAL, debug); - } - - @Override - public final long openLibraryGlobal(final String pathname, final boolean debug) throws SecurityException { - return this.openLibraryImpl(pathname, RTLD_LAZY | RTLD_GLOBAL, debug); - } - - @Override - public final long lookupSymbolGlobal(final String symbolName) throws SecurityException { - return this.lookupSymbolGlobalImpl(RTLD_DEFAULT, symbolName); - } - -} diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/DynamicLinkerImpl.java gluegen2-2.3.2/src/java/jogamp/common/os/DynamicLinkerImpl.java --- gluegen2-2.2.4/src/java/jogamp/common/os/DynamicLinkerImpl.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/DynamicLinkerImpl.java 2015-10-09 04:18:28.000000000 +0000 @@ -29,6 +29,7 @@ import com.jogamp.common.os.DynamicLinker; import com.jogamp.common.util.LongObjectHashMap; +import com.jogamp.common.util.SecurityUtil; /* pp */ abstract class DynamicLinkerImpl implements DynamicLinker { @@ -38,18 +39,134 @@ // ensuring no abuse via subclassing. // - private final LongObjectHashMap libHandle2Name = new LongObjectHashMap( 16 /* initialCapacity */ ); + private final Object secSync = new Object(); + private boolean allLinkPermissionGranted = false; - protected static final class LibRef { - public LibRef(final String name) { + /** + * @throws SecurityException if user is not granted global access + */ + public final void claimAllLinkPermission() throws SecurityException { + synchronized( secSync ) { + allLinkPermissionGranted = true; + } + } + + /** + * @throws SecurityException if user is not granted global access + */ + public final void releaseAllLinkPermission() throws SecurityException { + synchronized( secSync ) { + allLinkPermissionGranted = false; + } + } + + private final void checkLinkPermission(final String pathname) throws SecurityException { + synchronized( secSync ) { + if( !allLinkPermissionGranted ) { + SecurityUtil.checkLinkPermission(pathname); + } + } + } + private final void checkLinkPermission(final long libraryHandle) throws SecurityException { + synchronized( secSync ) { + if( !allLinkPermissionGranted ) { + final LibRef libRef = getLibRef( libraryHandle ); + if( null == libRef ) { + throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown."); + } + SecurityUtil.checkLinkPermission(libRef.getName()); + } + } + } + + private final void checkAllLinkPermission() throws SecurityException { + synchronized( secSync ) { + if( !allLinkPermissionGranted ) { + SecurityUtil.checkAllLinkPermission(); + } + } + } + + @Override + public final long openLibraryGlobal(final String pathname, final boolean debug) throws SecurityException { + checkLinkPermission(pathname); + final long handle = openLibraryGlobalImpl(pathname); + if( 0 != handle ) { + final LibRef libRef = incrLibRefCount(handle, pathname); + if( DEBUG || debug ) { + System.err.println("DynamicLinkerImpl.openLibraryGlobal \""+pathname+"\": 0x"+Long.toHexString(handle)+" -> "+libRef+")"); + } + } else if ( DEBUG || debug ) { + System.err.println("DynamicLinkerImpl.openLibraryGlobal \""+pathname+"\" failed, error: "+getLastError()); + } + return handle; + } + protected abstract long openLibraryGlobalImpl(final String pathname) throws SecurityException; + + @Override + public final long openLibraryLocal(final String pathname, final boolean debug) throws SecurityException { + checkLinkPermission(pathname); + final long handle = openLibraryLocalImpl(pathname); + if( 0 != handle ) { + final LibRef libRef = incrLibRefCount(handle, pathname); + if( DEBUG || debug ) { + System.err.println("DynamicLinkerImpl.openLibraryLocal \""+pathname+"\": 0x"+Long.toHexString(handle)+" -> "+libRef+")"); + } + } else if ( DEBUG || debug ) { + System.err.println("DynamicLinkerImpl.openLibraryLocal \""+pathname+"\" failed, error: "+getLastError()); + } + return handle; + } + protected abstract long openLibraryLocalImpl(final String pathname) throws SecurityException; + + @Override + public final long lookupSymbolGlobal(final String symbolName) throws SecurityException { + checkAllLinkPermission(); + final long addr = lookupSymbolGlobalImpl(symbolName); + if(DEBUG_LOOKUP) { + System.err.println("DynamicLinkerImpl.lookupSymbolGlobal("+symbolName+") -> 0x"+Long.toHexString(addr)); + } + return addr; + } + protected abstract long lookupSymbolGlobalImpl(final String symbolName) throws SecurityException; + + @Override + public final long lookupSymbol(final long libraryHandle, final String symbolName) throws SecurityException, IllegalArgumentException { + checkLinkPermission(libraryHandle); + final long addr = lookupSymbolLocalImpl(libraryHandle, symbolName); + if(DEBUG_LOOKUP) { + System.err.println("DynamicLinkerImpl.lookupSymbol(0x"+Long.toHexString(libraryHandle)+", "+symbolName+") -> 0x"+Long.toHexString(addr)); + } + return addr; + } + protected abstract long lookupSymbolLocalImpl(final long libraryHandle, final String symbolName) throws SecurityException; + + @Override + public final void closeLibrary(final long libraryHandle, final boolean debug) throws SecurityException, IllegalArgumentException { + final LibRef libRef = decrLibRefCount( libraryHandle ); + if( null == libRef ) { + throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown."); + } + checkLinkPermission(libRef.getName()); + if( DEBUG || debug ) { + System.err.println("DynamicLinkerImpl.closeLibrary(0x"+Long.toHexString(libraryHandle)+" -> "+libRef+")"); + } + closeLibraryImpl(libraryHandle); + } + protected abstract void closeLibraryImpl(final long libraryHandle) throws SecurityException; + + private static final LongObjectHashMap libHandle2Name = new LongObjectHashMap( 16 /* initialCapacity */ ); + + static final class LibRef { + LibRef(final String name) { this.name = name; this.refCount = 1; } - public final int incrRefCount() { return ++refCount; } - public final int decrRefCount() { return --refCount; } - public final int getRefCount() { return refCount; } + final int incrRefCount() { return ++refCount; } + final int decrRefCount() { return --refCount; } + final int getRefCount() { return refCount; } - public final String getName() { return name; } + final String getName() { return name; } @Override public final String toString() { return "LibRef["+name+", refCount "+refCount+"]"; } @@ -57,35 +174,40 @@ private int refCount; } - protected final synchronized LibRef getLibRef(final long handle) { - return (LibRef) libHandle2Name.get(handle); + private final LibRef getLibRef(final long handle) { + synchronized( libHandle2Name ) { + return (LibRef) libHandle2Name.get(handle); + } } - protected final synchronized LibRef incrLibRefCount(final long handle, final String libName) { - LibRef libRef = getLibRef(handle); - if( null == libRef ) { - libRef = new LibRef(libName); - libHandle2Name.put(handle, libRef); - } else { - libRef.incrRefCount(); - } - if(DEBUG) { - System.err.println("DynamicLinkerImpl.incrLibRefCount 0x"+Long.toHexString(handle)+ " -> "+libRef+", libs loaded "+libHandle2Name.size()); + private final LibRef incrLibRefCount(final long handle, final String libName) { + synchronized( libHandle2Name ) { + LibRef libRef = getLibRef(handle); + if( null == libRef ) { + libRef = new LibRef(libName); + libHandle2Name.put(handle, libRef); + } else { + libRef.incrRefCount(); + } + if(DEBUG) { + System.err.println("DynamicLinkerImpl.incrLibRefCount 0x"+Long.toHexString(handle)+ " -> "+libRef+", libs loaded "+libHandle2Name.size()); + } + return libRef; } - return libRef; } - protected final synchronized LibRef decrLibRefCount(final long handle) { - final LibRef libRef = getLibRef(handle); - if( null != libRef ) { - if( 0 == libRef.decrRefCount() ) { - libHandle2Name.remove(handle); + private final LibRef decrLibRefCount(final long handle) { + synchronized( libHandle2Name ) { + final LibRef libRef = getLibRef(handle); + if( null != libRef ) { + if( 0 == libRef.decrRefCount() ) { + libHandle2Name.remove(handle); + } } + if(DEBUG) { + System.err.println("DynamicLinkerImpl.decrLibRefCount 0x"+Long.toHexString(handle)+ " -> "+libRef+", libs loaded "+libHandle2Name.size()); + } + return libRef; } - if(DEBUG) { - System.err.println("DynamicLinkerImpl.decrLibRefCount 0x"+Long.toHexString(handle)+ " -> "+libRef+", libs loaded "+libHandle2Name.size()); - } - return libRef; } - } diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/elf/Ehdr.java gluegen2-2.3.2/src/java/jogamp/common/os/elf/Ehdr.java --- gluegen2-2.2.4/src/java/jogamp/common/os/elf/Ehdr.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/elf/Ehdr.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,175 +0,0 @@ -/* !---- DO NOT EDIT: This file autogenerated by com/jogamp/gluegen/JavaEmitter.java on Thu Feb 07 17:54:18 CET 2013 ----! */ - - -package jogamp.common.os.elf; - -import com.jogamp.common.nio.*; -import jogamp.common.os.MachineDescriptionRuntime; - - -public class Ehdr { - - StructAccessor accessor; - - private static final int mdIdx = MachineDescriptionRuntime.getStatic().ordinal(); - - private static final int[] Ehdr_size = new int[] { 52 /* ARMle_EABI */, 52 /* X86_32_UNIX */, 64 /* X86_64_UNIX */, 52 /* X86_32_MACOS */, 52 /* X86_32_WINDOWS */, 64 /* X86_64_WINDOWS */ }; - private static final int[] e_ident_offset = new int[] { 0 /* ARMle_EABI */, 0 /* X86_32_UNIX */, 0 /* X86_64_UNIX */, 0 /* X86_32_MACOS */, 0 /* X86_32_WINDOWS */, 0 /* X86_64_WINDOWS */ }; - private static final int[] e_type_offset = new int[] { 16 /* ARMle_EABI */, 16 /* X86_32_UNIX */, 16 /* X86_64_UNIX */, 16 /* X86_32_MACOS */, 16 /* X86_32_WINDOWS */, 16 /* X86_64_WINDOWS */ }; - private static final int[] e_machine_offset = new int[] { 18 /* ARMle_EABI */, 18 /* X86_32_UNIX */, 18 /* X86_64_UNIX */, 18 /* X86_32_MACOS */, 18 /* X86_32_WINDOWS */, 18 /* X86_64_WINDOWS */ }; - private static final int[] e_version_offset = new int[] { 20 /* ARMle_EABI */, 20 /* X86_32_UNIX */, 20 /* X86_64_UNIX */, 20 /* X86_32_MACOS */, 20 /* X86_32_WINDOWS */, 20 /* X86_64_WINDOWS */ }; - private static final int[] e_entry_offset = new int[] { 24 /* ARMle_EABI */, 24 /* X86_32_UNIX */, 24 /* X86_64_UNIX */, 24 /* X86_32_MACOS */, 24 /* X86_32_WINDOWS */, 24 /* X86_64_WINDOWS */ }; - private static final int[] e_phoff_offset = new int[] { 28 /* ARMle_EABI */, 28 /* X86_32_UNIX */, 32 /* X86_64_UNIX */, 28 /* X86_32_MACOS */, 28 /* X86_32_WINDOWS */, 32 /* X86_64_WINDOWS */ }; - private static final int[] e_shoff_offset = new int[] { 32 /* ARMle_EABI */, 32 /* X86_32_UNIX */, 40 /* X86_64_UNIX */, 32 /* X86_32_MACOS */, 32 /* X86_32_WINDOWS */, 40 /* X86_64_WINDOWS */ }; - private static final int[] e_flags_offset = new int[] { 36 /* ARMle_EABI */, 36 /* X86_32_UNIX */, 48 /* X86_64_UNIX */, 36 /* X86_32_MACOS */, 36 /* X86_32_WINDOWS */, 48 /* X86_64_WINDOWS */ }; - private static final int[] e_ehsize_offset = new int[] { 40 /* ARMle_EABI */, 40 /* X86_32_UNIX */, 52 /* X86_64_UNIX */, 40 /* X86_32_MACOS */, 40 /* X86_32_WINDOWS */, 52 /* X86_64_WINDOWS */ }; - private static final int[] e_phentsize_offset = new int[] { 42 /* ARMle_EABI */, 42 /* X86_32_UNIX */, 54 /* X86_64_UNIX */, 42 /* X86_32_MACOS */, 42 /* X86_32_WINDOWS */, 54 /* X86_64_WINDOWS */ }; - private static final int[] e_phnum_offset = new int[] { 44 /* ARMle_EABI */, 44 /* X86_32_UNIX */, 56 /* X86_64_UNIX */, 44 /* X86_32_MACOS */, 44 /* X86_32_WINDOWS */, 56 /* X86_64_WINDOWS */ }; - private static final int[] e_shentsize_offset = new int[] { 46 /* ARMle_EABI */, 46 /* X86_32_UNIX */, 58 /* X86_64_UNIX */, 46 /* X86_32_MACOS */, 46 /* X86_32_WINDOWS */, 58 /* X86_64_WINDOWS */ }; - private static final int[] e_shnum_offset = new int[] { 48 /* ARMle_EABI */, 48 /* X86_32_UNIX */, 60 /* X86_64_UNIX */, 48 /* X86_32_MACOS */, 48 /* X86_32_WINDOWS */, 60 /* X86_64_WINDOWS */ }; - private static final int[] e_shstrndx_offset = new int[] { 50 /* ARMle_EABI */, 50 /* X86_32_UNIX */, 62 /* X86_64_UNIX */, 50 /* X86_32_MACOS */, 50 /* X86_32_WINDOWS */, 62 /* X86_64_WINDOWS */ }; - - public static int size() { - return Ehdr_size[mdIdx]; - } - - public static Ehdr create() { - return create(Buffers.newDirectByteBuffer(size())); - } - - public static Ehdr create(final java.nio.ByteBuffer buf) { - return new Ehdr(buf); - } - - Ehdr(final java.nio.ByteBuffer buf) { - accessor = new StructAccessor(buf); - } - - public java.nio.ByteBuffer getBuffer() { - return accessor.getBuffer(); - } - - public Ehdr setE_ident(final byte[] val) { - accessor.setBytesAt(e_ident_offset[mdIdx], val); return this; - } - - public byte[] getE_ident() { - return accessor.getBytesAt(e_ident_offset[mdIdx], new byte[16]); } - - public Ehdr setE_type(final short val) { - accessor.setShortAt(e_type_offset[mdIdx], val); - return this; - } - - public short getE_type() { - return accessor.getShortAt(e_type_offset[mdIdx]); - } - - public Ehdr setE_machine(final short val) { - accessor.setShortAt(e_machine_offset[mdIdx], val); - return this; - } - - public short getE_machine() { - return accessor.getShortAt(e_machine_offset[mdIdx]); - } - - public Ehdr setE_version(final int val) { - accessor.setIntAt(e_version_offset[mdIdx], val); - return this; - } - - public int getE_version() { - return accessor.getIntAt(e_version_offset[mdIdx]); - } - - public Ehdr setE_entry(final long val) { - accessor.setLongAt(e_entry_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); - return this; - } - - public long getE_entry() { - return accessor.getLongAt(e_entry_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); - } - - public Ehdr setE_phoff(final long val) { - accessor.setLongAt(e_phoff_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); - return this; - } - - public long getE_phoff() { - return accessor.getLongAt(e_phoff_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); - } - - public Ehdr setE_shoff(final long val) { - accessor.setLongAt(e_shoff_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); - return this; - } - - public long getE_shoff() { - return accessor.getLongAt(e_shoff_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); - } - - public Ehdr setE_flags(final int val) { - accessor.setIntAt(e_flags_offset[mdIdx], val); - return this; - } - - public int getE_flags() { - return accessor.getIntAt(e_flags_offset[mdIdx]); - } - - public Ehdr setE_ehsize(final short val) { - accessor.setShortAt(e_ehsize_offset[mdIdx], val); - return this; - } - - public short getE_ehsize() { - return accessor.getShortAt(e_ehsize_offset[mdIdx]); - } - - public Ehdr setE_phentsize(final short val) { - accessor.setShortAt(e_phentsize_offset[mdIdx], val); - return this; - } - - public short getE_phentsize() { - return accessor.getShortAt(e_phentsize_offset[mdIdx]); - } - - public Ehdr setE_phnum(final short val) { - accessor.setShortAt(e_phnum_offset[mdIdx], val); - return this; - } - - public short getE_phnum() { - return accessor.getShortAt(e_phnum_offset[mdIdx]); - } - - public Ehdr setE_shentsize(final short val) { - accessor.setShortAt(e_shentsize_offset[mdIdx], val); - return this; - } - - public short getE_shentsize() { - return accessor.getShortAt(e_shentsize_offset[mdIdx]); - } - - public Ehdr setE_shnum(final short val) { - accessor.setShortAt(e_shnum_offset[mdIdx], val); - return this; - } - - public short getE_shnum() { - return accessor.getShortAt(e_shnum_offset[mdIdx]); - } - - public Ehdr setE_shstrndx(final short val) { - accessor.setShortAt(e_shstrndx_offset[mdIdx], val); - return this; - } - - public short getE_shstrndx() { - return accessor.getShortAt(e_shstrndx_offset[mdIdx]); - } -} diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/elf/Ehdr_p1.java gluegen2-2.3.2/src/java/jogamp/common/os/elf/Ehdr_p1.java --- gluegen2-2.2.4/src/java/jogamp/common/os/elf/Ehdr_p1.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/elf/Ehdr_p1.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,118 @@ +/* !---- DO NOT EDIT: This file autogenerated by com/jogamp/gluegen/JavaEmitter.java on Sun Feb 01 23:28:47 CET 2015 ----! */ + + +package jogamp.common.os.elf; + +import java.nio.*; + +import com.jogamp.gluegen.runtime.*; +import com.jogamp.common.os.*; +import com.jogamp.common.nio.*; +import jogamp.common.os.MachineDataInfoRuntime; + + +public class Ehdr_p1 { + + StructAccessor accessor; + + private static final int mdIdx = 0; + private final MachineDataInfo md; + + private static final int[] Ehdr_p1_size = new int[] { 24 /* ARM_MIPS_32 */, 24 /* X86_32_UNIX */, 24 /* X86_32_MACOS */, 24 /* PPC_32_UNIX */, 24 /* SPARC_32_SUNOS */, 24 /* X86_32_WINDOWS */, 24 /* LP64_UNIX */, 24 /* X86_64_WINDOWS */ }; + private static final int[] e_ident_offset = new int[] { 0 /* ARM_MIPS_32 */, 0 /* X86_32_UNIX */, 0 /* X86_32_MACOS */, 0 /* PPC_32_UNIX */, 0 /* SPARC_32_SUNOS */, 0 /* X86_32_WINDOWS */, 0 /* LP64_UNIX */, 0 /* X86_64_WINDOWS */ }; + private static final int[] e_ident_size = new int[] { 16 /* ARM_MIPS_32 */, 16 /* X86_32_UNIX */, 16 /* X86_32_MACOS */, 16 /* PPC_32_UNIX */, 16 /* SPARC_32_SUNOS */, 16 /* X86_32_WINDOWS */, 16 /* LP64_UNIX */, 16 /* X86_64_WINDOWS */ }; + private static final int[] e_type_offset = new int[] { 16 /* ARM_MIPS_32 */, 16 /* X86_32_UNIX */, 16 /* X86_32_MACOS */, 16 /* PPC_32_UNIX */, 16 /* SPARC_32_SUNOS */, 16 /* X86_32_WINDOWS */, 16 /* LP64_UNIX */, 16 /* X86_64_WINDOWS */ }; +//private static final int[] e_type_size = new int[] { 2 /* ARM_MIPS_32 */, 2 /* X86_32_UNIX */, 2 /* X86_32_MACOS */, 2 /* PPC_32_UNIX */, 2 /* SPARC_32_SUNOS */, 2 /* X86_32_WINDOWS */, 2 /* LP64_UNIX */, 2 /* X86_64_WINDOWS */ }; + private static final int[] e_machine_offset = new int[] { 18 /* ARM_MIPS_32 */, 18 /* X86_32_UNIX */, 18 /* X86_32_MACOS */, 18 /* PPC_32_UNIX */, 18 /* SPARC_32_SUNOS */, 18 /* X86_32_WINDOWS */, 18 /* LP64_UNIX */, 18 /* X86_64_WINDOWS */ }; +//private static final int[] e_machine_size = new int[] { 2 /* ARM_MIPS_32 */, 2 /* X86_32_UNIX */, 2 /* X86_32_MACOS */, 2 /* PPC_32_UNIX */, 2 /* SPARC_32_SUNOS */, 2 /* X86_32_WINDOWS */, 2 /* LP64_UNIX */, 2 /* X86_64_WINDOWS */ }; + private static final int[] e_version_offset = new int[] { 20 /* ARM_MIPS_32 */, 20 /* X86_32_UNIX */, 20 /* X86_32_MACOS */, 20 /* PPC_32_UNIX */, 20 /* SPARC_32_SUNOS */, 20 /* X86_32_WINDOWS */, 20 /* LP64_UNIX */, 20 /* X86_64_WINDOWS */ }; +//private static final int[] e_version_size = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 4 /* LP64_UNIX */, 4 /* X86_64_WINDOWS */ }; + + public static int size() { + return Ehdr_p1_size[mdIdx]; + } + + public static Ehdr_p1 create() { + return create(Buffers.newDirectByteBuffer(size())); + } + + public static Ehdr_p1 create(java.nio.ByteBuffer buf) { + return new Ehdr_p1(buf); + } + + Ehdr_p1(java.nio.ByteBuffer buf) { + md = MachineDataInfo.StaticConfig.values()[mdIdx].md; + accessor = new StructAccessor(buf); + } + + public java.nio.ByteBuffer getBuffer() { + return accessor.getBuffer(); + } + + /** Getter for native field: CType['char *', size [fixed false, lnx64 16], [array*1]], with array length of 16 */ + public static final int getE_identArrayLength() { + return 16; + } + + /** Setter for native field: CType['char *', size [fixed false, lnx64 16], [array*1]], with array length of 16 */ + public Ehdr_p1 setE_ident(final int offset, byte[] val) { + final int arrayLength = 16; + if( offset + val.length > arrayLength ) { throw new IndexOutOfBoundsException("offset "+offset+" + val.length "+val.length+" > array-length "+arrayLength); }; + final int elemSize = Buffers.SIZEOF_BYTE; + final ByteBuffer destB = getBuffer(); + final int bTotal = arrayLength * elemSize; + if( bTotal > e_ident_size[mdIdx] ) { throw new IndexOutOfBoundsException("bTotal "+bTotal+" > size "+e_ident_size[mdIdx]+", elemSize "+elemSize+" * "+arrayLength); }; + int bOffset = e_ident_offset[mdIdx]; + final int bLimes = bOffset + bTotal; + if( bLimes > destB.limit() ) { throw new IndexOutOfBoundsException("bLimes "+bLimes+" > buffer.limit "+destB.limit()+", elemOff "+bOffset+", elemSize "+elemSize+" * "+arrayLength); }; + bOffset += elemSize * offset; + accessor.setBytesAt(bOffset, val); + return this; + } + + /** Getter for native field: CType['char *', size [fixed false, lnx64 16], [array*1]], with array length of 16 */ + public ByteBuffer getE_ident() { + return accessor.slice(e_ident_offset[mdIdx], Buffers.SIZEOF_BYTE * 16); + } + + /** Getter for native field: CType['char *', size [fixed false, lnx64 16], [array*1]], with array length of 16 */ + public byte[] getE_ident(final int offset, byte result[]) { + final int arrayLength = 16; + if( offset + result.length > arrayLength ) { throw new IndexOutOfBoundsException("offset "+offset+" + result.length "+result.length+" > array-length "+arrayLength); }; + return accessor.getBytesAt(e_ident_offset[mdIdx] + (Buffers.SIZEOF_BYTE * offset), result); + } + + + /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public Ehdr_p1 setE_type(short val) { + accessor.setShortAt(e_type_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public short getE_type() { + return accessor.getShortAt(e_type_offset[mdIdx]); + } + + /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public Ehdr_p1 setE_machine(short val) { + accessor.setShortAt(e_machine_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public short getE_machine() { + return accessor.getShortAt(e_machine_offset[mdIdx]); + } + + /** Setter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ + public Ehdr_p1 setE_version(int val) { + accessor.setIntAt(e_version_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ + public int getE_version() { + return accessor.getIntAt(e_version_offset[mdIdx]); + } +} diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/elf/Ehdr_p2.java gluegen2-2.3.2/src/java/jogamp/common/os/elf/Ehdr_p2.java --- gluegen2-2.2.4/src/java/jogamp/common/os/elf/Ehdr_p2.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/elf/Ehdr_p2.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,176 @@ +/* !---- DO NOT EDIT: This file autogenerated by com/jogamp/gluegen/JavaEmitter.java on Sun Feb 01 23:28:47 CET 2015 ----! */ + + +package jogamp.common.os.elf; + +import java.nio.*; + +import com.jogamp.gluegen.runtime.*; +import com.jogamp.common.os.*; +import com.jogamp.common.nio.*; +import jogamp.common.os.MachineDataInfoRuntime; + + +public class Ehdr_p2 { + + StructAccessor accessor; + + private final int mdIdx; + private final MachineDataInfo md; + + private static final int[] Ehdr_p2_size = new int[] { 28 /* ARM_MIPS_32 */, 28 /* X86_32_UNIX */, 28 /* X86_32_MACOS */, 28 /* PPC_32_UNIX */, 28 /* SPARC_32_SUNOS */, 28 /* X86_32_WINDOWS */, 40 /* LP64_UNIX */, 40 /* X86_64_WINDOWS */ }; + private static final int[] e_entry_offset = new int[] { 0 /* ARM_MIPS_32 */, 0 /* X86_32_UNIX */, 0 /* X86_32_MACOS */, 0 /* PPC_32_UNIX */, 0 /* SPARC_32_SUNOS */, 0 /* X86_32_WINDOWS */, 0 /* LP64_UNIX */, 0 /* X86_64_WINDOWS */ }; +//private static final int[] e_entry_size = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 8 /* LP64_UNIX */, 8 /* X86_64_WINDOWS */ }; + private static final int[] e_phoff_offset = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 8 /* LP64_UNIX */, 8 /* X86_64_WINDOWS */ }; +//private static final int[] e_phoff_size = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 8 /* LP64_UNIX */, 8 /* X86_64_WINDOWS */ }; + private static final int[] e_shoff_offset = new int[] { 8 /* ARM_MIPS_32 */, 8 /* X86_32_UNIX */, 8 /* X86_32_MACOS */, 8 /* PPC_32_UNIX */, 8 /* SPARC_32_SUNOS */, 8 /* X86_32_WINDOWS */, 16 /* LP64_UNIX */, 16 /* X86_64_WINDOWS */ }; +//private static final int[] e_shoff_size = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 8 /* LP64_UNIX */, 8 /* X86_64_WINDOWS */ }; + private static final int[] e_flags_offset = new int[] { 12 /* ARM_MIPS_32 */, 12 /* X86_32_UNIX */, 12 /* X86_32_MACOS */, 12 /* PPC_32_UNIX */, 12 /* SPARC_32_SUNOS */, 12 /* X86_32_WINDOWS */, 24 /* LP64_UNIX */, 24 /* X86_64_WINDOWS */ }; +//private static final int[] e_flags_size = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 4 /* LP64_UNIX */, 4 /* X86_64_WINDOWS */ }; + private static final int[] e_ehsize_offset = new int[] { 16 /* ARM_MIPS_32 */, 16 /* X86_32_UNIX */, 16 /* X86_32_MACOS */, 16 /* PPC_32_UNIX */, 16 /* SPARC_32_SUNOS */, 16 /* X86_32_WINDOWS */, 28 /* LP64_UNIX */, 28 /* X86_64_WINDOWS */ }; +//private static final int[] e_ehsize_size = new int[] { 2 /* ARM_MIPS_32 */, 2 /* X86_32_UNIX */, 2 /* X86_32_MACOS */, 2 /* PPC_32_UNIX */, 2 /* SPARC_32_SUNOS */, 2 /* X86_32_WINDOWS */, 2 /* LP64_UNIX */, 2 /* X86_64_WINDOWS */ }; + private static final int[] e_phentsize_offset = new int[] { 18 /* ARM_MIPS_32 */, 18 /* X86_32_UNIX */, 18 /* X86_32_MACOS */, 18 /* PPC_32_UNIX */, 18 /* SPARC_32_SUNOS */, 18 /* X86_32_WINDOWS */, 30 /* LP64_UNIX */, 30 /* X86_64_WINDOWS */ }; +//private static final int[] e_phentsize_size = new int[] { 2 /* ARM_MIPS_32 */, 2 /* X86_32_UNIX */, 2 /* X86_32_MACOS */, 2 /* PPC_32_UNIX */, 2 /* SPARC_32_SUNOS */, 2 /* X86_32_WINDOWS */, 2 /* LP64_UNIX */, 2 /* X86_64_WINDOWS */ }; + private static final int[] e_phnum_offset = new int[] { 20 /* ARM_MIPS_32 */, 20 /* X86_32_UNIX */, 20 /* X86_32_MACOS */, 20 /* PPC_32_UNIX */, 20 /* SPARC_32_SUNOS */, 20 /* X86_32_WINDOWS */, 32 /* LP64_UNIX */, 32 /* X86_64_WINDOWS */ }; +//private static final int[] e_phnum_size = new int[] { 2 /* ARM_MIPS_32 */, 2 /* X86_32_UNIX */, 2 /* X86_32_MACOS */, 2 /* PPC_32_UNIX */, 2 /* SPARC_32_SUNOS */, 2 /* X86_32_WINDOWS */, 2 /* LP64_UNIX */, 2 /* X86_64_WINDOWS */ }; + private static final int[] e_shentsize_offset = new int[] { 22 /* ARM_MIPS_32 */, 22 /* X86_32_UNIX */, 22 /* X86_32_MACOS */, 22 /* PPC_32_UNIX */, 22 /* SPARC_32_SUNOS */, 22 /* X86_32_WINDOWS */, 34 /* LP64_UNIX */, 34 /* X86_64_WINDOWS */ }; +//private static final int[] e_shentsize_size = new int[] { 2 /* ARM_MIPS_32 */, 2 /* X86_32_UNIX */, 2 /* X86_32_MACOS */, 2 /* PPC_32_UNIX */, 2 /* SPARC_32_SUNOS */, 2 /* X86_32_WINDOWS */, 2 /* LP64_UNIX */, 2 /* X86_64_WINDOWS */ }; + private static final int[] e_shnum_offset = new int[] { 24 /* ARM_MIPS_32 */, 24 /* X86_32_UNIX */, 24 /* X86_32_MACOS */, 24 /* PPC_32_UNIX */, 24 /* SPARC_32_SUNOS */, 24 /* X86_32_WINDOWS */, 36 /* LP64_UNIX */, 36 /* X86_64_WINDOWS */ }; +//private static final int[] e_shnum_size = new int[] { 2 /* ARM_MIPS_32 */, 2 /* X86_32_UNIX */, 2 /* X86_32_MACOS */, 2 /* PPC_32_UNIX */, 2 /* SPARC_32_SUNOS */, 2 /* X86_32_WINDOWS */, 2 /* LP64_UNIX */, 2 /* X86_64_WINDOWS */ }; + private static final int[] e_shstrndx_offset = new int[] { 26 /* ARM_MIPS_32 */, 26 /* X86_32_UNIX */, 26 /* X86_32_MACOS */, 26 /* PPC_32_UNIX */, 26 /* SPARC_32_SUNOS */, 26 /* X86_32_WINDOWS */, 38 /* LP64_UNIX */, 38 /* X86_64_WINDOWS */ }; +//private static final int[] e_shstrndx_size = new int[] { 2 /* ARM_MIPS_32 */, 2 /* X86_32_UNIX */, 2 /* X86_32_MACOS */, 2 /* PPC_32_UNIX */, 2 /* SPARC_32_SUNOS */, 2 /* X86_32_WINDOWS */, 2 /* LP64_UNIX */, 2 /* X86_64_WINDOWS */ }; + + public java.nio.ByteBuffer getBuffer() { + return accessor.getBuffer(); + } + + /** Setter for native field: CType['ElfN_Addr' (typedef), size [fixed false, lnx64 8], [int]] */ + public Ehdr_p2 setE_entry(long val) { + accessor.setLongAt(e_entry_offset[mdIdx], val, md.longSizeInBytes()); + return this; + } + + /** Getter for native field: CType['ElfN_Addr' (typedef), size [fixed false, lnx64 8], [int]] */ + public long getE_entry() { + return accessor.getLongAt(e_entry_offset[mdIdx], md.longSizeInBytes()); + } + + /** Setter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]] */ + public Ehdr_p2 setE_phoff(long val) { + accessor.setLongAt(e_phoff_offset[mdIdx], val, md.longSizeInBytes()); + return this; + } + + /** Getter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]] */ + public long getE_phoff() { + return accessor.getLongAt(e_phoff_offset[mdIdx], md.longSizeInBytes()); + } + + /** Setter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]] */ + public Ehdr_p2 setE_shoff(long val) { + accessor.setLongAt(e_shoff_offset[mdIdx], val, md.longSizeInBytes()); + return this; + } + + /** Getter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]] */ + public long getE_shoff() { + return accessor.getLongAt(e_shoff_offset[mdIdx], md.longSizeInBytes()); + } + + /** Setter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ + public Ehdr_p2 setE_flags(int val) { + accessor.setIntAt(e_flags_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ + public int getE_flags() { + return accessor.getIntAt(e_flags_offset[mdIdx]); + } + + /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public Ehdr_p2 setE_ehsize(short val) { + accessor.setShortAt(e_ehsize_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public short getE_ehsize() { + return accessor.getShortAt(e_ehsize_offset[mdIdx]); + } + + /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public Ehdr_p2 setE_phentsize(short val) { + accessor.setShortAt(e_phentsize_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public short getE_phentsize() { + return accessor.getShortAt(e_phentsize_offset[mdIdx]); + } + + /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public Ehdr_p2 setE_phnum(short val) { + accessor.setShortAt(e_phnum_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public short getE_phnum() { + return accessor.getShortAt(e_phnum_offset[mdIdx]); + } + + /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public Ehdr_p2 setE_shentsize(short val) { + accessor.setShortAt(e_shentsize_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public short getE_shentsize() { + return accessor.getShortAt(e_shentsize_offset[mdIdx]); + } + + /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public Ehdr_p2 setE_shnum(short val) { + accessor.setShortAt(e_shnum_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public short getE_shnum() { + return accessor.getShortAt(e_shnum_offset[mdIdx]); + } + + /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public Ehdr_p2 setE_shstrndx(short val) { + accessor.setShortAt(e_shstrndx_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public short getE_shstrndx() { + return accessor.getShortAt(e_shstrndx_offset[mdIdx]); + } + + // --- Begin CustomJavaCode .cfg declarations + public static int size(final int mdIdx) { + return Ehdr_p2_size[mdIdx]; + } + + public static Ehdr_p2 create(final int mdIdx) { + return create(mdIdx, Buffers.newDirectByteBuffer(size(mdIdx))); + } + + public static Ehdr_p2 create(final int mdIdx, final java.nio.ByteBuffer buf) { + return new Ehdr_p2(mdIdx, buf); + } + + Ehdr_p2(final int mdIdx, final java.nio.ByteBuffer buf) { + this.mdIdx = mdIdx; + this.md = MachineDataInfo.StaticConfig.values()[mdIdx].md; + this.accessor = new StructAccessor(buf); + } + // ---- End CustomJavaCode .cfg declarations +} diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/elf/ElfHeader.java gluegen2-2.3.2/src/java/jogamp/common/os/elf/ElfHeader.java --- gluegen2-2.2.4/src/java/jogamp/common/os/elf/ElfHeader.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/elf/ElfHeader.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,645 +0,0 @@ -/** - * Copyright 2013 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ -package jogamp.common.os.elf; - -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; - -import static jogamp.common.os.elf.IOUtils.readBytes; -import static jogamp.common.os.elf.IOUtils.seek; -import static jogamp.common.os.elf.IOUtils.shortToInt; -import static jogamp.common.os.elf.IOUtils.toHexString; - -/** - * ELF ABI Header - *

    - * References: - *

      - *
    • http://linux.die.net/man/5/elf
    • - *
    • http://www.sco.com/developers/gabi/latest/contents.html
    • - *
    • http://infocenter.arm.com/ - *
        - *
      • ARM IHI 0044E, current through ABI release 2.09
      • - *
    • - *
    - *

    - */ -public class ElfHeader { - /** Size of e_ident array - {@value} */ - public static int EI_NIDENT = 16; - - /** ident byte #0 - {@value} */ - public static final byte ELFMAG0 = 0x7f; - /** ident byte #1 - {@value} */ - public static final byte ELFMAG1 = 'E'; - /** ident byte #2 - {@value} */ - public static final byte ELFMAG2 = 'L'; - /** ident byte #3 - {@value} */ - public static final byte ELFMAG3 = 'F'; - - /** ident byte #4 */ - public static final int EI_CLASS = 4; - public static final byte ELFCLASSNONE = 0; - public static final byte ELFCLASS32 = 1; - public static final byte ELFCLASS64 = 2; - - /** ident byte #5 */ - public static final int EI_DATA = 5; - public static final byte ELFDATANONE = 0; - public static final byte ELFDATA2LSB = 1; - public static final byte ELFDATA2MSB = 2; - - /** ident byte #6 */ - public static final int EI_VERSION = 6; - public static final byte EV_NONE = 0; - public static final byte EV_CURRENT = 1; - - /** ident byte #7 */ - public static final int EI_OSABI = 7; - /** Unix System V ABI - {@value} */ - public static final byte ELFOSABI_SYSV = 0; - public static final byte ELFOSABI_NONE = ELFOSABI_SYSV; - /** HP-UX ABI - {@value} */ - public static final byte ELFOSABI_HPUX = 1; - /** NetBSD ABI - {@value} **/ - public static final byte ELFOSABI_NETBSD = 2; - /** Linux ABI - {@value} **/ - public static final byte ELFOSABI_LINUX = 3; - /** Solaris ABI - {@value} **/ - public static final byte ELFOSABI_SOLARIS = 6; - /** IRIX ABI - {@value} **/ - public static final byte ELFOSABI_IRIX = 7; - /** FreeBSD ABI - {@value} **/ - public static final byte ELFOSABI_FREEBSD = 8; - /** ARM architecture ABI - {@value} **/ - public static final byte ELFOSABI_ARM = 8; // FIXME - /** Stand-alone (embedded) ABI - {@value} **/ - public static final byte ELFOSABI_STANDALONE = 9; // FIXME - /** TRU64 UNIX ABI - {@value} **/ - public static final byte ELFOSABI_TRU64 = 10; - /** Novell Modesto ABI - {@value} **/ - public static final byte ELFOSABI_MODESTO = 11; - /** Open BSD ABI - {@value} **/ - public static final byte ELFOSABI_OPENBSD = 12; - /** Open VMS ABI - {@value} **/ - public static final byte ELFOSABI_OPENVMS = 13; - /** Hewlett-Packard Non-Stop Kernel ABI - {@value} **/ - public static final byte ELFOSABI_NSK = 14; - /** Amiga Research OS ABI - {@value} **/ - public static final byte ELFOSABI_AROS = 15; - /** The FenixOS highly scalable multi-core OS 64-255 Architecture-specific value range - {@value} */ - public static final byte ELFOSABI_FENIXOS = 16; - - /** ident byte #8 - *

    - * This byte identifies the version of the ABI to which the object is targeted. - * This field is used to distinguish among incompatible versions of an ABI. - * The interpretation of this version number is dependent on the ABI identified by the EI_OSABI field. - * Applications conforming to this specification use the value 0. - *

    - */ - public static final int EI_ABIVERSION = 8; - - /** - * ident byte #9 .. ? - *

    - * Start of padding. - * These bytes are reserved and set to zero. - * Programs which read them should ignore them. - * The value for EI_PAD will change in the future if currently unused bytes are given meanings. - *

    - */ - public static final int EI_PAD = 9; - - /** - * This masks an 8-bit version number, the version of the ABI to which this - * ELF file conforms. This ABI is version 5. A value of 0 denotes unknown conformance. - * {@value} - */ - public static final int EF_ARM_ABIMASK = 0xFF000000; - public static final int EF_ARM_ABISHIFT = 24; - - /** - * ARM ABI version 5. - * {@value} - */ - public static final int EF_ARM_ABI5 = 0x05000000; - - /** - * The ELF file contains BE-8 code, suitable for execution on an ARM - * Architecture v6 processor. This flag must only be set on an executable file. - * {@value} - */ - public static final int EF_ARM_BE8 = 0x00800000; - - /** - * Legacy code (ABI version 4 and earlier) generated by gcc-arm-xxx might - * use these bits. - * {@value} - */ - public static final int EF_ARM_GCCMASK = 0x00400FFF; - - /** - * Set in executable file headers (e_type = ET_EXEC or ET_DYN) to note that - * the executable file was built to conform to the hardware floating-point - * procedure-call standard. - *

    - * Compatible with legacy (pre version 5) gcc use as EF_ARM_VFP_FLOAT. - *

    - *

    - * Note: This is not used (anymore) - *

    - * {@value} - */ - public static final int EF_ARM_ABI_FLOAT_HARD = 0x00000400; - - /** - * Set in executable file headers (e_type = ET_EXEC or ET_DYN) to note - * explicitly that the executable file was built to conform to the software - * floating-point procedure-call standard (the base standard). If both - * {@link #EF_ARM_ABI_FLOAT_HARD} and {@link #EF_ARM_ABI_FLOAT_SOFT} are clear, - * conformance to the base procedure-call standard is implied. - *

    - * Compatible with legacy (pre version 5) gcc use as EF_ARM_SOFT_FLOAT. - *

    - *

    - * Note: This is not used (anymore) - *

    - * {@value} - */ - public static final int EF_ARM_ABI_FLOAT_SOFT = 0x00000200; - - /** An unknown type - {@value} */ - public static final short ET_NONE = 0; - /** A relocatable file - {@value} */ - public static final short ET_REL = 1; - /** An executable file - {@value} */ - public static final short ET_EXEC = 2; - /** A shared object - {@value} */ - public static final short ET_DYN = 3; - /** A core file - {@value} */ - public static final short ET_CORE = 4; - - public static final short EM_NONE = 0; - public static final short EM_M32 = 1; - public static final short EM_SPARC = 2; - public static final short EM_386 = 3; - public static final short EM_68K = 4; - public static final short EM_88K = 5; - public static final short EM_486 = 6; - public static final short EM_860 = 7; - public static final short EM_MIPS = 8; - public static final short EM_S370 = 9; - public static final short EM_MIPS_RS3_LE = 10; - public static final short EM_PARISC = 15; - public static final short EM_res016 = 16; - public static final short EM_VPP550 = 17; - public static final short EM_SPARC32PLUS = 18; - public static final short EM_960 = 19; - public static final short EM_PPC = 20; - public static final short EM_PPC64 = 21; - public static final short EM_S390 = 22; - public static final short EM_SPU = 23; - public static final short EM_V800 = 36; - public static final short EM_FR20 = 37; - public static final short EM_RH32 = 38; - public static final short EM_MCORE = 39; - public static final short EM_RCE = 39; - public static final short EM_ARM = 40; - public static final short EM_OLD_ALPHA = 41; - public static final short EM_SH = 42; - public static final short EM_SPARCV9 = 43; - public static final short EM_TRICORE = 44; - public static final short EM_ARC = 45; - public static final short EM_H8_300 = 46; - public static final short EM_H8_300H = 47; - public static final short EM_H8S = 48; - public static final short EM_H8_500 = 49; - public static final short EM_IA_64 = 50; - public static final short EM_MIPS_X = 51; - public static final short EM_COLDFIRE = 52; - public static final short EM_68HC12 = 53; - public static final short EM_MMA = 54; - public static final short EM_PCP = 55; - public static final short EM_NCPU = 56; - public static final short EM_NDR1 = 57; - public static final short EM_STARCORE = 58; - public static final short EM_ME16 = 59; - public static final short EM_ST100 = 60; - public static final short EM_TINYJ = 61; - public static final short EM_X86_64 = 62; - public static final short EM_PDSP = 63; - public static final short EM_PDP10 = 64; - public static final short EM_PDP11 = 65; - public static final short EM_FX66 = 66; - public static final short EM_ST9PLUS = 67; - public static final short EM_ST7 = 68; - public static final short EM_68HC16 = 69; - public static final short EM_68HC11 = 70; - public static final short EM_68HC08 = 71; - public static final short EM_68HC05 = 72; - public static final short EM_SVX = 73; - public static final short EM_ST19 = 74; - public static final short EM_VAX = 75; - public static final short EM_CRIS = 76; - public static final short EM_JAVELIN = 77; - public static final short EM_FIREPATH = 78; - public static final short EM_ZSP = 79; - public static final short EM_MMIX = 80; - public static final short EM_HUANY = 81; - public static final short EM_PRISM = 82; - public static final short EM_AVR = 83; - public static final short EM_FR30 = 84; - public static final short EM_D10V = 85; - public static final short EM_D30V = 86; - public static final short EM_V850 = 87; - public static final short EM_M32R = 88; - public static final short EM_MN10300 = 89; - public static final short EM_MN10200 = 90; - public static final short EM_PJ = 91; - public static final short EM_OPENRISC = 92; - public static final short EM_ARC_A5 = 93; - public static final short EM_XTENSA = 94; - public static final short EM_VIDEOCORE = 95; - public static final short EM_TMM_GPP = 96; - public static final short EM_NS32K = 97; - public static final short EM_TPC = 98; - public static final short EM_SNP1K = 99; - public static final short EM_ST200 = 100; - public static final short EM_IP2K = 101; - public static final short EM_MAX = 102; - public static final short EM_CR = 103; - public static final short EM_F2MC16 = 104; - public static final short EM_MSP430 = 105; - public static final short EM_BLACKFIN = 106; - public static final short EM_SE_C33 = 107; - public static final short EM_SEP = 108; - public static final short EM_ARCA = 109; - public static final short EM_UNICORE = 110; - public static final short EM_EXCESS = 111; - public static final short EM_DXP = 112; - public static final short EM_ALTERA_NIOS2 = 113; - public static final short EM_CRX = 114; - public static final short EM_XGATE = 115; - public static final short EM_C166 = 116; - public static final short EM_M16C = 117; - public static final short EM_DSPIC30F = 118; - public static final short EM_CE = 119; - public static final short EM_M32C = 120; - public static final short EM_TSK3000 = 131; - public static final short EM_RS08 = 132; - public static final short EM_res133 = 133; - public static final short EM_ECOG2 = 134; - public static final short EM_SCORE = 135; - public static final short EM_SCORE7 = 135; - public static final short EM_DSP24 = 136; - public static final short EM_VIDEOCORE3 = 137; - public static final short EM_LATTICEMICO32 = 138; - public static final short EM_SE_C17 = 139; - public static final short EM_TI_C6000 = 140; - public static final short EM_TI_C2000 = 141; - public static final short EM_TI_C5500 = 142; - public static final short EM_MMDSP_PLUS = 160; - public static final short EM_CYPRESS_M8C = 161; - public static final short EM_R32C = 162; - public static final short EM_TRIMEDIA = 163; - public static final short EM_QDSP6 = 164; - public static final short EM_8051 = 165; - public static final short EM_STXP7X = 166; - public static final short EM_NDS32 = 167; - public static final short EM_ECOG1 = 168; - public static final short EM_ECOG1X = 168; - public static final short EM_MAXQ30 = 169; - public static final short EM_XIMO16 = 170; - public static final short EM_MANIK = 171; - public static final short EM_CRAYNV2 = 172; - public static final short EM_RX = 173; - public static final short EM_METAG = 174; - public static final short EM_MCST_ELBRUS = 175; - public static final short EM_ECOG16 = 176; - public static final short EM_CR16 = 177; - public static final short EM_ETPU = 178; - public static final short EM_SLE9X = 179; - public static final short EM_L1OM = 180; - public static final short EM_INTEL181 = 181; - public static final short EM_INTEL182 = 182; - public static final short EM_res183 = 183; - public static final short EM_res184 = 184; - public static final short EM_AVR32 = 185; - public static final short EM_STM8 = 186; - public static final short EM_TILE64 = 187; - public static final short EM_TILEPRO = 188; - public static final short EM_MICROBLAZE = 189; - public static final short EM_CUDA = 190; - - public static final boolean isIdentityValid(final byte[] ident) { - return ELFMAG0 == ident[0] && - ELFMAG1 == ident[1] && - ELFMAG2 == ident[2] && - ELFMAG3 == ident[3] ; - } - - /** Public access to the raw elf header */ - public final Ehdr d; - - /** Public access to the {@link SectionHeader} */ - public final SectionHeader[] sht; - - private final String string; - - /** - * Note: The input stream shall stay untouch to be able to read sections! - * - * @param in input stream of a binary file at position zero - * @return - * @throws IOException if reading from the given input stream fails or less then ELF Header size bytes - * @throws IllegalArgumentException if the given input stream does not represent an ELF Header - */ - public static ElfHeader read(final RandomAccessFile in) throws IOException, IllegalArgumentException { - final int eh_sz = Ehdr.size(); - final byte[] buf = new byte[eh_sz]; - readBytes (in, buf, 0, eh_sz); - final ElfHeader eh = new ElfHeader(ByteBuffer.wrap(buf, 0, buf.length), in); - return eh; - } - - /** - * @param buf ELF Header bytes - * @throws IllegalArgumentException if the given buffer does not represent an ELF Header - * @throws IOException - */ - ElfHeader(final java.nio.ByteBuffer buf, final RandomAccessFile in) throws IllegalArgumentException, IOException { - d = Ehdr.create(buf); - if( !isIdentityValid(d.getE_ident()) ) { - throw new IllegalArgumentException("Buffer is not an ELF Header"); - } - sht = readSectionHeaderTable(in); - string = toStringImpl(); - } - - public final short getSize() { return d.getE_ehsize(); } - - /** - * Returns the architecture class in bits, - * 32 for {@link #ELFCLASS32}, 64 for {@link #ELFCLASS64} - * and 0 for {@link #ELFCLASSNONE}. - */ - public final int getArchClassBits() { - switch( d.getE_ident()[EI_CLASS] ) { - case ELFCLASS32: return 32; - case ELFCLASS64: return 64; - default: return 0; - } - } - - /** - * Returns the processor's data encoding, i.e. - * {@link #ELFDATA2LSB}, {@link #ELFDATA2MSB} or {@link #ELFDATANONE}; - */ - public final byte getDataEncodingMode() { - return d.getE_ident()[EI_DATA]; - } - - /** Returns the ELF file version, should be {@link #EV_CURRENT}. */ - public final byte getVersion() { - return d.getE_ident()[EI_VERSION]; - } - - /** Returns the operating system and ABI for this file, 3 == Linux. Note: Often not used. */ - public final byte getOSABI() { - return d.getE_ident()[EI_OSABI]; - } - - /** Returns the version of the {@link #getOSABI() OSABI} for this file. */ - public final byte getOSABIVersion() { - return d.getE_ident()[EI_ABIVERSION]; - } - - /** Returns the object file type, e.g. {@link #ET_EXEC}, .. */ - public final short getType() { - return d.getE_type(); - } - - /** Returns the required architecture for the file, e.g. {@link #EM_386}, .. */ - public final short getMachine() { - return d.getE_machine(); - } - - /** - * Returns true if {@link #getMachine() machine} is a 32 or 64 bit ARM CPU - * of type {@link #EM_ARM}. */ - public final boolean isArm() { - return getMachine() == EM_ARM; - } - - /** - * Returns true if {@link #getMachine() machine} is a 32 or 64 bit Intel CPU - * of type {@link #EM_386}, {@link #EM_486} or {@link #EM_X86_64}. */ - public final boolean isX86_32() { - final short m = getMachine(); - return EM_386 == m || - EM_486 == m || - EM_X86_64 == m; - } - - /** - * Returns true if {@link #getMachine() machine} is a 64 bit AMD/Intel x86_64 CPU - * of type {@link #EM_X86_64}. */ - public final boolean isX86_64() { - return getMachine() == EM_X86_64; - } - - /** - * Returns true if {@link #getMachine() machine} is a 64 bit Intel Itanium CPU - * of type {@link #EM_IA_64}. */ - public final boolean isIA64() { - return getMachine() == EM_IA_64; - } - - /** - * Returns true if {@link #getMachine() machine} is a 32 or 64 bit MIPS CPU - * of type {@link #EM_MIPS}, {@link #EM_MIPS_X} or {@link #EM_MIPS_RS3_LE}. */ - public final boolean isMips() { - final short m = getMachine(); - return EM_MIPS == m || - EM_MIPS_X == m || - EM_MIPS_RS3_LE == m; - } - - /** Returns the processor-specific flags associated with the file. */ - public final int getFlags() { - return d.getE_flags(); - } - - /** Returns the ARM EABI version from {@link #getFlags() flags}, maybe 0 if not an ARM EABI. */ - public byte getArmABI() { - return (byte) ( ( ( EF_ARM_ABIMASK & d.getE_flags() ) >> EF_ARM_ABISHIFT ) & 0xff ); - } - - /** Returns the ARM EABI legacy GCC {@link #getFlags() flags}, maybe 0 if not an ARM EABI or not having legacy GCC flags. */ - public int getArmLegacyGCCFlags() { - final int f = d.getE_flags(); - return 0 != ( EF_ARM_ABIMASK & f ) ? ( EF_ARM_GCCMASK & f ) : 0; - } - - /** - * Returns the ARM EABI float mode from {@link #getFlags() flags}, - * i.e. 1 for {@link #EF_ARM_ABI_FLOAT_SOFT}, 2 for {@link #EF_ARM_ABI_FLOAT_HARD} - * or 0 for none. - *

    - * Note: This is not used (anymore) - *

    - */ - public byte getArmFloatMode() { - final int f = d.getE_flags(); - if( 0 != ( EF_ARM_ABIMASK & f ) ) { - if( ( EF_ARM_ABI_FLOAT_HARD & f ) != 0 ) { - return 2; - } - if( ( EF_ARM_ABI_FLOAT_SOFT & f ) != 0 ) { - return 1; - } - } - return 0; - } - - /** Returns the 1st occurence of matching SectionHeader {@link SectionHeader#getType() type}, or null if not exists. */ - public final SectionHeader getSectionHeader(final int type) { - for(int i=0; i= num ) { - throw new IllegalArgumentException("EHdr sh_num == 0 and 1st SHdr size == 0"); - } - sht = new SectionHeader[num]; - sht[0] = sh0; - i=1; - } else { - num = d.getE_shnum(); - sht = new SectionHeader[num]; - i=0; - } - for(; i + * Part-1 can be read w/o knowledge of CPUType! + *

    + *

    + * References: + *

      + *
    • http://www.sco.com/developers/gabi/latest/contents.html
    • + *
    • https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
    • + *
    • http://linux.die.net/man/5/elf
    • + *
    • http://infocenter.arm.com/ + *
        + *
      • ARM IHI 0044E, current through ABI release 2.09
      • + *
      • ARM IHI 0056B: Elf for ARM 64-bit Architecture
      • + *
    • + *
    + *

    + */ +public class ElfHeaderPart1 { + static final boolean DEBUG = Debug.debug("Platform"); + + /** Size of e_ident array - {@value} */ + public static int EI_NIDENT = 16; + + /** ident byte #0 - {@value} */ + public static final byte ELFMAG0 = 0x7f; + /** ident byte #1 - {@value} */ + public static final byte ELFMAG1 = 'E'; + /** ident byte #2 - {@value} */ + public static final byte ELFMAG2 = 'L'; + /** ident byte #3 - {@value} */ + public static final byte ELFMAG3 = 'F'; + + /** ident byte #4 */ + public static final int EI_CLASS = 4; + public static final byte ELFCLASSNONE = 0; + public static final byte ELFCLASS32 = 1; + public static final byte ELFCLASS64 = 2; + + /** ident byte #5 */ + public static final int EI_DATA = 5; + public static final byte ELFDATANONE = 0; + public static final byte ELFDATA2LSB = 1; + public static final byte ELFDATA2MSB = 2; + + /** ident byte #6 */ + public static final int EI_VERSION = 6; + public static final byte EV_NONE = 0; + public static final byte EV_CURRENT = 1; + + /** ident byte #7 */ + public static final int EI_OSABI = 7; + /** Unix System V ABI - {@value} */ + public static final byte ELFOSABI_SYSV = 0; + public static final byte ELFOSABI_NONE = ELFOSABI_SYSV; + /** HP-UX ABI - {@value} */ + public static final byte ELFOSABI_HPUX = 1; + /** NetBSD ABI - {@value} **/ + public static final byte ELFOSABI_NETBSD = 2; + /** Linux ABI - {@value} **/ + public static final byte ELFOSABI_LINUX = 3; + /** Solaris ABI - {@value} **/ + public static final byte ELFOSABI_SOLARIS = 6; + /** IRIX ABI - {@value} **/ + public static final byte ELFOSABI_IRIX = 7; + /** FreeBSD ABI - {@value} **/ + public static final byte ELFOSABI_FREEBSD = 8; + /** ARM architecture ABI - {@value} **/ + public static final byte ELFOSABI_ARM = 8; // FIXME + /** Stand-alone (embedded) ABI - {@value} **/ + public static final byte ELFOSABI_STANDALONE = 9; // FIXME + /** TRU64 UNIX ABI - {@value} **/ + public static final byte ELFOSABI_TRU64 = 10; + /** Novell Modesto ABI - {@value} **/ + public static final byte ELFOSABI_MODESTO = 11; + /** Open BSD ABI - {@value} **/ + public static final byte ELFOSABI_OPENBSD = 12; + /** Open VMS ABI - {@value} **/ + public static final byte ELFOSABI_OPENVMS = 13; + /** Hewlett-Packard Non-Stop Kernel ABI - {@value} **/ + public static final byte ELFOSABI_NSK = 14; + /** Amiga Research OS ABI - {@value} **/ + public static final byte ELFOSABI_AROS = 15; + /** The FenixOS highly scalable multi-core OS 64-255 Architecture-specific value range - {@value} */ + public static final byte ELFOSABI_FENIXOS = 16; + + /** ident byte #8 + *

    + * This byte identifies the version of the ABI to which the object is targeted. + * This field is used to distinguish among incompatible versions of an ABI. + * The interpretation of this version number is dependent on the ABI identified by the EI_OSABI field. + * Applications conforming to this specification use the value 0. + *

    + */ + public static final int EI_ABIVERSION = 8; + + /** + * ident byte #9 .. ? + *

    + * Start of padding. + * These bytes are reserved and set to zero. + * Programs which read them should ignore them. + * The value for EI_PAD will change in the future if currently unused bytes are given meanings. + *

    + */ + public static final int EI_PAD = 9; + + /** An unknown type - {@value} */ + public static final short ET_NONE = 0; + /** A relocatable file - {@value} */ + public static final short ET_REL = 1; + /** An executable file - {@value} */ + public static final short ET_EXEC = 2; + /** A shared object - {@value} */ + public static final short ET_DYN = 3; + /** A core file - {@value} */ + public static final short ET_CORE = 4; + + public static final short EM_NONE = 0; + public static final short EM_M32 = 1; + public static final short EM_SPARC = 2; + public static final short EM_386 = 3; + public static final short EM_68K = 4; + public static final short EM_88K = 5; + public static final short EM_486 = 6; + public static final short EM_860 = 7; + public static final short EM_MIPS = 8; + public static final short EM_S370 = 9; + public static final short EM_MIPS_RS3_LE = 10; + public static final short EM_PARISC = 15; + public static final short EM_res016 = 16; + public static final short EM_VPP550 = 17; + public static final short EM_SPARC32PLUS = 18; + public static final short EM_960 = 19; + public static final short EM_PPC = 20; + public static final short EM_PPC64 = 21; + public static final short EM_S390 = 22; + public static final short EM_SPU = 23; + public static final short EM_V800 = 36; + public static final short EM_FR20 = 37; + public static final short EM_RH32 = 38; + public static final short EM_MCORE = 39; + public static final short EM_RCE = 39; + public static final short EM_ARM = 40; + public static final short EM_OLD_ALPHA = 41; + public static final short EM_SH = 42; + public static final short EM_SPARCV9 = 43; + public static final short EM_TRICORE = 44; + public static final short EM_ARC = 45; + public static final short EM_H8_300 = 46; + public static final short EM_H8_300H = 47; + public static final short EM_H8S = 48; + public static final short EM_H8_500 = 49; + public static final short EM_IA_64 = 50; + public static final short EM_MIPS_X = 51; + public static final short EM_COLDFIRE = 52; + public static final short EM_68HC12 = 53; + public static final short EM_MMA = 54; + public static final short EM_PCP = 55; + public static final short EM_NCPU = 56; + public static final short EM_NDR1 = 57; + public static final short EM_STARCORE = 58; + public static final short EM_ME16 = 59; + public static final short EM_ST100 = 60; + public static final short EM_TINYJ = 61; + public static final short EM_X86_64 = 62; + public static final short EM_PDSP = 63; + public static final short EM_PDP10 = 64; + public static final short EM_PDP11 = 65; + public static final short EM_FX66 = 66; + public static final short EM_ST9PLUS = 67; + public static final short EM_ST7 = 68; + public static final short EM_68HC16 = 69; + public static final short EM_68HC11 = 70; + public static final short EM_68HC08 = 71; + public static final short EM_68HC05 = 72; + public static final short EM_SVX = 73; + public static final short EM_ST19 = 74; + public static final short EM_VAX = 75; + public static final short EM_CRIS = 76; + public static final short EM_JAVELIN = 77; + public static final short EM_FIREPATH = 78; + public static final short EM_ZSP = 79; + public static final short EM_MMIX = 80; + public static final short EM_HUANY = 81; + public static final short EM_PRISM = 82; + public static final short EM_AVR = 83; + public static final short EM_FR30 = 84; + public static final short EM_D10V = 85; + public static final short EM_D30V = 86; + public static final short EM_V850 = 87; + public static final short EM_M32R = 88; + public static final short EM_MN10300 = 89; + public static final short EM_MN10200 = 90; + public static final short EM_PJ = 91; + public static final short EM_OPENRISC = 92; + public static final short EM_ARC_A5 = 93; + public static final short EM_XTENSA = 94; + public static final short EM_VIDEOCORE = 95; + public static final short EM_TMM_GPP = 96; + public static final short EM_NS32K = 97; + public static final short EM_TPC = 98; + public static final short EM_SNP1K = 99; + public static final short EM_ST200 = 100; + public static final short EM_IP2K = 101; + public static final short EM_MAX = 102; + public static final short EM_CR = 103; + public static final short EM_F2MC16 = 104; + public static final short EM_MSP430 = 105; + public static final short EM_BLACKFIN = 106; + public static final short EM_SE_C33 = 107; + public static final short EM_SEP = 108; + public static final short EM_ARCA = 109; + public static final short EM_UNICORE = 110; + public static final short EM_EXCESS = 111; + public static final short EM_DXP = 112; + public static final short EM_ALTERA_NIOS2 = 113; + public static final short EM_CRX = 114; + public static final short EM_XGATE = 115; + public static final short EM_C166 = 116; + public static final short EM_M16C = 117; + public static final short EM_DSPIC30F = 118; + public static final short EM_CE = 119; + public static final short EM_M32C = 120; + public static final short EM_TSK3000 = 131; + public static final short EM_RS08 = 132; + public static final short EM_res133 = 133; + public static final short EM_ECOG2 = 134; + public static final short EM_SCORE = 135; + public static final short EM_SCORE7 = 135; + public static final short EM_DSP24 = 136; + public static final short EM_VIDEOCORE3 = 137; + public static final short EM_LATTICEMICO32 = 138; + public static final short EM_SE_C17 = 139; + public static final short EM_TI_C6000 = 140; + public static final short EM_TI_C2000 = 141; + public static final short EM_TI_C5500 = 142; + public static final short EM_MMDSP_PLUS = 160; + public static final short EM_CYPRESS_M8C = 161; + public static final short EM_R32C = 162; + public static final short EM_TRIMEDIA = 163; + public static final short EM_QDSP6 = 164; + public static final short EM_8051 = 165; + public static final short EM_STXP7X = 166; + public static final short EM_NDS32 = 167; + public static final short EM_ECOG1 = 168; + public static final short EM_ECOG1X = 168; + public static final short EM_MAXQ30 = 169; + public static final short EM_XIMO16 = 170; + public static final short EM_MANIK = 171; + public static final short EM_CRAYNV2 = 172; + public static final short EM_RX = 173; + public static final short EM_METAG = 174; + public static final short EM_MCST_ELBRUS = 175; + public static final short EM_ECOG16 = 176; + public static final short EM_CR16 = 177; + public static final short EM_ETPU = 178; + public static final short EM_SLE9X = 179; + public static final short EM_L1OM = 180; + public static final short EM_INTEL181 = 181; + public static final short EM_INTEL182 = 182; + public static final short EM_AARCH64 = 183; + public static final short EM_ARM184 = 184; + public static final short EM_AVR32 = 185; + public static final short EM_STM8 = 186; + public static final short EM_TILE64 = 187; + public static final short EM_TILEPRO = 188; + public static final short EM_MICROBLAZE = 189; + public static final short EM_CUDA = 190; + + public static final boolean isIdentityValid(final byte[] ident) { + return ELFMAG0 == ident[0] && + ELFMAG1 == ident[1] && + ELFMAG2 == ident[2] && + ELFMAG3 == ident[3] ; + } + + /** Public access to the raw elf header part-1 (CPU/ABI independent read) */ + public final Ehdr_p1 raw; + private final byte[] E_ident; + + /** Lower case CPUType name */ + public final String cpuName; + public final CPUType cpuType; + public final ABIType abiType; + + public final MachineDataInfo.StaticConfig machDesc; + + /** + * Note: The input stream shall stay untouch to be able to read sections! + * @param osType TODO + * @param in input stream of a binary file at position zero + * + * @return + * @throws IOException if reading from the given input stream fails or less then ELF Header size bytes + * @throws IllegalArgumentException if the given input stream does not represent an ELF Header + */ + public static ElfHeaderPart1 read(final OSType osType, final RandomAccessFile in) throws IOException, IllegalArgumentException { + return new ElfHeaderPart1(osType, in); + } + + /** + * @param osType TODO + * @param buf ELF Header bytes + * @throws IllegalArgumentException if the given buffer does not represent an ELF Header + * @throws IOException + */ + ElfHeaderPart1(final OSType osType, final RandomAccessFile in) throws IllegalArgumentException, IOException { + { + final byte[] buf = new byte[Ehdr_p1.size()]; + readBytes (in, buf, 0, buf.length); + final ByteBuffer eh1Bytes = ByteBuffer.wrap(buf, 0, buf.length); + raw = Ehdr_p1.create(eh1Bytes); + } + E_ident = raw.getE_ident(0, new byte[Ehdr_p1.getE_identArrayLength()]); + if( !isIdentityValid(E_ident) ) { + throw new IllegalArgumentException("Buffer is not an ELF Header"); + } + + final short machine = getMachine(); + switch ( machine ) { + case EM_ARM: + cpuName = "arm"; // lowest 32bit denominator, ok for now + abiType = ABIType.GENERIC_ABI; + break; + case EM_AARCH64: + cpuName = "aarch64"; + abiType = ABIType.EABI_AARCH64; + break; + case EM_X86_64: + cpuName = "x86_64"; + abiType = ABIType.GENERIC_ABI; + break; + case EM_386: + cpuName = "i386"; + abiType = ABIType.GENERIC_ABI; + break; + case EM_486: + cpuName = "i486"; + abiType = ABIType.GENERIC_ABI; + break; + case EM_IA_64: + cpuName = "ia64"; + abiType = ABIType.GENERIC_ABI; + break; + case EM_MIPS: + // Can be little-endian or big-endian and 32 or 64 bits + if( 64 == getArchClassBits() ) { + cpuName = isLittleEndian() ? "mips64le" : "mips64"; + } else { + cpuName = isLittleEndian() ? "mipsle" : "mips"; + } + abiType = ABIType.GENERIC_ABI; + break; + case EM_MIPS_RS3_LE: + cpuName = "mipsle-rs3"; // FIXME: Only little-endian? + abiType = ABIType.GENERIC_ABI; + break; + case EM_MIPS_X: + cpuName = isLittleEndian() ? "mipsle-x" : "mips-x"; // Can be little-endian + abiType = ABIType.GENERIC_ABI; + break; + case EM_PPC: + cpuName = "ppc"; + abiType = ABIType.GENERIC_ABI; + break; + case EM_PPC64: + cpuName = "ppc64"; + abiType = ABIType.GENERIC_ABI; + break; + case EM_SH: + cpuName = "superh"; + abiType = ABIType.GENERIC_ABI; + break; + default: + throw new IllegalArgumentException("CPUType and ABIType could not be determined"); + } + cpuType = CPUType.query(cpuName.toLowerCase()); + machDesc = MachineDataInfoRuntime.guessStaticMachineDataInfo(osType, cpuType); + if(DEBUG) { + System.err.println("ELF-1: cpuName "+cpuName+" -> "+cpuType+", "+abiType+", machDesc "+machDesc.toShortString()); + } + } + + /** + * Returns the architecture class in bits, + * 32 for {@link #ELFCLASS32}, 64 for {@link #ELFCLASS64} + * and 0 for {@link #ELFCLASSNONE}. + */ + public final int getArchClassBits() { + switch( E_ident[EI_CLASS] ) { + case ELFCLASS32: return 32; + case ELFCLASS64: return 64; + default: return 0; + } + } + + /** + * Returns the processor's data encoding, i.e. + * {@link #ELFDATA2LSB}, {@link #ELFDATA2MSB} or {@link #ELFDATANONE}; + */ + public final byte getDataEncodingMode() { + return E_ident[EI_DATA]; + } + + /** + * Returns whether the processor's {@link #getDataEncodingMode() data encoding} is {@link #ELFDATA2LSB}. + */ + public final boolean isLittleEndian() { return ELFDATA2LSB == E_ident[EI_DATA]; } + /** + * Returns whether the processor's {@link #getDataEncodingMode() data encoding} is {@link #ELFDATA2MSB}. + */ + public final boolean isBigEndian() { return ELFDATA2MSB == E_ident[EI_DATA]; } + /** + * Returns whether the processor's {@link #getDataEncodingMode() data encoding} is {@link #ELFDATANONE}. + */ + public final boolean isNoneEndian() { return ELFDATANONE == E_ident[EI_DATA]; } + + /** Returns the ELF file version, should be {@link #EV_CURRENT}. */ + public final byte getVersion() { + return E_ident[EI_VERSION]; + } + + /** Returns the operating system and ABI for this file, 3 == Linux. Note: Often not used. */ + public final byte getOSABI() { + return E_ident[EI_OSABI]; + } + + /** Returns the version of the {@link #getOSABI() OSABI} for this file. */ + public final byte getOSABIVersion() { + return E_ident[EI_ABIVERSION]; + } + + /** Returns the object file type, e.g. {@link #ET_EXEC}, .. */ + public final short getType() { + return raw.getE_type(); + } + + /** Returns the required architecture for the file, e.g. {@link #EM_386}, .. */ + public final short getMachine() { + return raw.getE_machine(); + } + + @Override + public final String toString() { + final int enc = getDataEncodingMode(); + final String encS; + switch(enc) { + case ELFDATA2LSB: encS = "LSB"; break; + case ELFDATA2MSB: encS = "MSB"; break; + default: encS = "NON"; break; /* ELFDATANONE */ + } + final int type = getType(); + final String typeS; + switch(type) { + case ET_REL: typeS = "reloc"; break; + case ET_EXEC: typeS = "exec"; break; + case ET_DYN: typeS = "shared"; break; + case ET_CORE: typeS = "core"; break; + default: typeS = "none"; break; /* ET_NONE */ + } + return "ELF-1[vers "+getVersion()+", machine["+getMachine()+", "+cpuType+", "+abiType+", machDesc "+machDesc.toShortString()+"], bits "+getArchClassBits()+", enc "+encS+ + ", abi[os "+getOSABI()+", vers "+getOSABIVersion()+"], type "+typeS+"]"; + } +} diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/elf/ElfHeaderPart2.java gluegen2-2.3.2/src/java/jogamp/common/os/elf/ElfHeaderPart2.java --- gluegen2-2.2.4/src/java/jogamp/common/os/elf/ElfHeaderPart2.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/elf/ElfHeaderPart2.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,375 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.common.os.elf; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; + +import com.jogamp.common.os.Platform.ABIType; +import com.jogamp.common.os.Platform.CPUFamily; +import com.jogamp.common.os.Platform.CPUType; + +import static jogamp.common.os.elf.IOUtils.readBytes; +import static jogamp.common.os.elf.IOUtils.seek; +import static jogamp.common.os.elf.IOUtils.shortToInt; +import static jogamp.common.os.elf.IOUtils.toHexString; + +/** + * ELF ABI Header Part-2 + *

    + * Part-2 can only be read w/ knowledge of CPUType! + *

    + *

    + * References: + *

      + *
    • http://www.sco.com/developers/gabi/latest/contents.html
    • + *
    • https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
    • + *
    • http://linux.die.net/man/5/elf
    • + *
    • http://infocenter.arm.com/ + *
        + *
      • ARM IHI 0044E, current through ABI release 2.09
      • + *
      • ARM IHI 0056B: Elf for ARM 64-bit Architecture
      • + *
    • + *
    + *

    + */ +public class ElfHeaderPart2 { + /** + * This masks an 8-bit version number, the version of the ABI to which this + * ELF file conforms. This ABI is version 5. A value of 0 denotes unknown conformance. + * {@value} + */ + public static final int EF_ARM_ABIMASK = 0xFF000000; + public static final int EF_ARM_ABISHIFT = 24; + + /** + * ARM ABI version 5. + * {@value} + */ + public static final int EF_ARM_ABI5 = 0x05000000; + + /** + * The ELF file contains BE-8 code, suitable for execution on an ARM + * Architecture v6 processor. This flag must only be set on an executable file. + * {@value} + */ + public static final int EF_ARM_BE8 = 0x00800000; + + /** + * Legacy code (ABI version 4 and earlier) generated by gcc-arm-xxx might + * use these bits. + * {@value} + */ + public static final int EF_ARM_GCCMASK = 0x00400FFF; + + /** + * Set in executable file headers (e_type = ET_EXEC or ET_DYN) to note that + * the executable file was built to conform to the hardware floating-point + * procedure-call standard. + *

    + * Compatible with legacy (pre version 5) gcc use as EF_ARM_VFP_FLOAT. + *

    + *

    + * Note: This is not used (anymore) + *

    + * {@value} + */ + public static final int EF_ARM_ABI_FLOAT_HARD = 0x00000400; + + /** + * Set in executable file headers (e_type = ET_EXEC or ET_DYN) to note + * explicitly that the executable file was built to conform to the software + * floating-point procedure-call standard (the base standard). If both + * {@link #EF_ARM_ABI_FLOAT_HARD} and {@link #EF_ARM_ABI_FLOAT_SOFT} are clear, + * conformance to the base procedure-call standard is implied. + *

    + * Compatible with legacy (pre version 5) gcc use as EF_ARM_SOFT_FLOAT. + *

    + *

    + * Note: This is not used (anymore) + *

    + * {@value} + */ + public static final int EF_ARM_ABI_FLOAT_SOFT = 0x00000200; + + /** Public access to the elf header part-1 (CPU/ABI independent read) */ + public final ElfHeaderPart1 eh1; + + /** Public access to the raw elf header part-2 (CPU/ABI dependent read) */ + public final Ehdr_p2 raw; + + /** Lower case CPUType name */ + public final String cpuName; + public final CPUType cpuType; + public final ABIType abiType; + + /** Public access to the {@link SectionHeader} */ + public final SectionHeader[] sht; + + /** + * Note: The input stream shall stay untouch to be able to read sections! + * + * @param in input stream of a binary file at position zero + * @return + * @throws IOException if reading from the given input stream fails or less then ELF Header size bytes + * @throws IllegalArgumentException if the given input stream does not represent an ELF Header + */ + public static ElfHeaderPart2 read(final ElfHeaderPart1 eh1, final RandomAccessFile in) throws IOException, IllegalArgumentException { + return new ElfHeaderPart2(eh1, in); + } + + /** + * @param buf ELF Header bytes + * @throws IllegalArgumentException if the given buffer does not represent an ELF Header + * @throws IOException + */ + ElfHeaderPart2(final ElfHeaderPart1 eh1, final RandomAccessFile in) throws IllegalArgumentException, IOException { + this.eh1 = eh1; + // + // Part-2 + // + { + final byte[] buf = new byte[Ehdr_p2.size(eh1.machDesc.ordinal())]; + readBytes (in, buf, 0, buf.length); + final ByteBuffer eh2Bytes = ByteBuffer.wrap(buf, 0, buf.length); + raw = Ehdr_p2.create(eh1.machDesc.ordinal(), eh2Bytes); + } + sht = readSectionHeaderTable(in); + + if( CPUFamily.ARM == eh1.cpuType.family && eh1.cpuType.is32Bit ) { + // AArch64, has no SHT_ARM_ATTRIBUTES or SHT_AARCH64_ATTRIBUTES SectionHeader defined in our builds! + String armCpuName = null; + String armCpuRawName = null; + boolean abiVFPArgsAcceptsVFPVariant = false; + final SectionHeader sh = getSectionHeader(SectionHeader.SHT_ARM_ATTRIBUTES); + if(ElfHeaderPart1.DEBUG) { + System.err.println("ELF-2: Got ARM Attribs Section Header: "+sh); + } + if( null != sh ) { + final SectionArmAttributes sArmAttrs = (SectionArmAttributes) sh.readSection(in); + if(ElfHeaderPart1.DEBUG) { + System.err.println("ELF-2: Got ARM Attribs Section Block : "+sArmAttrs); + } + final SectionArmAttributes.Attribute cpuNameArgsAttr = sArmAttrs.get(SectionArmAttributes.Tag.CPU_name); + if( null != cpuNameArgsAttr && cpuNameArgsAttr.isNTBS() ) { + armCpuName = cpuNameArgsAttr.getNTBS(); + } + final SectionArmAttributes.Attribute cpuRawNameArgsAttr = sArmAttrs.get(SectionArmAttributes.Tag.CPU_raw_name); + if( null != cpuRawNameArgsAttr && cpuRawNameArgsAttr.isNTBS() ) { + armCpuRawName = cpuRawNameArgsAttr.getNTBS(); + } + final SectionArmAttributes.Attribute abiVFPArgsAttr = sArmAttrs.get(SectionArmAttributes.Tag.ABI_VFP_args); + if( null != abiVFPArgsAttr ) { + abiVFPArgsAcceptsVFPVariant = SectionArmAttributes.abiVFPArgsAcceptsVFPVariant(abiVFPArgsAttr.getULEB128()); + } + } + { + String _cpuName; + if( null != armCpuName && armCpuName.length() > 0 ) { + _cpuName = armCpuName.toLowerCase().replace(' ', '-'); + } else if( null != armCpuRawName && armCpuRawName.length() > 0 ) { + _cpuName = armCpuRawName.toLowerCase().replace(' ', '-'); + } else { + _cpuName = eh1.cpuName; + } + + // 1st-try: native name + CPUType _cpuType = queryCPUTypeSafe(_cpuName); + if( null == _cpuType ) { + // 2nd-try: "arm-" + native name + _cpuName = "arm-"+_cpuName; + _cpuType = queryCPUTypeSafe(_cpuName); + if( null == _cpuType ) { + // finally: Use ELF-1 + _cpuName = eh1.cpuName; + _cpuType = queryCPUTypeSafe(_cpuName); + if( null == _cpuType ) { + throw new InternalError("XXX: "+_cpuName+", "+eh1); // shall not happen + } + } + } + cpuName = _cpuName; + cpuType = _cpuType; + if(ElfHeaderPart1.DEBUG) { + System.err.println("ELF-2: abiARM cpuName "+_cpuName+"[armCpuName "+armCpuName+", armCpuRawName "+armCpuRawName+"] -> "+cpuName+" -> "+cpuType+", abiVFPArgsAcceptsVFPVariant "+abiVFPArgsAcceptsVFPVariant); + } + } + if( cpuType.is32Bit ) { // always true, see above! + abiType = abiVFPArgsAcceptsVFPVariant ? ABIType.EABI_GNU_ARMHF : ABIType.EABI_GNU_ARMEL; + } else { + abiType = eh1.abiType; + } + } else { + cpuName = eh1.cpuName; + cpuType = eh1.cpuType; + abiType = eh1.abiType; + } + if(ElfHeaderPart1.DEBUG) { + System.err.println("ELF-2: cpuName "+cpuName+" -> "+cpuType+", "+abiType); + } + } + private static CPUType queryCPUTypeSafe(final String cpuName) { + CPUType res = null; + try { + res = CPUType.query(cpuName); + } catch (final Throwable t) { + if(ElfHeaderPart1.DEBUG) { + System.err.println("ELF-2: queryCPUTypeSafe("+cpuName+"): "+t.getMessage()); + } + } + return res; + } + + public final short getSize() { return raw.getE_ehsize(); } + + /** Returns the processor-specific flags associated with the file. */ + public final int getFlags() { + return raw.getE_flags(); + } + + /** Returns the ARM EABI version from {@link #getFlags() flags}, maybe 0 if not an ARM EABI. */ + public byte getArmABI() { + return (byte) ( ( ( EF_ARM_ABIMASK & raw.getE_flags() ) >> EF_ARM_ABISHIFT ) & 0xff ); + } + + /** Returns the ARM EABI legacy GCC {@link #getFlags() flags}, maybe 0 if not an ARM EABI or not having legacy GCC flags. */ + public int getArmLegacyGCCFlags() { + final int f = raw.getE_flags(); + return 0 != ( EF_ARM_ABIMASK & f ) ? ( EF_ARM_GCCMASK & f ) : 0; + } + + /** + * Returns the ARM EABI float mode from {@link #getFlags() flags}, + * i.e. 1 for {@link #EF_ARM_ABI_FLOAT_SOFT}, 2 for {@link #EF_ARM_ABI_FLOAT_HARD} + * or 0 for none. + *

    + * Note: This is not used (anymore) + *

    + */ + public byte getArmFloatMode() { + final int f = raw.getE_flags(); + if( 0 != ( EF_ARM_ABIMASK & f ) ) { + if( ( EF_ARM_ABI_FLOAT_HARD & f ) != 0 ) { + return 2; + } + if( ( EF_ARM_ABI_FLOAT_SOFT & f ) != 0 ) { + return 1; + } + } + return 0; + } + + /** Returns the 1st occurence of matching SectionHeader {@link SectionHeader#getType() type}, or null if not exists. */ + public final SectionHeader getSectionHeader(final int type) { + for(int i=0; i= num ) { + throw new IllegalArgumentException("EHdr sh_num == 0 and 1st SHdr size == 0"); + } + sht = new SectionHeader[num]; + sht[0] = sh0; + i=1; + } else { + num = raw.getE_shnum(); + sht = new SectionHeader[num]; + i=0; + } + for(; i v ) { throw new IllegalArgumentException("Read uint32 value "+toHexString(v)+" > int32-max "+toHexString(MAX_INT_VALUE)); } return v; - /** Need to fix endian for below path .. - checkBounds(in, offset, 4); - final byte[] uint = new byte[] { 0, 0, 0, 0, in[offset+0], in[offset+1], in[offset+2], in[offset+3] }; - final ByteBuffer b = ByteBuffer.wrap(uint, 0, 8).order(ByteOrder.nativeOrder()); - return b.asLongBuffer().get(0); */ } /** diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/elf/SectionArmAttributes.java gluegen2-2.3.2/src/java/jogamp/common/os/elf/SectionArmAttributes.java --- gluegen2-2.2.4/src/java/jogamp/common/os/elf/SectionArmAttributes.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/elf/SectionArmAttributes.java 2015-10-09 04:18:28.000000000 +0000 @@ -1,3 +1,30 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ package jogamp.common.os.elf; import static jogamp.common.os.elf.IOUtils.toHexString; @@ -172,7 +199,7 @@ SectionArmAttributes(final SectionHeader sh, final byte[] data, final int offset, final int length) throws IndexOutOfBoundsException, IllegalArgumentException { super(sh, data, offset, length); - this.vendorAttributesList = parse(data, offset, length); + this.vendorAttributesList = parse(sh, data, offset, length); } @Override @@ -208,6 +235,7 @@ } /** + * @param sh TODO * @param in byte source buffer to parse * @param offset offset within byte source buffer to start parsing * @param remaining remaining numbers of bytes to parse beginning w/ sb_off, @@ -215,7 +243,7 @@ * @throws IndexOutOfBoundsException if offset + remaining > sb.length. * @throws IllegalArgumentException if section parsing failed, i.e. incompatible version or data. */ - static List parse(final byte[] in, final int offset, final int remaining) throws IndexOutOfBoundsException, IllegalArgumentException { + static List parse(final SectionHeader sh, final byte[] in, final int offset, final int remaining) throws IndexOutOfBoundsException, IllegalArgumentException { Bitstream.checkBounds(in, offset, remaining); int i = offset; if( FORMAT_VERSION_A != in[ i ] ) { @@ -224,10 +252,11 @@ i++; final List vendorAttributesList = new ArrayList(); + final boolean isBigEndian = sh.eh2.eh1.isBigEndian(); while(i < remaining) { final int i_pre = i; - final int secLen = readUInt32(in, i); /* total section size: 4 + string + content, i.e. offset to next section */ + final int secLen = readUInt32(isBigEndian, in, i); /* total section size: 4 + string + content, i.e. offset to next section */ i+=4; final String vendor; @@ -241,7 +270,7 @@ while(i < secLen) { final int[] i_post = new int[] { 0 }; - parseSub(in, i, secLen - i, i_post, attributes); + parseSub(isBigEndian, in, i, secLen - i, i_post, attributes); i = i_post[0]; } @@ -261,6 +290,7 @@ } /** + * @param isBigEndian TODO * @param in byte source buffer to parse * @param offset offset within byte source buffer to start parsing * @param remaining remaining numbers of bytes to parse beginning w/ sb_off, @@ -268,7 +298,10 @@ * @throws IndexOutOfBoundsException if offset + remaining > sb.length. * @throws IllegalArgumentException if section parsing failed, i.e. incompatible version or data. */ - static void parseSub(final byte[] in, final int offset, final int remaining, final int[] offset_post, final List attributes) throws IndexOutOfBoundsException, IllegalArgumentException { + private static void parseSub(final boolean isBigEndian, final byte[] in, final int offset, final int remaining, + final int[] offset_post, final List attributes) + throws IndexOutOfBoundsException, IllegalArgumentException + { Bitstream.checkBounds(in, offset, remaining); // Starts w/ sub-section Tag @@ -283,7 +316,7 @@ case File: case Section: case Symbol: - subSecLen = readUInt32(in, i); + subSecLen = readUInt32(isBigEndian, in, i); i+=4; break; default: diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/elf/SectionHeader.java gluegen2-2.3.2/src/java/jogamp/common/os/elf/SectionHeader.java --- gluegen2-2.2.4/src/java/jogamp/common/os/elf/SectionHeader.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/elf/SectionHeader.java 2015-10-09 04:18:28.000000000 +0000 @@ -133,6 +133,12 @@ * {@value} */ public static final int SHT_ARM_ATTRIBUTES = 0x70000003; + + /** + * {@value}. FIXME: Same as {@link #SHT_ARM_ATTRIBUTES}, ok? + */ + public static final int SHT_AARCH64_ATTRIBUTES = 0x70000003; + /** * {@value} */ @@ -171,24 +177,28 @@ */ public static final short SHN_HIRESERVE = (short)0xffff; + /** Public access to the elf header */ + public final ElfHeaderPart2 eh2; + /** Public access to the raw elf section header */ - public final Shdr d; + public final Shdr raw; private final int idx; private String name; - SectionHeader(final byte[] buf, final int offset, final int length, final int sectionIdx) { - this( ByteBuffer.wrap(buf, 0, buf.length), sectionIdx ); + SectionHeader(final ElfHeaderPart2 eh, final byte[] buf, final int offset, final int length, final int sectionIdx) { + this( eh, ByteBuffer.wrap(buf, 0, buf.length), sectionIdx ); } - SectionHeader(final java.nio.ByteBuffer buf, final int idx) { - d = Shdr.create(buf); + SectionHeader(final ElfHeaderPart2 eh, final java.nio.ByteBuffer buf, final int idx) { + this.eh2 = eh; + this.raw = Shdr.create(eh.eh1.machDesc.ordinal(), buf); this.idx = idx; - name = null; + this.name = null; } @Override public String toString() { - return "SectionHeader[idx "+idx+", name "+name+", type "+toHexString(getType())+", link "+d.getSh_link()+", info "+toHexString(d.getSh_info())+", flags "+toHexString(getFlags())+"]"; + return "SectionHeader[idx "+idx+", name "+name+", type "+toHexString(getType())+", link "+raw.getSh_link()+", info "+toHexString(raw.getSh_info())+", flags "+toHexString(getFlags())+"]"; } /** @@ -206,17 +216,17 @@ /** Returns the type of this section. */ public int getType() { - return d.getSh_type(); + return raw.getSh_type(); } /** Returns the flags of this section. */ public long getFlags() { - return d.getSh_flags(); + return raw.getSh_flags(); } /** Returns the size of this section. */ public long getSize() { - return d.getSh_size(); + return raw.getSh_size(); } /** Returns this section name, maybe null if not read. */ @@ -232,9 +242,9 @@ * @throws IllegalArgumentException if section offset or size mismatch including size > {@link Integer#MAX_VALUE} */ public Section readSection(final RandomAccessFile in) throws IOException, IllegalArgumentException { - final int s_size = long2Int(d.getSh_size()); + final int s_size = long2Int(raw.getSh_size()); if( 0 == s_size || 0 > s_size ) { - throw new IllegalArgumentException("Shdr["+idx+"] has invalid int size: "+d.getSh_size()+" -> "+s_size); + throw new IllegalArgumentException("Shdr["+idx+"] has invalid int size: "+raw.getSh_size()+" -> "+s_size); } final byte[] s_buf = new byte[s_size]; return readSectionImpl(in, s_buf, 0, s_size); @@ -252,9 +262,9 @@ * @throws IllegalArgumentException if requested read length is > section size */ public Section readSection(final RandomAccessFile in, final byte[] b, final int b_off, final int r_len) throws IOException, IllegalArgumentException { - final int s_size = long2Int(d.getSh_size()); + final int s_size = long2Int(raw.getSh_size()); if( 0 == s_size || 0 > s_size ) { - throw new IllegalArgumentException("Shdr["+idx+"] has invalid int size: "+d.getSh_size()+" -> "+s_size); + throw new IllegalArgumentException("Shdr["+idx+"] has invalid int size: "+raw.getSh_size()+" -> "+s_size); } if( r_len > s_size ) { throw new IllegalArgumentException("Shdr["+idx+"] has only "+s_size+" bytes, while read request is of "+r_len+" bytes"); @@ -263,7 +273,7 @@ } Section readSectionImpl(final RandomAccessFile in, final byte[] b, final int b_off, final int r_len) throws IOException, IllegalArgumentException { - final long s_off = d.getSh_offset(); + final long s_off = raw.getSh_offset(); seek(in, s_off); readBytes(in, b, b_off, r_len); if( SectionHeader.SHT_ARM_ATTRIBUTES == getType() ) { diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/elf/Shdr.java gluegen2-2.3.2/src/java/jogamp/common/os/elf/Shdr.java --- gluegen2-2.2.4/src/java/jogamp/common/os/elf/Shdr.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/elf/Shdr.java 2015-10-09 04:18:28.000000000 +0000 @@ -1,137 +1,176 @@ -/* !---- DO NOT EDIT: This file autogenerated by com/jogamp/gluegen/JavaEmitter.java on Thu Feb 07 17:54:18 CET 2013 ----! */ +/* !---- DO NOT EDIT: This file autogenerated by com/jogamp/gluegen/JavaEmitter.java on Sun Feb 01 23:28:47 CET 2015 ----! */ package jogamp.common.os.elf; +import java.nio.*; + +import com.jogamp.gluegen.runtime.*; +import com.jogamp.common.os.*; import com.jogamp.common.nio.*; -import jogamp.common.os.MachineDescriptionRuntime; +import jogamp.common.os.MachineDataInfoRuntime; public class Shdr { StructAccessor accessor; - private static final int mdIdx = MachineDescriptionRuntime.getStatic().ordinal(); - - private static final int[] Shdr_size = new int[] { 40 /* ARMle_EABI */, 40 /* X86_32_UNIX */, 64 /* X86_64_UNIX */, 40 /* X86_32_MACOS */, 40 /* X86_32_WINDOWS */, 64 /* X86_64_WINDOWS */ }; - private static final int[] sh_name_offset = new int[] { 0 /* ARMle_EABI */, 0 /* X86_32_UNIX */, 0 /* X86_64_UNIX */, 0 /* X86_32_MACOS */, 0 /* X86_32_WINDOWS */, 0 /* X86_64_WINDOWS */ }; - private static final int[] sh_type_offset = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 4 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 4 /* X86_64_WINDOWS */ }; - private static final int[] sh_flags_offset = new int[] { 8 /* ARMle_EABI */, 8 /* X86_32_UNIX */, 8 /* X86_64_UNIX */, 8 /* X86_32_MACOS */, 8 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */ }; - private static final int[] sh_addr_offset = new int[] { 12 /* ARMle_EABI */, 12 /* X86_32_UNIX */, 16 /* X86_64_UNIX */, 12 /* X86_32_MACOS */, 12 /* X86_32_WINDOWS */, 16 /* X86_64_WINDOWS */ }; - private static final int[] sh_offset_offset = new int[] { 16 /* ARMle_EABI */, 16 /* X86_32_UNIX */, 24 /* X86_64_UNIX */, 16 /* X86_32_MACOS */, 16 /* X86_32_WINDOWS */, 24 /* X86_64_WINDOWS */ }; - private static final int[] sh_size_offset = new int[] { 20 /* ARMle_EABI */, 20 /* X86_32_UNIX */, 32 /* X86_64_UNIX */, 20 /* X86_32_MACOS */, 20 /* X86_32_WINDOWS */, 32 /* X86_64_WINDOWS */ }; - private static final int[] sh_link_offset = new int[] { 24 /* ARMle_EABI */, 24 /* X86_32_UNIX */, 40 /* X86_64_UNIX */, 24 /* X86_32_MACOS */, 24 /* X86_32_WINDOWS */, 40 /* X86_64_WINDOWS */ }; - private static final int[] sh_info_offset = new int[] { 28 /* ARMle_EABI */, 28 /* X86_32_UNIX */, 44 /* X86_64_UNIX */, 28 /* X86_32_MACOS */, 28 /* X86_32_WINDOWS */, 44 /* X86_64_WINDOWS */ }; - private static final int[] sh_addralign_offset = new int[] { 32 /* ARMle_EABI */, 32 /* X86_32_UNIX */, 48 /* X86_64_UNIX */, 32 /* X86_32_MACOS */, 32 /* X86_32_WINDOWS */, 48 /* X86_64_WINDOWS */ }; - private static final int[] sh_entsize_offset = new int[] { 36 /* ARMle_EABI */, 36 /* X86_32_UNIX */, 56 /* X86_64_UNIX */, 36 /* X86_32_MACOS */, 36 /* X86_32_WINDOWS */, 56 /* X86_64_WINDOWS */ }; + private final int mdIdx; + private final MachineDataInfo md; - public static int size() { - return Shdr_size[mdIdx]; - } - - public static Shdr create() { - return create(Buffers.newDirectByteBuffer(size())); - } - - public static Shdr create(final java.nio.ByteBuffer buf) { - return new Shdr(buf); - } - - Shdr(final java.nio.ByteBuffer buf) { - accessor = new StructAccessor(buf); - } + private static final int[] Shdr_size = new int[] { 40 /* ARM_MIPS_32 */, 40 /* X86_32_UNIX */, 40 /* X86_32_MACOS */, 40 /* PPC_32_UNIX */, 40 /* SPARC_32_SUNOS */, 40 /* X86_32_WINDOWS */, 64 /* LP64_UNIX */, 64 /* X86_64_WINDOWS */ }; + private static final int[] sh_name_offset = new int[] { 0 /* ARM_MIPS_32 */, 0 /* X86_32_UNIX */, 0 /* X86_32_MACOS */, 0 /* PPC_32_UNIX */, 0 /* SPARC_32_SUNOS */, 0 /* X86_32_WINDOWS */, 0 /* LP64_UNIX */, 0 /* X86_64_WINDOWS */ }; +//private static final int[] sh_name_size = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 4 /* LP64_UNIX */, 4 /* X86_64_WINDOWS */ }; + private static final int[] sh_type_offset = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 4 /* LP64_UNIX */, 4 /* X86_64_WINDOWS */ }; +//private static final int[] sh_type_size = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 4 /* LP64_UNIX */, 4 /* X86_64_WINDOWS */ }; + private static final int[] sh_flags_offset = new int[] { 8 /* ARM_MIPS_32 */, 8 /* X86_32_UNIX */, 8 /* X86_32_MACOS */, 8 /* PPC_32_UNIX */, 8 /* SPARC_32_SUNOS */, 8 /* X86_32_WINDOWS */, 8 /* LP64_UNIX */, 8 /* X86_64_WINDOWS */ }; +//private static final int[] sh_flags_size = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 8 /* LP64_UNIX */, 8 /* X86_64_WINDOWS */ }; + private static final int[] sh_addr_offset = new int[] { 12 /* ARM_MIPS_32 */, 12 /* X86_32_UNIX */, 12 /* X86_32_MACOS */, 12 /* PPC_32_UNIX */, 12 /* SPARC_32_SUNOS */, 12 /* X86_32_WINDOWS */, 16 /* LP64_UNIX */, 16 /* X86_64_WINDOWS */ }; +//private static final int[] sh_addr_size = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 8 /* LP64_UNIX */, 8 /* X86_64_WINDOWS */ }; + private static final int[] sh_offset_offset = new int[] { 16 /* ARM_MIPS_32 */, 16 /* X86_32_UNIX */, 16 /* X86_32_MACOS */, 16 /* PPC_32_UNIX */, 16 /* SPARC_32_SUNOS */, 16 /* X86_32_WINDOWS */, 24 /* LP64_UNIX */, 24 /* X86_64_WINDOWS */ }; +//private static final int[] sh_offset_size = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 8 /* LP64_UNIX */, 8 /* X86_64_WINDOWS */ }; + private static final int[] sh_size_offset = new int[] { 20 /* ARM_MIPS_32 */, 20 /* X86_32_UNIX */, 20 /* X86_32_MACOS */, 20 /* PPC_32_UNIX */, 20 /* SPARC_32_SUNOS */, 20 /* X86_32_WINDOWS */, 32 /* LP64_UNIX */, 32 /* X86_64_WINDOWS */ }; +//private static final int[] sh_size_size = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 8 /* LP64_UNIX */, 8 /* X86_64_WINDOWS */ }; + private static final int[] sh_link_offset = new int[] { 24 /* ARM_MIPS_32 */, 24 /* X86_32_UNIX */, 24 /* X86_32_MACOS */, 24 /* PPC_32_UNIX */, 24 /* SPARC_32_SUNOS */, 24 /* X86_32_WINDOWS */, 40 /* LP64_UNIX */, 40 /* X86_64_WINDOWS */ }; +//private static final int[] sh_link_size = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 4 /* LP64_UNIX */, 4 /* X86_64_WINDOWS */ }; + private static final int[] sh_info_offset = new int[] { 28 /* ARM_MIPS_32 */, 28 /* X86_32_UNIX */, 28 /* X86_32_MACOS */, 28 /* PPC_32_UNIX */, 28 /* SPARC_32_SUNOS */, 28 /* X86_32_WINDOWS */, 44 /* LP64_UNIX */, 44 /* X86_64_WINDOWS */ }; +//private static final int[] sh_info_size = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 4 /* LP64_UNIX */, 4 /* X86_64_WINDOWS */ }; + private static final int[] sh_addralign_offset = new int[] { 32 /* ARM_MIPS_32 */, 32 /* X86_32_UNIX */, 32 /* X86_32_MACOS */, 32 /* PPC_32_UNIX */, 32 /* SPARC_32_SUNOS */, 32 /* X86_32_WINDOWS */, 48 /* LP64_UNIX */, 48 /* X86_64_WINDOWS */ }; +//private static final int[] sh_addralign_size = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 8 /* LP64_UNIX */, 8 /* X86_64_WINDOWS */ }; + private static final int[] sh_entsize_offset = new int[] { 36 /* ARM_MIPS_32 */, 36 /* X86_32_UNIX */, 36 /* X86_32_MACOS */, 36 /* PPC_32_UNIX */, 36 /* SPARC_32_SUNOS */, 36 /* X86_32_WINDOWS */, 56 /* LP64_UNIX */, 56 /* X86_64_WINDOWS */ }; +//private static final int[] sh_entsize_size = new int[] { 4 /* ARM_MIPS_32 */, 4 /* X86_32_UNIX */, 4 /* X86_32_MACOS */, 4 /* PPC_32_UNIX */, 4 /* SPARC_32_SUNOS */, 4 /* X86_32_WINDOWS */, 8 /* LP64_UNIX */, 8 /* X86_64_WINDOWS */ }; public java.nio.ByteBuffer getBuffer() { return accessor.getBuffer(); } - public Shdr setSh_name(final int val) { + /** Setter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ + public Shdr setSh_name(int val) { accessor.setIntAt(sh_name_offset[mdIdx], val); return this; } + /** Getter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ public int getSh_name() { return accessor.getIntAt(sh_name_offset[mdIdx]); } - public Shdr setSh_type(final int val) { + /** Setter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ + public Shdr setSh_type(int val) { accessor.setIntAt(sh_type_offset[mdIdx], val); return this; } + /** Getter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ public int getSh_type() { return accessor.getIntAt(sh_type_offset[mdIdx]); } - public Shdr setSh_flags(final long val) { - accessor.setLongAt(sh_flags_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + /** Setter for native field: CType['ElfN_size' (typedef), size [fixed false, lnx64 8], [int]] */ + public Shdr setSh_flags(long val) { + accessor.setLongAt(sh_flags_offset[mdIdx], val, md.longSizeInBytes()); return this; } + /** Getter for native field: CType['ElfN_size' (typedef), size [fixed false, lnx64 8], [int]] */ public long getSh_flags() { - return accessor.getLongAt(sh_flags_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + return accessor.getLongAt(sh_flags_offset[mdIdx], md.longSizeInBytes()); } - public Shdr setSh_addr(final long val) { - accessor.setLongAt(sh_addr_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + /** Setter for native field: CType['ElfN_Addr' (typedef), size [fixed false, lnx64 8], [int]] */ + public Shdr setSh_addr(long val) { + accessor.setLongAt(sh_addr_offset[mdIdx], val, md.longSizeInBytes()); return this; } + /** Getter for native field: CType['ElfN_Addr' (typedef), size [fixed false, lnx64 8], [int]] */ public long getSh_addr() { - return accessor.getLongAt(sh_addr_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + return accessor.getLongAt(sh_addr_offset[mdIdx], md.longSizeInBytes()); } - public Shdr setSh_offset(final long val) { - accessor.setLongAt(sh_offset_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + /** Setter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]] */ + public Shdr setSh_offset(long val) { + accessor.setLongAt(sh_offset_offset[mdIdx], val, md.longSizeInBytes()); return this; } + /** Getter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]] */ public long getSh_offset() { - return accessor.getLongAt(sh_offset_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + return accessor.getLongAt(sh_offset_offset[mdIdx], md.longSizeInBytes()); } - public Shdr setSh_size(final long val) { - accessor.setLongAt(sh_size_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + /** Setter for native field: CType['ElfN_size' (typedef), size [fixed false, lnx64 8], [int]] */ + public Shdr setSh_size(long val) { + accessor.setLongAt(sh_size_offset[mdIdx], val, md.longSizeInBytes()); return this; } + /** Getter for native field: CType['ElfN_size' (typedef), size [fixed false, lnx64 8], [int]] */ public long getSh_size() { - return accessor.getLongAt(sh_size_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + return accessor.getLongAt(sh_size_offset[mdIdx], md.longSizeInBytes()); } - public Shdr setSh_link(final int val) { + /** Setter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ + public Shdr setSh_link(int val) { accessor.setIntAt(sh_link_offset[mdIdx], val); return this; } + /** Getter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ public int getSh_link() { return accessor.getIntAt(sh_link_offset[mdIdx]); } - public Shdr setSh_info(final int val) { + /** Setter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ + public Shdr setSh_info(int val) { accessor.setIntAt(sh_info_offset[mdIdx], val); return this; } + /** Getter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ public int getSh_info() { return accessor.getIntAt(sh_info_offset[mdIdx]); } - public Shdr setSh_addralign(final long val) { - accessor.setLongAt(sh_addralign_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + /** Setter for native field: CType['ElfN_size' (typedef), size [fixed false, lnx64 8], [int]] */ + public Shdr setSh_addralign(long val) { + accessor.setLongAt(sh_addralign_offset[mdIdx], val, md.longSizeInBytes()); return this; } + /** Getter for native field: CType['ElfN_size' (typedef), size [fixed false, lnx64 8], [int]] */ public long getSh_addralign() { - return accessor.getLongAt(sh_addralign_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + return accessor.getLongAt(sh_addralign_offset[mdIdx], md.longSizeInBytes()); } - public Shdr setSh_entsize(final long val) { - accessor.setLongAt(sh_entsize_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + /** Setter for native field: CType['ElfN_size' (typedef), size [fixed false, lnx64 8], [int]] */ + public Shdr setSh_entsize(long val) { + accessor.setLongAt(sh_entsize_offset[mdIdx], val, md.longSizeInBytes()); return this; } + /** Getter for native field: CType['ElfN_size' (typedef), size [fixed false, lnx64 8], [int]] */ public long getSh_entsize() { - return accessor.getLongAt(sh_entsize_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + return accessor.getLongAt(sh_entsize_offset[mdIdx], md.longSizeInBytes()); + } + + // --- Begin CustomJavaCode .cfg declarations + public static int size(final int mdIdx) { + return Shdr_size[mdIdx]; + } + + public static Shdr create(final int mdIdx) { + return create(mdIdx, Buffers.newDirectByteBuffer(size(mdIdx))); + } + + public static Shdr create(final int mdIdx, final java.nio.ByteBuffer buf) { + return new Shdr(mdIdx, buf); + } + + Shdr(final int mdIdx, final java.nio.ByteBuffer buf) { + this.mdIdx = mdIdx; + this.md = MachineDataInfo.StaticConfig.values()[mdIdx].md; + this.accessor = new StructAccessor(buf); } + // ---- End CustomJavaCode .cfg declarations } diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/MachineDataInfoRuntime.java gluegen2-2.3.2/src/java/jogamp/common/os/MachineDataInfoRuntime.java --- gluegen2-2.2.4/src/java/jogamp/common/os/MachineDataInfoRuntime.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/MachineDataInfoRuntime.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,178 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.common.os; + +import com.jogamp.common.os.MachineDataInfo; +import com.jogamp.common.os.Platform; +import com.jogamp.common.os.MachineDataInfo.StaticConfig; + +/** + * Runtime operations of {@link MachineDataInfo}. + */ +public class MachineDataInfoRuntime { + + static volatile boolean initialized = false; + static volatile MachineDataInfo runtimeMD = null; + static volatile MachineDataInfo.StaticConfig staticMD = null; + + public static void initialize() { + if( !initialized ) { + synchronized(MachineDataInfo.class) { // volatile dbl-checked-locking OK + if( !initialized ) { + MachineDataInfo.StaticConfig.validateUniqueMachineDataInfo(); + + final MachineDataInfo runtimeMD = getRuntimeImpl(); + final MachineDataInfo.StaticConfig staticMD = MachineDataInfo.StaticConfig.findCompatible(runtimeMD); + if( null == staticMD ) { + throw new RuntimeException("No compatible MachineDataInfo.StaticConfig for runtime:"+PlatformPropsImpl.NEWLINE+runtimeMD); + } + if( !staticMD.md.compatible(runtimeMD) ) { + throw new RuntimeException("Incompatible MachineDataInfo:"+PlatformPropsImpl.NEWLINE+ + " Static "+staticMD+PlatformPropsImpl.NEWLINE+ + " Runtime "+runtimeMD); + } + MachineDataInfoRuntime.runtimeMD = runtimeMD; + MachineDataInfoRuntime.staticMD = staticMD; + initialized=true; + if( PlatformPropsImpl.DEBUG ) { + System.err.println("MachineDataInfoRuntime.initialize():"+PlatformPropsImpl.NEWLINE+ + " Static "+staticMD+PlatformPropsImpl.NEWLINE+ + " Runtime "+runtimeMD); + } + return; + } + } + } + throw new InternalError("Already initialized"); + } + public static MachineDataInfo.StaticConfig getStatic() { + if(!initialized) { + synchronized(MachineDataInfo.class) { // volatile dbl-checked-locking OK + if(!initialized) { + throw new InternalError("Not set"); + } + } + } + return staticMD; + } + public static MachineDataInfo getRuntime() { + if(!initialized) { + synchronized(MachineDataInfo.class) { // volatile dbl-checked-locking OK + if(!initialized) { + throw new InternalError("Not set"); + } + } + } + return runtimeMD; + } + + public static MachineDataInfo.StaticConfig guessStaticMachineDataInfo(final Platform.OSType osType, final Platform.CPUType cpuType) { + if( cpuType.is32Bit ) { + if( Platform.CPUFamily.ARM == cpuType.family || + Platform.CPUType.MIPS_32 == cpuType ) { + return StaticConfig.ARM_MIPS_32; + } else if( Platform.OSType.WINDOWS == osType ) { + return StaticConfig.X86_32_WINDOWS; + } else if( Platform.OSType.MACOS == osType ) { + return StaticConfig.X86_32_MACOS; + } else if ( Platform.OSType.SUNOS == osType && + Platform.CPUType.SPARC_32 == cpuType ) { + return StaticConfig.SPARC_32_SUNOS; + } else if ( Platform.CPUType.PPC == cpuType ) { + return StaticConfig.PPC_32_UNIX; + } else { + return StaticConfig.X86_32_UNIX; + } + } else { + if( osType == Platform.OSType.WINDOWS ) { + return StaticConfig.X86_64_WINDOWS; + } else { + // for all 64bit unix types (x86_64, aarch64, sparcv9, ..) + return StaticConfig.LP64_UNIX; + } + } + } + + private static MachineDataInfo getRuntimeImpl() { + try { + Platform.initSingleton(); // loads native gluegen-rt library + } catch (final UnsatisfiedLinkError err) { + return null; + } + + final int pointerSizeInBytes = getPointerSizeInBytesImpl(); + switch(pointerSizeInBytes) { + case 4: + case 8: + break; + default: + throw new RuntimeException("Unsupported pointer size "+pointerSizeInBytes+"bytes, please implement."); + } + + final long pageSizeL = getPageSizeInBytesImpl(); + if(Integer.MAX_VALUE < pageSizeL) { + throw new InternalError("PageSize exceeds integer value: " + pageSizeL); + } + + // size: int, long, float, double, pointer, pageSize + // alignment: int8, int16, int32, int64, int, long, float, double, pointer + return new MachineDataInfo( + true /* runtime validated */, + + getSizeOfIntImpl(), getSizeOfLongImpl(), + getSizeOfFloatImpl(), getSizeOfDoubleImpl(), getSizeOfLongDoubleImpl(), + pointerSizeInBytes, (int)pageSizeL, + + getAlignmentInt8Impl(), getAlignmentInt16Impl(), getAlignmentInt32Impl(), getAlignmentInt64Impl(), + getAlignmentIntImpl(), getAlignmentLongImpl(), + getAlignmentFloatImpl(), getAlignmentDoubleImpl(), getAlignmentLongDoubleImpl(), + getAlignmentPointerImpl()); + } + + private static native int getPointerSizeInBytesImpl(); + private static native long getPageSizeInBytesImpl(); + + private static native int getAlignmentInt8Impl(); + private static native int getAlignmentInt16Impl(); + private static native int getAlignmentInt32Impl(); + private static native int getAlignmentInt64Impl(); + private static native int getAlignmentIntImpl(); + private static native int getAlignmentLongImpl(); + private static native int getAlignmentPointerImpl(); + private static native int getAlignmentFloatImpl(); + private static native int getAlignmentDoubleImpl(); + private static native int getAlignmentLongDoubleImpl(); + private static native int getSizeOfIntImpl(); + private static native int getSizeOfLongImpl(); + private static native int getSizeOfPointerImpl(); + private static native int getSizeOfFloatImpl(); + private static native int getSizeOfDoubleImpl(); + private static native int getSizeOfLongDoubleImpl(); +} + diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/MachineDescriptionRuntime.java gluegen2-2.3.2/src/java/jogamp/common/os/MachineDescriptionRuntime.java --- gluegen2-2.2.4/src/java/jogamp/common/os/MachineDescriptionRuntime.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/MachineDescriptionRuntime.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,187 +0,0 @@ -/** - * Copyright 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ - -package jogamp.common.os; - -import com.jogamp.common.os.MachineDescription; -import com.jogamp.common.os.Platform; -import com.jogamp.common.os.MachineDescription.StaticConfig; - -/** - * Runtime MachineDescription - */ -public class MachineDescriptionRuntime { - - static volatile boolean smdHardQueried = false; - static MachineDescription.StaticConfig smdHard = null; - - static volatile boolean smdSoftQueried = false; - static MachineDescription.StaticConfig smdSoft = null; - - static volatile boolean smdHardEnabled = false; - - /* pp */ static void notifyPropsInitialized() { smdHardEnabled = true; } - - public static MachineDescription.StaticConfig getStatic() { - if(!smdHardEnabled) { - if(!smdSoftQueried) { - synchronized(MachineDescription.class) { // volatile dbl-checked-locking OK - if(!smdSoftQueried) { - smdSoft = get(PlatformPropsImpl.OS_TYPE, PlatformPropsImpl.sCpuType, PlatformPropsImpl.LITTLE_ENDIAN); - smdSoftQueried=true; - } - } - } - return smdSoft; - } else { - if(!smdHardQueried) { - synchronized(MachineDescription.class) { // volatile dbl-checked-locking OK - if(!smdHardQueried) { - smdHard = get(PlatformPropsImpl.OS_TYPE, PlatformPropsImpl.CPU_ARCH, PlatformPropsImpl.LITTLE_ENDIAN); - smdHardQueried=true; - } - } - } - return smdHard; - } - } - - private static boolean isCPUArch32Bit(final Platform.CPUType cpuType) throws RuntimeException { - switch( cpuType ) { - case X86_32: - case ARM: - case ARMv5: - case ARMv6: - case ARMv7: - case SPARC_32: - case PPC: - return true; - case X86_64: - case IA64: - case SPARCV9_64: - case PA_RISC2_0: - return false; - default: - throw new RuntimeException("Please port CPU detection (32/64 bit) to your platform (" + PlatformPropsImpl.OS_lower + "/" + PlatformPropsImpl.ARCH_lower + "("+PlatformPropsImpl.CPU_ARCH+"))"); - } - } - - private static MachineDescription.StaticConfig get(final Platform.OSType osType, final Platform.CPUType cpuType, final boolean littleEndian) { - if( isCPUArch32Bit(cpuType) ) { - if( cpuType.getFamily() == Platform.CPUFamily.ARM && littleEndian) { - return StaticConfig.ARMle_EABI; - } else if( osType == Platform.OSType.WINDOWS ) { - return StaticConfig.X86_32_WINDOWS; - } else if( osType == Platform.OSType.MACOS ) { - return StaticConfig.X86_32_MACOS; - } else if ( osType == Platform.OSType.SUNOS ) { - if ( cpuType == Platform.CPUType.SPARC_32 ) { - return StaticConfig.SPARC_32_SUNOS; - } - // TODO SPARCv9 description is missing - } - return StaticConfig.X86_32_UNIX; - } else { - if( osType == Platform.OSType.WINDOWS ) { - return StaticConfig.X86_64_WINDOWS; - } - return StaticConfig.X86_64_UNIX; - } - } - - static volatile boolean rmdQueried = false; - static MachineDescription rmd = null; - - public static MachineDescription getRuntime() { - if(!rmdQueried) { - synchronized(MachineDescription.class) { // volatile dbl-checked-locking OK - if(!rmdQueried) { - rmd = getRuntimeImpl(); - rmdQueried=true; - } - } - } - return rmd; - } - private static MachineDescription getRuntimeImpl() { - try { - Platform.initSingleton(); // loads native gluegen-rt library - } catch (final UnsatisfiedLinkError err) { - return null; - } - - final int pointerSizeInBytes = getPointerSizeInBytesImpl(); - switch(pointerSizeInBytes) { - case 4: - case 8: - break; - default: - throw new RuntimeException("Unsupported pointer size "+pointerSizeInBytes+"bytes, please implement."); - } - - final long pageSizeL = getPageSizeInBytesImpl(); - if(Integer.MAX_VALUE < pageSizeL) { - throw new InternalError("PageSize exceeds integer value: " + pageSizeL); - } - - // size: int, long, float, double, pointer, pageSize - // alignment: int8, int16, int32, int64, int, long, float, double, pointer - return new MachineDescription( - true /* runtime validated */, PlatformPropsImpl.LITTLE_ENDIAN, - - getSizeOfIntImpl(), getSizeOfLongImpl(), - getSizeOfFloatImpl(), getSizeOfDoubleImpl(), getSizeOfLongDoubleImpl(), - pointerSizeInBytes, (int)pageSizeL, - - getAlignmentInt8Impl(), getAlignmentInt16Impl(), getAlignmentInt32Impl(), getAlignmentInt64Impl(), - getAlignmentIntImpl(), getAlignmentLongImpl(), - getAlignmentFloatImpl(), getAlignmentDoubleImpl(), getAlignmentLongDoubleImpl(), - getAlignmentPointerImpl()); - } - - private static native int getPointerSizeInBytesImpl(); - private static native long getPageSizeInBytesImpl(); - - private static native int getAlignmentInt8Impl(); - private static native int getAlignmentInt16Impl(); - private static native int getAlignmentInt32Impl(); - private static native int getAlignmentInt64Impl(); - private static native int getAlignmentIntImpl(); - private static native int getAlignmentLongImpl(); - private static native int getAlignmentPointerImpl(); - private static native int getAlignmentFloatImpl(); - private static native int getAlignmentDoubleImpl(); - private static native int getAlignmentLongDoubleImpl(); - private static native int getSizeOfIntImpl(); - private static native int getSizeOfLongImpl(); - private static native int getSizeOfPointerImpl(); - private static native int getSizeOfFloatImpl(); - private static native int getSizeOfDoubleImpl(); - private static native int getSizeOfLongDoubleImpl(); -} - diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java gluegen2-2.3.2/src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java --- gluegen2-2.2.4/src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java 2015-10-09 04:18:28.000000000 +0000 @@ -42,18 +42,18 @@ private static final int RTLD_GLOBAL = 0x00008; @Override - public final long openLibraryLocal(final String pathname, final boolean debug) throws SecurityException { - return this.openLibraryImpl(pathname, RTLD_LAZY | RTLD_LOCAL, debug); + protected final long openLibraryLocalImpl(final String pathname) throws SecurityException { + return dlopen(pathname, RTLD_LAZY | RTLD_LOCAL); } @Override - public final long openLibraryGlobal(final String pathname, final boolean debug) throws SecurityException { - return this.openLibraryImpl(pathname, RTLD_LAZY | RTLD_GLOBAL, debug); + protected final long openLibraryGlobalImpl(final String pathname) throws SecurityException { + return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL); } @Override - public final long lookupSymbolGlobal(final String symbolName) throws SecurityException { - return this.lookupSymbolGlobalImpl(RTLD_DEFAULT, symbolName); + protected final long lookupSymbolGlobalImpl(final String symbolName) throws SecurityException { + return dlsym(RTLD_DEFAULT, symbolName); } } diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/PlatformPropsImpl.java gluegen2-2.3.2/src/java/jogamp/common/os/PlatformPropsImpl.java --- gluegen2-2.2.4/src/java/jogamp/common/os/PlatformPropsImpl.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/PlatformPropsImpl.java 2015-10-09 04:18:28.000000000 +0000 @@ -11,9 +11,9 @@ import java.util.List; import jogamp.common.Debug; -import jogamp.common.os.elf.ElfHeader; +import jogamp.common.os.elf.ElfHeaderPart1; +import jogamp.common.os.elf.ElfHeaderPart2; import jogamp.common.os.elf.SectionArmAttributes; -import jogamp.common.os.elf.SectionHeader; import com.jogamp.common.nio.Buffers; import com.jogamp.common.os.AndroidVersion; @@ -48,6 +48,13 @@ public static final VersionNumber Mavericks = new VersionNumber(10,9,0); } + /** + * Returns {@code true} if the given {@link CPUType}s and {@link ABIType}s are compatible. + */ + public static final boolean isCompatible(final CPUType cpu1, final ABIType abi1, final CPUType cpu2, final ABIType abi2) { + return cpu1.isCompatible(cpu2) && abi1.isCompatible(abi2); + } + // // static initialization order: // @@ -56,6 +63,10 @@ public static final VersionNumber Version16; /** Version 1.7. As a JVM version, it enables certain JVM 1.7 features. */ public static final VersionNumber Version17; + /** Version 1.8. As a JVM version, it enables certain JVM 1.8 features. */ + public static final VersionNumber Version18; + /** Version 1.9. As a JVM version, it enables certain JVM 1.9 features. */ + public static final VersionNumber Version19; public static final String OS; public static final String OS_lower; @@ -72,14 +83,20 @@ public static final String JAVA_RUNTIME_NAME; /** True if having {@link java.nio.LongBuffer} and {@link java.nio.DoubleBuffer} available. */ public static final boolean JAVA_SE; - /** True if being compatible w/ language level 6, e.g. JRE 1.6. Implies {@link #JAVA_SE}. Note: We claim Android is compatible. */ + /** + * True only if being compatible w/ language level 6, e.g. JRE 1.6. + *

    + * Implies {@link #isJavaSE()}. + *

    + *

    + * Note: We claim Android is compatible. + *

    + */ public static final boolean JAVA_6; public static final String NEWLINE; public static final boolean LITTLE_ENDIAN; - /* pp */ static final CPUType sCpuType; - public static final CPUType CPU_ARCH; public static final ABIType ABI_TYPE; public static final OSType OS_TYPE; @@ -88,6 +105,8 @@ static { Version16 = new VersionNumber(1, 6, 0); Version17 = new VersionNumber(1, 7, 0); + Version18 = new VersionNumber(1, 8, 0); + Version19 = new VersionNumber(1, 9, 0); // We don't seem to need an AccessController.doPrivileged() block // here as these system properties are visible even to unsigned Applets. @@ -126,107 +145,183 @@ OS_VERSION_NUMBER = new VersionNumber(OS_VERSION); OS_TYPE = getOSTypeImpl(OS_lower, isAndroid); - LITTLE_ENDIAN = queryIsLittleEndianImpl(); - - // Soft values, i.e. w/o probing binaries - final String sARCH = System.getProperty("os.arch"); - final String sARCH_lower = sARCH.toLowerCase(); - sCpuType = getCPUTypeImpl(sARCH_lower); - if( DEBUG ) { - System.err.println("Platform.Soft: str "+sARCH+", cpuType "+sCpuType); - } - // Hard values, i.e. w/ probing binaries - // - // FIXME / HACK: - // We use sCPUType for MachineDescriptionRuntime.getStatic() - // until we have determined the final CPU_TYPE, etc. - // MachineDescriptionRuntime gets notified via MachineDescriptionRuntime.notifyPropsInitialized() below. - // - // We could use Elf Ehdr's machine value to determine the bit-size - // used for it's offset table! - // However, 'os.arch' should be a good guess for this task. - final CPUType ehCpuType; - final ABIType ehAbiType; - final boolean ehValid; + final String elfCpuName; + final CPUType elfCpuType; + final ABIType elfABIType; + final int elfLittleEndian; + final boolean elfValid; { - final CPUType[] _ehCpuType = { null }; - final ABIType[] _ehAbiType = { null }; - final ElfHeader eh = queryABITypeImpl(OS_TYPE, _ehCpuType, _ehAbiType); - if( null != eh && null != _ehCpuType[0] && null != _ehAbiType[0] ) { - ehCpuType = _ehCpuType[0]; - ehAbiType = _ehAbiType[0]; - if( isAndroid ) { - if( DEBUG ) { - System.err.println("Android: CPU_ABI1 str "+AndroidVersion.CPU_ABI+", cpu "+AndroidVersion.CPU_TYPE+", abi "+AndroidVersion.ABI_TYPE); - System.err.println("Android: CPU_ABI2 str "+AndroidVersion.CPU_ABI2+", cpu "+AndroidVersion.CPU_TYPE2+", abi "+AndroidVersion.ABI_TYPE2); - } - final CPUFamily aCpuFamily1 = null != AndroidVersion.CPU_TYPE ? AndroidVersion.CPU_TYPE.family : null; - final CPUFamily aCpuFamily2 = null != AndroidVersion.CPU_TYPE2 ? AndroidVersion.CPU_TYPE2.family : null; - if( ehCpuType.family != aCpuFamily1 && ehCpuType.family != aCpuFamily2 ) { - // Ooops ! - ehValid = false; - } else { - ehValid = true; - } - } else { - if( ehCpuType.family != sCpuType.family ) { - // Ooops ! - ehValid = false; - } else { - ehValid = true; + final String[] _elfCpuName = { null }; + final CPUType[] _elfCpuType = { null }; + final ABIType[] _elfAbiType = { null }; + final int[] _elfLittleEndian = { 0 }; // 1 - little, 2 - big + final boolean[] _elfValid = { false }; + AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Object run() { + RandomAccessFile in = null; + try { + final File file = queryElfFile(OS_TYPE); + if(DEBUG) { + System.err.println("ELF-1: Using "+file); + } + in = new RandomAccessFile(file, "r"); + final ElfHeaderPart1 eh1 = readElfHeaderPart1(OS_TYPE, in); + if(DEBUG) { + System.err.println("ELF-1: Got "+eh1); + } + if( null != eh1 ) { + final ElfHeaderPart2 eh2 = readElfHeaderPart2(eh1, in); + if(DEBUG) { + System.err.println("ELF-2: Got "+eh2); + } + if( null != eh2 ) { + _elfCpuName[0] = eh2.cpuName; + _elfCpuType[0] = eh2.cpuType; + _elfAbiType[0] = eh2.abiType; + if( eh1.isLittleEndian() ) { + _elfLittleEndian[0] = 1; + } else if( eh1.isBigEndian() ) { + _elfLittleEndian[0] = 2; + } + _elfValid[0] = true; + } + } + } catch (final Throwable t) { + if(DEBUG) { + t.printStackTrace(); + } + } finally { + if(null != in) { + try { + in.close(); + } catch (final IOException e) { } + } } - } - if( DEBUG ) { - System.err.println("Platform.Elf: cpuType "+ehCpuType+", abiType "+ehAbiType+", valid "+ehValid); - } - } else { - ehCpuType = null; - ehAbiType = null; - ehValid = false; - if( DEBUG ) { - System.err.println("Platform.Elf: n/a"); - } + return null; + } }); + elfCpuName = _elfCpuName[0]; + elfCpuType = _elfCpuType[0]; + elfABIType = _elfAbiType[0]; + elfLittleEndian = _elfLittleEndian[0]; + elfValid = _elfValid[0]; + if( DEBUG ) { + System.err.println("Platform.Elf: valid "+elfValid+", elfCpuName "+elfCpuName+", cpuType "+elfCpuType+", abiType "+elfABIType+", elfLittleEndian "+elfLittleEndian); + } + } + + // Determine endianess, favor ELF value + final boolean littleEndian = queryIsLittleEndianImpl(); + if( elfValid ) { + switch( elfLittleEndian ) { + case 1: + LITTLE_ENDIAN = true; + break; + case 2: + LITTLE_ENDIAN = false; + break; + default: + LITTLE_ENDIAN = littleEndian; + break; } + } else { + LITTLE_ENDIAN = littleEndian; + } + if( DEBUG ) { + System.err.println("Platform.Endian: test-little "+littleEndian+", elf[valid "+elfValid+", val "+elfLittleEndian+"] -> LITTLE_ENDIAN "+LITTLE_ENDIAN); } + + // Property values for comparison + // We might take the property values even if ELF values are available, + // since the latter only reflect the CPU/ABI version of the binary files! + final String propARCH = System.getProperty("os.arch"); + final String propARCH_lower = propARCH.toLowerCase(); + final CPUType propCpuType = CPUType.query(propARCH_lower); + final ABIType propABIType = ABIType.query(propCpuType, propARCH_lower); + if( DEBUG ) { + System.err.println("Platform.Property: ARCH "+propARCH+", CpuType "+propCpuType+", ABIType "+propABIType); + } + + final int strategy; if( isAndroid ) { - if( ehValid ) { - if( ehCpuType.family == AndroidVersion.CPU_TYPE.family ) { + if( DEBUG ) { + System.err.println("Android: CPU_ABI1 str "+AndroidVersion.CPU_ABI+", CPU_TYPE "+AndroidVersion.CPU_TYPE+", ABI_TYPE "+AndroidVersion.ABI_TYPE); + System.err.println("Android: CPU_ABI2 str "+AndroidVersion.CPU_ABI2+", CPU_TYPE2 "+AndroidVersion.CPU_TYPE2+", ABI_TYPE2 "+AndroidVersion.ABI_TYPE2); + } + if( elfValid ) { + if( null != AndroidVersion.CPU_TYPE && + isCompatible(elfCpuType, elfABIType, AndroidVersion.CPU_TYPE, AndroidVersion.ABI_TYPE) ) + { + // ELF matches Android-1 ARCH = AndroidVersion.CPU_ABI; + ARCH_lower = ARCH; CPU_ARCH = AndroidVersion.CPU_TYPE; - } else { + strategy = 110; + } else if( null != AndroidVersion.CPU_TYPE2 && + isCompatible(elfCpuType, elfABIType, AndroidVersion.CPU_TYPE2, AndroidVersion.ABI_TYPE2) ) + { + // ELF matches Android-2 ARCH = AndroidVersion.CPU_ABI2; + ARCH_lower = ARCH; CPU_ARCH = AndroidVersion.CPU_TYPE2; + strategy = 111; + } else { + // We assume our ELF data beats AndroidVersion info (correctness) + ARCH = elfCpuType.toString(); + ARCH_lower = ARCH.toLowerCase(); + CPU_ARCH = elfCpuType; + strategy = 112; } - ABI_TYPE = ehAbiType; + ABI_TYPE = elfABIType; } else { - // default - if( AndroidVersion.CPU_TYPE.family == CPUFamily.ARM || null == AndroidVersion.CPU_TYPE2 ) { + if( AndroidVersion.CPU_TYPE.family == CPUFamily.ARM || + null == AndroidVersion.CPU_TYPE2 ) { + // Favor Android-1: Either b/c ARM Family, or no Android-2 ARCH = AndroidVersion.CPU_ABI; + ARCH_lower = ARCH; CPU_ARCH = AndroidVersion.CPU_TYPE; ABI_TYPE = AndroidVersion.ABI_TYPE; + strategy = 120; } else { + // Last resort Android-2 ARCH = AndroidVersion.CPU_ABI2; + ARCH_lower = ARCH; CPU_ARCH = AndroidVersion.CPU_TYPE2; ABI_TYPE = AndroidVersion.ABI_TYPE2; + strategy = 121; } } - ARCH_lower = ARCH; } else { - ARCH = sARCH; - ARCH_lower = sARCH_lower; - if( ehValid && CPUFamily.ARM == ehCpuType.family ) { - // Use Elf for ARM - CPU_ARCH = ehCpuType; - ABI_TYPE = ehAbiType; + if( elfValid ) { + if( isCompatible(elfCpuType, elfABIType, propCpuType, propABIType) ) { + // Use property ARCH, compatible w/ ELF + ARCH = propARCH; + ARCH_lower = propARCH_lower; + CPU_ARCH = propCpuType; + ABI_TYPE = propABIType; + strategy = 210; + } else { + // use ELF ARCH + ARCH = elfCpuName; + ARCH_lower = elfCpuName; + CPU_ARCH = elfCpuType; + ABI_TYPE = elfABIType; + strategy = 211; + } } else { - // Otherwise trust detailed os.arch (?) - CPU_ARCH = sCpuType; - ABI_TYPE = ABIType.GENERIC_ABI; + // Last resort: properties + ARCH = propARCH; + ARCH_lower = propARCH_lower; + CPU_ARCH = propCpuType; + ABI_TYPE = propABIType; + strategy = 220; } } - MachineDescriptionRuntime.notifyPropsInitialized(); - os_and_arch = getOSAndArch(OS_TYPE, CPU_ARCH, ABI_TYPE); + if( DEBUG ) { + System.err.println("Platform.Hard: ARCH "+ARCH+", CPU_ARCH "+CPU_ARCH+", ABI_TYPE "+ABI_TYPE+" - strategy "+strategy+"(isAndroid "+isAndroid+", elfValid "+elfValid+")"); + } + os_and_arch = getOSAndArch(OS_TYPE, CPU_ARCH, ABI_TYPE, LITTLE_ENDIAN); } protected PlatformPropsImpl() {} @@ -266,43 +361,6 @@ return 0x0C0D == tst_s.get(0); } - private static final CPUType getCPUTypeImpl(final String archLower) { - if( archLower.equals("x86") || // jvm + android - archLower.equals("i386") || - archLower.equals("i486") || - archLower.equals("i586") || - archLower.equals("i686") ) { - return CPUType.X86_32; - } else if( archLower.equals("x86_64") || - archLower.equals("amd64") ) { - return CPUType.X86_64; - } else if( archLower.equals("ia64") ) { - return CPUType.IA64; - } else if( archLower.equals("arm") ) { - return CPUType.ARM; - } else if( archLower.equals("armv5l") ) { - return CPUType.ARMv5; - } else if( archLower.equals("armv6l") ) { - return CPUType.ARMv6; - } else if( archLower.equals("armv7l") || - archLower.equals("armeabi") || // android - archLower.equals("armeabi-v7a") ) { // android - return CPUType.ARMv7; - } else if( archLower.equals("sparc") ) { - return CPUType.SPARC_32; - } else if( archLower.equals("sparcv9") ) { - return CPUType.SPARCV9_64; - } else if( archLower.equals("pa_risc2.0") ) { - return CPUType.PA_RISC2_0; - } else if( archLower.equals("ppc") ) { - return CPUType.PPC; - } else if( archLower.equals("mips") ) { // android - return CPUType.MIPS_32; - } else { - throw new RuntimeException("Please port CPU detection to your platform (" + OS_lower + "/" + archLower + ")"); - } - } - @SuppressWarnings("unused") private static final boolean contains(final String data, final String[] search) { if(null != data && null != search) { @@ -330,98 +388,53 @@ * Elf ARM Tags are read using {@link ElfHeader}, .. and {@link SectionArmAttributes#abiVFPArgsAcceptsVFPVariant(byte)}. *

    */ - private static final ElfHeader queryABITypeImpl(final OSType osType, final CPUType[] cpuType, final ABIType[] abiType) { - return AccessController.doPrivileged(new PrivilegedAction() { - @Override - public ElfHeader run() { - ElfHeader res = null; - try { - File file = null; - if( OSType.ANDROID == osType ) { - file = new File(NativeLibrary.findLibrary("gluegen-rt", PlatformPropsImpl.class.getClassLoader())); - } else { - if( OSType.LINUX == osType ) { - file = new File("/proc/self/exe"); - if( !checkFileReadAccess(file) ) { - file = null; - } - } - if( null == file ) { - file = findSysLib("java"); - } - if( null == file ) { - file = findSysLib("jvm"); - } - } - if( null != file ) { - res = queryABITypeImpl(file, cpuType, abiType); - } - } catch(final Throwable t) { - if(DEBUG) { - t.printStackTrace(); - } - } - return res; - } } ); - } - private static final ElfHeader queryABITypeImpl(final File file, final CPUType[] cpuType, final ABIType[] abiType) { - ElfHeader res = null; - RandomAccessFile in = null; + private static final File queryElfFile(final OSType osType) { + File file = null; try { - in = new RandomAccessFile(file, "r"); - final ElfHeader eh = ElfHeader.read(in); - if(DEBUG) { - System.err.println("ELF: Got HDR "+file+": "+eh); - } - if( eh.isArm() ) { - boolean abiVFPArgsAcceptsVFPVariant = false; - final SectionHeader sh = eh.getSectionHeader(SectionHeader.SHT_ARM_ATTRIBUTES); - if( null != sh ) { - if(DEBUG) { - System.err.println("ELF: Got ARM Attribs Section Header: "+sh); - } - final SectionArmAttributes sArmAttrs = (SectionArmAttributes) sh.readSection(in); - if(DEBUG) { - System.err.println("ELF: Got ARM Attribs Section Block : "+sArmAttrs); - } - final SectionArmAttributes.Attribute abiVFPArgsAttr = sArmAttrs.get(SectionArmAttributes.Tag.ABI_VFP_args); - if( null != abiVFPArgsAttr ) { - abiVFPArgsAcceptsVFPVariant = SectionArmAttributes.abiVFPArgsAcceptsVFPVariant(abiVFPArgsAttr.getULEB128()); + if( OSType.ANDROID == osType ) { + file = new File(NativeLibrary.findLibrary("gluegen-rt", PlatformPropsImpl.class.getClassLoader())); + } else { + if( OSType.LINUX == osType ) { + file = new File("/proc/self/exe"); + if( !checkFileReadAccess(file) ) { + file = null; } } - cpuType[0] = CPUType.ARM; // lowest denominator, ok for us - abiType[0] = abiVFPArgsAcceptsVFPVariant ? ABIType.EABI_GNU_ARMHF : ABIType.EABI_GNU_ARMEL; - if(DEBUG) { - System.err.println("ELF: abiARM, abiVFPArgsAcceptsVFPVariant "+abiVFPArgsAcceptsVFPVariant); + if( null == file ) { + file = findSysLib("java"); + } + if( null == file ) { + file = findSysLib("jvm"); } - } else if ( eh.isX86_64() ) { - cpuType[0] = CPUType.X86_64; - abiType[0] = ABIType.GENERIC_ABI; - } else if ( eh.isX86_32() ) { - cpuType[0] = CPUType.X86_32; - abiType[0] = ABIType.GENERIC_ABI; - } else if ( eh.isIA64() ) { - cpuType[0] = CPUType.IA64; - abiType[0] = ABIType.GENERIC_ABI; - } else if ( eh.isMips() ) { - cpuType[0] = CPUType.MIPS_32; // FIXME - abiType[0] = ABIType.GENERIC_ABI; } - res = eh; } catch(final Throwable t) { if(DEBUG) { - System.err.println("Caught: "+t.getMessage()); t.printStackTrace(); } - } finally { - if(null != in) { - try { - in.close(); - } catch (final IOException e) { } + } + return file; + } + private static final ElfHeaderPart1 readElfHeaderPart1(final OSType osType, final RandomAccessFile in) { + ElfHeaderPart1 res = null; + try { + res = ElfHeaderPart1.read(osType, in); + } catch(final Throwable t) { + if(DEBUG) { + System.err.println("Caught: "+t.getMessage()); + t.printStackTrace(); } } - if(DEBUG) { - System.err.println("ELF: res "+res+", cpuType "+cpuType[0]+", abiType "+abiType[0]); + return res; + } + private static final ElfHeaderPart2 readElfHeaderPart2(final ElfHeaderPart1 eh1, final RandomAccessFile in) { + ElfHeaderPart2 res = null; + try { + res = ElfHeaderPart2.read(eh1, in); + } catch(final Throwable t) { + if(DEBUG) { + System.err.println("Caught: "+t.getMessage()); + t.printStackTrace(); + } } return res; } @@ -488,20 +501,34 @@ public static void initSingleton() { } /** - * Returns the GlueGen common name for the given OSType and CPUType - * as implemented in the build system in 'gluegen-cpptasks-base.xml'.
    + * Returns the GlueGen common name for the given + * {@link OSType}, {@link CPUType}, {@link ABIType} and {@code littleEndian}. + *

    + * Consult 'gluegen/make/gluegen-cpptasks-base.xml' to complete/sync mapping! + *

    * - * A list of currently supported os.and.arch strings: + * An excerpt of supported os.and.arch strings: *
      + *
    • android-armv6
    • + *
    • android-aarch64
    • + *
    • linux-armv6
    • + *
    • linux-armv6hf
    • + *
    • linux-i586
    • + *
    • linux-ppc
    • + *
    • linux-mips
    • + *
    • linux-mipsel
    • + *
    • linux-superh
    • + *
    • linux-sparc
    • + *
    • linux-aarch64
    • + *
    • linux-amd64
    • + *
    • linux-ppc64
    • + *
    • linux-mips64
    • + *
    • linux-ia64
    • + *
    • linux-sparcv9
    • + *
    • linux-risc2.0
    • *
    • freebsd-i586
    • *
    • freebsd-amd64
    • *
    • hpux-hppa
    • - *
    • linux-amd64
    • - *
    • linux-ia64
    • - *
    • linux-i586
    • - *
    • linux-armv6
    • - *
    • linux-armv6hf
    • - *
    • android-armv6
    • *
    • macosx-universal
    • *
    • solaris-sparc
    • *
    • solaris-sparcv9
    • @@ -512,33 +539,50 @@ *
    * @return The os.and.arch value. */ - public static final String getOSAndArch(final OSType osType, final CPUType cpuType, final ABIType abiType) { + public static final String getOSAndArch(final OSType osType, final CPUType cpuType, final ABIType abiType, final boolean littleEndian) { final String os_; final String _and_arch_tmp, _and_arch_final; switch( cpuType ) { - case X86_32: - _and_arch_tmp = "i586"; - break; case ARM: case ARMv5: case ARMv6: case ARMv7: if( ABIType.EABI_GNU_ARMHF == abiType ) { - _and_arch_tmp = "armv6hf" ; // TODO: sync with gluegen-cpptasks-base.xml + _and_arch_tmp = "armv6hf"; } else { - _and_arch_tmp = "armv6"; // TODO: sync with gluegen-cpptasks-base.xml + _and_arch_tmp = "armv6"; } break; + case X86_32: + _and_arch_tmp = "i586"; + break; + case PPC: + _and_arch_tmp = "ppc"; + break; + case MIPS_32: + _and_arch_tmp = littleEndian ? "mipsel" : "mips"; + break; + case SuperH: + _and_arch_tmp = "superh"; + break; case SPARC_32: _and_arch_tmp = "sparc"; break; - case PPC: - _and_arch_tmp = "ppc"; // TODO: sync with gluegen-cpptasks-base.xml + + case ARM64: + case ARMv8_A: + _and_arch_tmp = "aarch64"; break; case X86_64: _and_arch_tmp = "amd64"; break; + case PPC64: + _and_arch_tmp = "ppc64"; + break; + case MIPS_64: + _and_arch_tmp = "mips64"; + break; case IA64: _and_arch_tmp = "ia64"; break; @@ -546,10 +590,10 @@ _and_arch_tmp = "sparcv9"; break; case PA_RISC2_0: - _and_arch_tmp = "risc2.0"; // TODO: sync with gluegen-cpptasks-base.xml + _and_arch_tmp = "risc2.0"; break; default: - throw new InternalError("Complete case block"); + throw new InternalError("Unhandled CPUType: "+cpuType); } switch( osType ) { @@ -586,7 +630,7 @@ _and_arch_final = "hppa"; // TODO: really only hppa ? break; default: - throw new InternalError("Complete case block"); + throw new InternalError("Unhandled OSType: "+osType); } return os_ + "-" + _and_arch_final; } diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/PosixDynamicLinkerImpl.java gluegen2-2.3.2/src/java/jogamp/common/os/PosixDynamicLinkerImpl.java --- gluegen2-2.2.4/src/java/jogamp/common/os/PosixDynamicLinkerImpl.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/PosixDynamicLinkerImpl.java 2015-10-09 04:18:28.000000000 +0000 @@ -38,17 +38,17 @@ private static final int RTLD_GLOBAL = 0x00100; @Override - public final long openLibraryLocal(final String pathname, final boolean debug) throws SecurityException { - return this.openLibraryImpl(pathname, RTLD_LAZY | RTLD_LOCAL, debug); + protected final long openLibraryLocalImpl(final String pathname) throws SecurityException { + return dlopen(pathname, RTLD_LAZY | RTLD_LOCAL); } @Override - public final long openLibraryGlobal(final String pathname, final boolean debug) throws SecurityException { - return this.openLibraryImpl(pathname, RTLD_LAZY | RTLD_GLOBAL, debug); + protected final long openLibraryGlobalImpl(final String pathname) throws SecurityException { + return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL); } @Override - public final long lookupSymbolGlobal(final String symbolName) throws SecurityException { - return this.lookupSymbolGlobalImpl(RTLD_DEFAULT, symbolName); + protected final long lookupSymbolGlobalImpl(final String symbolName) throws SecurityException { + return dlsym(RTLD_DEFAULT, symbolName); } } diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java gluegen2-2.3.2/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java --- gluegen2-2.2.4/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java 2015-10-09 04:18:28.000000000 +0000 @@ -27,8 +27,6 @@ */ package jogamp.common.os; -import com.jogamp.common.util.SecurityUtil; - /* pp */ abstract class UnixDynamicLinkerImpl extends DynamicLinkerImpl { // @@ -49,46 +47,17 @@ /** Interface to C language function:
    void * dlsym(void * , const char * ); */ protected static native long dlsym(long arg0, java.lang.String arg1); - protected final long openLibraryImpl(final String pathname, final int dlSymFlags, final boolean debug) throws SecurityException { - SecurityUtil.checkLinkPermission(pathname); - final long handle = dlopen(pathname, dlSymFlags); - if( 0 != handle ) { - incrLibRefCount(handle, pathname); - } else if ( DEBUG || debug ) { - System.err.println("dlopen \""+pathname+"\" failed, error: "+dlerror()); - } - return handle; - } - - protected final long lookupSymbolGlobalImpl(final long dlSymGlobalFlag, final String symbolName) throws SecurityException { - SecurityUtil.checkAllLinkPermission(); - final long addr = dlsym(dlSymGlobalFlag, symbolName); - if(DEBUG_LOOKUP) { - System.err.println("DynamicLinkerImpl.lookupSymbolGlobal("+symbolName+") -> 0x"+Long.toHexString(addr)); - } - return addr; - } - @Override - public final long lookupSymbol(final long libraryHandle, final String symbolName) throws IllegalArgumentException { - if( null == getLibRef( libraryHandle ) ) { - throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown."); - } - final long addr = dlsym(libraryHandle, symbolName); - if(DEBUG_LOOKUP) { - System.err.println("DynamicLinkerImpl.lookupSymbol(0x"+Long.toHexString(libraryHandle)+", "+symbolName+") -> 0x"+Long.toHexString(addr)); - } - return addr; + protected final long lookupSymbolLocalImpl(final long libraryHandle, final String symbolName) throws SecurityException { + return dlsym(libraryHandle, symbolName); } @Override - public final void closeLibrary(final long libraryHandle) throws IllegalArgumentException { - if( null == decrLibRefCount( libraryHandle ) ) { - throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown."); - } - dlclose(libraryHandle); + protected final void closeLibraryImpl(final long libraryHandle) throws SecurityException { + dlclose(libraryHandle); } + @Override public final String getLastError() { return dlerror(); diff -Nru gluegen2-2.2.4/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java gluegen2-2.3.2/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java --- gluegen2-2.2.4/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java 2015-10-09 04:18:28.000000000 +0000 @@ -27,8 +27,6 @@ */ package jogamp.common.os; -import com.jogamp.common.util.SecurityUtil; - public final class WindowsDynamicLinkerImpl extends DynamicLinkerImpl { /** Interface to C language function:
    BOOL FreeLibrary(HANDLE hLibModule); */ @@ -44,28 +42,19 @@ private static native long LoadLibraryW(java.lang.String lpLibFileName); @Override - public final long openLibraryLocal(final String libraryName, final boolean debug) throws SecurityException { + protected final long openLibraryLocalImpl(final String libraryName) throws SecurityException { // How does that work under Windows ? - // Don't know .. so it's an alias for the time being - return openLibraryGlobal(libraryName, debug); + // Don't know .. so it's an alias to global, for the time being + return LoadLibraryW(libraryName); } @Override - public final long openLibraryGlobal(final String libraryName, final boolean debug) throws SecurityException { - SecurityUtil.checkLinkPermission(libraryName); - final long handle = LoadLibraryW(libraryName); - if( 0 != handle ) { - incrLibRefCount(handle, libraryName); - } else if ( DEBUG || debug ) { - final int err = GetLastError(); - System.err.println("LoadLibraryW \""+libraryName+"\" failed, error code: 0x"+Integer.toHexString(err)+", "+err); - } - return handle; + protected final long openLibraryGlobalImpl(final String libraryName) throws SecurityException { + return LoadLibraryW(libraryName); } @Override - public final long lookupSymbolGlobal(final String symbolName) throws SecurityException { - SecurityUtil.checkAllLinkPermission(); + protected final long lookupSymbolGlobalImpl(final String symbolName) throws SecurityException { if(DEBUG_LOOKUP) { System.err.println("lookupSymbolGlobal: Not supported on Windows"); } @@ -73,34 +62,26 @@ return 0; } + private static final int symbolArgAlignment=4; // 4 byte alignment of each argument + private static final int symbolMaxArguments=12; // experience .. + @Override - public final long lookupSymbol(final long libraryHandle, final String symbolName) throws IllegalArgumentException { - if( null == getLibRef( libraryHandle ) ) { - throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown."); - } + protected final long lookupSymbolLocalImpl(final long libraryHandle, final String symbolName) throws IllegalArgumentException { String _symbolName = symbolName; long addr = GetProcAddressA(libraryHandle, _symbolName); - if(0==addr) { + if( 0 == addr ) { // __stdcall hack: try some @nn decorations, // the leading '_' must not be added (same with cdecl) - final int argAlignment=4; // 4 byte alignment of each argument - final int maxArguments=12; // experience .. - for(int arg=0; 0==addr && arg<=maxArguments; arg++) { - _symbolName = symbolName+"@"+(arg*argAlignment); + for(int arg=0; 0==addr && arg<=symbolMaxArguments; arg++) { + _symbolName = symbolName+"@"+(arg*symbolArgAlignment); addr = GetProcAddressA(libraryHandle, _symbolName); } } - if(DEBUG_LOOKUP) { - System.err.println("DynamicLinkerImpl.lookupSymbol(0x"+Long.toHexString(libraryHandle)+", "+symbolName+") -> "+_symbolName+", 0x"+Long.toHexString(addr)); - } return addr; } @Override - public final void closeLibrary(final long libraryHandle) throws IllegalArgumentException { - if( null == decrLibRefCount( libraryHandle ) ) { - throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown."); - } + protected final void closeLibraryImpl(final long libraryHandle) throws IllegalArgumentException { FreeLibrary(libraryHandle); } diff -Nru gluegen2-2.2.4/src/java/jogamp/common/util/Int32ArrayBitfield.java gluegen2-2.3.2/src/java/jogamp/common/util/Int32ArrayBitfield.java --- gluegen2-2.2.4/src/java/jogamp/common/util/Int32ArrayBitfield.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/util/Int32ArrayBitfield.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,207 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.common.util; + +import com.jogamp.common.util.Bitfield; + +/** + * Simple bitfield interface for efficient storage access in O(1). + *

    + * Implementation uses a 32bit integer array for storage. + *

    + */ +public class Int32ArrayBitfield implements Bitfield { + private static final int UNIT_SHIFT = 5; + private final int[] storage; + private final int bitSize; + + /** + * @param storageBitSize + */ + public Int32ArrayBitfield(final int storageBitSize) { + final int units = Math.max(1, ( storageBitSize + 31 ) >>> UNIT_SHIFT); + this.storage = new int[units]; // initialized w/ default '0' + this.bitSize = units << UNIT_SHIFT; + } + + @Override + public int size() { + return bitSize; + } + + @Override + public final void clearField(final boolean bit) { + final int v; + if( bit ) { + v = Bitfield.UNSIGNED_INT_MAX_VALUE; + } else { + v = 0; + } + for(int i=storage.length-1; i>=0; i--) { + storage[i] = v; + } + } + + private static final void check(final int size, final int bitnum) throws IndexOutOfBoundsException { + if( 0 > bitnum || bitnum >= size ) { + throw new IndexOutOfBoundsException("Bitnum should be within [0.."+(size-1)+"], but is "+bitnum); + } + } + + @Override + public final int get32(final int lowBitnum, final int length) throws IndexOutOfBoundsException { + if( 0 > length || length > 32 ) { + throw new IndexOutOfBoundsException("length should be within [0..32], but is "+length); + } + check(bitSize-length+1, lowBitnum); + final int u = lowBitnum >>> UNIT_SHIFT; + final int left = 32 - ( lowBitnum - ( u << UNIT_SHIFT ) ); // remaining bits of first chunk storage + if( 32 == left ) { + // fast path + final int m = Util.getBitMask(length); // mask of chunk + return m & storage[u]; + } else { + // slow path + final int l = Math.min(length, left); // length of first chunk < 32 + final int m = ( 1 << l ) - 1; // mask of first chunk + final int d = m & ( storage[u] >>> lowBitnum ); + final int l2 = length - l; // length of last chunk < 32 + if( l2 > 0 ) { + final int m2 = ( 1 << l2 ) - 1; // mask of last chunk + return d | ( ( m2 & storage[u+1] ) << l ); + } else { + return d; + } + } + } + @Override + public final void put32(final int lowBitnum, final int length, final int data) throws IndexOutOfBoundsException { + if( 0 > length || length > 32 ) { + throw new IndexOutOfBoundsException("length should be within [0..32], but is "+length); + } + check(bitSize-length+1, lowBitnum); + final int u = lowBitnum >>> UNIT_SHIFT; + final int left = 32 - ( lowBitnum - ( u << UNIT_SHIFT ) ); // remaining bits of first chunk storage + if( 32 == left ) { + // fast path + final int m = Util.getBitMask(length); // mask of chunk + storage[u] = ( ( ~m ) & storage[u] ) // keep non-written storage bits + | ( m & data ); // overwrite storage w/ used data bits + } else { + // slow path + final int l = Math.min(length, left); // length of first chunk < 32 + final int m = ( 1 << l ) - 1; // mask of first chunk + storage[u] = ( ( ~( m << lowBitnum ) ) & storage[u] ) // keep non-written storage bits + | ( ( m & data ) << lowBitnum ); // overwrite storage w/ used data bits + final int l2 = length - l; // length of last chunk < 32 + if( l2 > 0 ) { + final int m2 = ( 1 << l2 ) - 1; // mask of last chunk + storage[u+1] = ( ( ~m2 ) & storage[u+1] ) // keep non-written storage bits + | ( m2 & ( data >>> l ) ); // overwrite storage w/ used data bits + } + } + } + @Override + public final int copy32(final int srcBitnum, final int dstBitnum, final int length) throws IndexOutOfBoundsException { + final int data = get32(srcBitnum, length); + put32(dstBitnum, length, data); + return data; + } + + @Override + public final boolean get(final int bitnum) throws IndexOutOfBoundsException { + check(bitSize, bitnum); + final int u = bitnum >>> UNIT_SHIFT; + final int b = bitnum - ( u << UNIT_SHIFT ); + return 0 != ( storage[u] & ( 1 << b ) ) ; + } + + @Override + public final boolean put(final int bitnum, final boolean bit) throws IndexOutOfBoundsException { + check(bitSize, bitnum); + final int u = bitnum >>> UNIT_SHIFT; + final int b = bitnum - ( u << UNIT_SHIFT ); + final int m = 1 << b; + final boolean prev = 0 != ( storage[u] & m ) ; + if( prev != bit ) { + if( bit ) { + storage[u] |= m; + } else { + storage[u] &= ~m; + } + } + return prev; + } + @Override + public final void set(final int bitnum) throws IndexOutOfBoundsException { + check(bitSize, bitnum); + final int u = bitnum >>> UNIT_SHIFT; + final int b = bitnum - ( u << UNIT_SHIFT ); + final int m = 1 << b; + storage[u] |= m; + } + @Override + public final void clear(final int bitnum) throws IndexOutOfBoundsException { + check(bitSize, bitnum); + final int u = bitnum >>> UNIT_SHIFT; + final int b = bitnum - ( u << UNIT_SHIFT ); + final int m = 1 << b; + storage[u] &= ~m; + } + @Override + public final boolean copy(final int srcBitnum, final int dstBitnum) throws IndexOutOfBoundsException { + check(bitSize, srcBitnum); + check(bitSize, dstBitnum); + final boolean bit; + // get + { + final int u = srcBitnum >>> UNIT_SHIFT; + final int b = srcBitnum - ( u << UNIT_SHIFT ); + bit = 0 != ( storage[u] & ( 1 << b ) ) ; + } + // put + final int u = dstBitnum >>> UNIT_SHIFT; + final int b = dstBitnum - ( u << UNIT_SHIFT ); + final int m = 1 << b; + if( bit ) { + storage[u] |= m; + } else { + storage[u] &= ~m; + } + return bit; + } + + @Override + public int bitCount() { + int c = 0; + for(int i = storage.length-1; i>=0; i--) { + c += Bitfield.Util.bitCount(storage[i]); + } + return c; + } +} diff -Nru gluegen2-2.2.4/src/java/jogamp/common/util/Int32Bitfield.java gluegen2-2.3.2/src/java/jogamp/common/util/Int32Bitfield.java --- gluegen2-2.2.4/src/java/jogamp/common/util/Int32Bitfield.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/util/Int32Bitfield.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,163 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.common.util; + +import com.jogamp.common.util.Bitfield; + +/** + * Simple bitfield interface for efficient storage access in O(1). + *

    + * Implementation uses one 32bit integer field for storage. + *

    + */ +public class Int32Bitfield implements Bitfield { + /** Unit size in bits, here 32 bits for one int unit. */ + private static final int UNIT_SIZE = 32; + private int storage; + + public Int32Bitfield() { + this.storage = 0; + } + + @Override + public int size() { + return UNIT_SIZE; + } + + @Override + public final void clearField(final boolean bit) { + if( bit ) { + storage = Bitfield.UNSIGNED_INT_MAX_VALUE; + } else { + storage = 0; + } + } + + private static final void check(final int size, final int bitnum) throws IndexOutOfBoundsException { + if( 0 > bitnum || bitnum >= size ) { + throw new IndexOutOfBoundsException("Bitnum should be within [0.."+(size-1)+"], but is "+bitnum); + } + } + + @Override + public final int get32(final int lowBitnum, final int length) throws IndexOutOfBoundsException { + if( 0 > length || length > 32 ) { + throw new IndexOutOfBoundsException("length should be within [0..32], but is "+length); + } + check(UNIT_SIZE-length+1, lowBitnum); + final int left = 32 - lowBitnum; // remaining bits of first chunk + if( 32 == left ) { + // fast path + final int m = Util.getBitMask(length); // mask of chunk + return m & storage; + } else { + // slow path + final int l = Math.min(length, left); // length of first chunk < 32 + final int m = ( 1 << l ) - 1; // mask of first chunk + return m & ( storage >>> lowBitnum ); + } + } + @Override + public final void put32(final int lowBitnum, final int length, final int data) throws IndexOutOfBoundsException { + if( 0 > length || length > 32 ) { + throw new IndexOutOfBoundsException("length should be within [0..32], but is "+length); + } + check(UNIT_SIZE-length+1, lowBitnum); + final int left = 32 - lowBitnum; // remaining bits of first chunk storage + if( 32 == left ) { + // fast path + final int m = Util.getBitMask(length); // mask of chunk + storage = ( ( ~m ) & storage ) // keep non-written storage bits + | ( m & data ); // overwrite storage w/ used data bits + } else { + // slow path + final int l = Math.min(length, left); // length of first chunk < 32 + final int m = ( 1 << l ) - 1; // mask of first chunk + storage = ( ( ~( m << lowBitnum ) ) & storage ) // keep non-written storage bits + | ( ( m & data ) << lowBitnum ); // overwrite storage w/ used data bits + } + } + @Override + public final int copy32(final int srcBitnum, final int dstBitnum, final int length) throws IndexOutOfBoundsException { + final int data = get32(srcBitnum, length); + put32(dstBitnum, length, data); + return data; + } + + @Override + public final boolean get(final int bitnum) throws IndexOutOfBoundsException { + check(UNIT_SIZE, bitnum); + return 0 != ( storage & ( 1 << bitnum ) ) ; + } + @Override + public final boolean put(final int bitnum, final boolean bit) throws IndexOutOfBoundsException { + check(UNIT_SIZE, bitnum); + final int m = 1 << bitnum; + final boolean prev = 0 != ( storage & m ) ; + if( prev != bit ) { + if( bit ) { + storage |= m; + } else { + storage &= ~m; + } + } + return prev; + } + @Override + public final void set(final int bitnum) throws IndexOutOfBoundsException { + check(UNIT_SIZE, bitnum); + final int m = 1 << bitnum; + storage |= m; + } + @Override + public final void clear (final int bitnum) throws IndexOutOfBoundsException { + check(UNIT_SIZE, bitnum); + final int m = 1 << bitnum; + storage &= ~m; + } + @Override + public final boolean copy(final int srcBitnum, final int dstBitnum) throws IndexOutOfBoundsException { + check(UNIT_SIZE, srcBitnum); + check(UNIT_SIZE, dstBitnum); + // get + final boolean bit = 0 != ( storage & ( 1 << srcBitnum ) ) ; + // put + final int m = 1 << dstBitnum; + if( bit ) { + storage |= m; + } else { + storage &= ~m; + } + return bit; + } + + @Override + public int bitCount() { + return Bitfield.Util.bitCount(storage); + } +} diff -Nru gluegen2-2.2.4/src/java/jogamp/common/util/locks/RecursiveLockImpl01CompleteFair.java gluegen2-2.3.2/src/java/jogamp/common/util/locks/RecursiveLockImpl01CompleteFair.java --- gluegen2-2.2.4/src/java/jogamp/common/util/locks/RecursiveLockImpl01CompleteFair.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/util/locks/RecursiveLockImpl01CompleteFair.java 2015-10-09 04:18:28.000000000 +0000 @@ -32,6 +32,7 @@ import java.util.List; import java.util.concurrent.locks.AbstractOwnableSynchronizer; +import com.jogamp.common.util.SourcedInterruptedException; import com.jogamp.common.util.locks.RecursiveLock; /** @@ -197,7 +198,7 @@ } catch (final InterruptedException e) { if( !wCur.signaledByUnlock ) { sync.queue.remove(wCur); // O(n) - throw e; // propagate interruption not send by unlock + throw SourcedInterruptedException.wrap(e); // propagate interruption not send by unlock } else if( cur != sync.getOwner() ) { // Issued by unlock, but still locked by other thread // @@ -215,6 +216,7 @@ } // else: Issued by unlock, owning lock .. expected! } } while ( cur != sync.getOwner() && 0 < timeout ) ; + Thread.interrupted(); // clear slipped interrupt if( 0 >= timeout && cur != sync.getOwner() ) { // timed out diff -Nru gluegen2-2.2.4/src/java/jogamp/common/util/locks/RecursiveThreadGroupLockImpl01Unfairish.java gluegen2-2.3.2/src/java/jogamp/common/util/locks/RecursiveThreadGroupLockImpl01Unfairish.java --- gluegen2-2.2.4/src/java/jogamp/common/util/locks/RecursiveThreadGroupLockImpl01Unfairish.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/util/locks/RecursiveThreadGroupLockImpl01Unfairish.java 2015-10-09 04:18:28.000000000 +0000 @@ -42,6 +42,7 @@ threadNum = 0; threads = null; holdCountAdditionOwner = 0; + waitingOrigOwner = null; } @Override public final void incrHoldCount(final Thread t) { @@ -64,6 +65,12 @@ public final boolean isOriginalOwner(final Thread t) { return super.isOwner(t); } + public final void setWaitingOrigOwner(final Thread origOwner) { + waitingOrigOwner = origOwner; + } + public final Thread getWaitingOrigOwner() { + return waitingOrigOwner; + } @Override public final boolean isOwner(final Thread t) { if(getExclusiveOwnerThread()==t) { @@ -133,6 +140,7 @@ private int holdCountAdditionOwner; private Thread[] threads; private int threadNum; + private Thread waitingOrigOwner; } public RecursiveThreadGroupLockImpl01Unfairish() { @@ -157,10 +165,10 @@ final Thread cur = Thread.currentThread(); final ThreadGroupSync tgSync = (ThreadGroupSync)sync; if(!tgSync.isOriginalOwner(cur)) { - throw new IllegalArgumentException("Current thread is not the original owner: orig-owner: "+tgSync.getOwner()+", current "+cur); + throw new IllegalArgumentException("Current thread is not the original owner: orig-owner: "+tgSync.getOwner()+", current "+cur+": "+toString()); } if(tgSync.isOriginalOwner(t)) { - throw new IllegalArgumentException("Passed thread is original owner: "+t); + throw new IllegalArgumentException("Passed thread is original owner: "+t+", "+toString()); } tgSync.addOwner(t); } @@ -179,19 +187,25 @@ // original locking owner thread if( tgSync.getHoldCount() - tgSync.getAdditionalOwnerHoldCount() == 1 ) { // release orig. lock - while ( tgSync.getAdditionalOwnerHoldCount() > 0 ) { - try { - sync.wait(); - } catch (final InterruptedException e) { - // regular wake up! + tgSync.setWaitingOrigOwner(cur); + try { + while ( tgSync.getAdditionalOwnerHoldCount() > 0 ) { + try { + sync.wait(); + } catch (final InterruptedException e) { + // regular wake up! + } } + } finally { + tgSync.setWaitingOrigOwner(null); + Thread.interrupted(); // clear slipped interrupt } tgSync.removeAllOwners(); } } else if( tgSync.getAdditionalOwnerHoldCount() == 1 ) { - // last additional owner thread wakes up original owner - final Thread originalOwner = tgSync.getOwner(); - if(originalOwner.getState() == Thread.State.WAITING) { + // last additional owner thread wakes up original owner if waiting in unlock(..) + final Thread originalOwner = tgSync.getWaitingOrigOwner(); + if( null != originalOwner ) { originalOwner.interrupt(); } } diff -Nru gluegen2-2.2.4/src/java/jogamp/common/util/locks/SingletonInstanceFileLock.java gluegen2-2.3.2/src/java/jogamp/common/util/locks/SingletonInstanceFileLock.java --- gluegen2-2.2.4/src/java/jogamp/common/util/locks/SingletonInstanceFileLock.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/util/locks/SingletonInstanceFileLock.java 2015-10-09 04:18:28.000000000 +0000 @@ -32,6 +32,8 @@ import java.io.IOException; import java.io.RandomAccessFile; import java.nio.channels.FileLock; + +import com.jogamp.common.util.InterruptSource; import com.jogamp.common.util.locks.SingletonInstance; public class SingletonInstanceFileLock extends SingletonInstance { @@ -76,7 +78,7 @@ private void setupFileCleanup() { file.deleteOnExit(); - Runtime.getRuntime().addShutdownHook(new Thread() { + Runtime.getRuntime().addShutdownHook(new InterruptSource.Thread() { @Override public void run() { if(isLocked()) { diff -Nru gluegen2-2.2.4/src/java/jogamp/common/util/locks/SingletonInstanceServerSocket.java gluegen2-2.3.2/src/java/jogamp/common/util/locks/SingletonInstanceServerSocket.java --- gluegen2-2.2.4/src/java/jogamp/common/util/locks/SingletonInstanceServerSocket.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/util/locks/SingletonInstanceServerSocket.java 2015-10-09 04:18:28.000000000 +0000 @@ -33,10 +33,16 @@ import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; + +import com.jogamp.common.ExceptionUtils; +import com.jogamp.common.util.InterruptSource; +import com.jogamp.common.util.InterruptedRuntimeException; +import com.jogamp.common.util.SourcedInterruptedException; import com.jogamp.common.util.locks.SingletonInstance; public class SingletonInstanceServerSocket extends SingletonInstance { + private static int serverInstanceCount = 0; private final Server singletonServer; private final String fullName; @@ -71,7 +77,7 @@ fullName = ilh.toString()+":"+portNumber; singletonServer = new Server(ilh, portNumber); - Runtime.getRuntime().addShutdownHook(new Thread() { + Runtime.getRuntime().addShutdownHook(new InterruptSource.Thread() { @Override public void run() { singletonServer.kill(); @@ -139,38 +145,58 @@ public final boolean start() { if(alive) return true; + final String sname; + synchronized (Server.class) { + serverInstanceCount++; + sname = "SingletonServerSocket"+serverInstanceCount+"-"+fullName; + } synchronized (syncOnStartStop) { - serverThread = new Thread(this); + shallQuit = false; + serverThread = new InterruptSource.Thread(null, this, sname); serverThread.setDaemon(true); // be a daemon, don't keep the JVM running serverThread.start(); try { - syncOnStartStop.wait(); + while( !alive && !shallQuit ) { + syncOnStartStop.wait(); + } } catch (final InterruptedException ie) { - ie.printStackTrace(); + final InterruptedException ie2 = SourcedInterruptedException.wrap(ie); + shutdown(false); + throw new InterruptedRuntimeException(ie2); } } final boolean ok = isBound(); if(!ok) { - shutdown(); + shutdown(true); } return ok; } public final boolean shutdown() { + return shutdown(true); + } + private final boolean shutdown(final boolean wait) { if(!alive) return true; - synchronized (syncOnStartStop) { - shallQuit = true; - connect(); - try { - syncOnStartStop.wait(); - } catch (final InterruptedException ie) { - ie.printStackTrace(); + try { + synchronized (syncOnStartStop) { + shallQuit = true; + connect(); + if( wait ) { + try { + while( alive ) { + syncOnStartStop.wait(); + } + } catch (final InterruptedException ie) { + throw new InterruptedRuntimeException(ie); + } + } + } + } finally { + if(alive) { + System.err.println(infoPrefix()+" EEE "+getName()+" - Unable to remove lock: ServerThread still alive ?"); + kill(); } - } - if(alive) { - System.err.println(infoPrefix()+" EEE "+getName()+" - Unable to remove lock: ServerThread still alive ?"); - kill(); } return true; } @@ -185,7 +211,8 @@ System.err.println(infoPrefix()+" XXX "+getName()+" - Kill @ JVM Shutdown"); } alive = false; - if(null != serverThread) { + shallQuit = false; + if(null != serverThread && serverThread.isAlive() ) { try { serverThread.stop(); } catch(final Throwable t) { } @@ -214,47 +241,49 @@ @Override public void run() { - { - final Thread currentThread = Thread.currentThread(); - currentThread.setName(currentThread.getName() + " - SISock: "+getName()); - if(DEBUG) { - System.err.println(currentThread.getName()+" - started"); - } + if(DEBUG) { + System.err.println(infoPrefix()+" III - Start"); } - alive = false; - synchronized (syncOnStartStop) { - try { - serverSocket = new ServerSocket(portNumber, 1, localInetAddress); - serverSocket.setReuseAddress(true); // reuse same port w/ subsequent instance, i.e. overcome TO state when JVM crashed - alive = true; - } catch (final IOException e) { - System.err.println(infoPrefix()+" III - Unable to install ServerSocket: "+e.getMessage()); - shallQuit = true; - } finally { - syncOnStartStop.notifyAll(); + try { + synchronized (syncOnStartStop) { + try { + serverSocket = new ServerSocket(portNumber, 1, localInetAddress); + serverSocket.setReuseAddress(true); // reuse same port w/ subsequent instance, i.e. overcome TO state when JVM crashed + alive = true; + } catch (final IOException e) { + System.err.println(infoPrefix()+" III - Unable to install ServerSocket: "+e.getMessage()); + shallQuit = true; + } finally { + syncOnStartStop.notifyAll(); + } } - } - while (!shallQuit) { - try { - final Socket clientSocket = serverSocket.accept(); - clientSocket.close(); - } catch (final IOException ioe) { - System.err.println(infoPrefix()+" EEE - Exception during accept: " + ioe.getMessage()); + while (!shallQuit) { + try { + final Socket clientSocket = serverSocket.accept(); + clientSocket.close(); + } catch (final IOException ioe) { + System.err.println(infoPrefix()+" EEE - Exception during accept: " + ioe.getMessage()); + } } - } - - synchronized (syncOnStartStop) { - try { + } catch(final ThreadDeath td) { + if( DEBUG ) { + ExceptionUtils.dumpThrowable("", td); + } + } finally { + synchronized (syncOnStartStop) { + if(DEBUG) { + System.err.println(infoPrefix()+" III - Stopping: alive "+alive+", shallQuit "+shallQuit+", hasSocket "+(null!=serverSocket)); + } if(null != serverSocket) { - serverSocket.close(); + try { + serverSocket.close(); + } catch (final IOException e) { + System.err.println(infoPrefix()+" EEE - Exception during close: " + e.getMessage()); + } } - } catch (final IOException e) { - System.err.println(infoPrefix()+" EEE - Exception during close: " + e.getMessage()); - } finally { serverSocket = null; alive = false; - shallQuit = false; syncOnStartStop.notifyAll(); } } diff -Nru gluegen2-2.2.4/src/java/jogamp/common/util/SyncedBitfield.java gluegen2-2.3.2/src/java/jogamp/common/util/SyncedBitfield.java --- gluegen2-2.2.4/src/java/jogamp/common/util/SyncedBitfield.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/java/jogamp/common/util/SyncedBitfield.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,96 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.common.util; + +import com.jogamp.common.util.Bitfield; + +/** + * Simple synchronized {@link Bitfield} by wrapping an existing {@link Bitfield}. + */ +public class SyncedBitfield implements Bitfield { + private final Bitfield impl; + + public SyncedBitfield(final Bitfield impl) { + this.impl = impl; + } + + @Override + public final synchronized int size() { + return impl.size(); + } + + @Override + public final synchronized void clearField(final boolean bit) { + impl.clearField(bit); + } + + @Override + public final synchronized int get32(final int lowBitnum, final int length) throws IndexOutOfBoundsException { + return impl.get32(lowBitnum, length); + } + + @Override + public final synchronized void put32(final int lowBitnum, final int length, final int data) throws IndexOutOfBoundsException { + impl.put32(lowBitnum, length, data); + } + + @Override + public final synchronized int copy32(final int srcLowBitnum, final int dstLowBitnum, final int length) throws IndexOutOfBoundsException { + return impl.copy32(srcLowBitnum, dstLowBitnum, length); + } + + @Override + public final synchronized boolean get(final int bitnum) throws IndexOutOfBoundsException { + return impl.get(bitnum); + } + + @Override + public final synchronized boolean put(final int bitnum, final boolean bit) throws IndexOutOfBoundsException { + return impl.put(bitnum, bit); + } + + @Override + public final synchronized void set(final int bitnum) throws IndexOutOfBoundsException { + impl.set(bitnum); + } + + @Override + public final synchronized void clear(final int bitnum) throws IndexOutOfBoundsException { + impl.clear(bitnum); + } + + @Override + public final synchronized boolean copy(final int srcBitnum, final int dstBitnum) throws IndexOutOfBoundsException { + return impl.copy(srcBitnum, dstBitnum); + } + + @Override + public final synchronized int bitCount() { + return impl.bitCount(); + } +} \ No newline at end of file diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/net/AssetURLConnectionBase.java gluegen2-2.3.2/src/junit/com/jogamp/common/net/AssetURLConnectionBase.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/net/AssetURLConnectionBase.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/net/AssetURLConnectionBase.java 2015-10-09 04:18:28.000000000 +0000 @@ -10,9 +10,9 @@ import com.jogamp.common.os.AndroidVersion; import com.jogamp.common.util.IOUtil; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; -public abstract class AssetURLConnectionBase extends JunitTracer { +public abstract class AssetURLConnectionBase extends SingletonJunitCase { /** In gluegen-rt.jar */ protected static final String test_asset_rt_url = "asset:gluegen/info.txt"; @@ -23,15 +23,15 @@ /** In gluegen.test.jar */ protected static final String test_asset_test1_url = "asset:gluegen-test/info.txt"; protected static final String test_asset_test1_entry = "gluegen-test/info.txt"; - protected static final String test_asset_test2_rel = "data/AssetURLConnectionTest.txt"; + protected static final Uri.Encoded test_asset_test2_rel = Uri.Encoded.cast("data/AssetURLConnectionTest.txt"); protected static final String test_asset_test2a_url = "asset:com/jogamp/common/net/data/AssetURLConnectionTest.txt"; protected static final String test_asset_test2b_url = "asset:/com/jogamp/common/net/data/AssetURLConnectionTest.txt"; protected static final String test_asset_test2_entry = "com/jogamp/common/net/data/AssetURLConnectionTest.txt"; - protected static final String test_asset_test3_rel = "RelativeData.txt"; + protected static final Uri.Encoded test_asset_test3_rel = Uri.Encoded.cast("RelativeData.txt"); protected static final String test_asset_test3a_url = "asset:com/jogamp/common/net/data/RelativeData.txt"; protected static final String test_asset_test3b_url = "asset:/com/jogamp/common/net/data/RelativeData.txt"; protected static final String test_asset_test3_entry = "com/jogamp/common/net/data/RelativeData.txt"; - protected static final String test_asset_test4_rel = "../data2/RelativeData2.txt"; + protected static final Uri.Encoded test_asset_test4_rel = Uri.Encoded.cast("../data2/RelativeData2.txt"); protected static final String test_asset_test4a_url = "asset:com/jogamp/common/net/data2/RelativeData2.txt"; protected static final String test_asset_test4b_url = "asset:/com/jogamp/common/net/data2/RelativeData2.txt"; protected static final String test_asset_test4_entry = "com/jogamp/common/net/data2/RelativeData2.txt"; diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/net/AssetURLConnectionRegisteredTest.java gluegen2-2.3.2/src/junit/com/jogamp/common/net/AssetURLConnectionRegisteredTest.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/net/AssetURLConnectionRegisteredTest.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/net/AssetURLConnectionRegisteredTest.java 2015-10-09 04:18:28.000000000 +0000 @@ -1,7 +1,6 @@ package com.jogamp.common.net; import java.io.IOException; -import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; @@ -48,12 +47,12 @@ Assert.assertEquals(test_asset_test2a_url, urlConn0.getURL().toExternalForm()); testAssetConnection(urlConn0, test_asset_test2_entry); - final URI uri1 = IOUtil.getRelativeOf(urlConn0.getURL().toURI(), test_asset_test3_rel); + final Uri uri1 = Uri.valueOf(urlConn0.getURL()).getRelativeOf(test_asset_test3_rel); Assert.assertNotNull(uri1); Assert.assertEquals(test_asset_test3a_url, uri1.toString()); testAssetConnection(uri1.toURL().openConnection(), test_asset_test3_entry); - final URI uri2 = IOUtil.getRelativeOf(urlConn0.getURL().toURI(), test_asset_test4_rel); + final Uri uri2 = Uri.valueOf(urlConn0.getURL()).getRelativeOf(test_asset_test4_rel); Assert.assertNotNull(uri2); Assert.assertEquals(test_asset_test4a_url, uri2.toString()); testAssetConnection(uri2.toURL().openConnection(), test_asset_test4_entry); @@ -66,12 +65,12 @@ Assert.assertEquals(test_asset_test2b_url, urlConn0.getURL().toExternalForm()); testAssetConnection(urlConn0, test_asset_test2_entry); - final URI uri1 = IOUtil.getRelativeOf(urlConn0.getURL().toURI(), test_asset_test3_rel); + final Uri uri1 = Uri.valueOf(urlConn0.getURL()).getRelativeOf(test_asset_test3_rel); Assert.assertNotNull(uri1); Assert.assertEquals(test_asset_test3b_url, uri1.toString()); testAssetConnection(uri1.toURL().openConnection(), test_asset_test3_entry); - final URI uri2 = IOUtil.getRelativeOf(urlConn0.getURL().toURI(), test_asset_test4_rel); + final Uri uri2 = Uri.valueOf(urlConn0.getURL()).getRelativeOf(test_asset_test4_rel); Assert.assertNotNull(uri2); Assert.assertEquals(test_asset_test4b_url, uri2.toString()); testAssetConnection(uri2.toURL().openConnection(), test_asset_test4_entry); diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/net/AssetURLConnectionUnregisteredTest.java gluegen2-2.3.2/src/junit/com/jogamp/common/net/AssetURLConnectionUnregisteredTest.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/net/AssetURLConnectionUnregisteredTest.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/net/AssetURLConnectionUnregisteredTest.java 2015-10-09 04:18:28.000000000 +0000 @@ -1,7 +1,6 @@ package com.jogamp.common.net; import java.io.IOException; -import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; @@ -39,14 +38,14 @@ @Test public void assetUnregisteredIOUtilGetResourceRel0_RT() throws IOException, URISyntaxException { - final URLConnection urlConn0 = IOUtil.getResource(this.getClass(), test_asset_test2_rel); + final URLConnection urlConn0 = IOUtil.getResource(test_asset_test2_rel.get(), this.getClass().getClassLoader(), this.getClass()); testAssetConnection(urlConn0, test_asset_test2_entry); - final URI uri1 = IOUtil.getRelativeOf(urlConn0.getURL().toURI(), test_asset_test3_rel); + final Uri uri1 = Uri.valueOf(urlConn0.getURL()).getRelativeOf(test_asset_test3_rel); Assert.assertNotNull(uri1); // JARFile URL .. testAssetConnection(uri1.toURL().openConnection(), test_asset_test3_entry); - final URI uri2 = IOUtil.getRelativeOf(urlConn0.getURL().toURI(), test_asset_test4_rel); + final Uri uri2 = Uri.valueOf(urlConn0.getURL()).getRelativeOf(test_asset_test4_rel); Assert.assertNotNull(uri2); testAssetConnection(uri2.toURL().openConnection(), test_asset_test4_entry); } diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/net/TestNetIOURIReservedCharsBug908.java gluegen2-2.3.2/src/junit/com/jogamp/common/net/TestNetIOURIReservedCharsBug908.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/net/TestNetIOURIReservedCharsBug908.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/net/TestNetIOURIReservedCharsBug908.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,170 +0,0 @@ -/** - * Copyright 2014 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ - -package com.jogamp.common.net; - -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLClassLoader; - -import org.junit.Assert; -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runners.MethodSorters; - -import com.jogamp.common.os.AndroidVersion; -import com.jogamp.common.os.Platform; -import com.jogamp.common.util.IOUtil; -import com.jogamp.common.util.JarUtil; -import com.jogamp.common.util.ReflectionUtil; -import com.jogamp.junit.util.JunitTracer; -import com.jogamp.junit.util.MiscUtils; - -/** - * Bug 908: Automated test, launching GlueGen jar file from an odd pathname. - *

    - * The currently used jar folder is copied into [1] - *

    - *    [1] build/test/build/TestNetIOURIReservedCharsBug908/test01TempJarCacheOddPath/A\$-B\^-C~-D#-E\]-F\[-öä
    - *    [2] build/test/build/TestNetIOURIReservedCharsBug908/test01TempJarCacheOddPath/A\$-B\^-C~-D#-E\]-F\[-öä/gluegen-rt.jar
    - * 
    - * A ClassLoader w/ the URL [2] is used to issue Platform.initSingleton(), - * i.e. issues a whole initialization sequence w/ native jar loading in the new ClassPath. - *

    - *

    - * The manual test below on the created odd folder [1] has also succeeded: - *

    - * java \
    - *     -Djogamp.debug.IOUtil -Djogamp.debug.JNILibLoader -Djogamp.debug.TempFileCache \
    - *     -Djogamp.debug.JarUtil -Djogamp.debug.TempJarCache \
    - *     -cp ../build-x86_64/test/build/TestNetIOURIReservedCharsBug908/test01TempJarCacheOddPath/A\$-B\^-C~-D#-E\]-F\[-öä/gluegen-rt.jar \
    - *     com.jogamp.common.GlueGenVersion
    - * 
    - *

    - */ -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestNetIOURIReservedCharsBug908 extends JunitTracer { - static class TestClassLoader extends URLClassLoader { - public TestClassLoader(final URL[] urls) { - super(urls); - } - public TestClassLoader(final URL[] urls, final ClassLoader parent) { - super(urls, parent); - } - } - - - @Test - public void test00TempJarCacheSimplePath() throws IOException, IllegalArgumentException, URISyntaxException { - testTempJarCacheOddJarPathImpl("simpletons/", "simpletons/"); - } - - @Test - public void test01TempJarCacheOddPath() throws IOException, IllegalArgumentException, URISyntaxException { - // Bug 908, issues w/ windows file path char: $ ^ ~ # [ ] - testTempJarCacheOddJarPathImpl("A$-B^-C~-D#-E]-F[-öä/", - // "A$-B%5E-C~-D#-E]-F[-%C3%B6%C3%A4/"); <- Firefox URI encoding! '#' -> [1] - // "A$-B%5E-C~-D%23-E]-F[-%C3%B6%C3%A4/"); <- '[' ']' -> [2] - "A$-B%5E-C~-D%23-E%5D-F%5B-%C3%B6%C3%A4/"); - /** - * [1] '#' - java.lang.IllegalArgumentException: URI has a fragment component - at java.io.File.(Unknown Source) - at com.jogamp.common.net.TestNetIOURIReservedCharsBug908.testTempJarCacheOddJarPathImpl(TestNetIOURIReservedCharsBug908.java:101) - [2] '[' ']' - java.net.URISyntaxException: Illegal character in path at index 137: file:/usr/local/projects/JOGL/gluegen/build-x86_64/test/build/TestNetIOURIReservedCharsBug908/test01TempJarCacheOddPath/A$-B%5E-C~-D%23-E]-F[-%C3%B6%C3%A4/ - at java.net.URI$Parser.fail(Unknown Source) - at java.net.URI$Parser.checkChars(Unknown Source) - at java.net.URI$Parser.parseHierarchical(Unknown Source) - at java.net.URI$Parser.parse(Unknown Source) - at java.net.URI.(Unknown Source) - at com.jogamp.common.net.TestNetIOURIReservedCharsBug908.testTempJarCacheOddJarPathImpl(TestNetIOURIReservedCharsBug908.java:106) - - */ - - } - private void testTempJarCacheOddJarPathImpl(final String subPathUTF, final String subPathEncoded) throws IOException, IllegalArgumentException, URISyntaxException { - if(AndroidVersion.isAvailable) { System.err.println("n/a on Android"); return; } - - final String reservedCharPathUnencoded = "test/build/"+getClass().getSimpleName()+"/"+getTestMethodName()+"/"+subPathUTF; - final String reservedCharPathEncoded = "test/build/"+getClass().getSimpleName()+"/"+getTestMethodName()+"/"+subPathEncoded; - - System.err.println("0 Unencoded: "+reservedCharPathUnencoded); - System.err.println("0 Encoded: "+reservedCharPathEncoded); - - // jar:file:/dir1/dir2/gluegen-rt.jar!/ - final URI jarFileURI = JarUtil.getJarFileURI(Platform.class.getName(), getClass().getClassLoader()); - System.err.println("1 jarFileURI: "+jarFileURI.toString()); - // gluegen-rt.jar - final String jarBasename = JarUtil.getJarBasename(jarFileURI); - System.err.println("2 jarBasename: "+jarBasename); - - // file:/dir1/build/gluegen-rt.jar - final URI fileURI = JarUtil.getJarSubURI(jarFileURI); - System.err.println("3 fileURI: "+fileURI.toString()); - // file:/dir1/build/ - final URI fileFolderURI = new URI(IOUtil.getParentOf(fileURI.toString())); - System.err.println("4 fileFolderURI: "+fileFolderURI.toString()); - // file:/dir1/build/test/build/A$-B^-C~-D#-E]-F[/ - final URI fileNewFolderURI = new URI(fileFolderURI.toString()+reservedCharPathEncoded); - System.err.println("5 fileNewFolderURI: "+fileNewFolderURI.toString()); - - final File srcFolder = new File(fileFolderURI); - final File dstFolder = new File(fileNewFolderURI); - System.err.println("6 srcFolder: "+srcFolder.toString()); - System.err.println("7 dstFolder: "+dstFolder.toString()); - try { - final MiscUtils.CopyStats copyStats = MiscUtils.copy(srcFolder, dstFolder, 1, true); - copyStats.dump("Copy ", true); - Assert.assertEquals(1, copyStats.totalFolders); - Assert.assertTrue(copyStats.totalBytes > 0); - Assert.assertEquals(0, copyStats.currentDepth); - - final URI jarFileNewFolderURI = new URI(fileNewFolderURI.toString()+jarBasename); - System.err.println("8 jarFileNewFolderURI: "+jarFileNewFolderURI.toString()); - - final URL[] urls = new URL[] { jarFileNewFolderURI.toURL() }; - System.err.println("url: "+urls[0]); - - final ClassLoader cl = new TestClassLoader(urls, null); - ReflectionUtil.callStaticMethod(Platform.class.getName(), "initSingleton", null, null, cl); - } finally { - // cleanup ? Skip this for now .. - // dstFolder.delete(); - } - } - - public static void main(final String args[]) throws IOException { - final String tstname = TestNetIOURIReservedCharsBug908.class.getName(); - org.junit.runner.JUnitCore.main(tstname); - } - -} diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/net/TestUri01.java gluegen2-2.3.2/src/junit/com/jogamp/common/net/TestUri01.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/net/TestUri01.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/net/TestUri01.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,461 @@ +package com.jogamp.common.net; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +import org.junit.Assert; +import org.junit.Test; + +import com.jogamp.common.net.URIDumpUtil; +import com.jogamp.common.util.IOUtil; +import com.jogamp.junit.util.SingletonJunitCase; + +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestUri01 extends SingletonJunitCase { + + @Test + public void test00BasicCoding() throws IOException, URISyntaxException { + final String string = "Hallo Welt öä"; + System.err.println("sp1 "+string); + final File file = new File(string); + System.err.println("file "+file); + System.err.println("file.path.dec "+file.getPath()); + System.err.println("file.path.abs "+file.getAbsolutePath()); + System.err.println("file.path.can "+file.getCanonicalPath()); + final Uri uri0 = Uri.valueOf(file); + URIDumpUtil.showUri(uri0); + URIDumpUtil.showReencodedURIOfUri(uri0); + + boolean ok = true; + { + final String s2 = IOUtil.slashify(file.getAbsolutePath(), true /* startWithSlash */, file.isDirectory() /* endWithSlash */); + System.err.println("uri2.slashify: "+s2); + final Uri uri1 = Uri.create(Uri.FILE_SCHEME, null, s2, null); + final boolean equalEncoded= uri0.getEncoded().equals(uri1.getEncoded()); + final boolean equalPath = uri0.path.decode().equals(uri1.path.decode()); + final boolean equalASCII= uri0.toASCIIString().equals(uri1.toASCIIString().get()); + System.err.println("uri2.enc : "+uri1.getEncoded()+" - "+(equalEncoded?"OK":"ERROR")); + System.err.println("uri2.pathD : "+uri1.path.decode()+" - "+(equalPath?"OK":"ERROR")); + System.err.println("uri2.asciiE: "+uri1.toASCIIString()+" - "+(equalASCII?"OK":"ERROR")); + ok = equalEncoded && equalPath && equalASCII && ok; + } + { + final String s2 = "/"+string; + System.err.println("uri3.orig: "+s2); + final Uri uri1 = Uri.create(Uri.FILE_SCHEME, s2, null); + final String rString = "file:/Hallo%20Welt%20öä"; + final String rPath = s2; + final String rASCII = "file:/Hallo%20Welt%20%C3%B6%C3%A4"; + final boolean equalEncoded = rString.equals(uri1.toString()); + final boolean equalPath = rPath.equals(uri1.path.decode()); + final boolean equalASCII= rASCII.equals(uri1.toASCIIString().get()); + System.err.println("uri3.enc : "+uri1.toString()+" - "+(equalEncoded?"OK":"ERROR")); + System.err.println("uri3.pathD : "+uri1.path.decode()+" - "+(equalPath?"OK":"ERROR")); + System.err.println("uri3.asciiE: "+uri1.toASCIIString()+" - "+(equalASCII?"OK":"ERROR")); + ok = equalEncoded && equalPath && equalASCII && ok; + } + { + final String s2 = "//lala.org/"+string; + System.err.println("uri4.orig: "+s2); + final Uri uri1 = Uri.create(Uri.HTTP_SCHEME, s2, null); + final String rString = "http://lala.org/Hallo%20Welt%20öä"; + final String rPath = "/"+string; + final String rASCII = "http://lala.org/Hallo%20Welt%20%C3%B6%C3%A4"; + final boolean equalString= rString.equals(uri1.toString()); + final boolean equalPath = rPath.equals(uri1.path.decode()); + final boolean equalASCII= rASCII.equals(uri1.toASCIIString().get()); + System.err.println("uri4.enc : "+uri1.toString()+" - "+(equalString?"OK":"ERROR")); + System.err.println("uri4.pathD : "+uri1.path.decode()+" - "+(equalPath?"OK":"ERROR")); + System.err.println("uri4.asciiE: "+uri1.toASCIIString()+" - "+(equalASCII?"OK":"ERROR")); + ok = equalString && equalPath && equalASCII && ok; + } + Assert.assertTrue("One or more errors occured see stderr above", ok); + } + + @Test + public void test02URIEscapeSpecialChars() throws IOException, URISyntaxException { + { + final String vanilla = "XXX ! # $ & ' ( ) * + , / : ; = ? @ [ ]"; + final Uri.Encoded escaped = Uri.Encoded.cast("XXX%20!%20%23%20%24%20%26%20%27%20%28%20%29%20%2A%20%2B%20%2C%20/%20%3A%20%3B%20%3D%20%3F%20%40%20%5B%20%5D"); + System.err.println("vanilla "+vanilla); + final Uri.Encoded esc1 = new Uri.Encoded(vanilla, Uri.PATH_LEGAL); + System.err.println("esc1 "+esc1); + Assert.assertEquals(escaped, esc1); + + final String invEsc1 = esc1.decode(); + System.err.println("inv(esc1) "+invEsc1); + Assert.assertEquals(vanilla, invEsc1); + } + { + final String vanilla = "/XXX R!# R$&'()*+,/:;=?z@y[x]"; + final Uri.Encoded escaped = Uri.Encoded.cast("/XXX%20R!%23%20R%24%26%27%28%29%2A%2B%2C/%3A%3B%3D%3Fz%40y%5Bx%5D"); + System.err.println("vanilla "+vanilla); + final Uri.Encoded esc1 = new Uri.Encoded(vanilla, Uri.PATH_LEGAL); + System.err.println("esc1 "+esc1); + Assert.assertEquals(escaped, esc1); + + final String invEsc1 = esc1.decode(); + System.err.println("inv(esc1) "+invEsc1); + Assert.assertEquals(vanilla, invEsc1); + } + { + // Bug 908: $ ^ ~ # [ ] + final String vanilla = "/XXX $ ^ ~ # [ ]"; + showDump0x(vanilla); + } + { + // Windows invalid File characters: * ? " < > | + final String vanilla = "/XXX ! & ' ( ) + , / ; = @ [ ]"; + showDump0x(vanilla); + } + } + @Test + public void test03URIEscapeCommonChars() throws IOException, URISyntaxException { + { + final String vanilla = "/XXX \"%-.<>\\^_`{|}~"; + final Uri.Encoded escaped = Uri.Encoded.cast("/XXX%20%22%25-.%3C%3E%5C%5E_%60%7B%7C%7D~"); + System.err.println("vanilla "+vanilla); + final Uri.Encoded esc1 = new Uri.Encoded(vanilla, Uri.PATH_LEGAL); + System.err.println("esc1 "+esc1); + Assert.assertEquals(escaped, esc1); + + final String invEsc1 = esc1.decode(); + System.err.println("inv(esc1) "+invEsc1); + Assert.assertEquals(vanilla, invEsc1); + showDump0x(vanilla); + } + } + private static void showDump0x(final String string) throws IOException, URISyntaxException { + final File file = new File(string); + System.err.println("file "+file); + System.err.println("file.path.dec "+file.getPath()); + System.err.println("file.path.abs "+file.getAbsolutePath()); + System.err.println("file.path.can "+file.getCanonicalPath()); + + System.err.println("File-path -> Uri:"); + final Uri uri0 = Uri.valueOfFilepath(string); + URIDumpUtil.showUri(uri0); + + System.err.println("Uri -> File:"); + final Uri uri2 = Uri.valueOf(file); + URIDumpUtil.showUri(uri2); + + System.err.println("Uri -> URI:"); + final URI uri3 = uri2.toURI(); + URIDumpUtil.showURI(uri3); + + System.err.println("URI -> Uri (keep encoding):"); + final Uri uri4 = Uri.valueOf(uri3); + URIDumpUtil.showUri(uri4); + + System.err.println("URI -> Uri (re-encode):"); + final Uri uri5 = Uri.valueOf(uri3); + URIDumpUtil.showUri(uri5); + } + + @Test + public void test04EqualsAndHashCode() throws IOException, URISyntaxException { + { + final Uri uri0 = Uri.cast("http://localhost/test01.html#tag01"); + final Uri uri1 = Uri.create("http", null, "localhost", -1, "/test01.html", null, "tag01"); + final Uri uri2 = Uri.create("http", "localhost", "/test01.html", "tag01"); + + Assert.assertEquals(uri0, uri1); + Assert.assertEquals(uri0.hashCode(), uri1.hashCode()); + + Assert.assertEquals(uri0, uri2); + Assert.assertEquals(uri0.hashCode(), uri2.hashCode()); + + Assert.assertEquals(uri1, uri2); + Assert.assertEquals(uri1.hashCode(), uri2.hashCode()); + + final Uri uriA = Uri.create("http", null, "localhost", -1, "/test02.html", null, "tag01"); + final Uri uriB = Uri.create("http", null, "localhost", -1, "/test01.html", null, "tag02"); + final Uri uriC = Uri.create("http", null, "lalalhost", -1, "/test01.html", null, "tag01"); + final Uri uriD = Uri.create("sftp", null, "localhost", -1, "/test01.html", null, "tag01"); + + Assert.assertNotEquals(uri1, uriA); + Assert.assertNotEquals(uri1, uriB); + Assert.assertNotEquals(uri1, uriC); + Assert.assertNotEquals(uri1, uriD); + } + { // 3 [scheme:][//[user-info@]host[:port]]path[?query][#fragment] + final Uri uri0 = Uri.cast("http://user@localhost:80/test01.html?test=01&test=02#tag01"); + final Uri uri1 = Uri.create("http", "user", "localhost", 80, "/test01.html", "test=01&test=02", "tag01"); + + Assert.assertEquals(uri0, uri1); + Assert.assertEquals(uri0.hashCode(), uri1.hashCode()); + + final Uri uriA = Uri.cast("http://user@localhost:80/test01.html?test=01&test=02#tag02"); + final Uri uriB = Uri.cast("http://user@localhost:80/test01.html?test=01&test=03#tag01"); + final Uri uriC = Uri.cast("http://user@localhost:80/test04.html?test=01&test=02#tag01"); + final Uri uriD = Uri.cast("http://user@localhost:88/test01.html?test=01&test=02#tag01"); + final Uri uriE = Uri.cast("http://user@lalalhost:80/test01.html?test=01&test=02#tag01"); + final Uri uriF = Uri.cast("http://test@localhost:80/test01.html?test=01&test=02#tag01"); + final Uri uriG = Uri.cast("sftp://user@localhost:80/test01.html?test=01&test=02#tag01"); + + Assert.assertNotEquals(uri1, uriA); + Assert.assertNotEquals(uri1, uriB); + Assert.assertNotEquals(uri1, uriC); + Assert.assertNotEquals(uri1, uriD); + Assert.assertNotEquals(uri1, uriE); + Assert.assertNotEquals(uri1, uriF); + Assert.assertNotEquals(uri1, uriG); + } + } + + @Test + public void test05Contained() throws IOException, URISyntaxException { + { + final Uri input = Uri.cast("http://localhost/test01.html#tag01"); + final Uri contained = input.getContainedUri(); + Assert.assertNull(contained); + } + { + final Uri input = Uri.cast("jar:http://localhost/test01.jar!/com/jogamp/Lala.class#tag01"); + final Uri expected = Uri.cast("http://localhost/test01.jar#tag01"); + final Uri contained = input.getContainedUri(); + URIDumpUtil.showUri(input); + URIDumpUtil.showUri(contained); + Assert.assertEquals(expected, contained); + Assert.assertEquals(expected.hashCode(), contained.hashCode()); + } + { + final Uri input = Uri.cast("jar:file://localhost/test01.jar!/"); + final Uri expected = Uri.cast("file://localhost/test01.jar"); + final Uri contained = input.getContainedUri(); + URIDumpUtil.showUri(input); + URIDumpUtil.showUri(contained); + Assert.assertEquals(expected, contained); + Assert.assertEquals(expected.hashCode(), contained.hashCode()); + } + { + final Uri input = Uri.cast("sftp:http://localhost/test01.jar?lala=01#tag01"); + final Uri expected = Uri.cast("http://localhost/test01.jar?lala=01#tag01"); + final Uri contained = input.getContainedUri(); + URIDumpUtil.showUri(input); + URIDumpUtil.showUri(contained); + Assert.assertEquals(expected, contained); + Assert.assertEquals(expected.hashCode(), contained.hashCode()); + } + } + + @Test + public void test08NormalizedHierarchy() throws IOException, URISyntaxException { + { + final Uri input = Uri.cast("./dummy/nop/../a.txt"); + final Uri expected = Uri.cast("dummy/a.txt"); + URIDumpUtil.showUri(input); + final Uri normal = input.getNormalized(); + Assert.assertEquals(expected, normal); + } + { + final Uri input = Uri.cast("../dummy/nop/../a.txt"); + final Uri expected = Uri.cast("../dummy/a.txt"); + URIDumpUtil.showUri(input); + final Uri normal = input.getNormalized(); + Assert.assertEquals(expected, normal); + } + { + final Uri input = Uri.cast("http://localhost/dummy/../"); + final Uri expected = Uri.cast("http://localhost/"); + URIDumpUtil.showUri(input); + final Uri normal = input.getNormalized(); + Assert.assertEquals(expected, normal); + } + { + final Uri input = Uri.cast("http://localhost/dummy/./../"); + final Uri expected = Uri.cast("http://localhost/"); + URIDumpUtil.showUri(input); + final Uri normal = input.getNormalized(); + Assert.assertEquals(expected, normal); + } + { + final Uri input = Uri.cast("http://localhost/dummy/../aa/././../"); + final Uri expected = Uri.cast("http://localhost/"); + URIDumpUtil.showUri(input); + final Uri normal = input.getNormalized(); + Assert.assertEquals(expected, normal); + } + { + final Uri input = Uri.cast("http://localhost/test/dummy/./../text.txt"); + final Uri expected = Uri.cast("http://localhost/test/text.txt"); + URIDumpUtil.showUri(input); + final Uri normal = input.getNormalized(); + Assert.assertEquals(expected, normal); + } + { + final Uri input = Uri.cast("http://localhost/test/dummy/../text.txt?lala=01&lili=02#frag01"); + final Uri expected = Uri.cast("http://localhost/test/text.txt?lala=01&lili=02#frag01"); + URIDumpUtil.showUri(input); + final Uri normal = input.getNormalized(); + Assert.assertEquals(expected, normal); + } + } + + @Test + public void test09NormalizedOpaque() throws IOException, URISyntaxException { + { + final Uri input = Uri.cast("jar:http://localhost/dummy/../abc.jar!/"); + final Uri expected = Uri.cast("jar:http://localhost/abc.jar!/"); + URIDumpUtil.showUri(input); + final Uri normal = input.getNormalized(); + Assert.assertEquals(expected, normal); + } + { + final Uri input = Uri.cast("jar:http://localhost/test/./dummy/../abc.jar!/"); + final Uri expected = Uri.cast("jar:http://localhost/test/abc.jar!/"); + URIDumpUtil.showUri(input); + final Uri normal = input.getNormalized(); + Assert.assertEquals(expected, normal); + } + { + final Uri input = Uri.cast("jar:http://localhost/test/dummy/../abc.jar!/a/b/C.class"); + final Uri expected = Uri.cast("jar:http://localhost/test/abc.jar!/a/b/C.class"); + URIDumpUtil.showUri(input); + final Uri normal = input.getNormalized(); + Assert.assertEquals(expected, normal); + } + { + final Uri input = Uri.cast("jar:http://localhost/test/dummy/../abc.jar!/a/b/C.class?lala=01&lili=02#frag01"); + final Uri expected = Uri.cast("jar:http://localhost/test/abc.jar!/a/b/C.class?lala=01&lili=02#frag01"); + URIDumpUtil.showUri(input); + final Uri normal = input.getNormalized(); + Assert.assertEquals(expected, normal); + } + } + + @Test + public void test10ParentAndDirHierarchy() throws IOException, URISyntaxException { + { + final Uri input = Uri.cast("http://localhost/"); + URIDumpUtil.showUri(input); + final Uri directory = input.getDirectory(); + Assert.assertEquals(input, directory); + final Uri parent = input.getParent(); + Assert.assertNull(parent); + } + { + final Uri input = Uri.cast("http://localhost/dummy/../test/"); + final Uri expectedD = Uri.cast("http://localhost/test/"); + final Uri expectedP = Uri.cast("http://localhost/"); + URIDumpUtil.showUri(input); + final Uri directory = input.getDirectory(); + Assert.assertEquals(expectedD, directory); + final Uri parent = input.getParent(); + Assert.assertEquals(expectedP, parent); + } + { + final Uri input = Uri.cast("http://localhost/dummy/../test/dummy/../"); + final Uri expectedD = Uri.cast("http://localhost/test/"); + final Uri expectedP = Uri.cast("http://localhost/"); + URIDumpUtil.showUri(input); + final Uri directory = input.getDirectory(); + Assert.assertEquals(expectedD, directory); + final Uri parent = input.getParent(); + Assert.assertEquals(expectedP, parent); + } + { + final Uri input = Uri.cast("http://localhost/dir/test01.jar?lala=01#frag01"); + final Uri expParen1 = Uri.cast("http://localhost/dir/?lala=01#frag01"); + final Uri expFolde1 = expParen1; + final Uri expParen2 = Uri.cast("http://localhost/?lala=01#frag01"); + final Uri expFolde2 = expParen1; // is folder already + final Uri expParen3 = null; + final Uri expFolde3 = expParen2; + Assert.assertNotEquals(input, expParen1); + Assert.assertNotEquals(expParen1, expParen2); + Assert.assertNotEquals(expParen1, expParen3); + URIDumpUtil.showUri(input); + + final Uri parent1 = input.getParent(); + Assert.assertEquals(expParen1, parent1); + Assert.assertEquals(expParen1.hashCode(), parent1.hashCode()); + final Uri folder1 = input.getDirectory(); + Assert.assertEquals(expFolde1, folder1); + + final Uri parent2 = parent1.getParent(); + Assert.assertEquals(expParen2, parent2); + Assert.assertEquals(expParen2.hashCode(), parent2.hashCode()); + final Uri folder2 = parent1.getDirectory(); + Assert.assertEquals(expFolde2, folder2); + + final Uri parent3 = parent2.getParent(); + Assert.assertEquals(expParen3, parent3); // NULL! + final Uri folder3 = parent2.getDirectory(); + Assert.assertEquals(expFolde3, folder3); // NULL! + } + } + + @Test + public void test11ParentAndDirOpaque() throws IOException, URISyntaxException { + { + final Uri input = Uri.cast("jar:http://localhost/test.jar!/"); + URIDumpUtil.showUri(input); + final Uri directory = input.getDirectory(); + Assert.assertEquals(input, directory); + final Uri parent = input.getParent(); + Assert.assertNull(parent); + } + { + final Uri input = Uri.cast("jar:http://localhost/dummy/../test/test.jar!/"); + final Uri expectedD = Uri.cast("jar:http://localhost/test/test.jar!/"); + final Uri expectedP = null; + URIDumpUtil.showUri(input); + final Uri directory = input.getDirectory(); + Assert.assertEquals(expectedD, directory); + final Uri parent = input.getParent(); + Assert.assertEquals(expectedP, parent); + } + { + final Uri input = Uri.cast("jar:http://localhost/dummy/../test/dummy/../test.jar!/a/b/C.class"); + final Uri expectedD = Uri.cast("jar:http://localhost/test/test.jar!/a/b/"); + final Uri expectedP = Uri.cast("jar:http://localhost/test/test.jar!/a/b/"); + URIDumpUtil.showUri(input); + final Uri directory = input.getDirectory(); + Assert.assertEquals(expectedD, directory); + final Uri parent = input.getParent(); + Assert.assertEquals(expectedP, parent); + } + { + final Uri input = Uri.cast("jar:http://localhost/test01.jar!/com/Lala.class?lala=01#frag01"); + final Uri expParen1 = Uri.cast("jar:http://localhost/test01.jar!/com/?lala=01#frag01"); + final Uri expFolde1 = expParen1; + final Uri expParen2 = Uri.cast("jar:http://localhost/test01.jar!/?lala=01#frag01"); + final Uri expFolde2 = expParen1; // is folder already + final Uri expParen3 = null; + final Uri expFolde3 = expParen2; // is folder already + Assert.assertNotEquals(input, expParen1); + Assert.assertNotEquals(expParen1, expParen2); + Assert.assertNotEquals(expParen1, expParen3); + URIDumpUtil.showUri(input); + + final Uri parent1 = input.getParent(); + Assert.assertEquals(expParen1, parent1); + Assert.assertEquals(expParen1.hashCode(), parent1.hashCode()); + final Uri folder1 = input.getDirectory(); + Assert.assertEquals(expFolde1, folder1); + + final Uri parent2 = parent1.getParent(); + Assert.assertEquals(expParen2, parent2); + Assert.assertEquals(expParen2.hashCode(), parent2.hashCode()); + final Uri folder2 = parent1.getDirectory(); + Assert.assertEquals(expFolde2, folder2); + + final Uri parent3 = parent2.getParent(); + Assert.assertEquals(expParen3, parent3); // NULL + final Uri folder3 = parent2.getDirectory(); + Assert.assertEquals(expFolde3, folder3); + } + } + + public static void main(final String args[]) throws IOException { + final String tstname = TestUri01.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } +} diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/net/TestUri02Composing.java gluegen2-2.3.2/src/junit/com/jogamp/common/net/TestUri02Composing.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/net/TestUri02Composing.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/net/TestUri02Composing.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,96 @@ +package com.jogamp.common.net; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.jogamp.junit.util.SingletonJunitCase; + +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestUri02Composing extends SingletonJunitCase { + + @BeforeClass + public static void assetRegistration() throws Exception { + try { + System.err.println("******* Asset URL Stream Handler Registration: PRE"); + Assert.assertTrue("GenericURLStreamHandlerFactory.register() failed", AssetURLContext.registerHandler(AssetURLConnectionRegisteredTest.class.getClassLoader())); + Assert.assertNotNull(AssetURLContext.getRegisteredHandler()); + System.err.println("******* Asset URL Stream Handler Registration: POST"); + } catch (final Exception e) { + setTestSupported(false); + throw e; + } + } + + @Test + public void test01URLCompositioning() throws IOException, URISyntaxException { + testURNCompositioning("file:///rootDir/file1.txt"); + testURNCompositioning("file://host/rootDir/file1.txt"); + testURNCompositioning("jar:file:/web1/file1.jar!/rootDir/file1.txt"); + testURNCompositioning("asset:gluegen-test/info.txt"); + testURNCompositioning("asset:/gluegen-test/info.txt"); + testURNCompositioning("http://domain.com/web1/index.html?lala=23&lili=24#anchor"); + testURNCompositioning("http://domain.com:1234/web1/index.html?lala=23&lili=24#anchor"); + + final Uri file1URI = Uri.cast("asset:jar:file:/web1/file1.jar!/rootDir/file1.txt"); + testURICompositioning(file1URI); + testUriCompositioning(file1URI, Uri.cast("asset:jar:file:/web1/file1.jar!/rootDir/./file1.txt")); + testUriCompositioning(file1URI, Uri.cast("asset:jar:file:/web1/file1.jar!/rootDir/dummyParent/../file1.txt")); + + final URL file1URL = new URL("asset:jar:file:/web1/file1.jar!/rootDir/file1.txt"); + testURLCompositioning(file1URL); + testURLCompositioning(file1URL, new URL("asset:jar:file:/web1/file1.jar!/rootDir/./file1.txt")); + testURLCompositioning(file1URL, new URL("asset:jar:file:/web1/file1.jar!/rootDir/dummyParent/../file1.txt")); + } + + static void testURNCompositioning(final String urn) throws MalformedURLException, URISyntaxException { + testURICompositioning( Uri.cast(urn) ); + testURLCompositioning( new URL(urn) ); + } + + static void testURICompositioning(final Uri uri) throws MalformedURLException, URISyntaxException { + testUriCompositioning(uri, uri); + } + static void testUriCompositioning(final Uri refURI, final Uri uri1) throws MalformedURLException, URISyntaxException { + System.err.println("scheme <"+uri1.scheme+">, ssp <"+uri1.schemeSpecificPart+">, fragment <"+uri1.fragment+">"); + final Uri uri2 = uri1.getRelativeOf(null); + + System.err.println("URL-equals: "+refURI.equals(uri2)); + System.err.println("URL-ref : <"+refURI+">"); + System.err.println("URL-orig : <"+uri1+">"); + System.err.println("URL-comp : <"+uri2+">"); + Assert.assertEquals(refURI, uri2); + } + + static void testURLCompositioning(final URL url) throws MalformedURLException, URISyntaxException { + testURLCompositioning(url, url); + } + static void testURLCompositioning(final URL refURL, final URL url1) throws MalformedURLException, URISyntaxException { + final Uri uri1 = Uri.valueOf(url1); + System.err.println("scheme <"+uri1.scheme+">, ssp <"+uri1.schemeSpecificPart+">, fragment <"+uri1.fragment+">"); + final Uri uri2 = uri1.getRelativeOf(null); + + System.err.println("URL-equals(1): "+refURL.toURI().equals(uri2)); + System.err.println("URL-equals(2): "+refURL.equals(uri2.toURL())); + System.err.println("URL-same : "+refURL.sameFile(uri2.toURL())); + System.err.println("URL-ref : <"+refURL+">"); + System.err.println("URL-orig : <"+url1+">"); + System.err.println("URL-comp : <"+uri2+">"); + Assert.assertEquals(Uri.valueOf(refURL), uri2); + Assert.assertEquals(refURL, uri2.toURL()); + Assert.assertTrue(refURL.sameFile(uri2.toURL())); + } + + public static void main(final String args[]) throws IOException { + final String tstname = TestUri02Composing.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } +} diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/net/TestUri03Resolving.java gluegen2-2.3.2/src/junit/com/jogamp/common/net/TestUri03Resolving.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/net/TestUri03Resolving.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/net/TestUri03Resolving.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,430 @@ +package com.jogamp.common.net; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; + +import jogamp.common.os.PlatformPropsImpl; + +import org.junit.Assert; +import org.junit.Test; + +import com.jogamp.common.net.Uri; +import com.jogamp.common.os.Platform; +import com.jogamp.junit.util.SingletonJunitCase; + +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestUri03Resolving extends SingletonJunitCase { + + // Bug 908, issues w/ windows file path char: $ ^ ~ # [ ] + + private static final String[][] uriHttpSArray = new String[][] { + new String[] {"http://localhost/gluegen/build-x86_64/gluegen-rt.jar"}, + + new String[] {"http://localhost/gluegen/"+'\u0394'+"/gluegen-rt.jar"}, + + new String[] {"http://localhost/gluegen/build-x86_64%20lala/gluegen-rt.jar"}, + + new String[] {"http://localhost/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar"}, + + new String[] {"jar:http://localhost/gluegen/build-x86_64/gluegen-rt.jar!/"}, + + new String[] {"jar:http://localhost/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/"}, + + new String[] {"jar:http://localhost/gluegen/build-x86_64/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, + + new String[] {"jar:http://localhost/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, + + new String[] {"jar:http://localhost/gluegen/R%23/gluegen-rt.jar!/"}, + + new String[] {"jar:http://localhost/gluegen/A%24/B%5E/C~/D%23/E%5B/F%5D/gluegen-rt.jar!/"}, + + new String[] {"jar:http://localhost/gluegen/%24/%5E/~/%23/%5B/%5D/gluegen-rt.jar!/"}, + + new String[] {"jar:http://localhost/gluegen/"+'\u0394'+"/gluegen-rt.jar!/"}, + }; + + private static final String[][] uriFileSArrayUnix = new String[][] { + new String[] {"file:/gluegen/build-x86_64/gluegen-rt.jar"}, + + new String[] {"file:/gluegen/"+'\u0394'+"/gluegen-rt.jar"}, + + new String[] {"file:/gluegen/build-x86_64%20lala/gluegen-rt.jar"}, + + new String[] {"file:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar"}, + + new String[] {"jar:file:/gluegen/build-x86_64/gluegen-rt.jar!/"}, + + new String[] {"jar:file:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/"}, + + new String[] {"jar:file:/gluegen/build-x86_64/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, + + new String[] {"jar:file:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, + + new String[] {"jar:file://filehost/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, + + new String[] {"jar:file:/gluegen/R%23/gluegen-rt.jar!/"}, + + new String[] {"jar:file:/gluegen/A%24/B%5E/C~/D%23/E%5B/F%5D/gluegen-rt.jar!/"}, + + new String[] {"jar:file:/gluegen/%24/%5E/~/%23/%5B/%5D/gluegen-rt.jar!/"}, + + new String[] {"jar:file:/gluegen/"+'\u0394'+"/gluegen-rt.jar!/"}, + }; + + private static final String[][] uriFileSArrayWindows = new String[][] { + new String[] {"file:/C%3A/gluegen/build-x86_64/gluegen-rt.jar"}, + + new String[] {"file:/C%3A/gluegen/"+'\u0394'+"/gluegen-rt.jar"}, + + new String[] {"file:/C%3A/gluegen/build-x86_64%20lala/gluegen-rt.jar"}, + + new String[] {"file:/C%3A/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar"}, + + new String[] {"jar:file:/C%3A/gluegen/build-x86_64/gluegen-rt.jar!/"}, + + new String[] {"jar:file:/C%3A/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/"}, + + new String[] {"jar:file:/C%3A/gluegen/build-x86_64/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, + + new String[] {"jar:file:/C%3A/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, + + new String[] {"jar:file:///C%3A/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, + + new String[] {"jar:file://filehost/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, + + new String[] {"jar:file:/C%3A/gluegen/R%23/gluegen-rt.jar!/"}, + + new String[] {"jar:file:/C%3A/gluegen/A%24/B%5E/C~/D%23/E%5B/F%5D/gluegen-rt.jar!/"}, + + new String[] {"jar:file:/C%3A/gluegen/%24/%5E/~/%23/%5B/%5D/gluegen-rt.jar!/"}, + + new String[] {"jar:file:/C%3A/gluegen/"+'\u0394'+"/gluegen-rt.jar!/"}, + }; + + private static final String[][] urlFileSArrayWindows = new String[][] { + new String[] {"file:/C:/gluegen/build-x86_64/gluegen-rt.jar"}, + + new String[] {"file:/C:/gluegen/"+'\u0394'+"/gluegen-rt.jar"}, + + new String[] {"file:/C:/gluegen/build-x86_64%20lala/gluegen-rt.jar"}, + + new String[] {"file:/C:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar"}, + + new String[] {"jar:file:/C:/gluegen/build-x86_64/gluegen-rt.jar!/"}, + + new String[] {"jar:file:/C:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/"}, + + new String[] {"jar:file:/C:/gluegen/build-x86_64/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, + + new String[] {"jar:file:/C:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, + + new String[] {"jar:file:///C:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, + + new String[] {"jar:file://filehost/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, + + new String[] {"jar:file:/C:/gluegen/R%23/gluegen-rt.jar!/"}, + + new String[] {"jar:file:/C:/gluegen/A%24/B%5E/C~/D%23/E%5B/F%5D/gluegen-rt.jar!/"}, + + new String[] {"jar:file:/C:/gluegen/%24/%5E/~/%23/%5B/%5D/gluegen-rt.jar!/"}, + + new String[] {"jar:file:/C:/gluegen/"+'\u0394'+"/gluegen-rt.jar!/"}, + }; + + public static final String[][] fileSArrayUnix = new String[][] { + new String[] {"/gluegen/build-x86_64/gluegen-rt.jar", + "file:/gluegen/build-x86_64/gluegen-rt.jar", + "/gluegen/build-x86_64/gluegen-rt.jar"}, + + new String[] {"/gluegen/"+'\u0394'+"/gluegen-rt.jar", + "file:/gluegen/"+'\u0394'+"/gluegen-rt.jar", + "/gluegen/"+'\u0394'+"/gluegen-rt.jar"}, + + new String[] {"/gluegen/build-x86_64 lala/gluegen-rt.jar", + "file:/gluegen/build-x86_64%20lala/gluegen-rt.jar", + "/gluegen/build-x86_64 lala/gluegen-rt.jar"}, + + new String[] {"/gluegen/build-x86_64 öä lala/gluegen-rt.jar", + "file:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar", + "/gluegen/build-x86_64 öä lala/gluegen-rt.jar"}, + + new String[] {"/gluegen/A$/B^/C~/D#/E[/F]/gluegen-rt.jar", + "file:/gluegen/A%24/B%5E/C~/D%23/E%5B/F%5D/gluegen-rt.jar", + "/gluegen/A$/B^/C~/D#/E[/F]/gluegen-rt.jar" }, + + new String[] {"/gluegen/$/^/~/#/[/]/gluegen-rt.jar", + "file:/gluegen/%24/%5E/~/%23/%5B/%5D/gluegen-rt.jar", + "/gluegen/$/^/~/#/[/]/gluegen-rt.jar" }, + }; + + public static final String[][] fileSArrayWindows = new String[][] { + new String[] {"C:/gluegen/build-x86_64/gluegen-rt.jar", + "file:/C%3A/gluegen/build-x86_64/gluegen-rt.jar", + "C:\\gluegen\\build-x86_64\\gluegen-rt.jar"}, + + new String[] {"C:/gluegen/"+'\u0394'+"/gluegen-rt.jar", + "file:/C%3A/gluegen/"+'\u0394'+"/gluegen-rt.jar", + "C:\\gluegen\\"+'\u0394'+"\\gluegen-rt.jar"}, + + new String[] {"C:/gluegen/build-x86_64 lala/gluegen-rt.jar", + "file:/C%3A/gluegen/build-x86_64%20lala/gluegen-rt.jar", + "C:\\gluegen\\build-x86_64 lala\\gluegen-rt.jar"}, + + new String[] {"C:/gluegen/build-x86_64 öä lala/gluegen-rt.jar", + "file:/C%3A/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar", + "C:\\gluegen\\build-x86_64 öä lala\\gluegen-rt.jar"}, + + new String[] {"C:\\gluegen\\build-x86_64 öä lala\\gluegen-rt.jar", + "file:/C%3A/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar", + "C:\\gluegen\\build-x86_64 öä lala\\gluegen-rt.jar"}, + + new String[] {"\\\\filehost\\gluegen\\build-x86_64 öä lala\\gluegen-rt.jar", + "file://filehost/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar", + "\\\\filehost\\gluegen\\build-x86_64 öä lala\\gluegen-rt.jar"}, + + new String[] {"C:/gluegen/A$/B^/C~/D#/E[/F]/gluegen-rt.jar", + "file:/C%3A/gluegen/A%24/B%5E/C~/D%23/E%5B/F%5D/gluegen-rt.jar", + "C:\\gluegen\\A$\\B^\\C~\\D#\\E[\\F]\\gluegen-rt.jar" }, + + new String[] {"C:/gluegen/$/^/~/#/[/]/gluegen-rt.jar", + "file:/C%3A/gluegen/%24/%5E/~/%23/%5B/%5D/gluegen-rt.jar", + "C:\\gluegen\\$\\^\\~\\#\\[\\]\\gluegen-rt.jar" }, + }; + + @Test + public void test01HttpUri2URL() throws IOException, URISyntaxException { + testUri2URL(getSimpleTestName("."), uriHttpSArray); + } + + @Test + public void test02FileUnixUri2URL() throws IOException, URISyntaxException { + testUri2URL(getSimpleTestName("."), uriFileSArrayUnix); + } + + @Test + public void test03FileWindowsUri2URL() throws IOException, URISyntaxException { + testUri2URL(getSimpleTestName("."), uriFileSArrayWindows); + } + + @Test + public void test11HttpURL2Uri() throws IOException, URISyntaxException { + testURL2Uri(getSimpleTestName("."), uriHttpSArray); + } + + @Test + public void test12FileUnixURL2Uri() throws IOException, URISyntaxException { + testURL2Uri(getSimpleTestName("."), uriFileSArrayUnix); + } + + @Test + public void test13FileWindowsURL2Uri() throws IOException, URISyntaxException { + testURL2Uri(getSimpleTestName("."), urlFileSArrayWindows); + } + + @Test + public void test24FileUnixURI2URL() throws IOException, URISyntaxException { + if( Platform.OSType.WINDOWS != PlatformPropsImpl.OS_TYPE ) { + testFile2Uri(getSimpleTestName("."), fileSArrayUnix); + } + } + + @Test + public void test25FileWindowsURI2URL() throws IOException, URISyntaxException { + if( Platform.OSType.WINDOWS == PlatformPropsImpl.OS_TYPE ) { + testFile2Uri(getSimpleTestName("."), fileSArrayWindows); + } + } + + static void testUri2URL(final String testname, final String[][] uriSArray) throws IOException, URISyntaxException { + boolean ok = true; + for(int i=0; iodd pathname. + *

    + * The currently used jar folder is copied into [1] + *

    + *    [1] build/test/build/TestNetIOURIReservedCharsBug908/test01TempJarCacheOddPath/A\$-B\^-C~-D#-E\]-F\[-öä
    + *    [2] build/test/build/TestNetIOURIReservedCharsBug908/test01TempJarCacheOddPath/A\$-B\^-C~-D#-E\]-F\[-öä/gluegen-rt.jar
    + * 
    + * A ClassLoader w/ the URL [2] is used to issue Platform.initSingleton(), + * i.e. issues a whole initialization sequence w/ native jar loading in the new ClassPath. + *

    + *

    + * The manual test below on the created odd folder [1] has also succeeded: + *

    + * java \
    + *     -Djogamp.debug.IOUtil -Djogamp.debug.JNILibLoader -Djogamp.debug.TempFileCache \
    + *     -Djogamp.debug.JarUtil -Djogamp.debug.TempJarCache \
    + *     -cp ../build-x86_64/test/build/TestNetIOURIReservedCharsBug908/test01TempJarCacheOddPath/A\$-B\^-C~-D#-E\]-F\[-öä/gluegen-rt.jar \
    + *     com.jogamp.common.GlueGenVersion
    + * 
    + *

    + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestUri99LaunchOnReservedCharPathBug908 extends SingletonJunitCase { + static class TestClassLoader extends URLClassLoader { + public TestClassLoader(final URL[] urls) { + super(urls); + } + public TestClassLoader(final URL[] urls, final ClassLoader parent) { + super(urls, parent); + } + } + + + @Test + public void test00TempJarCacheSimplePath() throws IOException, IllegalArgumentException, URISyntaxException { + testTempJarCacheOddJarPathImpl("simpletons/"); + } + + @Test + public void test01TempJarCacheOddPath() throws IOException, IllegalArgumentException, URISyntaxException { + // Bug 908, issues w/ windows file path char: $ ^ ~ # [ ] + testTempJarCacheOddJarPathImpl("A$-B^-C~-D#-E]-F[-öä/"); + // "A$-B%5E-C~-D#-E]-F[-%C3%B6%C3%A4/"); <- Firefox URI encoding! '#' -> [1] + // "A$-B%5E-C~-D%23-E]-F[-%C3%B6%C3%A4/"); <- '[' ']' -> [2] + // "A$-B%5E-C~-D%23-E%5D-F%5B-%C3%B6%C3%A4/"); + /** + * [1] '#' + java.lang.IllegalArgumentException: URI has a fragment component + at java.io.File.(Unknown Source) + at com.jogamp.common.net.TestNetIOURIReservedCharsBug908.testTempJarCacheOddJarPathImpl(TestNetIOURIReservedCharsBug908.java:101) + [2] '[' ']' + java.net.URISyntaxException: Illegal character in path at index 137: file:/usr/local/projects/JOGL/gluegen/build-x86_64/test/build/TestNetIOURIReservedCharsBug908/test01TempJarCacheOddPath/A$-B%5E-C~-D%23-E]-F[-%C3%B6%C3%A4/ + at java.net.URI$Parser.fail(Unknown Source) + at java.net.URI$Parser.checkChars(Unknown Source) + at java.net.URI$Parser.parseHierarchical(Unknown Source) + at java.net.URI$Parser.parse(Unknown Source) + at java.net.URI.(Unknown Source) + at com.jogamp.common.net.TestNetIOURIReservedCharsBug908.testTempJarCacheOddJarPathImpl(TestNetIOURIReservedCharsBug908.java:106) + + */ + + } + private void testTempJarCacheOddJarPathImpl(final String subPathUTF) throws IOException, IllegalArgumentException, URISyntaxException { + if(AndroidVersion.isAvailable) { System.err.println("n/a on Android"); return; } + + final Uri.Encoded subPathEncoded = new Uri.Encoded(subPathUTF, Uri.PATH_LEGAL); + final String reservedCharPathUnencoded = "test/build/"+getClass().getSimpleName()+"/"+getTestMethodName()+"/"+subPathUTF; + final Uri.Encoded reservedCharPathEncoded = Uri.Encoded.cast("test/build/"+getClass().getSimpleName()+"/"+getTestMethodName()+"/").concat(subPathEncoded); + + System.err.println("0 Unencoded: "+reservedCharPathUnencoded); + System.err.println("0 Encoded: "+reservedCharPathEncoded); + + // jar:file:/dir1/dir2/gluegen-rt.jar!/ + final Uri jarFileURI = JarUtil.getJarFileUri(Platform.class.getName(), getClass().getClassLoader()); + System.err.println("1 jarFileURI: "+jarFileURI.toString()); + // gluegen-rt.jar + final Uri.Encoded jarBasename = JarUtil.getJarBasename(jarFileURI); + System.err.println("2 jarBasename: "+jarBasename); + + // file:/dir1/build/gluegen-rt.jar + final Uri fileURI = jarFileURI.getContainedUri(); + System.err.println("3 fileURI: "+fileURI.toString()); + // file:/dir1/build/ + final Uri fileFolderURI = fileURI.getParent(); + System.err.println("4 fileFolderURI: "+fileFolderURI.toString()); + // file:/dir1/build/test/build/A$-B^-C~-D#-E]-F[/ + final Uri fileNewFolderURI = fileFolderURI.concat(reservedCharPathEncoded); + System.err.println("5 fileNewFolderURI: "+fileNewFolderURI.toString()); + + final File srcFolder = fileFolderURI.toFile(); + final File dstFolder = fileNewFolderURI.toFile(); + System.err.println("6 srcFolder: "+srcFolder.toString()); + System.err.println("7 dstFolder: "+dstFolder.toString()); + try { + final MiscUtils.CopyStats copyStats = MiscUtils.copy(srcFolder, dstFolder, 1, true); + copyStats.dump("Copy ", true); + Assert.assertEquals(1, copyStats.totalFolders); + Assert.assertTrue(copyStats.totalBytes > 0); + Assert.assertEquals(0, copyStats.currentDepth); + + final URI jarFileNewFolderURI = new URI(fileNewFolderURI.toString()+jarBasename); + System.err.println("8 jarFileNewFolderURI: "+jarFileNewFolderURI.toString()); + + final URL[] urls = new URL[] { jarFileNewFolderURI.toURL() }; + System.err.println("url: "+urls[0]); + + final ClassLoader cl = new TestClassLoader(urls, null); + ReflectionUtil.callStaticMethod(Platform.class.getName(), "initSingleton", null, null, cl); + } finally { + // cleanup ? Skip this for now .. + // dstFolder.delete(); + } + } + + public static void main(final String args[]) throws IOException { + final String tstname = TestUri99LaunchOnReservedCharPathBug908.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } + +} diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/net/TestUriQueryProps.java gluegen2-2.3.2/src/junit/com/jogamp/common/net/TestUriQueryProps.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/net/TestUriQueryProps.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/net/TestUriQueryProps.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,49 @@ +package com.jogamp.common.net; + +import static com.jogamp.common.net.URIDumpUtil.showUri; + +import java.io.IOException; +import java.net.URISyntaxException; + +import org.junit.Assert; +import org.junit.Test; + +import com.jogamp.junit.util.SingletonJunitCase; + +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestUriQueryProps extends SingletonJunitCase { + + @Test + public void test() throws IOException, URISyntaxException { + final String SCHEME = "camera"; + final String HOST = "somewhere"; + final String PATH = "0"; + final String[] args = new String[] { + SCHEME+"://"+HOST+"/"+PATH, + SCHEME+"://"+HOST+"/"+PATH+"?p1=1", + }; + for(int i=0; i -> "+uri1+" -> NULL"); + } else { + final Uri uri1T = data.appendQuery(uri0); + showUri(uri1T); + Assert.assertEquals(uri1, uri1T); + } + } + } + public static void main(final String args[]) throws IOException { + final String tstname = TestUriQueryProps.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } +} diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/net/TestURIQueryProps.java gluegen2-2.3.2/src/junit/com/jogamp/common/net/TestURIQueryProps.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/net/TestURIQueryProps.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/net/TestURIQueryProps.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -package com.jogamp.common.net; - -import static com.jogamp.common.net.URIDumpUtil.showURI; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; - -import org.junit.Assert; -import org.junit.Test; - -import com.jogamp.junit.util.JunitTracer; - -import org.junit.FixMethodOrder; -import org.junit.runners.MethodSorters; - -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestURIQueryProps extends JunitTracer { - - @Test - public void test() throws IOException, URISyntaxException { - final String SCHEME = "camera"; - final String HOST = "somewhere"; - final String PATH = "0"; - final String[] args = new String[] { - SCHEME+"://"+HOST+"/"+PATH, - SCHEME+"://"+HOST+"/"+PATH+"?p1=1", - }; - for(int i=0; i -> "+uri1+" -> NULL"); - } else { - final URI uri1T = data.appendQuery(uri0); - showURI(uri1T); - Assert.assertEquals(uri1, uri1T); - } - } - } - public static void main(final String args[]) throws IOException { - final String tstname = TestURIQueryProps.class.getName(); - org.junit.runner.JUnitCore.main(tstname); - } -} diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/net/TestUrisWithAssetHandler.java gluegen2-2.3.2/src/junit/com/jogamp/common/net/TestUrisWithAssetHandler.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/net/TestUrisWithAssetHandler.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/net/TestUrisWithAssetHandler.java 2015-10-09 04:18:28.000000000 +0000 @@ -11,10 +11,10 @@ import org.junit.Test; import org.junit.runners.MethodSorters; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestUrisWithAssetHandler extends JunitTracer { +public class TestUrisWithAssetHandler extends SingletonJunitCase { @BeforeClass public static void assetRegistration() throws Exception { diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/net/URIDumpUtil.java gluegen2-2.3.2/src/junit/com/jogamp/common/net/URIDumpUtil.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/net/URIDumpUtil.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/net/URIDumpUtil.java 2015-10-09 04:18:28.000000000 +0000 @@ -42,4 +42,57 @@ System.err.println("2.3.0 query: "+uri.getRawQuery()+" (raw), "+uri.getQuery()+" (dec)"); System.err.println("3.0.0 fragment: "+uri.getRawFragment()+" (raw), "+uri.getFragment()+" (dec)"); } + + public static void showUri(final Uri uri) throws URISyntaxException { + showUri("ZZZZZZ Uri "+uri+", isOpaque "+uri.opaque+", isAbs "+uri.absolute+", hasAuth "+uri.hasAuthority, uri); + } + + public static void showUri(final String message, final Uri uri) throws URISyntaxException { + System.err.println(message); + + System.err.println("0.0.0 string: "+uri.toString()); + System.err.println("0.0.0 ascii : "+uri.toASCIIString()); + System.err.println("0.0.0 native-file: "+uri.toFile()); + System.err.println("0.0.0 contained: "+uri.getContainedUri()); + + System.err.println("1.0.0 scheme: "+uri.scheme); + System.err.println("2.0.0 scheme-part: "+uri.schemeSpecificPart+" (raw), "+Uri.decode(uri.schemeSpecificPart)+" (dec)"); + System.err.println("2.1.0 auth: "+uri.authority+" (raw), "+Uri.decode(uri.authority)+" (dec)"); + System.err.println("2.1.1 user-info: "+uri.userInfo+" (raw), "+Uri.decode(uri.userInfo)+" (dec)"); + System.err.println("2.1.1 host: "+uri.host); + System.err.println("2.1.1 port: "+uri.port); + System.err.println("2.2.0 path: "+uri.path+" (raw), "+Uri.decode(uri.path)+" (dec)"); + System.err.println("2.3.0 query: "+uri.query+" (raw), "+Uri.decode(uri.query)+" (dec)"); + System.err.println("3.0.0 fragment: "+uri.fragment+" (raw), "+Uri.decode(uri.fragment)+" (dec)"); + } + + /** + * Just showing different encoding of Uri -> URI + * + * @param uri + * @throws URISyntaxException + */ + public static void showReencodedURIOfUri(final Uri uri) throws URISyntaxException { + final URI recomposedURI = uri.toURIReencoded(); + showURI("YYYYYY Recomposed URI "+recomposedURI+", isOpaque "+recomposedURI.isOpaque()+", isAbs "+recomposedURI.isAbsolute(), recomposedURI); + final String recomposedURIStr = recomposedURI.toString(); + final boolean equalsRecompURI = uri.input.equals(recomposedURIStr); + System.err.println("source Uri: "+uri.input); + System.err.println("recomp URI: "+recomposedURIStr+" - "+(equalsRecompURI?"EQUAL":"UNEQUAL")); + } + + /** + * Just showing different encoding of URI -> Uri + * + * @param uri + * @throws URISyntaxException + */ + public static void showReencodedUriOfURI(final URI uri) throws URISyntaxException { + final Uri recomposedUri = Uri.valueOf(uri); + showUri("ZZZZZZ Recomposed Uri "+recomposedUri+", isOpaque "+recomposedUri.opaque+", isAbs "+recomposedUri.absolute+", hasAuth "+recomposedUri.hasAuthority, recomposedUri); + final String recomposedUriStr = recomposedUri.toString(); + final boolean equalsRecompUri = uri.toString().equals(recomposedUriStr); + System.err.println("source URI: "+uri.toString()); + System.err.println("recomp Uri: "+recomposedUriStr+" - "+(equalsRecompUri?"EQUAL":"UNEQUAL")); + } } diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/nio/BuffersTest.java gluegen2-2.3.2/src/junit/com/jogamp/common/nio/BuffersTest.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/nio/BuffersTest.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/nio/BuffersTest.java 2015-10-09 04:18:28.000000000 +0000 @@ -31,10 +31,18 @@ */ package com.jogamp.common.nio; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; + import org.junit.Test; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import static org.junit.Assert.*; @@ -45,10 +53,69 @@ import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class BuffersTest extends JunitTracer { +public class BuffersTest extends SingletonJunitCase { + + @Test + public void test01PositionLimitCapacityAfterArrayAllocation() { + final byte[] byteData = { 1, 2, 3, 4, 5, 6, 7, 8 }; + final ByteBuffer byteBuffer = Buffers.newDirectByteBuffer(byteData); + assertEquals(0, byteBuffer.position()); + assertEquals(8, byteBuffer.limit()); + assertEquals(8, byteBuffer.capacity()); + assertEquals(8, byteBuffer.remaining()); + assertEquals(5, byteBuffer.get(4)); + + final double[] doubleData = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 }; + final DoubleBuffer doubleBuffer = Buffers.newDirectDoubleBuffer(doubleData); + assertEquals(0, doubleBuffer.position()); + assertEquals(8, doubleBuffer.limit()); + assertEquals(8, doubleBuffer.capacity()); + assertEquals(8, doubleBuffer.remaining()); + assertEquals(5.0, doubleBuffer.get(4), 0.1); + + final float[] floatData = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f }; + final FloatBuffer floatBuffer = Buffers.newDirectFloatBuffer(floatData); + assertEquals(0, floatBuffer.position()); + assertEquals(8, floatBuffer.limit()); + assertEquals(8, floatBuffer.capacity()); + assertEquals(8, floatBuffer.remaining()); + assertEquals(5.0f, floatBuffer.get(4), 0.1f); + + final int[] intData = { 1, 2, 3, 4, 5, 6, 7, 8 }; + final IntBuffer intBuffer = Buffers.newDirectIntBuffer(intData); + assertEquals(0, intBuffer.position()); + assertEquals(8, intBuffer.limit()); + assertEquals(8, intBuffer.capacity()); + assertEquals(8, intBuffer.remaining()); + assertEquals(5, intBuffer.get(4)); + + final long[] longData = { 1, 2, 3, 4, 5, 6, 7, 8 }; + final LongBuffer longBuffer = Buffers.newDirectLongBuffer(longData); + assertEquals(0, longBuffer.position()); + assertEquals(8, longBuffer.limit()); + assertEquals(8, longBuffer.capacity()); + assertEquals(8, longBuffer.remaining()); + assertEquals(5, longBuffer.get(4)); + + final short[] shortData = { 1, 2, 3, 4, 5, 6, 7, 8 }; + final ShortBuffer shortBuffer = Buffers.newDirectShortBuffer(shortData); + assertEquals(0, shortBuffer.position()); + assertEquals(8, shortBuffer.limit()); + assertEquals(8, shortBuffer.capacity()); + assertEquals(8, shortBuffer.remaining()); + assertEquals(5, shortBuffer.get(4)); + + final char[] charData = { 1, 2, 3, 4, 5, 6, 7, 8 }; + final CharBuffer charBuffer = Buffers.newDirectCharBuffer(charData); + assertEquals(0, charBuffer.position()); + assertEquals(8, charBuffer.limit()); + assertEquals(8, charBuffer.capacity()); + assertEquals(8, charBuffer.remaining()); + assertEquals(5, charBuffer.get(4)); + } @Test - public void slice() { + public void test10Slice() { final IntBuffer buffer = Buffers.newDirectIntBuffer(6); buffer.put(new int[]{1,2,3,4,5,6}).rewind(); @@ -87,8 +154,10 @@ assertEquals(42, buffer.get(2)); assertEquals(42, onetwothree.get(2)); - - } + public static void main(final String args[]) throws IOException { + final String tstname = BuffersTest.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } } diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/nio/CachedBufferFactoryTest.java gluegen2-2.3.2/src/junit/com/jogamp/common/nio/CachedBufferFactoryTest.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/nio/CachedBufferFactoryTest.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/nio/CachedBufferFactoryTest.java 2015-10-09 04:18:28.000000000 +0000 @@ -42,7 +42,7 @@ import org.junit.Before; import org.junit.Test; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import static java.lang.System.*; import static org.junit.Assert.*; @@ -55,7 +55,7 @@ import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class CachedBufferFactoryTest extends JunitTracer { +public class CachedBufferFactoryTest extends SingletonJunitCase { private final int BUFFERCOUNT = 120; diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/nio/TestBuffersFloatDoubleConversion.java gluegen2-2.3.2/src/junit/com/jogamp/common/nio/TestBuffersFloatDoubleConversion.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/nio/TestBuffersFloatDoubleConversion.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/nio/TestBuffersFloatDoubleConversion.java 2015-10-09 04:18:28.000000000 +0000 @@ -33,13 +33,13 @@ import org.junit.Test; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestBuffersFloatDoubleConversion extends JunitTracer { +public class TestBuffersFloatDoubleConversion extends SingletonJunitCase { public static boolean cmpFloatArray(final float[] d1, final int d1_offset, final float[] d2, final int d2_offset, final int len) { if( d1.length - d1_offset < len) { diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/nio/TestByteBufferCopyStream.java gluegen2-2.3.2/src/junit/com/jogamp/common/nio/TestByteBufferCopyStream.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/nio/TestByteBufferCopyStream.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/nio/TestByteBufferCopyStream.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,244 @@ +/** + * Copyright 2014 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.common.nio; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.channels.FileChannel; + +import org.junit.Assert; +import org.junit.Test; + +import com.jogamp.common.os.Platform; +import com.jogamp.junit.util.SingletonJunitCase; + +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; + +/** + * Testing {@link MappedByteBufferInputStream} and {@link MappedByteBufferOutputStream} + * direct stream to stream copy via mapped buffers. + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestByteBufferCopyStream extends SingletonJunitCase { + + static void testImpl(final String srcFileName, final long size, + final MappedByteBufferInputStream.CacheMode srcCacheMode, final int srcSliceShift, + final String dstFileName, + final MappedByteBufferInputStream.CacheMode dstCacheMode, final int dstSliceShift ) throws IOException { + final Runtime runtime = Runtime.getRuntime(); + final long[] usedMem0 = { 0 }; + final long[] freeMem0 = { 0 }; + final long[] usedMem1 = { 0 }; + final long[] freeMem1 = { 0 }; + final String prefix = "test "+String.format(TestByteBufferInputStream.PrintPrecision+" MiB", size/TestByteBufferInputStream.MIB); + TestByteBufferInputStream.dumpMem(prefix+" before", runtime, -1, -1, usedMem0, freeMem0 ); + + final File srcFile = new File(srcFileName); + srcFile.delete(); + srcFile.createNewFile(); + srcFile.deleteOnExit(); + + final RandomAccessFile input; + { + final RandomAccessFile _input = new RandomAccessFile(srcFile, "rw"); + _input.setLength(size); + _input.close(); + input = new RandomAccessFile(srcFile, "r"); + } + final MappedByteBufferInputStream mis = new MappedByteBufferInputStream(input.getChannel(), + FileChannel.MapMode.READ_ONLY, + srcCacheMode, + srcSliceShift); + Assert.assertEquals(size, input.length()); + Assert.assertEquals(size, mis.length()); + Assert.assertEquals(0, mis.position()); + Assert.assertEquals(size, mis.remaining()); + + final File dstFile = new File(dstFileName); + dstFile.delete(); + dstFile.createNewFile(); + dstFile.deleteOnExit(); + final RandomAccessFile output = new RandomAccessFile(dstFile, "rw"); + final MappedByteBufferInputStream.FileResizeOp szOp = new MappedByteBufferInputStream.FileResizeOp() { + @Override + public void setLength(final long newSize) throws IOException { + output.setLength(newSize); + } + }; + final MappedByteBufferOutputStream mos = new MappedByteBufferOutputStream(output.getChannel(), + FileChannel.MapMode.READ_WRITE, + dstCacheMode, + srcSliceShift, szOp); + Assert.assertEquals(0, output.length()); + Assert.assertEquals(0, mos.length()); + Assert.assertEquals(0, mos.position()); + Assert.assertEquals(0, mos.remaining()); + + OutOfMemoryError oome = null; + IOException ioe = null; + + try { + mos.write(mis, mis.remaining()); + + Assert.assertEquals(size, input.length()); + Assert.assertEquals(size, output.length()); + Assert.assertEquals(size, mis.length()); + Assert.assertEquals(size, mos.length()); + Assert.assertEquals(size, mis.position()); + Assert.assertEquals(size, mos.position()); + Assert.assertEquals(0, mis.remaining()); + Assert.assertEquals(0, mos.remaining()); + + } catch (final IOException e) { + if( e.getCause() instanceof OutOfMemoryError ) { + oome = (OutOfMemoryError) e.getCause(); // oops + } else { + ioe = e; + } + } catch (final OutOfMemoryError m) { + oome = m; // oops + } finally { + mos.close(); + mis.close(); + input.close(); + output.close(); + srcFile.delete(); + dstFile.delete(); + TestByteBufferInputStream.dumpMem(prefix+" after ", runtime, usedMem0[0], freeMem0[0], usedMem1, freeMem1 ); + System.gc(); + try { + Thread.sleep(500); + } catch (final InterruptedException e) { } + TestByteBufferInputStream.dumpMem(prefix+" gc'ed ", runtime, usedMem0[0], freeMem0[0], usedMem1, freeMem1 ); + } + if( null != ioe || null != oome ) { + if( null != oome ) { + System.err.printf("%s: OutOfMemoryError.2 %s%n", prefix, oome.getMessage()); + oome.printStackTrace(); + } else { + Assert.assertNull(ioe); + } + } + } + + /** {@value} */ + static final long halfMiB = 1L << 19; + /** {@value} */ + static final long quaterGiB = 1L << 28; + /** {@value} */ + static final long quaterPlusGiB = quaterGiB + halfMiB; + /** {@value} */ + static final long halfGiB = 1L << 29; + /** {@value} */ + static final long halfPlusGiB = halfGiB + halfMiB; + /** {@value} */ + static final long oneGiB = 1L << 30; + /** {@value} */ + static final long onePlusGiB = oneGiB + halfMiB; + /** {@value} */ + static final long twoGiB = ( 2L << 30 ); + /** {@value} */ + static final long twoPlusGiB = twoGiB + halfMiB; + + /** {@value} */ + static final long lala = ( 1L << 27 ); + + @Test + public void test00() throws IOException { + final long size; + if( !manualTest && Platform.OSType.MACOS == Platform.getOSType() ) { + size = quaterGiB; + } else { + size = twoPlusGiB; + } + final int srcSliceShift = MappedByteBufferInputStream.DEFAULT_SLICE_SHIFT; + final int dstSliceShift = MappedByteBufferInputStream.DEFAULT_SLICE_SHIFT; + testImpl(getSimpleTestName(".")+"_In.bin", size, MappedByteBufferInputStream.CacheMode.FLUSH_PRE_HARD, srcSliceShift, + getSimpleTestName(".")+"_Out.bin", MappedByteBufferInputStream.CacheMode.FLUSH_PRE_HARD, dstSliceShift ); + } + + @Test + public void test01() throws IOException { + final long size; + if( !manualTest && Platform.OSType.MACOS == Platform.getOSType() ) { + size = quaterGiB; + } else { + size = twoPlusGiB; + } + final int srcSliceShift = MappedByteBufferInputStream.DEFAULT_SLICE_SHIFT; + final int dstSliceShift = MappedByteBufferInputStream.DEFAULT_SLICE_SHIFT; + testImpl(getSimpleTestName(".")+"_In.bin", size, MappedByteBufferInputStream.CacheMode.FLUSH_PRE_SOFT, srcSliceShift, + getSimpleTestName(".")+"_Out.bin", MappedByteBufferInputStream.CacheMode.FLUSH_PRE_SOFT, dstSliceShift ); + } + + @Test + public void test02() throws IOException { + final long size; + if( !manualTest && Platform.OSType.MACOS == Platform.getOSType() ) { + size = quaterPlusGiB; + } else { + size = halfPlusGiB; + } + final int srcSliceShift = 27; // 125M bytes per slice + final int dstSliceShift = 27; // 125M bytes per slice + testImpl(getSimpleTestName(".")+"_In.bin", size, MappedByteBufferInputStream.CacheMode.FLUSH_PRE_SOFT, srcSliceShift, + getSimpleTestName(".")+"_Out.bin", MappedByteBufferInputStream.CacheMode.FLUSH_PRE_SOFT, dstSliceShift ); + } + + @Test + public void test11() throws IOException { + final int srcSliceShift = 26; // 64M bytes per slice + final int dstSliceShift = 25; // 32M bytes per slice + final long size = quaterPlusGiB; + testImpl(getSimpleTestName(".")+"_In.bin", size, MappedByteBufferInputStream.CacheMode.FLUSH_PRE_SOFT, srcSliceShift, + getSimpleTestName(".")+"_Out.bin", MappedByteBufferInputStream.CacheMode.FLUSH_PRE_SOFT, dstSliceShift ); + } + + @Test + public void test12() throws IOException { + final int srcSliceShift = 25; // 32M bytes per slice + final int dstSliceShift = 26; // 64M bytes per slice + final long size = quaterPlusGiB; + testImpl(getSimpleTestName(".")+"_In.bin", size, MappedByteBufferInputStream.CacheMode.FLUSH_PRE_SOFT, srcSliceShift, + getSimpleTestName(".")+"_Out.bin", MappedByteBufferInputStream.CacheMode.FLUSH_PRE_SOFT, dstSliceShift ); + } + + static boolean manualTest = false; + + public static void main(final String args[]) throws IOException { + for(int i=0; i + * Focusing on comparison with {@link BufferedInputStream} regarding + * performance, used memory heap and used virtual memory. + *

    + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestByteBufferInputStream extends SingletonJunitCase { + /** {@value} */ + static final int buffer__8KiB = 1 << 13; + + /** {@value} */ + static final int halfMiB = 1 << 19; + /** {@value} */ + static final int oneMiB = 1 << 20; + /** {@value} */ + static final int tenMiB = 1 << 24; + /** {@value} */ + static final int hunMiB = 1 << 27; + /** {@value} */ + static final int halfGiB = 1 << 29; + /** {@value} */ + static final int oneGiB = 1 << 30; + /** {@value} */ + static final long twoPlusGiB = ( 2L << 30 ) + halfMiB; + + static final String fileHalfMiB = "./testHalfMiB.bin" ; + static final String fileOneMiB = "./testOneMiB.bin" ; + static final String fileTenMiB = "./testTenMiB.bin" ; + static final String fileHunMiB = "./testHunMiB.bin" ; + static final String fileHalfGiB = "./testHalfGiB.bin" ; + static final String fileOneGiB = "./testOneGiB.bin" ; + static final String fileTwoPlusGiB = "./testTwoPlusGiB.bin" ; + static final String fileOut = "./testOut.bin" ; + + public static final String PrintPrecision = "%8.3f"; + public static final double MIB = 1024.0*1024.0; + + + @BeforeClass + public static void setup() throws IOException { + final Runtime runtime = Runtime.getRuntime(); + System.err.printf("Total Memory : "+PrintPrecision+" MiB%n", runtime.totalMemory() / MIB); + System.err.printf("Max Memory : "+PrintPrecision+" MiB%n", runtime.maxMemory() / MIB); + + setup(fileHalfMiB, halfMiB); + setup(fileOneMiB, oneMiB); + setup(fileTenMiB, tenMiB); + setup(fileHunMiB, hunMiB); + setup(fileHalfGiB, halfGiB); + setup(fileOneGiB, oneGiB); + setup(fileTwoPlusGiB, twoPlusGiB); + } + static void setup(final String fname, final long size) throws IOException { + final File file = new File(fname); + final RandomAccessFile out = new RandomAccessFile(file, "rws"); + out.setLength(size); + out.close(); + } + + @AfterClass + public static void cleanup() { + cleanup(fileHalfMiB); + cleanup(fileOneMiB); + cleanup(fileTenMiB); + cleanup(fileHunMiB); + cleanup(fileHalfGiB); + cleanup(fileOneGiB); + cleanup(fileTwoPlusGiB); + cleanup(fileOut); + } + static void cleanup(final String fname) { + final File file = new File(fname); + file.delete(); + } + + @Test + public void test01MixedIntSize() throws IOException { + // testCopyIntSize1Impl(fileHalfMiB, halfMiB); + + // testCopyIntSize1Impl(fileOneMiB, oneMiB); + + testCopyIntSize1Impl(fileTenMiB, tenMiB); + + testCopyIntSize1Impl(fileHunMiB, hunMiB); + + testCopyIntSize1Impl(fileHalfGiB, halfGiB); + + // testCopyIntSize1Impl(fileOneGiB, oneGiB); + } + + static enum SrcType { COPY, MMAP1, MMAP2_NONE, MMAP2_SOFT, MMAP2_HARD }; + + @Test + public void test11MMap1GiBFlushNone() throws IOException { + if( !manualTest && Platform.OSType.MACOS == Platform.getOSType() ) { + testCopyIntSize1Impl2(0, SrcType.MMAP2_NONE, 0, fileOneMiB, oneMiB); + } else { + testCopyIntSize1Impl2(0, SrcType.MMAP2_NONE, 0, fileOneGiB, oneGiB); + // testCopyIntSize1Impl2(0, SrcType.MMAP2_NONE, 0, fileTwoPlusGiB, twoPlusGiB); + } + } + + @Test + public void test12MMap1GiBFlushSoft() throws IOException { + if( !manualTest && Platform.OSType.MACOS == Platform.getOSType() ) { + testCopyIntSize1Impl2(0, SrcType.MMAP2_SOFT, 0, fileOneMiB, oneMiB); + } else { + testCopyIntSize1Impl2(0, SrcType.MMAP2_SOFT, 0, fileOneGiB, oneGiB); + // testCopyIntSize1Impl2(0, SrcType.MMAP2_SOFT, 0, fileTwoPlusGiB, twoPlusGiB); + } + } + + @Test + public void test13MMap2GiBFlushHard() throws IOException { + if( !manualTest && Platform.OSType.MACOS == Platform.getOSType() ) { + testCopyIntSize1Impl2(0, SrcType.MMAP2_HARD, 0, fileOneMiB, oneMiB); + } else { + // testCopyIntSize1Impl2(0, SrcType.MMAP2_HARD, 0, fileOneGiB, oneGiB); + testCopyIntSize1Impl2(0, SrcType.MMAP2_HARD, 0, fileTwoPlusGiB, twoPlusGiB); + } + } + + void testCopyIntSize1Impl(final String testFileName, final long expSize) throws IOException { + testCopyIntSize1Impl2(0, SrcType.COPY, buffer__8KiB, testFileName, expSize); + testCopyIntSize1Impl2(0, SrcType.COPY, hunMiB, testFileName, expSize); + testCopyIntSize1Impl2(0, SrcType.MMAP1, 0, testFileName, expSize); + testCopyIntSize1Impl2(0, SrcType.MMAP2_SOFT, 0, testFileName, expSize); + System.err.println(); + } + boolean testCopyIntSize1Impl2(final int iter, final SrcType srcType, final int reqBufferSize, final String testFileName, final long expSize) throws IOException { + final int expSizeI = (int) ( expSize <= Integer.MAX_VALUE ? expSize : Integer.MAX_VALUE ); + final int bufferSize = reqBufferSize < expSizeI ? reqBufferSize : expSizeI; + final File testFile = new File(testFileName); + final long hasSize1 = testFile.length(); + final long t0 = System.currentTimeMillis(); + Assert.assertEquals(expSize, hasSize1); + + final Runtime runtime = Runtime.getRuntime(); + final long[] usedMem0 = { 0 }; + final long[] freeMem0 = { 0 }; + final long[] usedMem1 = { 0 }; + final long[] freeMem1 = { 0 }; + + final String prefix = "test #"+iter+" "+String.format(PrintPrecision+" MiB", expSize/MIB); + System.err.printf("%s: mode %-5s, bufferSize %9d: BEGIN%n", prefix, srcType.toString(), bufferSize); + dumpMem(prefix+" before", runtime, -1, -1, usedMem0, freeMem0 ); + + final IOException[] ioe = { null }; + OutOfMemoryError oome = null; + InputStream bis = null; + FileInputStream fis = null; + FileChannel fic = null; + boolean isMappedByteBufferInputStream = false; + try { + fis = new FileInputStream(testFile); + if( SrcType.COPY == srcType ) { + if( hasSize1 > Integer.MAX_VALUE ) { + fis.close(); + throw new IllegalArgumentException("file size > MAX_INT for "+srcType+": "+hasSize1+" of "+testFile); + } + bis = new BufferedInputStream(fis, bufferSize); + } else if( SrcType.MMAP1 == srcType ) { + if( hasSize1 > Integer.MAX_VALUE ) { + fis.close(); + throw new IllegalArgumentException("file size > MAX_INT for "+srcType+": "+hasSize1+" of "+testFile); + } + fic = fis.getChannel(); + final MappedByteBuffer fmap = fic.map(FileChannel.MapMode.READ_ONLY, 0, hasSize1); // survives channel/stream closing until GC'ed! + bis = new ByteBufferInputStream(fmap); + } else { + isMappedByteBufferInputStream = true; + MappedByteBufferInputStream.CacheMode cmode; + switch(srcType) { + case MMAP2_NONE: cmode = MappedByteBufferInputStream.CacheMode.FLUSH_NONE; + break; + case MMAP2_SOFT: cmode = MappedByteBufferInputStream.CacheMode.FLUSH_PRE_SOFT; + break; + case MMAP2_HARD: cmode = MappedByteBufferInputStream.CacheMode.FLUSH_PRE_HARD; + break; + default: fis.close(); + throw new InternalError("XX: "+srcType); + } + final MappedByteBufferInputStream mis = new MappedByteBufferInputStream(fis.getChannel(), FileChannel.MapMode.READ_ONLY, cmode); + Assert.assertEquals(expSize, mis.remaining()); + Assert.assertEquals(expSize, mis.length()); + Assert.assertEquals(0, mis.position()); + bis = mis; + } + } catch (final IOException e) { + if( e.getCause() instanceof OutOfMemoryError ) { + oome = (OutOfMemoryError) e.getCause(); // oops + } else { + ioe[0] = e; + } + } catch (final OutOfMemoryError m) { + oome = m; // oops + } + IOException ioe2 = null; + try { + if( null != ioe[0] || null != oome ) { + if( null != oome ) { + System.err.printf("%s: mode %-5s, bufferSize %9d: OutOfMemoryError.1 %s%n", + prefix, srcType.toString(), bufferSize, oome.getMessage()); + oome.printStackTrace(); + } else { + Assert.assertNull(ioe[0]); + } + return false; + } + Assert.assertEquals(expSizeI, bis.available()); + + final long t1 = System.currentTimeMillis(); + + final File out = new File(fileOut); + IOUtil.copyStream2File(bis, out, -1); + final long t2 = System.currentTimeMillis(); + + final String suffix; + if( isMappedByteBufferInputStream ) { + suffix = ", cacheMode "+((MappedByteBufferInputStream)bis).getCacheMode(); + } else { + suffix = ""; + } + System.err.printf("%s: mode %-5s, bufferSize %9d: total %5d, setup %5d, copy %5d ms%s%n", + prefix, srcType.toString(), bufferSize, t2-t0, t1-t0, t2-t1, suffix); + + Assert.assertEquals(expSize, out.length()); + out.delete(); + + Assert.assertEquals(0, bis.available()); + if( isMappedByteBufferInputStream ) { + final MappedByteBufferInputStream mis = (MappedByteBufferInputStream)bis; + Assert.assertEquals(0, mis.remaining()); + Assert.assertEquals(expSize, mis.length()); + Assert.assertEquals(expSize, mis.position()); + } + dumpMem(prefix+" after ", runtime, usedMem0[0], freeMem0[0], usedMem1, freeMem1 ); + System.gc(); + try { + Thread.sleep(500); + } catch (final InterruptedException e) { } + dumpMem(prefix+" gc'ed ", runtime, usedMem0[0], freeMem0[0], usedMem1, freeMem1 ); + } catch( final IOException e ) { + if( e.getCause() instanceof OutOfMemoryError ) { + oome = (OutOfMemoryError) e.getCause(); // oops + } else { + ioe2 = e; + } + } catch (final OutOfMemoryError m) { + oome = m; // oops + } finally { + if( null != fic ) { + fic.close(); + } + if( null != fis ) { + fis.close(); + } + if( null != bis ) { + bis.close(); + } + System.err.printf("%s: mode %-5s, bufferSize %9d: END%n", prefix, srcType.toString(), bufferSize); + System.err.println(); + } + if( null != ioe2 || null != oome ) { + if( null != oome ) { + System.err.printf("%s: mode %-5s, bufferSize %9d: OutOfMemoryError.2 %s%n", + prefix, srcType.toString(), bufferSize, oome.getMessage()); + oome.printStackTrace(); + } else { + Assert.assertNull(ioe2); + } + return false; + } else { + return true; + } + } + + public static void dumpMem(final String pre, + final Runtime runtime, final long usedMem0, + final long freeMem0, final long[] usedMemN, + final long[] freeMemN ) + { + usedMemN[0] = runtime.totalMemory() - runtime.freeMemory(); + freeMemN[0] = runtime.freeMemory(); + + System.err.printf("%s Used Memory : "+PrintPrecision, pre, usedMemN[0] / MIB); + if( 0 < usedMem0 ) { + System.err.printf(", delta "+PrintPrecision, (usedMemN[0]-usedMem0) / MIB); + } + System.err.println(" MiB"); + /** + System.err.printf("%s Free Memory : "+printPrecision, pre, freeMemN[0] / mib); + if( 0 < freeMem0 ) { + System.err.printf(", delta "+printPrecision, (freeMemN[0]-freeMem0) / mib); + } + System.err.println(" MiB"); */ + } + + static boolean manualTest = false; + + public static void main(final String args[]) throws IOException { + for(int i=0; i= 0, reset .. redo + Assert.assertEquals(payLoadOffset+payLoad.length+postPayLoadFiller+endBytes.length, out.length()); + Assert.assertEquals(payLoadOffset+payLoad.length+postPayLoadFiller+endBytes.length, mos.length()); + mos.setLength(payLoadOffset+payLoad.length+1); + Assert.assertEquals(payLoadOffset+payLoad.length+1, out.length()); + Assert.assertEquals(payLoadOffset+payLoad.length+1, mos.length()); + Assert.assertEquals(payLoadOffset+payLoad.length, mos.position()); + mis.mark(1); + Assert.assertTrue(mis.read()>=0); + Assert.assertEquals(payLoadOffset+payLoad.length+1, mos.position()); + mis.reset(); + Assert.assertEquals(payLoadOffset+payLoad.length, mos.position()); + Assert.assertTrue(mis.read()>=0); + Assert.assertEquals(payLoadOffset+payLoad.length+1, mos.position()); + + // Shrink -1, read EOS + mos.setLength(payLoadOffset+payLoad.length); + Assert.assertEquals(payLoadOffset+payLoad.length, out.length()); + Assert.assertEquals(payLoadOffset+payLoad.length, mos.length()); + Assert.assertEquals(payLoadOffset+payLoad.length, mos.position()); + Assert.assertEquals(-1, mis.read()); + + // Expand + 1, mark, read >= 0, reset .. redo + mos.setLength(payLoadOffset+payLoad.length+1); + Assert.assertEquals(payLoadOffset+payLoad.length+1, out.length()); + Assert.assertEquals(payLoadOffset+payLoad.length+1, mos.length()); + Assert.assertEquals(payLoadOffset+payLoad.length, mos.position()); + mis.mark(1); + Assert.assertTrue(mis.read()>=0); + Assert.assertEquals(payLoadOffset+payLoad.length+1, mos.position()); + mis.reset(); + Assert.assertEquals(payLoadOffset+payLoad.length, mos.position()); + Assert.assertTrue(mis.read()>=0); + Assert.assertEquals(payLoadOffset+payLoad.length+1, mos.position()); + + // Shrink -1, read EOS, write-expand, reset and verify + mos.setLength(payLoadOffset+payLoad.length); + Assert.assertEquals(payLoadOffset+payLoad.length, out.length()); + Assert.assertEquals(payLoadOffset+payLoad.length, mos.length()); + Assert.assertEquals(payLoadOffset+payLoad.length, mos.position()); + Assert.assertEquals(-1, mis.read()); + mos.write('Z'); // expand while writing .. + Assert.assertEquals(payLoadOffset+payLoad.length+1, out.length()); + Assert.assertEquals(payLoadOffset+payLoad.length+1, mos.length()); + Assert.assertEquals(payLoadOffset+payLoad.length+1, mos.position()); + mis.reset(); + Assert.assertEquals(payLoadOffset+payLoad.length, mos.position()); + Assert.assertEquals(payLoadOffset+payLoad.length, mis.position()); + Assert.assertEquals('Z', mis.read()); + Assert.assertEquals(payLoadOffset+payLoad.length+1, mos.position()); + Assert.assertEquals(payLoadOffset+payLoad.length+1, mis.position()); + + // Shrink -2, shall clear mark, test reset failure + mos.setLength(payLoadOffset+payLoad.length-1); + Assert.assertEquals(payLoadOffset+payLoad.length-1, out.length()); + Assert.assertEquals(payLoadOffset+payLoad.length-1, mos.length()); + Assert.assertEquals(payLoadOffset+payLoad.length-1, mos.position()); + try { + mis.reset(); + Assert.assertTrue(false); // shall not reach + } catch( final IOException ioe ) { + Assert.assertNotNull(ioe); + } + mis.mark(1); + + // ZERO file, test reset failure, read EOS, write-expand + mos.setLength(0); + Assert.assertEquals(0, out.length()); + Assert.assertEquals(0, mos.length()); + Assert.assertEquals(0, mos.position()); + try { + mis.reset(); + Assert.assertTrue(false); // shall not reach + } catch( final IOException ioe ) { + Assert.assertNotNull(ioe); + } + Assert.assertEquals(-1, mis.read()); + mos.write('Z'); // expand while writing .. + Assert.assertEquals(1, out.length()); + Assert.assertEquals(1, mos.length()); + Assert.assertEquals(1, mos.position()); + mis.position(0); + Assert.assertEquals(0, mos.position()); + Assert.assertEquals(0, mis.position()); + Assert.assertEquals('Z', mis.read()); + } finally { + mos.close(); + mis.close(); + out.close(); + } + } finally { + file.delete(); + } + } + + @Test + public void test00() throws IOException { + final int sliceShift = 13; // 8192 bytes per slice + testImpl(getSimpleTestName(".")+".bin", "123456789AB".getBytes(), 0L, 0L, "EOF".getBytes(), sliceShift); + } + + @Test + public void test01() throws IOException { + final int sliceShift = 13; // 8192 bytes per slice + testImpl(getSimpleTestName(".")+".bin", "123456789AB".getBytes(), 9000L, 100L, "EOF".getBytes(), sliceShift); + } + + @Test + public void test02() throws IOException { + final int sliceShift = 13; // 8192 bytes per slice + testImpl(getSimpleTestName(".")+".bin", "123456789AB".getBytes(), 8189L, 9001L, "EOF".getBytes(), sliceShift); + } + + @Test + public void test03() throws IOException { + final int sliceShift = 13; // 8192 bytes per slice + testImpl(getSimpleTestName(".")+".bin", "123456789AB".getBytes(), 58189L, 109001L, "EOF".getBytes(), sliceShift); + } + + @Test + public void test10() throws IOException { + final int sliceShift = 10; // 1024 bytes per slice + final byte[] payLoad = new byte[4096]; + for(int i=0; i CPU: <"+PlatformPropsImpl.ARCH+"> Bits: <"+bitsPtr+"/"+bitsProp+">"); diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/nio/TestStructAccessorEndian.java gluegen2-2.3.2/src/junit/com/jogamp/common/nio/TestStructAccessorEndian.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/nio/TestStructAccessorEndian.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/nio/TestStructAccessorEndian.java 2015-10-09 04:18:28.000000000 +0000 @@ -10,19 +10,19 @@ import org.junit.Assert; import org.junit.Test; -import com.jogamp.common.os.MachineDescription; +import com.jogamp.common.os.MachineDataInfo; import com.jogamp.common.os.Platform; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestStructAccessorEndian extends JunitTracer { +public class TestStructAccessorEndian extends SingletonJunitCase { @Test public void testStructAccessorEndian1 () { - final MachineDescription machine = Platform.getMachineDescription(); + final MachineDataInfo machine = Platform.getMachineDataInfo(); final int bitsPtr = machine.pointerSizeInBytes() * 8; final String bitsProp = System.getProperty("sun.arch.data.model"); out.println("OS: <"+PlatformPropsImpl.OS+"> CPU: <"+PlatformPropsImpl.ARCH+"> Bits: <"+bitsPtr+"/"+bitsProp+">"); diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/os/TestElfReader01.java gluegen2-2.3.2/src/junit/com/jogamp/common/os/TestElfReader01.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/os/TestElfReader01.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/os/TestElfReader01.java 2015-10-09 04:18:28.000000000 +0000 @@ -8,7 +8,9 @@ import java.io.RandomAccessFile; import java.util.List; -import jogamp.common.os.elf.ElfHeader; +import jogamp.common.os.PlatformPropsImpl; +import jogamp.common.os.elf.ElfHeaderPart1; +import jogamp.common.os.elf.ElfHeaderPart2; import jogamp.common.os.elf.Section; import jogamp.common.os.elf.SectionArmAttributes; import jogamp.common.os.elf.SectionHeader; @@ -16,16 +18,17 @@ import org.junit.Test; import com.jogamp.common.os.Platform.OSType; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestElfReader01 extends JunitTracer { +public class TestElfReader01 extends SingletonJunitCase { public static String GNU_LINUX_SELF_EXE = "/proc/self/exe"; public static String ARM_HF_EXE = "tst-exe-armhf"; public static String ARM_SF_EXE = "tst-exe-arm"; + static File userFile = null; private static boolean checkFileReadAccess(final File file) { try { @@ -49,49 +52,64 @@ } @Test - public void testGNULinuxSelfExe () throws IOException { - if( OSType.LINUX == Platform.getOSType() ) { - final File f = new File(GNU_LINUX_SELF_EXE); - if( checkFileReadAccess(f) ) { - testElfHeaderImpl(f, false); + public void test01GNULinuxSelfExe () throws IOException { + if( null == userFile ) { + if( OSType.LINUX == Platform.getOSType() ) { + final File f = new File(GNU_LINUX_SELF_EXE); + if( checkFileReadAccess(f) ) { + testElfHeaderImpl(f, false); + } } } } @Test - public void testJavaLib () throws IOException { - File jvmLib = findJVMLib("java"); - if( null == jvmLib ) { - jvmLib = findJVMLib("jvm"); + public void test02JavaLib () throws IOException { + if( null == userFile ) { + File jvmLib = findJVMLib("java"); + if( null == jvmLib ) { + jvmLib = findJVMLib("jvm"); + } + if( null != jvmLib ) { + testElfHeaderImpl(jvmLib, false); + } } - if( null != jvmLib ) { - testElfHeaderImpl(jvmLib, false); + } + + @Test + public void test99UserFile() throws IOException { + if( null != userFile ) { + testElfHeaderImpl(userFile, false); } } void testElfHeaderImpl(final File file, final boolean fileOutSections) throws IOException { + Platform.initSingleton(); System.err.println("Test file "+file.getAbsolutePath()); final RandomAccessFile in = new RandomAccessFile(file, "r"); try { - final ElfHeader eh; + final ElfHeaderPart1 eh1; + final ElfHeaderPart2 eh2; try { - eh = ElfHeader.read(in); + eh1 = ElfHeaderPart1.read(PlatformPropsImpl.OS_TYPE, in); + eh2 = ElfHeaderPart2.read(eh1, in); } catch (final Exception e) { System.err.println("Probably not an ELF file - or not in current format: (caught) "+e.getMessage()); e.printStackTrace(); return; } int i=0; - System.err.println(eh); - System.err.println("SH entsz "+eh.d.getE_shentsize()); - System.err.println("SH off "+toHexString(eh.d.getE_shoff())); - System.err.println("SH strndx "+eh.d.getE_shstrndx()); - System.err.println("SH num "+eh.sht.length); - if( 0 < eh.sht.length ) { - System.err.println("SH size "+eh.sht[0].d.getBuffer().limit()); + System.err.println(eh1); + System.err.println(eh2); + System.err.println("SH entsz "+eh2.raw.getE_shentsize()); + System.err.println("SH off "+toHexString(eh2.raw.getE_shoff())); + System.err.println("SH strndx "+eh2.raw.getE_shstrndx()); + System.err.println("SH num "+eh2.sht.length); + if( 0 < eh2.sht.length ) { + System.err.println("SH size "+eh2.sht[0].raw.getBuffer().limit()); } { - final SectionHeader sh = eh.getSectionHeader(SectionHeader.SHT_ARM_ATTRIBUTES); + final SectionHeader sh = eh2.getSectionHeader(SectionHeader.SHT_ARM_ATTRIBUTES); boolean abiVFPArgsAcceptsVFPVariant = false; if( null != sh ) { final SectionArmAttributes sArmAttrs = (SectionArmAttributes) sh.readSection(in); @@ -102,8 +120,8 @@ } System.err.println("abiVFPArgsAcceptsVFPVariant "+abiVFPArgsAcceptsVFPVariant); } - for(i=0; i LSB over whole data + // + public static final byte[] testBytesMSB = new byte[] { (byte)0xde, (byte)0xaf, (byte)0xca, (byte)0xfe }; + public static final int testIntMSB = 0xdeafcafe; // 11011110 10101111 11001010 11111110 + public static final String[] testStringsMSB = new String[] { "11011110", "10101111", "11001010", "11111110" }; + public static final String testStringMSB = testStringsMSB[0]+testStringsMSB[1]+testStringsMSB[2]+testStringsMSB[3]; + + // + // MSB -> LSB, reverse bit-order over each byte of testBytesLSB + // + public static final byte[] testBytesMSB_rev = new byte[] { (byte)0xfe, (byte)0xca, (byte)0xaf, (byte)0xde }; + public static final int testIntMSB_rev = 0xfecaafde; + public static final String[] testStringsMSB_rev = new String[] { "11111110", "11001010", "10101111", "11011110" }; + public static final String testStringMSB_rev = testStringsMSB_rev[0]+testStringsMSB_rev[1]+testStringsMSB_rev[2]+testStringsMSB_rev[3]; + + // + // LSB -> MSB over whole data + // + public static final byte[] testBytesLSB = new byte[] { (byte)0x7f, (byte)0x53, (byte)0xf5, (byte)0x7b }; + public static final int testIntLSB = 0x7f53f57b; + public static final String[] testStringsLSB = new String[] { "01111111", "01010011", "11110101", "01111011" }; + public static final String testStringLSB = testStringsLSB[0]+testStringsLSB[1]+testStringsLSB[2]+testStringsLSB[3]; + + // + // LSB -> MSB, reverse bit-order over each byte of testBytesMSB + // + public static final byte[] testBytesLSB_revByte = new byte[] { (byte)0x7b, (byte)0xf5, (byte)0x53, (byte)0x7f }; + public static final int testIntLSB_revByte = 0x7bf5537f; + public static final String[] testStringsLSB_revByte = new String[] { "01111011", "11110101", "01010011", "01111111" }; + public static final String testStringLSB_revByte = testStringsLSB_revByte[0]+testStringsLSB_revByte[1]+testStringsLSB_revByte[2]+testStringsLSB_revByte[3]; + + public static final void dumpData(final String prefix, final byte[] data, final int offset, final int len) { + for(int i=0; i UNSIGNED_INT_MAX_VALUE ) { + throw new NumberFormatException("Exceeds "+toHexString(UNSIGNED_INT_MAX_VALUE)+": "+toHexString(res)+" - source "+bitPattern); + } + return (int)res; + } + + public static String toHexString(final int v) { + return "0x"+Integer.toHexString(v); + } + public static String toHexString(final long v) { + return "0x"+Long.toHexString(v); + } + public static final String strZeroPadding= "0000000000000000000000000000000000000000000000000000000000000000"; // 64 + public static String toBinaryString(final int v, final int bitCount) { + if( 0 == bitCount ) { + return ""; + } + final int mask = (int) ( ( 1L << bitCount ) - 1L ); + final String s0 = Integer.toBinaryString( mask & v ); + return strZeroPadding.substring(0, bitCount-s0.length())+s0; + } + public static String toBinaryString(final long v, final int bitCount) { + if( 0 == bitCount ) { + return ""; + } + final long mask = ( 1L << bitCount ) - 1L; + final String s0 = Long.toBinaryString( mask & v ); + return strZeroPadding.substring(0, bitCount-s0.length())+s0; + } + public static String toHexBinaryString(final long v, final int bitCount) { + final int nibbles = 0 == bitCount ? 2 : ( bitCount + 3 ) / 4; + return String.format("[%0"+nibbles+"X, %s]", v, toBinaryString(v, bitCount)); + } + public static String toHexBinaryString(final int v, final int bitCount) { + final int nibbles = 0 == bitCount ? 2 : ( bitCount + 3 ) / 4; + return String.format("[%0"+nibbles+"X, %s]", v, toBinaryString(v, bitCount)); + } + public static String toHexBinaryString(final short v, final int bitCount) { + final int nibbles = 0 == bitCount ? 2 : ( bitCount + 3 ) / 4; + return String.format("[%0"+nibbles+"X, %s]", v, toBinaryString(v, bitCount)); + } +} diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/BitstreamData.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/BitstreamData.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/BitstreamData.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/BitstreamData.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,118 +0,0 @@ -/** - * Copyright 2014 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ - -package com.jogamp.common.util; - -import java.nio.ByteBuffer; - -public class BitstreamData { - // - // MSB -> LSB over whole data - // - public static final byte[] testBytesMSB = new byte[] { (byte)0xde, (byte)0xaf, (byte)0xca, (byte)0xfe }; - public static final String[] testStringsMSB = new String[] { "11011110", "10101111", "11001010", "11111110" }; - public static final String testStringMSB = testStringsMSB[0]+testStringsMSB[1]+testStringsMSB[2]+testStringsMSB[3]; - - // - // MSB -> LSB, reverse bit-order over each byte of testBytesLSB - // - public static final byte[] testBytesMSB_rev = new byte[] { (byte)0xfe, (byte)0xca, (byte)0xaf, (byte)0xde }; - public static final String[] testStringsMSB_rev = new String[] { "11111110", "11001010", "10101111", "11011110" }; - public static final String testStringMSB_rev = testStringsMSB_rev[0]+testStringsMSB_rev[1]+testStringsMSB_rev[2]+testStringsMSB_rev[3]; - - // - // LSB -> MSB over whole data - // - public static final byte[] testBytesLSB = new byte[] { (byte)0x7f, (byte)0x53, (byte)0xf5, (byte)0x7b }; - public static final String[] testStringsLSB = new String[] { "01111111", "01010011", "11110101", "01111011" }; - public static final String testStringLSB = testStringsLSB[0]+testStringsLSB[1]+testStringsLSB[2]+testStringsLSB[3]; - - // - // LSB -> MSB, reverse bit-order over each byte of testBytesMSB - // - public static final byte[] testBytesLSB_revByte = new byte[] { (byte)0x7b, (byte)0xf5, (byte)0x53, (byte)0x7f }; - public static final String[] testStringsLSB_revByte = new String[] { "01111011", "11110101", "01010011", "01111111" }; - public static final String testStringLSB_revByte = testStringsLSB_revByte[0]+testStringsLSB_revByte[1]+testStringsLSB_revByte[2]+testStringsLSB_revByte[3]; - - public static final void dumpData(final String prefix, final byte[] data, final int offset, final int len) { - for(int i=0; i= _inSize || _inSize > Integer.MAX_VALUE ) { + throw new IllegalArgumentException(""); + } + inSize = (int) _inSize; + } + final byte[] input = new byte[inSize]; + InputStream in = null; + OutputStream out = null; + try { + in = new FileInputStream(fileIn); + int numBytes = 0; + try { + while (true) { + final int remBytes = inSize - numBytes; + int count; + if ( 0 >= remBytes || (count = in.read(input, numBytes, remBytes)) == -1 ) { + break; + } + numBytes += count; + } + } finally { + in.close(); + } + if( inSize != numBytes ) { + throw new IOException("Got "+numBytes+" bytes != expected "+inSize); + } + out = new FileOutputStream(fileOut); + CustomCompress.deflateToStream(input, 0, inSize, 9, out); + } catch (final IOException ioe) { + ioe.printStackTrace(); + } finally { + if( null != in ) { + try { in.close(); } catch (final IOException e) { } + } + if( null != out ) { + try { out.close(); } catch (final IOException e) { } + } + } + + // + // Test + // + in = null; + out = null; + try { + in = new FileInputStream(fileOut); + final byte[] compare = CustomCompress.inflateFromStream(in); + if( compare.length != inSize ) { + throw new InternalError("Inflated Size Mismatch: Has "+compare.length+", expected "+inSize); + } + for(int i=0; i l, final int start, final int len, + final int i2, final int i3, final int expectedPlusSize) { + final int oldSize = l.size(); + for(int pos = start+len-1; pos>=start; pos--) { + l.put(pos, new Dummy(pos, i2, i3)); + } + Assert.assertEquals(expectedPlusSize, l.size() - oldSize); + } + boolean checkOrder(final List l, final int startIdx, final int start, final int len) { + for(int i=0; i l = + new ArrayHashMap(supportNullValue, + ArrayHashSet.DEFAULT_INITIAL_CAPACITY, + ArrayHashSet.DEFAULT_LOAD_FACTOR); + Assert.assertEquals(supportNullValue, l.supportsNullValue()); + final int p7_22_34_key, p7_22_34_idx; + final Dummy p7_22_34_orig; + final int p6_22_34_key, p6_22_34_idx; + final Dummy p6_22_34_orig; + { + populate(l, 10, 100, 22, 34, 100); // [109 .. 10] + Assert.assertTrue(checkOrder(l.getData(), 0, 10, 100)); + populate(l, 10, 100, 22, 34, 0); // [109 .. 10] + Assert.assertTrue(checkOrder(l.getData(), 0, 10, 100)); + populate(l, 6, 5, 22, 34, 4); // [ 9 .. 6], 10 already exists + Assert.assertTrue(checkOrder(l.getData(), 100, 6, 4)); + p7_22_34_idx = l.size() - 2; + p7_22_34_key = 7; + p7_22_34_orig = l.get(p7_22_34_key); + p6_22_34_idx = l.size() - 1; + p6_22_34_key = 6; + p6_22_34_orig = l.get(p6_22_34_key); + } + Assert.assertNotNull(p7_22_34_orig); + Assert.assertEquals(7, p7_22_34_orig.i1); + Assert.assertEquals(l.getData().get(p7_22_34_idx), p7_22_34_orig); + Assert.assertNotNull(p6_22_34_orig); + Assert.assertEquals(6, p6_22_34_orig.i1); + Assert.assertEquals(l.getData().get(p6_22_34_idx), p6_22_34_orig); + + final Dummy p7_22_34_other = new Dummy(7, 22, 34); + Assert.assertEquals(p7_22_34_other, p7_22_34_orig); + Assert.assertTrue(p7_22_34_other.hashCode() == p7_22_34_orig.hashCode()); + Assert.assertTrue(p7_22_34_other != p7_22_34_orig); // diff reference + final Dummy p6_22_34_other = new Dummy(6, 22, 34); + Assert.assertEquals(p6_22_34_other, p6_22_34_orig); + Assert.assertTrue(p6_22_34_other.hashCode() == p6_22_34_orig.hashCode()); + Assert.assertTrue(p6_22_34_other != p6_22_34_orig); // diff reference + + // fast identity .. + Dummy q = l.get(p6_22_34_key); + Assert.assertNotNull(q); + Assert.assertEquals(p6_22_34_other, q); + Assert.assertTrue(p6_22_34_other.hashCode() == q.hashCode()); + Assert.assertTrue(p6_22_34_other != q); // diff reference + Assert.assertTrue(p6_22_34_orig == q); // same reference + + Assert.assertTrue(l.containsValue(q)); + Assert.assertTrue(l.containsValue(p6_22_34_other)); // add equivalent + + q = l.put(p6_22_34_key, p6_22_34_other); // override w/ diff hash-obj + Assert.assertNotNull(q); + Assert.assertEquals(p6_22_34_other, q); + Assert.assertTrue(p6_22_34_other.hashCode() == q.hashCode()); + Assert.assertTrue(p6_22_34_other != q); // diff reference new != old (q) + Assert.assertTrue(p6_22_34_orig == q); // same reference orig == old (q) + Assert.assertTrue(checkOrder(l.getData(), 0, 10, 100)); + Assert.assertTrue(checkOrder(l.getData(), 100, 6, 4)); + + final Dummy p1_2_3 = new Dummy(1, 2, 3); // a new one .. + q = l.put(1, p1_2_3); // added test + Assert.assertNull(q); + + final Dummy pNull = null; + NullPointerException npe = null; + try { + q = l.put(0, pNull); + Assert.assertNull(q); + } catch (final NullPointerException _npe) { npe = _npe; } + if( l.supportsNullValue() ) { + Assert.assertNull(npe); + } else { + Assert.assertNotNull(npe); + } + } + + public static void main(final String args[]) throws IOException { + final String tstname = TestArrayHashMap01.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } + +} diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestArrayHashSet01.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestArrayHashSet01.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestArrayHashSet01.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestArrayHashSet01.java 2015-10-09 04:18:28.000000000 +0000 @@ -34,13 +34,13 @@ import org.junit.Assert; import org.junit.Test; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestArrayHashSet01 extends JunitTracer { +public class TestArrayHashSet01 extends SingletonJunitCase { public static class Dummy { int i1, i2, i3; @@ -74,47 +74,99 @@ } } - public void populate(final List l, final int start, final int len, final int i2, final int i3, final int expectedPlusSize) { + void populate(final List l, final int start, final int len, + final int i2, final int i3, final int expectedPlusSize) { final int oldSize = l.size(); - int pos = start+len-1; - while(pos>=start) { - l.add(new Dummy(pos--, i2, i3)); + for(int pos = start+len-1; pos>=start; pos--) { + l.add(new Dummy(pos, i2, i3)); } Assert.assertEquals(expectedPlusSize, l.size() - oldSize); } + boolean checkOrder(final List l, final int startIdx, final int start, final int len) { + for(int i=0; i l = new ArrayHashSet(); - populate(l, 10, 100, 22, 34, 100); // [10 .. 109] - populate(l, 10, 100, 22, 34, 0); // [10 .. 109] - populate(l, 6, 5, 22, 34, 4); // [ 6 .. 9], 10 already exists - - final Dummy p6_22_34 = new Dummy(6, 22, 34); + public void test01ArrayHashSetWithNullValue() { + testArrayHashSetImpl(true); + } + @Test + public void test02ArrayHashSetWithoutNullValue() { + testArrayHashSetImpl(false); + } + void testArrayHashSetImpl(final boolean supportNullValue) { + final ArrayHashSet l = + new ArrayHashSet(supportNullValue, + ArrayHashSet.DEFAULT_INITIAL_CAPACITY, + ArrayHashSet.DEFAULT_LOAD_FACTOR); + Assert.assertEquals(supportNullValue, l.supportsNullValue()); + final int p7_22_34_idx; + final Dummy p7_22_34_orig; + final int p6_22_34_idx; + final Dummy p6_22_34_orig; + { + populate(l, 10, 100, 22, 34, 100); // [109 .. 10] + Assert.assertTrue(checkOrder(l, 0, 10, 100)); + populate(l, 10, 100, 22, 34, 0); // [109 .. 10] + Assert.assertTrue(checkOrder(l, 0, 10, 100)); + populate(l, 6, 5, 22, 34, 4); // [ 9 .. 6], 10 already exists + Assert.assertTrue(checkOrder(l, 100, 6, 4)); + p7_22_34_idx = l.size() - 2; + p7_22_34_orig = l.get(p7_22_34_idx); + p6_22_34_idx = l.size() - 1; + p6_22_34_orig = l.get(p6_22_34_idx); + } + Assert.assertNotNull(p7_22_34_orig); + Assert.assertEquals(7, p7_22_34_orig.i1); + Assert.assertEquals(l.getData().get(p7_22_34_idx), p7_22_34_orig); + Assert.assertNotNull(p6_22_34_orig); + Assert.assertEquals(6, p6_22_34_orig.i1); + Assert.assertEquals(l.getData().get(p6_22_34_idx), p6_22_34_orig); + + final Dummy p7_22_34_other = new Dummy(7, 22, 34); + Assert.assertEquals(p7_22_34_other, p7_22_34_orig); + Assert.assertTrue(p7_22_34_other.hashCode() == p7_22_34_orig.hashCode()); + Assert.assertTrue(p7_22_34_other != p7_22_34_orig); // diff reference + final Dummy p6_22_34_other = new Dummy(6, 22, 34); + Assert.assertEquals(p6_22_34_other, p6_22_34_orig); + Assert.assertTrue(p6_22_34_other.hashCode() == p6_22_34_orig.hashCode()); + Assert.assertTrue(p6_22_34_other != p6_22_34_orig); // diff reference // slow get on position .. - final int i = l.indexOf(p6_22_34); + final int i = l.indexOf(p6_22_34_other); Dummy q = l.get(i); Assert.assertNotNull(q); - Assert.assertEquals(p6_22_34, q); - Assert.assertTrue(p6_22_34.hashCode() == q.hashCode()); - Assert.assertTrue(p6_22_34 != q); // diff reference + Assert.assertEquals(p6_22_34_other, q); + Assert.assertTrue(p6_22_34_other.hashCode() == q.hashCode()); + Assert.assertTrue(p6_22_34_other != q); // diff reference + Assert.assertTrue(p6_22_34_orig == q); // same reference // fast identity .. - q = l.get(p6_22_34); + q = l.get(p6_22_34_other); Assert.assertNotNull(q); - Assert.assertEquals(p6_22_34, q); - Assert.assertTrue(p6_22_34.hashCode() == q.hashCode()); - Assert.assertTrue(p6_22_34 != q); // diff reference + Assert.assertEquals(p6_22_34_other, q); + Assert.assertTrue(p6_22_34_other.hashCode() == q.hashCode()); + Assert.assertTrue(p6_22_34_other != q); // diff reference + Assert.assertTrue(p6_22_34_orig == q); // same reference Assert.assertTrue(!l.add(q)); // add same - Assert.assertTrue(!l.add(p6_22_34)); // add equivalent + Assert.assertTrue(!l.add(p6_22_34_other)); // add equivalent - q = l.getOrAdd(p6_22_34); // not added test + q = l.getOrAdd(p6_22_34_other); // not added test w/ diff hash-obj Assert.assertNotNull(q); - Assert.assertEquals(p6_22_34, q); - Assert.assertTrue(p6_22_34.hashCode() == q.hashCode()); - Assert.assertTrue(p6_22_34 != q); // diff reference + Assert.assertEquals(p6_22_34_other, q); + Assert.assertTrue(p6_22_34_other.hashCode() == q.hashCode()); + Assert.assertTrue(p6_22_34_other != q); // diff reference + Assert.assertTrue(p6_22_34_orig == q); // same reference + Assert.assertTrue(checkOrder(l, 0, 10, 100)); + Assert.assertTrue(checkOrder(l, 100, 6, 4)); final Dummy p1_2_3 = new Dummy(1, 2, 3); // a new one .. q = l.getOrAdd(p1_2_3); // added test @@ -122,6 +174,29 @@ Assert.assertEquals(p1_2_3, q); Assert.assertTrue(p1_2_3.hashCode() == q.hashCode()); Assert.assertTrue(p1_2_3 == q); // _same_ reference, since getOrAdd added it + Assert.assertTrue(checkOrder(l, 0, 10, 100)); + Assert.assertTrue(checkOrder(l, 100, 6, 4)); + + final Dummy pNull = null; + NullPointerException npe = null; + try { + q = l.getOrAdd(pNull); + Assert.assertNull(q); + } catch (final NullPointerException _npe) { npe = _npe; } + if( l.supportsNullValue() ) { + Assert.assertNull(npe); + } else { + Assert.assertNotNull(npe); + } + + try { + Assert.assertTrue(l.remove(pNull)); + } catch (final NullPointerException _npe) { npe = _npe; } + if( l.supportsNullValue() ) { + Assert.assertNull(npe); + } else { + Assert.assertNotNull(npe); + } } public static void main(final String args[]) throws IOException { diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestBitfield00.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestBitfield00.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestBitfield00.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestBitfield00.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,431 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.common.util; + +import java.io.IOException; + +import org.junit.Test; +import org.junit.Assert; + +import com.jogamp.junit.util.SingletonJunitCase; + +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; + +/** + * Test basic bitfield operations for {@link Bitfield} + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestBitfield00 extends SingletonJunitCase { + + @Test + public void test01_BitCount32_One() { + final String[] pyramid32bit_one = BitDemoData.pyramid32bit_one; + for(int i=0; i=0x1FF; l++) { + test_BitCount32_Samples(l); + } + for(long l=MAX_half_minus; l<=MAX_half_plus; l++) { + test_BitCount32_Samples(l); + } + for(long l=MAX_minus; l<=MAX; l++) { + test_BitCount32_Samples(l); + } + } + static void test_BitCount32_Samples(final long l) { + final int oneBitCountL = Long.bitCount(l); + final int val0 = (int)l; + final int oneBitCountI = Integer.bitCount(val0); + final int oneBitCount1 = Bitfield.Util.bitCount(val0); + final String msg = String.format("Round 0x%08x, c %d / %d / %d", val0, + oneBitCountL, oneBitCountI, oneBitCount1); + Assert.assertEquals(msg, oneBitCountI, oneBitCountL); + Assert.assertEquals(msg, oneBitCountI, oneBitCount1); + } + + static int[] testDataOneBit = new int[] { + 0,0, 1,1, 2,1, 3,2, 4,1, 5,2, 6,2, 7,3, + 8,1, 9,2, 10,2, 11,3, 12,2, 13,3, 14,3, 15,4, 16,1, 17,2, + 0x3F,6, 0x40,1, 0x41,2, 0x7f,7, 0x80,1, 0x81,2, 0xfe,7, 0xff,8, + 0x4000,1, 0x4001,2, 0x7000,3, 0x7fff,15, + 0x0FFFFFF0,24, + 0x55555555,16, + 0x7F53F57B,23, 0xFEA7EAF6,23, /* << 1 */ + 0x80000000, 1, + 0xAAAAAAAA,16, + 0xC0C0C0C0, 8, + 0xFF000000, 8, + 0xFFFFFFFF,32 + }; + @Test + public void test03_BitCount32_Data() { + for(int i = 0; iL : 0x04030201: 00000100 00000011 00000010 00000001 + new TestDataBF(32, 0x04030201, "00000100000000110000001000000001"), + + // H->L : 0xAFFECAFE: 10101111 11111110 11001010 11111110 + new TestDataBF(32, 0xAFFECAFE, "10101111111111101100101011111110"), + // H->L : 0xDEADBEEF: 11011110 10101101 10111110 11101111 + new TestDataBF(32, 0xDEADBEEF, "11011110101011011011111011101111") + }; + static TestDataBF[] testDataBF16Bit = { + // H->L : 0x0201: 00000100 00000011 00000010 00000001 + new TestDataBF(16, 0x0201, "0000001000000001"), + // H->L : 0x0403: 00000100 00000011 + new TestDataBF(16, 0x0403, "0000010000000011"), + + // H->L : 0xAFFE: 10101111 11111110 + new TestDataBF(16, 0xAFFE, "1010111111111110"), + // H->L : 0xCAFE: 11001010 11111110 + new TestDataBF(16, 0xCAFE, "1100101011111110"), + + // H->L : 0xDEADBEEF: 11011110 10101101 10111110 11101111 + new TestDataBF(16, 0xDEAD, "1101111010101101"), + new TestDataBF(16, 0xBEEF, "1011111011101111") + }; + static TestDataBF[] testDataBF3Bit = { + new TestDataBF(3, 0x01, "001"), + new TestDataBF(3, 0x02, "010"), + new TestDataBF(3, 0x05, "101") + }; + + @Test + public void test20_ValidateTestData() { + for(int i=0; i>> 5); + return units << 5; + } + static void test_Aligned32bit(final TestDataBF d) { + final int oneBitCount = Bitfield.Util.bitCount(d.val); + + final Bitfield bf1 = Bitfield.Factory.create(d.bitSize); + Assert.assertEquals(get32BitStorageSize(d.bitSize), bf1.size()); + final Bitfield bf2 = Bitfield.Factory.create(d.bitSize+128); + Assert.assertEquals(get32BitStorageSize(d.bitSize+128), bf2.size()); + + bf1.put32( 0, d.bitSize, d.val); + Assert.assertEquals(d.val, bf1.get32( 0, d.bitSize)); + Assert.assertEquals(oneBitCount, bf1.bitCount()); + assertEquals(bf1, 0, d.val, d.pattern, oneBitCount); + + bf2.put32( 0, d.bitSize, d.val); + Assert.assertEquals(d.val, bf2.get32( 0, d.bitSize)); + Assert.assertEquals(oneBitCount*1, bf2.bitCount()); + assertEquals(bf2, 0, d.val, d.pattern, oneBitCount); + bf2.put32(64, d.bitSize, d.val); + Assert.assertEquals(d.val, bf2.get32(64, d.bitSize)); + Assert.assertEquals(oneBitCount*2, bf2.bitCount()); + assertEquals(bf2, 64, d.val, d.pattern, oneBitCount); + + Assert.assertEquals(d.val, bf2.copy32(0, 96, d.bitSize)); + Assert.assertEquals(d.val, bf2.get32(96, d.bitSize)); + Assert.assertEquals(oneBitCount*3, bf2.bitCount()); + assertEquals(bf2, 96, d.val, d.pattern, oneBitCount); + } + + @Test + public void test21_Unaligned() { + for(int i=0; i %d", + d.val, d.pattern, d.bitSize, bf.size(), oneBitCount, lowBitnum, maxBitpos); + + // + // via put32 + // + bf.put32( lowBitnum, d.bitSize, d.val); + for(int i=0; i=0; i--) { + Assert.assertEquals(msg+", bitpos "+i, 0 != ( d.val & ( 1 << i ) ), + bf.copy(lowBitnum+i, lowBitnum+1+i) ); + } + bf.clear(lowBitnum); + Assert.assertEquals(msg, d.val, bf.get32( lowBitnum+1, d.bitSize)); + for(int i=0; i, exp "+BitDemoData.toHexString(exp)); + Assert.assertEquals(msg+", bitpos "+i, exp, val); + } + for(int i=highBitnum+1; i, exp "+BitDemoData.toHexString(exp)); + Assert.assertEquals(msg+", bitpos "+i, exp, val); + } + } + + public static void main(final String args[]) throws IOException { + final String tstname = TestBitfield00.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } + +} diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestBitstream00.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestBitstream00.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestBitstream00.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestBitstream00.java 2015-10-09 04:18:28.000000000 +0000 @@ -40,9 +40,9 @@ import com.jogamp.common.nio.Buffers; import com.jogamp.common.os.Platform; -import static com.jogamp.common.util.BitstreamData.*; +import static com.jogamp.common.util.BitDemoData.*; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @@ -51,7 +51,7 @@ * Test basic bit operations for {@link Bitstream} */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestBitstream00 extends JunitTracer { +public class TestBitstream00 extends SingletonJunitCase { @Test public void test00ShowByteOrder() { @@ -129,6 +129,138 @@ } } + @Test + public void test10ReadWrite_13() throws UnsupportedOperationException, IllegalStateException, IOException { + // H->L : 00000011 00000010 00000001 000000110000001000000001 + // H->L rev: 10000000 01000000 11000000 100000000100000011000000 + // + // L->H : 00000001 00000010 00000011 000000010000001000000011 + // L->H rev: 11000000 01000000 10000000 110000000100000010000000 + test10ReadWrite1_31Impl(8, 8, 8, 0x030201, "000000110000001000000001"); + + // H->L: 00011 000010 00001 0001100001000001 + // L->H: 10000 010000 11000 1000001000011000 + test10ReadWrite1_31Impl(5, 6, 5, 0x1841, "0001100001000001"); + } + void test10ReadWrite1_31Impl(final int c1, final int c2, final int c3, final int v, final String vStrHigh2LowExp) + throws UnsupportedOperationException, IllegalStateException, IOException + { + // final Bitstream source = new Bitstream(); + final int bitCount = c1+c2+c3; + final int byteCount = ( bitCount + 7 ) / 8; + final String vStrHigh2Low0 = Bitstream.toBinString(true, v, bitCount); + System.err.printf("test10ReadWrite31 bits %d:%d:%d = %d = %d bytes%n", + c1, c2, c3, bitCount, byteCount); + System.err.printf("test10ReadWrite31 %s%n", Bitstream.toHexBinString(true, v, bitCount)); + System.err.printf("test10ReadWrite31 %s%n", Bitstream.toHexBinString(false, v, bitCount)); + Assert.assertEquals(vStrHigh2LowExp, vStrHigh2Low0); + + final ByteBuffer bbRead = ByteBuffer.allocate(byteCount); + for(int i=0; i>> 8*i ) & 0xff; + bbRead.put(i, (byte) b); + System.err.printf("testBytes[%d]: %s%n", i, Bitstream.toHexBinString(true, b, 8)); + } + final Bitstream.ByteBufferStream bbsRead = new Bitstream.ByteBufferStream(bbRead); + final Bitstream bsRead = new Bitstream(bbsRead, false /* outputMode */); + + String vStrHigh2Low1C1 = ""; + String vStrHigh2Low1C2 = ""; + String vStrHigh2Low1C3 = ""; + String vStrHigh2Low1 = ""; + { + bsRead.mark(byteCount); + System.err.println("readBit (msbFirst false): "); + int b; + int i=0; + String vStrHigh2Low1T = ""; // OK for LSB, MSB segmented + while( Bitstream.EOS != ( b = bsRead.readBit(false /* msbFirst */) ) ) { + vStrHigh2Low1T = b + vStrHigh2Low1T; + if(i < c1) { + vStrHigh2Low1C1 = b + vStrHigh2Low1C1; + } else if(i < c1+c2) { + vStrHigh2Low1C2 = b + vStrHigh2Low1C2; + } else { + vStrHigh2Low1C3 = b + vStrHigh2Low1C3; + } + i++; + } + vStrHigh2Low1 = vStrHigh2Low1C3 + vStrHigh2Low1C2 + vStrHigh2Low1C1; + System.err.printf("readBit.1 %s, 0x%s%n", vStrHigh2Low1C1, Integer.toHexString(Integer.valueOf(vStrHigh2Low1C1, 2))); + System.err.printf("readBit.2 %s, 0x%s%n", vStrHigh2Low1C2, Integer.toHexString(Integer.valueOf(vStrHigh2Low1C2, 2))); + System.err.printf("readBit.3 %s, 0x%s%n", vStrHigh2Low1C3, Integer.toHexString(Integer.valueOf(vStrHigh2Low1C3, 2))); + System.err.printf("readBit.T %s, ok %b%n%n", vStrHigh2Low1T, vStrHigh2LowExp.equals(vStrHigh2Low1T)); + System.err.printf("readBit.X %s, ok %b%n%n", vStrHigh2Low1, vStrHigh2LowExp.equals(vStrHigh2Low1)); + bsRead.reset(); + } + + { + String vStrHigh2Low3T = ""; // OK for LSB, MSB segmented + System.err.println("readBits32: "); + final int b = bsRead.readBits31(bitCount); + vStrHigh2Low3T = Bitstream.toBinString(true, b, bitCount); + System.err.printf("readBits31.T %s, ok %b, %s%n%n", vStrHigh2Low3T, vStrHigh2LowExp.equals(vStrHigh2Low3T), Bitstream.toHexBinString(true, b, bitCount)); + bsRead.reset(); + } + + String vStrHigh2Low2 = ""; + { + System.err.println("readBits32: "); + final int bC1 = bsRead.readBits31(c1); + System.err.printf("readBits31.1 %s%n", Bitstream.toHexBinString(true, bC1, c1)); + final int bC2 = bsRead.readBits31(c2); + System.err.printf("readBits31.2 %s%n", Bitstream.toHexBinString(true, bC2, c2)); + final int bC3 = bsRead.readBits31(c3); + System.err.printf("readBits31.3 %s%n", Bitstream.toHexBinString(true, bC3, c3)); + final int b = bC3 << (c1+c2) | bC2 << c1 | bC1; + vStrHigh2Low2 = Bitstream.toBinString(true, b, bitCount); + System.err.printf("readBits31.X %s, ok %b, %s%n%n", vStrHigh2Low2, vStrHigh2LowExp.equals(vStrHigh2Low2), Bitstream.toHexBinString(true, b, bitCount)); + bsRead.reset(); + } + + Assert.assertEquals(vStrHigh2LowExp, vStrHigh2Low1); + Assert.assertEquals(vStrHigh2LowExp, vStrHigh2Low2); + + boolean ok = true; + { + final ByteBuffer bbWrite = ByteBuffer.allocate(byteCount); + final Bitstream.ByteBufferStream bbsWrite = new Bitstream.ByteBufferStream(bbWrite); + final Bitstream bsWrite = new Bitstream(bbsWrite, true /* outputMode */); + { + int b; + while( Bitstream.EOS != ( b = bsRead.readBit(false)) ) { + bsWrite.writeBit(false, b); + } + } + bsRead.reset(); + for(int i=0; i bsWrite = new Bitstream(bbsWrite, true /* outputMode */); + { + bsWrite.writeBits31(bitCount, bsRead.readBits31(bitCount)); + } + bsRead.reset(); + for(int i=0; i{@link Bitstream#mark(int)} *
  • {@link Bitstream#reset()}
  • *
  • {@link Bitstream#flush()}
  • - *
  • {@link Bitstream#readBits31(boolean, int)}
  • - *
  • {@link Bitstream#writeBits31(boolean, int, int)}
  • + *
  • {@link Bitstream#readBits31(int)}
  • + *
  • {@link Bitstream#writeBits31(int, int)}
  • * */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestBitstream01 extends JunitTracer { +public class TestBitstream01 extends SingletonJunitCase { - Bitstream getTestStream(final boolean msbFirst, final int preBits, final int skipBits, final int postBits) throws IOException { - final int byteCount = ( preBits + skipBits + postBits + 7 ) / 8; + Bitstream getTestStream(final boolean msbFirstData, final boolean msbFirstWrite, + final int preBits, final int skipBits, final int postBits) throws IOException { + final int bitCount = preBits+skipBits+postBits; + final int byteCount = ( bitCount + 7 ) / 8; final ByteBuffer bbTest = ByteBuffer.allocate(byteCount); final Bitstream.ByteBufferStream bbsTest = new Bitstream.ByteBufferStream(bbTest); final Bitstream bsTest = new Bitstream(bbsTest, true /* outputMode */); final String sTest0; - if( msbFirst ) { + if( msbFirstData ) { sTest0 = testStringMSB.substring(0, preBits+skipBits+postBits); } else { sTest0 = testStringLSB.substring(0, preBits+skipBits+postBits); } - for(int i=0; i= 0; i--) { + final int bit = Integer.valueOf(sTest0.substring(i, i+1)); + bsTest.writeBit(msbFirstWrite, bit); + } } + System.err.printf("TestData: msbFirst[data %b, write %b], bits[pre %d, skip %d, post %d = %d]: <%s>%n", + msbFirstData, msbFirstWrite, preBits, skipBits, postBits, bitCount, sTest0); Assert.assertEquals(preBits+skipBits+postBits, bsTest.position()); bsTest.setStream(bsTest.getSubStream(), false /* outputMode */); // switch to input-mode, implies flush() + dumpData("TestData: ", bsTest.getSubStream(), 0, bsTest.getSubStream().limit()); return bsTest; } - String getTestStreamResultAsString(final boolean msbFirst, final int preBits, final int skipBits, final int postBits) { + String getTestStreamResultAsString(final boolean msbFirstData, final boolean msbFirstAssemble, + final int preBits, final int skipBits, final int postBits) { final String pre, post; - if( msbFirst ) { - pre = testStringMSB.substring(0, preBits); - post = testStringMSB.substring(preBits+skipBits, preBits+skipBits+postBits); + if( msbFirstData ) { + if( msbFirstAssemble ) { + pre = testStringMSB.substring(0, preBits); + post = testStringMSB.substring(preBits+skipBits, preBits+skipBits+postBits); + } else { + pre = testStringMSB.substring(postBits+skipBits, preBits+skipBits+postBits); + post = testStringMSB.substring(0, postBits); + } } else { - pre = testStringLSB.substring(0, preBits); - post = testStringLSB.substring(preBits+skipBits, preBits+skipBits+postBits); + if( msbFirstAssemble ) { + pre = testStringLSB.substring(0, preBits); + post = testStringLSB.substring(preBits+skipBits, preBits+skipBits+postBits); + } else { + pre = testStringMSB.substring(postBits+skipBits, preBits+skipBits+postBits); + post = testStringMSB.substring(0, postBits); + } } - final String r = pre + post; - System.err.println("Test: <"+pre+"> + <"+post+"> = <"+r+">"); + final String r = msbFirstAssemble ? pre + post : post + pre; + System.err.println("ResultExp: <"+pre+"> + <"+post+"> = <"+r+">"); return r; } @@ -155,9 +178,8 @@ // prepare bitstream System.err.println("Prepare bitstream"); - final Bitstream bsTest = getTestStream(msbFirst, preBits, skipBits, postBits); - dumpData("Test", bsTest.getSubStream(), 0, bsTest.getSubStream().limit()); - final String sTest = getTestStreamResultAsString(msbFirst, preBits, skipBits, postBits); + final Bitstream bsTest = getTestStream(msbFirst, msbFirst, preBits, skipBits, postBits); + final String sTest = getTestStreamResultAsString(msbFirst, true, preBits, skipBits, postBits); // init copy-bitstream final int byteCount = ( totalBits + 7 ) / 8; @@ -219,50 +241,48 @@ } @Test - public void test03BulkBitsMSBFirst() throws IOException { - testBulkBitsImpl(true); - } - @Test - public void test04BulkBitsLSBFirst() throws IOException { - testBulkBitsImpl(false); - } - void testBulkBitsImpl(final boolean msbFirst) throws IOException { - testBulkBitsImpl(msbFirst, 0, 0, 1); - testBulkBitsImpl(msbFirst, 0, 0, 3); - testBulkBitsImpl(msbFirst, 0, 0, 8); - testBulkBitsImpl(msbFirst, 0, 0, 10); - testBulkBitsImpl(msbFirst, 0, 0, 30); - testBulkBitsImpl(msbFirst, 0, 0, 31); - - testBulkBitsImpl(msbFirst, 3, 0, 3); - testBulkBitsImpl(msbFirst, 8, 0, 3); - testBulkBitsImpl(msbFirst, 9, 0, 3); - - testBulkBitsImpl(msbFirst, 0, 1, 1); - testBulkBitsImpl(msbFirst, 0, 1, 3); - testBulkBitsImpl(msbFirst, 0, 2, 8); - testBulkBitsImpl(msbFirst, 0, 8, 10); - testBulkBitsImpl(msbFirst, 0, 12, 20); - testBulkBitsImpl(msbFirst, 0, 23, 9); - testBulkBitsImpl(msbFirst, 0, 1, 31); - - testBulkBitsImpl(msbFirst, 1, 1, 1); - testBulkBitsImpl(msbFirst, 2, 1, 3); - testBulkBitsImpl(msbFirst, 7, 2, 8); - testBulkBitsImpl(msbFirst, 8, 8, 8); - testBulkBitsImpl(msbFirst, 15, 12, 5); - testBulkBitsImpl(msbFirst, 16, 11, 5); + public void test03BulkBits() throws IOException { + testBulkBitsImpl(0, 0, 1); + testBulkBitsImpl(0, 0, 3); + testBulkBitsImpl(0, 0, 8); + testBulkBitsImpl(0, 0, 10); + testBulkBitsImpl(0, 0, 30); + testBulkBitsImpl(0, 0, 31); + + testBulkBitsImpl(3, 0, 3); + testBulkBitsImpl(8, 0, 3); + testBulkBitsImpl(9, 0, 3); + testBulkBitsImpl(5, 0, 6); + testBulkBitsImpl(5, 0, 8); + + testBulkBitsImpl(0, 1, 1); + testBulkBitsImpl(3, 6, 4); + + testBulkBitsImpl(0, 1, 3); + testBulkBitsImpl(0, 2, 8); + testBulkBitsImpl(0, 8, 10); + testBulkBitsImpl(0, 12, 20); + testBulkBitsImpl(0, 23, 9); + testBulkBitsImpl(0, 1, 31); + + testBulkBitsImpl(1, 1, 1); + testBulkBitsImpl(2, 1, 3); + testBulkBitsImpl(7, 2, 8); + testBulkBitsImpl(8, 8, 8); + testBulkBitsImpl(15, 12, 5); + testBulkBitsImpl(16, 11, 5); + testBulkBitsImpl(5, 6, 5); + testBulkBitsImpl(5, 6, 8); } - void testBulkBitsImpl(final boolean msbFirst, final int preBits, final int skipBits, final int postBits) throws IOException { + void testBulkBitsImpl(final int preBits, final int skipBits, final int postBits) throws IOException { final int totalBits = preBits+skipBits+postBits; - System.err.println("XXX TestBulkBits: msbFirst "+msbFirst+", preBits "+preBits+", skipBits "+skipBits+", postBits "+postBits+", totalBits "+totalBits); + System.err.println("XXX TestBulkBits: preBits "+preBits+", skipBits "+skipBits+", postBits "+postBits+", totalBits "+totalBits); // prepare bitstream System.err.println("Prepare bitstream"); - final Bitstream bsTest = getTestStream(msbFirst, preBits, skipBits, postBits); - dumpData("Test", bsTest.getSubStream(), 0, bsTest.getSubStream().limit()); - final String sTest = getTestStreamResultAsString(msbFirst, preBits, skipBits, postBits); + final Bitstream bsTest = getTestStream(true, false, preBits, skipBits, postBits); + final String sTest = getTestStreamResultAsString(true, false, preBits, skipBits, postBits); // init copy-bitstream final int byteCount = ( totalBits + 7 ) / 8; @@ -273,18 +293,18 @@ // read-bitstream .. and copy bits while reading System.err.println("Reading bitstream: "+bsTest); { - final int readBitsPre = bsTest.readBits31(msbFirst, preBits); - Assert.assertEquals(readBitsPre, bsCopy.writeBits31(msbFirst, preBits, readBitsPre)); + final int readBitsPre = bsTest.readBits31(preBits); + Assert.assertEquals(readBitsPre, bsCopy.writeBits31(preBits, readBitsPre)); final int skippedReadBits = (int) bsTest.skip(skipBits); final int skippedBitsCopy = (int) bsCopy.skip(skipBits); - final int readBitsPost = bsTest.readBits31(msbFirst, postBits); - Assert.assertEquals(readBitsPost, bsCopy.writeBits31(msbFirst, postBits, readBitsPost)); - final String sReadPre = toBinaryString(readBitsPre, preBits); - final String sReadPost = toBinaryString(readBitsPost, postBits); - final String sRead = sReadPre + sReadPost; - System.err.println("Read.Test: <"+sReadPre+"> + <"+sReadPost+"> = <"+sRead+">"); + final int readBitsPost = bsTest.readBits31(postBits); + Assert.assertEquals(readBitsPost, bsCopy.writeBits31(postBits, readBitsPost)); + final String sReadPreLo = toBinaryString(readBitsPre, preBits); + final String sReadPostHi = toBinaryString(readBitsPost, postBits); + final String sRead = sReadPostHi + sReadPreLo; + System.err.println("Read.Test: <"+sReadPreLo+"> + <"+sReadPostHi+"> = <"+sRead+">"); Assert.assertEquals(skipBits, skippedReadBits); Assert.assertEquals(sTest, sRead); @@ -298,15 +318,15 @@ System.err.println("Reading copy-bitstream: "+bsCopy); Assert.assertEquals(0, bsCopy.position()); { - final int copyBitsPre = bsCopy.readBits31(msbFirst, preBits); + final int copyBitsPre = bsCopy.readBits31(preBits); final int skippedCopyBits = (int) bsCopy.skip(skipBits); - final int copyBitsPost = bsCopy.readBits31(msbFirst, postBits); - final String sCopyPre = toBinaryString(copyBitsPre, preBits); - final String sCopyPost = toBinaryString(copyBitsPost, postBits); - final String sCopy = sCopyPre + sCopyPost; - System.err.println("Copy.Test: <"+sCopyPre+"> + <"+sCopyPost+"> = <"+sCopy+">"); + final int copyBitsPost = bsCopy.readBits31(postBits); + final String sCopyPreLo = toBinaryString(copyBitsPre, preBits); + final String sCopyPostHi = toBinaryString(copyBitsPost, postBits); + final String sCopy = sCopyPostHi + sCopyPreLo; + System.err.println("Copy.Test: <"+sCopyPreLo+"> + <"+sCopyPostHi+"> = <"+sCopy+">"); Assert.assertEquals(skipBits, skippedCopyBits); Assert.assertEquals(sTest, sCopy); @@ -317,7 +337,7 @@ @Test public void test05ErrorHandling() throws IOException { // prepare bitstream - final Bitstream bsTest = getTestStream(false, 0, 0, 0); + final Bitstream bsTest = getTestStream(false, false, 0, 0, 0); System.err.println("01a: "+bsTest); bsTest.close(); System.err.println("01b: "+bsTest); diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestBitstream02.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestBitstream02.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestBitstream02.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestBitstream02.java 2015-10-09 04:18:28.000000000 +0000 @@ -35,9 +35,9 @@ import org.junit.Test; import com.jogamp.common.nio.Buffers; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; -import static com.jogamp.common.util.BitstreamData.*; +import static com.jogamp.common.util.BitDemoData.*; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @@ -51,7 +51,7 @@ * */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestBitstream02 extends JunitTracer { +public class TestBitstream02 extends SingletonJunitCase { @Test public void test01Int8BitsAligned() throws IOException { @@ -71,17 +71,17 @@ final Bitstream.ByteBufferStream bbs = new Bitstream.ByteBufferStream(bb); final Bitstream bs = new Bitstream(bbs, false /* outputMode */); { - final byte r8 = (byte) bs.readUInt8(true /* msbFirst */); + final byte r8 = (byte) bs.readUInt8(); System.err.println("Read8.1 "+r8+", "+toHexBinaryString(r8, 8)); Assert.assertEquals(val8, r8); } // Test with written bitstream value bs.setStream(bs.getSubStream(), true /* outputMode */); - bs.writeInt8(true /* msbFirst */, val8); + bs.writeInt8(val8); bs.setStream(bs.getSubStream(), false /* outputMode */); // switch to input-mode, implies flush() { - final byte r8 = (byte) bs.readUInt8(true /* msbFirst */); + final byte r8 = (byte) bs.readUInt8(); System.err.println("Read8.2 "+r8+", "+toHexBinaryString(r8, 8)); Assert.assertEquals(val8, r8); } @@ -114,12 +114,12 @@ // Test with written bitstream value final Bitstream.ByteBufferStream bbs = new Bitstream.ByteBufferStream(bb); final Bitstream bs = new Bitstream(bbs, true /* outputMode */); - bs.writeBits31(true /* msbFirst */, preBits, 0); - bs.writeInt8(true /* msbFirst */, val8); + bs.writeBits31(preBits, 0); + bs.writeInt8(val8); bs.setStream(bs.getSubStream(), false /* outputMode */); // switch to input-mode, implies flush() - final int rPre = (short) bs.readBits31(true /* msbFirst */, preBits); - final byte r8 = (byte) bs.readUInt8(true /* msbFirst */); + final int rPre = (short) bs.readBits31(preBits); + final byte r8 = (byte) bs.readUInt8(); System.err.println("ReadPre "+rPre+", "+toBinaryString(rPre, preBits)); System.err.println("Read8 "+r8+", "+toHexBinaryString(r8, 8)); Assert.assertEquals(val8, r8); diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestBitstream03.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestBitstream03.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestBitstream03.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestBitstream03.java 2015-10-09 04:18:28.000000000 +0000 @@ -36,9 +36,9 @@ import org.junit.Test; import com.jogamp.common.nio.Buffers; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; -import static com.jogamp.common.util.BitstreamData.*; +import static com.jogamp.common.util.BitDemoData.*; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @@ -47,12 +47,12 @@ * Test {@link Bitstream} w/ int16 read/write access w/ semantics * as well as with aligned and unaligned access. *
      - *
    • {@link Bitstream#readUInt16(boolean, boolean)}
    • - *
    • {@link Bitstream#writeInt16(boolean, boolean, short)}
    • + *
    • {@link Bitstream#readUInt16(boolean)}
    • + *
    • {@link Bitstream#writeInt16(boolean, short)}
    • *
    */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestBitstream03 extends JunitTracer { +public class TestBitstream03 extends SingletonJunitCase { @Test public void test01Int16BitsAligned() throws IOException { @@ -78,21 +78,23 @@ final boolean bigEndian = ByteOrder.BIG_ENDIAN == bb.order(); System.err.println("XXX Test01Int16BitsAligned: byteOrder "+byteOrder+" (bigEndian "+bigEndian+"), value "+val16+", "+toHexBinaryString(val16, 16)); bb.putShort(0, val16); + dumpData("TestData.1: ", bb, 0, 2); final Bitstream.ByteBufferStream bbs = new Bitstream.ByteBufferStream(bb); final Bitstream bs = new Bitstream(bbs, false /* outputMode */); { - final short r16 = (short) bs.readUInt16(true /* msbFirst */, bigEndian); + final short r16 = (short) bs.readUInt16(bigEndian); System.err.println("Read16.1 "+r16+", "+toHexBinaryString(r16, 16)); Assert.assertEquals(val16, r16); } // Test with written bitstream value bs.setStream(bs.getSubStream(), true /* outputMode */); - bs.writeInt16(true /* msbFirst */, bigEndian, val16); + bs.writeInt16(bigEndian, val16); bs.setStream(bs.getSubStream(), false /* outputMode */); // switch to input-mode, implies flush() + dumpData("TestData.2: ", bb, 0, 2); { - final short r16 = (short) bs.readUInt16(true /* msbFirst */, bigEndian); + final short r16 = (short) bs.readUInt16(bigEndian); System.err.println("Read16.2 "+r16+", "+toHexBinaryString(r16, 16)); Assert.assertEquals(val16, r16); } @@ -135,12 +137,13 @@ // Test with written bitstream value final Bitstream.ByteBufferStream bbs = new Bitstream.ByteBufferStream(bb); final Bitstream bs = new Bitstream(bbs, true /* outputMode */); - bs.writeBits31(true /* msbFirst */, preBits, 0); - bs.writeInt16(true /* msbFirst */, bigEndian, val16); + bs.writeBits31(preBits, 0); + bs.writeInt16(bigEndian, val16); bs.setStream(bs.getSubStream(), false /* outputMode */); // switch to input-mode, implies flush() + dumpData("TestData.1: ", bb, 0, byteCount); - final int rPre = (short) bs.readBits31(true /* msbFirst */, preBits); - final short r16 = (short) bs.readUInt16(true /* msbFirst */, bigEndian); + final int rPre = (short) bs.readBits31(preBits); + final short r16 = (short) bs.readUInt16(bigEndian); System.err.println("ReadPre "+rPre+", "+toBinaryString(rPre, preBits)); System.err.println("Read16 "+r16+", "+toHexBinaryString(r16, 16)); Assert.assertEquals(val16, r16); diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestBitstream04.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestBitstream04.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestBitstream04.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestBitstream04.java 2015-10-09 04:18:28.000000000 +0000 @@ -36,9 +36,9 @@ import org.junit.Test; import com.jogamp.common.nio.Buffers; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; -import static com.jogamp.common.util.BitstreamData.*; +import static com.jogamp.common.util.BitDemoData.*; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @@ -47,12 +47,12 @@ * Test {@link Bitstream} w/ int32 read/write access w/ semantics * as well as with aligned and unaligned access. *
      - *
    • {@link Bitstream#readUInt32(boolean, boolean)}
    • - *
    • {@link Bitstream#writeInt32(boolean, boolean, int)}
    • + *
    • {@link Bitstream#readUInt32(boolean)}
    • + *
    • {@link Bitstream#writeInt32(boolean, int)}
    • *
    */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestBitstream04 extends JunitTracer { +public class TestBitstream04 extends SingletonJunitCase { @Test public void test01Int32BitsAligned() throws IOException { @@ -82,11 +82,12 @@ System.err.println("XXX Test01Int32BitsAligned: "+val32+", "+val32_hs); bb.putInt(0, val32); + dumpData("TestData.1: ", bb, 0, 4); final Bitstream.ByteBufferStream bbs = new Bitstream.ByteBufferStream(bb); final Bitstream bs = new Bitstream(bbs, false /* outputMode */); { - final long uint32_l = bs.readUInt32(true /* msbFirst */, bigEndian); + final long uint32_l = bs.readUInt32(bigEndian); final int int32_l = (int)uint32_l; final String uint32_l_hs = toHexString(uint32_l); final int uint32_i = Bitstream.uint32LongToInt(uint32_l); @@ -99,10 +100,11 @@ // Test with written bitstream value bs.setStream(bs.getSubStream(), true /* outputMode */); - bs.writeInt32(true /* msbFirst */, bigEndian, val32); + bs.writeInt32(bigEndian, val32); bs.setStream(bs.getSubStream(), false /* outputMode */); // switch to input-mode, implies flush() + dumpData("TestData.2: ", bb, 0, 4); { - final long uint32_l = bs.readUInt32(true /* msbFirst */, bigEndian); + final long uint32_l = bs.readUInt32(bigEndian); final int int32_l = (int)uint32_l; final String uint32_l_hs = toHexString(uint32_l); final int uint32_i = Bitstream.uint32LongToInt(uint32_l); @@ -154,12 +156,12 @@ // Test with written bitstream value final Bitstream.ByteBufferStream bbs = new Bitstream.ByteBufferStream(bb); final Bitstream bs = new Bitstream(bbs, true /* outputMode */); - bs.writeBits31(true /* msbFirst */, preBits, 0); - bs.writeInt32(true /* msbFirst */, bigEndian, val32); + bs.writeBits31(preBits, 0); + bs.writeInt32(bigEndian, val32); bs.setStream(bs.getSubStream(), false /* outputMode */); // switch to input-mode, implies flush() - final int rPre = bs.readBits31(true /* msbFirst */, preBits); - final long uint32_l = bs.readUInt32(true /* msbFirst */, bigEndian); + final int rPre = bs.readBits31(preBits); + final long uint32_l = bs.readUInt32(bigEndian); final int int32_l = (int)uint32_l; final String uint32_l_hs = toHexString(uint32_l); final int uint32_i = Bitstream.uint32LongToInt(uint32_l); diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestFloatStack01.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestFloatStack01.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestFloatStack01.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestFloatStack01.java 2015-10-09 04:18:28.000000000 +0000 @@ -35,13 +35,13 @@ import org.junit.Assert; import org.junit.Test; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class /*testname*/TestFloatStack01/*testname*/ extends JunitTracer { +public class /*testname*/TestFloatStack01/*testname*/ extends SingletonJunitCase { static final boolean equals(final /*value*/float/*value*/[] b, final int bOffset, final /*value*/float/*value*/[] stack, final int stackOffset, final int length) { diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestIOUtil01.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestIOUtil01.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestIOUtil01.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestIOUtil01.java 2015-10-09 04:18:28.000000000 +0000 @@ -35,24 +35,29 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.net.URISyntaxException; import java.net.URLConnection; import java.nio.ByteBuffer; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import com.jogamp.common.os.MachineDescription; +import com.jogamp.common.ExceptionUtils; +import com.jogamp.common.net.URIDumpUtil; +import com.jogamp.common.net.Uri; +import com.jogamp.common.os.MachineDataInfo; import com.jogamp.common.os.Platform; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestIOUtil01 extends JunitTracer { +public class TestIOUtil01 extends SingletonJunitCase { - static final MachineDescription machine = Platform.getMachineDescription(); + static final MachineDataInfo machine = Platform.getMachineDataInfo(); static final int tsz = machine.pageSizeInBytes() + machine.pageSizeInBytes() / 2 ; static final byte[] orig = new byte[tsz]; static final String tfilename = "./test.bin" ; @@ -60,6 +65,7 @@ @BeforeClass public static void setup() throws IOException { final File tfile = new File(tfilename); + tfile.deleteOnExit(); final OutputStream tout = new BufferedOutputStream(new FileOutputStream(tfile)); for(int i=0; i=0 && orig[i]==bb.get(i); i--) ; + Assert.assertTrue("Bytes not equal orig vs array", 0>i); } finally { - IOUtil.close(bis, false); + file2.delete(); } - Assert.assertEquals("Byte number not equal orig vs buffer", orig.length, bb.limit()); - int i; - for(i=tsz-1; i>=0 && orig[i]==bb.get(i); i--) ; - Assert.assertTrue("Bytes not equal orig vs array", 0>i); } public static void main(final String args[]) throws IOException { diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestIOUtilURICompose.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestIOUtilURICompose.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestIOUtilURICompose.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestIOUtilURICompose.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -package com.jogamp.common.util; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; - -import org.junit.Assert; -import org.junit.Test; - -import com.jogamp.common.util.IOUtil; -import com.jogamp.junit.util.JunitTracer; - -import org.junit.FixMethodOrder; -import org.junit.runners.MethodSorters; - -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestIOUtilURICompose extends JunitTracer { - - @Test - public void test01URLCompositioning() throws IOException, URISyntaxException { - testURNCompositioning("file:///rootDir/file1.txt"); - testURNCompositioning("file://host/rootDir/file1.txt"); - testURNCompositioning("jar:file:/web1/file1.jar!/rootDir/file1.txt"); - testURNCompositioning("asset:gluegen-test/info.txt"); - testURNCompositioning("asset:/gluegen-test/info.txt"); - testURNCompositioning("http://domain.com/web1/index.html?lala=23&lili=24#anchor"); - testURNCompositioning("http://domain.com:1234/web1/index.html?lala=23&lili=24#anchor"); - - final URI file1URI = new URI("asset:jar:file:/web1/file1.jar!/rootDir/file1.txt"); - testURICompositioning(file1URI); - testURICompositioning(file1URI, new URI("asset:jar:file:/web1/file1.jar!/rootDir/./file1.txt")); - testURICompositioning(file1URI, new URI("asset:jar:file:/web1/file1.jar!/rootDir/dummyParent/../file1.txt")); - - final URL file1URL = new URL("asset:jar:file:/web1/file1.jar!/rootDir/file1.txt"); - testURLCompositioning(file1URL); - testURLCompositioning(file1URL, new URL("asset:jar:file:/web1/file1.jar!/rootDir/./file1.txt")); - testURLCompositioning(file1URL, new URL("asset:jar:file:/web1/file1.jar!/rootDir/dummyParent/../file1.txt")); - } - - static void testURNCompositioning(final String urn) throws MalformedURLException, URISyntaxException { - testURICompositioning( new URI(urn) ); - testURLCompositioning( new URL(urn) ); - } - - static void testURICompositioning(final URI uri) throws MalformedURLException, URISyntaxException { - testURICompositioning(uri, uri); - } - static void testURICompositioning(final URI refURI, final URI uri1) throws MalformedURLException, URISyntaxException { - final String scheme = uri1.getScheme(); - final String ssp = uri1.getRawSchemeSpecificPart(); - final String fragment = uri1.getRawFragment(); - - System.err.println("scheme <"+scheme+">, ssp <"+ssp+">, fragment <"+fragment+">"); - final URI uri2 = IOUtil.compose(scheme, ssp, null, fragment); - - System.err.println("URL-equals: "+refURI.equals(uri2)); - System.err.println("URL-ref : <"+refURI+">"); - System.err.println("URL-orig : <"+uri1+">"); - System.err.println("URL-comp : <"+uri2+">"); - Assert.assertEquals(refURI, uri2); - } - - static void testURLCompositioning(final URL url) throws MalformedURLException, URISyntaxException { - testURLCompositioning(url, url); - } - static void testURLCompositioning(final URL refURL, final URL url1) throws MalformedURLException, URISyntaxException { - final URI uri1 = url1.toURI(); - final String scheme = uri1.getScheme(); - final String ssp = uri1.getRawSchemeSpecificPart(); - final String fragment = uri1.getRawFragment(); - - System.err.println("scheme <"+scheme+">, ssp <"+ssp+">, fragment <"+fragment+">"); - final URI uri2 = IOUtil.compose(scheme, ssp, null, fragment); - - System.err.println("URL-equals(1): "+refURL.toURI().equals(uri2)); - System.err.println("URL-equals(2): "+refURL.equals(uri2.toURL())); - System.err.println("URL-same : "+refURL.sameFile(uri2.toURL())); - System.err.println("URL-ref : <"+refURL+">"); - System.err.println("URL-orig : <"+url1+">"); - System.err.println("URL-comp : <"+uri2+">"); - Assert.assertEquals(refURL.toURI(), uri2); - Assert.assertEquals(refURL, uri2.toURL()); - Assert.assertTrue(refURL.sameFile(uri2.toURL())); - } - - public static void main(final String args[]) throws IOException { - final String tstname = TestIOUtilURICompose.class.getName(); - org.junit.runner.JUnitCore.main(tstname); - } -} diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestIOUtilURIHandling.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestIOUtilURIHandling.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestIOUtilURIHandling.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestIOUtilURIHandling.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,393 +0,0 @@ -package com.jogamp.common.util; - -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; - -import jogamp.common.os.PlatformPropsImpl; - -import org.junit.Assert; -import org.junit.Test; - -import com.jogamp.common.net.URIDumpUtil; -import com.jogamp.common.os.Platform; -import com.jogamp.common.util.IOUtil; -import com.jogamp.junit.util.JunitTracer; - -import org.junit.FixMethodOrder; -import org.junit.runners.MethodSorters; - -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestIOUtilURIHandling extends JunitTracer { - - // Bug 908, issues w/ windows file path char: $ ^ ~ # [ ] - - public static final String[][] uriHttpSArray = new String[][] { - new String[] {"http://localhost/gluegen/build-x86_64/gluegen-rt.jar"}, - - new String[] {"http://localhost/gluegen/"+'\u0394'+"/gluegen-rt.jar"}, - - new String[] {"http://localhost/gluegen/build-x86_64%20lala/gluegen-rt.jar"}, - - new String[] {"http://localhost/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar"}, - - new String[] {"jar:http://localhost/gluegen/build-x86_64/gluegen-rt.jar!/"}, - - new String[] {"jar:http://localhost/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/"}, - - new String[] {"jar:http://localhost/gluegen/build-x86_64/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, - - new String[] {"jar:http://localhost/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, - - new String[] {"jar:http://localhost/gluegen/R%23/gluegen-rt.jar!/"}, - - new String[] {"jar:http://localhost/gluegen/"+'\u0394'+"/gluegen-rt.jar!/"}, - }; - - public static final String[][] uriFileSArrayUnix = new String[][] { - new String[] {"file:/gluegen/build-x86_64/gluegen-rt.jar"}, - - new String[] {"file:/gluegen/"+'\u0394'+"/gluegen-rt.jar"}, - - new String[] {"file:/gluegen/build-x86_64%20lala/gluegen-rt.jar"}, - - new String[] {"file:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar"}, - - new String[] {"jar:file:/gluegen/build-x86_64/gluegen-rt.jar!/"}, - - new String[] {"jar:file:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/"}, - - new String[] {"jar:file:/gluegen/build-x86_64/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, - - new String[] {"jar:file:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, - - new String[] {"jar:file://filehost/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, - - new String[] {"jar:file:/gluegen/R%23/gluegen-rt.jar!/"}, - - new String[] {"jar:file:/gluegen/"+'\u0394'+"/gluegen-rt.jar!/"}, - }; - - public static final String[][] uriFileSArrayWindows = new String[][] { - new String[] {"file:/C:/gluegen/build-x86_64/gluegen-rt.jar"}, - new String[] {"file:/C%3A/gluegen/build-x86_64/gluegen-rt.jar"}, - - new String[] {"file:/C:/gluegen/"+'\u0394'+"/gluegen-rt.jar"}, - - new String[] {"file:/C:/gluegen/build-x86_64%20lala/gluegen-rt.jar"}, - - new String[] {"file:/C:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar"}, - - new String[] {"jar:file:/C:/gluegen/build-x86_64/gluegen-rt.jar!/"}, - - new String[] {"jar:file:/C:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/"}, - - new String[] {"jar:file:/C:/gluegen/build-x86_64/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, - - new String[] {"jar:file:/C:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, - new String[] {"jar:file:/C%3A/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, - - new String[] {"jar:file:///C:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, - - new String[] {"jar:file://filehost/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar!/com/jogamp/common/os/Platform.class"}, - - new String[] {"jar:file:/C:/gluegen/R%23/gluegen-rt.jar!/"}, - - new String[] {"jar:file:/C:/gluegen/"+'\u0394'+"/gluegen-rt.jar!/"}, - }; - - public static final String[][] fileSArrayUnix = new String[][] { - new String[] {"/gluegen/build-x86_64/gluegen-rt.jar", - "file:/gluegen/build-x86_64/gluegen-rt.jar", - "/gluegen/build-x86_64/gluegen-rt.jar"}, - - new String[] {"/gluegen/"+'\u0394'+"/gluegen-rt.jar", - "file:/gluegen/"+'\u0394'+"/gluegen-rt.jar", - "/gluegen/"+'\u0394'+"/gluegen-rt.jar"}, - - new String[] {"/gluegen/build-x86_64 lala/gluegen-rt.jar", - "file:/gluegen/build-x86_64%20lala/gluegen-rt.jar", - "/gluegen/build-x86_64 lala/gluegen-rt.jar"}, - - new String[] {"/gluegen/build-x86_64 öä lala/gluegen-rt.jar", - "file:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar", - "/gluegen/build-x86_64 öä lala/gluegen-rt.jar"}, - - new String[] {"/gluegen/A$/B^/C~/D#/E[/F]/gluegen-rt.jar", - // "file:/gluegen/A%24/B%5E/C%7E/D%23/E%5B/F%5D/gluegen-rt.jar", // goal w/ new Uri class - "file:/gluegen/A$/B%5E/C~/D%23/E%5B/F%5D/gluegen-rt.jar", // current Java URI/URL decoding - "/gluegen/A$/B^/C~/D#/E[/F]/gluegen-rt.jar" }, // goal w/ new Uri class - - new String[] {"/gluegen/$/^/~/#/[/]/gluegen-rt.jar", - // "file:/gluegen/%24/%5E/%7E/%23/%5B/%5D/gluegen-rt.jar", - "file:/gluegen/$/%5E/~/%23/%5B/%5D/gluegen-rt.jar", // current Java URI/URL decoding - "/gluegen/$/^/~/#/[/]/gluegen-rt.jar" }, - }; - - public static final String[][] fileSArrayWindows = new String[][] { - new String[] {"C:/gluegen/build-x86_64/gluegen-rt.jar", - // "file:/C%3A/gluegen/build-x86_64/gluegen-rt.jar", - "file:/C:/gluegen/build-x86_64/gluegen-rt.jar", - "C:\\gluegen\\build-x86_64\\gluegen-rt.jar"}, - - new String[] {"C:/gluegen/"+'\u0394'+"/gluegen-rt.jar", - // "file:/C%3A/gluegen/"+'\u0394'+"/gluegen-rt.jar", - "file:/C:/gluegen/"+'\u0394'+"/gluegen-rt.jar", - "C:\\gluegen\\"+'\u0394'+"\\gluegen-rt.jar"}, - - new String[] {"C:/gluegen/build-x86_64 lala/gluegen-rt.jar", - // "file:/C%3A/gluegen/build-x86_64%20lala/gluegen-rt.jar", - "file:/C:/gluegen/build-x86_64%20lala/gluegen-rt.jar", - "C:\\gluegen\\build-x86_64 lala\\gluegen-rt.jar"}, - - new String[] {"C:/gluegen/build-x86_64 öä lala/gluegen-rt.jar", - // "file:/C%3A/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar", - "file:/C:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar", - "C:\\gluegen\\build-x86_64 öä lala\\gluegen-rt.jar"}, - - new String[] {"C:\\gluegen\\build-x86_64 öä lala\\gluegen-rt.jar", - // "file:/C%3A/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar", - "file:/C:/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar", - "C:\\gluegen\\build-x86_64 öä lala\\gluegen-rt.jar"}, - - new String[] {"\\\\filehost\\gluegen\\build-x86_64 öä lala\\gluegen-rt.jar", - "file:////filehost/gluegen/build-x86_64%20öä%20lala/gluegen-rt.jar", - "\\\\filehost\\gluegen\\build-x86_64 öä lala\\gluegen-rt.jar"}, - - new String[] {"C:/gluegen/A$/B^/C~/D#/E[/F]/gluegen-rt.jar", - // "file:/C%3A/gluegen/A%24/B%5E/C%7E/D%23/E%5B/F%5D/gluegen-rt.jar", - "file:/C:/gluegen/A$/B%5E/C~/D%23/E%5B/F%5D/gluegen-rt.jar", - "C:\\gluegen\\A$\\B^\\C~\\D#\\E[\\F]\\gluegen-rt.jar" }, - - new String[] {"C:/gluegen/$/^/~/#/[/]/gluegen-rt.jar", - // "file:/C%3A/gluegen/%24/%5E/%7E/%23/%5B/%5D/gluegen-rt.jar", - "file:/C:/gluegen/$/%5E/~/%23/%5B/%5D/gluegen-rt.jar", // current Java URI/URL decoding - "C:\\gluegen\\$\\^\\~\\#\\[\\]\\gluegen-rt.jar" }, - }; - - @Test - public void test00BasicCoding() throws IOException, URISyntaxException { - final String string = "Hallo Welt öä"; - System.err.println("sp1 "+string); - final File file = new File(string); - System.err.println("file "+file); - System.err.println("file.path.dec "+file.getPath()); - System.err.println("file.path.abs "+file.getAbsolutePath()); - System.err.println("file.path.can "+file.getCanonicalPath()); - final URI uri0 = file.toURI(); - System.err.println("uri0.string: "+uri0.toString()); - System.err.println("uri0.path : "+uri0.getPath()); - System.err.println("uri0.ascii : "+uri0.toASCIIString()); - boolean ok = true; - { - final URI uri1 = IOUtil.toURISimple(file); - final boolean equalString= uri0.toString().equals(uri1.toString()); - final boolean equalPath = uri0.getPath().equals(uri1.getPath()); - final boolean equalASCII= uri0.toASCIIString().equals(uri1.toASCIIString()); - System.err.println("uri1.string: "+uri1.toString()+" - "+(equalString?"OK":"ERROR")); - System.err.println("uri1.path : "+uri1.getPath()+" - "+(equalPath?"OK":"ERROR")); - System.err.println("uri1.ascii : "+uri1.toASCIIString()+" - "+(equalASCII?"OK":"ERROR")); - ok = equalString && equalPath && equalASCII && ok; - } - { - final String s2 = IOUtil.slashify(file.getAbsolutePath(), true /* startWithSlash */, file.isDirectory() /* endWithSlash */); - System.err.println("uri2.slashify: "+s2); - { - // Expected !equals due to double-escaping of space %20 -> %25%20 - // Double escaping is due to IOUtil.encodeToURI(s2). - @SuppressWarnings("deprecation") - final String s3 = IOUtil.encodeToURI(s2); - System.err.println("uri2.encoded: "+s3); - final URI uri1 = new URI(IOUtil.FILE_SCHEME, null, s3, null); - final boolean equalString= uri0.toString().equals(uri1.toString()); - final boolean equalPath = uri0.getPath().equals(uri1.getPath()); - final boolean equalASCII= uri0.toASCIIString().equals(uri1.toASCIIString()); - System.err.println("uri2.string: "+uri1.toString()+" - "+(equalString?"ERROR EQUAL":"OK NOT_EQUAL")); - System.err.println("uri2.path : "+uri1.getPath()+" - "+(equalPath?"ERROR EQUAL":"OK NOT_EQUAL")); - System.err.println("uri2.ascii : "+uri1.toASCIIString()+" - "+(equalASCII?"ERROR EQUAL":"OK NOT_EQUAL")); - ok = !equalString && !equalPath && !equalASCII && ok; - } - final URI uri1 = new URI(IOUtil.FILE_SCHEME, null, s2, null); - final boolean equalString= uri0.toString().equals(uri1.toString()); - final boolean equalPath = uri0.getPath().equals(uri1.getPath()); - final boolean equalASCII= uri0.toASCIIString().equals(uri1.toASCIIString()); - System.err.println("uri2.string: "+uri1.toString()+" - "+(equalString?"OK":"ERROR")); - System.err.println("uri2.path : "+uri1.getPath()+" - "+(equalPath?"OK":"ERROR")); - System.err.println("uri2.ascii : "+uri1.toASCIIString()+" - "+(equalASCII?"OK":"ERROR")); - ok = equalString && equalPath && equalASCII && ok; - } - { - final String s2 = "/"+string; - System.err.println("uri3.orig: "+s2); - final URI uri1 = new URI(IOUtil.FILE_SCHEME, s2, null); - final String rString = "file:/Hallo%20Welt%20öä"; - final String rPath = s2; - final String rASCII = "file:/Hallo%20Welt%20%C3%B6%C3%A4"; - final boolean equalString= rString.equals(uri1.toString()); - final boolean equalPath = rPath.equals(uri1.getPath()); - final boolean equalASCII= rASCII.equals(uri1.toASCIIString()); - System.err.println("uri3.string: "+uri1.toString()+" - "+(equalString?"OK":"ERROR")); - System.err.println("uri3.path : "+uri1.getPath()+" - "+(equalPath?"OK":"ERROR")); - System.err.println("uri3.ascii : "+uri1.toASCIIString()+" - "+(equalASCII?"OK":"ERROR")); - ok = equalString && equalPath && equalASCII && ok; - } - { - final String s2 = "//lala.org/"+string; - System.err.println("uri4.orig: "+s2); - final URI uri1 = new URI(IOUtil.HTTP_SCHEME, s2, null); - final String rString = "http://lala.org/Hallo%20Welt%20öä"; - final String rPath = "/"+string; - final String rASCII = "http://lala.org/Hallo%20Welt%20%C3%B6%C3%A4"; - final boolean equalString= rString.equals(uri1.toString()); - final boolean equalPath = rPath.equals(uri1.getPath()); - final boolean equalASCII= rASCII.equals(uri1.toASCIIString()); - System.err.println("uri4.string: "+uri1.toString()+" - "+(equalString?"OK":"ERROR")); - System.err.println("uri4.path : "+uri1.getPath()+" - "+(equalPath?"OK":"ERROR")); - System.err.println("uri4.ascii : "+uri1.toASCIIString()+" - "+(equalASCII?"OK":"ERROR")); - ok = equalString && equalPath && equalASCII && ok; - } - Assert.assertTrue("One or more errors occured see stderr above", ok); - } - - @Test - public void test01HttpURI2URL() throws IOException, URISyntaxException { - testURI2URL(getSimpleTestName("."), uriHttpSArray); - } - - @Test - public void test02FileUnixURI2URL() throws IOException, URISyntaxException { - testURI2URL(getSimpleTestName("."), uriFileSArrayUnix); - } - - @Test - public void test03FileWindowsURI2URL() throws IOException, URISyntaxException { - testURI2URL(getSimpleTestName("."), uriFileSArrayWindows); - } - - @Test - public void test04FileUnixURI2URL() throws IOException, URISyntaxException { - if( Platform.OSType.WINDOWS != PlatformPropsImpl.OS_TYPE ) { - testFile2URI(getSimpleTestName("."), fileSArrayUnix); - } - } - - @Test - public void test05FileWindowsURI2URL() throws IOException, URISyntaxException { - if( Platform.OSType.WINDOWS == PlatformPropsImpl.OS_TYPE ) { - testFile2URI(getSimpleTestName("."), fileSArrayWindows); - } - } - - static void testURI2URL(final String testname, final String[][] uriSArray) throws IOException, URISyntaxException { - boolean ok = true; - for(int i=0; i0); System.err.println("URLConnection of jarSubURL: "+urlConn); - final URI jarFileURL = JarUtil.getJarFileURI(clazzBinName, cl); + final Uri jarFileURL = JarUtil.getJarFileUri(clazzBinName, cl); validateJarFileURL(jarFileURL); final JarFile jarFile = JarUtil.getJarFile(clazzBinName, cl); @@ -146,10 +156,10 @@ final ClassLoader rootCL = this.getClass().getClassLoader(); // Get containing JAR file "TestJarsInJar.jar" and add it to the TempJarCache - TempJarCache.addAll(GlueGenVersion.class, JarUtil.getJarFileURI("ClassInJar0", rootCL)); + TempJarCache.addAll(GlueGenVersion.class, JarUtil.getJarFileUri("ClassInJar0", rootCL)); // Fetch and load the contained "ClassInJar1.jar" - final URL ClassInJar1_jarFileURL = JarUtil.getJarFileURI(TempJarCache.getResource("ClassInJar1.jar")).toURL(); + final URL ClassInJar1_jarFileURL = JarUtil.getJarFileUri(TempJarCache.getResourceUri("ClassInJar1.jar")).toURL(); final ClassLoader cl = new URLClassLoader(new URL[] { ClassInJar1_jarFileURL }, rootCL); Assert.assertNotNull(cl); validateJarUtil("ClassInJar1.jar", "ClassInJar1", cl); @@ -167,10 +177,10 @@ final ClassLoader rootCL = this.getClass().getClassLoader(); // Get containing JAR file "TestJarsInJar.jar" and add it to the TempJarCache - TempJarCache.addAll(GlueGenVersion.class, JarUtil.getJarFileURI("ClassInJar0", rootCL)); + TempJarCache.addAll(GlueGenVersion.class, JarUtil.getJarFileUri("ClassInJar0", rootCL)); // Fetch and load the contained "ClassInJar1.jar" - final URL ClassInJar2_jarFileURL = JarUtil.getJarFileURI(TempJarCache.getResource("sub/ClassInJar2.jar")).toURL(); + final URL ClassInJar2_jarFileURL = JarUtil.getJarFileUri(TempJarCache.getResourceUri("sub/ClassInJar2.jar")).toURL(); final ClassLoader cl = new URLClassLoader(new URL[] { ClassInJar2_jarFileURL }, rootCL); Assert.assertNotNull(cl); validateJarUtil("ClassInJar2.jar", "ClassInJar2", cl); @@ -231,7 +241,7 @@ public URL resolve( final URL url ) { if( url.getProtocol().equals("bundleresource") ) { try { - return new URL( IOUtil.JAR_SCHEME, "", url.getFile() ); + return new URL( Uri.JAR_SCHEME, "", url.getFile() ); } catch(final MalformedURLException e) { return url; } @@ -244,10 +254,10 @@ final ClassLoader rootCL = new CustomClassLoader(); // Get containing JAR file "TestJarsInJar.jar" and add it to the TempJarCache - TempJarCache.addAll(GlueGenVersion.class, JarUtil.getJarFileURI("ClassInJar0", rootCL)); + TempJarCache.addAll(GlueGenVersion.class, JarUtil.getJarFileUri("ClassInJar0", rootCL)); // Fetch and load the contained "ClassInJar1.jar" - final URL ClassInJar2_jarFileURL = JarUtil.getJarFileURI(TempJarCache.getResource("sub/ClassInJar2.jar")).toURL(); + final URL ClassInJar2_jarFileURL = JarUtil.getJarFileUri(TempJarCache.getResourceUri("sub/ClassInJar2.jar")).toURL(); final ClassLoader cl = new URLClassLoader(new URL[] { ClassInJar2_jarFileURL }, rootCL); Assert.assertNotNull(cl); validateJarUtil("ClassInJar2.jar", "ClassInJar2", cl); diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestPlatform01.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestPlatform01.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestPlatform01.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestPlatform01.java 2015-10-09 04:18:28.000000000 +0000 @@ -31,20 +31,20 @@ import org.junit.Assert; import org.junit.Test; -import com.jogamp.common.os.MachineDescription; +import com.jogamp.common.os.MachineDataInfo; import com.jogamp.common.os.Platform; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestPlatform01 extends JunitTracer { +public class TestPlatform01 extends SingletonJunitCase { @Test public void testInfo00() { System.err.println(); - System.err.println(); + System.err.print(Platform.getNewline()); System.err.println("OS name/type: "+Platform.getOSName()+", "+Platform.getOSType()); System.err.println("OS version: "+Platform.getOSVersion()+", "+Platform.getOSVersionNumber()); System.err.println(); @@ -55,14 +55,14 @@ System.err.println("Java vendor[name/url]: "+Platform.getJavaVendor()+"/"+Platform.getJavaVendorURL()); System.err.println("Java version, vm: "+Platform.getJavaVersion()+", "+Platform.getJavaVMName()); System.err.println(); - System.err.println("MD: "+Platform.getMachineDescription()); + System.err.println("MD: "+Platform.getMachineDataInfo()); System.err.println(); System.err.println(); } @Test public void testPageSize01() { - final MachineDescription machine = Platform.getMachineDescription(); + final MachineDataInfo machine = Platform.getMachineDataInfo(); final int ps = machine.pageSizeInBytes(); System.err.println("PageSize: "+ps); Assert.assertTrue("PageSize is 0", 0 < ps ); diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestRunnableTask01.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestRunnableTask01.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestRunnableTask01.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestRunnableTask01.java 2015-10-09 04:18:28.000000000 +0000 @@ -34,13 +34,13 @@ import org.junit.Assert; import org.junit.Test; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestRunnableTask01 extends JunitTracer { +public class TestRunnableTask01 extends SingletonJunitCase { @Test public void testInvokeAndWait00() throws IOException, InterruptedException, InvocationTargetException { @@ -60,7 +60,7 @@ System.err.println("BB.0: "+syncObject); synchronized (syncObject) { System.err.println("BB.1: "+syncObject); - new Thread(clientAction, Thread.currentThread().getName()+"-clientAction").start(); + new InterruptSource.Thread(null, clientAction, Thread.currentThread().getName()+"-clientAction").start(); try { System.err.println("BB.2"); syncObject.wait(); @@ -88,7 +88,7 @@ System.err.println("BB.0: "+rTask.getSyncObject()); synchronized (rTask.getSyncObject()) { System.err.println("BB.1: "+rTask.getSyncObject()); - new Thread(rTask, Thread.currentThread().getName()+"-clientAction").start(); + new InterruptSource.Thread(null, rTask, Thread.currentThread().getName()+"-clientAction").start(); try { System.err.println("BB.2"); rTask.getSyncObject().wait(); diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestSystemPropsAndEnvs.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestSystemPropsAndEnvs.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestSystemPropsAndEnvs.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestSystemPropsAndEnvs.java 2015-10-09 04:18:28.000000000 +0000 @@ -35,13 +35,13 @@ import org.junit.Test; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestSystemPropsAndEnvs extends JunitTracer { +public class TestSystemPropsAndEnvs extends SingletonJunitCase { @Test public void dumpProperties() { diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestTempJarCache.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestTempJarCache.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestTempJarCache.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestTempJarCache.java 2015-10-09 04:18:28.000000000 +0000 @@ -29,10 +29,8 @@ package com.jogamp.common.util; import java.io.File; - import java.io.IOException; import java.lang.reflect.Method; -import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; @@ -45,17 +43,18 @@ import org.junit.runners.MethodSorters; import com.jogamp.common.GlueGenVersion; -import com.jogamp.common.jvm.JNILibLoaderBase; +import com.jogamp.common.net.URIDumpUtil; +import com.jogamp.common.net.Uri; import com.jogamp.common.os.AndroidVersion; import com.jogamp.common.os.NativeLibrary; import com.jogamp.common.os.Platform; import com.jogamp.common.util.cache.TempCacheReg; import com.jogamp.common.util.cache.TempFileCache; import com.jogamp.common.util.cache.TempJarCache; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestTempJarCache extends JunitTracer { +public class TestTempJarCache extends SingletonJunitCase { static TempFileCache fileCache; static class TestClassLoader extends URLClassLoader { @@ -177,7 +176,7 @@ if(AndroidVersion.isAvailable) { System.err.println("n/a on Android"); return; } final ClassLoader cl = getClass().getClassLoader(); - TempJarCache.addAll(GlueGenVersion.class, JarUtil.getJarFileURI(GlueGenVersion.class.getName(), cl)); + TempJarCache.addAll(GlueGenVersion.class, JarUtil.getJarFileUri(GlueGenVersion.class.getName(), cl)); File f0 = new File(TempJarCache.getTempFileCache().getTempDir(), "META-INF/MANIFEST.MF"); Assert.assertTrue(f0.exists()); @@ -197,14 +196,28 @@ @Test public void testTempJarCache02AddNativeLibs() throws IOException, IllegalArgumentException, URISyntaxException { if(AndroidVersion.isAvailable) { System.err.println("n/a on Android"); return; } - final String nativeJarName = "gluegen-rt-natives-"+Platform.getOSAndArch()+".jar"; + final Uri.Encoded nativeJarName = Uri.Encoded.cast("gluegen-rt-natives-"+Platform.getOSAndArch()+".jar"); final String libBaseName = "gluegen-rt"; final ClassLoader cl = getClass().getClassLoader(); - URI jarUriRoot = JarUtil.getJarSubURI(TempJarCache.class.getName(), cl); - jarUriRoot = IOUtil.getURIDirname(jarUriRoot); - - final URI nativeJarURI = JarUtil.getJarFileURI(jarUriRoot, nativeJarName); + final Uri jarUri = JarUtil.getJarUri(TempJarCache.class.getName(), cl); + Assert.assertNotNull(jarUri); + System.err.println("1 - jarUri:"); + URIDumpUtil.showUri(jarUri); + + final Uri jarFileUri = jarUri.getContainedUri(); + Assert.assertNotNull(jarFileUri); + System.err.println("2 - jarFileUri:"); + URIDumpUtil.showUri(jarFileUri); + + final Uri jarFileDir = jarFileUri.getParent(); + Assert.assertNotNull(jarFileDir); + System.err.println("3 - jarFileDir:"); + URIDumpUtil.showUri(jarFileDir); + + final Uri nativeJarURI = JarUtil.getJarFileUri(jarFileDir, nativeJarName); + System.err.println("4 - nativeJarURI:"); + URIDumpUtil.showUri(nativeJarURI); TempJarCache.addNativeLibs(TempJarCache.class, nativeJarURI, null /* nativeLibraryPath */); final String libFullPath = TempJarCache.findLibrary(libBaseName); @@ -227,7 +240,7 @@ @Test public void testTempJarCache04bDiffClassLoader() throws IOException, IllegalArgumentException, URISyntaxException { if(AndroidVersion.isAvailable) { System.err.println("n/a on Android"); return; } - final URL[] urls = new URL[] { JarUtil.getJarFileURI(TempJarCache.class.getName(), getClass().getClassLoader()).toURL() }; + final URL[] urls = new URL[] { JarUtil.getJarFileUri(TempJarCache.class.getName(), getClass().getClassLoader()).toURL() }; System.err.println("url: "+urls[0]); final ClassLoader cl2 = new TestClassLoader(urls, null); final ClassLoader cl3 = new TestClassLoader(urls, null); diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestVersionInfo.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestVersionInfo.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestVersionInfo.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestVersionInfo.java 2015-10-09 04:18:28.000000000 +0000 @@ -32,13 +32,13 @@ import org.junit.Test; import com.jogamp.common.GlueGenVersion; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestVersionInfo extends JunitTracer { +public class TestVersionInfo extends SingletonJunitCase { @Test public void testInfo01() { diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestVersionNumber.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestVersionNumber.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestVersionNumber.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestVersionNumber.java 2015-10-09 04:18:28.000000000 +0000 @@ -33,13 +33,13 @@ import org.junit.Assert; import org.junit.Test; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestVersionNumber extends JunitTracer { +public class TestVersionNumber extends SingletonJunitCase { @Test public void test01() { diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestVersionSemantics.java gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestVersionSemantics.java --- gluegen2-2.2.4/src/junit/com/jogamp/common/util/TestVersionSemantics.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/common/util/TestVersionSemantics.java 2015-10-09 04:18:28.000000000 +0000 @@ -42,7 +42,7 @@ import com.jogamp.common.GlueGenVersion; import com.jogamp.common.util.VersionNumberString; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import com.jogamp.junit.util.VersionSemanticsUtil; /** @@ -64,11 +64,8 @@ * @throws URISyntaxException */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestVersionSemantics extends JunitTracer { +public class TestVersionSemantics extends SingletonJunitCase { static final String jarFile = "gluegen-rt.jar"; - static final VersionNumberString preVersionNumber = new VersionNumberString("2.2.0"); - // static final Delta.CompatibilityType expectedCompatibilityType = Delta.CompatibilityType.NON_BACKWARD_COMPATIBLE; - static final Delta.CompatibilityType expectedCompatibilityType = Delta.CompatibilityType.BACKWARD_COMPATIBLE_USER; static final DiffCriteria diffCriteria = new SimpleDiffCriteria(); // static final DiffCriteria diffCriteria = new PublicDiffCriteria(); @@ -76,22 +73,50 @@ static final JogampVersion curVersion = GlueGenVersion.getInstance(); static final VersionNumberString curVersionNumber = new VersionNumberString(curVersion.getImplementationVersion()); - static final Set excludes; + static final Set excludesDefault; static { - excludes = new HashSet(); - excludes.add("^\\Qjogamp/\\E.*$"); + excludesDefault = new HashSet(); + excludesDefault.add("^\\Qjogamp/\\E.*$"); } @Test - public void testVersionLatest() throws IllegalArgumentException, IOException, URISyntaxException { + public void testVersionV220V221() throws IllegalArgumentException, IOException, URISyntaxException { + testVersions(diffCriteria, Delta.CompatibilityType.BACKWARD_COMPATIBLE_USER, "2.2.0", "2.2.1", excludesDefault); + } + + @Test + public void testVersionV221V230() throws IllegalArgumentException, IOException, URISyntaxException { + testVersions(diffCriteria, Delta.CompatibilityType.NON_BACKWARD_COMPATIBLE, "2.2.1", "2.3.0", excludesDefault); + } + + void testVersions(final DiffCriteria diffCriteria, final Delta.CompatibilityType expectedCompatibilityType, + final String v1, final String v2, final Set excludes) + throws IllegalArgumentException, IOException, URISyntaxException { + final VersionNumberString preVersionNumber = new VersionNumberString(v1); + final File previousJar = new File("lib/v"+v1+"/"+jarFile); + + final VersionNumberString curVersionNumber = new VersionNumberString(v2); + final File currentJar = new File("lib/v"+v2+"/"+jarFile); + + VersionSemanticsUtil.testVersion(diffCriteria, expectedCompatibilityType, + previousJar, preVersionNumber, + currentJar, curVersionNumber, excludes); + } + + @Test + public void testVersionV230V23x() throws IllegalArgumentException, IOException, URISyntaxException { + // final Delta.CompatibilityType expectedCompatibilityType = Delta.CompatibilityType.NON_BACKWARD_COMPATIBLE; + // final Delta.CompatibilityType expectedCompatibilityType = Delta.CompatibilityType.BACKWARD_COMPATIBLE_USER; + final Delta.CompatibilityType expectedCompatibilityType = Delta.CompatibilityType.BACKWARD_COMPATIBLE_BINARY; + final VersionNumberString preVersionNumber = new VersionNumberString("2.3.0"); final File previousJar = new File("lib/v"+preVersionNumber.getVersionString()+"/"+jarFile); final ClassLoader currentCL = TestVersionSemantics.class.getClassLoader(); VersionSemanticsUtil.testVersion(diffCriteria, expectedCompatibilityType, previousJar, preVersionNumber, - curVersion.getClass(), currentCL, curVersionNumber, excludes); + curVersion.getClass(), currentCL, curVersionNumber, excludesDefault); } public static void main(final String args[]) throws IOException { diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java --- gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java 2015-10-09 04:18:28.000000000 +0000 @@ -30,9 +30,9 @@ import com.jogamp.common.nio.Buffers; import com.jogamp.common.nio.PointerBuffer; -import com.jogamp.common.os.MachineDescription; +import com.jogamp.common.os.MachineDataInfo; import com.jogamp.common.os.Platform; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -41,7 +41,7 @@ import java.nio.LongBuffer; import java.util.Arrays; -import jogamp.common.os.MachineDescriptionRuntime; +import jogamp.common.os.MachineDataInfoRuntime; import org.junit.Assert; @@ -50,7 +50,7 @@ * @author Michael Bien * @author Sven Gothel */ -public class BaseClass extends JunitTracer { +public class BaseClass extends SingletonJunitCase { /** * Verifies the existence and creation of the generated class. @@ -65,21 +65,25 @@ Assert.assertNotNull(ifName+" does not exist", clazzIf); Assert.assertNotNull(implName+" does not exist", clazzImpl); - Assert.assertEquals(1, clazzIf.getDeclaredField("CONSTANT_ONE").get(null)); + Assert.assertNotNull(clazzImpl.getDeclaredMethod("nopTest")); final Object obj = clazzImpl.newInstance(); Assert.assertTrue("Not of type "+ifName, clazzIf.isAssignableFrom(obj.getClass())); - Assert.assertTrue("Not of type com.jogamp.gluegen.test.junit.generation.Bindingtest1", (obj instanceof com.jogamp.gluegen.test.junit.generation.Bindingtest1)); + Assert.assertTrue("Not of type com.jogamp.gluegen.test.junit.generation.Bindingtest1", + (obj instanceof com.jogamp.gluegen.test.junit.generation.Bindingtest1)); } + public static final float EPSILON = 1.1920929E-7f; // Float.MIN_VALUE == 1.4e-45f ; double EPSILON 2.220446049250313E-16d + /** * Verifies if all generated method signatures are completed, * ie a compilation only coverage test without functional tests. */ public void chapter__TestCoverageSignature(final Bindingtest1 binding) throws Exception { - int i; + int i = 0; final long context = 0; LongBuffer lb=null; + ByteBuffer bb=null; final IntBuffer ib=null; final long[] larray = null; final int larray_offset = 0; @@ -89,10 +93,42 @@ final int iarray_offset = 0; long result = 0; long l = result; + ShortBlob sb = null; + Int32Struct i32s = null; + AnonBlob ab = null; + PointerBuffer pb=null; { - final ByteBuffer bb = binding.createAPtrBlob(); - PointerBuffer pb = safeByteBuffer2PointerBuffer(bb, 1); + l = binding.testXID(l); + l = binding.testXID_2(l); + + bb = binding.testAnonBuffer(bb); + + sb = binding.testShortBlob(sb); + sb = binding.testLPShortBlob0(sb); + sb = binding.testLPShortBlob1(sb); + sb = binding.testLPShortBlob2(sb); + sb = binding.testLPShortBlob3(sb); + sb = binding.testShortBlobL1(sb); + sb = binding.testShortBlobL2(sb); + + i32s = binding.testInt32Struct(i32s); + + ab = binding.testCreateAnonBlob(); + binding.testDestroyAnonBlob(ab); + + l = binding.testCreateAnonBlob2(); + binding.testDestroyAnonBlob2(l); + + lb = binding.testFooPtr(larray, 0); + lb = binding.testFooPtr(lb); + + i = binding.testDelegate(i); + } + + { + bb = binding.createAPtrBlob(); + pb = safeByteBuffer2PointerBuffer(bb, 1); long bb2A = binding.getAPtrAddress(bb); bb2A = bb2A - 0; // avoid warning @@ -119,9 +155,6 @@ binding.releaseAPtrBlob(bb); } - final ByteBuffer bb=null; - PointerBuffer pb=null; - result = binding.arrayTestInt32(context, ib); result = binding.arrayTestInt32(context, iarray, iarray_offset); @@ -177,6 +210,185 @@ l = binding.typeTestUIntPtrT(l, l); } + /** + * Verifies if all generated static constant values are completed, + * and whether their value is as expected! + *

    + * Covers all enumerates and defines. + *

    + */ + public void chapter01TestStaticConstants(final Bindingtest1 binding) throws Exception { + // Plain vanilla CPP constants + Assert.assertEquals( 1, Bindingtest1.CONSTANT_ONE); + Assert.assertEquals( 8, Bindingtest1.ARRAY_SIZE); + Assert.assertEquals(1234, Bindingtest1.DEFINE_01); + + // Enums + Assert.assertEquals( 1, Bindingtest1.LI); + Assert.assertEquals( 3, Bindingtest1.LO); + Assert.assertEquals( 2, Bindingtest1.LU); + Assert.assertEquals( 1, Bindingtest1.MI); + Assert.assertEquals( 3, Bindingtest1.MO); + Assert.assertEquals( 2, Bindingtest1.MU); + Assert.assertEquals( 0, Bindingtest1.ZERO); + Assert.assertEquals( 1, Bindingtest1.ONE); + Assert.assertEquals( 2, Bindingtest1.TWO); + Assert.assertEquals( 3, Bindingtest1.THREE); + + // CPP Macro Expansion! + Assert.assertEquals( 1, Bindingtest1.NUMBER_ONE); + Assert.assertEquals( 2, Bindingtest1.NUMBER_TWO); + Assert.assertEquals( 4, Bindingtest1.NUMBER_FOUR); + Assert.assertEquals( 5, Bindingtest1.NUMBER_FIVE); + Assert.assertEquals( 8, Bindingtest1.NUMBER_EIGHT); + Assert.assertEquals( 9, Bindingtest1.NUMBER_NINE); + Assert.assertEquals( 10, Bindingtest1.NUMBER_TEN); + + // Enum Constant Expressions! + Assert.assertEquals( 1, Bindingtest1.ENUM_NUM_ONE); + Assert.assertEquals( 2, Bindingtest1.ENUM_NUM_TWO); + Assert.assertEquals( 3, Bindingtest1.ENUM_NUM_THREE); + Assert.assertEquals( 4, Bindingtest1.ENUM_NUM_FOUR); + Assert.assertEquals( 5, Bindingtest1.ENUM_NUM_FIVE); + Assert.assertEquals( 8, Bindingtest1.ENUM_NUM_EIGHT); + Assert.assertEquals( 9, Bindingtest1.ENUM_NUM_NINE); + Assert.assertEquals( 10, Bindingtest1.ENUM_NUM_TEN); + + // Integer 32bit (int / enum) + final int ENUM_I0 = Bindingtest1.ENUM_I0; + final int ENUM_I1 = Bindingtest1.ENUM_I1; + final int ENUM_I2 = Bindingtest1.ENUM_I2; + final int ENUM_I3 = Bindingtest1.ENUM_I3; + final int ENUM_I4 = -Bindingtest1.ENUM_I4; + final int ENUM_I5 = -Bindingtest1.ENUM_I5; + final int ENUM_I6 = -Bindingtest1.ENUM_I6; + final int ENUM_I7 = Bindingtest1.ENUM_I7; + final int ENUM_I8 = Bindingtest1.ENUM_I8; + final int ENUM_I9 = Bindingtest1.ENUM_I9; + final int ENUM_IA = Bindingtest1.ENUM_IA; + final int ENUM_IB = Bindingtest1.ENUM_IB; + final int ENUM_IX = Bindingtest1.ENUM_IX; + int iexp = 10; + Assert.assertEquals(iexp++, ENUM_I0); + Assert.assertEquals(iexp++, ENUM_I1); + Assert.assertEquals(iexp++, ENUM_I2); + Assert.assertEquals(iexp++, ENUM_I3); + Assert.assertEquals(iexp++, ENUM_I4); + Assert.assertEquals(iexp++, ENUM_I5); + Assert.assertEquals(iexp++, ENUM_I6); + Assert.assertEquals(iexp++, ENUM_I7); + Assert.assertEquals(iexp++, ENUM_I8); + Assert.assertEquals(iexp++, ENUM_I9); + Assert.assertEquals(iexp++, ENUM_IA); + Assert.assertEquals(iexp++, ENUM_IB); + Assert.assertEquals(0xffffffff, ENUM_IX); + + // Integer 32bit (int / define) + final int CL_INT_I0 = Bindingtest1.CL_INT_I0; + final int CL_INT_I1 = Bindingtest1.CL_INT_I1; + final int CL_INT_I2 = Bindingtest1.CL_INT_I2; + final int CL_INT_I3 = Bindingtest1.CL_INT_I3; + final int CL_INT_I4 = -Bindingtest1.CL_INT_I4; + final int CL_INT_I5 = -Bindingtest1.CL_INT_I5; + final int CL_INT_I6 = -Bindingtest1.CL_INT_I6; + final int CL_INT_I7 = -Bindingtest1.CL_INT_I7; + final int CL_INT_I8 = Bindingtest1.CL_INT_I8; + final int CL_INT_I9 = Bindingtest1.CL_INT_I9; + final int CL_INT_IA = Bindingtest1.CL_INT_IA; + final int CL_INT_IB = Bindingtest1.CL_INT_IB; + final int CL_INT_IX = Bindingtest1.CL_INT_IX; + iexp = 10; + Assert.assertEquals(iexp++, CL_INT_I0); + Assert.assertEquals(iexp++, CL_INT_I1); + Assert.assertEquals(iexp++, CL_INT_I2); + Assert.assertEquals(iexp++, CL_INT_I3); + Assert.assertEquals(iexp++, CL_INT_I4); + Assert.assertEquals(iexp++, CL_INT_I5); + Assert.assertEquals(iexp++, CL_INT_I6); + Assert.assertEquals(iexp++, CL_INT_I7); + Assert.assertEquals(iexp++, CL_INT_I8); + Assert.assertEquals(iexp++, CL_INT_I9); + Assert.assertEquals(iexp++, CL_INT_IA); + Assert.assertEquals(iexp++, CL_INT_IB); + Assert.assertEquals(0xffffffff, CL_INT_IX); + + // Integer 64bit (long / define ) + final long CL_LNG_L0 = Bindingtest1.CL_LNG_L0; + final long CL_LNG_L1 = Bindingtest1.CL_LNG_L1; + final long CL_LNG_L2 = Bindingtest1.CL_LNG_L2; + final long CL_LNG_L3 = Bindingtest1.CL_LNG_L3; + final long CL_LNG_L4 = -Bindingtest1.CL_LNG_L4; + final long CL_LNG_L5 = -Bindingtest1.CL_LNG_L5; + final long CL_LNG_L6 = -Bindingtest1.CL_LNG_L6; + final long CL_LNG_L7 = -Bindingtest1.CL_LNG_L7; + final long CL_LNG_L8 = Bindingtest1.CL_LNG_L8; + final long CL_LNG_L9 = Bindingtest1.CL_LNG_L9; + final long CL_LNG_LA = Bindingtest1.CL_LNG_LA; + final long CL_LNG_LB = Bindingtest1.CL_LNG_LB; + final long CL_LNG_LX = Bindingtest1.CL_LNG_LX; + long lexp = 2147483648L; + Assert.assertEquals(lexp++, CL_LNG_L0); + Assert.assertEquals(lexp++, CL_LNG_L1); + Assert.assertEquals(lexp++, CL_LNG_L2); + Assert.assertEquals(lexp++, CL_LNG_L3); + Assert.assertEquals(lexp++, CL_LNG_L4); + Assert.assertEquals(lexp++, CL_LNG_L5); + Assert.assertEquals(lexp++, CL_LNG_L6); + Assert.assertEquals(lexp++, CL_LNG_L7); + Assert.assertEquals(lexp++, CL_LNG_L8); + Assert.assertEquals(lexp++, CL_LNG_L9); + Assert.assertEquals(lexp++, CL_LNG_LA); + Assert.assertEquals(lexp++, CL_LNG_LB); + Assert.assertEquals(0xffffffffffffffffL, CL_LNG_LX); + + // Floating point hexadecimals + final float CL_FLT_A0 = Bindingtest1.CL_FLT_A0; + final float CL_FLT_A1 = Bindingtest1.CL_FLT_A1; + final float CL_FLT_A2 = Bindingtest1.CL_FLT_A2; + final float CL_FLT_A3 = Bindingtest1.CL_FLT_A3; + final float CL_FLT_A4 = Bindingtest1.CL_FLT_A4; + final float CL_FLT_A5 = Bindingtest1.CL_FLT_A5; + final float CL_FLT_A6 = Bindingtest1.CL_FLT_A6; + final float CL_FLT_A7 = Bindingtest1.CL_FLT_A7; + Assert.assertEquals( 0x1.p127f, CL_FLT_A0, EPSILON); + Assert.assertEquals( 0x1.p+127F, CL_FLT_A1, EPSILON); + Assert.assertEquals( 0x1.p-127f, CL_FLT_A2, EPSILON); + Assert.assertEquals( -0.1f, CL_FLT_A3, EPSILON); + Assert.assertEquals( 0.2f, CL_FLT_A4, EPSILON); + Assert.assertEquals( 0.3f, CL_FLT_A5, EPSILON); + Assert.assertEquals( 0.4f, CL_FLT_A6, EPSILON); + Assert.assertEquals( 1.0f, CL_FLT_A7, EPSILON); + + final float CL_FLT_EPSILON = Bindingtest1.CL_FLT_EPSILON; + final double CL_FLT_MAX= Bindingtest1.CL_FLT_MAX; + final double CL_FLT_MIN = Bindingtest1.CL_FLT_MIN; + Assert.assertEquals( 0x1.0p-23f, CL_FLT_EPSILON, EPSILON); + Assert.assertEquals( 0x1.fffffep127f, CL_FLT_MAX, EPSILON); + Assert.assertEquals( 0x1.0p-126f, CL_FLT_MIN, EPSILON); + + final double CL_DBL_B0 = Bindingtest1.CL_DBL_B0; + final double CL_DBL_B1 = Bindingtest1.CL_DBL_B1; + final double CL_DBL_B2 = Bindingtest1.CL_DBL_B2; + final double CL_DBL_B3 = Bindingtest1.CL_DBL_B3; + final double CL_DBL_B4 = Bindingtest1.CL_DBL_B4; + final double CL_DBL_B5 = Bindingtest1.CL_DBL_B5; + final double CL_DBL_B6 = Bindingtest1.CL_DBL_B6; + Assert.assertEquals( 0x1.p127d, CL_DBL_B0, EPSILON); + Assert.assertEquals( 0x1.p+127D, CL_DBL_B1, EPSILON); + Assert.assertEquals( 0x1.p-127d, CL_DBL_B2, EPSILON); + Assert.assertEquals( -0.1, CL_DBL_B3, EPSILON); + Assert.assertEquals( 0.2, CL_DBL_B4, EPSILON); + Assert.assertEquals( 0.3, CL_DBL_B5, EPSILON); + Assert.assertEquals( 3.5e+38, CL_DBL_B6, EPSILON); + + final float CL_DBL_EPSILON = Bindingtest1.CL_DBL_EPSILON; + final double CL_DBL_MAX= Bindingtest1.CL_DBL_MAX; + final double CL_DBL_MIN = Bindingtest1.CL_DBL_MIN; + Assert.assertEquals( 0x1.0p-52f, CL_DBL_EPSILON, EPSILON); + Assert.assertEquals( 0x1.fffffffffffffp1023, CL_DBL_MAX, EPSILON); + Assert.assertEquals( 0x1.0p-1022, CL_DBL_MIN, EPSILON); + } + ByteBuffer newByteBuffer(final int size, final boolean direct) { if(direct) { final ByteBuffer bb = Buffers.newDirectByteBuffer(size); @@ -629,6 +841,66 @@ Assert.assertTrue("Wrong result: 0x"+Long.toHexString(pb.get(i))+"+1 != 0x"+Long.toHexString(pb2.get(i)), (pb.get(i)+1)==pb2.get(i)); } } + + { + final long l0 = 0xAAFFEE; + final long l1 = binding.testXID(l0); + final long l2 = binding.testXID_2(l0); + Assert.assertEquals(l0, l1); + Assert.assertEquals(l0, l2); + + final ByteBuffer bb = Buffers.newDirectByteBuffer(PointerBuffer.ELEMENT_SIZE); + for(int j=0; j4*4 */ { - Assert.assertEquals(4*4, model.getMat4x4ArrayLength()); + Assert.assertEquals(4*4, TK_ModelConst.getMat4x4ArrayLength()); final FloatBuffer mat4x4 = model.getMat4x4(); Assert.assertEquals(4*4, mat4x4.limit()); for(int i=0; i<4; i++) { @@ -1185,7 +1455,7 @@ // field: structArrayFixedLen // field: CType['TK_Dimension *', size [fixed false, lnx64 48], [array*1]], with array length of 3 { - final int size = model.getStructArrayFixedLenArrayLength(); + final int size = TK_ModelConst.getStructArrayFixedLenArrayLength(); final TK_Dimension[] all = model.getStructArrayFixedLen(0, new TK_Dimension[size]); for(int i=0; i public typedef checks +typedef TK_Surface * (MYAPIENTRY* PFNCREATESURFACEPROC)(); +typedef void (MYAPIENTRY* PFNDESTROYSURFACEPROC)(TK_Surface * surface); + MYAPI TK_Surface * MYAPIENTRY createSurface(); MYAPI void MYAPIENTRY destroySurface(TK_Surface * surface); - MYAPI TK_ComplicatedSuperSet * MYAPIENTRY createComplicatedSuperSet(); MYAPI Bool MYAPIENTRY hasInitValues(TK_ComplicatedSuperSet * s); MYAPI void MYAPIENTRY destroyComplicatedSuperSet(TK_ComplicatedSuperSet * s); @@ -266,6 +423,13 @@ MYAPI TK_Dimension MYAPIENTRY addDimensionPair(const TK_DimensionPair s); MYAPI void MYAPIENTRY zeroDimensions(TK_Dimension s[2]); + +// some implicity _local_ typedef -> public typedef checks +typedef void (MYAPIENTRY* PFNCOPYPRIMTODIMENSIONSPROC)(const int pos[2], const int size[2], TK_Dimension dest[1]); +typedef int (MYAPIENTRY* PFNRGBATOINTPROC)(const char rgba[4]); +typedef void (MYAPIENTRY* PFNINTTORGBAPROC)(int irgba, char rgbaSink[4]); +typedef void (MYAPIENTRY* PFNADDBYTEPROC)(const char summands[2], char result[1]); + MYAPI void MYAPIENTRY copyPrimToDimensions(const int pos[2], const int size[2], TK_Dimension dest[1]); MYAPI void MYAPIENTRY copyDimensionsToPrim(TK_Dimension dim, int dpos[2], int dsize[2]); MYAPI int MYAPIENTRY rgbaToInt(const char rgba[4]); @@ -296,7 +460,7 @@ const int32_t structPointerCustomLenVal; const TK_Dimension * structPointerOneElem; - const TK_Context ctx; + TK_Context ctx; const char modelNameArrayFixedLen[12]; /* 'Hello Array' len=11+1 */ const char * modelNamePointerCString; /* 'Hello CString' len=13+1 */ diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/generation/test1p1-gluegen.cfg gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/generation/test1p1-gluegen.cfg --- gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/generation/test1p1-gluegen.cfg 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/generation/test1p1-gluegen.cfg 2015-10-09 04:18:28.000000000 +0000 @@ -6,6 +6,8 @@ Extends Bindingtest1p1 Bindingtest1 +ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/com/jogamp/gluegen/test/junit/generation/Bindingtest1.java + Include test1-common.cfg Import com.jogamp.gluegen.test.junit.generation.Bindingtest1 diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java --- gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java 2015-10-09 04:18:28.000000000 +0000 @@ -50,7 +50,7 @@ * Verifies loading of the new library. */ @BeforeClass - public static void chapter01TestLoadLibrary() throws Exception { + public static void chapter__TestLoadLibrary() throws Exception { BindingJNILibLoader.loadBindingtest1p1(); } @@ -58,7 +58,7 @@ * Verifies the existence and creation of the generated class. */ @Test - public void chapter02TestClassExist() throws Exception { + public void chapter00TestClassExist() throws Exception { testClassExist("test1p1"); } @@ -71,6 +71,18 @@ } /** + * Verifies if all generated static constant values are completed, + * and whether their value is as expected! + *

    + * Covers all enumerates and defines. + *

    + */ + @Test + public void chapter01TestStaticConstants() throws Exception { + chapter01TestStaticConstants(new Bindingtest1p1Impl()); + } + + /** * Verifies if all methods / signatures are properly generated, * can be invoked and functions. * This is a compilation (coverage) and runtime time (semantic) test. diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/generation/test1p2-gluegen.cfg gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/generation/test1p2-gluegen.cfg --- gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/generation/test1p2-gluegen.cfg 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/generation/test1p2-gluegen.cfg 2015-10-09 04:18:28.000000000 +0000 @@ -6,6 +6,8 @@ Extends Bindingtest1p2 Bindingtest1 +ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/com/jogamp/gluegen/test/junit/generation/Bindingtest1.java + # Use a ProcAddressTable so we dynamically look up the routines EmitProcAddressTable true ProcAddressTableClassName Bindingtest1p2ProcAddressTable diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2LoadJNIAndImplLib.java gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2LoadJNIAndImplLib.java --- gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2LoadJNIAndImplLib.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2LoadJNIAndImplLib.java 2015-10-09 04:18:28.000000000 +0000 @@ -46,7 +46,7 @@ * Verifies loading of the new library. */ @BeforeClass - public static void chapter01TestLoadLibrary() throws Exception { + public static void chapter__TestLoadLibrary() throws Exception { BindingJNILibLoader.loadBindingtest1p2(); dynamicLookupHelper = NativeLibrary.open("test1", Test1p2LoadJNIAndImplLib.class.getClassLoader(), true); Assert.assertNotNull("NativeLibrary.open(test1) failed", dynamicLookupHelper); @@ -58,17 +58,16 @@ * Verifies the existence and creation of the generated class. */ @Test - public void chapter02TestClassExist() throws Exception { + public void chapter00TestClassExist() throws Exception { testClassExist("test1p2"); } - @SuppressWarnings("unused") public static void main(final String args[]) throws Exception { if( true ) { - chapter01TestLoadLibrary(); + chapter__TestLoadLibrary(); final Test1p2LoadJNIAndImplLib tst = new Test1p2LoadJNIAndImplLib(); - tst.chapter02TestClassExist(); + tst.chapter00TestClassExist(); } else { final String tstname = Test1p2LoadJNIAndImplLib.class.getName(); org.junit.runner.JUnitCore.main(tstname); diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java --- gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java 2015-10-09 04:18:28.000000000 +0000 @@ -30,6 +30,7 @@ import java.io.IOException; +import com.jogamp.gluegen.test.junit.generation.impl.Bindingtest1p1Impl; import com.jogamp.gluegen.test.junit.generation.impl.Bindingtest1p2Impl; import com.jogamp.common.os.NativeLibrary; @@ -54,7 +55,7 @@ * Verifies loading of the new library. */ @BeforeClass - public static void chapter01TestLoadLibrary() throws Exception { + public static void chapter__TestLoadLibrary() throws Exception { BindingJNILibLoader.loadBindingtest1p2(); dynamicLookupHelper = NativeLibrary.open("test1", Test1p2ProcAddressEmitter.class.getClassLoader(), true); Assert.assertNotNull("NativeLibrary.open(test1) failed", dynamicLookupHelper); @@ -66,7 +67,7 @@ * Verifies the existence and creation of the generated class. */ @Test - public void chapter02TestClassExist() throws Exception { + public void chapter00TestClassExist() throws Exception { testClassExist("test1p2"); } @@ -79,6 +80,18 @@ } /** + * Verifies if all generated static constant values are completed, + * and whether their value is as expected! + *

    + * Covers all enumerates and defines. + *

    + */ + @Test + public void chapter01TestStaticConstants() throws Exception { + chapter01TestStaticConstants(new Bindingtest1p2Impl()); + } + + /** * Verifies if all methods / signatures are properly generated, * can be invoked and functions. * This is a compilation (coverage) and runtime time (semantic) test. diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/internals/TestType.java gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/internals/TestType.java --- gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/internals/TestType.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/internals/TestType.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,85 @@ +/** + * Copyright 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.gluegen.test.junit.internals; + +import org.junit.Assert; +import org.junit.Test; + +import com.jogamp.gluegen.cgram.types.FloatType; +import com.jogamp.gluegen.cgram.types.IntType; +import com.jogamp.junit.util.SingletonJunitCase; + +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestType extends SingletonJunitCase { + + @Test + public void test01Equals() { + final FloatType f1 = new FloatType("GLfloat", null, 0, null); + final FloatType f2 = new FloatType("float", null, 0, null); + final IntType i1 = new IntType("GLint", null, false, 0, null); + final IntType i2 = new IntType("int", null, false, 0, null); + final int f1H = f1.hashCode(); + final int f2H = f2.hashCode(); + final int i1H = i1.hashCode(); + final int i2H = i2.hashCode(); + + final int f1HS = f1.hashCodeSemantics(); + final int f2HS = f2.hashCodeSemantics(); + final int i1HS = i1.hashCodeSemantics(); + final int i2HS = i2.hashCodeSemantics(); + + Assert.assertFalse(f1.getClass().isInstance(null)); + Assert.assertTrue(f1.getClass().isInstance(f2)); + Assert.assertTrue(i1.getClass().isInstance(i2)); + Assert.assertFalse(f1.getClass().isInstance(i2)); + + Assert.assertFalse(f1.equals(f2)); + Assert.assertFalse(i1.equals(i2)); + Assert.assertFalse(f1.equals(i2)); + Assert.assertNotEquals(f1H, f2H); + Assert.assertNotEquals(i1H, i2H); + Assert.assertNotEquals(f1H, i2H); + + Assert.assertTrue(f1.equalSemantics(f2)); + Assert.assertTrue(i1.equalSemantics(i2)); + Assert.assertFalse(f1.equalSemantics(i2)); + Assert.assertEquals(f1HS, f2HS); + Assert.assertEquals(i1HS, i2HS); + Assert.assertNotEquals(f1HS, i2HS); + } + + public static void main(final String args[]) { + final String tstname = TestType.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } + +} diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen01.java gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen01.java --- gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen01.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen01.java 2015-10-09 04:18:28.000000000 +0000 @@ -1,6 +1,6 @@ package com.jogamp.gluegen.test.junit.structgen; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import org.junit.Assert; import org.junit.BeforeClass; @@ -9,7 +9,7 @@ import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestStructGen01 extends JunitTracer { +public class TestStructGen01 extends SingletonJunitCase { @BeforeClass public static void init() { diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen02.java gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen02.java --- gluegen2-2.2.4/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen02.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen02.java 2015-10-09 04:18:28.000000000 +0000 @@ -1,6 +1,6 @@ package com.jogamp.gluegen.test.junit.structgen; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import org.junit.Assert; import org.junit.BeforeClass; @@ -9,7 +9,7 @@ import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestStructGen02 extends JunitTracer { +public class TestStructGen02 extends SingletonJunitCase { @BeforeClass public static void init() { diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/junit/sec/Applet01.java gluegen2-2.3.2/src/junit/com/jogamp/junit/sec/Applet01.java --- gluegen2-2.2.4/src/junit/com/jogamp/junit/sec/Applet01.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/junit/sec/Applet01.java 2015-10-09 04:18:28.000000000 +0000 @@ -34,14 +34,13 @@ import java.io.IOException; import java.io.OutputStream; import java.net.URISyntaxException; -import java.net.URL; import java.security.AccessControlException; -import com.jogamp.common.os.MachineDescription; +import com.jogamp.common.net.Uri; +import com.jogamp.common.os.MachineDataInfo; import com.jogamp.common.os.NativeLibrary; import com.jogamp.common.os.Platform; import com.jogamp.common.util.IOUtil; -import com.jogamp.common.util.JarUtil; /** * Applet: Provoke AccessControlException while writing to file! @@ -53,7 +52,7 @@ static final String os_name_propkey = "os.name"; static final String tfilename = "test.bin" ; - static final MachineDescription machine = Platform.getMachineDescription(); + static final MachineDataInfo machine = Platform.getMachineDataInfo(); static final int tsz = machine.pageSizeInBytes(); static final boolean usesSecurityManager; @@ -112,6 +111,17 @@ System.err.println("Unexpected exception for secure temp dir"); se0.printStackTrace(); } + } catch (final SecurityException e) { + se0 = e; + if( !isSecure ) { + System.err.println("Expected exception for insecure temp dir (2)"); + System.err.println("Message: "+se0.getMessage()); + } else { + System.err.println("Unexpected exception for secure temp dir (2)"); + se0.printStackTrace(); + } + } catch (final IOException e) { + throw new RuntimeException(e); // oops } if( isSecure ) { if( null != se0 ) { @@ -156,64 +166,64 @@ } } - private void testOpenLibrary(final boolean global) { + private void testOpenLibrary(final boolean global) throws URISyntaxException { final ClassLoader cl = getClass().getClassLoader(); System.err.println("CL "+cl); String libBaseName = null; final Class clazz = this.getClass(); - URL libURL = clazz.getResource("/libtest1.so"); - if( null != libURL ) { + Uri libUri = null; + try { + libUri = Uri.valueOf(clazz.getResource("/libtest1.so")); + } catch (final URISyntaxException e2) { + // not found .. OK + } + if( null != libUri ) { libBaseName = "libtest1.so"; } else { - libURL = clazz.getResource("/test1.dll"); - if( null != libURL ) { - libBaseName = "test1.dll"; + try { + libUri = Uri.valueOf(clazz.getResource("/test1.dll")); + if( null != libUri ) { + libBaseName = "test1.dll"; + } + } catch (final URISyntaxException e) { + // not found } } - System.err.println("Untrusted Library (URL): "+libURL); + System.err.println("Untrusted Library (URL): "+libUri); - String libDir1 = null; - if( null != libURL ) { + if( null != libUri ) { + Uri libDir1 = libUri.getContainedUri(); + System.err.println("libDir1.1: "+libDir1); + libDir1= libDir1.getParent(); + System.err.println("libDir1.2: "+libDir1); + System.err.println("Untrusted Library Dir1 (abs): "+libDir1); + final Uri absLib = libDir1.concat(Uri.Encoded.cast("natives/" + libBaseName)); + Exception sec01 = null; try { - libDir1 = JarUtil.getJarSubURI(libURL.toURI()).getPath(); - } catch (final Exception e) { - e.printStackTrace(); - } - if( null != libDir1 ) { - System.err.println("libDir1.1: "+libDir1); - try { - libDir1= IOUtil.getParentOf(libDir1); - } catch (final URISyntaxException e) { - e.printStackTrace(); + final NativeLibrary nlib = NativeLibrary.open(absLib.toFile().getPath(), cl); + System.err.println("NativeLibrary: "+nlib); + } catch (final SecurityException e) { + sec01 = e; + if( usesSecurityManager ) { + System.err.println("Expected exception for loading native library"); + System.err.println("Message: "+sec01.getMessage()); + } else { + System.err.println("Unexpected exception for loading native library"); + sec01.printStackTrace(); } - System.err.println("libDir1.2: "+libDir1); } - } - System.err.println("Untrusted Library Dir1 (abs): "+libDir1); - final String absLib = libDir1 + "natives/" + libBaseName; - Exception sec01 = null; - try { - final NativeLibrary nlib = NativeLibrary.open(absLib, cl); - System.err.println("NativeLibrary: "+nlib); - } catch (final SecurityException e) { - sec01 = e; - if( usesSecurityManager ) { - System.err.println("Expected exception for loading native library"); - System.err.println("Message: "+sec01.getMessage()); + if( !usesSecurityManager ) { + if( null != sec01 ) { + throw new Error("SecurityException thrown on loading native library", sec01); + } } else { - System.err.println("Unexpected exception for loading native library"); - sec01.printStackTrace(); - } - } - if( !usesSecurityManager ) { - if( null != sec01 ) { - throw new Error("SecurityException thrown on loading native library", sec01); + if( null == sec01 ) { + throw new Error("SecurityException not thrown on loading native library"); + } } } else { - if( null == sec01 ) { - throw new Error("SecurityException not thrown on loading native library"); - } + System.err.println("No library found"); } } @@ -244,7 +254,11 @@ testWriteFile(); System.err.println("writeFile: OK"); - testOpenLibrary(true); + try { + testOpenLibrary(true); + } catch (final URISyntaxException e) { + e.printStackTrace(); + } System.err.println("lib0: OK"); } diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/junit/sec/TestSecIOUtil01.java gluegen2-2.3.2/src/junit/com/jogamp/junit/sec/TestSecIOUtil01.java --- gluegen2-2.2.4/src/junit/com/jogamp/junit/sec/TestSecIOUtil01.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/junit/sec/TestSecIOUtil01.java 2015-10-09 04:18:28.000000000 +0000 @@ -29,7 +29,6 @@ package com.jogamp.junit.sec; import java.net.URISyntaxException; -import java.net.URL; import java.security.AccessControlException; import java.io.File; import java.io.IOException; @@ -38,17 +37,17 @@ import org.junit.BeforeClass; import org.junit.Test; +import com.jogamp.common.net.Uri; import com.jogamp.common.os.NativeLibrary; import com.jogamp.common.os.Platform; import com.jogamp.common.util.IOUtil; -import com.jogamp.common.util.JarUtil; -import com.jogamp.junit.util.JunitTracer; +import com.jogamp.junit.util.SingletonJunitCase; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestSecIOUtil01 extends JunitTracer { +public class TestSecIOUtil01 extends SingletonJunitCase { static final String java_io_tmpdir_propkey = "java.io.tmpdir"; static final String java_home_propkey = "java.home"; static final String os_name_propkey = "os.name"; @@ -124,6 +123,17 @@ System.err.println("Unexpected exception for secure temp dir"); se0.printStackTrace(); } + } catch (final SecurityException e) { + se0 = e; + if( !isSecure ) { + System.err.println("Expected exception for insecure temp dir (2)"); + System.err.println("Message: "+se0.getMessage()); + } else { + System.err.println("Unexpected exception for secure temp dir (2)"); + se0.printStackTrace(); + } + } catch (final IOException e) { + throw new RuntimeException(e); // oops } if( isSecure ) { Assert.assertNull("AccessControlException thrown on secure temp dir", se0); @@ -137,73 +147,75 @@ testTempDirImpl(false); } - private NativeLibrary openLibraryImpl(final boolean global) { + private NativeLibrary openLibraryImpl(final boolean global) throws URISyntaxException { final ClassLoader cl = getClass().getClassLoader(); System.err.println("CL "+cl); String libBaseName = null; final Class clazz = this.getClass(); - URL libURL = clazz.getResource("/libtest1.so"); - if( null != libURL ) { + Uri libUri = null; + try { + libUri = Uri.valueOf(clazz.getResource("/libtest1.so")); + } catch (final URISyntaxException e2) { + // not found .. OK + } + if( null != libUri ) { libBaseName = "libtest1.so"; } else { - libURL = clazz.getResource("/test1.dll"); - if( null != libURL ) { - libBaseName = "test1.dll"; + try { + libUri = Uri.valueOf(clazz.getResource("/test1.dll")); + if( null != libUri ) { + libBaseName = "test1.dll"; + } + } catch (final URISyntaxException e) { + // not found } } - System.err.println("Untrusted Library (URL): "+libURL); + System.err.println("Untrusted Library (URL): "+libUri); - String libDir1 = null; - if( null != libURL ) { + if( null != libUri ) { + Uri libDir1 = libUri.getContainedUri(); + System.err.println("libDir1.1: "+libDir1); + libDir1= libDir1.getParent(); + System.err.println("libDir1.2: "+libDir1); + System.err.println("Untrusted Library Dir1 (abs): "+libDir1); + final Uri absLib = libDir1.concat(Uri.Encoded.cast("natives/" + libBaseName)); + Exception se0 = null; + NativeLibrary nlib = null; try { - libDir1 = JarUtil.getJarSubURI(libURL.toURI()).getPath(); - } catch (final Exception e) { - e.printStackTrace(); - } - if( null != libDir1 ) { - System.err.println("libDir1.1: "+libDir1); - try { - libDir1= IOUtil.getParentOf(libDir1); - } catch (final URISyntaxException e) { - e.printStackTrace(); + nlib = NativeLibrary.open(absLib.toFile().getPath(), cl); + System.err.println("NativeLibrary: "+nlib); + } catch (final SecurityException e) { + se0 = e; + if( usesSecurityManager ) { + System.err.println("Expected exception for loading native library"); + System.err.println("Message: "+se0.getMessage()); + } else { + System.err.println("Unexpected exception for loading native library"); + se0.printStackTrace(); } - System.err.println("libDir1.2: "+libDir1); } - } - System.err.println("Untrusted Library Dir1 (abs): "+libDir1); - final String absLib = libDir1 + "natives/" + libBaseName; - Exception se0 = null; - NativeLibrary nlib = null; - try { - nlib = NativeLibrary.open(absLib, cl); - System.err.println("NativeLibrary: "+nlib); - } catch (final SecurityException e) { - se0 = e; - if( usesSecurityManager ) { - System.err.println("Expected exception for loading native library"); - System.err.println("Message: "+se0.getMessage()); + if( !usesSecurityManager ) { + Assert.assertNull("SecurityException thrown on loading native library", se0); } else { - System.err.println("Unexpected exception for loading native library"); - se0.printStackTrace(); + Assert.assertNotNull("SecurityException not thrown on loading native library", se0); } - } - if( !usesSecurityManager ) { - Assert.assertNull("SecurityException thrown on loading native library", se0); + return nlib; } else { - Assert.assertNotNull("SecurityException not thrown on loading native library", se0); + System.err.println("No library found"); + return null; } - return nlib; + } - public void testOpenLibrary() { + public void testOpenLibrary() throws URISyntaxException { final NativeLibrary nlib = openLibraryImpl(true); if( null != nlib ) { nlib.close(); } } - public static void main(final String args[]) throws IOException { + public static void main(final String args[]) throws IOException, URISyntaxException { TestSecIOUtil01.setup(); final TestSecIOUtil01 aa = new TestSecIOUtil01(); diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/junit/util/JunitTracer.java gluegen2-2.3.2/src/junit/com/jogamp/junit/util/JunitTracer.java --- gluegen2-2.2.4/src/junit/com/jogamp/junit/util/JunitTracer.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/junit/util/JunitTracer.java 2015-10-09 04:18:28.000000000 +0000 @@ -28,6 +28,10 @@ package com.jogamp.junit.util; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; @@ -41,11 +45,15 @@ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public abstract class JunitTracer { - @Rule public TestName _unitTestName = new TestName(); + @Rule public final TestName _unitTestName = new TestName(); static volatile boolean testSupported = true; - public static void setTestSupported(final boolean v) { + public static final boolean isTestSupported() { + return testSupported; + } + + public static final void setTestSupported(final boolean v) { System.err.println("setTestSupported: "+v); testSupported = v; } @@ -63,18 +71,18 @@ } @BeforeClass - public static void oneTimeSetUp() { + public static final void oneTimeSetUpBase() { // one-time initialization code } @AfterClass - public static void oneTimeTearDown() { + public static final void oneTimeTearDownBase() { // one-time cleanup code System.gc(); // force cleanup } @Before - public void setUp() { + public final void setUpBase() { System.err.print("++++ TestCase.setUp: "+getFullTestName(" - ")); if(!testSupported) { System.err.println(" - "+unsupportedTestMsg); @@ -84,10 +92,18 @@ } @After - public void tearDown() { + public final void tearDownBase() { System.err.println("++++ TestCase.tearDown: "+getFullTestName(" - ")); } static final String unsupportedTestMsg = "Test not supported on this platform."; + + public static final void waitForKey(final String preMessage) { + final BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); + System.err.println(preMessage+"> Press enter to continue"); + try { + System.err.println(stdin.readLine()); + } catch (final IOException e) { e.printStackTrace(); } + } } diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/junit/util/SingletonJunitCase.java gluegen2-2.3.2/src/junit/com/jogamp/junit/util/SingletonJunitCase.java --- gluegen2-2.2.4/src/junit/com/jogamp/junit/util/SingletonJunitCase.java 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/junit/util/SingletonJunitCase.java 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,91 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.junit.util; + +import com.jogamp.common.util.locks.SingletonInstance; + +import org.junit.BeforeClass; +import org.junit.AfterClass; +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public abstract class SingletonJunitCase extends JunitTracer { + public static final String SINGLE_INSTANCE_LOCK_FILE = "SingletonTestCase.lock"; + public static final int SINGLE_INSTANCE_LOCK_PORT = 59999; + + public static final long SINGLE_INSTANCE_LOCK_TO = 15*60*1000; // wait up to 15 mins + public static final long SINGLE_INSTANCE_LOCK_POLL = 500; // poll every 500 ms + + private static SingletonInstance singletonInstance = null; // system wide lock via port locking + private static final Object singletonSync = new Object(); // classloader wide lock + private static boolean enabled = true; + + /** + * Default is {@code true}. + */ + public static final void enableSingletonLock(final boolean v) { + enabled = v; + } + + @BeforeClass + public static final void oneTimeSetUpSingleton() { + // one-time initialization code + synchronized( singletonSync ) { + if( enabled ) { + if( null == singletonInstance ) { + System.err.println("++++ Test Singleton.ctor()"); + // singletonInstance = SingletonInstance.createFileLock(SINGLE_INSTANCE_LOCK_POLL, SINGLE_INSTANCE_LOCK_FILE); + singletonInstance = SingletonInstance.createServerSocket(SINGLE_INSTANCE_LOCK_POLL, SINGLE_INSTANCE_LOCK_PORT); + } + System.err.println("++++ Test Singleton.lock()"); + if(!singletonInstance.tryLock(SINGLE_INSTANCE_LOCK_TO)) { + throw new RuntimeException("Fatal: Could not lock single instance: "+singletonInstance.getName()); + } + } + } + } + + @AfterClass + public static final void oneTimeTearDownSingleton() { + // one-time cleanup code + synchronized( singletonSync ) { + System.gc(); // force cleanup + if( enabled ) { + System.err.println("++++ Test Singleton.unlock()"); + singletonInstance.unlock(); + try { + // allowing other JVM instances to pick-up socket + Thread.sleep( SINGLE_INSTANCE_LOCK_POLL ); + } catch (final InterruptedException e) { } + } + } + } +} + diff -Nru gluegen2-2.2.4/src/junit/com/jogamp/junit/util/VersionSemanticsUtil.java gluegen2-2.3.2/src/junit/com/jogamp/junit/util/VersionSemanticsUtil.java --- gluegen2-2.2.4/src/junit/com/jogamp/junit/util/VersionSemanticsUtil.java 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/junit/com/jogamp/junit/util/VersionSemanticsUtil.java 2015-10-09 04:18:28.000000000 +0000 @@ -29,7 +29,6 @@ import java.io.File; import java.io.IOException; -import java.net.URI; import java.net.URISyntaxException; import java.util.HashSet; import java.util.Set; @@ -40,7 +39,7 @@ import org.semver.Delta; import org.semver.Dumper; -import com.jogamp.common.util.IOUtil; +import com.jogamp.common.net.Uri; import com.jogamp.common.util.JarUtil; import com.jogamp.common.util.VersionNumberString; @@ -54,12 +53,10 @@ throws IllegalArgumentException, IOException, URISyntaxException { // Get containing JAR file "TestJarsInJar.jar" and add it to the TempJarCache - final URI currentJarURI = JarUtil.getJarSubURI(currentJarClazz.getName(), currentJarCL); - final String currentJarLocS = IOUtil.decodeURIIfFilePath(currentJarURI); - final File currentJar = new File(currentJarLocS); + final Uri currentJarUri = JarUtil.getJarUri(currentJarClazz.getName(), currentJarCL).getContainedUri(); testVersion(diffCriteria, expectedCompatibilityType, previousJar, preVersionNumber, - currentJar, curVersionNumber, + currentJarUri.toFile(), curVersionNumber, excludesRegExp); } @@ -89,16 +86,18 @@ } System.err.println("Semantic Version Test"); - System.err.println("Previous version: "+preVersionNumber+" - "+previousJar.toString()); - System.err.println("Current version: "+curVersionNumber+" - "+currentJar.toString()); - System.err.println("Compat. expected: "+expectedCompatibilityType); - System.err.println("Compat. detected: "+detectedCompatibilityType); - System.err.println("Compat. result: detected "+compS+" expected -> "+(compOK ? "OK" : "ERROR")); + System.err.println(" criteria: "+diffCriteria); + System.err.println(" Previous version: "+preVersionNumber+" - "+previousJar.toString()); + System.err.println(" Current version: "+curVersionNumber+" - "+currentJar.toString()); + System.err.println(" Field values changed: "+delta.fieldCompatChanged()); + System.err.println(" Compat. expected: "+expectedCompatibilityType); + System.err.println(" Compat. detected: "+detectedCompatibilityType); + System.err.println(" Compat. result: detected "+compS+" expected -> "+(compOK ? "OK" : "ERROR")); final String resS; if( compOK ) { - resS = "Current version "+curVersionNumber+" is "+expectedCompatibilityType+" to previous version "+preVersionNumber+", actually "+detectedCompatibilityType; + resS = " Current version "+curVersionNumber+" is "+expectedCompatibilityType+" to previous version "+preVersionNumber+", actually "+detectedCompatibilityType; } else { - resS = "Current version "+curVersionNumber+" is not "+expectedCompatibilityType+" to previous version "+preVersionNumber+", but "+detectedCompatibilityType; + resS = " Current version "+curVersionNumber+" is not "+expectedCompatibilityType+" to previous version "+preVersionNumber+", but "+detectedCompatibilityType; } System.err.println(resS); System.err.printf("%n%n"); diff -Nru gluegen2-2.2.4/src/native/common/JVMUtil.c gluegen2-2.3.2/src/native/common/JVMUtil.c --- gluegen2-2.2.4/src/native/common/JVMUtil.c 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/native/common/JVMUtil.c 2015-10-09 04:18:28.000000000 +0000 @@ -43,6 +43,11 @@ #include "jogamp_common_jvm_JVMUtil.h" +/* + * Class: jogamp_common_jvm_JVMUtil + * Method: initialize + * Signature: (Ljava/nio/ByteBuffer;)Z + */ JNIEXPORT jboolean JNICALL Java_jogamp_common_jvm_JVMUtil_initialize(JNIEnv *env, jclass _unused, jobject nioBuffer) { void * ptr = NULL; diff -Nru gluegen2-2.2.4/src/native/common/MachineDataInfoRuntime.c gluegen2-2.3.2/src/native/common/MachineDataInfoRuntime.c --- gluegen2-2.2.4/src/native/common/MachineDataInfoRuntime.c 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/native/common/MachineDataInfoRuntime.c 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,160 @@ + +#include + +#include + +#include "jogamp_common_os_MachineDataInfoRuntime.h" + +#if defined(_WIN32) + #include +#else /* assume POSIX sysconf() availability */ + #include +#endif + +#include + +JNIEXPORT jint JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getPointerSizeInBytesImpl(JNIEnv *env, jclass _unused) { + return sizeof(void *); +} + +JNIEXPORT jlong JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getPageSizeInBytesImpl(JNIEnv *env, jclass _unused) { +#if defined(_WIN32) + SYSTEM_INFO si; + GetSystemInfo(&si); + return (jlong) si.dwPageSize; +#else + return (jlong) sysconf(_SC_PAGESIZE); +#endif +} + +typedef struct { + int8_t c1; + int8_t v; +} struct_alignment_int8; + +typedef struct { + int8_t c1; + int16_t v; +} struct_alignment_int16; + +typedef struct { + int8_t c1; + int32_t v; +} struct_alignment_int32; + +typedef struct { + int8_t c1; + int64_t v; +} struct_alignment_int64; + +typedef struct { + int8_t c1; + int v; +} struct_alignment_int; + +typedef struct { + int8_t c1; + long v; +} struct_alignment_long; + +typedef struct { + int8_t c1; + void * v; +} struct_alignment_pointer; + +typedef struct { + int8_t c1; + float v; +} struct_alignment_float; + +typedef struct { + int8_t c1; + double v; +} struct_alignment_double; + +typedef struct { + int8_t c1; + long double v; +} struct_alignment_ldouble; + +// size_t padding(size_t totalsize, size_t typesize) { return totalsize - typesize - sizeof(char); } +// static size_t alignment(size_t totalsize, size_t typesize) { return totalsize - typesize; } +#define ALIGNMENT(a, b) ( (a) - (b) ) + +JNIEXPORT jint JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getAlignmentInt8Impl(JNIEnv *env, jclass _unused) { + return ALIGNMENT(sizeof( struct_alignment_int8 ), sizeof(int8_t)); +} + +JNIEXPORT jint JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getAlignmentInt16Impl(JNIEnv *env, jclass _unused) { + return ALIGNMENT(sizeof( struct_alignment_int16 ), sizeof(int16_t)); +} + +JNIEXPORT jint JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getAlignmentInt32Impl(JNIEnv *env, jclass _unused) { + return ALIGNMENT(sizeof( struct_alignment_int32 ), sizeof(int32_t)); +} + +JNIEXPORT jint JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getAlignmentInt64Impl(JNIEnv *env, jclass _unused) { + return ALIGNMENT(sizeof( struct_alignment_int64 ), sizeof(int64_t)); +} + +JNIEXPORT jint JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getAlignmentIntImpl(JNIEnv *env, jclass _unused) { + return ALIGNMENT(sizeof( struct_alignment_int ), sizeof(int)); +} + +JNIEXPORT jint JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getAlignmentLongImpl(JNIEnv *env, jclass _unused) { + return ALIGNMENT(sizeof( struct_alignment_long ), sizeof(long)); +} + +JNIEXPORT jint JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getAlignmentPointerImpl(JNIEnv *env, jclass _unused) { + return ALIGNMENT(sizeof( struct_alignment_pointer ), sizeof(void *)); +} + +JNIEXPORT jint JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getAlignmentFloatImpl(JNIEnv *env, jclass _unused) { + return ALIGNMENT(sizeof( struct_alignment_float ), sizeof(float)); +} + +JNIEXPORT jint JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getAlignmentDoubleImpl(JNIEnv *env, jclass _unused) { + return ALIGNMENT(sizeof( struct_alignment_double ), sizeof(double)); +} + +JNIEXPORT jint JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getAlignmentLongDoubleImpl(JNIEnv *env, jclass _unused) { + return ALIGNMENT(sizeof( struct_alignment_ldouble ), sizeof(long double)); +} + +JNIEXPORT jint JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getSizeOfIntImpl(JNIEnv *env, jclass _unused) { + return sizeof(int); +} + +JNIEXPORT jint JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getSizeOfLongImpl(JNIEnv *env, jclass _unused) { + return sizeof(long); +} + +JNIEXPORT jint JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getSizeOfFloatImpl(JNIEnv *env, jclass _unused) { + return sizeof(float); +} + +JNIEXPORT jint JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getSizeOfDoubleImpl(JNIEnv *env, jclass _unused) { + return sizeof(double); +} + +JNIEXPORT jint JNICALL +Java_jogamp_common_os_MachineDataInfoRuntime_getSizeOfLongDoubleImpl(JNIEnv *env, jclass _unused) { + return sizeof(long double); +} + diff -Nru gluegen2-2.2.4/src/native/common/MachineDescriptionRuntime.c gluegen2-2.3.2/src/native/common/MachineDescriptionRuntime.c --- gluegen2-2.2.4/src/native/common/MachineDescriptionRuntime.c 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/native/common/MachineDescriptionRuntime.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,160 +0,0 @@ - -#include - -#include - -#include "jogamp_common_os_MachineDescriptionRuntime.h" - -#if defined(_WIN32) - #include -#else /* assume POSIX sysconf() availability */ - #include -#endif - -#include - -JNIEXPORT jint JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getPointerSizeInBytesImpl(JNIEnv *env, jclass _unused) { - return sizeof(void *); -} - -JNIEXPORT jlong JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getPageSizeInBytesImpl(JNIEnv *env, jclass _unused) { -#if defined(_WIN32) - SYSTEM_INFO si; - GetSystemInfo(&si); - return (jlong) si.dwPageSize; -#else - return (jlong) sysconf(_SC_PAGESIZE); -#endif -} - -typedef struct { - int8_t c1; - int8_t v; -} struct_alignment_int8; - -typedef struct { - int8_t c1; - int16_t v; -} struct_alignment_int16; - -typedef struct { - int8_t c1; - int32_t v; -} struct_alignment_int32; - -typedef struct { - int8_t c1; - int64_t v; -} struct_alignment_int64; - -typedef struct { - int8_t c1; - int v; -} struct_alignment_int; - -typedef struct { - int8_t c1; - long v; -} struct_alignment_long; - -typedef struct { - int8_t c1; - void * v; -} struct_alignment_pointer; - -typedef struct { - int8_t c1; - float v; -} struct_alignment_float; - -typedef struct { - int8_t c1; - double v; -} struct_alignment_double; - -typedef struct { - int8_t c1; - long double v; -} struct_alignment_ldouble; - -// size_t padding(size_t totalsize, size_t typesize) { return totalsize - typesize - sizeof(char); } -// static size_t alignment(size_t totalsize, size_t typesize) { return totalsize - typesize; } -#define ALIGNMENT(a, b) ( (a) - (b) ) - -JNIEXPORT jint JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getAlignmentInt8Impl(JNIEnv *env, jclass _unused) { - return ALIGNMENT(sizeof( struct_alignment_int8 ), sizeof(int8_t)); -} - -JNIEXPORT jint JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getAlignmentInt16Impl(JNIEnv *env, jclass _unused) { - return ALIGNMENT(sizeof( struct_alignment_int16 ), sizeof(int16_t)); -} - -JNIEXPORT jint JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getAlignmentInt32Impl(JNIEnv *env, jclass _unused) { - return ALIGNMENT(sizeof( struct_alignment_int32 ), sizeof(int32_t)); -} - -JNIEXPORT jint JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getAlignmentInt64Impl(JNIEnv *env, jclass _unused) { - return ALIGNMENT(sizeof( struct_alignment_int64 ), sizeof(int64_t)); -} - -JNIEXPORT jint JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getAlignmentIntImpl(JNIEnv *env, jclass _unused) { - return ALIGNMENT(sizeof( struct_alignment_int ), sizeof(int)); -} - -JNIEXPORT jint JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getAlignmentLongImpl(JNIEnv *env, jclass _unused) { - return ALIGNMENT(sizeof( struct_alignment_long ), sizeof(long)); -} - -JNIEXPORT jint JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getAlignmentPointerImpl(JNIEnv *env, jclass _unused) { - return ALIGNMENT(sizeof( struct_alignment_pointer ), sizeof(void *)); -} - -JNIEXPORT jint JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getAlignmentFloatImpl(JNIEnv *env, jclass _unused) { - return ALIGNMENT(sizeof( struct_alignment_float ), sizeof(float)); -} - -JNIEXPORT jint JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getAlignmentDoubleImpl(JNIEnv *env, jclass _unused) { - return ALIGNMENT(sizeof( struct_alignment_double ), sizeof(double)); -} - -JNIEXPORT jint JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getAlignmentLongDoubleImpl(JNIEnv *env, jclass _unused) { - return ALIGNMENT(sizeof( struct_alignment_ldouble ), sizeof(long double)); -} - -JNIEXPORT jint JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getSizeOfIntImpl(JNIEnv *env, jclass _unused) { - return sizeof(int); -} - -JNIEXPORT jint JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getSizeOfLongImpl(JNIEnv *env, jclass _unused) { - return sizeof(long); -} - -JNIEXPORT jint JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getSizeOfFloatImpl(JNIEnv *env, jclass _unused) { - return sizeof(float); -} - -JNIEXPORT jint JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getSizeOfDoubleImpl(JNIEnv *env, jclass _unused) { - return sizeof(double); -} - -JNIEXPORT jint JNICALL -Java_jogamp_common_os_MachineDescriptionRuntime_getSizeOfLongDoubleImpl(JNIEnv *env, jclass _unused) { - return sizeof(long double); -} - diff -Nru gluegen2-2.2.4/src/native/tinype/make.sh gluegen2-2.3.2/src/native/tinype/make.sh --- gluegen2-2.2.4/src/native/tinype/make.sh 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/native/tinype/make.sh 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,15 @@ +# /cygdrive/c/mingw/bin/gcc -nodefaultlibs -nostdlib -s -Os -mconsole -o tiny-conso-i386.exe tiny.c + +jardir=../../../build-win64 + +/cygdrive/c/mingw/bin/gcc -nodefaultlibs -nostdlib -s -Os -mwindows -o tiny2-win32-i386.exe tiny2.c -lUser32 +java -cp "$jardir/test/build/gluegen-test.jar;$jardir/gluegen-rt.jar" com.jogamp.common.util.CustomDeflate tiny2-win32-i386.exe exe2-windows-i386.defl + +/cygdrive/c/mingw64/bin/gcc -nodefaultlibs -nostdlib -s -Os -mwindows -o tiny2-win32-x86_64.exe tiny2.c -lUser32 +java -cp "$jardir/test/build/gluegen-test.jar;$jardir/gluegen-rt.jar" com.jogamp.common.util.CustomDeflate tiny2-win32-x86_64.exe exe2-windows-x86_64.defl + +/cygdrive/c/mingw/bin/gcc -nodefaultlibs -nostdlib -s -Os -mwindows -o tiny-win32-i386.exe tiny.c +java -cp "$jardir/test/build/gluegen-test.jar;$jardir/gluegen-rt.jar" com.jogamp.common.util.CustomDeflate tiny-win32-i386.exe exe-windows-i386.defl + +/cygdrive/c/mingw64/bin/gcc -nodefaultlibs -nostdlib -s -Os -mwindows -o tiny-win32-x86_64.exe tiny.c +java -cp "$jardir/test/build/gluegen-test.jar;$jardir/gluegen-rt.jar" com.jogamp.common.util.CustomDeflate tiny-win32-x86_64.exe exe-windows-x86_64.defl diff -Nru gluegen2-2.2.4/src/native/tinype/tiny2.c gluegen2-2.3.2/src/native/tinype/tiny2.c --- gluegen2-2.2.4/src/native/tinype/tiny2.c 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/native/tinype/tiny2.c 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,15 @@ +#undef UNICODE +#define UNICODE +#include + +const wchar_t * id = L"JogAmp Windows Universal Test PE Executable"; +const wchar_t * cap = L"JogAmp"; + +// int __main() +// int main() +// int main( int argc, char* argv[] ) +int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) +{ + MessageBox(0, id, cap, MB_SETFOREGROUND | MB_OK); + return 0; +} diff -Nru gluegen2-2.2.4/src/native/tinype/tiny.c gluegen2-2.3.2/src/native/tinype/tiny.c --- gluegen2-2.2.4/src/native/tinype/tiny.c 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/native/tinype/tiny.c 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,13 @@ +#undef UNICODE +#define UNICODE +#include + +// const char * id = "JogAmp Windows Universal Test PE Executable"; + +// int __main() +// int main() +// int main( int argc, char* argv[] ) +int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) +{ + return 0; +} diff -Nru gluegen2-2.2.4/src/native/tinype-corkami/consts.inc gluegen2-2.3.2/src/native/tinype-corkami/consts.inc --- gluegen2-2.2.4/src/native/tinype-corkami/consts.inc 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/native/tinype-corkami/consts.inc 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,675 @@ +%define PREFIX_OPERANDSIZE db 66h + +IMAGE_RESOURCE_DATA_IS_DIRECTORY equ 80000000h +PAGE_READWRITE equ 4 +ExceptionContinueExecution equ 0 + +DLL_PROCESS_ATTACH equ 1 +DLL_PROCESS_DETACH equ 0 + +IMAGE_SCN_CNT_CODE equ 000000020h +IMAGE_SCN_CNT_INITIALIZED_DATA equ 000000040h +IMAGE_SCN_MEM_SHARED equ 010000000h +IMAGE_SCN_MEM_EXECUTE equ 020000000h +IMAGE_SCN_MEM_READ equ 040000000h +IMAGE_SCN_MEM_WRITE equ 080000000h + +MEM_COMMIT equ 1000h + +BREAKPOINT equ 080000003h +SINGLE_STEP equ 80000004h +ACCESS_VIOLATION equ 0c0000005h +INVALID_HANDLE equ 0C0000008h +INVALID_LOCK_SEQUENCE equ 0C000001eh +INTEGER_DIVIDE_BY_ZERO equ 0C0000094h +INTEGER_OVERFLOW equ 0C0000095h +PRIVILEGED_INSTRUCTION equ 0C0000096h + +struc exceptionHandler + .pException resd 1 ; EXCEPTION_RECORD + .pRegistrationRecord resd 1 ; EXCEPTION_REGISTRATION_RECORD + .pContext resd 1 ; CONTEXT +endstruc + +SIZE_OF_80387_REGISTERS equ 80 +MAXIMUM_SUPPORTED_EXTENSION equ 512 + +struc CONTEXT + .ContextFlags resd 1 + ;CONTEXT_DEBUG_REGISTERS + .iDr0 resd 1 + .iDr1 resd 1 + .iDr2 resd 1 + .iDr3 resd 1 + .iDr6 resd 1 + .iDr7 resd 1 + ;CONTEXT_FLOATING_POINT + .ControlWord resd 1 + .StatusWord resd 1 + .TagWord resd 1 + .ErrorOffset resd 1 + .ErrorSelector resd 1 + .DataOffset resd 1 + .DataSelector resd 1 + .RegisterArea resb SIZE_OF_80387_REGISTERS + .Cr0NpxState resd 1 + ;CONTEXT_SEGMENTS + .regGs resd 1 + .regFs resd 1 + .regEs resd 1 + .regDs resd 1 + ;CONTEXT_INTEGER + .regEdi resd 1 + .regEsi resd 1 + .regEbx resd 1 + .regEdx resd 1 + .regEcx resd 1 + .regEax resd 1 + ;CONTEXT_CONTROL + .regEbp resd 1 + .regEip resd 1 + .regCs resd 1 + .regFlag resd 1 + .regEsp resd 1 + .regSs resd 1 + ;CONTEXT_EXTENDED_REGISTERS + .ExtendedRegisters resb MAXIMUM_SUPPORTED_EXTENSION +endstruc + +IMAGE_SIZEOF_SHORT_NAME equ 8 + +struc IMAGE_DOS_HEADER + .e_magic resw 1 + .e_cblp resw 1 + .e_cp resw 1 + .e_crlc resw 1 + .e_cparhdr resw 1 + .e_minalloc resw 1 + .e_maxalloc resw 1 + .e_ss resw 1 + .e_sp resw 1 + .e_csum resw 1 + .e_ip resw 1 + .e_cs resw 1 + .e_lfarlc resw 1 + .e_ovno resw 1 + .e_res resw 4 + .e_oemid resw 1 + .e_oeminfo resw 1 + .e_res2 resw 10 + .e_lfanew resd 1 +endstruc + +struc IMAGE_NT_HEADERS + .Signature resd 1 +; .FileHeader resb IMAGE_FILE_HEADER_size +; .OptionalHeader resb IMAGE_OPTIONAL_HEADER32_size +endstruc + +struc IMAGE_FILE_HEADER + .Machine resw 1 + .NumberOfSections resw 1 + .TimeDateStamp resd 1 + .PointerToSymbolTable resd 1 + .NumberOfSymbols resd 1 + .SizeOfOptionalHeader resw 1 + .Characteristics resw 1 +endstruc + +IMAGE_FILE_MACHINE_I386 equ 014ch +IMAGE_FILE_DLL equ 02000h +IMAGE_NT_OPTIONAL_HDR32_MAGIC equ 010bh + +struc IMAGE_OPTIONAL_HEADER32 + .Magic resw 1 + .MajorLinkerVersion resb 1 + .MinorLinkerVersion resb 1 + .SizeOfCode resd 1 + .SizeOfInitializedData resd 1 + .SizeOfUninitializedData resd 1 + .AddressOfEntryPoint resd 1 + .BaseOfCode resd 1 + .BaseOfData resd 1 + .ImageBase resd 1 + .SectionAlignment resd 1 + .FileAlignment resd 1 + .MajorOperatingSystemVersion resw 1 + .MinorOperatingSystemVersion resw 1 + .MajorImageVersion resw 1 + .MinorImageVersion resw 1 + .MajorSubsystemVersion resw 1 + .MinorSubsystemVersion resw 1 + .Win32VersionValue resd 1 + .SizeOfImage resd 1 + .SizeOfHeaders resd 1 + .CheckSum resd 1 + .Subsystem resw 1 + .DllCharacteristics resw 1 + .SizeOfStackReserve resd 1 + .SizeOfStackCommit resd 1 + .SizeOfHeapReserve resd 1 + .SizeOfHeapCommit resd 1 + .LoaderFlags resd 1 + .NumberOfRvaAndSizes resd 1 + .DataDirectory resb 0 +endstruc + +struc IMAGE_DATA_DIRECTORY + VirtualAddress resd 1 + isize resd 1 +endstruc + +struc IMAGE_DATA_DIRECTORY_16 + .ExportsVA resd 1 + .ExportsSize resd 1 + .ImportsVA resd 1 + .ImportsSize resd 1 + .ResourceVA resd 1 + .ResourceSize resd 1 + .Exception resd 2 + .Security resd 2 + .FixupsVA resd 1 + .FixupsSize resd 1 + .DebugVA resd 1 + .DebugSize resd 1 + .Description resd 2 + .MIPS resd 2 + .TLSVA resd 1 + .TLSSize resd 1 + .Load resd 2 + .BoundImportsVA resd 1 + .BoundImportsSize resd 1 + .IATVA resd 1 + .IATSize resd 1 + .DelayImportsVA resd 1 + .DelayImportsSize resd 1 + .COM resd 2 + .reserved resd 2 +endstruc + +struc IMAGE_SECTION_HEADER + .Name resb IMAGE_SIZEOF_SHORT_NAME + .VirtualSize resd 1 + .VirtualAddress resd 1 + .SizeOfRawData resd 1 + .PointerToRawData resd 1 + .PointerToRelocations resd 1 + .PointerToLinenumbers resd 1 + .NumberOfRelocations resw 1 + .NumberOfLinenumbers resw 1 + .Characteristics resd 1 +endstruc + + +IMAGE_SUBSYSTEM_WINDOWS_CUI equ 3 +IMAGE_SUBSYSTEM_WINDOWS_GUI equ 2 +IMAGE_FILE_RELOCS_STRIPPED equ 00001h +IMAGE_FILE_EXECUTABLE_IMAGE equ 00002h +IMAGE_FILE_LINE_NUMS_STRIPPED equ 00004h +IMAGE_FILE_LOCAL_SYMS_STRIPPED equ 00008h +IMAGE_FILE_32BIT_MACHINE equ 00100h + +%macro _ 0 + nop +%endmacro + +%macro _c 0 + int3 + align 4, int3 +%endmacro + +%macro _d 0 + db 0 + align 16, db 0 +%endmacro + + +%macro setSEH 1 + push %1 + push dword [fs:0] + mov [fs:0], esp +%endmacro + +%macro clearSEH 0 + pop dword [fs:0] + add esp, 4 +%endmacro + +struc IMAGE_OPTIONAL_HEADER64 + .Magic resw 1 + .MajorLinkerVersion resb 1 + .MinorLinkerVersion resb 1 + .SizeOfCode resd 1 + .SizeOfInitializedData resd 1 + .SizeOfUninitializedData resd 1 + .AddressOfEntryPoint resd 1 + .BaseOfCode resd 1 + .ImageBase resq 1 + .SectionAlignment resd 1 + .FileAlignment resd 1 + .MajorOperatingSystemVersion resw 1 + .MinorOperatingSystemVersion resw 1 + .MajorImageVersion resw 1 + .MinorImageVersion resw 1 + .MajorSubsystemVersion resw 1 + .MinorSubsystemVersion resw 1 + .Win32VersionValue resd 1 + .SizeOfImage resd 1 + .SizeOfHeaders resd 1 + .CheckSum resd 1 + .Subsystem resw 1 + .DllCharacteristics resw 1 + .SizeOfStackReserve resq 1 + .SizeOfStackCommit resq 1 + .SizeOfHeapReserve resq 1 + .SizeOfHeapCommit resq 1 + .LoaderFlags resd 1 + .NumberOfRvaAndSizes resd 1 + .DataDirectory resb 0 +endstruc + +IMAGE_FILE_MACHINE_AMD64 equ 8664h +IMAGE_NT_OPTIONAL_HDR64_MAGIC equ 020bh + +IMAGE_REL_BASED_ABSOLUTE equ 0 ; used for padding +IMAGE_REL_BASED_HIGH equ 1 +IMAGE_REL_BASED_LOW equ 2 ; does nothing +IMAGE_REL_BASED_HIGHLOW equ 3 ; +IMAGE_REL_BASED_HIGHADJ equ 4 ; takes an argument but actually does nothing +IMAGE_REL_BASED_MIPS_JMPADDR equ 5 ; until W7 only +IMAGE_REL_BASED_SECTION equ 6 ; until W7 only ; does nothing anyway +IMAGE_REL_BASED_REL32 equ 7 ; until W7 only ; does nothing anyway +; 8 is always rejected, historically +IMAGE_REL_BASED_MIPS_JMPADDR16 equ 9 +IMAGE_REL_BASED_IA64_IMM64 equ 9 +IMAGE_REL_BASED_DIR64 equ 10 +IMAGE_REL_BASED_HIGH3ADJ equ 11 ; Win2k only + +CR equ 0dh +EOF equ 1ah +LF equ 0ah + +struc IMAGE_RESOURCE_DIRECTORY + .Characteristics resd 1 + .TimeDateStamp resd 1 + .MajorVersion resw 1 + .MinorVersion resw 1 + .NumberOfNamedEntries resw 1 + .NumberOfIdEntries resw 1 +endstruc + +struc IMAGE_RESOURCE_DIRECTORY_ENTRY + .NameID resd 1 + .OffsetToData resd 1 +endstruc + +struc IMAGE_RESOURCE_DATA_ENTRY + .OffsetToData resd 1 + .Size1 resd 1 + .CodePage resd 1 + .Reserved resd 1 +endstruc + +struc _IMAGE_DELAY_IMPORT_DESCRIPTOR + .grAttrs resd 1 ; attributes + .rvaDLLName resd 1 ; RVA to dll name + .rvaHmod resd 1 ; RVA of module handle + .rvaIAT resd 1 ; RVA of the IAT + .rvaINT resd 1 ; RVA of the INT + .rvaBoundIAT resd 1 ; RVA of the optional bound IAT + .rvaUnloadIAT resd 1 ; RVA of optional copy of original IAT + .dwTimeStamp resd 1 ; 0 if not bound +endstruc + +struc TRUNC_OPTIONAL_HEADER32 + .Magic resw 1 + .MajorLinkerVersion resb 1 + .MinorLinkerVersion resb 1 + .SizeOfCode resd 1 + .SizeOfInitializedData resd 1 + .SizeOfUninitializedData resd 1 + .AddressOfEntryPoint resd 1 + .BaseOfCode resd 1 + .BaseOfData resd 1 + .ImageBase resd 1 + .SectionAlignment resd 1 + .FileAlignment resd 1 + .MajorOperatingSystemVersion resw 1 + .MinorOperatingSystemVersion resw 1 + .MajorImageVersion resw 1 + .MinorImageVersion resw 1 + .MajorSubsystemVersion resw 1 + .MinorSubsystemVersion resw 1 + .Win32VersionValue resd 1 + .SizeOfImage resd 1 + .SizeOfHeaders resd 1 + .CheckSum resd 1 + .Subsystem resb 1 ; truncated as a byte + ; no more data +endstruc + +struc VS_FIXEDFILEINFO + .dwSignature resd 1 + .dwStrucVersion resd 1 + .dwFileVersionMS resd 1 + .dwFileVersionLS resd 1 + .dwProductVersionMS resd 1 + .dwProductVersionLS resd 1 + .dwFileFlagsMask resd 1 + .dwFileFlags resd 1 + .dwFileOS resd 1 + .dwFileType resd 1 + .dwFileSubtype resd 1 + .dwFileDateMS resd 1 + .dwFileDateLS resd 1 +endstruc + +CREATEPROCESS_MANIFEST_RESOURCE_ID EQU 1 +ISOLATIONAWARE_MANIFEST_RESOURCE_ID EQU 2 +ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID EQU 3 + + +struc ACTCTX ; typedef struct tagACTCTX { +.cbSize resd 1 ; ULONG cbSize; +.dwFlags resd 1 ; DWORD dwFlags; +.lpSource resd 1 ; LPCWSTR lpSource; +.wProcessorArchitecture resw 1 ; USHORT wProcessorArchitecture; +.wLangId resw 1 ; LANGID wLangId; +.lpAssemblyDirectory resd 1 ; LPCTSTR lpAssemblyDirectory; +.lpResourceName resd 1 ; LPCTSTR lpResourceName; +.lpApplicationName resd 1 ; LPCTSTR lpApplicationName; +.hModule resd 1 ; HMODULE hModule; +endstruc ; } ACTCTX, *PACTCTX; + +ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID equ 1 +ACTCTX_FLAG_LANGID_VALID equ 2 +ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID equ 4 +ACTCTX_FLAG_RESOURCE_NAME_VALID equ 8 +ACTCTX_FLAG_SET_PROCESS_DEFAULT equ 16 +ACTCTX_FLAG_APPLICATION_NAME_VALID equ 32 +ACTCTX_FLAG_HMODULE_VALID equ 128 + +; widechar string macro +%macro WIDE 1 +%assign %%__i 1 +%strlen %%__len %1 +%rep %%__len + %substr %%__c %1 %%__i + db %%__c + db 0 + %assign %%__i %%__i + 1 +%endrep + db 0, 0 +%endmacro + +%macro _widestr_no0 1 +%assign %%__i 1 +%strlen %%__len %1 +%rep %%__len + %substr %%__c %1 %%__i + db %%__c + db 0 + %assign %%__i %%__i + 1 +%endrep +%endmacro + +%macro __string 2 +%%string: +dw %%SLEN +dw %%VALLEN / 2 ; dammit ! +dw 1 ; text type +WIDE %1 + align 4, db 0 +%%val: + WIDE %2 + %%VALLEN equ $ - %%val + align 4, db 0 +%%SLEN equ $ - %%string +%endmacro + + +struc RUNTIME_FUNCTION + .FunctionStart resd 1 + .FunctionEnd resd 1 + .UnwindInfo resd 1 +endstruc + +struc UNWIND_INFO + .Ver3_Flags resb 1 ; versions and flags + .PrologSize resb 1 + .CntUnwindCodes resb 1 + .FrReg_FrRegOff resb 1 ; frame register and offsets + ; dd ExceptionHandler or FunctionEntry + ; ExceptionData +endstruc + +struc UNWIND_CODE + .PrologOff resb 1 + .OpCode_OpInfo resb 1 ; operation code and info +endstruc + +UNW_FLAG_EHANDLER equ 1 + +struc IMAGE_DEBUG_DIRECTORY + .Characteristics resd 1 + .TimeDateStamp resd 1 + .MajorVersion resw 1 + .MinorVersion resw 1 + .Type resd 1 + .SizeOfData resd 1 + .AddressOfRawData resd 1 + .PointerToRawData resd 1 +endstruc + +IMAGE_DEBUG_TYPE_COFF equ 1 +IMAGE_DEBUG_TYPE_CODEVIEW equ 2 +IMAGE_DEBUG_TYPE_MISC equ 4 + +SYMOPT_DEBUG equ 080000000h + +struc IMAGE_EXPORT_DIRECTORY + .Characteristics resd 1 + .TimeDateStamp resd 1 + .MajorVersion resw 1 + .MinorVersion resw 1 + .nName resd 1 + .nBase resd 1 + .NumberOfFunctions resd 1 + .NumberOfNames resd 1 + .AddressOfFunctions resd 1 + .AddressOfNames resd 1 + .AddressOfNameOrdinals resd 1 +endstruc + +struc IMAGE_IMPORT_DESCRIPTOR + .OriginalFirstThunk resd 1 ; Characteristics + .TimeDateStamp resd 1 + .ForwarderChain resd 1 + .Name1 resd 1 + .FirstThunk resd 1 +endstruc + +%macro _import_descriptor 1 +istruc IMAGE_IMPORT_DESCRIPTOR + at IMAGE_IMPORT_DESCRIPTOR.OriginalFirstThunk, dd %1_hintnames - IMAGEBASE + at IMAGE_IMPORT_DESCRIPTOR.Name1 , dd %1 - IMAGEBASE + at IMAGE_IMPORT_DESCRIPTOR.FirstThunk , dd %1_iat - IMAGEBASE +iend +%endmacro + +struc IMAGE_LOAD_CONFIG_DIRECTORY32 + .Size resd 1 + .TimeDateStamp resd 1 + .MajorVersion resw 1 + .MinorVersion resw 1 + .GlobalFlagsClear resd 1 + .GlobalFlagsSet resd 1 + .CriticalSectionDefaultTimeout resd 1 + .DeCommitFreeBlockThreshold resd 1 + .DeCommitTotalFreeThreshold resd 1 + .LockPrefixTable resd 1 ; VA + .MaximumAllocationSize resd 1 + .VirtualMemoryThreshold resd 1 + .ProcessHeapFlags resd 1 + .ProcessAffinityMask resd 1 + .CSDVersion resw 1 + .Reserved1 resw 1 + .EditList resd 1 ; VA + .SecurityCookie resd 1 ; VA + .SEHandlerTable resd 1 ; VA + .SEHandlerCount resd 1 + .GuardCFCheckFunctionPointer resd 1 ; VA + .Reserved2 resd 1 + .GuardCFFunctionTable resd 1 ; VA + .GuardCFFunctionCount resd 1 + .GuardFlags resd 1 +endstruc + +struc IMAGE_LOAD_CONFIG_DIRECTORY64 + .Size resd 1 + .TimeDateStamp resd 1 + .MajorVersion resw 1 + .MinorVersion resw 1 + .GlobalFlagsClear resd 1 + .GlobalFlagsSet resd 1 + .CriticalSectionDefaultTimeout resd 1 + .DeCommitFreeBlockThreshold resq 1 + .DeCommitTotalFreeThreshold resq 1 + .LockPrefixTable resq 1 ; VA + .MaximumAllocationSize resq 1 + .VirtualMemoryThreshold resq 1 + .ProcessAffinityMask resq 1 + .ProcessHeapFlags resd 1 + .CSDVersion resw 1 + .Reserved1 resw 1 + .EditList resq 1 ; VA + .SecurityCookie resq 1 ; VA + .SEHandlerTable resq 1 ; VA + .SEHandlerCount resq 1 + .GuardCFCheckFunctionPointer resq 1 ; VA + .Reserved2 resq 1 + .GuardCFFunctionTable resq 1 ; VA + .GuardCFFunctionCount resq 1 + .GuardFlags resd 1 +endstruc + +RT_ICON equ 3 +RT_STRING equ 6 +RT_GROUP_ICON equ 14 +RT_VERSION equ 16 +RT_MANIFEST equ 24 + +struc GRPICONDIR + .idReserved resw 1 ; always 0 - enforced + .idType resw 1 ; always 1 for icons + .idCount resw 1 +endstruc + +struc GRPICONDIRENTRY + .bWidth resb 1 + .bHeight resb 1 + .bColorCount resb 1 + .bReserved resb 1 + .wPlanes resw 1 + .wBitCount resw 1 + .dwBytesInRes resd 1 + .nId resw 1 +endstruc + +%macro _resourceDirectoryEntry 2 +istruc IMAGE_RESOURCE_DIRECTORY_ENTRY + at IMAGE_RESOURCE_DIRECTORY_ENTRY.NameID, dd %1 + at IMAGE_RESOURCE_DIRECTORY_ENTRY.OffsetToData, dd IMAGE_RESOURCE_DATA_IS_DIRECTORY | (%2 - Directory_Entry_Resource) +iend +%endmacro + +%macro _resource_tree 3 ; ID, Offset, Size +istruc IMAGE_RESOURCE_DIRECTORY + at IMAGE_RESOURCE_DIRECTORY.NumberOfIdEntries, dw 1 +iend +istruc IMAGE_RESOURCE_DIRECTORY_ENTRY + at IMAGE_RESOURCE_DIRECTORY_ENTRY.NameID, dd %1 + at IMAGE_RESOURCE_DIRECTORY_ENTRY.OffsetToData, dd IMAGE_RESOURCE_DATA_IS_DIRECTORY | (%%language - Directory_Entry_Resource) +iend + +%%language: +istruc IMAGE_RESOURCE_DIRECTORY + at IMAGE_RESOURCE_DIRECTORY.NumberOfIdEntries, dw 1 +iend +istruc IMAGE_RESOURCE_DIRECTORY_ENTRY + ; language doesn't matter + at IMAGE_RESOURCE_DIRECTORY_ENTRY.OffsetToData, dd %%entry - Directory_Entry_Resource +iend + +%%entry: +istruc IMAGE_RESOURCE_DATA_ENTRY + at IMAGE_RESOURCE_DATA_ENTRY.OffsetToData, dd %2 - IMAGEBASE + at IMAGE_RESOURCE_DATA_ENTRY.Size1, dd %3 +iend +%endmacro + +RichKey EQU 092033d19h + +struc IMAGE_TLS_DIRECTORY32 + .StartAddressOfRawData resd 1 + .EndAddressOfRawData resd 1 + .AddressOfIndex resd 1 + .AddressOfCallBacks resd 1 + .SizeOfZeroFill resd 1 + .Characteristics resd 1 +endstruc + +struc IMAGE_TLS_DIRECTORY64 + .StartAddressOfRawData resq 1 + .EndAddressOfRawData resq 1 + .AddressOfIndex resq 1 + .AddressOfCallBacks resq 1 + .SizeOfZeroFill resd 1 + .Characteristics resd 1 +endstruc + +struc IMAGE_BOUND_IMPORT_DESCRIPTOR + .TimeDateStamp resd 1 + .OffsetModuleName resw 1 + .NumberOfModulesForwarderRefs resw 1 +endstruc + +struc WIN_CERTIFICATE + .dwLength resd 1 + .wRevision resw 1 + .wCertificateType resw 1 + .bCertificate resb 0 +endstruc + +struc IMAGE_BASE_RELOCATION + .VirtualAddress resd 1 + .SizeOfBlock resd 1 +endstruc + +; can't make a struct of that one with Yasm :( +%macro _IMAGE_IMPORT_BY_NAME 1 + .Hint dw 0 + .Name db %1, 0 +%endmacro + +IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE equ 0040h +IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY equ 0080h +IMAGE_DLLCHARACTERISTICS_NX_COMPAT equ 0100h +IMAGE_DLLCHARACTERISTICS_NO_SEH equ 0400h +IMAGE_DLLCHARACTERISTICS_APPCONTAINER equ 1000h ; W8 +IMAGE_DLLCHARACTERISTICS_GUARD_CF equ 4000h ; W8.1 + +FLG_SHOW_LDR_SNAPS equ 2 + +MB_OK equ 00000000h +MB_ICONASTERISK equ 00000040h +MB_APPLMODAL equ 00000000h + +LOAD_LIBRARY_AS_DATAFILE equ 000000002h + +IMAGE_GUARD_CF_INSTRUMENTED equ 000000100h ;Module performs control flow integrity checks using system-supplied support +IMAGE_GUARD_CFW_INSTRUMENTED equ 000000200h ;Module performs control flow and write integrity checks +IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT equ 000000400h ;Module contains valid control flow target metadata +IMAGE_GUARD_SECURITY_COOKIE_UNUSED equ 000000800h ;Module does not make use of the /GS security cookie + +COOKIE_DEFAULT equ 0bb40e64eh diff -Nru gluegen2-2.2.4/src/native/tinype-corkami/make.bat gluegen2-2.3.2/src/native/tinype-corkami/make.bat --- gluegen2-2.2.4/src/native/tinype-corkami/make.bat 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/native/tinype-corkami/make.bat 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,13 @@ +REM +REM Using yasm 1.2.0 win64 or win32 +REM http://yasm.tortall.net/ +REM +REM TinyPE XP-W8 Compatible - x86 32bit and 64bit - 268 bytes +REM https://code.google.com/p/corkami/wiki/PE +REM https://code.google.com/p/corkami/source/browse/trunk/src/PE/tiny.asm +REM +REM See also: +REM http://www.phreedom.org/research/tinype/ +REM +c:\yasm\yasm.exe -f bin -o tiny-simple.exe tiny-simple.asm +REM c:\yasm\yasm.exe -f bin -o tiny.exe tiny.asm diff -Nru gluegen2-2.2.4/src/native/tinype-corkami/readme.txt gluegen2-2.3.2/src/native/tinype-corkami/readme.txt --- gluegen2-2.2.4/src/native/tinype-corkami/readme.txt 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/native/tinype-corkami/readme.txt 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,25 @@ +TinyPE XP-W8 Compatible - x86 32bit and 64bit - 268 bytes + +https://code.google.com/p/corkami/wiki/PE +https://code.google.com/p/corkami/source/browse/trunk/src/PE/tiny.asm + +by Ange Albertini, BSD Licence, 2010-2013 + +tiny-simple.asm (diff to tiny.asm): + - remove printf, and msvcrt.dll import + - just return 0 + ++++ + +See also: + +Tiny PE +http://www.phreedom.org/research/tinype/ +by Alexander Sotirov + ++++ + +Compiled w/ yasm 1.2.0 for win64 or win32. +http://yasm.tortall.net/ + ++++ diff -Nru gluegen2-2.2.4/src/native/tinype-corkami/tiny.asm gluegen2-2.3.2/src/native/tinype-corkami/tiny.asm --- gluegen2-2.2.4/src/native/tinype-corkami/tiny.asm 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/native/tinype-corkami/tiny.asm 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,117 @@ +; a 268-byte PE (as small as possible), XP-W8x64 compatible + +; similar with the w7 x64 PE, but larger sizeofimage and IAT required. XP compat also requires Debug Size and TLS VA to be null +; a few extra tricks required for Windows 8 compatibility + +;Ange Albertini, BSD Licence, 2010-2013 + +%include 'consts.inc' + +IMAGEBASE equ 400000h + +org IMAGEBASE + +DOS_HEADER: +.e_magic dw 'MZ' + +align 4, db 0 + +istruc IMAGE_NT_HEADERS + at IMAGE_NT_HEADERS.Signature, db 'PE',0,0 +iend +istruc IMAGE_FILE_HEADER + at IMAGE_FILE_HEADER.Machine, dw IMAGE_FILE_MACHINE_I386 + at IMAGE_FILE_HEADER.TimeDateStamp +msvcrt db 'msvcrt.dll', 0 ; keeping the extension in case it'd work under W2K + at IMAGE_FILE_HEADER.Characteristics, dw IMAGE_FILE_EXECUTABLE_IMAGE ; | IMAGE_FILE_32BIT_MACHINE + +iend + +istruc IMAGE_OPTIONAL_HEADER32 + at IMAGE_OPTIONAL_HEADER32.Magic, dw IMAGE_NT_OPTIONAL_HDR32_MAGIC +bits 32 + +realEntryPoint: + push message + call [__imp__printf] + jmp _2 + at IMAGE_OPTIONAL_HEADER32.AddressOfEntryPoint, dd EntryPoint - IMAGEBASE + at IMAGE_OPTIONAL_HEADER32.BaseOfCode, dd 0 ; must be valid for W7 +_2: + add esp, 1 * 4 + retn + at IMAGE_OPTIONAL_HEADER32.ImageBase, dd IMAGEBASE + at IMAGE_OPTIONAL_HEADER32.SectionAlignment, dd 4 ; also sets e_lfanew + at IMAGE_OPTIONAL_HEADER32.FileAlignment, dd 4 + +ImportsAddressTable: +msvcrt_iat: +__imp__printf: + dd hnprintf - IMAGEBASE + dd 0 +IMPORTSADDRESSTABLESIZE equ $ - ImportsAddressTable + + at IMAGE_OPTIONAL_HEADER32.MajorSubsystemVersion, dw 4 + at IMAGE_OPTIONAL_HEADER32.SizeOfImage, dd SIZEOFIMAGE + at IMAGE_OPTIONAL_HEADER32.SizeOfHeaders, dd SIZEOFIMAGE - 5 ; W8 enforce SizeOfHeaders <= EntryPoint + at IMAGE_OPTIONAL_HEADER32.Subsystem, db IMAGE_SUBSYSTEM_WINDOWS_CUI + +db 0 ; one byte delta to avoid setting DllCharacteristics to AppContainer + +hnprintf: + dw 0 + db 'printf', 0 + + at IMAGE_OPTIONAL_HEADER32.NumberOfRvaAndSizes, dd 13 +iend + +istruc IMAGE_DATA_DIRECTORY_13 + + at IMAGE_DATA_DIRECTORY_13.ImportsVA, dd Import_Descriptor - IMAGEBASE + +Import_Descriptor: +istruc IMAGE_IMPORT_DESCRIPTOR + at IMAGE_IMPORT_DESCRIPTOR.Name1 , dd msvcrt - IMAGEBASE + at IMAGE_IMPORT_DESCRIPTOR.FirstThunk, dd msvcrt_iat - IMAGEBASE +iend +istruc IMAGE_IMPORT_DESCRIPTOR +iend + at IMAGE_DATA_DIRECTORY_13.DebugSize, dd 0 ; required for safety under XP + + at IMAGE_DATA_DIRECTORY_13.TLSVA, dd 0 ; required for safety under XP + + at IMAGE_DATA_DIRECTORY_13.IATVA, dd ImportsAddressTable - IMAGEBASE ; required under XP + at IMAGE_DATA_DIRECTORY_13.IATSize, dd IMPORTSADDRESSTABLESIZE ; required under XP +iend + +message db " * 268b universal tiny PE", 0ah, 0 + +times 268 - 260 db 0 +EntryPoint: + jmp realEntryPoint + +SIZEOFIMAGE equ 268 + +struc IMAGE_DATA_DIRECTORY_13 + .ExportsVA resd 1 + .ExportsSize resd 1 + .ImportsVA resd 1 + .ImportsSize resd 1 + .ResourceVA resd 1 + .ResourceSize resd 1 + .Exception resd 2 + .Security resd 2 + .FixupsVA resd 1 + .FixupsSize resd 1 + .DebugVA resd 1 + .DebugSize resd 1 + .Description resd 2 + .MIPS resd 2 + .TLSVA resd 1 + .TLSSize resd 1 + .Load resd 2 + .BoundImportsVA resd 1 + .BoundImportsSize resd 1 + .IATVA resd 1 + .IATSize resd 1 +endstruc \ No newline at end of file diff -Nru gluegen2-2.2.4/src/native/tinype-corkami/tiny-simple.asm gluegen2-2.3.2/src/native/tinype-corkami/tiny-simple.asm --- gluegen2-2.2.4/src/native/tinype-corkami/tiny-simple.asm 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/src/native/tinype-corkami/tiny-simple.asm 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,102 @@ +; a 268-byte PE (as small as possible), XP-W8x64 compatible + +; similar with the w7 x64 PE, but larger sizeofimage and IAT required. XP compat also requires Debug Size and TLS VA to be null +; a few extra tricks required for Windows 8 compatibility + +;Ange Albertini, BSD Licence, 2010-2013 + +%include 'consts.inc' + +IMAGEBASE equ 400000h + +org IMAGEBASE + +DOS_HEADER: +.e_magic dw 'MZ' + +align 4, db 0 + +istruc IMAGE_NT_HEADERS + at IMAGE_NT_HEADERS.Signature, db 'PE',0,0 +iend +istruc IMAGE_FILE_HEADER + at IMAGE_FILE_HEADER.Machine, dw IMAGE_FILE_MACHINE_I386 + at IMAGE_FILE_HEADER.TimeDateStamp + at IMAGE_FILE_HEADER.Characteristics, dw IMAGE_FILE_EXECUTABLE_IMAGE ; | IMAGE_FILE_32BIT_MACHINE + +iend + +istruc IMAGE_OPTIONAL_HEADER32 + at IMAGE_OPTIONAL_HEADER32.Magic, dw IMAGE_NT_OPTIONAL_HDR32_MAGIC +bits 32 + +realEntryPoint: + push byte 0 + pop eax + ret + at IMAGE_OPTIONAL_HEADER32.AddressOfEntryPoint, dd EntryPoint - IMAGEBASE + at IMAGE_OPTIONAL_HEADER32.BaseOfCode, dd 0 ; must be valid for W7 + at IMAGE_OPTIONAL_HEADER32.ImageBase, dd IMAGEBASE + at IMAGE_OPTIONAL_HEADER32.SectionAlignment, dd 4 ; also sets e_lfanew + at IMAGE_OPTIONAL_HEADER32.FileAlignment, dd 4 + +ImportsAddressTable: + dd 0 +IMPORTSADDRESSTABLESIZE equ $ - ImportsAddressTable + + at IMAGE_OPTIONAL_HEADER32.MajorSubsystemVersion, dw 4 + at IMAGE_OPTIONAL_HEADER32.SizeOfImage, dd SIZEOFIMAGE + at IMAGE_OPTIONAL_HEADER32.SizeOfHeaders, dd SIZEOFIMAGE - 5 ; W8 enforce SizeOfHeaders <= EntryPoint + at IMAGE_OPTIONAL_HEADER32.Subsystem, db IMAGE_SUBSYSTEM_WINDOWS_CUI + +db 0 ; one byte delta to avoid setting DllCharacteristics to AppContainer + + at IMAGE_OPTIONAL_HEADER32.NumberOfRvaAndSizes, dd 13 +iend + +istruc IMAGE_DATA_DIRECTORY_13 + + at IMAGE_DATA_DIRECTORY_13.ImportsVA, dd Import_Descriptor - IMAGEBASE + +Import_Descriptor: +istruc IMAGE_IMPORT_DESCRIPTOR +iend + at IMAGE_DATA_DIRECTORY_13.DebugSize, dd 0 ; required for safety under XP + + at IMAGE_DATA_DIRECTORY_13.TLSVA, dd 0 ; required for safety under XP + + at IMAGE_DATA_DIRECTORY_13.IATVA, dd ImportsAddressTable - IMAGEBASE ; required under XP + at IMAGE_DATA_DIRECTORY_13.IATSize, dd IMPORTSADDRESSTABLESIZE ; required under XP +iend + +message db "JogAmp Windows TinyPE Universal", 0ah, 0 + +times 268 - 266 db 0 +EntryPoint: + jmp realEntryPoint + +SIZEOFIMAGE equ 268 + +struc IMAGE_DATA_DIRECTORY_13 + .ExportsVA resd 1 + .ExportsSize resd 1 + .ImportsVA resd 1 + .ImportsSize resd 1 + .ResourceVA resd 1 + .ResourceSize resd 1 + .Exception resd 2 + .Security resd 2 + .FixupsVA resd 1 + .FixupsSize resd 1 + .DebugVA resd 1 + .DebugSize resd 1 + .Description resd 2 + .MIPS resd 2 + .TLSVA resd 1 + .TLSSize resd 1 + .Load resd 2 + .BoundImportsVA resd 1 + .BoundImportsSize resd 1 + .IATVA resd 1 + .IATSize resd 1 +endstruc diff -Nru gluegen2-2.2.4/src/native/unix/UnixDynamicLinkerImpl_JNI.c gluegen2-2.3.2/src/native/unix/UnixDynamicLinkerImpl_JNI.c --- gluegen2-2.2.4/src/native/unix/UnixDynamicLinkerImpl_JNI.c 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/native/unix/UnixDynamicLinkerImpl_JNI.c 2015-10-09 04:18:28.000000000 +0000 @@ -13,49 +13,63 @@ #define RTLD_DEFAULT ((void *) 0) #endif -/* Java->C glue code: - * Java package: jogamp.common.os.UnixDynamicLinkerImpl - * Java method: int dlclose(long arg0) - * C function: int dlclose(void * ); +// #define DEBUG_DLOPEN 1 + +#ifdef DEBUG_DLOPEN + typedef void *(*DLOPEN_FPTR_TYPE)(const char *filename, int flag); + #define VERBOSE_ON 1 +#endif + +// #define VERBOSE_ON 1 + +#ifdef VERBOSE_ON + #ifdef ANDROID + #include + #define DBG_PRINT(...) __android_log_print(ANDROID_LOG_DEBUG, "JogAmp", __VA_ARGS__) + #else + #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) + #endif +#else + #define DBG_PRINT(...) +#endif + +/* + * Class: jogamp_common_os_UnixDynamicLinkerImpl + * Method: dlclose + * Signature: (J)I */ JNIEXPORT jint JNICALL -Java_jogamp_common_os_UnixDynamicLinkerImpl_dlclose__J(JNIEnv *env, jclass _unused, jlong arg0) { +Java_jogamp_common_os_UnixDynamicLinkerImpl_dlclose(JNIEnv *env, jclass _unused, jlong arg0) { int _res; _res = dlclose((void *) (intptr_t) arg0); return _res; } -/* Java->C glue code: - * Java package: jogamp.common.os.UnixDynamicLinkerImpl - * Java method: java.lang.String dlerror() - * C function: char * dlerror(void); +/* + * Class: jogamp_common_os_UnixDynamicLinkerImpl + * Method: dlerror + * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL -Java_jogamp_common_os_UnixDynamicLinkerImpl_dlerror__(JNIEnv *env, jclass _unused) { +Java_jogamp_common_os_UnixDynamicLinkerImpl_dlerror(JNIEnv *env, jclass _unused) { char * _res; _res = dlerror(); if (_res == NULL) return NULL; return (*env)->NewStringUTF(env, _res); } -// #define DEBUG_DLOPEN 1 - -#ifdef DEBUG_DLOPEN - typedef void *(*DLOPEN_FPTR_TYPE)(const char *filename, int flag); -#endif - -/* Java->C glue code: - * Java package: jogamp.common.os.UnixDynamicLinkerImpl - * Java method: long dlopen(java.lang.String arg0, int arg1) - * C function: void * dlopen(const char * , int); +/* + * Class: jogamp_common_os_UnixDynamicLinkerImpl + * Method: dlopen + * Signature: (Ljava/lang/String;I)J */ JNIEXPORT jlong JNICALL -Java_jogamp_common_os_UnixDynamicLinkerImpl_dlopen__Ljava_lang_String_2I(JNIEnv *env, jclass _unused, jstring arg0, jint arg1) { +Java_jogamp_common_os_UnixDynamicLinkerImpl_dlopen(JNIEnv *env, jclass _unused, jstring arg0, jint arg1) { const char* _UTF8arg0 = NULL; void * _res; #ifdef DEBUG_DLOPEN DLOPEN_FPTR_TYPE dlopenFunc = NULL; - fprintf(stderr, "XXX dlopen.0\n"); + DBG_PRINT("XXX dlopen.0\n"); #endif if (arg0 != NULL) { @@ -70,9 +84,9 @@ } #ifdef DEBUG_DLOPEN dlopenFunc = (DLOPEN_FPTR_TYPE) dlsym(RTLD_DEFAULT, "dlopen"); - fprintf(stderr, "XXX dlopen.1: lib %s, dlopen-fptr %p %p (%d)\n", _UTF8arg0, dlopen, dlopenFunc, dlopen==dlopenFunc); fflush(stderr); + DBG_PRINT("XXX dlopen.1: lib %s, dlopen-fptr %p %p (%d)\n", _UTF8arg0, dlopen, dlopenFunc, dlopen==dlopenFunc); _res = dlopen((char *) _UTF8arg0, (int) arg1); - fprintf(stderr, "XXX dlopen.2: %p\n", _res); fflush(stderr); + DBG_PRINT("XXX dlopen.2: %p\n", _res); #else _res = dlopen((char *) _UTF8arg0, (int) arg1); #endif @@ -80,19 +94,18 @@ (*env)->ReleaseStringUTFChars(env, arg0, _UTF8arg0); } #ifdef DEBUG_DLOPEN - fprintf(stderr, "XXX dlopen.X\n"); fflush(stderr); + DBG_PRINT("XXX dlopen.X\n"); #endif return (jlong) (intptr_t) _res; } - -/* Java->C glue code: - * Java package: jogamp.common.os.UnixDynamicLinkerImpl - * Java method: long dlsym(long arg0, java.lang.String arg1) - * C function: void * dlsym(void * , const char * ); +/* + * Class: jogamp_common_os_UnixDynamicLinkerImpl + * Method: dlsym + * Signature: (JLjava/lang/String;)J */ JNIEXPORT jlong JNICALL -Java_jogamp_common_os_UnixDynamicLinkerImpl_dlsym__JLjava_lang_String_2(JNIEnv *env, jclass _unused, jlong arg0, jstring arg1) { +Java_jogamp_common_os_UnixDynamicLinkerImpl_dlsym(JNIEnv *env, jclass _unused, jlong arg0, jstring arg1) { const char* _UTF8arg1 = NULL; void * _res; if (arg1 != NULL) { @@ -106,10 +119,11 @@ } } _res = dlsym((void *) (intptr_t) arg0, (char *) _UTF8arg1); + DBG_PRINT("XXX dlsym: handle %p, symbol %s -> %p\n", (void *) (intptr_t) arg0, _UTF8arg1, _res); + if (arg1 != NULL) { (*env)->ReleaseStringUTFChars(env, arg1, _UTF8arg1); } return (jlong) (intptr_t) _res; } - diff -Nru gluegen2-2.2.4/src/native/windows/WindowsDynamicLinkerImpl_JNI.c gluegen2-2.3.2/src/native/windows/WindowsDynamicLinkerImpl_JNI.c --- gluegen2-2.2.4/src/native/windows/WindowsDynamicLinkerImpl_JNI.c 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/src/native/windows/WindowsDynamicLinkerImpl_JNI.c 2015-10-09 04:18:28.000000000 +0000 @@ -24,7 +24,7 @@ * C function: BOOL FreeLibrary(HANDLE hLibModule); */ JNIEXPORT jint JNICALL -Java_jogamp_common_os_WindowsDynamicLinkerImpl_FreeLibrary__J(JNIEnv *env, jclass _unused, jlong hLibModule) { +Java_jogamp_common_os_WindowsDynamicLinkerImpl_FreeLibrary(JNIEnv *env, jclass _unused, jlong hLibModule) { BOOL _res; _res = FreeLibrary((HANDLE) (intptr_t) hLibModule); return _res; @@ -37,7 +37,7 @@ * C function: DWORD GetLastError(void); */ JNIEXPORT jint JNICALL -Java_jogamp_common_os_WindowsDynamicLinkerImpl_GetLastError__(JNIEnv *env, jclass _unused) { +Java_jogamp_common_os_WindowsDynamicLinkerImpl_GetLastError(JNIEnv *env, jclass _unused) { DWORD _res; _res = GetLastError(); return _res; @@ -50,7 +50,7 @@ * C function: PROC GetProcAddressA(HANDLE hModule, LPCSTR lpProcName); */ JNIEXPORT jlong JNICALL -Java_jogamp_common_os_WindowsDynamicLinkerImpl_GetProcAddressA__JLjava_lang_String_2(JNIEnv *env, jclass _unused, jlong hModule, jstring lpProcName) { +Java_jogamp_common_os_WindowsDynamicLinkerImpl_GetProcAddressA(JNIEnv *env, jclass _unused, jlong hModule, jstring lpProcName) { const char* _strchars_lpProcName = NULL; PROC _res; if (lpProcName != NULL) { @@ -75,7 +75,7 @@ * C function: HANDLE LoadLibraryW(LPCWSTR lpLibFileName); */ JNIEXPORT jlong JNICALL -Java_jogamp_common_os_WindowsDynamicLinkerImpl_LoadLibraryW__Ljava_lang_String_2(JNIEnv *env, jclass _unused, jstring lpLibFileName) { +Java_jogamp_common_os_WindowsDynamicLinkerImpl_LoadLibraryW(JNIEnv *env, jclass _unused, jstring lpLibFileName) { jchar* _strchars_lpLibFileName = NULL; HANDLE _res; if (lpLibFileName != NULL) { diff -Nru gluegen2-2.2.4/test/native/sizeof_dump.c gluegen2-2.3.2/test/native/sizeof_dump.c --- gluegen2-2.2.4/test/native/sizeof_dump.c 1970-01-01 00:00:00.000000000 +0000 +++ gluegen2-2.3.2/test/native/sizeof_dump.c 2015-10-09 04:18:28.000000000 +0000 @@ -0,0 +1,18 @@ +#include +#include +#include + +int main(int argc, const char ** argv) { + printf("sizeof int: %lu\n", sizeof(int)); + printf("sizeof long: %lu\n", sizeof(long)); + printf("sizeof long long: %lu\n", sizeof(long long)); + printf("sizeof intptr_t: %lu\n", sizeof(intptr_t)); + printf("sizeof uintptr_t: %lu\n", sizeof(uintptr_t)); + printf("sizeof ptrdiff_t: %lu\n", sizeof(ptrdiff_t)); + printf("sizeof size_t: %lu\n", sizeof(size_t)); + printf("sizeof float: %lu\n", sizeof(float)); + printf("sizeof double: %lu\n", sizeof(double)); + printf("sizeof long double: %lu\n", sizeof(long double)); + + return 0; +} diff -Nru gluegen2-2.2.4/www/index.html gluegen2-2.3.2/www/index.html --- gluegen2-2.2.4/www/index.html 2014-10-10 13:20:51.000000000 +0000 +++ gluegen2-2.3.2/www/index.html 2015-10-09 04:18:28.000000000 +0000 @@ -53,7 +53,8 @@

    GlueGen is currently used for the projects - JOGL, JOCL and + JOGL, + JOCL and JOAL.