From: Richard W.M. Jones Date: Tue, 19 Jul 2011 13:45:11 +0000 (+0100) Subject: java: Fix optional arguments in calls. X-Git-Tag: 1.11.20~5 X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=commitdiff_plain;h=d7da4807e83d4a960daca8f36bbc8a826063b135 java: Fix optional arguments in calls. This also adds tests. --- diff --git a/generator/generator_java.ml b/generator/generator_java.ml index 9cd84d8..4d51c53 100644 --- a/generator/generator_java.ml +++ b/generator/generator_java.ml @@ -106,7 +106,7 @@ public class GuestFS { let doc = replace_str longdesc "C [] then - doc ^ "\n\nOptional arguments are supplied in the final Map parameter, which is a hash of the argument name to its value (cast to Object). Pass an empty Map for no optional arguments." + doc ^ "\n\nOptional arguments are supplied in the final Map parameter, which is a hash of the argument name to its value (cast to Object). Pass an empty Map or null for no optional arguments." else doc in let doc = if List.mem ProtocolLimitWarning flags then @@ -142,6 +142,32 @@ public class GuestFS { pr " if (g == 0)\n"; pr " throw new LibGuestFSException (\"%s: handle is closed\");\n" name; + if optargs <> [] then ( + pr "\n"; + pr " /* Unpack optional args. */\n"; + pr " Object _optobj;\n"; + pr " long _optargs_bitmask = 0;\n"; + iteri ( + fun i argt -> + let t, boxed_t, convert, n, default = + match argt with + | Bool n -> "boolean", "Boolean", ".booleanValue()", n, "false" + | Int n -> "int", "Integer", ".intValue()", n, "0" + | Int64 n -> "long", "Long", ".longValue()", n, "0" + | String n -> "String", "String", "", n, "\"\"" + | _ -> assert false in + pr " %s %s = %s;\n" t n default; + pr " _optobj = null;\n"; + pr " if (optargs != null)\n"; + pr " _optobj = optargs.get (\"%s\");\n" n; + pr " if (_optobj != null) {\n"; + pr " %s = ((%s) _optobj)%s;\n" n boxed_t convert; + pr " _optargs_bitmask |= %Ld;\n" + (Int64.shift_left Int64.one i); + pr " }\n"; + ) optargs + ); + pr "\n"; (match ret with | RErr -> pr " _%s " name; @@ -162,6 +188,7 @@ public class GuestFS { pr ";\n" ); pr " }\n"; + pr "\n"; pr " "; generate_java_prototype ~privat:true ~native:true name style; pr "\n"; @@ -174,7 +201,10 @@ public class GuestFS { and generate_java_call_args ~handle (_, args, optargs) = pr "(%s" handle; List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args; - if optargs <> [] then pr ", optargs"; + if optargs <> [] then ( + pr ", _optargs_bitmask"; + List.iter (fun arg -> pr ", %s" (name_of_argt arg)) optargs + ); pr ")" and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false) @@ -243,7 +273,21 @@ and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false) if optargs <> [] then ( if !needs_comma then pr ", "; needs_comma := true; - pr "HashMap optargs" + + if not native then + pr "Map optargs" + else ( + pr "long _optargs_bitmask"; + List.iter ( + fun argt -> + match argt with + | Bool n -> pr ", boolean %s" n + | Int n -> pr ", int %s" n + | Int64 n -> pr ", long %s" n + | String n -> pr ", String %s" n + | _ -> assert false + ) optargs + ) ); pr ")\n"; @@ -369,8 +413,17 @@ Java_com_redhat_et_libguestfs_GuestFS__1close | Int64 n | Pointer (_, n) -> pr ", jlong j%s" n ) args; - if optargs <> [] then - pr ", jobject joptargs"; + if optargs <> [] then ( + pr ", jlong joptargs_bitmask"; + List.iter ( + function + | Bool n -> pr ", jboolean j%s" n + | Int n -> pr ", jint j%s" n + | Int64 n -> pr ", jlong j%s" n + | String n -> pr ", jstring j%s" n + | _ -> assert false + ) optargs + ); pr ")\n"; pr "{\n"; pr " guestfs_h *g = (guestfs_h *) (long) jg;\n"; @@ -484,10 +537,20 @@ Java_com_redhat_et_libguestfs_GuestFS__1close ) args; if optargs <> [] then ( - (* XXX *) - pr " throw_exception (env, \"%s: internal error: please let us know how to read a Java HashMap parameter from JNI bindings!\");\n" name; - pr " return NULL;\n"; - pr " /*\n"; + pr " struct guestfs_%s_argv optargs_s;\n" name; + pr " const struct guestfs_%s_argv *optargs = &optargs_s;\n" name; + pr " optargs_s.bitmask = joptargs_bitmask;\n"; + List.iter ( + function + | Bool n + | Int n + | Int64 n -> + pr " optargs_s.%s = j%s;\n" n n + | String n -> + pr " optargs_s.%s = (*env)->GetStringUTFChars (env, j%s, NULL);\n" + n n + | _ -> assert false + ) optargs; ); (* Make the call. *) @@ -526,6 +589,16 @@ Java_com_redhat_et_libguestfs_GuestFS__1close | Pointer _ -> () ) args; + List.iter ( + function + | Bool n + | Int n + | Int64 n -> () + | String n -> + pr " (*env)->ReleaseStringUTFChars (env, j%s, optargs_s.%s);\n" n n + | _ -> assert false + ) optargs; + (* Check for errors. *) (match errcode_of_ret ret with | `CannotReturnError -> () @@ -593,9 +666,6 @@ Java_com_redhat_et_libguestfs_GuestFS__1close pr " return jr;\n" ); - if optargs <> [] then - pr " */\n"; - pr "}\n"; pr "\n" ) all_functions diff --git a/java/Makefile.am b/java/Makefile.am index 3ae1123..fe55ec2 100644 --- a/java/Makefile.am +++ b/java/Makefile.am @@ -40,7 +40,8 @@ java_sources = \ java_tests = \ Bindtests.java \ t/GuestFS005Load.java \ - t/GuestFS010Basic.java + t/GuestFS010Basic.java \ + t/GuestFS080OptArgs.java EXTRA_DIST = \ $(java_sources) \ diff --git a/java/run-java-tests b/java/run-java-tests index 64ce079..a9fe957 100755 --- a/java/run-java-tests +++ b/java/run-java-tests @@ -18,7 +18,7 @@ set -e -for f in t/*.class; do +for f in $(ls -1 t/*.class | fgrep -v \$); do classname=$(basename $f .class) $JAVA -Djava.library.path=.libs -ea $classname done \ No newline at end of file diff --git a/java/t/GuestFS080OptArgs.java b/java/t/GuestFS080OptArgs.java new file mode 100644 index 0000000..291a8c3 --- /dev/null +++ b/java/t/GuestFS080OptArgs.java @@ -0,0 +1,63 @@ +/* libguestfs Java bindings + * Copyright (C) 2011 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +import java.io.*; +import java.util.HashMap; +import com.redhat.et.libguestfs.*; + +public class GuestFS080OptArgs +{ + public static void main (String[] argv) + { + try { + GuestFS g = new GuestFS (); + + g.add_drive_opts ("/dev/null", null); + + HashMap optargs; + + optargs = new HashMap() { + { + put ("readonly", Boolean.TRUE); + } + }; + g.add_drive_opts ("/dev/null", optargs); + + optargs = new HashMap() { + { + put ("readonly", Boolean.TRUE); + put ("format", "raw"); + } + }; + g.add_drive_opts ("/dev/null", optargs); + + optargs = new HashMap() { + { + put ("readonly", Boolean.TRUE); + put ("format", "raw"); + put ("iface", "virtio"); + } + }; + g.add_drive_opts ("/dev/null", optargs); + } + catch (Exception exn) { + System.err.println (exn); + System.exit (1); + } + } +}