public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
* [SCM]  master: Add char** strings2chars(String) and String chars2strings(char**).
@ 2008-05-09 13:40 cagney
  0 siblings, 0 replies; only message in thread
From: cagney @ 2008-05-09 13:40 UTC (permalink / raw)
  To: frysk-cvs

The branch, master has been updated
       via  dcceec6534cd5e28eca8dccc095f4c44113d9160 (commit)
      from  776b3cd28bc6c5bfecf4fec01b1d0a7d53445d48 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit dcceec6534cd5e28eca8dccc095f4c44113d9160
Author: Andrew Cagney <cagney@redhat.com>
Date:   Fri May 9 09:29:38 2008 -0400

    Add char** strings2chars(String) and String chars2strings(char**).
    
    frysk-sys/frysk/jnixx/ChangeLog
    2008-05-09  Andrew Cagney  <cagney@redhat.com>
    
    	* Main.java (treatAsNative(Method)): New.
    	(treatAsPrivate(Member)): New.
    	* PrintDeclarations.java: Use.
    	* PrintHxxDefinitions.java: Use.
    	* PrintCxxDefinitions.java: Use; Extend ClassWalker.
    	* TestJnixx.java (testCharsConversion()): New.
    	* chars.hxx: New.
    	* chars.cxx: .New.
    	* jni/Native.cxx (Native::copy): New.
    	* cni/Native.cxx (Native::copy): New.

-----------------------------------------------------------------------

Summary of changes:
 frysk-sys/frysk/jnixx/ChangeLog                  |   13 ++
 frysk-sys/frysk/jnixx/ClassVisitor.java          |    4 +
 frysk-sys/frysk/jnixx/Main.java                  |   45 +++++-
 frysk-sys/frysk/jnixx/Native.java                |    1 +
 frysk-sys/frysk/jnixx/PrintCxxDefinitions.java   |  168 ++++++++++++----------
 frysk-sys/frysk/jnixx/PrintDeclarations.java     |    2 +-
 frysk-sys/frysk/jnixx/PrintHxxDefinitions.java   |    2 +-
 frysk-sys/frysk/jnixx/TestJnixx.java             |    6 +
 frysk-sys/frysk/jnixx/{Main.java => chars.cxx}   |   87 ++++++-----
 frysk-sys/frysk/jnixx/{Native.java => chars.hxx} |   10 +-
 frysk-sys/frysk/jnixx/cni/Native.cxx             |    5 +
 frysk-sys/frysk/jnixx/jni/Native.cxx             |   13 ++
 12 files changed, 228 insertions(+), 128 deletions(-)
 copy frysk-sys/frysk/jnixx/{Main.java => chars.cxx} (56%)
 copy frysk-sys/frysk/jnixx/{Native.java => chars.hxx} (92%)

First 500 lines of diff:
diff --git a/frysk-sys/frysk/jnixx/ChangeLog b/frysk-sys/frysk/jnixx/ChangeLog
index d3758c1..c527462 100644
--- a/frysk-sys/frysk/jnixx/ChangeLog
+++ b/frysk-sys/frysk/jnixx/ChangeLog
@@ -1,3 +1,16 @@
+2008-05-09  Andrew Cagney  <cagney@redhat.com>
+
+	* Main.java (treatAsNative(Method)): New.
+	(treatAsPrivate(Member)): New.
+	* PrintDeclarations.java: Use.
+	* PrintHxxDefinitions.java: Use.
+	* PrintCxxDefinitions.java: Use; Extend ClassWalker.
+	* TestJnixx.java (testCharsConversion()): New.
+	* chars.hxx: New.
+	* chars.cxx: .New.
+	* jni/Native.cxx (Native::copy): New.
+	* cni/Native.cxx (Native::copy): New.
+
 2008-05-08  Andrew Cagney  <cagney@redhat.com>
 
 	* jnixx.hxx (jnixx::env): Fill in missing JNI bindings; match JNI
diff --git a/frysk-sys/frysk/jnixx/ClassVisitor.java b/frysk-sys/frysk/jnixx/ClassVisitor.java
index 20f34e2..6520b2d 100644
--- a/frysk-sys/frysk/jnixx/ClassVisitor.java
+++ b/frysk-sys/frysk/jnixx/ClassVisitor.java
@@ -67,6 +67,8 @@ abstract class ClassVisitor {
 	    Field field = fields[i];
 	    if (field.isSynthetic())
 		continue;
+	    if (Main.treatAsInvisible(field))
+		continue;
 	    acceptField(field);
 	}
 	Method[] methods = klass.getDeclaredMethods();
