public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
From: cagney@sourceware.org
To: frysk-cvs@sourceware.org
Subject: [SCM]  master: Add char** strings2chars(String) and String chars2strings(char**).
Date: Fri, 09 May 2008 13:40:00 -0000	[thread overview]
Message-ID: <20080509134020.29754.qmail@sourceware.org> (raw)

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


                 reply	other threads:[~2008-05-09 13:40 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080509134020.29754.qmail@sourceware.org \
    --to=cagney@sourceware.org \
    --cc=frysk-cvs@sourceware.org \
    --cc=frysk@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).