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).