@@ -74,6 +76,8 @@ abstract class ClassVisitor {
 	    Method method = methods[i];
 	    if (method.isSynthetic())
 		continue;
+	    if (Main.treatAsInvisible(method))
+		continue;
 	    acceptMethod(method);
 	}
 	Class[] classes = klass.getClasses();
diff --git a/frysk-sys/frysk/jnixx/Main.java b/frysk-sys/frysk/jnixx/Main.java
index 97ccadc..aeb1b19 100644
--- a/frysk-sys/frysk/jnixx/Main.java
+++ b/frysk-sys/frysk/jnixx/Main.java
@@ -40,9 +40,45 @@
 package frysk.jnixx;
 
 import java.io.PrintWriter;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Member;
 
 class Main {
 
+    /**
+     * Does this method require native bindings?  Methods that are not
+     * part of this JNI library, that are native, must be treated as
+     * virtual.
+     */
+    static boolean treatAsNative(Method method) {
+	// FIXME: Should be filtering based on something smarter than
+	// this.
+	if (method.getDeclaringClass().getName().startsWith("java."))
+	    return false;
+	if (method.getDeclaringClass().getName().startsWith("gnu."))
+	    return false;
+	if (Modifier.isNative(method.getModifiers()))
+	    return true;
+	return false;
+    }
+
+    /**
+     * Is the member visible to this generated JNI code.  Private
+     * methods and fileds and the java package are not visible.
+     */
+    static boolean treatAsInvisible(Member member) {
+	if (Modifier.isPrivate(member.getModifiers())) {
+	    // FIXME: Should be filtering based on something smarter
+	    // than is.
+	    if (member.getDeclaringClass().getName().startsWith("java."))
+		return true;
+	    if (member.getDeclaringClass().getName().startsWith("gnu."))
+		return true;
+	}
+	return false;
+    }
+
     private static void printHxxFile(Printer p, Class[] classes) {
 	p.println("#include \"frysk/jnixx/jnixx.hxx\"");
 	new PrintNamespaces(p).walk(classes);
@@ -53,12 +89,9 @@ class Main {
     private static void printCxxFile(Printer p, Class[] classes) {
 	printHxxFile(p, classes); // #include
 	p.println();
-	for (int i = 0; i < classes.length; i++) {
-	    p.print("jclass ");
-	    p.printQualifiedCxxName(classes[i]);
-	    p.println("::_class;");
-	}
-	new PrintCxxDefinitions(p).visit(classes);
+	p.println("\f");
+	p.println();
+	new PrintCxxDefinitions(p).walk(classes);
     }
 
     public static void main(String[] args) throws ClassNotFoundException {
diff --git a/frysk-sys/frysk/jnixx/Native.java b/frysk-sys/frysk/jnixx/Native.java
index 49614bd..066470b 100644
--- a/frysk-sys/frysk/jnixx/Native.java
+++ b/frysk-sys/frysk/jnixx/Native.java
@@ -43,4 +43,5 @@ class Native {
     static native boolean isJni();
     static native int sizeOfJnixxEnv();
     static native int sizeOfJnixxObject();
+    static native String[] copy(String[] strings);
 }
diff --git a/frysk-sys/frysk/jnixx/PrintCxxDefinitions.java b/frysk-sys/frysk/jnixx/PrintCxxDefinitions.java
index 0958db6..1e8be54 100644
--- a/frysk-sys/frysk/jnixx/PrintCxxDefinitions.java
+++ b/frysk-sys/frysk/jnixx/PrintCxxDefinitions.java
@@ -44,103 +44,123 @@ import java.lang.reflect.Field;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Modifier;
 
-class PrintCxxDefinitions extends ClassVisitor {
+class PrintCxxDefinitions extends ClassWalker {
 
     private final Printer p;
     PrintCxxDefinitions(Printer p) {
 	this.p = p;
     }
 
+    private ClassVisitor printer = new ClassVisitor() {
 
-    private void printNativeMethodDefinition(Method method) {
-	boolean isStatic = Modifier.isStatic(method.getModifiers());
-	p.println();
-	while (p.dent(0, "extern \"C\" {", "};")) {
-	    p.print("JNIEXPORT ");
-	    p.printJniType(method.getReturnType());
-	    p.print(" JNICALL ");
-	    p.printJniName(method);
-	    p.print("(");
-	    p.printFormalJniParameters(method, false);
-	    p.println(");");
-	}
-	p.println();
-	p.printJniType(method.getReturnType());
-	p.println();
-	p.printJniName(method);
-	p.print("(");
-	p.printFormalJniParameters(method, true);
-	p.print(")");
-	while (p.dent(0, "{", "};")) {
-	    p.println("try {");
-	    {
-		p.indent();
-		p.println("::jnixx::env _env = ::jnixx::env(_jni);");
-		Class returnType = method.getReturnType();
-		if (returnType != Void.TYPE) {
-		    p.printCxxType(returnType);
-		    p.print(" ret = ");
-		}
-		if (isStatic) {
-		    p.printQualifiedCxxName(method);
-		} else {
-		    p.printCxxType(method.getDeclaringClass());
-		    p.print("(object).");
-		    p.print(method.getName());
+	    private void printNativeMethodDefinition(Method method) {
+		boolean isStatic = Modifier.isStatic(method.getModifiers());
+		p.println();
+		while (p.dent(0, "extern \"C\" {", "};")) {
+		    p.print("JNIEXPORT ");
+		    p.printJniType(method.getReturnType());
+		    p.print(" JNICALL ");
+		    p.printJniName(method);
+		    p.print("(");
+		    p.printFormalJniParameters(method, false);
+		    p.println(");");
 		}
+		p.println();
+		p.printJniType(method.getReturnType());
+		p.println();
+		p.printJniName(method);
 		p.print("(");
-		p.printActualCxxParameters(method);
-		p.println(");");
-		if (returnType != Void.TYPE) {
-		    p.print("return ");
-		    if (returnType.isPrimitive()) {
-			p.print("ret");
-		    } else if (returnType == String.class) {
-			p.print("(jstring) ret._object");
-		    } else if (returnType.isArray()) {
-			if (returnType.getComponentType().isPrimitive()) {
-			    p.print("ret");
+		p.printFormalJniParameters(method, true);
+		p.print(")");
+		while (p.dent(0, "{", "};")) {
+		    p.println("try {");
+		    {
+			p.indent();
+			p.println("::jnixx::env _env = ::jnixx::env(_jni);");
+			Class returnType = method.getReturnType();
+			if (returnType != Void.TYPE) {
+			    p.printCxxType(returnType);
+			    p.print(" ret = ");
+			}
+			if (isStatic) {
+			    p.printQualifiedCxxName(method);
 			} else {
-			    p.print("(jobjectArray) ret._object");
+			    p.printCxxType(method.getDeclaringClass());
+			    p.print("(object).");
+			    p.print(method.getName());
+			}
+			p.print("(");
+			p.printActualCxxParameters(method);
+			p.println(");");
+			if (returnType != Void.TYPE) {
+			    p.print("return ");
+			    if (returnType.isPrimitive()) {
+				p.print("ret");
+			    } else if (returnType == String.class) {
+				p.print("(jstring) ret._object");
+			    } else if (returnType.isArray()) {
+				if (returnType.getComponentType().isPrimitive()) {
+				    p.print("ret");
+				} else {
+				    p.print("(jobjectArray) ret._object");
+				}
+			    } else {
+				p.print("ret._object");
+			    }
+			    p.println(";");
 			}
-		    } else {
-			p.print("ret._object");
+			p.outdent();
 		    }
-		    p.println(";");
+		    p.println("} catch (jnixx::exception) {");
+		    {
+			p.indent();
+			if (method.getReturnType() != Void.TYPE) {
+			    p.println("return 0;");
+			} else {
+			    p.println("return;");
+			}
+			p.outdent();
+		    }
+		    p.println("}");
 		}
-		p.outdent();
 	    }
-	    p.println("} catch (jnixx::exception) {");
-	    {
-		p.indent();
-		if (method.getReturnType() != Void.TYPE) {
-		    p.println("return 0;");
-		} else {
-		    p.println("return;");
+
+	    public void acceptMethod(Method method) {
+		if (Main.treatAsNative(method)) {
+		    printNativeMethodDefinition(method);
 		}
-		p.outdent();
 	    }
-	    p.println("}");
-	}
-    }
+	    void acceptInterface(Class constructor) {
+	    }
+	    void acceptConstructor(Constructor constructor) {
+	    }
+	    void acceptField(Field field) {
+	    }
+	    void acceptComponent(Class klass) {
+	    }
+	    void acceptClass(Class klass) {
+	    }
+	};
 
-    public void acceptMethod(Method method) {
-	if (Modifier.isNative(method.getModifiers())) {
-	    printNativeMethodDefinition(method);
-	}
+    void acceptArray(Class klass) {
+	acceptClass(klass);
     }
-    void acceptInterface(Class constructor) {
-    }
-    void acceptConstructor(Constructor constructor) {
-    }
-    void acceptField(Field field) {
-    }
-    void acceptComponent(Class klass) {
+    void acceptPrimitive(Class klass) {
+	acceptClass(klass);
     }
     void acceptClass(Class klass) {
+	if (klass.isPrimitive())
+	    return;
+	if (klass.isArray())
+	    return;
 	p.println();
 	p.print("jclass ");
 	p.printQualifiedCxxName(klass);
 	p.println("::_class;");
+	printer.visit(klass);
+    }
+    void acceptInterface(Class klass) {
+	acceptClass(klass);
     }
 }
+
diff --git a/frysk-sys/frysk/jnixx/PrintDeclarations.java b/frysk-sys/frysk/jnixx/PrintDeclarations.java
index 86b57d3..32c9b34 100644
--- a/frysk-sys/frysk/jnixx/PrintDeclarations.java
+++ b/frysk-sys/frysk/jnixx/PrintDeclarations.java
@@ -105,7 +105,7 @@ class PrintDeclarations extends ClassWalker {
 		if (Modifier.isStatic(method.getModifiers())) {
 		    p.print("static ");
 		}
-		if (!Modifier.isNative(method.getModifiers())) {
+		if (!Main.treatAsNative(method)) {
 		    p.print("inline ");
 		}
 		p.printCxxType(method.getReturnType());
diff --git a/frysk-sys/frysk/jnixx/PrintHxxDefinitions.java b/frysk-sys/frysk/jnixx/PrintHxxDefinitions.java
index fc7a7c6..8ae9bea 100644
--- a/frysk-sys/frysk/jnixx/PrintHxxDefinitions.java
+++ b/frysk-sys/frysk/jnixx/PrintHxxDefinitions.java
@@ -225,7 +225,7 @@ class PrintHxxDefinitions extends ClassWalker {
 	    }
 
 	    public void acceptMethod(Method method) {
-		if (!Modifier.isNative(method.getModifiers())) {
+		if (!Main.treatAsNative(method)) {
 		    printCxxMethodDefinition(method);
 		}
 	    }
diff --git a/frysk-sys/frysk/jnixx/TestJnixx.java b/frysk-sys/frysk/jnixx/TestJnixx.java
index 5b15f0d..ca08e0b 100644
--- a/frysk-sys/frysk/jnixx/TestJnixx.java
+++ b/frysk-sys/frysk/jnixx/TestJnixx.java
@@ -55,4 +55,10 @@ public class TestJnixx extends TestCase {
 	assertEquals("word-size", Host.wordSize(),
 		     Native.sizeOfJnixxObject() * 8);
     }
+    public void testCharsConversion() {
+	if (unsupported("CNI", !Native.isJni()))
+	    return;
+	String[] strings = new String[] { "arg1", "arg2", "arg3" };
+	assertEquals("converted", strings, Native.copy(strings));
+    }
 }
diff --git a/frysk-sys/frysk/jnixx/Main.java b/frysk-sys/frysk/jnixx/chars.cxx
similarity index 56%
copy from frysk-sys/frysk/jnixx/Main.java
copy to frysk-sys/frysk/jnixx/chars.cxx
index 97ccadc..f81b6e6 100644
--- a/frysk-sys/frysk/jnixx/Main.java
+++ b/frysk-sys/frysk/jnixx/chars.cxx
@@ -37,46 +37,53 @@
 // version and license this file solely under the GPL without
 // exception.
 
-package frysk.jnixx;
+#include "jni.hxx"
+#include <malloc.h>
 
-import java.io.PrintWriter;
-
-class Main {
-
-    private static void printHxxFile(Printer p, Class[] classes) {
-	p.println("#include \"frysk/jnixx/jnixx.hxx\"");
-	new PrintNamespaces(p).walk(classes);
-	new PrintDeclarations(p).walk(classes);
-	new PrintHxxDefinitions(p).walk(classes);
-    }
-
-    private static void printCxxFile(Printer p, Class[] classes) {
-	printHxxFile(p, classes); // #include
-	p.println();
-	for (int i = 0; i < classes.length; i++) {
-	    p.print("jclass ");
-	    p.printQualifiedCxxName(classes[i]);
-	    p.println("::_class;");
-	}
-	new PrintCxxDefinitions(p).visit(classes);
-    }
-
-    public static void main(String[] args) throws ClassNotFoundException {
-	if (args.length < 2) {
-	    throw new RuntimeException("Usage: jnixx cxx}hxx <class-name> ...");
-	}
-
-	Class[] classes = new Class[args.length - 1];
-	for (int i = 0; i < classes.length; i++) {
-	    classes[i] = Class.forName(args[i + 1], false,
-				       Main.class.getClassLoader());
-	}
+char**
+strings2chars(jnixx::env env, ::java::lang::StringArray strings) {
+  jsize arrayLength = env.GetArrayLength((jobjectArray)strings._object);
+  // compute the allocated size.
+  size_t size = 0;
+  size += sizeof(void*); // NULL
+  for (int i = 0; i < arrayLength; i++) {
+    size += sizeof(void*); // pointer
+    jstring string = (jstring) env.GetObjectArrayElement((jobjectArray)strings._object, i);
+    size += env.GetStringUTFLength(string); // chars
+    size += 1; // NUL
+    env.DeleteLocalRef(string);
+  }
+  // Create the array.
+  char **elements = (char**) ::malloc(size);
+  char **argv = elements;
+  // Store strings after the array
+  char *arg = (char*) (argv + arrayLength + 1);
+  // Copy
+  for (int i = 0; i < arrayLength; i++) {
+    *argv++ = arg;
+    jstring string = (jstring)env.GetObjectArrayElement((jobjectArray)strings._object, i);
+    int utfLength = env.GetStringUTFLength(string);
+    env.GetStringUTFRegion(string, 0, env.GetStringLength(string), arg);
+    arg += utfLength;
+    env.DeleteLocalRef(string);
+    *arg++ = '\0';
+  }
+  *argv = NULL;
+  return elements;
+}
 
-	Printer p = new Printer(new PrintWriter(System.out));
-	if (args[0].equals("hxx"))
-	    printHxxFile(p, classes);
-	else
-	    printCxxFile(p, classes);
-	p.flush();
-    }
+::java::lang::StringArray
+chars2strings(::jnixx::env env, char** argv) {
+  int length = 0;
+  for (char **p = argv; *p != NULL; p++) {
+    length++;
+  }
+  jclass stringClass = ::java::lang::String::_class_(env);
+  jobjectArray strings = env.NewObjectArray(length, stringClass, NULL);
+  for (int i = 0; i < length; i++) {
+    jstring string = env.NewStringUTF(argv[i]);
+    env.SetObjectArrayElement(strings, i, string);
+    env.DeleteLocalRef(string);
+  }
+  return strings;
 }
diff --git a/frysk-sys/frysk/jnixx/Native.java b/frysk-sys/frysk/jnixx/chars.hxx
similarity index 92%
copy from frysk-sys/frysk/jnixx/Native.java
copy to frysk-sys/frysk/jnixx/chars.hxx
index 49614bd..a0e5deb 100644
--- a/frysk-sys/frysk/jnixx/Native.java
+++ b/frysk-sys/frysk/jnixx/chars.hxx
@@ -37,10 +37,8 @@
 // version and license this file solely under the GPL without
 // exception.
 
-package frysk.jnixx;
+extern char** strings2chars(jnixx::env env,
+			    ::java::lang::StringArray strings);
 
-class Native {
-    static native boolean isJni();
-    static native int sizeOfJnixxEnv();
-    static native int sizeOfJnixxObject();
-}
+extern ::java::lang::StringArray chars2strings(::jnixx::env env,
+					       char** argv);
diff --git a/frysk-sys/frysk/jnixx/cni/Native.cxx b/frysk-sys/frysk/jnixx/cni/Native.cxx
index 4388148..a8a0852 100644
--- a/frysk-sys/frysk/jnixx/cni/Native.cxx
+++ b/frysk-sys/frysk/jnixx/cni/Native.cxx
@@ -55,3 +55,8 @@ jint
 frysk::jnixx::Native::sizeOfJnixxObject() {
   return -1;
 }
+
+JArray<jstring>*
+frysk::jnixx::Native::copy(JArray<jstring>* strings) {
+  return NULL;
+}
diff --git a/frysk-sys/frysk/jnixx/jni/Native.cxx b/frysk-sys/frysk/jnixx/jni/Native.cxx
index f397aaa..471d4ad 100644


hooks/post-receive
--
frysk system monitor/debugger


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-05-09 13:40 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-09 13:40 [SCM] master: Add char** strings2chars(String) and String chars2strings(char**) cagney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).