From 1754f08ec0fb62ecd23f1ec3ec7c94da9a44de7a Mon Sep 17 00:00:00 2001
From: Kenneth Russel <kbrussel@alum.mit.edu>
Date: Sun, 28 May 2006 00:33:56 +0000
Subject: Fixed and improved handling of Opaque directives for multiple pointer
 depths in particular to fix AGLPbuffer case supplied by Justin Couch. Tested
 with builds on Windows, Linux and Mac OS X and AGL test case.

git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/../svn-server-sync/gluegen/trunk@33 a78bb65f-1512-4460-ba86-f6dc96a7bf27
---
 src/java/com/sun/gluegen/JavaConfiguration.java    | 111 ++++++++++++++++++---
 .../com/sun/gluegen/JavaMethodBindingEmitter.java  |   2 +-
 src/java/com/sun/gluegen/MethodBinding.java        |   5 +-
 3 files changed, 100 insertions(+), 18 deletions(-)

(limited to 'src/java/com')

diff --git a/src/java/com/sun/gluegen/JavaConfiguration.java b/src/java/com/sun/gluegen/JavaConfiguration.java
index 39c1bf3..7488a30 100644
--- a/src/java/com/sun/gluegen/JavaConfiguration.java
+++ b/src/java/com/sun/gluegen/JavaConfiguration.java
@@ -40,6 +40,7 @@
 package com.sun.gluegen;
 
 import java.io.*;
+import java.lang.reflect.Array;
 import java.util.*;
 import java.util.regex.*;
 
@@ -252,6 +253,7 @@ public class JavaConfiguration {
   /** Returns the list of imports that should be emitted at the top of each .java file. */
   public List/*<String>*/ imports()                  { return imports; }
 
+  private static final boolean DEBUG_TYPE_INFO = false;
   /** If this type should be considered opaque, returns the TypeInfo
       describing the replacement type. Returns null if this type
       should not be considered opaque. */
@@ -259,16 +261,24 @@ public class JavaConfiguration {
     // 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);
     int pointerDepth = type.pointerDepth();
     for (int i = 0; i <= pointerDepth; i++) {
       String name = type.getName();
+      if (DEBUG_TYPE_INFO) {
+        System.err.println(" Type = " + type);
+        System.err.println(" Name = " + name);
+      }
       if (name != null) {
-        TypeInfo info = (TypeInfo) typeInfoMap.get(name);
-        while (info != null) {
-          if (info.name().equals(name) && info.pointerDepth() == i) {
-            return info;
+        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());
           }
-          info = info.next();
+          return promoteTypeInfo(info, i);
         }
       }
 
@@ -276,12 +286,14 @@ public class JavaConfiguration {
         // Try struct name as well
         name = type.asCompound().getStructName();
         if (name != null) {
-          TypeInfo info = (TypeInfo) typeInfoMap.get(name);
-          while (info != null) {
-            if (info.name().equals(name) && info.pointerDepth() == i) {
-              return info;
+          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());
             }
-            info = info.next();
+            return promoteTypeInfo(info, i);
           }
         }
       }
@@ -293,12 +305,17 @@ public class JavaConfiguration {
         // "eq" equality is OK to use here since all types have been canonicalized
         if (entry.getValue() == type) {
           name = (String) entry.getKey();
-          TypeInfo info = (TypeInfo) typeInfoMap.get(name);
-          while (info != null) {
-            if (info.name().equals(name) && info.pointerDepth() == i) {
-              return info;
+          if (DEBUG_TYPE_INFO) {
+            System.err.println("Looking under typedef name " + name);
+          }
+          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());
             }
-            info = info.next();
+            return promoteTypeInfo(info, i);
           }
         }
       }
@@ -311,6 +328,68 @@ public class JavaConfiguration {
     return null;
   }
 
