diff options
author | Richard Jones <rjones@redhat.com> | 2010-11-09 12:08:06 +0000 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2010-11-10 10:52:12 +0000 |
commit | 4ada0a7815075c9cbe9d8b00da791c105ae739a9 (patch) | |
tree | 3dbc7ddf2571460e58f366bfad39e5e66ed43891 /generator | |
parent | eaedf025f5c45a4e05cbf25e145215d48bea8f8d (diff) | |
download | libguestfs-4ada0a7815075c9cbe9d8b00da791c105ae739a9.tar.gz libguestfs-4ada0a7815075c9cbe9d8b00da791c105ae739a9.tar.xz libguestfs-4ada0a7815075c9cbe9d8b00da791c105ae739a9.zip |
generator: Add Pointer parameter type to the generator.
This allows generic "foo *bar" pointers to be passed to
library functions (not to daemon functions).
In the language bindings (except Perl) these are handled
as generic int64s with the assumption being that any
pointer can be converted to and from this. There is room
to add specific support for some pointer types in future
by specializing the match cases. However this is inherently
tricky because it depends on the implementation details of
other bindings (eg. to support virDomainPtr in OCaml depends
on the implementation details of the ocaml-libvirt project).
Perl is slightly different in that you have to supply a
typemap. Again this would depend on the implementation
detail of an external library unless you supplied a generic
typemap for int64.
Diffstat (limited to 'generator')
-rw-r--r-- | generator/generator_bindtests.ml | 1 | ||||
-rw-r--r-- | generator/generator_c.ml | 9 | ||||
-rw-r--r-- | generator/generator_capitests.ml | 4 | ||||
-rw-r--r-- | generator/generator_checks.ml | 13 | ||||
-rw-r--r-- | generator/generator_csharp.ml | 4 | ||||
-rw-r--r-- | generator/generator_daemon.ml | 2 | ||||
-rw-r--r-- | generator/generator_fish.ml | 4 | ||||
-rw-r--r-- | generator/generator_haskell.ml | 5 | ||||
-rw-r--r-- | generator/generator_java.ml | 15 | ||||
-rw-r--r-- | generator/generator_ocaml.ml | 9 | ||||
-rw-r--r-- | generator/generator_perl.ml | 5 | ||||
-rw-r--r-- | generator/generator_php.ml | 10 | ||||
-rw-r--r-- | generator/generator_python.ml | 16 | ||||
-rw-r--r-- | generator/generator_ruby.ml | 4 | ||||
-rw-r--r-- | generator/generator_types.ml | 17 | ||||
-rw-r--r-- | generator/generator_utils.ml | 2 | ||||
-rw-r--r-- | generator/generator_xdr.ml | 1 |
17 files changed, 95 insertions, 26 deletions
diff --git a/generator/generator_bindtests.ml b/generator/generator_bindtests.ml index 02b06809..ebe2e246 100644 --- a/generator/generator_bindtests.ml +++ b/generator/generator_bindtests.ml @@ -89,6 +89,7 @@ print_strings (char *const *argv) | Bool n -> pr " printf (\"%%s\\n\", %s ? \"true\" : \"false\");\n" n | Int n -> pr " printf (\"%%d\\n\", %s);\n" n | Int64 n -> pr " printf (\"%%\" PRIi64 \"\\n\", %s);\n" n + | Pointer _ -> assert false ) args; pr " /* Java changes stdout line buffering so we need this: */\n"; pr " fflush (stdout);\n"; diff --git a/generator/generator_c.ml b/generator/generator_c.ml index 4480200a..a2f40da3 100644 --- a/generator/generator_c.ml +++ b/generator/generator_c.ml @@ -116,6 +116,9 @@ let rec generate_prototype ?(extern = true) ?(static = false) pr "const char *%s" n; next (); pr "size_t %s_size" n + | Pointer (t, n) -> + next (); + pr "%s %s" t n ) args; if is_RBufferOut then (next (); pr "size_t *size_r"); if optargs <> [] then ( @@ -536,7 +539,8 @@ check_state (guestfs_h *g, const char *caller) | BufferIn n | StringList n | DeviceList n - | Key n -> + | Key n + | Pointer (_, n) -> pr " if (%s == NULL) {\n" n; pr " error (g, \"%%s: %%s: parameter cannot be NULL\",\n"; pr " \"%s\", \"%s\");\n" shortname n; @@ -639,6 +643,8 @@ check_state (guestfs_h *g, const char *caller) | BufferIn n -> (* RHBZ#646822 *) pr " fputc (' ', stderr);\n"; pr " guestfs___print_BufferIn (stderr, %s, %s_size);\n" n n + | Pointer (t, n) -> + pr " fprintf (stderr, \" (%s)%%p\", %s);\n" t n ) args; (* Optional arguments. *) @@ -770,6 +776,7 @@ check_state (guestfs_h *g, const char *caller) pr " }\n"; pr " args.%s.%s_val = (char *) %s;\n" n n n; pr " args.%s.%s_len = %s_size;\n" n n n + | Pointer _ -> assert false ) args; pr " serial = guestfs___send (g, GUESTFS_PROC_%s,\n" (String.uppercase shortname); diff --git a/generator/generator_capitests.ml b/generator/generator_capitests.ml index 325b37c5..190e10f7 100644 --- a/generator/generator_capitests.ml +++ b/generator/generator_capitests.ml @@ -744,6 +744,9 @@ and generate_test_command_call ?(expect_error = false) ?test test_name cmd = ) strs; pr " NULL\n"; pr " };\n"; + | Pointer _, _ -> + (* Difficult to make these pointers in order to run a test. *) + assert false ) (List.combine (snd style) args); let error_code = @@ -799,6 +802,7 @@ and generate_test_command_call ?(expect_error = false) ?test test_name cmd = pr ", %Ld" i | Bool _, arg -> let b = bool_of_string arg in pr ", %d" (if b then 1 else 0) + | Pointer _, _ -> assert false ) (List.combine (snd style) args); (match fst style with diff --git a/generator/generator_checks.ml b/generator/generator_checks.ml index 34740470..0fb8ea42 100644 --- a/generator/generator_checks.ml +++ b/generator/generator_checks.ml @@ -129,6 +129,19 @@ let () = ) optargs ) all_functions; + (* Some parameter types not supported for daemon functions. *) + List.iter ( + fun (name, (_, args, optargs), _, _, _, _, _) -> + let check_arg_type = function + | Pointer _ -> + failwithf "Pointer is not supported for daemon function %s." + name + | _ -> () + in + List.iter check_arg_type args; + List.iter check_arg_type optargs; + ) daemon_functions; + (* Check short descriptions. *) List.iter ( fun (name, _, _, _, _, shortdesc, _) -> diff --git a/generator/generator_csharp.ml b/generator/generator_csharp.ml index e178945a..5cc71c35 100644 --- a/generator/generator_csharp.ml +++ b/generator/generator_csharp.ml @@ -197,7 +197,7 @@ namespace Guestfs pr ", bool %s" n | Int n -> pr ", int %s" n - | Int64 n -> + | Int64 n | Pointer (_, n) -> pr ", long %s" n ) args; pr ");\n" @@ -222,7 +222,7 @@ namespace Guestfs next (); pr "bool %s" n | Int n -> next (); pr "int %s" n - | Int64 n -> + | Int64 n | Pointer (_, n) -> next (); pr "long %s" n ) args; pr ")\n" diff --git a/generator/generator_daemon.ml b/generator/generator_daemon.ml index df9f965a..e3d87e50 100644 --- a/generator/generator_daemon.ml +++ b/generator/generator_daemon.ml @@ -105,6 +105,7 @@ and generate_daemon_actions () = | BufferIn n -> pr " const char *%s;\n" n; pr " size_t %s_size;\n" n + | Pointer _ -> assert false ) args ); pr "\n"; @@ -174,6 +175,7 @@ and generate_daemon_actions () = | BufferIn n -> pr " %s = args.%s.%s_val;\n" n n n; pr " %s_size = args.%s.%s_len;\n" n n n + | Pointer _ -> assert false ) args; pr "\n" ); diff --git a/generator/generator_fish.ml b/generator/generator_fish.ml index 76b4c7aa..f59c520a 100644 --- a/generator/generator_fish.ml +++ b/generator/generator_fish.ml @@ -323,6 +323,7 @@ Guestfish will prompt for these separately." | Bool n -> pr " int %s;\n" n | Int n -> pr " int %s;\n" n | Int64 n -> pr " int64_t %s;\n" n + | Pointer _ -> assert false ) args; if optargs <> [] then ( @@ -423,6 +424,7 @@ Guestfish will prompt for these separately." parse_integer "argv[i++]" "xstrtoll" "long long" "int" range name | Int64 name -> parse_integer "argv[i++]" "xstrtoll" "long long" "int64_t" None name + | Pointer _ -> assert false ) args; (* Optional arguments are prefixed with <argname>:<value> and @@ -506,6 +508,7 @@ Guestfish will prompt for these separately." pr " free_file_in (%s);\n" name | StringList name | DeviceList name -> pr " free_strings (%s);\n" name + | Pointer _ -> assert false ) args; (* Any output flags? *) @@ -810,6 +813,7 @@ and generate_fish_actions_pod () = | FileIn n | FileOut n -> pr " (%s|-)" n | BufferIn n -> pr " %s" n | Key _ -> () (* keys are entered at a prompt *) + | Pointer _ -> assert false ) args; List.iter ( function diff --git a/generator/generator_haskell.ml b/generator/generator_haskell.ml index b49e385b..88e4f7fd 100644 --- a/generator/generator_haskell.ml +++ b/generator/generator_haskell.ml @@ -148,7 +148,7 @@ last_error h = do pr "withCStringLen %s $ \\(%s, %s_size) -> " n n n | OptString n -> pr "maybeWith withCString %s $ \\%s -> " n n | StringList n | DeviceList n -> pr "withMany withCString %s $ \\%s -> withArray0 nullPtr %s $ \\%s -> " n n n n - | Bool _ | Int _ | Int64 _ -> () + | Bool _ | Int _ | Int64 _ | Pointer _ -> () ) args; (* Convert integer arguments. *) let args = @@ -156,7 +156,7 @@ last_error h = do function | Bool n -> sprintf "(fromBool %s)" n | Int n -> sprintf "(fromIntegral %s)" n - | Int64 n -> sprintf "(fromIntegral %s)" n + | Int64 n | Pointer (_, n) -> sprintf "(fromIntegral %s)" n | FileIn n | FileOut n | Pathname n | Device n | Dev_or_Path n | String n | OptString n @@ -222,6 +222,7 @@ and generate_haskell_prototype ~handle ?(hs = false) (ret, args, optargs) = | Bool _ -> pr "%s" bool | Int _ -> pr "%s" int | Int64 _ -> pr "%s" int + | Pointer _ -> pr "%s" int | FileIn _ -> pr "%s" string | FileOut _ -> pr "%s" string ); diff --git a/generator/generator_java.ml b/generator/generator_java.ml index b5517408..5ac92f74 100644 --- a/generator/generator_java.ml +++ b/generator/generator_java.ml @@ -217,7 +217,7 @@ and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false) pr "boolean %s" n | Int n -> pr "int %s" n - | Int64 n -> + | Int64 n | Pointer (_, n) -> pr "long %s" n ) args; @@ -347,7 +347,7 @@ Java_com_redhat_et_libguestfs_GuestFS__1close pr ", jboolean j%s" n | Int n -> pr ", jint j%s" n - | Int64 n -> + | Int64 n | Pointer (_, n) -> pr ", jlong j%s" n ) args; if optargs <> [] then @@ -410,6 +410,8 @@ Java_com_redhat_et_libguestfs_GuestFS__1close pr " int %s;\n" n | Int64 n -> pr " int64_t %s;\n" n + | Pointer (t, n) -> + pr " %s %s;\n" t n ) args; let needs_i = @@ -458,6 +460,8 @@ Java_com_redhat_et_libguestfs_GuestFS__1close | Int n | Int64 n -> pr " %s = j%s;\n" n n + | Pointer (t, n) -> + pr " %s = (%s) j%s;\n" n t n ) args; if optargs <> [] then ( @@ -497,9 +501,10 @@ Java_com_redhat_et_libguestfs_GuestFS__1close pr " (*env)->ReleaseStringUTFChars (env, o, %s[i]);\n" n; pr " }\n"; pr " free (%s);\n" n - | Bool n - | Int n - | Int64 n -> () + | Bool _ + | Int _ + | Int64 _ + | Pointer _ -> () ) args; (* Check for errors. *) diff --git a/generator/generator_ocaml.ml b/generator/generator_ocaml.ml index 888a1527..860242c7 100644 --- a/generator/generator_ocaml.ml +++ b/generator/generator_ocaml.ml @@ -198,6 +198,7 @@ and generate_ocaml_c () = #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdint.h> #include <caml/config.h> #include <caml/alloc.h> @@ -400,6 +401,8 @@ copy_table (char * const * argv) pr " int %s = Int_val (%sv);\n" n n | Int64 n -> pr " int64_t %s = Int64_val (%sv);\n" n n + | Pointer (t, n) -> + pr " %s %s = (%s) (intptr_t) Int64_val (%sv);\n" t n t n ) args; (* Optional arguments. *) @@ -471,7 +474,7 @@ copy_table (char * const * argv) pr " free (%s);\n" n | StringList n | DeviceList n -> pr " ocaml_guestfs_free_strings (%s);\n" n; - | Bool _ | Int _ | Int64 _ -> () + | Bool _ | Int _ | Int64 _ | Pointer _ -> () ) args; List.iter ( function @@ -481,7 +484,7 @@ copy_table (char * const * argv) | Bool _ | Int _ | Int64 _ | Pathname _ | Device _ | Dev_or_Path _ | OptString _ | FileIn _ | FileOut _ | BufferIn _ | Key _ - | StringList _ | DeviceList _ -> () + | StringList _ | DeviceList _ | Pointer _ -> () ) optargs; pr " if (r == %s)\n" error_code; @@ -592,7 +595,7 @@ and generate_ocaml_function_type (ret, args, optargs) = | StringList _ | DeviceList _ -> pr "string array -> " | Bool _ -> pr "bool -> " | Int _ -> pr "int -> " - | Int64 _ -> pr "int64 -> " + | Int64 _ | Pointer _ -> pr "int64 -> " ) args; (match ret with | RErr -> pr "unit" (* all errors are turned into exceptions *) diff --git a/generator/generator_perl.ml b/generator/generator_perl.ml index 96b8dd18..72f978df 100644 --- a/generator/generator_perl.ml +++ b/generator/generator_perl.ml @@ -242,6 +242,7 @@ clear_progress_callback (g) | Bool n -> pr " int %s;\n" n | Int n -> pr " int %s;\n" n | Int64 n -> pr " int64_t %s;\n" n + | Pointer (t, n) -> pr " %s %s;\n" t n ) args; (* PREINIT section (local variable declarations). *) @@ -362,7 +363,7 @@ clear_progress_callback (g) | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _ | Bool _ | Int _ | Int64 _ | FileIn _ | FileOut _ - | BufferIn _ | Key _ -> () + | BufferIn _ | Key _ | Pointer _ -> () | StringList n | DeviceList n -> pr " free (%s);\n" n ) args; @@ -751,7 +752,7 @@ and generate_perl_prototype name (ret, args, optargs) = match arg with | Pathname n | Device n | Dev_or_Path n | String n | OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n - | BufferIn n | Key n -> + | BufferIn n | Key n | Pointer (_, n) -> pr "$%s" n | StringList n | DeviceList n -> pr "\\@%s" n diff --git a/generator/generator_php.ml b/generator/generator_php.ml index b71d5c35..d405656d 100644 --- a/generator/generator_php.ml +++ b/generator/generator_php.ml @@ -200,7 +200,7 @@ PHP_FUNCTION (guestfs_last_error) pr " char **%s;\n" n; | Bool n -> pr " zend_bool %s;\n" n - | Int n | Int64 n -> + | Int n | Int64 n | Pointer (_, n) -> pr " long %s;\n" n ) args; @@ -236,7 +236,7 @@ PHP_FUNCTION (guestfs_last_error) | OptString n -> "s!" | StringList n | DeviceList n -> "a" | Bool n -> "b" - | Int n | Int64 n -> "l" + | Int n | Int64 n | Pointer (_, n) -> "l" ) args ) in @@ -267,7 +267,7 @@ PHP_FUNCTION (guestfs_last_error) pr ", &z_%s" n | Bool n -> pr ", &%s" n - | Int n | Int64 n -> + | Int n | Int64 n | Pointer (_, n) -> pr ", &%s" n ) args; List.iter ( @@ -330,7 +330,7 @@ PHP_FUNCTION (guestfs_last_error) pr " %s[c] = NULL;\n" n; pr " }\n"; pr "\n" - | Bool n | Int n | Int64 n -> () + | Bool _ | Int _ | Int64 _ | Pointer _ -> () ) args; (* Optional arguments. *) @@ -406,7 +406,7 @@ PHP_FUNCTION (guestfs_last_error) pr " efree (%s);\n" n; pr " }\n"; pr "\n" - | Bool n | Int n | Int64 n -> () + | Bool _ | Int _ | Int64 _ | Pointer _ -> () ) args; (* Check for errors. *) diff --git a/generator/generator_python.ml b/generator/generator_python.ml index f85f5d6c..bc570a88 100644 --- a/generator/generator_python.ml +++ b/generator/generator_python.ml @@ -324,6 +324,9 @@ py_guestfs_close (PyObject *self, PyObject *args) | Bool n -> pr " int %s;\n" n | Int n -> pr " int %s;\n" n | Int64 n -> pr " long long %s;\n" n + | Pointer (t, n) -> + pr " long long %s_int64;\n" n; + pr " %s %s;\n" t n ) args; if optargs <> [] then ( @@ -360,9 +363,11 @@ py_guestfs_close (PyObject *self, PyObject *args) | StringList _ | DeviceList _ -> pr "O" | Bool _ -> pr "i" (* XXX Python has booleans? *) | Int _ -> pr "i" - | Int64 _ -> pr "L" (* XXX Whoever thought it was a good idea to - * emulate C's int/long/long long in Python? - *) + | Int64 _ | Pointer _ -> + (* XXX Whoever thought it was a good idea to + * emulate C's int/long/long long in Python? + *) + pr "L" | BufferIn _ -> pr "s#" ) args; @@ -388,6 +393,7 @@ py_guestfs_close (PyObject *self, PyObject *args) | Bool n -> pr ", &%s" n | Int n -> pr ", &%s" n | Int64 n -> pr ", &%s" n + | Pointer (_, n) -> pr ", &%s_int64" n | BufferIn n -> pr ", &%s, &%s_size" n n ) args; @@ -409,6 +415,8 @@ py_guestfs_close (PyObject *self, PyObject *args) | StringList n | DeviceList n -> pr " %s = get_string_list (py_%s);\n" n n; pr " if (!%s) return NULL;\n" n + | Pointer (t, n) -> + pr " %s = (%s) (intptr_t) %s_int64;\n" n t n ) args; pr "\n"; @@ -444,7 +452,7 @@ py_guestfs_close (PyObject *self, PyObject *args) function | Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _ | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _ - | BufferIn _ -> () + | BufferIn _ | Pointer _ -> () | StringList n | DeviceList n -> pr " free (%s);\n" n ) args; diff --git a/generator/generator_ruby.ml b/generator/generator_ruby.ml index d0a7cd20..6d627b05 100644 --- a/generator/generator_ruby.ml +++ b/generator/generator_ruby.ml @@ -148,6 +148,8 @@ static VALUE ruby_guestfs_close (VALUE gv) pr " int %s = NUM2INT (%sv);\n" n n | Int64 n -> pr " long long %s = NUM2LL (%sv);\n" n n + | Pointer (t, n) -> + pr " %s %s = (%s) (intptr_t) NUM2LL (%sv);\n" t n t n ) args; pr "\n"; @@ -210,7 +212,7 @@ static VALUE ruby_guestfs_close (VALUE gv) function | Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _ | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _ - | BufferIn _ -> () + | BufferIn _ | Pointer _ -> () | StringList n | DeviceList n -> pr " free (%s);\n" n ) args; diff --git a/generator/generator_types.ml b/generator/generator_types.ml index 262fb205..a480aac9 100644 --- a/generator/generator_types.ml +++ b/generator/generator_types.ml @@ -185,6 +185,23 @@ and argt = *) | FileIn of string | FileOut of string + (* This specifies an opaque pointer that is passed through + * untouched. Only non-daemon functions are supported. + * + * Pointer ("foo *", "bar") translates to "foo *bar" in the + * C API. The pointer ("bar") cannot be NULL. + * + * This is less well supported in other language bindings: + * if the pointer type is known then we may be able to produce + * a suitable binding, otherwise this is translated into a 64 + * bit int. + * + * Functions with this parameter type are not supported at all + * in guestfish (the function must be declared "NotInFish" else + * you will get an error). Also the function cannot contain + * tests, although we should fix this in future. + *) + | Pointer of (string * string) type flags = | ProtocolLimitWarning (* display warning about protocol size limits *) diff --git a/generator/generator_utils.ml b/generator/generator_utils.ml index 425a5794..6dc11bfd 100644 --- a/generator/generator_utils.ml +++ b/generator/generator_utils.ml @@ -230,7 +230,7 @@ let map_chars f str = let name_of_argt = function | Pathname n | Device n | Dev_or_Path n | String n | OptString n | StringList n | DeviceList n | Bool n | Int n | Int64 n - | FileIn n | FileOut n | BufferIn n | Key n -> n + | FileIn n | FileOut n | BufferIn n | Key n | Pointer (_, n) -> n let seq_of_test = function | TestRun s | TestOutput (s, _) | TestOutputList (s, _) diff --git a/generator/generator_xdr.ml b/generator/generator_xdr.ml index b44e2ef1..c6d8a4d0 100644 --- a/generator/generator_xdr.ml +++ b/generator/generator_xdr.ml @@ -86,6 +86,7 @@ let generate_xdr () = | BufferIn n -> pr " opaque %s<>;\n" n | FileIn _ | FileOut _ -> () + | Pointer _ -> assert false ) args; pr "};\n\n" ); |