+  // Helper functions for above
+  private TypeInfo closestTypeInfo(String name, int pointerDepth) {
+    TypeInfo info = (TypeInfo) typeInfoMap.get(name);
+    TypeInfo closest = null;
+    while (info != null) {
+      if (DEBUG_TYPE_INFO)
+        System.err.println("  Checking TypeInfo for " + name + " at pointerDepth " + pointerDepth);
+      if (info.pointerDepth() <= pointerDepth &&
+          (closest == null ||
+           info.pointerDepth() > closest.pointerDepth())) {
+        if (DEBUG_TYPE_INFO)
+          System.err.println("   Accepted");
+        closest = info;
+      }
+      info = info.next();
+    }
+    return closest;
+  }
+
+  // Promotes a TypeInfo to a higher pointer type (if necessary)
+  private TypeInfo promoteTypeInfo(TypeInfo info, int numPointersStripped) {
+    int diff = numPointersStripped - info.pointerDepth();
+    if (diff == 0) {
+      return info;
+    }
+
+    if (diff < 0) {
+      throw new RuntimeException("TypeInfo for " + info.name() + " and pointerDepth " +
+                                 info.pointerDepth() + " should not have matched for depth " +
+                                 numPointersStripped);
+    }
+
+    Class c = info.javaType().getJavaClass();
+    int pd = info.pointerDepth();
+
+    // Handle single-pointer stripping for types compatible with C
+    // integral and floating-point types specially so we end up
+    // generating NIO variants for these
+    if (diff == 1) {
+      JavaType jt = null;
+      if      (c == Boolean.TYPE) jt = JavaType.createForCCharPointer();
+      else if (c == Byte.TYPE)    jt = JavaType.createForCCharPointer();
+      else if (c == Short.TYPE)   jt = JavaType.createForCShortPointer();
+      else if (c == Integer.TYPE) jt = JavaType.createForCInt32Pointer();
+      else if (c == Long.TYPE)    jt = JavaType.createForCInt64Pointer();
+      else if (c == Float.TYPE)   jt = JavaType.createForCFloatPointer();
+      else if (c == Double.TYPE)  jt = JavaType.createForCDoublePointer();
+
+      if (jt != null) 
+        return new TypeInfo(info.name(), pd + numPointersStripped, jt);
+    }
+
+    while (diff > 0) {
+      c = Array.newInstance(c, 0).getClass();
+      --diff;
+    }
+    
+    return new TypeInfo(info.name(),
+                        numPointersStripped,
+                        JavaType.createForClass(c));
+  }
+
   /** Indicates whether the given function (which returns a
       <code>char*</code> in C) should be translated as returning a
       <code>java.lang.String</code>. */
@@ -748,7 +827,7 @@ public class JavaConfiguration {
 
   protected Class stringToPrimitiveType(String type) throws ClassNotFoundException {
     if (type.equals("boolean")) return Boolean.TYPE;
-    if (type.equals("byte"))    return Integer.TYPE;
+    if (type.equals("byte"))    return Byte.TYPE;
     if (type.equals("char"))    return Character.TYPE;
     if (type.equals("short"))   return Short.TYPE;
     if (type.equals("int"))     return Integer.TYPE;
diff --git a/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java b/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java
index b08d0e4..87b9521 100644
--- a/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java
+++ b/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java
@@ -602,7 +602,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
         } else {
           throw new RuntimeException("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 " + getName());
         }
         writer.print(offsetArgName(i));
       }
diff --git a/src/java/com/sun/gluegen/MethodBinding.java b/src/java/com/sun/gluegen/MethodBinding.java
index b8ebb09..f8a4d2c 100644
--- a/src/java/com/sun/gluegen/MethodBinding.java
+++ b/src/java/com/sun/gluegen/MethodBinding.java
@@ -354,7 +354,10 @@ public class MethodBinding {
       }
 
       if (cArgType.isPointer()) {
-        if (cArgType.asPointer().getTargetType().isPrimitive()) {
+        // Handle both real C primitive pointers and any constructions
+        // due to opaque directives
+        if (cArgType.asPointer().getTargetType().isPrimitive() ||
+            javaArgType.isCPrimitivePointerType()) {
           signatureUsesCPrimitivePointers = true;
         } else if (cArgType.asPointer().getTargetType().isVoid()) {
           signatureUsesCVoidPointers = true;
-- 
cgit v1.2.3